diff --git a/server/src/models/Pokestop.js b/server/src/models/Pokestop.js index cd4e5c5c5..5607e1777 100644 --- a/server/src/models/Pokestop.js +++ b/server/src/models/Pokestop.js @@ -755,6 +755,102 @@ class Pokestop extends Model { } } + static hasRocketPokemonFilter(filters, pokemonId, formId) { + if (!pokemonId) return false + return !!( + filters[`a${pokemonId}-${formId ?? 0}`] || filters[`a${pokemonId}`] + ) + } + + static invasionMatchesFilters( + invasion, + filters, + isMad, + hasMultiInvasions, + hasConfirmed, + ) { + const gruntType = Number(invasion.grunt_type ?? 0) + const info = state.event.invasions[gruntType] + if (!gruntType || !info) return false + + if (hasConfirmed && filters.onlyConfirmed && !invasion.confirmed) { + return false + } + if ( + filters.onlyExcludeGrunts && + state.event.rocketGruntIDs.includes(gruntType) + ) { + return false + } + if ( + filters.onlyExcludeLeaders && + state.event.rocketLeaderIDs.includes(gruntType) + ) { + return false + } + if ( + isMad && + !hasMultiInvasions && + MADE_UP_MAD_INVASIONS.includes(gruntType) + ) { + return false + } + + const isLeaderOrGiovanni = gruntType >= 41 && gruntType <= 44 + if (!isLeaderOrGiovanni) { + if ( + info.firstReward && + (hasConfirmed && invasion.confirmed + ? this.hasRocketPokemonFilter( + filters, + invasion.slot_1_pokemon_id, + invasion.slot_1_form, + ) + : info.encounters.first.some((poke) => + this.hasRocketPokemonFilter(filters, poke.id, poke.form), + )) + ) { + return true + } + + if ( + info.secondReward && + (hasConfirmed && invasion.confirmed + ? this.hasRocketPokemonFilter( + filters, + invasion.slot_2_pokemon_id, + invasion.slot_2_form, + ) + : info.encounters.second.some((poke) => + this.hasRocketPokemonFilter(filters, poke.id, poke.form), + )) + ) { + return true + } + + if ( + info.thirdReward && + (hasConfirmed && invasion.confirmed + ? this.hasRocketPokemonFilter( + filters, + invasion.slot_3_pokemon_id, + invasion.slot_3_form, + ) + : info.encounters.third.some((poke) => + this.hasRocketPokemonFilter(filters, poke.id, poke.form), + )) + ) { + return true + } + } + + return !!( + filters[`i${gruntType}`] || + (filters.onlyAllPokestops && + (filters.onlyConfirmed ? invasion.confirmed : true)) + ) + } + // filters and removes unwanted data static secondaryFilter( queryResults, @@ -858,61 +954,15 @@ class Pokestop extends Model { perms.invasions && (filters.onlyAllPokestops || filters.onlyInvasions) ) { - filtered.invasions = pokestop.invasions.filter((invasion) => { - const info = state.event.invasions[invasion.grunt_type] - if (!info) return false - - // Check if this is a team leader or Giovanni (grunt types 41-44) - const isLeaderOrGiovanni = - invasion.grunt_type >= 41 && invasion.grunt_type <= 44 - - // For team leaders and Giovanni, skip Pokemon-based filtering - if (!isLeaderOrGiovanni) { - if ( - info.firstReward && - (hasConfirmed && invasion.confirmed - ? filters[ - `a${invasion.slot_1_pokemon_id}-${invasion.slot_1_form}` - ] - : info.encounters.first.some( - (poke) => !!filters[`a${poke.id}-${poke.form}`], - )) - ) - return true - - if ( - info.secondReward && - (hasConfirmed && invasion.confirmed - ? filters[ - `a${invasion.slot_2_pokemon_id}-${invasion.slot_2_form}` - ] - : info.encounters.second.some( - (poke) => !!filters[`a${poke.id}-${poke.form}`], - )) - ) - return true - if ( - info.thirdReward && - (hasConfirmed && invasion.confirmed - ? filters[ - `a${invasion.slot_3_pokemon_id}-${invasion.slot_3_form}` - ] - : info.encounters.third.some( - (poke) => !!filters[`a${poke.id}-${poke.form}`], - )) - ) - return true - } - - return ( - filters[`i${invasion.grunt_type}`] || - (filters.onlyAllPokestops && - (filters.onlyConfirmed ? invasion.confirmed : true) && - (isMad && !hasMultiInvasions - ? !MADE_UP_MAD_INVASIONS.includes(invasion.grunt_type) - : invasion.grunt_type)) - ) - }) + filtered.invasions = pokestop.invasions.filter((invasion) => + this.invasionMatchesFilters( + invasion, + filters, + isMad, + hasMultiInvasions, + hasConfirmed, + ), + ) } if ( perms.lures && diff --git a/server/src/services/EventManager.js b/server/src/services/EventManager.js index a6538db11..58e3f3604 100644 --- a/server/src/services/EventManager.js +++ b/server/src/services/EventManager.js @@ -19,9 +19,9 @@ class EventManager extends Logger { super('event') /** @type {import("@rm/masterfile").Masterfile} */ this.masterfile = read() - /** @type {import("@rm/masterfile").Masterfile['invasions'] | {}} */ - this.invasions = - 'invasions' in this.masterfile ? this.masterfile.invasions : {} + this.setInvasions( + 'invasions' in this.masterfile ? this.masterfile.invasions : {}, + ) /** @type {{[key in keyof import('@rm/types').Available]: string[] }} */ this.available = getCache('available.json', { @@ -61,6 +61,21 @@ class EventManager extends Logger { this.authClients = {} } + /** @param {import("@rm/masterfile").Masterfile['invasions'] | {}} invasions */ + setInvasions(invasions) { + this.invasions = invasions + this.rocketGruntIDs = Object.keys(invasions) + .filter((key) => invasions[key].grunt === 'Grunt') + .map(Number) + this.rocketLeaderIDs = Object.keys(invasions) + .filter( + (key) => + invasions[key].grunt === 'Executive' || + invasions[key].grunt === 'Giovanni', + ) + .map(Number) + } + /** * * @param {keyof EventManager['available']} category @@ -368,19 +383,7 @@ class EventManager extends Logger { /** @type {import('@rm/masterfile').Masterfile['invasions']} */ const newInvasions = await fetch(endpoint).then((res) => res.json()) if (newInvasions) { - this.rocketGruntIDs = Object.keys(newInvasions) - .filter((key) => newInvasions[key].grunt === 'Grunt') - .map(Number) - - this.rocketLeaderIDs = Object.keys(newInvasions) - .filter( - (key) => - newInvasions[key].grunt === 'Executive' || - newInvasions[key].grunt === 'Giovanni', - ) - .map(Number) - - this.invasions = newInvasions + this.setInvasions(newInvasions) // Update available rocket Pokemon whenever invasions are refreshed if (Db) {