From 1b978470c6a1018dd373de37bf0f3e4245947b54 Mon Sep 17 00:00:00 2001 From: Ferywir <65760459+Ferywir@users.noreply.github.com> Date: Thu, 18 Jun 2026 13:59:44 +0200 Subject: [PATCH] fix(session): refresh the 30s user-cache after a player's own changes (#239) --- GameEngine/Alliance.php | 12 ++++++++++++ GameEngine/Building.php | 4 ++++ GameEngine/Lang/en.php | 1 + GameEngine/Lang/fr.php | 1 + GameEngine/Lang/ro.php | 1 + GameEngine/Profile.php | 12 ++++++++++++ Templates/Profile/account.tpl | 5 +++++ build.php | 5 +++++ dorf1.php | 4 ++++ 9 files changed, 45 insertions(+) diff --git a/GameEngine/Alliance.php b/GameEngine/Alliance.php index c2d22434..9bafa9e7 100755 --- a/GameEngine/Alliance.php +++ b/GameEngine/Alliance.php @@ -348,6 +348,10 @@ class Alliance { $database->removeInvitation($inviteID); $database->updateUserField($invite['uid'], "alliance", $invite['alliance'], 1); $database->createAlliPermissions($invite['uid'], $invite['alliance'], '', 0, 0, 0, 0, 0, 0, 0, 0); + // Invalidate the 30s session user-cache (see Session::PopulateVar) so the + // new alliance membership shows up immediately, without a re-login. + unset($_SESSION['cache_user_' . $session->username]); + $_SESSION['alliance_user'] = $invite['alliance']; // Log notice în alianță $notice = rc_tok('MSG_NEWS_JOINED', '' . addslashes($session->username) . ''); $database->insertAlliNotice($invite['alliance'], $notice); @@ -397,6 +401,10 @@ class Alliance { $database->updateUserField($session->uid, "alliance", $aid, 1); $database->procAllyPop($aid); $database->createAlliPermissions($session->uid, $aid, 'Alliance founder', '1', '1', '1', '1', '1', '1', '1', '1'); + // Invalidate the 30s session user-cache (see Session::PopulateVar) so the + // new alliance shows up immediately, without a re-login. + unset($_SESSION['cache_user_' . $session->username]); + $_SESSION['alliance_user'] = $aid; $notice = rc_tok('MSG_ALLIANCE_FOUNDED', '' . addslashes($session->username) . ''); $database->insertAlliNotice($aid, $notice); header("Location: build.php?gid=18"); @@ -606,6 +614,10 @@ class Alliance { $database->deleteAlliPermissions($uid); // șterge alianța dacă e goală (comportament original) $database->deleteAlliance($allyId); + // Invalidate the 30s session user-cache (see Session::PopulateVar) so the + // alliance the player just left disappears immediately, without a re-login. + unset($_SESSION['cache_user_' . $session->username]); + $_SESSION['alliance_user'] = 0; $notice = rc_tok('MSG_NEWS_QUIT', '' . addslashes($session->username) . ''); $database->insertAlliNotice($allyId, $notice); header("Location: spieler.php?uid=" . $uid); diff --git a/GameEngine/Building.php b/GameEngine/Building.php index 896d6856..45d26a75 100755 --- a/GameEngine/Building.php +++ b/GameEngine/Building.php @@ -1760,6 +1760,10 @@ class Building { $session->gold = $newgold; $_SESSION['gold'] = $newgold; + // Invalidate the 30s session user-cache (see Session::PopulateVar); the gold + // write is absolute ($session->gold - $spent), so a stale cache would revert + // the balance next request and could allow a double-spend. + unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]); } // un singur query diff --git a/GameEngine/Lang/en.php b/GameEngine/Lang/en.php index b0f47733..a56ef59b 100755 --- a/GameEngine/Lang/en.php +++ b/GameEngine/Lang/en.php @@ -1384,6 +1384,7 @@ tz_def('OLD_PASSWORD', 'Old password'); tz_def('NEW_PASSWORD', 'New password'); tz_def('CHANGE_EMAIL', 'Change email'); tz_def('CHANGE_EMAIL2', 'Please enter your old and your new e-mail addresses. You will then receive a code snippet at both e-mail addresses which you have to enter here'); +tz_def('CURRENT_EMAIL', 'Current email'); tz_def('OLD_EMAIL', 'Old email'); tz_def('NEW_EMAIL', 'New email'); tz_def('ACCOUNT_SITTERS', 'Account sitters'); diff --git a/GameEngine/Lang/fr.php b/GameEngine/Lang/fr.php index 45210cd5..03ea8b12 100644 --- a/GameEngine/Lang/fr.php +++ b/GameEngine/Lang/fr.php @@ -1703,6 +1703,7 @@ define('OLD_PASSWORD', 'Ancien mot de passe'); define('NEW_PASSWORD', 'Nouveau mot de passe'); define('CHANGE_EMAIL', 'Changer d\'e-mail'); define('CHANGE_EMAIL2', 'Veuillez saisir vos anciennes et nouvelles adresses e-mail. Vous recevrez ensuite un code à saisir ici aux deux adresses.'); +define('CURRENT_EMAIL', 'E-mail actuel'); define('OLD_EMAIL', 'Ancien e-mail'); define('NEW_EMAIL', 'Nouvel e-mail'); define('ACCOUNT_SITTERS', 'Substituts du compte'); diff --git a/GameEngine/Lang/ro.php b/GameEngine/Lang/ro.php index 5d2b5c8c..f901040f 100644 --- a/GameEngine/Lang/ro.php +++ b/GameEngine/Lang/ro.php @@ -1379,6 +1379,7 @@ define('OLD_PASSWORD', 'Parolă veche'); define('NEW_PASSWORD', 'Parolă nouă'); define('CHANGE_EMAIL', 'Schimbă email'); define('CHANGE_EMAIL2', 'Introdu adresa veche și cea nouă de email. Vei primi un cod pe ambele adrese pe care trebuie să-l introduci aici'); +define('CURRENT_EMAIL', 'Email actual'); define('OLD_EMAIL', 'Email vechi'); define('NEW_EMAIL', 'Email nou'); define('ACCOUNT_SITTERS', 'Sitteri cont'); diff --git a/GameEngine/Profile.php b/GameEngine/Profile.php index 433e37be..77ea74aa 100755 --- a/GameEngine/Profile.php +++ b/GameEngine/Profile.php @@ -238,6 +238,10 @@ class Profile { $database->RemoveXSS($post['custom_url']) ); + // Invalidate the 30s session user-cache (see Session::PopulateVar) so the + // new graphics pack applies immediately, without a re-login. + unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]); + header("Location: spieler.php?uid=" . $session->uid); exit; } @@ -377,6 +381,11 @@ class Profile { $_SESSION['valuearray'] = $_POST; } + // Invalidate the 30s session user-cache (see Session::PopulateVar) so the + // updated account fields (email, sitters, password) are reflected + // immediately, without a re-login. + unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]); + header("Location: spieler.php?s=3"); exit; } @@ -391,6 +400,9 @@ class Profile { if ($session->userinfo['sit' . $get['type']] == $get['id']) { $database->updateUserField($session->uid, "sit" . $get['type'], 0, 1); + // Invalidate the 30s session user-cache (see Session::PopulateVar) so the + // removed sitter disappears immediately, without a re-login. + unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]); } $session->changeChecker(); diff --git a/Templates/Profile/account.tpl b/Templates/Profile/account.tpl index 1706a679..cd2c96b8 100644 --- a/Templates/Profile/account.tpl +++ b/Templates/Profile/account.tpl @@ -87,6 +87,11 @@ if (!empty($pwError)) { + + + userinfo['email'] ?? '', ENT_QUOTES, 'UTF-8'); ?> + + diff --git a/build.php b/build.php index 9ca40224..c9b69e7a 100644 --- a/build.php +++ b/build.php @@ -110,6 +110,11 @@ if ($session->goldclub == 1 && count($session->villages) > 1) { $database->editTradeRoute($_POST['routeid'], "timeleft", 604800, 1); $newgold = $session->gold - 2; $database->updateUserField($session->uid, 'gold', $newgold, 1); + $session->gold = $newgold; + // Invalidate the 30s session user-cache (see Session::PopulateVar) so + // the gold balance is fresh next request; the write is absolute + // ($session->gold - 2), so a stale cache could double-spend. + unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]); } } $route = 1; diff --git a/dorf1.php b/dorf1.php index 6d959e4e..d5bdb478 100644 --- a/dorf1.php +++ b/dorf1.php @@ -22,6 +22,10 @@ AccessLogger::logRequest(); if(isset($_GET['ok'])){ $database->updateUserField($session->uid,'ok', 0, 1); $_SESSION['ok'] = '0'; + // Invalidate the 30s session user-cache (see Session::PopulateVar); otherwise + // it re-seeds $_SESSION['ok'] from the stale row and the welcome/maintenance + // redirect keeps firing for up to 30s after acknowledging. + unset($_SESSION['cache_user_' . ($_SESSION['username'] ?? '')]); } if(isset($_GET['newdid'])) {