mirror of
https://github.com/toast-ts/Daggerbot-TS.git
synced 2024-12-28 08:55:38 -05:00
Use Object literal lookups and add User-Agent
This commit is contained in:
parent
1abc442f1e
commit
7e711d62be
@ -3,22 +3,20 @@ 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 Sub = interaction.options.getSubcommand();
|
|
||||||
const word = interaction.options.getString('word');
|
const word = interaction.options.getString('word');
|
||||||
switch(Sub){
|
({
|
||||||
case 'view':
|
add: ()=>{
|
||||||
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})
|
|
||||||
break;
|
|
||||||
case 'add':
|
|
||||||
if (client.bannedWords._content.includes(word)) return interaction.reply({content: `\`${word}\` is already added.`, ephemeral: true});
|
if (client.bannedWords._content.includes(word)) return interaction.reply({content: `\`${word}\` is already added.`, ephemeral: true});
|
||||||
client.bannedWords.addData(word).forceSave();
|
client.bannedWords.addData(word).forceSave();
|
||||||
interaction.reply(`Successfully added \`${word}\` to the list.`)
|
interaction.reply(`Successfully added \`${word}\` to the list.`)
|
||||||
break;
|
},
|
||||||
case 'remove':
|
remove: ()=>{
|
||||||
if (client.bannedWords._content.includes(word) == false) return interaction.reply({content: `\`${word}\` doesn't exist on the list.`, ephemeral: true});
|
if (client.bannedWords._content.includes(word) == false) return interaction.reply({content: `\`${word}\` doesn't exist on the list.`, ephemeral: true});
|
||||||
client.bannedWords.removeData(word, 0, 0).forceSave();
|
client.bannedWords.removeData(word, 0, 0).forceSave();
|
||||||
interaction.reply(`Successfully removed \`${word}\` from the list.`)
|
interaction.reply(`Successfully removed \`${word}\` from the list.`)
|
||||||
}
|
},
|
||||||
|
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()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('bannedwords')
|
.setName('bannedwords')
|
||||||
|
@ -4,50 +4,48 @@ import { Punishment } from "src/typings/interfaces";
|
|||||||
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 Subb = interaction.options.getSubcommand();
|
|
||||||
const caseId = interaction.options.getInteger('id');
|
const caseId = interaction.options.getInteger('id');
|
||||||
if (Subb == 'update'){
|
({
|
||||||
const reason = interaction.options.getString('reason')
|
update: async()=>{
|
||||||
client.punishments._content.find((x:Punishment)=>x.id==caseId).reason = reason;
|
const reason = interaction.options.getString('reason');
|
||||||
client.punishments.forceSave();
|
client.punishments._content.find((x:Punishment)=>x.id==caseId).reason = reason;
|
||||||
const embed = new client.embed().setColor(client.config.embedColorGreen).setTitle('Case updated').setDescription(`Case #${caseId} has been successfully updated with new reason:\n\`${reason}\``);
|
client.punishments.forceSave();
|
||||||
await interaction.reply({embeds: [embed]})
|
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}\``)]})
|
||||||
} else if (Subb == 'view'){
|
},
|
||||||
const punishment = client.punishments._content.find((x:Punishment)=>x.id==caseId);
|
view: ()=>{
|
||||||
if (!punishment) return interaction.reply('Invalid case #');
|
const punishment = client.punishments._content.find((x:Punishment)=>x.id==caseId);
|
||||||
const cancelledBy = punishment.expired ? client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id) : null;
|
if (!punishment) return interaction.reply('Invalid case #');
|
||||||
const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null;
|
const cancelledBy = punishment.expired ? client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id) : null;
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(punishment.time).setTitle(`${client.formatPunishmentType(punishment, client, cancels)} | Case #${punishment.id}`).addFields(
|
const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null;
|
||||||
{name: '🔹 User', value: `<@${punishment.member}> \`${punishment.member}\``, inline: true},
|
const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(punishment.time).setTitle(`${client.formatPunishmentType(punishment, client, cancels)} | Case #${punishment.id}`).addFields(
|
||||||
{name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true},
|
{name: '🔹 User', value: `<@${punishment.member}> \`${punishment.member}\``, inline: true},
|
||||||
{name: '\u200b', value: '\u200b', inline: true},
|
{name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true},
|
||||||
{name: '🔹 Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true})
|
{name: '\u200b', value: '\u200b', inline: true},
|
||||||
if (punishment.duration){
|
{name: '🔹 Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true})
|
||||||
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.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites case #${cancels.id} with reason \`${cancels.reason}\``})
|
||||||
|
interaction.reply({embeds: [embed]});
|
||||||
|
},
|
||||||
|
member: ()=>{
|
||||||
|
// if caseid is user id, show their punishment history sorted by most recent.
|
||||||
|
const user = (interaction.options.getUser('user') as Discord.User);
|
||||||
|
if (user.bot) return interaction.reply(`<@${user.id}>'s punishment history cannot be viewed.`)
|
||||||
|
const punishment = client.punishments._content.find((x:Punishment)=>x.member===user.id);
|
||||||
|
if (!punishment) return interaction.reply(`<@${user.id}> has a clean record.`)
|
||||||
|
const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null;
|
||||||
|
const userPunishment = client.punishments._content.filter((x:Punishment)=>x.member==user.id).sort((a:Punishment,b:Punishment)=>a.time-b.time).map((punishment:Punishment)=>{
|
||||||
|
return {
|
||||||
|
name: `${client.formatPunishmentType(punishment, client, cancels)} | 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 #${client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id).id}` : ''}${punishment.cancels ? `\nOverwrites case #${punishment.cancels}` : ''}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 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');
|
||||||
|
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))]});
|
||||||
}
|
}
|
||||||
if (punishment.expired) embed.addFields({name: '🔹 Expired', value: `This case has been overwritten by case #${cancelledBy.id} for reason \`${cancelledBy.reason}\``})
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
if (punishment.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites case #${cancels.id} with reason \`${cancels.reason}\``})
|
|
||||||
interaction.reply({embeds: [embed]});
|
|
||||||
} else {
|
|
||||||
// if caseid is user id, show their punishment history sorted by most recent.
|
|
||||||
const user = (interaction.options.getUser('user') as Discord.User);
|
|
||||||
if (user.bot) return interaction.reply(`<@${user.id}>'s punishment history cannot be viewed.`)
|
|
||||||
const punishment = client.punishments._content.find((x:Punishment)=>x.member===user.id);
|
|
||||||
if (!punishment) return interaction.reply(`<@${user.id}> has a clean record.`)
|
|
||||||
const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null;
|
|
||||||
const userPunishment = client.punishments._content.filter((x:Punishment)=>x.member==user.id).sort((a:Punishment,b:Punishment)=>a.time-b.time).map((punishment:Punishment)=>{
|
|
||||||
return {
|
|
||||||
name: `${client.formatPunishmentType(punishment, client, cancels)} | 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 #${client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id).id}` : ''}${punishment.cancels ? `\nOverwrites case #${punishment.cancels}` : ''}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 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');
|
|
||||||
|
|
||||||
const pageNum = interaction.options.getInteger('page') ?? 1;
|
|
||||||
const embed = 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: [embed]});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('case')
|
.setName('case')
|
||||||
|
@ -22,8 +22,8 @@ const removeUsername = (text: string)=>{
|
|||||||
export default {
|
export default {
|
||||||
async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>) {
|
async 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');
|
||||||
switch (interaction.options.getSubcommand()){
|
({
|
||||||
case 'eval':
|
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';
|
||||||
@ -59,16 +59,8 @@ export default {
|
|||||||
{name: 'Output', value: `\`\`\`${removeUsername(output).slice(0,1016)}\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]}));
|
||||||
break
|
},
|
||||||
case 'logs':
|
update: async()=>{
|
||||||
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}\``))
|
|
||||||
break
|
|
||||||
case 'restart':
|
|
||||||
client.userLevels.forceSave();
|
|
||||||
interaction.reply(`Uptime before restarting: **${client.formatTime(client.uptime as number, 3, {commas: true, longNames: true})}**`).then(()=>exec('pm2 restart Daggerbot'))
|
|
||||||
break
|
|
||||||
case 'update':
|
|
||||||
var githubRepo = {owner: 'AnxietyisReal', repo: 'Daggerbot-TS', ref: 'HEAD'}
|
var githubRepo = {owner: 'AnxietyisReal', repo: 'Daggerbot-TS', ref: 'HEAD'}
|
||||||
const octokit = new Octokit({timeZone: 'Australia/NSW', userAgent: 'Daggerbot'})
|
const octokit = new Octokit({timeZone: 'Australia/NSW', userAgent: 'Daggerbot'})
|
||||||
const fetchCommitMsg = await octokit.repos.getCommit(githubRepo).then(x=>x.data.commit.message);
|
const fetchCommitMsg = await octokit.repos.getCommit(githubRepo).then(x=>x.data.commit.message);
|
||||||
@ -83,12 +75,8 @@ export default {
|
|||||||
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)
|
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)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break
|
},
|
||||||
case 'statsgraph':
|
presence: ()=>{
|
||||||
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()}***`);
|
|
||||||
break
|
|
||||||
case 'presence':
|
|
||||||
function convertType(Type?: number){
|
function convertType(Type?: number){
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case 0: return 'Playing';
|
case 0: return 'Playing';
|
||||||
@ -117,7 +105,20 @@ export default {
|
|||||||
`Name: **${currentActivities[0].name}**`,
|
`Name: **${currentActivities[0].name}**`,
|
||||||
`URL: \`${currentActivities[0].url}\``
|
`URL: \`${currentActivities[0].url}\``
|
||||||
].join('\n'))
|
].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: ()=>{
|
||||||
|
client.userLevels.forceSave();
|
||||||
|
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')
|
||||||
|
@ -2,33 +2,15 @@ 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'>){
|
||||||
switch(interaction.options.getString('question')){
|
({
|
||||||
case 'srp':
|
srp: ()=>interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('When will SRP (Survival Roleplay) return?').setImage('https://cdn.discordapp.com/attachments/1023338018720989305/1059259250242752562/IMG_8964.png')]}),
|
||||||
const embed = new client.embed().setColor(client.config.embedColor).setTitle('When will SRP (Survival Roleplay) return?').setImage('https://cdn.discordapp.com/attachments/1023338018720989305/1059259250242752562/IMG_8964.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')]}),
|
||||||
interaction.reply({embeds: [embed]})
|
vtcR: ()=>interaction.reply(`You can get the <@&${client.config.mainServer.roles.vtcmember}> role from <#802283932430106624> by reacting <@282859044593598464>'s message with :truck:\n*VTC skin can also be found in <#801975222609641472> as well.*`),
|
||||||
break;
|
mpR: ()=>interaction.reply(`You can get the <@&${client.config.mainServer.roles.mpplayer}> role from <#802283932430106624> by reacting <@282859044593598464>'s message with :tractor:`),
|
||||||
case 'dlskin':
|
ytscam: ()=>interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Scammers in YouTube comments section').setDescription('If you ever see a comment mentioning a giveaway or anything else, **it\'s a scam!**\nYou should report it to YouTube and move on or ignore it.\nP.S: They\'re on every channel and not just Daggerwin.').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1068078284996345916/image.png')]}),
|
||||||
const embed1 = 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');
|
fsShader: ()=>interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Clearing your shader cache folder').setDescription('If your game kees crashing shortly after opening your game, then the shaders might be an issue.\nTo resolve this, you can go to `Documents/My Games/FarmingSimulator2022` and delete the folder called `shader_cache`').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195687970943016/unknown.png')]}),
|
||||||
interaction.reply({embeds: [embed1]})
|
fsLogfile: ()=>interaction.reply({embeds: [new client.embed().setColor(client.config.embedColor).setTitle('Uploading your log file').setDescription('You can find `log.txt` in `Documents/My Games/FarmingSimulator2022` and upload it into <#596989522395398144> along with your issue, so people can assist you further and help you resolve.').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195643528101958/unknown.png')]})
|
||||||
break;
|
} as any)[interaction.options.getString('question', true)]();
|
||||||
case 'vtcR':
|
|
||||||
interaction.reply(`You can get the <@&${client.config.mainServer.roles.vtcmember}> role from <#802283932430106624> by reacting the ProBot\'s message with :truck:\n*VTC skin can also be found in <#801975222609641472> as well.*`)
|
|
||||||
break;
|
|
||||||
case 'mpR':
|
|
||||||
interaction.reply(`You can get the <@&${client.config.mainServer.roles.mpplayer}> role from <#802283932430106624> by reacting the ProBot\'s message with :tractor:`)
|
|
||||||
break;
|
|
||||||
case 'fsShader':
|
|
||||||
const embed2 = new client.embed().setColor(client.config.embedColor).setTitle('Clearing your shader cache folder').setDescription('If your game kees crashing shortly after opening your game, then the shaders might be an issue.\nTo resolve this, you can go to `Documents/My Games/FarmingSimulator2022` and delete the folder called `shader_cache`').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195687970943016/unknown.png');
|
|
||||||
interaction.reply({embeds: [embed2]})
|
|
||||||
break;
|
|
||||||
case 'fsLogfile':
|
|
||||||
const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('Uploading your log file').setDescription('You can find `log.txt` in `Documents/My Games/FarmingSimulator2022` and upload it into <#596989522395398144> along with your issue, so people can assist you further and help you resolve.').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195643528101958/unknown.png');
|
|
||||||
interaction.reply({embeds: [embed3]})
|
|
||||||
break;
|
|
||||||
case 'ytscam':
|
|
||||||
const embed4 = new client.embed().setColor(client.config.embedColor).setTitle('Scammers in YouTube comments section').setDescription('If you ever see a comment mentioning a giveaway or anything else, **it\'s a scam!**\nYou should report it to YouTube and move on or ignore it.\nP.S: They\'re on every channel and not just Daggerwin.').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1068078284996345916/image.png');
|
|
||||||
interaction.reply({embeds: [embed4]})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('faq')
|
.setName('faq')
|
||||||
|
@ -18,7 +18,7 @@ async function MPdata(client:TClient, interaction:Discord.ChatInputCommandIntera
|
|||||||
|
|
||||||
// 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}) // Finally got around to fixing the command when it cannot ping the host.
|
FSserver = await client.axios.get(completedURL, {timeout: 2588, headers: {'User-Agent': `Daggerbot - mp cmd/axios ${client.axios.VERSION}`}}) // Finally got around to fixing the command when it cannot ping the host.
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
// Blame Nawdic & RedRover92
|
// Blame Nawdic & RedRover92
|
||||||
embed.setTitle('Host is not responding.');
|
embed.setTitle('Host is not responding.');
|
||||||
@ -37,9 +37,8 @@ export default {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Subb = interaction.options.getSubcommand();
|
({
|
||||||
switch (Subb){
|
status: async()=>{
|
||||||
case 'status':
|
|
||||||
const embed0 = new client.embed();
|
const embed0 = new client.embed();
|
||||||
const FSserver0 = await MPdata(client, interaction, embed0);
|
const FSserver0 = await MPdata(client, interaction, embed0);
|
||||||
if (!FSserver0?.data) return console.log('FSserver0 failed - status');
|
if (!FSserver0?.data) return console.log('FSserver0 failed - status');
|
||||||
@ -60,11 +59,66 @@ export default {
|
|||||||
console.log(err)
|
console.log(err)
|
||||||
interaction.reply('FSserver0 Placeholder')
|
interaction.reply('FSserver0 Placeholder')
|
||||||
};
|
};
|
||||||
break;
|
},
|
||||||
case 'players':
|
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 DBURL = MPDB.findOne({where: {serverId: interaction.guildId}})
|
||||||
|
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](${(await DBURL).ip}/mods.html) **|** [Direct Download](${(await DBURL).ip}/all_mods_download?onlyActive=true)`,
|
||||||
|
'**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)',
|
||||||
|
'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 (!interaction.member.roles.cache.has(client.config.mainServer.roles.mpmanager) && !interaction.member.roles.cache.has(client.config.mainServer.roles.bottech) && !interaction.member.roles.cache.has(client.config.mainServer.roles.admin)) return client.youNeedRole(interaction, 'mpmanager');
|
||||||
|
MPDB.sync();
|
||||||
|
const address = interaction.options.getString('address');
|
||||||
|
if (!address){
|
||||||
|
try {
|
||||||
|
const Url = await MPDB.findOne({where:{serverId: 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})`);
|
||||||
|
const Url = await MPDB.create({
|
||||||
|
serverId: interaction.guildId,
|
||||||
|
ip: newURL[0],
|
||||||
|
code: newURL[1],
|
||||||
|
timesUpdated: 0
|
||||||
|
});
|
||||||
|
return interaction.reply(`Successfully set the URL to ${Url.ip}`)
|
||||||
|
} catch(err){
|
||||||
|
if (err.name == 'SequelizeUniqueConstraintError'){
|
||||||
|
const AffectedRows = await MPDB.update({ip: newURL[0], code: newURL[1]},{where:{serverId: interaction.guildId}});
|
||||||
|
await MPDB.increment('timesUpdated',{where:{serverId: interaction.guildId}});
|
||||||
|
if (AffectedRows) return interaction.reply(`Successfully updated the URL to ${newURL[0]}`)
|
||||||
|
}else{
|
||||||
|
console.log(err)
|
||||||
|
interaction.reply(`\`MPDB\` has caught an error, notify <@&${client.config.mainServer.roles.bottech}>`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
players: async()=>{
|
||||||
const embed1 = new client.embed();
|
const embed1 = new client.embed();
|
||||||
const data = JSON.parse(fs.readFileSync(path.join(__dirname, '../database/MPPlayerData.json'), {encoding: 'utf8'})).slice(client.statsGraph)
|
const data = JSON.parse(fs.readFileSync(path.join(__dirname, '../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) => {
|
||||||
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
||||||
@ -224,65 +278,8 @@ export default {
|
|||||||
embed1.addFields({name: `${player.name} ${player.isAdmin ? '| admin' : ''}`, value: `Farming for ${(Math.floor(player.uptime/60))} hr, ${('0' + (player.uptime % 60)).slice(-2)} min`})
|
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]})
|
interaction.reply({embeds: [embed1], files: [Image]})
|
||||||
break;
|
}/*,
|
||||||
case 'info':
|
series: ()=>{
|
||||||
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 DBURL = MPDB.findOne({where: {serverId: interaction.guildId}})
|
|
||||||
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](${(await DBURL).ip}/mods.html) **|** [Direct Download](${(await DBURL).ip}/all_mods_download?onlyActive=true)`,
|
|
||||||
'**Filters:** [Click here](https://discord.com/channels/468835415093411861/468835769092669461/926581585938120724)',
|
|
||||||
'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]})
|
|
||||||
break;
|
|
||||||
case 'url':
|
|
||||||
if (!interaction.member.roles.cache.has(client.config.mainServer.roles.mpmanager) && !interaction.member.roles.cache.has(client.config.mainServer.roles.bottech) && !interaction.member.roles.cache.has(client.config.mainServer.roles.admin)) return client.youNeedRole(interaction, 'mpmanager');
|
|
||||||
MPDB.sync();
|
|
||||||
const address = interaction.options.getString('address');
|
|
||||||
|
|
||||||
if (!address){
|
|
||||||
try {
|
|
||||||
const Url = await MPDB.findOne({where:{serverId: 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})`);
|
|
||||||
const Url = await MPDB.create({
|
|
||||||
serverId: interaction.guildId,
|
|
||||||
ip: newURL[0],
|
|
||||||
code: newURL[1],
|
|
||||||
timesUpdated: 0
|
|
||||||
});
|
|
||||||
return interaction.reply(`Successfully set the URL to ${Url.ip}`)
|
|
||||||
} catch(err){
|
|
||||||
if (err.name == 'SequelizeUniqueConstraintError'){
|
|
||||||
const AffectedRows = await MPDB.update({ip: newURL[0], code: newURL[1]},{where:{serverId: interaction.guildId}});
|
|
||||||
await MPDB.increment('timesUpdated',{where:{serverId: interaction.guildId}});
|
|
||||||
if (AffectedRows) return interaction.reply(`Successfully updated the URL to ${newURL[0]}`)
|
|
||||||
}else{
|
|
||||||
console.log(err)
|
|
||||||
interaction.reply(`\`MPDB\` has caught an error, notify <@&${client.config.mainServer.roles.bottech}>`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* case 'series':
|
|
||||||
const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('How to join the Daggerwin MP series')
|
const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('How to join the Daggerwin MP series')
|
||||||
.setDescription([
|
.setDescription([
|
||||||
'To join the Daggerwin MP series, you first need to:',
|
'To join the Daggerwin MP series, you first need to:',
|
||||||
@ -292,8 +289,9 @@ export default {
|
|||||||
'**4:** If you don\'t receive the role within a day or so, please message an Admin and they will sort it out.',
|
'**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.'
|
'**5:** Take a look in <#511657659364147200> to get information on how to join the server.'
|
||||||
].join('\n'));
|
].join('\n'));
|
||||||
interaction.reply({embeds: [embed3]}) */
|
interaction.reply({embeds: [embed3]})
|
||||||
}
|
}*/
|
||||||
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('mp')
|
.setName('mp')
|
||||||
|
@ -6,172 +6,164 @@ import fs from 'node:fs';
|
|||||||
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 subCmd = interaction.options.getSubcommand();
|
({
|
||||||
|
view: ()=>{
|
||||||
|
// fetch user or user interaction sender
|
||||||
|
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.')
|
||||||
|
const embed = new client.embed().setColor(member.displayColor)
|
||||||
|
// information about users progress on level roles
|
||||||
|
const information = client.userLevels._content[member.user.id];
|
||||||
|
|
||||||
if (subCmd === "leaderboard") {
|
const pronounBool = (you: string, they: string) => { // takes 2 words and chooses which to use based on if user did this command on themself
|
||||||
const messageCountsTotal = Object.values<UserLevels>(client.userLevels._content).reduce((a, b) => a + b.messages, 0);
|
if (interaction.user.id === member.user.id) return you || true;
|
||||||
const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24);
|
else return they || false;
|
||||||
|
};
|
||||||
const dailyMsgsPath = path.join(__dirname, '../database/dailyMsgs.json');
|
if (!information) {
|
||||||
const data = JSON.parse(fs.readFileSync(dailyMsgsPath, {encoding: 'utf8'})).map((x: Array<number>, i: number, a: any) => {
|
return interaction.reply(`${pronounBool('You', 'They')} currently don't have a level, send some messages to level up.`)
|
||||||
const yesterday = a[i - 1] || [];
|
|
||||||
return x[1] - (yesterday[1] || x[1]);
|
|
||||||
}).slice(1).slice(-60);
|
|
||||||
|
|
||||||
// handle negative days
|
|
||||||
data.forEach((change: number, i: number) => {
|
|
||||||
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
const maxValue = Math.max(...data);
|
|
||||||
const maxValueArr = maxValue.toString().split('');
|
|
||||||
|
|
||||||
const first_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 1)) * 10 ** (maxValueArr.length - 1);
|
|
||||||
// console.log({ first_graph_top });
|
|
||||||
|
|
||||||
const second_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 2)) * 10 ** (maxValueArr.length - 2);
|
|
||||||
// console.log({ second_graph_top });
|
|
||||||
|
|
||||||
const textSize = 32;
|
|
||||||
|
|
||||||
const canvas = require('canvas');
|
|
||||||
const img = canvas.createCanvas(950, 450);
|
|
||||||
const ctx = img.getContext('2d');
|
|
||||||
|
|
||||||
const graphOrigin = [10, 50];
|
|
||||||
const graphSize = [700, 360];
|
|
||||||
const nodeWidth = graphSize[0] / (data.length - 1);
|
|
||||||
ctx.fillStyle = '#36393f';
|
|
||||||
ctx.fillRect(0, 0, img.width, img.height);
|
|
||||||
|
|
||||||
// grey horizontal lines
|
|
||||||
ctx.lineWidth = 3;
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// console.log({ interval_candidates });
|
const index = Object.entries<UserLevels>(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).map(x => x[0]).indexOf(member.id) + 1;
|
||||||
const chosen_interval = interval_candidates.sort((a, b) => b[2] - a[2])[0];
|
const memberDifference = information.messages - client.userLevels.algorithm(information.level);
|
||||||
// console.log({ chosen_interval });
|
const levelDifference = client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level);
|
||||||
|
|
||||||
let previousY: Array<number> = [];
|
embed.setThumbnail(member.user.avatarURL({ extension: 'png', size: 256}) || member.user.defaultAvatarURL)
|
||||||
|
embed.setAuthor({name: `Ranking for ${member.user.tag}`})
|
||||||
ctx.strokeStyle = '#202225';
|
embed.setTitle(`Level: **${information.level}**\nRank: **${index ? '#' + index : 'last'}**\nProgress: **${information.messages - client.userLevels.algorithm(information.level)}/${client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level)} (${(memberDifference/levelDifference*100).toFixed(2)}%)**\nTotal: **${information.messages}**`);
|
||||||
for (let i = 0; i <= chosen_interval[1]; i++) {
|
interaction.reply({embeds: [embed]})
|
||||||
const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]);
|
},
|
||||||
if (y < graphOrigin[1]) continue;
|
leaderboard: ()=>{
|
||||||
const even = ((i + 1) % 2) === 0;
|
const messageCountsTotal = Object.values<UserLevels>(client.userLevels._content).reduce((a, b) => a + b.messages, 0);
|
||||||
if (even) ctx.strokeStyle = '#2c2f33';
|
const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24);
|
||||||
|
|
||||||
|
const dailyMsgsPath = path.join(__dirname, '../database/dailyMsgs.json');
|
||||||
|
const data = JSON.parse(fs.readFileSync(dailyMsgsPath, {encoding: '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);
|
||||||
|
|
||||||
|
// handle negative days
|
||||||
|
data.forEach((change: number, i: number) => {
|
||||||
|
if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const maxValue = Math.max(...data);
|
||||||
|
const maxValueArr = maxValue.toString().split('');
|
||||||
|
|
||||||
|
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 textSize = 32;
|
||||||
|
|
||||||
|
const canvas = require('canvas');
|
||||||
|
const img = canvas.createCanvas(950, 450);
|
||||||
|
const ctx = img.getContext('2d');
|
||||||
|
|
||||||
|
const graphOrigin = [10, 50];
|
||||||
|
const graphSize = [700, 360];
|
||||||
|
const nodeWidth = graphSize[0] / (data.length - 1);
|
||||||
|
ctx.fillStyle = '#36393f';
|
||||||
|
ctx.fillRect(0, 0, img.width, img.height);
|
||||||
|
|
||||||
|
// grey horizontal lines
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
let 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 = [y, i * chosen_interval[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 30d mark
|
||||||
|
ctx.setLineDash([8, 16]);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.lineTo(graphOrigin[0], y);
|
const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 30));
|
||||||
ctx.lineTo(graphOrigin[0] + graphSize[0], y);
|
ctx.lineTo(lastMonthStart, graphOrigin[1]);
|
||||||
|
ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
if (even) ctx.strokeStyle = '#202225';
|
ctx.setLineDash([]);
|
||||||
previousY = [y, i * chosen_interval[0]];
|
|
||||||
|
// draw points
|
||||||
|
ctx.strokeStyle = client.config.embedColor;
|
||||||
|
ctx.fillStyle = client.config.embedColor;
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
|
||||||
|
function getYCoordinate(value: number) {
|
||||||
|
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastCoords: Array<number> = [];
|
||||||
|
data.forEach((val: number, i: number) => {
|
||||||
|
ctx.beginPath();
|
||||||
|
if (lastCoords) ctx.moveTo(...lastCoords);
|
||||||
|
if (val < 0) val = 0;
|
||||||
|
const x = i * nodeWidth + graphOrigin[0];
|
||||||
|
const y = getYCoordinate(val);
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
lastCoords = [x, y];
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.closePath();
|
||||||
|
|
||||||
|
// ball
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, ctx.lineWidth * 1.2, 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;
|
||||||
|
const maxy = previousY[0] + (textSize / 3);
|
||||||
|
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
||||||
|
|
||||||
|
// lowest value
|
||||||
|
const lowx = graphOrigin[0] + graphSize[0] + textSize;
|
||||||
|
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
||||||
|
ctx.fillText('0 msgs/day', lowx, lowy);
|
||||||
|
|
||||||
|
// 30d
|
||||||
|
ctx.fillText('30d ago', lastMonthStart, graphOrigin[1] - (textSize / 3));
|
||||||
|
|
||||||
|
// time ->
|
||||||
|
const tx = graphOrigin[0] + (textSize / 2);
|
||||||
|
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
||||||
|
ctx.fillText('time ->', tx, ty);
|
||||||
|
|
||||||
|
const yeahok = new client.attachmentBuilder(img.toBuffer(), {name: 'dailymsgs.png'})
|
||||||
|
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.\nGraph updates daily @ <t:${Math.round((client.config.LRSstart+3600000)/1000)}:t>`)
|
||||||
|
.addFields({name: 'Top users by messages sent:', value: Object.entries<UserLevels>(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).slice(0, 10).map((x, i) => `\`${i + 1}.\` <@${x[0]}>: ${x[1].messages.toLocaleString('en-US')}`).join('\n')})
|
||||||
|
.setImage('attachment://dailymsgs.png').setColor(client.config.embedColor)
|
||||||
|
interaction.reply({embeds: [embed], files: [yeahok]})
|
||||||
}
|
}
|
||||||
|
} as any)[interaction.options.getSubcommand()]();
|
||||||
// 30d 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.strokeStyle = client.config.embedColor;
|
|
||||||
ctx.fillStyle = client.config.embedColor;
|
|
||||||
ctx.lineWidth = 3;
|
|
||||||
|
|
||||||
function getYCoordinate(value: number) {
|
|
||||||
return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastCoords: Array<number> = [];
|
|
||||||
data.forEach((val: number, i: number) => {
|
|
||||||
ctx.beginPath();
|
|
||||||
if (lastCoords) ctx.moveTo(...lastCoords);
|
|
||||||
if (val < 0) val = 0;
|
|
||||||
const x = i * nodeWidth + graphOrigin[0];
|
|
||||||
const y = getYCoordinate(val);
|
|
||||||
ctx.lineTo(x, y);
|
|
||||||
lastCoords = [x, y];
|
|
||||||
ctx.stroke();
|
|
||||||
ctx.closePath();
|
|
||||||
|
|
||||||
// ball
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(x, y, ctx.lineWidth * 1.2, 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;
|
|
||||||
const maxy = previousY[0] + (textSize / 3);
|
|
||||||
ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy);
|
|
||||||
|
|
||||||
// lowest value
|
|
||||||
const lowx = graphOrigin[0] + graphSize[0] + textSize;
|
|
||||||
const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3);
|
|
||||||
ctx.fillText('0 msgs/day', lowx, lowy);
|
|
||||||
|
|
||||||
// 30d
|
|
||||||
ctx.fillText('30d ago', lastMonthStart, graphOrigin[1] - (textSize / 3));
|
|
||||||
|
|
||||||
// time ->
|
|
||||||
const tx = graphOrigin[0] + (textSize / 2);
|
|
||||||
const ty = graphOrigin[1] + graphSize[1] + (textSize);
|
|
||||||
ctx.fillText('time ->', tx, ty);
|
|
||||||
|
|
||||||
const yeahok = new client.attachmentBuilder(img.toBuffer(), {name: 'dailymsgs.png'})
|
|
||||||
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.\nGraph updates daily @ <t:${Math.round((client.config.LRSstart+3600000)/1000)}:t>`)
|
|
||||||
.addFields({name: 'Top users by messages sent:', value: Object.entries<UserLevels>(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).slice(0, 10).map((x, i) => `\`${i + 1}.\` <@${x[0]}>: ${x[1].messages.toLocaleString('en-US')}`).join('\n')})
|
|
||||||
.setImage('attachment://dailymsgs.png').setColor(client.config.embedColor)
|
|
||||||
interaction.reply({embeds: [embed], files: [yeahok]});
|
|
||||||
return;
|
|
||||||
} else if (subCmd === "view") {
|
|
||||||
|
|
||||||
// fetch user or user interaction sender
|
|
||||||
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.')
|
|
||||||
const embed = new client.embed().setColor(member.displayColor)
|
|
||||||
|
|
||||||
// information about users progress on level roles
|
|
||||||
const information = client.userLevels._content[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
|
|
||||||
if (interaction.user.id === member.user.id) return you || true;
|
|
||||||
else return they || false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!information) {
|
|
||||||
return interaction.reply(`${pronounBool('You', 'They')} currently don't have a level, send some messages to level up.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const index = Object.entries<UserLevels>(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).map(x => x[0]).indexOf(member.id) + 1;
|
|
||||||
const memberDifference = information.messages - client.userLevels.algorithm(information.level);
|
|
||||||
const levelDifference = client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level);
|
|
||||||
|
|
||||||
embed.setThumbnail(member.user.avatarURL({ extension: 'png', size: 256}) || member.user.defaultAvatarURL)
|
|
||||||
embed.setAuthor({name: `Ranking for ${member.user.tag}`})
|
|
||||||
embed.setTitle(`Level: **${information.level}**\nRank: **${index ? '#' + index : 'last'}**\nProgress: **${information.messages - client.userLevels.algorithm(information.level)}/${client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level)} (${(memberDifference/levelDifference*100).toFixed(2)}%)**\nTotal: **${information.messages}**`);
|
|
||||||
interaction.reply({embeds: [embed]});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName('rank')
|
.setName('rank')
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
import Discord,{SlashCommandBuilder} from 'discord.js';
|
import Discord,{SlashCommandBuilder} from 'discord.js';
|
||||||
import TClient from 'src/client';
|
import TClient from 'src/client';
|
||||||
|
|
||||||
function convert(status:string){
|
function convert(status?:Discord.ClientPresenceStatus){
|
||||||
switch (status){
|
if (status){
|
||||||
case 'offline':
|
return {
|
||||||
return '⚫'
|
idle: '🟡',
|
||||||
case 'idle':
|
dnd: '🔴',
|
||||||
return '🟡'
|
online: '🟢'
|
||||||
case 'dnd':
|
}[status];
|
||||||
return '🔴'
|
} else {
|
||||||
case 'online':
|
return '⚫'
|
||||||
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 Discord.GuildMember;
|
const member = interaction.options.getMember('member');
|
||||||
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()
|
||||||
@ -30,22 +29,27 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
await member.user.fetch();
|
await member.user.fetch();
|
||||||
const embedArray = [];
|
const embedArray = [];
|
||||||
|
const presence = member.presence.clientStatus as Discord.ClientPresenceStatusData;
|
||||||
|
let title = 'Member';
|
||||||
|
if (member.user.bot) {
|
||||||
|
title = 'Bot'
|
||||||
|
} else if (member.user.id == interaction.guild.ownerId) {
|
||||||
|
title = ':crown: Server Owner'
|
||||||
|
};
|
||||||
const embed0 = new client.embed()
|
const embed0 = new client.embed()
|
||||||
.setColor(member.displayColor || client.config.embedColor)
|
.setColor(member.displayColor || client.config.embedColor)
|
||||||
.setURL(`https://discord.com/users/${member.user.id}`)
|
.setURL(`https://discord.com/users/${member.user.id}`)
|
||||||
.setThumbnail(member.user.avatarURL({size:2048}) || member.user.defaultAvatarURL)
|
.setThumbnail(member.user.avatarURL({size:2048}) || member.user.defaultAvatarURL)
|
||||||
.setImage(member.user.bannerURL({size:1024}) as string)
|
.setImage(member.user.bannerURL({size:1024}) as string)
|
||||||
.setTitle(`${member.user.bot ? 'Bot' : 'Member'} Info: ${member.user.tag}`)
|
.setTitle(`${title} Info: ${member.user.tag}`)
|
||||||
.setDescription(`<@${member.user.id}>\n\`${member.user.id}\`${member.user.id === interaction.guild.ownerId ? '\n__**Server Owner**__ 👑' : ''}`)
|
.setDescription(`<@${member.user.id}>\n\`${member.user.id}\``)
|
||||||
.addFields(
|
.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 as number)/1000)}>\n<t:${Math.round((member.joinedTimestamp as number)/1000)}:R>`},
|
{name: '🔹 Server Join Date', value: `<t:${Math.round((member.joinedTimestamp as number)/1000)}>\n<t:${Math.round((member.joinedTimestamp as number)/1000)}:R>`},
|
||||||
{name: `🔹 Roles: ${member.roles.cache.size - 1}`, value: member.roles.cache.size > 1 ? member.roles.cache.filter(x=>x.id !== interaction.guild.roles.everyone.id).sort((a,b)=>b.position - a.position).map(x=>x).join(member.roles.cache.size > 4 ? ' ' : '\n').slice(0,1024) : 'No roles'}
|
{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){
|
if (member.premiumSinceTimestamp !== null) embed0.addFields({name: '🔹 Server Boosting since', value: `<t:${Math.round(member.premiumSinceTimestamp/1000)}>\n<t:${Math.round(member.premiumSinceTimestamp/1000)}:R>`, inline: true})
|
||||||
embed0.addFields({name: '🔹 Server Boosting since', value: `<t:${Math.round(member.premiumSinceTimestamp/1000)}>\n<t:${Math.round(member.premiumSinceTimestamp/1000)}:R>`, inline: true})
|
if (member.presence) embed0.addFields({name: `🔹 Status: ${member.presence.status}`, value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${convert(presence.desktop)}\nWeb: ${convert(presence.web)}\nMobile: ${convert(presence.mobile)}`}`, inline: true})
|
||||||
}
|
|
||||||
if (member.presence){embed0.addFields({name: `🔹 Status: ${member.presence.status}`, value: `${member.presence.status === 'offline' ? '⚫' : `Desktop: ${(member.presence.clientStatus as Discord.ClientPresenceStatusData).desktop ? convert((member.presence.clientStatus as Discord.ClientPresenceStatusData).desktop as string) : convert('offline')}\nWeb: ${(member.presence.clientStatus as Discord.ClientPresenceStatusData).web ? convert((member.presence.clientStatus as Discord.ClientPresenceStatusData).web as string) : convert('offline')}\nMobile: ${(member.presence.clientStatus as Discord.ClientPresenceStatusData).mobile ? convert((member.presence.clientStatus as Discord.ClientPresenceStatusData).mobile as string) : convert('offline')}`}`, inline: true})}
|
|
||||||
embedArray.push(embed0)
|
embedArray.push(embed0)
|
||||||
interaction.reply({embeds: embedArray})
|
interaction.reply({embeds: embedArray})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user