Types/Filters

* followup on 748a78c3c7
 * fix return type of criteria filter callbacks (mostly in case of faulty input)
 * spread the criteria var into criteria filter callbacks
 * some magic numbers to constants and type declarations for params/return types
This commit is contained in:
Sarjuuk
2025-03-12 00:12:06 +01:00
parent 9345309c07
commit b2d3bc1076
12 changed files with 454 additions and 473 deletions

View File

@@ -1521,9 +1521,9 @@ abstract class Filter
{
if (is_bool($value))
return [$field, 0, ($value ? '>' : '<=')];
else if ($value == self::ENUM_ANY) // any
else if ($value == self::ENUM_ANY)
return [$field, 0, '!'];
else if ($value == self::ENUM_NONE) // none
else if ($value == self::ENUM_NONE)
return [$field, 0];
else if ($value !== null)
return [$field, $value];
@@ -1563,7 +1563,7 @@ abstract class Filter
$result = $this->genericEnum($colOrFn, $crs);
break;
case self::CR_CALLBACK:
$result = $this->{$colOrFn}([$cr, $crs, $crv], $param1, $param2);
$result = $this->{$colOrFn}($cr, $crs, $crv, $param1, $param2);
break;
case self::CR_NYI_PH: // do not limit with not implemented filters
if (is_int($param1))

View File

@@ -379,30 +379,30 @@ class AchievementListFilter extends Filter
return $parts;
}
protected function cbRelEvent($cr, $value)
protected function cbRelEvent(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if (is_int($_))
return ($_ > 0) ? ['category', $_] : ['id', abs($_)];
else
{
$ids = array_filter($this->enums[$cr[0]], fn($x) => is_int($x) && $x > 0);
$ids = array_filter($this->enums[$cr], fn($x) => is_int($x) && $x > 0);
return ['category', $ids, $_ ? null : '!'];
}
return false;
return null;
}
protected function cbSeries($cr, $value)
protected function cbSeries(int $cr, int $crs, string $crv, int $seriesFlag) : ?array
{
if ($this->int2Bool($cr[1]))
return $cr[1] ? ['AND', ['chainId', 0, '!'], ['cuFlags', $value, '&']] : ['AND', ['chainId', 0, '!'], [['cuFlags', $value, '&'], 0]];
if ($this->int2Bool($crs))
return $crs ? ['AND', ['chainId', 0, '!'], ['cuFlags', $seriesFlag, '&']] : ['AND', ['chainId', 0, '!'], [['cuFlags', $seriesFlag, '&'], 0]];
return false;
return null;
}
}

View File

@@ -73,9 +73,9 @@ class ArenaTeamListFilter extends Filter
if (!empty($_v['si']))
{
if ($_v['si'] == SIDE_ALLIANCE)
$parts[] = ['c.race', [1, 3, 4, 7, 11]];
$parts[] = ['c.race', ChrRace::fromMask(ChrRace::MASK_ALLIANCE)];
else if ($_v['si'] == SIDE_HORDE)
$parts[] = ['c.race', [2, 5, 6, 8, 10]];
$parts[] = ['c.race', ChrRace::fromMask(ChrRace::MASK_HORDE)];
}
// size [int]
@@ -85,7 +85,7 @@ class ArenaTeamListFilter extends Filter
return $parts;
}
protected function cbRegionCheck(&$v)
protected function cbRegionCheck(string &$v) : bool
{
if (in_array($v, Util::$regions))
{
@@ -98,7 +98,7 @@ class ArenaTeamListFilter extends Filter
return false;
}
protected function cbServerCheck(&$v)
protected function cbServerCheck(string &$v) : bool
{
foreach (Profiler::getRealms() as $realm)
if ($realm['name'] == $v)

View File

@@ -388,7 +388,7 @@ class CreatureListFilter extends Filter
return $parts;
}
protected function cbPetFamily(&$val)
protected function cbPetFamily(string &$val) : bool
{
if (!$this->parentCats || $this->parentCats[0] != 1)
return false;
@@ -402,9 +402,9 @@ class CreatureListFilter extends Filter
return $this->checkInput($type, $valid, $val);
}
protected function cbRelEvent($cr)
protected function cbRelEvent(int $cr, int $crs, string $crv) : ?array
{
if ($cr[1] == parent::ENUM_ANY)
if ($crs == parent::ENUM_ANY)
{
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0'))
if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_creature WHERE `eventEntry` IN (?a)', $eventIds))
@@ -412,7 +412,7 @@ class CreatureListFilter extends Filter
return [0];
}
else if ($cr[1] == parent::ENUM_NONE)
else if ($crs == parent::ENUM_NONE)
{
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0'))
if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_creature WHERE `eventEntry` IN (?a)', $eventIds))
@@ -420,29 +420,29 @@ class CreatureListFilter extends Filter
return [0];
}
else if (in_array($cr[1], $this->enums[$cr[0]]))
else if (in_array($crs, $this->enums[$cr]))
{
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` = ?d', $cr[1]))
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` = ?d', $crs))
if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM `game_event_creature` WHERE `eventEntry` IN (?a)', $eventIds))
return ['s.guid', $cGuids];
return [0];
}
return false;
return null;
}
protected function cbMoneyDrop($cr)
protected function cbMoneyDrop(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
return ['AND', ['((minGold + maxGold) / 2)', $cr[2], $cr[1]]];
return ['AND', ['((minGold + maxGold) / 2)', $crv, $crs]];
}
protected function cbQuestRelation($cr, $field, $val)
protected function cbQuestRelation(int $cr, int $crs, string $crv, $field, $val) : ?array
{
switch ($cr[1])
switch ($crs)
{
case 1: // any
return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!']];
@@ -457,25 +457,25 @@ class CreatureListFilter extends Filter
return [1];
}
return false;
return null;
}
protected function cbHealthMana($cr, $minField, $maxField)
protected function cbHealthMana(int $cr, int $crs, string $crv, $minField, $maxField) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
// remap OP for this special case
switch ($cr[1])
switch ($crs)
{
case '=': // min > max is totally possible
$this->extraOpts['ct']['h'][] = $minField.' = '.$maxField.' AND '.$minField.' = '.$cr[2];
$this->extraOpts['ct']['h'][] = $minField.' = '.$maxField.' AND '.$minField.' = '.$crv;
break;
case '>':
case '>=':
case '<':
case '<=':
$this->extraOpts['ct']['h'][] = 'IF('.$minField.' > '.$maxField.', '.$maxField.', '.$minField.') '.$cr[1].' '.$cr[2];
$this->extraOpts['ct']['h'][] = 'IF('.$minField.' > '.$maxField.', '.$maxField.', '.$minField.') '.$crs.' '.$crv;
break;
}
@@ -483,54 +483,53 @@ class CreatureListFilter extends Filter
return [1]; // always true, use post-filter
}
protected function cbSpecialSkinLoot($cr, $typeFlag)
protected function cbSpecialSkinLoot(int $cr, int $crs, string $crv, $typeFlag) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['AND', ['skinLootId', 0, '>'], ['typeFlags', $typeFlag, '&']];
else
return ['OR', ['skinLootId', 0], [['typeFlags', $typeFlag, '&'], 0]];
}
protected function cbRegularSkinLoot($cr, $typeFlag)
protected function cbRegularSkinLoot(int $cr, int $crs, string $crv, $typeFlag) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['AND', ['skinLootId', 0, '>'], [['typeFlags', $typeFlag, '&'], 0]];
else
return ['OR', ['skinLootId', 0], ['typeFlags', $typeFlag, '&']];
}
protected function cbReputation($cr, $op)
protected function cbReputation(int $cr, int $crs, string $crv, $op) : ?array
{
if (!in_array($cr[1], $this->enums[$cr[0]]))
return false;
if (!in_array($crs, $this->enums[$cr]))
return null;
if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE `id` = ?d', $cr[1]))
$this->formData['reputationCols'][] = [$cr[1], Util::localizedString($_, 'name')];
if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE `id` = ?d', $crs))
$this->formData['reputationCols'][] = [$crs, Util::localizedString($_, 'name')];
if ($cIds = DB::World()->selectCol('SELECT creature_id FROM creature_onkill_reputation WHERE (RewOnKillRepFaction1 = ?d AND RewOnKillRepValue1 '.$op.' 0) OR (RewOnKillRepFaction2 = ?d AND RewOnKillRepValue2 '.$op.' 0)', $cr[1], $cr[1]))
if ($cIds = DB::World()->selectCol('SELECT `creature_id` FROM creature_onkill_reputation WHERE (`RewOnKillRepFaction1` = ?d AND `RewOnKillRepValue1` '.$op.' 0) OR (`RewOnKillRepFaction2` = ?d AND `RewOnKillRepValue2` '.$op.' 0)', $crs, $crs))
return ['id', $cIds];
else
return [0];
}
protected function cbFaction($cr)
protected function cbFaction(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[1], NUM_CAST_INT))
return false;
if (!in_array($cr[1], $this->enums[$cr[0]]))
return false;
if (!Util::checkNumeric($crs, NUM_CAST_INT))
return null;
if (!in_array($crs, $this->enums[$cr]))
return null;
$facTpls = [];
$facs = new FactionList(array('OR', ['parentFactionId', $cr[1]], ['id', $cr[1]]));
$facs = new FactionList(array('OR', ['parentFactionId', $crs], ['id', $crs]));
foreach ($facs->iterate() as $__)
$facTpls = array_merge($facTpls, $facs->getField('templateIds'));

View File

@@ -186,17 +186,17 @@ class GameObjectListFilter extends Filter
return $parts;
}
protected function cbOpenable($cr)
protected function cbOpenable(int $cr, int $crs, string $crv) : ?array
{
if ($this->int2Bool($cr[1]))
return $cr[1] ? ['OR', ['flags', 0x2, '&'], ['type', 3]] : ['AND', [['flags', 0x2, '&'], 0], ['type', 3, '!']];
if ($this->int2Bool($crs))
return $crs ? ['OR', ['flags', 0x2, '&'], ['type', 3]] : ['AND', [['flags', 0x2, '&'], 0], ['type', 3, '!']];
return false;
return null;
}
protected function cbQuestRelation($cr, $field, $value)
protected function cbQuestRelation(int $cr, int $crs, string $crv, $field, $value) : ?array
{
switch ($cr[1])
switch ($crs)
{
case 1: // any
return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!']];
@@ -211,12 +211,12 @@ class GameObjectListFilter extends Filter
return [1];
}
return false;
return null;
}
protected function cbRelEvent($cr)
protected function cbRelEvent(int $cr, int $crs, string $crv) : ?array
{
if ($cr[1] == parent::ENUM_ANY)
if ($crs == parent::ENUM_ANY)
{
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0'))
if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN (?a)', $eventIds))
@@ -224,7 +224,7 @@ class GameObjectListFilter extends Filter
return [0];
}
else if ($cr[1] == parent::ENUM_NONE)
else if ($crs == parent::ENUM_NONE)
{
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0'))
if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN (?a)', $eventIds))
@@ -232,16 +232,16 @@ class GameObjectListFilter extends Filter
return [0];
}
else if (in_array($cr[1], $this->enums[$cr[0]]))
else if (in_array($crs, $this->enums[$cr]))
{
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` = ?d', $cr[1]))
if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` = ?d', $crs))
if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN (?a)', $eventIds))
return ['s.guid', $goGuids];
return [0];
}
return false;
return null;
}
}

View File

@@ -115,15 +115,15 @@ class GuildListFilter extends Filter
if (!empty($_v['si']))
{
if ($_v['si'] == SIDE_ALLIANCE)
$parts[] = ['c.race', [1, 3, 4, 7, 11]];
$parts[] = ['c.race', ChrRace::fromMask(ChrRace::MASK_ALLIANCE)];
else if ($_v['si'] == SIDE_HORDE)
$parts[] = ['c.race', [2, 5, 6, 8, 10]];
$parts[] = ['c.race', ChrRace::fromMask(ChrRace::MASK_HORDE)];
}
return $parts;
}
protected function cbRegionCheck(&$v)
protected function cbRegionCheck(string &$v) : bool
{
if (in_array($v, Util::$regions))
{
@@ -136,7 +136,7 @@ class GuildListFilter extends Filter
return false;
}
protected function cbServerCheck(&$v)
protected function cbServerCheck(string &$v) : bool
{
foreach (Profiler::getRealms() as $realm)
if ($realm['name'] == $v)

View File

@@ -137,7 +137,7 @@ class IconListFilter extends Filter
'ma' => [parent::V_EQUAL, 1, false] // match any / all filter
);
private function _getCnd($op, $val, $tbl)
private function _getCnd(string $op, int $val, string $tbl) : ?array
{
switch ($op)
{
@@ -158,6 +158,8 @@ class IconListFilter extends Filter
if ($val)
$op = '=';
break;
default:
return null;
}
$ids = DB::Aowow()->selectCol('SELECT `iconId` AS ARRAY_KEY, COUNT(*) AS "n" FROM ?# GROUP BY `iconId` HAVING n '.$op.' '.$val, $tbl);
@@ -177,18 +179,18 @@ class IconListFilter extends Filter
return $parts;
}
protected function cbUseAny($cr, $value)
protected function cbUseAny(int $cr, int $crs, string $crv) : ?array
{
if (Util::checkNumeric($cr[2], NUM_CAST_INT) && $this->int2Op($cr[1]))
return $this->_getCnd($cr[1], $cr[2], $this->criterion2field[$cr[0]]);
if (Util::checkNumeric($crv, NUM_CAST_INT) && $this->int2Op($crs))
return $this->_getCnd($crs, $crv, $this->criterion2field[$cr]);
return false;
return null;
}
protected function cbUseAll($cr)
protected function cbUseAll(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
if (!$this->totalUses)
{
@@ -202,19 +204,19 @@ class IconListFilter extends Filter
}
}
if ($cr[1] == '=')
$cr[1] = '==';
if ($crs == '=')
$crs = '==';
$op = $cr[1];
if ($cr[1] == '<=' && $cr[2])
$op = $crs;
if ($crs == '<=' && $crv)
$op = '>';
else if ($cr[1] == '<' && $cr[2])
else if ($crs == '<' && $crv)
$op = '>=';
else if ($cr[1] == '!=' && $cr[2])
else if ($crs == '!=' && $crv)
$op = '==';
$ids = array_filter($this->totalUses, fn($x) => eval('return '.$x.' '.$op.' '.$cr[2].';'));
$ids = array_filter($this->totalUses, fn($x) => eval('return '.$x.' '.$op.' '.$crv.';'));
if ($cr[1] != $op)
if ($crs != $op)
return $ids ? ['id', array_keys($ids), '!'] : [1];
else
return $ids ? ['id', array_keys($ids)] : ['id', array_keys($this->totalUses), '!'];

View File

@@ -1936,7 +1936,7 @@ class ItemListFilter extends Filter
104 => [parent::CR_STRING, 'description', STR_LOCALIZED ], // flavortext
105 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_DUNGEON_DROP, 1 ], // dropsinnormal [heroicdungeon-any]
106 => [parent::CR_CALLBACK, 'cbDropsInInstance', SRC_FLAG_DUNGEON_DROP, 2 ], // dropsinheroic [heroicdungeon-any]
107 => [parent::CR_NYI_PH, null, 1, ], // effecttext [str] not yet parsed ['effectsParsed_loc'.Lang::getLocale()->value, $cr[2]]
107 => [parent::CR_NYI_PH, null, 1, ], // effecttext [str] not yet parsed ['effectsParsed_loc'.Lang::getLocale()->value, $crv]
109 => [parent::CR_CALLBACK, 'cbArmorBonus', null, null ], // armorbonus [op] [int]
111 => [parent::CR_NUMERIC, 'requiredSkillRank', NUM_CAST_INT, true ], // reqskillrank
113 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots
@@ -2161,19 +2161,19 @@ class ItemListFilter extends Filter
switch ($_v['si'])
{
case 3:
case SIDE_BOTH:
$parts[] = ['OR', [['flagsExtra', 0x3, '&'], [0, 3]], ['requiredRace', ChrRace::MASK_ALL], ['requiredRace', 0]];
break;
case 2:
case SIDE_HORDE:
$parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 1]], ['OR', $notEx, ['requiredRace', ChrRace::MASK_HORDE, '&']]];
break;
case -2:
case -SIDE_HORDE:
$parts[] = ['OR', [['flagsExtra', 0x3, '&'], 1], ['AND', $ex, ['requiredRace', ChrRace::MASK_HORDE, '&']]];
break;
case 1:
case SIDE_ALLIANCE:
$parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 2]], ['OR', $notEx, ['requiredRace', ChrRace::MASK_ALLIANCE, '&']]];
break;
case -1:
case -SIDE_ALLIANCE:
$parts[] = ['OR', [['flagsExtra', 0x3, '&'], 2], ['AND', $ex, ['requiredRace', ChrRace::MASK_ALLIANCE, '&']]];
break;
}
@@ -2198,86 +2198,64 @@ class ItemListFilter extends Filter
return $parts;
}
protected function cbFactionQuestReward($cr) : mixed
protected function cbFactionQuestReward(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 1: // Yes
return ['src.src4', null, '!'];
case 2: // Alliance
return ['src.src4', SIDE_ALLIANCE];
case 3: // Horde
return ['src.src4', SIDE_HORDE];
case 4: // Both
return ['src.src4', SIDE_BOTH];
case 5: // No
return ['src.src4', null];
}
return false;
1 => ['src.src4', null, '!'], // Yes
2 => ['src.src4', SIDE_ALLIANCE], // Alliance
3 => ['src.src4', SIDE_HORDE], // Horde
4 => ['src.src4', SIDE_BOTH], // Both
5 => ['src.src4', null], // No
default => null
};
}
protected function cbAvailable($cr) : mixed
protected function cbAvailable(int $cr, int $crs, string $crv) : ?array
{
if ($this->int2Bool($cr[1]))
return [['cuFlags', CUSTOM_UNAVAILABLE, '&'], 0, $cr[1] ? null : '!'];
if ($this->int2Bool($crs))
return [['cuFlags', CUSTOM_UNAVAILABLE, '&'], 0, $crs ? null : '!'];
return false;
return null;
}
protected function cbHasSockets($cr) : mixed
protected function cbHasSockets(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 5: // Yes
return ['is.nsockets', 0, '!'];
case 6: // No
return ['is.nsockets', 0];
case 1: // Meta
case 2: // Red
case 3: // Yellow
case 4: // Blue
$mask = 1 << ($cr[1] - 1);
return ['OR', ['socketColor1', $mask], ['socketColor2', $mask], ['socketColor3', $mask]];
}
return false;
// Meta, Red, Yellow, Blue
1, 2, 3, 4 => ['OR', ['socketColor1', 1 << ($crs - 1)], ['socketColor2', 1 << ($crs - 1)], ['socketColor3', 1 << ($crs - 1)]],
5 => ['is.nsockets', 0, '!'], // Yes
6 => ['is.nsockets', 0], // No
default => null
};
}
protected function cbFitsGemSlot($cr) : mixed
protected function cbFitsGemSlot(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 5: // Yes
return ['gemEnchantmentId', 0, '!'];
case 6: // No
return ['gemEnchantmentId', 0];
case 1: // Meta
case 2: // Red
case 3: // Yellow
case 4: // Blue
$mask = 1 << ($cr[1] - 1);
return ['AND', ['gemEnchantmentId', 0, '!'], ['gemColorMask', $mask, '&']];
}
return false;
// Meta, Red, Yellow, Blue
1, 2, 3, 4 => ['AND', ['gemEnchantmentId', 0, '!'], ['gemColorMask', 1 << ($crs - 1), '&']],
5 => ['gemEnchantmentId', 0, '!'], // Yes
6 => ['gemEnchantmentId', 0], // No
default => null
};
}
protected function cbGlyphType($cr) : mixed
protected function cbGlyphType(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 1: // Major
case 2: // Minor
return ['AND', ['class', ITEM_CLASS_GLYPH], ['subSubClass', $cr[1]]];
}
return false;
// major, minor
1, 2 => ['AND', ['class', ITEM_CLASS_GLYPH], ['subSubClass', $crs]],
default => null
};
}
protected function cbHasRandEnchant($cr) : mixed
protected function cbHasRandEnchant(int $cr, int $crs, string $crv) : ?array
{
$n = preg_replace(parent::PATTERN_NAME, '', $cr[2]);
$n = preg_replace(parent::PATTERN_NAME, '', $crv);
$n = $this->transformString($n, false);
$randIds = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, ABS(`id`) AS `id`, name_loc?d, `name_loc0` FROM ?_itemrandomenchant WHERE name_loc?d LIKE ?', Lang::getLocale()->value, Lang::getLocale()->value, $n);
@@ -2305,103 +2283,103 @@ class ItemListFilter extends Filter
return [0]; // no results aren't really input errors
}
protected function cbReqArenaRating($cr) : mixed
protected function cbReqArenaRating(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
$this->formData['extraCols'][] = $cr[0];
$this->formData['extraCols'][] = $cr;
$items = [0];
if ($costs = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE `reqPersonalrating` '.$cr[1].' '.$cr[2]))
if ($costs = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE `reqPersonalrating` '.$crs.' '.$crv))
$items = DB::World()->selectCol($this->extCostQuery, $costs, $costs);
return ['id', $items];
}
protected function cbClassRaceSpec($cr, $field, $mask) : mixed
protected function cbClassRaceSpec(int $cr, int $crs, string $crv, string $field, int $mask) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if (is_bool($_))
return $_ ? ['AND', [[$field, $mask, '&'], $mask, '!'], [$field, 0, '>']] : ['OR', [[$field, $mask, '&'], $mask], [$field, 0]];
else if (is_int($_))
return ['AND', [[$field, $mask, '&'], $mask, '!'], [$field, 1 << ($_ - 1), '&']];
return false;
return null;
}
protected function cbDamageType($cr) : mixed
protected function cbDamageType(int $cr, int $crs, string $crv) : ?array
{
if (!$this->checkInput(parent::V_RANGE, [0, 6], $cr[1]))
return false;
if (!$this->checkInput(parent::V_RANGE, [SPELL_SCHOOL_NORMAL, SPELL_SCHOOL_ARCANE], $crs))
return null;
return ['OR', ['dmgType1', $cr[1]], ['dmgType2', $cr[1]]];
return ['OR', ['dmgType1', $crs], ['dmgType2', $crs]];
}
protected function cbArmorBonus($cr) : mixed
protected function cbArmorBonus(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_FLOAT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_FLOAT) || !$this->int2Op($crs))
return null;
$this->formData['extraCols'][] = $cr[0];
return ['AND', ['armordamagemodifier', $cr[2], $cr[1]], ['class', ITEM_CLASS_ARMOR]];
$this->formData['extraCols'][] = $cr;
return ['AND', ['armordamagemodifier', $crv, $crs], ['class', ITEM_CLASS_ARMOR]];
}
protected function cbCraftedByProf($cr) : mixed
protected function cbCraftedByProf(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if (is_bool($_))
return ['src.src1', null, $_ ? '!' : null];
else if (is_int($_))
return ['s.skillLine1', $_];
return false;
return null;
}
protected function cbQuestRewardIn($cr) : mixed
protected function cbQuestRewardIn(int $cr, int $crs, string $crv) : ?array
{
if (in_array($cr[1], $this->enums[$cr[0]]))
return ['AND', ['src.src4', null, '!'], ['src.moreZoneId', $cr[1]]];
else if ($cr[1] == parent::ENUM_ANY)
if (in_array($crs, $this->enums[$cr]))
return ['AND', ['src.src4', null, '!'], ['src.moreZoneId', $crs]];
else if ($crs == parent::ENUM_ANY)
return ['src.src4', null, '!']; // well, this seems a bit redundant..
return false;
return null;
}
protected function cbDropsInZone($cr) : mixed
protected function cbDropsInZone(int $cr, int $crs, string $crv) : ?array
{
if (in_array($cr[1], $this->enums[$cr[0]]))
return ['AND', ['src.src2', null, '!'], ['src.moreZoneId', $cr[1]]];
else if ($cr[1] == parent::ENUM_ANY)
if (in_array($crs, $this->enums[$cr]))
return ['AND', ['src.src2', null, '!'], ['src.moreZoneId', $crs]];
else if ($crs == parent::ENUM_ANY)
return ['src.src2', null, '!']; // well, this seems a bit redundant..
return false;
return null;
}
protected function cbDropsInInstance($cr, $moreFlag, $modeBit) : mixed
protected function cbDropsInInstance(int $cr, int $crs, string $crv, int $moreFlag, int $modeBit) : ?array
{
if (in_array($cr[1], $this->enums[$cr[0]]))
return ['AND', ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&'], ['src.moreZoneId', $cr[1]]];
else if ($cr[1] == parent::ENUM_ANY)
if (in_array($crs, $this->enums[$cr]))
return ['AND', ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&'], ['src.moreZoneId', $crs]];
else if ($crs == parent::ENUM_ANY)
return ['AND', ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&']];
return false;
return null;
}
protected function cbPurchasableWith($cr) : mixed
protected function cbPurchasableWith(int $cr, int $crs, string $crv) : ?array
{
if (in_array($cr[1], $this->enums[$cr[0]]))
$_ = (array)$cr[1];
else if ($cr[1] == parent::ENUM_ANY)
$_ = $this->enums[$cr[0]];
if (in_array($crs, $this->enums[$cr]))
$_ = (array)$crs;
else if ($crs == parent::ENUM_ANY)
$_ = $this->enums[$cr];
else
return false;
return null;
$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)',
@@ -2410,30 +2388,30 @@ class ItemListFilter extends Filter
if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs))
return ['id', $items];
return false;
return null;
}
protected function cbSoldByNPC($cr) : mixed
protected function cbSoldByNPC(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT))
return null;
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]))
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', $crv, $crv))
return ['i.id', $iIds];
else
return [0];
}
protected function cbAvgBuyout($cr) : mixed
protected function cbAvgBuyout(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
foreach (Profiler::getRealms() as $rId => $__)
{
// todo: do something sensible..
// // todo (med): get the avgbuyout into the listview
// if ($_ = DB::Characters()->select('SELECT ii.itemEntry AS ARRAY_KEY, AVG(ah.buyoutprice / ii.count) AS buyout FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid GROUP BY ii.itemEntry HAVING buyout '.$cr[1].' ?f', $c[1]))
// if ($_ = DB::Characters()->select('SELECT ii.itemEntry AS ARRAY_KEY, AVG(ah.buyoutprice / ii.count) AS buyout FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid GROUP BY ii.itemEntry HAVING buyout '.$crs.' ?f', $c[1]))
// return ['i.id', array_keys($_)];
// else
// return [0];
@@ -2443,123 +2421,122 @@ class ItemListFilter extends Filter
return [0];
}
protected function cbAvgMoneyContent($cr) : mixed
protected function cbAvgMoneyContent(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
$this->formData['extraCols'][] = $cr[0];
return ['AND', ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $cr[2], $cr[1]]];
$this->formData['extraCols'][] = $cr;
return ['AND', ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $crv, $crs]];
}
protected function cbCooldown($cr) : mixed
protected function cbCooldown(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
$cr[2] *= 1000; // field supplied in milliseconds
$crv *= 1000; // field supplied in milliseconds
$this->formData['extraCols'][] = $cr[0];
$this->extraOpts['is']['s'][] = ', GREATEST(spellCooldown1, spellCooldown2, spellCooldown3, spellCooldown4, spellCooldown5) AS cooldown';
$this->formData['extraCols'][] = $cr;
$this->extraOpts['is']['s'][] = ', GREATEST(`spellCooldown1`, `spellCooldown2`, `spellCooldown3`, `spellCooldown4`, `spellCooldown5`) AS "cooldown"';
return [
'OR',
['AND', ['spellTrigger1', SPELL_TRIGGER_USE], ['spellId1', 0, '!'], ['spellCooldown1', 0, '>'], ['spellCooldown1', $cr[2], $cr[1]]],
['AND', ['spellTrigger2', SPELL_TRIGGER_USE], ['spellId2', 0, '!'], ['spellCooldown2', 0, '>'], ['spellCooldown2', $cr[2], $cr[1]]],
['AND', ['spellTrigger3', SPELL_TRIGGER_USE], ['spellId3', 0, '!'], ['spellCooldown3', 0, '>'], ['spellCooldown3', $cr[2], $cr[1]]],
['AND', ['spellTrigger4', SPELL_TRIGGER_USE], ['spellId4', 0, '!'], ['spellCooldown4', 0, '>'], ['spellCooldown4', $cr[2], $cr[1]]],
['AND', ['spellTrigger5', SPELL_TRIGGER_USE], ['spellId5', 0, '!'], ['spellCooldown5', 0, '>'], ['spellCooldown5', $cr[2], $cr[1]]],
['AND', ['spellTrigger1', SPELL_TRIGGER_USE], ['spellId1', 0, '!'], ['spellCooldown1', 0, '>'], ['spellCooldown1', $crv, $crs]],
['AND', ['spellTrigger2', SPELL_TRIGGER_USE], ['spellId2', 0, '!'], ['spellCooldown2', 0, '>'], ['spellCooldown2', $crv, $crs]],
['AND', ['spellTrigger3', SPELL_TRIGGER_USE], ['spellId3', 0, '!'], ['spellCooldown3', 0, '>'], ['spellCooldown3', $crv, $crs]],
['AND', ['spellTrigger4', SPELL_TRIGGER_USE], ['spellId4', 0, '!'], ['spellCooldown4', 0, '>'], ['spellCooldown4', $crv, $crs]],
['AND', ['spellTrigger5', SPELL_TRIGGER_USE], ['spellId5', 0, '!'], ['spellCooldown5', 0, '>'], ['spellCooldown5', $crv, $crs]],
];
}
protected function cbQuestRelation($cr) : mixed
protected function cbQuestRelation(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 1: // any
return ['startQuest', 0, '>'];
case 2: // exclude horde only
return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_HORDE]];
case 3: // exclude alliance only
return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_ALLIANCE]];
case 4: // both
return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 0]];
case 5: // none
return ['startQuest', 0];
}
return false;
// any
1 => ['startQuest', 0, '>'],
// exclude horde only
2 => ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_HORDE]],
// exclude alliance only
3 => ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_ALLIANCE]],
// both
4 => ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 0]],
// none
5 => ['startQuest', 0],
default => null
};
}
protected function cbFieldHasVal($cr, $field, $val) : mixed
protected function cbFieldHasVal(int $cr, int $crs, string $crv, string $field, mixed $val) : ?array
{
if ($this->int2Bool($cr[1]))
return [$field, $val, $cr[1] ? null : '!'];
if ($this->int2Bool($crs))
return [$field, $val, $crs ? null : '!'];
return false;
return null;
}
protected function cbObtainedBy($cr, $field) : mixed
protected function cbObtainedBy(int $cr, int $crs, string $crv, string $field) : ?array
{
if ($this->int2Bool($cr[1]))
return ['src.src'.$field, null, $cr[1] ? '!' : null];
if ($this->int2Bool($crs))
return ['src.src'.$field, null, $crs ? '!' : null];
return false;
return null;
}
protected function cbPvpPurchasable($cr, $field) : mixed
protected function cbPvpPurchasable(int $cr, int $crs, string $crv, string $field) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
$costs = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE ?# > 0', $field);
if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs))
return ['id', $items, $cr[1] ? null : '!'];
return ['id', $items, $crs ? null : '!'];
return false;
return null;
}
protected function cbDisenchantsInto($cr) : mixed
protected function cbDisenchantsInto(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[1], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crs, NUM_CAST_INT))
return null;
if (!in_array($cr[1], $this->enums[$cr[0]]))
return false;
if (!in_array($crs, $this->enums[$cr]))
return null;
$refResults = [];
$newRefs = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE `item` = ?d AND `reference` = 0', LOOT_REFERENCE, $cr[1]);
$newRefs = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE `item` = ?d AND `reference` = 0', LOOT_REFERENCE, $crs);
while ($newRefs)
{
$refResults += $newRefs;
$newRefs = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE `reference` IN (?a)', LOOT_REFERENCE, $newRefs);
}
$lootIds = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE {`reference` IN (?a) OR }(`reference` = 0 AND `item` = ?d)', LOOT_DISENCHANT, $refResults ?: DBSIMPLE_SKIP, $cr[1]);
$lootIds = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE {`reference` IN (?a) OR }(`reference` = 0 AND `item` = ?d)', LOOT_DISENCHANT, $refResults ?: DBSIMPLE_SKIP, $crs);
return $lootIds ? ['disenchantId', $lootIds] : [0];
}
protected function cbObjectiveOfQuest($cr) : mixed
protected function cbObjectiveOfQuest(int $cr, int $crs, string $crv) : ?array
{
$w = '';
switch ($cr[1])
switch ($crs)
{
case 1: // Yes
case 5: // No
case 1: // Yes
case 5: // No
$w = 1;
break;
case 2: // Alliance
case 2: // Alliance
$w = '`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.' AND (`reqRaceMask` & '.ChrRace::MASK_HORDE.') = 0';
break;
case 3: // Horde
case 3: // Horde
$w = '`reqRaceMask` & '.ChrRace::MASK_HORDE.' AND (`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.') = 0';
break;
case 4: // Both
case 4: // Both
$w = '(`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.' AND `reqRaceMask` & '.ChrRace::MASK_HORDE.') OR `reqRaceMask` = 0';
break;
default:
return false;
return null;
}
$itemIds = DB::Aowow()->selectCol(sprintf(
@@ -2570,19 +2547,19 @@ class ItemListFilter extends Filter
));
if ($itemIds)
return ['id', $itemIds, $cr[1] == 5 ? '!' : null];
return ['id', $itemIds, $crs == 5 ? '!' : null];
return [0];
}
protected function cbReagentForAbility($cr) : mixed
protected function cbReagentForAbility(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if ($_ === null)
return false;
return null;
$ids = [];
$spells = DB::Aowow()->select( // todo (med): hmm, selecting all using SpellList would exhaust 128MB of memory :x .. see, that we only select the fields that are really needed
@@ -2605,18 +2582,18 @@ class ItemListFilter extends Filter
return ['id', $ids, '!'];
}
protected function cbSource($cr) : mixed
protected function cbSource(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if (is_int($_)) // specific
return ['src.src'.$_, null, '!'];
else if ($_) // any
{
$foo = ['OR'];
foreach ($this->enums[$cr[0]] as $bar)
foreach ($this->enums[$cr] as $bar)
if (is_int($bar))
$foo[] = ['src.src'.$bar, null, '!'];
@@ -2626,7 +2603,7 @@ class ItemListFilter extends Filter
return ['src.typeId', null];
}
protected function cbTypeCheck(&$v) : bool
protected function cbTypeCheck(string &$v) : bool
{
if (!$this->parentCats)
return false;
@@ -2659,7 +2636,7 @@ class ItemListFilter extends Filter
return false;
}
protected function cbSlotCheck(&$v) : bool
protected function cbSlotCheck(string &$v) : bool
{
if (!Util::checkNumeric($v, NUM_CAST_INT))
return false;
@@ -2687,7 +2664,7 @@ class ItemListFilter extends Filter
return false;
}
protected function cbWeightKeyCheck(&$v) : bool
protected function cbWeightKeyCheck(string &$v) : bool
{
if (preg_match('/\W/i', $v))
return false;

View File

@@ -242,17 +242,14 @@ class ItemsetListFilter extends Filter
return $parts;
}
protected function cbAvaliable($cr)
protected function cbAvaliable(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 1: // Yes
return ['src.typeId', null, '!'];
case 2: // No
return ['src.typeId', null];
}
return false;
1 => ['src.typeId', null, '!'], // Yes
2 => ['src.typeId', null], // No
default => null
};
}
}

View File

@@ -333,9 +333,9 @@ class ProfileListFilter extends Filter
if (!empty($_v['si']))
{
if ($_v['si'] == SIDE_ALLIANCE)
$parts[] = [$k.'.race', [1, 3, 4, 7, 11]];
$parts[] = [$k.'.race', ChrRace::fromMask(ChrRace::MASK_ALLIANCE)];
else if ($_v['si'] == SIDE_HORDE)
$parts[] = [$k.'.race', [2, 5, 6, 8, 10]];
$parts[] = [$k.'.race', ChrRace::fromMask(ChrRace::MASK_HORDE)];
}
// race [list]
@@ -357,7 +357,7 @@ class ProfileListFilter extends Filter
return $parts;
}
protected function cbRegionCheck(&$v)
protected function cbRegionCheck(string &$v) : bool
{
if (in_array($v, Util::$regions))
{
@@ -370,7 +370,7 @@ class ProfileListFilter extends Filter
return false;
}
protected function cbServerCheck(&$v)
protected function cbServerCheck(string &$v) : bool
{
foreach (Profiler::getRealms() as $realm)
if ($realm['name'] == $v)
@@ -384,10 +384,10 @@ class ProfileListFilter extends Filter
return false;
}
protected function cbProfession($cr, $skillId)
protected function cbProfession(int $cr, int $crs, string $crv, $skillId) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
$k = 'sk_'.Util::createHash(12);
$col = 'skill'.$skillId;
@@ -397,7 +397,7 @@ class ProfileListFilter extends Filter
if ($this->useLocalList)
{
$this->extraOpts[$k] = array(
'j' => [sprintf('?_profiler_completion_skills %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`skillId` = %2$d AND `%1$s`.`value` %3$s %4$d', $k, $skillId, $cr[1], $cr[2]), true],
'j' => [sprintf('?_profiler_completion_skills %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`skillId` = %2$d AND `%1$s`.`value` %3$s %4$d', $k, $skillId, $crs, $crv), true],
's' => [', '.$k.'.`value` AS '.$col]
);
return [$k.'.skillId', null, '!'];
@@ -405,96 +405,96 @@ class ProfileListFilter extends Filter
else
{
$this->extraOpts[$k] = array(
'j' => [sprintf('character_skills %1$s ON `%1$s`.`guid` = c.`guid` AND `%1$s`.`skill` = %2$d AND `%1$s`.`value` %3$s %4$d', $k, $skillId, $cr[1], $cr[2]), true],
'j' => [sprintf('character_skills %1$s ON `%1$s`.`guid` = c.`guid` AND `%1$s`.`skill` = %2$d AND `%1$s`.`value` %3$s %4$d', $k, $skillId, $crs, $crv), true],
's' => [', '.$k.'.`value` AS '.$col]
);
return [$k.'.skill', null, '!'];
}
}
protected function cbCompletedAcv($cr)
protected function cbCompletedAcv(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT))
return null;
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_achievement WHERE `id` = ?d', $cr[2]))
return false;
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_achievement WHERE `id` = ?d', $crv))
return null;
$k = 'acv_'.Util::createHash(12);
if ($this->useLocalList)
{
$this->extraOpts[$k] = ['j' => [sprintf('?_profiler_completion_achievements %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`achievementId` = %2$d', $k, $cr[2]), true]];
$this->extraOpts[$k] = ['j' => [sprintf('?_profiler_completion_achievements %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`achievementId` = %2$d', $k, $crv), true]];
return [$k.'.achievementId', null, '!'];
}
else
{
$this->extraOpts[$k] = ['j' => [sprintf('character_achievement %1$s ON `%1$s`.`guid` = c.`guid` AND `%1$s`.`achievement` = %2$d', $k, $cr[2]), true]];
$this->extraOpts[$k] = ['j' => [sprintf('character_achievement %1$s ON `%1$s`.`guid` = c.`guid` AND `%1$s`.`achievement` = %2$d', $k, $crv), true]];
return [$k.'.achievement', null, '!'];
}
}
protected function cbWearsItems($cr)
protected function cbWearsItems(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT))
return null;
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_items WHERE `id` = ?d', $cr[2]))
return false;
if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_items WHERE `id` = ?d', $crv))
return null;
$k = 'i_'.Util::createHash(12);
$this->extraOpts[$k] = ['j' => [sprintf('?_profiler_items %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`item` = %2$d', $k, $cr[2]), true]];
$this->extraOpts[$k] = ['j' => [sprintf('?_profiler_items %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`item` = %2$d', $k, $crv), true]];
return [$k.'.item', null, '!'];
}
protected function cbHasGuild($cr)
protected function cbHasGuild(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($this->useLocalList)
return ['p.guild', null, $cr[1] ? '!' : null];
return ['p.guild', null, $crs ? '!' : null];
else
return ['gm.guildId', null, $cr[1] ? '!' : null];
return ['gm.guildId', null, $crs ? '!' : null];
}
protected function cbHasGuildRank($cr)
protected function cbHasGuildRank(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
if ($this->useLocalList)
return ['p.guildrank', $cr[2], $cr[1]];
return ['p.guildrank', $crv, $crs];
else
return ['gm.rank', $cr[2], $cr[1]];
return ['gm.rank', $crv, $crs];
}
protected function cbTeamName($cr, $size)
protected function cbTeamName(int $cr, int $crs, string $crv, $size) : ?array
{
if ($_ = $this->modularizeString(['at.name'], $cr[2]))
if ($_ = $this->modularizeString(['at.name'], $crv))
return ['AND', ['at.type', $size], $_];
return false;
return null;
}
protected function cbTeamRating($cr, $size)
protected function cbTeamRating(int $cr, int $crs, string $crv, $size) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
return ['AND', ['at.type', $size], ['at.rating', $cr[2], $cr[1]]];
return ['AND', ['at.type', $size], ['at.rating', $crv, $crs]];
}
protected function cbAchievs($cr)
protected function cbAchievs(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
if ($this->useLocalList)
return ['p.achievementpoints', $cr[2], $cr[1]];
return ['p.achievementpoints', $crv, $crs];
else
return ['cap.counter', $cr[2], $cr[1]];
return ['cap.counter', $crv, $crs];
}
}

View File

@@ -555,138 +555,138 @@ class QuestListFilter extends Filter
return $parts;
}
protected function cbReputation($cr, $sign)
protected function cbReputation(int $cr, int $crs, string $crv, string $sign) : ?array
{
if (!Util::checkNumeric($cr[1], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crs, NUM_CAST_INT))
return null;
if (!in_array($cr[1], $this->enums[$cr[0]]))
return false;
if (!in_array($crs, $this->enums[$cr]))
return null;
if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE `id` = ?d', $cr[1]))
$this->formData['reputationCols'][] = [$cr[1], Util::localizedString($_, 'name')];
if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE `id` = ?d', $crs))
$this->formData['reputationCols'][] = [$crs, Util::localizedString($_, 'name')];
return [
'OR',
['AND', ['rewardFactionId1', $cr[1]], ['rewardFactionValue1', 0, $sign]],
['AND', ['rewardFactionId2', $cr[1]], ['rewardFactionValue2', 0, $sign]],
['AND', ['rewardFactionId3', $cr[1]], ['rewardFactionValue3', 0, $sign]],
['AND', ['rewardFactionId4', $cr[1]], ['rewardFactionValue4', 0, $sign]],
['AND', ['rewardFactionId5', $cr[1]], ['rewardFactionValue5', 0, $sign]]
['AND', ['rewardFactionId1', $crs], ['rewardFactionValue1', 0, $sign]],
['AND', ['rewardFactionId2', $crs], ['rewardFactionValue2', 0, $sign]],
['AND', ['rewardFactionId3', $crs], ['rewardFactionValue3', 0, $sign]],
['AND', ['rewardFactionId4', $crs], ['rewardFactionValue4', 0, $sign]],
['AND', ['rewardFactionId5', $crs], ['rewardFactionValue5', 0, $sign]]
];
}
protected function cbQuestRelation($cr, $flags)
protected function cbQuestRelation(int $cr, int $crs, string $crv, $flags) : ?array
{
return match ($cr[1])
return match ($crs)
{
Type::NPC,
Type::OBJECT,
Type::ITEM => ['AND', ['qse.type', $cr[1]], ['qse.method', $flags, '&']],
default => false
Type::ITEM => ['AND', ['qse.type', $crs], ['qse.method', $flags, '&']],
default => null
};
}
protected function cbCurrencyReward($cr)
protected function cbCurrencyReward(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[1], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crs, NUM_CAST_INT))
return null;
if (!in_array($cr[1], $this->enums[$cr[0]]))
return false;
if (!in_array($crs, $this->enums[$cr]))
return null;
return [
'OR',
['rewardItemId1', $cr[1]], ['rewardItemId2', $cr[1]], ['rewardItemId3', $cr[1]], ['rewardItemId4', $cr[1]],
['rewardChoiceItemId1', $cr[1]], ['rewardChoiceItemId2', $cr[1]], ['rewardChoiceItemId3', $cr[1]], ['rewardChoiceItemId4', $cr[1]], ['rewardChoiceItemId5', $cr[1]], ['rewardChoiceItemId6', $cr[1]]
['rewardItemId1', $crs], ['rewardItemId2', $crs], ['rewardItemId3', $crs], ['rewardItemId4', $crs],
['rewardChoiceItemId1', $crs], ['rewardChoiceItemId2', $crs], ['rewardChoiceItemId3', $crs], ['rewardChoiceItemId4', $crs], ['rewardChoiceItemId5', $crs], ['rewardChoiceItemId6', $crs]
];
}
protected function cbAvailable($cr)
protected function cbAvailable(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return [['cuFlags', CUSTOM_UNAVAILABLE | CUSTOM_DISABLED, '&'], 0];
else
return ['cuFlags', CUSTOM_UNAVAILABLE | CUSTOM_DISABLED, '&'];
}
protected function cbRepeatable($cr)
protected function cbRepeatable(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['OR', ['flags', QUEST_FLAG_REPEATABLE, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE, '&']];
else
return ['AND', [['flags', QUEST_FLAG_REPEATABLE, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE, '&'], 0]];
}
protected function cbItemChoices($cr)
protected function cbItemChoices(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
$this->extraOpts['q']['s'][] = ', (IF(rewardChoiceItemId1, 1, 0) + IF(rewardChoiceItemId2, 1, 0) + IF(rewardChoiceItemId3, 1, 0) + IF(rewardChoiceItemId4, 1, 0) + IF(rewardChoiceItemId5, 1, 0) + IF(rewardChoiceItemId6, 1, 0)) as numChoices';
$this->extraOpts['q']['h'][] = 'numChoices '.$cr[1].' '.$cr[2];
$this->extraOpts['q']['s'][] = ', (IF(`rewardChoiceItemId1`, 1, 0) + IF(`rewardChoiceItemId2`, 1, 0) + IF(`rewardChoiceItemId3`, 1, 0) + IF(`rewardChoiceItemId4`, 1, 0) + IF(`rewardChoiceItemId5`, 1, 0) + IF(`rewardChoiceItemId6`, 1, 0)) AS "numChoices"';
$this->extraOpts['q']['h'][] = '`numChoices` '.$crs.' '.$crv;
return [1];
}
protected function cbItemRewards($cr)
protected function cbItemRewards(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
$this->extraOpts['q']['s'][] = ', (IF(rewardItemId1, 1, 0) + IF(rewardItemId2, 1, 0) + IF(rewardItemId3, 1, 0) + IF(rewardItemId4, 1, 0)) as numRewards';
$this->extraOpts['q']['h'][] = 'numRewards '.$cr[1].' '.$cr[2];
$this->extraOpts['q']['s'][] = ', (IF(`rewardItemId1`, 1, 0) + IF(`rewardItemId2`, 1, 0) + IF(`rewardItemId3`, 1, 0) + IF(`rewardItemId4`, 1, 0)) AS "numRewards"';
$this->extraOpts['q']['h'][] = '`numRewards` '.$crs.' '.$crv;
return [1];
}
protected function cbLoremaster($cr)
protected function cbLoremaster(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['AND', ['zoneOrSort', 0, '>'], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]];
else
return ['OR', ['zoneOrSort', 0, '<'], ['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&']];
}
protected function cbSpellRewards($cr)
protected function cbSpellRewards(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['OR', ['sourceSpellId', 0, '>'], ['rewardSpell', 0, '>'], ['rsc.effect1Id', SpellList::EFFECTS_TEACH], ['rsc.effect2Id', SpellList::EFFECTS_TEACH], ['rsc.effect3Id', SpellList::EFFECTS_TEACH]];
else
return ['AND', ['sourceSpellId', 0], ['rewardSpell', 0], ['rewardSpellCast', 0]];
}
protected function cbEarnReputation($cr)
protected function cbEarnReputation(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[1], NUM_CAST_INT))
return false;
if (!Util::checkNumeric($crs, NUM_CAST_INT))
return null;
if ($cr[1] == parent::ENUM_ANY) // any
if ($crs == parent::ENUM_ANY)
return ['OR', ['reqFactionId1', 0, '>'], ['reqFactionId2', 0, '>']];
else if ($cr[1] == parent::ENUM_NONE) // none
else if ($crs == parent::ENUM_NONE)
return ['AND', ['reqFactionId1', 0], ['reqFactionId2', 0]];
else if (in_array($cr[1], $this->enums[$cr[0]]))
return ['OR', ['reqFactionId1', $cr[1]], ['reqFactionId2', $cr[1]]];
else if (in_array($crs, $this->enums[$cr]))
return ['OR', ['reqFactionId1', $crs], ['reqFactionId2', $crs]];
return false;
return null;
}
protected function cbClassSpec($cr)
protected function cbClassSpec(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if ($_ === true)
return ['AND', ['reqClassMask', 0, '!'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']];
else if ($_ === false)
@@ -694,15 +694,15 @@ class QuestListFilter extends Filter
else if (is_int($_))
return ['AND', ['reqClassMask', ChrClass::from($_)->toMask(), '&'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']];
return false;
return null;
}
protected function cbRaceSpec($cr)
protected function cbRaceSpec(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
$_ = $this->enums[$cr][$crs];
if ($_ === true)
return ['AND', ['reqRaceMask', 0, '!'], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']];
else if ($_ === false)
@@ -710,16 +710,16 @@ class QuestListFilter extends Filter
else if (is_int($_))
return ['AND', ['reqRaceMask', ChrRace::from($_)->toMask(), '&'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']];
return false;
return null;
}
protected function cbLacksStartEnd($cr)
protected function cbLacksStartEnd(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
$missing = DB::Aowow()->selectCol('SELECT `questId`, BIT_OR(`method`) AS "se" FROM ?_quests_startend GROUP BY `questId` HAVING "se" <> 3');
if ($cr[1])
if ($crs)
return ['id', $missing];
else
return ['id', $missing, '!'];

View File

@@ -2498,12 +2498,12 @@ class SpellListFilter extends Filter
return $parts;
}
public function getGenericFilter($cr) // access required by SpellDetailPage's SpellAttributes list
public function getGenericFilter(int $cr) : array // access required by SpellDetailPage's SpellAttributes list
{
return $this->genericFilter[$cr] ?? [];
}
protected function cbClasses(&$val)
protected function cbClasses(string &$val) : bool
{
if (!$this->parentCats || !in_array($this->parentCats[0], [-13, -2, 7]))
return false;
@@ -2512,12 +2512,12 @@ class SpellListFilter extends Filter
return false;
$type = parent::V_LIST;
$valid = [[1, 9], 11];
$valid = ChrClass::fromMask(ChrClass::MASK_ALL);
return $this->checkInput($type, $valid, $val);
}
protected function cbGlyphs(&$val)
protected function cbGlyphs(string &$val) : bool
{
if (!$this->parentCats || $this->parentCats[0] != -13)
return false;
@@ -2531,120 +2531,126 @@ class SpellListFilter extends Filter
return $this->checkInput($type, $valid, $val);
}
protected function cbCost($cr)
protected function cbCost(int $cr, int $crs, string $crv) : ?array
{
if (!Util::checkNumeric($cr[2], NUM_CAST_INT) || !$this->int2Op($cr[1]))
return false;
if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs))
return null;
return ['OR',
['AND', ['powerType', [POWER_RAGE, POWER_RUNIC_POWER]], ['powerCost', (10 * $cr[2]), $cr[1]]],
['AND', ['powerType', [POWER_RAGE, POWER_RUNIC_POWER], '!'], ['powerCost', $cr[2], $cr[1]]]
['AND', ['powerType', [POWER_RAGE, POWER_RUNIC_POWER]], ['powerCost', (10 * $crv), $crs]],
['AND', ['powerType', [POWER_RAGE, POWER_RUNIC_POWER], '!'], ['powerCost', $crv, $crs]]
];
}
protected function cbSource($cr)
protected function cbSource(int $cr, int $crs, string $crv) : ?array
{
if (!isset($this->enums[$cr[0]][$cr[1]]))
return false;
if (!isset($this->enums[$cr][$crs]))
return null;
$_ = $this->enums[$cr[0]][$cr[1]];
if (is_int($_)) // specific
$_ = $this->enums[$cr][$crs];
if (is_int($_)) // specific
return ['src.src'.$_, null, '!'];
else if ($_) // any
return ['OR', ['src.src1', null, '!'], ['src.src2', null, '!'], ['src.src4', null, '!'], ['src.src5', null, '!'], ['src.src6', null, '!'], ['src.src7', null, '!'], ['src.src9', null, '!'], ['src.src10', null, '!']];
else if (!$_) // none
return ['AND', ['src.src1', null], ['src.src2', null], ['src.src4', null], ['src.src5', null], ['src.src6', null], ['src.src7', null], ['src.src9', null], ['src.src10', null]];
else if ($_) // any
{
$foo = ['OR'];
foreach ($this->enums[$cr] as $bar)
if (is_int($bar))
$foo[] = ['src.src'.$bar, null, '!'];
return false;
return $foo;
}
else // none
return ['src.typeId', null];
return null;
}
protected function cbReagents($cr)
protected function cbReagents(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['OR', ['reagent1', 0, '>'], ['reagent2', 0, '>'], ['reagent3', 0, '>'], ['reagent4', 0, '>'], ['reagent5', 0, '>'], ['reagent6', 0, '>'], ['reagent7', 0, '>'], ['reagent8', 0, '>']];
else
return ['AND', ['reagent1', 0], ['reagent2', 0], ['reagent3', 0], ['reagent4', 0], ['reagent5', 0], ['reagent6', 0], ['reagent7', 0], ['reagent8', 0]];
}
protected function cbAuraNames($cr)
protected function cbAuraNames(int $cr, int $crs, string $crv) : ?array
{
if (!$this->checkInput(parent::V_RANGE, [1, self::MAX_SPELL_AURA], $cr[1]))
return false;
if (!$this->checkInput(parent::V_RANGE, [1, self::MAX_SPELL_AURA], $crs))
return null;
return ['OR', ['effect1AuraId', $cr[1]], ['effect2AuraId', $cr[1]], ['effect3AuraId', $cr[1]]];
return ['OR', ['effect1AuraId', $crs], ['effect2AuraId', $crs], ['effect3AuraId', $crs]];
}
protected function cbEffectNames($cr)
protected function cbEffectNames(int $cr, int $crs, string $crv) : ?array
{
if (!$this->checkInput(parent::V_RANGE, [1, self::MAX_SPELL_EFFECT], $cr[1]))
return false;
if (!$this->checkInput(parent::V_RANGE, [1, self::MAX_SPELL_EFFECT], $crs))
return null;
return ['OR', ['effect1Id', $cr[1]], ['effect2Id', $cr[1]], ['effect3Id', $cr[1]]];
return ['OR', ['effect1Id', $crs], ['effect2Id', $crs], ['effect3Id', $crs]];
}
protected function cbInverseFlag($cr, $field, $flag)
protected function cbInverseFlag(int $cr, int $crs, string $crv, string $field, int $flag) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return [[$field, $flag, '&'], 0];
else
return [$field, $flag, '&'];
}
protected function cbSpellstealable($cr, $field, $flag)
protected function cbSpellstealable(int $cr, int $crs, string $crv, string $field, int $flag) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['AND', [[$field, $flag, '&'], 0], ['dispelType', SPELL_DAMAGE_CLASS_MAGIC]];
else
return ['OR', [$field, $flag, '&'], ['dispelType', SPELL_DAMAGE_CLASS_MAGIC, '!']];
}
protected function cbReqFaction($cr)
protected function cbReqFaction(int $cr, int $crs, string $crv) : ?array
{
switch ($cr[1])
return match ($crs)
{
case 1: // yes
return ['reqRaceMask', 0, '!'];
case 2: // alliance
return ['AND', [['reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']];
case 3: // horde
return ['AND', [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
case 4: // both
return ['AND', ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['reqRaceMask', ChrRace::MASK_HORDE, '&']];
case 5: // no
return ['reqRaceMask', 0];
default:
return false;
}
// yes
1 => ['reqRaceMask', 0, '!'],
// alliance
2 => ['AND', [['reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']],
// horde
3 => ['AND', [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['reqRaceMask', ChrRace::MASK_HORDE, '&']],
// both
4 => ['AND', ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['reqRaceMask', ChrRace::MASK_HORDE, '&']],
// no
5 => ['reqRaceMask', 0],
default => null
};
}
protected function cbEquippedWeapon($cr, $mask, $useInvType)
protected function cbEquippedWeapon(int $cr, int $crs, string $crv, int $mask, bool $useInvType) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
$field = $useInvType ? 'equippedItemInventoryTypeMask' : 'equippedItemSubClassMask';
if ($cr[1])
if ($crs)
return ['AND', ['equippedItemClass', ITEM_CLASS_WEAPON], [$field, $mask, '&']];
else
return ['OR', ['equippedItemClass', ITEM_CLASS_WEAPON, '!'], [[$field, $mask, '&'], 0]];
}
protected function cbUsableInArena($cr)
protected function cbUsableInArena(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1])
if ($crs)
return ['AND',
[['attributes4', SPELL_ATTR4_NOT_USABLE_IN_ARENA, '&'], 0],
['OR', ['recoveryTime', 10 * MINUTE * 1000, '<='], ['attributes4', SPELL_ATTR4_USABLE_IN_ARENA, '&']]
@@ -2656,12 +2662,12 @@ class SpellListFilter extends Filter
];
}
protected function cbBandageSpell($cr)
protected function cbBandageSpell(int $cr, int $crs, string $crv) : ?array
{
if (!$this->int2Bool($cr[1]))
return false;
if (!$this->int2Bool($crs))
return null;
if ($cr[1]) // match exact, not as flag
if ($crs) // match exact, not as flag
return ['AND', ['attributes1', SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 | SPELL_ATTR1_CHANNEL_TRACK_TARGET], ['effect1ImplicitTargetA', 21]];
else
return ['OR', ['attributes1', SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 | SPELL_ATTR1_CHANNEL_TRACK_TARGET, '!'], ['effect1ImplicitTargetA', 21, '!']];