diff --git a/.pnp.cjs b/.pnp.cjs index 17ebbd8..eeec8b6 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -31,7 +31,7 @@ const RAW_RUNTIME_STATE = ["@sequelize/core", "virtual:20c353e2d6536e37339997f03975c6a660f4d296e664d291bd43620c6162cca8eb5ef90b0998dc9db75ff6862e5da587d0530bae26805f5fadc8f17aaa4ff794#npm:7.0.0-alpha.37"],\ ["@toast/tokenservice-client", "npm:1.0.12::__archiveUrl=https%3A%2F%2Fgit.toast-server.net%2Fapi%2Fpackages%2Ftoast%2Fnpm%2F%2540toast%252Ftokenservice-client%2F-%2F1.0.12%2Ftokenservice-client-1.0.12.tgz"],\ ["@types/ms", "npm:0.7.34"],\ - ["@types/node", "npm:20.11.21"],\ + ["@types/node", "npm:20.11.22"],\ ["@types/node-cron", "npm:3.0.11"],\ ["@types/pg", "npm:8.11.2"],\ ["ansi-colors", "npm:4.1.3"],\ @@ -54,10 +54,10 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@babel/runtime", [\ - ["npm:7.23.9", {\ - "packageLocation": "./.yarn/cache/@babel-runtime-npm-7.23.9-3b96e23cc2-9a520fe1bf.zip/node_modules/@babel/runtime/",\ + ["npm:7.24.0", {\ + "packageLocation": "./.yarn/cache/@babel-runtime-npm-7.24.0-7eb1dd11a2-8d32c7e116.zip/node_modules/@babel/runtime/",\ "packageDependencies": [\ - ["@babel/runtime", "npm:7.23.9"],\ + ["@babel/runtime", "npm:7.24.0"],\ ["regenerator-runtime", "npm:0.14.1"]\ ],\ "linkType": "HARD"\ @@ -151,10 +151,10 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@fastify/busboy", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/@fastify-busboy-npm-2.1.0-960844a007-f22c1e5c52.zip/node_modules/@fastify/busboy/",\ + ["npm:2.1.1", {\ + "packageLocation": "./.yarn/cache/@fastify-busboy-npm-2.1.1-455d8b6bf5-2bb8a7eca8.zip/node_modules/@fastify/busboy/",\ "packageDependencies": [\ - ["@fastify/busboy", "npm:2.1.0"]\ + ["@fastify/busboy", "npm:2.1.1"]\ ],\ "linkType": "HARD"\ }]\ @@ -738,10 +738,10 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@types/node", [\ - ["npm:20.11.21", {\ - "packageLocation": "./.yarn/cache/@types-node-npm-20.11.21-0adac022b0-a31ecc6a3c.zip/node_modules/@types/node/",\ + ["npm:20.11.22", {\ + "packageLocation": "./.yarn/cache/@types-node-npm-20.11.22-9da21a332b-855058a432.zip/node_modules/@types/node/",\ "packageDependencies": [\ - ["@types/node", "npm:20.11.21"],\ + ["@types/node", "npm:20.11.22"],\ ["undici-types", "npm:5.26.5"]\ ],\ "linkType": "HARD"\ @@ -761,7 +761,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/@types-pg-npm-8.11.2-bdf321bea4-7c05cf63be.zip/node_modules/@types/pg/",\ "packageDependencies": [\ ["@types/pg", "npm:8.11.2"],\ - ["@types/node", "npm:20.11.21"],\ + ["@types/node", "npm:20.11.22"],\ ["pg-protocol", "npm:1.6.0"],\ ["pg-types", "npm:4.0.2"]\ ],\ @@ -782,7 +782,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/@types-ws-npm-8.5.10-a877a38f71-9b414dc5e0.zip/node_modules/@types/ws/",\ "packageDependencies": [\ ["@types/ws", "npm:8.5.10"],\ - ["@types/node", "npm:20.11.21"]\ + ["@types/node", "npm:20.11.22"]\ ],\ "linkType": "HARD"\ }],\ @@ -790,7 +790,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/@types-ws-npm-8.5.9-91d1b2ab07-7cf66383b8.zip/node_modules/@types/ws/",\ "packageDependencies": [\ ["@types/ws", "npm:8.5.9"],\ - ["@types/node", "npm:20.11.21"]\ + ["@types/node", "npm:20.11.22"]\ ],\ "linkType": "HARD"\ }]\ @@ -878,7 +878,7 @@ const RAW_RUNTIME_STATE = ["@sequelize/core", "virtual:20c353e2d6536e37339997f03975c6a660f4d296e664d291bd43620c6162cca8eb5ef90b0998dc9db75ff6862e5da587d0530bae26805f5fadc8f17aaa4ff794#npm:7.0.0-alpha.37"],\ ["@toast/tokenservice-client", "npm:1.0.12::__archiveUrl=https%3A%2F%2Fgit.toast-server.net%2Fapi%2Fpackages%2Ftoast%2Fnpm%2F%2540toast%252Ftokenservice-client%2F-%2F1.0.12%2Ftokenservice-client-1.0.12.tgz"],\ ["@types/ms", "npm:0.7.34"],\ - ["@types/node", "npm:20.11.21"],\ + ["@types/node", "npm:20.11.22"],\ ["@types/node-cron", "npm:3.0.11"],\ ["@types/pg", "npm:8.11.2"],\ ["ansi-colors", "npm:4.1.3"],\ @@ -1169,7 +1169,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/mathjs-npm-12.4.0-4e73cebf2f-ee168a7e4b.zip/node_modules/mathjs/",\ "packageDependencies": [\ ["mathjs", "npm:12.4.0"],\ - ["@babel/runtime", "npm:7.23.9"],\ + ["@babel/runtime", "npm:7.24.0"],\ ["complex.js", "npm:2.1.1"],\ ["decimal.js", "npm:10.4.3"],\ ["escape-latex", "npm:1.2.0"],\ @@ -1700,7 +1700,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/undici-npm-5.27.2-141c109c0a-2bf96b102f.zip/node_modules/undici/",\ "packageDependencies": [\ ["undici", "npm:5.27.2"],\ - ["@fastify/busboy", "npm:2.1.0"]\ + ["@fastify/busboy", "npm:2.1.1"]\ ],\ "linkType": "HARD"\ }],\ @@ -1708,7 +1708,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/undici-npm-6.6.2-a0bd6785a6-e08ac9c279.zip/node_modules/undici/",\ "packageDependencies": [\ ["undici", "npm:6.6.2"],\ - ["@fastify/busboy", "npm:2.1.0"]\ + ["@fastify/busboy", "npm:2.1.1"]\ ],\ "linkType": "HARD"\ }]\ @@ -1761,7 +1761,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./.yarn/cache/wkx-npm-0.5.0-fca5152cd8-b8975e33f9.zip/node_modules/wkx/",\ "packageDependencies": [\ ["wkx", "npm:0.5.0"],\ - ["@types/node", "npm:20.11.21"]\ + ["@types/node", "npm:20.11.22"]\ ],\ "linkType": "HARD"\ }]\ diff --git a/Dockerfile b/Dockerfile index d8744dc..27f4b3a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,10 @@ FROM node:21.1.0-bookworm-slim ENV YARN_VERSION 4.1.0 ENV TZ Australia/Sydney RUN yarn policies set-version $YARN_VERSION -RUN apt update -y && apt upgrade -y && apt install -y git fontconfig -RUN npm install -g typescript +RUN apt update -y && apt upgrade -y && apt install -y git fontconfig && npm install -g typescript WORKDIR /Daggerbot RUN git config --global --add safe.directory /Daggerbot COPY tsconfig.json package.json yarn.lock .yarnrc.yml ./ -RUN yarn workspaces focus +RUN yarn CMD [ "yarn", "node", "." ] diff --git a/README.md b/README.md index 7f904bb..3cf7f95 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

Daggerbot V3 Description

-

+ This is a repository for V3 revision that has been transitioned and rewritten from V2 bot to be more robust and reliable with today's standards. This revision took **4 months** (Late September to Mid December) working on and off to do literally everything that needed a rewrite so badly that it cannot be done in V2. @@ -21,6 +21,15 @@ If you're looking for V2 revision, it has been moved to a [branch called `old`]( This is a revision history of how far we come in development cycle; | Revision | Language | Library | Commands | -|---------|----------|-----------|----------| +|----------|----------|---------|----------| | V1 | JavaScript | Discord.JS v13 | Message commands | | V2-V3 | TypeScript | Discord.JS v14 | Slash/message commands | + +## CLI arguments (`process.argv[..]`) +`yarn dev` - Starts the development bot with predefined args. +The args in question is; +| Argument | Usage | +|----------|-------| +| `src/DB-Beta.config.json` | Location of config file - [2] | +| `daggerbotbeta` | Service name in TokenService to fetch tokens data from - [3] | +| `true` | Toggle debug mode in Discord.js library - [4] | diff --git a/package.json b/package.json index 02d7c34..c8f1a3e 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "devDependencies": { "@types/ms": "0.7.34", - "@types/node": "20.11.21", + "@types/node": "20.11.22", "@types/node-cron": "3.0.11", "@types/pg": "8.11.2", "typescript": "5.3.3" diff --git a/src/commands/mp.ts b/src/commands/mp.ts index 634c34f..70de466 100644 --- a/src/commands/mp.ts +++ b/src/commands/mp.ts @@ -28,12 +28,12 @@ const channels = { serverInfo: '543494084363288637', } export default class MP { - static async autocomplete(client: TClient, interaction: Discord.AutocompleteInteraction<'cached'>) { + static async autocomplete(client:TClient, interaction:Discord.AutocompleteInteraction<'cached'>) { const serversInCache = await client.MPServer?.findInCache(); const filterByActive = serversInCache?.filter(x=>x.isActive)?.map(x=>x.serverName); await interaction?.respond(filterByActive?.map(server=>({name: server, value: server}))); } - static async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>) { + static async run(client:TClient, interaction:Discord.ChatInputCommandInteraction<'cached'>) { if (client.config.botSwitches.mpSys === false) return interaction.reply({embeds: [mpModuleDisabled(client)]}); if (client.uptime < refreshTimerSecs) return interaction.reply('MPModule isn\'t initialized yet, please wait a moment and try again.'); if ([channels.mainMpChat, client.config.dcServer.channels.multifarm_chat].includes(interaction.channelId) && !MessageTool.isStaff(interaction.member) && ['status', 'players'].includes(interaction.options.getSubcommand())) return interaction.reply(`Please use <#${channels.activePlayers}> for \`/mp status/players\` commands to prevent clutter in this channel.`).then(()=>setTimeout(()=>interaction.deleteReply(), 6000)); @@ -77,6 +77,9 @@ export default class MP { if (!DSS) return console.log('Endpoint failed - details'); const db = await client.MPServer.findInCache(); const server = db.find(x=>x.serverName === choiceSelector); + if (!server) return; + // Shouldn't throw "Cannot read properties of undefined" error now, + // but I hate people finding new ways to cause the bot to have a minor aneurysm const dEmbed = new client.embed().setColor(client.config.embedColor).setAuthor({name: 'Crossplay server'}).setDescription(MessageTool.concatMessage( `**Name:** \`${DSS.server?.name.length > 0 ? DSS.server.name : '\u200b'}\``, @@ -164,7 +167,7 @@ export default class MP { }, null, 2)), {name: `pollResults-${msg.id}.json`}) ]}); - msg.edit({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Voting has ended!').setDescription('The next map will be '+msg.embeds[0].description.split('\n')[msg.reactions.cache.map(x=>x.count).indexOf(Math.max(...msg.reactions.cache.map(x=>x.count)))].slice(3)).setFooter({text: `Poll ended by ${interaction.user.tag}`, iconURL: interaction.member.displayAvatarURL({extension: 'webp', size: 1024})})]}).then(()=>msg.reactions.removeAll()); + msg.edit({content: null, embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Voting has ended!').setDescription('The next map will be '+msg.embeds[0].description.split('\n')[msg.reactions.cache.map(x=>x.count).indexOf(Math.max(...msg.reactions.cache.map(x=>x.count)))].slice(3)).setFooter({text: `Poll ended by ${interaction.user.tag}`, iconURL: interaction.member.displayAvatarURL({extension: 'webp', size: 1024})})]}).then(()=>msg.reactions.removeAll()); await interaction.reply(`Successfully ended the [poll]() in <#${channels.announcements}>`) }, maps: async()=>{ diff --git a/src/components/CanvasBuilder.ts b/src/components/CanvasBuilder.ts index 6e8f42f..59f722d 100644 --- a/src/components/CanvasBuilder.ts +++ b/src/components/CanvasBuilder.ts @@ -20,11 +20,11 @@ export default class CanvasBuilder { // Handle negative for (const [i, change] of data.entries()) if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0; - const LBdataFirst = Math.ceil(Math.max(...data) * 10 ** (-Math.max(...data).toString().split('').length + 2)) * 10 ** (Math.max(...data).toString().split('').length - 2) - const LBdataSecond = Math.ceil(Math.max(...data) * 10 ** (-Math.max(...data).toString().split('').length + 3)) * 10 ** (Math.max(...data).toString().split('').length - 3) + const LB_MAX_VAL = Math.max(...data); + const LB_SCALE_UP = Math.pow(10, -Math.floor(Math.log10(LB_MAX_VAL))); + const LB_SCALED_DATA = Math.ceil(LB_MAX_VAL*LB_SCALE_UP) / LB_SCALE_UP; - const firstTop = type === 'leaderboard' ? LBdataFirst : 16; - const secondTop = type === 'leaderboard' ? LBdataSecond : 16; + const top = type === 'leaderboard' ? LB_SCALED_DATA : 16; const textSize = 40; const origin = [15, 65]; const size = [1300, 630]; @@ -37,7 +37,7 @@ export default class CanvasBuilder { const intervalCandidates:[number, number, number][] = []; for (let i = 4; i < 10; i++) { - const interval = firstTop / i; + const interval = top / i; if (Number.isInteger(interval)) intervalCandidates.push([interval, i, i * Math.max(interval.toString().split('').filter(x=>x === '0').length / interval.toString().length, 0.3) * (['1', '2', '4', '5', '6', '8'].includes(interval.toString()[0]) ? 1.5 : 0.67)]); } const chosenInterval = intervalCandidates.sort((a,b)=>b[2]-a[2])[0]; @@ -45,7 +45,7 @@ export default class CanvasBuilder { this.ctx.strokeStyle = this.palette.oddHorizontal; for (let i = 0; i <= chosenInterval[1]; i++) { - const y = origin[1] + size[1] - (i * (chosenInterval[0] / secondTop) * size[1]); + const y = origin[1] + size[1] - (i * (chosenInterval[0] / top) * size[1]); if (y < origin[1]) continue; const even = ((i + 1) % 2) === 0; if (even) this.ctx.strokeStyle = this.palette.evenHorizontal; @@ -82,7 +82,7 @@ export default class CanvasBuilder { for (let [i, currentValue] of data.entries()) { if (currentValue < 0) currentValue = 0; const X = i * nodeWidth + origin[0]; - const Y = ((1 - (currentValue / secondTop)) * size[1]) + origin[1]; + const Y = ((1 - (currentValue / top)) * size[1]) + origin[1]; const nextValue = data[i + 1]; const previousValue = data[i - 1]; this.ctx.strokeStyle = type === 'players' ? gradient : null; @@ -103,7 +103,7 @@ export default class CanvasBuilder { this.ctx.closePath(); if (currentValue !== previousValue || currentValue !== nextValue) { - // Ball. What else? + // Balls. What else? I mean.. I'm not that creative, I'm just a comment not a funny comedian. this.ctx.fillStyle = type === 'players' ? gradient : null; this.ctx.beginPath(); this.ctx.arc(X, Y, this.ctx.lineWidth * 1.2, 0, 2 * Math.PI); @@ -131,6 +131,7 @@ export default class CanvasBuilder { // Time this.ctx.fillText('time ->', origin[0] + (textSize / 2), origin[1] + size[1] + (textSize)); + // 100degree the fuck back to sender. return this.canvas; } } diff --git a/src/events/messageUpdate.ts b/src/events/messageUpdate.ts index debe913..708dae6 100644 --- a/src/events/messageUpdate.ts +++ b/src/events/messageUpdate.ts @@ -1,13 +1,14 @@ import Discord from 'discord.js'; import TClient from '../client.js'; import MessageTool from '../helpers/MessageTool.js'; +import Automoderator from '../components/Automod.js'; import {disabledChannels, rawSwitches} from '../index.js'; export default class MessageUpdate { static async run(client:TClient, oldMsg:Discord.Message|Discord.PartialMessage, newMsg:Discord.Message){ if (!client.config.botSwitches.logs) return; - if (oldMsg.guild?.id != client.config.dcServer.id || oldMsg.author === null || oldMsg?.author.bot || newMsg.partial || !newMsg.member || disabledChannels.includes(newMsg.channelId)) return; - if (await client.prohibitedWords.findWord(newMsg.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n?0-9]|[]|ing\b/g, '').split(' ').join('')) && (!MessageTool.isStaff(newMsg.member))) newMsg.delete(); - if (!rawSwitches.MESSAGE_UPDATE || (rawSwitches.MESSAGE_UPDATE && newMsg.content !== oldMsg.content)) { + if (oldMsg.guild?.id != client.config.dcServer.id || oldMsg.author === null || oldMsg?.author.bot || newMsg.partial || !newMsg.member || newMsg.content === oldMsg.content || disabledChannels.includes(newMsg.channelId)) return; + if (await client.prohibitedWords.findWord(Automoderator.scanMsg(newMsg)) && (!MessageTool.isStaff(newMsg.member))) newMsg.delete(); + if (!rawSwitches.MESSAGE_UPDATE || rawSwitches.MESSAGE_UPDATE) { rawSwitches.MESSAGE_UPDATE = true; (client.channels.resolve(client.config.dcServer.channels.logs) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.username} (${oldMsg.author.id})`, iconURL: oldMsg.author.displayAvatarURL()}).setTitle('Message edited').addFields({name: 'Old content', value: `\`\`\`${oldMsg.content.length < 1 ? '(Attachment)' : Discord.escapeCodeBlock(oldMsg.content.slice(0,2048))}\`\`\``}, {name: 'New content', value: `\`\`\`${Discord.escapeCodeBlock(newMsg.content.slice(0,2048))}\`\`\``}, {name: 'Channel', value: `<#${oldMsg.channelId}>`})], components: [new Discord.ActionRowBuilder().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(oldMsg.url).setLabel('Jump to message'))]}); } diff --git a/yarn.lock b/yarn.lock index c796738..2243b8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,11 +6,11 @@ __metadata: cacheKey: 10 "@babel/runtime@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/runtime@npm:7.23.9" + version: 7.24.0 + resolution: "@babel/runtime@npm:7.24.0" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10/9a520fe1bf72249f7dd60ff726434251858de15cccfca7aa831bd19d0d3fb17702e116ead82724659b8da3844977e5e13de2bae01eb8a798f2823a669f122be6 + checksum: 10/8d32c7e116606ea322b89f9fde8ffae6be9503b549dc0d0abb38bd9dc26e87469b9fb7a66964cc089ee558fd0a97d304fb0a3cfec140694764fb0d71b6a6f5e4 languageName: node linkType: hard @@ -94,9 +94,9 @@ __metadata: linkType: hard "@fastify/busboy@npm:^2.0.0": - version: 2.1.0 - resolution: "@fastify/busboy@npm:2.1.0" - checksum: 10/f22c1e5c52dc350ddf9ba8be9f87b48d3ea5af00a37fd0a0d1e3e4b37f94d96763e514c68a350c7f570260fdd2f08b55ee090cdd879f92a03249eb0e3fd19113 + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 10/2bb8a7eca8289ed14c9eb15239bc1019797454624e769b39a0b90ed204d032403adc0f8ed0d2aef8a18c772205fa7808cf5a1b91f21c7bfc7b6032150b1062c5 languageName: node linkType: hard @@ -530,12 +530,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:20.11.21": - version: 20.11.21 - resolution: "@types/node@npm:20.11.21" +"@types/node@npm:*, @types/node@npm:20.11.22": + version: 20.11.22 + resolution: "@types/node@npm:20.11.22" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/a31ecc6a3c615bca310ffe7dea23613153ff9e1e175c09d14198402b2cef9b1bb1bf3912aff6ffc6cb01b99a025ec6dd6474c797bfb0aaf83daf4edaea063760 + checksum: 10/855058a4328c0c88bd0616b2fcfedc6504ca08c3e5304674dc2e6485147d7f523d0ff591e002c765a1ec761b26fc0934599d694a2749634e9244ba3bf02de703 languageName: node linkType: hard @@ -642,7 +642,7 @@ __metadata: "@sequelize/core": "npm:7.0.0-alpha.37" "@toast/tokenservice-client": "npm:1.0.12" "@types/ms": "npm:0.7.34" - "@types/node": "npm:20.11.21" + "@types/node": "npm:20.11.22" "@types/node-cron": "npm:3.0.11" "@types/pg": "npm:8.11.2" ansi-colors: "npm:4.1.3"