mirror of
https://github.com/yuzu-emu/Command-fix.git
synced 2024-12-23 04:05:35 +00:00
Initial push of discord-bot code.
This commit is contained in:
parent
7ded8c2c45
commit
cbcab5e343
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules
|
||||||
|
jspm_packages
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
config/production.json
|
||||||
|
config/development.json
|
9
app.js
Normal file
9
app.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/* Application State */
|
||||||
|
var Application = function() {
|
||||||
|
this.guild = null;
|
||||||
|
this.logChannel = null;
|
||||||
|
this.warnings = [];
|
||||||
|
this.bans = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = new Application();
|
28
commands/ban.js
Normal file
28
commands/ban.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
var discord = require('discord.js');
|
||||||
|
var app = require('../app.js');
|
||||||
|
var data = require('../data.js');
|
||||||
|
var logger = require('../logging.js');
|
||||||
|
var UserBan = require('../models/UserBan.js');
|
||||||
|
|
||||||
|
exports.roles = ['Admins', 'Moderators', 'Secret', 'CitraBot'];
|
||||||
|
exports.command = function(message) {
|
||||||
|
message.mentions.users.map((user) => {
|
||||||
|
var count = app.warnings.filter(function(x) { return x.id == user.id && !x.cleared }).length || 0;
|
||||||
|
|
||||||
|
message.channel.sendMessage(`${user} You will now be banned from this channel.`).catch(function (error) {
|
||||||
|
logger.error('Error sending #admin-log message.', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info(`${message.author.username} ${message.author} has banned ${user.username} ${user}.`);
|
||||||
|
app.logChannel.sendMessage(`${message.author} has banned ${user} [${count} + 1].`).catch(function (error) {
|
||||||
|
logger.error('Error sending #admin-log message.', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
message.guild.member(user).ban().catch(function (error) {
|
||||||
|
logger.error(`Error banning ${user.username} ${user.id}.`, error);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.bans.push(new UserBan(user.id, user.username, message.author.id, message.author.username, count));
|
||||||
|
data.flushBans();
|
||||||
|
});
|
||||||
|
}
|
18
commands/clearWarnings.js
Normal file
18
commands/clearWarnings.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
var app = require('../app.js');
|
||||||
|
var data = require('../data.js');
|
||||||
|
var logger = require('../logging.js');
|
||||||
|
|
||||||
|
exports.roles = ['Admins', 'Moderators'];
|
||||||
|
exports.command = function(message) {
|
||||||
|
message.mentions.users.map((user) => {
|
||||||
|
var count = app.warnings.filter(function(x) { return x.id == user.id && !x.cleared }).length || 0;
|
||||||
|
count.forEach(function(warning) {
|
||||||
|
warning.cleared = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
data.flushWarnings();
|
||||||
|
|
||||||
|
message.channel.sendMessage(`${user}, your warnings have been cleared.`);
|
||||||
|
app.logChannel.sendMessage(`${message.author} has cleared all warnings for ${user} [${count}].`);
|
||||||
|
});
|
||||||
|
}
|
13
commands/quote.js
Normal file
13
commands/quote.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
var app = require('../app.js');
|
||||||
|
var logger = require('../logging.js');
|
||||||
|
|
||||||
|
exports.roles = ['Admins', 'Moderators', 'Secret'];
|
||||||
|
exports.command = function(message, reply) {
|
||||||
|
let replyMessage = 'Hello.';
|
||||||
|
if (reply == null) { replyMessage = message.content.substr(message.content.indexOf(' ') + 1); }
|
||||||
|
else { replyMessage = `${message.mentions.users.map(function (user) { return `${user}`; })} ${reply}`; }
|
||||||
|
|
||||||
|
message.channel.sendMessage(replyMessage).catch(function (error) {
|
||||||
|
logger.error('Unable to send reply message to quote.', error);
|
||||||
|
});
|
||||||
|
}
|
15
commands/testing.js
Normal file
15
commands/testing.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
var app = require('../app.js');
|
||||||
|
var logger = require('../logging.js');
|
||||||
|
|
||||||
|
exports.command = function(message) {
|
||||||
|
var roleId = '254036987508424714';
|
||||||
|
var alreadyJoined = app.guild.roles.get(roleId).members.find(function(member) { return member.id == message.member.id });
|
||||||
|
|
||||||
|
if (alreadyJoined != null) {
|
||||||
|
message.member.removeRole(roleId);
|
||||||
|
message.reply('You are no longer part of the testing group.');
|
||||||
|
} else {
|
||||||
|
message.member.addRole(roleId);
|
||||||
|
message.reply('You are now part of the testing group.');
|
||||||
|
}
|
||||||
|
}
|
29
commands/warn.js
Normal file
29
commands/warn.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
var discord = require('discord.js');
|
||||||
|
var app = require('../app.js');
|
||||||
|
var data = require('../data.js');
|
||||||
|
var logger = require('../logging.js');
|
||||||
|
var UserWarning = require('../models/UserWarning.js');
|
||||||
|
|
||||||
|
exports.roles = ['Admins', 'Moderators', 'Secret', 'Helpers'];
|
||||||
|
exports.command = function(message) {
|
||||||
|
message.mentions.users.map((user) => {
|
||||||
|
var count = app.warnings.filter(function(x) { return x.id == user.id && !x.cleared }).length || 0;
|
||||||
|
|
||||||
|
message.channel.sendMessage(`${user} You have been warned. Additional infractions may result in a ban.`).catch(function (error) {
|
||||||
|
logger.error('Error sending #admin-log message.', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info(`${message.author.username} ${message.author} has warned ${user.username} ${user} [${count} + 1].`);
|
||||||
|
app.logChannel.sendMessage(`${message.author} has warned ${user} [${count} + 1].`).catch(function (error) {
|
||||||
|
logger.error('Error sending #admin-log message.', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.warnings.push(new UserWarning(user.id, user.username, message.author.id, message.author.username, count));
|
||||||
|
data.flushWarnings();
|
||||||
|
|
||||||
|
if (count + 1 >= 3) {
|
||||||
|
app.logChannel.sendMessage(`.ban ${user}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
12
commands/warnings.js
Normal file
12
commands/warnings.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
var app = require('../app.js');
|
||||||
|
var logger = require('../logging.js');
|
||||||
|
|
||||||
|
exports.command = function(message) {
|
||||||
|
message.mentions.users.map((user) => {
|
||||||
|
var count = app.warnings.filter(function(x) { return x.id == user.id && !x.cleared }).length || 0;
|
||||||
|
|
||||||
|
message.channel.sendMessage(`${user}, you have ${count} warnings.`).catch(function (error) {
|
||||||
|
logger.error('Error sending #admin-log message.', error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
19
config/default.json
Normal file
19
config/default.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"commandPrefix": ".",
|
||||||
|
"logChannel": null,
|
||||||
|
"clientLoginToken": null,
|
||||||
|
"pmReply": "Please refer to our frequently asked questions. <https://citra-emu.org/wikis/faq>",
|
||||||
|
"quotes": {
|
||||||
|
"faq": { "reply": "Please refer to our frequently asked questions. <https://citra-emu.org/wikis/faq>" },
|
||||||
|
"requirements": { "reply": "Please refer to our frequently asked questions. The only requirements for Citra is a GPU that supports at least OpenGL 3.3 and a 64-bit OS, but you definitely want a processor with the highest possible performance per core. <https://citra-emu.org/wikis/faq>"},
|
||||||
|
"roms": { "warn": true, "reply": "Please read our community rules. Warez/downloading games talk is prohibited. To prevent legal issues, you may not post links or refer to any kind of ROM, NAND, ISO, game, or other copyrighted material that has been illegally obtained or shared. <https://citra-emu.org/page/rules>"},
|
||||||
|
"dump-game": { "reply": "Please refer to our game dumping guides. <https://citra-emu.org/wiki/dumping-game-cartridges> & <https://citra-emu.org/wiki/dumping-installed-titles>"},
|
||||||
|
"dump-system": { "reply": "Please refer to our system dumping guide. <https://citra-emu.org/wikis/dumping-system-archives-and-the-shared-fonts-from-a-3ds-console>"},
|
||||||
|
"pokemon": { "reply": "Here is the current status of Pokemon games on our emulator. All games require a home-folder dump. \nPokemon X&Y: Crashes in several places.\nPokemon OR&AS: Better stability, crashes in Petalburg Woods\nPokemon S&M: Best stability, crashes when defeating the last boss."},
|
||||||
|
"alpha": { "reply": "Citra is currently in very early stages of development. Games usually run less than full-speed even on the best computers. Expect bugs and glitches to appear in most games. Many features of more stable emulators are still in the works. For any major updates, please check <https://citra-emu.org/>"},
|
||||||
|
"updates": { "reply": "You can see our latest updates on Github. <https://github.com/citra-emu/citra/pulse>"},
|
||||||
|
"download": { "reply": "Please only download from the official Citra website, as downloading from other sources is not supported here. <https://citra-emu.org/page/download>"},
|
||||||
|
"legal": { "reply": "Citra is legal, we don't support illegal activities. Dumping your purchased games and system files from your 3DS is legal. Downloading them is not."},
|
||||||
|
"building": { "reply": "Please refer to our building guides.\nWindows: <https://citra-emu.org/wiki/building-for-windows> \nOSX: <https://citra-emu.org/wiki/building-for-macos> \nLinux: <https://citra-emu.org/wiki/building-for-linux>"}
|
||||||
|
}
|
||||||
|
}
|
41
data.js
Normal file
41
data.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
var fs = require('fs');
|
||||||
|
var app = require('./app.js');
|
||||||
|
var logger = require('./logging.js');
|
||||||
|
|
||||||
|
function readWarnings() {
|
||||||
|
// Load the warnings file into the bans variable.
|
||||||
|
fs.readFile('./data/discordWarnings.json', 'utf8', function (err, data) {
|
||||||
|
if (err && err.code === 'ENOENT') { return; }
|
||||||
|
if (err) { logger.error(err); }
|
||||||
|
app.warnings = JSON.parse(data);
|
||||||
|
logger.info('Loaded warnings file.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBans() {
|
||||||
|
// Load the ban file into the bans variable.
|
||||||
|
fs.readFile('./data/discordBans.json', 'utf8', function (err, data) {
|
||||||
|
if (err && err.code === 'ENOENT') { return; }
|
||||||
|
if (err) { logger.error(err); }
|
||||||
|
app.bans = JSON.parse(data);
|
||||||
|
logger.info('Loaded bans file.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function flushWarnings() {
|
||||||
|
var warningsJson = JSON.stringify(app.warnings, null, 4);
|
||||||
|
if (!fs.existsSync('./data/')) fs.mkdirSync('./data/');
|
||||||
|
fs.writeFile('./data/discordWarnings.json', warningsJson, 'utf8', function (err) {
|
||||||
|
if (err) return console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function flushBans() {
|
||||||
|
var bansJson = JSON.stringify(app.bans, null, 4);
|
||||||
|
if (!fs.existsSync('./data/')) fs.mkdirSync('./data/');
|
||||||
|
fs.writeFile('./data/discordBans.json', bansJson, 'utf8', function (err) {
|
||||||
|
if (err) return console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { readWarnings: readWarnings, readBans: readBans, flushWarnings: flushWarnings, flushBans: flushBans }
|
26
logging.js
Normal file
26
logging.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
var winston = require('winston');
|
||||||
|
winston.emitErrs = true;
|
||||||
|
|
||||||
|
var logger = new winston.Logger({
|
||||||
|
transports: [
|
||||||
|
new winston.transports.File({
|
||||||
|
level: 'info',
|
||||||
|
filename: './server.log',
|
||||||
|
handleExceptions: true,
|
||||||
|
humanReadableUnhandledException: true,
|
||||||
|
json: true,
|
||||||
|
maxsize: 5242880, //5MB
|
||||||
|
maxFiles: 5,
|
||||||
|
colorize: false
|
||||||
|
}),
|
||||||
|
new winston.transports.Console({
|
||||||
|
level: 'debug',
|
||||||
|
handleExceptions: true,
|
||||||
|
json: false,
|
||||||
|
colorize: true
|
||||||
|
})
|
||||||
|
],
|
||||||
|
exitOnError: false
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = logger;
|
12
models/UserBan.js
Normal file
12
models/UserBan.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class UserBan {
|
||||||
|
constructor(id, username, warnedBy, warnedByUsername, priorWarnings) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.date = new Date();
|
||||||
|
this.warnedBy = warnedBy;
|
||||||
|
this.warnedByUsername = warnedByUsername;
|
||||||
|
this.priorWarnings = priorWarnings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UserBan;
|
12
models/UserWarning.js
Normal file
12
models/UserWarning.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class UserWarning {
|
||||||
|
constructor(id, username, warnedBy, warnedByUsername, priorWarnings) {
|
||||||
|
this.id = id;
|
||||||
|
this.username = username;
|
||||||
|
this.date = new Date();
|
||||||
|
this.warnedBy = warnedBy;
|
||||||
|
this.warnedByUsername = warnedByUsername;
|
||||||
|
this.priorWarnings = priorWarnings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UserWarning;
|
19
package.json
Normal file
19
package.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "citra-discord-bot",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Citra bot for Discord",
|
||||||
|
"author": "chris062689 <chris062689@gmail.com>",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"preferGlobal": true,
|
||||||
|
"private": true,
|
||||||
|
"subdomain": "citra-emu",
|
||||||
|
"analyze": true,
|
||||||
|
"license": "GPL-2.0+",
|
||||||
|
"dependencies": {
|
||||||
|
"config": "^1.24.0",
|
||||||
|
"discord.js": "^10.0.1",
|
||||||
|
"winston": "^2.3.0"
|
||||||
|
}
|
||||||
|
}
|
87
server.js
Normal file
87
server.js
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
var discord = require('discord.js');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var config = require('config');
|
||||||
|
|
||||||
|
var logger = require('./logging.js');
|
||||||
|
var app = require('./app.js');
|
||||||
|
var data = require('./data.js');
|
||||||
|
|
||||||
|
var cachedModules = [];
|
||||||
|
var client = new discord.Client();
|
||||||
|
|
||||||
|
function findArray(haystack, arr) {
|
||||||
|
return arr.some(function (v) {
|
||||||
|
return haystack.indexOf(v) >= 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
client.on('ready', () => {
|
||||||
|
|
||||||
|
// Cache all command modules.
|
||||||
|
require("fs").readdirSync('./commands/').forEach(function(file) {
|
||||||
|
cachedModules[file] = require(`./commands/${file}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initalize app channels.
|
||||||
|
app.logChannel = client.channels.get(config.logChannel);
|
||||||
|
app.guild = app.logChannel.guild;
|
||||||
|
|
||||||
|
data.readWarnings();
|
||||||
|
data.readBans();
|
||||||
|
|
||||||
|
logger.info('Startup complete. Bot is now online and connected to server.');
|
||||||
|
app.logChannel.sendMessage(`Startup complete.`);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('message', message => {
|
||||||
|
if (message.author.bot && message.content.startsWith('.ban') == false) { return; }
|
||||||
|
|
||||||
|
if (message.guild == null) {
|
||||||
|
// We want to log PM attempts.
|
||||||
|
logger.info(`${message.author.username} ${message.author} [PM]: ${message.content}`);
|
||||||
|
app.logChannel.sendMessage(`${message.author} [PM]: ${message.content}`);
|
||||||
|
message.reply(config.pmReply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.verbose(`${message.author.username} ${message.author} [Channel: ${message.channel}]: ${message.content}`);
|
||||||
|
|
||||||
|
if (message.content.startsWith(config.commandPrefix)) {
|
||||||
|
let cmd = message.content.split(' ')[0].slice(1);
|
||||||
|
|
||||||
|
// Check by the name of the command.
|
||||||
|
let cachedModule = cachedModules[`${cmd}.js`];
|
||||||
|
let cachedModuleType = 'Command';
|
||||||
|
// Check by the quotes in the configuration.
|
||||||
|
if (cachedModule == null) { cachedModule = config.quotes[cmd]; cachedModuleType = 'Quote'; }
|
||||||
|
|
||||||
|
if (cachedModule) {
|
||||||
|
// Check access permissions.
|
||||||
|
if (cachedModule.roles != undefined && findArray(message.member.roles.map(function(x) { return x.name; }), cachedModule.roles) == false) {
|
||||||
|
app.logChannel.sendMessage(`${message.author} attempted to use admin command: ${message.content}`);
|
||||||
|
logger.info(`${message.author.username} ${message.author} attempted to use admin command: ${message.content}`)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`${message.author.username} ${message.author} [Channel: ${message.channel}] triggered command: ${message.content}`);
|
||||||
|
message.delete();
|
||||||
|
|
||||||
|
if (cachedModuleType == 'Command') {
|
||||||
|
cachedModule.command(message);
|
||||||
|
} else if (cachedModuleType == 'Quote') {
|
||||||
|
cachedModules['quote.js'].command(message, cachedModule.reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the command requires a warning.
|
||||||
|
if (cmd != 'warn' && cachedModule.warn == true) {
|
||||||
|
cachedModules['warn.js'].command(message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not a valid command.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
client.login(config.clientLoginToken);
|
Loading…
Reference in a new issue