Skip to content

Commit d0ca1bc

Browse files
v5 Release Milestone 1 (#23)
v5 Release Milestone 1 * Added ban command * Added config command * Added kick command * Updated reactionroles command to allow cancellation * Added unban command * Updated channelCreate, channelDelete, and channelUpdate as there were many problems in the last commit. * Added emojiCreate, emojiDelete, emojiUpdate * guildBanAdd and guildBanRemove events now work and are now added in this commit. * Added guildCreate and updated guildDelete so that invite tracking is working. * Updated guildMemberRemove and guildMemberAdd * Added guildMemberUpdate * Added guildUpdate * Added inviteCreate and inviteDelete for invite tracking. * Updated messageCreate, messageDelete, messageDeleteBulk, messageUpdate events to remedy many bugs. * Updated ready event to track invites properly. * Updated roleCreate, roleDelete, and roleUpdate to remedy even more bugs * Added to the bootloader the new settings you can play with! (logging stuff) * Added Member Welcome Image Generation (with some templates) * Corrected bot file to not die when unloading events and updated intents to include ALL intents * Fix a itty bitsy ~~spider~~ bug in the explode cmd (#20) - (if args weren't an user that it would get the first part of the message instead of full args.) Co-authored-by: Sophie Mondz <anthonymondz@gmail.com>
1 parent 1cc85a7 commit d0ca1bc

43 files changed

Lines changed: 1606 additions & 128 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/app/cfg/app.js

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,69 @@ const app = {
4646
}
4747
},
4848

49+
defaults: {
50+
// -- HEY!!!
51+
// -- WARNING :: THIS IS DANGEROUS | ONLY ACCESS DATA FROM MESSAGE. DO NOT ACCESS DATA FROM OTHER VARIABLES.
52+
// -- It poses a major security risk and TMC Software is not responsible for that.
53+
54+
join: {
55+
msg: "Hello and welcome %user% to the %server%!",
56+
types: [
57+
// SERVER INFO
58+
{ "%server%": { "desc": "Server Name (Cool Place)", "replaceWith": "guild|name" } },
59+
{ "%serverID%": { "desc": "Server ID (99999999999999999)", "replaceWith": "guild|id" } },
60+
61+
// USER INFO
62+
{ "%username%": { "desc": "Username (John Doe)", "replaceWith": "user|username" } },
63+
{ "%userID%": { "desc": "User ID (99999999999999999)", "replaceWith": "user|id" } },
64+
{ "%userdisc%": { "desc": "User Discriminator (#0001)", "replaceWith": "user|discriminator" } },
65+
{ "%usertag%": { "desc": "User Tag (John Doe#0001)", "replaceWith": "user|tag" } },
66+
{ "%user%": { "desc": "User Mention (@John Doe#0001)", "replaceWith": "user|toString()" } },
67+
68+
// INVITE INFO
69+
{ "%invitecode%": { "desc": "Invite Code (HdKeWtV)", "replaceWith": "Unknown" } },
70+
{ "%inviteuses%": { "desc": "Invite Uses (34)", "replaceWith": "" } },
71+
{ "%invitername%": { "desc": "Inviter Username (Jane Doe)", "replaceWith": "" } },
72+
{ "%inviterID%": { "desc": "Inviter ID (11111111111111111)", "replaceWith": "" } },
73+
{ "%inviterdisc%": { "desc": "Inviter Discriminator (#0002)", "replaceWith": "" } },
74+
{ "%invitertag%": { "desc": "Inviter Tag (Jane Doe#0001)", "replaceWith": "" } },
75+
{ "%inviter%": { "desc": "Inviter Mention (@Jane Doe#0002)", "replaceWith": "" } }
76+
]
77+
},
78+
leave: {
79+
msg: "Aw... %user% just left the server...",
80+
types: [
81+
// SERVER INFO
82+
{ "%server%": { "desc": "Server Name (Cool Place)", "replaceWith": "guild|name" } },
83+
{ "%serverID%": { "desc": "Server ID (99999999999999999)", "replaceWith": "guild|id" } },
84+
85+
// USER INFO
86+
{ "%username%": { "desc": "Username (John Doe)", "replaceWith": "user|username" } },
87+
{ "%userID%": { "desc": "User ID (99999999999999999)", "replaceWith": "user|id" } },
88+
{ "%userdisc%": { "desc": "User Discriminator (#0001)", "replaceWith": "user|discriminator" } },
89+
{ "%usertag%": { "desc": "User Tag (John Doe#0001)", "replaceWith": "user|tag" } },
90+
{ "%user%": { "desc": "User Mention (@John Doe#0001)", "replaceWith": "user|toString()" } }
91+
]
92+
}
93+
},
94+
4995
functions: {
96+
getTypes: { // these functions were retardly dumb and overly complicated for no reason.
97+
desc: (val) => {
98+
var temp = [],
99+
defaults = app.defaults;
100+
for (var i = 0; i < Object.keys(defaults[val]["types"]).length; i++) temp.push(Object.keys(defaults[val]["types"][i]) + " = " + defaults[val]["types"][i][Object.keys(defaults[val]["types"][i])]["desc"]);
101+
return temp;
102+
},
103+
104+
replaceWith: (val) => {
105+
var temp = {},
106+
defaults = app.defaults;
107+
for (var i = 0; i < Object.keys(defaults[val]["types"]).length; i++) temp[[Object.keys(defaults[val]["types"][i])[0]]] = defaults[val]["types"][i][Object.keys(defaults[val]["types"][i])[0]]["replaceWith"];
108+
return temp;
109+
}
110+
},
111+
50112
sleep: function(ms) {
51113
return new Promise(resolve => setTimeout(resolve, ms));
52114
},
@@ -234,14 +296,37 @@ const app = {
234296
delete options["author"];
235297
};
236298
if (!options.embeds[0]["footer"]) options.embeds[0]["footer"] = { text: app.config.system.footerText }; // Install branding.exe
299+
if (options.embeds[0]["thumbnail"] != null) {
300+
var user = options.embeds[0]["thumbnail"];
301+
if (user["url"] == null)
302+
options.embeds[0]["thumbnail"] = { url: user.displayAvatarURL({ format: 'png', dynamic: true, size: 1024 }) };
303+
304+
}
237305
};
238306

307+
var currTime = new Date().getTime();
308+
239309
if (action == 0) {
240-
if (doReply) options["reply"] = { messageReference: message.id };
241-
message.channel.send(options).then(msg => { if (callback != null) callback(msg); });
310+
if (doReply && message.channel) options["reply"] = { messageReference: message.id };
311+
312+
if (message.channel)
313+
message.channel.send(options).then(msg => {
314+
if (message.createdTimestamp)
315+
app.logger.debug("DISCORD", `[MESSAGE] Got message in ${(currTime - message.createdTimestamp) / 1000}ms. | Responded in ${(currTime - msg.createdTimestamp) / 1000}ms.`);
316+
if (callback != null) callback(msg);
317+
}).catch(err => { app.logger.warn("DISCORD", `[MESSAGE] Message failed to send! Error: ${err.message}`) });
318+
else
319+
message.send(options).then(msg => { if (callback != null) callback(msg); }).catch(err => { app.logger.warn("DISCORD", `[MESSAGE] Message failed to send! Error: ${err.message}`) });
242320
} else if (action == 1) {
243-
if (message.edit) message.edit(options).then(msg => { if (callback != null) callback(msg); });
244-
else if (message.update) message.update(options).then(msg => { if (callback != null) callback(msg); });
321+
if (!message.channel) return; // Hate to break it, but you can't edit a channel as a message. 💀 (imagine that)
322+
if (message.edit) message.edit(options).then(msg => {
323+
if (message.editedTimestamp) app.logger.debug("DISCORD", `[MESSAGE] Edited message in ${(currTime - msg.editedTimestamp) / 1000}ms.`);
324+
if (callback != null) callback(msg);
325+
}).catch(err => { app.logger.warn("DISCORD", `[MESSAGE] Message failed to edit! Error: ${err.message}`) });
326+
else if (message.update) message.update(options).then(msg => {
327+
if (message.editedTimestamp) app.logger.debug("DISCORD", `[MESSAGE] Edited message in ${(currTime - msg.editedTimestamp) / 1000}ms.`);
328+
if (callback != null) callback(msg);
329+
}).catch(err => { app.logger.warn("DISCORD", `[MESSAGE] Message failed to update! Error: ${err.message}`) });
245330
};
246331
},
247332

@@ -311,7 +396,7 @@ const app = {
311396
};
312397

313398
app.functions.msgHandler(message, data, 0, true);
314-
console.log(err);
399+
app.logger.error("SYS", "[ERRHANDLER] " + (err.stack || err.message || err));
315400
return;
316401
},
317402

@@ -334,6 +419,16 @@ const app = {
334419
},
335420
getID: function(string) { return string.replace(/[<#@&!>]/g, ''); },
336421
doesArrayStartsWith: function(string, array) { return array.findIndex((item) => { return item.startsWith(string); }, string) != -1; },
422+
arrayDifference: function(arr1, arr2) {
423+
var a = [],
424+
diff = [];
425+
for (var i = 0; i < arr1.length; i++) { a[arr1[i]] = true; };
426+
for (var i = 0; i < arr2.length; i++) {
427+
if (a[arr2[i]]) { delete a[arr2[i]]; } else { a[arr2[i]] = true; };
428+
};
429+
for (var k in a) { diff.push(k); };
430+
return diff;
431+
},
337432

338433
clearCache: function(module) {
339434
if (module == null)
@@ -342,7 +437,7 @@ const app = {
342437
delete require.cache[module];
343438
},
344439
getFiles: async function(dir, filter = []) {
345-
if (filter.length > 2) return "Fliter too powerfuuuuul [startsWith, endsWith] only please, or no fliter.";
440+
if (filter.length > 2) return "filter too powerfuuuuul [startsWith, endsWith] only please, or no filter.";
346441

347442
const { resolve } = app.modules["path"];
348443
const { readdir } = app.modules["fs"].promises;

src/app/cmds/Fun/explode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module.exports = {
99
aliases: [],
1010
syntax: [],
1111
execute: async(app, message, args) => {
12-
var target = message.mentions.users.first() || args[0],
12+
var target = message.mentions.users.first() || args.slice(0).join(" "),
1313
sender = message.author;
1414
if (!target) return app.functions.msgHandler(message, { content: "You need to add something to explode!!" }, 0, true);
1515
else if (target == sender) return app.functions.msgHandler(message, { content: "Why would you want to send a bomb to yourself???" }, 0, true);

src/app/cmds/General/about.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ module.exports = {
3838
}]
3939
});
4040
}
41-
}
41+
}

src/app/cmds/General/help.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ module.exports = {
4242
fields = [];
4343
app.commands.forEach(cmd => {
4444
var category = cmd.category || "Uncategorized";
45-
console.log(category)
4645
if (category == categoryName && app.functions.hasPermissions(message, cmd) && !cmd.hidden)
4746
commands.push("`" + cmd.name + "`");
4847
});

src/app/cmds/Moderation/ban.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
module.exports = {
2+
name: "ban",
3+
description: "Ban those pesky members!",
4+
guildOnly: true,
5+
authorizedGuilds: [],
6+
hidden: false,
7+
permissions: ["BAN_MEMBERS"],
8+
cooldown: 5,
9+
aliases: ["banhammer"],
10+
syntax: [" <@MentionOrUserID> [reason]"],
11+
execute: async(app, message, args) => {
12+
function BanError(msg) {
13+
return app.functions.msgHandler(message, {
14+
embeds: [{
15+
title: `${app.config.system.emotes.error} Ban Error!`,
16+
color: app.config.system.embedColors.red,
17+
description: msg ? msg : "Missing error data??",
18+
}],
19+
author: message.author
20+
}, 0, true);
21+
};
22+
if (!args[0]) return BanError("Well, you can't really ban air, can you...");
23+
24+
var userID = app.functions.getID(args[0]),
25+
reason = args.slice(1).join(" ");
26+
27+
var user;
28+
await app.client.users.fetch(userID, true, true)
29+
.then(u => {
30+
user = u;
31+
})
32+
.catch(err => {
33+
if (err.message.includes("Unknown User")) {
34+
return BanError("That was an invalid user. I even tried searching through Discord...");
35+
} else {
36+
return BanError(`Something went wrong while fetching the user.\nError: ${err.message}`);
37+
};
38+
});
39+
40+
if (user.id) {
41+
if (user.id === message.author.id) return BanError("Banning yourself is rather pointless.");
42+
var guildMember = message.guild.members.cache.get(user.id),
43+
forced = false;
44+
45+
46+
var getBan = async(userID) => await message.guild.bans.fetch(userID, true, true).then(b => { return true; }).catch(() => { return false; });
47+
48+
49+
if (!guildMember)
50+
forced = true;
51+
else {
52+
if (!guildMember.bannable) return BanError("That user is higher than me... sorry kiddo.");
53+
forced = false;
54+
};
55+
56+
try {
57+
if (await getBan(userID)) return BanError("That user is already banned!");
58+
var banReason = message.author.tag + " " + ((reason) ? reason : "provided no reason for the ban.");
59+
message.guild.members.ban(userID, { reason: banReason }).then(() => {
60+
var embed = {
61+
title: `${app.config.system.emotes.success} ${(forced) ? "Force-" : ""}Ban Success!`,
62+
color: app.config.system.embedColors.lime,
63+
description: `You know the rules and so do I, so say goodbye to ${user.tag}!`,
64+
fields: []
65+
};
66+
if (reason) embed.fields.push({ name: "Reason", value: ((reason) ? reason : "Missing reason yet this is here???") });
67+
68+
return app.functions.msgHandler(message, {
69+
embeds: [embed],
70+
author: message.author
71+
}, 0, true);
72+
}).catch(err => {
73+
return BanError(`I failed to ban that user because: ${err.message}`);
74+
})
75+
} catch (Ex) {
76+
return BanError(`I failed to ban that user because: ${Ex.message}`);
77+
}
78+
}
79+
}
80+
};

0 commit comments

Comments
 (0)