Some hot fixes!!!

Some hot fixes!!!
This commit is contained in:
novgorodschi catalin
2026-09-03 13:51:05 +03:00
parent b572760ee7
commit 1bab6640d0
7 changed files with 87 additions and 119 deletions
+20 -1
View File
@@ -278,12 +278,31 @@ trait DatabaseConnectionCore {
// se arunca mai departe neschimbata. Sigur fata de tranzactii: singurele tranzactii
// explicite din cod (updateStore, populateWorldData) folosesc mysqli_query direct,
// nu metoda aceasta - verificat pe tot repo-ul.
//
// HOTFIX "MySQL server has gone away" (log 1-3 sep, cod 2006/CR_SERVER_GONE_ERROR
// sau 2013/CR_SERVER_LOST): conexiunea poate cadea intre tick-urile ciclului intern
// al cron.php (pana la CRON_LOOP_SECONDS=300s), la fel de fatal pe PHP 8.1+. Cod
// separat de cel de deadlock (reconectam, nu doar reincercam): $this->reconnect()
// (deja existent in acest trait) inchide si redeschide $this->dblink inainte de a
// repeta interogarea. Maxim 2 reconectari, dupa care aruncam eroarea mai departe.
$attempt = 0;
$reconnectAttempt = 0;
while (true) {
try {
return mysqli_query($this->dblink, $query);
} catch (mysqli_sql_exception $e) {
if (!in_array((int) $e->getCode(), [1213, 1205], true) || ++$attempt >= 3) {
$code = (int) $e->getCode();
if (in_array($code, [2006, 2013], true)) {
if (++$reconnectAttempt > 2) {
throw $e;
}
$this->reconnect();
usleep(150000 * $reconnectAttempt);
continue;
}
if (!in_array($code, [1213, 1205], true) || ++$attempt >= 3) {
throw $e;
}
usleep(150000 * $attempt); // 150ms, apoi 300ms
+26 -2
View File
@@ -692,7 +692,11 @@ trait DatabaseTroopQueries {
// return a single value
if (!$array_passed) {
self::$villageFromReinforcementsCache[$vid[0].$from[0]] = $result[0];
// BUG FIXED: $result is empty (no reinforcement row for this vid/from
// pair - a normal, common outcome) -> $result[0] doesn't exist ->
// "Undefined array key 0". Null-coalesce; the cached value stays null
// exactly as before, just without the warning on every miss.
self::$villageFromReinforcementsCache[$vid[0].$from[0]] = $result[0] ?? null;
} else {
if ($result && count($result)) {
foreach ( $result as $record ) {
@@ -762,7 +766,13 @@ trait DatabaseTroopQueries {
} else if ($mode == 3) {
$q = "SELECT e.*,o.conqured,o.wref,o.high, o.owner as ownero, v.owner as ownerv FROM ".TB_PREFIX."enforcement as e LEFT JOIN ".TB_PREFIX."odata as o ON e.vref=o.wref LEFT JOIN ".TB_PREFIX."vdata as v ON e.from=v.wref where o.conqured IN(".implode(', ', $ref).") AND o.owner=v.owner";
}
$result = $this->mysqli_fetch_all(mysqli_query($this->dblink,$q));
// BUG FIXED (fatal, log 3 sep): raw mysqli_query() here bypassed $this->query(),
// the only place with retry/reconnect logic - when the connection drops between
// cron.php's internal ticks (cod 2006/2013, "MySQL server has gone away"), this
// call threw an uncaught mysqli_sql_exception straight from Technology::getUpkeep(),
// killing the whole automation tick. Routed through $this->query() (identical
// return value) so it now benefits from the reconnect-and-retry added there.
$result = $this->mysqli_fetch_all($this->query($q));
// return a single value
if (!$array_passed) {
@@ -897,6 +907,20 @@ trait DatabaseTroopQueries {
$mode = [(int) $mode];
}
// BUG FIXED: this only normalized $amt/$mode into arrays when $unit itself
// wasn't one. AutomationStarvation.php calls this with $unit/$amt as arrays
// (array_keys/array_values($killedUnits)) but $mode as a bare scalar (0,
// meaning "subtract, for all of them") - $mode stayed an int, so
// "(int) $mode[$index]" below tried to array-offset an int ("Trying to
// access array offset on int"). Broadcast a scalar $amt/$mode to match
// $unit's length; already-matching arrays are left untouched.
if (!is_array($amt)) {
$amt = array_fill(0, count($unit), (int) $amt);
}
if (!is_array($mode)) {
$mode = array_fill(0, count($unit), (int) $mode);
}
foreach ($unit as $index => $unitType) {
$unitType = ($unitType != 'hero' ? 'u' . $this->escape($unitType) : $unitType);