mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-11-17 00:10:58 -05:00
Compare commits
3 Commits
c4b5d59033
...
e3f0da75b3
Author | SHA1 | Date | |
---|---|---|---|
|
e3f0da75b3 | ||
|
793c22dbcd | ||
|
de7169035f |
56
.pnp.cjs
generated
56
.pnp.cjs
generated
@ -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"\
|
||||
}]\
|
||||
|
@ -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",
|
||||
|
119
src/client.ts
119
src/client.ts
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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')
|
||||
|
@ -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.`)
|
||||
|
@ -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.||')
|
||||
})
|
||||
}
|
||||
|
@ -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')
|
||||
|
@ -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)}`;
|
||||
|
@ -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: {
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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
20
src/funcs/Punish.ts
Normal 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
18
src/funcs/YTLoop.ts
Normal 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']}})
|
||||
}
|
||||
}
|
5
src/helpers/FormatBytes.ts
Normal file
5
src/helpers/FormatBytes.ts
Normal 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]
|
||||
}
|
22
src/helpers/FormatPlayer.ts
Normal file
22
src/helpers/FormatPlayer.ts
Normal 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
35
src/helpers/FormatTime.ts
Normal 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();
|
||||
}
|
18
src/helpers/UsernameHelper.ts
Normal file
18
src/helpers/UsernameHelper.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
13
src/index.ts
13
src/index.ts
@ -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
|
||||
|
@ -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){
|
||||
|
6
src/typings/interfaces.d.ts
vendored
6
src/typings/interfaces.d.ts
vendored
@ -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
|
||||
}
|
||||
|
58
yarn.lock
58
yarn.lock
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user