diff --git a/package.json b/package.json index db33f3d0c..374a8791f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reactmap", - "version": "1.3.3", + "version": "1.3.4", "description": "React based frontend map.", "main": "ReactMap.mjs", "author": "TurtIeSocks <58572875+TurtIeSocks@users.noreply.github.com>", diff --git a/server/src/graphql/resolvers.js b/server/src/graphql/resolvers.js index afd3fd72d..41f1392f3 100644 --- a/server/src/graphql/resolvers.js +++ b/server/src/graphql/resolvers.js @@ -23,7 +23,7 @@ module.exports = { return { ...available, masterfile: { ...Event.masterfile, invasions: Event.invasions }, - filters: Utility.buildDefaultFilters(perms, available), + filters: Utility.buildDefaultFilters(perms, available, Db.models), } }, badges: async (_, _args, { req, perms, Db, serverV, clientV }) => { diff --git a/server/src/graphql/scannerTypes.js b/server/src/graphql/scannerTypes.js index e6db35ff9..108d20c10 100644 --- a/server/src/graphql/scannerTypes.js +++ b/server/src/graphql/scannerTypes.js @@ -4,7 +4,7 @@ module.exports = gql` type Device { id: ID instance_name: String - last_seen: Int + updated: Int last_lat: Float last_lon: Float type: String diff --git a/server/src/index.js b/server/src/index.js index c42a986e6..6bdab66d9 100644 --- a/server/src/index.js +++ b/server/src/index.js @@ -74,6 +74,21 @@ const server = new ApolloServer({ } return { message: e.message } }, + formatResponse: (data, context) => { + if (config.devOptions.enabled) { + const endpoint = + context?.operation?.selectionSet?.selections?.[0]?.name?.value + const returned = data?.data?.[endpoint]?.length + console.log( + '[GQL]', + 'Endpoint:', + endpoint, + returned ? 'Returned:' : '', + returned || '', + ) + } + return null + }, }) server.start().then(() => server.applyMiddleware({ app, path: '/graphql' })) @@ -82,6 +97,7 @@ if (config.devOptions.enabled) { app.use( logger((tokens, req, res) => [ + '[EXPRESS]', tokens.method(req, res), tokens.url(req, res), tokens.status(req, res), diff --git a/server/src/models/Device.js b/server/src/models/Device.js index 6d7989ef4..ccb05dca0 100644 --- a/server/src/models/Device.js +++ b/server/src/models/Device.js @@ -18,7 +18,7 @@ module.exports = class Device extends Model { 'settings_device.name AS id', 'settings_area.name AS instance_name', 'mode AS type', - raw('UNIX_TIMESTAMP(lastProtoDateTime)').as('last_seen'), + raw('UNIX_TIMESTAMP(lastProtoDateTime)').as('updated'), raw('X(currentPos)').as('last_lat'), raw('Y(currentPos)').as('last_lon'), raw(true).as('isMad'), @@ -28,7 +28,7 @@ module.exports = class Device extends Model { .join('instance', 'device.instance_name', 'instance.name') .select( 'uuid AS id', - 'last_seen', + 'last_seen AS updated', 'last_lat', 'last_lon', 'type', diff --git a/server/src/models/Pokestop.js b/server/src/models/Pokestop.js index a20f5f0c8..2ed518924 100644 --- a/server/src/models/Pokestop.js +++ b/server/src/models/Pokestop.js @@ -59,6 +59,7 @@ module.exports = class Pokestop extends Model { multiInvasionMs, hasRewardAmount, hasLayerColumn, + hasPowerUp, }, ) { const { @@ -466,7 +467,7 @@ module.exports = class Pokestop extends Model { }) } }) - } else if (onlyLevels !== 'all' && !isMad) { + } else if (onlyLevels !== 'all' && hasPowerUp) { query.andWhere('power_up_level', onlyLevels) } const results = await query diff --git a/server/src/routes/rootRouter.js b/server/src/routes/rootRouter.js index dded45a46..33e5c1215 100644 --- a/server/src/routes/rootRouter.js +++ b/server/src/routes/rootRouter.js @@ -258,6 +258,7 @@ rootRouter.get('/settings', async (req, res) => { serverSettings.defaultFilters = Utility.buildDefaultFilters( serverSettings.user.perms, serverSettings.available, + Db.models, ) // Backup in case there are Pokemon/Quests/Raids etc that are not in the masterfile diff --git a/server/src/services/DbCheck.js b/server/src/services/DbCheck.js index 122627991..a01430136 100644 --- a/server/src/services/DbCheck.js +++ b/server/src/services/DbCheck.js @@ -79,10 +79,13 @@ module.exports = class DbCheck { const [isMad, pvpV2] = await schema('pokemon') .columnInfo() .then((columns) => ['cp_multiplier' in columns, 'pvp' in columns]) - const [hasRewardAmount, hasAltQuests] = await schema('pokestop') + const [hasRewardAmount, hasPowerUp, hasAltQuests] = await schema( + 'pokestop', + ) .columnInfo() .then((columns) => [ 'quest_reward_amount' in columns || isMad, + 'power_up_level' in columns, 'alternative_quest_type' in columns, ]) const [hasLayerColumn] = isMad @@ -109,6 +112,7 @@ module.exports = class DbCheck { this.models[category][j].isMad = isMad this.models[category][j].pvpV2 = pvpV2 this.models[category][j].hasRewardAmount = hasRewardAmount + this.models[category][j].hasPowerUp = hasPowerUp this.models[category][j].hasAltQuests = hasAltQuests this.models[category][j].hasMultiInvasions = hasMultiInvasions this.models[category][j].multiInvasionMs = multiInvasionMs @@ -159,7 +163,7 @@ module.exports = class DbCheck { async historicalRarity() { console.log('[DB] Setting historical rarity stats') const results = await Promise.all( - this.models.Pokemon.map(async (source) => + (this.models.Pokemon ?? []).map(async (source) => source.isMad ? [] : source.SubModel.query() @@ -218,13 +222,21 @@ module.exports = class DbCheck { static deDupeResults(results) { if (results.length === 1) return results[0] if (results.length > 1) { - const returnObj = {} - for (let i = 0; i < results.length; i += 1) { - for (let j = 0; j < results[i].length; j += 1) { - returnObj[results[i][j].id] = results[i][j] + const returnObj = new Map() + const { length } = results + for (let i = 0; i < length; i += 1) { + const { length: subLength } = results[i] + for (let j = 0; j < subLength; j += 1) { + const item = results[i][j] + if ( + !returnObj.has(item.id) || + item.updated > returnObj.get(item.id).updated + ) { + returnObj.set(item.id, item) + } } } - return Object.values(returnObj) + return returnObj.values() } return [] } diff --git a/server/src/services/Utility.js b/server/src/services/Utility.js index 5ce5dd65d..8509fc13d 100644 --- a/server/src/services/Utility.js +++ b/server/src/services/Utility.js @@ -5,7 +5,6 @@ const buildDefaultFilters = require('./defaultFilters/buildDefaultFilters') const primaryUi = require('./ui/primary') const advMenus = require('./ui/advMenus') const clientOptions = require('./ui/clientOptions') -const dbSelection = require('./functions/dbSelection') const webhook = require('./ui/webhook') const geocoder = require('./geocoder') const areaPerms = require('./functions/areaPerms') @@ -43,10 +42,6 @@ module.exports = class Utility { return clientOptions(...args) } - static dbSelection(...args) { - return dbSelection(...args) - } - static webhookUi(...args) { return webhook(...args) } diff --git a/server/src/services/defaultFilters/buildDefaultFilters.js b/server/src/services/defaultFilters/buildDefaultFilters.js index e5308af07..0d4e02f5a 100644 --- a/server/src/services/defaultFilters/buildDefaultFilters.js +++ b/server/src/services/defaultFilters/buildDefaultFilters.js @@ -14,7 +14,7 @@ const custom = new PokemonFilter( ...Object.values(defaultFilters.pokemon.globalValues), ) -module.exports = function buildDefault(perms, available) { +module.exports = function buildDefault(perms, available, dbModels) { const stopReducer = perms.pokestops || perms.lures || perms.quests || perms.invasions const gymReducer = perms.gyms || perms.raids @@ -22,129 +22,141 @@ module.exports = function buildDefault(perms, available) { const pokemon = buildPokemon(defaultFilters, base, custom, available) return { - gyms: gymReducer - ? { - enabled: defaultFilters.gyms.enabled, - allGyms: perms.gyms ? defaultFilters.gyms.enabled : undefined, - levels: perms.gyms ? defaultFilters.gyms.levels : undefined, - raids: perms.raids ? defaultFilters.gyms.raids : undefined, - exEligible: perms.gyms ? defaultFilters.gyms.exEligible : undefined, - inBattle: perms.gyms ? defaultFilters.gyms.exEligible : undefined, - arEligible: perms.gyms ? false : undefined, - gymBadges: perms.gymBadges - ? defaultFilters.gyms.gymBadges - : undefined, - badge: perms.gymBadges ? 'all' : undefined, - raidTier: perms.raids ? 'all' : undefined, - filter: { - ...buildGyms(perms, defaultFilters.gyms, available), - ...pokemon.raids, - }, - } - : undefined, - nests: perms.nests - ? { - enabled: defaultFilters.nests.enabled, - pokemon: defaultFilters.nests.pokemon, - polygons: defaultFilters.nests.polygons, - avgFilter: defaultFilters.nests.avgFilter, - filter: pokemon.nests, - } - : undefined, - pokestops: stopReducer - ? { - enabled: defaultFilters.pokestops.enabled, - allPokestops: perms.pokestops - ? defaultFilters.pokestops.enabled - : undefined, - levels: perms.pokestops ? defaultFilters.pokestops.levels : undefined, - lures: perms.lures ? defaultFilters.pokestops.lures : undefined, - quests: perms.quests ? defaultFilters.pokestops.quests : undefined, - showQuestSet: defaultFilters.pokestops.questSet, - invasions: perms.invasions - ? defaultFilters.pokestops.invasions - : undefined, - arEligible: perms.pokestops ? false : undefined, - filter: { - ...buildPokestops(perms, defaultFilters.pokestops, available), - ...pokemon.quests, - }, - } - : undefined, - pokemon: perms.pokemon - ? { - enabled: defaultFilters.pokemon.enabled, - legacy: - pokemonReducer && enableMapJsFilter - ? defaultFilters.pokemon.legacyFilter + gyms: + gymReducer && dbModels.Gym + ? { + enabled: defaultFilters.gyms.enabled, + allGyms: perms.gyms ? defaultFilters.gyms.enabled : undefined, + levels: perms.gyms ? defaultFilters.gyms.levels : undefined, + raids: perms.raids ? defaultFilters.gyms.raids : undefined, + exEligible: perms.gyms ? defaultFilters.gyms.exEligible : undefined, + inBattle: perms.gyms ? defaultFilters.gyms.exEligible : undefined, + arEligible: perms.gyms ? false : undefined, + gymBadges: perms.gymBadges + ? defaultFilters.gyms.gymBadges : undefined, - iv: perms.iv ? true : undefined, - pvp: perms.pvp ? true : undefined, - standard: base, - ivOr: custom, - xsRat: false, - xlKarp: false, - zeroIv: perms.iv ? false : undefined, - hundoIv: perms.iv ? true : undefined, - filter: pokemon.full, - } - : undefined, - portals: perms.portals - ? { - enabled: defaultFilters.portals.enabled, - filter: { - global: new GenericFilter(), - old: new GenericFilter(), - new: new GenericFilter(), - }, - } - : undefined, + badge: perms.gymBadges ? 'all' : undefined, + raidTier: perms.raids ? 'all' : undefined, + filter: { + ...buildGyms(perms, defaultFilters.gyms, available), + ...pokemon.raids, + }, + } + : undefined, + nests: + perms.nests && dbModels.Nest + ? { + enabled: defaultFilters.nests.enabled, + pokemon: defaultFilters.nests.pokemon, + polygons: defaultFilters.nests.polygons, + avgFilter: defaultFilters.nests.avgFilter, + filter: pokemon.nests, + } + : undefined, + pokestops: + stopReducer && dbModels.Pokestop + ? { + enabled: defaultFilters.pokestops.enabled, + allPokestops: perms.pokestops + ? defaultFilters.pokestops.enabled + : undefined, + levels: perms.pokestops + ? defaultFilters.pokestops.levels + : undefined, + lures: perms.lures ? defaultFilters.pokestops.lures : undefined, + quests: perms.quests ? defaultFilters.pokestops.quests : undefined, + showQuestSet: defaultFilters.pokestops.questSet, + invasions: perms.invasions + ? defaultFilters.pokestops.invasions + : undefined, + arEligible: perms.pokestops ? false : undefined, + filter: { + ...buildPokestops(perms, defaultFilters.pokestops, available), + ...pokemon.quests, + }, + } + : undefined, + pokemon: + perms.pokemon && dbModels.Pokemon + ? { + enabled: defaultFilters.pokemon.enabled, + legacy: + pokemonReducer && enableMapJsFilter + ? defaultFilters.pokemon.legacyFilter + : undefined, + iv: perms.iv ? true : undefined, + pvp: perms.pvp ? true : undefined, + standard: base, + ivOr: custom, + xsRat: false, + xlKarp: false, + zeroIv: perms.iv ? false : undefined, + hundoIv: perms.iv ? true : undefined, + filter: pokemon.full, + } + : undefined, + portals: + perms.portals && dbModels.Portal + ? { + enabled: defaultFilters.portals.enabled, + filter: { + global: new GenericFilter(), + old: new GenericFilter(), + new: new GenericFilter(), + }, + } + : undefined, scanAreas: perms.scanAreas ? { enabled: defaultFilters.scanAreas.enabled, filter: { areas: [] }, } : undefined, - submissionCells: perms.submissionCells - ? { - enabled: defaultFilters.submissionCells.enabled, - rings: defaultFilters.submissionCells.rings, - s17Cells: defaultFilters.submissionCells.s17Cells, - s14Cells: defaultFilters.submissionCells.s14Cells, - filter: { global: new GenericFilter() }, - } - : undefined, - weather: perms.weather - ? { - enabled: defaultFilters.weather.enabled, - filter: { global: new GenericFilter() }, - } - : undefined, - spawnpoints: perms.spawnpoints - ? { - enabled: defaultFilters.spawnpoints.enabled, - filter: { - global: new GenericFilter(), - confirmed: new GenericFilter(), - unconfirmed: new GenericFilter(), - }, - } - : undefined, - scanCells: perms.scanCells - ? { - enabled: defaultFilters.scanCells.enabled, - filter: { global: new GenericFilter() }, - } - : undefined, - devices: perms.devices - ? { - enabled: defaultFilters.devices.enabled, - filter: { - online: new GenericFilter(), - offline: new GenericFilter(), - global: new GenericFilter(), - }, - } - : undefined, + submissionCells: + perms.submissionCells && dbModels.Pokestop && dbModels.Gym + ? { + enabled: defaultFilters.submissionCells.enabled, + rings: defaultFilters.submissionCells.rings, + s17Cells: defaultFilters.submissionCells.s17Cells, + s14Cells: defaultFilters.submissionCells.s14Cells, + filter: { global: new GenericFilter() }, + } + : undefined, + weather: + perms.weather && dbModels.Weather + ? { + enabled: defaultFilters.weather.enabled, + filter: { global: new GenericFilter() }, + } + : undefined, + spawnpoints: + perms.spawnpoints && dbModels.Spawnpoint + ? { + enabled: defaultFilters.spawnpoints.enabled, + filter: { + global: new GenericFilter(), + confirmed: new GenericFilter(), + unconfirmed: new GenericFilter(), + }, + } + : undefined, + scanCells: + perms.scanCells && dbModels.ScanCell + ? { + enabled: defaultFilters.scanCells.enabled, + filter: { global: new GenericFilter() }, + } + : undefined, + devices: + perms.devices && dbModels.Device + ? { + enabled: defaultFilters.devices.enabled, + filter: { + online: new GenericFilter(), + offline: new GenericFilter(), + global: new GenericFilter(), + }, + } + : undefined, } } diff --git a/server/src/services/functions/dbSelection.js b/server/src/services/functions/dbSelection.js deleted file mode 100644 index 3d8e8d4f3..000000000 --- a/server/src/services/functions/dbSelection.js +++ /dev/null @@ -1,10 +0,0 @@ -const { - database: { schemas }, -} = require('../config') - -module.exports = function dbSelection(category) { - if (category === 'quest' || category === 'invasion' || category === 'lure') - category = 'pokestop' - if (category === 'raid') category = 'gym' - return schemas.find(({ useFor }) => useFor.includes(category)) -} diff --git a/server/src/services/sessionStore.js b/server/src/services/sessionStore.js index 2e7759cff..c725e5306 100644 --- a/server/src/services/sessionStore.js +++ b/server/src/services/sessionStore.js @@ -5,13 +5,13 @@ const MySQLStore = require('express-mysql-session')(session) const { api: { maxSessions }, database: { + schemas, settings: { sessionTableName }, }, } = require('./config') -const Utility = require('./Utility') const { Session } = require('../models/index') -const dbSelection = Utility.dbSelection('session') +const dbSelection = schemas.find(({ useFor }) => useFor?.includes('session')) // MySQL session store const sessionStore = new MySQLStore({ diff --git a/server/src/services/ui/clientOptions.js b/server/src/services/ui/clientOptions.js index 6720dd0a6..a1bb162f0 100644 --- a/server/src/services/ui/clientOptions.js +++ b/server/src/services/ui/clientOptions.js @@ -5,7 +5,6 @@ const { pvp: { levels }, }, } = require('../config') -const dbSelection = require('../functions/dbSelection') module.exports = function clientOptions(perms) { // the values here are the relevant perms to use them, they are looped through and the values are set based on your config, then the type is set based off of those values in the above function @@ -81,9 +80,6 @@ module.exports = function clientOptions(perms) { if (clientSideOptions.pokemon.glow.length) { clientMenus.pokemon.glow = { type: 'bool', sub: {}, perm: ['pokemon'] } } - if (dbSelection('pokestop').type === 'mad') { - clientMenus.pokestops.madQuestText = { type: 'bool', perm: ['quests'] } - } // only the keys & values are stored locally const clientValues = {} diff --git a/src/components/popups/Device.jsx b/src/components/popups/Device.jsx index c1807f9e5..961fb0489 100644 --- a/src/components/popups/Device.jsx +++ b/src/components/popups/Device.jsx @@ -32,8 +32,8 @@ export default function DevicePopup({ device, isOnline, ts }) { } const Timer = ({ device, t, ts }) => { - const { last_seen } = device - const lastSeen = new Date(last_seen * 1000) + const { updated } = device + const lastSeen = new Date(updated * 1000) const [since, setSince] = useState(Utility.getTimeUntil(lastSeen)) useEffect(() => { @@ -45,7 +45,7 @@ const Timer = ({ device, t, ts }) => { return ( - {t('last_seen')}: {Utility.dayCheck(ts, last_seen)} ( + {t('last_seen')}: {Utility.dayCheck(ts, updated)} ( {since.str.replace('days', t('days')).replace('day', t('day'))}) ) diff --git a/src/components/tiles/Device.jsx b/src/components/tiles/Device.jsx index 4c7a9912d..084bc2d87 100644 --- a/src/components/tiles/Device.jsx +++ b/src/components/tiles/Device.jsx @@ -8,7 +8,7 @@ import DevicePoly from '../popups/DevicePoly' const DeviceTile = ({ item, ts, Icons, userSettings }) => { const [poly, setPoly] = useState(false) const markerRef = useRef(null) - const isOnline = ts - item.last_seen < 900 + const isOnline = ts - item.updated < 900 useEffect(() => { if (poly && markerRef) { @@ -40,6 +40,6 @@ const areEqual = (prev, next) => prev.item.type === next.item.type && prev.item.last_lat === next.item.last_lat && prev.item.last_lon === next.item.last_lon && - prev.item.last_seen === next.item.last_seen + prev.item.updated === next.item.updated export default memo(DeviceTile, areEqual) diff --git a/src/services/queries/device.js b/src/services/queries/device.js index ec39878a8..4743cdfe2 100644 --- a/src/services/queries/device.js +++ b/src/services/queries/device.js @@ -5,7 +5,7 @@ const getAllDevices = gql` devices(filters: $filters) { id instance_name - last_seen + updated last_lat last_lon route