From b2d3bc1076a69a8e7a80a0e3c5c50bd4c102c995 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Wed, 12 Mar 2025 00:12:06 +0100 Subject: [PATCH] Types/Filters * followup on 748a78c3c7c5c52c71d994182afc1849f589139b * 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 --- includes/basetype.class.php | 6 +- includes/types/achievement.class.php | 20 +- includes/types/arenateam.class.php | 8 +- includes/types/creature.class.php | 81 +++--- includes/types/gameobject.class.php | 26 +- includes/types/guild.class.php | 8 +- includes/types/icon.class.php | 34 +-- includes/types/item.class.php | 361 +++++++++++++-------------- includes/types/itemset.class.php | 15 +- includes/types/profile.class.php | 88 +++---- includes/types/quest.class.php | 142 +++++------ includes/types/spell.class.php | 138 +++++----- 12 files changed, 454 insertions(+), 473 deletions(-) diff --git a/includes/basetype.class.php b/includes/basetype.class.php index 394b1653..0dd14cb9 100644 --- a/includes/basetype.class.php +++ b/includes/basetype.class.php @@ -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)) diff --git a/includes/types/achievement.class.php b/includes/types/achievement.class.php index 2652de40..2c524eb7 100644 --- a/includes/types/achievement.class.php +++ b/includes/types/achievement.class.php @@ -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; } } diff --git a/includes/types/arenateam.class.php b/includes/types/arenateam.class.php index 926c4ba8..4f732415 100644 --- a/includes/types/arenateam.class.php +++ b/includes/types/arenateam.class.php @@ -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) diff --git a/includes/types/creature.class.php b/includes/types/creature.class.php index 6ca1a35f..bc5c867c 100644 --- a/includes/types/creature.class.php +++ b/includes/types/creature.class.php @@ -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')); diff --git a/includes/types/gameobject.class.php b/includes/types/gameobject.class.php index d1b38d6e..d39a7e4f 100644 --- a/includes/types/gameobject.class.php +++ b/includes/types/gameobject.class.php @@ -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; } } diff --git a/includes/types/guild.class.php b/includes/types/guild.class.php index e8192b18..730ff789 100644 --- a/includes/types/guild.class.php +++ b/includes/types/guild.class.php @@ -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) diff --git a/includes/types/icon.class.php b/includes/types/icon.class.php index 290c9357..34f7d038 100644 --- a/includes/types/icon.class.php +++ b/includes/types/icon.class.php @@ -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), '!']; diff --git a/includes/types/item.class.php b/includes/types/item.class.php index 83b77b36..28fd38ab 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -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; diff --git a/includes/types/itemset.class.php b/includes/types/itemset.class.php index 0a7cbbc6..f833c9a4 100644 --- a/includes/types/itemset.class.php +++ b/includes/types/itemset.class.php @@ -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 + }; } } diff --git a/includes/types/profile.class.php b/includes/types/profile.class.php index bf79e84d..db24a851 100644 --- a/includes/types/profile.class.php +++ b/includes/types/profile.class.php @@ -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]; } } diff --git a/includes/types/quest.class.php b/includes/types/quest.class.php index 23f2bac0..cd55058a 100644 --- a/includes/types/quest.class.php +++ b/includes/types/quest.class.php @@ -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, '!']; diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php index 65c30d11..3a92e8eb 100644 --- a/includes/types/spell.class.php +++ b/includes/types/spell.class.php @@ -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, '!']];