mirror of
https://github.com/vicr123/AstralMod.git
synced 2025-01-22 03:41:48 -05:00
3a717f41f2
Warnings no longer spam the console
3989 lines
No EOL
151 KiB
JavaScript
Executable file
3989 lines
No EOL
151 KiB
JavaScript
Executable file
/****************************************
|
||
*
|
||
* AstralMod: Moderation bot for bits & Bytes and other Discord servers
|
||
* Copyright (C) 2019 Victor Tran, John Tur
|
||
*
|
||
* This program is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*
|
||
* *************************************/
|
||
|
||
|
||
const Discord = require('discord.js');
|
||
const consts = require('./consts.js');
|
||
const fs = require('fs');
|
||
const readline = require('readline');
|
||
const events = require('events');
|
||
const blessed = require('blessed');
|
||
const moment = require('moment');
|
||
require("moment-duration-format");
|
||
const http = require('http');
|
||
const https = require('https');
|
||
const crypto = require('crypto');
|
||
const client = new Discord.Client({
|
||
restTimeOffset: 10,
|
||
disableEveryone: true
|
||
});
|
||
const i18next = require('i18next');
|
||
let i18nextbackend = require('i18next-node-fs-backend');
|
||
|
||
global.shutdown = () => {
|
||
if (global.settings != null) {
|
||
log("Saving settings...");
|
||
try {
|
||
var contents = JSON.stringify(settings, null, 4);
|
||
|
||
//Encrypt the contents
|
||
let iv = Buffer.from(crypto.randomBytes(16)).toString("hex").slice(0, 16);
|
||
|
||
var cipher = crypto.createCipheriv(cipherAlg, settingsKey, iv);
|
||
var settingsJson = Buffer.concat([cipher.update(Buffer.from(contents, "utf8"), cipher.final())]);
|
||
|
||
fs.writeFileSync("settings.json", settingsJson, "utf8");
|
||
fs.writeFileSync("iv", iv);
|
||
log("Settings saved!", logType.good);
|
||
} catch (exception) {
|
||
log("Settings couldn't be saved. You may lose some settings.", logType.critical);
|
||
}
|
||
}
|
||
|
||
log("Now exiting AstralMod.", logType.good);
|
||
|
||
client.user.setStatus("invisible").then((user) => {
|
||
// log(user.presence.status);
|
||
process.exit();
|
||
})
|
||
}
|
||
|
||
process.on("SIGINT", shutdown);
|
||
process.on("SIGTERM", shutdown);
|
||
process.on("SIGQUIT", shutdown);
|
||
process.on("SIGHUP", shutdown);
|
||
|
||
global.prefix = (id) => {
|
||
if (id && settings && settings.guilds && settings.guilds[id] && settings.guilds[id].serverPrefix) {
|
||
return settings.guilds[id].serverPrefix;
|
||
}
|
||
|
||
return defaultPrefix;
|
||
}
|
||
|
||
if (process.argv.indexOf("--blueprint") == -1) {
|
||
global.amVersion = "3.0";
|
||
global.defaultPrefix = consts.config.prefix;
|
||
} else {
|
||
amVersion = "Blueprint";
|
||
global.defaultPrefix = consts.config.bprefix;
|
||
}
|
||
|
||
global.botOwner = undefined;
|
||
|
||
global.tempMods = {};
|
||
|
||
let doNotDeleteGuilds = [];
|
||
|
||
let availableTranslations = fs.readdirSync("translations");
|
||
|
||
availableTranslations.getTranslation = function(language) {
|
||
language = language.toLowerCase()
|
||
let aT = availableTranslations; //.map(t => t.toLowerCase());
|
||
if (aT.includes(language)) {
|
||
return language;
|
||
}
|
||
|
||
if (aT.filter(t => t.toLowerCase().startsWith(language)).length > 1) {
|
||
return null;
|
||
} else {
|
||
return aT.filter(t => t.toLowerCase().startsWith(language))[0];
|
||
}
|
||
};
|
||
|
||
i18next.use(i18nextbackend).init({
|
||
fallbackLng: ["en", false],
|
||
preload: availableTranslations,
|
||
ns: ["translation", "help"],
|
||
//saveMissing: true,
|
||
backend: {
|
||
loadPath: "./translations/{{lng}}/{{ns}}.json",
|
||
addPath: "./translations/{{lng}}/{{ns}}.json",
|
||
jsonIndent: 4
|
||
},
|
||
interpolation: {
|
||
format: function fmt(value, format, lng) {
|
||
if (value == null) return "[[[TRANSLATION ERROR]]]";
|
||
if (value.duration && moment.isDuration(value.duration)) {
|
||
//Special case for Chinese
|
||
if (lng.startsWith("zh")) lng = "zh-cn";
|
||
|
||
let m = value.duration.locale(lng);
|
||
|
||
if (format == "humanize") {
|
||
return m.humanize(value.prefixed);
|
||
} else {
|
||
return m.format(format, value.settings);
|
||
}
|
||
}
|
||
|
||
if (value.date instanceof Date || value.date instanceof moment) {
|
||
//maybe have different formats here later
|
||
//also take into account the user's 12/24h settings somehow at some point
|
||
|
||
//Special case for Chinese
|
||
if (lng.startsWith("zh")) lng = "zh-cn";
|
||
|
||
let m;
|
||
if (value.date instanceof moment) {
|
||
m = value.date.locale(lng);
|
||
} else {
|
||
m = moment.utc(value.date).locale(lng);
|
||
}
|
||
|
||
if (value.offset != null) {
|
||
m = m.utcOffset(value.offset);
|
||
}
|
||
|
||
if (format == "datetime") {
|
||
return arguments.callee(_[lng]("SPECIAL_DATETIME", { time: {date: m, h24: value.h24, offset: value.offset} }));
|
||
} else if (format == "date") {
|
||
return m.format("ddd MMM DD YYYY");
|
||
} else if (format == "time") {
|
||
if (value.h24) {
|
||
return m.format("HH:mm:ss");
|
||
} else {
|
||
return m.format("hh:mm:ss A");
|
||
}
|
||
} else if (format == "stime") {
|
||
if (value.h24) {
|
||
return m.format("HH:mm");
|
||
} else {
|
||
return m.format("hh:mm A");
|
||
}
|
||
} else {
|
||
return m.format(format);
|
||
}
|
||
}
|
||
if (format == "bold") return "**" + value + "**";
|
||
return value;
|
||
},
|
||
escapeValue: false
|
||
}
|
||
});
|
||
|
||
global._ = {
|
||
help: {}
|
||
};
|
||
|
||
for (let tr of availableTranslations) {
|
||
_[tr] = i18next.getFixedT(tr, "translation");
|
||
_.help[tr] = i18next.getFixedT(tr, "help");
|
||
}
|
||
|
||
global.tr = function() {
|
||
log("Warning: the tr function is being used", logType.warning);
|
||
return arguments[0];
|
||
}
|
||
|
||
const cipherAlg = "aes-256-ctr";
|
||
const sha256 = crypto.createHash("sha256");
|
||
const settingsKey = consts.keys.settingsKey.slice(0, 32);
|
||
|
||
const commandEmitter = new events.EventEmitter();
|
||
commandEmitter.setMaxListeners(100);
|
||
var plugins = {};
|
||
|
||
/** @type{Object} */
|
||
global.settings = null;
|
||
var listening = true;
|
||
var nickChanges = {};
|
||
var lockBox = [];
|
||
var banCounts = {};
|
||
var knownInvites = {};
|
||
var finalStdout = "";
|
||
global.banDescriptor = {};
|
||
|
||
let logFile = fs.createWriteStream("./log.log", {flags: 'a'});
|
||
logFile.write("\n\n-----NEW SESSION START-----\n");
|
||
logFile.write("ASTRALMOD " + amVersion + "\n");
|
||
|
||
global.UserInputError = function() {
|
||
var temp = Error.apply(this, arguments);
|
||
temp.name = "UserInputError";
|
||
this.name = "UserInputError";
|
||
this.message = temp.message;
|
||
}
|
||
|
||
UserInputError.prototype = Object.create(Error.prototype, {
|
||
constructor: {
|
||
value: UserInputError,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
});
|
||
|
||
global.CommandError = function() {
|
||
var temp = Error.apply(this, arguments);
|
||
temp.name = "CommandError";
|
||
this.name = "CommandError";
|
||
this.message = temp.message;
|
||
}
|
||
|
||
CommandError.prototype = Object.create(Error.prototype, {
|
||
constructor: {
|
||
value: CommandError,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
});
|
||
|
||
global.getRandom = function() {
|
||
if (arguments.length == 1) {
|
||
if (typeof arguments[0] == Array) {
|
||
var random = Math.floor(Math.random() * 1000) % arguments[0].length;
|
||
return arguments[0][random];
|
||
}
|
||
} else {
|
||
var random = Math.floor(Math.random() * 1000) % arguments.length;
|
||
return arguments[random];
|
||
}
|
||
}
|
||
|
||
global.filterOffensive = function(offensive) {
|
||
offensive = offensive.replace("shit", "s•••");
|
||
offensive = offensive.replace("fuck", "f•••");
|
||
return offensive;
|
||
}
|
||
|
||
global.getEmoji = function(emojiName) {
|
||
if (consts.config.emojiServer == null) return ":arrow_right:"; //No emoji server configured
|
||
try {
|
||
return client.guilds.get(consts.config.emojiServer).emojis.find(function(item) {
|
||
return item.name == emojiName;
|
||
}).toString();
|
||
} catch (err) {
|
||
return ":arrow_right:";
|
||
}
|
||
}
|
||
|
||
global.sendPreloader = function(text, channel) {
|
||
return channel.send(getEmoji("loader") + " " + text);
|
||
}
|
||
|
||
global.logType = {
|
||
debug: 0,
|
||
info: 1,
|
||
warning: 2,
|
||
critical: 3,
|
||
good: 4
|
||
}
|
||
|
||
var capture = {};
|
||
global.captureInput = function(func, guild, author) {
|
||
capture[guild] = {
|
||
function: func,
|
||
guild: guild,
|
||
author: author
|
||
};
|
||
}
|
||
|
||
global.releaseInput = function(guild) {
|
||
delete capture[guild];
|
||
}
|
||
|
||
global.unembed = function(embed) {
|
||
let embedString = "";
|
||
if (embed.author) embedString += `**${embed.author.name}**\n`;
|
||
if (embed.title) embedString += `**${embed.title}**\n`;
|
||
if (embed.description) embedString += `${embed.description}\n`;
|
||
for (let i in embed.fields) {
|
||
embedString += `\n**${embed.fields[i].name}**\n${embed.fields[i].value}\n`
|
||
}
|
||
if (embed.footer) embedString += `\n${embed.footer.text}`
|
||
return embedString || $("PINS_EMPTY_EMBED"); //returns a string
|
||
}
|
||
|
||
global.awaitUserConfirmation = function(options) {
|
||
let $ = _[options.locale];
|
||
return new Promise(function(resolve, reject) {
|
||
if (options.time == null || options.time < 1) options.time = 5; //Default to 5 seconds
|
||
|
||
let embed = new Discord.RichEmbed();
|
||
embed.setTitle(options.title);
|
||
embed.setDescription(options.msg);
|
||
embed.setColor(consts.colors.info);
|
||
embed.setFooter($("AWAITUSERCONFIRMATION_CANCEL_PROMPT", {emoji: "🚫", time: options.time}));
|
||
if (options.extraFields != null) {
|
||
for (let field in options.extraFields) {
|
||
let currentField = options.extraFields[field];
|
||
embed.addField(currentField[0], currentField[1]);
|
||
}
|
||
}
|
||
|
||
options.channel.send(embed).then(function(message) {
|
||
message.react('🚫');
|
||
|
||
let timeout = setTimeout(function() {
|
||
if (!options.doNotClear)
|
||
message.clearReactions();
|
||
else {
|
||
for (let [, reaction] of message.reactions) {
|
||
reaction.remove().catch(() => { });
|
||
}
|
||
}
|
||
|
||
if (options.msgOnSuccess != "") {
|
||
embed.setDescription(options.msgOnSuccess);
|
||
}
|
||
embed.fields = [];
|
||
embed.setColor(consts.colors.done);
|
||
embed.setFooter($("AWAITUSERCONFIRMATION_FULFILLED"));
|
||
message.edit(embed);
|
||
resolve();
|
||
}, options.time * 1000);
|
||
message.awaitReactions(function(reaction) {
|
||
if (reaction.count > 1 && reaction.users.has(options.author.id)) return true;
|
||
return false;
|
||
}, {
|
||
max: 1
|
||
}).then(function() {
|
||
//Cancel the function
|
||
clearTimeout(timeout);
|
||
|
||
if (!options.doNotClear)
|
||
message.clearReactions();
|
||
else {
|
||
for (let [, reaction] of message.reactions) {
|
||
reaction.remove().catch(() => { });
|
||
}
|
||
}
|
||
|
||
if (options.msgOnFail != "") {
|
||
embed.setDescription(options.msgOnFail);
|
||
}
|
||
embed.fields = [];
|
||
embed.setColor(consts.colors.fail);
|
||
embed.setFooter($("AWAITUSERCONFIRMATION_CANCELLED"));
|
||
message.edit(embed);
|
||
reject();
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
//Set up screen
|
||
var screen = blessed.screen({
|
||
smartCSR: true,
|
||
dockBorders: true
|
||
});
|
||
screen.title = 'AstralMod ' + amVersion;
|
||
|
||
var titleBox = blessed.text({
|
||
top: "0",
|
||
left: "0",
|
||
width: "100%",
|
||
height: "1",
|
||
content: "AstralMod " + amVersion + " Console",
|
||
tags: true,
|
||
style: {
|
||
fg: 'black',
|
||
bg: 'white'
|
||
},
|
||
padding: {
|
||
left: 1
|
||
}
|
||
});
|
||
screen.append(titleBox);
|
||
|
||
var logBox = blessed.log({
|
||
top: 1,
|
||
left: 0,
|
||
width: "100%",
|
||
height: "100%-4",
|
||
tags: true,
|
||
style: {
|
||
fg: 'white',
|
||
bg: 'black',
|
||
scrollbar: {
|
||
bg: 'white'
|
||
}
|
||
},
|
||
padding: {
|
||
left: 1 // ,
|
||
// bottom: 2
|
||
},
|
||
scrollable: true,
|
||
alwaysScroll: true,
|
||
scrollOnInput: true,
|
||
scrollbar: true //,
|
||
//clickable: true
|
||
});
|
||
screen.append(logBox);
|
||
|
||
function clearBoxes() {
|
||
while (lockBox.length > 0) {
|
||
var box = lockBox.pop();
|
||
box.hide();
|
||
box.destroy();
|
||
}
|
||
|
||
}
|
||
|
||
logBox.on('click', function(mouse) {
|
||
var x = mouse.x;
|
||
var y = mouse.y;
|
||
|
||
//var line = logBox.getScreenLines()[y + 1];
|
||
var line = logBox.getBaseLine(y - 1);
|
||
|
||
//Remove escapes
|
||
while (line.indexOf("\x1b") != -1) {
|
||
var removeStart = line.indexOf("\x1b");
|
||
var removeEnd = line.indexOf("m", removeStart);
|
||
line = line.replace(line.slice(removeStart, removeEnd + 1), "");
|
||
}
|
||
//logBox.log(line);
|
||
|
||
//Get word around line
|
||
var previousSpace = line.lastIndexOf(" ", x - 2);
|
||
var nextSpace = line.indexOf(" ", x - 2);
|
||
|
||
previousSpace++;
|
||
|
||
if (nextSpace == -1) {
|
||
nextSpace = line.length;// - previousSpace;
|
||
}
|
||
var word = line.substring(previousSpace, nextSpace);
|
||
|
||
if (word.startsWith("[")) word = word.substr(1);
|
||
if (word.endsWith("]")) word = word.substr(0, word.length - 2);
|
||
|
||
var goUpwards = false;
|
||
var top = y + 1;
|
||
if (top + 7 > screen.height) {
|
||
top = y - 7;
|
||
goUpwards = true;
|
||
}
|
||
|
||
var left = x - 10;
|
||
if (left + 50 > screen.width) {
|
||
left = screen.width - 50;
|
||
} else if (left < 0) {
|
||
left = 0;
|
||
}
|
||
|
||
var boxOptions = {
|
||
top: top,
|
||
left: left,
|
||
width: 50,
|
||
style: {
|
||
fg: "black",
|
||
bg: "white",
|
||
border: {
|
||
fg: 'white',
|
||
bg: 'black'
|
||
}
|
||
},
|
||
border: {
|
||
type: "line"
|
||
},
|
||
padding: {
|
||
left: 2,
|
||
top: 1,
|
||
right: 2,
|
||
bottom: 1
|
||
}
|
||
};
|
||
|
||
clearBoxes();
|
||
|
||
//Determine type of object clicked
|
||
if (client.guilds.has(word)) {
|
||
//This is a guild
|
||
var guild = client.guilds.get(word);
|
||
var box = blessed.box(JSON.parse(JSON.stringify(boxOptions)));
|
||
box.content = "For Guild " + word + "\n" +
|
||
"Name: " + guild.name;
|
||
box.height = 7;
|
||
screen.append(box);
|
||
|
||
if (goUpwards) {
|
||
boxOptions.top -= 6;
|
||
} else {
|
||
boxOptions.top += 6;
|
||
}
|
||
|
||
var moreInfoButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
moreInfoButton.content = "More Info";
|
||
moreInfoButton.left = 0;
|
||
moreInfoButton.top = 2;
|
||
moreInfoButton.width = 9;
|
||
moreInfoButton.height = 1;
|
||
moreInfoButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("ginfo " + word);
|
||
});
|
||
box.append(moreInfoButton);
|
||
|
||
var membersButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
membersButton.content = "Members";
|
||
membersButton.left = 10;
|
||
membersButton.top = 2;
|
||
membersButton.width = 7;
|
||
membersButton.height = 1;
|
||
membersButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("ginfom " + word);
|
||
});
|
||
box.append(membersButton);
|
||
|
||
var channelsButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
channelsButton.content = "Channels";
|
||
channelsButton.left = 18;
|
||
channelsButton.top = 2;
|
||
channelsButton.width = 8;
|
||
channelsButton.height = 1;
|
||
channelsButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("ginfoc " + word);
|
||
});
|
||
box.append(channelsButton);
|
||
|
||
var bansButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
bansButton.content = "Bans";
|
||
bansButton.left = 27;
|
||
bansButton.top = 2;
|
||
bansButton.width = 4;
|
||
bansButton.height = 1;
|
||
bansButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("ginfob " + word);
|
||
});
|
||
box.append(bansButton);
|
||
|
||
lockBox.push(box);
|
||
}
|
||
|
||
if (client.channels.has(word)) {
|
||
//This is a channel
|
||
var channel = client.channels.get(word);
|
||
var box = blessed.box(JSON.parse(JSON.stringify(boxOptions)));
|
||
box.content = "For Channel " + word + "\n" +
|
||
"Name: " + channel.name;
|
||
box.height = 7;
|
||
screen.append(box);
|
||
|
||
if (goUpwards) {
|
||
boxOptions.top -= 6;
|
||
} else {
|
||
boxOptions.top += 6;
|
||
}
|
||
|
||
var moreInfoButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
moreInfoButton.content = "More Info";
|
||
moreInfoButton.left = 0;
|
||
moreInfoButton.top = 2;
|
||
moreInfoButton.width = 9;
|
||
moreInfoButton.height = 1;
|
||
moreInfoButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("cinfo " + word);
|
||
});
|
||
box.append(moreInfoButton);
|
||
|
||
var sendButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
sendButton.content = "Send";
|
||
sendButton.left = 10;
|
||
sendButton.top = 2;
|
||
sendButton.width = 4;
|
||
sendButton.height = 1;
|
||
sendButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
//processConsoleInput("cinfo " + word);
|
||
showTextBox();
|
||
textBox.setValue("> send " + word + " ");
|
||
renderScreen();
|
||
});
|
||
box.append(sendButton);
|
||
|
||
lockBox.push(box);
|
||
}
|
||
|
||
if (client.users.has(word)) {
|
||
//This is a user
|
||
var user = client.users.get(word);
|
||
var box = blessed.box(JSON.parse(JSON.stringify(boxOptions)));
|
||
box.content = "For User " + word + "\n" +
|
||
"Name: " + user.username;
|
||
box.height = 7;
|
||
screen.append(box);
|
||
|
||
if (goUpwards) {
|
||
boxOptions.top -= 6;
|
||
} else {
|
||
boxOptions.top += 6;
|
||
}
|
||
|
||
lockBox.push(box);
|
||
}
|
||
|
||
if (plugins.hasOwnProperty(word)) {
|
||
//This is a plugin
|
||
var plugin = plugins[word];
|
||
var box = blessed.box(JSON.parse(JSON.stringify(boxOptions)));
|
||
box.content = "For Plugin \"" + plugin.name + "\"\n" +
|
||
"Filename: " + word;
|
||
box.height = 7;
|
||
screen.append(box);
|
||
|
||
if (goUpwards) {
|
||
boxOptions.top -= 6;
|
||
} else {
|
||
boxOptions.top += 6;
|
||
}
|
||
|
||
var unloadButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
unloadButton.content = "Unload";
|
||
unloadButton.left = 0;
|
||
unloadButton.top = 2;
|
||
unloadButton.width = 6;
|
||
unloadButton.height = 1;
|
||
unloadButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("unload " + word);
|
||
});
|
||
box.append(unloadButton);
|
||
|
||
var reloadButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
}
|
||
});
|
||
reloadButton.content = "Reload";
|
||
reloadButton.left = 7;
|
||
reloadButton.top = 2;
|
||
reloadButton.width = 6;
|
||
reloadButton.height = 1;
|
||
reloadButton.on('click', function() {
|
||
clearBoxes();
|
||
renderScreen();
|
||
|
||
processConsoleInput("reload " + word);
|
||
});
|
||
box.append(reloadButton);
|
||
|
||
lockBox.push(box);
|
||
}
|
||
|
||
if (word == "save" || word == "plugins" || word == "vacuum" || word == "guilds" || word == "exit") {
|
||
processConsoleInput(word);
|
||
}
|
||
|
||
screen.render();
|
||
});
|
||
|
||
var textBox = blessed.textbox({
|
||
top: "100%-3",
|
||
left: -1,
|
||
width: "100%+2",
|
||
height: 3,
|
||
tags: true,
|
||
value: "> ",
|
||
border: {
|
||
type: "line"
|
||
},
|
||
style: {
|
||
fg: 'white',
|
||
bg: 'black',
|
||
border: {
|
||
fg: 'white',
|
||
bg: 'black'
|
||
}
|
||
},
|
||
inputOnFocus: true
|
||
});
|
||
screen.append(textBox);
|
||
|
||
var keyBox = blessed.box({
|
||
top: "100%-1",
|
||
left: "0",
|
||
width: "100%",
|
||
height: 1,
|
||
tags: true,
|
||
style: {
|
||
fg: 'black',
|
||
bg: 'white'
|
||
},
|
||
padding: {
|
||
left: 1
|
||
}
|
||
});
|
||
screen.append(keyBox);
|
||
|
||
var guildsButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
},
|
||
content: "^G Guilds",
|
||
left: 10,
|
||
width: 9,
|
||
height: 1,
|
||
top: "100%-1"
|
||
});
|
||
guildsButton.on('click', function() {
|
||
processConsoleInput("guilds");
|
||
});
|
||
screen.append(guildsButton);
|
||
|
||
var pluginsButton = blessed.button({
|
||
style: {
|
||
fg: "yellow",
|
||
bg: "blue"
|
||
},
|
||
content: "^P Plugins",
|
||
left: 20,
|
||
width: 10,
|
||
height: 1,
|
||
top: "100%-1"
|
||
});
|
||
pluginsButton.on('click', function() {
|
||
processConsoleInput("plugins");
|
||
});
|
||
screen.append(pluginsButton);
|
||
|
||
textBox.key('C-c', function(ch, key) {
|
||
shutdown();
|
||
});
|
||
|
||
screen.key('C-c', function() {
|
||
shutdown();
|
||
});
|
||
|
||
screen.key('C-g', function() {
|
||
processConsoleInput("guilds");
|
||
});
|
||
|
||
screen.key('C-p', function() {
|
||
processConsoleInput("plugins");
|
||
});
|
||
|
||
screen.key('up', function() {
|
||
logBox.scroll(-1);
|
||
renderScreen();
|
||
});
|
||
|
||
screen.on('keypress', function(key) {
|
||
if (lockBox.length != 0) {
|
||
clearBoxes();
|
||
} else if (key != undefined && !textBox.focused && key != "\r") {
|
||
showTextBox();
|
||
|
||
if (key != ":") {
|
||
textBox.setValue("> " + key);
|
||
}
|
||
}
|
||
});
|
||
|
||
screen.key('pageup', function() {
|
||
logBox.scroll(-logBox.height);
|
||
renderScreen();
|
||
});
|
||
|
||
screen.key('down', function() {
|
||
logBox.scroll(1);
|
||
renderScreen();
|
||
});
|
||
|
||
screen.key('pagedown', function() {
|
||
logBox.scroll(logBox.height);
|
||
renderScreen();
|
||
});
|
||
|
||
function showTextBox() {
|
||
logBox.height = "100%-4";
|
||
keyBox.content = "ESC Cancel Command ENTER Issue Command";
|
||
textBox.show();
|
||
textBox.focus();
|
||
guildsButton.hide();
|
||
pluginsButton.hide();
|
||
|
||
renderScreen();
|
||
}
|
||
|
||
var currentHistoryEntry = -1;
|
||
function hideTextBox() {
|
||
textBox.setValue("> ");
|
||
logBox.height = "100%-2";
|
||
keyBox.content = "^C Exit To issue a command, just start typing away.";
|
||
textBox.hide();
|
||
logBox.focus();
|
||
guildsButton.show();
|
||
pluginsButton.show();
|
||
currentHistoryEntry = -1;
|
||
|
||
renderScreen();
|
||
}
|
||
|
||
textBox.key("up", function() {
|
||
currentHistoryEntry++;
|
||
if (commandHistory[currentHistoryEntry] != null) {
|
||
textBox.setValue("> " + commandHistory[currentHistoryEntry]);
|
||
} else {
|
||
currentHistoryEntry = -1;
|
||
textBox.setValue("> ");
|
||
}
|
||
renderScreen();
|
||
});
|
||
|
||
textBox.key("down", function() {
|
||
currentHistoryEntry--
|
||
if (commandHistory[currentHistoryEntry] != null) {
|
||
textBox.setValue("> " + commandHistory[currentHistoryEntry]);
|
||
} else {
|
||
currentHistoryEntry = -1;
|
||
textBox.setValue("> ");
|
||
}
|
||
renderScreen();
|
||
});
|
||
|
||
textBox.on("cancel", function() {
|
||
hideTextBox();
|
||
});
|
||
|
||
function renderScreen() {
|
||
screen.render();
|
||
}
|
||
|
||
renderScreen();
|
||
hideTextBox();
|
||
|
||
console.error = function(data, ...args){
|
||
log(data, logType.warning);
|
||
};
|
||
|
||
global.log = function(logMessage, type = logType.debug) {
|
||
if (logMessage == null) {
|
||
return;
|
||
}
|
||
|
||
if (logMessage instanceof Error) {
|
||
logMessage = logMessage.toString() + "\n" + logMessage.stack;
|
||
} else {
|
||
logMessage = logMessage.toString();
|
||
}
|
||
|
||
//Log a message to the console
|
||
if (type == logType.debug) {
|
||
if (process.argv.indexOf("--debug") == -1) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
var logFormatting;
|
||
var logString;
|
||
|
||
var lines = logMessage.split("\n");
|
||
|
||
|
||
for (i = 0; i < lines.length; i++) {
|
||
switch (type) {
|
||
case logType.debug:
|
||
if (i == 0) {
|
||
logString = "[ ] ";
|
||
} else if (i == lines.length - 1) {
|
||
logString = " └─ ";
|
||
} else {
|
||
logString = " ├─ ";
|
||
}
|
||
logString += lines[i];
|
||
logFormatting = "\x1b[1m\x1b[34m";
|
||
break;
|
||
case logType.info:
|
||
if (i == 0) {
|
||
logString = "[i] ";
|
||
} else if (i == lines.length - 1) {
|
||
logString = " └─ ";
|
||
} else {
|
||
logString = " ├─ ";
|
||
}
|
||
logString += lines[i];
|
||
logFormatting = "\x1b[1m\x1b[37m";
|
||
break;
|
||
case logType.warning:
|
||
if (i == 0) {
|
||
logString = "[!] ";
|
||
} else if (i == lines.length - 1) {
|
||
logString = " └─ ";
|
||
} else {
|
||
logString = " ├─ ";
|
||
}
|
||
logString += lines[i];
|
||
logFormatting = "\x1b[1m\x1b[33m";
|
||
break;
|
||
case logType.critical:
|
||
if (i == 0) {
|
||
logString = "[X] ";
|
||
} else if (i == lines.length - 1) {
|
||
logString = " └─ ";
|
||
} else {
|
||
logString = " ├─ ";
|
||
}
|
||
logString += lines[i];
|
||
logFormatting = "\x1b[1m\x1b[31m";
|
||
break;
|
||
case logType.good:
|
||
if (i == 0) {
|
||
logString = "[>] ";
|
||
} else if (i == lines.length - 1) {
|
||
logString = " └─ ";
|
||
} else {
|
||
logString = " ├─ ";
|
||
}
|
||
logString += lines[i];
|
||
logFormatting = "\x1b[1m\x1b[32m";
|
||
break;
|
||
}
|
||
|
||
var logOutput = logFormatting + logString + "\x1b[0m";
|
||
|
||
logBox.log("[" + new Date().toLocaleTimeString("us", {
|
||
hour12: false
|
||
}) + "] " + logOutput);
|
||
|
||
logFile.write("[" + new Date().toLocaleTimeString("us", {
|
||
hour12: false
|
||
}) + "] " + logString + "\n");
|
||
|
||
renderScreen();
|
||
}
|
||
}
|
||
|
||
global.logPromiseRejection = function(object, action) {
|
||
log("Couldn't delete message " + object.id + " in channel " + object.channel.id, logType.warning);
|
||
};
|
||
|
||
// HACK HACK HACK HACK
|
||
// THIS SHOULD NOT BE RELIED UPON
|
||
// We should attach .catch() listeners to all promises ASAP
|
||
process.removeAllListeners('unhandledRejection').on('unhandledRejection', function(err, p) {
|
||
p.catch(function(error) {
|
||
log(error, logType.critical);
|
||
});
|
||
});
|
||
|
||
global.handleUnexpectedRejection = function(error) {
|
||
log(error, logType.critical);
|
||
}
|
||
|
||
process.on('uncaughtException', function(err) {
|
||
//Uncaught Exception
|
||
|
||
if (err.code == "ECONNRESET") {
|
||
log("Uncaught Exception: ECONNRESET", logType.critical);
|
||
log(err.stack, logType.critical);
|
||
} else {
|
||
log("Uncaught Exception:", logType.critical);
|
||
log(err.stack, logType.critical);
|
||
}
|
||
});
|
||
|
||
var stdinInterface = readline.createInterface({
|
||
input: process.stdin,
|
||
output: process.stdout,
|
||
terminal: false
|
||
});
|
||
|
||
global.parseTime = function(time) {
|
||
if (time.endsWith("m")) {
|
||
return parseInt(time.substr(0, time.length - 1)) * 60;
|
||
} else if (time.endsWith("h")) {
|
||
return parseInt(time.substr(0, time.length - 1)) * 60 * 60;
|
||
} else if (time.endsWith("d")) {
|
||
return parseInt(time.substr(0, time.length - 1)) * 60 * 60 * 24;
|
||
} else if (time.endsWith("w")) {
|
||
return parseInt(time.substr(0, time.length - 1)) * 60 * 60 * 24 * 7;
|
||
} else if (time.endsWith("s")) {
|
||
return parseInt(time.substr(0, time.length - 1));
|
||
} else {
|
||
return parseInt(time) * 60;
|
||
}
|
||
}
|
||
|
||
var commandHistory = [];
|
||
|
||
function processConsoleInput(line) {
|
||
commandHistory.unshift(line);
|
||
|
||
logBox.log(line);
|
||
|
||
const memberLine = function(member) {
|
||
var line = member.id + " " + member.user.tag;
|
||
if (member.nickname != null) {
|
||
line += " [" + member.nickname + "]";
|
||
}
|
||
if (member.user.bot) {
|
||
line += " \x1b[46m[BOT]";
|
||
}
|
||
return line;
|
||
};
|
||
|
||
var lLine = line.toLowerCase();
|
||
if (lLine == "help") {
|
||
var help = "AstralMod Console Commands:\n" +
|
||
"save Saves AstralMod configuration settings to disk. This happens every 30 seconds.\n" +
|
||
"loadunenc [filename] Loads an unencrypted settings.json file from disk.\n" +
|
||
"dumpsettings Prints the settings file contents, unencrypted, to the console\n" +
|
||
"plugins List loaded plugins\n" +
|
||
"load [plugin] Loads a plugin into AstralMod\n" +
|
||
"unload [plugin] Unloads a plugin from AstralMod\n" +
|
||
"reload [plugin] Unloads and then loads a plugin into AstralMod\n" +
|
||
"broadcast [message] Broadcasts a message to every server AstralMod is connected to\n" +
|
||
"vacuum Check the AstralMod Configuration File for errors\n" +
|
||
"reconnect Attempts to disconnect and reconnect to Discord\n" +
|
||
"guilds Lists guilds AstralMod knows about\n" +
|
||
"ginfo [guildid] Shows information about a guild\n" +
|
||
"ginfom [guildid] Shows members inside a guild\n" +
|
||
"ginfoc [guildid] Shows channels inside a guild\n" +
|
||
"ginfob [guildid] Shows bans of a guild\n" +
|
||
"cinfo [channelid] Finds a channel by its ID\n" +
|
||
"block [userid] Globally blocks a user from using AstralMod\n" +
|
||
"unblock [userid] Unblocks a user from AstralMod\n" +
|
||
"exit Exits AstralMod";
|
||
log(help, logType.info);
|
||
} else if (lLine == "exit") {
|
||
shutdown();
|
||
} else if (lLine == "loadunenc") {
|
||
log("Usage: loadunenc [filename]", logType.critical);
|
||
} else if (lLine.startsWith("loadunenc ")) {
|
||
var file = line.substr(10);
|
||
try {
|
||
var json = fs.readFileSync(file, "utf8");
|
||
var object = JSON.parse(json);
|
||
if (object != null) {
|
||
settings = object;
|
||
fs.unlink(file);
|
||
log("Settings loaded successfully, and the file has been deleted from disk. Please use the vacuum command now.", logType.good);
|
||
}
|
||
} catch (err) {
|
||
log("Couldn't load settings", logType.critical);
|
||
}
|
||
} else if (lLine == "dumpsettings") {
|
||
log(JSON.stringify(settings, null, 4), logType.info);
|
||
} else if (lLine == "plugins") {
|
||
var pluginsList = "Loaded plugins:";
|
||
for (plugin in plugins) {
|
||
pluginsList += "\n" + plugin;
|
||
}
|
||
log(pluginsList, logType.info);
|
||
} else if (lLine.startsWith("unload ")) {
|
||
unloadPlugin(line.substr(7));
|
||
log("Plugin " + line.substr(7) + " unloaded.", logType.good);
|
||
} else if (lLine == "unload") {
|
||
log("Usage: unload [filename]", logType.critical);
|
||
} else if (lLine.startsWith("load ")) {
|
||
if (loadPlugin(line.substr(5))) {
|
||
log("Plugin " + line.substr(5) + " loaded.", logType.good);
|
||
}
|
||
} else if (lLine == "load") {
|
||
log("Usage: load [filename]", logType.critical);
|
||
} else if (lLine.startsWith("reload ")) {
|
||
unloadPlugin(line.substr(7));
|
||
log("Plugin " + line.substr(7) + " unloaded.", logType.good);
|
||
if (loadPlugin(line.substr(7))) {
|
||
log("Plugin " + line.substr(7) + " loaded.", logType.good);
|
||
}
|
||
} else if (lLine == "reload") {
|
||
log("Usage: reload [filename]", logType.critical);
|
||
} else if (lLine == "save") {
|
||
saveSettings(true);
|
||
} else if (lLine == "reconnect") {
|
||
if (consts.keys.token != null) {
|
||
client.login(consts.keys.token).catch(function() {
|
||
log("Couldn't establish a connection to Discord.", logType.critical);
|
||
});
|
||
} else {
|
||
log("Couldn't find token", logType.critical);
|
||
}
|
||
} else if (lLine.startsWith("block ")) {
|
||
let blocked = line.substr(6);
|
||
if (settings.generalConfiguration.blockedUsers == undefined) {
|
||
settings.generalConfiguration.blockedUsers = []
|
||
}
|
||
|
||
settings.generalConfiguration.blockedUsers.push(blocked);
|
||
} else if (lLine.startsWith("unblock ")) {
|
||
let unblocked = line.substr(8);
|
||
if (settings.generalConfiguration.blockedUsers == undefined) {
|
||
settings.generalConfiguration.blockedUsers = [];
|
||
return;
|
||
}
|
||
|
||
settings.generalConfiguration.blockedUsers = settings.generalConfiguration.blockedUsers.filter(u => u != unblocked);
|
||
|
||
} else if (lLine == "blocked") {
|
||
if (settings.generalConfiguration.blockedUsers == undefined) {
|
||
settings.generalConfiguration.blockedUsers = [];
|
||
return;
|
||
}
|
||
|
||
log("List of blocked users:", logType.info);
|
||
for (let blocked of settings.generalConfiguration.blockedUsers) {
|
||
log(blocked, logType.info);
|
||
}
|
||
|
||
} else if (lLine.startsWith("broadcast ")) {
|
||
//Broadcast message to each server in either #general or the bot warnings general
|
||
var broadcast = line.substr(10);
|
||
log("Broadcasting message: " + broadcast, logType.info);
|
||
|
||
//Iterate over each server
|
||
for (key in settings.guilds) {
|
||
var guildSetting = settings.guilds[key];
|
||
var guild = client.guilds.get(key);
|
||
|
||
if (guildSetting != null) {
|
||
var channel = null;
|
||
if (guildSetting.botWarnings != null) {
|
||
if (guild != null) {
|
||
channel = guild.channels.get(guildSetting.botWarnings);
|
||
}
|
||
}
|
||
|
||
if (channel == null && guild != null && guild.channels.size > 0) {
|
||
//channel = guild.defaultChannel;
|
||
channel = guild.channels.array()[0];
|
||
}
|
||
|
||
if (channel != null) {
|
||
channel.send("SERVICE ANNOUNCEMENT: " + broadcast);
|
||
}
|
||
}
|
||
}
|
||
log("Broadcasting message complete", logType.good);
|
||
} else if (lLine == "broadcast") {
|
||
log("Usage: broadcast message", logType.critical);
|
||
} else if (lLine == "vacuum") {
|
||
vacuumSettings();
|
||
} else if (lLine.startsWith("cinfo ")) {
|
||
var channelId = line.substr(6);
|
||
var channel = client.channels.get(channelId);
|
||
if (channel == null) {
|
||
log("Unknown channel.", logType.info);
|
||
} else {
|
||
var info = "Information for channel " + channelId + ":\n" +
|
||
"Name: " + channel.name + "\n" +
|
||
"Guild: " + channel.guild.name + " [" + channel.guild.id + "]";
|
||
log(info, logType.info);
|
||
}
|
||
} else if (lLine == "cinfo") {
|
||
log("Usage: cinfo [channelid]", logType.critical);
|
||
} else if (lLine == "guilds") {
|
||
var response = "Guilds AstralMod is connected to:";
|
||
|
||
for ([id, guild] of client.guilds) {
|
||
response += "\n" + guild.id + " " + guild.name + "";
|
||
}
|
||
|
||
log(response, logType.info);
|
||
} else if (lLine.startsWith("ginfo ")) {
|
||
var guildLine = line.substr(6);
|
||
var guild = client.guilds.get(guildLine);
|
||
if (guild == null) {
|
||
log("Unknown guild.", logType.info);
|
||
} else {
|
||
var info = "Information for guild " + guildLine + ":\n" +
|
||
"Name: " + guild.name + "\n" +
|
||
"Owner: " + memberLine(guild.owner) + "\n" +
|
||
"Members: " + parseInt(guild.memberCount) + "\n" +
|
||
"Channels: " + parseInt(guild.channels.size);
|
||
log(info, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("ginfom ")) {
|
||
var guildLine = line.substr(7);
|
||
var guild = client.guilds.get(guildLine);
|
||
if (guild == null) {
|
||
log("Unknown guild.", logType.info);
|
||
} else {
|
||
var info = "Information for guild " + guildLine + ":\n" +
|
||
"Members: " + parseInt(guild.memberCount);
|
||
|
||
for ([id, member] of guild.members) {
|
||
info += "\n" + memberLine(member);
|
||
}
|
||
|
||
log(info, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("ginfoc ")) {
|
||
var guildLine = line.substr(7);
|
||
var guild = client.guilds.get(guildLine);
|
||
if (guild == null) {
|
||
log("Unknown guild.", logType.info);
|
||
} else {
|
||
var info = "Information for guild " + guildLine + ":\n" +
|
||
"Members: " + parseInt(guild.channels.size);
|
||
|
||
for ([id, channel] of guild.channels) {
|
||
info += "\n" + channel.id + " " + (channel.type == "text" ? "#" : " ") + channel.name;
|
||
}
|
||
|
||
log(info, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("ginfob ")) {
|
||
var guildLine = line.substr(7);
|
||
var guild = client.guilds.get(guildLine);
|
||
if (guild == null) {
|
||
log("Unknown guild.", logType.info);
|
||
} else {
|
||
guild.fetchBans().then(function(bans) {
|
||
var info = "Information for guild " + guildLine + ":\n" +
|
||
"Bans: " + parseInt(bans.size);
|
||
|
||
for ([id, user] of bans) {
|
||
info += "\n" + user.id + " " + user.username + "#" + user.discriminator;
|
||
}
|
||
|
||
log(info, logType.info);
|
||
}).catch(function() {
|
||
log("Couldn't fetch bans for that guild.", logType.critical);
|
||
});
|
||
}
|
||
} else if (lLine.startsWith("send ")) {
|
||
var args = line.substr(5);
|
||
|
||
var split = args.indexOf(" ");
|
||
if (split == -1) {
|
||
log("Usage: send [channelid] [message]", logType.critical);
|
||
} else {
|
||
var message = args.substr(split + 1);
|
||
var channel = args.substr(0, split);
|
||
|
||
var dChannel = client.channels.get(channel);
|
||
if (dChannel == null) {
|
||
log("Couldn't find that channel.", logType.critical);
|
||
} else {
|
||
dChannel.send(message);
|
||
log("Sent.", logType.good);
|
||
}
|
||
}
|
||
} else if (lLine == "send") {
|
||
log("Usage: send [channelid] [message]", logType.critical);
|
||
} else if (lLine == "ginfo") {
|
||
log("Usage: ginfo [guildid]", logType.critical);
|
||
} else {
|
||
log("Unknown command. For help, type \"help\" into the console.", logType.critical);
|
||
}
|
||
}
|
||
|
||
textBox.on("submit", function() {
|
||
//Input received!
|
||
var line = textBox.getText().substr(2);
|
||
hideTextBox();
|
||
|
||
processConsoleInput(line);
|
||
});
|
||
|
||
textBox.key('backspace', function() {
|
||
var line = textBox.getText();
|
||
if (!line.startsWith("> ")) {
|
||
if (line == ">") {
|
||
line = "> ";
|
||
} else if (line.startsWith(" ")) {
|
||
line = "> " + line.substring(1);
|
||
} else {
|
||
line = "> " + line;
|
||
}
|
||
textBox.setValue(line);
|
||
}
|
||
});
|
||
|
||
textBox.key('tab', function() {
|
||
//Autocomplete!
|
||
|
||
var line = textBox.getText().substr(2, textBox.getText().length - 6);
|
||
textBox.setValue("> " + line);
|
||
var lLine = line.toLowerCase();
|
||
|
||
if (lLine.startsWith("ginfo ")) {
|
||
var guildLine = line.substr(6);
|
||
var guilds = [];
|
||
for ([id, guild] of client.guilds) {
|
||
var id = guild.id;
|
||
if (id.startsWith(guildLine)) {
|
||
guilds.push(guild.id);
|
||
}
|
||
}
|
||
|
||
if (guilds.length == 1) {
|
||
textBox.setValue("> ginfo " + guilds[0]);
|
||
} else if (guilds.length == 0) {
|
||
log("No results.", logType.info)
|
||
} else {
|
||
var acOutput = "";
|
||
for (guild of guilds) {
|
||
acOutput += guild + " ";
|
||
}
|
||
log(acOutput, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("ginfom ")) {
|
||
var guildLine = line.substr(7);
|
||
var guilds = [];
|
||
for ([id, guild] of client.guilds) {
|
||
var id = guild.id;
|
||
if (id.startsWith(guildLine)) {
|
||
guilds.push(guild.id);
|
||
}
|
||
}
|
||
|
||
if (guilds.length == 1) {
|
||
textBox.setValue("> ginfom " + guilds[0]);
|
||
} else if (guilds.length == 0) {
|
||
log("No results.", logType.info)
|
||
} else {
|
||
var acOutput = "";
|
||
for (guild of guilds) {
|
||
acOutput += guild + " ";
|
||
}
|
||
log(acOutput, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("ginfoc ")) {
|
||
var guildLine = line.substr(7);
|
||
var guilds = [];
|
||
for ([id, guild] of client.guilds) {
|
||
var id = guild.id;
|
||
if (id.startsWith(guildLine)) {
|
||
guilds.push(guild.id);
|
||
}
|
||
}
|
||
|
||
if (guilds.length == 1) {
|
||
textBox.setValue("> ginfoc " + guilds[0]);
|
||
} else if (guilds.length == 0) {
|
||
log("No results.", logType.info)
|
||
} else {
|
||
var acOutput = "";
|
||
for (guild of guilds) {
|
||
acOutput += guild + " ";
|
||
}
|
||
log(acOutput, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("ginfob ")) {
|
||
var guildLine = line.substr(7);
|
||
var guilds = [];
|
||
for ([id, guild] of client.guilds) {
|
||
var id = guild.id;
|
||
if (id.startsWith(guildLine)) {
|
||
guilds.push(guild.id);
|
||
}
|
||
}
|
||
|
||
if (guilds.length == 1) {
|
||
textBox.setValue("> ginfob " + guilds[0]);
|
||
} else if (guilds.length == 0) {
|
||
log("No results.", logType.info)
|
||
} else {
|
||
var acOutput = "";
|
||
for (guild of guilds) {
|
||
acOutput += guild + " ";
|
||
}
|
||
log(acOutput, logType.info);
|
||
}
|
||
} else if (lLine.startsWith("send ")) {
|
||
var channelLine = line.substr(5);
|
||
if (channelLine.indexOf(" ") == -1) {
|
||
var channels = [];
|
||
for ([id, channel] of client.channels) {
|
||
var id = channel.id;
|
||
if (id.startsWith(channelLine)) {
|
||
channels.push(channel.id);
|
||
}
|
||
}
|
||
|
||
if (channels.length == 1) {
|
||
textBox.setValue("> send " + channels[0] + " ");
|
||
} else if (channels.length == 0) {
|
||
log("No results.", logType.info)
|
||
} else {
|
||
var acOutput = "";
|
||
for (channel of channels) {
|
||
acOutput += channel + " ";
|
||
}
|
||
log(acOutput, logType.info);
|
||
}
|
||
}
|
||
} else if (lLine.startsWith("cinfo ")) {
|
||
var channelLine = line.substr(6);
|
||
if (channelLine.indexOf(" ") == -1) {
|
||
var channels = [];
|
||
for ([id, channel] of client.channels) {
|
||
var id = channel.id;
|
||
if (id.startsWith(channelLine)) {
|
||
channels.push(channel.id);
|
||
}
|
||
}
|
||
|
||
if (channels.length == 1) {
|
||
textBox.setValue("> cinfo " + channels[0]);
|
||
} else if (channels.length == 0) {
|
||
log("No results.", logType.info)
|
||
} else {
|
||
var acOutput = "";
|
||
for (channel of channels) {
|
||
acOutput += channel + " ";
|
||
}
|
||
log(acOutput, logType.info);
|
||
}
|
||
}
|
||
} else {
|
||
log("Command autocompletion coming soon.", logType.info);
|
||
//TODO: Command autocompletion
|
||
}
|
||
});
|
||
|
||
log("Welcome to AstralMod!", logType.good);
|
||
|
||
global.getUserString = function(user) {
|
||
var u = user;
|
||
if (user.user != null) {
|
||
u = user.user;
|
||
}
|
||
return u.tag;
|
||
}
|
||
|
||
global.parseUser = function(query, guild = null) {
|
||
if (query.startsWith("<@!") && query.endsWith(">")) {
|
||
query = query.substr(3);
|
||
query = query.slice(0, -1);
|
||
} else if (query.startsWith("<@") && query.endsWith(">")) {
|
||
query = query.substr(2);
|
||
query = query.slice(0, -1);
|
||
}
|
||
var searchResults = [];
|
||
|
||
for (let [snowflake, user] of client.users) {
|
||
if (user.username.toLowerCase() == query.toLowerCase()) {
|
||
searchResults.unshift(user);
|
||
} else if (user.username.toLowerCase().indexOf(query.toLowerCase()) != -1) {
|
||
searchResults.push(user);
|
||
} else if ((user.username.toLowerCase() + "#" + user.discriminator).indexOf(query.toLowerCase()) != -1) {
|
||
searchResults.push(user);
|
||
} else if (user.id == query) {
|
||
searchResults.unshift(user);
|
||
}
|
||
}
|
||
|
||
if (guild != null) {
|
||
var guildSpecificResults = [];
|
||
for (let [snowflake, member] of guild.members) {
|
||
if (member.nickname != null) {
|
||
if (member.nickname.toLowerCase() == query.toLowerCase()) {
|
||
guildSpecificResults.unshift(member.user);
|
||
} else if (member.nickname.toLowerCase().indexOf(query.toLowerCase()) != -1) {
|
||
guildSpecificResults.push(member.user);
|
||
}
|
||
}
|
||
}
|
||
|
||
var pop = guildSpecificResults.pop();
|
||
while (pop != undefined) {
|
||
searchResults.unshift(pop);
|
||
pop = guildSpecificResults.pop();
|
||
}
|
||
}
|
||
|
||
return searchResults;
|
||
}
|
||
|
||
function setGame() {
|
||
client.user.setActivity(getRandom("with ban buttons",
|
||
"Annoying Victor",
|
||
prefix() + "help",
|
||
"Version " + amVersion,
|
||
"Google Pay",
|
||
"theShell",
|
||
"Monopoly",
|
||
"Final Fantastic Card",
|
||
"Ski jacket shopping"),
|
||
{
|
||
type: "PLAYING"
|
||
}
|
||
);
|
||
}
|
||
|
||
function isMod(member) {
|
||
if (member.id == global.botOwner.id)
|
||
return true;
|
||
|
||
if (tempMods[member.guild.id] != null && tempMods[member.guild.id].includes(member.id)) {
|
||
return true;
|
||
}
|
||
|
||
var modRoles = settings.guilds[member.guild.id].modRoles;
|
||
if (modRoles == null) {
|
||
if (member.permissions.has(Discord.Permissions.FLAGS.BAN_MEMBERS, true)) {
|
||
return true;
|
||
}
|
||
} else {
|
||
for (role of modRoles) {
|
||
if (member.roles.has(role)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
global.uinfo = function(user, channel, locale, offset, h24 = true, guild = null, compact = false) {
|
||
let $ = _[locale];
|
||
sendPreloader($("UINFO_RETRIEVING"), channel).then(function(messageToEdit) {
|
||
var member = null;
|
||
if (guild != null) {
|
||
for ([id, gMember] of guild.members) {
|
||
if (gMember.user.id == user.id) {
|
||
member = gMember;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (member == null) {
|
||
member = {
|
||
displayName: user.username,
|
||
tag: user.tag,
|
||
noGuild: true,
|
||
noGuildMessage: $("UINFO_NOT_PART_OF_SERVER"),
|
||
user: user
|
||
}
|
||
}
|
||
} else {
|
||
member = {
|
||
displayName: user.username,
|
||
tag: user.tag,
|
||
noGuild: true,
|
||
noGuildMessage: $("UINFO_NOT_ALLOWED_SERVER_SPECIFIC"),
|
||
user: user
|
||
}
|
||
}
|
||
|
||
var embed = new Discord.RichEmbed("uinfo");
|
||
embed.setAuthor(member.displayName, user.displayAvatarURL);
|
||
embed.setAuthor(getUserString(member), user.displayAvatarURL);
|
||
embed.setColor(consts.colors.info);
|
||
embed.setFooter($("UINFO_USER_ID", {id:user.id}));
|
||
|
||
if (compact) {
|
||
var msg = $("UINFO_DISCRIMINATOR", {discriminator:user.discriminator}) + "\n" +
|
||
$("UINFO_CREATEDAT", {createdat:{date: member.user.createdAt, h24: h24, offset: offset}}) + "\n";
|
||
|
||
if (member.noGuild != true) {
|
||
if (member.joinedAt.getTime() == 0) {
|
||
msg += $("UINFO_JOINEDAT", {joinedat:$("UINFO_INVALID_JOIN")});
|
||
} else {
|
||
msg += $("UINFO_JOINEDAT", {joinedat:{date: member.joinedAt, h24: h24, offset: offset}});
|
||
}
|
||
}
|
||
embed.setDescription(msg);
|
||
} else {
|
||
if (member.noGuild != true) {
|
||
embed.setDescription($("UINFO_USER_INFORMATION"));
|
||
} else {
|
||
embed.setDescription(member.noGuildMessage);
|
||
}
|
||
|
||
{
|
||
var msg = $("UINFO_CREATEDAT", {createdat:{date:member.user.createdAt, h24:h24, offset: offset}}) + "\n";
|
||
|
||
if (member.noGuild != true) {
|
||
if (member.joinedAt.getTime() == 0) {
|
||
msg += $("UINFO_JOINEDAT", {joinedat:$("UINFO_INVALID_JOIN")});
|
||
} else {
|
||
msg += $("UINFO_JOINEDAT", {joinedat:{date:member.joinedAt, h24:h24, offset: offset}});
|
||
}
|
||
}
|
||
|
||
embed.addField($("UINFO_TIMESTAMPS"), msg);
|
||
}
|
||
|
||
var msg;
|
||
if (member.noGuild) {
|
||
msg = $("UINFO_USERNAME", {username:user.username});
|
||
|
||
embed.addField($("UINFO_NAMES"), msg);
|
||
} else {
|
||
msg = $("UINFO_DISPLAYNAME", {displayname:member.displayName}) + "\n";
|
||
msg += $("UINFO_USERNAME", {username:user.username}) + "\n";
|
||
msg += $("UINFO_NICKNAME",{nickname: (member.nickname == null ? $("UINFO_NONICKNAME") : member.nickname)});
|
||
|
||
embed.addField($("UINFO_NAMES"), msg);
|
||
}
|
||
|
||
{
|
||
var msg = "";
|
||
|
||
if (user.bot) {
|
||
msg += "- " + $("UINFO_BOT_ACCOUNT_WARNING") + "\n";
|
||
}
|
||
|
||
if (banCounts[user.id] != 0 && banCounts[user.id] != null) {
|
||
msg += "- " + $("UINFO_BANNED_FROM", {count:parseInt(banCounts[user.id])});
|
||
}
|
||
|
||
if (msg != "") {
|
||
embed.addField($("UINFO_ALERTS"), msg);
|
||
}
|
||
}
|
||
}
|
||
messageToEdit.edit(embed);
|
||
}).catch(handleUnexpectedRejection);
|
||
}
|
||
|
||
function processModCommand(message, command) {
|
||
let $ = _[settings.users[message.author.id].locale];
|
||
var text = message.content;
|
||
var lText = text.toLowerCase();
|
||
|
||
let options = {
|
||
locale: settings.users[message.author.id].locale,
|
||
imperial: settings.users[message.author.id].units === "imperial",
|
||
h24: settings.users[message.author.id].timeunit !== "12h",
|
||
offset: settings.users[message.author.id].timezone
|
||
};
|
||
|
||
//Special cases
|
||
if (lText == prefix(message.guild.id) + "config") {
|
||
//Make sure person isn't configuring any other guild
|
||
for (key in settings.guilds) {
|
||
var guildSetting = settings.guilds[key];
|
||
if (guildSetting != null) {
|
||
if (guildSetting.configuringStage != 0) {
|
||
if (guildSetting.configuringUser == message.author.id) {
|
||
message.reply($("CONFIG_ALREADY_CONFIGURATING", {guild: client.guilds.get(key).name}));
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//Clear all user configuring for this user
|
||
for (key in settings.guilds) {
|
||
var guildSetting = settings.guilds[key];
|
||
if (guildSetting != null) {
|
||
if (guildSetting.configuringUser == message.author.id) {
|
||
settings.guilds[key].configuringUser = null;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (settings.guilds[message.guild.id].requiresConfig) {
|
||
// This branch is dead; no strings here need translation
|
||
if (message.author.id == global.botOwner.id || message.author.id == message.guild.owner.user.id) {
|
||
settings.guilds[message.guild.id].configuringUser = message.author.id;
|
||
settings.guilds[message.guild.id].configuringStage = 0;
|
||
|
||
message.author.send("Welcome to AstralMod! To start, let's get the roles of mods on the server. Enter the roles of mods on this server, separated by a space.");
|
||
|
||
var roles = "```";
|
||
for (let [, role] of message.guild.roles) {
|
||
roles += role.id + " = " + role.name + "\n";
|
||
}
|
||
roles += "```";
|
||
message.author.send(roles);
|
||
|
||
message.reply(":arrow_left: Continue in DMs.");
|
||
return true;
|
||
} else {
|
||
message.reply("You're not " + message.guild.owner.displayName);
|
||
return true;
|
||
}
|
||
} else {
|
||
//Configuration menu
|
||
|
||
//Make sure person has necessary permissions
|
||
if (message.author.id == global.botOwner.id || message.author.id == message.guild.owner.user.id || message.member.hasPermission("ADMINISTRATOR")) {
|
||
settings.guilds[message.guild.id].configuringUser = message.author.id;
|
||
settings.guilds[message.guild.id].configuringStage = 0;
|
||
message.author.send($("CONFIG_INTRO"), getSingleConfigureWelcomeText(message.guild, message.author));
|
||
|
||
message.reply($("CONFIG_CONTINUE_IN_DMS"), {emoji: ":arrow_left:"});
|
||
}
|
||
}
|
||
} else if (lText == prefix(message.guild.id) + "poweroff") {
|
||
if (message.author.id == global.botOwner.id) {
|
||
message.reply("AstralMod is now exiting.").then(function () {
|
||
shutdown();
|
||
}).then(function() {
|
||
shudtdown();
|
||
});
|
||
}
|
||
}
|
||
|
||
if (isMod(message.member)) {
|
||
if (command.startsWith("oknick")) {
|
||
let userId = command.substr(7);
|
||
acceptNicknameChange(message.guild.id, userId, message.channel.id, options);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function requestNickname(member, nickname, guild, options) {
|
||
if (nickname.length > 32) {
|
||
return "length";
|
||
}
|
||
|
||
if (settings.guilds[guild.id].pendingNicks == null) {
|
||
settings.guilds[guild.id].pendingNicks = {};
|
||
}
|
||
|
||
let pendingNicks = settings.guilds[guild.id].pendingNicks; //save us some typing
|
||
if (pendingNicks.cooldowns == null) {
|
||
pendingNicks.cooldowns = {};
|
||
}
|
||
|
||
let botwarningsChannel = client.channels.get(settings.guilds[guild.id].botWarnings);
|
||
if (botwarningsChannel == null) {
|
||
return "configuration";
|
||
}
|
||
|
||
if (pendingNicks.cooldowns[member.user.id] == null || moment.utc().isSameOrAfter(moment(pendingNicks.cooldowns[member.user.id]).utc().add(1, 'd'))) {
|
||
pendingNicks.cooldowns[member.user.id] = moment.utc().toDate();
|
||
|
||
if (nickChanges[guild.id] == null) {
|
||
nickChanges[guild.id] = {};
|
||
}
|
||
|
||
nickChanges[guild.id][member.user.id] = nickname;
|
||
|
||
let botwarningsChannelMessage;
|
||
if (nickname == "") {
|
||
botwarningsChannelMessage = ":arrows_counterclockwise: <@" + member.user.id + "> :arrow_right: `[clear]`. `" + prefix(member.guild.id) + "oknick " + member.user.id + "`";
|
||
} else {
|
||
botwarningsChannelMessage = ":arrows_counterclockwise: <@" + member.user.id + "> :arrow_right: `" + nickname + "`. `" + prefix(member.guild.id) + "oknick " + member.user.id + "`";
|
||
}
|
||
botwarningsChannel.send(botwarningsChannelMessage).then(function(message) {
|
||
message.react("✅").then(function() {
|
||
let acceptor;
|
||
message.awaitReactions(function(reaction) {
|
||
if (reaction.count <= 1) return false;
|
||
for (let user of reaction.users) {
|
||
if (isMod(message.guild.member(user[1]))) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}, {
|
||
max: 1
|
||
}).then(function() {
|
||
//Accept the nickname
|
||
acceptNicknameChange(message.guild.id, member.user.id, message.channel.id, options);
|
||
});
|
||
});
|
||
}).catch(handleUnexpectedRejection);
|
||
|
||
settings.guilds[guild.id].pendingNicks = pendingNicks;
|
||
return "ok";
|
||
} else {
|
||
settings.guilds[guild.id].pendingNicks = pendingNicks;
|
||
return moment(pendingNicks.cooldowns[member.user.id]).utc().add(1, 'd');
|
||
}
|
||
}
|
||
|
||
function acceptNicknameChange(guildId, userId, channelId, options) {
|
||
let $ = _[options.locale];
|
||
let guild = client.guilds.get(guildId);
|
||
if (nickChanges[guildId] != null) {
|
||
if (nickChanges[guildId][userId] != null) {
|
||
client.fetchUser(userId).then(function(user) {
|
||
return guild.fetchMember(user);
|
||
}).then(function(member) {
|
||
return member.setNickname(nickChanges[guildId][userId]);
|
||
}).then(function() {
|
||
nickChanges[guildId][userId] = null;
|
||
guild.channels.get(channelId).send($("OKNICK_ACCEPTED", {emoji: ":white_check_mark:"}));
|
||
}).catch(function() {
|
||
guild.channels.get(channelId).send($("OKNICK_THAT_DIDNT_WORK", {emoji: ":no_entry_sign:"}));
|
||
});
|
||
} else {
|
||
guild.channels.get(channelId).send($("OKNICK_THAT_DIDNT_WORK", {emoji: ":no_entry_sign:"}));
|
||
}
|
||
}
|
||
}
|
||
|
||
function getNickStatus(member, nickname, guild) {
|
||
if (nickname.length > 32) {
|
||
return "length";
|
||
}
|
||
|
||
let botwarningsChannel = client.channels.get(settings.guilds[guild.id].botWarnings);
|
||
if (botwarningsChannel == null) {
|
||
return "configuration";
|
||
}
|
||
|
||
let pendingNicks = settings.guilds[guild.id].pendingNicks; //save us some typing
|
||
if (pendingNicks == null || pendingNicks.cooldowns[member.user.id] == null || moment.utc().isSameOrAfter(moment(pendingNicks.cooldowns[member.user.id]).utc().add(1, 'd'))) {
|
||
return "ok";
|
||
}
|
||
|
||
return moment.duration(moment.utc().add(1, "day").diff(pendingNicks.cooldowns[member.user.id]));
|
||
}
|
||
|
||
function processAmCommand(message, options, command) {
|
||
var text = message.content;
|
||
var command;
|
||
let $ = _[options.locale];
|
||
|
||
if (command == "ping") {
|
||
let pingDate = Date.now();
|
||
message.channel.send($("PING_PINGING", {emoji: getEmoji("signal0"), interpolation: { escapeValue: false }})).then(function(message) {
|
||
let time = Date.now() - pingDate;
|
||
|
||
/* Times:
|
||
0 - 100ms: signal5
|
||
100 - 200ms: signal4
|
||
200 - 300ms: signal3
|
||
300 - 500ms: signal2
|
||
500 - 1000ms: signal1
|
||
1000ms+: signal0
|
||
*/
|
||
|
||
if (time == 420) {
|
||
message.edit($("PING_DONE_420", {emoji: getEmoji("signal2"), interpolation: { escapeValue: false }}));
|
||
} else {
|
||
let e;
|
||
if (time < 100) {
|
||
e = getEmoji("signal5");
|
||
} else if (time <= 200) {
|
||
e = getEmoji("signal4");
|
||
} else if (time <= 300) {
|
||
e = getEmoji("signal3");
|
||
} else if (time <= 500) {
|
||
e = getEmoji("signal2");
|
||
} else if (time <= 1000) {
|
||
e = getEmoji("signal1");
|
||
} else {
|
||
e = getEmoji("signal0");
|
||
}
|
||
message.edit($("PING_DONE", {emoji: e, time: time.toString(), interpolation: {escapeValue: false}}));
|
||
}
|
||
}).catch(function(error) {
|
||
log("Uncaught Exception:", logType.critical);
|
||
log(error.stack, logType.critical);
|
||
});
|
||
return true;
|
||
} else if (command == "nick") {
|
||
if (settings.guilds[message.guild.id].nickModeration) {
|
||
let nickResult = getNickStatus(message.member, "", message.guild);
|
||
if (moment.isDuration(nickResult)) {
|
||
message.reply($("NICK_WAIT", {time: {duration: nickResult}}));
|
||
} else if (nickResult == "length") {
|
||
message.reply($("NICK_TOO_LONG"));
|
||
} else if (nickResult == "configuration") {
|
||
message.reply($("NICK_SERVER_IMPROPER_CONFIG", {prefix: prefix(message.guild.id)}));
|
||
} else {
|
||
awaitUserConfirmation({
|
||
title: $("NICK_RESET_REQUEST_TITLE"),
|
||
msg: $("NICK_RESET_REQUEST_MESSAGE"),
|
||
msgOnSuccess: $("NICK_RESET_REQUEST_SUCCESS"),
|
||
msgOnFail: $("NICK_REQUEST_CANCEL"),
|
||
channel: message.channel,
|
||
author: message.author,
|
||
locale: options.locale
|
||
}).then(() => {
|
||
requestNickname(message.member, text.substr(8), message.guild, options);
|
||
}).catch(() => {
|
||
//Don't do anything
|
||
});
|
||
}
|
||
} else {
|
||
message.reply($("NICK_NOT_ACCEPTED"));
|
||
}
|
||
|
||
return true;
|
||
} else if (command.startsWith("nick ")) {
|
||
if (settings.guilds[message.guild.id].nickModeration) {
|
||
let nickResult = getNickStatus(message.member, text.substr(8), message.guild);
|
||
if (moment.isDuration(nickResult)) {
|
||
message.reply($("NICK_WAIT", {time: {duration: nickResult}}));
|
||
} else if (nickResult == "length") {
|
||
message.reply($("NICK_TOO_LONG"));
|
||
} else if (nickResult == "configuration") {
|
||
message.reply($("NICK_SERVER_IMPROPER_CONFIG", {prefix: prefix(message.guild.id)}));
|
||
} else {
|
||
awaitUserConfirmation({
|
||
title: $("NICK_CHANGE_REQUEST_TITLE"),
|
||
msg: $("NICK_CHANGE_REQUEST_MESSAGE"),
|
||
msgOnSuccess: $("NICK_CHANGE_REQUEST_SUCCESS"),
|
||
msgOnFail: $("NICK_REQUEST_CANCEL"),
|
||
channel: message.channel,
|
||
author: message.author,
|
||
extraFields: [
|
||
[$("NICK_NICKNAME"), text.substr(8)]
|
||
],
|
||
locale: options.locale
|
||
}).then(function() {
|
||
requestNickname(message.member, text.substr(8), message.guild, options);
|
||
}).catch(function() {
|
||
//Don't do anything
|
||
});
|
||
}
|
||
} else {
|
||
message.reply($("NICK_NOT_ACCEPTED"));
|
||
}
|
||
return true;
|
||
} else if (command == "version") {
|
||
message.channel.send($("VERSION", {version: amVersion}));
|
||
return true;
|
||
} else if (command == "about") {
|
||
let embed = new Discord.RichEmbed();
|
||
embed.setColor(consts.colors.done);
|
||
embed.setAuthor($("ABOUT_TITLE", {verion: amVersion}), client.user.avatarURL);
|
||
embed.setDescription($("ABOUT_ABOUT"));
|
||
embed.addField($("ABOUT_FILE_BUG"), $("ABOUT_FILE_BUG_CONTENT", {link: "(https://github.com/vicr123/AstralMod/issues)"}));
|
||
embed.addField($("ABOUT_SOURCE"), $("ABOUT_SOURCE_CONTENT", {link: "(https://github.com/vicr123/AstralMod/issues)"}));
|
||
embed.addField($("ABOUT_CONTRIBUTORS"), $("ABOUT_CONTRIBUTORS_CONTENT", {contributors: "\n- Blake#0007\n- reflectronic#5190"}));
|
||
embed.setFooter($("ABOUT_THANKS", {version: amVersion}));
|
||
message.channel.send(embed);
|
||
return true;
|
||
} else if (command == "setlocale") {
|
||
let embed = new Discord.RichEmbed();
|
||
embed.setColor(consts.colors.done);
|
||
embed.setAuthor($("SETLOC_TITLE"));
|
||
|
||
let thisLocale = $("THIS_LOCALE");
|
||
if (options.locale == "en") thisLocale = "English";
|
||
embed.addField($("SETLOC_YOUR_LOCALE"), "`" + options.locale + "` - " + thisLocale);
|
||
|
||
let availableLocales = "";
|
||
for (let locale of availableTranslations) {
|
||
let thisLocale = _[locale]("THIS_LOCALE");
|
||
if (thisLocale == _.en("THIS_LOCALE")) thisLocale = "";
|
||
if (locale == "en") thisLocale = "English";
|
||
availableLocales += "`" + locale + "` - " + thisLocale + "\n";
|
||
}
|
||
embed.addField($("SETLOC_AVAILABLE_LOCALES"), availableLocales);
|
||
|
||
embed.setFooter($("SETLOC_DISCLAIMER"));
|
||
message.channel.send(embed);
|
||
} else if (command.startsWith("setlocale ")) {
|
||
let locale = command.substr(10);
|
||
|
||
let setLocale = function(locale) {
|
||
settings.users[message.author.id].locale = locale;
|
||
|
||
let thisLocale = _[locale]("THIS_LOCALE");
|
||
if (locale == "en") thisLocale = "English";
|
||
|
||
let embed = new Discord.RichEmbed();
|
||
embed.setColor(consts.colors.done);
|
||
embed.setAuthor(_[locale]("SETLOC_TITLE"));
|
||
embed.setDescription(_[locale]("SETLOC_LANGUAGE", {locale: thisLocale}));
|
||
embed.setFooter(_[locale]("SETLOC_DISCLAIMER"));
|
||
message.channel.send(embed);
|
||
}
|
||
|
||
if (availableTranslations.getTranslation(locale) != undefined) {
|
||
setLocale(availableTranslations.getTranslation(locale));
|
||
return true;
|
||
}
|
||
|
||
//Locale unavailable
|
||
locale = settings.users[message.author.id].locale;
|
||
if (locale == null) locale = "en";
|
||
var embed = new Discord.RichEmbed();
|
||
embed.setColor(consts.colors.fail);
|
||
embed.setAuthor($("SETLOC_TITLE"));
|
||
embed.setDescription($("SETLOC_UNAVAILABLE"))
|
||
|
||
let availableLocales = "";
|
||
for (let locale of availableTranslations) {
|
||
let thisLocale = _[locale]("THIS_LOCALE");
|
||
if (thisLocale == _.en("THIS_LOCALE")) thisLocale = "";
|
||
if (locale == "en") thisLocale = "English";
|
||
availableLocales += "`" + locale + "` - " + thisLocale + "\n";
|
||
}
|
||
embed.addField($("SETLOC_AVAILABLE_LOCALES"), availableLocales);
|
||
embed.setFooter($("SETLOC_DISCLAIMER"));
|
||
|
||
message.channel.send(embed);
|
||
return true;
|
||
} else if (command == "help") { //General help
|
||
var embed = new Discord.RichEmbed();
|
||
embed.setColor(consts.colors.done);
|
||
embed.setAuthor($("HELP_CONTENTS"));
|
||
embed.setDescription($("HELP_CONTENTS_INTRODUCTION", {prefix: prefix(message.guild.id)}));
|
||
|
||
embed.addField($("HELP_CORE_COMMANDS"), "**config**\n**shoo**\n**oknick**\nping\nnick\nsetlocale\nsudo\nversion\nabout\nhelp", true);
|
||
|
||
for (key in plugins) {
|
||
var plugin = plugins[key];
|
||
if (plugin.availableCommands != null) {
|
||
var commandsList = "";
|
||
|
||
if (plugin.availableCommands.general != null) {
|
||
if (plugin.availableCommands.general.modCommands != null) {
|
||
for (command of plugin.availableCommands.general.modCommands) {
|
||
commandsList += "**" + command + "**\n";
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands.general.commands != null) {
|
||
for (command of plugin.availableCommands.general.commands) {
|
||
commandsList += command + "\n";
|
||
}
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands[message.guild.id] != null) {
|
||
if (plugin.availableCommands[message.guild.id].modCommands != null) {
|
||
for (command of plugin.availableCommands[message.guild.id].modCommands) {
|
||
commandsList += "**" + command + "**\n";
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands[message.guild.id].commands != null) {
|
||
for (command of plugin.availableCommands[message.guild.id].commands) {
|
||
commandsList += command + "\n";
|
||
}
|
||
}
|
||
}
|
||
|
||
if (commandsList != "") {
|
||
if (plugin.translatableName == null) {
|
||
embed.addField(plugin.name, commandsList, true);
|
||
} else {
|
||
embed.addField(_.help[options.locale](plugin.translatableName), commandsList, true);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
embed.setFooter($("HELP_FOOTER", {amVersion: amVersion}));
|
||
message.channel.send("", { embed: embed });
|
||
return true;
|
||
} else if (command.startsWith("sudo")) {
|
||
if (isMod(message.member)) {
|
||
message.reply($("SUDO_ALREADY_SUDO"));
|
||
return;
|
||
}
|
||
|
||
let embed = new Discord.RichEmbed;
|
||
embed.setTitle($("SUDO_TITLE", {emoji: ":shield:"}));
|
||
embed.setDescription($("SUDO_USER", {user: message.author.tag}) + "\n" +
|
||
$("SUDO_ROLE", {role: message.member.highestRole.name}) + "\n" +
|
||
$("SUDO_SERVER", {server: message.guild.name}));
|
||
embed.setFooter($("SUDO_FOOTER", {emoji1: "✅", emoji2: "🚫", time: "5"}));
|
||
embed.setColor(consts.colors.info);
|
||
|
||
|
||
message.channel.send(embed).then(m => {
|
||
m.react("✅");
|
||
m.react("🚫");
|
||
|
||
let okay = false;
|
||
if (global.tempMods[message.guild.id] == null) global.tempMods[message.guild.id] = [];
|
||
let collector = m.createReactionCollector(function(reaction) {
|
||
if (reaction.count <= 1) return false;
|
||
if (reaction.emoji.name == "✅" || reaction.emoji.name == "🚫") {
|
||
for (let user of reaction.users) {
|
||
if (isMod(message.guild.members.get(user[0])) && user[1].id != client.user.id || (reaction.emoji.name == "🚫" && user[1].id == message.author.id)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}, {time: 300000});
|
||
collector.on('collect', r => {
|
||
if (r.emoji.name == "✅") {
|
||
global.tempMods[message.guild.id].push(message.author.id);
|
||
setTimeout(() => global.tempMods[message.guild.id].splice(global.tempMods[message.guild.id].indexOf(message.author.id), 1), 300000)
|
||
embed.setDescription($("SUDO_FULFILLED_DESCRIPTION"))
|
||
embed.setFooter($("AWAITUSERCONFIRMATION_FULFILLED"));
|
||
embed.setColor(consts.colors.done)
|
||
m.edit(embed);
|
||
m.clearReactions();
|
||
okay = true;
|
||
collector.stop();
|
||
} else if (r.emoji.name == "🚫") {
|
||
embed.setFooter($("AWAITUSERCONFIRMATION_CANCELLED"));
|
||
embed.setDescription($("SUDO_CANCELLED_DESCRIPTION"))
|
||
embed.setColor(consts.colors.fail)
|
||
m.edit(embed);
|
||
m.clearReactions();
|
||
okay = true;
|
||
collector.stop();
|
||
}
|
||
});
|
||
collector.on('end', () => {
|
||
if (!okay) {
|
||
embed.setFooter($("AWAITUSERCONFIRMATION_CANCELLED"));
|
||
embed.setDescription($("SUDO_TIMED_OUT"))
|
||
embed.setColor(consts.colors.fail)
|
||
m.edit(embed);
|
||
m.clearReactions();
|
||
}
|
||
});
|
||
})
|
||
} else if (command.startsWith("help ")) { //Contextual help
|
||
//Get help for specific command
|
||
let h$ = _.help[options.locale];
|
||
var embed = new Discord.RichEmbed();
|
||
embed.setAuthor($("HELP_CONTENTS"));
|
||
|
||
var helpCmd = command.substr(5);
|
||
|
||
var help = {};
|
||
switch (helpCmd) {
|
||
case "config":
|
||
help.title = prefix(message.guild.id) + "config";
|
||
help.helpText = h$("CONFIG_HELPTEXT");
|
||
break;
|
||
case "shoo":
|
||
help.title = prefix(message.guild.id) + "shoo";
|
||
help.helpText = h$("SHOO_HELPTEXT");
|
||
break;
|
||
case "oknick":
|
||
help.title = prefix(message.guild.id) + "oknick";
|
||
help.helpText = h$("OKNICK_HELPTEXT");
|
||
break;
|
||
case "ping":
|
||
help.title = prefix(message.guild.id) + "ping";
|
||
help.helpText = h$("PING_HELPTEXT");
|
||
break;
|
||
case "version":
|
||
help.title = prefix(message.guild.id) + "version";
|
||
help.helpText = h$("VERSION_HELPTEXT");
|
||
break;
|
||
case "nick":
|
||
help.title = prefix(message.guild.id) + "nick";
|
||
help.usageText = prefix(message.guild.id) + "nick nickname";
|
||
help.helpText = h$("NICK_HELPTEXT");
|
||
help.param1 = h$("NICK_PARAM1");
|
||
break;
|
||
case "setlocale":
|
||
help.title = prefix(message.guild.id) + "setlocale";
|
||
help.usageText = prefix(message.guild.id) + "setlocale [locale]";
|
||
help.helpText = h$("SETLOCALE_HELPTEXT");
|
||
break;
|
||
case "help":
|
||
help.title = prefix(message.guild.id) + "help";
|
||
help.usageText = prefix(message.guild.id) + "help [command]";
|
||
help.helpText = h$("HELP_HELPTEXT");
|
||
help.param1 = h$("HELP_PARAM1");
|
||
break;
|
||
case "about":
|
||
help.title = prefix(message.guild.id) + "about";
|
||
help.usageText = prefix(message.guild.id) + "about";
|
||
help.helpText = h$("ABOUT_HELPTEXT");
|
||
break;
|
||
case "sudo":
|
||
help.title = prefix(message.guild.id) + "sudo";
|
||
help.usageText = prefix(message.guild.id) + "sudo";
|
||
help.helpText = h$("SUDO_HELPTEXT");
|
||
break;
|
||
default:
|
||
//Look thorough plugins for help
|
||
for (key in plugins) {
|
||
var plugin = plugins[key];
|
||
if (plugin.acquireHelp != null) {
|
||
if (plugin.availableCommands != null) {
|
||
if (plugin.availableCommands.general != null) {
|
||
if (plugin.availableCommands.general.hiddenCommands != null) {
|
||
if (plugin.availableCommands.general.hiddenCommands.indexOf(helpCmd) != -1) {
|
||
help = plugin.acquireHelp(helpCmd, message, h$);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands.general.modCommands != null) {
|
||
if (plugin.availableCommands.general.modCommands.indexOf(helpCmd) != -1) {
|
||
help = plugin.acquireHelp(helpCmd, message, h$);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands.general.commands != null) {
|
||
if (plugin.availableCommands.general.commands.indexOf(helpCmd) != -1) {
|
||
help = plugin.acquireHelp(helpCmd, message, h$);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands[message.guild.id] != null) {
|
||
if (plugin.availableCommands[message.guild.id].modCommands != null) {
|
||
if (plugin.availableCommands[message.guild.id].modCommands.indexOf(helpCmd) != -1) {
|
||
help = plugin.acquireHelp(helpCmd, message, h$);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (plugin.availableCommands[message.guild.id].commands != null) {
|
||
if (plugin.availableCommands[message.guild.id].commands.indexOf(helpCmd) != -1) {
|
||
help = plugin.acquireHelp(helpCmd, message, h$);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (help.helpText == null) {
|
||
embed.setColor(consts.colors.fail);
|
||
embed.setDescription($("HELP_UNAVAILABLE"));
|
||
} else {
|
||
embed.setColor(consts.colors.done);
|
||
if (help.title == null) {
|
||
embed.setDescription($("HELP_COMMAND_TITLE"));
|
||
} else {
|
||
embed.setDescription($("HELP_COMMAND_FOR", {title: help.title}));
|
||
}
|
||
|
||
if (help.usageText != null) {
|
||
embed.addField($("HELP_COMMAND_USAGE"), help.usageText);
|
||
}
|
||
|
||
embed.addField($("HELP_COMMAND_DESCRIPTION"), help.helpText);
|
||
|
||
|
||
if (help.options != null) {
|
||
var options = "```";
|
||
for (value of help.options) {
|
||
options += value + "\n";
|
||
}
|
||
options += "```";
|
||
embed.addField($("HELP_COMMAND_OPTIONS"), options);
|
||
}
|
||
|
||
if (help.availableOptions != null) {
|
||
embed.addField($("HELP_COMMAND_AVAILABLE_OPTIONS"), help.availableOptions);
|
||
}
|
||
|
||
if (help.param1 != null) {
|
||
embed.addField($("HELP_COMMAND_PARAM", {param: "1"}), help.param1);
|
||
}
|
||
|
||
if (help.param2 != null) {
|
||
embed.addField($("HELP_COMMAND_PARAM", {param: "2"}), help.param2);
|
||
}
|
||
|
||
if (help.param3 != null) {
|
||
embed.addField($("HELP_COMMAND_PARAM", {param: "3"}), help.param3);
|
||
}
|
||
|
||
if (help.remarks != null) {
|
||
embed.addField($("HELP_COMMAND_REMARKS"), help.remarks);
|
||
}
|
||
}
|
||
embed.setFooter("AstralMod " + amVersion);
|
||
message.channel.send("", { embed: embed });
|
||
return true;
|
||
} else if (command.startsWith("throw ")) {
|
||
var msg = command.substr(6);
|
||
throw new Error(msg);
|
||
return true;
|
||
} else if (command == "shoo") {
|
||
if (message.author.id == global.botOwner.id | message.member.hasPermission(Discord.Permissions.FLAGS.KICK_MEMBERS, false, true, true)) {
|
||
awaitUserConfirmation({
|
||
title: $("SHOO_TITLE"),
|
||
msg: $("SHOO_MESSAGE"),
|
||
msgOnSuccess: $("SHOO_SUCCESS", {emoji: ":arrow_left:"}),
|
||
msgOnFail: $("SHOO_CANCEL"),
|
||
channel: message.channel,
|
||
author: message.author,
|
||
time: 10,
|
||
locale: options.locale
|
||
}).then(() => {
|
||
message.guild.leave().catch(function() {
|
||
message.reply($("SHOO_FAILURE"));
|
||
});
|
||
saveSettings();
|
||
}).catch(err => {
|
||
//Do nothing
|
||
});
|
||
|
||
} else {
|
||
message.reply($("SHOO_NO_PERMS"));
|
||
}
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
function getChannels(guild) {
|
||
let str = "```\n";
|
||
for (let channel of guild.channels.array().sort((a, b) => a.name.localeCompare(b.name))) {
|
||
if (channel.type == "text" && channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
|
||
str += `${channel.id} — #${channel.name}\n`
|
||
}
|
||
}
|
||
str += "```"
|
||
|
||
return str;
|
||
}
|
||
|
||
function getSingleConfigureWelcomeText(guild, author) {
|
||
var guildSetting = settings.guilds[guild.id];
|
||
let $ = _[settings.users[author.id].locale];
|
||
|
||
let embed = new Discord.RichEmbed();
|
||
|
||
|
||
if (guildSetting.modRoles == null) {
|
||
embed.addField($("CONFIG_STAFF_ROLES_TITLE", {number: 1}), $("CONFIG_STAFF_ROLES_DISCORD_PERMISSIONS"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_STAFF_ROLES_TITLE", {number: 1}), $("CONFIG_STAFF_ROLES_COUNT", {count: guildSetting.modRoles.length}), true);
|
||
}
|
||
|
||
if (guild.channels.get(guildSetting.memberAlerts) == null) {
|
||
embed.addField($("CONFIG_MEMBER_ALERTS_TITLE", {number: 2}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_MEMBER_ALERTS_TITLE", {number: 2}), `<#${guild.channels.get(guildSetting.memberAlerts).id}>`, true);
|
||
}
|
||
|
||
if (guild.channels.get(guildSetting.chatLogs) == null) {
|
||
embed.addField($("CONFIG_CHAT_LOGS_TITLE", {number: 3}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_CHAT_LOGS_TITLE", {number: 3}), `<#${guild.channels.get(guildSetting.chatLogs).id}>`, true);
|
||
}
|
||
|
||
if (guild.channels.get(guildSetting.botWarnings) == null) {
|
||
embed.addField($("CONFIG_BOT_WARNINGS_TITLE", {number: 4}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_CHAT_LOGS_TITLE", {number: 4}), `<#${guild.channels.get(guildSetting.botWarnings).id}>`, true);
|
||
}
|
||
|
||
if (guild.channels.get(guildSetting.suggestions) == null) {
|
||
embed.addField($("CONFIG_SUGGESTIONS_TITLE", {number: 5}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_SUGGESTIONS_TITLE", {number: 5}), `<#${guild.channels.get(guildSetting.suggestions).id}>`, true);
|
||
}
|
||
|
||
if (guildSetting.locale == null) {
|
||
guildSetting.locale = "en"
|
||
}
|
||
|
||
let thisLocale = _[guildSetting.locale]("THIS_LOCALE");
|
||
if (thisLocale == _.en("THIS_LOCALE")) thisLocale = "";
|
||
if (guildSetting.locale == "en") thisLocale = "English";
|
||
|
||
|
||
embed.addField($("CONFIG_LOCALE_TITLE", {number: 6}), `${thisLocale} (${guildSetting.locale})`, true);
|
||
embed.addField($("CONFIG_SERVER_PREFIX_TITLE", {number: 7}), guildSetting.serverPrefix === undefined ? $("CONFIG_SERVER_PREFIX_DEFAULT", {prefix: prefix()}) : guildSetting.serverPrefix, true);
|
||
|
||
|
||
if (guildSetting.nickModeration == null || guildSetting.nickModeration == false) {
|
||
embed.addField($("CONFIG_NICK_MODERATION_TITLE", {number: "A"}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_NICK_MODERATION_TITLE", {number: "A"}), $("CONFIG_ENABLED"), true);
|
||
}
|
||
|
||
|
||
if (guildSetting.echoOffensive == null || guildSetting.echoOffensive == false) {
|
||
embed.addField($("CONFIG_FILTERING_TITLE", {number: "B"}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_FILTERING_TITLE", {number: "B"}), $("CONFIG_ENABLED"), true);
|
||
}
|
||
|
||
if (guildSetting.pinToPin == null || guildSetting.pinToPin == false) {
|
||
embed.addField($("CONFIG_PIN_TO_PIN_TITLE", {number: "C"}), $("CONFIG_DISABLED"), true);
|
||
} else {
|
||
embed.addField($("CONFIG_PIN_TO_PIN_TITLE", {number: "C"}), $("CONFIG_ENABLED"), true);
|
||
}
|
||
|
||
embed.setFooter($("CONFIG_FOOTER"));
|
||
embed.setColor(consts.colors.info)
|
||
|
||
return embed;
|
||
}
|
||
|
||
function processSingleConfigure(message, guild) {
|
||
let $ = _[settings.users[message.author.id].locale]
|
||
var text = message.content.toLowerCase();
|
||
var guildSetting = settings.guilds[guild.id];
|
||
|
||
switch (guildSetting.configuringStage) {
|
||
case -10: { //Reset AstralMod
|
||
if (message.content == "Reset AstralMod") { //Purge all configuration for this server
|
||
log("Purging all configuration for " + guild.id);
|
||
guildSetting = {
|
||
requiresConfig: false
|
||
};
|
||
log("Configuration for " + guild.id + " purged.", logType.good);
|
||
message.author.send($("CONFIG_CONFIG_PURGED", {prefix: prefix(message.guild.id)}));
|
||
} else { //Cancel
|
||
message.author.send($("CONFIG_CANCEL_CONFIGURATION"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
}
|
||
break;
|
||
}
|
||
case 0: { //Main Menu
|
||
switch (text) {
|
||
case "1": //Staff Roles
|
||
settings.guilds[guild.id].configuringUser = message.author.id;
|
||
settings.guilds[guild.id].configuringStage = 0;
|
||
message.author.send($("CONFIG_STAFF_SETUP"));
|
||
|
||
var roles = "```";
|
||
for (let role of guild.roles.array().sort((a, b) => a.name.localeCompare(b.name))) {
|
||
roles += role.id + " — " + role.name + "\n";
|
||
}
|
||
roles += "```";
|
||
message.author.send(roles);
|
||
|
||
guildSetting.configuringStage = 10;
|
||
break;
|
||
case "2": //Member Alerts
|
||
message.author.send($("CONFIG_MEMBER_ALERT_SETUP"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 20;
|
||
break;
|
||
case "3": //Chat Logs
|
||
message.author.send($("CONFIG_CHAT_LOGS_SETUP"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 30;
|
||
break;
|
||
case "4": //Bot warnings
|
||
message.author.send($("CONFIG_BOT_WARNINGS_SETUP"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 40;
|
||
break;
|
||
case "5": //Suggestions
|
||
message.author.send($("CONFIG_SUGGESTIONS_SETUP"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 50;
|
||
break;
|
||
case "6": //Locale
|
||
message.author.send($("CONIFG_LOCALE_SETUP"));
|
||
let locales = "";
|
||
for (let locale of availableTranslations) {
|
||
let thisLocale = _[locale]("THIS_LOCALE");
|
||
if (thisLocale == _.en("THIS_LOCALE")) thisLocale = "";
|
||
if (locale == "en") thisLocale = "English";
|
||
locales += "`" + locale + "` - " + thisLocale + "\n";
|
||
}
|
||
|
||
message.author.send(locales);
|
||
guildSetting.configuringStage = 60;
|
||
break;
|
||
case "7": //Server prefix
|
||
message.author.send($("CONFIG_SERVER_PREFIX_SETUP"));
|
||
guildSetting.configuringStage = 70;
|
||
break;
|
||
case "0": //Exit
|
||
message.author.send($("CONFIG_CONFIGURATION_COMPLETE"));
|
||
guildSetting.configuringUser = null;
|
||
break;
|
||
case "a": //Nick Moderation
|
||
if (guildSetting.nickModeration) {
|
||
guildSetting.nickModeration = false;
|
||
} else {
|
||
guildSetting.nickModeration = true;
|
||
}
|
||
|
||
message.author.send($("CONFIG_NICK_MODERATION_TOGGLED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
break;
|
||
case "b": //Nick Moderation
|
||
if (guildSetting.echoOffensive) {
|
||
guildSetting.echoOffensive = false;
|
||
message.author.send($("CONFIG_FILTERING_OFF"));
|
||
} else {
|
||
guildSetting.echoOffensive = true;
|
||
message.author.send($("CONFIG_FILTERING_ON"));
|
||
}
|
||
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
break;
|
||
case "c": //Pin to pin
|
||
guildSetting.pinToPin = !guildSetting.pinToPin;
|
||
|
||
message.author.send($("CONFIG_PINTOPIN_TOGGLED", {emoji: consts.config.pinToPinEmoji}));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
break;
|
||
case "!": //Reset AstralMod
|
||
message.author.send($("CONFIG_RESET_ASTRALMOD_CONFIRMATION"));
|
||
guildSetting.configuringStage = -10;
|
||
break;
|
||
default:
|
||
//message.author.send("That's not an option.");
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
}
|
||
break;
|
||
}
|
||
case 10: { //Staff Roles
|
||
if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_CLEAR").toLowerCase()) {
|
||
guildSetting.modRoles = null;
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else {
|
||
var roles = text.split(" ");
|
||
var isValid = true;
|
||
|
||
for (role of roles) {
|
||
if (guild.roles.has(role)) {
|
||
message.author.send(role + " = " + guild.roles.get(role).name);
|
||
} else {
|
||
message.author.send(role + " = ???");
|
||
isValid = false;
|
||
}
|
||
}
|
||
|
||
if (!isValid) {
|
||
message.author.send($("CONFIG_STAFF_INVALID"));
|
||
return;
|
||
} else {
|
||
guildSetting.tentativeModRoles = roles;
|
||
|
||
message.author.send($("CONFIG_STAFF_CONFIRMATION"));
|
||
guildSetting.configuringStage = 11;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case 11: { //Staff Roles Confirm
|
||
if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION").toLowerCase()) {
|
||
guildSetting.modRoles = guildSetting.tentativeModRoles;
|
||
delete guildSetting.tentativeModRoles;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION").toLowerCase()) {
|
||
guildSetting.tentativeModRoles = null;
|
||
message.author.send($("CONFIG_STAFF_INVALID"));
|
||
guildSetting.configuringStage = 10;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
|
||
case 20: { //Member Alerts Channel
|
||
if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NONE").toLowerCase()) {
|
||
message.author.send($("CONFIG_MEMBER_ALERT_DISBLING"));
|
||
guildSetting.tentativeMemberAlerts = null;
|
||
guildSetting.configuringStage = 21;
|
||
} else {
|
||
if (!guild.channels.has(text)) {
|
||
message.author.send($("CONFIG_CHANNEL_DOESNT_EXIST"));
|
||
} else {
|
||
var channel = guild.channels.get(text);
|
||
if (channel.type != "text") {
|
||
message.author.send($("CONFIG_CHANNEL_INVALID_CHANNEL"));
|
||
} else {
|
||
message.author.send($("CONFIG_MEMBER_ALERT_CONFIRMATION", {channel: channel.name}));
|
||
guildSetting.tentativeMemberAlerts = channel.id;
|
||
guildSetting.configuringStage = 21;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case 21: { //Member Alerts Channel - Confirm
|
||
if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION").toLowerCase()) {
|
||
try {
|
||
guildSetting.blocked[guildSetting.memberAlerts].splice(guildSetting.blocked[guildSetting.memberAlerts].indexOf("log"), 1);
|
||
} catch (err) { } //If it's not disabled (i.e. we're changing channels) we'll need to clear that channel's block status, but we can ignore any "cannot read property of null" errors
|
||
|
||
guildSetting.memberAlerts = guildSetting.tentativeMemberAlerts;
|
||
|
||
if (guildSetting.memberAlerts) {
|
||
guildSetting.blocked[guildSetting.memberAlerts] = guildSetting.blocked[guildSetting.memberAlerts] == null ? [] : guildSetting.blocked[guildSetting.memberAlerts]
|
||
guildSetting.blocked[guildSetting.memberAlerts].push("log");
|
||
}
|
||
|
||
delete guildSetting.tentativeMemberAlerts;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION")) {
|
||
guildSetting.tentativeMemberAlerts = null;
|
||
message.author.send($("CONFIG_MEMBER_ALERT_CANCELLED"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 20;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
|
||
case 30: { //Chat Logs Channel
|
||
if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NONE").toLowerCase()) {
|
||
message.author.send($("CONFIG_CHAT_LOGS_DISABLE"));
|
||
guildSetting.tentativeChatLogs = null;
|
||
guildSetting.configuringStage = 31;
|
||
} else {
|
||
if (!guild.channels.has(text)) {
|
||
message.author.send($("CONFIG_CHANNEL_DOESNT_EXIST"));
|
||
} else {
|
||
var channel = guild.channels.get(text);
|
||
if (channel.type != "text") {
|
||
message.author.send($("CONFIG_CHANNEL_INVALID_CHANNEL"));
|
||
} else {
|
||
message.author.send($("CONFIG_CHAT_LOGS_CONFIRMATION", {channel: channel.name}));
|
||
guildSetting.tentativeChatLogs = channel.id;
|
||
guildSetting.configuringStage = 31;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case 31: { //Chat Logs Channel - Confirm
|
||
if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION")) {
|
||
try {
|
||
guildSetting.blocked[guildSetting.chatLogs].splice(guildSetting.blocked[guildSetting.chatLogs].indexOf("log"), 1);
|
||
} catch (err) { } //If it's not disabled (i.e. we're changing channels) we'll need to clear that channel's block status, but we can ignore any "cannot read property of null" errors
|
||
|
||
guildSetting.chatLogs = guildSetting.tentativeChatLogs;
|
||
|
||
if (guildSetting.chatLogs) {
|
||
guildSetting.blocked[guildSetting.chatLogs] = guildSetting.blocked[guildSetting.chatLogs] == null ? [] : guildSetting.blocked[guildSetting.chatLogs]
|
||
guildSetting.blocked[guildSetting.chatLogs].push("log");
|
||
}
|
||
|
||
delete guildSetting.tentativeChatLogs;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION")) {
|
||
guildSetting.tentativeChatLogs = null;
|
||
message.author.send($("CONFIG_CHAT_LOGS_RETRY"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 30;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
case 40: { //Botwarnings Channel
|
||
if (text.toLowerCase() == $("CONFIG_NONE").toLowerCase()) {
|
||
message.author.send($("CONFIG_BOT_WARNINGS_DISABLE"));
|
||
guildSetting.tentativeBotWarnings = null;
|
||
guildSetting.configuringStage = 41;
|
||
} else if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else {
|
||
if (!guild.channels.has(text)) {
|
||
message.author.send($("CONFIG_CHANNEL_DOESNT_EXIST"));
|
||
} else {
|
||
var channel = guild.channels.get(text);
|
||
if (channel.type != "text") {
|
||
message.author.send($("CONFIG_CHANNEL_INVALID_CHANNEL"));
|
||
} else {
|
||
message.author.send($("CONFIG_BOT_WARNINGS_CONFIRMATION", {channel: channel.name}));
|
||
guildSetting.tentativeBotWarnings = channel.id;
|
||
guildSetting.configuringStage = 41;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case 41: { //Botwarnings Channel - Confirm
|
||
if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION")) {
|
||
try {
|
||
guildSetting.blocked[guildSetting.botWarnings].splice(guildSetting.blocked[guildSetting.botWarnings].indexOf("log"), 1);
|
||
} catch (err) { } //If it's not disabled (i.e. we're changing channels) we'll need to clear that channel's block status, but we can ignore any "cannot read property of null" errors
|
||
|
||
guildSetting.botWarnings = guildSetting.tentativeBotWarnings;
|
||
|
||
if (guildSetting.botWarnings) {
|
||
guildSetting.blocked[guildSetting.botWarnings] = guildSetting.blocked[guildSetting.botWarnings] == null ? [] : guildSetting.blocked[guildSetting.botWarnings]
|
||
guildSetting.blocked[guildSetting.botWarnings].push("log");
|
||
}
|
||
|
||
delete guildSetting.tentativeBotWarnings;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION")) {
|
||
guildSetting.tentativeBotWarnings = null;
|
||
message.author.send($("CONFIG_BOT_WARNINGS_RETRY"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 40;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
|
||
case 50: { //Suggestions Channel
|
||
if (text.toLowerCase() == $("CONFIG_NONE").toLowerCase()) {
|
||
message.author.send($("CONFIG_SUGGESTIONS_DISABLE"));
|
||
guildSetting.tentativeBotWarnings = null;
|
||
guildSetting.configuringStage = 51;
|
||
} else if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else {
|
||
if (!guild.channels.has(text)) {
|
||
message.author.send($("CONFIG_CHANNEL_DOESNT_EXIST"));
|
||
} else if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else {
|
||
var channel = guild.channels.get(text);
|
||
if (channel.type != "text") {
|
||
message.author.send($("CONFIG_CHANNEL_INVALID_CHANNEL"));
|
||
} else {
|
||
message.author.send($("CONFIG_SUGGESTIONS_CONFIRMATION", {channel: channel.name}));
|
||
guildSetting.tentativeSuggestions = channel.id;
|
||
guildSetting.configuringStage = 51;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case 51: { //Suggestions Channel - Confirm
|
||
if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION")) {
|
||
guildSetting.suggestions = guildSetting.tentativeSuggestions;
|
||
delete guildSetting.tentativeSuggestions;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION")) {
|
||
guildSetting.tentativeSuggestions = null;
|
||
message.author.send($("CONFIG_SUGGESTIONS_RETRY"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 50;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
case 60: { //Locale
|
||
if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else {
|
||
if (!availableTranslations.includes(text)) {
|
||
message.author.send($("CONFIG_LOCALE_INVALID"));
|
||
|
||
let locales = "";
|
||
for (let locale of availableTranslations) {
|
||
let thisLocale = _[locale]("THIS_LOCALE");
|
||
if (thisLocale == _.en("THIS_LOCALE")) thisLocale = "";
|
||
if (locale == "en") thisLocale = "English";
|
||
locales += "`" + locale + "` - " + thisLocale + "\n";
|
||
}
|
||
|
||
message.author.send(locales);
|
||
} else {
|
||
message.author.send($("CONFIG_LOCALE_CONFIRMATION", {locale: text}));
|
||
guildSetting.tentativeLocale = text;
|
||
guildSetting.configuringStage = 61;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
case 61: { //Locale - Confirm
|
||
if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION")) {
|
||
guildSetting.locale = guildSetting.tentativeLocale;
|
||
delete guildSetting.tentativeLocale;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION")) {
|
||
guildSetting.locale = "en";
|
||
message.author.send($("CONFIG_LOCALE_RETRY"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 60;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
case 70: { //Server prefix
|
||
if (text.toLowerCase() == $("CONFIG_CANCEL").toLowerCase()) {
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else {
|
||
if (text.toLowerCase() == $("CONFIG_DEFAULT").toLowerCase() || text == prefix()) {
|
||
message.author.send($("CONFIG_SERVER_PREFIX_CONFIRMATION", {prefix: prefix()}));
|
||
guildSetting.tentativePrefix = undefined;
|
||
guildSetting.configuringStage = 71;
|
||
} else {
|
||
message.author.send($("CONFIG_SERVER_PREFIX_CONFIRMATION", {prefix: text}));
|
||
guildSetting.tentativePrefix = text;
|
||
guildSetting.configuringStage = 71;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
case 71: { //Locale - Confirm
|
||
if (text.toLowerCase() == $("CONFIG_YES").toLowerCase() || text.toLowerCase() == $("CONFIG_YES_ABBREVIATION")) {
|
||
guildSetting.serverPrefix = guildSetting.tentativePrefix;
|
||
delete guildSetting.tentativePrefix;
|
||
|
||
message.author.send($("CONFIG_CONFIGURATED"));
|
||
message.author.send(getSingleConfigureWelcomeText(guild, message.author));
|
||
guildSetting.configuringStage = 0;
|
||
} else if (text.toLowerCase() == $("CONFIG_NO").toLowerCase() || text.toLowerCase() == $("CONFIG_NO_ABBREVIATION")) {
|
||
guildSetting.serverPrefix = undefined;
|
||
message.author.send($("CONFIG_SERVER_PREFIX_RETRY"));
|
||
message.author.send(getChannels(guild));
|
||
guildSetting.configuringStage = 70;
|
||
} else {
|
||
message.author.send($("CONFIG_NOT_VALID_CONFIRMATION"));
|
||
}
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
settings.guilds[guild.id] = guildSetting;
|
||
}
|
||
|
||
async function processMessage(message) {
|
||
try {
|
||
//Ignore self
|
||
if (message.author.id == client.user.id) return;
|
||
|
||
//Ignore bots
|
||
if (message.author.bot) return;
|
||
|
||
//Get language
|
||
if (settings.users[message.author.id] == null) {
|
||
settings.users[message.author.id] = {};
|
||
}
|
||
|
||
if (settings.users[message.author.id].locale == null) {
|
||
settings.users[message.author.id].locale = "en";
|
||
}
|
||
|
||
if (settings.generalConfiguration.blockedUsers.includes(message.author.id)) {
|
||
return;
|
||
}
|
||
|
||
let options = {
|
||
locale: settings.users[message.author.id].locale,
|
||
imperial: settings.users[message.author.id].units === "imperial",
|
||
h24: settings.users[message.author.id].timeunit !== "12h",
|
||
offset: settings.users[message.author.id].timezone
|
||
};
|
||
|
||
let text = message.content;
|
||
|
||
for (const param of text.split(" ")) {
|
||
if (param == "--") break; //End of options
|
||
if (param.startsWith("--")) {
|
||
if (param === "--12" || param === "--12h" || param === "--12hr") {
|
||
options.h24 = false;
|
||
} else if (param === "--24" || param === "--24h" || param === "--24hr") {
|
||
options.h24 = true;
|
||
} else if (param === "--metric") {
|
||
options.imperial = false;
|
||
} else if (param === "--imperial") {
|
||
options.imperial = true;
|
||
} else if (availableTranslations.getTranslation(param.substr(2)) != null) {
|
||
options.locale = availableTranslations.getTranslation(param.substr(2));
|
||
} else {
|
||
continue;
|
||
}
|
||
|
||
text = text.replace(param, "");
|
||
}
|
||
}
|
||
|
||
text = text.trim();
|
||
|
||
//Don't respond to direct messages
|
||
if (message.guild != null) {
|
||
await message.guild.fetchMember(message.author);
|
||
options.glocale = settings.guilds[message.guild.id].locale;
|
||
|
||
if (settings.guilds[message.guild.id].blocked == null) {
|
||
settings.guilds[message.guild.id].blocked = [];
|
||
}
|
||
|
||
if (settings.guilds[message.guild.id].blocked[message.channel.id] == null) {
|
||
settings.guilds[message.guild.id].blocked[message.channel.id] = [];
|
||
}
|
||
if (settings.guilds[message.guild.id].blocked.guild == null) {
|
||
settings.guilds[message.guild.id].blocked.guild = [];
|
||
}
|
||
|
||
if (capture[message.guild.id] != null && capture[message.guild.id].author == message.author.id) {
|
||
capture[message.guild.id].function(message);
|
||
} else if (text.toLowerCase().startsWith(prefix(message.guild.id)) || text.startsWith(message.guild.me.toString())) {
|
||
//Check if the command has been blocked
|
||
let prefixLength = prefix(message.guild.id).length;
|
||
if(text.startsWith(message.guild.me.toString())) {
|
||
prefixLength = message.guild.me.toString().length
|
||
if (message.content[prefixLength] == " ") {
|
||
prefixLength += 1;
|
||
}
|
||
}
|
||
|
||
for (let key in settings.guilds[message.guild.id].blocked[message.channel.id]) {
|
||
let c = settings.guilds[message.guild.id].blocked[message.channel.id][key];
|
||
let triedCommand = text.toLowerCase().substr(prefixLength);
|
||
if (triedCommand.startsWith(c) || triedCommand == c ||
|
||
(c == "all" && !triedCommand.startsWith("block") && !triedCommand.startsWith("unblock"))) {
|
||
//Block this command and treat it like a normal message
|
||
commandEmitter.emit('newMessage', message, options);
|
||
return;
|
||
}
|
||
}
|
||
|
||
for (let key in settings.guilds[message.guild.id].blocked.guild) {
|
||
let c = settings.guilds[message.guild.id].blocked.guild[key];
|
||
let triedCommand = text.toLowerCase().substr(prefixLength);
|
||
if (triedCommand.startsWith(c) || triedCommand == c ||
|
||
(c == "all" && !triedCommand.startsWith("block") && !triedCommand.startsWith("unblock"))) {
|
||
//Block this command and treat it like a normal message
|
||
commandEmitter.emit('newMessage', message, options);
|
||
return;
|
||
}
|
||
}
|
||
|
||
//Determine if this is a command
|
||
if (isMod(message.member) || text == prefix(message.guild.id) + "config") { //This is a mod command
|
||
if (!processModCommand(message, text.substr(prefixLength).toLowerCase())) {
|
||
if (!processAmCommand(message, options, text.substr(prefixLength).toLowerCase())) {
|
||
//Pass command onto plugins
|
||
commandEmitter.emit('processCommand', message, true, text.substr(prefixLength).toLowerCase(), options);
|
||
}
|
||
}
|
||
} else {
|
||
if (!processAmCommand(message, options, text.substr(prefixLength).toLowerCase())) {
|
||
//Pass command onto plugins
|
||
commandEmitter.emit('processCommand', message, false, text.substr(prefixLength).toLowerCase(), options);
|
||
}
|
||
}
|
||
} else {
|
||
commandEmitter.emit('newMessage', message, options);
|
||
}
|
||
} else {
|
||
//Determine if this is within a workflow or if this is unsolicited
|
||
for (key in settings.guilds) {
|
||
var guildSetting = settings.guilds[key];
|
||
if (guildSetting != null) {
|
||
//First check if user is currently configuring
|
||
if (guildSetting.configuringUser == message.author.id) {
|
||
//Check if this is during first time keys
|
||
if (guildSetting.requiresConfig) {
|
||
// processConfigure(message, client.guilds.get(key));
|
||
} else {
|
||
processSingleConfigure(message, client.guilds.get(key));
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
//Pass command onto plugins
|
||
commandEmitter.emit('newDM', message);
|
||
}
|
||
} catch (err) {
|
||
//Get locale settings
|
||
if (settings.users[message.author.id].locale == null) {
|
||
settings.users[message.author.id].locale = "en";
|
||
}
|
||
let $ = _[settings.users[message.author.id].locale];
|
||
|
||
var embed = new Discord.RichEmbed;
|
||
embed.setColor(consts.colors.fail);
|
||
embed.addField($("ERROR_DETAILS"), err.message);
|
||
|
||
if (err.name == "UserInputError") {
|
||
embed.setTitle(getEmoji("userexception") + " " + $("ERROR_USER_INPUT"));
|
||
embed.setDescription($("ERROR_NOT_UNDERSTAND"));
|
||
} else if (err.name == "CommandError") {
|
||
embed.setTitle(getEmoji("userexception") + " Command Error");
|
||
embed.setDescription($("ERROR_COULDNT_COMPLETE"));
|
||
} else {
|
||
log("Uncaught Exception:", logType.critical);
|
||
log(err.stack, logType.critical);
|
||
|
||
embed.setTitle(getEmoji("exception") + " " + $("ERROR_INTERNAL"));
|
||
embed.setFooter($("ERROR_LOGGED"));
|
||
embed.setDescription($("ERROR_INTERNAL_DESCRIPTION"));
|
||
}
|
||
|
||
message.channel.send("", {embed: embed});
|
||
message.channel.stopTyping(true);
|
||
}
|
||
}
|
||
|
||
function newGuild(guild) {
|
||
log("New Guild: " + guild.id, logType.info);
|
||
|
||
if (settings.guilds[guild.id] != null) {
|
||
log("Preserving information about guild!" + guild.id, logType.info);
|
||
return;
|
||
}
|
||
|
||
settings.guilds[guild.id] = {
|
||
requiresConfig: false,
|
||
};
|
||
|
||
|
||
if (process.argv.indexOf("--nowelcome") == -1) {
|
||
let channel = guild.channels.find("name", "general");
|
||
if (channel == null) {
|
||
channel = guild.channels.find("name", "lounge");
|
||
} if (channel == null) {
|
||
channel = guild.channels.find("name", "main");
|
||
}
|
||
|
||
|
||
let message = ":wave: Welcome to AstralMod! To get started, set me up in `" + guild.name + "` by typing `" + prefix(guild.id) + "config`. To see the help index, use `" + prefix(guild.id) + "help`.";
|
||
if (channel == null) {
|
||
guild.owner.send(message);
|
||
} else {
|
||
channel.send(message);
|
||
}
|
||
}
|
||
}
|
||
|
||
function removeGuild(guild) {
|
||
if (doNotDeleteGuilds.indexOf(guild.id) == -1) {
|
||
//Delete guild from database
|
||
settings.guilds[guild.id] = null;
|
||
delete settings.guilds[guild.id];
|
||
log("Removed Guild: " + guild.id, logType.info);
|
||
} else {
|
||
log("Attempted to delete unavailable guild: " + guild.id, logType.warning);
|
||
}
|
||
}
|
||
|
||
function saveSettings(showOkMessage = false) {
|
||
log("Saving settings...");
|
||
var contents = JSON.stringify(settings, null, 4);
|
||
|
||
//Encrypt the contents
|
||
let iv = Buffer.from(crypto.randomBytes(16));
|
||
|
||
var cipher = crypto.createCipheriv(cipherAlg, settingsKey, iv);
|
||
var settingsJson = Buffer.concat([
|
||
cipher.update(Buffer.from(contents, "utf8")),
|
||
cipher.final()
|
||
]);
|
||
|
||
//Write to secondary file first
|
||
fs.writeFile("settings.prewrite.json", settingsJson, "utf8", function(error) {
|
||
if (error) {
|
||
log("Settings couldn't be saved", logType.critical);
|
||
setTimeout(saveSettings, 30000);
|
||
} else {
|
||
fs.writeFile("iv", iv, "utf8", function(error) {
|
||
if (error) {
|
||
log("IV couldn't be saved. Aborting save of normal settings file.", logType.critical);
|
||
} else {
|
||
fs.writeFile("settings.json", settingsJson, "utf8", function(error) {
|
||
if (error) {
|
||
log("Settings couldn't be saved, but the prewrite settings were saved successfully.", logType.critical);
|
||
} else {
|
||
fs.unlinkSync("settings.prewrite.json");
|
||
|
||
if (showOkMessage) {
|
||
log("Settings saved!", logType.good);
|
||
} else {
|
||
log("Settings saved!");
|
||
}
|
||
}
|
||
|
||
setTimeout(saveSettings, 30000);
|
||
});
|
||
}
|
||
})
|
||
}
|
||
});
|
||
}
|
||
|
||
function parseCleanContent(content) {
|
||
let inCode = false;
|
||
for (let i = 0; i < content.length; i++) {
|
||
let char = content[i];
|
||
if (char == "`") {
|
||
if (content[i + 1] == "`" && content[i + 2] == "`") {
|
||
if (inCode) {
|
||
content = content.substr(0, i) + "]" + content.substr(i + 3, content.length - 2);
|
||
} else {
|
||
content = content.substr(0, i) + "[" + content.substr(i + 3, content.length - 2);
|
||
}
|
||
inCode = !inCode;
|
||
}
|
||
}
|
||
}
|
||
//content.replace("```", "[");
|
||
return content;
|
||
}
|
||
|
||
function messageDeleted(message) {
|
||
var channel = null;
|
||
if (message.guild != null) {
|
||
if (settings.guilds[message.guild.id].chatLogs != null) {
|
||
if (client.channels.has(settings.guilds[message.guild.id].chatLogs)) {
|
||
channel = client.channels.get(settings.guilds[message.guild.id].chatLogs);
|
||
} else {
|
||
log("Chat Logs channel " + settings.guilds[message.guild.id].chatLogs + " not found", logType.warning);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (channel != null) {
|
||
if (settings.guilds[message.guild.id].blocked[message.channel.id].includes("log")) { //If the channel the message was in has logs blocked (or the message was in a log channel, which shouldn't get logged either)
|
||
return;
|
||
}
|
||
|
||
let glocale = settings.guilds[message.guild.id].locale;
|
||
let $$ = _[glocale];
|
||
|
||
var msg = $$("GUILD_MESSAGE_DELETE", {time: {date: moment(message.createdAt), h24: true}, emoji: ":wastebasket:", user: getUserString(message.author), channel: `<#${message.channel.id}>`,
|
||
message: message.cleanContent.length ? "```\n" + parseCleanContent(message.cleanContent) + "\n" +"```" : $$("GUILD_MESSAGE_NO_CONTENT")})
|
||
|
||
channel.send(msg);
|
||
|
||
if (message.attachments.size > 0) {
|
||
var msg = $$("GUILD_ATTACHMENTS");
|
||
|
||
for (let [, attachment] of message.attachments) {
|
||
msg += "\n" + $$("GUILD_ATTACHMENT", {filename: attachment.filename, count: parseInt(attachment.filesize)});
|
||
if (attachment.height != null) {
|
||
msg += attachment.proxyURL;
|
||
}
|
||
}
|
||
|
||
channel.send(msg);
|
||
}
|
||
}
|
||
}
|
||
|
||
function messageUpdated(oldMessage, newMessage) {
|
||
if (oldMessage.cleanContent == newMessage.cleanContent) return; //Ignore
|
||
var channel = null;
|
||
if (oldMessage.guild != null) {
|
||
if (settings.guilds[oldMessage.guild.id].chatLogs != null) {
|
||
if (client.channels.has(settings.guilds[oldMessage.guild.id].chatLogs)) {
|
||
channel = client.channels.get(settings.guilds[oldMessage.guild.id].chatLogs);
|
||
} else {
|
||
log("Chat Logs channel " + settings.guilds[oldMessage.guild.id].chatLogs + " not found", logType.warning);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (channel != null && oldMessage.channel != channel) {
|
||
if (settings.guilds[newMessage.guild.id].blocked[newMessage.channel.id].includes("log")) { //If the channel the message was in has logs blocked (or the message was in a log channel, which shouldn't get logged either)
|
||
return;
|
||
}
|
||
|
||
let glocale = settings.guilds[newMessage.guild.id].locale;
|
||
let $$ = _[glocale];
|
||
|
||
var msg = $$("GUILD_MESSAGE_EDIT", {time: {date: moment(oldMessage.createdAt), h24: true}, emoji: ":pencil:", user: getUserString(oldMessage.author), channel: `<#${oldMessage.channel.id}>`,
|
||
oldmessage: oldMessage.cleanContent.length ? "```\n" + parseCleanContent(oldMessage.cleanContent) +"\n```" : $$("GUILD_MESSAGE_NO_CONTENT"), newmessage: newMessage.cleanContent.length ? "```\n" + parseCleanContent(newMessage.cleanContent) + "```\n" : $$("GUILD_MESSAGE_NO_CONTENT")})
|
||
|
||
channel.send(msg);
|
||
|
||
if (oldMessage.attachments.size > 0) {
|
||
var msg = $$("GUILD_ATTACHMENTS");
|
||
|
||
for (let [, attachment] of oldMessage.attachments) {
|
||
msg += "\n" + $$("GUILD_ATTACHMENT", {filename: attachment.filename, count: parseInt(attachment.filesize)});
|
||
if (attachment.height != null) {
|
||
msg += attachment.proxyURL;
|
||
}
|
||
}
|
||
|
||
channel.send(msg);
|
||
}
|
||
}
|
||
}
|
||
|
||
function memberAdd(member) {
|
||
var channel = null;
|
||
if (member.guild != null) {
|
||
if (settings.guilds[member.guild.id].memberAlerts != null) {
|
||
if (client.channels.has(settings.guilds[member.guild.id].memberAlerts)) {
|
||
channel = client.channels.get(settings.guilds[member.guild.id].memberAlerts);
|
||
} else {
|
||
log("Member Alerts channel " + settings.guilds[member.guild.id].memberAlerts + " not found", logType.critical);
|
||
}
|
||
}
|
||
}
|
||
|
||
let glocale = settings.guilds[member.guild.id].locale;
|
||
let $$ = _[glocale];
|
||
|
||
if (channel != null) {
|
||
let sendWelcome = function(inviteCode) {
|
||
if (inviteCode == "") {
|
||
channel.send($$("GUILD_USER_ADD", {emoji: ":arrow_right:", user: `<@${member.user.id}>`}))
|
||
} else {
|
||
channel.send($$("GUILD_USER_ADD", {emoji: ":arrow_right:", user: `<@${member.user.id}>`, invite: inviteCode}))
|
||
}
|
||
|
||
uinfo(member.user, channel, glocale, 0, true, member.guild, true);
|
||
|
||
//This is a candidate for confighood...
|
||
//This one will go in AM 3.1 too :)
|
||
|
||
if (member.guild.id == consts.wow.id) {
|
||
var now = new Date();
|
||
var joinDate = member.user.createdAt;
|
||
if (joinDate.getDate() == now.getDate() && joinDate.getMonth() == now.getMonth() && joinDate.getFullYear() == now.getFullYear()) {
|
||
if (member.guild.id == 287937616685301762) {
|
||
channel.send(":calendar: <@&326915978392764426> This member was created today.");
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
member.guild.fetchInvites().then(function(invites) {
|
||
let inviteCode = "";
|
||
for ([id, invite] of invites) {
|
||
if (knownInvites[invite.code] < invite.uses) {
|
||
inviteCode = invite.code;
|
||
knownInvites[invite.code] = invite.uses;
|
||
}
|
||
}
|
||
|
||
sendWelcome(inviteCode);
|
||
}).catch(function() {
|
||
sendWelcome("");
|
||
});
|
||
}
|
||
}
|
||
|
||
function banAdd(guild, user) {
|
||
let glocale = settings.guilds[guild.id].locale;
|
||
let $$ = _[glocale];
|
||
|
||
var channel = null;
|
||
if (guild != null) {
|
||
if (settings.guilds[guild.id].memberAlerts != null) {
|
||
if (client.channels.has(settings.guilds[guild.id].memberAlerts)) {
|
||
channel = client.channels.get(settings.guilds[guild.id].memberAlerts);
|
||
} else {
|
||
log("Member Alerts channel " + settings.guilds[guild.id].memberAlerts + " not found", logType.critical);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (channel != null) {
|
||
var embed = new Discord.RichEmbed();
|
||
|
||
embed.setColor(consts.colors.fail);
|
||
embed.setTitle($$("GUILD_BAN_ADD_TITLE", {emoji: ":hammer:"}));
|
||
embed.setDescription($$("GUILD_BAN_ADD_DESCRIPTION"));
|
||
|
||
embed.addField($$("GUILD_BAN_ADD_USER"), user.tag, true);
|
||
embed.addField($$("GUILD_BAN_ADD_USER_ID"), user.id, true);
|
||
|
||
guild.fetchInvites().then(function(invites) {
|
||
var inviteString = "";
|
||
|
||
for ([code, invite] of invites) {
|
||
if (invite.inviter != null && invite.inviter.id == user.id) {
|
||
inviteString += invite.code + "\n";
|
||
}
|
||
}
|
||
|
||
if (inviteString != "") {
|
||
embed.addField($$("GUILD_BAN_ADD_INVITES"), inviteString);
|
||
}
|
||
|
||
if (banDescriptor[guild.id][user.id] != null) {
|
||
return banDescriptor[guild.id][user.id];
|
||
} else {
|
||
return guild.fetchAuditLogs({
|
||
limit: 1,
|
||
type: "MEMBER_BAN_ADD"
|
||
});
|
||
}
|
||
}).then(function(auditLogs) {
|
||
if (auditLogs.author == null) {
|
||
let log = auditLogs.entries.first();
|
||
embed.addField($$("GUILD_BAN_ADD_BANNED_BY"), log.executor.tag);
|
||
|
||
if (log.reason != null) {
|
||
embed.addField($$("GUILD_BAN_ADD_BAN_REASON"), log.reason);
|
||
}
|
||
} else {
|
||
embed.addField($$("GUILD_BAN_ADD_BANNED_BY"), auditLogs.author.tag);
|
||
embed.addField($$("GUILD_BAN_ADD_BAN_REASON"), auditLogs.reason);
|
||
}
|
||
|
||
channel.send("", {embed: embed});
|
||
}).catch(function() {
|
||
channel.send("", {embed: embed});
|
||
});
|
||
}
|
||
|
||
countBans();
|
||
}
|
||
|
||
function memberRemove(member) {
|
||
if (member.guild != null) {
|
||
var channel = null;
|
||
if (member.guild != null) {
|
||
if (settings.guilds[member.guild.id].chatLogs != null) {
|
||
if (client.channels.has(settings.guilds[member.guild.id].memberAlerts)) {
|
||
channel = client.channels.get(settings.guilds[member.guild.id].memberAlerts);
|
||
} else {
|
||
log("Member Alerts channel " + settings.guilds[member.guild.id].memberAlerts + " not found", logType.critical);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (channel != null) {
|
||
channel.send(":arrow_left: <@" + member.user.id + "> (" + member.displayName + "#" + member.user.discriminator + ")");
|
||
}
|
||
}
|
||
}
|
||
|
||
function userUpdate(oldUser, newUser) {
|
||
if (newUser.username != oldUser.username) {
|
||
for (key in settings.guilds) {
|
||
var bwChannel = settings.guilds[key].botWarnings;
|
||
var guild = client.guilds.get(key);
|
||
if (bwChannel != null) {
|
||
//Check if member exists
|
||
|
||
for ([id, member] of guild.members) {
|
||
if (member.user.id == newUser.id) {
|
||
var channel = client.channels.get(bwChannel); //282513354118004747
|
||
if (channel != null) {
|
||
channel.send(":ab: " + getUserString(oldUser).replace("@", "@") + " :arrow_right: " + newUser.username.toString().replace("@", "@"));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function loadPlugin(file) {
|
||
try {
|
||
if (plugins[file] != null) {
|
||
throw new Error("Plugin is already loaded.");
|
||
}
|
||
|
||
var plugin = require('./plugins/' + file);
|
||
|
||
if (plugin.name == null) {
|
||
throw new Error("Plugin has no name");
|
||
}
|
||
|
||
if (plugin.constructor == null) {
|
||
throw new Error("Plugin has no constructor");
|
||
}
|
||
|
||
plugin.constructor(client, commandEmitter, consts);
|
||
plugins[file] = plugin;
|
||
log("Plugin \"" + plugin.name + "\" from file " + file + " has been loaded successfully.", logType.good);
|
||
return true;
|
||
} catch (err) {
|
||
log(err.message, logType.critical);
|
||
log("Plugin " + file + " cannot be loaded.", logType.critical);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function unloadPlugin(file) {
|
||
try {
|
||
if (plugins[file] == null) {
|
||
throw new Error("Plugin not loaded");
|
||
}
|
||
|
||
if (plugins[file].destructor != null) {
|
||
plugins[file].destructor(commandEmitter);
|
||
}
|
||
|
||
var moduleResolve = require.resolve('./plugins/' + file);
|
||
//var module = require.cache[moduleResolve];
|
||
delete require.cache[moduleResolve];
|
||
delete plugins[file];
|
||
return true;
|
||
} catch (err) {
|
||
log(err.message, logType.critical);
|
||
log("Plugin " + file + " is cannot be unloaded.", logType.critical);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function vacuumSettings() {
|
||
if (process.argv.indexOf("--novacuum") != -1) {
|
||
log("--novacuum argument was passed. Vacuuming has been disabled.", logType.info);
|
||
return false;
|
||
}
|
||
|
||
log("Checking the AstralMod Configuration file...", logType.info);
|
||
fs.createReadStream('settings.json').pipe(fs.createWriteStream('.settings-backup.json'));
|
||
|
||
var changesMade = false;
|
||
var error = false;
|
||
|
||
//Check settings file objects
|
||
if (!settings.hasOwnProperty("guilds")) {
|
||
log("Settings does not contain guilds.", logType.critical);
|
||
error = true;
|
||
}
|
||
|
||
if (!settings.hasOwnProperty("users")) {
|
||
log("Settings does not contain users.", logType.critical);
|
||
error = true;
|
||
}
|
||
|
||
if (!settings.hasOwnProperty("generalConfiguration")) {
|
||
log("Settings does not contain general configuration.", logType.critical);
|
||
error = true;
|
||
}
|
||
|
||
if (error) {
|
||
//Quit AstralMod
|
||
log("AstralMod Configuration contains errors.", logType.critical);
|
||
log("From here, you can either\n- Attempt to fix the AstralMod configuration file, settings.json\n- Delete the AstralMod configuration file and start again.", logType.info);
|
||
log("AstralMod Configuration is corrupted. AstralMod cannot continue running. Exiting now.", logType.critical);
|
||
debugger;
|
||
process.exit(1);
|
||
}
|
||
|
||
//Check that blocked users is a valid setting
|
||
if (!settings.generalConfiguration.hasOwnProperty("blockedUsers")) {
|
||
changesMade = true;
|
||
settings.generalConfiguration.blockedUsers = [];
|
||
log("Added blocked users to settings", logType.info);
|
||
}
|
||
|
||
//Check that each guild still exists
|
||
var availableGuilds = [];
|
||
for (let [id, guild] of client.guilds) {
|
||
log("Checking Discord guild " + guild.id);
|
||
availableGuilds.push(guild.id);
|
||
|
||
if (!settings.guilds.hasOwnProperty(guild.id)) {
|
||
//Add guild to database
|
||
changesMade = true;
|
||
log("Adding guild " + guild.id + " to the database.", logType.info);
|
||
newGuild(guild);
|
||
}
|
||
|
||
if (settings.guilds[guild.id].requiresConfig == true) {
|
||
settings.guilds[guild.id].requiresConfig = false;
|
||
}
|
||
}
|
||
|
||
for (let key in settings.users) {
|
||
log("Checking internal user " + key);
|
||
|
||
if (settings.users[key].hasOwnProperty("timers") && settings.users[key].timers.length > 0)
|
||
for (let timer of settings.users[key].timers) {
|
||
if (timer.timeout instanceof Date) {
|
||
log(`Detected timer on user ${key} with Date timeout. Converting to moment.`, logType.info);
|
||
timer.timeout = moment(timer.timeout);
|
||
changesMade = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
//Iterate over all guilds in settings
|
||
for (let key in settings.guilds) {
|
||
log("Checking internal guild " + key);
|
||
if (!availableGuilds.includes(key)) {
|
||
changesMade = true;
|
||
log("Deleting guild " + key + " as this guild is no longer recognised.", logType.info);
|
||
delete settings.guilds[key];
|
||
continue;
|
||
}
|
||
|
||
for (let logChannel of ["chatLogs, botWarnings, memberAlerts"]) {
|
||
if(settings.guilds[key][logChannel] != undefined) {
|
||
if (settings.guilds[key].blocked[logChannel] == undefined) {
|
||
log(`Detected logging channel ${settings.guilds[key].chatLogs} without blocked feature list. Creating array.`, logType.info);
|
||
settings.guilds[key].blocked[logChannel] = [];
|
||
changesMade = true;
|
||
}
|
||
|
||
if (!settings.guilds[key].blocked[logChannel].includes("log")) {
|
||
log(`Detected logging channel ${settings.guilds[key].chatLogs} without blocked logging. Blocking logs.`, logType.info);
|
||
settings.guilds[key].blocked[settings.guilds[key][logChannel]].push("log");
|
||
changesMade = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* for (let warnArray in settings.guilds[key].warnings) {
|
||
for (let warn of settings.guilds[key].warnings[warnArray]) {
|
||
if (typeof warn.timestamp === 'string' || warn.timestamp instanceof String) {
|
||
log("Detected warning with String timestamp. Converting to moment.", logType.info);
|
||
warn.timestamp = moment(warn.timestamp).utc();
|
||
changesMade = true;
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
if (settings.guilds[key].locale == undefined) {
|
||
changesMade = true;
|
||
log(`Detected guild ${key} without set locale. Setting locale to en.`, logType.info);
|
||
settings.guilds[key].locale = "en";
|
||
}
|
||
}
|
||
|
||
if (changesMade) {
|
||
log("AstralMod Configuration was checked and changes were made. No other actions need to be taken.", logType.warning);
|
||
log("Old settings backed up as .settings-backup.json", logType.info);
|
||
} else {
|
||
fs.unlinkSync(".settings-backup.json");
|
||
log("AstralMod Configuration checked. No changes have been made", logType.good);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function guildUnavailable(guild) {
|
||
log(guild.id + " has become unavailable.", logType.critical);
|
||
doNotDeleteGuilds.push(guild.id);
|
||
}
|
||
|
||
function guildMemberUpdate(oldUser, newUser) {
|
||
if (newUser.nickname != oldUser.nickname) {
|
||
var guildSetting = settings.guilds[oldUser.guild.id];
|
||
if (guildSetting.botWarnings != null) {
|
||
if (oldUser.guild != null) {
|
||
channel = oldUser.guild.channels.get(guildSetting.botWarnings);
|
||
if (channel != null) {
|
||
if (newUser.nickname == null) {
|
||
let glocale = settings.guilds[oldUser.guild.id].locale;
|
||
let $$ = _[glocale];
|
||
|
||
channel.send(":abcd: " + getUserString(oldUser).replace("@", "@") + " :arrow_right: " + $$("GUILD_NICKNAME_CLEARED"));
|
||
} else {
|
||
channel.send(":abcd: " + getUserString(oldUser).replace("@", "@") + " :arrow_right: " + newUser.nickname.toString().replace("@", "@"));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function messageReactionAdd(messageReaction, user) {
|
||
if (user.bot) return;
|
||
|
||
commandEmitter.emit("messageReactionAdd", messageReaction, user);
|
||
}
|
||
|
||
function messageReactionRemove(messageReaction, user) {
|
||
if (user.bot) return;
|
||
|
||
commandEmitter.emit("messageReactionRemove", messageReaction, user);
|
||
}
|
||
|
||
function readyAgain() {
|
||
log("AstralMod is ready again.", logType.good);
|
||
}
|
||
|
||
function resume(replayed) {
|
||
log("AstralMod has reconnected to Discord. " + parseInt(replayed) + " events were replayed.", logType.good);
|
||
|
||
client.setInterval(setGame, 300000);
|
||
setGame();
|
||
|
||
commandEmitter.emit('reconnect');
|
||
}
|
||
|
||
function countBans() {
|
||
banCounts = {};
|
||
|
||
banCounts['334842311135577346'] = 1;
|
||
|
||
for (let [id, guild] of client.guilds) {
|
||
guild.fetchBans().then(function(bans) {
|
||
for ([uid, user] of bans) {
|
||
if (banCounts[user.id] == null) {
|
||
banCounts[user.id] = 1;
|
||
} else {
|
||
banCounts[user.id]++;
|
||
}
|
||
}
|
||
}).catch(function() {
|
||
|
||
});
|
||
}
|
||
}
|
||
|
||
function loadInvites() {
|
||
for (let [id, guild] of client.guilds) {
|
||
knownInvites[guild.id] = {};
|
||
guild.fetchInvites().then(function(invites) {
|
||
for ([id, invite] of invites) {
|
||
knownInvites[invite.code] = invite.uses;
|
||
}
|
||
}).catch(function() {
|
||
|
||
});
|
||
}
|
||
}
|
||
|
||
function loadSettingsFile(file) {
|
||
if(fs.existsSync("iv.txt") && !fs.existsSync("iv")) {
|
||
log("Converting legacy file 'iv.txt'...", logType.info);
|
||
fs.copyFileSync("iv.txt", "iv");
|
||
}
|
||
|
||
if (file.startsWith("{")) {
|
||
//File unencrypted
|
||
var intermediarySettings = JSON.parse(file);
|
||
|
||
log("settings.js file is unencrypted. Creating a backup copy...", logType.info);
|
||
fs.createReadStream('settings.json').pipe(fs.createWriteStream('.settings-beforeEncrypt.json'));
|
||
|
||
log("settings.js file will be encrypted on next save.", logType.warning);
|
||
|
||
global.settings = intermediarySettings;
|
||
} else if (!fs.existsSync("iv")) {
|
||
//File encrypted
|
||
log("Decrypting the settings.js file...", logType.info);
|
||
|
||
var buf = fs.readFileSync("settings.json");
|
||
var cipher = crypto.createDecipher(cipherAlg, consts.keys.settingsKey);
|
||
var settingsJson = Buffer.concat([cipher.update(buf), cipher.final()]);
|
||
settingsJson = settingsJson.toString("utf8");
|
||
|
||
global.settings = JSON.parse(settingsJson);
|
||
log("settings.js encryption will be upgraded on next save.", logType.warning);
|
||
} else {
|
||
//File encrypted with IV
|
||
log("Decrypting the settings.js file...", logType.info);
|
||
|
||
let iv = fs.readFileSync("iv");
|
||
|
||
var buf = fs.readFileSync("settings.json");
|
||
var cipher = crypto.createDecipheriv(cipherAlg, settingsKey, iv);
|
||
var settingsJson = Buffer.concat([cipher.update(buf), cipher.final()]);
|
||
settingsJson = settingsJson.toString("utf8");
|
||
|
||
global.settings = JSON.parse(settingsJson);
|
||
}
|
||
}
|
||
|
||
function clientError(err) {
|
||
log(err.stack, logType.critical);
|
||
}
|
||
|
||
function readyOnce() {
|
||
log("Now connected to Discord.", logType.good);
|
||
log("Checking if configuration file exists...");
|
||
|
||
if (!fs.existsSync("settings.json")) {
|
||
log("AstralMod configuration file does not exist. Creating now.", logType.warning);
|
||
global.settings = {
|
||
guilds: {
|
||
|
||
},
|
||
users: {
|
||
|
||
},
|
||
generalConfiguration: {
|
||
|
||
}
|
||
};
|
||
|
||
//Load in all guilds
|
||
client.guilds.forEach(newGuild);
|
||
} else {
|
||
log("Loading AstralMod configuration file...", logType.info);
|
||
|
||
try {
|
||
var file = fs.readFileSync("settings.json", "utf8");
|
||
|
||
loadSettingsFile(file);
|
||
} catch (err) {
|
||
try {
|
||
//Try loading the prewrite file
|
||
var file = fs.readFileSync("settings.prewrite.json", "utf8");
|
||
loadSettingsFile(file);
|
||
|
||
log("Settings file was corrupted, but prewrite file is good. Using prewrite file.", logType.warning);
|
||
|
||
fs.createReadStream('settings.json').pipe(fs.createWriteStream('.settings-backup.json'));
|
||
fs.createReadStream('settings.prewrite.json').pipe(fs.createWriteStream('settings.json'));
|
||
} catch (err2) {
|
||
log("Either the settings file is corrupted, or the encryption key is incorrect. AstralMod cannot start.", logType.critical);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (vacuumSettings()) {
|
||
log("AstralMod Configuration loaded.", logType.good);
|
||
} else {
|
||
log("AstralMod Configuration contains errors.", logType.critical);
|
||
}
|
||
|
||
client.setInterval(setGame, 300000);
|
||
setGame();
|
||
|
||
log("Loading suggestions channels...");
|
||
for (key in settings.guilds) {
|
||
var guildSetting = settings.guilds[key];
|
||
if (guildSetting != null) {
|
||
if (guildSetting.suggestions != null && guildSetting.suggestions != undefined) {
|
||
//Get all messages in #suggestions
|
||
var channel = client.channels.get(guildSetting.suggestions);
|
||
if (channel == null) {
|
||
log("Suggestions channel " + guildSetting.suggestions + " not found", logType.critical);
|
||
} else {
|
||
channel.fetchMessages({
|
||
limit: 100
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//Load plugins
|
||
log("Loading plugins...");
|
||
if (!fs.existsSync("plugins/")) {
|
||
log("AstralMod plugins folder does not exist. Creating now.", logType.warning);
|
||
fs.mkdirSync("plugins/");
|
||
}
|
||
|
||
fs.readdirSync('plugins').forEach(function(file, index) {//Load plugin
|
||
if (!fs.lstatSync("./plugins/" + file).isDirectory()) {
|
||
log("Plugin " + file + " detected. Attempting to load now.");
|
||
loadPlugin(file);
|
||
}
|
||
});
|
||
|
||
commandEmitter.emit('startup');
|
||
|
||
client.on('message', processMessage);
|
||
client.on('guildCreate', newGuild);
|
||
client.on('guildDelete', removeGuild);
|
||
client.on('messageDelete', messageDeleted);
|
||
client.on('messageUpdate', messageUpdated);
|
||
client.on('guildMemberAdd', memberAdd);
|
||
client.on('guildMemberRemove', memberRemove);
|
||
client.on('guildUnavailable', guildUnavailable);
|
||
client.on('guildMemberUpdate', guildMemberUpdate);
|
||
client.on('messageReactionAdd', messageReactionAdd);
|
||
client.on('messageReactionRemove', messageReactionRemove);
|
||
client.on('userUpdate', userUpdate);
|
||
client.on('ready', readyAgain);
|
||
client.on('resume', resume);
|
||
client.on('guildBanAdd', banAdd);
|
||
client.on('error', clientError);
|
||
|
||
setTimeout(saveSettings, 30000);
|
||
|
||
log("AstralMod " + amVersion + " - locked and loaded!", logType.good);
|
||
|
||
if (process.argv.includes("--debug")) { //Leaf hair :)
|
||
client.users.set("334842301035577346", {
|
||
avatar: "341014541221625868",
|
||
avatarURL: "https://cdn.discordapp.com/attachments/337665122908504074/341014541221625868/9k1.png",
|
||
bot: false,
|
||
client: client,
|
||
createdAt: new Date("2017-07-12T23:43:21+0000"),
|
||
discriminator: "0889",
|
||
displayAvatarURL: "https://cdn.discordapp.com/attachments/337665122908504074/341014541221625868/9k1.png",
|
||
dmChannel: client.users.get("384454726512672768").dmChannel,
|
||
id: "334842311135577346",
|
||
presence: {
|
||
game: null,
|
||
status: "offline",
|
||
},
|
||
tag: "Vrabbers#0889",
|
||
username: "Vrabbers",
|
||
|
||
send: (content, options) => client.users.get("384454726512672768").send(content, options),
|
||
toString: () => "<@334842311135577346>"
|
||
})
|
||
|
||
|
||
}
|
||
|
||
countBans();
|
||
loadInvites();
|
||
setInterval(loadInvites, 300000);
|
||
|
||
setInterval(function() {
|
||
titleBox.content = " " + moment().format("HH:mm:ss") + " | AstralMod " + amVersion + " Console │ Uptime: " + moment.duration(client.uptime).humanize() +
|
||
" │ Guilds: " + parseInt(client.guilds.size);
|
||
renderScreen();
|
||
}, 1000);
|
||
|
||
client.fetchApplication().then(app => global.botOwner = app.owner);
|
||
}
|
||
|
||
client.once('ready', readyOnce);
|
||
|
||
client.on('disconnect', function(closeEvent) {
|
||
log("AstralMod has disconnected from Discord and will not attempt to reconnect.", logType.critical);
|
||
log("Close code: " + parseInt(closeEvent.code), logType.critical);
|
||
log("At this point, you'll need to restart AstralMod.", logType.critical);
|
||
|
||
commandEmitter.emit('disconnect');
|
||
});
|
||
client.on('reconnecting', function() {
|
||
log("AstralMod has disconnected from Discord and is now attempting to reconnect.", logType.warning);
|
||
|
||
commandEmitter.emit('disconnect');
|
||
});
|
||
|
||
if (process.argv.indexOf("--debug") == -1) {
|
||
log("Running AstralMod without --debug command line flag. Debug output disabled.", logType.info);
|
||
} else {
|
||
//Enable debugging output from discord.js
|
||
|
||
client.on('debug', function(info) {
|
||
log(info);
|
||
});
|
||
client.on('warn', function(info) {
|
||
log(info, logType.warning);
|
||
});
|
||
}
|
||
|
||
if (process.argv.indexOf("--httpserver") != -1) {
|
||
log("Initializing HTTP server");
|
||
var httpServer = http.createServer(function(req, res) {
|
||
if (req.method == "GET") {
|
||
if (req.url == "/") {
|
||
res.writeHead(200, "OK");
|
||
res.end(fs.readFileSync("webserver.html"));
|
||
} else {
|
||
res.writeHead(400, "Not Found");
|
||
res.end();
|
||
}
|
||
} else if (req.method == "POST") {
|
||
var body = "";
|
||
req.on('data', function(chunk) {
|
||
body += chunk;
|
||
});
|
||
req.on('end', function() {
|
||
var command = body;
|
||
textBox.setValue("> " + command);
|
||
textBox.submit();
|
||
|
||
res.writeHead(204, "No Content");
|
||
res.end();
|
||
});
|
||
}
|
||
});
|
||
httpServer.listen(28931);
|
||
}
|
||
|
||
log("Checking configuration...", logType.info);
|
||
|
||
const requireDiscordVersion = "11.4.2";
|
||
if (Discord.version != requireDiscordVersion) {
|
||
log("Invalid Discord.JS version", logType.critical);
|
||
log("This version of AstralMod requires Discord.JS version " + requireDiscordVersion, logType.info);
|
||
log("Execution halted.", logType.critical);
|
||
} else {
|
||
if (consts.keys.settingsKey == null) {
|
||
log("Settings Encryption Key not found.", logType.critical);
|
||
log("To inform AstralMod about your settings encryption key,\n" +
|
||
"1. Create a file called keys.js in the same directory as AstralMod\n" +
|
||
"2. Save the file with the following:\n" +
|
||
" exports.settingsKey = \"[a random password]\"", logType.info);
|
||
} else {
|
||
log("Establishing connection to Discord...", logType.info);
|
||
client.options.disabledEvents = [
|
||
"TYPING_START"
|
||
]
|
||
try {
|
||
if (consts.keys.token != null) {
|
||
client.login(consts.keys.token).catch(function() {
|
||
log("Couldn't establish a connection to Discord.", logType.critical);
|
||
});
|
||
} else {
|
||
log("Login Token not found.", logType.critical);
|
||
log("To inform AstralMod about your token,\n" +
|
||
"1. Create a file called keys.js in the same directory as AstralMod\n" +
|
||
"2. Save the file with the following:\n" +
|
||
" exports.key = \"[your key here]\"", logType.info);
|
||
}
|
||
} catch (err) {
|
||
log("Login Token not found.", logType.critical);
|
||
log("To inform AstralMod about your token,\n" +
|
||
"1. Create a file called keys.js in the same directory as AstralMod\n" +
|
||
"2. Save the file with the following:\n" +
|
||
" exports.key = \"[your key here]\"", logType.info);
|
||
}
|
||
}
|
||
} |