- converted articles for MorePages to use STATIC_URL (also neutralized some self-references)

- added config-option to restrict available locales
- fixed opensearch suggestions by generating strict json
- include TalentCalc.css as lowerCase (fixes display under *nix)
- some minor formating
- Setup:
 * added some additional files to be generated (they required STATIC_URL or HOST_URL to be set)
 * moved class Locale from global.js to own template and generate it with CFG_LOCALES
 * changed urlParam (?build=script): may be empty (builds everything) or specific scriptNames chained together with ; (?build=script1;script2)

you are required to run the following command to regenerate files affected by these cahnges
?build=demo;power;realmMenu;searchboxBody;searchboxScript;searchplugin;locales
This commit is contained in:
Sarjuuk
2014-09-13 21:26:11 +02:00
parent 70f703b4b2
commit feaee59cd0
53 changed files with 1992 additions and 1895 deletions

View File

@@ -1,230 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'enchants'-file for available locales
// this script requires the following dbc-files to be parsed and available
// Spells, SkillLineAbility, SpellItemEnchantment
// todo (high): restructure to work more efficiently (outer loop: spells, inner loop: locales)
/* Examples
15: {
name:'Leichtes R<>stungsset',
quality:1,
icon:'INV_Misc_ArmorKit_17',
source:-2304,
skill:-1,
slots:525008,
enchantment:'Verst<73>rkt (+8 R<>stung)',
jsonequip:{"armor":8,"reqlevel":1},
temp:0,
classes:0,
gearscore:1
},
2928: {
name:'Ring - Zaubermacht',
quality:-1,
icon:'INV_Misc_Note_01',
source:27924,
skill:333,
slots:1024,
enchantment:'+12 Zaubermacht',
jsonequip:{"splpwr":12},
temp:0,
classes:0,
gearscore:15
},
3231: {
name:['Handschuhe - Waffenkunde','Armschiene - Waffenkunde'],
quality:-1,
icon:'spell_holy_greaterheal',
source:[44484,44598],
skill:333,
slots:[512,256],
enchantment:'+15 Waffenkundewertung',
jsonequip:{reqlevel:60,"exprtng":15},
temp:0,
classes:0,
gearscore:20 // nope, i'm not doing this
},
*/
// from g_item_slots: 13:"One-Hand", 26:"Ranged", 17:"Two-Hand",
$slotPointer = [13, 17, 26, 26, 13, 17, 17, 13, 17, null, 17, null, null, 13, null, 13, null, null, null, null, 17];
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
$enchantSpells = new SpellList([['effect1Id', 53], ['name_loc0', 'QA%', '!'], CFG_SQL_LIMIT_NONE]); // enchantItemPermanent && !qualityAssurance
$castItems = [];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
$enchIds = [];
foreach ($enchantSpells->iterate() as $__)
$enchIds[] = $enchantSpells->getField('effect1MiscValue');
$enchMisc = [];
$enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc);
echo "script set up in ".Util::execTime()."<br>\n";
foreach ($locales as $lId)
{
set_time_limit(180);
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$enchantsOut = [];
foreach ($enchantSpells->iterate() as $__)
{
// slots have to be recalculated
$slot = 0;
if ($enchantSpells->getField('equippedItemClass') == 4) // armor
{
if ($invType = $enchantSpells->getField('equippedItemInventoryTypeMask'))
$slot = $invType >> 1;
else /* if (equippedItemSubClassMask == 64) */ // shields have it their own way <_<
$slot = (1 << (14 - 1));
}
else if ($enchantSpells->getField('equippedItemClass') == 2) // weapon
{
foreach ($slotPointer as $i => $sp)
{
if (!$sp)
continue;
if ((1 << $i) & $enchantSpells->getField('equippedItemSubClassMask'))
{
if ($sp == 13) // also mainHand & offHand *siiigh*
$slot |= ((1 << (21 - 1)) | (1 << (22 - 1)));
$slot |= (1 << ($sp - 1));
}
}
}
$eId = $enchantSpells->getField('effect1MiscValue');
// defaults
$ench = array(
'name' => [], // set by skill or item
'quality' => -1, // modified if item
'icon' => strToLower($enchantSpells->getField('iconString')), // item over spell
'source' => [], // <0: item; >0:spell
'skill' => -1, // modified if skill
'slots' => [], // determined per spell but set per item
'enchantment' => Util::localizedString($enchMisc[$eId]['text'], 'text'),
'jsonequip' => @$enchJSON[$eId] ?: [],
'temp' => 0, // always 0
'classes' => 0, // modified by item
);
if (isset($enchMisc[$eId]['reqskill']))
$ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskill'];
if (isset($enchMisc[$eId]['reqskillrank']))
$ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskillrank'];
if (isset($enchMisc[$eId]['requiredLevel']))
$ench['jsonequip']['requiredLevel'] = $enchMisc[$eId]['requiredLevel'];
// check if the spell has an entry in skill_line_ability -> Source:Profession
if ($skill = DB::Aowow()->SelectCell('SELECT skillLineId FROM dbc.skilllineability WHERE spellId = ?d', $enchantSpells->id))
{
$ench['name'][] = $enchantSpells->getField('name', true);
$ench['source'][] = $enchantSpells->id;
$ench['skill'] = $skill;
$ench['slots'][] = $slot;
}
// check if this spell can be cast via item -> Source:Item
if (!isset($castItems[$enchantSpells->id]))
$castItems[$enchantSpells->id] = new ItemList([['spellId1', $enchantSpells->id], ['name_loc0', 'Scroll of Enchant%', '!']]); // do not reuse enchantment scrolls
$cI = &$castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy
foreach ($cI->iterate() as $__)
{
$ench['name'][] = $cI->getField('name', true);
$ench['source'][] = -$cI->id;
$ench['icon'] = strTolower($cI->getField('iconString'));
$ench['slots'][] = $slot;
if ($cI->getField('quality') > $ench['quality'])
$ench['quality'] = $cI->getField('quality');
if ($cI->getField('requiredClass') > 0)
{
$ench['classes'] = $cI->getField('requiredClass');
$ench['jsonequip']['classes'] = $cI->getField('requiredClass');
}
if (!isset($ench['jsonequip']['reqlevel']))
if ($cI->getField('requiredLevel') > 0)
$ench['jsonequip']['reqlevel'] = $cI->getField('requiredLevel');
}
// enchant spell not in use
if (empty($ench['source']))
continue;
// everything gathered
if (isset($enchantsOut[$eId])) // already found, append data
{
foreach ($enchantsOut[$eId] as $k => $v)
{
if (is_array($v))
{
while ($pop = array_pop($ench[$k]))
$enchantsOut[$eId][$k][] = $pop;
}
else
{
if ($k == 'quality') // quality:-1 if spells and items are mixed
{
if ($enchantsOut[$eId]['source'][0] > 0 && $ench['source'][0] < 0)
$enchantsOut[$eId][$k] = -1;
else if ($enchantsOut[$eId]['source'][0] < 0 && $ench['source'][0] > 0)
$enchantsOut[$eId][$k] = -1;
else
$enchantsOut[$eId][$k] = $ench[$k];
}
else if ($enchantsOut[$eId][$k] <= 0)
$enchantsOut[$eId][$k] = $ench[$k];
}
}
}
else // nothing yet, create new
$enchantsOut[$eId] = $ench;
}
// walk over each entry and strip single-item arrays
foreach ($enchantsOut as &$ench)
{
foreach ($ench as $k => $v)
if (is_array($v) && count($v) == 1 && $k != 'jsonequip')
$ench[$k] = $v[0];
}
$toFile = "var g_enchants = ";
$toFile .= json_encode($enchantsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/enchants';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done enchants loc: ".$lId." in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,106 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'gems'-file for available locales
// this script requires the following dbc-files to be parsed and available
// ItemEnchantment, GemProperties, Spells, Icons
/* Example
22460: {
name:'Prismatic Sphere',
quality:3,
icon:'INV_Enchant_PrismaticSphere',
enchantment:'+3 Resist All',
jsonequip:{"arcres":3,"avgbuyout":242980,"firres":3,"frores":3,"holres":3,"natres":3,"shares":3},
colors:14,
expansion:1
gearscore:8 // as if.....
},
*/
// sketchy, but should work
// Id < 36'000 || ilevel < 70 ? BC : WOTLK
$gemQuery = "
SELECT
it.entry AS itemId,
it.name,
li.*,
IF (it.entry < 36000 OR it.ItemLevel < 70, 1 , 2) AS expansion,
it.Quality AS quality,
i.inventoryicon1 AS icon,
gp.spellItemEnchantmentId AS enchId,
gp.colorMask AS colors
FROM
item_template it
LEFT JOIN
locales_item li ON li.entry = it.entry
JOIN
dbc.gemproperties gp ON gp.Id = it.GemProperties
JOIN
dbc.itemdisplayinfo i ON i.Id = it.displayid
WHERE
it.GemProperties <> 0
ORDER BY
it.entry DESC
;
";
$gems = DB::Aowow()->Select($gemQuery);
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
$enchIds = [];
foreach ($gems as $pop)
$enchIds[] = $pop['enchId'];
$enchMisc = [];
$enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc);
echo "script set up in ".Util::execTime()."<br>\n";
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$gemsOut = [];
foreach ($gems as $pop)
{
$gemsOut[$pop['itemId']] = array(
'name' => Util::localizedString($pop, 'name'),
'quality' => $pop['quality'],
'icon' => strToLower($pop['icon']),
'enchantment' => Util::localizedString(@$enchMisc[$pop['enchId']]['text'] ?: [], 'text'),
'jsonequip' => @$enchJSON[$pop['enchId']] ?: [],
'colors' => $pop['colors'],
'expansion' => $pop['expansion']
);
}
$toFile = "var g_gems = ";
$toFile .= json_encode($gemsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/gems';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done gems loc: ".$lId." in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,105 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'glyphs'-file for available locales
// this script requires the following dbc-files to be parsed and available
// GlyphProperties, Spells, SkillLineAbility
/* Example
40896: {
"name":"Glyph of Frenzied Regeneration",
"description":"For 6 sec after activating Frenzied Regeneration, healing effects on you are 40% more powerful. However, your Frenzied Regeneration now always costs 60 Rage and no longer converts Rage into health.",
"icon":"ability_bullrush",
"type":1,
"classs":11,
"skill":798,
"level":25,
},
*/
$queryGlyphs = '
SELECT
i.id AS itemId,
i.*,
IF (g.typeFlags & 0x1, 2, 1) AS type,
i.subclass AS classs,
i.requiredLevel AS level,
s1.Id AS glyphSpell,
s1.iconStringAlt AS icon,
s1.skillLine1 AS skillId,
s2.Id AS glyphEffect,
s2.Id AS ARRAY_KEY
FROM
?_items i
JOIN
?_spell s1 ON s1.Id = i.spellid1
JOIN
?_glyphproperties g ON g.Id = s1.effect1MiscValue
JOIN
?_spell s2 ON s2.Id = g.spellId
WHERE
i.classBak = 16
;
';
$glyphList = DB::Aowow()->Select($queryGlyphs);
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
echo "script set up in ".Util::execTime()."<br>\n";
$glyphSpells = new SpellList(array(['s.id', array_keys($glyphList)], CFG_SQL_LIMIT_NONE));
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$glyphsOut = [];
foreach ($glyphSpells->iterate() as $__)
{
$pop = $glyphList[$glyphSpells->id];
if (!$pop['glyphEffect'])
continue;
if ($glyphSpells->getField('effect1Id') != 6 && $glyphSpells->getField('effect2Id') != 6 && $glyphSpells->getField('effect3Id') != 6)
continue;
$glyphsOut[$pop['itemId']] = array(
'name' => Util::localizedString($pop, 'name'),
'description' => $glyphSpells->parseText()[0],
'icon' => $pop['icon'],
'type' => $pop['type'],
'classs' => $pop['classs'],
'skill' => $pop['skillId'],
'level' => $pop['level']
);
}
$toFile = "var g_glyphs = ";
$toFile .= json_encode($glyphsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/glyphs';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done glyphs loc: ".$lId." in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,141 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'itemsets'-file for available locales
// this script requires the following dbc-files to be parsed and available
// GlyphProperties, Spells, SkillLineAbility
/* Example
"-447": { // internal id, freely chosen
"classes":["6"], // array
"elite":true,
"heroic":false,
"id":"-447",
"idbak":"924", // actual setId
"maxlevel":"390",
"minlevel":"390",
"name":"3Cataclysmic Gladiator's Desecration",
"note":"37", // contentGroup
"pieces":["73742","73741","73740","73739","73738"],
"reqclass":"32", // mask
"type":"4",
"setbonus":{
"2":{"resirtng":"400","str":"70"},
"4":{"str":"90"}
}
},
*/
$setList = DB::Aowow()->Select('SELECT * FROM ?_itemset ORDER BY refSetId DESC');
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
$jsonBonus = [];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
echo "script set up in ".Util::execTime()."<br>\n";
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$itemsetOut = [];
foreach ($setList as $set)
{
set_time_limit(15);
$setOut = array(
'id' => $set['id'],
'name' => (7 - $set['quality']).Util::jsEscape(Util::localizedString($set, 'name')),
'pieces' => [],
'heroic' => DB::Aowow()->SelectCell('SELECT IF (Flags & 0x8, "true", "false") FROM item_template WHERE entry = ?d', $set['item1']),
'maxlevel' => $set['maxLevel'],
'minlevel' => $set['minLevel'],
'type' => $set['type'],
'setbonus' => []
);
if ($set['classMask'])
{
$setOut['reqclass'] = $set['classMask'];
$setOut['classes'] = [];
for ($i = 0; $i < 12; $i++)
if ($set['classMask'] & (1 << ($i - 1)))
$setOut['classes'][] = $i;
}
if ($set['contentGroup'])
$setOut['note'] = $set['contentGroup'];
if ($set['id'] < 0)
$setOut['idbak'] = $set['refSetId'];
for ($i = 1; $i < 11; $i++)
if ($set['item'.$i])
$setOut['pieces'][] = $set['item'.$i];
for ($i = 1; $i < 9; $i++)
{
if (!$set['bonus'.$i] || !$set['spell'.$i])
continue;
// costy and locale-independant -> cache
if (!isset($jsonBonus[$set['spell'.$i]]))
$jsonBonus[$set['spell'.$i]] = (new SpellList(array(['s.id', (int)$set['spell'.$i]])))->getStatGain()[$set['spell'.$i]];
if (!isset($setOut['setbonus'][$set['bonus'.$i]]))
$setOut['setbonus'][$set['bonus'.$i]] = $jsonBonus[$set['spell'.$i]];
else
foreach ($jsonBonus[$set['spell'.$i]] as $k => $v)
@$setOut['setbonus'][$set['bonus'.$i]][$k] += $v;
}
foreach ($setOut['setbonus'] as $k => $v)
{
if (empty($v))
unset($setOut['setbonus'][$k]);
else
{
foreach ($v as $sk => $sv)
{
if ($str = Util::$itemMods[$sk])
{
$setOut['setbonus'][$k][$str] = $sv;
unset($setOut['setbonus'][$k][$sk]);
}
}
}
}
if (empty($setOut['setbonus']))
unset($setOut['setbonus']);
$itemsetOut[$setOut['id']] = $setOut;
}
$toFile = "var g_itemsets = ";
$toFile .= json_encode($itemsetOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/itemsets';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done itemsets loc: ".$lId." in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,161 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// builds 'pets'-file for available locales
// this script requires the following dbc-files to be parsed and available
// CreatureFamily, CreatureDisplayInfo, FactionTemplate, AreaTable
// Todo:
// locations are a tiny bit wide at the moment.
// I'm still undecided wether the old system is pure genius or pure madness. While building the zone-maps it also generated masks for that zone, using the alpha-channel in the *.blp
// When deciding what spawn lies where you could check against the relative coordinates of that mask. black => isInZone; white => notInZone
// Since i'm lacking other options this will probably be reimplemented.
/* Example data
30: {
id:30,
name:'Forest Spider',
minlevel:5,
maxlevel:6,
location:[12], // master-AreaTableId's (?)
react:[-1,-1],
classification:0, // 0:"Normal", 1:"Elite", 2:"Rar Elite", 3:"Boss", 4:"Rar"
family:3, // creatureFamily
displayId:382,
skin:'TarantulaSkinOrange',
icon:'Ability_Hunter_Pet_Spider', // from creatureFamily.dbc
type:2 // 0:Ferocity, 1:Tenacity, 2:Cunning
},
*/
$petQuery = '
SELECT
ct.entry AS id,
ct.name,
lc.*,
ct.minlevel,
ct.maxlevel,
CONCAT("[", ft.A, ", ", ft.H, "]") AS react,
ct.rank AS classification,
ct.family,
ct.modelId1 AS displayId,
cdi.skin1 AS skin,
SUBSTRING_INDEX(cf.iconFile, "\\\\", -1) AS icon,
cf.petTalentType AS type
FROM
creature_template ct
JOIN
?_factiontemplate ft ON
ft.Id = ct.faction
JOIN
dbc.creaturefamily cf ON
cf.Id = ct.family
LEFT JOIN
locales_creature lc ON
lc.entry = ct.entry
JOIN
dbc.creaturedisplayinfo cdi ON
cdi.id = ct.modelId1
WHERE
cf.petTalentType <> -1 AND
ct.type_flags & 0x1
ORDER BY
ct.entry ASC;
';
$queryZones = '
SELECT DISTINCT
z.id
FROM
creature c
JOIN
?_zones z ON
z.xMin < c.position_x AND
z.xMax > c.position_x AND
z.yMin < c.position_y AND
z.yMax > c.position_y AND
z.mapId = c.map
WHERE
c.id = ?d;
';
$queryInstanceZone = '
SELECT DISTINCT
z.id
FROM
creature c,
?_zones z
WHERE
z.mapId = c.map AND
c.id = ?d;
';
$petList = DB::Aowow()->Select($petQuery);
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
$locations = [];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
echo "script set up in ".Util::execTime()."<br>\n";
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$petsOut = [];
foreach ($petList as $pet)
{
// get locations
// again: caching will save you time and nerves
if (!isset($locations[$pet['id']]))
{
$locations[$pet['id']] = DB::Aowow()->SelectCol($queryZones, $pet['id']);
// probably instanced, map <=> areaId _should_ be bijective
if (empty($locations[$pet['id']]))
if ($z = DB::Aowow()->SelectCell($queryInstanceZone, $pet['id']))
$locations[$pet['id']][] = $z;
}
$petsOut[$pet['id']] = array(
'id' => $pet['id'],
'name' => Util::localizedString($pet, 'name'),
'minlevel' => $pet['minlevel'],
'maxlevel' => $pet['maxlevel'],
'location' => $locations[$pet['id']],
'react' => $pet['react'],
'classification' => $pet['classification'],
'family' => $pet['family'],
'displayId' => $pet['displayId'],
'skin' => $pet['skin'],
'icon' => $pet['icon'],
'type' => $pet['type']
);
}
$toFile = "var g_pets = ";
$toFile .= json_encode($petsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/pets';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done pets loc: ".$lId." in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,328 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// gatheres quasi-static data used in profiler: all available quests, achievements, titles, mounts, companions, factions, recipes
// this script requires a fully set up database and is expected to be run last
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
$sides = [1, 2];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
echo "script set up in ".Util::execTime()."<br><br>\n\n";
/**********/
/* Quests */
/**********/
{
$cnd = [
CFG_SQL_LIMIT_NONE,
'AND',
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW], 0],
[['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE | QUEST_FLAG_AUTO_REWARDED, '&'], 0],
[['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_DUNGEON_FINDER | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]
];
$questz = new QuestList($cnd);
$_ = [];
$currencies = array_column($questz->rewards, TYPE_CURRENCY);
foreach ($currencies as $curr)
foreach ($curr as $cId => $qty)
$_[] = $cId;
$relCurr = new CurrencyList(array(['id', $_]));
foreach ($locales as $l)
{
set_time_limit(20);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$handle = fOpen('datasets/'.User::$localeString.'/p-quests', "w");
if (!$handle)
die('could not create quests file '.$l);
$buff = "var _ = g_gatheredcurrencies;\n";
foreach($relCurr->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
$buff .= "\n\nvar _ = g_quests;\n";
foreach($questz->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
$buff .= "\ng_quest_catorder = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n";
fWrite($handle, $buff);
fClose($handle);
echo "done quests loc: ".$l." in ".Util::execTime()."<br>\n";
}
echo "<br>\n";
}
/****************/
/* Achievements */
/****************/
{
set_time_limit(10);
$cnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
[['flags', 1, '&'], 0], // no statistics
);
$achievez = new AchievementList($cnd);
foreach ($locales as $l)
{
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$handle = fOpen('datasets/'.User::$localeString.'/p-achievements', "w");
if (!$handle)
die('could not create achievements file '.$l);
$sumPoints = 0;
$buff = "var _ = g_achievements;\n";
foreach ($achievez->getListviewData(ACHIEVEMENTINFO_PROFILE) as $id => $data)
{
$sumPoints += $data['points'];
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
// categories to sort by
$buff .= "\ng_achievement_catorder = [92, 14863, 97, 169, 170, 171, 172, 14802, 14804, 14803, 14801, 95, 161, 156, 165, 14806, 14921, 96, 201, 160, 14923, 14808, 14805, 14778, 14865, 14777, 14779, 155, 14862, 14861, 14864, 14866, 158, 162, 14780, 168, 14881, 187, 14901, 163, 14922, 159, 14941, 14961, 14962, 14981, 15003, 15002, 15001, 15041, 15042, 81]";
// sum points
$buff .= "\ng_achievement_points = [".$sumPoints."];\n";
fWrite($handle, $buff);
fClose($handle);
echo "done achievements loc: ".$l." in ".Util::execTime()."<br>\n";
}
echo "<br>\n";
}
/**********/
/* Titles */
/**********/
{
set_time_limit(10);
$cnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
);
$titlez = new TitleList($cnd);
foreach ($locales as $l)
{
foreach ([0, 1] as $g) // gender
{
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$handle = fOpen('datasets/'.User::$localeString.'/p-titles-'.$g, "w");
if (!$handle)
die('could not create titles file '.$l.' '.$g);
$buff = "var _ = g_titles;\n";
foreach ($titlez->getListviewData() as $id => $data)
{
$data['name'] = Util::localizedString($titlez->getEntry($id), $g ? 'female' : 'male');
unset($data['namefemale']);
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
fWrite($handle, $buff);
fClose($handle);
echo "done titles loc: ".$l.", gender: ".$g." in ".Util::execTime()."<br>\n";
}
}
echo "<br>\n";
}
/**********/
/* Mounts */
/**********/
{
set_time_limit(10);
$cnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
['typeCat', -5]
);
$mountz = new SpellList($cnd);
foreach ($locales as $l)
{
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$handle = fOpen('datasets/'.User::$localeString.'/p-mounts', "w");
if (!$handle)
die('could not create mounts file '.$l);
$buff = "var _ = g_spells;\n";
foreach ($mountz->getListviewData(ITEMINFO_MODEL) as $id => $data)
{
$data['quality'] = $data['name'][0];
$data['name'] = substr($data['name'], 1);
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
fWrite($handle, $buff);
fClose($handle);
echo "done mounts loc: ".$l." in ".Util::execTime()."<br>\n";
}
echo "<br>\n";
}
/**************/
/* Companions */
/**************/
{
set_time_limit(10);
$cnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
['typeCat', -6]
);
$companionz = new SpellList($cnd);
foreach ($locales as $l)
{
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$handle = fOpen('datasets/'.User::$localeString.'/p-companions', "w");
if (!$handle)
die('could not create companions file '.$l);
$buff = "var _ = g_spells;\n";
foreach ($companionz->getListviewData(ITEMINFO_MODEL) as $id => $data)
{
$data['quality'] = $data['name'][0];
$data['name'] = substr($data['name'], 1);
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
fWrite($handle, $buff);
fClose($handle);
echo "done companions loc: ".$l." in ".Util::execTime()."<br>\n";
}
echo "<br>\n";
}
/************/
/* Factions */
/************/
{
set_time_limit(10);
// todo (med): exclude non-gaining reputation-header
$cnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]
);
$factionz = new FactionList($cnd);
foreach ($locales as $l)
{
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$handle = fOpen('datasets/'.User::$localeString.'/p-factions', "w");
if (!$handle)
die('could not create factions file '.$l);
$buff = "var _ = g_factions;\n";
foreach ($factionz->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
$buff .= "\ng_faction_order = [0, 469, 891, 1037, 1118, 67, 1052, 892, 936, 1117, 169, 980, 1097];\n";
fWrite($handle, $buff);
fClose($handle);
echo "done factions loc: ".$l." in ".Util::execTime()."<br>\n";
}
echo "<br>\n";
}
/***********/
/* Recipes */
/***********/
{
// special case: secondary skills are always requested, so put them in one single file (185, 129, 356); also it contains g_skill_order
$skills = [171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, [185, 129, 356]];
$baseCnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
['effect1Id', [6, 45, 57, 127, 33, 158, 99, 28, 95], '!'], // aura, tradeSkill, Tracking, Prospecting, Decipher, Milling, Disenchant, Summon (Engineering), Skinning
['effect2Id', [118, 60], '!'], // not the skill itself
['OR', ['typeCat', 9], ['typeCat', 11]]
);
foreach ($skills as $s)
{
set_time_limit(20);
$file = is_array($s) ? 'sec' : (string)$s;
$cnd = array_merge($baseCnd, [['skillLine1', $s]]);
$recipez = new SpellList($cnd);
$created = '';
foreach ($recipez->iterate() as $__)
{
foreach ($recipez->canCreateItem() as $idx)
{
$id = $recipez->getField('effect'.$idx.'CreateItemId');
$created .= "g_items.add(".$id.", {'icon':'".$recipez->relItems->getEntry($id)['iconString']."'});\n";
}
}
foreach ($locales as $l)
{
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$buff = '';
foreach ($recipez->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
if (!$buff)
{
echo " - file: ".$file." has no content => skipping<br>\n";
continue;
}
$handle = fOpen('datasets/'.User::$localeString.'/p-recipes-'.$file, "w");
if (!$handle)
die('could not create '.$file.' file '.$l);
$buff = $created."\nvar _ = g_spells;\n".$buff;
if (is_array($s))
$buff .= "\ng_skill_order = [171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, 185, 129, 356];\n";
fWrite($handle, $buff);
fClose($handle);
echo "done ".$file." loc: ".$l." in ".Util::execTime()."<br>\n";
}
}
echo "<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,120 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'realms'-file in datasets; update profile_all with real realms
// this script requires all realms in use to be defined in auth.realmlist
// battlegroups has to be set in config file
/* seems to be unused, was located in the same file as g_realms
var g_regions = {
us => 'www.wowarmory.com',
eu => 'eu.wowarmory.com'
};
*/
/* Examples
1 => {
name:'Eldre\'Thalas',
battlegroup:'Reckoning',
region:'us'
},
var mn_profiles = [
["us","US & Oceanic",,[
["bloodlust","Bloodlust",,[
["amanthul","Aman'Thul"],
["barthilas","Barthilas"]
]],
["cyclone","Cyclone",,[
["azjol-nerub","Azjol-Nerub"],
["bloodscalp","Bloodscalp"]
]]
]],
["eu","Europe",,[
["blackout","Blackout",,[
["agamaggan","Agamaggan"],
["aggramar","Aggramar"]
]],
["blutdurst","Blutdurst",,[
["aegwynn","Aegwynn"],
["destromath","Destromath"]
]]
]]
];
*/
function urlize($str)
{
$pairs = [
"ß" => "ss",
"á" => "a", "ä" => "a", "à" => "a", "â" => "a",
"è" => "e", "ê" => "e", "é" => "e", "ë" => "e",
"í" => "i", "î" => "i", "ì" => "i", "ï" => "i",
"ñ" => "n",
"ò" => "o", "ó" => "o", "ö" => "o", "ô" => "o",
"ú" => "u", "ü" => "u", "û" => "u", "ù" => "u",
"œ" => "oe",
"Á" => "A", "Ä" => "A", "À" => "A", "Â" => "A",
"È" => "E", "Ê" => "E", "É" => "E", "Ë" => "E",
"Í" => "I", "Î" => "I", "Ì" => "I", "Ï" => "I",
"Ñ" => "N",
"Ò" => "O", "Ó" => "O", "Ö" => "O", "Ô" => "O",
"Ú" => "U", "Ü" => "U", "Û" => "U", "Ù" => "U",
"œ" => "Oe",
" " => "-"
];
return preg_replace('/[^\d\w\-]/', '', strtr(strToLower($str), $pairs));
}
if (!file_exists('config/profile_all.js.in'))
die('profile_all source file is missing; cannot create realm file');
$menu = [
["us", "US & Oceanic", null,[
[urlize(CFG_BATTLEGROUP), CFG_BATTLEGROUP, null, []]
]],
["eu", "Europe", null,[
[urlize(CFG_BATTLEGROUP), CFG_BATTLEGROUP, null, []]
]]
];
$rows = DB::Auth()->select('SELECT id AS ARRAY_KEY, name, ? AS battlegroup, IF(timezone IN (8, 9, 10, 11, 12), "eu", "us") AS region FROM realmlist WHERE allowedSecurityLevel = 0', CFG_BATTLEGROUP);
$str = 'var g_realms = '.json_encode($rows, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE).';';
$handle = fOpen('datasets/realms', "w");
fWrite($handle, $str);
fClose($handle);
$set = 0x0;
foreach ($rows as $row)
{
if ($row['region'] == 'eu')
{
$set |= 0x1;
$menu[1][3][0][3][] = [urlize($row['name']),$row['name']];
}
else if ($row['region'] == 'us')
{
$set |= 0x2;
$menu[0][3][0][3][] = [urlize($row['name']),$row['name']];
}
}
if (!($set & 0x1))
array_pop($menu);
if (!($set & 0x2))
array_shift($menu);
$file = file_get_contents('config/profile_all.js.in');
$dest = fOpen('template/js/profile_all.js', "w");
fWrite($dest, str_replace('[/*setup:realms*/]', json_encode($menu, JSON_UNESCAPED_UNICODE), $file));
fClose($dest);
echo 'all done';
?>

View File

@@ -1,140 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'statistics'-file in datasets
// this script requires the following dbcs to be parsed and available
// gtChanceToMeleeCrit.dbc, gtChanceToSpellCrit.dbc, gtChanceToMeleeCritBase.dbc, gtChanceToSpellCritBase.dbc, gtOCTRegenHP, gtRegenHPPperSpt.dbc, gtRegenMPPerSpt.dbc
function classs()
{
// constants and mods taken from TrinityCore (Player.cpp, StatSystem.cpp)
/* content per Index
mleatkpwr[base, strMultiplier, agiMultiplier, levelMultiplier]
rngatkpwr[base, strMultiplier, agiMultiplier, levelMultiplier]
baseCritPct[phys, spell]
diminishingConstant
baseDodgePct
DodgeCap
baseParryPct
ParryCap
baseBlockPct
directMod1 applies mod directly only one class having something worth mentioning: DK
directMod2 applies mod directly so what were they originally used for..?
*/
$dataz = array(
1 => [[-20, 2, 0, 3], [-10, 0, 1, 1], null, 0.9560, 3.6640, 88.129021, 5, 47.003525, 5, 0, 0],
2 => [[-20, 2, 0, 3], [-10, 0, 1, 0], null, 0.9560, 3.4943, 88.129021, 5, 47.003525, 5, 0, 0],
3 => [[-20, 1, 1, 2], [-10, 0, 2, 2], null, 0.9880, -4.0873, 145.560408, 5, 145.560408, 0, 0, 0],
4 => [[-20, 1, 1, 2], [-10, 0, 1, 1], null, 0.9880, 2.0957, 145.560408, 5, 145.560408, 0, 0, 0],
5 => [[-10, 1, 0, 0], [-10, 0, 1, 0], null, 0.9830, 3.4178, 150.375940, 0, 0.0, 0, 0, 0],
6 => [[-20, 2, 0, 3], [-10, 0, 1, 0], null, 0.9560, 3.6640, 88.129021, 5, 47.003525, 0, 0, ['parryrtng' => [0.25, 'percentOf', 'str']]], // Forcefull Deflection (49410)
7 => [[-20, 1, 1, 2], [-10, 0, 1, 0], null, 0.9880, 2.1080, 145.560408, 0, 145.560408, 5, 0, 0],
8 => [[-10, 1, 0, 0], [-10, 0, 1, 0], null, 0.9830, 3.6587, 150.375940, 0, 0.0, 0, 0, 0],
9 => [[-10, 1, 0, 0], [-10, 0, 1, 0], null, 0.9830, 2.4211, 150.375940, 0, 0.0, 0, 0, 0],
11 => [[-20, 2, 0, 0], [-10, 0, 1, 0], null, 0.9720, 5.6097, 116.890707, 0, 0.0, 0, 0, 0]
);
foreach ($dataz as $class => &$data)
$data[2] = array_values(DB::Aowow()->selectRow('SELECT mle.chance*100 cMle, spl.chance*100 cSpl FROM dbc.gtchancetomeleecritbase mle, dbc.gtchancetospellcritbase spl WHERE mle.idx = spl.idx AND mle.idx = ?d', $class - 1));
return $dataz;
}
function race()
{
// { str, agi, sta, int, spi, hp, mana, directMod1, directMod2 }
return array(
1 => [20, 20, 20, 20, 20, 0, ['spi' => [0.05, 'percentOf', 'spi']]], // The Human Spirit (20598)
2 => [23, 17, 22, 17, 23, 0, 0],
3 => [22, 16, 23, 19, 19, 0, 0],
4 => [17, 25, 19, 20, 20, 0, 0],
5 => [19, 18, 21, 18, 25, 0, 0],
6 => [25, 15, 22, 15, 22, 0, ['health' => [0.05, 'functionOf', '$function(p) { return g_statistics.combo[p.classs][p.level][5]; }']]], // Endurance (20550) ... if you are looking for something elegant, look away!
7 => [15, 23, 19, 24, 20, 0, ['int' => [0.05, 'percentOf', 'int']]], // Expansive Mind (20591)
8 => [21, 22, 21, 16, 21, 0, ['healthrgn' => [0.1, 'percentOf', 'healthrgn']]], // Regeneration (20555)
10 => [17, 22, 18, 24, 19, 0, 0],
11 => [21, 17, 19, 21, 22, 0, 0] // ['mlehitpct' => [1, 'add'], 'splhitpct' => [1, 'add'], 'rgdhitpct' => [1, 'add']] // Heroic Presence (6562, 28878) (not actually shown..?)
);
}
function combo()
{
$result = [];
$critToDodge = array(
1 => 0.85/1.15, 2 => 1.00/1.15, 3 => 1.11/1.15,
4 => 2.00/1.15, 5 => 1.00/1.15, 6 => 0.85/1.15,
7 => 1.60/1.15, 8 => 1.00/1.15, 9 => 0.97/1.15, 11 => 2.00/1.15
);
// TrinityCore claims, DodgePerAgi per level and class can be constituted from critPerAgi (and level (and class))
// who am i to argue
// rebase stats to a specific race. chosen human as all stats are 20
// level:{ str, agi, sta, int, spi, hp, mana, mleCrt%Agi, splCrt%Int, dodge%Agi, HealthRegenModToBaseStat, HealthRegenModToBonusStat }
foreach ($critToDodge as $class => $mod)
{
// humans can't be hunter, shaman, druids (use tauren here)
if (in_array($class, [3, 7, 11]))
$offset = [25, 15, 22, 15, 22];
else
$offset = [20, 20, 20, 20, 20];
$rows = DB::Aowow()->select('SELECT pls.level AS ARRAY_KEY, str-?d, agi-?d, sta-?d, inte-?d, spi-?d, basehp, IF(basemana <> 0, basemana, 100), mlecrt.chance*100, splcrt.chance*100, mlecrt.chance*100 * ?f, baseHP5.ratio*1, extraHP5.ratio*1 ' .
'FROM player_levelstats pls JOIN player_classlevelstats pcls ON pls.level = pcls.level AND pls.class = pcls.class JOIN' .
' dbc.gtchancetomeleecrit mlecrt ON mlecrt.idx = ((pls.class - 1) * 100) + (pls.level - 1) JOIN' .
' dbc.gtchancetospellcrit splcrt ON splcrt.idx = ((pls.class - 1) * 100) + (pls.level - 1) JOIN' .
' dbc.gtoctregenhp baseHP5 ON baseHP5.idx = ((pls.class - 1) * 100) + (pls.level - 1) JOIN' .
' dbc.gtregenhpperspt extraHP5 ON extraHP5.idx = ((pls.class - 1) * 100) + (pls.level - 1) ' .
'WHERE pls.race = ?d AND pls.class = ?d ORDER BY pls.level ASC',
$offset[0], $offset[1], $offset[2], $offset[3], $offset[4],
$mod,
in_array($class, [3, 7, 11]) ? 6 : 1,
$class
);
$result[$class] = [];
foreach ($rows as $k => $row)
$result[$class][$k] = array_values($row);
}
return $result;
}
function level()
{
// base mana regeneration per level
// identical across classes (just use one, that acutally has mana (offset: 100))
// content of gtRegenMPPerSpt.dbc
return DB::Aowow()->selectCol('SELECT idx-99 AS ARRAY_KEY, ratio FROM dbc.gtregenmpperspt WHERE idx >= 100 AND idx < 100 + ?d', MAX_LEVEL);
}
function skills()
{
// profession perks (skinning => +crit, mining => +stam) and maybe some others; skillId:{rankNo:someJSON, ..}?
return [];
}
// todo: x
$sub = ['classs', 'race', 'combo', 'level', 'skills'];
$out = [];
foreach($sub as $s)
$out[$s] = $s();
$json = json_encode($out, JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$json = preg_replace('/"\$([^$"]+)"/', '\1', $json);
$handle = fOpen('datasets/statistics', "w");
fWrite($handle, 'g_statistics = '.$json.';');
fClose($handle);
echo 'all done';
?>

View File

@@ -1,80 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// builds image-textures for the talent-calculator
// spellIcons must be extracted and converted to at least medium size
// this script requires the following dbc-files to be parsed and available
// Talent, TalentTab, Spell
$query = 'SELECT s.iconString FROM ?_spell s JOIN dbc.talent t ON t.rank1 = s.Id JOIN dbc.talenttab tt ON tt.Id = t.tabId WHERE tt.?# = ?d AND tt.tabNumber = ?d ORDER BY t.row, t.column, t.petCategory1 ASC;';
$dims = 36; //v-pets
$filenames = ['icons', 'warrior', 'paladin', 'hunter', 'rogue', 'priest', 'deathknight', 'shaman', 'mage', 'warlock', null, 'druid'];
// create directory if missing
if (!is_dir('static/images/wow/talents/icons'))
mkdir('static/images/wow/talents/icons', 0755, true);
if (!is_dir('static/images/wow/hunterpettalents'))
mkdir('static/images/wow/hunterpettalents', 0755, true);
echo "script set up in ".Util::execTime()."<br>\n";
foreach ($filenames as $k => $v)
{
if (!$v)
continue;
set_time_limit(10);
for ($tree = 0; $tree < 3; $tree++)
{
$what = $k ? 'classMask' : 'creatureFamilyMask';
$set = $k ? 1 << ($k - 1) : 1 << $tree;
$subset = $k ? $tree : 0;
$path = $k ? 'talents/icons' : 'hunterpettalents';
$icons = DB::Aowow()->SelectCol($query, $what, $set, $subset);
if (empty($icons))
die('error: query for '.$v.' tree: '.$k.' empty');
$res = imageCreateTrueColor(count($icons) * $dims, 2 * $dims);
for($i = 0; $i < count($icons); $i++)
{
$im = @imagecreatefromjpeg('static/images/wow/icons/medium/'.strtolower($icons[$i]).'.jpg');
if(!$im)
die('error: raw image '.$icons[$i]. ' not found');
// colored
imagecopymerge($res, $im, $i * $dims, 0, 0, 0, imageSX($im), imageSY($im), 100);
// grayscale
if (imageistruecolor($im))
imagetruecolortopalette($im, false, 256);
for ($j = 0; $j < imagecolorstotal($im); $j++)
{
$color = imagecolorsforindex($im, $j);
$gray = round(0.299 * $color['red'] + 0.587 * $color['green'] + 0.114 * $color['blue']);
imagecolorset($im, $j, $gray, $gray, $gray);
}
imagecopymerge($res, $im, $i * $dims, $dims, 0, 0, imageSX($im), imageSY($im), 100);
if (@!imagejpeg($res, 'static/images/wow/'.$path.'/'.$v.'_'.($tree + 1).'.jpg'))
die('error: '.$v.'_'.($tree + 1).'.jpg could not be written!');
}
}
echo "textures for ".($k ? ucFirst($v) : "Pet")." done in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -1,236 +0,0 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// builds talent-tree-data for the talent-calculator
// this script requires the following dbc-files to be parsed and available
// Talent, TalentTab, Spell, CreatureFamily
// talents
// i - int talentId (id of aowow_talent)
// n - str name (spellname of aowow_spell for spellID = rank1)
// m - int number of ranks (6+ are empty)
// s - array:int spells to ranks (rank1, rank2, ..., rank5 of aowow_talent)
// d - array:str description of spells
// x - int column (col from aowow_talent)
// y - int row (row of aowow_talent)
// r - array:int on what the talent depends on: "r:[u, v]", u - nth talent in tree, v - required rank of u
// f - array:int [pets only] creatureFamilies, that use this spell
// t - array:str if the talent teaches a spell, this is the upper tooltip-table containing castTime, cost, cooldown
// j - array of modifier-arrays per rank for the Profiler [nyi]
// tabs
// n - name of the tab
// t - array of talent-objects
// f - array:int [pets only] creatureFamilies in that category
$buildTree = function ($class) use (&$petFamIcons, &$tSpells)
{
$petCategories = [];
$mask = $class ? 1 << ($class - 1) : 0;
// All "tabs" of a given class talent
$tabs = DB::Aowow()->select('
SELECT
*
FROM
dbc.talenttab
WHERE
classMask = ?d
ORDER BY
`tabNumber`, `creatureFamilyMask`',
$mask
);
$result = [];
for ($l = 0; $l < count($tabs); $l++)
{
$talents = DB::Aowow()->select('
SELECT
t.id AS tId,
t.*,
s.*
FROM
dbc.talent t,
?_spell s
WHERE
t.`tabId`= ?d AND
s.`Id` = t.`rank1`
ORDER by t.`row`, t.`column`
',
$tabs[$l]['Id']
);
$result[$l] = array(
'n' => Util::localizedString($tabs[$l], 'name'),
't' => []
);
if (!$class)
{
$petFamId = log($tabs[$l]['creatureFamilyMask'], 2);
$result[$l]['icon'] = $petFamIcons[$petFamId];
$petCategories = DB::Aowow()->SelectCol('SELECT Id AS ARRAY_KEY, category FROM ?_pet WHERE type = ?d', $petFamId);
$result[$l]['f'] = array_keys($petCategories);
}
// talent dependencies go here
$depLinks = [];
$tNums = [];
for($j = 0; $j < count($talents); $j++)
{
$tNums[$talents[$j]['tId']] = $j;
$d = [];
$s = [];
$i = $talents[$j]['tId'];
$n = Util::localizedString($talents[$j], 'name');
$x = $talents[$j]['column'];
$y = $talents[$j]['row'];
$r = null;
$t = [];
$icon = $talents[$j]['iconString'];
$m = $talents[$j]['rank2'] == 0 ? 1 : (
$talents[$j]['rank3'] == 0 ? 2 : (
$talents[$j]['rank4'] == 0 ? 3 : (
$talents[$j]['rank5'] == 0 ? 4 : 5
)
)
);
// duplet handling
$f = [];
foreach ($petCategories as $k => $v)
{
// cant handle 64bit integer .. split
if ($v >= 32 && ((1 << ($v - 32)) & $talents[$j]['petCategory2']))
$f[] = $k;
else if ($v < 32 && ((1 << $v) & $talents[$j]['petCategory1']))
$f[] = $k;
}
for ($k = 0; $k <= ($m - 1); $k++)
{
if (!$tSpells->getEntry($talents[$j]['rank'.($k + 1)]))
continue;
$d[] = $tSpells->parseText()[0];
$s[] = $talents[$j]['rank'.($k + 1)];
if ($talents[$j]['talentSpell'])
$t[] = $tSpells->getTalentHeadForCurrent();
}
if ($talents[$j]['reqTalent'])
{
// we didn't encounter the required talent yet => create reference
if (!isset($tNums[$talents[$j]['reqTalent']]))
$depLinks[$talents[$j]['reqTalent']] = $j;
$r = @[$tNums[$talents[$j]['reqTalent']], $talents[$j]['reqRank'] + 1];
}
$result[$l]['t'][$j] = array(
'i' => $i,
'n' => $n,
'm' => $m,
'd' => $d,
's' => $s,
'x' => $x,
'y' => $y,
);
if (isset($r))
$result[$l]['t'][$j]['r'] = $r;
if (!empty($t))
$result[$l]['t'][$j]['t'] = $t;
if (!empty($f))
$result[$l]['t'][$j]['f'] = $f;
if ($class)
$result[$l]['t'][$j]['iconname'] = $icon;
// If this talent is a reference, add it to the array of talent dependencies
if (isset($depLinks[$talents[$j]['tId']]))
{
$result[$l]['t'][$depLinks[$talents[$j]['tId']]]['r'][0] = $j;
unset($depLinks[$talents[$j]['tId']]);
}
}
// Remove all dependencies for which the talent has not been found
foreach ($depLinks as $dep_link)
unset($result[$l]['t'][$dep_link]['r']);
}
return $result;
};
$classes = [CLASS_WARRIOR, CLASS_PALADIN, CLASS_HUNTER, CLASS_ROGUE, CLASS_PRIEST, CLASS_DEATHKNIGHT, CLASS_SHAMAN, CLASS_MAGE, CLASS_WARLOCK, CLASS_DRUID];
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
// my neighbour is noisy as fuck and my head hurts, so ..
$petFamIcons = ['Ability_Druid_KingoftheJungle', 'Ability_Druid_DemoralizingRoar', 'Ability_EyeOfTheOwl']; // .. i've no idea where to fetch these from
$petIcons = '';
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!is_dir('datasets/'.$dir))
mkdir('datasets/'.$dir, 0755, true);
$tSpellIds = DB::Aowow()->selectCol('SELECT rank1 FROM dbc.talent UNION SELECT rank2 FROM dbc.talent UNION SELECT rank3 FROM dbc.talent UNION SELECT rank4 FROM dbc.talent UNION SELECT rank5 FROM dbc.talent');
$tSpells = new SpellList(array(['s.id', $tSpellIds], CFG_SQL_LIMIT_NONE));
echo "script set up in ".Util::execTime()."<br>\n";
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
// TalentCalc
foreach ($classes as $cMask)
{
set_time_limit(20);
$cId = log($cMask, 2) + 1;
$file = 'datasets/'.User::$localeString.'/talents-'.$cId;
$toFile = '$WowheadTalentCalculator.registerClass('.$cId.', '.json_encode($buildTree($cId), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).')';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done class: ".$cId." loc: ".$lId." in ".Util::execTime()."<br>\n";
}
// PetCalc
if (empty($petIcons))
{
$pets = DB::Aowow()->SelectCol('SELECT Id AS ARRAY_KEY, iconString FROM ?_pet');
$petIcons = json_encode($pets, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
}
$toFile = "var g_pet_icons = ".$petIcons."\n\n";
$toFile .= 'var g_pet_talents = '.json_encode($buildTree(0), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$file = 'datasets/'.User::$localeString.'/pet-talents';
$handle = fOpen($file, "w");
fWrite($handle, $toFile);
fClose($handle);
echo "done pets loc: ".$lId." in ".Util::execTime()."<br>\n";
}
echo "<br>\nall done";
Lang::load(Util::$localeStrings[LOCALE_EN]);
$stats = DB::Aowow()->getStatistics();
echo "<br>\n".$stats['count']." queries in: ".Util::formatTime($stats['time'] * 1000);
?>

View File

@@ -0,0 +1,224 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'enchants'-file for available locales
// this script requires the following dbc-files to be parsed and available
// Spells, SkillLineAbility, SpellItemEnchantment
// todo (high): restructure to work more efficiently (outer loop: spells, inner loop: locales)
/* Examples
15: {
name:'Leichtes R<>stungsset',
quality:1,
icon:'INV_Misc_ArmorKit_17',
source:-2304,
skill:-1,
slots:525008,
enchantment:'Verst<73>rkt (+8 R<>stung)',
jsonequip:{"armor":8,"reqlevel":1},
temp:0,
classes:0,
gearscore:1
},
2928: {
name:'Ring - Zaubermacht',
quality:-1,
icon:'INV_Misc_Note_01',
source:27924,
skill:333,
slots:1024,
enchantment:'+12 Zaubermacht',
jsonequip:{"splpwr":12},
temp:0,
classes:0,
gearscore:15
},
3231: {
name:['Handschuhe - Waffenkunde','Armschiene - Waffenkunde'],
quality:-1,
icon:'spell_holy_greaterheal',
source:[44484,44598],
skill:333,
slots:[512,256],
enchantment:'+15 Waffenkundewertung',
jsonequip:{reqlevel:60,"exprtng":15},
temp:0,
classes:0,
gearscore:20 // nope, i'm not doing this
},
*/
function enchants(&$log, $locales)
{
// from g_item_slots: 13:"One-Hand", 26:"Ranged", 17:"Two-Hand",
$slotPointer = [13, 17, 26, 26, 13, 17, 17, 13, 17, null, 17, null, null, 13, null, 13, null, null, null, null, 17];
$locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU];
$castItems = [];
$successs = true;
$enchantSpells = new SpellList([['effect1Id', 53], ['name_loc0', 'QA%', '!'], CFG_SQL_LIMIT_NONE]); // enchantItemPermanent && !qualityAssurance
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
$enchIds = [];
foreach ($enchantSpells->iterate() as $__)
$enchIds[] = $enchantSpells->getField('effect1MiscValue');
$enchMisc = [];
$enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc);
foreach ($locales as $lId)
{
set_time_limit(120);
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$enchantsOut = [];
foreach ($enchantSpells->iterate() as $__)
{
// slots have to be recalculated
$slot = 0;
if ($enchantSpells->getField('equippedItemClass') == 4) // armor
{
if ($invType = $enchantSpells->getField('equippedItemInventoryTypeMask'))
$slot = $invType >> 1;
else /* if (equippedItemSubClassMask == 64) */ // shields have it their own way <_<
$slot = (1 << (14 - 1));
}
else if ($enchantSpells->getField('equippedItemClass') == 2) // weapon
{
foreach ($slotPointer as $i => $sp)
{
if (!$sp)
continue;
if ((1 << $i) & $enchantSpells->getField('equippedItemSubClassMask'))
{
if ($sp == 13) // also mainHand & offHand *siiigh*
$slot |= ((1 << (21 - 1)) | (1 << (22 - 1)));
$slot |= (1 << ($sp - 1));
}
}
}
$eId = $enchantSpells->getField('effect1MiscValue');
// defaults
$ench = array(
'name' => [], // set by skill or item
'quality' => -1, // modified if item
'icon' => strToLower($enchantSpells->getField('iconString')), // item over spell
'source' => [], // <0: item; >0:spell
'skill' => -1, // modified if skill
'slots' => [], // determined per spell but set per item
'enchantment' => Util::localizedString($enchMisc[$eId]['text'], 'text'),
'jsonequip' => @$enchJSON[$eId] ?: [],
'temp' => 0, // always 0
'classes' => 0, // modified by item
);
if (isset($enchMisc[$eId]['reqskill']))
$ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskill'];
if (isset($enchMisc[$eId]['reqskillrank']))
$ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskillrank'];
if (isset($enchMisc[$eId]['requiredLevel']))
$ench['jsonequip']['requiredLevel'] = $enchMisc[$eId]['requiredLevel'];
// check if the spell has an entry in skill_line_ability -> Source:Profession
if ($skill = DB::Aowow()->SelectCell('SELECT skillLineId FROM dbc.skilllineability WHERE spellId = ?d', $enchantSpells->id))
{
$ench['name'][] = $enchantSpells->getField('name', true);
$ench['source'][] = $enchantSpells->id;
$ench['skill'] = $skill;
$ench['slots'][] = $slot;
}
// check if this spell can be cast via item -> Source:Item
if (!isset($castItems[$enchantSpells->id]))
$castItems[$enchantSpells->id] = new ItemList([['spellId1', $enchantSpells->id], ['name_loc0', 'Scroll of Enchant%', '!']]); // do not reuse enchantment scrolls
$cI = &$castItems[$enchantSpells->id]; // this construct is a bit .. unwieldy
foreach ($cI->iterate() as $__)
{
$ench['name'][] = $cI->getField('name', true);
$ench['source'][] = -$cI->id;
$ench['icon'] = strTolower($cI->getField('iconString'));
$ench['slots'][] = $slot;
if ($cI->getField('quality') > $ench['quality'])
$ench['quality'] = $cI->getField('quality');
if ($cI->getField('requiredClass') > 0)
{
$ench['classes'] = $cI->getField('requiredClass');
$ench['jsonequip']['classes'] = $cI->getField('requiredClass');
}
if (!isset($ench['jsonequip']['reqlevel']))
if ($cI->getField('requiredLevel') > 0)
$ench['jsonequip']['reqlevel'] = $cI->getField('requiredLevel');
}
// enchant spell not in use
if (empty($ench['source']))
continue;
// everything gathered
if (isset($enchantsOut[$eId])) // already found, append data
{
foreach ($enchantsOut[$eId] as $k => $v)
{
if (is_array($v))
{
while ($pop = array_pop($ench[$k]))
$enchantsOut[$eId][$k][] = $pop;
}
else
{
if ($k == 'quality') // quality:-1 if spells and items are mixed
{
if ($enchantsOut[$eId]['source'][0] > 0 && $ench['source'][0] < 0)
$enchantsOut[$eId][$k] = -1;
else if ($enchantsOut[$eId]['source'][0] < 0 && $ench['source'][0] > 0)
$enchantsOut[$eId][$k] = -1;
else
$enchantsOut[$eId][$k] = $ench[$k];
}
else if ($enchantsOut[$eId][$k] <= 0)
$enchantsOut[$eId][$k] = $ench[$k];
}
}
}
else // nothing yet, create new
$enchantsOut[$eId] = $ench;
}
// walk over each entry and strip single-item arrays
foreach ($enchantsOut as &$ench)
foreach ($ench as $k => $v)
if (is_array($v) && count($v) == 1 && $k != 'jsonequip')
$ench[$k] = $v[0];
$toFile = "var g_enchants = ";
$toFile .= json_encode($enchantsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/enchants';
if (!writeFile($file, $toFile, $log))
$success = false;
}
return $successs;
}
?>

View File

@@ -0,0 +1,91 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'gems'-file for available locales
// this script requires the following dbc-files to be parsed and available
// ItemEnchantment, GemProperties, Spells, Icons
/* Example
22460: {
name:'Prismatic Sphere',
quality:3,
icon:'INV_Enchant_PrismaticSphere',
enchantment:'+3 Resist All',
jsonequip:{"arcres":3,"avgbuyout":242980,"firres":3,"frores":3,"holres":3,"natres":3,"shares":3},
colors:14,
expansion:1
gearscore:8 // as if.....
},
*/
function gems(&$log, $locales)
{
// sketchy, but should work
// Id < 36'000 || ilevel < 70 ? BC : WOTLK
$gems = DB::Aowow()->Select(
'SELECT it.entry AS itemId,
it.name,
li.*,
IF (it.entry < 36000 OR it.ItemLevel < 70, 1 , 2) AS expansion,
it.Quality AS quality,
i.inventoryicon1 AS icon,
gp.spellItemEnchantmentId AS enchId,
gp.colorMask AS colors
FROM item_template it
LEFT JOIN locales_item li ON li.entry = it.entry
JOIN dbc.gemproperties gp ON gp.Id = it.GemProperties
JOIN dbc.itemdisplayinfo i ON i.Id = it.displayid
WHERE it.GemProperties <> 0
ORDER BY it.entry DESC');
$success = true;
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
$enchIds = [];
foreach ($gems as $pop)
$enchIds[] = $pop['enchId'];
$enchMisc = [];
$enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc);
foreach ($locales as $lId)
{
set_time_limit(5);
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$gemsOut = [];
foreach ($gems as $pop)
{
$gemsOut[$pop['itemId']] = array(
'name' => Util::localizedString($pop, 'name'),
'quality' => $pop['quality'],
'icon' => strToLower($pop['icon']),
'enchantment' => Util::localizedString(@$enchMisc[$pop['enchId']]['text'] ?: [], 'text'),
'jsonequip' => @$enchJSON[$pop['enchId']] ?: [],
'colors' => $pop['colors'],
'expansion' => $pop['expansion']
);
}
$toFile = "var g_gems = ";
$toFile .= json_encode($gemsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/gems';
if (!writeFile($file, $toFile, $log))
$success = false;
}
return $success;
}
?>

View File

@@ -0,0 +1,90 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'glyphs'-file for available locales
// this script requires the following dbc-files to be parsed and available
// GlyphProperties, Spells, SkillLineAbility
/* Example
40896: {
"name":"Glyph of Frenzied Regeneration",
"description":"For 6 sec after activating Frenzied Regeneration, healing effects on you are 40% more powerful. However, your Frenzied Regeneration now always costs 60 Rage and no longer converts Rage into health.",
"icon":"ability_bullrush",
"type":1,
"classs":11,
"skill":798,
"level":25,
},
*/
function glyphs(&$log, $locales)
{
$success = true;
$glyphList = DB::Aowow()->Select(
'SELECT i.id AS itemId,
i.*,
IF (g.typeFlags & 0x1, 2, 1) AS type,
i.subclass AS classs,
i.requiredLevel AS level,
s1.Id AS glyphSpell,
s1.iconStringAlt AS icon,
s1.skillLine1 AS skillId,
s2.Id AS glyphEffect,
s2.Id AS ARRAY_KEY
FROM ?_items i
JOIN ?_spell s1 ON s1.Id = i.spellid1
JOIN ?_glyphproperties g ON g.Id = s1.effect1MiscValue
JOIN ?_spell s2 ON s2.Id = g.spellId
WHERE i.classBak = 16');
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
$glyphSpells = new SpellList(array(['s.id', array_keys($glyphList)], CFG_SQL_LIMIT_NONE));
foreach ($locales as $lId)
{
set_time_limit(30);
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$glyphsOut = [];
foreach ($glyphSpells->iterate() as $__)
{
$pop = $glyphList[$glyphSpells->id];
if (!$pop['glyphEffect'])
continue;
if ($glyphSpells->getField('effect1Id') != 6 && $glyphSpells->getField('effect2Id') != 6 && $glyphSpells->getField('effect3Id') != 6)
continue;
$glyphsOut[$pop['itemId']] = array(
'name' => Util::localizedString($pop, 'name'),
'description' => $glyphSpells->parseText()[0],
'icon' => $pop['icon'],
'type' => $pop['type'],
'classs' => $pop['classs'],
'skill' => $pop['skillId'],
'level' => $pop['level']
);
}
$toFile = "var g_glyphs = ";
$toFile .= json_encode($glyphsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/glyphs';
if (!writeFile($file, $toFile, $log))
$success = false;
}
return $success;
}
?>

View File

@@ -0,0 +1,134 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'itemsets'-file for available locales
// this script requires the following dbc-files to be parsed and available
// GlyphProperties, Spells, SkillLineAbility
/* Example
"-447": { // internal id, freely chosen
"classes":["6"], // array
"elite":true,
"heroic":false,
"id":"-447",
"idbak":"924", // actual setId
"maxlevel":"390",
"minlevel":"390",
"name":"3Cataclysmic Gladiator's Desecration",
"note":"37", // contentGroup
"pieces":["73742","73741","73740","73739","73738"],
"reqclass":"32", // mask
"type":"4",
"setbonus":{
"2":{"resirtng":"400","str":"70"},
"4":{"str":"90"}
}
},
*/
function itemsets(&$log, $locales)
{
$success = true;
$setList = DB::Aowow()->Select('SELECT * FROM ?_itemset ORDER BY refSetId DESC');
$jsonBonus = [];
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$itemsetOut = [];
foreach ($setList as $set)
{
set_time_limit(15);
$setOut = array(
'id' => $set['id'],
'name' => (7 - $set['quality']).Util::jsEscape(Util::localizedString($set, 'name')),
'pieces' => [],
'heroic' => DB::Aowow()->SelectCell('SELECT IF (Flags & 0x8, "true", "false") FROM item_template WHERE entry = ?d', $set['item1']),
'maxlevel' => $set['maxLevel'],
'minlevel' => $set['minLevel'],
'type' => $set['type'],
'setbonus' => []
);
if ($set['classMask'])
{
$setOut['reqclass'] = $set['classMask'];
$setOut['classes'] = [];
for ($i = 0; $i < 12; $i++)
if ($set['classMask'] & (1 << ($i - 1)))
$setOut['classes'][] = $i;
}
if ($set['contentGroup'])
$setOut['note'] = $set['contentGroup'];
if ($set['id'] < 0)
$setOut['idbak'] = $set['refSetId'];
for ($i = 1; $i < 11; $i++)
if ($set['item'.$i])
$setOut['pieces'][] = $set['item'.$i];
for ($i = 1; $i < 9; $i++)
{
if (!$set['bonus'.$i] || !$set['spell'.$i])
continue;
// costy and locale-independant -> cache
if (!isset($jsonBonus[$set['spell'.$i]]))
$jsonBonus[$set['spell'.$i]] = (new SpellList(array(['s.id', (int)$set['spell'.$i]])))->getStatGain()[$set['spell'.$i]];
if (!isset($setOut['setbonus'][$set['bonus'.$i]]))
$setOut['setbonus'][$set['bonus'.$i]] = $jsonBonus[$set['spell'.$i]];
else
foreach ($jsonBonus[$set['spell'.$i]] as $k => $v)
@$setOut['setbonus'][$set['bonus'.$i]][$k] += $v;
}
foreach ($setOut['setbonus'] as $k => $v)
{
if (empty($v))
unset($setOut['setbonus'][$k]);
else
{
foreach ($v as $sk => $sv)
{
if ($str = Util::$itemMods[$sk])
{
$setOut['setbonus'][$k][$str] = $sv;
unset($setOut['setbonus'][$k][$sk]);
}
}
}
}
if (empty($setOut['setbonus']))
unset($setOut['setbonus']);
$itemsetOut[$setOut['id']] = $setOut;
}
$toFile = "var g_itemsets = ";
$toFile .= json_encode($itemsetOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/itemsets';
if (!writeFile($file, $toFile, $log))
$success = false;
}
return $success;
}
?>

View File

@@ -0,0 +1,53 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'locale.js'-file in static/js
// available locales have to be set in aowow.aowow_config
function locales(&$log, $locales)
{
$result = [];
$available = array(
LOCALE_EN => " 0: { // English\r\n" .
" id: LOCALE_ENUS,\r\n" .
" name: 'enus',\r\n" .
" domain: 'www',\r\n" .
" description: 'English'\r\n" .
" }",
LOCALE_FR => " 2: { // French\r\n" .
" id: LOCALE_FRFR,\r\n" .
" name: 'frfr',\r\n" .
" domain: 'fr',\r\n" .
" description: 'Fran' + String.fromCharCode(231) + 'ais'\r\n" .
" }",
LOCALE_DE => " 3: { // German\r\n" .
" id: LOCALE_DEDE,\r\n" .
" name: 'dede',\r\n" .
" domain: 'de',\r\n" .
" description: 'Deutsch'\r\n" .
" }",
LOCALE_ES => " 6: { // Spanish\r\n" .
" id: LOCALE_ESES,\r\n" .
" name: 'eses',\r\n" .
" domain: 'es',\r\n" .
" description: 'Espa' + String.fromCharCode(241) + 'ol'\r\n" .
" }",
LOCALE_RU => " 8: { // Russian\r\n" .
" id: LOCALE_RURU,\r\n" .
" name: 'ruru',\r\n" .
" domain: 'ru',\r\n" .
" description: String.fromCharCode(1056, 1091, 1089, 1089, 1082, 1080, 1081)\r\n" .
" }",
);
foreach ($locales as $l)
if (isset($available[$l]))
$result[] = $available[$l];
return implode(",\r\n", $result);
}
?>

View File

@@ -0,0 +1,73 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'profile_all.js'-file in static/js;
// this script requires all realms in use to be defined in auth.realmlist
// battlegroups has to be set in config file
/* Example
var mn_profiles = [
["us","US & Oceanic",,[
["bloodlust","Bloodlust",,[
["amanthul","Aman'Thul"],
["barthilas","Barthilas"]
]],
["cyclone","Cyclone",,[
["azjol-nerub","Azjol-Nerub"],
["bloodscalp","Bloodscalp"]
]]
]],
["eu","Europe",,[
["blackout","Blackout",,[
["agamaggan","Agamaggan"],
["aggramar","Aggramar"]
]],
["blutdurst","Blutdurst",,[
["aegwynn","Aegwynn"],
["destromath","Destromath"]
]]
]]
];
*/
function mnProfiles(/* &$log */)
{
$menu = [
["us", "US & Oceanic", null,[
[Util::urlize(CFG_BATTLEGROUP), CFG_BATTLEGROUP, null, []]
]],
["eu", "Europe", null,[
[Util::urlize(CFG_BATTLEGROUP), CFG_BATTLEGROUP, null, []]
]]
];
$rows = DB::Auth()->select('SELECT name, IF(timezone IN (8, 9, 10, 11, 12), "eu", "us") AS region FROM realmlist WHERE allowedSecurityLevel = 0');
$set = 0x0;
foreach ($rows as $row)
{
if ($row['region'] == 'eu')
{
$set |= 0x1;
$menu[1][3][0][3][] = [Util::urlize($row['name']),$row['name']];
}
else if ($row['region'] == 'us')
{
$set |= 0x2;
$menu[0][3][0][3][] = [Util::urlize($row['name']),$row['name']];
}
}
if (!($set & 0x1))
array_pop($menu);
if (!($set & 0x2))
array_shift($menu);
return json_encode($menu, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
?>

View File

@@ -0,0 +1,119 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// builds 'pets'-file for available locales
// this script requires the following dbc-files to be parsed and available
// CreatureFamily, CreatureDisplayInfo, FactionTemplate, AreaTable
// Todo:
// locations are a tiny bit wide at the moment.
// I'm still undecided wether the old system is pure genius or pure madness. While building the zone-maps it also generated masks for that zone, using the alpha-channel in the *.blp
// When deciding what spawn lies where you could check against the relative coordinates of that mask. black => isInZone; white => notInZone
// Since i'm lacking other options this will probably be reimplemented.
/* Example data
30: {
id:30,
name:'Forest Spider',
minlevel:5,
maxlevel:6,
location:[12], // master-AreaTableId's (?)
react:[-1,-1],
classification:0, // 0:"Normal", 1:"Elite", 2:"Rar Elite", 3:"Boss", 4:"Rar"
family:3, // creatureFamily
displayId:382,
skin:'TarantulaSkinOrange',
icon:'Ability_Hunter_Pet_Spider', // from creatureFamily.dbc
type:2 // 0:Ferocity, 1:Tenacity, 2:Cunning
},
*/
function pets(&$log, $locales)
{
$success = true;
$locations = [];
$qZones = 'SELECT DISTINCT z.id
FROM creature c
JOIN ?_zones z ON z.xMin < c.position_x AND z.xMax > c.position_x AND z.yMin < c.position_y AND z.yMax > c.position_y AND z.mapId = c.map
WHERE c.id = ?d';
$qInstances = 'SELECT DISTINCT z.id
FROM creature c, ?_zones z
WHERE z.mapId = c.map AND c.id = ?d';
$petList = DB::Aowow()->Select(
'SELECT ct.entry AS id,
ct.name,
lc.*,
ct.minlevel,
ct.maxlevel,
CONCAT("[", ft.A, ", ", ft.H, "]") AS react,
ct.rank AS classification,
ct.family,
ct.modelId1 AS displayId,
cdi.skin1 AS skin,
SUBSTRING_INDEX(cf.iconFile, "\\\\", -1) AS icon,
cf.petTalentType AS type
FROM creature_template ct
JOIN ?_factiontemplate ft ON ft.Id = ct.faction
JOIN dbc.creaturefamily cf ON cf.Id = ct.family
LEFT JOIN locales_creature lc ON lc.entry = ct.entry
JOIN dbc.creaturedisplayinfo cdi ON cdi.id = ct.modelId1
WHERE cf.petTalentType <> -1 AND ct.type_flags & 0x1
ORDER BY ct.entry ASC');
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
$petsOut = [];
foreach ($petList as $pet)
{
// get locations
// again: caching will save you time and nerves
if (!isset($locations[$pet['id']]))
{
$locations[$pet['id']] = DB::Aowow()->SelectCol($qZones, $pet['id']);
// probably instanced, map <=> areaId _should_ be bijective
if (empty($locations[$pet['id']]))
if ($z = DB::Aowow()->SelectCell($qInstances, $pet['id']))
$locations[$pet['id']][] = $z;
}
$petsOut[$pet['id']] = array(
'id' => $pet['id'],
'name' => Util::localizedString($pet, 'name'),
'minlevel' => $pet['minlevel'],
'maxlevel' => $pet['maxlevel'],
'location' => $locations[$pet['id']],
'react' => $pet['react'],
'classification' => $pet['classification'],
'family' => $pet['family'],
'displayId' => $pet['displayId'],
'skin' => $pet['skin'],
'icon' => $pet['icon'],
'type' => $pet['type']
);
}
$toFile = "var g_pets = ";
$toFile .= json_encode($petsOut, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
$toFile .= ";";
$file = 'datasets/'.User::$localeString.'/pets';
if (!writeFile($file, $toFile, $log))
$success = false;
}
return $success;
}
?>

View File

@@ -0,0 +1,316 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// gatheres quasi-static data used in profiler: all available quests, achievements, titles, mounts, companions, factions, recipes
// this script requires a fully set up database and is expected to be run last
function profiler(&$log, $locales)
{
$success = true;
$scripts = [];
/**********/
/* Quests */
/**********/
$scripts[] = function(&$log) use ($locales)
{
$success = true;
$condition = [
CFG_SQL_LIMIT_NONE,
'AND',
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW], 0],
[['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE | QUEST_FLAG_AUTO_REWARDED, '&'], 0],
[['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_DUNGEON_FINDER | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]
];
$questz = new QuestList($condition);
$_ = [];
$currencies = array_column($questz->rewards, TYPE_CURRENCY);
foreach ($currencies as $curr)
foreach ($curr as $cId => $qty)
$_[] = $cId;
$relCurr = new CurrencyList(array(['id', $_]));
foreach ($locales as $l)
{
set_time_limit(20);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$buff = "var _ = g_gatheredcurrencies;\n";
foreach ($relCurr->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
$buff .= "\n\nvar _ = g_quests;\n";
foreach ($questz->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
$buff .= "\ng_quest_catorder = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n";
if (!writeFile('datasets/'.User::$localeString.'/p-quests', $buff, $log))
$success = false;
}
return $success;
};
/****************/
/* Achievements */
/****************/
$scripts[] = function(&$log) use ($locales)
{
$success = true;
$condition = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
[['flags', 1, '&'], 0], // no statistics
);
$achievez = new AchievementList($condition);
foreach ($locales as $l)
{
set_time_limit(5);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$sumPoints = 0;
$buff = "var _ = g_achievements;\n";
foreach ($achievez->getListviewData(ACHIEVEMENTINFO_PROFILE) as $id => $data)
{
$sumPoints += $data['points'];
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
// categories to sort by
$buff .= "\ng_achievement_catorder = [92, 14863, 97, 169, 170, 171, 172, 14802, 14804, 14803, 14801, 95, 161, 156, 165, 14806, 14921, 96, 201, 160, 14923, 14808, 14805, 14778, 14865, 14777, 14779, 155, 14862, 14861, 14864, 14866, 158, 162, 14780, 168, 14881, 187, 14901, 163, 14922, 159, 14941, 14961, 14962, 14981, 15003, 15002, 15001, 15041, 15042, 81]";
// sum points
$buff .= "\ng_achievement_points = [".$sumPoints."];\n";
if (!writeFile('datasets/'.User::$localeString.'/p-achievements', $buff, $log))
$success = false;
}
return $success;
};
/**********/
/* Titles */
/**********/
$scripts[] = function(&$log) use ($locales)
{
$success = true;
$condition = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
);
$titlez = new TitleList($condition);
foreach ($locales as $l)
{
set_time_limit(5);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
foreach ([0, 1] as $g) // gender
{
$buff = "var _ = g_titles;\n";
foreach ($titlez->getListviewData() as $id => $data)
{
$data['name'] = Util::localizedString($titlez->getEntry($id), $g ? 'female' : 'male');
unset($data['namefemale']);
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
if (!writeFile('datasets/'.User::$localeString.'/p-titles-'.$g, $buff, $log))
$success = false;
}
}
return $success;
};
/**********/
/* Mounts */
/**********/
$scripts[] = function(&$log) use ($locales)
{
$success = true;
$condition = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
['typeCat', -5]
);
$mountz = new SpellList($condition);
foreach ($locales as $l)
{
set_time_limit(5);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$buff = "var _ = g_spells;\n";
foreach ($mountz->getListviewData(ITEMINFO_MODEL) as $id => $data)
{
$data['quality'] = $data['name'][0];
$data['name'] = substr($data['name'], 1);
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
if (!writeFile('datasets/'.User::$localeString.'/p-mounts', $buff, $log))
$success = false;
}
return $success;
};
/**************/
/* Companions */
/**************/
$scripts[] = function(&$log) use ($locales)
{
$success = true;
$condition = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
['typeCat', -6]
);
$companionz = new SpellList($condition);
foreach ($locales as $l)
{
set_time_limit(5);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$buff = "var _ = g_spells;\n";
foreach ($companionz->getListviewData(ITEMINFO_MODEL) as $id => $data)
{
$data['quality'] = $data['name'][0];
$data['name'] = substr($data['name'], 1);
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
}
if (!writeFile('datasets/'.User::$localeString.'/p-companions', $buff, $log))
$success = false;
}
return $success;
};
/************/
/* Factions */
/************/
$scripts[] = function(&$log) use ($locales)
{
$success = true;
$condition = array( // todo (med): exclude non-gaining reputation-header
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]
);
$factionz = new FactionList($condition);
foreach ($locales as $l)
{
set_time_limit(5);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$buff = "var _ = g_factions;\n";
foreach ($factionz->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
$buff .= "\ng_faction_order = [0, 469, 891, 1037, 1118, 67, 1052, 892, 936, 1117, 169, 980, 1097];\n";
if (!writeFile('datasets/'.User::$localeString.'/p-factions', $buff, $log))
$success = false;
}
return $success;
};
/***********/
/* Recipes */
/***********/
$scripts[] = function(&$log) use ($locales)
{
// special case: secondary skills are always requested, so put them in one single file (185, 129, 356); it also contains g_skill_order
$skills = [171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, [185, 129, 356]];
$success = true;
$baseCnd = array(
CFG_SQL_LIMIT_NONE,
[['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0],
['effect1Id', [6, 45, 57, 127, 33, 158, 99, 28, 95], '!'], // aura, tradeSkill, Tracking, Prospecting, Decipher, Milling, Disenchant, Summon (Engineering), Skinning
['effect2Id', [118, 60], '!'], // not the skill itself
['OR', ['typeCat', 9], ['typeCat', 11]]
);
foreach ($skills as $s)
{
$file = is_array($s) ? 'sec' : (string)$s;
$cnd = array_merge($baseCnd, [['skillLine1', $s]]);
$recipez = new SpellList($cnd);
$created = '';
foreach ($recipez->iterate() as $__)
{
foreach ($recipez->canCreateItem() as $idx)
{
$id = $recipez->getField('effect'.$idx.'CreateItemId');
$created .= "g_items.add(".$id.", {'icon':'".$recipez->relItems->getEntry($id)['iconString']."'});\n";
}
}
foreach ($locales as $l)
{
set_time_limit(10);
User::useLocale($l);
Lang::load(Util::$localeStrings[$l]);
$buff = '';
foreach ($recipez->getListviewData() as $id => $data)
$buff .= '_['.$id.'] = '.json_encode($data, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).";\n";
if (!$buff)
{
// this behaviour is intended, do not create an error
$log[] = [time(), ' notice: profiler - file datasets/'.User::$localeString.'/p-recipes-'.$file.' has no content => skipping'];
continue;
}
$buff = $created."\nvar _ = g_spells;\n".$buff;
if (is_array($s))
$buff .= "\ng_skill_order = [171, 164, 333, 202, 182, 773, 755, 165, 186, 393, 197, 185, 129, 356];\n";
if (!writeFile('datasets/'.User::$localeString.'/p-recipes-'.$file, $buff, $log))
$success = false;
}
}
return $success;
};
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
// run scripts
foreach ($scripts as $func)
if (!$func($log))
$success = false;
return $success;
}
?>

View File

@@ -0,0 +1,35 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'realms'-file in datasets
// this script requires all realms in use to be defined in auth.realmlist
// battlegroups has to be set in aowow.aowow_config
/* seems to be unused, was located in the same file as g_realms
var g_regions = {
us => 'www.wowarmory.com',
eu => 'eu.wowarmory.com'
};
*/
/* Examples
1 => {
name:'Eldre\'Thalas',
battlegroup:'Reckoning',
region:'us'
},
*/
function realms(&$log)
{
$file = 'datasets/realms';
$rows = DB::Auth()->select('SELECT id AS ARRAY_KEY, name, ? AS battlegroup, IF(timezone IN (8, 9, 10, 11, 12), "eu", "us") AS region FROM realmlist WHERE allowedSecurityLevel = 0', CFG_BATTLEGROUP);
$str = 'var g_realms = '.json_encode($rows, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE).';';
return writeFile($file, $str, $log);
}
?>

View File

@@ -0,0 +1,195 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// shared funcs
function writeFile($file, $content, &$log)
{
$success = false;
if ($handle = @fOpen($file, "w"))
{
if (fWrite($handle, $content))
{
$success = true;
$log[] = [time(), sprintf(ERR_NONE, $file)];
}
else
$log[] = [time(), sprintf(ERR_WRITE_FILE, $file)];
fClose($handle);
}
else
$log[] = [time(), sprintf(ERR_CREATE_FILE, $file)];
if ($success)
chmod($file, 0766);
return $success;
}
function writeDir($dir, &$log)
{
if (is_dir($dir) || @mkdir($dir, 0766, true))
return true;
$log[] = [time(), ' error: could not create output directory '.$dir];
return false;
}
// shared strings
define('ERR_CREATE_FILE', ' error: could not create file at destination %s');
define('ERR_WRITE_FILE', ' error: could not write to file at destination %s');
define('ERR_READ_FILE', ' error: file %s could not be read');
define('ERR_MISSING_FILE', ' error: file %s not found');
define('ERR_NONE', 'success: created file(s) %s');
define('ERR_MISSING_INCL', ' error: required function %s() could not be found at %s');
$log = [];
$locales = [];
$tplPath = 'setup/tools/filegen/templates/';
$pairs = array(
'CFG_NAME' => CFG_NAME,
'CFG_NAME_SHORT' => CFG_NAME_SHORT,
'HOST_URL' => HOST_URL,
'STATIC_URL' => STATIC_URL
);
$tplFiles = array(
'searchplugin' => ['aowow.xml', 'static/download/searchplugins/'],
'power' => ['power.js', 'static/widgets/' ],
'searchboxScript' => ['searchbox.js', 'static/widgets/' ],
'demo' => ['demo.html', 'static/widgets/power/' ],
'searchboxBody' => ['searchbox.html', 'static/widgets/searchbox/' ],
'realmMenu' => ['profile_all.js', 'static/js/' ],
'locales' => ['locale.js', 'static/js/' ],
// 'itemScaling => ['item-scaling', 'datasets/' ], # provided 'as is', as dbc-content doesn't usualy change
);
$nullFiles = array(
'realms', 'statistics', 'profiler', // profiler related
'talents', 'talentIcons', 'glyphs', // talentCalc related
'itemsets', 'enchants', 'gems', // comparison related
'pets',
);
// restrict actual locales
foreach (Util::$localeStrings as $idx => $str)
if ($str && (CFG_LOCALES & (1 << $idx)))
$locales[] = $idx;
// check $pageParam; limit to real scriptNames
$scList = array_merge(array_keys($tplFiles), $nullFiles);
if ($pageParam)
$scList = array_intersect(explode(';', $pageParam), $scList);
if ($scList)
{
// start
$log[] = [time(), 'begin generation of '. implode(', ', $scList)];
$log[] = null;
// files with template
foreach ($tplFiles as $name => list($file, $destPath))
{
if ($scList && !in_array($name, $scList))
continue;
if (!file_exists($tplPath.$file.'.in'))
{
$log[] = [time(), sprintf(ERR_MISSING_FILE, $tplPath.$file.'.in')];
continue;
}
if (!writeDir($destPath, $log))
continue;
if ($content = file_get_contents($tplPath.$file.'.in'))
{
if ($dest = @fOpen($destPath.$file, "w"))
{
// replace constants
$content = strtr($content, $pairs);
// must generate content
// PH format: /*setup:<setupFunc>*/
if (preg_match('/\/\*setup:([\w\d_-]+)\*\//i', $content, $m))
{
$res = '';
if (file_exists('setup/tools/filegen/'.$m[1].'.func.php'))
{
include 'setup/tools/filegen/'.$m[1].'.func.php';
$res = $m[1]($log, $locales);
}
else
$log[] = [time(), sprintf(ERR_MISSING_INCL, $m[1], 'setup/tools/filegen/'.$m[1].'.func.php')];
$content = str_replace('/*setup:'.$m[1].'*/', $res, $content);
}
if (fWrite($dest, $content))
{
fClose($dest);
$log[] = [time(), sprintf(ERR_NONE, $destPath.$file)];
}
else
{
$log[] = [time(), sprintf(ERR_WRITE_FILE, $destPath.$file)];
fClose($dest);
continue;
}
}
else
{
$log[] = [time(), sprintf(ERR_CREATE_FILE, $destPath.$file)];
continue;
}
}
else
{
$log[] = [time(), sprintf(ERR_READ_FILE, $tplPath.$file.'.in')];
continue;
}
}
// files without template
foreach ($nullFiles as $file)
{
if ($scList && !in_array($file, $scList))
continue;
if (file_exists('setup/tools/filegen/'.$file.'.func.php'))
{
include 'setup/tools/filegen/'.$file.'.func.php';
if ($file($log, $locales))
$log[] = [time(), ' - subscript returned sucessfully'];
else
$log[] = [time(), ' - subscript returned with errors'];
set_time_limit(30); // reset to default for the next script
}
else
$log[] = [time(), sprintf(ERR_MISSING_INCL, $file, 'setup/tools/filegen/'.$file.'.func.php')];
}
// end
$log[] = null;
$log[] = [time(), 'finished file generation'];
}
else
$log[] = [time(), 'no valid script names supplied'];
// print accumulated log
echo "<pre>\n";
foreach ($log as $l)
if ($l)
echo date('H:i:s', $l[0]) . ' ' . $l[1]."\n";
else
echo "\n";
echo "</pre>\n";
?>

View File

@@ -0,0 +1,152 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// Create 'statistics'-file in datasets
// this script requires the following dbcs to be parsed and available
// gtChanceToMeleeCrit.dbc, gtChanceToSpellCrit.dbc, gtChanceToMeleeCritBase.dbc, gtChanceToSpellCritBase.dbc, gtOCTRegenHP, gtRegenHPPperSpt.dbc, gtRegenMPPerSpt.dbc
function statistics(&$log)
{
$classs = function()
{
// constants and mods taken from TrinityCore (Player.cpp, StatSystem.cpp)
/* content per Index
mleatkpwr[base, strMultiplier, agiMultiplier, levelMultiplier]
rngatkpwr[base, strMultiplier, agiMultiplier, levelMultiplier]
baseCritPct[phys, spell]
diminishingConstant
baseDodgePct
DodgeCap
baseParryPct
ParryCap
baseBlockPct
directMod1 applies mod directly only one class having something worth mentioning: DK
directMod2 applies mod directly so what were they originally used for..?
*/
$dataz = array(
1 => [[-20, 2, 0, 3], [-10, 0, 1, 1], null, 0.9560, 3.6640, 88.129021, 5, 47.003525, 5, 0, 0],
2 => [[-20, 2, 0, 3], [-10, 0, 1, 0], null, 0.9560, 3.4943, 88.129021, 5, 47.003525, 5, 0, 0],
3 => [[-20, 1, 1, 2], [-10, 0, 2, 2], null, 0.9880, -4.0873, 145.560408, 5, 145.560408, 0, 0, 0],
4 => [[-20, 1, 1, 2], [-10, 0, 1, 1], null, 0.9880, 2.0957, 145.560408, 5, 145.560408, 0, 0, 0],
5 => [[-10, 1, 0, 0], [-10, 0, 1, 0], null, 0.9830, 3.4178, 150.375940, 0, 0.0, 0, 0, 0],
6 => [[-20, 2, 0, 3], [-10, 0, 1, 0], null, 0.9560, 3.6640, 88.129021, 5, 47.003525, 0, 0, ['parryrtng' => [0.25, 'percentOf', 'str']]], // Forcefull Deflection (49410)
7 => [[-20, 1, 1, 2], [-10, 0, 1, 0], null, 0.9880, 2.1080, 145.560408, 0, 145.560408, 5, 0, 0],
8 => [[-10, 1, 0, 0], [-10, 0, 1, 0], null, 0.9830, 3.6587, 150.375940, 0, 0.0, 0, 0, 0],
9 => [[-10, 1, 0, 0], [-10, 0, 1, 0], null, 0.9830, 2.4211, 150.375940, 0, 0.0, 0, 0, 0],
11 => [[-20, 2, 0, 0], [-10, 0, 1, 0], null, 0.9720, 5.6097, 116.890707, 0, 0.0, 0, 0, 0]
);
foreach ($dataz as $class => &$data)
$data[2] = array_values(DB::Aowow()->selectRow('SELECT mle.chance*100 cMle, spl.chance*100 cSpl FROM dbc.gtchancetomeleecritbase mle, dbc.gtchancetospellcritbase spl WHERE mle.idx = spl.idx AND mle.idx = ?d', $class - 1));
return $dataz;
};
$race = function()
{
// { str, agi, sta, int, spi, hp, mana, directMod1, directMod2 }
return array(
1 => [20, 20, 20, 20, 20, 0, ['spi' => [0.05, 'percentOf', 'spi']]], // The Human Spirit (20598)
2 => [23, 17, 22, 17, 23, 0, 0],
3 => [22, 16, 23, 19, 19, 0, 0],
4 => [17, 25, 19, 20, 20, 0, 0],
5 => [19, 18, 21, 18, 25, 0, 0],
6 => [25, 15, 22, 15, 22, 0, ['health' => [0.05, 'functionOf', '$function(p) { return g_statistics.combo[p.classs][p.level][5]; }']]], // Endurance (20550) ... if you are looking for something elegant, look away!
7 => [15, 23, 19, 24, 20, 0, ['int' => [0.05, 'percentOf', 'int']]], // Expansive Mind (20591)
8 => [21, 22, 21, 16, 21, 0, ['healthrgn' => [0.1, 'percentOf', 'healthrgn']]], // Regeneration (20555)
10 => [17, 22, 18, 24, 19, 0, 0],
11 => [21, 17, 19, 21, 22, 0, 0] // ['mlehitpct' => [1, 'add'], 'splhitpct' => [1, 'add'], 'rgdhitpct' => [1, 'add']] // Heroic Presence (6562, 28878) (not actually shown..?)
);
};
$combo = function()
{
$result = [];
$critToDodge = array(
1 => 0.85/1.15, 2 => 1.00/1.15, 3 => 1.11/1.15,
4 => 2.00/1.15, 5 => 1.00/1.15, 6 => 0.85/1.15,
7 => 1.60/1.15, 8 => 1.00/1.15, 9 => 0.97/1.15, 11 => 2.00/1.15
);
// TrinityCore claims, DodgePerAgi per level and class can be constituted from critPerAgi (and level (and class))
// who am i to argue
// rebase stats to a specific race. chosen human as all stats are 20
// level:{ str, agi, sta, int, spi, hp, mana, mleCrt%Agi, splCrt%Int, dodge%Agi, HealthRegenModToBaseStat, HealthRegenModToBonusStat }
foreach ($critToDodge as $class => $mod)
{
// humans can't be hunter, shaman, druids (use tauren here)
if (in_array($class, [3, 7, 11]))
$offset = [25, 15, 22, 15, 22];
else
$offset = [20, 20, 20, 20, 20];
$rows = DB::Aowow()->select('SELECT pls.level AS ARRAY_KEY, str-?d, agi-?d, sta-?d, inte-?d, spi-?d, basehp, IF(basemana <> 0, basemana, 100), mlecrt.chance*100, splcrt.chance*100, mlecrt.chance*100 * ?f, baseHP5.ratio*1, extraHP5.ratio*1 ' .
'FROM player_levelstats pls JOIN player_classlevelstats pcls ON pls.level = pcls.level AND pls.class = pcls.class JOIN' .
' dbc.gtchancetomeleecrit mlecrt ON mlecrt.idx = ((pls.class - 1) * 100) + (pls.level - 1) JOIN' .
' dbc.gtchancetospellcrit splcrt ON splcrt.idx = ((pls.class - 1) * 100) + (pls.level - 1) JOIN' .
' dbc.gtoctregenhp baseHP5 ON baseHP5.idx = ((pls.class - 1) * 100) + (pls.level - 1) JOIN' .
' dbc.gtregenhpperspt extraHP5 ON extraHP5.idx = ((pls.class - 1) * 100) + (pls.level - 1) ' .
'WHERE pls.race = ?d AND pls.class = ?d ORDER BY pls.level ASC',
$offset[0], $offset[1], $offset[2], $offset[3], $offset[4],
$mod,
in_array($class, [3, 7, 11]) ? 6 : 1,
$class
);
$result[$class] = [];
foreach ($rows as $k => $row)
$result[$class][$k] = array_values($row);
}
return $result;
};
$level = function()
{
// base mana regeneration per level
// identical across classes (just use one, that acutally has mana (offset: 100))
// content of gtRegenMPPerSpt.dbc
return DB::Aowow()->selectCol('SELECT idx-99 AS ARRAY_KEY, ratio FROM dbc.gtregenmpperspt WHERE idx >= 100 AND idx < 100 + ?d', MAX_LEVEL);
};
$skills = function()
{
// profession perks (skinning => +crit, mining => +stam) and maybe some others; skillId:{rankNo:someJSON, ..}?
return [];
};
// todo: x
$sub = ['classs', 'race', 'combo', 'level', 'skills'];
$out = [];
$success = true;
foreach ($sub as $s)
{
$res = $$s();
$out[$s] = $res;
if (!$res)
{
$log[] = [time(), ' error: statistics - generator $'.$s.'() returned empty'];
$success = false;
}
}
$json = json_encode($out, JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$toFile = 'g_statistics = '.preg_replace('/"\$([^$"]+)"/', '\1', $json).';';
if (!writeFile('datasets/statistics', $toFile, $log))
$success = false;
return $success;
}
?>

View File

@@ -0,0 +1,99 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// builds image-textures for the talent-calculator
// spellIcons must be extracted and converted to at least medium size
// this script requires the following dbc-files to be parsed and available
// Talent, TalentTab, Spell
function talentIcons(&$log)
{
$success = true;
$query = 'SELECT s.iconString FROM ?_spell s JOIN dbc.talent t ON t.rank1 = s.Id JOIN dbc.talenttab tt ON tt.Id = t.tabId WHERE tt.?# = ?d AND tt.tabNumber = ?d ORDER BY t.row, t.column, t.petCategory1 ASC;';
$dims = 36; //v-pets
$filenames = ['icons', 'warrior', 'paladin', 'hunter', 'rogue', 'priest', 'deathknight', 'shaman', 'mage', 'warlock', null, 'druid'];
// create directory if missing
if (!writeDir('static/images/wow/talents/icons', $log))
$success = false;
if (!writeDir('static/images/wow/hunterpettalents', $log))
$success = false;
foreach ($filenames as $k => $v)
{
if (!$v)
continue;
set_time_limit(10);
for ($tree = 0; $tree < 3; $tree++)
{
$what = $k ? 'classMask' : 'creatureFamilyMask';
$set = $k ? 1 << ($k - 1) : 1 << $tree;
$subset = $k ? $tree : 0;
$path = $k ? 'talents/icons' : 'hunterpettalents';
$outFile = 'static/images/wow/'.$path.'/'.$v.'_'.($tree + 1).'.jpg';
$icons = DB::Aowow()->SelectCol($query, $what, $set, $subset);
if (empty($icons))
{
$log[] = [time(), ' error: talentIcons - query for '.$v.' tree: '.$k.' empty'];
$success = false;
continue;
}
if ($res = imageCreateTrueColor(count($icons) * $dims, 2 * $dims))
{
for ($i = 0; $i < count($icons); $i++)
{
$imgFile = 'static/images/wow/icons/medium/'.strtolower($icons[$i]).'.jpg';
if (!file_exists($imgFile))
{
$log[] = [time(), ' error: talentIcons - raw image '.$imgFile. ' not found'];
$success = false;
break;
}
$im = imagecreatefromjpeg($imgFile);
// colored
imagecopymerge($res, $im, $i * $dims, 0, 0, 0, imageSX($im), imageSY($im), 100);
// grayscale
if (imageistruecolor($im))
imagetruecolortopalette($im, false, 256);
for ($j = 0; $j < imagecolorstotal($im); $j++)
{
$color = imagecolorsforindex($im, $j);
$gray = round(0.299 * $color['red'] + 0.587 * $color['green'] + 0.114 * $color['blue']);
imagecolorset($im, $j, $gray, $gray, $gray);
}
imagecopymerge($res, $im, $i * $dims, $dims, 0, 0, imageSX($im), imageSY($im), 100);
}
if (@imagejpeg($res, $outFile))
$log[] = [time(), sprintf(ERR_NONE, $outFile)];
else
{
$success = false;
$log[] = [time(), ' error: talentIcons - '.$outFile.'.jpg could not be written!'];
}
}
else
{
$success = false;
$log[] = [time(), ' error: talentIcons - image resource not created'];
continue;
}
}
}
return $success;
}
?>

View File

@@ -0,0 +1,207 @@
<?php
if (!defined('AOWOW_REVISION'))
die('illegal access');
// builds talent-tree-data for the talent-calculator
// this script requires the following dbc-files to be parsed and available
// Talent, TalentTab, Spell, CreatureFamily
// talents
// i - int talentId (id of aowow_talent)
// n - str name (spellname of aowow_spell for spellID = rank1)
// m - int number of ranks (6+ are empty)
// s - array:int spells to ranks (rank1, rank2, ..., rank5 of aowow_talent)
// d - array:str description of spells
// x - int column (col from aowow_talent)
// y - int row (row of aowow_talent)
// r - array:int on what the talent depends on: "r:[u, v]", u - nth talent in tree, v - required rank of u
// f - array:int [pets only] creatureFamilies, that use this spell
// t - array:str if the talent teaches a spell, this is the upper tooltip-table containing castTime, cost, cooldown
// j - array of modifier-arrays per rank for the Profiler [nyi]
// tabs
// n - name of the tab
// t - array of talent-objects
// f - array:int [pets only] creatureFamilies in that category
function talents(&$log, $locales)
{
$success = true;
$buildTree = function ($class) use (&$petFamIcons, &$tSpells)
{
$petCategories = [];
$mask = $class ? 1 << ($class - 1) : 0;
// All "tabs" of a given class talent
$tabs = DB::Aowow()->select('SELECT * FROM dbc.talenttab WHERE classMask = ?d ORDER BY `tabNumber`, `creatureFamilyMask`', $mask);
$result = [];
for ($l = 0; $l < count($tabs); $l++)
{
$talents = DB::Aowow()->select('
SELECT t.id AS tId, t.*, s.*
FROM dbc.talent t, ?_spell s
WHERE t.`tabId`= ?d AND s.`Id` = t.`rank1`
ORDER by t.`row`, t.`column`',
$tabs[$l]['Id']
);
$result[$l] = array(
'n' => Util::localizedString($tabs[$l], 'name'),
't' => []
);
if (!$class)
{
$petFamId = log($tabs[$l]['creatureFamilyMask'], 2);
$result[$l]['icon'] = $petFamIcons[$petFamId];
$petCategories = DB::Aowow()->SelectCol('SELECT Id AS ARRAY_KEY, category FROM ?_pet WHERE type = ?d', $petFamId);
$result[$l]['f'] = array_keys($petCategories);
}
// talent dependencies go here
$depLinks = [];
$tNums = [];
for ($j = 0; $j < count($talents); $j++)
{
$tNums[$talents[$j]['tId']] = $j;
$d = [];
$s = [];
$i = $talents[$j]['tId'];
$n = Util::localizedString($talents[$j], 'name');
$x = $talents[$j]['column'];
$y = $talents[$j]['row'];
$r = null;
$t = [];
$icon = $talents[$j]['iconString'];
$m = $talents[$j]['rank2'] == 0 ? 1 : (
$talents[$j]['rank3'] == 0 ? 2 : (
$talents[$j]['rank4'] == 0 ? 3 : (
$talents[$j]['rank5'] == 0 ? 4 : 5
)
)
);
// duplet handling
$f = [];
foreach ($petCategories as $k => $v)
{
// cant handle 64bit integer .. split
if ($v >= 32 && ((1 << ($v - 32)) & $talents[$j]['petCategory2']))
$f[] = $k;
else if ($v < 32 && ((1 << $v) & $talents[$j]['petCategory1']))
$f[] = $k;
}
for ($k = 0; $k <= ($m - 1); $k++)
{
if (!$tSpells->getEntry($talents[$j]['rank'.($k + 1)]))
continue;
$d[] = $tSpells->parseText()[0];
$s[] = $talents[$j]['rank'.($k + 1)];
if ($talents[$j]['talentSpell'])
$t[] = $tSpells->getTalentHeadForCurrent();
}
if ($talents[$j]['reqTalent'])
{
// we didn't encounter the required talent yet => create reference
if (!isset($tNums[$talents[$j]['reqTalent']]))
$depLinks[$talents[$j]['reqTalent']] = $j;
$r = @[$tNums[$talents[$j]['reqTalent']], $talents[$j]['reqRank'] + 1];
}
$result[$l]['t'][$j] = array(
'i' => $i,
'n' => $n,
'm' => $m,
'd' => $d,
's' => $s,
'x' => $x,
'y' => $y,
);
if (isset($r))
$result[$l]['t'][$j]['r'] = $r;
if (!empty($t))
$result[$l]['t'][$j]['t'] = $t;
if (!empty($f))
$result[$l]['t'][$j]['f'] = $f;
if ($class)
$result[$l]['t'][$j]['iconname'] = $icon;
// If this talent is a reference, add it to the array of talent dependencies
if (isset($depLinks[$talents[$j]['tId']]))
{
$result[$l]['t'][$depLinks[$talents[$j]['tId']]]['r'][0] = $j;
unset($depLinks[$talents[$j]['tId']]);
}
}
// Remove all dependencies for which the talent has not been found
foreach ($depLinks as $dep_link)
unset($result[$l]['t'][$dep_link]['r']);
}
return $result;
};
// my neighbour is noisy as fuck and my head hurts, so ..
$petFamIcons = ['Ability_Druid_KingoftheJungle', 'Ability_Druid_DemoralizingRoar', 'Ability_EyeOfTheOwl']; // .. i've no idea where to fetch these from
$classes = [CLASS_WARRIOR, CLASS_PALADIN, CLASS_HUNTER, CLASS_ROGUE, CLASS_PRIEST, CLASS_DEATHKNIGHT, CLASS_SHAMAN, CLASS_MAGE, CLASS_WARLOCK, CLASS_DRUID];
$petIcons = '';
// check directory-structure
foreach (Util::$localeStrings as $dir)
if (!writeDir('datasets/'.$dir, $log))
$success = false;
$tSpellIds = DB::Aowow()->selectCol('SELECT rank1 FROM dbc.talent UNION SELECT rank2 FROM dbc.talent UNION SELECT rank3 FROM dbc.talent UNION SELECT rank4 FROM dbc.talent UNION SELECT rank5 FROM dbc.talent');
$tSpells = new SpellList(array(['s.id', $tSpellIds], CFG_SQL_LIMIT_NONE));
foreach ($locales as $lId)
{
User::useLocale($lId);
Lang::load(Util::$localeStrings[$lId]);
// TalentCalc
foreach ($classes as $cMask)
{
set_time_limit(20);
$cId = log($cMask, 2) + 1;
$file = 'datasets/'.User::$localeString.'/talents-'.$cId;
$toFile = '$WowheadTalentCalculator.registerClass('.$cId.', '.json_encode($buildTree($cId), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).')';
if (!writeFile($file, $toFile, $log))
$success = false;
}
// PetCalc
if (empty($petIcons))
{
$pets = DB::Aowow()->SelectCol('SELECT Id AS ARRAY_KEY, iconString FROM ?_pet');
$petIcons = json_encode($pets, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
}
$toFile = "var g_pet_icons = ".$petIcons.";\n\n";
$toFile .= 'var g_pet_talents = '.json_encode($buildTree(0), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK).';';
$file = 'datasets/'.User::$localeString.'/pet-talents';
if (!writeFile($file, $toFile, $log))
$success = false;
}
return $success;
}
?>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>CFG_NAME_SHORT</ShortName>
<Description>CFG_NAME_SHORT Search Plugin</Description>
<Url
type="text/html"
method="get"
template="HOST_URL/?search={searchTerms}" />
<Url
type="application/x-suggestions+json"
method="get"
template="HOST_URL/?search={searchTerms}&amp;opensearch" />
<Image height="16" width="16" type="image/vnd.microsoft.icon">STATIC_URL/images/logos/favicon.ico</Image>
<Image height="16" width="16" type="image/gif">STATIC_URL/images/icons/favicon.gif</Image>
</OpenSearchDescription>

View File

@@ -0,0 +1,114 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>'Powered by CFG_NAME_SHORT' Demo</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<script src="../power.js?lang=en" type="text/javascript"></script>
<script>var aowow_tooltips = { "colorlinks": true, "iconizelinks": true, "renamelinks": true, "hide": { "reagents": true, "sellprice": true }}</script>
<style type="text/css">
body { padding: 50px 15px 15px 15px; margin: 0; font-family: Arial; color: white; background: black }
a { color: #FFD100; cursor: pointer; outline: none }
a:hover { color: white }
h2 { font-size: 20px; margin-top: 0; padding-top: 0; line-height: 1.5em }
h2 small { font-size: 13px; font-weight: normal }
</style>
</head>
<body>
<h2>'Powered by CFG_NAME_SHORT' Demo<br /><small><a href="/">&laquo; Return to the site</a></small></h2>
<div style="float: left; width: 400px; margin-right: 64px">
<i>Items</i><br /><br />
<a href="HOST_URL/?item=31015" class="q4">Skyshatter Cover</a><br />
<a href="HOST_URL/?item=30987" class="q4">Lightbringer Faceguard</a><br /><br />
<a href="HOST_URL/?item=48718" rel="lvl=42" class="q7">Repurposed Lava Dredger</a> <small>(Level 42 scaling)</small><br /><br />
<a href="http://www.example.com" rel="item=28288" class="q3">Abacus of Violent Odds</a> <small>(Custom URL)</small><br />
<a href="HOST_URL/?item=22589&amp;lvl=80" class="q5">Atiesh, Greatstaff of the Guardian</a> <small>(Level 80 conversions)</small><br />
<a href="HOST_URL/?item=25697" rel="gems=23121&amp;ench=2647&amp;pcs=25697:25695:25696" class="q3">Felstalker Bracers</a> <small>(Enchant, gem, set bonus)</small><br />
<a href="HOST_URL/?item=31928" rel="rand=-63&amp;ench=2931" class="q3">Dark Band of Agility</a> <small>(Random enchantment, enchant)</small><br />
<a href="HOST_URL/?item=32474" rel="ench=3003&amp;gems=32409:31865" class="q3">Surestrike Goggles v2.0</a> <small>(Enchant, gems)</small><br /><br />
<hr />
<i>Spells</i><br /><br />
<a href="HOST_URL/?spell=18562">Swiftmend</a><br />
<a href="HOST_URL/?spell=589">Shadow Word: Pain</a><br />
<a href="HOST_URL/?spell=36257">Blacksmithing: Bulwark of the Ancient Kings</a><br /><br />
<a href="HOST_URL/?spell=1126" rel="buff">Mark of the Wild</a> <small>(Buff)</small><br /><br />
<hr />
<i>Quests</i><br /><br />
<a href="HOST_URL/?quest=826">Zalazane</a><br />
<a href="HOST_URL/?quest=11389">Wanted: Arcatraz Sentinels</a><br />
<a href="HOST_URL/?quest=11058">An Apexis Relic</a><br />
<a href="HOST_URL/?quest=9637">Kalynna's Request</a><br /><br />
<hr />
<i>Achievements</i><br /><br />
<a href="HOST_URL/?achievement=277">'Tis the Season</a><br />
<a href="HOST_URL/?achievement=1558" rel="who=Shadowrogue&amp;when=1273022820000">100 Fish</a> <small>(Earned)</small><br /><br />
<hr />
<i>Profiles</i><br /><br />
<a href="HOST_URL/?profile=us.draenor.drekdarok">Drekdarok</a><br />
<a href="HOST_URL/?profile=10344553">DPS</a><br /><br/>
<a href="http://www.example.com" rel="profile=us.draenor.drekdarok">Drekdarok</a><small> (Custom URL)</small><br />
<a href="http://www.example.com" rel="profile=10344553">DPS</a><small> (Custom URL)</small><br />
<hr />
<i>Custom</i><br /><br />
<a href="javascript:;" onmouseover="$WowheadPower.showTooltip(event, 'Hello :0', 'inv_sword_14')" onmousemove="$WowheadPower.moveTooltip(event)" onmouseout="$WowheadPower.hideTooltip();">Hai to you!</a><br /><br />
<hr />
<i>Image Map</i><br /><br />
<map id="planetmap" name="planetmap">
<area shape="rect" coords="0,0,82,126" href="HOST_URL/?item=30987" target="_blank" alt="Sun" />
<area shape="circle" coords="90,58,3" href="HOST_URL/?spell=1126" target="_blank" alt="Mercury" />
<area shape="circle" coords="124,58,8" href="HOST_URL/?quest=11058" target="_blank" alt="Venus" />
</map>
<img src="http://www.w3schools.com/TAGS/planets.gif" width="145" height="126" alt="" border="0" usemap ="#planetmap" />
</div>
<div style="float: left">
<i>Localized links</i> <small>(requires your site to use UTF-8 encoding)</small><br /><br />
<b>Deutsch:</b> <a href="http://de.wowhead.com/item=31015">Skyshatter Cover</a><br />
<b>Français:</b> <a href="http://www.wowhead.com/item=31015" rel="domain=fr">Skyshatter Cover</a><br />
<b>Español:</b> <a href="http://es.wowhead.com/item=31015">Skyshatter Cover</a><br />
<b>&#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;:</b> <a href="http://ru.wowhead.com/item=31015">Skyshatter Cover</a><br />
</div>
<div style="clear: both"></div>
<div style="width: 30px; height: 800px"></div>
<center>
<a href="HOST_URL/?item=30301">Item #30301</a><br />
<a href="HOST_URL/?item=99999">Item #99999</a>
</center>
<a style="position: absolute; right: 0; bottom: 0; background: black" href="HOST_URL/?item=30319">Item #30319</a>
<a style="position: absolute; left: 0; bottom: 0; background: black" href="HOST_URL/?item=22589">Item #22589</a>
<a style="position: absolute; right: 0; top: 0; background: black" href="HOST_URL/?item=8171">Item #8171</a>
<a style="position: absolute; left: 0; top: 0; background: black" href="HOST_URL/?item=6479">Item #6479!</a>
</body>
</html>

View File

@@ -0,0 +1,9 @@
$WH.g_convertRatingToPercent.RB = {/*setup:gtCombatRatings*/};
$WH.g_convertScalingFactor.SV = {/*setup:scalingStatValues*/};
$WH.g_convertScalingFactor.SD = {/*setup:scalingStatDistribution*/};
if ($WH.isset('$WowheadPower')) {
$WowheadPower.loadScales(3);
}

View File

@@ -0,0 +1,62 @@
/*
Locale class
*/
var LOCALE_ENUS = 0;
var LOCALE_FRFR = 2;
var LOCALE_DEDE = 3;
var LOCALE_ESES = 6;
var LOCALE_RURU = 8;
var Locale = {
current: {},
// All
locales: {
/*setup:locales*/
},
getAll: function() {
var result = [];
for (var id in Locale.locales) {
result.push(Locale.locales[id]);
}
return result;
},
getAllByName: function() {
var result = Locale.getAll();
result.sort(function(a, b) {
return $WH.strcmp(a.description, b.description);
});
return result;
},
getId: function() {
return Locale.current.id;
},
getName: function() {
var localeId = Locale.getId();
return Locale.locales[localeId].name;
},
get: function() {
var localeId = Locale.getId();
return Locale.locales[localeId];
},
set: function(localeId) {
$.extend(Locale.current, Locale.locales[localeId]);
}
};
Locale.set(LOCALE_ENUS); // Default

View File

@@ -0,0 +1,817 @@
if (typeof $WH == "undefined") {
$WH = { wowheadRemote: true };
/* custom */
var g_host = 'HOST_URL';
var g_staticUrl = 'STATIC_URL';
}
if (typeof $WowheadPower == "undefined") {
var $WowheadPower = new function () {
var isRemote = $WH.wowheadRemote;
var
opt = { applyto: 3 },
head = document.getElementsByTagName("head")[0],
whcss,
currentType,
currentId,
currentLocale,
currentDomain,
currentParams,
currentA,
cursorX,
cursorY,
mode = 0,
eventAttached = false,
npcs = {},
objects = {},
items = {},
quests = {},
spells = {},
achievements = {},
profiles = {},
showLogo = 1,
STATUS_NONE = 0,
STATUS_QUERYING = 1,
STATUS_ERROR = 2,
STATUS_NOTFOUND = 3,
STATUS_OK = 4,
STATUS_SCALES = 5,
SCALES_NONE = 0,
SCALES_LOADED = 1,
SCALES_QUERYING = 2,
TYPE_NPC = 1,
TYPE_OBJECT = 2,
TYPE_ITEM = 3,
TYPE_QUEST = 5,
TYPE_SPELL = 6,
TYPE_ACHIEVEMENT = 10,
TYPE_PROFILE = 100,
CURSOR_HSPACE = 15,
CURSOR_VSPACE = 15,
_LANG = {
loading: "Loading...",
noresponse: "No response from server :(",
achievementcomplete: "Achievement earned by $1 on $2/$3/$4"
},
LOOKUPS = {
1: [npcs, "npc", "NPC" ],
2: [objects, "object", "Object" ],
3: [items, "item", "Item" ],
5: [quests, "quest", "Quest" ],
6: [spells, "spell", "Spell" ],
10: [achievements, "achievement", "Achievement"],
100: [profiles, "profile", "Profile" ]
},
SCALES = {
3: { url: "?data=item-scaling" }
},
LOCALES = {
0: "enus",
2: "frfr",
3: "dede",
6: "eses",
8: "ruru"
},
REDIRECTS = {
wotlk: "www",
ptr: "www",
www: "en"
};
if (isRemote) {
var Locale = { id: 0, name: "enus" };
}
function init() {
if (isRemote) {
var script = document.createElement("script");
// script.src = (document.location.protocol != "https:" ? "http:": document.location.protocol) + "//wowjs.zamimg.com/js/basic.js?5";
script.src = g_staticUrl + "/js/basic.js";
head.appendChild(script);
}
else {
attachEvent();
}
for (var type in SCALES) {
for (var localeId in LOCALES) {
SCALES[type][localeId] = SCALES_NONE
}
}
}
function initCSS() {
if (typeof aowow_tooltips == "undefined") {
return;
}
if (!("hide" in aowow_tooltips)) {
return;
}
if (typeof whcss != "undefined") {
return;
}
if (!document.styleSheets) {
return
}
var style = document.createElement("style");
style.type = "text/css";
head.appendChild(style);
if (!window.createPopup) {
head.appendChild(document.createTextNode(""));
}
whcss = document.styleSheets[document.styleSheets.length - 1];
for (var k in aowow_tooltips.hide) {
if (!aowow_tooltips.hide[k]) {
continue;
}
if (whcss.insertRule) {
whcss.insertRule(".wowhead-tooltip .whtt-" + k + "{display : none}", whcss.cssRules.length);
}
else if (whcss.addRule) {
whcss.addRule(".wowhead-tooltip .whtt-" + k, "display : none", -1);
}
}
}
function attachEvent() {
if (eventAttached) {
return;
}
eventAttached = true;
$WH.aE(document, "mouseover", onMouseOver);
}
function onDOMReady(func) {
if (typeof jQuery != "undefined") {
jQuery(func);
return
}
/in/.test(document.readyState) ? setTimeout(onDOMReady.bind(null, func), 9) : func();
}
this.init = function () {
if (isRemote) {
$WH.ae(head, $WH.ce("link", {
type: "text/css",
// href: (document.location.protocol != "https:" ? "http:": document.location.protocol) + "//wowcss.zamimg.com/css/basic.css?5",
href: g_staticUrl + "/css/basic.css",
rel: "stylesheet"
}));
}
attachEvent();
onDOMReady(function () {
if (typeof aowow_tooltips != "undefined") {
for (var i = 0; i < document.links.length; i++) {
var link = document.links[i];
scanElement(link);
}
initCSS();
}
});
};
function updateCursorPos(e) {
var pos = $WH.g_getCursorPos(e);
cursorX = pos.x;
cursorY = pos.y;
}
function scanElement(t, e) {
if (t.nodeName != "A" && t.nodeName != "AREA") {
return -2323;
}
if (!t.href.length && !t.rel) {
return;
}
if (t.rel && t.rel.indexOf("np") != -1) {
return;
}
var
i0,
i1,
i2,
url,
params = {};
currentParams = params;
var p = function (url, k, v) {
if (k == "buff" || k == "sock" || k == "map") {
params[k] = true;
}
else if (k == "rand" || k == "ench" || k == "lvl" || k == "c") {
params[k] = parseInt(v);
}
else if (k == "gems" || k == "pcs" || k == "know") {
params[k] = v.split(":");
}
else if (k == "who" || k == "domain") {
params[k] = v;
}
else if (k == "when") {
params[k] = new Date(parseInt(v));
}
else if (k == "premium") {
params[k] = true;
}
else if (k == "text") {
params[k] = true;
}
};
if (opt.applyto & 1) {
i1 = 2;
i2 = 3;
if (t.href.indexOf("http://") == 0 || t.href.indexOf("https://") == 0) {
i0 = 1;
// url = t.href.match(/^https?:\/\/(.+?)?\.?wowhead\.com(?:\:\d+)?\/\??(item|quest|spell|achievement|npc|object)=([0-9]+)/);
url = t.href.match(/^https?:\/\/(.*)\/?\??(item|quest|spell|achievement|npc|object)=([0-9]+)/);
if (url == null) {
// url = t.href.match(/^http:\/\/(.+?)?\.?wowhead\.com\/\?(profile)=([^&#]+)/)
url = t.href.match(/^https?:\/\/(.*)\/?\??(profile)=([^&#]+)/);
}
showLogo = 0;
}
else {
url = t.href.match(/()\?(item|quest|spell|achievement|npc|object)=([0-9]+)/);
if (url == null) {
url = t.href.match(/()\?(profile)=([^&#]+)/);
}
showLogo = 1;
}
}
if (url == null && t.rel && (opt.applyto & 2)) {
i0 = 0;
i1 = 1;
i2 = 2;
url = t.rel.match(/(item|quest|spell|achievement|npc|object).?([0-9]+)/);
// if (url == null) { // sarjuuk: also matches 'profiler' and 'profiles' which screws with the language-menu workaround
// url = t.rel.match(/(profile).?([^&#]+)/);
// }
showLogo = 1;
}
t.href.replace(/([a-zA-Z]+)=?([a-zA-Z0-9:-]*)/g, p);
if (t.rel) {
t.rel.replace(/([a-zA-Z]+)=?([a-zA-Z0-9:-]*)/g, p);
}
if (params.gems && params.gems.length > 0) {
var i;
for (i = Math.min(3, params.gems.length - 1); i >= 0; --i) {
if (parseInt(params.gems[i])) {
break;
}
}
++i;
if (i == 0) {
delete params.gems;
}
else if (i < params.gems.length) {
params.gems = params.gems.slice(0, i);
}
}
if (url) {
var
locale,
domain = "www";
currentA = t;
if (params.domain) {
domain = params.domain;
}
else if (i0 && url[i0]) {
// domain = url[i0];
domain = url[i0].split(".")[0];
}
if (REDIRECTS[domain]) {
domain = REDIRECTS[domain];
}
locale = $WH.g_getLocaleFromDomain(domain);
/* edit start */
if ($WH.in_array(['fr', 'de', 'es', 'ru', 'en'], domain) == -1) {
for (i in document.scripts) {
if (!document.scripts[i].src)
continue;
var dmn = document.scripts[i].src.match(/widgets\/power.js\?(lang|locale)=(en|fr|de|es|ru)/i);
if (dmn) {
domain = dmn[2];
locale = $WH.g_getLocaleFromDomain(dmn[2]);
break;
}
}
}
/* end of edit */
currentDomain = domain;
if (t.href.indexOf("#") != -1 && document.location.href.indexOf(url[i1] + "=" + url[i2]) != -1) {
return;
}
mode = t.parentNode.className.indexOf("icon") == 0 && t.parentNode.nodeName == "DIV" ? 1 : 0;
if (!t.onmouseout) {
if (mode == 0) {
t.onmousemove = onMouseMove;
}
t.onmouseout = onMouseOut;
}
if (e) {
updateCursorPos(e);
}
var
type = $WH.g_getIdFromTypeName(url[i1]),
typeId = url[i2];
display(type, typeId, locale, params);
if (e || typeof aowow_tooltips == "undefined") {
return;
}
var data = LOOKUPS[type][0][getFullId(typeId, params)];
var timeout = function (t) {
if (data.status[locale] != STATUS_OK && data.status[locale] != STATUS_NOTFOUND) {
window.setTimeout(function () {
timeout(t);
}, 5);
return;
}
if (aowow_tooltips.renamelinks) {
eval("name = data.name_" + LOCALES[locale]);
if (name) {
t.innerHTML = '<span>' + name + '</span>';
}
}
if (aowow_tooltips.iconizelinks && (type == TYPE_ITEM || type == TYPE_ACHIEVEMENT || type == TYPE_SPELL) && data.icon) {
// t.children[0].style.marginLeft = "18px";
t.className += " icontinyl";
t.style.paddingLeft = "18px !important";
t.style.verticalAlign = "center";
// t.style.background = "url(" + (document.location.protocol != "https:" ? "http:": document.location.protocol) + "//wowimg.zamimg.com/images/wow/icons/tiny/" + data.icon.toLocaleLowerCase() + ".gif) left center no-repeat"
t.style.background = "url(" + g_staticUrl + "/images/wow/icons/tiny/" + data.icon.toLocaleLowerCase() + ".gif) left center no-repeat"
}
if (aowow_tooltips.colorlinks) {
if (type == TYPE_ITEM) {
t.className += " q" + data.quality;
}
}
};
timeout(t);
}
}
function onMouseOver(e) {
e = $WH.$E(e);
var t = e._target;
var i = 0;
while (t != null && i < 5 && scanElement(t, e) == -2323) {
t = t.parentNode;
++i;
}
}
function onMouseMove(e) {
e = $WH.$E(e);
updateCursorPos(e);
$WH.Tooltip.move(cursorX, cursorY, 0, 0, CURSOR_HSPACE, CURSOR_VSPACE);
}
function onMouseOut() {
currentType = null;
currentA = null;
$WH.Tooltip.hide();
}
function getTooltipField(locale, n) {
var prefix = "tooltip";
if (currentParams && currentParams.buff) {
prefix = "buff";
}
if (currentParams && currentParams.text) {
prefix = "text";
}
if (currentParams && currentParams.premium) {
prefix = "tooltip_premium";
}
return prefix + (n ? n : "") + "_" + LOCALES[locale];
}
function getIconField() {
return (currentParams && currentParams.text) ? "text_icon" : "icon";
}
function getSpellsField(locale) {
return (currentParams && currentParams.buff ? "buff" : "") + "spells_" + LOCALES[locale];
}
function initElement(type, id, locale) {
var arr = LOOKUPS[type][0];
if (arr[id] == null) {
arr[id] = {};
}
if (arr[id].status == null) {
arr[id].status = {};
}
if (arr[id].response == null) {
arr[id].response = {};
}
if (arr[id].status[locale] == null) {
arr[id].status[locale] = STATUS_NONE;
}
}
function display(type, id, locale, params) {
if (!params) {
params = {};
}
var fullId = getFullId(id, params);
currentType = type;
currentId = fullId;
currentLocale = locale;
currentParams = params;
initElement(type, fullId, locale);
var arr = LOOKUPS[type][0];
if (arr[fullId].status[locale] == STATUS_OK || arr[fullId].status[locale] == STATUS_NOTFOUND) {
showTooltip(arr[fullId][getTooltipField(locale)], arr[fullId][getIconField()], arr[fullId].map, arr[fullId][getSpellsField(locale)], arr[fullId][getTooltipField(locale, 2)]);
}
else if (arr[fullId].status[locale] == STATUS_QUERYING || arr[fullId].status[locale] == STATUS_SCALES) {
showTooltip(_LANG.loading);
}
else {
request(type, id, locale, null, params);
}
}
function request(type, id, locale, stealth, params) {
var fullId = getFullId(id, params);
var arr = LOOKUPS[type][0];
if (arr[fullId].status[locale] != STATUS_NONE && arr[fullId].status[locale] != STATUS_ERROR) {
return;
}
arr[fullId].status[locale] = STATUS_QUERYING;
if (!stealth) {
arr[fullId].timer = setTimeout(function () {
showLoading.apply(this, [type, fullId, locale]);
}, 333);
}
var p = "";
for (var i in params) {
if (i != "rand" && i != "ench" && i != "gems" && i != "sock" && i != "lvl") {
continue;
}
if (typeof params[i] == "object") {
p += "&" + i + "=" + params[i].join(":");
}
else if (params[i] === true) {
p += "&" + i;
}
else {
p += "&" + i + "=" + params[i];
}
}
// var url = "http://" + $WH.g_getDomainFromLocale(locale) + ".wowhead.com"
// var url = (document.location.protocol != "https:" ? "http:": document.location.protocol) + "//" + localeDomain + ".wowhead.com";
var
localeDomain = $WH.g_getDomainFromLocale(locale),
url = g_host + "/";
// $WH.g_ajaxIshRequest(url + "?" + LOOKUPS[type][1] + "=" + id + "&power" + p);
$WH.g_ajaxIshRequest(url + "?" + LOOKUPS[type][1] + "=" + id + "&domain=" + localeDomain + "&power" + p);
if (SCALES[type] && SCALES[type][locale] == SCALES_NONE) {
$WH.g_ajaxIshRequest(url + SCALES[type].url);
SCALES[type][locale] = SCALES_QUERYING;
}
}
function showTooltip(html, icon, map, spellData, html2) {
if (currentA && currentA._fixTooltip) {
html = currentA._fixTooltip(html, currentType, currentId, currentA);
}
initCSS();
var notFound = false;
if (!html) {
html = LOOKUPS[currentType][2] + " not found :(";
icon = "inv_misc_questionmark";
notFound = true;
}
else {
if (currentParams != null) {
if (currentParams.pcs && currentParams.pcs.length) {
var n = 0;
for (var i = 0, len = currentParams.pcs.length; i < len; ++i) {
var m;
if (m = html.match(new RegExp("<span><!--si([0-9]+:)*" + currentParams.pcs[i] + '(:[0-9]+)*--><a href="\\?item=(\\d+)">(.+?)</a></span>'))) {
html = html.replace(m[0], '<span class="q8"><!--si' + currentParams.pcs[i] + '--><a href="?item=' + m[3] + '">' + (($WH.isset("g_items") && g_items[currentParams.pcs[i]]) ? g_items[currentParams.pcs[i]]["name_" + LOCALES[currentLocale]] : m[4]) + "</a></span>");
++n;
}
}
if (n > 0) {
html = html.replace("(0/", "(" + n + "/");
html = html.replace(new RegExp("<span>\\(([0-" + n + "])\\)", "g"), '<span class="q2">($1)');
}
}
if (currentParams.c) {
html = html.replace(/<span class="c([0-9]+?)">(.+?)<\/span><br \/>/g, '<span class="c$1" style="display: none">$2</span>');
html = html.replace(new RegExp('<span class="c(' + currentParams.c + ')" style="display: none">(.+?)</span>', "g"), '<span class="c$1">$2</span><br />');
}
if (currentParams.know && currentParams.know.length) {
html = $WH.g_setTooltipSpells(html, currentParams.know, spellData);
}
if (currentParams.lvl) {
html = $WH.g_setTooltipLevel(html, currentParams.lvl, currentParams.buff);
}
// custom start
else if ($WH.gc('compare_level') && window.location.href.match(/\?compare/i)) {
html = $WH.g_setTooltipLevel(html, $WH.gc('compare_level'), currentParams.buff);
}
// custom end
if (currentParams.who && currentParams.when) {
html = html.replace("<table><tr><td><br />", '<table><tr><td><br /><span class="q2">' + $WH.sprintf(_LANG.achievementcomplete, currentParams.who, currentParams.when.getMonth() + 1, currentParams.when.getDate(), currentParams.when.getFullYear()) + "</span><br /><br />");
html = html.replace(/class="q0"/g, 'class="r3"');
}
}
}
if (currentParams.map && map && map.getMap) {
html2 = map.getMap();
}
if (mode == 1) {
$WH.Tooltip.setIcon(null);
$WH.Tooltip.show(currentA, html, null, null, null, html2);
}
else {
$WH.Tooltip.setIcon(icon);
$WH.Tooltip.showAtXY(html, cursorX, cursorY, CURSOR_HSPACE, CURSOR_VSPACE, html2);
}
if (isRemote && $WH.Tooltip.logo) {
$WH.Tooltip.logo.style.display = (showLogo ? "block": "none");
}
}
function showLoading(type, id, locale) {
if (currentType == type && currentId == id && currentLocale == locale) {
showTooltip(_LANG.loading);
var arr = LOOKUPS[type][0];
arr[id].timer = setTimeout(function () {
notFound.apply(this, [type, id, locale]);
}, 3850);
}
}
function notFound(type, id, locale) {
var arr = LOOKUPS[type][0];
arr[id].status[locale] = STATUS_ERROR;
if (currentType == type && currentId == id && currentLocale == locale) {
showTooltip(_LANG.noresponse);
}
}
function getFullId(id, params) {
return id + (params.rand ? "r" + params.rand : "") + (params.ench ? "e" + params.ench : "") + (params.gems ? "g" + params.gems.join(",") : "") + (params.sock ? "s" : "");
}
this.loadScales = function (type, locale) {
var arr = LOOKUPS[type][0];
for (var i in LOCALES) {
if (locale == i || (!locale && !isNaN(i))) {
SCALES[type][i] = SCALES_LOADED;
for (var id in arr) {
if (arr[id].status[i] == STATUS_SCALES && arr[id].response[i]) {
arr[id].response[i]();
}
}
}
}
};
this.register = function (type, id, locale, json) {
var arr = LOOKUPS[type][0];
initElement(type, id, locale);
if (SCALES[type] && SCALES[type][locale] != SCALES_LOADED) {
arr[id].status[locale] = STATUS_SCALES;
arr[id].response[locale] = this.register.bind(this, type, id, locale, json);
return;
}
if (arr[id].timer) {
clearTimeout(arr[id].timer);
arr[id].timer = null;
}
if (!$WH.wowheadRemote && json.map) {
if (arr[id].map == null) {
arr[id].map = new Mapper({
parent: $WH.ce("div"),
zoom: 3,
zoomable: false,
buttons: false
});
}
arr[id].map.update(json.map);
delete json.map;
}
$WH.cO(arr[id], json);
if (arr[id].status[locale] == STATUS_QUERYING || arr[id].status[locale] == STATUS_SCALES) {
if (arr[id][getTooltipField(locale)]) {
arr[id].status[locale] = STATUS_OK;
}
else {
arr[id].status[locale] = STATUS_NOTFOUND;
}
}
if (currentType == type && id == currentId && currentLocale == locale) {
showTooltip(arr[id][getTooltipField(locale)], arr[id].icon, arr[id].map, arr[id][getSpellsField(locale)], arr[id][getTooltipField(locale, 2)]);
}
};
this.registerNpc = function (id, locale, json) {
this.register(TYPE_NPC, id, locale, json);
};
this.registerObject = function (id, locale, json) {
this.register(TYPE_OBJECT, id, locale, json);
};
this.registerItem = function (id, locale, json) {
this.register(TYPE_ITEM, id, locale, json);
};
this.registerQuest = function (id, locale, json) {
this.register(TYPE_QUEST, id, locale, json);
};
this.registerSpell = function (id, locale, json) {
this.register(TYPE_SPELL, id, locale, json);
};
this.registerAchievement = function (id, locale, json) {
this.register(TYPE_ACHIEVEMENT, id, locale, json);
};
this.registerProfile = function (id, locale, json) {
this.register(TYPE_PROFILE, id, locale, json);
};
this.displayTooltip = function (type, id, locale, params) {
display(type, id, locale, params);
};
this.request = function (type, id, locale, params) {
if (!params) {
params = {};
}
var fullId = getFullId(id, params);
initElement(type, fullId, locale);
request(type, id, locale, 1, params);
};
this.requestItem = function (id, params) {
this.request(TYPE_ITEM, id, Locale.id, params);
};
this.requestSpell = function (id) {
this.request(TYPE_SPELL, id, Locale.id);
};
this.getStatus = function (type, id, locale) {
var arr = LOOKUPS[type][0];
if (arr[id] != null) {
return arr[id].status[locale];
}
else {
return STATUS_NONE;
}
};
this.getItemStatus = function (id, locale) {
this.getStatus(TYPE_ITEM, id, locale);
};
this.getSpellStatus = function (id, locale) {
this.getStatus(TYPE_SPELL, id, locale);
};
this.refreshLinks = function () {
if (typeof aowow_tooltips != "undefined") {
for (var i = 0; i < document.links.length; i++) {
var link = document.links[i];
var node = link.parentNode;
var isTooltipChild = false;
while (node != null) {
if ((" " + node.className + " ").replace(/[\n\t]/g, " ").indexOf(" wowhead-tooltip ") > -1) {
isTooltipChild = true;
break;
}
node = node.parentNode
}
if (!isTooltipChild) {
scanElement(link);
}
}
}
this.hideTooltip();
};
this.setParent = function (newParent) {
$WH.Tooltip.reset();
$WH.Tooltip.prepare(newParent);
};
if (isRemote) {
this.set = function (foo) {
$WH.cO(opt, foo);
};
this.showTooltip = function (e, tooltip, icon) {
updateCursorPos(e);
showTooltip(tooltip, icon);
};
this.hideTooltip = function () {
$WH.Tooltip.hide();
};
this.moveTooltip = function (e) {
onMouseMove(e);
}
}
init();
}
};

View File

@@ -0,0 +1,7 @@
var mn_profiles = /*setup:mnProfiles*/;
var mn_guilds = $.extend(true,[],mn_profiles);
var mn_arenateams = $.extend(true,[],mn_profiles);
Menu.fixUrls(mn_profiles,"?profiles=",{useSimpleIdsAfter:1});
Menu.fixUrls(mn_guilds,"?guilds=",{useSimpleIdsAfter:1});
Menu.fixUrls(mn_arenateams,"?arena-teams=",{useSimpleIdsAfter:1});

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<title>CFG_NAME_SHORT</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<base target="_blank" />
<link rel="stylesheet" type="text/css" href="searchbox.css" />
<script type="text/javascript" src="STATIC_URL/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="searchbox.js"></script>
</head>
<body>
<a href="HOST_URL" class="logo"></a>
<form action="HOST_URL" class="search">
<span><a href="#"></a><input type="text" name="search" /></span>
</form>
<div class="expanded">
<div class="links"><a href="HOST_URL/?talent">Talent Calculator</a></div>
<div class="links"><a href="HOST_URL/?profiles">Profiler</a></div>
<div class="links"><a href="HOST_URL/?maps">Maps</a></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,35 @@
(function () {
function create(w, h) {
var body = 'STATIC_URL/widgets/searchbox/searchbox.html';;
var buff = '<iframe src="' + body + '" width="' + w + '" height="' + h + '" frameborder="0" class="aowow-searchbox"';
buff += "></iframe>";
document.write(buff);
}
function init() {
var formats = {
"160x200": { width: 160, height: 200 },
"160x120": { width: 160, height: 120 },
"120x200": { width: 120, height: 200 },
"120x120": { width: 120, height: 120 },
"150x120": { width: 150, height: 120 }
};
var dim;
if (typeof aowow_searchbox_format != "undefined") {
if (formats[aowow_searchbox_format]) {
dim = formats[aowow_searchbox_format];
}
}
if (!dim) {
dim = formats["160x200"];
}
create(dim.width, dim.height);
}
init();
})();

View File

@@ -411,7 +411,7 @@ else
}
foreach ($items as &$list)
while(count($list) < 10)
while (count($list) < 10)
$list[] = 0;
$rId = $id;
@@ -441,7 +441,7 @@ else
if (!$note)
{
foreach($tagsByNamePart as $tag => $strings)
foreach ($tagsByNamePart as $tag => $strings)
{
foreach ($strings as $str)
{

File diff suppressed because one or more lines are too long