From b7feb7f2a1da04bd2d4db089995240bc8b46c0d7 Mon Sep 17 00:00:00 2001 From: Ferywir <65760459+Ferywir@users.noreply.github.com> Date: Tue, 16 Jun 2026 15:53:51 +0200 Subject: [PATCH] Perf(sendunitsComplete): batch-preload getMInfo in preloadBattleData [#155] (#234) --- GameEngine/Automation.php | 1 + GameEngine/Database.php | 62 +++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php index f07034fe..ed1cc2a3 100644 --- a/GameEngine/Automation.php +++ b/GameEngine/Automation.php @@ -1387,6 +1387,7 @@ class Automation { $database->getEnforceVillage($vilIDs, 0); $database->getMovement(34, $vilIDs, 1); $database->getABTech($vilIDs); + $database->getMInfo($vilIDs); } private function buildScoutReport($data, $spy_pic, $isoasis, $targettribe, $crannySpy, $totwood, $totclay, $totiron, $totcrop) { diff --git a/GameEngine/Database.php b/GameEngine/Database.php index d02ae256..fd9edc8e 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -2211,19 +2211,63 @@ class MYSQLi_DB implements IDbConnection { } function getMInfo($id, $use_cache = true) { - list($id) = $this->escape_input((int) $id); + $array_passed = is_array($id); - // first of all, check if we should be using cache and whether the field - // required is already cached - if ($use_cache && ($cachedValue = self::returnCachedContent(self::$worldAndVillageDataCache, $id)) && !is_null($cachedValue)) { - return $cachedValue; - } + if (!$array_passed) { + $id = [(int) $id]; + } else { + foreach ($id as $index => $idValue) { + $id[$index] = (int) $idValue; + } + } - $q = "SELECT * FROM " . TB_PREFIX . "wdata left JOIN " . TB_PREFIX . "vdata ON " . TB_PREFIX . "vdata.wref = " . TB_PREFIX . "wdata.id where " . TB_PREFIX . "wdata.id = $id LIMIT 1"; + if (!count($id)) { + return []; + } + + // first of all, check if we should be using cache and whether the data + // required is already cached + if ($use_cache && !$array_passed && ($cachedValue = self::returnCachedContent(self::$worldAndVillageDataCache, $id[0])) && !is_null($cachedValue)) { + return $cachedValue; + } else if ($use_cache && $array_passed) { + // only select the world IDs we haven't cached yet + $newIDs = []; + foreach ($id as $key) { + if (!isset(self::$worldAndVillageDataCache[$key])) { + $newIDs[] = $key; + } + } + + // everything's cached, return the whole cache + if (!count($newIDs)) { + return self::$worldAndVillageDataCache; + } + $id = $newIDs; + } + + $q = "SELECT * FROM " . TB_PREFIX . "wdata left JOIN " . TB_PREFIX . "vdata ON " . TB_PREFIX . "vdata.wref = " . TB_PREFIX . "wdata.id where " . TB_PREFIX . "wdata.id IN(".implode(', ', $id).")"; $result = mysqli_query($this->dblink,$q); - self::$worldAndVillageDataCache[$id] = mysqli_fetch_array($result); - return self::$worldAndVillageDataCache[$id]; + // preserve the original MYSQLI_BOTH semantics (numeric + associative keys) + $rows = []; + if ($result) { + while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)) { + $rows[] = $row; + } + } + + // return a single value + if (!$array_passed) { + self::$worldAndVillageDataCache[$id[0]] = isset($rows[0]) ? $rows[0] : null; + return self::$worldAndVillageDataCache[$id[0]]; + } + + // cache each returned record by its world ID (wdata.id) + foreach ($rows as $record) { + self::$worldAndVillageDataCache[$record['id']] = $record; + } + + return self::$worldAndVillageDataCache; } function getOMInfo($id, $use_cache = true) {