- Error handling:

* replaced error-suppressions with proper checks
  * log php errors to db
  * use __callStatic() to access localization and thus handle erronous keys
- Setup:
  * fixed some erronous filenames when generating icons
  * increased alpha threshold for spawn maps (should improve spawn points)
- disentangled DB::Aowow and DB::World. Aowow should now be able to run
  with DB::World being on a different server
- added missing faction transfer pendants (title/quest/faction/..)
- fixed extended costs for specific vendors
This commit is contained in:
Sarjuuk
2015-02-03 01:22:12 +01:00
parent acbe969b8d
commit c7fe84b7e0
59 changed files with 926 additions and 592 deletions

View File

@@ -140,10 +140,10 @@ class CommunityContent
foreach ($comments as $idx => &$c)
{
if ($subj = @$subjCache[$c['type']][$c['typeId']])
if (!empty($subjCache[$c['type']][$c['typeId']]))
{
// apply subject
$c['subject'] = $subj;
$c['subject'] = $subjCache[$c['type']][$c['typeId']];
// format date
$c['date'] = date(Util::$dateFormatInternal, $c['date']);

View File

@@ -95,7 +95,44 @@ foreach ($sets as $k => $v)
}
// handle occuring errors
error_reporting($AoWoWconf && CFG_DEBUG ? (E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED | E_STRICT)) : 0);
$errHandled = false;
set_error_handler(function($errNo, $errStr, $errFile, $errLine) use (&$errHandled) {
$errName = 'unknown error'; // errors not in this list can not be handled by set_error_handler (as per documentation) or are ignored
if ($errNo == E_WARNING) // 0x0002
$errName = 'E_WARNING';
else if ($errNo == E_PARSE) // 0x0004
$errName = 'E_PARSE';
else if ($errNo == E_NOTICE) // 0x0008
$errName = 'E_NOTICE';
else if ($errNo == E_USER_ERROR) // 0x0100
$errName = 'E_USER_ERROR';
else if ($errNo == E_USER_WARNING) // 0x0200
$errName = 'E_USER_WARNING';
else if ($errNo == E_USER_NOTICE) // 0x0400
$errName = 'E_USER_NOTICE';
else if ($errNo == E_RECOVERABLE_ERROR) // 0x1000
$errName = 'E_RECOVERABLE_ERROR';
if (User::isInGroup(U_GROUP_STAFF))
{
if (!$errHandled)
{
Util::addNote(U_GROUP_STAFF, 'one or more php related error occured, while generating this page.');
$errHandled = true;
}
Util::addNote(U_GROUP_STAFF, $errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine);
}
DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()',
AOWOW_REVISION, $errNo, $errFile, $errLine, CLI ? 'CLI' : $_SERVER['QUERY_STRING'], User::$groups, $errStr
);
return !(User::isInGroup(U_GROUP_STAFF) && defined('CFG_DEBUG') && CFG_DEBUG);
}, E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED | E_STRICT));
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || ($AoWoWconf && CFG_FORCE_SSL);
if (defined('CFG_STATIC_HOST')) // points js to images & scripts
@@ -141,8 +178,11 @@ if (!CLI)
}
// parse page-parameters .. sanitize before use!
@list($str, $trash) = explode('&', $_SERVER['QUERY_STRING'], 2);
@list($pageCall, $pageParam) = explode('=', $str, 2);
$str = explode('&', $_SERVER['QUERY_STRING'], 2)[0];
$_ = explode('=', $str, 2);
$pageCall = $_[0];
$pageParam = isset($_[1]) ? $_[1] : null;
Util::$wowheadLink = 'http://'.Util::$subDomains[User::$localeId].'.wowhead.com/'.$str;
}
else if ($AoWoWconf)

View File

@@ -89,7 +89,7 @@ class Loot
if (!$tableName || !$lootId)
return null;
$rows = DB::Aowow()->select('SELECT * FROM ?# WHERE entry = ?d{ AND groupid = ?d}', $tableName, $lootId, $groupId ?: DBSIMPLE_SKIP);
$rows = DB::World()->select('SELECT * FROM ?# WHERE entry = ?d{ AND groupid = ?d}', $tableName, $lootId, $groupId ?: DBSIMPLE_SKIP);
if (!$rows)
return null;
@@ -167,7 +167,10 @@ class Loot
}
else if ($entry['GroupId'] && $entry['Chance'])
{
@$groupChances[$entry['GroupId']] += $entry['Chance'];
if (empty($groupChances[$entry['GroupId']]))
$groupChances[$entry['GroupId']] = 0;
$groupChances[$entry['GroupId']] += $entry['Chance'];
$set['groupChance'] = $entry['Chance'];
}
else // shouldn't have happened
@@ -184,7 +187,7 @@ class Loot
$sum = $groupChances[$k];
if (!$sum)
$sum = 0;
else if ($sum > 100)
else if ($sum >= 100.01)
{
Util::addNote(U_GROUP_EMPLOYEE, 'Loot::getByContainerRecursive: entry '.$lootId.' / group '.$k.' has a total chance of '.number_format($sum, 2).'%. Some items cannot drop!');
$sum = 100;
@@ -298,9 +301,10 @@ class Loot
{
foreach ($fields as $idx => $field)
{
$val = isset($foo[$field]) ? $foo[$field] : 0;
if (!isset($base[$idx]))
$base[$idx] = @$foo[$field];
else if ($base[$idx] != @$foo[$field])
$base[$idx] = $val;
else if ($base[$idx] != $val)
$set |= 1 << $idx;
}
@@ -422,7 +426,7 @@ class Loot
/*
get references containing the item
*/
$newRefs = DB::Aowow()->select(
$newRefs = DB::World()->select(
sprintf($query, 'lt1.item = ?d AND lt1.reference = 0'),
LOOT_REFERENCE, LOOT_REFERENCE,
$this->entry
@@ -431,7 +435,7 @@ class Loot
while ($newRefs)
{
$curRefs = $newRefs;
$newRefs = DB::Aowow()->select(
$newRefs = DB::World()->select(
sprintf($query, 'lt1.reference IN (?a)'),
LOOT_REFERENCE, LOOT_REFERENCE,
array_keys($curRefs)
@@ -445,7 +449,7 @@ class Loot
*/
for ($i = 1; $i < count($this->lootTemplates); $i++)
{
$result = $calcChance(DB::Aowow()->select(
$result = $calcChance(DB::World()->select(
sprintf($query, '{lt1.reference IN (?a) OR }(lt1.reference = 0 AND lt1.item = ?d)'),
$this->lootTemplates[$i], $this->lootTemplates[$i],
$refResults ? array_keys($refResults) : DBSIMPLE_SKIP,

View File

@@ -13,11 +13,9 @@ class AchievementList extends BaseType
public $criteria = [];
protected $queryBase = 'SELECT `a`.*, `ar`.*, `lar`.*, `a`.`id` AS ARRAY_KEY FROM ?_achievement a';
protected $queryBase = 'SELECT `a`.*, `a`.`id` AS ARRAY_KEY FROM ?_achievement a';
protected $queryOpts = array(
'a' => [['ar', 'lar', 'si'], 'o' => 'orderInGroup ASC'],
'ar' => ['j' => ['achievement_reward ar ON ar.entry = a.id', true]],
'lar' => ['j' => ['locales_achievement_reward lar ON lar.entry = a.id', true]],
'a' => [['si'], 'o' => 'orderInGroup ASC'],
'si' => ['j' => ['?_spellicon si ON si.id = a.iconId', true], 's' => ', si.iconString'],
'ac' => ['j' => ['?_achievementcriteria AS `ac` ON `ac`.`refAchievementId` = `a`.`id`', true], 'g' => '`a`.`id`']
);
@@ -30,20 +28,31 @@ class AchievementList extends BaseType
{
parent::__construct($conditions, $miscData);
if ($this->error)
return;
// post processing
foreach ($this->iterate() as &$_curTpl)
$rewards = DB::World()->select('
SELECT ar.entry AS ARRAY_KEY, ar.*, lar.* FROM achievement_reward ar LEFT JOIN locales_achievement_reward lar ON lar.entry = ar.entry WHERE ar.entry IN (?a)',
$this->getFoundIDs()
);
foreach ($this->iterate() as $_id => &$_curTpl)
{
if (!empty($rewards[$_id]))
$_curTpl = array_merge($rewards[$_id], $_curTpl);
//"rewards":[[11,137],[3,138]] [type, typeId]
$_curTpl['rewards'] = [];
if ($_ = $_curTpl['item'])
$_curTpl['rewards'][] = [TYPE_ITEM, $_];
if ($_ = $_curTpl['itemExtra'])
$_curTpl['rewards'][] = [TYPE_ITEM, $_];
if ($_ = $_curTpl['title_A'])
$_curTpl['rewards'][] = [TYPE_TITLE, $_];
if ($_ = $_curTpl['title_H'])
if ($_ != $_curTpl['title_A'])
$_curTpl['rewards'][] = [TYPE_TITLE, $_];
if (!empty($_curTpl['item']))
$_curTpl['rewards'][] = [TYPE_ITEM, $_curTpl['item']];
if (!empty($_curTpl['itemExtra']))
$_curTpl['rewards'][] = [TYPE_ITEM, $_curTpl['itemExtra']];
if (!empty($_curTpl['title_A']))
$_curTpl['rewards'][] = [TYPE_TITLE, $_curTpl['title_A']];
if (!empty($_curTpl['title_H']))
if (empty($_curTpl['title_A']) || $_curTpl['title_A'] != $_curTpl['title_H'])
$_curTpl['rewards'][] = [TYPE_TITLE, $_curTpl['title_H']];
// icon
$_curTpl['iconString'] = $_curTpl['iconString'] ?: 'trade_engineering';
@@ -285,7 +294,7 @@ class AchievementListFilter extends Filter
case 6: // last in series [yn]
return $this->int2Bool($cr[1]) ? ['AND', ['series', 0, '!'], [['series', 0xFFFF, '&'], 0]] : [['series', 0xFFFF, '&'], 0, '!'];
case 11: // Related Event [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if (is_int($_))

View File

@@ -498,7 +498,6 @@ trait listviewHelper
return false;
}
}
/*
@@ -516,11 +515,7 @@ trait spawnHelper
SPAWNINFO_ZONES => null
);
/*
todo (med): map in tooltips is activated by either '#map' as anchor (will automatic open mapviewer, when hovering link) in the href or as parameterless rel-parameter e.g. rel="map" in the anchor
*/
private function createShortSpawns() // [zoneId, floor, [[x1, y1], [x2, y2], ..]] as tooltip2 if enabled by <a rel="map" ...> (one area, one floor, one creature, no survivor)
private function createShortSpawns() // [zoneId, floor, [[x1, y1], [x2, y2], ..]] as tooltip2 if enabled by <a rel="map" ...> or anchor #map (one area, one floor, one creature, no survivors)
{
// first get zone/floor with the most spawns
if ($res = DB::Aowow()->selectRow('SELECT areaId, floor FROM ?_spawns WHERE type = ?d && typeId = ?d GROUP BY areaId, floor ORDER BY count(1) DESC LIMIT 1', self::$type, $this->id))
@@ -547,7 +542,7 @@ trait spawnHelper
foreach ($spawns as $s)
{
// check, if we can attach waypoints to creature
// we will get a nice clusterfuck of dots if we do this for more GUIDs, than we have colors
// we will get a nice clusterfuck of dots if we do this for more GUIDs, than we have colors though
if (count($spawns) < 6 && self::$type == TYPE_NPC)
{
if ($wPoints = DB::Aowow()->select('SELECT * FROM ?_creature_waypoints WHERE creatureOrPath = ?d AND floor = ?d', $s['pathId'] ? -$s['pathId'] : $this->id, $s['floor']))
@@ -566,7 +561,10 @@ trait spawnHelper
$set['lines'] = [[$wPoints[$i - 1]['posX'], $wPoints[$i - 1]['posY']]];
$data[$s['areaId']][$s['floor']]['coords'][] = [$p['posX'], $p['posY'], $set];
@$wpSum[$s['areaId']][$s['floor']]++;
if (empty($wpSum[$s['areaId']][$s['floor']]))
$wpSum[$s['areaId']][$s['floor']] = 1;
else
$wpSum[$s['areaId']][$s['floor']]++;
}
$wpIdx++;
}

View File

@@ -13,13 +13,10 @@ class CreatureList extends BaseType
protected $queryBase = 'SELECT ct.*, ct.id AS ARRAY_KEY FROM ?_creature ct';
public $queryOpts = array(
'ct' => [['ft', 'clsMin', 'clsMax', 'qse']],
'ct' => [['ft', 'qse']],
'ft' => ['j' => '?_factiontemplate ft ON ft.id = ct.faction', 's' => ', ft.A, ft.H, ft.factionId'],
'clsMin' => ['j' => 'creature_classlevelstats clsMin ON ct.unitClass = clsMin.class AND ct.minLevel = clsMin.level', 's' => ', clsMin.attackpower AS mleAtkPwrMin, clsMin.rangedattackpower AS rngAtkPwrMin, clsMin.baseArmor * ct.armorMod AS armorMin, (CASE ct.exp WHEN 0 THEN clsMin.damage_base WHEN 1 THEN clsMin.damage_exp1 ELSE clsMin.damage_exp2 END) AS dmgMin, (CASE ct.exp WHEN 0 THEN clsMin.basehp0 WHEN 1 THEN clsMin.basehp1 ELSE clsMin.basehp2 END) * ct.healthMod AS healthMin, clsMin.baseMana * ct.manaMod AS manaMin'],
'clsMax' => ['j' => 'creature_classlevelstats clsMax ON ct.unitClass = clsMax.class AND ct.maxLevel = clsMax.level', 's' => ', clsMax.attackpower AS mleAtkPwrMax, clsMax.rangedattackpower AS rngAtkPwrMax, clsMax.baseArmor * ct.armorMod AS armorMax, (CASE ct.exp WHEN 0 THEN clsMin.damage_base WHEN 1 THEN clsMin.damage_exp1 ELSE clsMin.damage_exp2 END) AS dmgMax, (CASE ct.exp WHEN 0 THEN clsMax.basehp0 WHEN 1 THEN clsMax.basehp1 ELSE clsMax.basehp2 END) * ct.healthMod AS healthMax, clsMax.baseMana * ct.manaMod AS manaMax'],
'qse' => ['j' => ['?_quests_startend qse ON qse.type = 1 AND qse.typeId = ct.id', true], 's' => ', IF(min(qse.method) = 1 OR max(qse.method) = 3, 1, 0) AS startsQuests, IF(min(qse.method) = 2 OR max(qse.method) = 3, 1, 0) AS endsQuests', 'g' => 'ct.id'],
'qt' => ['j' => '?_quests qt ON qse.questId = qt.id'],
'rep' => ['j' => ['creature_onkill_reputation rep ON rep.creature_id = ct.id', true]],
's' => ['j' => '?_spawns s ON s.type = 1 AND s.typeId = ct.id']
);
@@ -48,19 +45,7 @@ class CreatureList extends BaseType
public static function getName($id)
{
$n = DB::Aowow()->SelectRow('
SELECT
name_loc0,
name_loc2,
name_loc3,
name_loc6,
name_loc8
FROM
?_creature
WHERE
id = ?d',
$id
);
$n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_creature WHERE id = ?d', $id);
return Util::localizedString($n, 'name');
}
@@ -134,6 +119,7 @@ class CreatureList extends BaseType
public function getBaseStats($type)
{
// i'm aware of the BaseVariance/RangedVariance fields ... i'm just totaly unsure about the whole damage calculation
switch ($type)
{
case 'health':
@@ -171,7 +157,7 @@ class CreatureList extends BaseType
/* looks like this data differs per occasion
*
* NPCINFO_TAMEABLE (0x1): include texture & react
* NPCINFO_MODEL (0x2):
* NPCINFO_MODEL (0x2):
*/
$data = [];
@@ -325,20 +311,19 @@ class CreatureListFilter extends Filter
switch ($cr[1])
{
case '=': // min > max is totally possible
$this->extraOpts['clsMin']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) <= '.$cr[2];
$this->extraOpts['clsMax']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) >= '.$cr[2];
$this->extraOpts['ct']['h'][] = 'healthMin = healthMax AND healthMin = '.$cr[2];
break;
case '>':
$this->extraOpts['clsMin']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) > '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) > '.$cr[2];
break;
case '>=':
$this->extraOpts['clsMin']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) >= '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMax, healthMin) >= '.$cr[2];
break;
case '<':
$this->extraOpts['clsMax']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) < '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) < '.$cr[2];
break;
case '<=':
$this->extraOpts['clsMax']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) <= '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(healthMin > healthMax, healthMin, healthMax) <= '.$cr[2];
break;
}
return [1]; // always true, use post-filter
@@ -350,20 +335,19 @@ class CreatureListFilter extends Filter
switch ($cr[1])
{
case '=':
$this->extraOpts['clsMin']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) <= '.$cr[2];
$this->extraOpts['clsMax']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) => '.$cr[2];
$this->extraOpts['ct']['h'][] = 'manaMin = manaMax AND manaMin = '.$cr[2];
break;
case '>':
$this->extraOpts['clsMax']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) > '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) > '.$cr[2];
break;
case '>=':
$this->extraOpts['clsMax']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) >= '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMin, manaMax) >= '.$cr[2];
break;
case '<':
$this->extraOpts['clsMin']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) < '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) < '.$cr[2];
break;
case '<=':
$this->extraOpts['clsMin']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) <= '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF(manaMin > manaMax, manaMax, manaMin) <= '.$cr[2];
break;
}
return [1]; // always true, use post-filter
@@ -419,29 +403,42 @@ class CreatureListFilter extends Filter
if ($cr[1] == FILTER_ENUM_ANY)
{
$cGuids = DB::Aowow()->selectCol('SELECT DISTINCT gec.guid FROM game_event_creature gec JOIN ?_events e ON e.id = ABS(gec.eventEntry) WHERE e.holidayId <> 0');
$eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId <> 0');
$cGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_creature WHERE eventEntry IN (?a)', $eventIds);
return ['s.guid', $cGuids];
}
else if ($cr[1] == FILTER_ENUM_NONE)
{
$cGuids = DB::Aowow()->selectCol('SELECT DISTINCT gec.guid FROM game_event_creature gec JOIN ?_events e ON e.id = ABS(gec.eventEntry) WHERE e.holidayId <> 0');
$eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId <> 0');
$cGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_creature WHERE eventEntry IN (?a)', $eventIds);
return ['s.guid', $cGuids, '!'];
}
else if ($cr[1])
{
$cGuids = DB::Aowow()->selectCol('SELECT DISTINCT gec.guid FROM game_event_creature gec JOIN ?_events e ON e.id = ABS(gec.eventEntry) WHERE e.holidayId = ?d', $cr[1]);
$eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId = ?d', $cr[1]);
$cGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_creature WHERE eventEntry IN (?a)', $eventIds);
return ['s.guid', $cGuids];
}
break;
case 42: // increasesrepwith [enum]
if (in_array($cr[1], $this->enums[3])) // reuse
return ['OR', ['AND', ['rep.RewOnKillRepFaction1', $cr[1]], ['rep.RewOnKillRepValue1', 0, '>']], ['AND', ['rep.RewOnKillRepFaction2', $cr[1]], ['rep.RewOnKillRepValue2', 0, '>']]];
{
if ($cIds = DB::World()->selectCol('SELECT creature_id FROM creature_onkill_reputation WHERE (RewOnKillRepFaction1 = ?d AND RewOnKillRepValue1 > 0) OR (RewOnKillRepFaction2 = ?d AND RewOnKillRepValue2 > 0)', $cr[1], $cr[1]))
return ['id', $cIds];
else
return [0];
}
break;
case 43: // decreasesrepwith [enum]
if (in_array($cr[1], $this->enums[3])) // reuse
return ['OR', ['AND', ['rep.RewOnKillRepFaction1', $cr[1]], ['rep.RewOnKillRepValue1', 0, '<']], ['AND', ['rep.RewOnKillRepFaction2', $cr[1]], ['rep.RewOnKillRepValue2', 0, '<']]];
{
if ($cIds = DB::World()->selectCol('SELECT creature_id FROM creature_onkill_reputation WHERE (RewOnKillRepFaction1 = ?d AND RewOnKillRepValue1 < 0) OR (RewOnKillRepFaction2 = ?d AND RewOnKillRepValue2 < 0)', $cr[1], $cr[1]))
return ['id', $cIds];
else
return [0];
}
break;
case 12: // averagemoneydropped [op] [int]

View File

@@ -36,19 +36,7 @@ class FactionList extends BaseType
public static function getName($id)
{
$n = DB::Aowow()->SelectRow('
SELECT
name_loc0,
name_loc2,
name_loc3,
name_loc6,
name_loc8
FROM
?_factions
WHERE
id = ?d',
$id
);
$n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_factions WHERE id = ?d', $id);
return Util::localizedString($n, 'name');
}

View File

@@ -58,19 +58,7 @@ class GameObjectList extends BaseType
public static function getName($id)
{
$n = DB::Aowow()->SelectRow('
SELECT
name,
name_loc2,
name_loc3,
name_loc6,
name_loc8
FROM
?_objects
WHERE
id = ?d',
$id
);
$n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_objects WHERE id = ?d', $id);
return Util::localizedString($n, 'name');
}
@@ -104,7 +92,7 @@ class GameObjectList extends BaseType
$x = '<table>';
$x .= '<tr><td><b class="q">'.$this->getField('name', true).'</b></td></tr>';
if ($_ = @Lang::$gameObject['type'][$this->curTpl['typeCat']])
if ($_ = Lang::gameObject('type', $this->curTpl['typeCat']))
$x .= '<tr><td>'.$_.'</td></tr>';
if (isset($this->curTpl['lockId']))
@@ -216,23 +204,26 @@ class GameObjectListFilter extends Filter
return [1];
}
break;
case 16; // relatedevent
case 16; // relatedevent (ignore removed by event)
if (!$this->isSaneNumeric($cr[1]))
break;
if ($cr[1] == FILTER_ENUM_ANY)
{
$goGuids = DB::Aowow()->selectCol('SELECT DISTINCT geo.guid FROM game_event_gameobject geo JOIN ?_events e ON e.id = ABS(geo.eventEntry) WHERE e.holidayId <> 0');
$eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId <> 0');
$goGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_gameobject WHERE eventEntry IN (?a)', $eventIds);
return ['s.guid', $goGuids];
}
else if ($cr[1] == FILTER_ENUM_NONE)
{
$goGuids = DB::Aowow()->selectCol('SELECT DISTINCT geo.guid FROM game_event_gameobject geo JOIN ?_events e ON e.id = ABS(geo.eventEntry) WHERE e.holidayId <> 0');
$eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId <> 0');
$goGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_gameobject WHERE eventEntry IN (?a)', $eventIds);
return ['s.guid', $goGuids, '!'];
}
else if ($cr[1])
{
$goGuids = DB::Aowow()->selectCol('SELECT DISTINCT geo.guid FROM game_event_gameobject geo JOIN ?_events e ON e.id = ABS(geo.eventEntry) WHERE e.holidayId = ?d', $cr[1]);
$eventIds = DB::Aowow()->selectCol('SELECT id FROM ?_events WHERE holidayId = ?d', $cr[1]);
$goGuids = DB::World()->selectCol('SELECT DISTINCT guid FROM game_event_gameobject WHERE eventEntry IN (?a)', $eventIds);
return ['s.guid', $goGuids];
}

View File

@@ -25,9 +25,9 @@ class ItemList extends BaseType
protected $queryBase = 'SELECT i.*, `is`.*, i.id AS id, i.id AS ARRAY_KEY FROM ?_items i';
protected $queryOpts = array(
'i' => [['is', 'src'], 'o' => 'i.quality DESC, i.itemLevel DESC'],
'is' => ['j' => ['?_item_stats AS `is` ON `is`.`id` = `i`.`id`', true]],
's' => ['j' => ['?_spell AS `s` ON s.effect1CreateItemId = i.id', true], 'g' => 'i.id'],
'i' => [['is', 'src'], 'o' => 'i.quality DESC, i.itemLevel DESC'],
'src' => ['j' => ['?_source src ON type = 3 AND typeId = i.id', true], 's' => ', moreType, moreTypeId, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15, src16, src17, src18, src19, src20, src21, src22, src23, src24']
);
@@ -73,15 +73,7 @@ class ItemList extends BaseType
// use if you JUST need the name
public static function getName($id)
{
$n = DB::Aowow()->selectRow('
SELECT
name_loc0, name_loc2, name_loc3, name_loc6, name_loc8
FROM
?_items
WHERE
id = ?d',
$id
);
$n = DB::Aowow()->selectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_items WHERE id = ?d', $id);
return Util::localizedString($n, 'name');
}
@@ -91,54 +83,65 @@ class ItemList extends BaseType
{
if (empty($this->vendors))
{
$ids = array_keys($this->templates);
$itemz = DB::Aowow()->select('
SELECT nv.item AS ARRAY_KEY1, nv.entry AS ARRAY_KEY2, 0 AS eventId, nv.maxcount, iec.* FROM npc_vendor nv LEFT JOIN ?_itemextendedcost iec ON nv.extendedCost = iec.id WHERE {nv.entry IN (?a) AND} nv.item IN (?a)
$itemz = DB::World()->select('
SELECT nv.item AS ARRAY_KEY1, nv.entry AS ARRAY_KEY2, 0 AS eventId, nv.maxcount, nv.extendedCost FROM npc_vendor nv WHERE {nv.entry IN (?a) AND} nv.item IN (?a)
UNION
SELECT genv.item AS ARRAY_KEY1, c.id AS ARRAY_KEY2, IFNULL(IF(e.holidayId, e.holidayId, -e.id), 0) AS eventId, genv.maxcount, iec.* FROM game_event_npc_vendor genv JOIN creature c ON c.guid = genv.guid LEFT JOIN ?_events e ON genv.eventEntry = e.id LEFT JOIN ?_itemextendedcost iec ON genv.extendedCost = iec.id {JOIN creature c ON c.guid = genv.guid AND 1= ?d} WHERE {c.id IN (?a) AND} genv.item IN (?a)',
SELECT genv.item AS ARRAY_KEY1, c.id AS ARRAY_KEY2, IFNULL(IF(ge.holiday, ge.holiday, -ge.eventEntry), 0) AS eventId, genv.maxcount, genv.extendedCost FROM game_event_npc_vendor genv LEFT JOIN game_event ge ON genv.eventEntry = ge.eventEntry JOIN creature c ON c.guid = genv.guid WHERE {c.id IN (?a) AND} genv.item IN (?a)',
empty($filter[TYPE_NPC]) || !is_array($filter[TYPE_NPC]) ? DBSIMPLE_SKIP : $filter[TYPE_NPC],
$ids,
empty($filter[TYPE_NPC]) || !is_array($filter[TYPE_NPC]) ? DBSIMPLE_SKIP : 1,
array_keys($this->templates),
empty($filter[TYPE_NPC]) || !is_array($filter[TYPE_NPC]) ? DBSIMPLE_SKIP : $filter[TYPE_NPC],
$ids
array_keys($this->templates)
);
$xCosts = [];
foreach ($itemz as $i => $vendors)
$xCosts = array_merge($xCosts, array_column($vendors, 'extendedCost'));
if ($xCosts)
$xCosts = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_itemextendedcost WHERE id IN (?a)', $xCosts);
$cItems = [];
foreach ($itemz as $k => $vendors)
{
foreach ($vendors as $l => $costs)
foreach ($vendors as $l => $vInfo)
{
$data = array(
'stock' => $costs['maxcount'] ? $costs['maxcount'] : -1,
'event' => $costs['eventId'],
'reqRtg' => $costs['reqPersonalRating']
$costs = [];
if (!empty($xCosts[$vInfo['extendedCost']]))
$costs = $xCosts[$vInfo['extendedCost']];
$data = array(
'stock' => $vInfo['maxcount'] ?: -1,
'event' => $vInfo['eventId'],
'reqRtg' => $costs ? $costs['reqPersonalRating'] : 0
);
if ($_ = $this->getField('buyPrice')) // somewhat nonsense.. is identical for all vendors (obviously)
$data[0] = $_;
// hardcode arena(103) & honor(104)
if ($_ = @$costs['reqArenaPoints'])
if (!empty($costs['reqArenaPoints']))
{
$data[-103] = $_;
$data[-103] = $costs['reqArenaPoints'];
$this->jsGlobals[TYPE_CURRENCY][103] = 103;
}
if ($_ = @$costs['reqHonorPoints'])
if (!empty($costs['reqHonorPoints']))
{
$data[-104] = $_;
$data[-104] = $costs['reqHonorPoints'];
$this->jsGlobals[TYPE_CURRENCY][104] = 104;
}
for ($i = 1; $i < 6; $i++)
{
if (($_ = @$costs['reqItemId'.$i]) && $costs['itemCount'.$i] > 0)
if (!empty($costs['reqItemId'.$i]) && $costs['itemCount'.$i] > 0)
{
$data[$_] = $costs['itemCount'.$i];
$cItems[] = $_;
$data[$costs['reqItemId'.$i]] = $costs['itemCount'.$i];
$cItems[] = $costs['reqItemId'.$i];
}
}
// no extended cost or additional gold required
if (!$costs || $this->getField('flagsExtra') & 0x04)
if ($_ = $this->getField('buyPrice'))
$data[0] = $_;
$vendors[$l] = $data;
}
@@ -189,8 +192,8 @@ class ItemList extends BaseType
$result = $this->vendors;
// apply filter if given
$tok = @$filter[TYPE_ITEM];
$cur = @$filter[TYPE_CURRENCY];
$tok = !empty($filter[TYPE_ITEM]) ? $filter[TYPE_ITEM] : null;
$cur = !empty($filter[TYPE_CURRENCY]) ? $filter[TYPE_CURRENCY] : null;
foreach ($result as $itemId => &$data)
{
@@ -289,10 +292,12 @@ class ItemList extends BaseType
{
// just use the first results
// todo (med): dont use first result; search for the right one
if ($cost = @reset($this->getExtendedCost($miscData)[$this->id]))
if (!empty($this->getExtendedCost($miscData)[$this->id]))
{
$cost = reset($this->getExtendedCost($miscData)[$this->id]);
$currency = [];
$tokens = [];
foreach ($cost as $k => $qty)
{
if (is_string($k))
@@ -306,7 +311,7 @@ class ItemList extends BaseType
$data[$this->id]['stock'] = $cost['stock']; // display as column in lv
$data[$this->id]['avail'] = $cost['stock']; // display as number on icon
$data[$this->id]['cost'] = [$this->getField('buyPrice')];
$data[$this->id]['cost'] = [empty($cost[0]) ? 0 : $cost[0]];
if ($cost['event'])
{
@@ -320,8 +325,8 @@ class ItemList extends BaseType
if ($tokens)
$data[$this->id]['cost'][] = $tokens;
if ($_ = @$this->getExtendedCost($miscData)[$this->id]['reqRating'])
$data[$this->id]['reqarenartng'] = $_;
if (!empty($cost['reqRating']))
$data[$this->id]['reqarenartng'] = $cost['reqRating'];
}
if ($x = $this->curTpl['buyPrice'])
@@ -799,7 +804,7 @@ class ItemList extends BaseType
$x .= sprintf(Lang::$game['reqLevel'], $_reqLvl).'<br />';
// required arena team rating / personal rating / todo (low): sort out what kind of rating
if (@$this->getExtendedCost([], $reqRating)[$this->id] && $reqRating)
if (!empty($this->getExtendedCost([], $reqRating)[$this->id]) && $reqRating)
$x .= sprintf(Lang::$item['reqRating'], $reqRating).'<br />';
// item level
@@ -1140,11 +1145,18 @@ class ItemList extends BaseType
$this->itemMods[$this->id] = [];
foreach (Util::$itemMods as $mod)
{
if (isset($this->curTpl[$mod]) && ($_ = floatVal($this->curTpl[$mod])))
@$this->itemMods[$this->id][$mod] += $_;
{
if (!isset($this->itemMods[$this->id][$mod]))
$this->itemMods[$this->id][$mod] = 0;
$this->itemMods[$this->id][$mod] += $_;
}
}
// fetch and add socketbonusstats
if (@$this->json[$this->id]['socketbonus'] > 0)
if (!empty($this->json[$this->id]['socketbonus']))
$enchantments[$this->json[$this->id]['socketbonus']][] = $this->id;
// Item is a gem (don't mix with sockets)
@@ -1163,9 +1175,8 @@ class ItemList extends BaseType
{
if ($item > 0) // apply socketBonus
$this->json[$item]['socketbonusstat'] = $stats;
else /* if ($item < 0) */
foreach ($stats as $mod => $qty) // apply gemEnchantment
@$this->json[-$item][$mod] += $qty;
else /* if ($item < 0) */ // apply gemEnchantment
Util::arraySumByKey($this->json[-$item][$mod], $stats);
}
}
}
@@ -1199,8 +1210,7 @@ class ItemList extends BaseType
{
$eqpSplList = new SpellList(array(['s.id', $useSpells]));
foreach ($eqpSplList->getStatGain() as $stat)
foreach ($stat as $mId => $qty)
@$onUseStats[$mId] += $qty;
Util::arraySumByKey($onUseStats, $stat);
}
return $onUseStats;
@@ -1353,19 +1363,45 @@ class ItemList extends BaseType
if (!array_keys($this->templates))
return;
$ire = DB::Aowow()->select('
SELECT i.id AS ARRAY_KEY_1, ire.id AS ARRAY_KEY_2, iet.chance, ire.*
FROM ?_items i
JOIN item_enchantment_template iet ON iet.entry = ABS(i.randomenchant)
JOIN ?_itemrandomenchant ire ON IF(i.randomenchant > 0, ire.id = iet.ench, ire.id = -iet.ench)
WHERE i.id IN (?a)',
array_keys($this->templates)
$subItemIds = [];
foreach ($this->iterate() as $__)
if ($_ = $this->getField('randomEnchant'))
$subItemIds[abs($_)] = $_;
if (!$subItemIds)
return;
// remember: id < 0: randomSuffix; id > 0: randomProperty
$subItemTpls = DB::World()->select('
SELECT CAST( entry as SIGNED) AS ARRAY_KEY, CAST( ench as SIGNED) AS ARRAY_KEY2, chance FROM item_enchantment_template WHERE entry IN (?a) UNION
SELECT CAST(-entry as SIGNED) AS ARRAY_KEY, CAST(-ench as SIGNED) AS ARRAY_KEY2, chance FROM item_enchantment_template WHERE entry IN (?a)',
array_keys(array_filter($subItemIds, function ($v) { return $v > 0; })) ?: [0],
array_keys(array_filter($subItemIds, function ($v) { return $v < 0; })) ?: [0]
);
foreach ($ire as $mstItem => $subItem)
$randIds = [];
foreach ($subItemTpls as $tpl)
$randIds = array_merge($randIds, array_keys($tpl));
if (!$randIds)
return;
$randEnchants = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_itemrandomenchant WHERE id IN (?a)', $randIds);
foreach ($this->iterate() as $mstItem => $__)
{
foreach ($subItem as $subId => $data)
if (!$this->getField('randomEnchant'))
continue;
if (empty($subItemTpls[$this->getField('randomEnchant')]))
continue;
foreach ($subItemTpls[$this->getField('randomEnchant')] as $subId => $data)
{
if (empty($randEnchants[$subId]))
continue;
$data = array_merge($randEnchants[$subId], $data);
$jsonEquip = [];
$jsonText = [];
$enchIds = [];
@@ -1419,7 +1455,8 @@ class ItemList extends BaseType
);
}
$this->json[$mstItem]['subitems'] = $this->subItems[$mstItem];
if (!empty($this->subItems[$mstItem]))
$this->json[$mstItem]['subitems'] = $this->subItems[$mstItem];
}
}
@@ -1508,8 +1545,8 @@ class ItemList extends BaseType
class ItemListFilter extends Filter
{
private $ubFilter = []; // usable-by - limit weapon/armor selection per CharClass - itemClass => available itemsubclasses
private $extCostQuery = 'SELECT item FROM npc_vendor nv JOIN ?_itemextendedcost iec ON iec.id = nv.extendedCost WHERE %s UNION
SELECT item FROM game_event_npc_vendor genv JOIN ?_itemextendedcost iec ON iec.id = genv.extendedCost WHERE %1$s';
private $extCostQuery = 'SELECT item FROM npc_vendor WHERE extendedCost IN (?a) UNION
SELECT item FROM game_event_npc_vendor WHERE extendedCost IN (?a)';
private $otFields = [18 => 4, 68 => 15, 69 => 16, 70 => 17, 72 => 2, 73 => 19, 75 => 21, 76 => 23, 88 => 20, 92 => 5, 93 => 3, 143 => 18, 171 => 8, 172 => 12];
public $extraOpts = []; // score for statWeights
@@ -1715,8 +1752,8 @@ class ItemListFilter extends Filter
foreach ($data['wt'] as $k => $v)
{
@$str = Util::$itemFilter[$v];
$qty = intVal($data['wtv'][$k]);
$str = isset(Util::$itemFilter[$v]) ? Util::$itemFilter[$v] : null;
$qty = intVal($data['wtv'][$k]);
if ($str && $qty)
{
@@ -1828,7 +1865,7 @@ class ItemListFilter extends Filter
break;
case 107: // effecttext [str] not yet parsed ['effectsParsed_loc'.User::$localeId, $cr[2]]
/* todo */ return [1];
case 132: // glyphtype [enum] susubclass not yet set
case 132: // glyphtype [enum]
switch ($cr[1])
{
case 1: // Major
@@ -1837,12 +1874,14 @@ class ItemListFilter extends Filter
}
break;
case 124: // randomenchants [str]
// joining this in one step results in hell .. so .. two steps
// todo (low): in _theory_ Filter::modularizeString() should also be applied here
$randIds = DB::Aowow()->selectCol('SELECT IF (ire.id > 0, iet.entry, -iet.entry) FROM item_enchantment_template iet JOIN ?_itemrandomenchant ire ON ABS(ire.id) = iet.ench WHERE ire.name_loc'.User::$localeId.' LIKE ?', '%'.$cr[2].'%');
$randIds = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, ABS(id) FROM ?_itemrandomenchant WHERE name_loc?d LIKE ?', User::$localeId, '%'.$cr[2].'%');
$tplIds = $randIds ? DB::World()->select('SELECT entry, ench FROM item_enchantment_template WHERE ench IN (?a)', $randIds) : [];
foreach ($tplIds as $k => &$set)
if (array_search($set['ench'], $randIds) < 0)
$set['entry'] *= -1;
if ($randIds)
return ['randomEnchant', $randIds];
if ($tplIds)
return ['randomEnchant', array_column($tplIds, 'entry')];
else
return [0]; // no results aren't really input errors
case 125: // reqarenartng [op] [int] todo (low): find out, why "IN (W, X, Y) AND IN (X, Y, Z)" doesn't result in "(X, Y)"
@@ -1850,12 +1889,13 @@ class ItemListFilter extends Filter
break;
$this->formData['extraCols'][] = $cr[0];
$query = sprintf($this->extCostQuery, 'iec.reqPersonalrating '.$cr[1].' '.$cr[2]);
return ['id', DB::Aowow()->selectCol($query)];
$costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqPersonalrating '.$cr[1].' '.$cr[2]);
$items = DB::World()->selectCol($this->extCostQuery, $costs, $costs);
return ['id', $items];
case 160: // relatedevent [enum] like 169 .. crawl though npc_vendor and loot_templates of event-related spawns
/* todo */ return [1];
case 152: // classspecific [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if (is_bool($_))
@@ -1865,7 +1905,7 @@ class ItemListFilter extends Filter
}
break;
case 153: // racespecific [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if (is_bool($_))
@@ -1886,7 +1926,7 @@ class ItemListFilter extends Filter
$this->formData['extraCols'][] = $cr[0];
return ['AND', ['armordamagemodifier', $cr[2], $cr[1]], ['class', ITEM_CLASS_ARMOR]];
case 86: // craftedprof [enum]
$_ = @$this->enums[99][$cr[1]]; // recycled enum
$_ = isset($this->enums[99][$cr[1]]) ? $this->enums[99][$cr[1]] : null;
if (is_bool($_))
return ['src.src1', null, $_ ? '!' : null];
else if (is_int($_))
@@ -1959,32 +1999,35 @@ class ItemListFilter extends Filter
else
break;
$query = sprintf($this->extCostQuery, 'iec.reqItemId1 IN (?a) OR iec.reqItemId2 IN (?a) OR iec.reqItemId3 IN (?a) OR iec.reqItemId4 IN (?a) OR iec.reqItemId5 IN (?a)');
if ($foo = DB::Aowow()->selectCol($query, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_))
return ['id', $foo];
$costs = DB::Aowow()->selectCol(
'SELECT id FROM ?_itemextendedcost WHERE reqItemId1 IN (?a) OR reqItemId2 IN (?a) OR reqItemId3 IN (?a) OR reqItemId4 IN (?a) OR reqItemId5 IN (?a)',
$_, $_, $_, $_, $_
);
if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs))
return ['id', $items];
break;
case 144: // purchasablewithhonor [yn]
if ($this->int2Bool($cr[1]))
{
$query = sprintf($this->extCostQuery, 'iec.reqHonorPoints > 0');
if ($foo = DB::Aowow()->selectCol($query))
return ['id', $foo, $cr[1] ? null : '!'];
$costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqHonorPoints > 0');
if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs))
return ['id', $items, $cr[1] ? null : '!'];
}
break;
case 145: // purchasablewitharena [yn]
if ($this->int2Bool($cr[1]))
{
$query = sprintf($this->extCostQuery, 'iec.reqArenaPoints > 0');
if ($foo = DB::Aowow()->selectCol($query))
return ['id', $foo, $cr[1] ? null : '!'];
$costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqArenaPoints > 0');
if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs))
return ['id', $items, $cr[1] ? null : '!'];
}
break;
case 129: // soldbynpc [str-small]
if (!$this->isSaneNumeric($cr[2], true))
break;
if ($iIds = DB::Aowow()->selectCol('SELECT item FROM npc_vendor WHERE entry = ?d UNION SELECT item FROM game_event_npc_vendor v JOIN creature c ON c.guid = v.guid WHERE c.id = ?d', $cr[2], $cr[2]))
if ($iIds = DB::World()->selectCol('SELECT item FROM npc_vendor WHERE entry = ?d UNION SELECT item FROM game_event_npc_vendor v JOIN creature c ON c.guid = v.guid WHERE c.id = ?d', $cr[2], $cr[2]))
return ['i.id', $iIds];
else
return [0];
@@ -2023,7 +2066,7 @@ class ItemListFilter extends Filter
case 85: // objectivequest [side]
/* todo */ return [1];
case 87: // reagentforability [enum]
$_ = @$this->enums[99][$cr[1]]; // recycled enum
$_ = isset($this->enums[99][$cr[1]]) ? $this->enums[99][$cr[1]] : null;
if ($_ !== null)
{
$ids = [];
@@ -2063,7 +2106,7 @@ class ItemListFilter extends Filter
}
break;
case 128: // source [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if (is_int($_)) // specific

View File

@@ -166,7 +166,7 @@ class ProfileList extends BaseType
private function getTalentDistribution()
{
if (!empty($this->tDistribution))
$this->tDistribution[$this->curTpl['classId']] = DB::Aowow()->selectCol('SELECT COUNT(t.id) FROM dbc.talent t JOIN dbc.talenttab tt ON t.tabId = tt.id WHERE tt.classMask & ?d GROUP BY tt.id ORDER BY tt.tabNumber ASC', 1 << ($this->curTpl['classId'] - 1));
$this->tDistribution[$this->curTpl['classId']] = DB::Aowow()->selectCol('SELECT COUNT(t.id) FROM dbc_talent t JOIN dbc_talenttab tt ON t.tabId = tt.id WHERE tt.classMask & ?d GROUP BY tt.id ORDER BY tt.tabNumber ASC', 1 << ($this->curTpl['classId'] - 1));
$result = [];
$start = 0;

View File

@@ -368,8 +368,11 @@ class QuestList extends BaseType
$data[TYPE_TITLE][$this->curTpl['rewardTitleId']] = $this->curTpl['rewardTitleId'];
// currencies
if ($_ = @$this->rewards[$this->id][TYPE_CURRENCY])
if (!empty($this->rewards[$this->id][TYPE_CURRENCY]))
{
$_ = $this->rewards[$this->id][TYPE_CURRENCY];
$data[TYPE_CURRENCY] = array_combine(array_keys($_), array_keys($_));
}
}
if ($addMask & GLOBALINFO_SELF)
@@ -509,7 +512,7 @@ class QuestListFilter extends Filter
break;
case 37: // classspecific [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if ($_ === true)
@@ -521,7 +524,7 @@ class QuestListFilter extends Filter
}
break;
case 38: // racespecific [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if ($_ === true)

View File

@@ -32,19 +32,7 @@ class SkillList extends BaseType
public static function getName($id)
{
$n = DB::Aowow()->SelectRow('
SELECT
name_loc0,
name_loc2,
name_loc3,
name_loc6,
name_loc8
FROM
?_skillline
WHERE
id = ?d',
$id
);
$n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_skillline WHERE id = ?d', $id);
return Util::localizedString($n, 'name');
}

View File

@@ -125,13 +125,13 @@ class SpellList extends BaseType
}
if ($foo)
$this->relItems = new ItemList(array(['i.id', array_unique($foo)], 0));
$this->relItems = new ItemList(array(['i.id', array_unique($foo)], CFG_SQL_LIMIT_NONE));
}
// use if you JUST need the name
public static function getName($id)
{
$n = DB::Aowow()->SelectRow('SELECT * FROM ?_spell WHERE id = ?d', $id );
$n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_spell WHERE id = ?d', $id );
return Util::localizedString($n, 'name');
}
// end static use
@@ -167,10 +167,10 @@ class SpellList extends BaseType
if ($mv < 0) // all stats
{
for ($j = 0; $j < 5; $j++)
@$stats[ITEM_MOD_AGILITY + $j] += $pts;
Util::arraySumByKey($stats, [(ITEM_MOD_AGILITY + $j) => $pts]);
}
else // one stat
@$stats[ITEM_MOD_AGILITY + $mv] += $pts;
Util::arraySumByKey($stats, [(ITEM_MOD_AGILITY + $mv) => $pts]);
break;
}
@@ -178,7 +178,7 @@ class SpellList extends BaseType
case 230:
case 250:
{
@$stats[ITEM_MOD_HEALTH] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_HEALTH => $pts]);
break;
}
case 13: // damage splpwr + physical (dmg & any)
@@ -186,80 +186,80 @@ class SpellList extends BaseType
// + weapon damage
if ($mv == (1 << SPELL_SCHOOL_NORMAL))
{
@$stats[ITEM_MOD_WEAPON_DMG] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_WEAPON_DMG => $pts]);
break;
}
// full magic mask, also counts towards healing
if ($mv == 0x7E)
{
@$stats[ITEM_MOD_SPELL_POWER] += $pts;
@$stats[ITEM_MOD_SPELL_DAMAGE_DONE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_SPELL_POWER => $pts]);
Util::arraySumByKey($stats, [ITEM_MOD_SPELL_DAMAGE_DONE => $pts]);
}
else
{
// HolySpellpower (deprecated; still used in randomproperties)
if ($mv & (1 << SPELL_SCHOOL_HOLY))
@$stats[ITEM_MOD_HOLY_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_HOLY_POWER => $pts]);
// FireSpellpower (deprecated; still used in randomproperties)
if ($mv & (1 << SPELL_SCHOOL_FIRE))
@$stats[ITEM_MOD_FIRE_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_FIRE_POWER => $pts]);
// NatureSpellpower (deprecated; still used in randomproperties)
if ($mv & (1 << SPELL_SCHOOL_NATURE))
@$stats[ITEM_MOD_NATURE_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_NATURE_POWER => $pts]);
// FrostSpellpower (deprecated; still used in randomproperties)
if ($mv & (1 << SPELL_SCHOOL_FROST))
@$stats[ITEM_MOD_FROST_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_FROST_POWER => $pts]);
// ShadowSpellpower (deprecated; still used in randomproperties)
if ($mv & (1 << SPELL_SCHOOL_SHADOW))
@$stats[ITEM_MOD_SHADOW_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_SHADOW_POWER => $pts]);
// ArcaneSpellpower (deprecated; still used in randomproperties)
if ($mv & (1 << SPELL_SCHOOL_ARCANE))
@$stats[ITEM_MOD_ARCANE_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_ARCANE_POWER => $pts]);
}
break;
}
case 135: // healing splpwr (healing & any) .. not as a mask..
{
@$stats[ITEM_MOD_SPELL_HEALING_DONE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_SPELL_HEALING_DONE => $pts]);
break;
}
case 35: // ModPower - MiscVal:type see defined Powers only energy/mana in use
{
if ($mv == POWER_HEALTH)
@$stats[ITEM_MOD_HEALTH] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_HEALTH => $pts]);
if ($mv == POWER_ENERGY)
@$stats[ITEM_MOD_ENERGY] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_ENERGY => $pts]);
else if ($mv == POWER_MANA)
@$stats[ITEM_MOD_MANA] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_MANA => $pts]);
else if ($mv == POWER_RUNIC_POWER)
@$stats[ITEM_MOD_RUNIC_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_RUNIC_POWER => $pts]);
break;
}
case 189: // CombatRating MiscVal:ratingMask
case 220:
if ($mod = Util::itemModByRatingMask($mv))
@$stats[$mod] += $pts;
Util::arraySumByKey($stats, [$mod => $pts]);
break;
case 143: // Resistance MiscVal:school
case 83:
case 22:
if ($mv == 1) // Armor only if explicitly specified
{
@$stats[ITEM_MOD_ARMOR] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_ARMOR => $pts]);
break;
}
if ($mv == 2) // holy-resistance ONLY if explicitly specified (shouldn't even exist...)
{
@$stats[ITEM_MOD_HOLY_RESISTANCE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_HOLY_RESISTANCE => $pts]);
break;
}
@@ -271,19 +271,19 @@ class SpellList extends BaseType
switch ($j)
{
case 2:
@$stats[ITEM_MOD_FIRE_RESISTANCE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_FIRE_RESISTANCE => $pts]);
break;
case 3:
@$stats[ITEM_MOD_NATURE_RESISTANCE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_NATURE_RESISTANCE => $pts]);
break;
case 4:
@$stats[ITEM_MOD_FROST_RESISTANCE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_FROST_RESISTANCE => $pts]);
break;
case 5:
@$stats[ITEM_MOD_SHADOW_RESISTANCE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_SHADOW_RESISTANCE => $pts]);
break;
case 6:
@$stats[ITEM_MOD_ARCANE_RESISTANCE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_ARCANE_RESISTANCE => $pts]);
break;
}
}
@@ -291,22 +291,22 @@ class SpellList extends BaseType
case 8: // hp5
case 84:
case 161:
@$stats[ITEM_MOD_HEALTH_REGEN] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_HEALTH_REGEN => $pts]);
break;
case 85: // mp5
@$stats[ITEM_MOD_MANA_REGENERATION] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_MANA_REGENERATION => $pts]);
break;
case 99: // atkpwr
@$stats[ITEM_MOD_ATTACK_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_ATTACK_POWER => $pts]);
break; // ?carries over to rngatkpwr?
case 124: // rngatkpwr
@$stats[ITEM_MOD_RANGED_ATTACK_POWER] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_RANGED_ATTACK_POWER => $pts]);
break;
case 158: // blockvalue
@$stats[ITEM_MOD_BLOCK_VALUE] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_BLOCK_VALUE => $pts]);
break;
case 240: // ModExpertise
@$stats[ITEM_MOD_EXPERTISE_RATING] += $pts;
Util::arraySumByKey($stats, [ITEM_MOD_EXPERTISE_RATING => $pts]);
break;
}
}
@@ -490,7 +490,10 @@ class SpellList extends BaseType
}
}
return $targetId ? @$results[$targetId] : $results;
if ($targetId)
return !empty($results[$targetId]) ? $results[$targetId] : 0;
return $results;
}
private function createRangesForCurrent()
@@ -679,7 +682,10 @@ class SpellList extends BaseType
private function resolveEvaluation($formula)
{
// see Traits in javascript locales
$pl = $PL = $this->charLevel;
// if (character level is set manually (profiler only))
// $pl = $PL = $this->charLevel;
$PlayerName = Lang::$main['name'];
$ap = $AP = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.atkpwr[0]', Lang::$spell['traitShort']['atkpwr']) : Lang::$spell['traitShort']['atkpwr'];
$rap = $RAP = $this->interactive ? sprintf(Util::$dfnString, 'LANG.traits.rgdatkpwr[0]', Lang::$spell['traitShort']['rgdatkpwr']) : Lang::$spell['traitShort']['rgdatkpwr'];
@@ -715,7 +721,7 @@ class SpellList extends BaseType
foreach ($vars[0] as $var) // oh lord, forgive me this sin .. but is_callable seems to bug out and function_exists doesn't find lambda-functions >.<
{
$eval = eval('return '.$var.';');
$eval = eval('return @'.$var.';'); // attention: error suppression active here
if (getType($eval) == 'object')
continue;
else if (is_numeric($eval))
@@ -1085,7 +1091,7 @@ class SpellList extends BaseType
$formCurPos++;
}
if (@$formula[++$formCurPos] == '.')
if (isset($formula[++$formCurPos]) && $formula[$formCurPos] == '.')
{
$formPrecision = (int)$formula[++$formCurPos];
++$formCurPos; // for some odd reason the precision decimal survives if wo dont increment further..
@@ -1743,11 +1749,11 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.]
if ($addInfoMask & ITEMINFO_MODEL)
{
if ($mi = @$modelInfo[$this->id])
if (!empty($modelInfo[$this->id]))
{
$data[$this->id]['npcId'] = $mi['typeId'];
$data[$this->id]['displayId'] = $mi['displayId'];
$data[$this->id]['displayName'] = $mi['displayName'];
$data[$this->id]['npcId'] = $modelInfo[$this->id]['typeId'];
$data[$this->id]['displayId'] = $modelInfo[$this->id]['displayId'];
$data[$this->id]['displayName'] = $modelInfo[$this->id]['displayName'];
}
}
}
@@ -1801,9 +1807,9 @@ spells / buffspells = {
$extra[$id] = array(
'id' => $id,
'tooltip' => $tTip[0],
'buff' => @$buff[0],
'buff' => !empty($buff[0]) ? $buff[0] : null,
'spells' => $tTip[1],
'buffspells' => @$buff[1]
'buffspells' => !empty($buff[1]) ? $buff[1] : null
);
}
}
@@ -1964,7 +1970,7 @@ class SpellListFilter extends Filter
return ['OR', ['AND', ['powerType', [1, 6]], ['powerCost', (10 * $cr[2]), $cr[1]]], ['AND', ['powerType', [1, 6], '!'], ['powerCost', $cr[2], $cr[1]]]];
case 9: // source [enum]
$_ = @$this->enums[$cr[0]][$cr[1]];
$_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null;
if ($_ !== null)
{
if (is_int($_)) // specific

View File

@@ -14,15 +14,7 @@ class ZoneList extends BaseType
// use if you JUST need the name
public static function getName($id)
{
$n = DB::Aowow()->selectRow('
SELECT
name_loc0, name_loc2, name_loc3, name_loc6, name_loc8
FROM
?_zones
WHERE
id = ?d',
$id
);
$n = DB::Aowow()->selectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_zones WHERE id = ?d', $id );
return Util::localizedString($n, 'name');
}

View File

@@ -711,7 +711,7 @@ class Util
$notes = [];
foreach (self::$notes as $data)
if (!$restricted || ($data[0] && User::isInGroup($data[0])))
if (!$restricted || !$data[0] || User::isInGroup($data[0]))
$notes[] = $data[1];
return $notes;
@@ -1164,49 +1164,57 @@ class Util
switch ($e['type'.$h])
{
case 2:
@$jsonStats[ITEM_MOD_WEAPON_DMG] += $val;
$obj = ITEM_MOD_WEAPON_DMG;
break;
case 3:
case 7:
$spl = new SpellList(array(['s.id', $obj]));
$spl = new SpellList(array(['s.id', $obj]));
if ($spl->error)
break;
$gains = $spl->getStatGain();
foreach ($gains as $gain)
foreach ($gain as $k => $v) // array_merge screws up somehow...
@$jsonStats[$k] += $v;
Util::arraySumByKey($jsonStats, $spl->getStatGain()[$obj]);
$obj = null;
break;
case 4:
switch ($obj)
{
case 0: // Physical
@$jsonStats[ITEM_MOD_ARMOR] += $val;
case 0: // Physical
$obj = ITEM_MOD_ARMOR;
break;
case 1: // Holy
@$jsonStats[ITEM_MOD_HOLY_RESISTANCE] += $val;
case 1: // Holy
$obj = ITEM_MOD_HOLY_RESISTANCE;
break;
case 2: // Fire
@$jsonStats[ITEM_MOD_FIRE_RESISTANCE] += $val;
case 2: // Fire
$obj = ITEM_MOD_FIRE_RESISTANCE;
break;
case 3: // Nature
@$jsonStats[ITEM_MOD_NATURE_RESISTANCE] += $val;
case 3: // Nature
$obj = ITEM_MOD_NATURE_RESISTANCE;
break;
case 4: // Frost
@$jsonStats[ITEM_MOD_FROST_RESISTANCE] += $val;
case 4: // Frost
$obj = ITEM_MOD_FROST_RESISTANCE;
break;
case 5: // Shadow
@$jsonStats[ITEM_MOD_SHADOW_RESISTANCE] += $val;
case 5: // Shadow
$obj = ITEM_MOD_SHADOW_RESISTANCE;
break;
case 6: // Arcane
@$jsonStats[ITEM_MOD_ARCANE_RESISTANCE] += $val;
case 6: // Arcane
$obj = ITEM_MOD_ARCANE_RESISTANCE;
break;
default:
$obj = null;
}
break;
case 5:
@$jsonStats[$obj] += $val;
break;
default: // skip assignment below
$obj = null;
}
if ($obj)
{
if (!isset($jsonStats[$obj]))
$jsonStats[$obj] = 0;
$jsonStats[$obj] += $val;
}
}
@@ -1321,8 +1329,8 @@ class Util
// note: omits required spell and chance in skill_discovery_template
$data = array_merge(
DB::Aowow()->selectCol('SELECT spellId FROM spell_learn_spell WHERE entry IN (?a)', $lookup),
DB::Aowow()->selectCol('SELECT spellId FROM skill_discovery_template WHERE reqSpell IN (?a)', $lookup),
DB::World()->selectCol('SELECT spellId FROM spell_learn_spell WHERE entry IN (?a)', $lookup),
DB::World()->selectCol('SELECT spellId FROM skill_discovery_template WHERE reqSpell IN (?a)', $lookup),
$extraIds
);
@@ -1570,8 +1578,8 @@ class Util
if (empty(self::$alphaMapCache[$areaId]))
self::$alphaMapCache[$areaId] = imagecreatefrompng($file);
// alphaMaps are 1000 x 1000, adapt points [0 => black => valid point]
if (imagecolorat(self::$alphaMapCache[$areaId], $set['posX'] * 10, $set['posY'] * 10))
// alphaMaps are 1000 x 1000, adapt points [black => valid point]
if (!imagecolorat(self::$alphaMapCache[$areaId], $set['posX'] * 10, $set['posY'] * 10))
$set = null;
return true;
@@ -1585,7 +1593,7 @@ class Util
$result = [];
$jsGlobals = [];
$conditions = DB::Aowow()->select(
$conditions = DB::World()->select(
'SELECT SourceTypeOrReferenceId, SourceEntry, SourceGroup, ElseGroup,
ConditionTypeOrReference, ConditionTarget, ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition
FROM conditions