mirror of
https://github.com/danbulant/cnmc-bot
synced 2026-05-24 12:45:56 +00:00
Initial commit
This commit is contained in:
commit
3f7a3134e4
6 changed files with 312 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
3
config.json
Normal file
3
config.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"token": "NzQ5MTc3MzEzNjE4NTU4OTk3.X0oLvg.ux4hH4E43YCj0xy3xAAJ6QkEQmQ"
|
||||||
|
}
|
||||||
115
index.js
Normal file
115
index.js
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
const config = require("./config.json");
|
||||||
|
const discord = require("discord.js");
|
||||||
|
const { app, answers, messages, challenge, points } = require("./src");
|
||||||
|
|
||||||
|
const client = new discord.Client({
|
||||||
|
presence: {
|
||||||
|
status: "online",
|
||||||
|
activity: {
|
||||||
|
name: "CNMC",
|
||||||
|
type: "PLAYING"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("ready", () => {
|
||||||
|
console.log("Ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("message", async msg => {
|
||||||
|
try {
|
||||||
|
await app.message(msg);
|
||||||
|
} catch(e) {
|
||||||
|
console.error("APP", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function check(member, bonus = 0) {
|
||||||
|
var pointNum = bonus + (answers.get(member.user.id) ? (0.5 + ((challenge.get("num") || 1) * 0.5)) : 0);
|
||||||
|
if(points.get(member.user.id) === pointNum) return;
|
||||||
|
if(points.get(member.user.id) && points.get(member.user.id) > 1) return;
|
||||||
|
var diff = pointNum - (points.get(member.user.id) || 0);
|
||||||
|
points.set(pointNum);
|
||||||
|
member.setNickname(member.displayName.replace(/\[([0-9.]+)\]/, (match, num) => {
|
||||||
|
return `[${parseFloat(num) + diff}]`;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
client.on("messageDelete", msg => {
|
||||||
|
if(messages.get(msg.id)) {
|
||||||
|
messages.delete(msg.id);
|
||||||
|
messages.delete(msg.id);
|
||||||
|
var an = answers.get(msg.author.id) || 0;
|
||||||
|
if(an) answers.set(msg.author.id, an - 1);
|
||||||
|
check(msg.member);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("messageReactionAdd", async (react, user) => {
|
||||||
|
if(react.message.channel.id !== "745989024099074068") return;
|
||||||
|
if(user.id !== "694395936809418816") {
|
||||||
|
if(user.id !== client.user.id) {
|
||||||
|
await react.users.remove(user);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(user.id === client.user.id) return;
|
||||||
|
if(react.emoji.name !== "❌" && react.emoji.name !== "✅") return;
|
||||||
|
if(react.emoji.name === "✅") {
|
||||||
|
var r = await react.message.reactions.resolve("❌");
|
||||||
|
await r.remove();
|
||||||
|
|
||||||
|
var points = 0;
|
||||||
|
|
||||||
|
if(challenge.get("hint")) {
|
||||||
|
var msg = await react.message.channel.messages.fetch(challenge.get("hint"));
|
||||||
|
if(msg.createdTimestamp < react.message.createdTimestamp) {
|
||||||
|
points -= 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!challenge.get("answered")) {
|
||||||
|
challenge.set("answered", 0);
|
||||||
|
}
|
||||||
|
switch(challenge.get("answered")) {
|
||||||
|
case 0:
|
||||||
|
points += 2;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
points += 1.5;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
points += 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
points += 0.5;
|
||||||
|
}
|
||||||
|
challenge.set("answered", challenge.get("answered") + 1);
|
||||||
|
|
||||||
|
if(points > 0) {
|
||||||
|
check(react.message.member, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
react.message.channel.messages.cache.filter(val => val.author.id === react.message.author.id)
|
||||||
|
.filter(val => val.id !== react.message.id)
|
||||||
|
.forEach(msg => msg.reactions.removeAll());
|
||||||
|
} else {
|
||||||
|
var r = await react.message.reactions.resolve("✅");
|
||||||
|
await r.remove();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on("messageUpdate", (msg, msg2) => {
|
||||||
|
if(msg.channel.id === "745989024099074068") {
|
||||||
|
if(messages.get(msg.id)) {
|
||||||
|
messages.delete(msg.id);
|
||||||
|
var an = answers.get(msg.author.id) || 0;
|
||||||
|
if(an) answers.set(msg.author.id, an - 1);
|
||||||
|
check(msg.member);
|
||||||
|
}
|
||||||
|
msg.author.send("You've edited the messages so it got deleted.");
|
||||||
|
msg.delete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.login(config.token);
|
||||||
119
lib/middleware.js
Normal file
119
lib/middleware.js
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = class Router {
|
||||||
|
/**
|
||||||
|
* @type {{
|
||||||
|
path: string,
|
||||||
|
callback: function(Message): boolean | string,
|
||||||
|
break: boolean,
|
||||||
|
opts: {
|
||||||
|
guildOnly: boolean,
|
||||||
|
permissions: string[],
|
||||||
|
clientPermissions: string[],
|
||||||
|
ownerOnly: boolean
|
||||||
|
}
|
||||||
|
}[]} middlewares
|
||||||
|
*/
|
||||||
|
middlewares = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a command
|
||||||
|
* @param {string} path command format
|
||||||
|
* @param {function(Message): boolean | string} callback to call on match
|
||||||
|
* @param {{
|
||||||
|
guildOnly: boolean,
|
||||||
|
permissions: string[],
|
||||||
|
clientPermissions: string[]
|
||||||
|
}} opts options to use
|
||||||
|
*/
|
||||||
|
command(path, callback, opts = {}) {
|
||||||
|
this.middlewares.push({
|
||||||
|
path,
|
||||||
|
callback,
|
||||||
|
opts,
|
||||||
|
break: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
use(path, router, opts = {}) {
|
||||||
|
if(typeof path !== "string") {
|
||||||
|
[router, opts] = [path, router];
|
||||||
|
path = "";
|
||||||
|
}
|
||||||
|
if(typeof router === "function") {
|
||||||
|
this.middlewares.push({
|
||||||
|
path,
|
||||||
|
callback: router,
|
||||||
|
opts,
|
||||||
|
break: false
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
for(var middleware of router.middlewares) {
|
||||||
|
this.middlewares.push({
|
||||||
|
...middleware,
|
||||||
|
path: (path + " " + middleware.path).trim(),
|
||||||
|
opts: Object.assign(middleware.opts, opts)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
processPath(path, content) {
|
||||||
|
if(!path) return {};
|
||||||
|
var segments = path.split(" ");
|
||||||
|
var contentSegments = content.split(" ");
|
||||||
|
if(!contentSegments) return null;
|
||||||
|
if(segments.length > contentSegments.length) return null;
|
||||||
|
var args = {};
|
||||||
|
for(var segmentID in segments) {
|
||||||
|
var segment = segments[segmentID];
|
||||||
|
if(segment.startsWith(":")) {
|
||||||
|
args[segment.substr(1)] = contentSegments[segmentID];
|
||||||
|
} else if(segment !== contentSegments[segmentID]) return null;
|
||||||
|
}
|
||||||
|
var keys = segments.filter(segment => segment.startsWith(":")).map(segment => segment.substr(1));
|
||||||
|
if(contentSegments.length > segments.length && keys.length) {
|
||||||
|
args[keys[keys.length - 1]] += contentSegments.splice(segments.length).join(" ");
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Message} msg
|
||||||
|
* @param {{
|
||||||
|
guildOnly: boolean,
|
||||||
|
permissions: string[],
|
||||||
|
clientPermissions: string[]
|
||||||
|
}} opts options to use
|
||||||
|
*/
|
||||||
|
async checkOpts(msg, opts) {
|
||||||
|
if(!opts) return true;
|
||||||
|
if(!msg.guild && opts.guildOnly) return false;
|
||||||
|
if(opts.permissions && msg.member)
|
||||||
|
for(var permission of opts.permissions)
|
||||||
|
if(!msg.member.hasPermission(permission)) return false;
|
||||||
|
if(opts.clientPermissions && msg.guild.me)
|
||||||
|
for(var permission of opts.clientPermissions)
|
||||||
|
if(!msg.guild.me.hasPermission(permission)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async message(msg) {
|
||||||
|
var middlewares = this.middlewares;
|
||||||
|
|
||||||
|
for(var middleware of middlewares) {
|
||||||
|
var args = this.processPath(middleware.path, msg.content);
|
||||||
|
if(args === null) continue;
|
||||||
|
if(!this.checkOpts(msg, middleware.opts)) continue;
|
||||||
|
var result = await middleware.callback(msg, args);
|
||||||
|
if(typeof result === "string") {
|
||||||
|
await msg.channel.send(result);
|
||||||
|
}
|
||||||
|
if(result === false || middleware.break) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
package.json
Normal file
15
package.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "cnmc",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"discord.js": "^12.3.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/index.js
Normal file
58
src/index.js
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
const App = require("../lib/middleware");
|
||||||
|
const app = new App();
|
||||||
|
|
||||||
|
const answers = new Map();
|
||||||
|
const messages = new Map();
|
||||||
|
const challenge = new Map();
|
||||||
|
const points = new Map();
|
||||||
|
|
||||||
|
app
|
||||||
|
.use(msg => !msg.author.bot) // ignore bots
|
||||||
|
.use(async msg => {
|
||||||
|
if(msg.author.id === "694395936809418816" && msg.content === "!reset") {
|
||||||
|
answers.clear();
|
||||||
|
messages.clear();
|
||||||
|
challenge.clear();
|
||||||
|
msg.reply("done.");
|
||||||
|
return false;
|
||||||
|
} else if(msg.author.id === "694395936809418816" && msg.content.startsWith("!start")) {
|
||||||
|
var num = msg.content.split(" ")[1][0];
|
||||||
|
if(isNaN(parseInt(num))) {
|
||||||
|
msg.reply("Invalid type, must start with a number");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
challenge.set("num", num);
|
||||||
|
msg.reply("challenge type set.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.use(msg => msg.channel.id === "745989024099074068")
|
||||||
|
.use(msg => {
|
||||||
|
if(challenge.get("hint")) return;
|
||||||
|
if(msg.author.id === "694395936809418816") {
|
||||||
|
challenge.set("hint", msg.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.use(msg => {
|
||||||
|
if(!/^\[[0-9.]+\]/.test(msg.member.displayName)) {
|
||||||
|
msg.author.send("You must register first");
|
||||||
|
msg.delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.use(async msg => {
|
||||||
|
var answerCount = answers.get(msg.author.id) || 0;
|
||||||
|
answerCount++;
|
||||||
|
answers.set(msg.author.id, answerCount);
|
||||||
|
if(answerCount > 3) return await msg.delete();
|
||||||
|
if(answerCount === 3) {
|
||||||
|
await msg.author.send("You've used all your 3 answers, you won't be able to add any more.");
|
||||||
|
}
|
||||||
|
console.log("New answer:", msg.content, "by", msg.member.displayName);
|
||||||
|
messages.set(msg.id, 1);
|
||||||
|
msg.react("✅");
|
||||||
|
msg.react("❌");
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = { app, answers, messages, challenge, points };
|
||||||
Loading…
Reference in a new issue