lock, mute, prefix, tempban

This commit is contained in:
yhqe committed 2026-03-22 02:15:16 -05:00
1 parent 27894dac21
commit f637673a4e
18 files changed
+3482 -2658

No files matched your search

+6
View File
@@ -1,5 +1,11 @@
{ {
"autoroles": { "autoroles": {
"1133441692196950101": "1192595134026616894" "1133441692196950101": "1192595134026616894"
},
"autobans": {
"1133441692196950101": "1264634623950848158"
},
"prefixes": {
"1362160460253761536": "*"
} }
} }
+2614 -2601
View File
File diff suppressed because it is too large. Load diff
+81 -41
View File
@@ -4,6 +4,7 @@ const { time } = require("discord.js");
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const logger = require('../../utils/logger'); const logger = require('../../utils/logger');
const env = process.env;
async function fetch_avatar(id) { async function fetch_avatar(id) {
const res = await fetch(`https://thumbnails.roproxy.com/v1/users/avatar?userIds=${id}&size=420x420&format=Png&isCircular=false`, { const res = await fetch(`https://thumbnails.roproxy.com/v1/users/avatar?userIds=${id}&size=420x420&format=Png&isCircular=false`, {
@@ -47,7 +48,7 @@ module.exports = {
name: 'rbx', name: 'rbx',
description: `various commands related to roblox`, description: `various commands related to roblox`,
aliases: ['roblox'], aliases: ['roblox'],
usage: 'rbx user <username>\n.rbx item <item id>\n.rbx group <group id>\n.rbx game <game id>', usage: `rbx user <username>\n${env.PREFIX}rbx item <item id>\n${env.PREFIX}rbx group <group id>\n${env.PREFIX}rbx game <game id>\n${env.PREFIX}rbx avatar <username>`,
async execute(client, message) { async execute(client, message) {
var embed = {}; var embed = {};
@@ -91,49 +92,46 @@ module.exports = {
}] }]
}); });
let latency = Date.now() - message.createdTimestamp; const res = await fetch(`https://users.roblox.com/v1/usernames/users`, {
let apiLatency = Math.round(client.ws.ping); method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.ROBLOSECURITY}` },
body: JSON.stringify({ usernames: [argument], excludeBannedUsers: false })
});
const data = await res.json();
logger.debug(`[rbx] fetched user data (roblox, standard) for "${argument}": ${JSON.stringify(data)}`);
if (!data.data || !data.data[0]) {
throw new Error(`user ${argument} not found...`);
}
const extra_res = await fetch(`https://users.roblox.com/v1/users/${data.data[0].id}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.ROBLOSECURITY}` }
});
const extra_data = await extra_res.json();
logger.debug(`[rbx] fetched user data (roblox, extra) for "${argument}": ${JSON.stringify(extra_data)}`);
const r_res = await fetch(`https://api.rolimons.com/players/v1/playerinfo/${data.data[0].id}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
let r_data = {};
if (r_res.ok) {
r_data = await r_res.json();
} else {
logger.warn(`[rbx] Failed to fetch rolimons playerinfo for id ${data.data[0].id}: HTTP ${r_res.status}`);
r_data = {};
}
logger.debug(`[rbx] fetched user data (rolimons) for "${argument}": ${JSON.stringify(r_data)}`);
const ra_res = await fetch(`https://api.rolimons.com/players/v1/playerassets/${data.data[0].id}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
const ra_data = await ra_res.json();
logger.debug(`[rbx] fetched user data (rolimons, assets) for "${argument}": ${JSON.stringify(ra_data)}`);
if (subcommand === 'user' || subcommand === 'u') { if (subcommand === 'user' || subcommand === 'u') {
try { try {
const res = await fetch(`https://users.roproxy.com/v1/usernames/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.ROBLOSECURITY}` },
body: JSON.stringify({ usernames: [argument], excludeBannedUsers: false })
});
const data = await res.json();
logger.debug(`[rbx] fetched user data (roblox, standard) for "${argument}": ${JSON.stringify(data)}`);
if (!data.data || !data.data[0]) {
throw new Error('User not found');
}
const extra_res = await fetch(`https://users.roproxy.com/v1/users/${data.data[0].id}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.ROBLOSECURITY}` }
});
const extra_data = await extra_res.json();
logger.debug(`[rbx] fetched user data (roblox, extra) for "${argument}": ${JSON.stringify(extra_data)}`);
const r_res = await fetch(`https://api.rolimons.com/players/v1/playerinfo/${data.data[0].id}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
let r_data = {};
if (r_res.ok) {
r_data = await r_res.json();
} else {
logger.warn(`[rbx] Failed to fetch rolimons playerinfo for id ${data.data[0].id}: HTTP ${r_res.status}`);
r_data = {};
}
logger.debug(`[rbx] fetched user data (rolimons) for "${argument}": ${JSON.stringify(r_data)}`);
const ra_res = await fetch(`https://api.rolimons.com/players/v1/playerassets/${data.data[0].id}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
const ra_data = await ra_res.json();
logger.debug(`[rbx] fetched user data (rolimons, assets) for "${argument}": ${JSON.stringify(ra_data)}`);
if (!data.data || !data.data[0]) { if (!data.data || !data.data[0]) {
embed = { embed = {
color: 0x8aa2b3, color: 0x8aa2b3,
@@ -208,6 +206,48 @@ module.exports = {
timestamp: new Date(), timestamp: new Date(),
} }
} }
} else if (subcommand === 'avatar') {
try {
const user = data.data[0];
const a_res = await fetch(`https://thumbnails.roproxy.com/v1/users/avatar?userIds=${user.id}&size=720x720&format=Png&isCircular=false`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
const a_data = await a_res.json();
logger.debug(`[rbx] fetched avatar for "${argument}": ${JSON.stringify(a_data)}`);
embed = {
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: `**${user.displayName}**'s avatar`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
image: {
url: `${a_data.data[0].imageUrl}`
},
timestamp: new Date(),
};
} catch (err) {
logger.error(`[rbx] failed to fetch avatar for user id "${argument}":`, err);
embed = {
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: `<:no:1481811955592466492> could not fetch avatar data for user "${argument}"!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
}
} else if (subcommand === 'item') { } else if (subcommand === 'item') {
try { try {
const res = await fetch(`https://economy.roproxy.com/v2/assets/${argument}/details`, { const res = await fetch(`https://economy.roproxy.com/v2/assets/${argument}/details`, {
+11 -3
View File
@@ -1,7 +1,12 @@
const { EmbedBuilder } = require('discord.js'); const { EmbedBuilder } = require('discord.js');
const db = require('../../db.json');
'use strict'; 'use strict';
const get_guild_prefix = (guildId) => {
return db.prefixes?.[guildId] || null;
};
module.exports = { module.exports = {
name: 'help', name: 'help',
description: 'lists all available commands or shows info about a specific one', description: 'lists all available commands or shows info about a specific one',
@@ -10,9 +15,13 @@ module.exports = {
execute(client, message, args) { execute(client, message, args) {
var embed; var embed;
const prefix = process.env.PREFIX || '!';
// Show info for a specific command let prefix = process.env.PREFIX;
if (message.guild) {
const guildPrefix = get_guild_prefix(message.guild.id);
if (guildPrefix) prefix = guildPrefix;
}
if (args.length > 0) { if (args.length > 0) {
const name = args[0].toLowerCase(); const name = args[0].toLowerCase();
const command = client.commands.get(name); const command = client.commands.get(name);
@@ -43,7 +52,6 @@ module.exports = {
return message.reply({ embeds: [embed] }); return message.reply({ embeds: [embed] });
} }
// Build a deduplicated command list (ignore aliases pointing to the same command)
const seen = new Set(); const seen = new Set();
const commandList = []; const commandList = [];
+102
View File
@@ -0,0 +1,102 @@
'use strict';
const { time } = require("discord.js");
const fs = require('fs');
const path = require('path');
module.exports = {
name: 'autoban',
description: `automatically ban a user if they join the server`,
aliases: ['ab', 'banish'],
usage: 'ban <user> [reason] [duration]',
async execute(client, message, args) {
if (!message.member.permissions.has('BanMembers')) {
return message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> you do not have permission to use this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
const user = message.mentions.users.first() || await client.users.fetch(args[0]).catch(() => null);
if (!user) {
return message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> please specify a user to autoban!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
const reason = args.slice(1).join(' ') || 'autobanned (twitter)';
const dbPath = path.join(__dirname, '..', '..', '..', 'db.json');
let db = {};
if (fs.existsSync(dbPath)) {
db = JSON.parse(fs.readFileSync(dbPath, 'utf8'));
}
if (!db.autobans) {
db.autobans = {};
}
db.autobans[message.guild.id] = user.id;
try {
await fs.writeFileSync(dbPath, JSON.stringify(db, null, 2));
message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: `<:check:1481811973447356496> ${user.username} has been added to the autoban list!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
} catch (error) {
console.error(error);
message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> an error occurred while trying to add the user to the autoban list!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
},
};
+2 -3
View File
@@ -5,8 +5,8 @@ const { time } = require("discord.js");
module.exports = { module.exports = {
name: 'ban', name: 'ban',
description: `ban a user from the current server`, description: `ban a user from the current server`,
aliases: ['banish'], aliases: ['b'],
usage: 'ban <user> [reason] [duration]', usage: 'ban <user> [reason]',
async execute(client, message, args) { async execute(client, message, args) {
if (!message.member.permissions.has('BanMembers')) { if (!message.member.permissions.has('BanMembers')) {
@@ -47,7 +47,6 @@ module.exports = {
} }
const reason = args.slice(1).join(' ') || 'no reason provided (twitter)'; const reason = args.slice(1).join(' ') || 'no reason provided (twitter)';
const duration = args[2] ? parseInt(args[2]) : null;
try { try {
await message.guild.members.ban(user, { reason }); await message.guild.members.ban(user, { reason });
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const { time } = require("discord.js");
module.exports = {
name: 'lockdown',
description: 'lockdown the the current channel ',
aliases: ['ld', 'lock'],
usage: 'lockdown',
async execute(client, message) {
var embed;
if (!message.member?.permissions?.has('ManageChannels')) {
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> you do not have permissions to run this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
const channel = message.channel;
await channel.permissionOverwrites.edit(message.guild.roles.everyone, { SendMessages: false });
await channel.permissionOverwrites.edit(message.guild.roles.cache.find(r => r.permissions.has('Administrator')), { SendMessages: true });
embed = {
color: 0x8aa2b3,
title: '',
description: `<:check:1481811973447356496> ${channel} is now locked!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
await message.reply({ content: null, embeds: [embed] });
},
};
+64
View File
@@ -0,0 +1,64 @@
'use strict';
const { time } = require("discord.js");
module.exports = {
name: 'role',
description: `give or take a role from a user`,
aliases: ['r'],
usage: 'role <user> (-)<role>',
async execute(client, message) {
var embed = {
color: 0x8aa2b3,
title: '',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}
if (!message.member.permissions.has('Administrator')) {
embed.description = '<:no:1481811955592466492> you do not have permissions to run this command!';
await message.reply({ content: null, embeds: [embed] });
return;
}
if (!message.mentions.members.size) {
embed.description = '<:no:1481811955592466492> please specify a user to give or take a role from!';
await message.reply({ content: null, embeds: [embed] });
return;
}
const member = message.mentions.members.first();
const roleName = message.content.split(' ').slice(2).join(' ').replace(/^-/, '');
const role = message.guild.roles.cache.find(r => r.name === roleName);
if (!role) {
embed.description = '<:no:1481811955592466492> role not found!';
await message.reply({ content: null, embeds: [embed] });
return;
}
if (message.content.split(' ')[2].startsWith('-')) {
if (!member.roles.cache.has(role.id)) {
embed.description = `<:no:1481811955592466492> ${member} does not have the ${role} role!`;
await message.reply({ content: null, embeds: [embed] });
return;
}
await member.roles.remove(role);
embed.description = `<:check:1481811973447356496> ${role} role has been taken from ${member}!`;
} else {
if (member.roles.cache.has(role.id)) {
embed.description = `<:no:1481811955592466492> ${member} already has the ${role} role!`;
await message.reply({ content: null, embeds: [embed] });
return;
}
await member.roles.add(role);
embed.description = `<:check:1481811973447356496> ${role} role has been given to ${member}!`;
}
await message.reply({ content: null, embeds: [embed] });
},
};
+115
View File
@@ -0,0 +1,115 @@
'use strict';
const { PermissionFlagsBits } = require("discord.js");
module.exports = {
name: 'tempban',
description: `temporarily ban a user from the current server`,
aliases: ['tban'],
usage: 'tempban <user> <duration> [reason]',
async execute(client, message, args) {
if (!message.member.permissions.has('BanMembers')) {
return message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> you do not have permission to use this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user) {
return message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> please specify a user to ban!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
const durationStr = args[1];
const durationMap = { s: 1000, m: 60000, h: 3600000, d: 86400000, w: 604800000 };
const match = durationStr?.match(/^(\d+)([smhdw])$/);
if (!match || !durationMap[match[2]]) {
return message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> please specify a valid duration (e.g., 1s, 1m, 1d, 1w)!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
const duration = parseInt(match[1]) * durationMap[match[2]];
const reason = args.slice(2).join(' ') || 'no reason provided (twitter)';
try {
await message.guild.members.ban(user, { reason: `${reason} (twitter, moderator: ${message.author.username})` });
setTimeout(() => {
message.guild.bans.remove(user, 'temporary ban expired (twitter)');
}, duration);
message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: `<:check:1481811973447356496> ${user.username} has been temporarily banned for ${durationStr}!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
} catch (error) {
console.error(error);
message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> an error occurred while trying to ban the user!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
},
};
+117
View File
@@ -0,0 +1,117 @@
'use strict';
const { time } = require("discord.js");
module.exports = {
name: 'timeout',
description: `timeout a user`,
aliases: ['mute'],
usage: 'timeout <user> <duration>',
async execute(client, message, args) {
var embed;
if (!message.member.permissions.has('ModerateMembers')) {
await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> you do not have permissions to run this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
if (!message.mentions.members.size) {
await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> please specify a user to timeout!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
const member = message.mentions.members.first();
const durationStr = args[1];
const durationMap = { s: 1000, m: 60000, h: 3600000, d: 86400000, w: 604800000 };
const match = durationStr?.match(/^(\d+)([smhdw])$/);
if (!match || !durationMap[match[2]]) {
return message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> please specify a valid duration (e.g., 1s, 1m, 1d, 1w)!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
}
const duration = parseInt(match[1]) * durationMap[match[2]];
if (!duration) {
await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> please specify a valid duration for the timeout!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
try {
await member.timeout(duration);
embed = {
color: 0x8aa2b3,
title: '',
description: `<:check:1481811973447356496> ${member} has been timed out for ${durationStr}!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
} catch (error) {
console.error(error);
embed = {
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> an error occurred while trying to timeout the user!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
}
await message.reply({ content: null, embeds: [embed] });
},
};
+50
View File
@@ -0,0 +1,50 @@
'use strict';
const { time } = require("discord.js");
module.exports = {
name: 'unlockdown',
description: 'unlock the current channel ',
aliases: ['ud', 'unlock'],
usage: 'unlockdown',
async execute(client, message) {
var embed;
if (!message.member?.permissions?.has('ManageChannels')) {
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> you do not have permissions to run this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
const channel = message.channel;
await channel.permissionOverwrites.edit(
message.guild.roles.everyone,
{ SendMessages: null }
);
embed = {
color: 0x8aa2b3,
title: '',
description: `<:check:1481811973447356496> ${channel} is now unlocked!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
await message.reply({ content: null, embeds: [embed] });
},
};
+92
View File
@@ -0,0 +1,92 @@
'use strict';
const { time } = require("discord.js");
module.exports = {
name: 'untimeout',
description: `untimeout a user`,
aliases: ['unmute'],
usage: 'untimeout <user>',
async execute(client, message, args) {
var embed;
if (!message.member.permissions.has('ModerateMembers')) {
await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> you do not have permissions to run this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
if (!message.mentions.members.size || !message.mentions.members.first().communicationDisabledUntil) {
await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> that user is not timed out!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
if (!message.mentions.members.size) {
await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> please specify a user to timeout!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
return;
}
const member = message.mentions.members.first();
try {
await member.timeout(null);
embed = {
color: 0x8aa2b3,
title: '',
description: `<:check:1481811973447356496> ${member} has been untimed out!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
} catch (error) {
console.error(error);
embed = {
color: 0x8aa2b3,
title: '',
description: '<:no:1481811955592466492> an error occurred while trying to untimeout the user!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
};
}
await message.reply({ content: null, embeds: [embed] });
},
};
+16 -1
View File
@@ -9,7 +9,22 @@ module.exports = {
usage: 'ping', usage: 'ping',
async execute(client, message) { async execute(client, message) {
const sent = await message.reply('pinging'); const sent = await message.reply({
content: null, embeds: [{
color: 0x8aa2b3,
title: '',
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<a:loading_icon:1366587619890302998> pinging...',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date(),
}]
});
const latency = sent.createdTimestamp - message.createdTimestamp; const latency = sent.createdTimestamp - message.createdTimestamp;
const apiLatency = Math.round(client.ws.ping); const apiLatency = Math.round(client.ws.ping);
+137
View File
@@ -0,0 +1,137 @@
'use strict';
const { time } = require("discord.js");
const fs = require('node:fs');
const path = require('node:path');
const DB_PATH = path.join(__dirname, '../../../db.json');
const readDb = () => {
try {
return JSON.parse(fs.readFileSync(DB_PATH, 'utf8'));
} catch {
return {};
}
};
const writeDb = (db) => {
fs.writeFileSync(DB_PATH, JSON.stringify(db, null, 2), 'utf8');
};
module.exports = {
name: 'prefix',
description: 'change the server command prefix',
aliases: ['setprefix'],
usage: 'prefix <new prefix>',
execute: async (client, message, args = []) => {
var embed;
if (!message.guild) {
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> this command can only be used in a server!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date()
}]
});
return;
}
if (!message.member?.permissions?.has('ManageGuild')) {
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> you do not have permissions to run this command!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date()
}]
});
return;
}
let newPrefix = args[0];
if (!newPrefix) {
const parts = message.content.trim().split(/\s+/);
newPrefix = parts[1];
}
if (!newPrefix) {
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> you must provide a new prefix!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date()
}]
});
return;
}
if (newPrefix.length > 5) {
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: '<:no:1481811955592466492> prefix must be 5 characters or less!',
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date()
}]
});
return;
}
const db = readDb();
db.prefixes = db.prefixes || {};
db.prefixes[message.guild.id] = newPrefix;
writeDb(db);
await message.reply({
embeds: [{
color: 0x8aa2b3,
title: '',
author: {
name: message.author.username,
icon_url: message.author.displayAvatarURL(),
},
description: `<:check:1481811973447356496> prefix for **${message.guild.name}** updated to \`${newPrefix}\`!`,
footer: {
text: `twitter @ ${message.guild.name}`,
icon_url: client.user.displayAvatarURL(),
},
timestamp: new Date()
}]
});
}
};
void time;
+17
View File
@@ -30,4 +30,21 @@ module.exports = (client, member) => {
.then(() => logger.info(`assigned role "${role.name}" to user "${member.user.tag}"!`)) .then(() => logger.info(`assigned role "${role.name}" to user "${member.user.tag}"!`))
.catch(error => logger.error(`failed to assign role "${role.name}" to user "${member.user.tag}": ${error}`)); .catch(error => logger.error(`failed to assign role "${role.name}" to user "${member.user.tag}": ${error}`));
} }
// autoban
{
const autoban = db.autobans ? db.autobans[member.guild.id] : null;
if (!autoban) {
logger.info(`no autoban is set up for ${member.user.tag} in "${member.guild.name}"`);
return;
}
if (member.user.tag === autoban) {
member.ban({ reason: 'autobanned (twitter)' })
.then(() => logger.info(`autobanned user "${member.user.tag}" from guild "${member.guild.name}"`))
.catch(error => logger.error(`failed to autoban user "${member.user.tag}" from guild "${member.guild.name}": ${error}`));
} else {
logger.info(`user "${member.user.tag}" is not on the autoban list for "${member.guild.name}"`);
}
}
}; };
+12 -3
View File
@@ -2,18 +2,27 @@
const { Events } = require('discord.js'); const { Events } = require('discord.js');
const logger = require('../utils/logger'); const logger = require('../utils/logger');
const db = require('../../db.json'); // adjust path as needed
const get_guild_prefix = (guildId) => {
return db.prefixes?.[guildId] || null;
};
module.exports = { module.exports = {
name: Events.MessageCreate, name: Events.MessageCreate,
async execute(client, message) { async execute(client, message) {
// Ignore bots and messages without the prefix
if (message.author.bot) return; if (message.author.bot) return;
const prefix = process.env.PREFIX || '!'; let prefix = process.env.PREFIX || '!';
if (message.guild) {
const guildPrefix = get_guild_prefix(message.guild.id);
if (guildPrefix) prefix = guildPrefix;
}
if (!message.content.startsWith(prefix)) return; if (!message.content.startsWith(prefix)) return;
// Parse command name and arguments
const args = message.content.slice(prefix.length).trim().split(/\s+/); const args = message.content.slice(prefix.length).trim().split(/\s+/);
const commandName = args.shift().toLowerCase(); const commandName = args.shift().toLowerCase();
-1
View File
@@ -20,7 +20,6 @@ module.exports = {
const variables = Object.keys(db); const variables = Object.keys(db);
logger.info(`[db] loaded variables from db.json: ${variables.length > 0 ? variables.join(', ') : 'none'}`); logger.info(`[db] loaded variables from db.json: ${variables.length > 0 ? variables.join(', ') : 'none'}`);
// cache rolimons item list
fetch('https://api.rolimons.com/items/v2/itemdetails') fetch('https://api.rolimons.com/items/v2/itemdetails')
.then(res => res.ok ? res.json() : Promise.reject(new Error('Failed to fetch rolimons item list'))) .then(res => res.ok ? res.json() : Promise.reject(new Error('Failed to fetch rolimons item list')))
.then(data => { .then(data => {
-5
View File
@@ -5,15 +5,11 @@ const path = require('path');
const logger = require('../utils/logger'); const logger = require('../utils/logger');
/** /**
* Loads all command files from src/commands and registers them on the client.
* Each command file must export: { name, description, aliases?, usage?, execute }
*
* @param {import('discord.js').Client} client * @param {import('discord.js').Client} client
*/ */
function loadCommands(client) { function loadCommands(client) {
const commandsPath = path.join(__dirname, '..', 'commands'); const commandsPath = path.join(__dirname, '..', 'commands');
// Recursively get all .js files in commandsPath
function getAllCommandFiles(dir) { function getAllCommandFiles(dir) {
let results = []; let results = [];
const list = fs.readdirSync(dir, { withFileTypes: true }); const list = fs.readdirSync(dir, { withFileTypes: true });
@@ -45,7 +41,6 @@ function loadCommands(client) {
client.commands.set(command.name.toLowerCase(), command); client.commands.set(command.name.toLowerCase(), command);
// Register aliases if provided
if (Array.isArray(command.aliases)) { if (Array.isArray(command.aliases)) {
for (const alias of command.aliases) { for (const alias of command.aliases) {
client.commands.set(alias.toLowerCase(), command); client.commands.set(alias.toLowerCase(), command);