From bc2eaa1380c3cd723bd83847efaf150df0425262 Mon Sep 17 00:00:00 2001 From: Martin Ambrus Date: Mon, 20 Nov 2017 23:46:45 +0100 Subject: [PATCH] refactor: s1_abdata & s1_tdata caching implemented #313 --- GameEngine/Automation.php | 1 + GameEngine/Battle.php | 45 +++++++++++++---------- GameEngine/Database.php | 76 ++++++++++++++++++++++++++++++++++----- 3 files changed, 95 insertions(+), 27 deletions(-) diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php index a427d31b..9533ba14 100755 --- a/GameEngine/Automation.php +++ b/GameEngine/Automation.php @@ -1227,6 +1227,7 @@ class Automation { $database->getEnforceVillage($vilIDs, 0); $database->getMovement(34, $vilIDs, 1); $database->getPrisoners($vilIDs, 0); + $database->getABTech($vilIDs); // calculate battles foreach($dataarray as $data) { diff --git a/GameEngine/Battle.php b/GameEngine/Battle.php index 811ab229..65c02b40 100755 --- a/GameEngine/Battle.php +++ b/GameEngine/Battle.php @@ -4,9 +4,9 @@ ## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ## ## --------------------------------------------------------------------------- ## ## Project: TravianZ ## -## Version: 22.06.2015 ## +## Version: 22.06.2015 ## ## Filename Battle.php ## -## Developed by: Dzoki & Dixie ## +## Developed by: Dzoki & Dixie ## ## Fixed by: Shadow ## ## Thanks to: Akakori & Elmar ## ## Reworked and Fix by: ronix ## @@ -14,7 +14,7 @@ ## License: TravianZ Project ## ## Copyright: TravianZ (c) 2010-2015. All rights reserved. ## ## URLs: http://travian.shadowss.ro ## -## Source code: https://github.com/Shadowss/TravianZ ## +## Source code: https://github.com/Shadowss/TravianZ ## ## ## ################################################################################# @@ -41,16 +41,16 @@ class Battle { } if(isset($post['a2_v5'])) { array_push($target,5); - } + } $_POST['target'] = $target; if(isset($post['h_off_bonus'])) { if (intval($post['h_off_bonus'])>20) {$post['h_off_bonus']=20;} }else $post['h_off_bonus']=0; - + if(isset($post['h_def_bonus'])) { if (intval($post['h_def_bonus'])>20) {$post['h_def_bonus']=20;} }else $post['h_def_bonus']=0; - + if(isset($post['a1_1'])) { $sum = $sum2 = $post['walllevel'] = 0; for($i=1;$i<=10;$i++) { @@ -58,13 +58,13 @@ class Battle { } if($sum > 0) { $post['palast'] = intval($post['palast']); - if($post['palast'] > 20) $post['palast'] = 20; + if($post['palast'] > 20) $post['palast'] = 20; if(isset($post['wall1'])) { $post['wall1'] = intval($post['wall1']); if ($post['wall1'] > 20) $post['wall1']=20; if ($post['walllevel']==0) $post['walllevel']=$post['wall1']; - } + } if(isset($post['wall2'])) { $post['wall2'] = intval($post['wall2']); if ($post['wall2'] > 20) $post['wall2']=20; @@ -110,7 +110,7 @@ class Battle { return array('heroid'=>(int) $heroarray[0]['heroid'],'unit'=>$heroarray[0]['unit'],'atk'=>$h_atk,'di'=>$h_di,'dc'=>$h_dc,'ob'=>$h_ob,'db'=>$h_db,'health'=>$heroarray['health']); } - + private function getBattleHeroSim($attbonus) { global $database; $h_atk =0; @@ -118,7 +118,7 @@ class Battle { return array('unit'=>16,'atk'=>$h_atk,'ob'=>$h_ob); } - + private function simulate($post) { //set the arrays with attacking and defending units $attacker = array('u1'=>0,'u2'=>0,'u3'=>0,'u4'=>0,'u5'=>0,'u6'=>0,'u7'=>0,'u8'=>0,'u9'=>0,'u10'=>0,'u11'=>0,'u12'=>0,'u13'=>0,'u14'=>0,'u15'=>0,'u16'=>0,'u17'=>0,'u18'=>0,'u19'=>0,'u20'=>0,'u21'=>0,'u22'=>0,'u23'=>0,'u24'=>0,'u25'=>0,'u26'=>0,'u27'=>0,'u28'=>0,'u29'=>0,'u30'=>0,'u31'=>0,'u32'=>0,'u33'=>0,'u34'=>0,'u35'=>0,'u36'=>0,'u37'=>0,'u38'=>0,'u39'=>0,'u40'=>0,'u41'=>0,'u42'=>0,'u43'=>0,'u44'=>0,'u45'=>0,'u46'=>0,'u47'=>0,'u48'=>0,'u49'=>0,'u50'=>0); @@ -126,7 +126,7 @@ class Battle { $index = 1; $offhero=intval($post['h_off_bonus']); $hero_strenght=intval($post['h_off']); - $deffhero=intval($post['h_def_bonus']); + $deffhero=intval($post['h_def_bonus']); for($i=$start;$i<=($start+9);$i++) { $attacker['u'.$i] = $post['a1_'.$index]; if($index <=8) { @@ -134,7 +134,7 @@ class Battle { } $index += 1; } - + $defender = array(); $defscout=0; //fix by ronix @@ -145,7 +145,7 @@ class Battle { if($i == 4 || $i == 14 || $i == 23 || $i == 44){ $defscout+=$defender['u'.$i]; } - + } else { $defender['u'.$i] = 0; @@ -174,20 +174,20 @@ class Battle { $walllevel=$post['walllevel']; $wall = $walllevel; $palast = $post['palast']; - + if($scout ==1 && $defscout==0) { $walllevel = 0; $wall = 0; $palast = 0; } - + if($scout ==1) { $palast = 0; //no def point palace n residence when scout } - - if(!$scout) + + if(!$scout) return $this->calculateBattle($attacker,$defender,$wall,$post['a1_v'],$deftribe,$palast,$post['ew1'],$post['ew2'],$post['ktyp']+3,$def_ab,$att_ab1,$att_ab2,$att_ab3,$att_ab4,$att_ab5,$att_ab6,$att_ab7,$att_ab8,$post['kata'],$post['stonemason'],$walllevel,$offhero,$post['h_off'],$deffhero,0,0,0,0,0); - else + else return $this->calculateBattle($attacker,$defender,$wall,$post['a1_v'],$deftribe,$palast,$post['ew1'],$post['ew2'],1,$def_ab,$att_ab1,$att_ab2,$att_ab3,$att_ab4,$att_ab5,$att_ab6,$att_ab7,$att_ab8,$post['kata'],$post['stonemason'],$walllevel,0,0,0,0,0,0,0,0); } @@ -308,6 +308,15 @@ class Battle { $DefendersAll = (!is_null($defReinforcements) ? $database->getEnforceVillage($DefenderWref,0) : $defReinforcements); if(!empty($DefendersAll) && $DefenderWref>0){ + // preload village IDs + $vilIDs = []; + foreach($DefendersAll as $defenders) { + $vilIDs[$defenders['from']] = true; + $vilIDs[$defenders['to']] = true; + } + $vilIDs = array_keys($vilIDs); + $database->getABTech($vilIDs); + foreach($DefendersAll as $defenders) { for ($i=1;$i<=50;$i++) {$def_ab[$i]=0;} $fromvillage = $defenders['from']; diff --git a/GameEngine/Database.php b/GameEngine/Database.php index bfdd8694..17a8d7f8 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -5733,19 +5733,68 @@ References: User ID/Message ID, Mode } function getABTech($vid, $use_cache = true) { - list($vid) = $this->escape_input((int) $vid); + $array_passed = is_array($vid); + + if (!$array_passed) { + $vid = [(int) $vid]; + } else { + foreach ($vid as $index => $ivdValue) { + $vid[$index] = (int) $ivdValue; + } + } + + if (!count($vid)) { + return []; + } // 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::$abTechCache, $vid)) && !is_null($cachedValue)) { + if ($use_cache && !$array_passed && isset(self::$abTechCache[$vid[0]]) && is_array(self::$abTechCache[$vid[0]]) && !count(self::$abTechCache[$vid[0]])) { + return self::$abTechCache[$vid[0]]; + } else if ($use_cache && $array_passed) { + // check what we can return from cache + $newVIDs = []; + foreach ($vid as $key) { + if (!isset(self::$abTechCache[$key])) { + $newVIDs [] = $key; + } + } + + // everything's cached, just return the cache + if (!count($newVIDs)) { + return self::$abTechCache; + } else { + // update remaining IDs to select and cache + $vid = $newVIDs; + } + } else if ($use_cache && !$array_passed && ($cachedValue = self::returnCachedContent(self::$abTechCache, $vid[0])) && !is_null($cachedValue)) { + // special case when we have empty arrays cached for this cache only return $cachedValue; } - $q = "SELECT * FROM " . TB_PREFIX . "abdata where vref = $vid"; - $result = mysqli_query($this->dblink,$q); + $q = "SELECT * FROM " . TB_PREFIX . "abdata where vref IN(".implode(', ', $vid).")"; + $result = $this->mysqli_fetch_all(mysqli_query($this->dblink,$q)); - self::$abTechCache[$vid] = mysqli_fetch_assoc($result); - return self::$abTechCache[$vid]; + // return a single value + if (!$array_passed) { + self::$abTechCache[$vid[0]] = $result; + } else { + if ($result && count($result)) { + foreach ( $result as $record ) { + self::$abTechCache[ $record['vref']] = $record; + } + } + + // check for any missing IDs and fill them in with blanks, + // since no reinforcements were found for these villages + foreach ($vid as $key) { + if (!isset(self::$abTechCache[$key])) { + self::$abTechCache[$key] = []; + } + } + } + + return ($array_passed ? self::$abTechCache : self::$abTechCache[$vid[0]]); } function addResearch($vid, $tech, $time) { @@ -5781,13 +5830,22 @@ References: User ID/Message ID, Mode return self::$isResearchedCache[$vref][$unit]; } - // no need to cache this method function getTech($vid) { - list($vid) = $this->escape_input((int) $vid); + // this is a somewhat non-ideal, externally non-changeable way of caching + // but since we're only ever going to be calling this from Village constructor + // for our current village, this will more than suffice + static $cachedData = []; + $vid = (int) $vid; + + if (isset($cachedData[$vid])) { + return $cachedData[$vid]; + } $q = "SELECT * from " . TB_PREFIX . "tdata where vref = $vid"; $result = mysqli_query($this->dblink,$q); - return mysqli_fetch_assoc($result); + $cachedData[$vid] = mysqli_fetch_assoc($result); + + return $cachedData[$vid]; } // no need to cache this method