mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-12-27 04:15:38 -05:00
Compare commits
4 Commits
a6eace4ed4
...
5dec21ad85
Author | SHA1 | Date | |
---|---|---|---|
|
5dec21ad85 | ||
|
83ce7db7c3 | ||
|
6bea048c0e | ||
|
8ac4de874c |
@ -104,6 +104,7 @@ export default async(client:TClient,Channel:string,Message:string,ServerName:str
|
|||||||
{name: 'Version', value: DSS.data.server.version.length === 0 ? '\u200b' : DSS.data.server.version, inline: true},
|
{name: 'Version', value: DSS.data.server.version.length === 0 ? '\u200b' : DSS.data.server.version, inline: true},
|
||||||
{name: 'In-game Time', value: `${('0'+Math.floor((DSS.data.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((DSS.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true},
|
{name: 'In-game Time', value: `${('0'+Math.floor((DSS.data.server.dayTime/3600/1000))).slice(-2)}:${('0'+Math.floor((DSS.data.server.dayTime/60/1000)%60)).slice(-2)}`, inline: true},
|
||||||
{name: 'Slot Usage', value: isNaN(Number(CSG.data.slotSystem?._attributes.slotUsage)) === true ? 'Unavailable' : Number(CSG.data.slotSystem?._attributes.slotUsage).toLocaleString('en-us'), inline: true},
|
{name: 'Slot Usage', value: isNaN(Number(CSG.data.slotSystem?._attributes.slotUsage)) === true ? 'Unavailable' : Number(CSG.data.slotSystem?._attributes.slotUsage).toLocaleString('en-us'), inline: true},
|
||||||
|
{name: 'Autosave Interval', value: isNaN(Number(CSG.data.settings?.autoSaveInterval._text)) === true ? 'Unavailable' : Number(CSG.data.settings?.autoSaveInterval._text).toFixed(0)+' mins', inline:true},
|
||||||
{name: 'Timescale', value: isNaN(Number(CSG.data.settings?.timeScale._text)) === true ? 'Unavailable' : formatTimescale(Number(CSG.data.settings?.timeScale._text), 0, 'x'), inline: true}
|
{name: 'Timescale', value: isNaN(Number(CSG.data.settings?.timeScale._text)) === true ? 'Unavailable' : formatTimescale(Number(CSG.data.settings?.timeScale._text), 0, 'x'), inline: true}
|
||||||
);
|
);
|
||||||
embed.setColor(client.config.embedColor).setTitle(DSS.data.server.name).setDescription(DSS.data.slots.used === 0 ? '*No players online*' : playerData.join('\n\n')).setAuthor({name:`${DSS.data.slots.used}/${DSS.data.slots.capacity}`});
|
embed.setColor(client.config.embedColor).setTitle(DSS.data.server.name).setDescription(DSS.data.slots.used === 0 ? '*No players online*' : playerData.join('\n\n')).setAuthor({name:`${DSS.data.slots.used}/${DSS.data.slots.capacity}`});
|
||||||
|
@ -160,14 +160,6 @@ export default class TClient extends Client {
|
|||||||
|
|
||||||
logTime = ()=>`[${this.moment().format('DD/MM/YY HH:mm:ss')}]`;
|
logTime = ()=>`[${this.moment().format('DD/MM/YY HH:mm:ss')}]`;
|
||||||
|
|
||||||
alignText(text: string, length: number, alignment: string, emptyChar = ' '){
|
|
||||||
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(interaction: Discord.ChatInputCommandInteraction<'cached'>, type: string){
|
async punish(interaction: Discord.ChatInputCommandInteraction<'cached'>, type: string){
|
||||||
if (!this.isStaff(interaction.member as Discord.GuildMember)) return this.youNeedRole(interaction, "dcmod");
|
if (!this.isStaff(interaction.member as Discord.GuildMember)) return this.youNeedRole(interaction, "dcmod");
|
||||||
|
|
||||||
@ -187,21 +179,19 @@ export default class TClient extends Client {
|
|||||||
}
|
}
|
||||||
async YTLoop(YTChannelID: string, YTChannelName: string, DCChannelID: string){
|
async YTLoop(YTChannelID: string, YTChannelName: string, DCChannelID: string){
|
||||||
let Data:any;
|
let Data:any;
|
||||||
let error;
|
|
||||||
|
|
||||||
try {
|
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}))
|
await this.axios.get(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelID}`, {timeout: 5000}).then(xml=>Data = this.xjs.xml2js(xml.data, {compact: true}))
|
||||||
} catch(err){
|
} catch(err){
|
||||||
error = true;
|
|
||||||
console.log(this.logTime(), `${YTChannelName} YT fail`)
|
console.log(this.logTime(), `${YTChannelName} YT fail`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Data) return;
|
if (!Data) return;
|
||||||
if (this.YTCache[YTChannelID] == undefined){
|
if (this.YTCache[YTChannelID] === undefined){
|
||||||
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
|
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Data.feed.entry[1]['yt:videoId']._text == this.YTCache[YTChannelID]){
|
if (Data.feed.entry[1]['yt:videoId']._text === this.YTCache[YTChannelID]){
|
||||||
this.YTCache[YTChannelID] = Data.feed.entry[0]['yt:videoId']._text;
|
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}`)
|
(this.channels.resolve(DCChannelID) as Discord.TextChannel).send(`**${YTChannelName}** just uploaded a video!\n${Data.feed.entry[0].link._attributes.href}`)
|
||||||
}
|
}
|
||||||
@ -210,19 +200,15 @@ export default class TClient extends Client {
|
|||||||
formatBytes(bytes:number, decimals:number = 2) {
|
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 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(decimals < 0 ? 0 : decimals)) + ' ' + ['Bytes', 'KB', 'MB', 'GB'][i];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WClient extends WebhookClient {
|
export class WClient extends WebhookClient {
|
||||||
tokens: Tokens;
|
tokens: Tokens;
|
||||||
constructor(){
|
constructor(){
|
||||||
super({
|
super({url: tokens.webhook_url})
|
||||||
url: tokens.webhook_url
|
|
||||||
})
|
|
||||||
this.tokens = tokens as Tokens;
|
this.tokens = tokens as Tokens;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,7 @@ export default {
|
|||||||
//if (!client.isStaff(interaction.member) && interaction.channelId == '468835415093411863') return interaction.reply('This command is restricted to staff only in this channel due to high usage.')
|
//if (!client.isStaff(interaction.member) && interaction.channelId == '468835415093411863') return interaction.reply('This command is restricted to staff only in this channel due to high usage.')
|
||||||
const member = interaction.options.getMember('member') as Discord.GuildMember;
|
const member = interaction.options.getMember('member') as Discord.GuildMember;
|
||||||
const reason = interaction.options.getString('reason');
|
const reason = interaction.options.getString('reason');
|
||||||
const adminPerm = member.permissions.has('Administrator');
|
if (member.permissions.has('Administrator')) return interaction.reply('You cannot bonk an admin!');
|
||||||
if (adminPerm) return interaction.reply('You cannot bonk an admin!');
|
|
||||||
|
|
||||||
await client.bonkCount._incrementUser(member.id);
|
await client.bonkCount._incrementUser(member.id);
|
||||||
interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor)
|
interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor)
|
||||||
|
@ -2,8 +2,7 @@ import Discord from 'discord.js';
|
|||||||
import TClient from '../client.js';
|
import TClient from '../client.js';
|
||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){
|
||||||
const inviteCode = interaction.options.getString('code',true).replace(/(https:\/\/|discord.gg\/)/g,'')
|
await client.axios.get(`https://discord.com/api/v${Discord.APIVersion}/invites/${interaction.options.getString('code',true).replace(/(https:\/\/|discord.gg\/)/g,'')}`).then(async inviteInfo=>
|
||||||
await client.axios.get(`https://discord.com/api/v${Discord.APIVersion}/invites/${inviteCode}`).then(async inviteInfo=>
|
|
||||||
await interaction.reply({embeds: [
|
await interaction.reply({embeds: [
|
||||||
new client.embed().setColor(client.config.embedColor).setURL(`https://discord.gg/${inviteInfo.data.code}`).setTitle(inviteInfo.data.guild.name).setDescription([
|
new client.embed().setColor(client.config.embedColor).setURL(`https://discord.gg/${inviteInfo.data.code}`).setTitle(inviteInfo.data.guild.name).setDescription([
|
||||||
`ID: \`${inviteInfo.data.guild.id}\``,
|
`ID: \`${inviteInfo.data.guild.id}\``,
|
||||||
|
@ -26,7 +26,7 @@ async function MPdata(client:TClient, interaction:Discord.ChatInputCommandIntera
|
|||||||
export default {
|
export default {
|
||||||
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(()=>setTimeout(()=>interaction.deleteReply(), 6000));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
({
|
({
|
||||||
@ -93,7 +93,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
players: async()=>{
|
players: async()=>{
|
||||||
const embed1 = new client.embed();
|
|
||||||
const data = JSON.parse(readFileSync(path.join('src/database/MPPlayerData.json'), {encoding: 'utf8'})).slice(client.statsGraph)
|
const data = JSON.parse(readFileSync(path.join('src/database/MPPlayerData.json'), {encoding: 'utf8'})).slice(client.statsGraph)
|
||||||
// handle negative days
|
// handle negative days
|
||||||
data.forEach((change: number, i: number) => {
|
data.forEach((change: number, i: number) => {
|
||||||
@ -235,15 +234,15 @@ export default {
|
|||||||
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 Image = new client.attachmentBuilder(img.toBuffer(),{name: 'FSStats.png'})
|
const embed1 = new client.embed();
|
||||||
embed1.setImage('attachment://FSStats.png')
|
|
||||||
const FSserver1 = await MPdata(client, interaction, embed1)
|
const FSserver1 = await MPdata(client, interaction, embed1)
|
||||||
if (!FSserver1?.data) return console.log('FSserver1 failed - players')
|
if (!FSserver1?.data) return console.log('FSserver1 failed - players')
|
||||||
embed1.setTitle(FSserver1?.data.server.name.length == 0 ? 'Offline' : FSserver1?.data.server.name)
|
embed1.setTitle(FSserver1?.data.server.name.length === 0 ? 'Offline' : FSserver1?.data.server.name)
|
||||||
.setDescription(`${FSserver1?.data.slots.used}/${FSserver1?.data.slots.capacity}`)
|
.setDescription(`${FSserver1?.data.slots.used}/${FSserver1?.data.slots.capacity}`)
|
||||||
.setColor(FSserver1?.data.server.name.length == 0 ? client.config.embedColorRed : client.config.embedColor);
|
.setColor(FSserver1?.data.server.name.length === 0 ? client.config.embedColorRed : client.config.embedColor)
|
||||||
|
.setImage('attachment://FSStats.png');
|
||||||
FSserver1?.data.slots.players.filter(x=>x.isUsed).forEach(player=>embed1.addFields({name: `${player.name} ${player.isAdmin ? '| admin' : ''}`, value: `Farming for ${client.formatPlayerUptime(player.uptime)}`}))
|
FSserver1?.data.slots.players.filter(x=>x.isUsed).forEach(player=>embed1.addFields({name: `${player.name} ${player.isAdmin ? '| admin' : ''}`, value: `Farming for ${client.formatPlayerUptime(player.uptime)}`}))
|
||||||
interaction.reply({embeds: [embed1], files: [Image]})
|
interaction.reply({embeds: [embed1], files: [new client.attachmentBuilder(img.toBuffer(),{name:'FSStats.png'})]})
|
||||||
},
|
},
|
||||||
maintenance: ()=>{
|
maintenance: ()=>{
|
||||||
if (client.config.mainServer.id == interaction.guildId) {
|
if (client.config.mainServer.id == interaction.guildId) {
|
||||||
|
@ -11,8 +11,7 @@ export default {
|
|||||||
clientId: client.tokens.dontlookatme.client,
|
clientId: client.tokens.dontlookatme.client,
|
||||||
clientSecret: client.tokens.dontlookatme.secret
|
clientSecret: client.tokens.dontlookatme.secret
|
||||||
});
|
});
|
||||||
const voiceCh = interaction.member.voice.channel;
|
if (!interaction.member.voice.channel) return interaction.reply('Please join a voice channel first to use the command.');
|
||||||
if (!voiceCh) return interaction.reply('Please join a voice channel first to use the command.');
|
|
||||||
player.nodes.create(interaction.guildId, {
|
player.nodes.create(interaction.guildId, {
|
||||||
metadata: {
|
metadata: {
|
||||||
channel: interaction.channel,
|
channel: interaction.channel,
|
||||||
|
@ -3,8 +3,7 @@ import TClient from '../client.js';
|
|||||||
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;
|
msg.edit(`Websocket: \`${client.formatTime(client.ws.ping, 3, {longNames: false, commas: true})}\`\nBot: \`${client.formatTime(msg.createdTimestamp - interaction.createdTimestamp, 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 Discord.SlashCommandBuilder()
|
data: new Discord.SlashCommandBuilder()
|
||||||
.setName('ping')
|
.setName('ping')
|
||||||
|
@ -8,12 +8,11 @@ export default {
|
|||||||
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 {
|
||||||
|
@ -3,7 +3,7 @@ import TClient from '../client.js';
|
|||||||
export default {
|
export default {
|
||||||
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 Discord.SlashCommandBuilder()
|
data: new Discord.SlashCommandBuilder()
|
||||||
|
@ -10,7 +10,7 @@ export default {
|
|||||||
({
|
({
|
||||||
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 the rank data from the users instead.');
|
if (member.user.bot) return interaction.reply('Bots don\'t level up, try viewing the rank data from the users 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);
|
||||||
@ -27,13 +27,8 @@ export default {
|
|||||||
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.toLocaleString('en-US')}**`).setThumbnail(member.avatarURL({extension:'png',size:1024}) || member.user.avatarURL({extension:'png',size:1024}) || member.user.defaultAvatarURL).setFooter({text: userData.notificationPing === true ? 'Ping notification enabled' : 'Ping notification disabled'})]})
|
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.toLocaleString('en-US')}**`).setThumbnail(member.avatarURL({extension:'png',size:1024}) || member.user.avatarURL({extension:'png',size:1024}) || member.user.defaultAvatarURL).setFooter({text: userData.notificationPing === true ? 'Ping notification enabled' : 'Ping notification disabled'})]})
|
||||||
},
|
},
|
||||||
leaderboard: ()=>{
|
leaderboard: ()=>{
|
||||||
const messageCountsTotal = allData.reduce((a, b) => a + b.messages, 0);
|
const data = JSON.parse(readFileSync(path.join('./src/database/dailyMsgs.json'), 'utf8')).map((x: Array<number>, i: number, a: any) => {
|
||||||
const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24);
|
return x[1] - ((a[i - 1] || [])[1] || x[1])
|
||||||
|
|
||||||
const dailyMsgsPath = path.join('./src/database/dailyMsgs.json');
|
|
||||||
const data = JSON.parse(readFileSync(dailyMsgsPath, 'utf8')).map((x: Array<number>, i: number, a: any) => {
|
|
||||||
const yesterday = a[i - 1] || [];
|
|
||||||
return x[1] - (yesterday[1] || x[1]);
|
|
||||||
}).slice(1).slice(-60);
|
}).slice(1).slice(-60);
|
||||||
|
|
||||||
// handle negative days
|
// handle negative days
|
||||||
@ -130,32 +125,24 @@ export default {
|
|||||||
ctx.fillStyle = 'white';
|
ctx.fillStyle = 'white';
|
||||||
|
|
||||||
// highest value
|
// highest value
|
||||||
const maxx = graphOrigin[0] + graphSize[0] + textSize;
|
ctx.fillText(previousY[1].toLocaleString('en-US'), graphOrigin[0] + graphSize[0] + textSize, previousY[0] + (textSize / 3));
|
||||||
const maxy = previousY[0] + (textSize / 3);
|
|
||||||
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
|
||||||
|
|
||||||
// lowest value
|
// lowest value
|
||||||
const lowx = graphOrigin[0] + graphSize[0] + textSize;
|
ctx.fillText('0 msgs', graphOrigin[0] + graphSize[0] + textSize, graphOrigin[1] + graphSize[1] + (textSize / 3));
|
||||||
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
|
||||||
ctx.fillText('0 msgs', 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);
|
ctx.fillText('time ->', graphOrigin[0] + (textSize / 2), graphOrigin[1] + graphSize[1] + (textSize));
|
||||||
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
|
||||||
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');
|
interaction.reply({embeds: [
|
||||||
|
new client.embed().setTitle('Ranking leaderboard')
|
||||||
const graphImage = new client.attachmentBuilder(img.toBuffer(), {name: 'dailymsgs.png'})
|
.setDescription(`Level System was created **${Math.floor((Date.now()-client.config.LRSstart)/1000/60/60/24)}** days ago. Since then, a total of **${allData.reduce((a, b)=>a+b.messages, 0).toLocaleString('en-US')}** messages have been sent in this server.`)
|
||||||
const embed = new client.embed().setTitle('Ranking leaderboard')
|
.addFields({name: 'Top users by messages sent:', value: 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')})
|
||||||
.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})
|
|
||||||
.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]})
|
], files: [new client.attachmentBuilder(img.toBuffer(),{name: 'dailymsgs.png'})]})
|
||||||
},
|
},
|
||||||
notification: async()=>{
|
notification: async()=>{
|
||||||
const findUserInMongo = await client.userLevels._content.findById(interaction.user.id);
|
const findUserInMongo = await client.userLevels._content.findById(interaction.user.id);
|
||||||
|
@ -4,14 +4,13 @@ export default {
|
|||||||
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.username}**`).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.members.map((e:Discord.GuildMember)=>`**${e.user.username}**`).join('\n') || '' : ''}`, inline: true},
|
||||||
{name: '🔹 Permissions', value: `${permissions.includes('Administrator') ? ['Administrator'] : permissions.join(', ') || 'None'}`, inline: true}
|
{name: '🔹 Permissions', value: `${permissions.includes('Administrator') ? ['Administrator'] : permissions.join(', ').replace(/([a-z])([A-Z])/g, '$1 $2') || 'No permissions'}`, inline: true}
|
||||||
)]})
|
)]})// https://stackoverflow.com/questions/15343163/add-a-space-between-two-words - For anonymous programmer, you know who I am talking to. You're welcome...
|
||||||
},
|
},
|
||||||
data: new Discord.SlashCommandBuilder()
|
data: new Discord.SlashCommandBuilder()
|
||||||
.setName('roleinfo')
|
.setName('roleinfo')
|
||||||
|
@ -13,7 +13,7 @@ export default {
|
|||||||
|
|
||||||
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.command.default.data.name.length), columns[0].length) + 2;
|
const nameLength = Math.max(...includedCommands.map(x=>x.command.default.data.name.length), columns[0].length) + 2;
|
||||||
const amountLength = Math.max(...includedCommands.map(x=>x.uses.toString().length), columns[1].length) + 1;
|
const 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'];
|
||||||
|
@ -36,12 +36,12 @@ export default {
|
|||||||
if (client.config.mainServer.id === interaction.guildId) {
|
if (client.config.mainServer.id === interaction.guildId) {
|
||||||
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.bottech)) return client.youNeedRole(interaction, 'bottech');
|
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.bottech)) return client.youNeedRole(interaction, 'bottech');
|
||||||
}
|
}
|
||||||
if ((await client.suggestion._content.findById(suggestionIDReply)).state == 'Rejected') return interaction.reply({content: 'This suggestion\'s state is locked and cannot be modified.', ephemeral: true});
|
if ((await client.suggestion._content.findById(suggestionIDReply)).state === 'Rejected') return interaction.reply({content: 'This suggestion\'s state is locked and cannot be modified.', ephemeral: true});
|
||||||
(await client.users.fetch(userid)).send({embeds: [new client.embed()
|
(await client.users.fetch(userid)).send({embeds: [new client.embed()
|
||||||
.setColor(client.config.embedColorGreen)
|
.setColor(client.config.embedColorGreen)
|
||||||
.setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size: 256})})
|
.setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size: 256})})
|
||||||
.setTitle('Your suggestion has been approved.')
|
.setTitle('Your suggestion has been approved.')
|
||||||
.setDescription(`> **Your suggestion:**\n${theirIdea}\n> **Their message:**\n${replyInDM.length == null ? '*No message from them.*' : replyInDM}`)
|
.setDescription(`> **Your suggestion:**\n${theirIdea}\n> **Their message:**\n${replyInDM.length === null ? '*No message from them.*' : replyInDM}`)
|
||||||
.setFooter({text: `Timestamp: ${timeFormatting} | Suggestion ID: ${suggestionIDReply}`})
|
.setFooter({text: `Timestamp: ${timeFormatting} | Suggestion ID: ${suggestionIDReply}`})
|
||||||
]});
|
]});
|
||||||
await client.suggestion._content.findByIdAndUpdate(suggestionIDReply, {state: 'Approved'});
|
await client.suggestion._content.findByIdAndUpdate(suggestionIDReply, {state: 'Approved'});
|
||||||
@ -51,12 +51,12 @@ export default {
|
|||||||
if (client.config.mainServer.id === interaction.guildId) {
|
if (client.config.mainServer.id === interaction.guildId) {
|
||||||
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.bottech)) return client.youNeedRole(interaction, 'bottech');
|
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.bottech)) return client.youNeedRole(interaction, 'bottech');
|
||||||
}
|
}
|
||||||
if ((await client.suggestion._content.findById(suggestionIDReply)).state == 'Approved') return interaction.reply({content: 'This suggestion\'s state is locked and cannot be modified.', ephemeral: true});
|
if ((await client.suggestion._content.findById(suggestionIDReply)).state === 'Approved') return interaction.reply({content: 'This suggestion\'s state is locked and cannot be modified.', ephemeral: true});
|
||||||
(await client.users.fetch(userid)).send({embeds: [new client.embed()
|
(await client.users.fetch(userid)).send({embeds: [new client.embed()
|
||||||
.setColor(client.config.embedColorRed)
|
.setColor(client.config.embedColorRed)
|
||||||
.setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size: 256})})
|
.setAuthor({name: interaction.user.username, iconURL: interaction.user.avatarURL({size: 256})})
|
||||||
.setTitle('Your suggestion has been rejected.')
|
.setTitle('Your suggestion has been rejected.')
|
||||||
.setDescription(`> **Your suggestion:**\n${theirIdea}\n> **Their message:**\n${replyInDM.length == null ? '*No message from them.*' : replyInDM}`)
|
.setDescription(`> **Your suggestion:**\n${theirIdea}\n> **Their message:**\n${replyInDM.length === null ? '*No message from them.*' : replyInDM}`)
|
||||||
.setFooter({text: `Timestamp: ${timeFormatting} | Suggestion ID: ${suggestionIDReply}`})
|
.setFooter({text: `Timestamp: ${timeFormatting} | Suggestion ID: ${suggestionIDReply}`})
|
||||||
]});
|
]});
|
||||||
await client.suggestion._content.findByIdAndUpdate(suggestionIDReply, {state: 'Rejected'});
|
await client.suggestion._content.findByIdAndUpdate(suggestionIDReply, {state: 'Rejected'});
|
||||||
|
@ -15,14 +15,14 @@ export default {
|
|||||||
const member = interaction.options.getMember('member') as Discord.GuildMember;
|
const member = interaction.options.getMember('member') as Discord.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()
|
interaction.reply({embeds: [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.username}`)
|
.setTitle(`${user.bot ? 'Bot' : 'User'} Info: ${user.username}`)
|
||||||
.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]})
|
]})
|
||||||
} 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;
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
import path from 'node:path';
|
|
||||||
import { readFileSync, writeFileSync } from 'node:fs';
|
|
||||||
import moment from 'moment';
|
|
||||||
export class Database {
|
|
||||||
public _dataType: string;
|
|
||||||
public _path: string;
|
|
||||||
public _interval?: NodeJS.Timer;
|
|
||||||
public _saveNotifs: boolean;
|
|
||||||
public _content: any;
|
|
||||||
constructor(dir: string, dataType: string){
|
|
||||||
this._dataType = dataType;
|
|
||||||
this._path = path.resolve(dir);
|
|
||||||
this._interval = undefined;
|
|
||||||
this._saveNotifs = true;
|
|
||||||
this._content = dataType === 'array' ? [] : {};
|
|
||||||
}
|
|
||||||
addData(data: any, data1?: any){
|
|
||||||
if (Array.isArray(this._content)) this._content.push(data);
|
|
||||||
else if (typeof this._content === 'object') this._content[data] = data1;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
removeData(key: any, type: number, element: any){
|
|
||||||
if (this._dataType === 'array'){
|
|
||||||
({
|
|
||||||
0: ()=>this._content = this._content.filter((x:any)=>x!=key),
|
|
||||||
1: ()=>this._content = this._content.filter((x:any)=>x[element]!=key)
|
|
||||||
})[type]()
|
|
||||||
} else if (this._dataType === 'object') delete this._content[key];
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
initLoad(){
|
|
||||||
this._content = JSON.parse(readFileSync(this._path, {encoding: 'utf8'}));
|
|
||||||
console.log(this._path + ' Database loaded');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
forceSave(db=this, force=false){
|
|
||||||
const oldJson = readFileSync(db._path, {encoding: 'utf8'});
|
|
||||||
const newJson = JSON.stringify(db._content);
|
|
||||||
if (oldJson !== newJson || force){
|
|
||||||
writeFileSync(this._path, JSON.stringify(this._content, null, 2));
|
|
||||||
if (this._saveNotifs) console.log(`[${moment().format('DD/MM/YY HH:mm:ss')}] ` + this._path + ' DB saved');
|
|
||||||
}
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
intervalSave(milliseconds?: number){
|
|
||||||
this._interval = setInterval(()=>this.forceSave(this), milliseconds || 60000);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
stopInterval(){
|
|
||||||
if (this._interval) clearInterval(this._interval);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
disableSaveNotifs(){
|
|
||||||
this._saveNotifs = false;
|
|
||||||
console.log(this._path + ' "DB saved" Notifications disabled');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,8 +3,7 @@ import TClient from '../client.js';
|
|||||||
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 banLog = (await member.guild.fetchAuditLogs({ limit: 1, type: AuditLogEvent.MemberBanAdd })).entries.first();
|
||||||
const banLog = fetchBanlog.entries.first();
|
|
||||||
if (!banLog) return console.log(`Member was banned from ${member.guild.name} but no audit log for this member.`)
|
if (!banLog) return console.log(`Member was banned from ${member.guild.name} but no audit log for this member.`)
|
||||||
const {executor, target, reason } = banLog;
|
const {executor, target, reason } = banLog;
|
||||||
if (target.id === member.user.id) {
|
if (target.id === member.user.id) {
|
||||||
|
@ -3,8 +3,7 @@ import TClient from '../client.js';
|
|||||||
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 unbanLog = (await member.guild.fetchAuditLogs({limit: 1, type: AuditLogEvent.MemberBanRemove})).entries.first();
|
||||||
const unbanLog = fetchUnbanlog.entries.first();
|
|
||||||
if (!unbanLog) return console.log(`User was unbanned from ${member.guild.name} but no audit log for this user.`)
|
if (!unbanLog) return console.log(`User 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) (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
if (target.id === member.user.id) (client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [
|
||||||
|
@ -21,13 +21,12 @@ export default {
|
|||||||
const newInvites = await member.guild.invites.fetch();
|
const newInvites = await member.guild.invites.fetch();
|
||||||
const usedInvite = newInvites.find((inv:Discord.Invite)=>client.invites.get(inv.code)?.uses < inv.uses);
|
const usedInvite = newInvites.find((inv:Discord.Invite)=>client.invites.get(inv.code)?.uses < inv.uses);
|
||||||
newInvites.forEach((inv:Discord.Invite)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviterId, channel: inv.channel.name}));
|
newInvites.forEach((inv:Discord.Invite)=>client.invites.set(inv.code,{uses: inv.uses, creator: inv.inviterId, channel: inv.channel.name}));
|
||||||
const evadedCase = await client.punishments._content.findOne({'member': member.user.id, type: 'mute', expired: undefined});
|
|
||||||
(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(`${isBot} Joined: ${member.user.username}`).setDescription(`<@${member.user.id}>\n\`${member.user.id}\``).setFooter({text: `Total members: ${index}${suffix}`}).addFields(
|
new client.embed().setColor(client.config.embedColorGreen).setTimestamp().setThumbnail(member.user.displayAvatarURL({size: 2048})).setTitle(`${isBot} Joined: ${member.user.username}`).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: '🔹 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?.username}**\nChannel: **#${usedInvite.channel.name}**` : 'No invite data could be fetched.'}
|
{name: '🔹 Invite Data:', value: usedInvite ? `Invite: \`${usedInvite.code}\`\nCreated by: **${usedInvite.inviter?.username}**\nChannel: **#${usedInvite.channel.name}**` : 'No invite data could be fetched.'}
|
||||||
)]});
|
)]});
|
||||||
if (evadedCase){
|
if (await client.punishments._content.findOne({'member': member.user.id, type: 'mute', expired: undefined})){
|
||||||
(client.channels.resolve(client.config.mainServer.channels.dcmod_chat) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColorYellow).setTitle('Case evasion detected').setDescription([
|
(client.channels.resolve(client.config.mainServer.channels.dcmod_chat) as Discord.TextChannel).send({embeds: [new client.embed().setColor(client.config.embedColorYellow).setTitle('Case evasion detected').setDescription([
|
||||||
`**${member.user.username}** (\`${member.user.id}\`) has been detected for case evasion.`,
|
`**${member.user.username}** (\`${member.user.id}\`) has been detected for case evasion.`,
|
||||||
'Timeout has been automatically added. (25 days)'
|
'Timeout has been automatically added. (25 days)'
|
||||||
|
@ -3,7 +3,6 @@ import TClient from '../client.js';
|
|||||||
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();
|
(await (invite.guild as Discord.Guild).invites.fetch()).forEach(inv=>client.invites.set(inv.code,{uses: inv.code, creator: inv.inviterId, channel: inv.channel.name}))
|
||||||
newInvites.forEach(inv=>client.invites.set(inv.code,{uses: inv.code, creator: inv.inviterId, channel: inv.channel.name}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ export default {
|
|||||||
const msgarr = message.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n?1234567890]/g, '').split(' ');
|
const msgarr = message.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n?1234567890]/g, '').split(' ');
|
||||||
let automodded: boolean;
|
let automodded: boolean;
|
||||||
|
|
||||||
const Whitelist = [] // Array of channel ids for automod to be disabled in (Disables bannedWords and advertisement, mind you.)
|
//const Whitelist = [] // Array of channel ids for automod to be disabled in (Disables bannedWords and advertisement, mind you.)
|
||||||
|
|
||||||
async function repeatedMessages(thresholdTime:number, thresholdAmount:number, type:string, muteTime:string, muteReason:string){
|
async function repeatedMessages(thresholdTime:number, thresholdAmount:number, type:string, muteTime:string, muteReason:string){
|
||||||
if (client.repeatedMessages[message.author.id]){
|
if (client.repeatedMessages[message.author.id]){
|
||||||
@ -35,7 +35,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (client.config.botSwitches.automod && !message.member.roles.cache.has(client.config.mainServer.roles.admin) && message.guildId == client.config.mainServer.id){
|
if (client.config.botSwitches.automod && !message.member.roles.cache.has(client.config.mainServer.roles.admin) && message.guildId == client.config.mainServer.id){
|
||||||
if (await client.bannedWords._content.findById(msgarr) && !Whitelist.includes(message.channelId)){
|
if (await client.bannedWords._content.findById(msgarr)/* && !Whitelist.includes(message.channelId) */){
|
||||||
automodded = true;
|
automodded = true;
|
||||||
message.delete().catch(()=>console.log('bannedWords automod; msg got possibly deleted by another bot.'));
|
message.delete().catch(()=>console.log('bannedWords automod; msg got possibly deleted by another bot.'));
|
||||||
message.channel.send('That word isn\'t allowed here.').then(x=>setTimeout(()=>x.delete(), 10000));
|
message.channel.send('That word isn\'t allowed here.').then(x=>setTimeout(()=>x.delete(), 10000));
|
||||||
|
@ -3,7 +3,6 @@ import TClient from '../client.js';
|
|||||||
export default {
|
export default {
|
||||||
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 disabledChannels = ['548032776830582794', '541677709487505408', '949380187668242483']
|
const disabledChannels = ['548032776830582794', '541677709487505408', '949380187668242483']
|
||||||
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;
|
||||||
if (Discord.DiscordAPIError.name === '10008') return console.log(client.logTime(), 'Caught an unexpected error returned by Discord API. (Unknown Message)');
|
if (Discord.DiscordAPIError.name === '10008') return console.log(client.logTime(), 'Caught an unexpected error returned by Discord API. (Unknown Message)');
|
||||||
@ -15,6 +14,6 @@ export default {
|
|||||||
)
|
)
|
||||||
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})
|
(client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [embed], files: attachments})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,7 @@ import Discord from 'discord.js';
|
|||||||
import TClient from '../client.js';
|
import TClient from '../client.js';
|
||||||
export default {
|
export default {
|
||||||
run(client:TClient, reaction:Discord.MessageReaction, user:Discord.User){
|
run(client:TClient, reaction:Discord.MessageReaction, user:Discord.User){
|
||||||
if (!client.config.botSwitches.logs) return;
|
if (!client.config.botSwitches.logs || reaction.message.guildId != client.config.mainServer.id || reaction.message.partial) return;
|
||||||
if (reaction.message.guildId != client.config.mainServer.id || reaction.message.partial) return;
|
|
||||||
if (reaction.emoji.name === '🖕') return (client.channels.cache.get(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${user.username} (${user.id})`, iconURL: `${user.displayAvatarURL()}`}).setTitle('Message reaction').setDescription(`<@${user.id}>\nRemoved a reaction from the message.\n**Emoji**\n${reaction.emoji.name}\n**Channel**\n<#${reaction.message.channelId}>`)]})
|
if (reaction.emoji.name === '🖕') return (client.channels.cache.get(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds:[new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${user.username} (${user.id})`, iconURL: `${user.displayAvatarURL()}`}).setTitle('Message reaction').setDescription(`<@${user.id}>\nRemoved a reaction from the message.\n**Emoji**\n${reaction.emoji.name}\n**Channel**\n<#${reaction.message.channelId}>`)]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@ import TClient from '../client.js';
|
|||||||
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', '949380187668242483']
|
if (oldMsg.guild?.id != client.config.mainServer.id || oldMsg.author === null || oldMsg?.author.bot || oldMsg.partial || newMsg.partial || !newMsg.member || ['548032776830582794', '541677709487505408', '949380187668242483'].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;
|
|
||||||
if (await client.bannedWords._content.findOne({_id:newMsg.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n]/g, ' ').split(' ')}) && (!client.isStaff(newMsg.member))) newMsg.delete();
|
if (await client.bannedWords._content.findOne({_id:newMsg.content.toLowerCase().replaceAll(/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\n]/g, ' ').split(' ')}) && (!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.username} (${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 Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents(new Discord.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.username} (${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 Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents(new Discord.ButtonBuilder().setStyle(5).setURL(`${oldMsg.url}`).setLabel('Jump to message'))]});
|
||||||
|
10
src/index.ts
10
src/index.ts
@ -31,9 +31,7 @@ client.on('ready', async()=>{
|
|||||||
function DZ(error:Error, type:string){// Yes, I may have shiternet but I don't need to wake up to like a hundred messages or so.
|
function DZ(error:Error, type:string){// Yes, I may have shiternet but I don't need to wake up to like a hundred messages or so.
|
||||||
if (['getaddrinfo ENOTFOUND discord.com', 'getaddrinfo EAI_AGAIN discord.com', '[Error: 30130000:error:0A000410:SSL'].includes(error.message)) return;
|
if (['getaddrinfo ENOTFOUND discord.com', 'getaddrinfo EAI_AGAIN discord.com', '[Error: 30130000:error:0A000410:SSL'].includes(error.message)) return;
|
||||||
//console.error(error);
|
//console.error(error);
|
||||||
const channel = client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel | null;
|
(client.channels.resolve(client.config.mainServer.channels.errors) as Discord.TextChannel | null)?.send({embeds: [new client.embed().setColor('#560000').setTitle('Error caught!').setFooter({text: 'Error type: ' + type}).setDescription(`**Error:**\n\`\`\`${error.message}\`\`\`**Stack:**\n\`\`\`${`${error.stack}`.slice(0, 2500)}\`\`\``)]})
|
||||||
// vvv Oh yes, that looks really hot.
|
|
||||||
channel?.send({embeds: [new client.embed().setColor('#560000').setTitle('Error caught!').setFooter({text: 'Error type: ' + type}).setDescription(`**Error:**\n\`\`\`${error.message}\`\`\`**Stack:**\n\`\`\`${`${error.stack}`.slice(0, 2500)}\`\`\``)]})
|
|
||||||
}
|
}
|
||||||
process.on('unhandledRejection', (error: Error)=>DZ(error, 'unhandledRejection'));
|
process.on('unhandledRejection', (error: Error)=>DZ(error, 'unhandledRejection'));
|
||||||
process.on('uncaughtException', (error: Error)=>DZ(error, 'uncaughtException'));
|
process.on('uncaughtException', (error: Error)=>DZ(error, 'uncaughtException'));
|
||||||
@ -72,16 +70,14 @@ 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 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!');
|
console.log(client.logTime(), await client.punishments.removePunishment(punishment._id, client.user.id, 'Time\'s up!'));
|
||||||
console.log(client.logTime(), unpunishResult);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const formattedDate = Math.floor((now - lrsStart)/1000/60/60/24);
|
const formattedDate = Math.floor((now - client.config.LRSstart)/1000/60/60/24);
|
||||||
const dailyMsgs = JSON.parse(readFileSync('./src/database/dailyMsgs.json', {encoding: 'utf8'}))
|
const dailyMsgs = JSON.parse(readFileSync('./src/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
|
||||||
|
Loading…
Reference in New Issue
Block a user