Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions server/src/models/Gym.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const config = require('@rm/config')
const { getAreaSql } = require('../utils/getAreaSql')
const { state } = require('../services/state')

const { applyManualIdFilter } = require('../utils/manualFilter')

const coreFields = [
'id',
'name',
Expand Down Expand Up @@ -83,6 +85,7 @@ class Gym extends Model {
onlyGymBadges,
onlyBadge,
onlyAreas = [],
onlyManualId,
} = args.filters
const ts = Math.floor(Date.now() / 1000)
const query = this.query()
Expand Down Expand Up @@ -130,9 +133,22 @@ class Gym extends Model {
} else if (hideOldGyms) {
query.where('updated', '>', ts - gymValidDataLimit * 86400)
}
query
.whereBetween(isMad ? 'latitude' : 'lat', [args.minLat, args.maxLat])
.andWhereBetween(isMad ? 'longitude' : 'lon', [args.minLon, args.maxLon])
const latCol = isMad ? 'latitude' : 'lat'
const lonCol = isMad ? 'longitude' : 'lon'
const idCol = isMad ? 'gym.gym_id' : 'id'

applyManualIdFilter(query, {
manualId: onlyManualId,
latColumn: latCol,
lonColumn: lonCol,
idColumn: idCol,
bounds: {
minLat: args.minLat,
maxLat: args.maxLat,
minLon: args.minLon,
maxLon: args.maxLon,
},
})
Gym.onlyValid(query, isMad)

const raidBosses = new Set()
Expand Down
14 changes: 9 additions & 5 deletions server/src/models/Nest.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const config = require('@rm/config')

const { state } = require('../services/state')
const { getAreaSql } = require('../utils/getAreaSql')
const { applyManualIdFilter } = require('../utils/manualFilter')

/** @typedef {Nest & Partial<import("@rm/types").Nest>} FullNest */

Expand All @@ -27,11 +28,14 @@ class Nest extends Model {
static async getAll(perms, args, { polygon }) {
const { areaRestrictions } = perms
const { minLat, minLon, maxLat, maxLon, filters } = args
const query = this.query()
.select(['*', 'nest_id AS id'])
// .whereNotNull('pokemon_id')
.whereBetween('lat', [minLat, maxLat])
.andWhereBetween('lon', [minLon, maxLon])
const query = this.query().select(['*', 'nest_id AS id'])
applyManualIdFilter(query, {
manualId: filters.onlyManualId,
latColumn: 'lat',
lonColumn: 'lon',
idColumn: 'nest_id',
bounds: { minLat, maxLat, minLon, maxLon },
})

const pokemon = []
if (filters.onlyPokemon) {
Expand Down
237 changes: 153 additions & 84 deletions server/src/models/Pokemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const config = require('@rm/config')
const { getAreaSql } = require('../utils/getAreaSql')
const { filterRTree } = require('../utils/filterRTree')
const { fetchJson } = require('../utils/fetchJson')
const {
applyManualIdFilter,
normalizeManualId,
} = require('../utils/manualFilter')
const {
IV_CALC,
LEVEL_CALC,
Expand Down Expand Up @@ -148,6 +152,10 @@ class Pokemon extends Model {

const query = this.query()

const manualIdFilter = normalizeManualId(args.filters.onlyManualId)

let manualId = manualIdFilter

const pokemonIds = []
const pokemonForms = []
Object.values(filterMap).forEach((filter) => {
Expand All @@ -169,75 +177,81 @@ class Pokemon extends Model {
} else {
query.select(['*', hasSize && !hasHeight ? 'size AS height' : 'size'])
}
query
.where(
isMad ? 'disappear_time' : 'expire_timestamp',
'>=',
isMad ? this.knex().fn.now() : ts,
)
.andWhereBetween(isMad ? 'pokemon.latitude' : 'lat', [
args.minLat,
args.maxLat,
])
.andWhereBetween(isMad ? 'pokemon.longitude' : 'lon', [
args.minLon,
args.maxLon,
])
.andWhere((ivOr) => {
if (ivs || pvp) {
if (globalFilter.filterKeys.size) {
ivOr.andWhere((pkmn) => {
const keys = globalFilter.keyArray
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i]
switch (key) {
case 'xxs':
case 'xxl':
if (hasSize) {
pkmn.orWhere('pokemon.size', key === 'xxl' ? 5 : 1)
}
break
case 'gender':
pkmn.andWhere('pokemon.gender', onlyIvOr[key])
break
case 'cp':
case 'level':
case 'atk_iv':
case 'def_iv':
case 'sta_iv':
case 'iv':
if (perms.iv) {
pkmn.andWhereBetween(
isMad ? MAD_KEY_MAP[key] : key,
onlyIvOr[key],
)
}
break
default:
if (
perms.pvp &&
BASE_KEYS.every((x) => !globalFilter.filterKeys.has(x))
) {
// doesn't return everything if only pvp stats for individual pokemon
pkmn.whereNull('pokemon_id')
}
break
}
query.where(
isMad ? 'disappear_time' : 'expire_timestamp',
'>=',
isMad ? this.knex().fn.now() : ts,
)
manualId = applyManualIdFilter(query, {
manualId: manualIdFilter,
latColumn: isMad ? 'pokemon.latitude' : 'lat',
lonColumn: isMad ? 'pokemon.longitude' : 'lon',
idColumn: isMad ? 'pokemon.encounter_id' : 'id',
bounds: {
minLat: args.minLat,
maxLat: args.maxLat,
minLon: args.minLon,
maxLon: args.maxLon,
},
})
query.andWhere((ivOr) => {
if (ivs || pvp) {
if (globalFilter.filterKeys.size) {
ivOr.andWhere((pkmn) => {
const keys = globalFilter.keyArray
for (let i = 0; i < keys.length; i += 1) {
const key = keys[i]
switch (key) {
case 'xxs':
case 'xxl':
if (hasSize) {
pkmn.orWhere('pokemon.size', key === 'xxl' ? 5 : 1)
}
break
case 'gender':
pkmn.andWhere('pokemon.gender', onlyIvOr[key])
break
case 'cp':
case 'level':
case 'atk_iv':
case 'def_iv':
case 'sta_iv':
case 'iv':
if (perms.iv) {
pkmn.andWhereBetween(
isMad ? MAD_KEY_MAP[key] : key,
onlyIvOr[key],
)
}
break
default:
if (
perms.pvp &&
BASE_KEYS.every((x) => !globalFilter.filterKeys.has(x))
) {
// doesn't return everything if only pvp stats for individual pokemon
pkmn.whereNull('pokemon_id')
}
break
}
})
} else {
ivOr.whereNull('pokemon_id')
}
ivOr.orWhereIn('pokemon_id', pokemonIds)
ivOr.orWhereIn('pokemon.form', pokemonForms)
}
if (onlyZeroIv && ivs) {
ivOr.orWhere(isMad ? raw(IV_CALC) : 'iv', 0)
}
if (onlyHundoIv && ivs) {
ivOr.orWhere(isMad ? raw(IV_CALC) : 'iv', 100)
}
})
} else {
ivOr.whereNull('pokemon_id')
}
})
ivOr.orWhereIn('pokemon_id', pokemonIds)
ivOr.orWhereIn('pokemon.form', pokemonForms)
}
if (onlyZeroIv && ivs) {
ivOr.orWhere(isMad ? raw(IV_CALC) : 'iv', 0)
}
if (onlyHundoIv && ivs) {
ivOr.orWhere(isMad ? raw(IV_CALC) : 'iv', 100)
}
if (manualId !== null) {
ivOr.orWhereIn(isMad ? 'pokemon.encounter_id' : 'id', [manualId])
}
})
if (!getAreaSql(query, areaRestrictions, onlyAreas, isMad, 'pokemon')) {
return []
}
Expand Down Expand Up @@ -272,7 +286,7 @@ class Pokemon extends Model {
filters.push({ iv: { min: 100, max: 100 }, pokemon: globalPokes })
}
/** @type {import("@rm/types").Pokemon[]} */
const results = await this.evalQuery(
let results = await this.evalQuery(
mem ? `${mem}/api/pokemon/v2/scan` : null,
mem
? JSON.stringify({
Expand All @@ -293,6 +307,30 @@ class Pokemon extends Model {
httpAuth,
)

if (mem && manualId !== null) {
const loadedIds = Array.isArray(results)
? new Set(results.map((pkmn) => `${pkmn.id}`))
: new Set()
if (!loadedIds.has(`${manualId}`)) {
const manualResult = await this.evalQuery(
`${mem}/api/pokemon/id/${manualId}`,
null,
'GET',
secret,
httpAuth,
).catch(() => null)
if (manualResult) {
results = Array.isArray(results)
? [...results, manualResult]
: [manualResult]
}
}
}

if (!Array.isArray(results)) {
results = []
}

const finalResults = []
const pvpResults = []
const listOfIds = []
Expand Down Expand Up @@ -326,20 +364,23 @@ class Pokemon extends Model {
if (isMad) {
Pokemon.getMadSql(pvpQuery)
}
pvpQuery
.where(
isMad ? 'disappear_time' : 'expire_timestamp',
'>=',
isMad ? this.knex().fn.now() : ts,
)
.andWhereBetween(isMad ? 'pokemon.latitude' : 'lat', [
args.minLat,
args.maxLat,
])
.andWhereBetween(isMad ? 'pokemon.longitude' : 'lon', [
args.minLon,
args.maxLon,
])
pvpQuery.where(
isMad ? 'disappear_time' : 'expire_timestamp',
'>=',
isMad ? this.knex().fn.now() : ts,
)
applyManualIdFilter(pvpQuery, {
manualId,
latColumn: isMad ? 'pokemon.latitude' : 'lat',
lonColumn: isMad ? 'pokemon.longitude' : 'lon',
idColumn: isMad ? 'pokemon.encounter_id' : 'id',
bounds: {
minLat: args.minLat,
maxLat: args.maxLat,
minLon: args.minLon,
maxLon: args.maxLon,
},
})
if (isMad && listOfIds.length) {
pvpQuery.whereRaw(
`pokemon.encounter_id NOT IN ( ${listOfIds.join(',')} )`,
Expand Down Expand Up @@ -643,6 +684,7 @@ class Pokemon extends Model {
const { isMad, hasSize, hasHeight, mem, secret, httpAuth } = ctx
const ts = Math.floor(Date.now() / 1000)
const { filterMap, globalFilter } = this.getFilters(perms, args, ctx)
const manualIdFilter = normalizeManualId(args.filters.onlyManualId)
const queryLimits = config.getSafe('api.queryLimits')

if (!perms.iv && !perms.pvp) {
Expand Down Expand Up @@ -682,14 +724,25 @@ class Pokemon extends Model {
) {
return []
}

const manualId = applyManualIdFilter(query, {
manualId: manualIdFilter,
latColumn: isMad ? 'pokemon.latitude' : 'lat',
lonColumn: isMad ? 'pokemon.longitude' : 'lon',
idColumn: isMad ? 'pokemon.encounter_id' : 'id',
bounds: {
minLat: args.minLat,
maxLat: args.maxLat,
minLon: args.minLon,
maxLon: args.maxLon,
},
})
const filters = mem
? Object.values(filterMap).flatMap((filter) => filter.buildApiFilter())
: []
if ((perms.iv || perms.pvp) && mem)
filters.push(...globalFilter.buildApiFilter())

const results = await this.evalQuery(
let results = await this.evalQuery(
mem ? `${mem}/api/pokemon/v2/scan` : null,
mem
? JSON.stringify({
Expand All @@ -709,6 +762,22 @@ class Pokemon extends Model {
secret,
httpAuth,
)

if (mem && manualId !== null) {
const loaded = new Set(results.map((pkmn) => `${pkmn.id}`))
if (!loaded.has(`${manualId}`)) {
const manualResult = await this.evalQuery(
`${mem}/api/pokemon/id/${manualId}`,
null,
'GET',
secret,
httpAuth,
).catch(() => null)
if (manualResult) {
results = [...results, manualResult]
}
}
}
const filtered = results.filter(
(item) =>
!mem ||
Expand Down
Loading
Loading