From 71570118b0199e08411e397183cc841eee31353a Mon Sep 17 00:00:00 2001 From: toast-ts <96593068+toast-ts@users.noreply.github.com> Date: Mon, 27 Feb 2023 10:45:56 +1100 Subject: [PATCH] Overhaul '/mp url' for new database. --- src/client.ts | 5 +-- src/commands/mp.ts | 73 ++++++++++++++++-------------------------- src/index.ts | 45 ++++++++++++-------------- src/models/MPServer.ts | 58 ++++++++++++++------------------- 4 files changed, 74 insertions(+), 107 deletions(-) diff --git a/src/client.ts b/src/client.ts index 80540a5..3045e09 100644 --- a/src/client.ts +++ b/src/client.ts @@ -8,7 +8,7 @@ import bannedWords from './models/bannedWords'; import userLevels from './models/userLevels'; import punishments from './models/punishments'; import bonkCount from './models/bonkCount'; -import MPDB from './models/MPServer'; +import MPServer from './models/MPServer'; import axios from 'axios'; import moment from 'moment'; import tokens from './tokens.json'; @@ -43,6 +43,7 @@ export default class TClient extends Client { punishments: punishments; bonkCount: bonkCount; bannedWords: bannedWords; + MPServer: MPServer; repeatedMessages: repeatedMessages; statsGraph: number; @@ -81,12 +82,12 @@ export default class TClient extends Client { this.bonkCount = new bonkCount(this); this.punishments = new punishments(this); this.bannedWords = new bannedWords(this); + this.MPServer = new MPServer(this); this.repeatedMessages = {}; this.setMaxListeners(80); this.statsGraph = -60; } async init(){ - MPDB.sync(); mongoose.set('strictQuery', true); await mongoose.connect(this.tokens.mongodb_uri, { autoIndex: true, diff --git a/src/commands/mp.ts b/src/commands/mp.ts index a53884d..9f0ad22 100644 --- a/src/commands/mp.ts +++ b/src/commands/mp.ts @@ -1,30 +1,28 @@ -import Discord,{EmbedBuilder, SlashCommandBuilder} from 'discord.js'; -import MPDB from '../models/MPServer'; +import Discord,{SlashCommandBuilder} from 'discord.js'; import TClient from 'src/client'; import path from 'node:path'; import canvas from 'canvas'; import fs from 'node:fs'; -async function MPdata(client:TClient, interaction:Discord.ChatInputCommandInteraction, embed: EmbedBuilder) { +async function MPdata(client:TClient, interaction:Discord.ChatInputCommandInteraction, embed: Discord.EmbedBuilder) { let FSserver; - MPDB.sync(); - if (!await MPDB.findOne({where: {serverId: interaction.guildId}})) return interaction.reply('This server isn\'t linked.') - const ServerURL = await MPDB.findOne({where: { serverId: interaction.guildId }}); - if (!ServerURL) return interaction.reply(`No gameserver found, please contact <@&${client.config.mainServer.roles.mpmanager}> to add it.`) - const DBURL = ServerURL.ip - const DBCode = ServerURL.code - const verifyURL = DBURL.match(/http/) - const completedURL = DBURL + '/feed/dedicated-server-stats.json?code=' + DBCode - if (!verifyURL) return interaction.reply(`Invalid gameserver IP, please contact <@&${client.config.mainServer.roles.mpmanager}> to update it.`) + if (!await client.MPServer._content.findOne({_id:interaction.guildId})) return interaction.reply('This server isn\'t linked to the bot.'); + const ServerURL = await client.MPServer._content.findById(interaction.guildId); + if (!ServerURL) return interaction.reply(`No FS server found, please notify <@&${client.config.mainServer.roles.mpmanager}> to add it.`) + const MPURL = ServerURL.ip + const MPCode = ServerURL.code + const verifyURL = MPURL.match(/http|https/) + const completedURL = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode + if (!verifyURL) return interaction.reply(`The server IP for this server is currently invalid, please notify <@&${client.config.mainServer.roles.mpmanager}>`) // Fetch dss try { // v I am aware timeout has decreased from 2800 to 2588 to fit within Discord's interaction timeouts (3s) -Toast - FSserver = await client.axios.get(completedURL, {timeout: 2588, headers: {'User-Agent': `Daggerbot - mp cmd/axios ${client.axios.VERSION}`}}) // Finally got around to fixing the command when it cannot ping the host. + FSserver = await client.axios.get(completedURL, {timeout: 2588, headers: {'User-Agent': `Daggerbot - mp cmd/axios ${client.axios.VERSION}`}}) } catch(err) { // Blame Nawdic & RedRover92 embed.setTitle('Host is not responding.'); embed.setColor(client.config.embedColorRed); - console.log(client.logTime, 'dag mp fail to fetch, host is not responding.'); + console.log(client.logTime(), 'DagMP failed to fetch, host didn\'t respond in time.'); return interaction.reply('Server didn\'t respond in time.'); } return FSserver @@ -33,9 +31,7 @@ async function MPdata(client:TClient, interaction:Discord.ChatInputCommandIntera export default { async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ if (interaction.channelId == '468835769092669461' && !client.isStaff(interaction.member) && ['status', 'players'].includes(interaction.options.getSubcommand())) { - interaction.reply(`Please use <#739084625862852715> for \`/mp status/players\` commands to prevent clutter in this channel.`).then((msg)=>{ - setTimeout(()=>{interaction.deleteReply()}, 6000) - }); + interaction.reply(`Please use <#739084625862852715> for \`/mp status/players\` commands to prevent clutter in this channel.`).then((msg)=>{setTimeout(()=>{interaction.deleteReply()}, 6000)}); return; } ({ @@ -53,43 +49,38 @@ export default { {name: 'In-game Time', value: `${('0' + Math.floor((FSserver0.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSserver0.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true} ) interaction.reply({embeds: [embed0]}) - } else if (FSserver0.data.server.name.length == 0) { - interaction.reply('Server is currently offline.') - } + } else if (FSserver0.data.server.name.length == 0) interaction.reply('Server is currently offline.') } catch (err){ console.log(err) - interaction.reply('FSserver0 Placeholder') + interaction.reply('FSserver0 Error placeholder') }; }, info: async()=>{ const embed2 = new client.embed().setColor(client.config.embedColor) const FSserver2 = await MPdata(client, interaction, embed2) if (!FSserver2?.data) return console.log('FSserver2 failed - info') - const DBURL = MPDB.findOne({where: {serverId: interaction.guildId}}) + const MPURL = await client.MPServer._content.findById(interaction.guildId); embed2.setDescription([ `**Server name**: \`${FSserver2?.data.server.name.length == 0 ? '\u200b' : FSserver2?.data.server.name}\``, '**Password:** `mf4700`', '**Crossplay server**', `**Map:** ${FSserver2.data.server.mapName.length == 0 ? 'Null Island' : FSserver2.data.server.mapName}`, - `**Mods:** [Click here](${(await DBURL).ip}/mods.html) **|** [Direct Download](${(await DBURL).ip}/all_mods_download?onlyActive=true)`, + `**Mods:** [Click here](${MPURL.ip}/mods.html) **|** [Direct Download](${MPURL.id}/all_mods_download?onlyActive=true)`, '**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)', 'Please see <#543494084363288637> for additional information.' ].join('\n')); - if (FSserver2?.data.server.name.length == 0){ - embed2.setFooter({text: 'Server is currently offline.'}) - } + if (FSserver2?.data.server.name.length == 0) embed2.setFooter({text: 'Server is currently offline.'}) interaction.reply({embeds: [embed2]}) }, url: async()=>{ if (!interaction.member.roles.cache.has(client.config.mainServer.roles.mpmanager) && !interaction.member.roles.cache.has(client.config.mainServer.roles.bottech) && !interaction.member.roles.cache.has(client.config.mainServer.roles.admin)) return client.youNeedRole(interaction, 'mpmanager'); - MPDB.sync(); const address = interaction.options.getString('address'); if (!address){ try { - const Url = await MPDB.findOne({where:{serverId: interaction.guildId}}) - if (Url.ip && Url.code){return interaction.reply(`${Url.get('ip')}` + '/feed/dedicated-server-stats.json?code=' + `${Url.get('code')}`)} + const Url = await client.MPServer._content.findById(interaction.guildId); + if (Url.ip && Url.code) return interaction.reply(`${Url.get('ip')}`+'/feed/dedicated-server-stats.json?code='+`${Url.get('code')}`) } catch(err){ - console.log(`MPDB | ${err}`) + console.log(`MPDB :: ${err}`) interaction.reply('**Database error:**\nTry inserting an URL first.') } }else{ @@ -97,23 +88,13 @@ export default { if (!verifyURL) return interaction.reply('The URL does not match `dedicated-server-stats.xml`') const newURL = address.replace('xml','json').split('/feed/dedicated-server-stats.json?code=') try{ - console.log(`MPDB | URL for ${interaction.guild.name} has been updated by ${interaction.member.displayName} (${interaction.member.id})`); - const Url = await MPDB.create({ - serverId: interaction.guildId, - ip: newURL[0], - code: newURL[1], - timesUpdated: 0 - }); - return interaction.reply(`Successfully set the URL to ${Url.ip}`) + console.log(`MPDB :: URL for ${interaction.guild.name} has been updated by ${interaction.member.displayName} (${interaction.member.id})`); + await client.MPServer._content.create({_id: interaction.guildId, ip: newURL[0], code: newURL[1], timesUpdated: 0}) + return interaction.reply('This server is now linked and URL has been added.'); } catch(err){ - if (err.name == 'SequelizeUniqueConstraintError'){ - const AffectedRows = await MPDB.update({ip: newURL[0], code: newURL[1]},{where:{serverId: interaction.guildId}}); - await MPDB.increment('timesUpdated',{where:{serverId: interaction.guildId}}); - if (AffectedRows) return interaction.reply(`Successfully updated the URL to ${newURL[0]}`) - }else{ - console.log(err) - interaction.reply(`\`MPDB\` has caught an error, notify <@&${client.config.mainServer.roles.bottech}>`) - } + const affectedValues = await client.MPServer._content.findByIdAndUpdate({_id: interaction.guildId}, {ip: newURL[0], code: newURL[1]}); + await client.MPServer._increment(interaction.guildId); + if (affectedValues) return interaction.reply('URL successfully updated.') } } }, diff --git a/src/index.ts b/src/index.ts index b5ce366..f73bf7e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,6 @@ import TClient from './client'; const client = new TClient; client.init(); import fs from 'node:fs'; -import MPDB from './models/MPServer'; import {FSData, FSCareerSavegame} from './typings/interfaces'; client.on('ready', async()=>{ @@ -44,13 +43,12 @@ setInterval(async()=>{ let error; // Connect to DB to retrieve the Gameserver info to fetch data. - MPDB.sync(); - const ServerURL = MPDB.findOne({where: {serverId: client.config.mainServer.id}}) - const DBURL = (await ServerURL).ip - const DBCode = (await ServerURL).code - const verifyURL = DBURL.match(/http/); - const completedURL_DSS = DBURL + '/feed/dedicated-server-stats.json?code=' + DBCode - const completedURL_CSG = DBURL + '/feed/dedicated-server-savegame.html?code=' + DBCode + '&file=careerSavegame' + const ServerURL = await client.MPServer._content.findById(client.config.mainServer.id); + const MPURL = ServerURL.ip; + const MPCode = ServerURL.code; + const verifyURL = MPURL.match(/http|https/); + const completedURL_DSS = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode; + const completedURL_CSG = MPURL+'/feed/dedicated-server-savegame.html?code='+MPCode+'&file=careerSavegame'; const FSdss = { data: {} as FSData, fetchResult: '' as string @@ -59,30 +57,27 @@ setInterval(async()=>{ data: {} as FSCareerSavegame, fetchResult: '' as string }; - if (!verifyURL) return msg.edit({content: 'Invalid gameserver IP, please update!', embeds: null}) + if (!verifyURL) return msg.edit({content: '*Detected an invalid IP.*', embeds: null}) async function serverData(client:TClient, URL: string){ return await client.axios.get(URL, {timeout: 4000, maxContentLength: Infinity, headers: {'User-Agent': `Daggerbot/axios ${client.axios.VERSION}`}}).catch((error:Error)=>error.message) } await Promise.all([serverData(client, completedURL_DSS), serverData(client, completedURL_CSG)]).then(function(results){ if (typeof results[0] == 'string'){ - FSdss.fetchResult = `dag mp dss fail, ${results[0]}`; + FSdss.fetchResult = `DagMP DSS failed, ${results[0]}`; embed.addFields({name: 'DSS Status', value: results[0]}) } else if (results[0].status != 200){ - FSdss.fetchResult = `dag mp dss fail with ${results[0].status + ' ' + results[0].statusText}`; + FSdss.fetchResult = `DagMP DSS failed with ${results[0].status + ' ' + results[0].statusText}`; embed.addFields({name: 'DSS Status', value: results[0].status + ' ' + results[0].statusText}) - } else { - FSdss.data = results[0].data as FSData - } + } else FSdss.data = results[0].data as FSData + if (typeof results[1] == 'string'){ - FScsg.fetchResult = `dag mp csg fail, ${results[1]}`; + FScsg.fetchResult = `DagMP CSG failed, ${results[1]}`; embed.addFields({name: 'CSG Status', value: results[1]}) } else if (results[1].status != 200){ - if (results[1].status == 204){embed.setImage('https://http.cat/204')} - FScsg.fetchResult = `dag mp csg fail with ${results[1].status + ' ' + results[1].statusText}`; + if (results[1].status == 204) embed.setImage('https://http.cat/204'); + FScsg.fetchResult = `DagMP CSG failed with ${results[1].status + ' ' + results[1].statusText}`; embed.addFields({name: 'CSG Status', value: results[1].status + ' ' + results[1].statusText}) - } else { - FScsg.data = client.xjs.xml2js(results[1].data,{compact:true,spaces:2}).careerSavegame as FSCareerSavegame; - } + } else FScsg.data = client.xjs.xml2js(results[1].data,{compact:true,spaces:2}).careerSavegame as FSCareerSavegame; }).catch((error)=>console.log(error)) if (FSdss.fetchResult.length != 0){ error = true; @@ -115,11 +110,11 @@ setInterval(async()=>{ msg.edit({content: 'This embed will resume when server is back online.', embeds: [embed]}) } else { const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Server details').addFields( - {name: 'Current Map', value: `${FSdss.data.server.mapName.length == 0 ? '\u200b' : FSdss.data.server.mapName}`, inline: true}, - {name: 'Version', value: `${FSdss.data.server.version.length == 0 ? '\u200b' : FSdss.data.server.version}`, inline: true}, - {name: 'In-game Time', value: `${('0' + Math.floor((FSdss.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSdss.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}, - {name: 'Slot Usage', value: `${slotSystem}`, inline: true}, - {name: 'Timescale', value: `${timeScale}`, inline: true} + {name: 'Current Map', value: `${FSdss.data.server.mapName.length == 0 ? '\u200b' : FSdss.data.server.mapName}`, inline: true}, + {name: 'Version', value: `${FSdss.data.server.version.length == 0 ? '\u200b' : FSdss.data.server.version}`, inline: true}, + {name: 'In-game Time', value: `${('0' + Math.floor((FSdss.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSdss.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}, + {name: 'Slot Usage', value: `${slotSystem}`, inline: true}, + {name: 'Timescale', value: `${timeScale}`, inline: true} ); FSdss.data.slots.players.filter((x)=>x.isUsed !== false).forEach(player=>{ Players.push(`**${player.name} ${player.isAdmin ? '| admin' : ''}**\nFarming for ${(Math.floor(player.uptime/60))} hr & ${('' + (player.uptime % 60)).slice(-2)} min`) diff --git a/src/models/MPServer.ts b/src/models/MPServer.ts index eb1ba2c..bddc8aa 100644 --- a/src/models/MPServer.ts +++ b/src/models/MPServer.ts @@ -1,35 +1,25 @@ -import {Sequelize, DataTypes, Model, InferAttributes, InferCreationAttributes} from 'sequelize'; -var db = new Sequelize('database', 'daggerbot', 'toastsus', { - host: 'localhost', - dialect: 'sqlite', - logging: false, - storage: 'src/database/MPDB.dat' -}) -class MPDB extends Model, InferCreationAttributes>{ - declare serverId: string | null; - declare ip: string | null; - declare code: string | null; - declare timesUpdated: number | null; +import TClient from 'src/client'; +import mongoose from 'mongoose'; + +const Schema = mongoose.model('mpserver', new mongoose.Schema({ + _id: {type: String, required:true}, + ip: {type: String}, + code: {type: String}, + timesUpdated: {type: Number, required: true} +}, {versionKey: false})); + +export default class MPServer extends Schema { + client: TClient; + _content: typeof Schema; + constructor(client:TClient){ + super(); + this.client = client; + this._content = Schema; + } + async _increment(serverId: string){ + const server = await this._content.findById(serverId) + if (server) await this._content.findByIdAndUpdate(server, {timesUpdated: server.timesUpdated + 1}) + else await this._content.create({_id:serverId, timesUpdated: 1}) + //console.log(`[${serverId}] :: timesUpdated value incremented`) + } } -MPDB.init({ - serverId: { - type: DataTypes.STRING, - unique: true - }, - ip: { - type: DataTypes.STRING, - defaultValue: 'Missing IP', - allowNull: false - }, - code: { - type: DataTypes.STRING, - defaultValue: 'Missing Code', - allowNull: false - }, - timesUpdated: { - type: DataTypes.INTEGER, - defaultValue: 0, - allowNull: false - } -}, { sequelize: db, modelName: 'urls', timestamps: false }); -export default MPDB \ No newline at end of file