diff --git a/includes/class.charclass.php b/includes/class.charclass.php index f3789573..388bbd97 100644 --- a/includes/class.charclass.php +++ b/includes/class.charclass.php @@ -16,7 +16,7 @@ class CharClassList extends BaseType { $data[$this->id] = array( 'id' => $this->id, - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'races' => $this->curTpl['raceMask'], 'roles' => $this->curTpl['roles'], 'weapon' => $this->curTpl['weaponTypeMask'], @@ -40,7 +40,7 @@ class CharClassList extends BaseType $refs['gClasses'] = []; while ($this->iterate()) - $refs['gClasses'][$this->id] = ['name' => $this->names[$this->id]]; + $refs['gClasses'][$this->id] = ['name' => $this->getField('name', true)]; } public function addRewardsToJScript(&$ref) { } diff --git a/includes/class.charrace.php b/includes/class.charrace.php index c8133e3e..3777ae59 100644 --- a/includes/class.charrace.php +++ b/includes/class.charrace.php @@ -16,7 +16,7 @@ class CharRaceList extends BaseType { $data[$this->id] = array( 'id' => $this->id, - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'classes' => $this->curTpl['classMask'], 'faction' => $this->curTpl['factionId'], 'leader' => $this->curTpl['leader'], @@ -36,7 +36,7 @@ class CharRaceList extends BaseType if (!isset($refs['gRaces'])) $refs['gRaces'] = []; - $refs['gRaces'][$this->id] = Util::jsEscape($this->names[$this->id]); + $refs['gRaces'][$this->id] = Util::jsEscape($this->getField('name', true)); } public function addRewardsToJScript(&$ref) { } diff --git a/includes/class.currency.php b/includes/class.currency.php index 69526701..aa9b5ab0 100644 --- a/includes/class.currency.php +++ b/includes/class.currency.php @@ -17,7 +17,7 @@ class CurrencyList extends BaseType $data[$this->id] = array( 'id' => $this->id, 'category' => $this->curTpl['category'], - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'icon' => $this->curTpl['iconString'] ); } @@ -35,7 +35,7 @@ class CurrencyList extends BaseType while ($this->iterate()) { $refs['gCurrencies'][$this->id] = array( - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'icon' => $this->curTpl['iconString'] ); } diff --git a/includes/class.filter.php b/includes/class.filter.php index 181fa198..0a58eee5 100644 --- a/includes/class.filter.php +++ b/includes/class.filter.php @@ -30,10 +30,8 @@ abstract class Filter $sub = []; foreach ($v as $sk => $sv) - { - $sv = str_replace("'", "\'", stripslashes($sv)); $sub[$sk] = is_numeric($sv) ? (int)$sv : urlencode($sv); - } + if (!empty($sub) && in_array($k, Filter::$criteria)) $this->fiData['c'][$k] = $sub; else if (!empty($sub)) @@ -41,8 +39,6 @@ abstract class Filter } else // stings and integer { - $v = str_replace("'", "\'", stripslashes($v)); - if (in_array($k, Filter::$criteria)) $this->fiData['c'][$k] = is_numeric($v) ? (int)$v : urlencode($v); else diff --git a/includes/class.item.php b/includes/class.item.php index 94bcddb5..e8457446 100644 --- a/includes/class.item.php +++ b/includes/class.item.php @@ -167,7 +167,7 @@ class ItemList extends BaseType while ($this->iterate()) { $refs['gItems'][$this->id] = array( - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'quality' => $this->curTpl['Quality'], 'icon' => $this->curTpl['icon'], ); @@ -187,7 +187,7 @@ class ItemList extends BaseType if ($this->error) return; - $name = $this->names[$this->id]; + $name = $this->getField('name', true); if (!empty($this->tooltip[$this->id])) return $this->tooltip[$this->id]; @@ -1000,7 +1000,7 @@ class ItemList extends BaseType { $json = array( 'id' => $this->id, - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'quality' => ITEM_QUALITY_HEIRLOOM - $this->curTpl['Quality'], 'icon' => $this->curTpl['icon'], 'classs' => $this->curTpl['class'], diff --git a/includes/class.itemset.php b/includes/class.itemset.php index 98ed4a26..bd591799 100644 --- a/includes/class.itemset.php +++ b/includes/class.itemset.php @@ -53,7 +53,7 @@ class ItemsetList extends BaseType $data[$this->id] = array( 'id' => $this->id, 'idbak' => $this->curTpl['refSetId'], - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'quality' => 7 - $this->curTpl['quality'], 'minlevel' => $this->curTpl['minLevel'], 'maxlevel' => $this->curTpl['maxLevel'], diff --git a/includes/class.pet.php b/includes/class.pet.php index a07fe26a..71639f7b 100644 --- a/includes/class.pet.php +++ b/includes/class.pet.php @@ -25,7 +25,7 @@ class PetList extends BaseType 'id' => $this->id, 'maxlevel' => $this->curTpl['maxLevel'], 'minlevel' => $this->curTpl['minLevel'], - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'type' => $this->curTpl['type'], 'exotic' => $this->curTpl['exotic'], 'spells' => [] diff --git a/includes/class.quest.php b/includes/class.quest.php index 55c26d8d..96d2f97a 100644 --- a/includes/class.quest.php +++ b/includes/class.quest.php @@ -76,7 +76,7 @@ class QuestList extends BaseType while ($this->iterate()) { $data[$this->id] = array( - "n" => Util::localizedString($this->curTpl, 'Title'), + "n" => $this->getField('Title', true), "t" => TYPE_QUEST, "ti" => $this->id, "c" => $this->cat1, @@ -99,7 +99,7 @@ class QuestList extends BaseType 'id' => $this->id, 'level' => $this->curTpl['Level'], 'reqlevel' => $this->curTpl['MinLevel'], - 'name' => Util::localizedString($this->curTpl, 'Title'), + 'name' => $this->getField('Title', true), 'side' => Util::sideByRaceMask($this->curTpl['RequiredRaces']) ); diff --git a/includes/class.spell.php b/includes/class.spell.php index 4f403d40..6c529ca5 100644 --- a/includes/class.spell.php +++ b/includes/class.spell.php @@ -636,7 +636,7 @@ class SpellList extends BaseType if (is_array($var)) { $str .= $var[0]; - $suffix = $var[1]; + $suffix = ' '.$var[1]; } else $str .= $var; @@ -648,7 +648,7 @@ class SpellList extends BaseType $evaled = $this->resolveEvaluation($str); $return = is_numeric($evaled) ? number_format($evaled, $precision) : $evaled; - return $return.' '.$suffix; + return $return.$suffix; } // should probably used only once to create ?_spell. come to think of it, it yields the same results every time.. it absolutely has to! @@ -919,8 +919,9 @@ class SpellList extends BaseType // step 5: variable-depentant variable-text // special case $lONE:ELSE; - while (preg_match('/([\d\.]+)([^\d]*)\$l([\w\s]*):([\w\s]*);/i', $str, $m)) - $str = str_replace($m[1].$m[2].'$l'.$m[3].':'.$m[4].';', $m[1].$m[2].($m[1] == 1 ? $m[3] : $m[4]), $str); + // todo: russian uses THREE (wtf?! oO) cases ($l[singular]:[plural1]:[plural2]) .. explode() chooses always the first plural option :/ + while (preg_match('/([\d\.]+)([^\d]*)(\$l:*)([^:]*):([^;]*);/i', $str, $m)) + $str = str_ireplace($m[1].$m[2].$m[3].$m[4].':'.$m[5].';', $m[1].$m[2].($m[1] == 1 ? $m[4] : explode(':', $m[5])[0]), $str); // step 6: HTMLize // colors @@ -1025,7 +1026,7 @@ class SpellList extends BaseType $x .= '
| '; // name - $x .= ''.$this->names[$this->id].''; + $x .= ''.$this->getField('name', true).''; // rank if (!empty($rankText)) @@ -1276,7 +1277,7 @@ class SpellList extends BaseType while ($this->iterate()) { $data[$this->id] = array( - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'icon' => $this->curTpl['iconString'], 'level' => $this->curTpl['baseLevel'], ); @@ -1296,7 +1297,7 @@ class SpellList extends BaseType $refs['gSpells'][$this->id] = array( 'icon' => $this->curTpl[$iconString], - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), ); } } diff --git a/includes/class.title.php b/includes/class.title.php index 5f73e7c6..319ab976 100644 --- a/includes/class.title.php +++ b/includes/class.title.php @@ -19,11 +19,6 @@ class TitleList extends BaseType // post processing while ($this->iterate()) { - // overwrite names with gender-speciffics - $this->names[$this->id][GENDER_MALE] = Util::localizedString($this->curTpl, 'male'); - if ($this->curTpl['female_loc0'] || $this->curTpl['female_loc'.User::$localeId]) - $this->names[$this->id][GENDER_FEMALE] = Util::localizedString($this->curTpl, 'female'); - // preparse sources if (!empty($this->curTpl['source'])) { @@ -47,7 +42,7 @@ class TitleList extends BaseType { $data[$this->id] = array( 'id' => $this->id, - 'name' => $this->names[$this->id][GENDER_MALE], + 'name' => $this->getField('male', true), 'side' => $this->curTpl['side'], 'gender' => $this->curTpl['gender'], 'expansion' => $this->curTpl['expansion'], @@ -58,8 +53,8 @@ class TitleList extends BaseType $data[$this->id]['source'] = $this->curTpl['source']; } - if (isset($this->name[GENDER_FEMALE])) - $data['namefemale'] = $this->name[GENDER_FEMALE]; + if ($_ = $this->getField('female', true)) + $data['namefemale'] = $_; return $data; } @@ -71,10 +66,10 @@ class TitleList extends BaseType while ($this->iterate()) { - $refs['gTitles'][$this->id]['name'] = Util::jsEscape($this->names[$this->id][GENDER_MALE]); + $refs['gTitles'][$this->id]['name'] = Util::jsEscape($this->getField('male', true)); - if (isset($this->names[$this->id][GENDER_FEMALE])) - $refs['gTitles'][$this->id]['namefemale'] = Util::jsEscape($this->names[$this->id][GENDER_FEMALE]); + if ($_ = $this->getField('female', true)) + $refs['gTitles'][$this->id]['namefemale'] = $_; } } @@ -130,7 +125,8 @@ class TitleList extends BaseType public function getHtmlizedName($gender = GENDER_MALE) { - return str_replace('%s', '<'.Lang::$main['name'].'>', $this->names[$this->id][$gender]); + $field = $gender == GENDER_FEMALE ? 'female' : 'male'; + return str_replace('%s', '<'.Lang::$main['name'].'>', $this->getField($field, true)); } public function addRewardsToJScript(&$ref) { } diff --git a/includes/class.worldevent.php b/includes/class.worldevent.php index 002cc7d4..40e20cd3 100644 --- a/includes/class.worldevent.php +++ b/includes/class.worldevent.php @@ -64,24 +64,18 @@ class WorldEventList extends BaseType // change Ids if holiday is set if ($this->curTpl['holidayId'] > 0) { - // template - $this->curTpl['id'] = $this->curTpl['holidayId']; + $this->curTpl['id'] = $this->curTpl['holidayId']; + $this->curTpl['name'] = $this->getField('name', true); + $replace[$this->id] = $this->curTpl; unset($this->curTpl['description']); - $replace[$this->id] = $this->curTpl; - - // names - unset($this->names[$this->id]); - $this->names[$this->curTpl['id']] = Util::localizedString($this->curTpl, 'name'); } else // set a name if holiday is missing { // template $this->curTpl['name_loc0'] = $this->curTpl['description']; $this->curTpl['iconString'] = 'trade_engineering'; - $replace[$this->id] = $this->curTpl; - - // names - $this->names[$this->id] = '(SERVERSIDE) '.$this->curTpl['description']; + $this->curTpl['name'] = '(SERVERSIDE) '.$this->getField('description', true); + $replace[$this->id] = $this->curTpl; } } @@ -154,7 +148,7 @@ class WorldEventList extends BaseType $data[$this->id] = array( 'category' => $this->curTpl['category'], 'id' => $this->id, - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'rec' => $this->curTpl['occurence'], 'startDate' => $this->curTpl['startTime'], 'endDate' => $this->curTpl['startTime'] + $this->curTpl['length'] @@ -178,7 +172,7 @@ class WorldEventList extends BaseType while ($this->iterate()) { $refs['gHolidays'][$this->id] = array( - 'name' => $this->names[$this->id], + 'name' => $this->getField('name', true), 'icon' => $this->curTpl['iconString'] ); } diff --git a/includes/utilities.php b/includes/utilities.php index eb98a1db..8114ca6a 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -5,14 +5,13 @@ if (!defined('AOWOW_REVISION')) abstract class BaseType { - public $names = []; - public $Id = 0; - public $matches = 0; // total matches unaffected by sqlLimit in config + public $id = 0; public $error = true; protected $templates = []; protected $curTpl = []; // lets iterate! protected $filter = null; + protected $matches = null; // total matches unaffected by sqlLimit in config protected $setupQuery = ''; protected $matchQuery = ''; @@ -170,13 +169,8 @@ abstract class BaseType if (!$rows) return; - $this->matches = DB::Aowow()->SelectCell($this->matchQuery); - foreach ($rows as $k => $tpl) - { - $this->names[$k] = Util::localizedString($tpl, Util::getNameFieldName($tpl)); $this->templates[$k] = $tpl; - } $this->reset(); @@ -205,12 +199,23 @@ abstract class BaseType } // read-access to templates - public function getField($field) + public function getField($field, $localized = false) { - if (!$this->curTpl || !isset($this->curTpl[$field])) - return null; + if (!$this->curTpl || (!$localized && !isset($this->curTpl[$field]))) + return ''; - return $this->curTpl[$field]; + if (!$localized) + return $this->curTpl[$field]; + else + return Util::localizedString($this->curTpl, $field); + } + + public function getMatches() + { + if ($this->matches === null) + $this->matches = DB::Aowow()->SelectCell($this->matchQuery); + + return $this->matches; } public function filterGetSetCriteria() @@ -386,14 +391,14 @@ class Lang $schoolMask &= SPELL_ALL_SCHOOLS; // clamp to available schools.. $tmp = []; - $i = 1; + $i = 0; while ($schoolMask) { - if ($schoolMask & (1 << ($i - 1))) + if ($schoolMask & (1 << $i)) { $tmp[] = self::$game['sc'][$i]; - $schoolMask &= ~(1 << ($i - 1)); + $schoolMask &= ~(1 << $i); } $i++; } @@ -551,21 +556,24 @@ class SmartyAoWoW extends Smarty } // creates the cache file - public function saveCache($key, $data) + public function saveCache($key, $data, $filter = null) { if ($this->debugging) return; $file = $this->cache_dir.'data/'.$key; - $cache_data = time()." ".AOWOW_REVISION."\n"; - $cache_data .= serialize($data); + $cacheData = time()." ".AOWOW_REVISION."\n"; + $cacheData .= serialize($data); - file_put_contents($file, $cache_data); + if ($filter) + $cacheData .= "\n".serialize($filter); + + file_put_contents($file, $cacheData); } // loads and evaluates the cache file - public function loadCache($key, &$data) + public function loadCache($key, &$data, &$filter = null) { if ($this->debugging) return false; @@ -582,6 +590,8 @@ class SmartyAoWoW extends Smarty return false; $data = unserialize($cache[1]); + if (isset($cache[2])) + $filter = unserialize($cache[2]); return true; } @@ -676,6 +686,104 @@ class Util null, 'bc', 'wotlk', 'cata', 'mop' ); + // todo: translate and move to Lang + public static $spellModOp = array( + 0 => 'DAMAGE', + 1 => 'DURATION', + 2 => 'THREAT', + 3 => 'EFFECT1', + 4 => 'CHARGES', + 5 => 'RANGE', + 6 => 'RADIUS', + 7 => 'CRITICAL_CHANCE', + 8 => 'ALL_EFFECTS', + 9 => 'NOT_LOSE_CASTING_TIME', + 10 => 'CASTING_TIME', + 11 => 'COOLDOWN', + 12 => 'EFFECT2', + 13 => 'IGNORE_ARMOR', + 14 => 'COST', + 15 => 'CRIT_DAMAGE_BONUS', + 16 => 'RESIST_MISS_CHANCE', + 17 => 'JUMP_TARGETS', + 18 => 'CHANCE_OF_SUCCESS', + 19 => 'ACTIVATION_TIME', + 20 => 'DAMAGE_MULTIPLIER', + 21 => 'GLOBAL_COOLDOWN', + 22 => 'DOT', + 23 => 'EFFECT3', + 24 => 'BONUS_MULTIPLIER', + 25 => '25_UNUSED', + 26 => 'PROC_PER_MINUTE', + 27 => 'VALUE_MULTIPLIER', + 28 => 'RESIST_DISPEL_CHANCE', + 29 => 'CRIT_DAMAGE_BONUS_2', //one not used spell + 30 => 'SPELL_COST_REFUND_ON_FAIL' + ); + + public static $combatRating = array( + 0 => 'WEAPON_SKILL', + 1 => 'DEFENSE_SKILL', + 2 => 'DODGE', + 3 => 'PARRY', + 4 => 'BLOCK', + 5 => 'HIT_MELEE', + 6 => 'HIT_RANGED', + 7 => 'HIT_SPELL', + 8 => 'CRIT_MELEE', + 9 => 'CRIT_RANGED', + 10 => 'CRIT_SPELL', + 11 => 'HIT_TAKEN_MELEE', + 12 => 'HIT_TAKEN_RANGED', + 13 => 'HIT_TAKEN_SPELL', + 14 => 'CRIT_TAKEN_MELEE', + 15 => 'CRIT_TAKEN_RANGED', + 16 => 'CRIT_TAKEN_SPELL', + 17 => 'HASTE_MELEE', + 18 => 'HASTE_RANGED', + 19 => 'HASTE_SPELL', + 20 => 'WEAPON_SKILL_MAINHAND', + 21 => 'WEAPON_SKILL_OFFHAND', + 22 => 'WEAPON_SKILL_RANGED', + 23 => 'EXPERTISE', + 24 => 'ARMOR_PENETRATION' + ); + + public static $lockType = array( + 1 => 'PICKLOCK', + 2 => 'HERBALISM', + 3 => 'MINING', + 4 => 'DISARM_TRAP', + 5 => 'OPEN', + 6 => 'TREASURE', + 7 => 'CALCIFIED_ELVEN_GEMS', + 8 => 'CLOSE', + 9 => 'ARM_TRAP', + 10 => 'QUICK_OPEN', + 11 => 'QUICK_CLOSE', + 12 => 'OPEN_TINKERING', + 13 => 'OPEN_KNEELING', + 14 => 'OPEN_ATTACKING', + 15 => 'GAHZRIDIAN', + 16 => 'BLASTING', + 17 => 'SLOW_OPEN', + 18 => 'SLOW_CLOSE', + 19 => 'FISHING', + 20 => 'INSCRIPTION', + 21 => 'OPEN_FROM_VEHICLE' + ); + + public static $stealthType = array( + 0 => 'GENERAL', + 1 => 'TRAP' + ); + + public static $invisibilityType = array( + 0 => 'GENERAL', + 3 => 'TRAP', + 6 => 'DRUNK' + ); + public static $spellEffectStrings = array( 0 => 'None', 1 => 'Instakill', @@ -702,13 +810,13 @@ class Util 22 => 'Parry', 23 => 'Block', 24 => 'Create Item', - 25 => 'Weapon', + 25 => 'Can Use Weapon', 26 => 'Defense', 27 => 'Persistent Area Aura', 28 => 'Summon', 29 => 'Leap', 30 => 'Energize', - 31 => 'Weapon Percent Damage', + 31 => 'Weapon Damage Percent', 32 => 'Trigger Missile', 33 => 'Open Lock', 34 => 'Summon Change Item', @@ -735,7 +843,7 @@ class Util 55 => 'Tame Creature', 56 => 'Summon Pet', 57 => 'Learn Pet Spell', - 58 => 'Weapon Damage', + 58 => 'Weapon Damage Flat', 59 => 'Create Random Item', 60 => 'Proficiency', 61 => 'Send Event', @@ -790,7 +898,7 @@ class Util 110 => 'Destroy All Totems', 111 => 'Durability Damage', 112 => 'Summon Demon', - 113 => 'Resurrect New', + 113 => 'Resurrect Flat', 114 => 'Attack Me', 115 => 'Durability Damage Percent', 116 => 'Skin Player Corpse', @@ -798,7 +906,7 @@ class Util 118 => 'Skill', 119 => 'Apply Area Aura Pet', 120 => 'Teleport Graveyard', - 121 => 'Normalized Weapon Dmg', + 121 => 'Weapon Damage Normalized', 122 => 'Unknown Effect', 123 => 'Send Taxi', 124 => 'Pull Towards', @@ -865,8 +973,8 @@ class Util 17 => 'Mod Stealth Detection', 18 => 'Mod Invisibility', 19 => 'Mod Invisibility Detection', - 20 => 'Obsolete Mod Health', - 21 => 'Obsolete Mod Power', + 20 => 'Mod Health Percent', + 21 => 'Mod Power Percent', 22 => 'Mod Resistance', 23 => 'Periodic Trigger Spell', 24 => 'Periodic Energize', @@ -880,10 +988,10 @@ class Util 32 => 'Mod Increase Mounted Speed', 33 => 'Mod Decrease Speed', 34 => 'Mod Increase Health', - 35 => 'Mod Increase Energy', + 35 => 'Mod Increase Power', 36 => 'Shapeshift', - 37 => 'Effect Immunity', - 38 => 'State Immunity', + 37 => 'Spell Effect Immunity', + 38 => 'Spell Aura Immunity', 39 => 'School Immunity', 40 => 'Damage Immunity', 41 => 'Dispel Immunity', @@ -897,7 +1005,7 @@ class Util 49 => 'Mod Dodge Percent', 50 => 'Mod Critical Healing Amount', 51 => 'Mod Block Percent', - 52 => 'Mod Weapon Crit Percent', + 52 => 'Mod Physical Crit Percent', 53 => 'Periodic Leech', 54 => 'Mod Hit Chance', 55 => 'Mod Spell Hit Chance', @@ -963,7 +1071,7 @@ class Util 115 => 'Mod Healing', 116 => 'Mod Regeneration During Combat', 117 => 'Mod Mechanic Resistance', - 118 => 'Mod Healing Percent', + 118 => 'Mod Healing Taken Percent', 119 => 'Share Pet Tracking', 120 => 'Untrackable', 121 => 'Empathy', @@ -1038,7 +1146,7 @@ class Util 190 => 'Mod Faction Reputation Gain', 191 => 'Use Normal Movement Speed', 192 => 'Mod Melee Ranged Haste', - 193 => 'Melee Slow', + 193 => 'Mod Haste', 194 => 'Mod Target Absorb School', 195 => 'Mod Target Ability Absorb School', 196 => 'Mod Cooldown', @@ -1059,10 +1167,10 @@ class Util 211 => 'Mod Flight Speed (not stacking)', 212 => 'Mod Ranged Attack Power Of Stat Percent', 213 => 'Mod Rage from Damage Dealt', - 214 => 'Unknown Aura', + 214 => 'Tamed Pet Passive', 215 => 'Arena Preparation', 216 => 'Haste Spells', - 217 => 'Unknown Aura', + 217 => 'Killing Spree', 218 => 'Haste Ranged', 219 => 'Mod Mana Regeneration from Stat', 220 => 'Mod Rating from Stat', @@ -1075,11 +1183,11 @@ class Util 227 => 'Periodic Trigger Spell With Value', 228 => 'Detect Stealth', 229 => 'Mod AoE Damage Avoidance', - 230 => 'Unknown Aura', + 230 => 'Mod Increase Health', 231 => 'Proc Trigger Spell With Value', - 232 => 'Mechanic Duration Mod', - 233 => 'Unknown Aura', - 234 => 'Mechanic Duration Mod (not stacking)', + 232 => 'Mod Mechanic Duration', + 233 => 'Mod Display Model', + 234 => 'Mod Mechanic Duration (not stacking)', 235 => 'Mod Dispel Resist', 236 => 'Control Vehicle', 237 => 'Mod Spell Damage Of Attack Power', @@ -1103,7 +1211,7 @@ class Util 255 => 'Mod Mechanic Damage Taken Percent', 256 => 'No Reagent Use', 257 => 'Mod Target Resist By Spell Class', - 258 => 'Unknown Aura', + 258 => 'Mod Spell Visual', 259 => 'Mod HoT Percent', 260 => 'Screen Effect', 261 => 'Phase', @@ -1116,12 +1224,12 @@ class Util 268 => 'Mod Attack Power Of Stat Percent', 269 => 'Mod Ignore Target Resist', 270 => 'Mod Ability Ignore Target Resist', - 271 => 'Mod Damage from Caster', + 271 => 'Mod Damage Percent Taken Form Caster', 272 => 'Ignore Melee Reset', 273 => 'X Ray', 274 => 'Ability Consume No Ammo', 275 => 'Mod Ignore Shapeshift', - 276 => 'Unknown Aura', + 276 => 'Mod Damage Percent Mechanic', 277 => 'Mod Max Affected Targets', 278 => 'Mod Disarm Ranged', 279 => 'Initialize Images', @@ -1153,7 +1261,7 @@ class Util 305 => 'Mod Minimum Speed', 306 => 'Unknown Aura', 307 => 'Heal Absorb Test', - 308 => 'Unknown Aura', + 308 => 'Hunter Trap', 309 => 'Unknown Aura', 310 => 'Mod Creature AoE Damage Avoidance', 311 => 'Unknown Aura', @@ -1225,7 +1333,7 @@ class Util public static function parseTime($sec) { - $time = []; + $time = ['d' => 0, 'h' => 0, 'm' => 0, 's' => 0, 'ms' => 0]; if ($sec >= 3600 * 24) { @@ -1264,19 +1372,34 @@ class Util if ($short) { - if (isset($s['d'])) + if ($s['d']) return round($s['d'])." ".Lang::$main['daysAbbr']; - if (isset($s['h'])) + if ($s['h']) return round($s['h'])." ".Lang::$main['hoursAbbr']; - if (isset($s['m'])) + if ($s['m']) return round($s['m'])." ".Lang::$main['minutesAbbr']; - if (isset($s['s'])) - return round($s['s'] + @$s['ms'] / 1000, 2)." ".Lang::$main['secondsAbbr']; - if (isset($s['ms'])) + if ($s['s']) + return round($s['s'] + $s['ms'] / 1000, 2)." ".Lang::$main['secondsAbbr']; + if ($s['ms']) return $s['ms']." ".Lang::$main['millisecsAbbr']; + + return '0 '.Lang::$main['secondsAbbr']; } else { + if ($s['d']) + return round($s['d'] + $s['h'] / 24, 2)." ".Lang::$main['days']; + if ($s['h']) + return round($s['h'] + $s['m'] / 60, 2)." ".Lang::$main['hours']; + if ($s['m']) + return round($s['m'] + $s['s'] / 60, 2)." ".Lang::$main['minutes']; + if ($s['s']) + return round($s['s'] + $s['ms'] / 1000, 2)." ".Lang::$main['seconds']; + if ($s['ms']) + return $s['ms']." ".Lang::$main['millisecs']; + + return '0 '.Lang::$main['seconds']; +/* kept for reference if (isset($s['d'])) $fmt[] = $s['d']." ".Lang::$main['days']; if (isset($s['h'])) @@ -1287,9 +1410,10 @@ class Util $fmt[] = $s['s']." ".Lang::$main['seconds']; if (isset($s['ms'])) $fmt[] = $s['ms']." ".Lang::$main['millisecs']; - } - return implode(' ', $fmt); + // return implode(' ', $fmt); +*/ + } } public static function sideByRaceMask($race) @@ -1306,6 +1430,26 @@ class Util return 0; } + public static function asHex($val) + { + $_ = decHex($val); + while (fMod(strLen($_), 4)) // in 4-blocks + $_ = '0'.$_; + + return '0x'.strToUpper($_); + } + + public static function asBin($val) + { + $_ = decBin($val); + while (fMod(strLen($_), 4)) // in 4-blocks + { + $_ = '0'.$_; + } + + return 'b'.strToUpper($_); + } + public static function sqlEscape($data) { if (!is_array($data)) @@ -1519,20 +1663,6 @@ class Util } // BaseType::_construct craaap! - // todo: unify names - public static function getNameFieldName($tpl) - { - if (isset($tpl['name']) || isset($tpl['name_loc0'])) - return 'name'; - else if (isset($tpl['title']) || isset($tpl['title_loc0'])) - return 'title'; - else if (isset($tpl['male']) || isset($tpl['male_loc'])) - return 'male'; - else - return null; - } - - // BaseType::iterate craaaaaaaaap!!! // todo: unify indizes public static function getIdFieldName($tpl) { diff --git a/index.php b/index.php index 1898094f..e4608275 100644 --- a/index.php +++ b/index.php @@ -91,7 +91,7 @@ switch ($pageCall) break; case 'data': // tool: dataset-loader case 'search': // tool: searches - include $pageCall.'.php'; + require $pageCall.'.php'; break; /* other */ case '': // no parameter given -> MainPage diff --git a/pages/achievement.php b/pages/achievement.php index 95cd466a..73498d90 100644 --- a/pages/achievement.php +++ b/pages/achievement.php @@ -40,7 +40,7 @@ if (isset($_GET['power'])) if (!$smarty->loadCache($cacheKeyTooltip, $x)) { $x = '$WowheadPower.registerAchievement('.$id.', '.User::$localeId.",{\n"; - $x .= "\tname_".User::$localeString.": '".Util::jsEscape($acv->names[$id])."',\n"; + $x .= "\tname_".User::$localeString.": '".Util::jsEscape($acv->getField('name', true))."',\n"; $x .= "\ticon: '".$acv->getField('iconString')."',\n"; $x .= "\ttooltip_".User::$localeString.': \''.$acv->renderTooltip()."'\n"; $x .= "});"; @@ -70,7 +70,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pageData['path'] = array_reverse(array_merge($pageData['path'], [9, 0])); - array_unshift($pageData['title'], $acv->names[$id]); + array_unshift($pageData['title'], $acv->getField('name', true)); $acv->addRewardsToJscript($pageData); $pageData['page'] = $acv->getDetailedData()[$id]; @@ -95,7 +95,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // listview: "see also" $conditions = array( - ['name_loc'.User::$localeId, $acv->names[$id]], + ['name_loc'.User::$localeId, $acv->getField('name', true)], ['id', $id, '!'] ); $saList = new AchievementList($conditions); @@ -257,7 +257,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: $crtSpl = new SpellList(array(['s.id', $obj])); $crtSpl->addGlobalsToJscript($pageData); - $text = $crtName ? $crtName : $crtSpl->names[$crtSpl->id]; + $text = $crtName ? $crtName : $crtSpl->getField('name', true); $tmp['link'] = array( 'href' => '?spell='.$obj, 'text' => $text @@ -276,7 +276,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: $crtItm = new ItemList(array(['id', $obj])); $crtItm->addGlobalsToJscript($pageData); - $text = $crtName ? $crtName : $crtItm->names[$crtItm->id]; + $text = $crtName ? $crtName : $crtItm->getField('name', true); $tmp['link'] = array( 'href' => '?item='.$obj, 'text' => $text, @@ -334,7 +334,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pageData['page']['series'] = array( array( 'id' => $id, - 'name' => $acv->names[$id], + 'name' => $acv->getField('name', true), 'parent' => $acv->getField('series') >> 16, ) ); diff --git a/pages/achievements.php b/pages/achievements.php index 4dcf26a2..827cee89 100644 --- a/pages/achievements.php +++ b/pages/achievements.php @@ -44,7 +44,8 @@ if (!$smarty->loadCache($cacheKey, $pageData)) // include child categories if current category is empty $condition = !$cats[0] ? null : (int)end($cats); $acvList = new AchievementList($condition ? [['category', $condition]] : [], true); - if (!$acvList->matches) + + if (!$acvList->getMatches()) { $curCats = $catList = [$condition ? $condition : 0]; while ($curCats) @@ -88,9 +89,9 @@ if (!$smarty->loadCache($cacheKey, $pageData)) $pageData['params']['visibleCols'] = "$['category']"; // create note if search limit was exceeded - if ($acvList->matches > $AoWoWconf['sqlLimit']) + if ($acvList->getMatches() > $AoWoWconf['sqlLimit']) { - $pageData['params']['note'] = '$'.sprintf(Util::$filterResultString, 'LANG.lvnote_achievementsfound', $acvList->matches, $AoWoWconf['sqlLimit']); + $pageData['params']['note'] = '$'.sprintf(Util::$filterResultString, 'LANG.lvnote_achievementsfound', $acvList->getMatches(), $AoWoWconf['sqlLimit']); $pageData['params']['_truncated'] = 1; } diff --git a/pages/compare.php b/pages/compare.php index 2d513f2b..7fe57420 100644 --- a/pages/compare.php +++ b/pages/compare.php @@ -56,7 +56,7 @@ if ($compareString) $pageData['items'][] = [ $id, - Util::jsEscape($iList->names[$id]), + Util::jsEscape($iList->getField('name', true)), $iList->getField('Quality'), $iList->getField('icon'), json_encode($item, JSON_NUMERIC_CHECK) diff --git a/pages/item.php b/pages/item.php index e3f813ac..2fd5c458 100644 --- a/pages/item.php +++ b/pages/item.php @@ -58,7 +58,7 @@ if (isset($_GET['power'])) $item->renderTooltip($enh); $x .= '$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.", {\n"; - $x .= "\tname_".User::$localeString.": '".Util::jsEscape($item->names[$id])."',\n"; + $x .= "\tname_".User::$localeString.": '".Util::jsEscape($item->getField('name', true))."',\n"; $x .= "\tquality: ".$item->getField('Quality').",\n"; $x .= "\ticon: '".Util::jsEscape($item->getField('icon'))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($item->tooltip[$id])."'\n"; diff --git a/pages/itemsets.php b/pages/itemsets.php index 50f9198b..992d5da1 100644 --- a/pages/itemsets.php +++ b/pages/itemsets.php @@ -30,9 +30,9 @@ if (!$smarty->loadCache($cacheKey, $pageData)) $pageData['params'] = ['tabs' => false]; // create note if search limit was exceeded - if ($itemsets->matches > $AoWoWconf['sqlLimit']) + if ($itemsets->getMatches() > $AoWoWconf['sqlLimit']) { - $pageData['params']['note'] = '$'.sprintf(Util::$filterResultString, 'LANG.lvnote_itemsetsfound', $itemsets->matches, $AoWoWconf['sqlLimit']); + $pageData['params']['note'] = '$'.sprintf(Util::$filterResultString, 'LANG.lvnote_itemsetsfound', $itemsets->getMatches(), $AoWoWconf['sqlLimit']); $pageData['params']['_truncated'] = 1; } diff --git a/pages/spell.php b/pages/spell.php index 1acc83c8..4060dd0d 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -28,7 +28,7 @@ if (isset($_GET['power'])) $x = '$WowheadPower.registerSpell('.$id.', '.User::$localeId.", {\n"; $pt = []; - if ($n = $spell->names[$id]) + if ($n = $spell->getField('name', true)) $pt[] = "\tname_".User::$localeString.": '".Util::jsEscape($n)."'"; if ($i = $spell->getField('iconString')) $pt[] = "\ticon: '".Util::jsEscape($i)."'"; diff --git a/pages/title.php b/pages/title.php index b9a01360..6c4d4f1d 100644 --- a/pages/title.php +++ b/pages/title.php @@ -81,7 +81,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) } } - $pageData['title'] = ucFirst(trim(str_replace('%s', '', str_replace(',', '', $title->names[$title->id][0])))); + $pageData['title'] = ucFirst(trim(str_replace('%s', '', str_replace(',', '', $title->getField('male', true))))); $pageData['path'] = '[0, 10, '.$title->getField('category').']'; $smarty->saveCache($cacheKeyPage, $pageData); diff --git a/search.php b/search.php index e0535620..45e158ef 100644 --- a/search.php +++ b/search.php @@ -58,7 +58,7 @@ $type = @intVal($_GET['type']); $searchMask = 0x0; $found = []; $jsGlobals = []; -$maxResults = 1000; // todo: move to config +$maxResults = 500; // todo: move to config if (isset($_GET['json'])) { @@ -68,7 +68,10 @@ if (isset($_GET['json'])) $searchMask |= SEARCH_TYPE_JSON | 0x40; } else if (isset($_GET['opensearch'])) +{ + $maxResults = 10; $searchMask |= SEARCH_TYPE_OPEN | SEARCH_MASK_OPEN; +} else $searchMask |= SEARCH_TYPE_REGULAR | SEARCH_MASK_ALL; @@ -112,7 +115,7 @@ if ($searchMask & 0x1) weapon: build manually - ItemSubClassMask roles: build manually - 1:heal; 2:mleDPS; 4:rngDPS; 8:tank */ - $classes = new CharClassList(array(['name_loc'.User::$localeId, $query])); + $classes = new CharClassList(array(['name_loc'.User::$localeId, $query]], $maxResults)); if ($data = $classes->getListviewData()) { @@ -122,6 +125,7 @@ if ($searchMask & 0x1) $found['class'] = array( 'type' => TYPE_CLASS, 'appendix' => ' (Class)', + 'matches' => $classes->getMatches(), 'data' => $data, 'params' => ['tabs' => '$myTabs'] ); @@ -137,7 +141,7 @@ if ($searchMask & 0x2) zone: starting zone... */ - $races = new CharRaceList(array(['name_loc'.User::$localeId, $query])); + $races = new CharRaceList(array(['name_loc'.User::$localeId, $query], $maxResults)); if ($data = $races->getListviewData()) { @@ -147,6 +151,7 @@ if ($searchMask & 0x2) $found['race'] = array( 'type' => TYPE_RACE, 'appendix' => ' (Race)', + 'matches' => $races->getMatches(), 'data' => $data, 'params' => ['tabs' => '$myTabs'] ); @@ -173,7 +178,8 @@ if ($searchMask & 0x4) $conditions = array( 'OR', ['male_loc'.User::$localeId, $query], - ['female_loc'.User::$localeId, $query] + ['female_loc'.User::$localeId, $query], + $maxResults ); $titles = new TitleList($conditions); @@ -183,6 +189,7 @@ if ($searchMask & 0x4) $found['title'] = array( 'type' => TYPE_TITLE, 'appendix' => ' (Title)', + 'matches' => $titles->getMatches(), 'data' => $data, 'params' => ['tabs' => '$myTabs'] ); @@ -196,18 +203,18 @@ if ($searchMask & 0x8) icons: data/interface/calendar/calendar_[a-z]start.blp */ - // limited by my own system.. >.< - // cant construct a query like: name = X OR (desc = X AND holidayId = 0) - $wEvents1 = new WorldEventList(array(['h.name_loc'.User::$localeId, $query])); - $wEvents2 = new WorldEventList(array(['e.description', $query], ['e.holidayId', 0], 'AND')); + $conditions = array( + 'OR', + ['h.name_loc'.User::$localeId, $query], + ['AND', ['e.description', $query], ['e.holidayId', 0]], + $maxResults + ); - $data = $wEvents1->getListviewData(); - $data += $wEvents2->getListviewData(); + $wEvents = new WorldEventList($conditions); - if ($data) + if ($data = $wEvents->getListviewData()) { - $wEvents1->addGlobalsToJscript($jsGlobals); - $wEvents2->addGlobalsToJscript($jsGlobals); + $wEvents->addGlobalsToJscript($jsGlobals); foreach ($data as &$d) { @@ -219,6 +226,7 @@ if ($searchMask & 0x8) $found['event'] = array( 'type' => TYPE_WORLDEVENT, 'appendix' => ' (World Event)', + 'matches' => $money->getMatches(), 'data' => $data, 'params' => ['tabs' => '$myTabs'] ); @@ -238,13 +246,14 @@ if ($searchMask & 0x10) $found['currency'] = array( 'type' => TYPE_CURRENCY, 'appendix' => ' (Currency)', + 'matches' => $money->getMatches(), 'data' => $data, 'params' => ['tabs' => '$myTabs'] ); - if ($money->matches > $maxResults) + if ($money->getMatches() > $maxResults) { - $found['currency']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_currenciesfound', $money->matches, $maxResults); + $found['currency']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_currenciesfound', $money->getMatches(), $maxResults); $found['currency']['params']['_truncated'] = 1; } } @@ -253,7 +262,13 @@ if ($searchMask & 0x10) // 6 Itemsets if ($searchMask & 0x20) { - $sets = new ItemsetList(array($maxResults, ['item1', 0, '!'], ['name_loc'.User::$localeId, $query])); // remove empty sets from search + $conditions = array( + ['item1', 0, '!'], // remove empty sets from search + ['name_loc'.User::$localeId, $query], + $maxResults + ); + + $sets = new ItemsetList($conditions); if ($data = $sets->getListviewData()) { @@ -265,14 +280,15 @@ if ($searchMask & 0x20) $found['itemset'] = array( 'type' => TYPE_ITEMSET, 'appendix' => ' (Item Set)', + 'matches' => $sets->getMatches(), 'data' => $data, 'params' => ['tabs' => '$myTabs'], 'pcsToSet' => $sets->pieceToSet ); - if ($sets->matches > $maxResults) + if ($sets->getMatches() > $maxResults) { - $found['itemset']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_itemsetsfound', $sets->matches, $maxResults); + $found['itemset']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_itemsetsfound', $sets->getMatches(), $maxResults); $found['itemset']['params']['_truncated'] = 1; } } @@ -306,13 +322,14 @@ if ($searchMask & 0x40) $found['item'] = array( 'type' => TYPE_ITEM, 'appendix' => ' (Item)', + 'matches' => $items->getMatches(), 'params' => ['tabs' => '$myTabs'], 'data' => $data, ); - if ($items->matches > $maxResults) + if ($items->getMatches() > $maxResults) { - $found['item']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_itemsfound', $items->matches, $maxResults); + $found['item']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_itemsfound', $items->getMatches(), $maxResults); $found['item']['params']['_truncated'] = 1; } } @@ -348,7 +365,13 @@ if ($searchMask & 0x40) // 17 Achievements if ($searchMask & 0x10000) { - $acvs = new AchievementList(array($maxResults, 'AND', ['flags', ~ACHIEVEMENT_FLAG_COUNTER, "&"], ['name_loc'.User::$localeId, $query])); + $conditions = array( + [['flags', ACHIEVEMENT_FLAG_COUNTER, '&'], 0], + ['name_loc'.User::$localeId, $query], + $maxResults + ); + + $acvs = new AchievementList($conditions); if ($data = $acvs->getListviewData()) { @@ -361,6 +384,7 @@ if ($searchMask & 0x10000) $found['achievement'] = array( 'type' => TYPE_ACHIEVEMENT, 'appendix' => ' (Achievement)', + 'matches' => $acvs->getMatches(), 'data' => $data, 'params' => [ 'tabs' => '$myTabs', @@ -368,9 +392,9 @@ if ($searchMask & 0x10000) ] ); - if ($acvs->matches > $maxResults) + if ($acvs->getMatches() > $maxResults) { - $found['achievement']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_achievementsfound', $acvs->matches, $maxResults); + $found['achievement']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_achievementsfound', $acvs->getMatches(), $maxResults); $found['achievement']['params']['_truncated'] = 1; } } @@ -379,7 +403,13 @@ if ($searchMask & 0x10000) // 18 Statistics if ($searchMask & 0x20000) { - $stats = new AchievementList(array($maxResults, 'AND', ['flags', ACHIEVEMENT_FLAG_COUNTER, '&'], ['name_loc'.User::$localeId, $query])); + $conditions = array( + ['flags', ACHIEVEMENT_FLAG_COUNTER, '&'], + ['name_loc'.User::$localeId, $query], + $maxResults + ); + + $stats = new AchievementList($conditions); if ($data = $stats->getListviewData()) { @@ -388,6 +418,7 @@ if ($searchMask & 0x20000) $found['statistic'] = array( 'type' => TYPE_ACHIEVEMENT, + 'matches' => $stats->getMatches(), 'data' => $data, 'params' => [ 'tabs' => '$myTabs', @@ -398,9 +429,9 @@ if ($searchMask & 0x20000) ] ); - if ($stats->matches > $maxResults) + if ($stats->getMatches() > $maxResults) { - $found['statistic']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_statisticsfound', $stats->matches, $maxResults); + $found['statistic']['params']['note'] = '$'.sprintf(Util::$narrowResultString, 'LANG.lvnote_statisticsfound', $stats->getMatches(), $maxResults); $found['statistic']['params']['_truncated'] = 1; } } @@ -432,6 +463,7 @@ if ($searchMask & 0x400000) $found['pet'] = array( 'type' => TYPE_PET, 'appendix' => ' (Pet)', + 'matches' => $pets->getMatches(), 'data' => $data, 'params' => [ 'tabs' => '$myTabs', @@ -507,14 +539,14 @@ else if ($searchMask & SEARCH_TYPE_OPEN) $info = []; foreach ($found as $tmp) - $foundTotal += count($tmp['data']); + $foundTotal += $tmp['matches']; if (!$foundTotal) exit('["'.Util::jsEscape($query).'", []]'); foreach ($found as $id => $set) { - $max = max(1, round($maxResults * count($set['data']) / $foundTotal)); + $max = max(1, (int)($maxResults * $set['matches'] / $foundTotal)); $maxResults -= $max; for ($i = 0; $i < $max; $i++) @@ -534,6 +566,9 @@ else if ($searchMask & SEARCH_TYPE_OPEN) $info[] = '['.implode(', ', $extra).']'; } + + if ($maxResults <= 0) + break; } header("Content-type: text/javascript"); diff --git a/setup/tools/dataset-assembler/enchants.php b/setup/tools/dataset-assembler/enchants.php index ca7901bd..40e3eafa 100644 --- a/setup/tools/dataset-assembler/enchants.php +++ b/setup/tools/dataset-assembler/enchants.php @@ -134,7 +134,7 @@ if (!defined('AOWOW_REVISION')) // check if the spell has an entry in skill_line_ability -> Source:Profession if ($skill = DB::Aowow()->SelectCell('SELECT skillId FROM ?_skill_line_ability WHERE spellId = ?d', $enchantSpells->id)) { - $ench['name'][] = Util::jsEscape($enchantSpells->names[$enchantSpells->id])); + $ench['name'][] = Util::jsEscape($enchantSpells->getField('name', true))); $ench['source'][] = $enchantSpells->id; $ench['skill'] = $skill; $ench['slots'][] = $slot; @@ -147,7 +147,7 @@ if (!defined('AOWOW_REVISION')) $cI &= $castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy while ($cI->iterate()) { - $ench['name'][] = Util::jsEscape($cI->names[$cI->id]); + $ench['name'][] = Util::jsEscape($cI->getField('name', true)); $ench['source'][] = -$cI->id; $ench['icon'] = strTolower($cI->getField('icon')); $ench['slots'][] = $slot; diff --git a/template/bricks/infobox.tpl b/template/bricks/infobox.tpl index 19e0f6a2..a26e308a 100644 --- a/template/bricks/infobox.tpl +++ b/template/bricks/infobox.tpl @@ -3,8 +3,10 @@ |
| {$lang.screenshots} |
|---|
| {$lang.videos} |
| {$lang.videos} |