From 551c58fc3c94e37587f8cf0ddcacc2647bea2b3e Mon Sep 17 00:00:00 2001 From: novgorodschi catalin Date: Mon, 7 Sep 2026 12:48:07 +0300 Subject: [PATCH] Fix Support Account Fix Support Account --- install/include/accounts.php | 74 +++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/install/include/accounts.php b/install/include/accounts.php index be1d7a61..3f20517d 100644 --- a/install/include/accounts.php +++ b/install/include/accounts.php @@ -118,12 +118,32 @@ /** * Satul contului Support. * - * BUG REPARAT: Support primea doar parola, fara sat. La prima autentificare, - * Village.php nu gasea niciun sat, iar lantul se termina cu o eroare fatala - * in getUnit() (interogare SQL construita din valori goale) - adica 500 pe - * toata interfata, fara nicio cale de iesire. + * BUG REPARAT (istoric): Support primea doar parola, fara sat. La prima + * autentificare, Village.php nu gasea niciun sat, iar lantul se termina + * cu o eroare fatala in getUnit() (interogare SQL construita din valori + * goale) - adica 500 pe toata interfata, fara nicio cale de iesire. * - * Ii dam un sat langa Multihunter, cu aceeasi configuratie 4-4-4-6. + * BUG REPARAT (07.09.2026, raportat de Catalin cu exemplu concret): + * fix-ul de mai sus cauta liber DOAR pe o linie dreapta (y=0, x=1..19, + * 19 casute in total, toate la est de Multihunter). Pe serverul lui, + * exact (1|0) a ajuns sa fie oaza, iar Support a primit satul acolo - + * asta stricat randarea hartii mari in jurul acelei casute. Cautarea + * originala verifica deja getVillageState() == 0, care exclude si + * oazele (occupied != 0 || oasistype != 0) - problema nu e ca lipsea + * verificarea, ci ca o singura linie ingusta de 19 casute e fragila: + * daca zona imediat la est de centru contine un ciorchine de oaze + * (frecvent langa centrul hartii), cautarea poate nimeri exact intr-o + * stare inconsistenta intre momentul verificarii si cel al asignarii. + * + * Fix: cautare in spirala (inele patrate concentrice) in jurul lui + * (0,0), pe toate cele 4 directii, nu doar spre est. Toti candidatii + * dintr-un inel sunt verificati intr-o SINGURA interogare SQL directa + * (getFreeVillage: occupied = 0 AND oasistype = 0), citita proaspat + * din DB, nu din cache-ul PHP. Raza creste pana la 20 (inel maxim), + * adica pana la 1680 de casute candidate - practic imposibil sa fie + * toate ocupate sau oaza. Daca totusi nu se gaseste nimic (n-ar trebui + * sa se intample niciodata), scriem in error_log in loc sa sarim peste + * in tacere, ca sa nu revenim la bug-ul original (Support fara sat). */ $supportRow = mysqli_fetch_assoc(mysqli_query($database->dblink, "SELECT id FROM " . TB_PREFIX . "users WHERE username = 'Support' LIMIT 1")); @@ -134,23 +154,41 @@ "SELECT COUNT(*) AS total FROM " . TB_PREFIX . "vdata WHERE owner = " . $supportUid)); if (!$supportHas || (int) $supportHas['total'] === 0) { - // pornim de langa Multihunter (0,0) si mergem pana gasim liber - $supportX = 1; + $supportWid = 0; - while ($supportX < 20) { - $supportWid = $admin->getWref($supportX, 0); + // inelul 0 ar fi doar (0,0), care e deja al Multihunter-ului, + // deci pornim direct de la inelul 1 + for ($radius = 1; $radius <= 20 && $supportWid === 0; $radius++) { + $ringWids = []; - if ($database->getVillageState($supportWid) == 0) { - $database->setFieldTaken($supportWid); - $database->addVillage($supportWid, $supportUid, 'Support', 1); - $database->addResourceFields($supportWid, 3); - $database->addUnits($supportWid); - $database->addTech($supportWid); - $database->addABTech($supportWid); - break; + for ($dx = -$radius; $dx <= $radius; $dx++) { + for ($dy = -$radius; $dy <= $radius; $dy++) { + // doar marginea inelului curent (interiorul a fost + // deja verificat la razele anterioare) + if (max(abs($dx), abs($dy)) != $radius) { + continue; + } + + $ringWids[] = ((int) WORLD_MAX - $dy) * ((int) WORLD_MAX * 2 + 1) + ((int) WORLD_MAX + $dx + 1); + } } - $supportX++; + // o singura interogare, sursa de adevar = DB-ul curent + $supportWid = (int) $database->getFreeVillage($ringWids); + } + + if ($supportWid > 0) { + $database->setFieldTaken($supportWid); + $database->addVillage($supportWid, $supportUid, 'Support', 1); + $database->addResourceFields($supportWid, 3); + $database->addUnits($supportWid); + $database->addTech($supportWid); + $database->addABTech($supportWid); + } else { + // extrem de improbabil (ar insemna 1680 de casute ocupate + // sau oaza chiar langa centrul hartii) - semnalam clar in + // loc sa lasam Support fara sat in tacere + error_log('TravianZ install: nu am gasit nicio casuta libera (non-oaza) pentru satul Support in raza de 20 fata de centrul hartii.'); } } }