mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-12-25 23:15:38 -05:00
enough coding for now, gonna get milk™️
This commit is contained in:
parent
49af49423b
commit
386ee4f54e
5
.gitignore
vendored
5
.gitignore
vendored
@ -5,4 +5,7 @@ package-lock.json
|
||||
# TypeScript stuff
|
||||
dist/
|
||||
# Bot stuff
|
||||
src/database/MPDB.dat
|
||||
src/database/MPDB.dat
|
||||
src/commands/disabled
|
||||
src/commands/roleinfo.ts
|
||||
src/commands/rank.ts
|
1
botStartup.sh
Normal file
1
botStartup.sh
Normal file
@ -0,0 +1 @@
|
||||
npx ts-node src/index.ts
|
@ -32,8 +32,9 @@
|
||||
"discord.js": "14.6.0",
|
||||
"moment": "2.29.4",
|
||||
"ms": "2.1.3",
|
||||
"sequelize": "7.0.0-alpha.9",
|
||||
"sequelize": "6.25.6",
|
||||
"sqlite3": "5.1.2",
|
||||
"systeminformation": "5.12.15",
|
||||
"xml-js": "1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -2,6 +2,7 @@ import Discord, { Client, GatewayIntentBits, Partials } from 'discord.js';
|
||||
import fs from 'node:fs';
|
||||
import { Database } from './database';
|
||||
import timeNames from './timeNames';
|
||||
import { Punishment, formatTimeOpt, createTableOpt, punOpt } from './typings/interfaces';
|
||||
export class TClient extends Client {
|
||||
invites: Map<any, any>;
|
||||
commands: Discord.Collection<string, any>;
|
||||
@ -30,14 +31,14 @@ export class TClient extends Client {
|
||||
GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers,
|
||||
GatewayIntentBits.GuildBans, GatewayIntentBits.GuildInvites,
|
||||
GatewayIntentBits.GuildPresences, GatewayIntentBits.GuildMessageReactions,
|
||||
GatewayIntentBits.DirectMessages, GatewayIntentBits.MessageContent
|
||||
GatewayIntentBits.DirectMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages
|
||||
],
|
||||
partials: [
|
||||
Partials.Channel,
|
||||
Partials.Reaction,
|
||||
Partials.Message
|
||||
],
|
||||
allowedMentions: { users: [], roles: [] } // idk if it would work but requires testing...
|
||||
allowedMentions: { users: [], roles: [] }
|
||||
})
|
||||
this.invites = new Map();
|
||||
this.commands = new Discord.Collection();
|
||||
@ -77,7 +78,7 @@ export class TClient extends Client {
|
||||
this.registry.push(command.default.data.toJSON())
|
||||
}
|
||||
}
|
||||
formatPunishmentType(punishment: Punishment, client: TClient, cancels: Punishment){
|
||||
formatPunishmentType(punishment: Punishment, client: TClient, cancels?: Punishment){
|
||||
if (punishment.type == 'removeOtherPunishment'){
|
||||
cancels ||= this.punishments._content.find((x: Punishment)=>x.id === punishment.cancels)
|
||||
return cancels.type[0].toUpperCase()+cancels.type.slice(1)+' Removed';
|
||||
@ -86,13 +87,12 @@ export class TClient extends Client {
|
||||
formatTime(integer: number, accuracy = 1, options?: formatTimeOpt){
|
||||
let achievedAccuracy = 0;
|
||||
let text:any = '';
|
||||
const { longNames, commas } = options
|
||||
for (const timeName of timeNames){
|
||||
if (achievedAccuracy < accuracy){
|
||||
const fullTimelengths = Math.floor(integer/timeName.length);
|
||||
if (fullTimelengths == 0) continue;
|
||||
achievedAccuracy++;
|
||||
text += fullTimelengths + (longNames ? (' '+timeName.name+(fullTimelengths === 1 ? '' : 's')) : timeName.name.slice(0, timeName.name === 'month' ? 2 : 1)) + (commas ? ', ' : ' ');
|
||||
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;
|
||||
@ -182,8 +182,8 @@ export class TClient extends Client {
|
||||
async punish(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>, type: string){
|
||||
let result: any;
|
||||
if (!client.isStaff(interaction.member as Discord.GuildMember)) return this.youNeedRole(interaction, 'dcmod')
|
||||
if (type !== ('warn' || 'mute') && (interaction.member as Discord.GuildMember).roles.cache.has(client.config.mainServer.roles.idk)) return this.youNeedRole(interaction, 'dcmod');
|
||||
const time = this.ms(interaction.options.getString('time'));
|
||||
//if (type !== ('warn' || 'mute') && (interaction.member as Discord.GuildMember).roles.cache.has(client.config.mainServer.roles.idk)) return this.youNeedRole(interaction, 'dcmod');
|
||||
const time = interaction.options.getString('time') as string;
|
||||
const reason = interaction.options.getString('reason') ?? 'Reason unspecified';
|
||||
if (type == 'ban'){
|
||||
const user = interaction.options.getUser('member') as Discord.User;
|
||||
@ -208,7 +208,18 @@ export class TClient extends Client {
|
||||
}
|
||||
|
||||
async YTLoop(YTChannelID: string, YTChannelName: string, DCChannelID: string){
|
||||
const Data = this.xjs.xml2js((await this.axios.get(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelID}`, {timeout: 5000})), {compact: true, spaces: 2}).catch(()=>{return null});
|
||||
let Data:any;
|
||||
let error;
|
||||
|
||||
try {
|
||||
await this.axios.get(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelID}`, {timeout: 5000}).then((xml:any)=>{
|
||||
Data = this.xjs.xml2js(xml.data, {compact: true, spaces: 2});
|
||||
})
|
||||
} catch(err){
|
||||
error = true;
|
||||
console.log(`\x1b[36m[${this.moment().format('DD/MM/YY HH:mm:ss')}]`, `\x1b[31m${YTChannelName} YT fail`)
|
||||
}
|
||||
|
||||
if (!Data) return;
|
||||
if (this.YTCache[YTChannelID] == undefined){
|
||||
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
|
||||
@ -251,7 +262,7 @@ class punishments extends Database {
|
||||
}
|
||||
switch (type) {
|
||||
case 'ban':
|
||||
const banData: Punishment={type, id: this.createId(), member: member.id, moderator, time: now};
|
||||
const banData:Punishment={type, id: this.createId(), member: member.id, moderator, time: now};
|
||||
const dm1: Discord.Message = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')})
|
||||
const banResult = await interaction.guild.bans.create(member.id, {reason: `${reason || 'Reason unspecified'} | Case #${banData.id}`}).catch((err:Error)=>err.message);
|
||||
if (typeof banResult === 'string'){
|
||||
@ -272,16 +283,84 @@ class punishments extends Database {
|
||||
}
|
||||
case 'softban':
|
||||
const guild = member.guild;
|
||||
const softbanData: Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
const softbanData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
const dm2 = Discord.Message = await member.send(`You've been softbanned from ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${softbanData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')})
|
||||
const softbanResult = await member.ban({deleteMessageDays: 3, reason: `${reason || 'Reason unspecified'} | Case #${softbanData.id}`}).catch((err:Error)=>err.message);
|
||||
if (typeof softbanResult === 'string') {
|
||||
dm2.delete();
|
||||
return `Softban was unsuccessful: ${softbanResult}`;
|
||||
} else {
|
||||
const unbanResult = guild.members.unban(softbanData.member, `${reason || 'Reason unspecified'} | Case #${softbanData.id}`).catch((err:Error)=>err.message);
|
||||
if (typeof unbanResult === 'string'){
|
||||
return `Softban (unban) was unsuccessful: ${softbanResult}`
|
||||
} else {
|
||||
if (reason) softbanData.reason = reason;
|
||||
this.client.makeModlogEntry(softbanData, this.client);
|
||||
this.addData(softbanData).forceSave();
|
||||
return new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${softbanData.id}: Softban`).setDescription(`${member.user.tag}\n<@${member.user.tag}>\n(\`${member.user.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}
|
||||
)
|
||||
}
|
||||
}
|
||||
case 'kick':
|
||||
const kickData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
const dm3: Discord.Message = await member.send(`You've been kicked from ${member.guild.name} for reason \`${reason || 'Reason unspecified'}\` (Case #${kickData.id})`).catch(()=>{interaction.channel.send(`Failed to DM <@${member.user.id}>.`); return null});
|
||||
const kickResult = await member.kick(`${reason || 'Reason unspecified'} | Case #${kickData.id}`).catch((err:Error)=>err.message)
|
||||
if (typeof kickResult === 'string'){
|
||||
if (dm3) dm3.delete();
|
||||
return `Kick was unsuccessful: ${kickResult}`
|
||||
} else {
|
||||
if (reason) kickData.reason = reason;
|
||||
this.client.makeModlogEntry(kickData, this.client);
|
||||
this.addData(kickData).forceSave();
|
||||
return new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${kickData.id}: Kick`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}
|
||||
)
|
||||
}
|
||||
case 'warn':
|
||||
const warnData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
const warnResult: Discord.Message = await member.send(`You've been warned in ${member.guild.name} for reason \`${reason || 'Reason unspecified'}\` (Case #${warnData.id})`).catch(()=>{interaction.channel.send(`Failed to DM <@${member.user.id}>`); return null;})
|
||||
if (typeof warnResult === 'string'){
|
||||
return `Warn was unsuccessful: ${warnResult}`
|
||||
} else {
|
||||
if (reason) warnData.reason = reason;
|
||||
this.client.makeModlogEntry(warnData, this.client);
|
||||
this.addData(warnData).forceSave();
|
||||
const embedw = new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${warnData.id}: Warn`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}
|
||||
)
|
||||
if (moderator !== '795443537356521502') {return embedw}
|
||||
}
|
||||
case 'mute':
|
||||
const muteData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now};
|
||||
let muteResult;
|
||||
if (this.client.isStaff(member)) return 'Staff cannot be muted.'
|
||||
const dm4: Discord.Message = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch(()=>{interaction.channel.send('Failed to DM user.'); return null});
|
||||
if (timeInMillis) {
|
||||
muteResult = await member.timeout(timeInMillis, `${reason || 'Reason unspecified'} | Case #${muteData.id}`).catch((err:Error)=>err.message);
|
||||
} else {
|
||||
muteResult = await member.timeout(2419200000, `${reason || 'Reason unspecified'} | Case #${muteData.id}`).catch((err:Error)=>err.message);
|
||||
}
|
||||
if (typeof muteResult === 'string'){
|
||||
if (dm4) dm4.delete();
|
||||
return `Mute was unsuccessful: ${muteResult}`;
|
||||
} else {
|
||||
if (timeInMillis) {
|
||||
muteData.endTime = now + timeInMillis;
|
||||
muteData.duration = timeInMillis;
|
||||
}
|
||||
if (reason) muteData.reason = reason;
|
||||
this.client.makeModlogEntry(muteData, this.client);
|
||||
this.addData(muteData).forceSave();
|
||||
const embedm = new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${muteData.id}: Mute`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields(
|
||||
{name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``},
|
||||
{name: 'Duration',
|
||||
value: `${this.client.formatTime(timeInMillis, 4, {
|
||||
longNames: true,
|
||||
commas: true
|
||||
})} (${timeInMillis}ms)`})
|
||||
if (moderator !== '795443537356521502') {return embedm};
|
||||
}
|
||||
}
|
||||
}
|
||||
async removePunishment(caseId:number, moderator:any, reason:string):Promise<any>{}
|
||||
|
32
src/commands/bonk.ts
Normal file
32
src/commands/bonk.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (!client.isStaff(interaction.member) && interaction.channelId == '468835415093411863') return interaction.reply('This command is restricted to staff only in this channel due to high usage.')
|
||||
const member = interaction.options.getUser('member');
|
||||
const reason = interaction.options.getString('reason');
|
||||
const adminPerm = interaction.member.permissions.has('Administrator')
|
||||
if (!member) {
|
||||
return interaction.reply('You can\'t bonk the ghost.')
|
||||
} else {
|
||||
//if (member && adminPerm) return interaction.reply('You cannot bonk an admin!')
|
||||
if (member) {
|
||||
const embed = new client.embed().setColor(client.config.embedColor)
|
||||
.setDescription(`> <@${member.id}> has been bonked!\n${reason?.length == null ? '' : `> Reason: ${reason}`}`)
|
||||
.setImage('https://media.tenor.com/7tRddlNUNNcAAAAd/hammer-on-head-minions.gif')
|
||||
.setFooter({text: `Bonk count for ${member.tag}: ${await client.bonkCount.getUser(member.id).toLocaleString('en-US')}`})
|
||||
interaction.reply({embeds: [embed]})
|
||||
client.bonkCount._incrementUser(member.id).forceSave();
|
||||
}
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('bonk')
|
||||
.setDescription('Bonk a member')
|
||||
.addUserOption((opt)=>opt
|
||||
.setName('member')
|
||||
.setDescription('Which member to bonk?'))
|
||||
.addStringOption((opt)=>opt
|
||||
.setName('reason')
|
||||
.setDescription('Reason for the bonk'))
|
||||
}
|
20
src/commands/contributors.ts
Normal file
20
src/commands/contributors.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
|
||||
'Toast <@190407856527376384>',
|
||||
'TÆMBØ <@615761944154210305>',
|
||||
'Buzz <@593696856165449749>',
|
||||
'Monster <@215497515934416896>',
|
||||
'RainbowDave <@141304507249197057>',
|
||||
'Hitchhiker <@506022868157595648>',
|
||||
'RedRover92 <@633345781780185099>',
|
||||
'Nawdic <@178941218510602240>'
|
||||
].join('\n'))
|
||||
interaction.reply({embeds: [embed]})
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('contributors')
|
||||
.setDescription('List of people who helped and worked on the bot.')
|
||||
}
|
58
src/commands/fsurl.ts
Normal file
58
src/commands/fsurl.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
import MPDB from '../models/MPServer';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (interaction.guildId !== client.config.mainServer.id) return interaction.reply('This command doesn\'t work in this server.');
|
||||
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.mpmanager) && !interaction.member.roles.cache.has(client.config.mainServer.roles.bottech) && !interaction.member.roles.cache.has(client.config.mainServer.roles.admin)) return client.youNeedRole(interaction, 'mpmanager');
|
||||
|
||||
MPDB.sync();
|
||||
const newServerId = interaction.guildId
|
||||
const address = interaction.options.getString('address')
|
||||
|
||||
if (!address) {
|
||||
try {
|
||||
const Url = await MPDB.findOne({where: {serverId: newServerId}})
|
||||
if (Url.ip && Url.code){return interaction.reply(`${Url.get('ip')}` + '/feed/dedicated-server-stats.json?code=' + `${Url.get('code')}`)}
|
||||
} catch(err) {
|
||||
if (err.name == 'SequelizeDatabaseError'){
|
||||
console.log('MPDB | File doesn\'t exist in database folder, generating one now.')
|
||||
interaction.reply('`MPDB.dat` is being createdm run the command again.')
|
||||
} else {
|
||||
console.log(`MPDB | Error: ${err}`)
|
||||
interaction.reply('Database error:\nTry inserting an URL first.')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const verifyURL = address.match(/feed/)
|
||||
if (!verifyURL) return interaction.reply('Invalid URL, try again.')
|
||||
const convertURL = address
|
||||
const newURL = convertURL.replace('xml','json').split('/feed/dedicated-server-stats.json?code=')
|
||||
try {
|
||||
console.log(`MPDB | URL for ${interaction.guild.name} has been updated by ${interaction.member.displayName} (${interaction.member.id})`)
|
||||
const Url = await MPDB.create({
|
||||
serverId: newServerId,
|
||||
ip: newURL[0],
|
||||
code: newURL[1]
|
||||
});
|
||||
return interaction.reply(`Successfully set the URL to ${Url.ip}`)
|
||||
} catch(err) {
|
||||
if (err.name == 'SequelizeUniqueConstraintError'){
|
||||
const AffectedRows = await MPDB.update({ip: newURL[0], code: newURL[1]},{where:{serverId: newServerId}});
|
||||
if (AffectedRows){return interaction.reply(`Successfully updated the URL to ${newURL[0]}`)}
|
||||
} else {
|
||||
console.log(err)
|
||||
interaction.reply(`\`MPDB\` has caught an error, notify <@&${client.config.mainServer.roles.bottech}>`)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('url')
|
||||
.setDescription('Update the URL for FSMP functions')
|
||||
.addStringOption((opt)=>opt
|
||||
.setName('address')
|
||||
.setDescription('Insert a \'dedicated-server-stats\' url')
|
||||
.setRequired(false))
|
||||
}
|
262
src/commands/mp.ts
Normal file
262
src/commands/mp.ts
Normal file
@ -0,0 +1,262 @@
|
||||
import Discord,{EmbedBuilder, SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
import MPDB from '../models/MPServer';
|
||||
|
||||
async function MPdata(client:TClient, interaction:Discord.ChatInputCommandInteraction, embed: EmbedBuilder) {
|
||||
let FSserver;
|
||||
MPDB.sync();
|
||||
const newServerId = interaction.guildId;
|
||||
const ServerURL = await MPDB.findOne({where: { serverId: newServerId }});
|
||||
const DBURL = ServerURL.ip
|
||||
const DBCode = ServerURL.code
|
||||
const verifyURL = DBURL.match(/http/)
|
||||
const completedURL = DBURL + '/feed/dedicated-server-stats.json?code=' + DBCode
|
||||
if (!verifyURL) return interaction.reply(`No gameserver found, please contact <@&${client.config.mainServer.roles.mpmanager}> to update it.`)
|
||||
|
||||
// Fetch dss
|
||||
try {
|
||||
FSserver = await client.axios.get(completedURL, {timeout: 2800}) // 2800 seems doable with database latency added to it.
|
||||
} catch(err) {
|
||||
// Blame Nawdic & RedRover92
|
||||
embed.setTitle('Host is not responding.');
|
||||
embed.setColor(client.config.embedColorRed);
|
||||
interaction.reply({embeds: [embed]});
|
||||
console.log('dag mp fail to fetch, host is not responding.');
|
||||
return;
|
||||
}
|
||||
return FSserver
|
||||
}
|
||||
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (interaction.channelId == '468835769092669461' && !client.isStaff(interaction.member) && ['status', 'players'].includes(interaction.options.getSubcommand())) {
|
||||
interaction.reply(`Please use <#739084625862852715> for \`/mp status/players\` commands to prevent clutter in this channel.`).then((msg)=>{
|
||||
setTimeout(()=>{interaction.deleteReply()}, 500)
|
||||
});
|
||||
return;
|
||||
}
|
||||
const Subb = interaction.options.getSubcommand();
|
||||
switch (Subb){
|
||||
case 'status':
|
||||
const embed0 = new client.embed();
|
||||
const FSserver0 = await MPdata(client, interaction, embed0);
|
||||
if (FSserver0.data.server.name.length > 1) {
|
||||
embed0.setTitle('Status/Details').setColor(client.config.embedColor).addFields(
|
||||
{name: 'Server name', value: `${FSserver0?.data.server.name.length == 0 ? '\u200b' : `\`${FSserver0?.data.server.name}\``}`, inline: true},
|
||||
{name: 'Players', value: `${FSserver0.data.slots.used} out of ${FSserver0.data.slots.capacity}`, inline: true},
|
||||
{name: 'Current map', value: `${FSserver0?.data.server.mapName.length == 0 ? '\u200b' : FSserver0.data.server.mapName}`, inline: true},
|
||||
{name: 'Version', value: `${FSserver0?.data.server.version.length == 0 ? '\u200b' : FSserver0.data.server.version}`, inline: true},
|
||||
{name: 'In-game Time', value: `${('0' + Math.floor((FSserver0.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSserver0.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true}
|
||||
)
|
||||
}
|
||||
interaction.reply({embeds: [embed0]})
|
||||
break;
|
||||
case 'players':
|
||||
const embed1 = new client.embed();
|
||||
const data = require('../database/MPPlayerData.json').slice(-60)
|
||||
|
||||
// handle negative days
|
||||
data.forEach((change: number, i: number) => {
|
||||
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
||||
});
|
||||
|
||||
const first_graph_top = 16;
|
||||
|
||||
const second_graph_top = 16;
|
||||
|
||||
const textSize = 40;
|
||||
|
||||
const canvas = require('canvas');
|
||||
const img = canvas.createCanvas(1500, 750);
|
||||
const ctx = img.getContext('2d');
|
||||
|
||||
const graphOrigin = [15, 65];
|
||||
const graphSize = [1300, 630];
|
||||
const nodeWidth = graphSize[0] / (data.length - 1);
|
||||
ctx.fillStyle = '#36393f';
|
||||
ctx.fillRect(0, 0, img.width, img.height);
|
||||
|
||||
// grey horizontal lines
|
||||
ctx.lineWidth = 5;
|
||||
|
||||
let interval_candidates = [];
|
||||
for (let i = 4; i < 10; i++) {
|
||||
const interval = first_graph_top / i;
|
||||
if (Number.isInteger(interval)) {
|
||||
let intervalString = interval.toString();
|
||||
const reference_number = i * Math.max(intervalString.split('').filter(x => x === '0').length / intervalString.length, 0.3) * (['1', '2', '4', '5', '6', '8'].includes(intervalString[0]) ? 1.5 : 0.67)
|
||||
interval_candidates.push([interval, i, reference_number]);
|
||||
}
|
||||
}
|
||||
const chosen_interval = interval_candidates.sort((a, b) => b[2] - a[2])[0];
|
||||
|
||||
const previousY: Array<number> = [];
|
||||
|
||||
ctx.strokeStyle = '#202225';
|
||||
for (let i = 0; i <= chosen_interval[1]; i++) {
|
||||
const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]);
|
||||
if (y < graphOrigin[1]) continue;
|
||||
const even = ((i + 1) % 2) === 0;
|
||||
if (even) ctx.strokeStyle = '#2c2f33';
|
||||
ctx.beginPath();
|
||||
ctx.lineTo(graphOrigin[0], y);
|
||||
ctx.lineTo(graphOrigin[0] + graphSize[0], y);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
if (even) ctx.strokeStyle = '#202225';
|
||||
previousY.push(y, i * chosen_interval[0]);
|
||||
}
|
||||
|
||||
// 30m mark
|
||||
ctx.setLineDash([8, 16]);
|
||||
ctx.beginPath();
|
||||
const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 60));
|
||||
ctx.lineTo(lastMonthStart, graphOrigin[1]);
|
||||
ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
// draw points
|
||||
ctx.lineWidth = 5;
|
||||
|
||||
|
||||
function getYCoordinate(value: number) {
|
||||
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
||||
}
|
||||
|
||||
function colorAtPlayercount(playercount: number) {
|
||||
if (playercount === first_graph_top) {
|
||||
return client.config.embedColorRed;
|
||||
} else if (playercount > 9) {
|
||||
return client.config.embedColorYellow;
|
||||
} else {return client.config.embedColorGreen;}
|
||||
}
|
||||
let lastCoords: Array<number> = [];
|
||||
data.forEach((curPC: number /* current player count */, i: number) => {
|
||||
if (curPC < 0) curPC = 0;
|
||||
const x = i * nodeWidth + graphOrigin[0];
|
||||
const y = getYCoordinate(curPC);
|
||||
const nexPC /* next player count */ = data[i + 1];
|
||||
const prvPC /* previous player count */ = data[i - 1];
|
||||
const curColor = colorAtPlayercount(curPC); // color now
|
||||
const prvColor = colorAtPlayercount(prvPC); // color at last point
|
||||
if (curColor !== prvColor && !isNaN(prvPC) && lastCoords.length > 0) { // gradient should be used when the color between now and last point is not the same
|
||||
// gradient from now to last point
|
||||
const grd = ctx.createLinearGradient(...lastCoords, x, y);
|
||||
grd.addColorStop(0, colorAtPlayercount(prvPC)); // prev color at the beginning
|
||||
grd.addColorStop(1, colorAtPlayercount(curPC)); // cur color at the end
|
||||
// special case: playercount rises or falls rapidly accross all colors (eg. straight from red to green)
|
||||
if (curColor !== client.config.embedColorYellow && prvColor !== client.config.embedColorYellow) {
|
||||
const yellowY = getYCoordinate(10); // y coordinate at which line should be yellow
|
||||
const stop = (yellowY - lastCoords[1]) / (y - lastCoords[1]); // between 0 and 1, where is yellowY between y and nextPointCoords[1] ?
|
||||
grd.addColorStop(stop, client.config.embedColorYellow); // add a yellow stop to the gradient
|
||||
}
|
||||
ctx.strokeStyle = grd;
|
||||
} else {
|
||||
ctx.strokeStyle = colorAtPlayercount(curPC);
|
||||
}
|
||||
ctx.beginPath();
|
||||
if (lastCoords.length > 0) ctx.moveTo(...lastCoords);
|
||||
// if the line being drawn is horizontal, make it go until it has to go down
|
||||
if (y === lastCoords[1]) {
|
||||
let newX = x;
|
||||
for (let j = i + 1; j <= data.length; j++) {
|
||||
if (data[j] === curPC) newX += nodeWidth; else break;
|
||||
}
|
||||
ctx.lineTo(newX, y);
|
||||
} else {
|
||||
ctx.lineTo(x, y);
|
||||
}
|
||||
lastCoords = [x, y];
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
|
||||
if (curPC === prvPC && curPC === nexPC) {
|
||||
return; // no ball because no vertical difference to next or prev point
|
||||
} else {
|
||||
// ball
|
||||
ctx.fillStyle = colorAtPlayercount(curPC);
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, ctx.lineWidth * 1.3, 0, 2 * Math.PI)
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
});
|
||||
|
||||
// draw text
|
||||
ctx.font = '400 ' + textSize + 'px sans-serif';
|
||||
ctx.fillStyle = 'white';
|
||||
|
||||
// highest value
|
||||
const maxx = graphOrigin[0] + graphSize[0] + textSize / 2;
|
||||
const maxy = previousY[0] + (textSize / 3);
|
||||
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
||||
|
||||
// lowest value
|
||||
const lowx = graphOrigin[0] + graphSize[0] + textSize / 2;
|
||||
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
||||
ctx.fillText('0 players', lowx, lowy);
|
||||
|
||||
// 30m
|
||||
ctx.fillText('30 mins ago', lastMonthStart, graphOrigin[1] - (textSize / 2));
|
||||
|
||||
// time ->
|
||||
const tx = graphOrigin[0] + (textSize / 2);
|
||||
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
||||
ctx.fillText('time ->', tx, ty);
|
||||
|
||||
const Image = new client.attachmentBuilder(img.toBuffer(),{name: 'FSStats.png'})
|
||||
embed1.setImage('attachment://FSStats.png')
|
||||
const FSserver1 = await MPdata(client, interaction, embed1)
|
||||
embed1.setTitle(FSserver1.data.server.name.length == 0 ? 'Offline' : FSserver1?.data.server.name)
|
||||
.setDescription(`${FSserver1?.data.slots.used}/${FSserver1?.data.slots.capacity}`)
|
||||
.setColor(FSserver1?.data.server.name.length == 0 ? client.config.embedColorRed : client.config.embedColor);
|
||||
FSserver1?.data.slots.players.filter(x=>x.isUsed).forEach(player=>{
|
||||
embed1.addFields({name: `${player.name} ${player.isAdmin ? '| admin' : ''}`, value: `Farming for ${(Math.floor(player.uptime/60))} hr, ${('0' + (player.uptime % 60)).slice(-2)} min`})
|
||||
})
|
||||
interaction.reply({embeds: [embed1], files: [Image]})
|
||||
break;
|
||||
case 'info':
|
||||
const embed2 = new client.embed().setColor(client.config.embedColor)
|
||||
const FSserver2 = await MPdata(client, interaction, embed2)
|
||||
const DBURL = MPDB.findOne({where: {serverId: interaction.guildId}})
|
||||
embed2.setDescription([
|
||||
`**Server name**: ${FSserver2?.data.server.name.length == 0 ? 'Unknown Server' : `\`${FSserver2.data.server.name}\``}`,
|
||||
'**Password:** `mf4700`',
|
||||
'**Crossplay server**',
|
||||
`**Map:** ${FSserver2.data.server.mapName.length == 0 ? 'Null Island' : FSserver2.data.server.mapName}`,
|
||||
`**Mods:** [Click here](${(await DBURL).ip}/mods.html) **|** [Direct Download](${(await DBURL).ip}/all_mods_download?onlyActive=true)`,
|
||||
'**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)'
|
||||
].join('\n'));
|
||||
interaction.reply({embeds: [embed2]})
|
||||
break;
|
||||
case 'series':
|
||||
const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('How to join the Daggerwin MP series')
|
||||
.setDescription([
|
||||
'To join the Daggerwin MP series, you first need to:',
|
||||
'**1:** Note that only PC players can join the MP series due to the mods that are used.',
|
||||
'**2:** Become a YouTube Member by pressing the `Join` button on [Daggerwin\'s YouTube page](https://www.youtube.com/c/Daggerwin) next to the `Subscribe` button.',
|
||||
'**3:** Link your YouTube account to your Discord account via Settings>Connections>Add connection. Be sure that you link the same YouTube account you used to become a channel member.',
|
||||
'**4:** If you don\'t receive the role within a day or so, please message an Admin and they will sort it out.',
|
||||
'**5:** Take a look in <#511657659364147200> to get information on how to join the server.'
|
||||
].join('\n'));
|
||||
interaction.reply({embeds: [embed3]})
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('mp')
|
||||
.setDescription('Display MP status and other things')
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('status')
|
||||
.setDescription('Check server status and details'))
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('players')
|
||||
.setDescription('Check who\'s playing on the server'))
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('info')
|
||||
.setDescription('Provides you with server information such as filters and so on'))
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('series')
|
||||
.setDescription('Step-by-step on joining Daggerwin\'s MP series'))
|
||||
}
|
20
src/commands/mute.ts
Normal file
20
src/commands/mute.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
client.punish(client, interaction, 'mute');
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('mute')
|
||||
.setDescription('Mute a member')
|
||||
.addUserOption((opt)=>opt
|
||||
.setName('member')
|
||||
.setDescription('Which member to mute?')
|
||||
.setRequired(true))
|
||||
.addStringOption((opt)=>opt
|
||||
.setName('time')
|
||||
.setDescription('Mute duration'))
|
||||
.addStringOption((opt)=>opt
|
||||
.setName('reason')
|
||||
.setDescription('Reason for the mute'))
|
||||
}
|
@ -4,7 +4,7 @@ export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const msg = await interaction.reply({content: 'Pinging...', fetchReply: true})
|
||||
const time = msg.createdTimestamp - interaction.createdTimestamp;
|
||||
msg.edit(`Websocket: \`${client.ws.ping}\`ms\nBot: \`${time}\``)
|
||||
msg.edit(`Websocket: \`${client.ws.ping}\`ms\nBot: \`${time}\`ms`)
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
|
11
src/commands/restart.ts
Normal file
11
src/commands/restart.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
if (!client.config.eval.whitelist.includes(interaction.user.id)) return client.youNeedRole(interaction, 'bottech');
|
||||
interaction.reply('Restarting...').then(()=>require('node:child_process').exec('pm2 restart Daggerbot'))
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('restart')
|
||||
.setDescription('Restart the bot for technical reasons')
|
||||
}
|
85
src/commands/statistics.ts
Normal file
85
src/commands/statistics.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import Discord,{SlashCommandBuilder, version} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
import si from 'systeminformation';
|
||||
import os from 'node:os';
|
||||
import { versionMajorMinor } from 'typescript';
|
||||
import { VERSION } from 'ts-node';
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
switch (interaction.options.getSubcommand()) {
|
||||
case 'commands':
|
||||
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 as number, 2, {longNames: true, commas: true})}`);
|
||||
const nameLength = Math.max(...includedCommands.map(x=>x.default.data.name.length), columns[0].length) + 2;
|
||||
const amountLength = Math.max(...includedCommands.map(x=>x.uses.toLocaleString().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'];
|
||||
includedCommands.forEach(command=>{
|
||||
const name = command.default.data.name;
|
||||
const count = command.uses.toString();
|
||||
rows.push(`${name + ' '.repeat(nameLength - name.length)}${' '.repeat(amountLength - count.length) + count}\n`);
|
||||
});
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Statistics: Command Usage')
|
||||
.setDescription([
|
||||
'List of commands that have been used in this session, ordered by amount of use. Table contains command name and amount of uses.',
|
||||
`Total amount of commands used in this session: ${client.commands.filter(x=>x.uses).map(x=>x.uses).reduce((a,b)=>a+b, 0)}`
|
||||
].join('\n'))
|
||||
if (rows.join('').length > 1024){
|
||||
let fieldValue = '';
|
||||
rows.forEach(row=>{
|
||||
if (fieldValue.length + row.length > 1024){
|
||||
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
|
||||
fieldValue = row;
|
||||
} else {
|
||||
fieldValue += row;
|
||||
}
|
||||
});
|
||||
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
|
||||
} else {
|
||||
embed.addFields({name: '\u200b', value: `\`\`\`\n${rows.join('')}\`\`\``})
|
||||
};
|
||||
interaction.reply({embeds: [embed]})
|
||||
break;
|
||||
case 'host':
|
||||
// Bytes conversion
|
||||
function formatBytes(bytes, decimals = 2) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
}
|
||||
await interaction.deferReply();
|
||||
const cpu = await si.cpu();
|
||||
const ram = await si.mem();
|
||||
const osInfo = await si.osInfo();
|
||||
const currentLoad = await si.currentLoad();
|
||||
const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Statistics: Host Info').setDescription([
|
||||
`> __Dependencies__`,
|
||||
`**TypeScript:** ${versionMajorMinor}`,
|
||||
`**TS-Node:** ${VERSION}`,
|
||||
`**NodeJS:** ${process.version}`,
|
||||
`**DiscordJS:** ${version}`,
|
||||
`> __Host__`,
|
||||
`**Operating System:** ${osInfo.distro + ' ' + osInfo.release}`,
|
||||
`**CPU:** ${cpu.manufacturer, cpu.brand}`,
|
||||
`**Memory:** ${formatBytes(ram.used)}/${formatBytes(ram.total)}`,
|
||||
`**NodeJS:** ${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 as number, 2, {commas: true, longNames: true})}`
|
||||
].join('\n'))
|
||||
.setFooter({text: `Load time: ${Date.now() - interaction.createdTimestamp}ms`});
|
||||
interaction.editReply({embeds: [embed1]});
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('statistics')
|
||||
.setDescription('See a list of commands ordered by their usage or bot stats')
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('commands')
|
||||
.setDescription('View command usage stats'))
|
||||
.addSubcommand((opt)=>opt
|
||||
.setName('host')
|
||||
.setDescription('View host stats'))
|
||||
}
|
@ -12,7 +12,7 @@ export default {
|
||||
} else if (stdout.includes('Already up to date')){
|
||||
msg.edit(`Pull aborted:\nUp to date with the repository`)
|
||||
} else {
|
||||
setTimeout(()=>{msg.edit('Restarting...').then(()=>eval(process.exit(-1)))},1000)
|
||||
setTimeout(()=>{msg.edit('Restarting...').then(()=>require('node:child_process').exec('pm2 restart Daggerbot'))},1000)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
61
src/commands/whois.ts
Normal file
61
src/commands/whois.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||
import { TClient } from 'src/client';
|
||||
|
||||
function convert(status:string){
|
||||
switch (status){
|
||||
case 'offline':
|
||||
return '⚫'
|
||||
case 'idle':
|
||||
return '🟡'
|
||||
case 'dnd':
|
||||
return '🔴'
|
||||
case 'online':
|
||||
return '🟢'
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||
const member = interaction.options.getMember('member') as Discord.GuildMember;
|
||||
if (member == null){
|
||||
const user = interaction.options.getUser('member') as Discord.User;
|
||||
const embed = new client.embed()
|
||||
.setColor(client.config.embedColor)
|
||||
.setURL(`https://discord.com/users/${user.id}`)
|
||||
.setThumbnail(user.avatarURL({size:2048}) || user.defaultAvatarURL)
|
||||
.setTitle(`${user.bot ? 'Bot': 'User'} Info: ${user.tag}`)
|
||||
.setDescription(`<@${user.id}>\n\`${user.id}\``)
|
||||
.addFields({name: '🔹 Account Creation Date', value: `<t:${Math.round(user.createdTimestamp/1000)}>\n<t:${Math.round(user.createdTimestamp/1000)}:R>`})
|
||||
interaction.reply({embeds: [embed]})
|
||||
} else {
|
||||
await member.user.fetch();
|
||||
const embedArray = [];
|
||||
const embed0 = new client.embed()
|
||||
.setColor(member.displayColor || client.config.embedColor)
|
||||
.setURL(`https://discord.com/users/${member.user.id}`)
|
||||
.setThumbnail(member.user.avatarURL({size:2048}) || member.user.defaultAvatarURL)
|
||||
.setImage(member.user.bannerURL({size:1024}) as string)
|
||||
.setTitle(`${member.user.bot ? 'Bot' : 'Member'} Info: ${member.user.tag}`)
|
||||
.setDescription(`<@${member.user.id}>\n\`${member.user.id}\`${member.user.id === interaction.guild.ownerId ? '\n__**Server Owner**__ 👑' : ''}`)
|
||||
.addFields(
|
||||
{name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/1000)}:R>`},
|
||||
{name: '🔹 Server Join Date', value: `<t:${Math.round((member.joinedTimestamp as number)/1000)}>\n<t:${Math.round((member.joinedTimestamp as number)/1000)}:R>`},
|
||||
{name: `🔹 Roles: ${member.roles.cache.size - 1}`, value: member.roles.cache.size > 1 ? member.roles.cache.filter(x=>x.id !== interaction.guild.roles.everyone.id).sort((a,b)=>b.position - a.position).map(x=>x).join(member.roles.cache.size > 4 ? ' ' : '\n').slice(0,1024) : 'No roles'}
|
||||
)
|
||||
console.log(member.guild.banner)
|
||||
if (member.premiumSinceTimestamp !== null){
|
||||
embed0.addFields({name: '🔹 Server Boosting since', value: `<t:${Math.round(member.premiumSinceTimestamp/1000)}>\n<t:${Math.round(member.premiumSinceTimestamp/1000)}:R>`, inline: true})
|
||||
}
|
||||
if (member.presence){embed0.addFields({name: `🔹 Status: ${member.presence.status}`, value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${(member.presence.clientStatus as Discord.ClientPresenceStatusData).desktop ? convert((member.presence.clientStatus as Discord.ClientPresenceStatusData).desktop as string) : convert('offline')}\nWeb: ${(member.presence.clientStatus as Discord.ClientPresenceStatusData).web ? convert((member.presence.clientStatus as Discord.ClientPresenceStatusData).web as string) : convert('offline')}\nMobile: ${(member.presence.clientStatus as Discord.ClientPresenceStatusData).mobile ? convert((member.presence.clientStatus as Discord.ClientPresenceStatusData).mobile as string) : convert('offline')}`}`, inline: true})}
|
||||
embedArray.push(embed0)
|
||||
interaction.reply({embeds: embedArray})
|
||||
}
|
||||
},
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('whois')
|
||||
.setDescription('View your own or someone else\'s information')
|
||||
.addUserOption((opt)=>opt
|
||||
.setName('member')
|
||||
.setDescription('Member or user to view their information')
|
||||
.setRequired(true))
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
["fuck","fck","fů","fuk","fúck","fùck","fûck","fück","fūck","fůck","fűck","fùçk","fûćk","fucking","fųck","shit","shite","sht","shìt","shít","shît","shït","shīt","shįt","shıt","shlt","whore","pelotudo","boludo","nigger","nigga","nigs","niggas@","cunt","cnut","bitch","dick","pussy","asshole","b1tch","b!tch","blowjob","cock","c0ck","retard","fag","faggot","tits","boobs","dick","sex","porn","bjob","stfu","","","͏","͏","","ᅟ","ᅠ","឴","឵","","","","stfu","ass","kkk","<@1011334031478100099>","<@468835415093411861>","asf","af","wtf","piss","pissed","pissing"]
|
||||
["fuck","fck","fů","fuk","fúck","fùck","fûck","fück","fūck","fůck","fűck","fùçk","fûćk","fucking","fųck","shit","shite","sht","shìt","shít","shît","shït","shīt","shįt","shıt","shlt","whore","pelotudo","boludo","nigger","nigga","nigs","niggas@","cunt","cnut","bitch","dick","pussy","asshole","b1tch","b!tch","blowjob","cock","c0ck","retard","fag","faggot","tits","boobs","dick","sex","porn","bjob","stfu","","","͏","͏","","ᅟ","ᅠ","឴","឵","","","","stfu","ass","kkk","<@1011334031478100099>","<@468835415093411861>","asf","af","wtf","piss","pissed"]
|
@ -1 +1 @@
|
||||
[[0,674965],[1,675885],[2,676639],[3,677245],[4,677609],[5,678188],[6,678916],[7,679465],[8,679938],[9,680540],[10,681614],[11,682079],[12,682780],[13,683187],[14,683547],[15,683900],[16,684592],[17,685466],[18,686078],[19,686481],[20,676748],[21,676968],[22,677427],[23,677592],[24,677894],[25,678116],[26,676785],[27,677570],[28,678491],[29,679137],[30,679818],[31,680094],[32,680417],[33,680783],[34,681563],[35,682070],[36,682670],[37,683504],[38,684078],[39,684383],[40,684692],[41,685448],[42,685664],[43,685994],[44,686366],[45,687118],[46,687626],[47,688008],[48,688754],[49,688942],[50,689107],[51,689472],[52,690143],[53,690644],[54,691124],[55,692196],[56,692624],[57,692906],[58,693456],[59,693952],[60,694586],[61,695070],[62,696163],[63,696564],[64,697315],[65,698548],[66,699138],[67,699558],[68,700307],[69,701063],[70,701394],[71,701868],[72,702453],[73,702917],[76,705187],[77,705243],[78,705488],[79,705961],[80,706585],[81,707467],[82,708212],[83,709024],[84,709773],[85,710256]]
|
||||
[[0,674965],[1,675885],[2,676639],[3,677245],[4,677609],[5,678188],[6,678916],[7,679465],[8,679938],[9,680540],[10,681614],[11,682079],[12,682780],[13,683187],[14,683547],[15,683900],[16,684592],[17,685466],[18,686078],[19,686481],[20,676748],[21,676968],[22,677427],[23,677592],[24,677894],[25,678116],[26,676785],[27,677570],[28,678491],[29,679137],[30,679818],[31,680094],[32,680417],[33,680783],[34,681563],[35,682070],[36,682670],[37,683504],[38,684078],[39,684383],[40,684692],[41,685448],[42,685664],[43,685994],[44,686366],[45,687118],[46,687626],[47,688008],[48,688754],[49,688942],[50,689107],[51,689472],[52,690143],[53,690644],[54,691124],[55,692196],[56,692624],[57,692906],[58,693456],[59,693952],[60,694586],[61,695070],[62,696163],[63,696564],[64,697315],[65,698548],[66,699138],[67,699558],[68,700307],[69,701063],[70,701394],[71,701868],[72,702453],[73,702917],[76,705187],[77,705243],[78,705488],[79,705961],[80,706585],[81,707467],[82,708212],[83,709024],[84,709773],[85,710256],[86,710980]]
|
@ -94,5 +94,13 @@
|
||||
"moderator": "532662366354276352",
|
||||
"time": 1668331244780,
|
||||
"reason": "innapropiate profile picture"
|
||||
},
|
||||
{
|
||||
"type": "ban",
|
||||
"id": 13,
|
||||
"member": "985447227755495425",
|
||||
"moderator": "141304507249197057",
|
||||
"time": 1668526989338,
|
||||
"reason": "steam scammer"
|
||||
}
|
||||
]
|
@ -1,54 +1,54 @@
|
||||
{
|
||||
"190407856527376384": {
|
||||
"messages": 53012,
|
||||
"messages": 53029,
|
||||
"level": 59
|
||||
},
|
||||
"593696856165449749": {
|
||||
"messages": 51421,
|
||||
"messages": 51456,
|
||||
"level": 58
|
||||
},
|
||||
"141304507249197057": {
|
||||
"messages": 67626,
|
||||
"messages": 67631,
|
||||
"level": 67
|
||||
},
|
||||
"533707949831487488": {
|
||||
"messages": 56992,
|
||||
"messages": 57038,
|
||||
"level": 61
|
||||
},
|
||||
"532662366354276352": {
|
||||
"messages": 33701,
|
||||
"messages": 33775,
|
||||
"level": 47
|
||||
},
|
||||
"824043915539513406": {
|
||||
"messages": 18442,
|
||||
"messages": 18452,
|
||||
"level": 35
|
||||
},
|
||||
"178941218510602240": {
|
||||
"messages": 6375,
|
||||
"messages": 6394,
|
||||
"level": 20
|
||||
},
|
||||
"215497515934416896": {
|
||||
"messages": 33124,
|
||||
"messages": 33129,
|
||||
"level": 46
|
||||
},
|
||||
"301350210926280704": {
|
||||
"messages": 14317,
|
||||
"messages": 14334,
|
||||
"level": 30
|
||||
},
|
||||
"695323013813633076": {
|
||||
"messages": 14076,
|
||||
"messages": 14090,
|
||||
"level": 30
|
||||
},
|
||||
"389237487094071337": {
|
||||
"messages": 12240,
|
||||
"messages": 12254,
|
||||
"level": 28
|
||||
},
|
||||
"716355511552966737": {
|
||||
"messages": 9138,
|
||||
"messages": 9146,
|
||||
"level": 24
|
||||
},
|
||||
"633345781780185099": {
|
||||
"messages": 29365,
|
||||
"messages": 29379,
|
||||
"level": 44
|
||||
},
|
||||
"711527768185372742": {
|
||||
@ -64,31 +64,31 @@
|
||||
"level": 18
|
||||
},
|
||||
"458688902102908928": {
|
||||
"messages": 6209,
|
||||
"messages": 6237,
|
||||
"level": 20
|
||||
},
|
||||
"475037861725339649": {
|
||||
"messages": 10194,
|
||||
"messages": 10201,
|
||||
"level": 26
|
||||
},
|
||||
"392699530912727041": {
|
||||
"messages": 4937,
|
||||
"messages": 4944,
|
||||
"level": 18
|
||||
},
|
||||
"468837263577579524": {
|
||||
"messages": 7677,
|
||||
"messages": 7695,
|
||||
"level": 22
|
||||
},
|
||||
"734703851558535188": {
|
||||
"messages": 20203,
|
||||
"messages": 20211,
|
||||
"level": 36
|
||||
},
|
||||
"488683638310043677": {
|
||||
"messages": 15457,
|
||||
"messages": 15477,
|
||||
"level": 32
|
||||
},
|
||||
"606595407769894995": {
|
||||
"messages": 23240,
|
||||
"messages": 23251,
|
||||
"level": 39
|
||||
},
|
||||
"322835877027905547": {
|
||||
@ -96,7 +96,7 @@
|
||||
"level": 25
|
||||
},
|
||||
"485793265568841728": {
|
||||
"messages": 37883,
|
||||
"messages": 37885,
|
||||
"level": 50
|
||||
},
|
||||
"837979120142778388": {
|
||||
@ -112,7 +112,7 @@
|
||||
"level": 18
|
||||
},
|
||||
"690090143008555064": {
|
||||
"messages": 9974,
|
||||
"messages": 9978,
|
||||
"level": 25
|
||||
},
|
||||
"849633082440941628": {
|
||||
@ -120,15 +120,15 @@
|
||||
"level": 0
|
||||
},
|
||||
"687720203773149238": {
|
||||
"messages": 572,
|
||||
"level": 0
|
||||
"messages": 573,
|
||||
"level": 6
|
||||
},
|
||||
"452576735494406175": {
|
||||
"messages": 1679,
|
||||
"messages": 1684,
|
||||
"level": 10
|
||||
},
|
||||
"763055599654666291": {
|
||||
"messages": 971,
|
||||
"messages": 972,
|
||||
"level": 8
|
||||
},
|
||||
"623176215800446976": {
|
||||
@ -148,11 +148,11 @@
|
||||
"level": 0
|
||||
},
|
||||
"169891949464125441": {
|
||||
"messages": 521,
|
||||
"messages": 538,
|
||||
"level": 5
|
||||
},
|
||||
"718453763932946432": {
|
||||
"messages": 13548,
|
||||
"messages": 13549,
|
||||
"level": 30
|
||||
},
|
||||
"472809522226790420": {
|
||||
@ -160,7 +160,7 @@
|
||||
"level": 13
|
||||
},
|
||||
"763803832542035978": {
|
||||
"messages": 683,
|
||||
"messages": 685,
|
||||
"level": 6
|
||||
},
|
||||
"931816463113814066": {
|
||||
@ -172,7 +172,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"771892617599516674": {
|
||||
"messages": 626,
|
||||
"messages": 630,
|
||||
"level": 6
|
||||
},
|
||||
"468437000232501269": {
|
||||
@ -188,7 +188,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"309373272594579456": {
|
||||
"messages": 3585,
|
||||
"messages": 3588,
|
||||
"level": 15
|
||||
},
|
||||
"399625244588900362": {
|
||||
@ -200,7 +200,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"615761944154210305": {
|
||||
"messages": 3063,
|
||||
"messages": 3070,
|
||||
"level": 14
|
||||
},
|
||||
"397101726047666197": {
|
||||
@ -228,7 +228,7 @@
|
||||
"level": 2
|
||||
},
|
||||
"645342896312156181": {
|
||||
"messages": 684,
|
||||
"messages": 693,
|
||||
"level": 6
|
||||
},
|
||||
"488505753133645826": {
|
||||
@ -240,7 +240,7 @@
|
||||
"level": 2
|
||||
},
|
||||
"848489550065827850": {
|
||||
"messages": 42,
|
||||
"messages": 44,
|
||||
"level": 1
|
||||
},
|
||||
"862138850423472128": {
|
||||
@ -248,7 +248,7 @@
|
||||
"level": 1
|
||||
},
|
||||
"700053257996992573": {
|
||||
"messages": 75,
|
||||
"messages": 76,
|
||||
"level": 2
|
||||
},
|
||||
"949404588673482872": {
|
||||
@ -280,7 +280,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"509374532109336576": {
|
||||
"messages": 29,
|
||||
"messages": 31,
|
||||
"level": 1
|
||||
},
|
||||
"464887328138199042": {
|
||||
@ -344,7 +344,7 @@
|
||||
"level": 1
|
||||
},
|
||||
"132183685658050561": {
|
||||
"messages": 8,
|
||||
"messages": 9,
|
||||
"level": 0
|
||||
},
|
||||
"549295707304099846": {
|
||||
@ -400,8 +400,8 @@
|
||||
"level": 0
|
||||
},
|
||||
"903147621961588757": {
|
||||
"messages": 14,
|
||||
"level": 0
|
||||
"messages": 15,
|
||||
"level": 1
|
||||
},
|
||||
"386627658773168137": {
|
||||
"messages": 2,
|
||||
@ -416,15 +416,15 @@
|
||||
"level": 0
|
||||
},
|
||||
"774337023804833825": {
|
||||
"messages": 81,
|
||||
"level": 0
|
||||
"messages": 83,
|
||||
"level": 2
|
||||
},
|
||||
"700434438890323990": {
|
||||
"messages": 9,
|
||||
"level": 0
|
||||
},
|
||||
"281518331427553280": {
|
||||
"messages": 28,
|
||||
"messages": 29,
|
||||
"level": 1
|
||||
},
|
||||
"708758234407895050": {
|
||||
@ -528,7 +528,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"818595993121062974": {
|
||||
"messages": 46,
|
||||
"messages": 48,
|
||||
"level": 1
|
||||
},
|
||||
"273755695680192513": {
|
||||
@ -540,7 +540,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"869718328313278555": {
|
||||
"messages": 97,
|
||||
"messages": 98,
|
||||
"level": 2
|
||||
},
|
||||
"772197160372404234": {
|
||||
@ -632,7 +632,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"280115935057281024": {
|
||||
"messages": 1,
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"595727217271635969": {
|
||||
@ -652,7 +652,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"188304766923833344": {
|
||||
"messages": 21,
|
||||
"messages": 22,
|
||||
"level": 1
|
||||
},
|
||||
"749311773819142326": {
|
||||
@ -668,8 +668,8 @@
|
||||
"level": 1
|
||||
},
|
||||
"673950857238413362": {
|
||||
"messages": 12,
|
||||
"level": 0
|
||||
"messages": 16,
|
||||
"level": 1
|
||||
},
|
||||
"434344693824749568": {
|
||||
"messages": 3,
|
||||
@ -764,7 +764,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"552473047144071168": {
|
||||
"messages": 20,
|
||||
"messages": 21,
|
||||
"level": 1
|
||||
},
|
||||
"587377817893994538": {
|
||||
@ -820,7 +820,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"513009978315898891": {
|
||||
"messages": 20,
|
||||
"messages": 23,
|
||||
"level": 1
|
||||
},
|
||||
"667815332047486978": {
|
||||
@ -1052,7 +1052,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"781289786143932499": {
|
||||
"messages": 107,
|
||||
"messages": 111,
|
||||
"level": 2
|
||||
},
|
||||
"348617165135544321": {
|
||||
@ -1232,8 +1232,8 @@
|
||||
"level": 0
|
||||
},
|
||||
"444415772001959936": {
|
||||
"messages": 14,
|
||||
"level": 0
|
||||
"messages": 16,
|
||||
"level": 1
|
||||
},
|
||||
"629585796290314250": {
|
||||
"messages": 103,
|
||||
@ -1312,7 +1312,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"486352184707907585": {
|
||||
"messages": 4,
|
||||
"messages": 5,
|
||||
"level": 0
|
||||
},
|
||||
"309170189164085249": {
|
||||
@ -1340,8 +1340,8 @@
|
||||
"level": 0
|
||||
},
|
||||
"98464148379148288": {
|
||||
"messages": 1436,
|
||||
"level": 9
|
||||
"messages": 1504,
|
||||
"level": 10
|
||||
},
|
||||
"1025723411680460840": {
|
||||
"messages": 1,
|
||||
@ -1372,7 +1372,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"786733440003211285": {
|
||||
"messages": 15,
|
||||
"messages": 17,
|
||||
"level": 1
|
||||
},
|
||||
"853043920505012255": {
|
||||
@ -1472,7 +1472,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"889624632724963329": {
|
||||
"messages": 38,
|
||||
"messages": 51,
|
||||
"level": 1
|
||||
},
|
||||
"687692546314600530": {
|
||||
@ -1656,7 +1656,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"937750032344571934": {
|
||||
"messages": 102,
|
||||
"messages": 103,
|
||||
"level": 2
|
||||
},
|
||||
"873149038709571594": {
|
||||
@ -1684,7 +1684,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"633339908827643974": {
|
||||
"messages": 12,
|
||||
"messages": 13,
|
||||
"level": 0
|
||||
},
|
||||
"174267277187874816": {
|
||||
@ -1724,8 +1724,8 @@
|
||||
"level": 0
|
||||
},
|
||||
"796040852400635914": {
|
||||
"messages": 367,
|
||||
"level": 4
|
||||
"messages": 396,
|
||||
"level": 5
|
||||
},
|
||||
"1011307308325818438": {
|
||||
"messages": 23,
|
||||
@ -1740,7 +1740,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"673289306424475659": {
|
||||
"messages": 122,
|
||||
"messages": 129,
|
||||
"level": 2
|
||||
},
|
||||
"907163452043305000": {
|
||||
@ -1824,7 +1824,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"335637071878422529": {
|
||||
"messages": 125,
|
||||
"messages": 127,
|
||||
"level": 2
|
||||
},
|
||||
"646684489573203968": {
|
||||
@ -1856,7 +1856,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"1031950921233600662": {
|
||||
"messages": 15,
|
||||
"messages": 17,
|
||||
"level": 1
|
||||
},
|
||||
"907951346769092618": {
|
||||
@ -1924,7 +1924,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"813866707365265419": {
|
||||
"messages": 109,
|
||||
"messages": 114,
|
||||
"level": 2
|
||||
},
|
||||
"726188513518813275": {
|
||||
@ -1944,7 +1944,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"715615331938467962": {
|
||||
"messages": 8,
|
||||
"messages": 9,
|
||||
"level": 0
|
||||
},
|
||||
"1033047374597214298": {
|
||||
@ -1968,7 +1968,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"1030526730462572558": {
|
||||
"messages": 191,
|
||||
"messages": 192,
|
||||
"level": 3
|
||||
},
|
||||
"530533266206359552": {
|
||||
@ -2092,7 +2092,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"123080080946757632": {
|
||||
"messages": 37,
|
||||
"messages": 39,
|
||||
"level": 1
|
||||
},
|
||||
"1001530115148226711": {
|
||||
@ -2120,7 +2120,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"969867332304400404": {
|
||||
"messages": 6,
|
||||
"messages": 7,
|
||||
"level": 0
|
||||
},
|
||||
"881867367418826812": {
|
||||
@ -2228,7 +2228,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"591972887812898816": {
|
||||
"messages": 1,
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"718100655851438090": {
|
||||
@ -2320,7 +2320,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"1029465066174677132": {
|
||||
"messages": 10,
|
||||
"messages": 11,
|
||||
"level": 0
|
||||
},
|
||||
"387345064927428611": {
|
||||
@ -2340,7 +2340,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"938332923042598933": {
|
||||
"messages": 1,
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"719181129390751755": {
|
||||
@ -2352,7 +2352,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"972513020972519484": {
|
||||
"messages": 87,
|
||||
"messages": 94,
|
||||
"level": 2
|
||||
},
|
||||
"953310806538330163": {
|
||||
@ -2376,7 +2376,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"703628676310368257": {
|
||||
"messages": 4,
|
||||
"messages": 6,
|
||||
"level": 0
|
||||
},
|
||||
"444715401159639042": {
|
||||
@ -2488,7 +2488,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"284482432684785664": {
|
||||
"messages": 2,
|
||||
"messages": 3,
|
||||
"level": 0
|
||||
},
|
||||
"727948378067173407": {
|
||||
@ -2500,7 +2500,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"490183428990304286": {
|
||||
"messages": 75,
|
||||
"messages": 77,
|
||||
"level": 2
|
||||
},
|
||||
"787352638811013151": {
|
||||
@ -2520,7 +2520,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"534500956688351242": {
|
||||
"messages": 4,
|
||||
"messages": 8,
|
||||
"level": 0
|
||||
},
|
||||
"989466115803590686": {
|
||||
@ -2544,7 +2544,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"697953686487564348": {
|
||||
"messages": 110,
|
||||
"messages": 123,
|
||||
"level": 2
|
||||
},
|
||||
"664233182941413427": {
|
||||
@ -2592,7 +2592,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"340587045250531358": {
|
||||
"messages": 84,
|
||||
"messages": 86,
|
||||
"level": 2
|
||||
},
|
||||
"911709434554777660": {
|
||||
@ -2680,7 +2680,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"999736341220839464": {
|
||||
"messages": 7,
|
||||
"messages": 9,
|
||||
"level": 0
|
||||
},
|
||||
"901565970974392331": {
|
||||
@ -2688,7 +2688,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"388211913621897216": {
|
||||
"messages": 21,
|
||||
"messages": 22,
|
||||
"level": 1
|
||||
},
|
||||
"1039241529912475729": {
|
||||
@ -2700,12 +2700,12 @@
|
||||
"level": 0
|
||||
},
|
||||
"995622955897864272": {
|
||||
"messages": 70,
|
||||
"messages": 92,
|
||||
"level": 2
|
||||
},
|
||||
"153323923633733632": {
|
||||
"messages": 8,
|
||||
"level": 0
|
||||
"messages": 17,
|
||||
"level": 1
|
||||
},
|
||||
"190028480786726913": {
|
||||
"messages": 2,
|
||||
@ -2716,7 +2716,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"590595536537518091": {
|
||||
"messages": 2,
|
||||
"messages": 4,
|
||||
"level": 0
|
||||
},
|
||||
"576383133763764225": {
|
||||
@ -2728,7 +2728,7 @@
|
||||
"level": 0
|
||||
},
|
||||
"328602696040841216": {
|
||||
"messages": 7,
|
||||
"messages": 10,
|
||||
"level": 0
|
||||
},
|
||||
"222861120329744387": {
|
||||
@ -2736,11 +2736,11 @@
|
||||
"level": 0
|
||||
},
|
||||
"927957676120473671": {
|
||||
"messages": 1,
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"846431793715871749": {
|
||||
"messages": 1,
|
||||
"messages": 3,
|
||||
"level": 0
|
||||
},
|
||||
"838471706871988234": {
|
||||
@ -2748,11 +2748,31 @@
|
||||
"level": 0
|
||||
},
|
||||
"259798326705127435": {
|
||||
"messages": 1,
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"910647475570901054": {
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"1037133851190890589": {
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
},
|
||||
"945263081095852042": {
|
||||
"messages": 5,
|
||||
"level": 0
|
||||
},
|
||||
"521087871776718869": {
|
||||
"messages": 4,
|
||||
"level": 0
|
||||
},
|
||||
"299940980680032279": {
|
||||
"messages": 3,
|
||||
"level": 0
|
||||
},
|
||||
"248226483967885312": {
|
||||
"messages": 2,
|
||||
"level": 0
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ export default {
|
||||
const usedInvite = newInvites.find((inv:any)=>oldInvites.get(inv.code)?.uses < inv.uses);
|
||||
newInvites.forEach((inv:any)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviter.id}));
|
||||
|
||||
const embed1 = new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Joined: ${member.user.tag}`).setDescription(`<@${member.user.id}>\n\`${member.user.id}\``).addFields(
|
||||
const embed1 = new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Joined: ${member.user.tag}`).setDescription(`<@${member.user.id}>\n\`${member.user.id}\``).setFooter({text: `Total members: ${index}${suffix}`}).addFields(
|
||||
{name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/1000)}:R>`},
|
||||
{name: '🔹 Invite Data:', value: usedInvite ? `Invite: \`${usedInvite.code}\`\nCreated by: **${usedInvite.inviter?.tag}**` : 'I couldn\'t find out how they joined!'}
|
||||
);
|
||||
|
@ -3,7 +3,7 @@ import { TClient } from '../client';
|
||||
export default {
|
||||
name: 'messageCreate',
|
||||
execute: async(client:TClient, message:Discord.Message)=>{
|
||||
if (!client.config.botSwitches.commands && !client.config.eval.whitelist.includes(message.author.id)) return
|
||||
if (!client.config.botSwitches.commands && !client.config.eval.whitelist.includes(message.author.id)) return
|
||||
if (message.author.bot) return;
|
||||
if (message.channel.type === ChannelType.DM) return;
|
||||
const msgarr = message.content.toLowerCase().split(' ');
|
||||
@ -73,15 +73,15 @@ export default {
|
||||
}
|
||||
|
||||
// Autoresponse:tm:
|
||||
if (!client.config.botSwitches.autores && !automodded) {
|
||||
if (client.config.botSwitches.autores && !automodded) {
|
||||
if (message.mentions.members.has('309373272594579456') && !client.isStaff(message.member) && message.type != 19){
|
||||
message.reply('Please don\'t tag Daggerwin, read rule 14 in <#468846117405196289>')
|
||||
}
|
||||
if (message.mentions.members.has('215497515934416896') && !client.isStaff(message.member) && message.type != 19){
|
||||
message.reply('Please don\'t tag Monster unless it\'s important!')
|
||||
}
|
||||
if (message.content.toLowerCase().startsWith(`${client.config.prefix}players`) || message.content.toLowerCase().startsWith(`${client.config.prefix}status`)){
|
||||
message.reply('Commands for the MP server have been moved to `*mp players` and `*mp status`.')
|
||||
if (message.content.toLowerCase().startsWith(`*mp players`) || message.content.toLowerCase().startsWith(`*mp status`)){
|
||||
message.reply('Prefix-based MP commands has been moved to `/mp players` and `/mp status`')
|
||||
}
|
||||
if (message.content.toLowerCase().includes('whats the password') || message.content.toLowerCase().includes('what\'s the password') || message.content.toLowerCase().includes('password pls')){
|
||||
message.reply('Password and other details can be found in <#543494084363288637>')
|
||||
|
@ -12,7 +12,7 @@ export default {
|
||||
const msgarr = newMsg.content.toLowerCase().split(' ');
|
||||
if (client.bannedWords._content.some((word:string)=>msgarr.includes(word)) && (!client.isStaff(newMsg.member))) newMsg.delete();
|
||||
if (newMsg.content === oldMsg.content) return;
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.tag} (${oldMsg.author.id})`, iconURL: `${oldMsg.author.displayAvatarURL()}`}).setTitle('Message edited').setDescription(`<@${oldMsg.author.id}>\nOld content:\n\`\`\`\n${oldMsg.content}\n\`\`\`\nNew content:\n\`\`\`\nChannel: <#${oldMsg.channelId}>`);
|
||||
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setAuthor({name: `Author: ${oldMsg.author.tag} (${oldMsg.author.id})`, iconURL: `${oldMsg.author.displayAvatarURL()}`}).setTitle('Message edited').setDescription(`<@${oldMsg.author.id}>\nOld content:\n\`\`\`\n${oldMsg.content}\n\`\`\`\nNew content:\n\`\`\`\n${newMsg.content}\`\`\`\nChannel: <#${oldMsg.channelId}>`);
|
||||
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [embed], components: [new ActionRowBuilder<ButtonBuilder>().addComponents(new ButtonBuilder().setStyle(5).setURL(`${oldMsg.url}`).setLabel('Jump to message'))]});
|
||||
}
|
||||
}
|
24
src/index.ts
24
src/index.ts
@ -1,14 +1,20 @@
|
||||
interface punOpt {
|
||||
time?: string,
|
||||
reason?: string,
|
||||
interaction?: any
|
||||
}
|
||||
import Discord from 'discord.js';
|
||||
import { TClient } from './client';
|
||||
const client = new TClient;
|
||||
client.init();
|
||||
import fs from 'node:fs';
|
||||
import MPDB from './models/MPServer';
|
||||
import { Punishment } from './typings/interfaces';
|
||||
|
||||
client.on('ready', async()=>{
|
||||
client.guilds.cache.forEach(async(e: { members: { fetch: () => any; }; })=>{await e.members.fetch()});
|
||||
setInterval(async()=>{
|
||||
client.user.setPresence({activities: [{ name: 'TypeScript is pog', type: 0 }], status: 'online'});
|
||||
client.user.setPresence({activities: [{ name: 'Slash commands!', type: 0 }], status: 'online'});
|
||||
// Playing: 0, Streaming (Requires YT/Twitch URL to work): 1, Listening to: 2, Watching: 3, Competing in: 5
|
||||
}, 60000);
|
||||
if (client.config.botSwitches.registerCommands) (client.guilds.cache.get(client.config.mainServer.id) as Discord.Guild).commands.set(client.registry).catch((e)=>{console.log(`Couldn't register slash commands: ${e}`)})
|
||||
@ -22,7 +28,7 @@ client.on('ready', async()=>{
|
||||
}, 500000);
|
||||
console.log(`${client.user.tag} has logged into Discord API and now ready for operation`);
|
||||
console.log(client.config.botSwitches);
|
||||
(client.channels.resolve(client.config.mainServer.channels.bot_status) as Discord.TextChannel).send(`${client.user.username} is active\n\`\`\`json\n${Object.entries(client.config.botSwitches).map((hi)=>`${hi[0]}: ${hi[1]}`).join('\n')}\`\`\``);
|
||||
//(client.channels.resolve(client.config.mainServer.channels.bot_status) as Discord.TextChannel).send(`${client.user.username} is active\n\`\`\`json\n${Object.entries(client.config.botSwitches).map((hi)=>`${hi[0]}: ${hi[1]}`).join('\n')}\`\`\``);
|
||||
|
||||
// Event handler
|
||||
const eventFiles = fs.readdirSync('src/events').filter(file=>file.endsWith('.ts'));
|
||||
@ -35,21 +41,21 @@ client.on('ready', async()=>{
|
||||
// Handle errors
|
||||
process.on('unhandledRejection', async(error: Error)=>{
|
||||
console.log(error);
|
||||
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send({embeds: [new client.embed().setColor('#420420').setTitle('Error caught!').setDescription(`**Error:** \`${error.message}\`\n\n**Stack:** \`${`${error.stack}`.slice(0, 2500)}\``)]})
|
||||
//(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send({embeds: [new client.embed().setColor('#420420').setTitle('Error caught!').setDescription(`**Error:** \`${error.message}\`\n\n**Stack:** \`${`${error.stack}`.slice(0, 2500)}\``)]})
|
||||
});
|
||||
process.on('uncaughtException', async(error: Error)=>{
|
||||
console.log(error);
|
||||
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send({embeds: [new client.embed().setColor('#420420').setTitle('Error caught!').setDescription(`**Error:** \`${error.message}\`\n\n**Stack:** \`${`${error.stack}`.slice(0, 2500)}\``)]})
|
||||
//(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send({embeds: [new client.embed().setColor('#420420').setTitle('Error caught!').setDescription(`**Error:** \`${error.message}\`\n\n**Stack:** \`${`${error.stack}`.slice(0, 2500)}\``)]})
|
||||
});
|
||||
process.on('error', async(error: Error)=>{
|
||||
console.log(error);
|
||||
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send({embeds: [new client.embed().setColor('#420420').setTitle('Error caught!').setDescription(`**Error:** \`${error.message}\`\n\n**Stack:** \`${`${error.stack}`.slice(0, 2500)}\``)]})
|
||||
//(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send({embeds: [new client.embed().setColor('#420420').setTitle('Error caught!').setDescription(`**Error:** \`${error.message}\`\n\n**Stack:** \`${`${error.stack}`.slice(0, 2500)}\``)]})
|
||||
});
|
||||
|
||||
// Daggerwin MP loop
|
||||
setInterval(async()=>{
|
||||
if (!client.config.botSwitches.mpstats) return;
|
||||
const msg = await (client.channels.resolve('904192878140608563') as Discord.TextChannel).messages.fetch('1042464209709051974')
|
||||
const msg = await (client.channels.resolve('904192878140608563') as Discord.TextChannel).messages.fetch('1042835699906400346')
|
||||
const embed = new client.embed();
|
||||
let Players = [];
|
||||
let Server: any;
|
||||
@ -115,7 +121,7 @@ setInterval(async()=>{
|
||||
} else {
|
||||
const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Server details').addFields(
|
||||
{name: 'Current Map', value: `${Server.data.server.mapName.length == 0 ? '\u200b' : Server.data.server.mapName}`, inline: true},
|
||||
{name: 'Game Version', value: `${Server.data.server.version.length == 0 ? '\u200b' : Server.data.server.version}`, inline: true},
|
||||
{name: 'Version', value: `${Server.data.server.version.length == 0 ? '\u200b' : Server.data.server.version}`, inline: true},
|
||||
{name: 'In-game Time', value: `${('0' + Math.floor((Server.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((Server.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true},
|
||||
{name: 'Slot Usage', value: `${Number(xmlData?.slotSystem?._attributes?.slotUsage).toLocaleString('en-US')}`, inline: true},
|
||||
{name: 'Timescale', value: `${formatNumber(timeScale, 0, 'x')}`, inline: true}
|
||||
@ -131,7 +137,7 @@ setInterval(async()=>{
|
||||
|
||||
// YouTube Upload notification
|
||||
setInterval(async()=>{
|
||||
client.YTLoop('UCQ8k8yTDLITldfWYKDs3xFg', 'Daggerwin', '528967918772551702'); // 528967918772551702 = #videos-and-streams
|
||||
client.YTLoop('UCQ8k8yTDLITldfWYKDs3xFg', 'Daggerwin', '904192878140608563'); // 528967918772551702 = #videos-and-streams
|
||||
client.YTLoop('UCguI73--UraJpso4NizXNzA', 'Machinery Restorer', '767444045520961567') // 767444045520961567 = #machinery-restorer
|
||||
}, 300000)
|
||||
|
||||
@ -159,7 +165,7 @@ setInterval(async()=>{
|
||||
total = yesterday
|
||||
}
|
||||
dailyMsgs.push([formattedDate, total]);
|
||||
fs.writeFileSync(__dirname + 'dailyMsgs.json', JSON.stringify(dailyMsgs))
|
||||
fs.writeFileSync(__dirname + '/database/dailyMsgs.json', JSON.stringify(dailyMsgs))
|
||||
console.log(`\x1b[36m[${client.moment().format('DD/MM/YY HH:mm:ss')}] \x1b[33m`, `Pushed [${formattedDate}, ${total}] to dailyMsgs`)
|
||||
}
|
||||
}, 5000)
|
||||
|
8
src/typings/interfaces.d.ts
vendored
8
src/typings/interfaces.d.ts
vendored
@ -1,18 +1,18 @@
|
||||
interface formatTimeOpt {
|
||||
export interface formatTimeOpt {
|
||||
longNames: boolean,
|
||||
commas: boolean
|
||||
}
|
||||
interface createTableOpt {
|
||||
export interface createTableOpt {
|
||||
columnAlign: any,
|
||||
columnSeparator: any,
|
||||
columnEmptyChar: any
|
||||
}
|
||||
interface punOpt {
|
||||
export interface punOpt {
|
||||
time?: string,
|
||||
reason?: string,
|
||||
interaction?: any
|
||||
}
|
||||
interface Punishment {
|
||||
export interface Punishment {
|
||||
id: number;
|
||||
type: string;
|
||||
member: string;
|
||||
|
@ -1,5 +1,4 @@
|
||||
{
|
||||
"ts-node": {
|
||||
"transpileOnly": true,
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
@ -12,11 +11,8 @@
|
||||
"rootDir": "src/",
|
||||
"outDir": "dist/",
|
||||
"moduleResolution": "Node",
|
||||
"declarationDir": "src/typings",
|
||||
"typeRoots": [ "node_modules/@types", "src/typings" ],
|
||||
"typeRoots": [ "node_modules/@types", "./src/typings" ],
|
||||
},
|
||||
|
||||
},
|
||||
"include": [ "node_modules/@types", "src/**/*" ],
|
||||
"exclude": [ "dist", "node_modules" ],
|
||||
}
|
Loading…
Reference in New Issue
Block a user