1
0
mirror of https://github.com/toast-ts/Daggerbot-TS.git synced 2024-11-17 00:10:58 -05:00

Compare commits

...

3 Commits

Author SHA1 Message Date
AnxietyisReal
e3f0da75b3 Update packages 2023-08-30 18:38:48 +10:00
AnxietyisReal
793c22dbcd Move essentials out of client.ts 2023-08-30 18:34:59 +10:00
AnxietyisReal
de7169035f Rename dontlookatme to spotify 2023-08-30 16:42:06 +10:00
25 changed files with 238 additions and 224 deletions

56
.pnp.cjs generated
View File

@ -39,10 +39,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["discord.js", "npm:14.13.0"],\
["libsodium-wrappers", "npm:0.7.11"],\
["moment", "npm:2.29.4"],\
["mongoose", "npm:7.4.5"],\
["mongoose", "npm:7.5.0"],\
["ms", "npm:2.1.3"],\
["prism-media", "virtual:20c353e2d6536e37339997f03975c6a660f4d296e664d291bd43620c6162cca8eb5ef90b0998dc9db75ff6862e5da587d0530bae26805f5fadc8f17aaa4ff794#npm:1.3.5"],\
["systeminformation", "npm:5.21.0"],\
["systeminformation", "npm:5.21.1"],\
["typescript", "patch:typescript@npm%3A5.2.2#~builtin<compat/typescript>::version=5.2.2&hash=f3b441"],\
["xml-js", "npm:1.6.11"],\
["youtube-sr", "npm:4.3.4"],\
@ -268,6 +268,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["@mongodb-js/saslprep", [\
["npm:1.1.0", {\
"packageLocation": "./.yarn/cache/@mongodb-js-saslprep-npm-1.1.0-3906c025b8-1479a43e21.zip/node_modules/@mongodb-js/saslprep/",\
"packageDependencies": [\
["@mongodb-js/saslprep", "npm:1.1.0"],\
["sparse-bitfield", "npm:3.0.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["@npmcli/fs", [\
["npm:3.1.0", {\
"packageLocation": "./.yarn/cache/@npmcli-fs-npm-3.1.0-0844a57978-a50a6818de.zip/node_modules/@npmcli/fs/",\
@ -922,10 +932,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["discord.js", "npm:14.13.0"],\
["libsodium-wrappers", "npm:0.7.11"],\
["moment", "npm:2.29.4"],\
["mongoose", "npm:7.4.5"],\
["mongoose", "npm:7.5.0"],\
["ms", "npm:2.1.3"],\
["prism-media", "virtual:20c353e2d6536e37339997f03975c6a660f4d296e664d291bd43620c6162cca8eb5ef90b0998dc9db75ff6862e5da587d0530bae26805f5fadc8f17aaa4ff794#npm:1.3.5"],\
["systeminformation", "npm:5.21.0"],\
["systeminformation", "npm:5.21.1"],\
["typescript", "patch:typescript@npm%3A5.2.2#~builtin<compat/typescript>::version=5.2.2&hash=f3b441"],\
["xml-js", "npm:1.6.11"],\
["youtube-sr", "npm:4.3.4"],\
@ -1842,18 +1852,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["mongodb", [\
["npm:5.7.0", {\
"packageLocation": "./.yarn/cache/mongodb-npm-5.7.0-c5e415a2e7-16357b6229.zip/node_modules/mongodb/",\
["npm:5.8.1", {\
"packageLocation": "./.yarn/cache/mongodb-npm-5.8.1-d655990b24-da8fc05952.zip/node_modules/mongodb/",\
"packageDependencies": [\
["mongodb", "npm:5.7.0"]\
["mongodb", "npm:5.8.1"]\
],\
"linkType": "SOFT"\
}],\
["virtual:f13f0698828b1136b9c2fe7fd47b1d970be7543f740ea5a6542d5de086caf8ce3fde9627ee2446a16f34f568a86debbe37012d1a655c3979e155ff37d7833a12#npm:5.7.0", {\
"packageLocation": "./.yarn/__virtual__/mongodb-virtual-66143c0721/0/cache/mongodb-npm-5.7.0-c5e415a2e7-16357b6229.zip/node_modules/mongodb/",\
["virtual:dd2c4ef6f94e58af1d1910a9e458d5ca3cd2a693365aac2a33b0318c1be1170eb680a561461dbf9dbd8568b885dbf5005ce2287e0fee26acec16b0e35305f4e2#npm:5.8.1", {\
"packageLocation": "./.yarn/__virtual__/mongodb-virtual-2b368f364a/0/cache/mongodb-npm-5.8.1-d655990b24-da8fc05952.zip/node_modules/mongodb/",\
"packageDependencies": [\
["mongodb", "virtual:f13f0698828b1136b9c2fe7fd47b1d970be7543f740ea5a6542d5de086caf8ce3fde9627ee2446a16f34f568a86debbe37012d1a655c3979e155ff37d7833a12#npm:5.7.0"],\
["mongodb", "virtual:dd2c4ef6f94e58af1d1910a9e458d5ca3cd2a693365aac2a33b0318c1be1170eb680a561461dbf9dbd8568b885dbf5005ce2287e0fee26acec16b0e35305f4e2#npm:5.8.1"],\
["@aws-sdk/credential-providers", null],\
["@mongodb-js/saslprep", "npm:1.1.0"],\
["@mongodb-js/zstd", null],\
["@types/aws-sdk__credential-providers", null],\
["@types/kerberos", null],\
@ -1864,7 +1875,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["kerberos", null],\
["mongodb-client-encryption", null],\
["mongodb-connection-string-url", "npm:2.6.0"],\
["saslprep", "npm:1.0.3"],\
["snappy", null],\
["socks", "npm:2.7.1"]\
],\
@ -1895,13 +1905,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["mongoose", [\
["npm:7.4.5", {\
"packageLocation": "./.yarn/cache/mongoose-npm-7.4.5-f13f069882-a017bd90bb.zip/node_modules/mongoose/",\
["npm:7.5.0", {\
"packageLocation": "./.yarn/cache/mongoose-npm-7.5.0-dd2c4ef6f9-3e4219fd29.zip/node_modules/mongoose/",\
"packageDependencies": [\
["mongoose", "npm:7.4.5"],\
["mongoose", "npm:7.5.0"],\
["bson", "npm:5.4.0"],\
["kareem", "npm:2.5.1"],\
["mongodb", "virtual:f13f0698828b1136b9c2fe7fd47b1d970be7543f740ea5a6542d5de086caf8ce3fde9627ee2446a16f34f568a86debbe37012d1a655c3979e155ff37d7833a12#npm:5.7.0"],\
["mongodb", "virtual:dd2c4ef6f94e58af1d1910a9e458d5ca3cd2a693365aac2a33b0318c1be1170eb680a561461dbf9dbd8568b885dbf5005ce2287e0fee26acec16b0e35305f4e2#npm:5.8.1"],\
["mpath", "npm:0.9.0"],\
["mquery", "npm:5.0.0"],\
["ms", "npm:2.1.3"],\
@ -2335,16 +2345,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
["saslprep", [\
["npm:1.0.3", {\
"packageLocation": "./.yarn/cache/saslprep-npm-1.0.3-8db649c346-4fdc0b70fb.zip/node_modules/saslprep/",\
"packageDependencies": [\
["saslprep", "npm:1.0.3"],\
["sparse-bitfield", "npm:3.0.3"]\
],\
"linkType": "HARD"\
}]\
]],\
["sax", [\
["npm:1.2.4", {\
"packageLocation": "./.yarn/cache/sax-npm-1.2.4-178f05f12f-d3df7d32b8.zip/node_modules/sax/",\
@ -2598,10 +2598,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["systeminformation", [\
["npm:5.21.0", {\
"packageLocation": "./.yarn/unplugged/systeminformation-npm-5.21.0-553db82075/node_modules/systeminformation/",\
["npm:5.21.1", {\
"packageLocation": "./.yarn/unplugged/systeminformation-npm-5.21.1-9b1e539abd/node_modules/systeminformation/",\
"packageDependencies": [\
["systeminformation", "npm:5.21.0"]\
["systeminformation", "npm:5.21.1"]\
],\
"linkType": "HARD"\
}]\

View File

@ -37,10 +37,10 @@
"discord.js": "14.13.0",
"libsodium-wrappers": "0.7.11",
"moment": "2.29.4",
"mongoose": "7.4.5",
"mongoose": "7.5.0",
"ms": "2.1.3",
"prism-media": "1.3.5",
"systeminformation": "5.21.0",
"systeminformation": "5.21.1",
"typescript": "5.2.2",
"xml-js": "1.6.11",
"youtube-sr": "4.3.4",

View File

@ -1,6 +1,6 @@
import Discord, {Client, GatewayIntentBits, Partials} from 'discord.js';
import Discord from 'discord.js';
import {readFileSync, readdirSync} from 'node:fs';
import {formatTimeOpt, Tokens, Config, repeatedMessages, type MPServerCache} from './typings/interfaces';
import {Tokens, Config, repeatedMessages, type MPServerCache} from './typings/interfaces';
import bannedWords from './models/bannedWords.js';
import userLevels from './models/userLevels.js';
import suggestion from './models/suggestion.js';
@ -23,7 +23,7 @@ try{
console.log('Using production config')
}
export default class TClient extends Client {
export default class TClient extends Discord.Client {
invites: Map<any, any>;
commands: Discord.Collection<string, any>;
registry: Array<Discord.ApplicationCommandDataResolvable>;
@ -36,7 +36,6 @@ export default class TClient extends Client {
attachmentBuilder: any;
moment: typeof moment;
xjs: typeof xjs;
ms: any;
userLevels: userLevels;
punishments: punishments;
bonkCount: bonkCount;
@ -51,13 +50,13 @@ export default class TClient extends Client {
constructor(){
super({
intents: [
GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildModeration, GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.GuildPresences,
GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.DirectMessages
Discord.GatewayIntentBits.Guilds, Discord.GatewayIntentBits.GuildMembers,
Discord.GatewayIntentBits.GuildModeration, Discord.GatewayIntentBits.GuildInvites,
Discord.GatewayIntentBits.GuildMessageReactions, Discord.GatewayIntentBits.GuildPresences,
Discord.GatewayIntentBits.MessageContent, Discord.GatewayIntentBits.GuildMessages,
Discord.GatewayIntentBits.GuildVoiceStates, Discord.GatewayIntentBits.DirectMessages
], partials: [
Partials.Channel, Partials.Reaction, Partials.Message
Discord.Partials.Channel, Discord.Partials.Reaction, Discord.Partials.Message
], allowedMentions: {users:[],roles:[]}
})
this.invites = new Map();
@ -75,7 +74,6 @@ export default class TClient extends Client {
this.attachmentBuilder = Discord.AttachmentBuilder;
this.moment = moment;
this.xjs = xjs;
this.ms = import('ms').then(i=>i);
this.userLevels = new userLevels(this);
this.bonkCount = new bonkCount(this);
this.punishments = new punishments(this);
@ -109,106 +107,7 @@ export default class TClient extends Client {
}
}
}
formatTime(integer: number, accuracy = 1, options?: formatTimeOpt){
let achievedAccuracy = 0;
let text:any = '';
for (const timeName of [
{name: 'year', length: 31536000000},
{name: 'month', length: 2592000000},
{name: 'week', length: 604800000},
{name: 'day', length: 86400000},
{name: 'hour', length: 3600000},
{name: 'minute', length: 60000},
{name: 'second', length: 1000}
]){
if (achievedAccuracy < accuracy){
const fullTimelengths = Math.floor(integer/timeName.length);
if (fullTimelengths === 0) continue;
achievedAccuracy++;
text += fullTimelengths + (options?.longNames ? (' '+timeName.name+(fullTimelengths === 1 ? '' : 's')) : timeName.name.slice(0, timeName.name === 'month' ? 2 : 1)) + (options?.commas ? ', ' : ' ');
integer -= fullTimelengths*timeName.length;
} else break;
}
if (text.length == 0) text = integer + (options?.longNames ? ' milliseconds' : 'ms') + (options?.commas ? ', ' : '');
if (options?.commas){
text = text.slice(0, -2);
if (options?.longNames){
text = text.split('');
text[text.lastIndexOf(',')] = ' and';
text = text.join('');
}
} return text.trim();
}
formatPlayerUptime(oldTime:number){
var Hours=0;
oldTime=Math.floor(Number(oldTime));
if(oldTime>=60){
var Hours=Math.floor(Number(oldTime)/60);
var Minutes=(Number(oldTime)-(Hours*60));
} else Minutes=Number(oldTime)
if(Hours>=24){
var Days=Math.floor(Number(Hours)/24);
var Hours=(Hours-(Days*24));
} return (Days>0?Days+' d ':'')+(Hours>0?Hours+' h ':'')+(Minutes>0?Minutes+' m':'')
}
isStaff = (guildMember:Discord.GuildMember)=>this.config.mainServer.staffRoles.map((x: string)=>this.config.mainServer.roles[x]).some((x: string)=>guildMember.roles.cache.has(x));
youNeedRole = (interaction:Discord.CommandInteraction, role:string)=>interaction.reply(`This command is restricted to <@&${this.config.mainServer.roles[role]}>`);
logTime = ()=>`[${this.moment().format('DD/MM/YY HH:mm:ss')}]`;
async punish(interaction: Discord.ChatInputCommandInteraction<'cached'>, type: string){
if (!this.isStaff(interaction.member as Discord.GuildMember)) return this.youNeedRole(interaction, "dcmod");
const time = interaction.options.getString('time') ?? undefined;
const reason = interaction.options.getString('reason') ?? 'Reason unspecified';
const GuildMember = interaction.options.getMember('member') ?? undefined;
const User = interaction.options.getUser('member', true);
console.log(this.logTime(), `[PunishmentLog] ${GuildMember?.user?.username ?? User?.username ?? 'No user data'} ${time ? ['warn', 'kick'].includes(this.punishments.type) ? 'and no duration set' : `and ${time} (duration)` : ''} was used in /${interaction.commandName} for ${reason}`);
(this.channels.cache.get(this.config.mainServer.channels.punishment_log) as Discord.TextChannel).send({embeds:[new this.embed().setColor(this.config.embedColor).setAuthor({name: interaction?.user?.username, iconURL: interaction?.user?.displayAvatarURL({size:2048})}).setTitle('Punishment Log').setDescription(`${GuildMember?.user?.username ?? User?.username ?? 'No user data'} ${time ? ['warn', 'kick'].includes(this.punishments.type) ? 'and no duration set' : `and ${time} (duration)` : ''} was used in \`/${interaction.commandName}\` for \`${reason}\``).setTimestamp()]});
if (interaction.user.id === User.id) return interaction.reply(`You cannot ${type} yourself.`);
if (!GuildMember && type != 'unban') return interaction.reply(`You cannot ${type} someone who is not in the server.`);
if (User.bot) return interaction.reply(`You cannot ${type} a bot!`);
await interaction.deferReply();
await this.punishments.addPunishment(type, { time, interaction }, interaction.user.id, reason, User, GuildMember);
}
async YTLoop(YTChannelID: string, YTChannelName: string, DCChannelID: string){
let Data:any;
try {
await fetch(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelID}`, {signal: AbortSignal.timeout(6000),headers:{'User-Agent':`Daggerbot - Notification/undici`}}).then(async xml=>Data = this.xjs.xml2js(await xml.text(), {compact: true}))
} catch(err){
console.log(this.logTime(), `${YTChannelName} YT fail`)
}
if (!Data) return;
if (!this.YTCache[YTChannelID]) return this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
if (Data.feed.entry[1]['yt:videoId']._text === this.YTCache[YTChannelID]){
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
(this.channels.resolve(DCChannelID) as Discord.TextChannel).send(`**${YTChannelName}** just uploaded a video!\n${Data.feed.entry[0].link._attributes.href}`)
}
}
formatBytes(bytes:number, decimals:number = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals < 0 ? 0 : decimals)) + ' ' + ['Bytes', 'KB', 'MB', 'GB'][i];
}
removeUsername = (text: string)=>{
let matchesLeft = true;
const dirSlash = process.platform === 'linux' ? '\/' : '\\';
const array = text.split(dirSlash);
while (matchesLeft){
let usersIndex = array.indexOf(process.platform === 'linux' ? 'home' : 'Users');
if (usersIndex<1) matchesLeft = false;
else {
let usernameIndex = usersIndex+1;
if(array[usernameIndex].length == 0) usernameIndex += 1;
array[usernameIndex] = '・'.repeat(array[usernameIndex].length);
array[usersIndex] = process.platform === 'linux' ? 'ho\u200bme' : 'Us\u200bers';
}
} return array.join(dirSlash);
}
}

View File

@ -1,8 +1,9 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import Punish from '../funcs/Punish.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
client.punish(interaction, 'ban');
Punish(client, interaction, 'ban');
},
data: new Discord.SlashCommandBuilder()
.setName('ban')

View File

@ -1,5 +1,6 @@
import Discord from "discord.js";
import Discord from 'discord.js';
import TClient from '../client.js';
import FormatTime from '../helpers/FormatTime.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
@ -21,7 +22,7 @@ export default {
{name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true},
{name: '\u200b', value: '\u200b', inline: true},
{name: '🔹 Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true})
if (punishment.duration) embed.addFields({name: '🔹 Duration', value: client.formatTime(punishment.duration, 100)})
if (punishment.duration) embed.addFields({name: '🔹 Duration', value: `${FormatTime(punishment.duration, 100)}`})
if (punishment.expired) embed.addFields({name: '🔹 Expired', value: `This case has been overwritten by Case #${cancelledBy.id} for reason \`${cancelledBy.reason}\``})
if (punishment.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id} with reason \`${cancels.reason}\``})
interaction.reply({embeds: [embed]});
@ -34,7 +35,7 @@ export default {
const userPunishment = userPunishmentData.sort((a,b)=>a.time-b.time).map((punishment)=>{
return {
name: `${punishment.type[0].toUpperCase()+punishment.type.slice(1)} | Case #${punishment.id}`,
value: `Reason: \`${punishment.reason}\`\n${punishment.duration ? `Duration: ${client.formatTime(punishment.duration, 3)}\n` : ''}Moderator: <@${punishment.moderator}>${punishment.expired ? `\nOverwritten by Case #${punishments.find(x=>x.cancels===punishment._id)?._id}` : ''}${punishment.cancels ? `\nOverwrites Case #${punishment.cancels}` : ''}`
value: `Reason: \`${punishment.reason}\`\n${punishment.duration ? `Duration: ${FormatTime(punishment.duration, 3)}\n` : ''}Moderator: <@${punishment.moderator}>${punishment.expired ? `\nOverwritten by Case #${punishments.find(x=>x.cancels===punishment._id)?._id}` : ''}${punishment.cancels ? `\nOverwrites Case #${punishment.cancels}` : ''}`
}
});
if (!punishments || !userPunishment) return interaction.reply(`**${user.username}** has a clean record.`)

View File

@ -3,6 +3,8 @@ import {Octokit} from '@octokit/rest';
import {createTokenAuth} from '@octokit/auth-token';
import {exec} from 'node:child_process';
import MessageTool from '../helpers/MessageTool.js';
import UsernameHelper from '../helpers/UsernameHelper.js';
import FormatTime from '../helpers/FormatTime.js';
import fs from 'node:fs';
import util from 'node:util';
import TClient from '../client.js';
@ -27,7 +29,7 @@ export default {
const filter = (x:any)=>x.content === 'stack' && x.author.id === interaction.user.id
const messagecollector = (interaction.channel as Discord.TextChannel).createMessageCollector({filter, max: 1, time: 60000});
messagecollector.on('collect', collected=>{
collected.reply({content: `\`\`\`\n${client.removeUsername(err.stack)}\n\`\`\``, allowedMentions: {repliedUser: false}});
collected.reply({content: `\`\`\`\n${UsernameHelper.stripName(err.stack)}\n\`\`\``, allowedMentions: {repliedUser: false}});
});
});
}
@ -35,12 +37,12 @@ export default {
if (typeof output === 'object') output = 'js\n'+util.formatWithOptions({depth: 1}, '%O', output)
else output = '\n' + String(output);
[
client.tokens.main,client.tokens.beta,client.tokens.toast,client.tokens.dontlookatme.client,client.tokens.dontlookatme.secret,
client.tokens.main,client.tokens.beta,client.tokens.toast,client.tokens.spotify.client,client.tokens.spotify.secret,
client.tokens.mongodb_uri,client.tokens.mongodb_uri_dev,client.tokens.octokit
].forEach(x=>output = output.replace(new RegExp(x as string,'g'),':noblank: No token?'));
const embed = new client.embed().setColor(client.config.embedColor).setTitle('__Eval__').addFields(
{name: 'Input', value: `\`\`\`js\n${code.slice(0,1010)}\n\`\`\``},
{name: 'Output', value: `\`\`\`${client.removeUsername(output).slice(0,1016)}\n\`\`\``}
{name: 'Output', value: `\`\`\`${UsernameHelper.stripName(output).slice(0,1016)}\n\`\`\``}
);
interaction.reply({embeds: [embed]}).catch(()=>(interaction.channel as Discord.TextChannel).send({embeds: [embed]}));
},
@ -63,11 +65,11 @@ export default {
}
};
exec('git pull',{windowsHide:true},(err:Error,stdout)=>{
if (err) clarkson.edit(`\`\`\`${client.removeUsername(err.message)}\`\`\``)
if (err) clarkson.edit(`\`\`\`${UsernameHelper.stripName(err.message)}\`\`\``)
else if (stdout.includes('Already up to date')) clarkson.edit('I am already up to date with the upstream repository.')
else clarkson.edit('Compiling TypeScript files...').then(()=>exec('yarn tsc', {windowsHide:true}, (err:Error)=>{
if (err) clarkson.edit(`\`\`\`${client.removeUsername(err.message)}\`\`\``)
if (interaction.options.getBoolean('restart')) clarkson.edit(`[Commit:](<${github.fetchCommit.url}>) **${github.fetchCommit.msg}**\nCommit author: **${github.fetchCommit.author}**\n\n__Commit changes__\nTotal: **${github.fetchChanges.total}**\nAdditions: **${github.fetchChanges.addition}**\nDeletions: **${github.fetchChanges.deletion}**\n\nSuccessfully compiled TypeScript files into JavaScript!\nUptime before restarting: **${client.formatTime(client.uptime, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot', {windowsHide:true}));
if (err) clarkson.edit(`\`\`\`${UsernameHelper.stripName(err.message)}\`\`\``)
if (interaction.options.getBoolean('restart')) clarkson.edit(`[Commit:](<${github.fetchCommit.url}>) **${github.fetchCommit.msg}**\nCommit author: **${github.fetchCommit.author}**\n\n__Commit changes__\nTotal: **${github.fetchChanges.total}**\nAdditions: **${github.fetchChanges.addition}**\nDeletions: **${github.fetchChanges.deletion}**\n\nSuccessfully compiled TypeScript files into JavaScript!\nUptime before restarting: **${FormatTime(client.uptime, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot', {windowsHide:true}));
else clarkson.edit(`[Commit:](<${github.fetchCommit.url}>) **${github.fetchCommit.msg}**\nCommit author: **${github.fetchCommit.author}**\n\n__Commit changes__\nTotal: **${github.fetchChanges.total}**\nAdditions: **${github.fetchChanges.addition}**\nDeletions: **${github.fetchChanges.deletion}**\n\nSuccessfully compiled TypeScript files into JavaScript!`)
}))
})
@ -112,15 +114,15 @@ export default {
restart: async()=>{
const i = await interaction.reply({content: 'Compiling TypeScript files...', fetchReply: true});
exec('yarn tsc',{windowsHide:true},(err:Error)=>{
if (err) i.edit(`\`\`\`${client.removeUsername(err.message)}\`\`\``)
else i.edit(`Successfully compiled TypeScript files into JavaScript!\nUptime before restarting: **${client.formatTime(client.uptime, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot', {windowsHide:true}))
if (err) i.edit(`\`\`\`${UsernameHelper.stripName(err.message)}\`\`\``)
else i.edit(`Successfully compiled TypeScript files into JavaScript!\nUptime before restarting: **${FormatTime(client.uptime, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot', {windowsHide:true}))
})
},
file: ()=>interaction.reply({files:[`./src/database/${interaction.options.getString('name')}.json`]}).catch(()=>'Filesize is too large, upload cancelled.'),
wake_device: async()=>{
const i = await interaction.reply({content: 'Spawning a task...', fetchReply: true});
exec(`cd "../../Desktop/System Tools/wakemeonlan" && WakeMeOnLan.exe /wakeup ${interaction.options.getString('name')}`, {windowsHide:true}, (err:Error)=>{
if (err) i.edit(client.removeUsername(err.message))
if (err) i.edit(UsernameHelper.stripName(err.message))
else i.edit('Your device should be awake by now!\n||Don\'t blame me if it isn\'t on.||')
})
}

View File

@ -1,8 +1,9 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import Punish from '../funcs/Punish.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
client.punish(interaction, 'kick');
Punish(client, interaction, 'kick');
},
data: new Discord.SlashCommandBuilder()
.setName('kick')

View File

@ -2,9 +2,10 @@ import Discord from 'discord.js';
import TClient from '../client.js';
import path from 'node:path';
import canvas from 'canvas';
import FormatPlayer from '../helpers/FormatPlayer.js';
import MessageTool from '../helpers/MessageTool.js';
import {readFileSync} from 'node:fs';
import {FSData} from 'src/typings/interfaces.js';
import {FSData} from '../typings/interfaces.js';
const serverChoices = [
{name: 'Main Server', value: 'mainServer'},
@ -149,11 +150,7 @@ export default {
else if (endpoint.slots.used > 8) Color = client.config.embedColorYellow;
else Color = client.config.embedColorGreen;
for (const player of endpoint.slots.players.filter(x=>x.isUsed)){
let decorator = player.isAdmin ? ':detective:' : '';
decorator += player.name.includes('Toast') ? '<:toastv2:1132681026662056079>' : '';
playerData.push(`**${player.name}${decorator}**\nFarming for ${client.formatPlayerUptime(player.uptime)}`)
}
for (const player of endpoint.slots.players.filter(x=>x.isUsed)) playerData.push(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}**\nFarming for ${FormatPlayer.uptimeFormat(player.uptime)}`)
const slot = `${endpoint.slots.used}/${endpoint.slots.capacity}`;
const ingameTime = `${('0'+Math.floor((endpoint.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((endpoint.server.dayTime/60/1000)%60)).slice(-2)}`;

View File

@ -7,7 +7,7 @@ export default {
if (!client.config.botSwitches.music && !client.config.whitelist.includes(interaction.user.id)) return interaction.reply({content:'Music module is currently disabled.',ephemeral:true});
if (!client.isStaff(interaction.member) && !client.config.whitelist.includes(interaction.member.id)) return interaction.reply('Music module is close to being completed, some parts may be incomplete or broken, so it has been restricted to staff for time-being.');
const player = Player.singleton(client);
await player.extractors.register(SpotifyExtractor,{clientId: client.tokens.dontlookatme.client, clientSecret: client.tokens.dontlookatme.secret});
await player.extractors.register(SpotifyExtractor,{clientId: client.tokens.spotify.client, clientSecret: client.tokens.spotify.secret});
if (!interaction.member.voice.channel) return interaction.reply('Please join a voice channel first to use the command.');
player.nodes.create(interaction.guildId, {
metadata: {

View File

@ -1,8 +1,9 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import Punish from '../funcs/Punish.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
client.punish(interaction, 'mute');
Punish(client, interaction, 'mute');
},
data: new Discord.SlashCommandBuilder()
.setName('mute')

View File

@ -1,10 +1,11 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import FormatTime from '../helpers/FormatTime.js';
export default {
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
if (client.uptime < 15500) return interaction.reply('I just restarted, wait 15 seconds and try again.')
const msg = await interaction.reply({content: 'Pinging...', fetchReply: true})
msg.edit(`API Latency: \`${client.formatTime(client.ws.ping, 3, {longNames: false, commas: true})}\`\nBot Latency: \`${client.formatTime(msg.createdTimestamp - interaction.createdTimestamp, 3, {longNames: false, commas: true})}\``)
msg.edit(`API Latency: \`${FormatTime(client.ws.ping, 3, {longNames: false, commas: true})}\`\nBot Latency: \`${FormatTime(msg.createdTimestamp - interaction.createdTimestamp, 3, {longNames: false, commas: true})}\``)
},
data: new Discord.SlashCommandBuilder()
.setName('ping')

View File

@ -1,8 +1,9 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import Punish from '../funcs/Punish.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
client.punish(interaction, 'softban');
Punish(client, interaction, 'softban');
},
data: new Discord.SlashCommandBuilder()
.setName('softban')

View File

@ -1,6 +1,8 @@
import Discord from 'discord.js';
import pkg from 'typescript';
import MessageTool from '../helpers/MessageTool.js';
import FormatBytes from '../helpers/FormatBytes.js';
import FormatTime from '../helpers/FormatTime.js';
import si from 'systeminformation';
import TClient from '../client.js';
import os from 'node:os';
@ -16,7 +18,7 @@ export default {
const columns = ['Command name', 'Count'];
const includedCommands = client.commands.filter(x=>x.uses).sort((a,b)=>b.uses - a.uses);
if (includedCommands.size === 0) return interaction.reply(`No commands have been used yet.\nUptime: **${client.formatTime(client.uptime, 3, {longNames: true, commas: true})}**`);
if (includedCommands.size === 0) return interaction.reply(`No commands have been used yet.\nUptime: **${FormatTime(client.uptime, 3, {longNames: true, commas: true})}**`);
const nameLength = Math.max(...includedCommands.map(x=>x.command.default.data.name.length), columns[0].length) + 2;
const amountLength = Math.max(...includedCommands.map(x=>x.uses.toString().length), columns[1].length) + 1;
const rows = [`${columns[0] + ' '.repeat(nameLength - columns[0].length)}|${' '.repeat(amountLength - columns[1].length) + columns[1]}\n`, '-'.repeat(nameLength) + '-'.repeat(amountLength) + '\n'];
@ -50,13 +52,13 @@ export default {
{name: '> __Host__', value: MessageTool.concatMessage(
`**Operating System:** ${osInfo.distro + ' ' + osInfo.release}`,
`**CPU:** ${cpu.manufacturer} ${cpu.brand}`,
`**Memory:** ${client.formatBytes(ram.used)}/${client.formatBytes(ram.total)}`,
`**Process:** ${client.formatBytes(process.memoryUsage().heapUsed)}/${client.formatBytes(process.memoryUsage().heapTotal)}`,
`**Memory:** ${FormatBytes(ram.used)}/${FormatBytes(ram.total)}`,
`**Process:** ${FormatBytes(process.memoryUsage().heapUsed)}/${FormatBytes(process.memoryUsage().heapTotal)}`,
`**Load Usage:**\nUser: ${currentLoad.currentLoadUser.toFixed(1)}%\nSystem: ${currentLoad.currentLoadSystem.toFixed(1)}%`,
`**Uptime:**\nHost: ${client.formatTime((os.uptime()*1000), 2, {longNames: true, commas: true})}\nBot: ${client.formatTime(client.uptime, 2, {commas: true, longNames: true})}`
`**Uptime:**\nHost: ${FormatTime((os.uptime()*1000), 2, {longNames: true, commas: true})}\nBot: ${FormatTime(client.uptime, 2, {commas: true, longNames: true})}`
)}
);
waitForData.edit({content:null,embeds:[embed]}).then(x=>x.edit({embeds:[new client.embed(x.embeds[0].data).setFooter({text: `Load time: ${client.formatTime(x.createdTimestamp - interaction.createdTimestamp, 2, {longNames: true, commas: true})}`})]}))
waitForData.edit({content:null,embeds:[embed]}).then(x=>x.edit({embeds:[new client.embed(x.embeds[0].data).setFooter({text: `Load time: ${FormatTime(x.createdTimestamp - interaction.createdTimestamp, 2, {longNames: true, commas: true})}`})]}))
},
data: new Discord.SlashCommandBuilder()
.setName('statistics')

View File

@ -1,8 +1,9 @@
import Discord from 'discord.js';
import TClient from '../client.js';
import Punish from '../funcs/Punish.js';
export default {
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
client.punish(interaction, 'warn');
Punish(client, interaction, 'warn');
},
data: new Discord.SlashCommandBuilder()
.setName('warn')

View File

@ -1,5 +1,6 @@
import Discord from 'discord.js';
import TClient from '../client';
import FormatPlayer from '../helpers/FormatPlayer.js';
import {writeFileSync, readFileSync} from 'node:fs';
import {FSPlayer, FSData, FSCareerSavegame, TServer} from '../typings/interfaces';
@ -12,12 +13,6 @@ export default async(client:TClient, Channel:string, Message:string, Server:TSer
const serverErrorEmbed = new client.embed().setColor(client.config.embedColorRed).setTitle('Host did not respond back in time');
const genericEmbed = new client.embed();
const decoPlayer = (player:FSPlayer)=>{
let decorator = player.isAdmin ? ':detective:' : '';
decorator += player.name.includes('Toast') ? '<:toastv2:1132681026662056079>' : '';
return decorator
}
const HITALL = async()=>{
let sessionInit = {signal: AbortSignal.timeout(8200),headers:{'User-Agent':`Daggerbot - HITALL/undici`}};
try {
@ -42,17 +37,17 @@ export default async(client:TClient, Channel:string, Message:string, Server:TSer
// Join/Leave log
function playerLogEmbed(player:FSPlayer,joinLog:boolean){
const logEmbed = new client.embed().setDescription(`**${player.name}${decoPlayer(player)}** ${joinLog ? 'joined' : 'left'} **${client.MPServerCache[ServerName].name}** at <t:${Math.round(Date.now()/1000)}:t>`);
const logEmbed = new client.embed().setDescription(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}** ${joinLog ? 'joined' : 'left'} **${client.MPServerCache[ServerName].name}** at <t:${Math.round(Date.now()/1000)}:t>`);
if (joinLog) return logEmbed.setColor(client.config.embedColorGreen);
else if (player.uptime > 0) return logEmbed.setColor(client.config.embedColorRed).setFooter({text:`Farmed for ${client.formatPlayerUptime(player.uptime)}`});
else if (player.uptime > 0) return logEmbed.setColor(client.config.embedColorRed).setFooter({text:`Farmed for ${FormatPlayer.uptimeFormat(player.uptime)}`});
else return logEmbed.setColor(client.config.embedColorRed);
}
const serverLog = client.channels.resolve(client.config.mainServer.channels.fs_server_log) as Discord.TextChannel;
const playersOnServer = hitDSS.slots?.players.filter(x=>x.isUsed);
const playersInCache = client.MPServerCache[ServerName].players;
if (!playersOnServer ?? playersOnServer === undefined) return new Error('[MPLoop] Empty array, ignoring...'); // For the love of god, stop throwing errors everytime.
playersOnServer.forEach(player=>playerData.push(`**${player.name}${decoPlayer(player)}**\nFarming for ${client.formatPlayerUptime(player.uptime)}`));
if (!playersOnServer ?? playersOnServer === undefined) return console.log('[MPLoop] Empty array, ignoring...'); // For the love of god, stop throwing errors everytime.
playersOnServer.forEach(player=>playerData.push(`**${player.name}${FormatPlayer.decoratePlayerIcons(player)}**\nFarming for ${FormatPlayer.uptimeFormat(player.uptime)}`));
// Player leaving
for (const player of playersInCache.filter(x=>!playersOnServer.some(y=>y.name === x.name))){

20
src/funcs/Punish.ts Normal file
View File

@ -0,0 +1,20 @@
import Discord from 'discord.js';
import TClient from '../client.js';
export default async(client:TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>, type: string)=>{
if (!client.isStaff(interaction.member as Discord.GuildMember)) return client.youNeedRole(interaction, 'dcmod');
const time = interaction.options.getString('time') ?? undefined;
const reason = interaction.options.getString('reason') ?? 'Reason unspecified';
const GuildMember = interaction.options.getMember('member') ?? undefined;
const User = interaction.options.getUser('member', true);
console.log(client.logTime(), `[PunishmentLog] ${GuildMember?.user?.username ?? User?.username ?? 'No user data'} ${time ? ['warn', 'kick'].includes(type) ? 'and no duration set' : `and ${time} (duration)` : ''} was used in /${interaction.commandName} for ${reason}`);
(client.channels.cache.get(client.config.mainServer.channels.punishment_log) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColor).setAuthor({name: interaction?.user?.username, iconURL: interaction?.user?.displayAvatarURL({size:2048})}).setTitle('Punishment Log').setDescription(`${GuildMember?.user?.username ?? User?.username ?? 'No user data'} ${time ? ['warn', 'kick'].includes(client.punishments.type) ? 'and no duration set' : `and ${time} (duration)` : ''} was used in \`/${interaction.commandName}\` for \`${reason}\``).setTimestamp()]});
if (interaction.user.id === User.id) return interaction.reply(`You cannot ${type} yourself.`);
if (!GuildMember && type != 'unban') return interaction.reply(`You cannot ${type} someone who is not in the server.`);
if (User.bot) return interaction.reply(`You cannot ${type} a bot!`);
await interaction.deferReply();
await client.punishments.addPunishment(type, {time, interaction}, interaction.user.id, reason, User, GuildMember);
}

18
src/funcs/YTLoop.ts Normal file
View File

@ -0,0 +1,18 @@
import {TextChannel} from 'discord.js';
import TClient from '../client.js';
export default async(client: TClient, YTChannelID: string, YTChannelName: string, DiscordChannelID: string, DiscordRoleID: string)=>{
let Data: any;
try {
await fetch(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelID}`, {signal: AbortSignal.timeout(8000), headers: {'User-Agent': 'Daggerbot - Notification/undici'}}).then(async xml=>Data = client.xjs.xml2js(await xml.text(), {compact: true}))
} catch(err){
console.log(client.logTime(), `Failed to fetch "${YTChannelName}" from YouTube`)
}
if (!Data) return;
if (!client.YTCache[YTChannelID]) return client.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
if (Data.feed.entry[1]['yt:videoId']._text === client.YTCache[YTChannelID]){
client.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
(client.channels.resolve(DiscordChannelID) as TextChannel).send({content: `<@&${DiscordRoleID}> (Ping notification are currently WIP, no eta when complete, the mentioned role is a placeholder for now)\n**${YTChannelName}** just uploaded a video!\n${Data.feed.entry[0].link._attributes.href}`, allowedMentions: {parse: ['roles']}})
}
}

View File

@ -0,0 +1,5 @@
export default (bytes:number, decimals:number = 2)=>{
if (bytes === 0) return '0 Bytes';
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return parseFloat((bytes / Math.pow(1024, i)).toFixed(decimals < 0 ? 0 : decimals))+ ' ' +['Bytes', 'KB', 'MB', 'GB', 'TB'][i]
}

View File

@ -0,0 +1,22 @@
import {FSPlayer} from '../typings/interfaces';
export default class FormatPlayer {
static uptimeFormat(playTime: number){
var Hours = 0;
playTime = Math.floor(Number(playTime));
if(playTime >= 60){
var Hours = Math.floor(Number(playTime)/60);
var Minutes = (Number(playTime)-(Hours*60));
} else Minutes = Number(playTime)
if(Hours >= 24){
var Days = Math.floor(Number(Hours)/24);
var Hours = (Hours-(Days*24));
} return (Days > 0 ? Days+' d ':'')+(Hours > 0 ? Hours+' h ':'')+(Minutes > 0 ? Minutes+' m':'')
}
static decoratePlayerIcons(player:FSPlayer){
let decorator = player.isAdmin ? ':detective:' : '';
decorator += player.name.includes('Toast') ? '<:toast:1132681026662056079>' : '';
decorator += player.name.includes('Daggerwin') ? '<:Daggerwin:549283056079339520>' : ''; // Probably useless lol, but we'll see.
return decorator
}
}

35
src/helpers/FormatTime.ts Normal file
View File

@ -0,0 +1,35 @@
interface formatTimeOpt {
longNames: boolean,
commas: boolean
}
export default (integer:number, accuracy:number = 1, options?:formatTimeOpt)=>{
let achievedAccuracy = 0;
let text:any = '';
for (const timeName of [
{name: 'year', length: 31536000000},
{name: 'month', length: 2592000000},
{name: 'week', length: 604800000},
{name: 'day', length: 86400000},
{name: 'hour', length: 3600000},
{name: 'minute', length: 60000},
{name: 'second', length: 1000}
]){
if (achievedAccuracy < accuracy){
const fullTimelengths = Math.floor(integer/timeName.length);
if (fullTimelengths === 0) continue;
achievedAccuracy++;
text += fullTimelengths + (options?.longNames ? (' '+timeName.name+(fullTimelengths === 1 ? '' : 's')) : timeName.name.slice(0, timeName.name === 'month' ? 2 : 1)) + (options?.commas ? ', ' : ' ');
integer -= fullTimelengths*timeName.length;
} else break;
}
if (text.length === 0) text = integer + (options?.longNames ? ' milliseconds' : 'ms') + (options?.commas ? ', ' : '');
if (options?.commas){
text = text.slice(0, -2);
if (options?.longNames){
text = text.split('');
text[text.lastIndexOf(',')] = ' and';
text = text.join('');
}
} return text.trim();
}

View File

@ -0,0 +1,18 @@
export default class UsernameHelper {
static stripName(text: string){
let matchesLeft = true;
const dirSlash = process.platform === 'linux' ? '\/' : '\\';
const array = text.split(dirSlash);
while (matchesLeft) {
let usersIndex = array.indexOf(process.platform === 'linux' ? 'media' : 'Users');
if (usersIndex < 1) matchesLeft = false;
else {
let usernameIndex = usersIndex + 1;
if (array[usernameIndex].length === 0) usernameIndex += 1;
array[usernameIndex] = '・'.repeat(array[usernameIndex].length);
array[usersIndex] = process.platform === 'linux' ? 'med\u200bia' : 'Us\u200bers';
}
return array.join(dirSlash);
}
}
}

View File

@ -2,6 +2,7 @@ import Discord from 'discord.js';
import TClient from './client.js';
const client = new TClient;
client.init();
import YTLoop from './funcs/YTLoop.js';
import MPLoop from './funcs/MPLoop.js';
import {Player} from 'discord-player';
const player = Player.singleton(client);
@ -10,11 +11,7 @@ import {writeFileSync, readFileSync} from 'node:fs';
// Error handler
function DZ(error:Error, type:string){// Yes, I may have shiternet but I don't need to wake up to like a hundred messages or so.
if ([
'ConnectTimeoutError: Connect Timeout Error', 'getaddrinfo EAI_AGAIN discord.com',
'[Error: 30130000:error:0A000410:SSL', '[Error: F8200000:error:0A000410:SSL',
'HTTPError: Internal Server Error'
].includes(error.message)) return;
if (JSON.parse(readFileSync('src/errorBlocklist.json', 'utf8')).includes(error.message)) return;// I wonder if my idea works, if not then please run me over with a bulldozer.
console.error(error);
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel | null)?.send({embeds: [new client.embed().setColor('#560000').setTitle('Error caught!').setFooter({text: 'Error type: ' + type}).setDescription(`**Error:**\n\`\`\`${error.message}\`\`\`**Stack:**\n\`\`\`${`${error.stack}`.slice(0, 2500)}\`\`\``)]})
}
@ -41,9 +38,9 @@ if (client.config.botSwitches.mpstats) setInterval(async()=>{
const serverlake = (await client.MPServer._content.findById(client.config.mainServer.id));
for await (const [locName, locArea] of Object.entries(client.config.MPStatsLocation)) await MPLoop(client, locArea.channel, locArea.message, serverlake[locName], locName)
}, 35000);
setInterval(async()=>{
client.YTLoop('UCQ8k8yTDLITldfWYKDs3xFg', 'Daggerwin', '528967918772551702'); // 528967918772551702 = #videos-and-streams
client.YTLoop('UCguI73--UraJpso4NizXNzA', 'Machinery Restorer', '767444045520961567') // 767444045520961567 = #machinery-restorer
setInterval(async()=>{// Ping notification is currently WIP, it might be active in production but I want to see how it goes with role mentions first so I can make any further changes.
YTLoop(client, 'UCQ8k8yTDLITldfWYKDs3xFg', 'Daggerwin', '528967918772551702', '1011341005389307925'); // 528967918772551702 = #videos-and-streams; 1011341005389307925 = Bot Tech;
YTLoop(client, 'UCguI73--UraJpso4NizXNzA', 'Machinery Restorer', '767444045520961567', '989591094524276796') // 767444045520961567 = #machinery-restorer; 989591094524276796 = Temp;
}, 300000)
// Event loop for punishments and daily msgs

View File

@ -2,6 +2,7 @@ import Discord from 'discord.js';
import TClient from '../client.js';
import mongoose from 'mongoose';
import ms from 'ms';
import FormatTime from '../helpers/FormatTime.js';
import {Punishment} from '../typings/interfaces.js';
const Schema = mongoose.model('punishments', new mongoose.Schema({
@ -36,7 +37,7 @@ export default class punishments extends Schema {
{name: '\u200b', value: '\u200b', inline: true},
{name: '🔹 Reason', value: `\`${punishment.reason}\``, inline: true})
.setColor(this.client.config.embedColor).setTimestamp(punishment.time)
if (punishment.duration) embed.addFields({name: '🔹 Duration', value: this.client.formatTime(punishment.duration, 100), inline: true}, {name: '\u200b', value: '\u200b', inline: true})
if (punishment.duration) embed.addFields({name: '🔹 Duration', value: `${FormatTime(punishment.duration, 100)}`, inline: true}, {name: '\u200b', value: '\u200b', inline: true})
if (punishment.cancels) {
const cancels = await this._content.findById(punishment.cancels);
embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id}\n\`${cancels.reason}\``})
@ -72,7 +73,7 @@ export default class punishments extends Schema {
if (type == 'mute') timeInMillis = time ? ms(time) : 2419140000; // Timeouts have a limit of 4 weeks
else timeInMillis = time ? ms(time) : null;
const durationText = timeInMillis ? ` for ${this.client.formatTime(timeInMillis, 4, {longNames:true,commas:true})}` : '';
const durationText = timeInMillis ? ` for ${FormatTime(timeInMillis, 4, {longNames:true,commas:true})}` : '';
if (time) embed.addFields({name: 'Duration', value: durationText});
if (GuildMember){

View File

@ -4,10 +4,6 @@ export interface UserLevels {
messages: number,
level: number
}
export interface formatTimeOpt {
longNames: boolean,
commas: boolean
}
export interface punOpt {
time?: string,
reason?: string,
@ -116,7 +112,7 @@ export interface Tokens {
main: string
beta: string
toast: string
dontlookatme: {
spotify: {
client: string,
secret: string
}

View File

@ -198,6 +198,15 @@ __metadata:
languageName: node
linkType: hard
"@mongodb-js/saslprep@npm:^1.1.0":
version: 1.1.0
resolution: "@mongodb-js/saslprep@npm:1.1.0"
dependencies:
sparse-bitfield: ^3.0.3
checksum: 1479a43e216734672f8eb1a2a55165b6896841bd00fb5bd645390a24374ef6c29f0f6d19a43618a19b8f1912fcbd2b2cc2210a62361103d1f28dce6852cf31d4
languageName: node
linkType: hard
"@npmcli/fs@npm:^3.1.0":
version: 3.1.0
resolution: "@npmcli/fs@npm:3.1.0"
@ -743,10 +752,10 @@ __metadata:
discord.js: 14.13.0
libsodium-wrappers: 0.7.11
moment: 2.29.4
mongoose: 7.4.5
mongoose: 7.5.0
ms: 2.1.3
prism-media: 1.3.5
systeminformation: 5.21.0
systeminformation: 5.21.1
typescript: 5.2.2
xml-js: 1.6.11
youtube-sr: 4.3.4
@ -1545,22 +1554,22 @@ __metadata:
languageName: node
linkType: hard
"mongodb@npm:5.7.0":
version: 5.7.0
resolution: "mongodb@npm:5.7.0"
"mongodb@npm:5.8.1":
version: 5.8.1
resolution: "mongodb@npm:5.8.1"
dependencies:
"@mongodb-js/saslprep": ^1.1.0
bson: ^5.4.0
mongodb-connection-string-url: ^2.6.0
saslprep: ^1.0.3
socks: ^2.7.1
peerDependencies:
"@aws-sdk/credential-providers": ^3.201.0
"@mongodb-js/zstd": ^1.1.0
kerberos: ^2.0.1
"@aws-sdk/credential-providers": ^3.188.0
"@mongodb-js/zstd": ^1.0.0
kerberos: ^1.0.0 || ^2.0.0
mongodb-client-encryption: ">=2.3.0 <3"
snappy: ^7.2.2
dependenciesMeta:
saslprep:
"@mongodb-js/saslprep":
optional: true
peerDependenciesMeta:
"@aws-sdk/credential-providers":
@ -1573,22 +1582,22 @@ __metadata:
optional: true
snappy:
optional: true
checksum: 16357b6229abac165aecea15a6efa873ec8662a00411ecb9e49853f05a590be31aab63d404486125778eedaafe76d70e84eea682fa89b138decc247f4870d2ec
checksum: da8fc05952266f9b636000d74e6c8889306fc287922651526029a61ede3c75f793edb504a02c1f64fec9fea9aa17323bf95eb4902776778a1def5eba07b32b72
languageName: node
linkType: hard
"mongoose@npm:7.4.5":
version: 7.4.5
resolution: "mongoose@npm:7.4.5"
"mongoose@npm:7.5.0":
version: 7.5.0
resolution: "mongoose@npm:7.5.0"
dependencies:
bson: ^5.4.0
kareem: 2.5.1
mongodb: 5.7.0
mongodb: 5.8.1
mpath: 0.9.0
mquery: 5.0.0
ms: 2.1.3
sift: 16.0.1
checksum: a017bd90bbdf64bf2867abfb0ba5fe84049bf09f8bca53af465a3ad694abd9475c1140041910af8ac86b1185d00ec02fd4c936ffc05b9f67ba8c4b9b246a7a7e
checksum: 3e4219fd29a44efe9d1fe41134bdbafca9b44f6da58fc01be3723379954d9ca6bdd8d2bdd352ded932432b9d0e0c5146490add84eb14f4aee3743d94e6cae643
languageName: node
linkType: hard
@ -1939,15 +1948,6 @@ __metadata:
languageName: node
linkType: hard
"saslprep@npm:^1.0.3":
version: 1.0.3
resolution: "saslprep@npm:1.0.3"
dependencies:
sparse-bitfield: ^3.0.3
checksum: 4fdc0b70fb5e523f977de405e12cca111f1f10dd68a0cfae0ca52c1a7919a94d1556598ba2d35f447655c3b32879846c77f9274c90806f6673248ae3cea6ee43
languageName: node
linkType: hard
"sax@npm:^1.1.3, sax@npm:^1.2.4":
version: 1.2.4
resolution: "sax@npm:1.2.4"
@ -2175,12 +2175,12 @@ __metadata:
languageName: node
linkType: hard
"systeminformation@npm:5.21.0":
version: 5.21.0
resolution: "systeminformation@npm:5.21.0"
"systeminformation@npm:5.21.1":
version: 5.21.1
resolution: "systeminformation@npm:5.21.1"
bin:
systeminformation: lib/cli.js
checksum: 0d6f22ed92c6e92167a27af5dcc5f1a9c0b2b82a33f9e674f9b2a6c1ebb79141ba405b8bde8e624101766c5d7ef087f50c45411d00690513e38f77e654f468cf
checksum: e08e56ea3bf0efc54c7bc0d2a675c4c181d7413d0b26fc80590433f24957e7e3c28fa35c46fae6c066bde4b73d9fccc6305c3b02616b35117df297356f793aa0
conditions: (os=darwin | os=linux | os=win32 | os=freebsd | os=openbsd | os=netbsd | os=sunos | os=android)
languageName: node
linkType: hard