ownerDocument; $node->appendChild($no->createCDATASection($str)); return $this; } } class Util { const FILE_ACCESS = 0755; public static $localeStrings = array( // zero-indexed 'enus', null, 'frfr', 'dede', null, null, 'eses', null, 'ruru' ); public static $subDomains = array( 'www', null, 'fr', 'de', null, null, 'es', null, 'ru' ); public static $typeClasses = array( null, 'CreatureList', 'GameObjectList', 'ItemList', 'ItemsetList', 'QuestList', 'SpellList', 'ZoneList', 'FactionList', 'PetList', 'AchievementList', 'TitleList', 'WorldEventList', 'CharClassList', 'CharRaceList', 'SkillList', null, 'CurrencyList', null, 'SoundList', TYPE_ICON => 'IconList', TYPE_EMOTE => 'EmoteList', TYPE_ENCHANTMENT => 'EnchantmentList' ); public static $typeStrings = array( // zero-indexed null, 'npc', 'object', 'item', 'itemset', 'quest', 'spell', 'zone', 'faction', 'pet', 'achievement', 'title', 'event', 'class', 'race', 'skill', null, 'currency', null, 'sound', TYPE_ICON => 'icon', TYPE_USER => 'user', TYPE_EMOTE => 'emote', TYPE_ENCHANTMENT => 'enchantment' ); # todo (high): find a sensible way to write data here on setup private static $gtCombatRatings = array( 12 => 1.5, 13 => 13.8, 14 => 13.8, 15 => 5, 16 => 10, 17 => 10, 18 => 8, 19 => 14, 20 => 14, 21 => 14, 22 => 10, 23 => 10, 24 => 8, 25 => 0, 26 => 0, 27 => 0, 28 => 10, 29 => 10, 30 => 10, 31 => 10, 32 => 14, 33 => 0, 34 => 0, 35 => 28.75, 36 => 10, 37 => 2.5, 44 => 4.268292513760655 ); public static $itemFilter = array( 20 => 'str', 21 => 'agi', 23 => 'int', 22 => 'sta', 24 => 'spi', 25 => 'arcres', 26 => 'firres', 27 => 'natres', 28 => 'frores', 29 => 'shares', 30 => 'holres', 37 => 'mleatkpwr', 32 => 'dps', 35 => 'damagetype', 33 => 'dmgmin1', 34 => 'dmgmax1', 36 => 'speed', 38 => 'rgdatkpwr', 39 => 'rgdhitrtng', 40 => 'rgdcritstrkrtng', 41 => 'armor', 44 => 'blockrtng', 43 => 'block', 42 => 'defrtng', 45 => 'dodgertng', 46 => 'parryrtng', 48 => 'splhitrtng', 49 => 'splcritstrkrtng', 50 => 'splheal', 51 => 'spldmg', 52 => 'arcsplpwr', 53 => 'firsplpwr', 54 => 'frosplpwr', 55 => 'holsplpwr', 56 => 'natsplpwr', 60 => 'healthrgn', 61 => 'manargn', 57 => 'shasplpwr', 77 => 'atkpwr', 78 => 'mlehastertng', 79 => 'resirtng', 84 => 'mlecritstrkrtng', 94 => 'splpen', 95 => 'mlehitrtng', 96 => 'critstrkrtng', 97 => 'feratkpwr', 100 => 'nsockets', 101 => 'rgdhastertng', 102 => 'splhastertng', 103 => 'hastertng', 114 => 'armorpenrtng', 115 => 'health', 116 => 'mana', 117 => 'exprtng', 119 => 'hitrtng', 123 => 'splpwr', 134 => 'mledps', 135 => 'mledmgmin', 136 => 'mledmgmax', 137 => 'mlespeed', 138 => 'rgddps', 139 => 'rgddmgmin', 140 => 'rgddmgmax', 141 => 'rgdspeed' ); public static $ssdMaskFields = array( 'shoulderMultiplier', 'trinketMultiplier', 'weaponMultiplier', 'primBudged', 'rangedMultiplier', 'clothShoulderArmor', 'leatherShoulderArmor', 'mailShoulderArmor', 'plateShoulderArmor', 'weaponDPS1H', 'weaponDPS2H', 'casterDPS1H', 'casterDPS2H', 'rangedDPS', 'wandDPS', 'spellPower', null, null, 'tertBudged', 'clothCloakArmor', 'clothChestArmor', 'leatherChestArmor', 'mailChestArmor', 'plateChestArmor' ); public static $weightScales = array( 'agi', 'int', 'sta', 'spi', 'str', 'health', 'mana', 'healthrgn', 'manargn', 'armor', 'blockrtng', 'block', 'defrtng', 'dodgertng', 'parryrtng', 'resirtng', 'atkpwr', 'feratkpwr', 'armorpenrtng', 'critstrkrtng', 'exprtng', 'hastertng', 'hitrtng', 'splpen', 'splpwr', 'arcsplpwr', 'firsplpwr', 'frosplpwr', 'holsplpwr', 'natsplpwr', 'shasplpwr', 'dmg', 'mledps', 'rgddps', 'mledmgmin', 'rgddmgmin', 'mledmgmax', 'rgddmgmax', 'mlespeed', 'rgdspeed', 'arcres', 'firres', 'frores', 'holres', 'natres', 'shares', 'mleatkpwr', 'mlecritstrkrtng', 'mlehastertng', 'mlehitrtng', 'rgdatkpwr', 'rgdcritstrkrtng', 'rgdhastertng', 'rgdhitrtng', 'splcritstrkrtng', 'splhastertng', 'splhitrtng', 'spldmg', 'splheal', 'nsockets' ); public static $dateFormatInternal = "Y/m/d H:i:s"; public static $changeLevelString = '%s'; public static $setRatingLevelString = '%s'; public static $filterResultString = '$$WH.sprintf(LANG.lvnote_filterresults, \'%s\')'; public static $tryFilteringString = '$$WH.sprintf(%s, %s, %s) + LANG.dash + LANG.lvnote_tryfiltering.replace(\'\', \'\')'; public static $tryFilteringEntityString = '$$WH.sprintf(LANG.lvnote_entitiesfound, %s, %s, %s) + LANG.dash + LANG.lvnote_tryfiltering.replace(\'\', \'\')'; public static $tryNarrowingString = '$$WH.sprintf(%s, %s, %s) + LANG.dash + LANG.lvnote_trynarrowing'; public static $dfnString = '%s'; public static $mapSelectorString = '%s (%d)'; public static $expansionString = array( // 3 & 4 unused .. obviously null, 'bc', 'wotlk', 'cata', 'mop' ); public static $bgImagePath = array ( 'tiny' => 'style="background-image: url(%s/images/wow/icons/tiny/%s.gif)"', 'small' => 'style="background-image: url(%s/images/wow/icons/small/%s.jpg)"', 'medium' => 'style="background-image: url(%s/images/wow/icons/medium/%s.jpg)"', 'large' => 'style="background-image: url(%s/images/wow/icons/large/%s.jpg)"', ); public static $configCats = array( 'Other', 'Site', 'Caching', 'Account', 'Session', 'Site Reputation', 'Google Analytics' ); public static $tcEncoding = '0zMcmVokRsaqbdrfwihuGINALpTjnyxtgevElBCDFHJKOPQSUWXYZ123456789'; public static $wowheadLink = ''; private static $notes = []; public static function addNote($uGroupMask, $str) { self::$notes[] = [$uGroupMask, $str]; } public static function getNotes() { $notes = []; foreach (self::$notes as $data) if (!$data[0] || User::isInGroup($data[0])) $notes[] = $data[1]; return $notes; } private static $execTime = 0.0; public static function execTime($set = false) { if ($set) { self::$execTime = microTime(true); return; } if (!self::$execTime) return; $newTime = microTime(true); $tDiff = $newTime - self::$execTime; self::$execTime = $newTime; return self::formatTime($tDiff * 1000, true); } public static function getBuyoutForItem($itemId) { if (!$itemId) return 0; // try, when having filled char-DB at hand // return DB::Characters()->selectCell('SELECT SUM(a.buyoutprice) / SUM(ii.count) FROM auctionhouse a JOIN item_instance ii ON ii.guid = a.itemguid WHERE ii.itemEntry = ?d', $itemId); return 0; } public static function formatMoney($qty) { $money = ''; if ($qty >= 10000) { $g = floor($qty / 10000); $money .= ''.$g.' '; $qty -= $g * 10000; } if ($qty >= 100) { $s = floor($qty / 100); $money .= ''.$s.' '; $qty -= $s * 100; } if ($qty > 0) $money .= ''.$qty.''; return $money; } public static function parseTime($sec) { $time = ['d' => 0, 'h' => 0, 'm' => 0, 's' => 0, 'ms' => 0]; if ($sec >= 3600 * 24) { $time['d'] = floor($sec / 3600 / 24); $sec -= $time['d'] * 3600 * 24; } if ($sec >= 3600) { $time['h'] = floor($sec / 3600); $sec -= $time['h'] * 3600; } if ($sec >= 60) { $time['m'] = floor($sec / 60); $sec -= $time['m'] * 60; } if ($sec > 0) { $time['s'] = (int)$sec; $sec -= $time['s']; } if (($sec * 1000) % 1000) $time['ms'] = (int)($sec * 1000); return $time; } public static function formatTime($base, $short = false) { $s = self::parseTime($base / 1000); $fmt = []; if ($short) { if ($_ = round($s['d'] / 364)) return $_." ".Lang::timeUnits('ab', 0); if ($_ = round($s['d'] / 30)) return $_." ".Lang::timeUnits('ab', 1); if ($_ = round($s['d'] / 7)) return $_." ".Lang::timeUnits('ab', 2); if ($_ = round($s['d'])) return $_." ".Lang::timeUnits('ab', 3); if ($_ = round($s['h'])) return $_." ".Lang::timeUnits('ab', 4); if ($_ = round($s['m'])) return $_." ".Lang::timeUnits('ab', 5); if ($_ = round($s['s'] + $s['ms'] / 1000, 2)) return $_." ".Lang::timeUnits('ab', 6); if ($s['ms']) return $s['ms']." ".Lang::timeUnits('ab', 7); return '0 '.Lang::timeUnits('ab', 6); } else { $_ = $s['d'] + $s['h'] / 24; if ($_ > 1 && !($_ % 364)) // whole years return round(($s['d'] + $s['h'] / 24) / 364, 2)." ".Lang::timeUnits($s['d'] / 364 == 1 && !$s['h'] ? 'sg' : 'pl', 0); if ($_ > 1 && !($_ % 30)) // whole month return round(($s['d'] + $s['h'] / 24) / 30, 2)." ".Lang::timeUnits($s['d'] / 30 == 1 && !$s['h'] ? 'sg' : 'pl', 1); if ($_ > 1 && !($_ % 7)) // whole weeks return round(($s['d'] + $s['h'] / 24) / 7, 2)." ".Lang::timeUnits($s['d'] / 7 == 1 && !$s['h'] ? 'sg' : 'pl', 2); if ($s['d']) return round($s['d'] + $s['h'] / 24, 2)." ".Lang::timeUnits($s['d'] == 1 && !$s['h'] ? 'sg' : 'pl', 3); if ($s['h']) return round($s['h'] + $s['m'] / 60, 2)." ".Lang::timeUnits($s['h'] == 1 && !$s['m'] ? 'sg' : 'pl', 4); if ($s['m']) return round($s['m'] + $s['s'] / 60, 2)." ".Lang::timeUnits($s['m'] == 1 && !$s['s'] ? 'sg' : 'pl', 5); if ($s['s']) return round($s['s'] + $s['ms'] / 1000, 2)." ".Lang::timeUnits($s['s'] == 1 && !$s['ms'] ? 'sg' : 'pl', 6); if ($s['ms']) return $s['ms']." ".Lang::timeUnits($s['ms'] == 1 ? 'sg' : 'pl', 7); return '0 '.Lang::timeUnits('pl', 6); } } // pageText for Books (Item or GO) and questText public static function parseHtmlText($text) { if (stristr($text, '')) // text is basically a html-document with weird linebreak-syntax { $pairs = array( '' => '', '' => '', '
' => '', '' => '', '