escape(stripslashes($_POST['name'])); mysqli_query($database->dblink, "UPDATE " . TB_PREFIX . "hero SET `name`='" . $_POST['name'] . "' where `uid`='" . $database->escape($session->uid) . "' AND dead = 0") or die("ERROR:" . mysqli_error($database->dblink)); $hero_info['name'] = $_POST['name']; echo "" . NAME_CHANGED . ""; } // Explicit lookup: action from URL (?add=...) => column from `hero` table. // Used for both "(+)" links in the table and for the update // in the DB below. Single source of truth instead of 5 identical blocks. $heroStatColumns = [ 'off' => 'attack', 'deff' => 'defence', 'obonus' => 'attackbonus', 'dbonus' => 'defencebonus', 'reg' => 'regeneration', ]; // Atributul "Resources" apartine sistemului de erou T4: apare si poate primi // puncte doar cand functiile T4 sunt pornite. Tot flag-ul asta decide si daca // productia se aplica (vezi Village::loadHeroProd), deci cele doua nu pot ajunge // in dezacord - altfel jucatorii ar investi in ceva care nu produce nimic. // In plus, cu flag-ul stins interogarile de mai jos nu mai ating coloanele // `resources` / `res_type`, deci pagina merge si pe un server care inca nu a // rulat scriptul add-hero-resources.sql. $t4HeroRes = defined('NEW_FUNCTIONS_HERO_T4') && NEW_FUNCTIONS_HERO_T4; if ($t4HeroRes) { $heroStatColumns['res'] = 'resources'; } // Render the "(+)" link for a stat, or "(+)" uneditable // if the hero has no more points or the stat is already at the top (100). // Identical behavior to the original 5 if/else blocks. $renderAddLink = function ($action) use ($hero_info, $id, $heroStatColumns) { $field = $heroStatColumns[$action]; if ($hero_info['points'] > 0 && $hero_info[$field] < 100) { // class + data-* pentru JS; linkul ramane un GET valid, deci fara JS // pagina se comporta exact ca inainte (un punct per click, cu refresh). return "(+)"; } return "(+)"; }; ?>
| % | ||||
| : | ||||
% .
VillageOasisCount($village->wid); ?> .
: / ( + )
= 0 && $t4Type <= 4) { $t4Stmt = $database->dblink->prepare( "UPDATE " . TB_PREFIX . "hero SET `res_type` = ? WHERE `heroid` = ? LIMIT 1" ); if ($t4Stmt) { $t4HeroId = (int) $hero_info['heroid']; $t4Stmt->bind_param('ii', $t4Type, $t4HeroId); $t4Stmt->execute(); $t4Stmt->close(); } } header("Location: build.php?id=" . $id); exit; } // Distribuire IN BLOC (butonul "Save" din interfata cu JS). // Siguranta: totul se valideaza pe server intr-un SINGUR UPDATE atomic, cu // garzi in WHERE. Daca cineva trimite un POST modificat (mai multe puncte decat // are, sau peste 100 la o statistica), conditiile nu se potrivesc, UPDATE-ul nu // afecteaza niciun rand si nu se schimba nimic. Fiind o singura instructiune, // nici doua cereri trimise simultan nu pot cheltui aceleasi puncte de doua ori. if (isset($_POST['t4points'])) { $t4Alloc = array(); $t4Total = 0; foreach ($heroStatColumns as $t4Key => $t4Col) { $t4Value = isset($_POST['p_' . $t4Key]) ? (int) $_POST['p_' . $t4Key] : 0; if ($t4Value < 0) { $t4Value = 0; } $t4Alloc[$t4Col] = $t4Value; $t4Total += $t4Value; } if ($t4Total > 0) { // Interogarea se construieste din $heroStatColumns, deci acopera exact // atributele active. Cu functiile T4 oprite nu apare deloc coloana // `resources`, asa ca pagina merge si pe un server care inca nu a rulat // scriptul add-hero-resources.sql. $t4Cols = array_values($heroStatColumns); $t4Set = array(); $t4Guard = array(); foreach ($t4Cols as $t4Col) { $t4Set[] = "`" . $t4Col . "` = `" . $t4Col . "` + ?"; $t4Guard[] = "`" . $t4Col . "` + ? <= 100"; } $t4Stmt = $database->dblink->prepare( "UPDATE " . TB_PREFIX . "hero SET " . implode(", ", $t4Set) . ", `points` = `points` - ? WHERE `heroid` = ? AND `points` >= ? AND " . implode(" AND ", $t4Guard) ); if ($t4Stmt) { $t4HeroId = (int) $hero_info['heroid']; // ordinea parametrilor: cresterile, punctele scazute, heroid, garda // de puncte, apoi garzile de maxim 100 pentru fiecare atribut $t4Values = array(); foreach ($t4Cols as $t4Col) { $t4Values[] = $t4Alloc[$t4Col]; } $t4Values[] = $t4Total; $t4Values[] = $t4HeroId; $t4Values[] = $t4Total; foreach ($t4Cols as $t4Col) { $t4Values[] = $t4Alloc[$t4Col]; } $t4Stmt->bind_param(str_repeat('i', count($t4Values)), ...$t4Values); $t4Stmt->execute(); $t4Stmt->close(); } } header("Location: build.php?id=" . $id); exit; } if (isset($_GET['add'])) { $action = $_GET['add']; if ($action == "reset") { if ($hero_info['level'] <= 3) { /** * Resetarea atributelor. * * BUG REPARAT: interogarea enumera coloanele scrise de mana si nu * includea "resources" (atributul T4). Doua consecinte: * * - punctele puse in Resurse NU se stergeau, dar erau rambursate * oricum, deci eroul se alegea cu puncte in plus la fiecare reset; * - daca TOATE punctele erau in Resurse, conditia din WHERE era * falsa si resetarea nu facea absolut nimic. * * Acum coloanele se iau din $heroStatColumns, care contine "resources" * doar cand functiile T4 sunt pornite. Asa lista nu mai poate ramane * in urma daca se adauga un atribut nou. */ $resetCols = array_values($heroStatColumns); $resetSet = array(); $resetWhere = array(); foreach ($resetCols as $resetCol) { $resetSet[] = "`" . $resetCol . "` = 0"; $resetWhere[] = "`" . $resetCol . "` != 0"; } // tipul de resursa produsa revine si el la valoarea implicita if (isset($heroStatColumns['res'])) { $resetSet[] = "`res_type` = 0"; } mysqli_query($database->dblink, "UPDATE " . TB_PREFIX . "hero SET `points` = (`level` * 5) + 5, " . implode(', ', $resetSet) . " WHERE `heroid` = " . (int) $hero_info['heroid'] . " AND `level` <= 3 AND (" . implode(' OR ', $resetWhere) . ")"); header("Location: build.php?id=" . $id . ""); exit; } // if level > 3, exactly like in the original: nothing happens (no redirect). } elseif (isset($heroStatColumns[$action])) { $column = $heroStatColumns[$action]; mysqli_query($database->dblink, "UPDATE " . TB_PREFIX . "hero SET `$column` = `$column` + 1, `points` = `points` - 1 WHERE `heroid` = " . $hero_info['heroid'] . " AND `points` > 0 AND `$column` < 100"); header("Location: build.php?id=" . $id . ""); exit; } } ?>