Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File based filter configuration #606

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ logs/*
config/*.json
config/customMaps/*
config/dts/*.json
config/filters/*.json
docker-compose.yml
.cache/*
.idea
Expand Down
20 changes: 0 additions & 20 deletions config/defaults/custom.en.json.emoji-override

This file was deleted.

Empty file added config/filters/.keep
Empty file.
43 changes: 43 additions & 0 deletions src/lib/channelConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const stripJsonComments = require('strip-json-comments')
const fs = require('fs')
const path = require('path')

async function processChannelConfig(trackManager, filterLogic) {
let channels

try {
const filterText = stripJsonComments(fs.readFileSync(path.join(__dirname, '../../config/channels.json'), 'utf8'))
channels = JSON.parse(filterText)
} catch (err) {
throw new Error(`channels.json - ${err.message}`)
}

if (channels.clones) {
for (const [id, destinations] of Object.entries(channels.clones)) {
const targets = []
for (const destId of destinations) {
targets.push(...await trackManager.resolveId(destId))
}
for (const destId of targets) {
await trackManager.copy(id, 0, destId, 0)
}
}
}

if (channels.filters) {
for (const [id, filters] of Object.entries(channels.filters)) {
const targets = []
targets.push(...await trackManager.resolveId(id))

for (const destId of targets) {
const profileNo = await trackManager.getProfileNo(destId)
await trackManager.reset(destId, profileNo)
for (const filter of filters) {
await filterLogic.applyFilter(id, profileNo, filter, false)
}
}
}
}
}

module.exports = processChannelConfig
13 changes: 13 additions & 0 deletions src/lib/discord/commando/commands/addfilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const PoracleDiscordMessage = require('../../poracleDiscordMessage')
const PoracleDiscordState = require('../../poracleDiscordState')

const commandLogic = require('../../../poracleMessage/commands/addfilter')

exports.run = async (client, msg, command) => {
const pdm = new PoracleDiscordMessage(client, msg)
const pds = new PoracleDiscordState(client)

for (const c of command) {
await commandLogic.run(pds, pdm, c)
}
}
11 changes: 11 additions & 0 deletions src/lib/discord/commando/commands/channelsync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const PoracleDiscordMessage = require('../../poracleDiscordMessage')
const PoracleDiscordState = require('../../poracleDiscordState')

const commandLogic = require('../../../poracleMessage/commands/channelsync')

exports.run = async (client, msg, command) => {
const pdm = new PoracleDiscordMessage(client, msg)
const pds = new PoracleDiscordState(client)

await commandLogic.run(pds, pdm, command[0])
}
11 changes: 11 additions & 0 deletions src/lib/discord/commando/commands/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const PoracleDiscordMessage = require('../../poracleDiscordMessage')
const PoracleDiscordState = require('../../poracleDiscordState')

const commandLogic = require('../../../poracleMessage/commands/copy')

exports.run = async (client, msg, command) => {
const pdm = new PoracleDiscordMessage(client, msg)
const pds = new PoracleDiscordState(client)

await commandLogic.run(pds, pdm, command[0])
}
13 changes: 13 additions & 0 deletions src/lib/discord/commando/commands/reset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const PoracleDiscordMessage = require('../../poracleDiscordMessage')
const PoracleDiscordState = require('../../poracleDiscordState')

const commandLogic = require('../../../poracleMessage/commands/reset')

exports.run = async (client, msg, command) => {
const pdm = new PoracleDiscordMessage(client, msg)
const pds = new PoracleDiscordState(client)

for (const c of command) {
await commandLogic.run(pds, pdm, c)
}
}
114 changes: 114 additions & 0 deletions src/lib/filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const fs = require('fs')
const stripJsonComments = require('strip-json-comments')
const path = require('path')

class FilterProcessor {
constructor(config, query, trackingChanger) {
this.query = query
this.config = config
this.trackingChanger = trackingChanger
}

// eslint-disable-next-line class-methods-use-this
async loadFilter(filterName) {
let filter

try {
const filterText = stripJsonComments(fs.readFileSync(path.join(__dirname, '../../config/filters', `${filterName}.json`), 'utf8'))
filter = JSON.parse(filterText)
} catch (err) {
throw new Error(`filters/${filterName}.json - ${err.message}`)
}

return filter
}

async applyFilter(id, profileNo, filterName, performUserChecks) {
let filter = await this.loadFilter(filterName)
let messages = ''

if (filter.based_on) {
// Load other filters
const filterStack = [[filterName, filter]]
let currentFilter = filter
while (currentFilter.based_on) {
// check here for circular reference ==> crash
const baseFilter = await this.loadFilter(currentFilter.based_on)
filterStack.unshift([currentFilter.based_on, baseFilter])
currentFilter = baseFilter
}

// Now combine filters

filter = {}
for (const [, addition] of filterStack) {
for (const category of ['pokemon', 'egg']) {
if (addition[category]) {
if (!(category in filter)) filter[category] = {}
Object.assign(filter[category], addition[category])
}
}
}
}
if (filter.pokemon) {
messages += await this.applyPokemonFilter(id, profileNo, filter.pokemon, performUserChecks)
}

return messages
}

async applyPokemonFilter(id, profileNo, filter, performUserChecks) {
const defaultTo = ((value, x) => ((value === undefined) ? x : value))

if (filter.pokemon.length === 0) filter.pokemon = [0]

const insert = filter.pokemon.map((pokemonId) => {
let distance
if (performUserChecks) {
distance = +filter.distance || this.config.tracking.defaultDistance || 0
distance = Math.min(distance, this.config.tracking.maxDistance || 40000000) // circumference of Earth
} else {
distance = +defaultTo(filter.distance, 0)
}

const newRow = {
id,
profile_no: profileNo,
ping: defaultTo(filter.ping, ''),
template: (filter.template || this.config.general.defaultTemplateName).toString(),
pokemon_id: +pokemonId,
distance: +distance,
min_iv: +defaultTo(filter.min_iv, -1),
max_iv: +defaultTo(filter.max_iv, 100),
min_cp: +defaultTo(filter.min_cp, 0),
max_cp: +defaultTo(filter.max_cp, 9000),
min_level: +defaultTo(filter.min_level, 0),
max_level: +defaultTo(filter.max_level, 40),
atk: +defaultTo(filter.atk, 0),
def: +defaultTo(filter.def, 0),
sta: +defaultTo(filter.sta, 0),
min_weight: +defaultTo(filter.min_weight, 0),
max_weight: +defaultTo(filter.max_weight, 9000000),
form: +defaultTo(filter.form, 0),
max_atk: +defaultTo(filter.max_atk, 15),
max_def: +defaultTo(filter.max_def, 15),
max_sta: +defaultTo(filter.max_sta, 15),
gender: +defaultTo(filter.gender, 0),
clean: +defaultTo(filter.clean, 0),
pvp_ranking_league: +defaultTo(filter.pvp_ranking_league, 0),
pvp_ranking_best: +defaultTo(filter.pvp_ranking_best, 1),
pvp_ranking_worst: +defaultTo(filter.pvp_ranking_worst, 4096),
pvp_ranking_min_cp: +defaultTo(filter.pvp_ranking_min_cp, 0),
rarity: +defaultTo(filter.rarity, -1),
max_rarity: +defaultTo(filter.max_rarity, 6),
min_time: +defaultTo(filter.min_time, 0),
}

return newRow
})

return this.trackingChanger.applyMonsters(insert, id, profileNo)
}
}

module.exports = FilterProcessor
39 changes: 39 additions & 0 deletions src/lib/poracleMessage/commands/addfilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const FilterLogic = require('../../filters')
const TrackingChangeLogic = require('../../trackingChangeLogic')

exports.run = async (client, msg, args, options) => {
const logReference = Math.random().toString().slice(2, 11)

try {
// Check target
const util = client.createUtil(msg, options)

const {
canContinue, target, language, currentProfileNo,
} = await util.buildTarget(args)

if (!canContinue) return
const commandName = __filename.slice(__dirname.length + 1, -3)
client.log.info(`${logReference}: ${target.name}/${target.type}-${target.id}: ${commandName} ${args}`)

const translator = client.translatorFactory.Translator(language)

if (!await util.commandAllowed(commandName) && !args.find((arg) => arg === 'remove')) {
await msg.react('🚫')
return msg.reply(translator.translate('You do not have permission to execute this command'))
}

const trackingChanger = new TrackingChangeLogic(client.config, client.query, client.scannerQuery, translator, client.GameData)
const filterLogic = new FilterLogic(client.config, client.query, trackingChanger)

let message = ''
for (const filterName of args) {
message += await filterLogic.applyFilter(target.id, currentProfileNo, filterName, !msg.isFromAdmin)
}

await msg.reply(message)
await msg.react('✅')
} catch (err) {
client.log.error(`addfilter command ${msg.content} unhappy:`, err)
}
}
33 changes: 33 additions & 0 deletions src/lib/poracleMessage/commands/channelsync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const TrackingChangeLogic = require('../../trackingChangeLogic')
const FilterLogic = require('../../filters')
const channelConfig = require('../../channelConfig')

exports.run = async (client, msg, args, options) => {
const logReference = Math.random().toString().slice(2, 11)

try {
if (!msg.isFromAdmin) return await msg.react('🙅')

// Check target
const util = client.createUtil(msg, options)

const {
canContinue, target, language,
} = await util.buildTarget(args)

if (!canContinue) return
const commandName = __filename.slice(__dirname.length + 1, -3)
client.log.info(`${logReference}: ${target.name}/${target.type}-${target.id}: ${commandName} ${args}`)

const translator = client.translatorFactory.Translator(language)

const trackingChanger = new TrackingChangeLogic(client.config, client.query, client.scannerQuery, translator, client.GameData)
const filterLogic = new FilterLogic(client.config, client.query, trackingChanger)

await channelConfig(trackingChanger, filterLogic)

await msg.react('✅')
} catch (err) {
client.log.error(`channelsync command ${msg.content} unhappy:`, err)
}
}
49 changes: 49 additions & 0 deletions src/lib/poracleMessage/commands/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const TrackingChangeLogic = require('../../trackingChangeLogic')

exports.run = async (client, msg, args, options) => {
const logReference = Math.random().toString().slice(2, 11)

try {
if (!msg.isFromAdmin) return await msg.react('🙅')

// Check target
const util = client.createUtil(msg, options)

const {
canContinue, target, language, currentProfileNo,
} = await util.buildTarget(args)

if (!canContinue) return
const commandName = __filename.slice(__dirname.length + 1, -3)
client.log.info(`${logReference}: ${target.name}/${target.type}-${target.id}: ${commandName} ${args}`)

const translator = client.translatorFactory.Translator(language)

if (args.length < 2 || !['from', 'to'].includes(args[0])) {
return await msg.reply(
translator.translateFormat('Valid commands are e.g. `{0}copy from <id>`, `{0}copy to <id> <id> <id>`', util.prefix),
{ style: 'markdown' },
)
}

const trackingChanger = new TrackingChangeLogic(client.config, client.query, client.scannerQuery, translator, client.GameData)

if (args[0] === 'to') {
for (let x = 1; x < args.length; x++) {
const targets = []
targets.push(...await trackingChanger.resolveId(args[x]))

for (const destId of targets) {
await trackingChanger.copy(target.id, currentProfileNo, destId, 0)
}
}
} else {
// from
await trackingChanger.copy(args[1], 0, target.id, currentProfileNo)
}

await msg.react('✅')
} catch (err) {
client.log.error(`addfilter command ${msg.content} unhappy:`, err)
}
}
Loading