mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-11-17 12:21:00 -05:00
Stupid GitHub formatting...
This commit is contained in:
parent
36c598f1bc
commit
18ee078bd0
@ -1,2 +1,3 @@
|
|||||||
# Daggerbot-TS
|
![https://discord.gg/4SnUAFu](https://cdn.discordapp.com/attachments/1015195575693627442/1081877631068295178/DaggerwinServerBanner2023.gif)
|
||||||
TypeScript-based Daggerbot converted from JavaScript at [SpaceManBuzz/DaggerBot-](https://github.com/SpaceManBuzz/DaggerBot-)
|
# Daggerbot-TS Description
|
||||||
|
This is 1st generation bot that is a TypeScript-based Daggerbot converted from JavaScript at (now archived and privated) ~~[SpaceManBuzz/DaggerBot-](https://github.com/SpaceManBuzz/DaggerBot-)~~
|
329
src/client.ts
329
src/client.ts
@ -16,185 +16,184 @@ import tokens from './tokens.json';
|
|||||||
|
|
||||||
let importconfig:Config
|
let importconfig:Config
|
||||||
try{
|
try{
|
||||||
importconfig = require('./DB-Beta.config.json')
|
importconfig = require('./DB-Beta.config.json')
|
||||||
console.log('Using development config :: Daggerbot Beta')
|
console.log('Using development config :: Daggerbot Beta')
|
||||||
//importconfig = require('./Toast-Testbot.config.json')
|
//importconfig = require('./Toast-Testbot.config.json')
|
||||||
//console.log('Using development config :: Toast-Testbot')
|
//console.log('Using development config :: Toast-Testbot')
|
||||||
} catch(e){
|
} catch(e){
|
||||||
importconfig = require('./config.json')
|
importconfig = require('./config.json')
|
||||||
console.log('Using production config')
|
console.log('Using production config')
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TClient extends Client {
|
export default class TClient extends Client {
|
||||||
invites: Map<any, any>;
|
invites: Map<any, any>;
|
||||||
commands: Discord.Collection<string, any>;
|
commands: Discord.Collection<string, any>;
|
||||||
registry: Array<Discord.ApplicationCommandDataResolvable>;
|
registry: Array<Discord.ApplicationCommandDataResolvable>;
|
||||||
config: Config;
|
config: Config;
|
||||||
tokens: Tokens;
|
tokens: Tokens;
|
||||||
YTCache: any;
|
YTCache: any;
|
||||||
embed: typeof Discord.EmbedBuilder;
|
embed: typeof Discord.EmbedBuilder;
|
||||||
collection: any;
|
collection: any;
|
||||||
messageCollector: any;
|
messageCollector: any;
|
||||||
attachmentBuilder: any;
|
attachmentBuilder: any;
|
||||||
moment: typeof moment;
|
moment: typeof moment;
|
||||||
xjs: any;
|
xjs: any;
|
||||||
axios: typeof axios;
|
axios: typeof axios;
|
||||||
ms: any;
|
ms: any;
|
||||||
userLevels: userLevels;
|
userLevels: userLevels;
|
||||||
punishments: punishments;
|
punishments: punishments;
|
||||||
bonkCount: bonkCount;
|
bonkCount: bonkCount;
|
||||||
bannedWords: bannedWords;
|
bannedWords: bannedWords;
|
||||||
MPServer: MPServer;
|
MPServer: MPServer;
|
||||||
suggestion: suggestion;
|
suggestion: suggestion;
|
||||||
repeatedMessages: repeatedMessages;
|
repeatedMessages: repeatedMessages;
|
||||||
statsGraph: number;
|
statsGraph: number;
|
||||||
|
|
||||||
constructor(){
|
constructor(){
|
||||||
super({
|
super({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers,
|
GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers,
|
||||||
GatewayIntentBits.GuildBans, GatewayIntentBits.GuildInvites,
|
GatewayIntentBits.GuildModeration, GatewayIntentBits.GuildInvites,
|
||||||
GatewayIntentBits.GuildPresences, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages
|
GatewayIntentBits.GuildPresences, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages
|
||||||
],
|
],
|
||||||
partials: [
|
partials: [
|
||||||
Partials.Channel,
|
Partials.Channel,
|
||||||
Partials.Reaction,
|
Partials.Reaction,
|
||||||
Partials.Message
|
Partials.Message
|
||||||
],
|
],
|
||||||
allowedMentions: { users: [], roles: [] }
|
allowedMentions: {users:[],roles:[]}
|
||||||
})
|
})
|
||||||
this.invites = new Map();
|
this.invites = new Map();
|
||||||
this.commands = new Discord.Collection();
|
this.commands = new Discord.Collection();
|
||||||
this.registry = [];
|
this.registry = [];
|
||||||
this.config = importconfig as Config;
|
this.config = importconfig as Config;
|
||||||
this.tokens = tokens as Tokens;
|
this.tokens = tokens as Tokens;
|
||||||
this.YTCache = {
|
this.YTCache = {
|
||||||
'UCQ8k8yTDLITldfWYKDs3xFg': undefined, // Daggerwin
|
'UCQ8k8yTDLITldfWYKDs3xFg': undefined, // Daggerwin
|
||||||
'UCguI73--UraJpso4NizXNzA': undefined // Machinery Restorer
|
'UCguI73--UraJpso4NizXNzA': undefined // Machinery Restorer
|
||||||
}
|
|
||||||
this.embed = Discord.EmbedBuilder;
|
|
||||||
this.collection = Discord.Collection;
|
|
||||||
this.messageCollector = Discord.MessageCollector;
|
|
||||||
this.attachmentBuilder = Discord.AttachmentBuilder;
|
|
||||||
this.moment = moment;
|
|
||||||
this.xjs = require('xml-js');
|
|
||||||
this.axios = axios;
|
|
||||||
this.ms = require('ms');
|
|
||||||
this.userLevels = new userLevels(this);
|
|
||||||
this.bonkCount = new bonkCount(this);
|
|
||||||
this.punishments = new punishments(this);
|
|
||||||
this.bannedWords = new bannedWords(this);
|
|
||||||
this.MPServer = new MPServer(this);
|
|
||||||
this.suggestion = new suggestion(this);
|
|
||||||
this.repeatedMessages = {};
|
|
||||||
this.setMaxListeners(80);
|
|
||||||
this.statsGraph = -60;
|
|
||||||
}
|
}
|
||||||
async init(){
|
this.embed = Discord.EmbedBuilder;
|
||||||
mongoose.set('strictQuery', true);
|
this.collection = Discord.Collection;
|
||||||
await mongoose.connect(this.tokens.mongodb_uri, {
|
this.messageCollector = Discord.MessageCollector;
|
||||||
replicaSet: 'toastyy',
|
this.attachmentBuilder = Discord.AttachmentBuilder;
|
||||||
autoIndex: true,
|
this.moment = moment;
|
||||||
keepAlive: true,
|
this.xjs = require('xml-js');
|
||||||
serverSelectionTimeoutMS: 15000,
|
this.axios = axios;
|
||||||
waitQueueTimeoutMS: 50000,
|
this.ms = require('ms');
|
||||||
socketTimeoutMS: 30000,
|
this.userLevels = new userLevels(this);
|
||||||
family: 4
|
this.bonkCount = new bonkCount(this);
|
||||||
}).then(()=>console.log(this.logTime(), 'Successfully connected to MongoDB')).catch((err)=>{console.error(this.logTime(), `Failed to connect to MongoDB\n${err.reason}`); exec('pm2 stop Daggerbot')})
|
this.punishments = new punishments(this);
|
||||||
await this.login(this.tokens.main);
|
this.bannedWords = new bannedWords(this);
|
||||||
const commandFiles = fs.readdirSync('src/commands').filter(file=>file.endsWith('.ts'));
|
this.MPServer = new MPServer(this);
|
||||||
for (const file of commandFiles){
|
this.suggestion = new suggestion(this);
|
||||||
const command = require(`./commands/${file}`);
|
this.repeatedMessages = {};
|
||||||
this.commands.set(command.default.data.name, command)
|
this.setMaxListeners(80);
|
||||||
this.registry.push(command.default.data.toJSON())
|
this.statsGraph = -60;
|
||||||
}
|
}
|
||||||
fs.readdirSync('src/events').forEach((file)=>{
|
async init(){
|
||||||
const eventFile = require(`./events/${file}`);
|
console.time('Startup');
|
||||||
this.on(file.replace('.ts', ''), async(...args)=>eventFile.default.run(this,...args));
|
mongoose.set('strictQuery', true);
|
||||||
});
|
await mongoose.connect(this.tokens.mongodb_uri, {
|
||||||
|
replicaSet: 'toastyy',
|
||||||
|
autoIndex: true,
|
||||||
|
keepAlive: true,
|
||||||
|
serverSelectionTimeoutMS: 15000,
|
||||||
|
waitQueueTimeoutMS: 50000,
|
||||||
|
socketTimeoutMS: 30000,
|
||||||
|
family: 4
|
||||||
|
}).then(()=>console.log(this.logTime(), 'Successfully connected to MongoDB')).catch((err)=>{console.error(this.logTime(), `Failed to connect to MongoDB\n${err.reason}`); exec('pm2 stop Daggerbot')})
|
||||||
|
await this.login(this.tokens.main);
|
||||||
|
const commandFiles = fs.readdirSync('src/commands').filter(file=>file.endsWith('.ts'));
|
||||||
|
for (const file of commandFiles){
|
||||||
|
const command = require(`./commands/${file}`);
|
||||||
|
this.commands.set(command.default.data.name, command)
|
||||||
|
this.registry.push(command.default.data.toJSON())
|
||||||
}
|
}
|
||||||
formatTime(integer: number, accuracy = 1, options?: formatTimeOpt){
|
fs.readdirSync('src/events').forEach((file)=>{
|
||||||
let achievedAccuracy = 0;
|
const eventFile = require(`./events/${file}`);
|
||||||
let text:any = '';
|
this.on(file.replace('.ts', ''), async(...args)=>eventFile.default.run(this,...args));
|
||||||
for (const timeName of timeNames){
|
});
|
||||||
if (achievedAccuracy < accuracy){
|
}
|
||||||
const fullTimelengths = Math.floor(integer/timeName.length);
|
formatTime(integer: number, accuracy = 1, options?: formatTimeOpt){
|
||||||
if (fullTimelengths == 0) continue;
|
let achievedAccuracy = 0;
|
||||||
achievedAccuracy++;
|
let text:any = '';
|
||||||
text += fullTimelengths + (options?.longNames ? (' '+timeName.name+(fullTimelengths === 1 ? '' : 's')) : timeName.name.slice(0, timeName.name === 'month' ? 2 : 1)) + (options?.commas ? ', ' : ' ');
|
for (const timeName of timeNames){
|
||||||
integer -= fullTimelengths*timeName.length;
|
if (achievedAccuracy < accuracy){
|
||||||
} else {
|
const fullTimelengths = Math.floor(integer/timeName.length);
|
||||||
break;
|
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 ? ', ' : ' ');
|
||||||
if (text.length == 0) text = integer + (options?.longNames ? ' milliseconds' : 'ms') + (options?.commas ? ', ' : '');
|
integer -= fullTimelengths*timeName.length;
|
||||||
if (options?.commas){
|
} else break;
|
||||||
text = text.slice(0, -2);
|
|
||||||
if (options?.longNames){
|
|
||||||
text = text.split('');
|
|
||||||
text[text.lastIndexOf(',')] = ' and';
|
|
||||||
text = text.join('');
|
|
||||||
}
|
|
||||||
} return text.trim();
|
|
||||||
}
|
}
|
||||||
isStaff(guildMember: Discord.GuildMember){
|
if (text.length == 0) text = integer + (options?.longNames ? ' milliseconds' : 'ms') + (options?.commas ? ', ' : '');
|
||||||
return this.config.mainServer.staffRoles.map((x: string)=>this.config.mainServer.roles[x]).some((x: string)=>guildMember.roles.cache.has(x))
|
if (options?.commas){
|
||||||
}
|
text = text.slice(0, -2);
|
||||||
youNeedRole(interaction: Discord.CommandInteraction, role:string){
|
if (options?.longNames){
|
||||||
return interaction.reply(`This command is restricted to <@&${this.config.mainServer.roles[role]}>`)
|
text = text.split('');
|
||||||
}
|
text[text.lastIndexOf(',')] = ' and';
|
||||||
logTime(){
|
text = text.join('');
|
||||||
return `[${this.moment().format('DD/MM/YY HH:mm:ss')}]`
|
}
|
||||||
}
|
} return text.trim();
|
||||||
alignText(text: string, length: number, alignment: string, emptyChar = ' '){
|
}
|
||||||
if (alignment == 'right'){
|
isStaff = (guildMember:Discord.GuildMember)=>this.config.mainServer.staffRoles.map((x: string)=>this.config.mainServer.roles[x]).some((x: string)=>guildMember.roles.cache.has(x));
|
||||||
text = emptyChar.repeat(length - text.length)+text;
|
|
||||||
} else if (alignment == 'middle'){
|
|
||||||
const emptyCharsPerSide = (length - text.length)/2;
|
|
||||||
text = emptyChar.repeat(Math.floor(emptyCharsPerSide))+text+emptyChar.repeat(Math.floor(emptyCharsPerSide));
|
|
||||||
} else {
|
|
||||||
text = text + emptyChar.repeat(length - text.length);
|
|
||||||
} return text;
|
|
||||||
}
|
|
||||||
async punish(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;
|
youNeedRole = (interaction:Discord.CommandInteraction, role:string)=>interaction.reply(`This command is restricted to <@&${this.config.mainServer.roles[role]}>`);
|
||||||
const reason = interaction.options.getString('reason') ?? 'Reason unspecified';
|
|
||||||
const GuildMember = interaction.options.getMember('member') ?? undefined;
|
|
||||||
const User = interaction.options.getUser('member', true);
|
|
||||||
|
|
||||||
if (interaction.user.id == User.id) return interaction.reply(`You cannot ${type} yourself.`);
|
logTime = ()=>`[${this.moment().format('DD/MM/YY HH:mm:ss')}]`;
|
||||||
if (!GuildMember && type != 'ban') 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();
|
alignText(text: string, length: number, alignment: string, emptyChar = ' '){
|
||||||
await client.punishments.addPunishment(type, { time, interaction }, interaction.user.id, reason, User, GuildMember);
|
if (alignment == 'right') text = emptyChar.repeat(length - text.length)+text;
|
||||||
|
else if (alignment == 'middle'){
|
||||||
|
const emptyCharsPerSide = (length - text.length)/2;
|
||||||
|
text = emptyChar.repeat(Math.floor(emptyCharsPerSide))+text+emptyChar.repeat(Math.floor(emptyCharsPerSide));
|
||||||
|
} else text = text + emptyChar.repeat(length - text.length);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
async punish(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);
|
||||||
|
|
||||||
|
if (interaction.user.id == User.id) return interaction.reply(`You cannot ${type} yourself.`);
|
||||||
|
if (!GuildMember && type != 'ban') 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);
|
||||||
|
}
|
||||||
|
async YTLoop(YTChannelID: string, YTChannelName: string, DCChannelID: string){
|
||||||
|
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(this.logTime(), `${YTChannelName} YT fail`)
|
||||||
}
|
}
|
||||||
async YTLoop(YTChannelID: string, YTChannelName: string, DCChannelID: string){
|
|
||||||
let Data:any;
|
|
||||||
let error;
|
|
||||||
|
|
||||||
try {
|
if (!Data) return;
|
||||||
await this.axios.get(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelID}`, {timeout: 5000}).then((xml:any)=>{
|
if (this.YTCache[YTChannelID] == undefined){
|
||||||
Data = this.xjs.xml2js(xml.data, {compact: true, spaces: 2});
|
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
|
||||||
})
|
return;
|
||||||
} catch(err){
|
|
||||||
error = true;
|
|
||||||
console.log(this.logTime(), `${YTChannelName} YT fail`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Data) return;
|
|
||||||
if (this.YTCache[YTChannelID] == undefined){
|
|
||||||
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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}`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WClient extends WebhookClient {tokens: Tokens; constructor(){super({url: tokens.webhook_url})}}
|
export class WClient extends WebhookClient {
|
||||||
|
tokens: Tokens;
|
||||||
|
constructor(){
|
||||||
|
super({
|
||||||
|
url: tokens.webhook_url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
// hi tae, ik you went to look for secret hello msgs in here too.
|
// hi tae, ik you went to look for secret hello msgs in here too.
|
@ -1,20 +1,20 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'ban');
|
client.punish(client, interaction, 'ban');
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('ban')
|
.setName('ban')
|
||||||
.setDescription('Ban a member from the server')
|
.setDescription('Ban a member from the server')
|
||||||
.addUserOption((opt)=>opt
|
.addUserOption((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('Which member to ban?')
|
.setDescription('Which member to ban?')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('time')
|
.setName('time')
|
||||||
.setDescription('How long the ban will be?'))
|
.setDescription('How long the ban will be?'))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('reason')
|
.setName('reason')
|
||||||
.setDescription('Reason for the ban'))
|
.setDescription('Reason for the ban'))
|
||||||
}
|
}
|
@ -1,42 +1,42 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (!client.isStaff(interaction.member) && !client.config.eval.whitelist.includes(interaction.member.id)) return client.youNeedRole(interaction, 'admin')
|
if (!client.isStaff(interaction.member) && !client.config.eval.whitelist.includes(interaction.member.id)) return client.youNeedRole(interaction, 'admin')
|
||||||
const word = interaction.options.getString('word', true);
|
const word = interaction.options.getString('word', true);
|
||||||
const wordExists = await client.bannedWords._content.findById(word);
|
const wordExists = await client.bannedWords._content.findById(word);
|
||||||
({
|
({
|
||||||
add: async()=>{
|
add: async()=>{
|
||||||
if (wordExists) return interaction.reply({content: `\`${word}\` is already added.`, ephemeral: true});
|
if (wordExists) return interaction.reply({content: `\`${word}\` is already added.`, ephemeral: true});
|
||||||
await client.bannedWords._content.create({_id:word}).then(a=>a.save());
|
await client.bannedWords._content.create({_id:word}).then(a=>a.save());
|
||||||
interaction.reply(`Successfully added \`${word}\` to the database.`)
|
interaction.reply(`Successfully added \`${word}\` to the database.`)
|
||||||
},
|
},
|
||||||
remove: async()=>{
|
remove: async()=>{
|
||||||
if (!wordExists) return interaction.reply({content: `\`${word}\` doesn't exist on the list.`, ephemeral: true});
|
if (!wordExists) return interaction.reply({content: `\`${word}\` doesn't exist on the list.`, ephemeral: true});
|
||||||
await client.bannedWords._content.findOneAndDelete({_id:word});
|
await client.bannedWords._content.findOneAndDelete({_id:word});
|
||||||
interaction.reply(`Successfully removed \`${word}\` from the database.`)
|
interaction.reply(`Successfully removed \`${word}\` from the database.`)
|
||||||
},
|
},
|
||||||
//view: ()=>interaction.reply({content: 'Here is a complete list of banned words!\n*You can open it with a web browser, e.g Chrome/Firefox/Safari, or you can use Visual Studio Code/Notepad++*', files: ['src/database/bannedWords.json'], ephemeral: true})
|
//view: ()=>interaction.reply({content: 'Here is a complete list of banned words!\n*You can open it with a web browser, e.g Chrome/Firefox/Safari, or you can use Visual Studio Code/Notepad++*', files: ['src/database/bannedWords.json'], ephemeral: true})
|
||||||
} as any)[interaction.options.getSubcommand()]();
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('bannedwords')
|
.setName('bannedwords')
|
||||||
.setDescription('description placeholder')
|
.setDescription('description placeholder')/*
|
||||||
/*.addSubcommand((opt)=>opt
|
.addSubcommand((opt)=>opt
|
||||||
.setName('view')
|
.setName('view')
|
||||||
.setDescription('View the list of currently banned words.'))
|
.setDescription('View the list of currently banned words.'))*/
|
||||||
*/.addSubcommand((opt)=>opt
|
.addSubcommand((opt)=>opt
|
||||||
.setName('add')
|
.setName('add')
|
||||||
.setDescription('What word do you want to add?')
|
.setDescription('What word do you want to add?')
|
||||||
.addStringOption((optt)=>optt
|
.addStringOption((optt)=>optt
|
||||||
.setName('word')
|
.setName('word')
|
||||||
.setDescription('Add the specific word to automod\'s bannedWords database.')
|
.setDescription('Add the specific word to automod\'s bannedWords database.')
|
||||||
.setRequired(true)))
|
.setRequired(true)))
|
||||||
.addSubcommand((opt)=>opt
|
.addSubcommand((opt)=>opt
|
||||||
.setName('remove')
|
.setName('remove')
|
||||||
.setDescription('What word do you want to remove?')
|
.setDescription('What word do you want to remove?')
|
||||||
.addStringOption((optt)=>optt
|
.addStringOption((optt)=>optt
|
||||||
.setName('word')
|
.setName('word')
|
||||||
.setDescription('Remove the specific word from automod\'s bannedWords list.')
|
.setDescription('Remove the specific word from automod\'s bannedWords list.')
|
||||||
.setRequired(true)))
|
.setRequired(true)))
|
||||||
}
|
}
|
||||||
|
@ -1,79 +1,79 @@
|
|||||||
import Discord,{SlashCommandBuilder} from "discord.js";
|
import Discord,{SlashCommandBuilder} from "discord.js";
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
||||||
const caseId = interaction.options.getInteger('id');
|
const caseId = interaction.options.getInteger('id');
|
||||||
({
|
({
|
||||||
update: async()=>{
|
update: async()=>{
|
||||||
const reason = interaction.options.getString('reason');
|
const reason = interaction.options.getString('reason');
|
||||||
await client.punishments._content.findByIdAndUpdate(caseId, {reason});
|
await client.punishments._content.findByIdAndUpdate(caseId, {reason});
|
||||||
await interaction.reply({embeds: [new client.embed().setColor(client.config.embedColorGreen).setTitle('Case updated').setDescription(`Case #${caseId} has been successfully updated with new reason:\n\`${reason}\``)]})
|
await interaction.reply({embeds: [new client.embed().setColor(client.config.embedColorGreen).setTitle('Case updated').setDescription(`Case #${caseId} has been successfully updated with new reason:\n\`${reason}\``)]})
|
||||||
},
|
},
|
||||||
view: async()=>{
|
view: async()=>{
|
||||||
const punishment = await client.punishments._content.findById(caseId);
|
const punishment = await client.punishments._content.findById(caseId);
|
||||||
if (!punishment) return interaction.reply('Invalid Case #');
|
if (!punishment) return interaction.reply('Invalid Case #');
|
||||||
const cancelledBy = punishment.expired ? await client.punishments._content.findOne({cancels:punishment.id}) : null;
|
const cancelledBy = punishment.expired ? await client.punishments._content.findOne({cancels:punishment.id}) : null;
|
||||||
const cancels = punishment.cancels ? await client.punishments._content.findOne({_id:punishment.cancels}) : null;
|
const cancels = punishment.cancels ? await client.punishments._content.findOne({_id:punishment.cancels}) : null;
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(punishment.time).setTitle(`${punishment.type[0].toUpperCase()+punishment.type.slice(1)} | Case #${punishment.id}`).addFields(
|
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(punishment.time).setTitle(`${punishment.type[0].toUpperCase()+punishment.type.slice(1)} | Case #${punishment.id}`).addFields(
|
||||||
{name: '🔹 User', value: `<@${punishment.member}> \`${punishment.member}\``, inline: true},
|
{name: '🔹 User', value: `<@${punishment.member}> \`${punishment.member}\``, inline: true},
|
||||||
{name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true},
|
{name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true},
|
||||||
{name: '\u200b', value: '\u200b', inline: true},
|
{name: '\u200b', value: '\u200b', inline: true},
|
||||||
{name: '🔹 Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, 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: client.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.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}\``})
|
if (punishment.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites case #${cancels.id} with reason \`${cancels.reason}\``})
|
||||||
interaction.reply({embeds: [embed]});
|
interaction.reply({embeds: [embed]});
|
||||||
},
|
},
|
||||||
member: async()=>{
|
member: async()=>{
|
||||||
// if caseid is user id, show their punishment history sorted by most recent.
|
// if caseid is user id, show their punishment history sorted by most recent.
|
||||||
const user = (interaction.options.getUser('user') as Discord.User);
|
const user = (interaction.options.getUser('user') as Discord.User);
|
||||||
if (user.bot) return interaction.reply(`<@${user.id}>'s punishment history cannot be viewed.`)
|
if (user.bot) return interaction.reply(`<@${user.id}>'s punishment history cannot be viewed.`)
|
||||||
const punishments = await client.punishments._content.find({});
|
const punishments = await client.punishments._content.find({});
|
||||||
if (!punishments) return interaction.reply(`<@${user.id}> has a clean record.`)
|
if (!punishments) return interaction.reply(`<@${user.id}> has a clean record.`)
|
||||||
const userPunishmentData = await client.punishments._content.find({'member':user.id});
|
const userPunishmentData = await client.punishments._content.find({'member':user.id});
|
||||||
const userPunishment = userPunishmentData.sort((a,b)=>a.time-b.time).map((punishment)=>{
|
const userPunishment = userPunishmentData.sort((a,b)=>a.time-b.time).map((punishment)=>{
|
||||||
return {
|
return {
|
||||||
name: `${punishment.type[0].toUpperCase()+punishment.type.slice(1)} | Case #${punishment.id}`,
|
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: ${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}` : ''}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// if caseid is not a punishment nor a user, failed
|
// if caseid is not a punishment nor a user, failed
|
||||||
if (!userPunishment || userPunishment.length == 0) return interaction.reply('No punishments found for that case # or User ID');
|
if (!userPunishment || userPunishment.length == 0) return interaction.reply('No punishments found for that case # or User ID');
|
||||||
const pageNum = interaction.options.getInteger('page') ?? 1;
|
const pageNum = interaction.options.getInteger('page') ?? 1;
|
||||||
return interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle(`${user.username}'s punishment history`).setDescription(`**ID:** \`${user.id}\``).setFooter({text: `${userPunishment.length} total punishments. Viewing page ${pageNum} out of ${Math.ceil(userPunishment.length/6)}.`}).addFields(userPunishment.slice((pageNum - 1) * 6, pageNum * 6))]});
|
return interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle(`${user.username}'s punishment history`).setDescription(`**ID:** \`${user.id}\``).setFooter({text: `${userPunishment.length} total punishments. Viewing page ${pageNum} out of ${Math.ceil(userPunishment.length/6)}.`}).addFields(userPunishment.slice((pageNum - 1) * 6, pageNum * 6))]});
|
||||||
}
|
}
|
||||||
} as any)[interaction.options.getSubcommand()]();
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('case')
|
.setName('case')
|
||||||
.setDescription('Retrieve case information or user\'s punishment history')
|
.setDescription('Retrieve case information or user\'s punishment history')
|
||||||
.addSubcommand((opt)=>opt
|
.addSubcommand((opt)=>opt
|
||||||
.setName('view')
|
.setName('view')
|
||||||
.setDescription('View a single case.')
|
.setDescription('View a single case.')
|
||||||
.addIntegerOption((optt)=>optt
|
.addIntegerOption((optt)=>optt
|
||||||
.setName('id')
|
.setName('id')
|
||||||
.setDescription('Case #')
|
.setDescription('Case #')
|
||||||
.setRequired(true)))
|
.setRequired(true)))
|
||||||
.addSubcommand((opt)=>opt
|
.addSubcommand((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('View member\'s punishment history')
|
.setDescription('View member\'s punishment history')
|
||||||
.addUserOption((optt)=>optt
|
.addUserOption((optt)=>optt
|
||||||
.setName('user')
|
.setName('user')
|
||||||
.setDescription('Which user do you want to view their punishment history?')
|
.setDescription('Which user do you want to view their punishment history?')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addIntegerOption((optt)=>optt
|
.addIntegerOption((optt)=>optt
|
||||||
.setName('page')
|
.setName('page')
|
||||||
.setDescription('Select the page number')))
|
.setDescription('Select the page number')))
|
||||||
.addSubcommand((opt)=>opt
|
.addSubcommand((opt)=>opt
|
||||||
.setName('update')
|
.setName('update')
|
||||||
.setDescription('Update the case with new reason')
|
.setDescription('Update the case with new reason')
|
||||||
.addIntegerOption((optt)=>optt
|
.addIntegerOption((optt)=>optt
|
||||||
.setName('id')
|
.setName('id')
|
||||||
.setDescription('Case # to be updated')
|
.setDescription('Case # to be updated')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addStringOption((optt)=>optt
|
.addStringOption((optt)=>optt
|
||||||
.setName('reason')
|
.setName('reason')
|
||||||
.setDescription('New reason for the case')
|
.setDescription('New reason for the case')
|
||||||
.setRequired(true)))
|
.setRequired(true)))
|
||||||
};
|
};
|
@ -1,20 +1,20 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
|
interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([
|
||||||
'**Thanks to those below that contributed to the bot!**',
|
'**Thanks to those below that contributed to the bot!**',
|
||||||
'Toast <@190407856527376384>',
|
'Toast <@190407856527376384>',
|
||||||
'TÆMBØ <@615761944154210305>',
|
'TÆMBØ <@615761944154210305>',
|
||||||
'Buzz <@593696856165449749>',
|
'Buzz <@593696856165449749>',
|
||||||
'Monster <@215497515934416896>',
|
'Monster <@215497515934416896>',
|
||||||
'RainbowDave <@141304507249197057>',
|
'RainbowDave <@141304507249197057>',
|
||||||
'Hitchhiker <@506022868157595648>',
|
'Hitchhiker <@506022868157595648>',
|
||||||
'RedRover92 <@633345781780185099>',
|
'RedRover92 <@633345781780185099>',
|
||||||
'Nawdic <@178941218510602240>'
|
'Nawdic <@178941218510602240>'
|
||||||
].join('\n'))]})
|
].join('\n'))]})
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('contributors')
|
.setName('contributors')
|
||||||
.setDescription('List of people who contributed to the bot.')
|
.setDescription('List of people who contributed to the bot.')
|
||||||
}
|
}
|
@ -20,155 +20,147 @@ const removeUsername = (text: string)=>{
|
|||||||
} return array.join('\\');
|
} return array.join('\\');
|
||||||
};
|
};
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>) {
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>) {
|
||||||
if (!client.config.eval.whitelist.includes(interaction.user.id)) return client.youNeedRole(interaction, 'bottech');
|
if (!client.config.eval.whitelist.includes(interaction.user.id)) return client.youNeedRole(interaction, 'bottech');
|
||||||
({
|
({
|
||||||
eval: async()=>{
|
eval: async()=>{
|
||||||
if (!client.config.eval.allowed) return interaction.reply({content: 'Eval is disabled.', ephemeral: true});
|
if (!client.config.eval.allowed) return interaction.reply({content: 'Eval is disabled.', ephemeral: true});
|
||||||
const code = interaction.options.getString('code') as string;
|
const code = interaction.options.getString('code') as string;
|
||||||
let output = 'error';
|
let output = 'error';
|
||||||
let error = false;
|
let error = false;
|
||||||
try {
|
try {
|
||||||
output = await eval(code);
|
output = await eval(code);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
error = true
|
error = true
|
||||||
const embed = new client.embed().setColor('#ff0000').setTitle('__Eval__').addFields(
|
const embed = new client.embed().setColor('#ff0000').setTitle('__Eval__').addFields(
|
||||||
{name: 'Input', value: `\`\`\`js\n${code.slice(0, 1010)}\n\`\`\``},
|
{name: 'Input', value: `\`\`\`js\n${code.slice(0, 1010)}\n\`\`\``},
|
||||||
{name: 'Output', value: `\`\`\`\n${err}\`\`\``}
|
{name: 'Output', value: `\`\`\`\n${err}\`\`\``}
|
||||||
)
|
)
|
||||||
interaction.reply({embeds: [embed]}).catch(()=>(interaction.channel as Discord.TextChannel).send({embeds: [embed]})).then(errorEmbedMessage=>{
|
interaction.reply({embeds: [embed]}).catch(()=>(interaction.channel as Discord.TextChannel).send({embeds: [embed]})).then(errorEmbedMessage=>{
|
||||||
const filter = (x:any)=>x.content === 'stack' && x.author.id === interaction.user.id
|
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});
|
const messagecollector = (interaction.channel as Discord.TextChannel).createMessageCollector({filter, max: 1, time: 60000});
|
||||||
messagecollector.on('collect', collected=>{
|
messagecollector.on('collect', collected=>{
|
||||||
collected.reply({content: `\`\`\`\n${removeUsername(err.stack)}\n\`\`\``, allowedMentions: {repliedUser: false}});
|
collected.reply({content: `\`\`\`\n${removeUsername(err.stack)}\n\`\`\``, allowedMentions: {repliedUser: false}});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error) return;
|
if (error) return;
|
||||||
if (typeof output == 'object') {
|
if (typeof output == 'object') output = 'js\n'+util.formatWithOptions({depth: 1}, '%O', output)
|
||||||
output = 'js\n'+util.formatWithOptions({depth: 1}, '%O', output)
|
else output = '\n' + String(output);
|
||||||
} else {
|
|
||||||
output = '\n' + String(output);
|
[client.tokens.main,client.tokens.beta,client.tokens.toast,client.tokens.tae,client.tokens.webhook_url,client.tokens.webhook_url_test,client.tokens.mongodb_uri,client.tokens.mongodb_uri_dev].forEach((x)=>{
|
||||||
}
|
const regexp = new RegExp(x as string,'g');
|
||||||
[client.tokens.main,client.tokens.beta,client.tokens.toast,client.tokens.tae,client.tokens.webhook_url,client.tokens.webhook_url_test,client.tokens.mongodb_uri,client.tokens.mongodb_uri_dev].forEach((x)=>{
|
output = output.replace(regexp, ':noblank: No token?');
|
||||||
const regexp = new RegExp(x as string,'g');
|
})
|
||||||
output = output.replace(regexp, ':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\`\`\``},
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('__Eval__').addFields(
|
{name: 'Output', value: `\`\`\`${removeUsername(output).slice(0,1016)}\n\`\`\``}
|
||||||
{name: 'Input', value: `\`\`\`js\n${code.slice(0,1010)}\n\`\`\``},
|
);
|
||||||
{name: 'Output', value: `\`\`\`${removeUsername(output).slice(0,1016)}\n\`\`\``}
|
interaction.reply({embeds: [embed]}).catch(()=>(interaction.channel as Discord.TextChannel).send({embeds: [embed]}));
|
||||||
);
|
},
|
||||||
interaction.reply({embeds: [embed]}).catch(()=>(interaction.channel as Discord.TextChannel).send({embeds: [embed]}));
|
update: async()=>{
|
||||||
},
|
var githubRepo = {owner: 'AnxietyisReal', repo: 'Daggerbot-TS', ref: 'HEAD'}
|
||||||
update: async()=>{
|
const octokit = new Octokit({timeZone: 'Australia/NSW', userAgent: 'Daggerbot'})
|
||||||
var githubRepo = {owner: 'AnxietyisReal', repo: 'Daggerbot-TS', ref: 'HEAD'}
|
const fetchCommitMsg = await octokit.repos.getCommit(githubRepo).then(x=>x.data.commit.message).catch(err=>{console.log(err); interaction.reply({content: 'Placeholder error for `fetchCommitMsg`', ephemeral: true})});
|
||||||
const octokit = new Octokit({timeZone: 'Australia/NSW', userAgent: 'Daggerbot'})
|
const fetchCommitAuthor = await octokit.repos.getCommit(githubRepo).then(x=>x.data.commit.author.name).catch(err=>{console.log(err); interaction.reply({content: 'Placeholder error for `fetchCommitAuthor`', ephemeral: true})});
|
||||||
const fetchCommitMsg = await octokit.repos.getCommit(githubRepo).then(x=>x.data.commit.message).catch(err=>{console.log(err); interaction.reply({content: 'Placeholder error for `fetchCommitMsg`', ephemeral: true})});
|
const clarkson = await interaction.reply({content: 'Pulling from repository...', fetchReply: true});
|
||||||
const fetchCommitAuthor = await octokit.repos.getCommit(githubRepo).then(x=>x.data.commit.author.name).catch(err=>{console.log(err); interaction.reply({content: 'Placeholder error for `fetchCommitAuthor`', ephemeral: true})});
|
exec('git pull',(err:Error,stdout)=>{
|
||||||
const clarkson = await interaction.reply({content: 'Pulling from repository...', fetchReply: true});
|
if (err) clarkson.edit(`\`\`\`${removeUsername(err.message)}\`\`\``)
|
||||||
exec('git pull',(err:Error,stdout)=>{
|
else if (stdout.includes('Already up to date')) clarkson.edit('Bot is already up to date with the repository, did you forgor to push the changes? :skull:')
|
||||||
if (err){
|
else setTimeout(()=>clarkson.edit(`Commit: **${fetchCommitMsg}**\nCommit author: **${fetchCommitAuthor}**\n\nUptime before restarting: **${client.formatTime(client.uptime as number, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot')),650)
|
||||||
clarkson.edit(`\`\`\`${removeUsername(err.message)}\`\`\``)
|
});
|
||||||
} else if (stdout.includes('Already up to date')){
|
},
|
||||||
clarkson.edit('Bot is already up to date with the repository, did you forgor to push the changes? :skull:')
|
presence: ()=>{
|
||||||
} else {
|
function convertType(Type?: number){
|
||||||
setTimeout(()=>{clarkson.edit(`Commit: **${fetchCommitMsg}**\nCommit author: **${fetchCommitAuthor}**\n\nUptime before restarting: **${client.formatTime(client.uptime as number, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot'))},650)
|
switch (Type) {
|
||||||
}
|
case 0: return 'Playing';
|
||||||
});
|
case 1: return 'Streaming';
|
||||||
},
|
case 2: return 'Listening to';
|
||||||
presence: ()=>{
|
case 3: return 'Watching';
|
||||||
function convertType(Type?: number){
|
case 5: return 'Competing in';
|
||||||
switch (Type) {
|
|
||||||
case 0: return 'Playing';
|
|
||||||
case 1: return 'Streaming';
|
|
||||||
case 2: return 'Listening to';
|
|
||||||
case 3: return 'Watching';
|
|
||||||
case 5: return 'Competing in';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const status = interaction.options.getString('status') as Discord.PresenceStatusData | null;
|
|
||||||
const type = interaction.options.getInteger('type');
|
|
||||||
const name = interaction.options.getString('name');
|
|
||||||
const url = interaction.options.getString('url');
|
|
||||||
const currentActivities = client.config.botPresence.activities as Discord.ActivitiesOptions[];
|
|
||||||
if (status) client.config.botPresence.status = status;
|
|
||||||
if (type) currentActivities[0].type = type;
|
|
||||||
if (name) currentActivities[0].name = name;
|
|
||||||
if (url) currentActivities[0].url = url;
|
|
||||||
client.user.setPresence(client.config.botPresence);
|
|
||||||
interaction.reply([
|
|
||||||
'Presence updated:',
|
|
||||||
`Status: **${client.config.botPresence.status}**`,
|
|
||||||
`Type: **${convertType(currentActivities[0].type)}**`,
|
|
||||||
`Name: **${currentActivities[0].name}**`,
|
|
||||||
`URL: \`${currentActivities[0].url}\``
|
|
||||||
].join('\n'))
|
|
||||||
},
|
|
||||||
statsgraph: ()=>{
|
|
||||||
client.statsGraph = -(interaction.options.getInteger('number', true));
|
|
||||||
interaction.reply(`Successfully set to \`${client.statsGraph}\`\n*Total data points: **${JSON.parse(readFileSync(path.join(__dirname, '../database/MPPlayerData.json'), {encoding: 'utf8'})).length.toLocaleString()}***`)
|
|
||||||
},
|
|
||||||
logs: ()=>{
|
|
||||||
interaction.deferReply();
|
|
||||||
(client.channels.resolve(client.config.mainServer.channels.console) as Discord.TextChannel).send({content: `Uploaded the current console dump as of <t:${Math.round(Date.now()/1000)}:R>`, files: [`${process.env.pm2_home}/logs/Daggerbot-out-0.log`, `${process.env.pm2_home}/logs/Daggerbot-error-0.log`]}).then(()=>interaction.editReply('It has been uploaded to dev server.')).catch((e:Error)=>interaction.editReply(`\`${e.message}\``))
|
|
||||||
},
|
|
||||||
restart: ()=>{
|
|
||||||
interaction.reply(`Uptime before restarting: **${client.formatTime(client.uptime as number, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot'))
|
|
||||||
}
|
}
|
||||||
} as any)[interaction.options.getSubcommand()]();
|
};
|
||||||
|
const status = interaction.options.getString('status') as Discord.PresenceStatusData | null;
|
||||||
|
const type = interaction.options.getInteger('type');
|
||||||
|
const name = interaction.options.getString('name');
|
||||||
|
const url = interaction.options.getString('url');
|
||||||
|
const currentActivities = client.config.botPresence.activities as Discord.ActivitiesOptions[];
|
||||||
|
if (status) client.config.botPresence.status = status;
|
||||||
|
if (type) currentActivities[0].type = type;
|
||||||
|
if (name) currentActivities[0].name = name;
|
||||||
|
if (url) currentActivities[0].url = url;
|
||||||
|
client.user.setPresence(client.config.botPresence);
|
||||||
|
interaction.reply([
|
||||||
|
'Presence updated:',
|
||||||
|
`Status: **${client.config.botPresence.status}**`,
|
||||||
|
`Type: **${convertType(currentActivities[0].type)}**`,
|
||||||
|
`Name: **${currentActivities[0].name}**`,
|
||||||
|
`URL: \`${currentActivities[0].url}\``
|
||||||
|
].join('\n'))
|
||||||
|
},
|
||||||
|
statsgraph: ()=>{
|
||||||
|
client.statsGraph = -(interaction.options.getInteger('number', true));
|
||||||
|
interaction.reply(`Successfully set to \`${client.statsGraph}\`\n*Total data points: **${JSON.parse(readFileSync(path.join(__dirname, '../database/MPPlayerData.json'), {encoding: 'utf8'})).length.toLocaleString()}***`)
|
||||||
|
},
|
||||||
|
logs: ()=>{
|
||||||
|
interaction.deferReply();
|
||||||
|
(client.channels.resolve(client.config.mainServer.channels.console) as Discord.TextChannel).send({content: `Uploaded the current console dump as of <t:${Math.round(Date.now()/1000)}:R>`, files: [`${process.env.pm2_home}/logs/Daggerbot-out-0.log`, `${process.env.pm2_home}/logs/Daggerbot-error-0.log`]}).then(()=>interaction.editReply('It has been uploaded to dev server.')).catch((e:Error)=>interaction.editReply(`\`${e.message}\``))
|
||||||
|
},
|
||||||
|
restart: ()=>interaction.reply(`Uptime before restarting: **${client.formatTime(client.uptime as number, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot'))
|
||||||
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('dev')
|
.setName('dev')
|
||||||
.setDescription('Developer commands')
|
.setDescription('Developer commands')
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('eval')
|
.setName('eval')
|
||||||
.setDescription('Execute the code to the bot')
|
.setDescription('Execute the code to the bot')
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('code')
|
.setName('code')
|
||||||
.setDescription('Execute your code')
|
.setDescription('Execute your code')
|
||||||
.setRequired(true)))
|
.setRequired(true)))
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('logs')
|
.setName('logs')
|
||||||
.setDescription('Retrieve the logs from host and sends it to dev server'))
|
.setDescription('Retrieve the logs from host and sends it to dev server'))
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('restart')
|
.setName('restart')
|
||||||
.setDescription('Restart the bot for technical reasons'))
|
.setDescription('Restart the bot for technical reasons'))
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('update')
|
.setName('update')
|
||||||
.setDescription('Pull from repository and restart'))
|
.setDescription('Pull from repository and restart'))
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('statsgraph')
|
.setName('statsgraph')
|
||||||
.setDescription('Edit the number of data points to pull')
|
.setDescription('Edit the number of data points to pull')
|
||||||
.addIntegerOption((hiTae)=>hiTae
|
.addIntegerOption((hiTae)=>hiTae
|
||||||
.setName('number')
|
.setName('number')
|
||||||
.setDescription('Number of data points to pull')
|
.setDescription('Number of data points to pull')
|
||||||
.setRequired(true)))
|
.setRequired(true)))
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('presence')
|
.setName('presence')
|
||||||
.setDescription('Update the bot\'s presence')
|
.setDescription('Update the bot\'s presence')
|
||||||
.addIntegerOption((hiTae)=>hiTae
|
.addIntegerOption((hiTae)=>hiTae
|
||||||
.setName('type')
|
.setName('type')
|
||||||
.setDescription('Set an activity type')
|
.setDescription('Set an activity type')
|
||||||
.addChoices(
|
.addChoices(
|
||||||
{name: 'Playing', value: Discord.ActivityType.Playing},
|
{name: 'Playing', value: Discord.ActivityType.Playing},
|
||||||
{name: 'Streaming', value: Discord.ActivityType.Streaming},
|
{name: 'Streaming', value: Discord.ActivityType.Streaming},
|
||||||
{name: 'Listening to', value: Discord.ActivityType.Listening},
|
{name: 'Listening to', value: Discord.ActivityType.Listening},
|
||||||
{name: 'Watching', value: Discord.ActivityType.Watching},
|
{name: 'Watching', value: Discord.ActivityType.Watching},
|
||||||
{name: 'Competing in', value: Discord.ActivityType.Competing}
|
{name: 'Competing in', value: Discord.ActivityType.Competing}
|
||||||
))
|
))
|
||||||
.addStringOption((hiAgain)=>hiAgain
|
.addStringOption((hiAgain)=>hiAgain
|
||||||
.setName('name')
|
.setName('name')
|
||||||
.setDescription('Set a message for the activity status'))
|
.setDescription('Set a message for the activity status'))
|
||||||
.addStringOption((hiAgainx2)=>hiAgainx2
|
.addStringOption((hiAgainx2)=>hiAgainx2
|
||||||
.setName('url')
|
.setName('url')
|
||||||
.setDescription('Set an url for streaming status'))
|
.setDescription('Set an url for streaming status'))
|
||||||
.addStringOption((hiAgainx3)=>hiAgainx3
|
.addStringOption((hiAgainx3)=>hiAgainx3
|
||||||
.setName('status')
|
.setName('status')
|
||||||
.setDescription('Set a status indicator for the bot')
|
.setDescription('Set a status indicator for the bot')
|
||||||
.setChoices(
|
.setChoices(
|
||||||
{name: 'Online', value: Discord.PresenceUpdateStatus.Online},
|
{name: 'Online', value: Discord.PresenceUpdateStatus.Online},
|
||||||
{name: 'Idle', value: Discord.PresenceUpdateStatus.Idle},
|
{name: 'Idle', value: Discord.PresenceUpdateStatus.Idle},
|
||||||
{name: 'Do Not Distrub', value: Discord.PresenceUpdateStatus.DoNotDisturb},
|
{name: 'Do Not Distrub', value: Discord.PresenceUpdateStatus.DoNotDisturb},
|
||||||
{name: 'Invisible', value: Discord.PresenceUpdateStatus.Offline}
|
{name: 'Invisible', value: Discord.PresenceUpdateStatus.Offline}
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
({
|
({
|
||||||
srp: ()=>interaction.reply('Ballyspring is the map that is used in Survival Roleplay S4.'),
|
srp: ()=>interaction.reply('Ballyspring is the map that is used in Survival Roleplay S4.'),
|
||||||
dlskin: ()=>interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Daggerwin Logistics hex code').setDescription('The main color will be Onyx (`#353839`) with red bumpers.').setImage('https://cdn.discordapp.com/attachments/801965516947324969/806871878736019456/image0.png')]}),
|
dlskin: ()=>interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Daggerwin Logistics hex code').setDescription('The main color will be Onyx (`#353839`) with red bumpers.').setImage('https://cdn.discordapp.com/attachments/801965516947324969/806871878736019456/image0.png')]}),
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'kick');
|
client.punish(client, interaction, 'kick');
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('kick')
|
.setName('kick')
|
||||||
.setDescription('Boot a member from the server')
|
.setDescription('Boot a member from the server')
|
||||||
.addUserOption((opt)=>opt
|
.addUserOption((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('Which member to kick?')
|
.setDescription('Which member to kick?')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('reason')
|
.setName('reason')
|
||||||
.setDescription('Reason for the kick'))
|
.setDescription('Reason for the kick'))
|
||||||
}
|
}
|
@ -5,296 +5,284 @@ import canvas from 'canvas';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
|
||||||
async function MPdata(client:TClient, interaction:Discord.ChatInputCommandInteraction, embed: Discord.EmbedBuilder) {
|
async function MPdata(client:TClient, interaction:Discord.ChatInputCommandInteraction, embed: Discord.EmbedBuilder) {
|
||||||
let FSserver;
|
let FSserver;
|
||||||
if (!await client.MPServer._content.findOne({_id:interaction.guildId})) return interaction.reply('This server isn\'t linked to the bot.');
|
if (!await client.MPServer._content.findOne({_id:interaction.guildId})) return interaction.reply('This server isn\'t linked to the bot.');
|
||||||
const ServerURL = await client.MPServer._content.findById(interaction.guildId);
|
const ServerURL = await client.MPServer._content.findById(interaction.guildId);
|
||||||
if (!ServerURL) return interaction.reply(`No FS server found, please notify <@&${client.config.mainServer.roles.mpmanager}> to add it.`)
|
if (!ServerURL) return interaction.reply(`No FS server found, please notify <@&${client.config.mainServer.roles.mpmanager}> to add it.`)
|
||||||
const MPURL = ServerURL.ip
|
const MPURL = ServerURL.ip
|
||||||
const MPCode = ServerURL.code
|
const MPCode = ServerURL.code
|
||||||
const verifyURL = MPURL.match(/http|https/)
|
const verifyURL = MPURL.match(/http|https/)
|
||||||
const completedURL = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode
|
const completedURL = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode
|
||||||
if (!verifyURL) return interaction.reply(`The server IP for this server is currently invalid, please notify <@&${client.config.mainServer.roles.mpmanager}>`)
|
if (!verifyURL) return interaction.reply(`The server IP for this server is currently invalid, please notify <@&${client.config.mainServer.roles.mpmanager}>`)
|
||||||
|
|
||||||
// Fetch dss
|
// Fetch dss
|
||||||
try { // v I am aware timeout has decreased from 2800 to 2588 to fit within Discord's interaction timeouts (3s) -Toast
|
try { // v I am aware timeout has decreased from 2800 to 2588 to fit within Discord's interaction timeouts (3s) -Toast
|
||||||
FSserver = await client.axios.get(completedURL, {timeout: 2588, headers: {'User-Agent': `Daggerbot - mp cmd/axios ${client.axios.VERSION}`}})
|
FSserver = await client.axios.get(completedURL, {timeout: 2588, headers: {'User-Agent': `Daggerbot - mp cmd/axios ${client.axios.VERSION}`}})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
// Blame Nawdic & RedRover92
|
// Blame Nawdic & RedRover92
|
||||||
embed.setTitle('Host is not responding.');
|
embed.setTitle('Host is not responding.');
|
||||||
embed.setColor(client.config.embedColorRed);
|
embed.setColor(client.config.embedColorRed);
|
||||||
console.log(client.logTime(), 'DagMP failed to fetch, host didn\'t respond in time.');
|
console.log(client.logTime(), 'DagMP failed to fetch, host didn\'t respond in time.');
|
||||||
return interaction.reply('Server didn\'t respond in time.');
|
return interaction.reply('Server didn\'t respond in time.');
|
||||||
}
|
} return FSserver
|
||||||
return FSserver
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (interaction.channelId == '468835769092669461' && !client.isStaff(interaction.member) && ['status', 'players'].includes(interaction.options.getSubcommand())) {
|
if (interaction.channelId == '468835769092669461' && !client.isStaff(interaction.member) && ['status', 'players'].includes(interaction.options.getSubcommand())) {
|
||||||
interaction.reply(`Please use <#739084625862852715> for \`/mp status/players\` commands to prevent clutter in this channel.`).then((msg)=>{setTimeout(()=>{interaction.deleteReply()}, 6000)});
|
interaction.reply(`Please use <#739084625862852715> for \`/mp status/players\` commands to prevent clutter in this channel.`).then((msg)=>{setTimeout(()=>{interaction.deleteReply()}, 6000)});
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
({
|
||||||
|
status: async()=>{
|
||||||
|
const embed0 = new client.embed();
|
||||||
|
const FSserver0 = await MPdata(client, interaction, embed0);
|
||||||
|
if (!FSserver0?.data) return console.log('FSserver0 failed - status');
|
||||||
|
try {
|
||||||
|
if (FSserver0.data.server.name.length > 1){
|
||||||
|
interaction.reply({embeds: [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}
|
||||||
|
)]})
|
||||||
|
} else if (FSserver0.data.server.name.length == 0) interaction.reply('Server is currently offline.')
|
||||||
|
} catch (err){
|
||||||
|
console.log(err)
|
||||||
|
interaction.reply('FSserver0 Error placeholder')
|
||||||
|
};
|
||||||
|
},
|
||||||
|
info: async()=>{
|
||||||
|
const embed2 = new client.embed().setColor(client.config.embedColor)
|
||||||
|
const FSserver2 = await MPdata(client, interaction, embed2)
|
||||||
|
if (!FSserver2?.data) return console.log('FSserver2 failed - info')
|
||||||
|
const MPURL = await client.MPServer._content.findById(interaction.guildId);
|
||||||
|
interaction.reply({embeds: [embed2.setDescription([
|
||||||
|
`**Server name**: \`${FSserver2?.data.server.name.length == 0 ? '\u200b' : FSserver2?.data.server.name}\``,
|
||||||
|
'**Password:** `mf4700`',
|
||||||
|
'**Crossplay server**',
|
||||||
|
`**Map:** ${FSserver2.data.server.mapName.length == 0 ? 'Null Island' : FSserver2.data.server.mapName}`,
|
||||||
|
`**Mods:** [Click here](${MPURL.ip}/mods.html) **|** [Direct Download](${MPURL.ip}/all_mods_download?onlyActive=true)`,
|
||||||
|
'**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)',
|
||||||
|
'Please see <#543494084363288637> for additional information.'
|
||||||
|
].join('\n'))]});
|
||||||
|
if (FSserver2?.data.server.name.length == 0) embed2.setFooter({text: 'Server is currently offline.'})
|
||||||
|
},
|
||||||
|
url: async()=>{
|
||||||
|
if (client.config.mainServer.id == interaction.guildId) {
|
||||||
|
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');
|
||||||
}
|
}
|
||||||
({
|
const address = interaction.options.getString('address');
|
||||||
status: async()=>{
|
if (!address){
|
||||||
const embed0 = new client.embed();
|
try {
|
||||||
const FSserver0 = await MPdata(client, interaction, embed0);
|
const Url = await client.MPServer._content.findById(interaction.guildId);
|
||||||
if (!FSserver0?.data) return console.log('FSserver0 failed - status');
|
if (Url.ip && Url.code) return interaction.reply(`${Url.get('ip')}`+'/feed/dedicated-server-stats.json?code='+`${Url.get('code')}`)
|
||||||
try {
|
} catch(err){
|
||||||
if (FSserver0.data.server.name.length > 1){
|
console.log(`MPDB :: ${err}`)
|
||||||
embed0.setTitle('Status/Details').setColor(client.config.embedColor).addFields(
|
interaction.reply('**Database error:**\nTry inserting an URL first.')
|
||||||
{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},
|
}else{
|
||||||
{name: 'Current map', value: `${FSserver0?.data.server.mapName.length == 0 ? '\u200b' : FSserver0.data.server.mapName}`, inline: true},
|
const verifyURL = address.match(/dedicated-server-stats/)
|
||||||
{name: 'Version', value: `${FSserver0?.data.server.version.length == 0 ? '\u200b' : FSserver0.data.server.version}`, inline: true},
|
if (!verifyURL) return interaction.reply('The URL does not match `dedicated-server-stats.xml`')
|
||||||
{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}
|
const newURL = address.replace('xml','json').split('/feed/dedicated-server-stats.json?code=')
|
||||||
)
|
try{
|
||||||
interaction.reply({embeds: [embed0]})
|
console.log(`MPDB :: URL for ${interaction.guild.name} has been updated by ${interaction.member.displayName} (${interaction.member.id})`);
|
||||||
} else if (FSserver0.data.server.name.length == 0) interaction.reply('Server is currently offline.')
|
await client.MPServer._content.create({_id: interaction.guildId, ip: newURL[0], code: newURL[1], timesUpdated: 0})
|
||||||
} catch (err){
|
return interaction.reply('This server is now linked and URL has been added.');
|
||||||
console.log(err)
|
} catch(err){
|
||||||
interaction.reply('FSserver0 Error placeholder')
|
const affectedValues = await client.MPServer._content.findByIdAndUpdate({_id: interaction.guildId}, {ip: newURL[0], code: newURL[1]});
|
||||||
};
|
await client.MPServer._increment(interaction.guildId);
|
||||||
},
|
if (affectedValues) return interaction.reply('URL successfully updated.')
|
||||||
info: async()=>{
|
}
|
||||||
const embed2 = new client.embed().setColor(client.config.embedColor)
|
}
|
||||||
const FSserver2 = await MPdata(client, interaction, embed2)
|
},
|
||||||
if (!FSserver2?.data) return console.log('FSserver2 failed - info')
|
players: async()=>{
|
||||||
const MPURL = await client.MPServer._content.findById(interaction.guildId);
|
const embed1 = new client.embed();
|
||||||
embed2.setDescription([
|
const data = JSON.parse(fs.readFileSync(path.join(__dirname, '../database/MPPlayerData.json'), {encoding: 'utf8'})).slice(client.statsGraph)
|
||||||
`**Server name**: \`${FSserver2?.data.server.name.length == 0 ? '\u200b' : FSserver2?.data.server.name}\``,
|
// handle negative days
|
||||||
'**Password:** `mf4700`',
|
data.forEach((change: number, i: number) => {
|
||||||
'**Crossplay server**',
|
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
||||||
`**Map:** ${FSserver2.data.server.mapName.length == 0 ? 'Null Island' : FSserver2.data.server.mapName}`,
|
});
|
||||||
`**Mods:** [Click here](${MPURL.ip}/mods.html) **|** [Direct Download](${MPURL.ip}/all_mods_download?onlyActive=true)`,
|
|
||||||
'**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)',
|
|
||||||
'Please see <#543494084363288637> for additional information.'
|
|
||||||
].join('\n'));
|
|
||||||
if (FSserver2?.data.server.name.length == 0) embed2.setFooter({text: 'Server is currently offline.'})
|
|
||||||
interaction.reply({embeds: [embed2]})
|
|
||||||
},
|
|
||||||
url: async()=>{
|
|
||||||
if (client.config.mainServer.id == interaction.guildId) {
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
const address = interaction.options.getString('address');
|
|
||||||
if (!address){
|
|
||||||
try {
|
|
||||||
const Url = await client.MPServer._content.findById(interaction.guildId);
|
|
||||||
if (Url.ip && Url.code) return interaction.reply(`${Url.get('ip')}`+'/feed/dedicated-server-stats.json?code='+`${Url.get('code')}`)
|
|
||||||
} catch(err){
|
|
||||||
console.log(`MPDB :: ${err}`)
|
|
||||||
interaction.reply('**Database error:**\nTry inserting an URL first.')
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
const verifyURL = address.match(/dedicated-server-stats/)
|
|
||||||
if (!verifyURL) return interaction.reply('The URL does not match `dedicated-server-stats.xml`')
|
|
||||||
const newURL = address.replace('xml','json').split('/feed/dedicated-server-stats.json?code=')
|
|
||||||
try{
|
|
||||||
console.log(`MPDB :: URL for ${interaction.guild.name} has been updated by ${interaction.member.displayName} (${interaction.member.id})`);
|
|
||||||
await client.MPServer._content.create({_id: interaction.guildId, ip: newURL[0], code: newURL[1], timesUpdated: 0})
|
|
||||||
return interaction.reply('This server is now linked and URL has been added.');
|
|
||||||
} catch(err){
|
|
||||||
const affectedValues = await client.MPServer._content.findByIdAndUpdate({_id: interaction.guildId}, {ip: newURL[0], code: newURL[1]});
|
|
||||||
await client.MPServer._increment(interaction.guildId);
|
|
||||||
if (affectedValues) return interaction.reply('URL successfully updated.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
players: async()=>{
|
|
||||||
const embed1 = new client.embed();
|
|
||||||
const data = JSON.parse(fs.readFileSync(path.join(__dirname, '../database/MPPlayerData.json'), {encoding: 'utf8'})).slice(client.statsGraph)
|
|
||||||
// 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 first_graph_top = 16;
|
||||||
const second_graph_top = 16;
|
const second_graph_top = 16;
|
||||||
const textSize = 40;
|
const textSize = 40;
|
||||||
|
|
||||||
const img = canvas.createCanvas(1500, 750);
|
const img = canvas.createCanvas(1500, 750);
|
||||||
const ctx = img.getContext('2d');
|
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 - 30));
|
|
||||||
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) {
|
const graphOrigin = [15, 65];
|
||||||
if (playercount === first_graph_top) {
|
const graphSize = [1300, 630];
|
||||||
return client.config.embedColorRed as string;
|
const nodeWidth = graphSize[0] / (data.length - 1);
|
||||||
} else if (playercount > 9) {
|
ctx.fillStyle = '#36393f';
|
||||||
return client.config.embedColorYellow as string;
|
ctx.fillRect(0, 0, img.width, img.height);
|
||||||
} else {return client.config.embedColorGreen as string}
|
|
||||||
}
|
|
||||||
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[0], lastCoords[1], 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 as string); // add a yellow stop to the gradient
|
|
||||||
}
|
|
||||||
ctx.strokeStyle = grd;
|
|
||||||
} else {
|
|
||||||
ctx.strokeStyle = colorAtPlayercount(curPC);
|
|
||||||
}
|
|
||||||
ctx.beginPath();
|
|
||||||
if (lastCoords.length > 0) ctx.moveTo(lastCoords[0], lastCoords[1]);
|
|
||||||
// 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
|
// grey horizontal lines
|
||||||
const lowx = graphOrigin[0] + graphSize[0] + textSize / 2;
|
ctx.lineWidth = 5;
|
||||||
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
|
||||||
ctx.fillText('0 players', lowx, lowy);
|
|
||||||
|
|
||||||
// 30m
|
let interval_candidates = [];
|
||||||
ctx.fillText('30 mins ago', lastMonthStart, graphOrigin[1] - (textSize / 2));
|
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];
|
||||||
|
|
||||||
// time ->
|
const previousY: Array<number> = [];
|
||||||
const tx = graphOrigin[0] + (textSize / 2);
|
|
||||||
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
ctx.strokeStyle = '#202225';
|
||||||
ctx.fillText('time ->', tx, ty);
|
for (let i = 0; i <= chosen_interval[1]; i++) {
|
||||||
|
const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]);
|
||||||
const Image = new client.attachmentBuilder(img.toBuffer(),{name: 'FSStats.png'})
|
if (y < graphOrigin[1]) continue;
|
||||||
embed1.setImage('attachment://FSStats.png')
|
const even = ((i + 1) % 2) === 0;
|
||||||
const FSserver1 = await MPdata(client, interaction, embed1)
|
if (even) ctx.strokeStyle = '#2c2f33';
|
||||||
if (!FSserver1?.data) return console.log('FSserver1 failed - players')
|
ctx.beginPath();
|
||||||
embed1.setTitle(FSserver1?.data.server.name.length == 0 ? 'Offline' : FSserver1?.data.server.name)
|
ctx.lineTo(graphOrigin[0], y);
|
||||||
.setDescription(`${FSserver1?.data.slots.used}/${FSserver1?.data.slots.capacity}`)
|
ctx.lineTo(graphOrigin[0] + graphSize[0], y);
|
||||||
.setColor(FSserver1?.data.server.name.length == 0 ? client.config.embedColorRed : client.config.embedColor);
|
ctx.stroke();
|
||||||
FSserver1?.data.slots.players.filter(x=>x.isUsed).forEach(player=>{
|
ctx.closePath();
|
||||||
embed1.addFields({name: `${player.name} ${player.isAdmin ? '| admin' : ''}`, value: `Farming for ${(Math.floor(player.uptime/60))} hr, ${('0' + (player.uptime % 60)).slice(-2)} min`})
|
if (even) ctx.strokeStyle = '#202225';
|
||||||
})
|
previousY.push(y, i * chosen_interval[0]);
|
||||||
interaction.reply({embeds: [embed1], files: [Image]})
|
}
|
||||||
}/*,
|
|
||||||
series: ()=>{
|
// 30m mark
|
||||||
const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('How to join the Daggerwin MP series')
|
ctx.setLineDash([8, 16]);
|
||||||
.setDescription([
|
ctx.beginPath();
|
||||||
'To join the Daggerwin MP series, you first need to:',
|
const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 30));
|
||||||
'**1:** Note that only PC players can join the MP series due to the mods that are used.',
|
ctx.lineTo(lastMonthStart, graphOrigin[1]);
|
||||||
'**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.',
|
ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]);
|
||||||
'**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.',
|
ctx.stroke();
|
||||||
'**4:** If you don\'t receive the role within a day or so, please message an Admin and they will sort it out.',
|
ctx.closePath();
|
||||||
'**5:** Take a look in <#511657659364147200> to get information on how to join the server.'
|
ctx.setLineDash([]);
|
||||||
].join('\n'));
|
|
||||||
interaction.reply({embeds: [embed3]})
|
// draw points
|
||||||
}*/
|
ctx.lineWidth = 5;
|
||||||
} as any)[interaction.options.getSubcommand()]();
|
|
||||||
},
|
function getYCoordinate(value: number) {
|
||||||
data: new SlashCommandBuilder()
|
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
||||||
.setName('mp')
|
}
|
||||||
.setDescription('Display MP status and other things')
|
|
||||||
.addSubcommand((opt)=>opt
|
function colorAtPlayercount(playercount: number) {
|
||||||
.setName('status')
|
if (playercount === first_graph_top) return client.config.embedColorRed as string;
|
||||||
.setDescription('Check server status and details'))
|
else if (playercount > 9) return client.config.embedColorYellow as string;
|
||||||
.addSubcommand((opt)=>opt
|
else return client.config.embedColorGreen as string
|
||||||
.setName('players')
|
}
|
||||||
.setDescription('Check who\'s playing on the server'))
|
let lastCoords: Array<number> = [];
|
||||||
.addSubcommand((opt)=>opt
|
data.forEach((curPC: number /* current player count */, i: number) => {
|
||||||
.setName('info')
|
if (curPC < 0) curPC = 0;
|
||||||
.setDescription('Provides you with server information such as filters and so on'))
|
const x = i * nodeWidth + graphOrigin[0];
|
||||||
.addSubcommand((opt)=>opt
|
const y = getYCoordinate(curPC);
|
||||||
.setName('url')
|
const nexPC /* next player count */ = data[i + 1];
|
||||||
.setDescription('View the URL for this server\'s FSMP server or update the URL')
|
const prvPC /* previous player count */ = data[i - 1];
|
||||||
.addStringOption((opt)=>opt
|
const curColor = colorAtPlayercount(curPC); // color now
|
||||||
.setName('address')
|
const prvColor = colorAtPlayercount(prvPC); // color at last point
|
||||||
.setDescription('Insert a \'dedicated-server-stats\' URL')))
|
if (curColor !== prvColor && !isNaN(prvPC) && lastCoords.length > 0) { // gradient should be used when the color between now and last point is not the same
|
||||||
/* .addSubcommand((opt)=>opt
|
// gradient from now to last point
|
||||||
.setName('series')
|
const grd = ctx.createLinearGradient(lastCoords[0], lastCoords[1], x, y);
|
||||||
.setDescription('Step-by-step on joining Daggerwin\'s MP series')) */
|
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 as string); // add a yellow stop to the gradient
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = grd;
|
||||||
|
} else ctx.strokeStyle = colorAtPlayercount(curPC);
|
||||||
|
ctx.beginPath();
|
||||||
|
if (lastCoords.length > 0) ctx.moveTo(lastCoords[0], lastCoords[1]);
|
||||||
|
// 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)
|
||||||
|
if (!FSserver1?.data) return console.log('FSserver1 failed - players')
|
||||||
|
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]})
|
||||||
|
}/*,
|
||||||
|
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]})
|
||||||
|
}*/
|
||||||
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
|
},
|
||||||
|
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('url')
|
||||||
|
.setDescription('View the URL for this server\'s FSMP server or update the URL')
|
||||||
|
.addStringOption((opt)=>opt
|
||||||
|
.setName('address')
|
||||||
|
.setDescription('Insert a \'dedicated-server-stats\' URL')))/*
|
||||||
|
.addSubcommand((opt)=>opt
|
||||||
|
.setName('series')
|
||||||
|
.setDescription('Step-by-step on joining Daggerwin\'s MP series'))*/
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'mute');
|
client.punish(client, interaction, 'mute');
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('mute')
|
.setName('mute')
|
||||||
.setDescription('Mute a member')
|
.setDescription('Mute a member')
|
||||||
.addUserOption((opt)=>opt
|
.addUserOption((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('Which member to mute?')
|
.setDescription('Which member to mute?')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('time')
|
.setName('time')
|
||||||
.setDescription('Mute duration'))
|
.setDescription('Mute duration'))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('reason')
|
.setName('reason')
|
||||||
.setDescription('Reason for the mute'))
|
.setDescription('Reason for the mute'))
|
||||||
}
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const msg = await interaction.reply({content: 'Pinging...', fetchReply: true})
|
const msg = await interaction.reply({content: 'Pinging...', fetchReply: true})
|
||||||
const time = msg.createdTimestamp - interaction.createdTimestamp;
|
const time = msg.createdTimestamp - interaction.createdTimestamp;
|
||||||
msg.edit(`Websocket: \`${client.formatTime(client.ws.ping, 3, {longNames: false, commas: true})}\`\nBot: \`${client.formatTime(time, 3, {longNames: false, commas: true})}\``)
|
msg.edit(`Websocket: \`${client.formatTime(client.ws.ping, 3, {longNames: false, commas: true})}\`\nBot: \`${client.formatTime(time, 3, {longNames: false, commas: true})}\``)
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('ping')
|
.setName('ping')
|
||||||
.setDescription('Check bot\'s latency')
|
.setDescription('Check bot\'s latency')
|
||||||
}
|
}
|
@ -1,37 +1,35 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod');
|
||||||
const amount = interaction.options.getInteger('amount') as number;
|
const amount = interaction.options.getInteger('amount') as number;
|
||||||
if (amount > 100) return interaction.reply({content: 'Discord API limits purging up to 100 messages.', ephemeral: true})
|
if (amount > 100) return interaction.reply({content: 'Discord API limits purging up to 100 messages.', ephemeral: true})
|
||||||
const user = interaction.options.getUser('user');
|
const user = interaction.options.getUser('user');
|
||||||
|
|
||||||
let messagesArray: Array<string> = [];
|
let messagesArray: Array<string> = [];
|
||||||
|
|
||||||
if (user){
|
if (user){
|
||||||
(interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then((msgs)=>{
|
(interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then(msgs=>{
|
||||||
const msgList = msgs.filter(x=>x.author.id == user.id);
|
const msgList = msgs.filter(x=>x.author.id == user.id);
|
||||||
(interaction.channel as Discord.TextChannel).bulkDelete(msgList);
|
(interaction.channel as Discord.TextChannel).bulkDelete(msgList);
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
(interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then(async messages=>{
|
(interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then(async messages=>{
|
||||||
messages.forEach(message=>{
|
messages.forEach(message=>messagesArray.push(message.id));
|
||||||
messagesArray.push(message.id);
|
await (interaction.channel as Discord.TextChannel).bulkDelete(messagesArray);
|
||||||
});
|
})
|
||||||
await (interaction.channel as Discord.TextChannel).bulkDelete(messagesArray);
|
}
|
||||||
})
|
await interaction.reply({content: `Successfully purged ${amount} messages.`, ephemeral: true})
|
||||||
}
|
},
|
||||||
await interaction.reply({content: `Successfully purged ${amount} messages.`, ephemeral: true})
|
data: new SlashCommandBuilder()
|
||||||
},
|
.setName('purge')
|
||||||
data: new SlashCommandBuilder()
|
.setDescription('Purge the amount of messages in this channel')
|
||||||
.setName('purge')
|
.addIntegerOption((opt)=>opt
|
||||||
.setDescription('Purge the amount of messages in this channel')
|
.setName('amount')
|
||||||
.addIntegerOption((opt)=>opt
|
.setDescription('Amount of messages to be obliterated')
|
||||||
.setName('amount')
|
.setRequired(true))
|
||||||
.setDescription('Amount of messages to be obliterated')
|
.addUserOption((opt)=>opt
|
||||||
.setRequired(true))
|
.setName('user')
|
||||||
.addUserOption((opt)=>opt
|
.setDescription('Which user to have their messages obliterated?'))
|
||||||
.setName('user')
|
|
||||||
.setDescription('Which user to have their messages obliterated?'))
|
|
||||||
}
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const embed = new client.embed().setColor(Math.floor(Math.random()*16777215));
|
const embed = new client.embed().setColor(Math.floor(Math.random()*16777215));
|
||||||
embed.addFields({name: 'Hex code', value: `#${embed.data.color.toString(16).toUpperCase()}`});
|
embed.addFields({name: 'Hex code', value: `#${embed.data.color.toString(16).toUpperCase()}`});
|
||||||
interaction.reply({embeds: [embed]});
|
interaction.reply({embeds: [embed]});
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('randomcolor')
|
.setName('randomcolor')
|
||||||
.setDescription('Generate a random hex code')
|
.setDescription('Generate a random hex code')
|
||||||
}
|
}
|
@ -4,171 +4,171 @@ import path from 'node:path';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import canvas from 'canvas';
|
import canvas from 'canvas';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
if (interaction.guildId !== client.config.mainServer.id) return interaction.reply({content: 'This command doesn\'t work in this server.', ephemeral: true});
|
if (interaction.guildId !== client.config.mainServer.id) return interaction.reply({content: 'This command doesn\'t work in this server.', ephemeral: true});
|
||||||
const allData = await client.userLevels._content.find({});
|
const allData = await client.userLevels._content.find({});
|
||||||
({
|
({
|
||||||
view: async()=>{
|
view: async()=>{
|
||||||
// fetch user or user interaction sender
|
// fetch user or user interaction sender
|
||||||
const member = interaction.options.getMember("member") ?? interaction.member as Discord.GuildMember;
|
const member = interaction.options.getMember("member") ?? interaction.member as Discord.GuildMember;
|
||||||
if (member.user.bot) return interaction.reply('Bots don\'t level up, try viewing non-bots instead.')
|
if (member.user.bot) return interaction.reply('Bots don\'t level up, try viewing non-bots instead.')
|
||||||
// information about users progress on level roles
|
// information about users progress on level roles
|
||||||
const userData = await client.userLevels._content.findById(member.user.id);
|
const userData = await client.userLevels._content.findById(member.user.id);
|
||||||
|
|
||||||
const pronounBool = (you: string, they: string) => { // takes 2 words and chooses which to use based on if user did this command on themself
|
const pronounBool = (you: string, they: string) => { // takes 2 words and chooses which to use based on if user did this command on themself
|
||||||
if (interaction.user.id === member.user.id) return you || true;
|
if (interaction.user.id === member.user.id) return you || true;
|
||||||
else return they || false;
|
else return they || false;
|
||||||
};
|
};
|
||||||
if (!userData) return interaction.reply(`${pronounBool('You', 'They')} currently don't have a level, send some messages to level up.`)
|
if (!userData) return interaction.reply(`${pronounBool('You', 'They')} currently don't have a level, send some messages to level up.`)
|
||||||
|
|
||||||
const index = allData.sort((a, b) => b.messages - a.messages).map(x => x._id).indexOf(member.id) + 1;
|
const index = allData.sort((a, b) => b.messages - a.messages).map(x => x._id).indexOf(member.id) + 1;
|
||||||
const memberDifference = userData.messages - client.userLevels.algorithm(userData.level);
|
const memberDifference = userData.messages - client.userLevels.algorithm(userData.level);
|
||||||
const levelDifference = client.userLevels.algorithm(userData.level+1) - client.userLevels.algorithm(userData.level);
|
const levelDifference = client.userLevels.algorithm(userData.level+1) - client.userLevels.algorithm(userData.level);
|
||||||
interaction.reply({embeds: [new client.embed().setColor(member.displayColor).setTitle(`Level: **${userData.level}**\nRank: **${index ? '#' + index : 'last'}**\nProgress: **${memberDifference}/${levelDifference} (${(memberDifference/levelDifference*100).toFixed(2)}%)**\nTotal: **${userData.messages}**`).setThumbnail(member.user.avatarURL({ extension: 'png', size: 256}) || member.user.defaultAvatarURL)]})
|
interaction.reply({embeds: [new client.embed().setColor(member.displayColor).setTitle(`Level: **${userData.level}**\nRank: **${index ? '#' + index : 'last'}**\nProgress: **${memberDifference}/${levelDifference} (${(memberDifference/levelDifference*100).toFixed(2)}%)**\nTotal: **${userData.messages}**`).setThumbnail(member.user.avatarURL({ extension: 'png', size: 256}) || member.user.defaultAvatarURL)]})
|
||||||
},
|
},
|
||||||
leaderboard: ()=>{
|
leaderboard: ()=>{
|
||||||
const messageCountsTotal = allData.reduce((a, b) => a + b.messages, 0);
|
const messageCountsTotal = allData.reduce((a, b) => a + b.messages, 0);
|
||||||
const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24);
|
const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24);
|
||||||
|
|
||||||
const dailyMsgsPath = path.join(__dirname, '../database/dailyMsgs.json');
|
const dailyMsgsPath = path.join(__dirname, '../database/dailyMsgs.json');
|
||||||
const data = JSON.parse(fs.readFileSync(dailyMsgsPath, 'utf8')).map((x: Array<number>, i: number, a: any) => {
|
const data = JSON.parse(fs.readFileSync(dailyMsgsPath, 'utf8')).map((x: Array<number>, i: number, a: any) => {
|
||||||
const yesterday = a[i - 1] || [];
|
const yesterday = a[i - 1] || [];
|
||||||
return x[1] - (yesterday[1] || x[1]);
|
return x[1] - (yesterday[1] || x[1]);
|
||||||
}).slice(1).slice(-60);
|
}).slice(1).slice(-60);
|
||||||
|
|
||||||
// handle negative days
|
// handle negative days
|
||||||
data.forEach((change: number, i: number) => {
|
data.forEach((change: number, i: number) => {
|
||||||
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const maxValue = Math.max(...data);
|
const maxValue = Math.max(...data);
|
||||||
const maxValueArr = maxValue.toString().split('');
|
const maxValueArr = maxValue.toString().split('');
|
||||||
|
|
||||||
const first_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 1)) * 10 ** (maxValueArr.length - 1);
|
const first_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 1)) * 10 ** (maxValueArr.length - 1);
|
||||||
const second_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 2)) * 10 ** (maxValueArr.length - 2);
|
const second_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 2)) * 10 ** (maxValueArr.length - 2);
|
||||||
const textSize = 32;
|
const textSize = 32;
|
||||||
|
|
||||||
const img = canvas.createCanvas(950, 450);
|
const img = canvas.createCanvas(950, 450);
|
||||||
const ctx = img.getContext('2d');
|
const ctx = img.getContext('2d');
|
||||||
|
|
||||||
const graphOrigin = [10, 50];
|
const graphOrigin = [10, 50];
|
||||||
const graphSize = [700, 360];
|
const graphSize = [700, 360];
|
||||||
const nodeWidth = graphSize[0] / (data.length - 1);
|
const nodeWidth = graphSize[0] / (data.length - 1);
|
||||||
ctx.fillStyle = '#36393f';
|
ctx.fillStyle = '#36393f';
|
||||||
ctx.fillRect(0, 0, img.width, img.height);
|
ctx.fillRect(0, 0, img.width, img.height);
|
||||||
|
|
||||||
// grey horizontal lines
|
// grey horizontal lines
|
||||||
ctx.lineWidth = 3;
|
ctx.lineWidth = 3;
|
||||||
|
|
||||||
let interval_candidates = [];
|
let interval_candidates = [];
|
||||||
for (let i = 4; i < 10; i++) {
|
for (let i = 4; i < 10; i++) {
|
||||||
const interval = first_graph_top / i;
|
const interval = first_graph_top / i;
|
||||||
if (Number.isInteger(interval)) {
|
if (Number.isInteger(interval)) {
|
||||||
let intervalString = interval.toString();
|
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)
|
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]);
|
interval_candidates.push([interval, i, reference_number]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const chosen_interval = interval_candidates.sort((a, b) => b[2] - a[2])[0];
|
const chosen_interval = interval_candidates.sort((a, b) => b[2] - a[2])[0];
|
||||||
let previousY: Array<number> = [];
|
let previousY: Array<number> = [];
|
||||||
|
|
||||||
ctx.strokeStyle = '#202225';
|
ctx.strokeStyle = '#202225';
|
||||||
for (let i = 0; i <= chosen_interval[1]; i++) {
|
for (let i = 0; i <= chosen_interval[1]; i++) {
|
||||||
const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]);
|
const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]);
|
||||||
if (y < graphOrigin[1]) continue;
|
if (y < graphOrigin[1]) continue;
|
||||||
const even = ((i + 1) % 2) === 0;
|
const even = ((i + 1) % 2) === 0;
|
||||||
if (even) ctx.strokeStyle = '#2c2f33';
|
if (even) ctx.strokeStyle = '#2c2f33';
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.lineTo(graphOrigin[0], y);
|
ctx.lineTo(graphOrigin[0], y);
|
||||||
ctx.lineTo(graphOrigin[0] + graphSize[0], y);
|
ctx.lineTo(graphOrigin[0] + graphSize[0], y);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
if (even) ctx.strokeStyle = '#202225';
|
if (even) ctx.strokeStyle = '#202225';
|
||||||
previousY = [y, i * chosen_interval[0]];
|
previousY = [y, i * chosen_interval[0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 30d mark
|
// 30d mark
|
||||||
ctx.setLineDash([8, 16]);
|
ctx.setLineDash([8, 16]);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 30));
|
const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 30));
|
||||||
ctx.lineTo(lastMonthStart, graphOrigin[1]);
|
ctx.lineTo(lastMonthStart, graphOrigin[1]);
|
||||||
ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]);
|
ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
|
|
||||||
// draw points
|
// draw points
|
||||||
ctx.strokeStyle = client.config.embedColor as string;
|
ctx.strokeStyle = client.config.embedColor as string;
|
||||||
ctx.fillStyle = client.config.embedColor as string;
|
ctx.fillStyle = client.config.embedColor as string;
|
||||||
ctx.lineWidth = 3;
|
ctx.lineWidth = 3;
|
||||||
|
|
||||||
function getYCoordinate(value: number) {
|
function getYCoordinate(value: number) {
|
||||||
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastCoords: Array<number> = [];
|
let lastCoords: Array<number> = [];
|
||||||
data.forEach((val: number, i: number) => {
|
data.forEach((val: number, i: number) => {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
if (lastCoords) ctx.moveTo(lastCoords[0], lastCoords[1]);
|
if (lastCoords) ctx.moveTo(lastCoords[0], lastCoords[1]);
|
||||||
if (val < 0) val = 0;
|
if (val < 0) val = 0;
|
||||||
const x = i * nodeWidth + graphOrigin[0];
|
const x = i * nodeWidth + graphOrigin[0];
|
||||||
const y = getYCoordinate(val);
|
const y = getYCoordinate(val);
|
||||||
ctx.lineTo(x, y);
|
ctx.lineTo(x, y);
|
||||||
lastCoords = [x, y];
|
lastCoords = [x, y];
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
|
|
||||||
// ball
|
// ball
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(x, y, ctx.lineWidth * 1.2, 0, 2 * Math.PI)
|
ctx.arc(x, y, ctx.lineWidth * 1.2, 0, 2 * Math.PI)
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
});
|
});
|
||||||
|
|
||||||
// draw text
|
// draw text
|
||||||
ctx.font = '400 ' + textSize + 'px sans-serif';
|
ctx.font = '400 ' + textSize + 'px sans-serif';
|
||||||
ctx.fillStyle = 'white';
|
ctx.fillStyle = 'white';
|
||||||
|
|
||||||
// highest value
|
// highest value
|
||||||
const maxx = graphOrigin[0] + graphSize[0] + textSize;
|
const maxx = graphOrigin[0] + graphSize[0] + textSize;
|
||||||
const maxy = previousY[0] + (textSize / 3);
|
const maxy = previousY[0] + (textSize / 3);
|
||||||
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
||||||
|
|
||||||
// lowest value
|
// lowest value
|
||||||
const lowx = graphOrigin[0] + graphSize[0] + textSize;
|
const lowx = graphOrigin[0] + graphSize[0] + textSize;
|
||||||
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
||||||
ctx.fillText('0 msgs/day', lowx, lowy);
|
ctx.fillText('0 msgs/day', lowx, lowy);
|
||||||
|
|
||||||
// 30d
|
// 30d
|
||||||
ctx.fillText('30d ago', lastMonthStart, graphOrigin[1] - (textSize / 3));
|
ctx.fillText('30d ago', lastMonthStart, graphOrigin[1] - (textSize / 3));
|
||||||
|
|
||||||
// time ->
|
// time ->
|
||||||
const tx = graphOrigin[0] + (textSize / 2);
|
const tx = graphOrigin[0] + (textSize / 2);
|
||||||
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
||||||
ctx.fillText('time ->', tx, ty);
|
ctx.fillText('time ->', tx, ty);
|
||||||
|
|
||||||
const topUsers = allData.sort((a,b)=>b.messages - a.messages).slice(0,10).map((x,i)=>`\`${i+1}.\` <@${x._id}>: ${x.messages.toLocaleString('en-US')}`).join('\n');
|
const topUsers = allData.sort((a,b)=>b.messages - a.messages).slice(0,10).map((x,i)=>`\`${i+1}.\` <@${x._id}>: ${x.messages.toLocaleString('en-US')}`).join('\n');
|
||||||
|
|
||||||
const graphImage = new client.attachmentBuilder(img.toBuffer(), {name: 'dailymsgs.png'})
|
const graphImage = new client.attachmentBuilder(img.toBuffer(), {name: 'dailymsgs.png'})
|
||||||
const embed = new client.embed().setTitle('Ranking leaderboard')
|
const embed = new client.embed().setTitle('Ranking leaderboard')
|
||||||
.setDescription(`Level System was created **${timeActive}** days ago. Since then, a total of **${messageCountsTotal.toLocaleString('en-US')}** messages have been sent in this server.`)
|
.setDescription(`Level System was created **${timeActive}** days ago. Since then, a total of **${messageCountsTotal.toLocaleString('en-US')}** messages have been sent in this server.`)
|
||||||
.addFields({name: 'Top users by messages sent:', value: topUsers})
|
.addFields({name: 'Top users by messages sent:', value: topUsers})
|
||||||
.setImage('attachment://dailymsgs.png').setColor(client.config.embedColor)
|
.setImage('attachment://dailymsgs.png').setColor(client.config.embedColor)
|
||||||
.setFooter({text: 'Graph updates daily.'})
|
.setFooter({text: 'Graph updates daily.'})
|
||||||
interaction.reply({embeds: [embed], files: [graphImage]})
|
interaction.reply({embeds: [embed], files: [graphImage]})
|
||||||
}
|
}
|
||||||
} as any)[interaction.options.getSubcommand()]();
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('rank')
|
.setName('rank')
|
||||||
.setDescription('Level system')
|
.setDescription('Level system')
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('view')
|
.setName('view')
|
||||||
.setDescription('View your rank or someone else\'s rank')
|
.setDescription('View your rank or someone else\'s rank')
|
||||||
.addUserOption((opt)=>opt
|
.addUserOption((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('Which member do you want to view?')))
|
.setDescription('Which member do you want to view?')))
|
||||||
.addSubcommand((optt)=>optt
|
.addSubcommand((optt)=>optt
|
||||||
.setName('leaderboard')
|
.setName('leaderboard')
|
||||||
.setDescription('View top 10 users on leaderboard'))
|
.setDescription('View top 10 users on leaderboard'))
|
||||||
}
|
}
|
@ -1,23 +1,23 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const role = interaction.options.getRole('role') as Discord.Role;
|
const role = interaction.options.getRole('role') as Discord.Role;
|
||||||
const permissions = role.permissions.toArray();
|
const permissions = role.permissions.toArray();
|
||||||
const Role = role.members.map((e:Discord.GuildMember)=>`**${e.user.tag}**`).join('\n') || '';
|
const Role = role.members.map((e:Discord.GuildMember)=>`**${e.user.tag}**`).join('\n') || '';
|
||||||
interaction.reply({embeds: [new client.embed().setColor(role.color || '#fefefe').setThumbnail(role?.iconURL()).setTitle(`Role Info: ${role.name}`).addFields(
|
interaction.reply({embeds: [new client.embed().setColor(role.color || '#fefefe').setThumbnail(role?.iconURL()).setTitle(`Role Info: ${role.name}`).addFields(
|
||||||
{name: '🔹 ID', value: `\`${role.id}\``, inline: true},
|
{name: '🔹 ID', value: `\`${role.id}\``, inline: true},
|
||||||
{name: '🔹 Color', value: `\`${role.hexColor}\``, inline: true},
|
{name: '🔹 Color', value: `\`${role.hexColor}\``, inline: true},
|
||||||
{name: '🔹 Creation Date', value: `<t:${Math.round(role.createdTimestamp/1000)}>\n<t:${Math.round(role.createdTimestamp/1000)}:R>`, inline: true},
|
{name: '🔹 Creation Date', value: `<t:${Math.round(role.createdTimestamp/1000)}>\n<t:${Math.round(role.createdTimestamp/1000)}:R>`, inline: true},
|
||||||
{name: '🔹 Misc', value: `Hoist: \`${role.hoist}\`\nMentionable: \`${role.mentionable}\`\nPosition: \`${role.position}\` from bottom\nMembers: \`${role.members.size}\`\n${role.members.size < 21 ? Role : ''}`, inline: true},
|
{name: '🔹 Misc', value: `Hoist: \`${role.hoist}\`\nMentionable: \`${role.mentionable}\`\nPosition: \`${role.position}\` from bottom\nMembers: \`${role.members.size}\`\n${role.members.size < 21 ? Role : ''}`, inline: true},
|
||||||
{name: '🔹 Permissions', value: `${permissions.includes('Administrator') ? ['Administrator'] : permissions.join(', ') || 'None'}`, inline: true}
|
{name: '🔹 Permissions', value: `${permissions.includes('Administrator') ? ['Administrator'] : permissions.join(', ') || 'None'}`, inline: true}
|
||||||
)]})
|
)]})
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('roleinfo')
|
.setName('roleinfo')
|
||||||
.setDescription('View information about the selected role')
|
.setDescription('View information about the selected role')
|
||||||
.addRoleOption((opt)=>opt
|
.addRoleOption((opt)=>opt
|
||||||
.setName('role')
|
.setName('role')
|
||||||
.setDescription('Role name to view information')
|
.setDescription('Role name to view information')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
}
|
}
|
@ -1,17 +1,17 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'softban');
|
client.punish(client, interaction, 'softban');
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('softban')
|
.setName('softban')
|
||||||
.setDescription('Softban a member from the server')
|
.setDescription('Softban a member from the server')
|
||||||
.addUserOption((opt)=>opt
|
.addUserOption((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('Which member to softban?')
|
.setDescription('Which member to softban?')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('reason')
|
.setName('reason')
|
||||||
.setDescription('Reason for the softban'))
|
.setDescription('Reason for the softban'))
|
||||||
}
|
}
|
@ -4,73 +4,69 @@ import si from 'systeminformation';
|
|||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
// Host specification (L9-L22, L55-L70)
|
// Host specification (L9-L22, L51-L66)
|
||||||
// Bytes conversion
|
// Bytes conversion
|
||||||
function formatBytes(bytes:number, decimals:number = 2) {
|
function formatBytes(bytes:number, decimals:number = 2) {
|
||||||
if (bytes === 0) return '0 Bytes';
|
if (bytes === 0) return '0 Bytes';
|
||||||
const k = 1024;
|
const k = 1024;
|
||||||
const dm = decimals < 0 ? 0 : decimals;
|
const dm = decimals < 0 ? 0 : decimals;
|
||||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||||
};
|
};
|
||||||
var DJSver = require('discord.js').version;
|
var DJSver = require('discord.js').version;
|
||||||
const cpu = await si.cpu();
|
const cpu = await si.cpu();
|
||||||
const ram = await si.mem();
|
const ram = await si.mem();
|
||||||
const osInfo = await si.osInfo();
|
const osInfo = await si.osInfo();
|
||||||
const currentLoad = await si.currentLoad();
|
const currentLoad = await si.currentLoad();
|
||||||
|
|
||||||
// Command usage (L25-L54)
|
// Command usage (L25-L50)
|
||||||
const columns = ['Command name', 'Count'];
|
const columns = ['Command name', 'Count'];
|
||||||
const includedCommands = client.commands.filter(x=>x.uses).sort((a,b)=>b.uses - a.uses);
|
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, 3, {longNames: true, commas: true})}**`);
|
if (includedCommands.size == 0) return interaction.reply(`No commands have been used yet.\nUptime: **${client.formatTime(client.uptime as number, 3, {longNames: true, commas: true})}**`);
|
||||||
const nameLength = Math.max(...includedCommands.map(x=>x.default.data.name.length), columns[0].length) + 2;
|
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.toString().length), columns[1].length) + 1;
|
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'];
|
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=>{
|
includedCommands.forEach(command=>{
|
||||||
const name = command.default.data.name;
|
const name = command.default.data.name;
|
||||||
const count = command.uses.toString();
|
const count = command.uses.toString();
|
||||||
rows.push(`${name + ' '.repeat(nameLength - name.length)}${' '.repeat(amountLength - count.length) + count}\n`);
|
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')
|
const embed = new client.embed().setColor(client.config.embedColor).setTitle('Statistics: Command Usage')
|
||||||
.setDescription([
|
.setDescription([
|
||||||
'List of commands that have been used in this session, ordered by amount of use. Table contains command name and amount of uses.',
|
'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)}`
|
`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'))
|
].join('\n'))
|
||||||
if (rows.join('').length > 1024){
|
if (rows.join('').length > 1024){
|
||||||
let fieldValue = '';
|
let fieldValue = '';
|
||||||
rows.forEach(row=>{
|
rows.forEach(row=>{
|
||||||
if (fieldValue.length + row.length > 1024){
|
if (fieldValue.length + row.length > 1024){
|
||||||
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
|
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
|
||||||
fieldValue = row;
|
fieldValue = row;
|
||||||
} else {
|
} else fieldValue += row
|
||||||
fieldValue += row;
|
});
|
||||||
}
|
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
|
||||||
});
|
} else embed.addFields({name: '\u200b', value: `\`\`\`\n${rows.join('')}\`\`\``});
|
||||||
embed.addFields({name: '\u200b', value: `\`\`\`\n${fieldValue}\`\`\``});
|
embed.addFields(
|
||||||
} else {
|
{name: '> __Dependencies__', value: [
|
||||||
embed.addFields({name: '\u200b', value: `\`\`\`\n${rows.join('')}\`\`\``})
|
`**TypeScript:** ${version}`,
|
||||||
};
|
`**NodeJS:** ${process.version}`,
|
||||||
embed.addFields(
|
`**DiscordJS:** ${DJSver}`,
|
||||||
{name: '> __Dependencies__', value: [
|
`**Axios:** ${client.axios.VERSION}`
|
||||||
`**TypeScript:** ${version}`,
|
].join('\n')},
|
||||||
`**NodeJS:** ${process.version}`,
|
{name: '> __Host__', value: [
|
||||||
`**DiscordJS:** ${DJSver}`,
|
`**Operating System:** ${osInfo.distro + ' ' + osInfo.release}`,
|
||||||
`**Axios:** ${client.axios.VERSION}`
|
`**CPU:** ${cpu.manufacturer} ${cpu.brand}`,
|
||||||
].join('\n')},
|
`**Memory:** ${formatBytes(ram.used)}/${formatBytes(ram.total)}`,
|
||||||
{name: '> __Host__', value: [
|
`**NodeJS:** ${formatBytes(process.memoryUsage().heapUsed)}/${formatBytes(process.memoryUsage().heapTotal)}`,
|
||||||
`**Operating System:** ${osInfo.distro + ' ' + osInfo.release}`,
|
`**Load Usage:**\nUser: ${currentLoad.currentLoadUser.toFixed(1)}%\nSystem: ${currentLoad.currentLoadSystem.toFixed(1)}%`,
|
||||||
`**CPU:** ${cpu.manufacturer} ${cpu.brand}`,
|
`**Uptime:**\nHost: ${client.formatTime((os.uptime()*1000), 2, {longNames: true, commas: true})}\nBot: ${client.formatTime(client.uptime as number, 2, {commas: true, longNames: true})}`
|
||||||
`**Memory:** ${formatBytes(ram.used)}/${formatBytes(ram.total)}`,
|
].join('\n')}
|
||||||
`**NodeJS:** ${formatBytes(process.memoryUsage().heapUsed)}/${formatBytes(process.memoryUsage().heapTotal)}`,
|
);
|
||||||
`**Load Usage:**\nUser: ${currentLoad.currentLoadUser.toFixed(1)}%\nSystem: ${currentLoad.currentLoadSystem.toFixed(1)}%`,
|
interaction.reply({embeds: [embed], fetchReply: true}).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})}`})]}))
|
||||||
`**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')} // Nice
|
data: new SlashCommandBuilder()// Nice
|
||||||
);
|
.setName('statistics')
|
||||||
interaction.reply({embeds: [embed], fetchReply: true}).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})}`})]}))
|
.setDescription('See a list of commands ordered by their usage or host stats')
|
||||||
},
|
|
||||||
data: new SlashCommandBuilder()
|
|
||||||
.setName('statistics')
|
|
||||||
.setDescription('See a list of commands ordered by their usage or host stats')
|
|
||||||
}
|
}
|
@ -56,7 +56,7 @@ export default {
|
|||||||
]});
|
]});
|
||||||
await client.suggestion._content.findByIdAndUpdate(suggestionIDReply, {state: 'Rejected'});
|
await client.suggestion._content.findByIdAndUpdate(suggestionIDReply, {state: 'Rejected'});
|
||||||
return interaction.reply({embeds:[new client.embed().setColor(client.config.embedColorRed).setTitle(`Suggestion rejected | ${suggestionIDReply}`).setDescription(stateChanged)]});
|
return interaction.reply({embeds:[new client.embed().setColor(client.config.embedColorRed).setTitle(`Suggestion rejected | ${suggestionIDReply}`).setDescription(stateChanged)]});
|
||||||
},
|
}
|
||||||
} as any)[interaction.options.getSubcommand()]();
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
client.punish(client, interaction, 'warn');
|
client.punish(client, interaction, 'warn');
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('warn')
|
.setName('warn')
|
||||||
.setDescription('Warn a member')
|
.setDescription('Warn a member')
|
||||||
.addUserOption((opt)=>opt
|
.addUserOption((opt)=>opt
|
||||||
.setName('member')
|
.setName('member')
|
||||||
.setDescription('Which member to warn?')
|
.setDescription('Which member to warn?')
|
||||||
.setRequired(true))
|
.setRequired(true))
|
||||||
.addStringOption((opt)=>opt
|
.addStringOption((opt)=>opt
|
||||||
.setName('reason')
|
.setName('reason')
|
||||||
.setDescription('Reason for the warning')
|
.setDescription('Reason for the warning')
|
||||||
.setRequired(false))
|
.setRequired(false))
|
||||||
}
|
}
|
@ -2,64 +2,59 @@ import Discord,{GuildMember, SlashCommandBuilder} from 'discord.js';
|
|||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
|
|
||||||
function convert(status?:Discord.ClientPresenceStatus){
|
function convert(status?:Discord.ClientPresenceStatus){
|
||||||
if (status){
|
if (status) return {
|
||||||
return {
|
idle: '🟡',
|
||||||
idle: '🟡',
|
dnd: '🔴',
|
||||||
dnd: '🔴',
|
online: '🟢'
|
||||||
online: '🟢'
|
}[status];
|
||||||
}[status];
|
else return '⚫'
|
||||||
} else {
|
|
||||||
return '⚫'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const member = interaction.options.getMember('member') as GuildMember;
|
const member = interaction.options.getMember('member') as GuildMember;
|
||||||
if (member == null){
|
if (member == null){
|
||||||
const user = interaction.options.getUser('member') as Discord.User;
|
const user = interaction.options.getUser('member') as Discord.User;
|
||||||
const embed = new client.embed()
|
const embed = new client.embed()
|
||||||
.setColor(client.config.embedColor)
|
.setColor(client.config.embedColor)
|
||||||
.setURL(`https://discord.com/users/${user.id}`)
|
.setURL(`https://discord.com/users/${user.id}`)
|
||||||
.setThumbnail(user.avatarURL({size:2048}) || user.defaultAvatarURL)
|
.setThumbnail(user.avatarURL({size:2048}) || user.defaultAvatarURL)
|
||||||
.setTitle(`${user.bot ? 'Bot': 'User'} Info: ${user.tag}`)
|
.setTitle(`${user.bot ? 'Bot': 'User'} Info: ${user.tag}`)
|
||||||
.setDescription(`<@${user.id}>\n\`${user.id}\``)
|
.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>`})
|
.addFields({name: '🔹 Account Creation Date', value: `<t:${Math.round(user.createdTimestamp/1000)}>\n<t:${Math.round(user.createdTimestamp/1000)}:R>`})
|
||||||
interaction.reply({embeds: [embed]})
|
interaction.reply({embeds: [embed]})
|
||||||
} else {
|
} else {
|
||||||
await member.user.fetch();
|
await member.user.fetch();
|
||||||
const presence = member.presence?.clientStatus as Discord.ClientPresenceStatusData;
|
const presence = member.presence?.clientStatus as Discord.ClientPresenceStatusData;
|
||||||
const embedArray = [];
|
const embedArray = [];
|
||||||
let title = 'Member';
|
let title = 'Member';
|
||||||
if (member.user.bot) {
|
if (member.user.bot) title = 'Bot';
|
||||||
title = 'Bot'
|
else if (member.user.id == interaction.guild.ownerId) title = ':crown: Server Owner';
|
||||||
} else if (member.user.id == interaction.guild.ownerId) {
|
|
||||||
title = ':crown: Server Owner'
|
const embed = new client.embed()
|
||||||
};
|
.setColor(member.displayColor || client.config.embedColor)
|
||||||
const embed = new client.embed()
|
.setURL(`https://discord.com/users/${member.user.id}`)
|
||||||
.setColor(member.displayColor || client.config.embedColor)
|
.setThumbnail(member.user.avatarURL({size:2048}) || member.user.defaultAvatarURL)
|
||||||
.setURL(`https://discord.com/users/${member.user.id}`)
|
.setImage(member.user.bannerURL({size:1024}) as string)
|
||||||
.setThumbnail(member.user.avatarURL({size:2048}) || member.user.defaultAvatarURL)
|
.setTitle(`${title} Info: ${member.user.tag}`)
|
||||||
.setImage(member.user.bannerURL({size:1024}) as string)
|
.setDescription(`<@${member.user.id}>\n\`${member.user.id}\``)
|
||||||
.setTitle(`${title} Info: ${member.user.tag}`)
|
.addFields(
|
||||||
.setDescription(`<@${member.user.id}>\n\`${member.user.id}\``)
|
{name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/1000)}:R>`},
|
||||||
.addFields(
|
{name: '🔹 Server Join Date', value: `<t:${Math.round((member.joinedTimestamp as number)/1000)}>\n<t:${Math.round((member.joinedTimestamp as number)/1000)}:R>`},
|
||||||
{name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/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'}
|
||||||
{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'}
|
if (member.premiumSinceTimestamp !== null) embed.addFields({name: '🔹 Server Boosting since', value: `<t:${Math.round(member.premiumSinceTimestamp/1000)}>\n<t:${Math.round(member.premiumSinceTimestamp/1000)}:R>`, inline: true})
|
||||||
)
|
if (!presence) embed.addFields({name: `🔹 Status: Unavailable to retrieve`, value: '\u200b'})
|
||||||
if (member.premiumSinceTimestamp !== null) embed.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) embed.addFields({name: `🔹 Status: ${member.presence.status}`, value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${convert(presence.desktop)}\nWeb: ${convert(presence.web)}\nMobile: ${convert(presence.mobile)}`}`, inline: true})
|
||||||
if (!presence) embed.addFields({name: `🔹 Status: Unavailable to retrieve`, value: '\u200b'})
|
embedArray.push(embed)
|
||||||
if (member.presence) embed.addFields({name: `🔹 Status: ${member.presence.status}`, value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${convert(presence.desktop)}\nWeb: ${convert(presence.web)}\nMobile: ${convert(presence.mobile)}`}`, inline: true})
|
interaction.reply({embeds: embedArray})
|
||||||
embedArray.push(embed)
|
}
|
||||||
interaction.reply({embeds: embedArray})
|
},
|
||||||
}
|
data: new SlashCommandBuilder()
|
||||||
},
|
.setName('whois')
|
||||||
data: new SlashCommandBuilder()
|
.setDescription('View your own or someone else\'s information')
|
||||||
.setName('whois')
|
.addUserOption((opt)=>opt
|
||||||
.setDescription('View your own or someone else\'s information')
|
.setName('member')
|
||||||
.addUserOption((opt)=>opt
|
.setDescription('Member or user to view their information')
|
||||||
.setName('member')
|
.setRequired(true))
|
||||||
.setDescription('Member or user to view their information')
|
|
||||||
.setRequired(true))
|
|
||||||
}
|
}
|
136
src/config.json
136
src/config.json
@ -1,73 +1,73 @@
|
|||||||
{
|
{
|
||||||
"embedColor": "#0052cf",
|
"embedColor": "#0052cf",
|
||||||
"embedColorBackup": "#0052cf",
|
"embedColorBackup": "#0052cf",
|
||||||
"embedColorGreen": "#57f287",
|
"embedColorGreen": "#57f287",
|
||||||
"embedColorYellow": "#ffea00",
|
"embedColorYellow": "#ffea00",
|
||||||
"embedColorRed": "#e62c3b",
|
"embedColorRed": "#e62c3b",
|
||||||
"embedColorBCA": "#ff69b4",
|
"embedColorBCA": "#ff69b4",
|
||||||
"embedColorXmas": "#FFFFFF",
|
"embedColorXmas": "#FFFFFF",
|
||||||
"LRSstart": 1661236321433,
|
"LRSstart": 1661236321433,
|
||||||
"whitelistedServers": [
|
"whitelistedServers": [
|
||||||
"929807948748832798", "468835415093411861", "1058183358267543552"
|
"929807948748832798", "468835415093411861", "1058183358267543552"
|
||||||
],
|
],
|
||||||
"botSwitches": {
|
"botSwitches": {
|
||||||
"registerCommands": true,
|
"registerCommands": true,
|
||||||
"commands": true,
|
"commands": true,
|
||||||
"logs": true,
|
"logs": true,
|
||||||
"automod": true,
|
"automod": true,
|
||||||
"mpstats": true,
|
"mpstats": true,
|
||||||
"autores": true
|
"autores": true
|
||||||
},
|
},
|
||||||
"botPresence": {
|
"botPresence": {
|
||||||
"activities": [
|
"activities": [
|
||||||
{"name": "the new SRP", "url": "https://www.youtube.com/watch?v=5BDEzgbJ7c0", "type": 1}
|
{"name": "the new SRP", "url": "https://www.youtube.com/watch?v=5BDEzgbJ7c0", "type": 1}
|
||||||
],
|
],
|
||||||
"status": "idle"
|
"status": "idle"
|
||||||
},
|
},
|
||||||
"eval": {
|
"eval": {
|
||||||
"allowed": true,
|
"allowed": true,
|
||||||
"whitelist": [
|
"whitelist": [
|
||||||
"190407856527376384",
|
"190407856527376384",
|
||||||
"615761944154210305",
|
"615761944154210305",
|
||||||
"593696856165449749",
|
"593696856165449749",
|
||||||
"633345781780185099",
|
"633345781780185099",
|
||||||
"506022868157595648",
|
"506022868157595648",
|
||||||
"215497515934416896",
|
"215497515934416896",
|
||||||
"309373272594579456"
|
"309373272594579456"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"mainServer": {
|
||||||
|
"id": "468835415093411861",
|
||||||
|
"staffRoles": [
|
||||||
|
"admin",
|
||||||
|
"dcmod",
|
||||||
|
"mpmanager",
|
||||||
|
"mpmod",
|
||||||
|
"vtcmanager",
|
||||||
|
"vtcstaff",
|
||||||
|
"ytmod"
|
||||||
|
],
|
||||||
|
"roles": {
|
||||||
|
"admin": "468842789053136897",
|
||||||
|
"bottech": "1011341005389307925",
|
||||||
|
"dcmod": "468841295150972929",
|
||||||
|
"mpmanager": "1028735939813585029",
|
||||||
|
"mpmod": "572151330710487041",
|
||||||
|
"vtcmanager": "1028735871370940490",
|
||||||
|
"vtcstaff": "801945627268481046",
|
||||||
|
"ytmod": "734888335851388958",
|
||||||
|
"mphelper": "1034453973412884500",
|
||||||
|
"mpplayer": "798285830669598762",
|
||||||
|
"vtcmember": "802282391652663338"
|
||||||
},
|
},
|
||||||
"mainServer": {
|
"channels": {
|
||||||
"id": "468835415093411861",
|
"console": "1011318687065710663",
|
||||||
"staffRoles": [
|
"errors": "1009754872188506192",
|
||||||
"admin",
|
"thismeanswar": "930588618085502987",
|
||||||
"dcmod",
|
"bot_status": "1009753780188884992",
|
||||||
"mpmanager",
|
"logs": "548032776830582794",
|
||||||
"mpmod",
|
"welcome": "621134751897616406",
|
||||||
"vtcmanager",
|
"botcommands": "468888722210029588"
|
||||||
"vtcstaff",
|
|
||||||
"ytmod"
|
|
||||||
],
|
|
||||||
"roles": {
|
|
||||||
"admin": "468842789053136897",
|
|
||||||
"bottech": "1011341005389307925",
|
|
||||||
"dcmod": "468841295150972929",
|
|
||||||
"mpmanager": "1028735939813585029",
|
|
||||||
"mpmod": "572151330710487041",
|
|
||||||
"vtcmanager": "1028735871370940490",
|
|
||||||
"vtcstaff": "801945627268481046",
|
|
||||||
"ytmod": "734888335851388958",
|
|
||||||
"mphelper": "1034453973412884500",
|
|
||||||
"mpplayer": "798285830669598762",
|
|
||||||
"vtcmember": "802282391652663338"
|
|
||||||
},
|
|
||||||
"channels": {
|
|
||||||
"console": "1011318687065710663",
|
|
||||||
"errors": "1009754872188506192",
|
|
||||||
"thismeanswar": "930588618085502987",
|
|
||||||
"bot_status": "1009753780188884992",
|
|
||||||
"logs": "548032776830582794",
|
|
||||||
"welcome": "621134751897616406",
|
|
||||||
"botcommands": "468888722210029588"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,26 +15,17 @@ export class Database {
|
|||||||
this._content = dataType === 'array' ? [] : {};
|
this._content = dataType === 'array' ? [] : {};
|
||||||
}
|
}
|
||||||
addData(data: any, data1?: any){
|
addData(data: any, data1?: any){
|
||||||
if (Array.isArray(this._content)){
|
if (Array.isArray(this._content)) this._content.push(data);
|
||||||
this._content.push(data);
|
else if (typeof this._content === 'object') this._content[data] = data1;
|
||||||
} else if (typeof this._content === 'object'){
|
|
||||||
this._content[data] = data1;
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
removeData(key: any, type: number, element: any){
|
removeData(key: any, type: number, element: any){
|
||||||
if (this._dataType === 'array'){
|
if (this._dataType === 'array'){
|
||||||
switch (type){
|
({
|
||||||
case 0:
|
0: ()=>this._content = this._content.filter((x:any)=>x!=key),
|
||||||
this._content = this._content.filter((x:any)=>x != key);
|
1: ()=>this._content = this._content.filter((x:any)=>x[element]!=key)
|
||||||
break;
|
})[type]()
|
||||||
case 1:
|
} else if (this._dataType === 'object') delete this._content[key];
|
||||||
this._content = this._content.filter((x:any)=>x[element] != key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (this._dataType === 'object'){
|
|
||||||
delete this._content[key];
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
initLoad(){
|
initLoad(){
|
||||||
@ -64,6 +55,4 @@ export class Database {
|
|||||||
console.log(this._path + ' "DB saved" Notifications disabled');
|
console.log(this._path + ' "DB saved" Notifications disabled');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // Nice.
|
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
import Discord, { AuditLogEvent } from 'discord.js';
|
import Discord, { AuditLogEvent } from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (member.guild?.id != client.config.mainServer.id) return;
|
if (member.guild?.id != client.config.mainServer.id) return;
|
||||||
const fetchBanlog = await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberBanAdd})
|
const fetchBanlog = await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberBanAdd})
|
||||||
const banLog = fetchBanlog.entries.first();
|
const banLog = fetchBanlog.entries.first();
|
||||||
if (!banLog) return console.log(`${member.user.tag} was banned from ${member.guild.name} but no audit log for this user.`)
|
if (!banLog) return console.log(`${member.user.tag} was banned from ${member.guild.name} but no audit log for this user.`)
|
||||||
const {executor, target, reason } = banLog;
|
const {executor, target, reason } = banLog;
|
||||||
if (target.id == member.user.id) {
|
if (target.id == member.user.id) (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
||||||
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
new client.embed().setColor(client.config.embedColorRed).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Banned: ${target.tag}`).setDescription(`🔹 **User**\n<@${target.id}>\n\`${target.id}\``).addFields(
|
||||||
new client.embed().setColor(client.config.embedColorRed).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Banned: ${target.tag}`).setDescription(`🔹 **User**\n<@${target.id}>\n\`${target.id}\``).addFields(
|
{name: '🔹 Moderator', value: `<@${executor.id}>\n\`${executor.id}\``},
|
||||||
{name: '🔹 Moderator', value: `<@${executor.id}>\n\`${executor.id}\``},
|
{name: '🔹 Reason', value: `${reason == null ? 'Reason unspecified': reason}`}
|
||||||
{name: '🔹 Reason', value: `${reason == null ? 'Reason unspecified': reason}`}
|
)]});
|
||||||
)]})
|
else console.log(`${target.tag} was banned from ${member.guild.name} but no audit log could be fetched.`)
|
||||||
} else {
|
}
|
||||||
console.log(`${target.tag} was banned from ${member.guild.name} but no audit log could be fetched.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
import Discord, { AuditLogEvent } from 'discord.js';
|
import Discord, { AuditLogEvent } from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (member.guild?.id != client.config.mainServer.id) return;
|
if (member.guild?.id != client.config.mainServer.id) return;
|
||||||
const fetchUnbanlog = await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberBanRemove})
|
const fetchUnbanlog = await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberBanRemove})
|
||||||
const unbanLog = fetchUnbanlog.entries.first();
|
const unbanLog = fetchUnbanlog.entries.first();
|
||||||
if (!unbanLog) return console.log(`${member.user.tag} was unbanned from ${member.guild.name} but no audit log for this user.`)
|
if (!unbanLog) return console.log(`${member.user.tag} was unbanned from ${member.guild.name} but no audit log for this user.`)
|
||||||
const { executor, target, reason } = unbanLog;
|
const { executor, target, reason } = unbanLog;
|
||||||
if (target.id == member.user.id) {
|
if (target.id == member.user.id) (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
||||||
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Unbanned: ${target.tag}`).setDescription(`🔹 **User**\n<@${target.id}>\n\`${target.id}\``).addFields(
|
||||||
new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`Member Unbanned: ${target.tag}`).setDescription(`🔹 **User**\n<@${target.id}>\n\`${target.id}\``).addFields(
|
{name: '🔹 Moderator', value: `<@${executor.id}>\n\`${executor.id}\``},
|
||||||
{name: '🔹 Moderator', value: `<@${executor.id}>\n\`${executor.id}\``},
|
{name: '🔹 Reason', value: `${reason == null ? 'Reason unspecified.': reason}`}
|
||||||
{name: '🔹 Reason', value: `${reason == null ? 'Reason unspecified.': reason}`}
|
)]});
|
||||||
)]})
|
else console.log(`${target.tag} was unbanned from ${member.guild.name} but no audit log could be fetched.`)
|
||||||
} else {
|
}
|
||||||
console.log(`${target.tag} was unbanned from ${member.guild.name} but no audit log could be fetched.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,29 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (member.partial || member.guild?.id != client.config.mainServer.id) return;
|
if (member.partial || member.guild?.id != client.config.mainServer.id) return;
|
||||||
const index = member.guild.memberCount;
|
const index = member.guild.memberCount;
|
||||||
const suffix = ((index)=>{
|
const suffix = ((index)=>{
|
||||||
const numbers = index.toString().split('').reverse(); // eg 1850 --> [0,5,8,1]
|
const numbers = index.toString().split('').reverse(); // eg 1850 --> [0,5,8,1]
|
||||||
if (numbers[1] === '1'){// this is some -teen
|
if (numbers[1] === '1') return 'th'; // this is some -teen
|
||||||
return 'th';
|
else {
|
||||||
} else {
|
if (numbers[0] === '1') return 'st';
|
||||||
if (numbers[0] === '1') return 'st';
|
else if (numbers[0] === '2') return 'nd';
|
||||||
else if (numbers[0] === '2') return 'nd';
|
else if (numbers[0] === '3') return 'rd';
|
||||||
else if (numbers[0] === '3') return 'rd';
|
else return 'th';
|
||||||
else return 'th';
|
|
||||||
}
|
|
||||||
})(index);
|
|
||||||
|
|
||||||
(client.channels.resolve(client.config.mainServer.channels.welcome) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setThumbnail(member.user.displayAvatarURL({size: 2048}) || member.user.defaultAvatarURL).setTitle(`Welcome to Daggerwin, ${member.user.tag}!`).setFooter({text: `${index}${suffix} member`})]})
|
|
||||||
if (!client.config.botSwitches.logs) return;
|
|
||||||
const newInvites = await member.guild.invites.fetch();
|
|
||||||
const usedInvite = newInvites.find((inv:any)=>client.invites.get(inv.code)?.uses < inv.uses);
|
|
||||||
newInvites.forEach((inv:any)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviter.id}));
|
|
||||||
|
|
||||||
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
|
||||||
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}**` : 'No invite data could be found.'}
|
|
||||||
)]})
|
|
||||||
}
|
}
|
||||||
|
})(index);
|
||||||
|
(client.channels.resolve(client.config.mainServer.channels.welcome) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColor).setThumbnail(member.user.displayAvatarURL({size: 2048}) || member.user.defaultAvatarURL).setTitle(`Welcome to Daggerwin, ${member.user.tag}!`).setFooter({text: `${index}${suffix} member`})]})
|
||||||
|
if (!client.config.botSwitches.logs) return;
|
||||||
|
const newInvites = await member.guild.invites.fetch();
|
||||||
|
const usedInvite = newInvites.find((inv:any)=>client.invites.get(inv.code)?.uses < inv.uses);
|
||||||
|
newInvites.forEach((inv:any)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviter.id}));
|
||||||
|
|
||||||
|
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
||||||
|
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}**` : 'No invite data could be found.'}
|
||||||
|
)]})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, member:Discord.GuildMember){
|
async run(client:TClient, member:Discord.GuildMember){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
if (!member.joinedTimestamp || member.guild?.id != client.config.mainServer.id) return;
|
if (!member.joinedTimestamp || member.guild?.id != client.config.mainServer.id) return;
|
||||||
const levelData = await client.userLevels._content.findById(member.id);
|
const levelData = await client.userLevels._content.findById(member.id);
|
||||||
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048}) as string).setTitle(`Member Left: ${member.user.tag}`).setDescription(`<@${member.user.id}>\n\`${member.user.id}\``).addFields(
|
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048}) as string).setTitle(`Member Left: ${member.user.tag}`).setDescription(`<@${member.user.id}>\n\`${member.user.id}\``).addFields(
|
||||||
{name: '🔹 Account Creation Date', value: `<t:${Math.round(member.user.createdTimestamp/1000)}>\n<t:${Math.round(member.user.createdTimestamp/1000)}:R>`},
|
{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/1000)}>\n<t:${Math.round(member.joinedTimestamp/1000)}:R>`},
|
{name: '🔹 Server Join Date', value: `<t:${Math.round(member.joinedTimestamp/1000)}>\n<t:${Math.round(member.joinedTimestamp/1000)}:R>`},
|
||||||
{name: `🔹 Roles: ${member.roles.cache.size - 1}`, value: `${member.roles.cache.size > 1 ? member.roles.cache.filter((x)=>x.id !== member.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'}`, inline: true}
|
{name: `🔹 Roles: ${member.roles.cache.size - 1}`, value: `${member.roles.cache.size > 1 ? member.roles.cache.filter((x)=>x.id !== member.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'}`, inline: true}
|
||||||
);
|
);
|
||||||
if (levelData && levelData.messages > 1) embed.addFields({name: '🔹 Total messages', value: levelData.messages.toLocaleString('en-US'), inline: true});
|
if (levelData && levelData.messages > 1) embed.addFields({name: '🔹 Total messages', value: levelData.messages.toLocaleString('en-US'), inline: true});
|
||||||
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds:[embed]});
|
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds:[embed]});
|
||||||
await client.userLevels._content.findByIdAndDelete(member.id)
|
await client.userLevels._content.findByIdAndDelete(member.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, oldMember:Discord.GuildMember, newMember:Discord.GuildMember){
|
run(client:TClient, oldMember:Discord.GuildMember, newMember:Discord.GuildMember){
|
||||||
if (oldMember.guild.id != client.config.mainServer.id) return;
|
if (oldMember.guild.id != client.config.mainServer.id) return;
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
const channel = (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel)
|
const channel = (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel)
|
||||||
if (oldMember.nickname != newMember.nickname){
|
if (oldMember.nickname != newMember.nickname){
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setThumbnail(newMember.user.displayAvatarURL({size: 2048})).setTitle(`Nickname updated: ${newMember.user.tag}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``)
|
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp().setThumbnail(newMember.user.displayAvatarURL({size: 2048})).setTitle(`Nickname updated: ${newMember.user.tag}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``)
|
||||||
oldMember.nickname == null ? '' : embed.addFields({name: '🔹 Old nickname', value: `\`\`\`${oldMember.nickname}\`\`\``})
|
oldMember.nickname == null ? '' : embed.addFields({name: '🔹 Old nickname', value: `\`\`\`${oldMember.nickname}\`\`\``})
|
||||||
newMember.nickname == null ? '' : embed.addFields({name: '🔹 New nickname', value: `\`\`\`${newMember.nickname}\`\`\``})
|
newMember.nickname == null ? '' : embed.addFields({name: '🔹 New nickname', value: `\`\`\`${newMember.nickname}\`\`\``})
|
||||||
channel.send({embeds: [embed]})
|
channel.send({embeds: [embed]})
|
||||||
}
|
|
||||||
|
|
||||||
const newRoles = newMember.roles.cache.map((x,i)=>i).filter(x=>!oldMember.roles.cache.map((x,i)=>i).some(y=>y==x));
|
|
||||||
const oldRoles = oldMember.roles.cache.map((x,i)=>i).filter(x=>!newMember.roles.cache.map((x,i)=>i).some(y=>y==x));
|
|
||||||
if (newRoles.length == 0 && oldRoles.length == 0) return;
|
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setThumbnail(newMember.user.displayAvatarURL({size: 2048})).setTitle(`Role updated: ${newMember.user.tag}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``)
|
|
||||||
if (newRoles.length != 0) embed.addFields({name: '🔹 Role added', value: newRoles.map((x)=>`<@&${x}>`).join(' ')});
|
|
||||||
if (oldRoles.length != 0) embed.addFields({name: '🔹 Role removed', value: oldRoles.map((x)=>`<@&${x}>`).join(' ')});
|
|
||||||
channel.send({embeds: [embed]})
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
const newRoles = newMember.roles.cache.map((x,i)=>i).filter(x=>!oldMember.roles.cache.map((x,i)=>i).some(y=>y==x));
|
||||||
|
const oldRoles = oldMember.roles.cache.map((x,i)=>i).filter(x=>!newMember.roles.cache.map((x,i)=>i).some(y=>y==x));
|
||||||
|
if (newRoles.length == 0 && oldRoles.length == 0) return;
|
||||||
|
const embed = new client.embed().setColor(client.config.embedColor).setThumbnail(newMember.user.displayAvatarURL({size: 2048})).setTitle(`Role updated: ${newMember.user.tag}`).setDescription(`<@${newMember.user.id}>\n\`${newMember.user.id}\``)
|
||||||
|
if (newRoles.length != 0) embed.addFields({name: '🔹 Role added', value: newRoles.map((x)=>`<@&${x}>`).join(' ')});
|
||||||
|
if (oldRoles.length != 0) embed.addFields({name: '🔹 Role removed', value: oldRoles.map((x)=>`<@&${x}>`).join(' ')});
|
||||||
|
channel.send({embeds: [embed]})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, interaction:Discord.BaseInteraction){
|
run(client:TClient, interaction:Discord.BaseInteraction){
|
||||||
if (!interaction.inGuild() || !interaction.inCachedGuild()) return;
|
if (!interaction.inGuild() || !interaction.inCachedGuild()) return;
|
||||||
if (interaction.isChatInputCommand()){
|
if (interaction.isChatInputCommand()){
|
||||||
const commandFile = client.commands.get(interaction.commandName);
|
const commandFile = client.commands.get(interaction.commandName);
|
||||||
@ -9,13 +9,13 @@ export default {
|
|||||||
if (!client.config.botSwitches.commands && !client.config.eval.whitelist.includes(interaction.user.id)) return interaction.reply({content: 'Bot is currently being run in development mode.', ephemeral: true});
|
if (!client.config.botSwitches.commands && !client.config.eval.whitelist.includes(interaction.user.id)) return interaction.reply({content: 'Bot is currently being run in development mode.', ephemeral: true});
|
||||||
if (commandFile){
|
if (commandFile){
|
||||||
try{
|
try{
|
||||||
commandFile.default.run(client, interaction);
|
commandFile.default.run(client, interaction);
|
||||||
commandFile.uses ? commandFile.uses++ : commandFile.uses = 1;
|
commandFile.uses ? commandFile.uses++ : commandFile.uses = 1;
|
||||||
} catch (error){
|
} catch (error){
|
||||||
console.log(`An error occured while running command "${commandFile.name}"`, error, error.stack);
|
console.log(`An error occured while running command "${commandFile.name}"`, error, error.stack);
|
||||||
return interaction.reply('An error occured while executing that command.');
|
return interaction.reply('An error occured while executing that command.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, invite: Discord.Invite){
|
async run(client:TClient, invite: Discord.Invite){
|
||||||
if (!invite.guild) return;
|
if (!invite.guild) return;
|
||||||
const newInvites = await (invite.guild as Discord.Guild).invites.fetch();
|
const newInvites = await (invite.guild as Discord.Guild).invites.fetch();
|
||||||
newInvites.forEach(inv=>client.invites.set(inv.code,{uses: inv.code, creator: inv.inviterId}))
|
newInvites.forEach(inv=>client.invites.set(inv.code,{uses: inv.code, creator: inv.inviterId}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, invite: Discord.Invite){
|
run(client:TClient, invite: Discord.Invite){
|
||||||
client.invites.delete(invite.code)
|
client.invites.delete(invite.code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,131 +1,130 @@
|
|||||||
import Discord, { ChannelType } from 'discord.js';
|
import Discord, { ChannelType } from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, message:Discord.Message){
|
async run(client:TClient, message:Discord.Message){
|
||||||
if (message.author.bot || message.channel.type === ChannelType.DM) return;
|
if (message.author.bot || message.channel.type === ChannelType.DM) return;
|
||||||
const msgarr = message.content.toLowerCase().split(' ');
|
const msgarr = message.content.toLowerCase().split(' ');
|
||||||
let automodded: boolean;
|
let automodded: boolean;
|
||||||
|
|
||||||
function onTimeout(){
|
function onTimeout(){
|
||||||
delete client.repeatedMessages[message.author.id]
|
delete client.repeatedMessages[message.author.id]
|
||||||
}
|
|
||||||
|
|
||||||
const Whitelist = [
|
|
||||||
// Arrary of channel ids for automod to be disabled in
|
|
||||||
]
|
|
||||||
|
|
||||||
if (await client.bannedWords._content.findOne({_id:msgarr}) && !message.member.roles.cache.has(client.config.mainServer.roles.dcmod) && message.guildId == client.config.mainServer.id && !Whitelist.includes(message.channelId) && client.config.botSwitches.automod){
|
|
||||||
automodded = true;
|
|
||||||
const threshold = 30000;
|
|
||||||
message.delete().catch(err=>console.log('bannedWords automod; msg got possibly deleted by another bot.'))
|
|
||||||
message.channel.send('That word is banned here.').then((x)=>setTimeout(()=>x.delete(), 10000));
|
|
||||||
if (client.repeatedMessages[message.author.id]){
|
|
||||||
// add this message to the list
|
|
||||||
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp, {cont: 0, ch: message.channelId});
|
|
||||||
|
|
||||||
// reset timeout
|
|
||||||
clearTimeout(client.repeatedMessages[message.author.id].timeout);
|
|
||||||
client.repeatedMessages[message.author.id].timeout = setTimeout(onTimeout, threshold);
|
|
||||||
|
|
||||||
// message mustve been sent after (now - threshold), so purge those that were sent earlier
|
|
||||||
client.repeatedMessages[message.author.id].data = client.repeatedMessages[message.author.id].data.filter((x, i)=>i >= Date.now() - threshold)
|
|
||||||
|
|
||||||
// a spammed message is one that has been sent atleast 4 times in the last threshold milliseconds
|
|
||||||
const spammedMessage = client.repeatedMessages[message.author.id]?.data.find((x)=>{
|
|
||||||
return client.repeatedMessages[message.author.id].data.size >= 4;
|
|
||||||
});
|
|
||||||
|
|
||||||
// if a spammed message exists;
|
|
||||||
if (spammedMessage){
|
|
||||||
delete client.repeatedMessages[message.author.id];
|
|
||||||
await client.punishments.addPunishment('mute', { time: '30m' }, (client.user as Discord.User).id, 'Automod; Banned words', message.author, message.member as Discord.GuildMember);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
client.repeatedMessages[message.author.id] = { data: new client.collection(), timeout: setTimeout(onTimeout, threshold) };
|
|
||||||
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp, {cont: 0, ch: message.channelId});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (message.content.toLowerCase().includes('discord.gg/') && !message.member.roles.cache.has(client.config.mainServer.roles.dcmod) && message.guildId == client.config.mainServer.id && !Whitelist.includes(message.channelId)) {
|
|
||||||
automodded = true;
|
|
||||||
const threshold = 60000;
|
|
||||||
message.delete().catch(err=>console.log('advertisement automod; msg got possibly deleted by another bot.'))
|
|
||||||
message.channel.send('Advertising other Discord servers is not allowed.').then(x=>setTimeout(()=>x.delete(), 15000))
|
|
||||||
if (client.repeatedMessages[message.author.id]){
|
|
||||||
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp,{cont:1,ch:message.channelId});
|
|
||||||
|
|
||||||
clearTimeout(client.repeatedMessages[message.author.id].timeout);
|
|
||||||
client.repeatedMessages[message.author.id].timeout = setTimeout(onTimeout, threshold);
|
|
||||||
client.repeatedMessages[message.author.id].data = client.repeatedMessages[message.author.id].data.filter((x, i)=> i >= Date.now() - threshold)
|
|
||||||
const spammedMessage = client.repeatedMessages[message.author.id].data.find((x)=>{
|
|
||||||
return client.repeatedMessages[message.author.id].data.filter((y)=>x.cont === y.cont).size >= 4;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (spammedMessage){
|
|
||||||
delete client.repeatedMessages[message.author.id];
|
|
||||||
await client.punishments.addPunishment('mute', {time: '1h'}, (client.user as Discord.User).id, 'Automod; Discord advertisement', message.author, message.member as Discord.GuildMember);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
client.repeatedMessages[message.author.id] = { data: new client.collection(), timeout: setTimeout(onTimeout, threshold) };
|
|
||||||
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp, {cont: 1, ch: message.channelId});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.guildId == client.config.mainServer.id && !automodded) client.userLevels.incrementUser(message.author.id)
|
|
||||||
// Mop gifs from banned channels without Monster having to mop them.
|
|
||||||
const bannedChannels = [
|
|
||||||
'516344221452599306', // #mp-moderators
|
|
||||||
'742324777934520350', // #discord-moderators
|
|
||||||
]
|
|
||||||
const gifURL = ['tenor.com/view', 'giphy.com/gifs', 'giphy.com/media']
|
|
||||||
if (gifURL.some(e=>message.content.toLowerCase().includes(e)) && bannedChannels.includes(message.channelId)) message.reply('Gifs are not allowed in this channel.').then((msg)=>message.delete())
|
|
||||||
|
|
||||||
// Autoresponse:tm:
|
|
||||||
if (client.config.botSwitches.autores && !automodded) {
|
|
||||||
const MorningArray = ['good morning all', 'good morning everyone', 'morning all', 'morning everyone', 'morning lads', 'morning guys', 'good morning everybody']
|
|
||||||
const AfternoonArray = ['good afternoon', 'afternoon all', 'afternoon everyone']
|
|
||||||
const EveningArray = ['good evening', 'evening all', 'evening everyone']
|
|
||||||
const NightArray = ['night all', 'night everyone', 'night guys']
|
|
||||||
const PasswordArray = ['whats the password', 'what\'s the password', 'password pls']
|
|
||||||
const cantRead = ['i cant read', 'i can\'t read', 'cant read', 'can\'t read']
|
|
||||||
const NawdicBrokeIt = ['break', 'broke', 'broken']
|
|
||||||
const deadChat = ['dead chat', 'chat is dead', 'dead server']
|
|
||||||
|
|
||||||
const PersonnyMcPerson = `**${message.member.displayName}**`;
|
|
||||||
const GeneralChatID = '468835415093411863';
|
|
||||||
const MorningPhrases = [
|
|
||||||
`Morning ${PersonnyMcPerson}, did you sleep great?`, `Good morning ${PersonnyMcPerson}!`, `Hope you enjoyed your breakfast, ${PersonnyMcPerson}!`,
|
|
||||||
`Gm ${PersonnyMcPerson}`, `Uh.. What time is it? Oh yea, morning ${PersonnyMcPerson}`, `Morning and hope you had a good dream last night, ${PersonnyMcPerson}`,
|
|
||||||
'Time to get started with today\'s stuff!', `Don't forget to do your morning routine, ${PersonnyMcPerson}!`, 'Enjoy the breakfast and start your day.',
|
|
||||||
'Nuh! No morning message for you!\n*Just kidding, good morning!*'
|
|
||||||
]
|
|
||||||
const AfternoonPhrases = [
|
|
||||||
`Afternoon ${PersonnyMcPerson}!`, `What a nice day outside, ${PersonnyMcPerson}`, `Good afternoon ${PersonnyMcPerson}`,
|
|
||||||
'Hope you had a good day so far.', `Did you enjoy your day yet, ${PersonnyMcPerson}?`, 'Weather doesn\'t look too bad outside right?',
|
|
||||||
`How's the trip outside, ${PersonnyMcPerson}?`, `~~Morning~~ Afternoon ${PersonnyMcPerson}!`
|
|
||||||
]
|
|
||||||
const EveningPhrases = [
|
|
||||||
'I can\'t believe the time flies so quickly!', `Evening ${PersonnyMcPerson}!`, `Hope you enjoyed the dinner, ${PersonnyMcPerson}!`,
|
|
||||||
`Good evening ${PersonnyMcPerson}!`, 'You look tired, ready to go to sleep yet?', 'Being outside was an exhausting task isn\'t it?',
|
|
||||||
'Did you have a good day so far?', 'May I suggest sleep?', `You heard me! ${PersonnyMcPerson}, it's almost dinner time!`
|
|
||||||
]
|
|
||||||
const NightPhrases = [
|
|
||||||
`Good night ${PersonnyMcPerson}!`, `Night ${PersonnyMcPerson}!`, `Sweet dreams, ${PersonnyMcPerson}.`, `Don't fall out of sky in your dreamworld, ${PersonnyMcPerson}!`,
|
|
||||||
'Nighty night!', `I hope tomorrow is a good day for you, ${PersonnyMcPerson}!`, `Have a good sleep, ${PersonnyMcPerson}!`, `I :b:et you a cookie if you actually slept through the night! ${PersonnyMcPerson}`
|
|
||||||
]
|
|
||||||
|
|
||||||
if (message.mentions.members.has('309373272594579456') && !client.isStaff(message.member)) 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 (PasswordArray.some(e=>msgarr.includes(e))) message.reply('Password and other details can be found in <#543494084363288637>');
|
|
||||||
if (cantRead.some(e=>msgarr.includes(e))) message.reply('https://tenor.com/view/aristocats-george-pen-cap-meticulous-gif-5330931');
|
|
||||||
if (msgarr.includes('is daggerbot working')) message.reply('https://tenor.com/view/i-still-feel-alive-living-existing-active-singing-gif-14630579');
|
|
||||||
if (deadChat.some(e=>msgarr.includes(e))) message.reply('https://cdn.discordapp.com/attachments/925589318276382720/1011333656167579849/F57G5ZS.png');
|
|
||||||
if (msgarr.includes('nawdic') && NawdicBrokeIt.some(e=>msgarr.includes(e)) && message.channelId !== '516344221452599306') message.reply({embeds: [new client.embed().setTitle('*Nawdic has done an oopsie*').setImage('https://c.tenor.com/JSj9ie_MD9kAAAAC/kopfsch%C3%BCtteln-an-kopf-fassen-oh-no.gif').setColor(client.config.embedColor)]});
|
|
||||||
if (MorningArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${MorningPhrases[Math.floor(Math.random()*MorningPhrases.length)]}`);
|
|
||||||
if (AfternoonArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${AfternoonPhrases[Math.floor(Math.random()*AfternoonPhrases.length)]}`);
|
|
||||||
if (EveningArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${EveningPhrases[Math.floor(Math.random()*EveningPhrases.length)]}`);
|
|
||||||
if (NightArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${NightPhrases[Math.floor(Math.random()*NightPhrases.length)]}`);
|
|
||||||
// Failsafe thingy (Toastproof maybe)
|
|
||||||
if (message.content.startsWith('!!_wepanikfrfr') && client.config.eval.whitelist.includes(message.author.id)) (client.guilds.cache.get(message.guildId) as Discord.Guild).commands.set(client.registry).then(()=>message.reply('How did you manage to lose the commands??? Anyways, it\'s re-registered now.')).catch((e:Error)=>message.reply(`Failed to deploy slash commands:\n\`\`\`${e.message}\`\`\``));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Whitelist = [] // Array of channel ids for automod to be disabled in (Disables bannedWords and advertisement, mind you.)
|
||||||
|
|
||||||
|
if (await client.bannedWords._content.findOne({_id:msgarr}) && !message.member.roles.cache.has(client.config.mainServer.roles.dcmod) && message.guildId == client.config.mainServer.id && !Whitelist.includes(message.channelId) && client.config.botSwitches.automod){
|
||||||
|
automodded = true;
|
||||||
|
const threshold = 30000;
|
||||||
|
message.delete().catch(err=>console.log('bannedWords automod; msg got possibly deleted by another bot.'))
|
||||||
|
message.channel.send('That word is banned here.').then((x)=>setTimeout(()=>x.delete(), 10000));
|
||||||
|
if (client.repeatedMessages[message.author.id]){
|
||||||
|
// add this message to the list
|
||||||
|
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp, {cont: 0, ch: message.channelId});
|
||||||
|
|
||||||
|
// reset timeout
|
||||||
|
clearTimeout(client.repeatedMessages[message.author.id].timeout);
|
||||||
|
client.repeatedMessages[message.author.id].timeout = setTimeout(onTimeout, threshold);
|
||||||
|
|
||||||
|
// message mustve been sent after (now - threshold), so purge those that were sent earlier
|
||||||
|
client.repeatedMessages[message.author.id].data = client.repeatedMessages[message.author.id].data.filter((x, i)=>i >= Date.now() - threshold)
|
||||||
|
|
||||||
|
// a spammed message is one that has been sent atleast 4 times in the last threshold milliseconds
|
||||||
|
const spammedMessage = client.repeatedMessages[message.author.id]?.data.find((x)=>{
|
||||||
|
return client.repeatedMessages[message.author.id].data.size >= 4;
|
||||||
|
});
|
||||||
|
|
||||||
|
// if a spammed message exists;
|
||||||
|
if (spammedMessage){
|
||||||
|
delete client.repeatedMessages[message.author.id];
|
||||||
|
await client.punishments.addPunishment('mute', { time: '30m' }, (client.user as Discord.User).id, 'Automod; Banned words', message.author, message.member as Discord.GuildMember);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
client.repeatedMessages[message.author.id] = { data: new client.collection(), timeout: setTimeout(onTimeout, threshold) };
|
||||||
|
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp, {cont: 0, ch: message.channelId});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.content.toLowerCase().includes('discord.gg/') && !message.member.roles.cache.has(client.config.mainServer.roles.dcmod) && message.guildId == client.config.mainServer.id && !Whitelist.includes(message.channelId)) {
|
||||||
|
automodded = true;
|
||||||
|
const threshold = 60000;
|
||||||
|
message.delete().catch(err=>console.log('advertisement automod; msg got possibly deleted by another bot.'))
|
||||||
|
message.channel.send('Advertising other Discord servers is not allowed.').then(x=>setTimeout(()=>x.delete(), 15000))
|
||||||
|
if (client.repeatedMessages[message.author.id]){
|
||||||
|
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp,{cont:1,ch:message.channelId});
|
||||||
|
|
||||||
|
clearTimeout(client.repeatedMessages[message.author.id].timeout);
|
||||||
|
client.repeatedMessages[message.author.id].timeout = setTimeout(onTimeout, threshold);
|
||||||
|
client.repeatedMessages[message.author.id].data = client.repeatedMessages[message.author.id].data.filter((x, i)=> i >= Date.now() - threshold)
|
||||||
|
const spammedMessage = client.repeatedMessages[message.author.id].data.find((x)=>{
|
||||||
|
return client.repeatedMessages[message.author.id].data.filter((y)=>x.cont === y.cont).size >= 4;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (spammedMessage){
|
||||||
|
delete client.repeatedMessages[message.author.id];
|
||||||
|
await client.punishments.addPunishment('mute', {time: '1h'}, (client.user as Discord.User).id, 'Automod; Discord advertisement', message.author, message.member as Discord.GuildMember);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
client.repeatedMessages[message.author.id] = { data: new client.collection(), timeout: setTimeout(onTimeout, threshold) };
|
||||||
|
client.repeatedMessages[message.author.id].data.set(message.createdTimestamp, {cont: 1, ch: message.channelId});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.guildId == client.config.mainServer.id && !automodded) client.userLevels.incrementUser(message.author.id)
|
||||||
|
// Mop gifs from banned channels without Monster having to mop them.
|
||||||
|
const bannedChannels = [
|
||||||
|
'516344221452599306', // #mp-moderators
|
||||||
|
'742324777934520350', // #discord-moderators
|
||||||
|
]
|
||||||
|
const gifURL = ['tenor.com/view', 'giphy.com/gifs', 'giphy.com/media']
|
||||||
|
if (gifURL.some(e=>message.content.toLowerCase().includes(e)) && bannedChannels.includes(message.channelId)) message.reply('Gifs are not allowed in this channel.').then((msg)=>message.delete())
|
||||||
|
|
||||||
|
// Autoresponse:tm:
|
||||||
|
if (client.config.botSwitches.autores && !automodded) {
|
||||||
|
const MorningArray = ['good morning all', 'good morning everyone', 'morning all', 'morning everyone', 'morning lads', 'morning guys', 'good morning everybody']
|
||||||
|
const AfternoonArray = ['good afternoon', 'afternoon all', 'afternoon everyone']
|
||||||
|
const EveningArray = ['good evening', 'evening all', 'evening everyone']
|
||||||
|
const NightArray = ['night all', 'night everyone', 'night guys']
|
||||||
|
const PasswordArray = ['whats the password', 'what\'s the password', 'password pls']
|
||||||
|
const cantRead = ['i cant read', 'i can\'t read', 'cant read', 'can\'t read']
|
||||||
|
const NawdicBrokeIt = ['break', 'broke', 'broken']
|
||||||
|
const deadChat = ['dead chat', 'chat is dead', 'dead server']
|
||||||
|
|
||||||
|
const PersonnyMcPerson = `**${message.member.displayName}**`;
|
||||||
|
const GeneralChatID = '468835415093411863';
|
||||||
|
const MorningPhrases = [
|
||||||
|
`Morning ${PersonnyMcPerson}, did you sleep great?`, `Good morning ${PersonnyMcPerson}!`, `Hope you enjoyed your breakfast, ${PersonnyMcPerson}!`,
|
||||||
|
`Gm ${PersonnyMcPerson}`, `Uh.. What time is it? Oh yea, morning ${PersonnyMcPerson}`, `Morning and hope you had a good dream last night, ${PersonnyMcPerson}`,
|
||||||
|
'Time to get started with today\'s stuff!', `Don't forget to do your morning routine, ${PersonnyMcPerson}!`, 'Enjoy the breakfast and start your day.',
|
||||||
|
'Nuh! No morning message for you!\n*Just kidding, good morning!*'
|
||||||
|
]
|
||||||
|
const AfternoonPhrases = [
|
||||||
|
`Afternoon ${PersonnyMcPerson}!`, `What a nice day outside, ${PersonnyMcPerson}`, `Good afternoon ${PersonnyMcPerson}`,
|
||||||
|
'Hope you had a good day so far.', `Did you enjoy your day yet, ${PersonnyMcPerson}?`, 'Weather doesn\'t look too bad outside right?',
|
||||||
|
`How's the trip outside, ${PersonnyMcPerson}?`, `~~Morning~~ Afternoon ${PersonnyMcPerson}!`
|
||||||
|
]
|
||||||
|
const EveningPhrases = [
|
||||||
|
'I can\'t believe the time flies so quickly!', `Evening ${PersonnyMcPerson}!`, `Hope you enjoyed the dinner, ${PersonnyMcPerson}!`,
|
||||||
|
`Good evening ${PersonnyMcPerson}!`, 'You look tired, ready to go to sleep yet?', 'Being outside was an exhausting task isn\'t it?',
|
||||||
|
'Did you have a good day so far?', 'May I suggest sleep?', `You heard me! ${PersonnyMcPerson}, it's almost dinner time!`
|
||||||
|
]
|
||||||
|
const NightPhrases = [
|
||||||
|
`Good night ${PersonnyMcPerson}!`, `Night ${PersonnyMcPerson}!`, `Sweet dreams, ${PersonnyMcPerson}.`, `Don't fall out of sky in your dreamworld, ${PersonnyMcPerson}!`,
|
||||||
|
'Nighty night!', `I hope tomorrow is a good day for you, ${PersonnyMcPerson}!`, `Have a good sleep, ${PersonnyMcPerson}!`, `I :b:et you a cookie if you actually slept through the night! ${PersonnyMcPerson}`
|
||||||
|
]
|
||||||
|
|
||||||
|
if (message.mentions.members.has('309373272594579456') && !client.isStaff(message.member)) 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 (PasswordArray.some(e=>msgarr.includes(e))) message.reply('Password and other details can be found in <#543494084363288637>');
|
||||||
|
if (cantRead.some(e=>msgarr.includes(e))) message.reply('https://tenor.com/view/aristocats-george-pen-cap-meticulous-gif-5330931');
|
||||||
|
if (msgarr.includes('is daggerbot working')) message.reply('https://tenor.com/view/i-still-feel-alive-living-existing-active-singing-gif-14630579');
|
||||||
|
if (deadChat.some(e=>msgarr.includes(e))) message.reply('https://cdn.discordapp.com/attachments/925589318276382720/1011333656167579849/F57G5ZS.png');
|
||||||
|
if (msgarr.includes('nawdic') && NawdicBrokeIt.some(e=>msgarr.includes(e)) && message.channelId !== '516344221452599306') message.reply({embeds: [new client.embed().setTitle('*Nawdic has done an oopsie*').setImage('https://c.tenor.com/JSj9ie_MD9kAAAAC/kopfsch%C3%BCtteln-an-kopf-fassen-oh-no.gif').setColor(client.config.embedColor)]});
|
||||||
|
if (MorningArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${MorningPhrases[Math.floor(Math.random()*MorningPhrases.length)]}`);
|
||||||
|
if (AfternoonArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${AfternoonPhrases[Math.floor(Math.random()*AfternoonPhrases.length)]}`);
|
||||||
|
if (EveningArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${EveningPhrases[Math.floor(Math.random()*EveningPhrases.length)]}`);
|
||||||
|
if (NightArray.some(e=>message.content.toLowerCase().startsWith(e)) && message.channelId == GeneralChatID && message.type == 0) message.reply(`${NightPhrases[Math.floor(Math.random()*NightPhrases.length)]}`);
|
||||||
|
// Failsafe thingy (Toastproof maybe)
|
||||||
|
if (message.content.startsWith('!!_wepanikfrfr') && client.config.eval.whitelist.includes(message.author.id)) (client.guilds.cache.get(message.guildId) as Discord.Guild).commands.set(client.registry).then(()=>message.reply('How did you manage to lose the commands??? Anyways, it\'s re-registered now.')).catch((e:Error)=>message.reply(`Failed to deploy slash commands:\n\`\`\`${e.message}\`\`\``));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, msg:Discord.Message){
|
run(client:TClient, msg:Discord.Message){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
||||||
const disabledChannels = ['548032776830582794', '541677709487505408']
|
const disabledChannels = [ '548032776830582794', '541677709487505408']
|
||||||
if (msg.guild?.id != client.config.mainServer.id || msg.partial || msg.author.bot || disabledChannels.includes(msg.channelId)) return;
|
if (msg.guild?.id != client.config.mainServer.id || msg.partial || msg.author.bot || disabledChannels.includes(msg.channelId)) return;
|
||||||
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.tag} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\n\`${msg.author.id}\``);
|
const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.tag} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\n\`${msg.author.id}\``);
|
||||||
if (msg.content.length != 0) embed.addFields({name: 'Content', value: `\`\`\`\n${msg.content.slice(0,1000)}\n\`\`\``});
|
if (msg.content.length != 0) embed.addFields({name: 'Content', value: `\`\`\`\n${msg.content.slice(0,1000)}\n\`\`\``});
|
||||||
embed.addFields(
|
embed.addFields(
|
||||||
{ name: 'Channel', value: `<#${msg.channelId}>` },
|
{ name: 'Channel', value: `<#${msg.channelId}>` },
|
||||||
{ name: 'Sent at', value: `<t:${Math.round(msg.createdTimestamp/1000)}>\n<t:${Math.round(msg.createdTimestamp/1000)}:R>` }
|
{ name: 'Sent at', value: `<t:${Math.round(msg.createdTimestamp/1000)}>\n<t:${Math.round(msg.createdTimestamp/1000)}:R>` }
|
||||||
)
|
)
|
||||||
const attachments: Array<string> = [];
|
const attachments: Array<string> = [];
|
||||||
msg.attachments.forEach((x) => attachments.push(x.url));
|
msg.attachments.forEach((x) => attachments.push(x.url));
|
||||||
channel.send({embeds: [embed], files: attachments})
|
channel.send({embeds: [embed], files: attachments})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, messages:Discord.Collection<string, Discord.Message<boolean>>){
|
run(client:TClient, messages:Discord.Collection<string, Discord.Message<boolean>>){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
if (client.config.mainServer.id != '468835415093411861') return;
|
if (client.config.mainServer.id != '468835415093411861') return;
|
||||||
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel;
|
||||||
channel.send({embeds: [new client.embed().setColor(client.config.embedColorRed).setTimestamp().setTitle(`${messages.size} messages were purged`).setDescription(`\`\`\`${messages.map((msgs)=>`${msgs.member?.displayName}: ${msgs.content}`).reverse().join('\n').slice(0,3900)}\`\`\``).addFields({name: 'Channel', value: `<#${messages.first().channel.id}>`})]})
|
channel.send({embeds: [new client.embed().setColor(client.config.embedColorRed).setTimestamp().setTitle(`${messages.size} messages were purged`)
|
||||||
}
|
.setDescription(`\`\`\`${messages.map((msgs)=>`${msgs.member?.displayName}: ${msgs.content}`).reverse().join('\n').slice(0,3900)}\`\`\``).addFields(
|
||||||
}
|
{name: 'Channel', value: `<#${messages.first().channel.id}>`}
|
||||||
|
)]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import Discord, { ActionRowBuilder, ButtonBuilder } from 'discord.js';
|
import Discord, { ActionRowBuilder, ButtonBuilder } from 'discord.js';
|
||||||
import TClient from '../client';
|
import TClient from '../client';
|
||||||
export default {
|
export default {
|
||||||
async run(client:TClient, oldMsg:Discord.Message, newMsg:Discord.Message){
|
async run(client:TClient, oldMsg:Discord.Message, newMsg:Discord.Message){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs) return;
|
||||||
const disabledChannels = ['548032776830582794', '541677709487505408']
|
const disabledChannels = ['548032776830582794', '541677709487505408']
|
||||||
if (oldMsg.guild?.id != client.config.mainServer.id || oldMsg.author == null || oldMsg?.author.bot || oldMsg.partial || newMsg.partial || !newMsg.member || disabledChannels.includes(newMsg.channelId)) return;
|
if (oldMsg.guild?.id != client.config.mainServer.id || oldMsg.author == null || oldMsg?.author.bot || oldMsg.partial || newMsg.partial || !newMsg.member || disabledChannels.includes(newMsg.channelId)) return;
|
||||||
const msgarr = newMsg.content.toLowerCase().split(' ');
|
const msgarr = newMsg.content.toLowerCase().split(' ');
|
||||||
if (await client.bannedWords._content.findOne({_id:msgarr}) && (!client.isStaff(newMsg.member))) newMsg.delete();
|
if (await client.bannedWords._content.findOne({_id:msgarr}) && (!client.isStaff(newMsg.member))) newMsg.delete();
|
||||||
if (newMsg.content === oldMsg.content) return;
|
if (newMsg.content === oldMsg.content) return;
|
||||||
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [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}>`)], components: [new ActionRowBuilder<ButtonBuilder>().addComponents(new ButtonBuilder().setStyle(5).setURL(`${oldMsg.url}`).setLabel('Jump to message'))]});
|
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [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.length < 1 ? '(Attachment)' : oldMsg.content}\n\`\`\`\nNew content:\n\`\`\`\n${newMsg.content}\`\`\`\nChannel: <#${oldMsg.channelId}>`)], components: [new ActionRowBuilder<ButtonBuilder>().addComponents(new ButtonBuilder().setStyle(5).setURL(`${oldMsg.url}`).setLabel('Jump to message'))]});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
189
src/index.ts
189
src/index.ts
@ -12,14 +12,15 @@ client.on('ready', async()=>{
|
|||||||
setInterval(()=>guild.invites.fetch().then(invites=>invites.forEach(inv=>client.invites.set(inv.code, {uses: inv.uses, creator: inv.inviterId}))),300000)
|
setInterval(()=>guild.invites.fetch().then(invites=>invites.forEach(inv=>client.invites.set(inv.code, {uses: inv.uses, creator: inv.inviterId}))),300000)
|
||||||
});
|
});
|
||||||
if (client.config.botSwitches.registerCommands){
|
if (client.config.botSwitches.registerCommands){
|
||||||
client.config.whitelistedServers.forEach((guildId)=>(client.guilds.cache.get(guildId) as Discord.Guild).commands.set(client.registry).catch((e:Error)=>{
|
client.config.whitelistedServers.forEach((guildId)=>(client.guilds.cache.get(guildId) as Discord.Guild).commands.set(client.registry).catch((e:Error)=>{
|
||||||
console.log(`Couldn't register slash commands for ${guildId} because`, e.stack);
|
console.log(`Couldn't register slash commands for ${guildId} because`, e.stack);
|
||||||
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send(`Cannot register slash commands for **${client.guilds.cache.get(guildId).name}** (\`${guildId}\`):\n\`\`\`${e.message}\`\`\``)
|
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel).send(`Cannot register slash commands for **${client.guilds.cache.get(guildId).name}** (\`${guildId}\`):\n\`\`\`${e.message}\`\`\``)
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
console.log(`${client.user.tag} has logged into Discord API`);
|
console.log(`${client.user.tag} has logged into Discord API`);
|
||||||
console.log(client.config.botSwitches, client.config.whitelistedServers);
|
console.log(client.config.botSwitches, client.config.whitelistedServers);
|
||||||
(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')}\`\`\``);
|
||||||
|
console.timeEnd('Startup')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handle errors
|
// Handle errors
|
||||||
@ -49,80 +50,78 @@ setInterval(async()=>{
|
|||||||
const verifyURL = MPURL.match(/http|https/);
|
const verifyURL = MPURL.match(/http|https/);
|
||||||
const completedURL_DSS = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode;
|
const completedURL_DSS = MPURL+'/feed/dedicated-server-stats.json?code='+MPCode;
|
||||||
const completedURL_CSG = MPURL+'/feed/dedicated-server-savegame.html?code='+MPCode+'&file=careerSavegame';
|
const completedURL_CSG = MPURL+'/feed/dedicated-server-savegame.html?code='+MPCode+'&file=careerSavegame';
|
||||||
const FSdss = {
|
const FSdss = {
|
||||||
data: {} as FSData,
|
data: {} as FSData,
|
||||||
fetchResult: '' as string
|
fetchResult: '' as string
|
||||||
};
|
};
|
||||||
const FScsg = {
|
const FScsg = {
|
||||||
data: {} as FSCareerSavegame,
|
data: {} as FSCareerSavegame,
|
||||||
fetchResult: '' as string
|
fetchResult: '' as string
|
||||||
};
|
};
|
||||||
if (!verifyURL) return msg.edit({content: '*Detected an invalid IP.*', embeds: null})
|
if (!verifyURL) return msg.edit({content: '*Detected an invalid IP.*', embeds: null})
|
||||||
async function serverData(client:TClient, URL: string){
|
async function serverData(client:TClient, URL: string){
|
||||||
return await client.axios.get(URL, {timeout: 4000, maxContentLength: Infinity, headers: {'User-Agent': `Daggerbot/axios ${client.axios.VERSION}`}}).catch((error:Error)=>error.message)
|
return await client.axios.get(URL, {timeout: 4000, maxContentLength: Infinity, headers: {'User-Agent': `Daggerbot/axios ${client.axios.VERSION}`}}).catch((error:Error)=>error.message)
|
||||||
}
|
}
|
||||||
await Promise.all([serverData(client, completedURL_DSS), serverData(client, completedURL_CSG)]).then(function(results){
|
await Promise.all([serverData(client, completedURL_DSS), serverData(client, completedURL_CSG)]).then(function(results){
|
||||||
if (typeof results[0] == 'string'){
|
if (typeof results[0] == 'string'){
|
||||||
FSdss.fetchResult = `DagMP DSS failed, ${results[0]}`;
|
FSdss.fetchResult = `DagMP DSS failed, ${results[0]}`;
|
||||||
embed.addFields({name: 'DSS Status', value: results[0]})
|
embed.addFields({name: 'DSS Status', value: results[0]})
|
||||||
} else if (results[0].status != 200){
|
} else if (results[0].status != 200){
|
||||||
FSdss.fetchResult = `DagMP DSS failed with ${results[0].status + ' ' + results[0].statusText}`;
|
FSdss.fetchResult = `DagMP DSS failed with ${results[0].status + ' ' + results[0].statusText}`;
|
||||||
embed.addFields({name: 'DSS Status', value: results[0].status + ' ' + results[0].statusText})
|
embed.addFields({name: 'DSS Status', value: results[0].status + ' ' + results[0].statusText})
|
||||||
} else FSdss.data = results[0].data as FSData
|
} else FSdss.data = results[0].data as FSData
|
||||||
|
|
||||||
if (typeof results[1] == 'string'){
|
if (typeof results[1] == 'string'){
|
||||||
FScsg.fetchResult = `DagMP CSG failed, ${results[1]}`;
|
FScsg.fetchResult = `DagMP CSG failed, ${results[1]}`;
|
||||||
embed.addFields({name: 'CSG Status', value: results[1]})
|
embed.addFields({name: 'CSG Status', value: results[1]})
|
||||||
} else if (results[1].status != 200){
|
} else if (results[1].status != 200){
|
||||||
if (results[1].status == 204) embed.setImage('https://http.cat/204');
|
if (results[1].status == 204) embed.setImage('https://http.cat/204');
|
||||||
FScsg.fetchResult = `DagMP CSG failed with ${results[1].status + ' ' + results[1].statusText}`;
|
FScsg.fetchResult = `DagMP CSG failed with ${results[1].status + ' ' + results[1].statusText}`;
|
||||||
embed.addFields({name: 'CSG Status', value: results[1].status + ' ' + results[1].statusText})
|
embed.addFields({name: 'CSG Status', value: results[1].status + ' ' + results[1].statusText})
|
||||||
} else FScsg.data = client.xjs.xml2js(results[1].data,{compact:true,spaces:2}).careerSavegame as FSCareerSavegame;
|
} else FScsg.data = client.xjs.xml2js(results[1].data,{compact:true,spaces:2}).careerSavegame as FSCareerSavegame;
|
||||||
}).catch((error)=>console.log(error))
|
}).catch((error)=>console.log(error))
|
||||||
if (FSdss.fetchResult.length != 0){
|
if (FSdss.fetchResult.length != 0){
|
||||||
error = true;
|
error = true;
|
||||||
console.log(client.logTime(), FSdss.fetchResult);
|
console.log(client.logTime(), FSdss.fetchResult);
|
||||||
}
|
}
|
||||||
if (FScsg.fetchResult.length != 0){
|
if (FScsg.fetchResult.length != 0){
|
||||||
error = true;
|
error = true;
|
||||||
console.log(client.logTime(), FScsg.fetchResult);
|
console.log(client.logTime(), FScsg.fetchResult);
|
||||||
}
|
}
|
||||||
if (error) { // Blame RedRover and Nawdic
|
if (error) { // Blame RedRover and Nawdic
|
||||||
embed.setTitle('Host is not responding').setColor(client.config.embedColorRed);
|
embed.setTitle('Host is not responding').setColor(client.config.embedColorRed);
|
||||||
msg.edit({content: null, embeds: [embed]})
|
msg.edit({content: null, embeds: [embed]})
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DB = JSON.parse(fs.readFileSync(__dirname + '/database/MPPlayerData.json', {encoding: 'utf8'}));
|
const DB = JSON.parse(fs.readFileSync(__dirname + '/database/MPPlayerData.json', {encoding: 'utf8'}));
|
||||||
DB.push(FSdss.data.slots.used)
|
DB.push(FSdss.data.slots.used)
|
||||||
fs.writeFileSync(__dirname + '/database/MPPlayerData.json', JSON.stringify(DB))
|
fs.writeFileSync(__dirname + '/database/MPPlayerData.json', JSON.stringify(DB))
|
||||||
|
|
||||||
// Number format function
|
|
||||||
function formatNumber(number: any, digits: any, icon: any){
|
|
||||||
var n = Number(number)
|
|
||||||
return n.toLocaleString(undefined, {minimumFractionDigits: digits})+icon
|
|
||||||
} // Temporary workaround for fresh save.
|
|
||||||
const slotSystem = isNaN(Number(FScsg.data.slotSystem?._attributes.slotUsage)) == true ? 'Unavailable' : Number(FScsg.data.slotSystem?._attributes.slotUsage).toLocaleString('en-US');
|
|
||||||
const timeScale = isNaN(Number(FScsg.data.settings?.timeScale._text)) == true ? 'Unavailable' : formatNumber(Number(FScsg.data.settings?.timeScale._text), 0, 'x');
|
|
||||||
|
|
||||||
if (FSdss.data.server.name.length == 0){
|
// Number format function
|
||||||
embed.setTitle('The server seems to be offline.').setColor(client.config.embedColorRed);
|
function formatNumber(number: any, digits: any, icon: any){
|
||||||
msg.edit({content: 'This embed will resume when server is back online.', embeds: [embed]})
|
var n = Number(number)
|
||||||
} else {
|
return n.toLocaleString(undefined, {minimumFractionDigits: digits})+icon
|
||||||
const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Server details').addFields(
|
} // Temporary workaround for fresh save.
|
||||||
{name: 'Current Map', value: `${FSdss.data.server.mapName.length == 0 ? '\u200b' : FSdss.data.server.mapName}`, inline: true},
|
const slotSystem = isNaN(Number(FScsg.data.slotSystem?._attributes.slotUsage)) == true ? 'Unavailable' : Number(FScsg.data.slotSystem?._attributes.slotUsage).toLocaleString('en-US');
|
||||||
{name: 'Version', value: `${FSdss.data.server.version.length == 0 ? '\u200b' : FSdss.data.server.version}`, inline: true},
|
const timeScale = isNaN(Number(FScsg.data.settings?.timeScale._text)) == true ? 'Unavailable' : formatNumber(Number(FScsg.data.settings?.timeScale._text), 0, 'x');
|
||||||
{name: 'In-game Time', value: `${('0' + Math.floor((FSdss.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSdss.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true},
|
|
||||||
{name: 'Slot Usage', value: `${slotSystem}`, inline: true},
|
if (FSdss.data.server.name.length == 0){
|
||||||
{name: 'Timescale', value: `${timeScale}`, inline: true}
|
embed.setTitle('The server seems to be offline.').setColor(client.config.embedColorRed);
|
||||||
);
|
msg.edit({content: 'This embed will resume when server is back online.', embeds: [embed]})
|
||||||
FSdss.data.slots.players.filter((x)=>x.isUsed !== false).forEach(player=>{
|
} else {
|
||||||
Players.push(`**${player.name} ${player.isAdmin ? '| admin' : ''}**\nFarming for ${(Math.floor(player.uptime/60))} hr & ${('' + (player.uptime % 60)).slice(-2)} min`)
|
const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Server details').addFields(
|
||||||
})
|
{name: 'Current Map', value: `${FSdss.data.server.mapName.length == 0 ? '\u200b' : FSdss.data.server.mapName}`, inline: true},
|
||||||
embed.setDescription(`${FSdss.data.slots.used == 0 ? '*No players online*' : Players.join('\n\n')}`).setTitle(FSdss.data.server.name).setColor(client.config.embedColor)
|
{name: 'Version', value: `${FSdss.data.server.version.length == 0 ? '\u200b' : FSdss.data.server.version}`, inline: true},
|
||||||
embed.setAuthor({name: `${FSdss.data.slots.used}/${FSdss.data.slots.capacity}`});
|
{name: 'In-game Time', value: `${('0' + Math.floor((FSdss.data.server.dayTime/3600/1000))).slice(-2)}:${('0' + Math.floor((FSdss.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true},
|
||||||
msg.edit({content: 'This embed updates every minute.', embeds: [embed1, embed]})
|
{name: 'Slot Usage', value: `${slotSystem}`, inline: true},
|
||||||
}
|
{name: 'Timescale', value: `${timeScale}`, inline: true}
|
||||||
|
);
|
||||||
|
FSdss.data.slots.players.filter((x)=>x.isUsed !== false).forEach(player=>Players.push(`**${player.name} ${player.isAdmin ? '| admin' : ''}**\nFarming for ${(Math.floor(player.uptime/60))} hr & ${('' + (player.uptime % 60)).slice(-2)} min`))
|
||||||
|
embed.setDescription(`${FSdss.data.slots.used == 0 ? '*No players online*' : Players.join('\n\n')}`).setTitle(FSdss.data.server.name).setColor(client.config.embedColor)
|
||||||
|
embed.setAuthor({name: `${FSdss.data.slots.used}/${FSdss.data.slots.capacity}`});
|
||||||
|
msg.edit({content: 'This embed updates every minute.', embeds: [embed1, embed]})
|
||||||
|
}
|
||||||
}, 60000)
|
}, 60000)
|
||||||
|
|
||||||
// YouTube Upload notification
|
// YouTube Upload notification
|
||||||
@ -133,27 +132,25 @@ setInterval(async()=>{
|
|||||||
|
|
||||||
// Event loop for punishments and daily msgs
|
// Event loop for punishments and daily msgs
|
||||||
setInterval(async()=>{
|
setInterval(async()=>{
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const lrsStart = client.config.LRSstart;
|
const lrsStart = client.config.LRSstart;
|
||||||
|
|
||||||
const punishments = await client.punishments._content.find({});
|
const punishments = await client.punishments._content.find({});
|
||||||
punishments.filter(x=>x.endTime && x.endTime<= now && !x.expired).forEach(async punishment=>{
|
punishments.filter(x=>x.endTime && x.endTime<= now && !x.expired).forEach(async punishment=>{
|
||||||
console.log(client.logTime(), `${punishment.member}\'s ${punishment.type} should expire now`);
|
console.log(client.logTime(), `${punishment.member}\'s ${punishment.type} should expire now`);
|
||||||
const unpunishResult = await client.punishments.removePunishment(punishment._id, client.user.id, 'Time\'s up!');
|
const unpunishResult = await client.punishments.removePunishment(punishment._id, client.user.id, 'Time\'s up!');
|
||||||
console.log(client.logTime(), unpunishResult);
|
console.log(client.logTime(), unpunishResult);
|
||||||
});
|
});
|
||||||
|
|
||||||
const formattedDate = Math.floor((now - lrsStart)/1000/60/60/24);
|
const formattedDate = Math.floor((now - lrsStart)/1000/60/60/24);
|
||||||
const dailyMsgs = JSON.parse(fs.readFileSync(__dirname + '/database/dailyMsgs.json', {encoding: 'utf8'}))
|
const dailyMsgs = JSON.parse(fs.readFileSync(__dirname + '/database/dailyMsgs.json', {encoding: 'utf8'}))
|
||||||
if (!dailyMsgs.some((x:Array<number>)=>x[0] === formattedDate)){
|
if (!dailyMsgs.some((x:Array<number>)=>x[0] === formattedDate)){
|
||||||
let total = (await client.userLevels._content.find({})).reduce((a,b)=>a + b.messages, 0); // sum of all users
|
let total = (await client.userLevels._content.find({})).reduce((a,b)=>a + b.messages, 0); // sum of all users
|
||||||
const yesterday = dailyMsgs.find((x:Array<number>)=>x[0] === formattedDate - 1);
|
const yesterday = dailyMsgs.find((x:Array<number>)=>x[0] === formattedDate - 1);
|
||||||
if (total < yesterday){ // messages went down.
|
if (total < yesterday) total = yesterday // messages went down.
|
||||||
total = yesterday
|
dailyMsgs.push([formattedDate, total]);
|
||||||
}
|
fs.writeFileSync(__dirname + '/database/dailyMsgs.json', JSON.stringify(dailyMsgs))
|
||||||
dailyMsgs.push([formattedDate, total]);
|
console.log(client.logTime(), `Pushed [${formattedDate}, ${total}] to dailyMsgs`);
|
||||||
fs.writeFileSync(__dirname + '/database/dailyMsgs.json', JSON.stringify(dailyMsgs))
|
client.guilds.cache.get(client.config.mainServer.id).commands.fetch().then((commands)=>(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send(`:pencil: Pushed \`[${formattedDate}, ${total}]\` to </rank leaderboard:${commands.find(x=>x.name == 'rank').id}>`))
|
||||||
console.log(client.logTime(), `Pushed [${formattedDate}, ${total}] to dailyMsgs`);
|
}
|
||||||
client.guilds.cache.get(client.config.mainServer.id).commands.fetch().then((commands)=>(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send(`:pencil: Pushed \`[${formattedDate}, ${total}]\` to </rank leaderboard:${commands.find(x=>x.name == 'rank').id}>`))
|
|
||||||
}
|
|
||||||
}, 5000)
|
}, 5000)
|
||||||
|
276
src/typings/interfaces.d.ts
vendored
276
src/typings/interfaces.d.ts
vendored
@ -1,187 +1,187 @@
|
|||||||
import Discord from 'discord.js';
|
import Discord from 'discord.js';
|
||||||
|
|
||||||
export interface UserLevels {
|
export interface UserLevels {
|
||||||
messages: number,
|
messages: number,
|
||||||
level: number
|
level: number
|
||||||
}
|
}
|
||||||
export interface formatTimeOpt {
|
export interface formatTimeOpt {
|
||||||
longNames: boolean,
|
longNames: boolean,
|
||||||
commas: boolean
|
commas: boolean
|
||||||
}
|
}
|
||||||
export interface punOpt {
|
export interface punOpt {
|
||||||
time?: string,
|
time?: string,
|
||||||
reason?: string,
|
reason?: string,
|
||||||
interaction?: Discord.ChatInputCommandInteraction<"cached">
|
interaction?: Discord.ChatInputCommandInteraction<"cached">
|
||||||
}
|
}
|
||||||
export interface repeatedMessages {
|
export interface repeatedMessages {
|
||||||
[key:string]: {data: Discord.Collection<number,{cont:number,ch:string}>, timeout: NodeJS.Timeout}
|
[key:string]: {data: Discord.Collection<number,{cont:number,ch:string}>, timeout: NodeJS.Timeout}
|
||||||
}
|
}
|
||||||
export interface Punishment {
|
export interface Punishment {
|
||||||
_id: number;
|
_id: number;
|
||||||
type: string;
|
type: string;
|
||||||
member: string;
|
member: string;
|
||||||
moderator: string;
|
moderator: string;
|
||||||
expired?: boolean;
|
expired?: boolean;
|
||||||
time: number;
|
time: number;
|
||||||
reason: string;
|
reason: string;
|
||||||
endTime?: number;
|
endTime?: number;
|
||||||
cancels?: number;
|
cancels?: number;
|
||||||
duration?: number;
|
duration?: number;
|
||||||
}
|
}
|
||||||
export interface DSS_serverName {
|
export interface DSS_serverName {
|
||||||
data: FSData
|
data: FSData
|
||||||
}
|
}
|
||||||
export interface FSData {
|
export interface FSData {
|
||||||
server: FSServer,
|
server: FSServer,
|
||||||
slots: FSslots
|
slots: FSslots
|
||||||
}
|
}
|
||||||
export interface FSServer {
|
export interface FSServer {
|
||||||
dayTime: number,
|
dayTime: number,
|
||||||
game: string,
|
game: string,
|
||||||
mapName: string,
|
mapName: string,
|
||||||
mapSize: number,
|
mapSize: number,
|
||||||
mapOverviewFilename: string,
|
mapOverviewFilename: string,
|
||||||
money: number,
|
money: number,
|
||||||
name: string,
|
name: string,
|
||||||
server: string,
|
server: string,
|
||||||
version: string
|
version: string
|
||||||
}
|
}
|
||||||
export interface FSslots {
|
export interface FSslots {
|
||||||
capacity: number,
|
capacity: number,
|
||||||
used: number,
|
used: number,
|
||||||
players: Array<FSPlayers>
|
players: Array<FSPlayers>
|
||||||
}
|
}
|
||||||
export interface FSPlayers {
|
export interface FSPlayers {
|
||||||
isUsed: boolean,
|
isUsed: boolean,
|
||||||
isAdmin: boolean,
|
isAdmin: boolean,
|
||||||
uptime: number,
|
uptime: number,
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
export interface FSCareerSavegame {
|
export interface FSCareerSavegame {
|
||||||
settings: FSCareerSavegameSettings,
|
settings: FSCareerSavegameSettings,
|
||||||
statistics: FSCareerSavegameStatistics,
|
statistics: FSCareerSavegameStatistics,
|
||||||
slotSystem: FSCareerSavegameSlotSystem
|
slotSystem: FSCareerSavegameSlotSystem
|
||||||
}
|
}
|
||||||
export interface FSCareerSavegameSettings {
|
export interface FSCareerSavegameSettings {
|
||||||
savegameName: XMLText,
|
savegameName: XMLText,
|
||||||
creationDate: XMLText,
|
creationDate: XMLText,
|
||||||
mapId: XMLText,
|
mapId: XMLText,
|
||||||
mapTitle: XMLText,
|
mapTitle: XMLText,
|
||||||
saveDataFormatted: XMLText,
|
saveDataFormatted: XMLText,
|
||||||
saveDate: XMLText,
|
saveDate: XMLText,
|
||||||
resetVehicles: XMLText,
|
resetVehicles: XMLText,
|
||||||
trafficeEnabled: XMLText,
|
trafficeEnabled: XMLText,
|
||||||
stopAndGoBraking: XMLText,
|
stopAndGoBraking: XMLText,
|
||||||
trailerFillLimit: XMLText,
|
trailerFillLimit: XMLText,
|
||||||
automaticMotorStartEnabled: XMLText,
|
automaticMotorStartEnabled: XMLText,
|
||||||
growthMode: XMLText,
|
growthMode: XMLText,
|
||||||
fixedSeasonalVisuals: XMLText,
|
fixedSeasonalVisuals: XMLText,
|
||||||
plannedDaysPerPeriod: XMLText,
|
plannedDaysPerPeriod: XMLText,
|
||||||
fruitDestruction: XMLText,
|
fruitDestruction: XMLText,
|
||||||
plowingRequiredEnabled: XMLText,
|
plowingRequiredEnabled: XMLText,
|
||||||
stonesEnabled: XMLText,
|
stonesEnabled: XMLText,
|
||||||
weedsEnabled: XMLText,
|
weedsEnabled: XMLText,
|
||||||
limeRequired: XMLText,
|
limeRequired: XMLText,
|
||||||
isSnowEnabled: XMLText,
|
isSnowEnabled: XMLText,
|
||||||
fuelUsage: XMLText,
|
fuelUsage: XMLText,
|
||||||
helperBuyFuel: XMLText,
|
helperBuyFuel: XMLText,
|
||||||
helperBuySeeds: XMLText,
|
helperBuySeeds: XMLText,
|
||||||
helperSlurrySource: XMLText,
|
helperSlurrySource: XMLText,
|
||||||
helperManureSource: XMLText,
|
helperManureSource: XMLText,
|
||||||
densityMapRevision: XMLText,
|
densityMapRevision: XMLText,
|
||||||
terrainTextureRevision: XMLText,
|
terrainTextureRevision: XMLText,
|
||||||
terrainLodTextureRevision: XMLText,
|
terrainLodTextureRevision: XMLText,
|
||||||
splitShapesRevision: XMLText,
|
splitShapesRevision: XMLText,
|
||||||
tipCollisionRevision: XMLText,
|
tipCollisionRevision: XMLText,
|
||||||
placementCollisionRevision: XMLText,
|
placementCollisionRevision: XMLText,
|
||||||
navigationCollisionRevision: XMLText,
|
navigationCollisionRevision: XMLText,
|
||||||
mapDensityMapRevision: XMLText,
|
mapDensityMapRevision: XMLText,
|
||||||
mapTerrainTextureRevision: XMLText,
|
mapTerrainTextureRevision: XMLText,
|
||||||
mapTerrainLodTextureRevision: XMLText,
|
mapTerrainLodTextureRevision: XMLText,
|
||||||
mapSplitShapesRevision: XMLText,
|
mapSplitShapesRevision: XMLText,
|
||||||
mapTipCollisionRevision: XMLText,
|
mapTipCollisionRevision: XMLText,
|
||||||
mapPlacementCollisionRevision: XMLText,
|
mapPlacementCollisionRevision: XMLText,
|
||||||
mapNavigationCollisionRevision: XMLText,
|
mapNavigationCollisionRevision: XMLText,
|
||||||
difficulty: XMLText,
|
difficulty: XMLText,
|
||||||
economicDifficulty: XMLText,
|
economicDifficulty: XMLText,
|
||||||
dirtInterval: XMLText,
|
dirtInterval: XMLText,
|
||||||
timeScale: XMLText,
|
timeScale: XMLText,
|
||||||
autoSaveInterval: XMLText
|
autoSaveInterval: XMLText
|
||||||
}
|
}
|
||||||
export interface FSCareerSavegameStatistics {
|
export interface FSCareerSavegameStatistics {
|
||||||
money: XMLText,
|
money: XMLText,
|
||||||
playTime: XMLText
|
playTime: XMLText
|
||||||
}
|
}
|
||||||
export interface FSCareerSavegameSlotSystem {
|
export interface FSCareerSavegameSlotSystem {
|
||||||
_attributes: slotUsage
|
_attributes: slotUsage
|
||||||
}
|
}
|
||||||
interface slotUsage {
|
interface slotUsage {
|
||||||
slotUsage: string
|
slotUsage: string
|
||||||
}
|
}
|
||||||
interface XMLText {
|
interface XMLText {
|
||||||
_text: string
|
_text: string
|
||||||
}
|
}
|
||||||
export interface Tokens {
|
export interface Tokens {
|
||||||
main: string
|
main: string
|
||||||
beta: string
|
beta: string
|
||||||
toast: string
|
toast: string
|
||||||
tae: string
|
tae: string
|
||||||
webhook_url: string
|
webhook_url: string
|
||||||
webhook_url_test: string
|
webhook_url_test: string
|
||||||
mongodb_uri: string
|
mongodb_uri: string
|
||||||
mongodb_uri_dev: string
|
mongodb_uri_dev: string
|
||||||
}
|
}
|
||||||
export interface Config {
|
export interface Config {
|
||||||
embedColor: Discord.ColorResolvable,
|
embedColor: Discord.ColorResolvable,
|
||||||
embedColorGreen: Discord.ColorResolvable,
|
embedColorGreen: Discord.ColorResolvable,
|
||||||
embedColorYellow: Discord.ColorResolvable,
|
embedColorYellow: Discord.ColorResolvable,
|
||||||
embedColorRed: Discord.ColorResolvable,
|
embedColorRed: Discord.ColorResolvable,
|
||||||
embedColorBCA: Discord.ColorResolvable,
|
embedColorBCA: Discord.ColorResolvable,
|
||||||
embedColorXmas: Discord.ColorResolvable,
|
embedColorXmas: Discord.ColorResolvable,
|
||||||
LRSstart: number,
|
LRSstart: number,
|
||||||
whitelistedServers: Array<string>,
|
whitelistedServers: Array<string>,
|
||||||
botSwitches: botSwitches,
|
botSwitches: botSwitches,
|
||||||
botPresence: Discord.PresenceData,
|
botPresence: Discord.PresenceData,
|
||||||
eval: Eval,
|
eval: Eval,
|
||||||
mainServer: mainServer
|
mainServer: mainServer
|
||||||
}
|
}
|
||||||
interface botSwitches {
|
interface botSwitches {
|
||||||
registerCommands: boolean,
|
registerCommands: boolean,
|
||||||
commands: boolean,
|
commands: boolean,
|
||||||
logs: boolean,
|
logs: boolean,
|
||||||
automod: boolean,
|
automod: boolean,
|
||||||
mpstats: boolean,
|
mpstats: boolean,
|
||||||
autores: boolean
|
autores: boolean
|
||||||
}
|
}
|
||||||
interface Eval {
|
interface Eval {
|
||||||
allowed: boolean,
|
allowed: boolean,
|
||||||
whitelist: Array<string>
|
whitelist: Array<string>
|
||||||
}
|
}
|
||||||
interface mainServer {
|
interface mainServer {
|
||||||
id: string,
|
id: string,
|
||||||
staffRoles: Array<string>,
|
staffRoles: Array<string>,
|
||||||
roles: mainServerRoles,
|
roles: mainServerRoles,
|
||||||
channels: mainServerChannels
|
channels: mainServerChannels
|
||||||
}
|
}
|
||||||
interface mainServerRoles {
|
interface mainServerRoles {
|
||||||
admin: string,
|
admin: string,
|
||||||
bottech: string,
|
bottech: string,
|
||||||
dcmod: string,
|
dcmod: string,
|
||||||
mpmanager: string,
|
mpmanager: string,
|
||||||
mpmod: string,
|
mpmod: string,
|
||||||
vtcmanager: string,
|
vtcmanager: string,
|
||||||
vtcstaff: string,
|
vtcstaff: string,
|
||||||
ytmod: string,
|
ytmod: string,
|
||||||
mphelper: string,
|
mphelper: string,
|
||||||
mpplayer: string,
|
mpplayer: string,
|
||||||
vtcmember: string
|
vtcmember: string
|
||||||
}
|
}
|
||||||
interface mainServerChannels {
|
interface mainServerChannels {
|
||||||
console: string,
|
console: string,
|
||||||
errors: string,
|
errors: string,
|
||||||
thismeanswar: string,
|
thismeanswar: string,
|
||||||
bot_status: string,
|
bot_status: string,
|
||||||
logs: string,
|
logs: string,
|
||||||
welcome: string,
|
welcome: string,
|
||||||
botcommands: string
|
botcommands: string
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user