Sfoglia il codice sorgente

Overhaul commands system and guide system

ghorsington 6 anni fa
parent
commit
436172b7ec
9 ha cambiato i file con 236 aggiunte e 171 eliminazioni
  1. 110 57
      commands/guide.js
  2. 4 3
      commands/help.js
  3. 0 22
      commands/image_statistics.js
  4. 4 3
      commands/inspire.js
  5. 59 47
      commands/quote.js
  6. 4 3
      commands/rcg.js
  7. 33 24
      commands/react.js
  8. 7 5
      db.js
  9. 15 7
      main.js

+ 110 - 57
commands/guide.js

@@ -2,78 +2,131 @@ const db = require("../db.js");
 const util = require("../util.js");
 
 const documentation = {
-    "make guide <keywords> <NEWLINE> <content>": {
+    "make <guidetype> <NEWLINE>name: <name> <NEWLINE>keywords: <keywords> <NEWLINE>contents: <content>": {
         auth: true,
-        description: "Creates a new guide."
+        description: "Creates a new guide of the specified type, the specified keywords and content."
     },
-    "delete guide <keywords>": {
+    "delete <guidetype> <keywords>": {
         auth: true,
-        description: "Deletes a guide."
+        description: "Deletes a guide of the specified type."
     },
     "guides": {
         auth: false,
-        description: "Lists all keywords that will trigger a guide."
+        description: "Lists all guides and keywords that trigger them."
+    },
+    "memes": {
+        auth: false,
+        description: "Lists all memes and keywords that trigger them."
+    },
+    "miscs": {
+        auth: false,
+        description: "Lists all additional keywords the bot reacts to."
     }
 };
 
-const commands = {
-    "make guide": msg => {
-        if (!util.isAuthorised(msg.member)) return;
-        let content = msg.content.substring(msg.content.indexOf("make guide") + "make guide ".length);
-        let guideName = content.substring(0, content.indexOf("\n")).trim();
-        let guideContent = content.substring(content.indexOf("\n")).trim();
+const VALID_GUIDE_TYPES = new Set(["meme", "guide", "misc"]);
 
-        let guide = db.get("guides").find({
-            name: guideName
-        });
+const makePattern = /^make (\w+)\s+name:(.+)\s*keywords:(.+)\s*contents:((.*[\n\r]*)+)$/i;
+const deletePattern = /^delete (\w+)\s+(.+)$/i;
 
-        if (!guide.isUndefined().value()) {
-            guide.assign({
-                content: guideContent
-            }).write();
-        } else {
-            db.get("guides")
-                .push({
-                    name: guideName,
-                    content: guideContent
-                })
-                .write();
-        }
+function listGuides(msg, guideType, message){
+    let guides = db
+            .get(guideType)
+            .reduce((p, c) => `${p}\n${c.displayName} -- ${c.name}`, "\n")
+            .value();
+    msg.channel.send(`${msg.author.toString()} ${message}\n\`\`\`${guides}\`\`\`\n\nTo display the guides, ping me with one or more keywords, like \`@NoctBot sybaris com\``);
+}
 
-        msg.channel.send(
-            `${msg.author.toString()} Added/updated "${guideName}"!`
-        );
-    },
-    "delete guide": (msg, s) => {
-        if (!util.isAuthorised(msg.member)) return;
-        let guideName = s.substring("delete guide ".length).trim();
-        let val = db.get("guides").find({
-            name: guideName
-        });
+const commands = [
+    {
+        pattern: makePattern,
+        action: (msg, s, match) => {
+            if (!util.isAuthorised(msg.member)) return;
+            let type = match[1].toLowerCase();
+            let name = match[2].trim();
+            let keywords = match[3].trim().toLowerCase();
+            let contents = match[4].trim();
 
-        if (val.isUndefined().value()) {
-            msg.channel.send(`${msg.author.toString()} No guide "${guideName}"!`);
-            return;
+            if(contents.length == 0){
+                msg.channel.send(
+                    `${msg.author.toString()} The guide must have some content!`
+                );
+                return;
+            }
+    
+            if(!VALID_GUIDE_TYPES.has(type)){
+                msg.channel.send(
+                    `${msg.author.toString()} The type ${type} is not a valid guide type!`
+                );
+                return;
+            }
+    
+            let typeDB = `${type}s`;
+    
+            let guide = db.get(typeDB).find({
+                name: keywords
+            });
+    
+            if (!guide.isUndefined().value()) {
+                guide.assign({
+                    displayName: name,
+                    content: contents
+                }).write();
+            } else {
+                db.get(typeDB)
+                    .push({
+                        name: keywords,
+                        displayName: name,
+                        content: contents
+                    })
+                    .write();
+            }
+    
+            msg.channel.send(
+                `${msg.author.toString()} Added/updated "${name}" (keywords \`${keywords}\`)!`
+            );
         }
-
-        db.get("guides")
-            .remove({
-                name: guideName
-            })
-            .write();
-        msg.channel.send(
-            `${msg.author.toString()} Removed guide "${guideName}"!`
-        );
     },
-    "guides": msg => {
-        let guides = db
-            .get("guides")
-            .map(g => g.name)
-            .reduce((p, c) => `${p}\n${c}`, "\n")
-            .value();
-        msg.channel.send(`${msg.author.toString()} Ping me with one of the following keywords for a guide related to the topic:\n\`\`\`${guides}\`\`\``);
-    }
-};
+    {
+        pattern: deletePattern,
+        action: (msg, s, match) => {
+            if (!util.isAuthorised(msg.member)) return;
+            let type = match[1];
+            let keywords = match[2].trim();
+    
+            if(!VALID_GUIDE_TYPES.has(type)){
+                msg.channel.send(
+                    `${msg.author.toString()} The type ${type} is not a valid guide type!`
+                );
+                return;
+            }
+    
+            let typeDB = `${type}s`;
+    
+            let val = db.get(typeDB).find({
+                name: keywords
+            });
+    
+            if (val.isUndefined().value()) {
+                msg.channel.send(`${msg.author.toString()} No ${type} "${keywords}"!`);
+                return;
+            }
+    
+            db.get(typeDB)
+                .remove({
+                    name: keywords
+                })
+                .write();
+    
+            msg.channel.send(
+                `${msg.author.toString()} Removed ${type} "${keywords}"!`
+            );
+        }
+    },
+    { pattern: "guides", action: msg => listGuides(msg, "guides", "Here are the guides I have:") },
+    { pattern: "memes", action: msg => listGuides(msg, "memes", "Here are some random memes I have:") },
+    { pattern: "misc", action: msg => listGuides(msg, "misc", "These are some misc stuff I can also do:") },
+];
 
 const onDirectMention = (msg, content, actionsDone) => {
     if (actionsDone)

+ 4 - 3
commands/help.js

@@ -1,7 +1,8 @@
 const util = require("../util.js");
 
-const commands = {
-    "help": msg => {
+const commands = [{
+    pattern: "help",
+    action: msg => {
         let isAuthed = util.isAuthorised(msg.member);
 
         let baseCommands = "\n";
@@ -25,7 +26,7 @@ const commands = {
 
         msg.channel.send(message);
     }
-};
+}];
 
 module.exports = {
     commands: commands

+ 0 - 22
commands/image_statistics.js

@@ -1,22 +0,0 @@
-const fs = require("fs");
-const util = require("../util.js");
-const path = require("path");
-
-const statsFilePath = path.resolve(path.dirname(module.filename), "../imagestats.csv");
-const statsFile = fs.openSync(statsFilePath, "a");
-
-const onMessage = msg => {
-    let imagesCount = msg.attachments.filter(v => util.isValidImage(v.filename)).size;
-
-    if(imagesCount > 0) {
-        let now = new Date();
-        fs.writeSync(statsFile, `${now.getUTCFullYear()}-${now.getUTCMonth()+1}-${now.getUTCDate()} ${now.getUTCHours()}:${now.getUTCMinutes()};${imagesCount};${msg.channel.name}\n`);
-    }
-
-    return false;
-};
-
-module.exports = {
-    onMessage: onMessage
-};
-

+ 4 - 3
commands/inspire.js

@@ -15,11 +15,12 @@ async function inspire(msg) {
     });
 }
 
-const commands = {
-    "inspire me": msg => {
+const commands = [{
+    pattern: "inspire me",
+    action: msg => {
         inspire(msg);    
     }
-};
+}];
 
 module.exports = {
     commands: commands,

+ 59 - 47
commands/quote.js

@@ -29,59 +29,71 @@ function minify(str, maxLength) {
     return result;
 }
 
-const commands = {
-    "add quote": (msg, c) => {
-        if (!util.isAuthorised(msg.member))
-            return;
-
-        let result = quotePattern.exec(c);
-
-        if (result == null)
-            return;
-
-        let author = result[1].trim();
-        let message = result[2].trim();
-
-        db.get("quotes").push({
-            author: author,
-            message: message
-        }).write();
-
-        msg.channel.send(`${msg.author.toString()} Added quote #${db.get("quotes").size().value()}!`);
-    },
-    "random quote": (msg) => {
-        if (db.get("quotes").size().value() == 0) {
-            msg.channel.send("I have no quotes!");
-            return;
+const commands = [
+    {
+        pattern: "add quote",
+        action: (msg, c) => {
+            if (!util.isAuthorised(msg.member))
+                return;
+    
+            let result = quotePattern.exec(c);
+    
+            if (result == null)
+                return;
+    
+            let author = result[1].trim();
+            let message = result[2].trim();
+    
+            db.get("quotes").push({
+                author: author,
+                message: message
+            }).write();
+    
+            msg.channel.send(`${msg.author.toString()} Added quote #${db.get("quotes").size().value()}!`);
         }
-        let quote = db.get("quotes").randomElement().value();
-        let index = db.get("quotes").indexOf(quote).value();
-        msg.channel.send(`Quote #${index + 1}:\n*"${quote.message}"*\n- ${quote.author}`);
     },
-    "remove quote": (msg, c) => {
-        let quoteNum = c.substring("remove quote".length).trim();
-        let val = parseInt(quoteNum);
-        if (isNaN(val) || db.get("quotes").size().value() < val - 1)
-            return;
-
-        db.get("quotes").pullAt(val - 1).write();
-        msg.channel.send(`${msg.author.toString()} Removed quote #${val}!`);
+    {
+        pattern: "random quote",
+        action: (msg) => {
+            if (db.get("quotes").size().value() == 0) {
+                msg.channel.send("I have no quotes!");
+                return;
+            }
+            let quote = db.get("quotes").randomElement().value();
+            let index = db.get("quotes").indexOf(quote).value();
+            msg.channel.send(`Quote #${index + 1}:\n*"${quote.message}"*\n- ${quote.author}`);
+        }
     },
-    "quotes": msg => {
-        if (!util.isAuthorised(msg.member)) {
-            msg.channel.send(`${msg.author.toString()} To prevent spamming, only bot moderators can view all quotes!`);
-            return;
+    {
+        pattern: "remove quote",
+        action: (msg, c) => {
+            let quoteNum = c.substring("remove quote".length).trim();
+            let val = parseInt(quoteNum);
+            if (isNaN(val) || db.get("quotes").size().value() < val - 1)
+                return;
+    
+            db.get("quotes").pullAt(val - 1).write();
+            msg.channel.send(`${msg.author.toString()} Removed quote #${val}!`);
         }
-
-        if (db.get("quotes").size().value() == 0) {
-            msg.channel.send("I have no quotes!");
-            return;
+    },
+    {
+        pattern: "quotes",
+        action: msg => {
+            if (!util.isAuthorised(msg.member)) {
+                msg.channel.send(`${msg.author.toString()} To prevent spamming, only bot moderators can view all quotes!`);
+                return;
+            }
+    
+            if (db.get("quotes").size().value() == 0) {
+                msg.channel.send("I have no quotes!");
+                return;
+            }
+    
+            let quotes = db.get("quotes").reduce((prev, curr, i) => `${prev}[${i+1}] "${minify(curr.message, 10)}" by ${curr.author}\n`, "\n").value();
+            msg.channel.send(`${msg.author.toString()}I know the following quotes:\n\`\`\`${quotes}\`\`\``);
         }
-
-        let quotes = db.get("quotes").reduce((prev, curr, i) => `${prev}[${i+1}] "${minify(curr.message, 10)}" by ${curr.author}\n`, "\n").value();
-        msg.channel.send(`${msg.author.toString()}I know the following quotes:\n\`\`\`${quotes}\`\`\``);
     }
-};
+];
 
 
 module.exports = {

+ 4 - 3
commands/rcg.js

@@ -19,11 +19,12 @@ async function randomComic(msg) {
     });
 }
 
-const commands = {
-    "random comic": msg => {
+const commands = [{
+    pattern: "random comic",
+    action: msg => {
         randomComic(msg);
     }
-};
+}];
 
 module.exports = {
     commands: commands,

+ 33 - 24
commands/react.js

@@ -19,36 +19,45 @@ const documentation = {
     }
 };
 
-const commands = {
-    "react to": (msg, s) => {
-        if (!util.isAuthorised(msg.member)) return;
-        let contents = pattern.exec(s);
-        if (contents != null) {
-            let reactable = contents[1].trim().toLowerCase();
-            let reactionEmoji = contents[2];
-            if (!client.emojis.has(reactionEmoji)) {
-                msg.channel.send(`${msg.author.toString()} I cannot react with this emoji :(`);
-                return;
+const commands = [
+    {
+        pattern: "react to",
+        action: (msg, s) => {
+            if (!util.isAuthorised(msg.member)) return;
+            let contents = pattern.exec(s);
+            if (contents != null) {
+                let reactable = contents[1].trim().toLowerCase();
+                let reactionEmoji = contents[2];
+                if (!client.emojis.has(reactionEmoji)) {
+                    msg.channel.send(`${msg.author.toString()} I cannot react with this emoji :(`);
+                    return;
+                }
+                db.get("messageReactions").set(reactable, reactionEmoji).write();
+                msg.channel.send(`${msg.author.toString()} Added reaction!`);
             }
-            db.get("messageReactions").set(reactable, reactionEmoji).write();
-            msg.channel.send(`${msg.author.toString()} Added reaction!`);
         }
     },
-    "remove reaction to": (msg, s) => {
-        if (!util.isAuthorised(msg.member)) return;
-        let content = s.substring("remove reaction to ".length).trim().toLowerCase();
-        if (!db.get("messageReactions").has(content).value()) {
-            msg.channel.send(`${msg.author.toString()} No such reaction available!`);
-            return;
+    {
+        pattern: "remove reaction to",
+        action: (msg, s) => {
+            if (!util.isAuthorised(msg.member)) return;
+            let content = s.substring("remove reaction to ".length).trim().toLowerCase();
+            if (!db.get("messageReactions").has(content).value()) {
+                msg.channel.send(`${msg.author.toString()} No such reaction available!`);
+                return;
+            }
+            db.get("messageReactions").unset(content).write();
+            msg.channel.send(`${msg.author.toString()} Removed reaction!`);
         }
-        db.get("messageReactions").unset(content).write();
-        msg.channel.send(`${msg.author.toString()} Removed reaction!`);
     },
-    "reactions": msg => {
-        let reactions = db.get("messageReactions").keys().value().reduce((p, c) => `${p}\n${c}`, "");
-        msg.channel.send(`I'll react to the following messages:\n\`\`\`${reactions}\`\`\``);
+    {
+        pattern: "reactions",
+        action: msg => {
+            let reactions = db.get("messageReactions").keys().value().reduce((p, c) => `${p}\n${c}`, "");
+            msg.channel.send(`I'll react to the following messages:\n\`\`\`${reactions}\`\`\``);
+        }
     }
-};
+];
 
 const onMessage = (msg, content, actionsDone) => {
     if (actionsDone)

+ 7 - 5
db.js

@@ -48,6 +48,8 @@ db.defaults({
     bigUsers: ["432821242366656512"],
     dedUsers: ["326520875027267584"],
     guides: [],
+    memes: [],
+    miscs: [],
     editors: {
         roles: ["484046157971193866", "305844721622712322"],
         users: [
@@ -57,11 +59,11 @@ db.defaults({
         ]
     },
     rssFeeds: [
-        {
-            url: "http://custommaid3d2.com/index.php?forums/news.49/index.rss",
-            lastUpdate: "",
-            contentElement: "content:encoded"
-        }
+        // {
+        //     url: "http://custommaid3d2.com/index.php?forums/news.49/index.rss",
+        //     lastUpdate: "",
+        //     contentElement: "content:encoded"
+        // }
     ],
     postedNewsGuids: {},
     feedOutputs: ["422693157692637184"],

+ 15 - 7
main.js

@@ -15,7 +15,7 @@ function trigger(actions, ...params) {
     return actionDone;
 }
 
-let commands = {};
+let commands = [];
 let msgActions = [];
 let indirectMentionActions = [];
 let startActions = [];
@@ -49,11 +49,18 @@ client.on("message", m => {
             content = content.substring(`@${client.user.username}`.length).trim();
 
             let lowerCaseContent = content.toLowerCase();
-            for (let c in commands) {
-                if (lowerCaseContent.startsWith(c)) {
-                    commands[c](m, content);
+            for (let c of commands) {
+                if (typeof(c.pattern) == "string" && lowerCaseContent.startsWith(c.pattern)) {
+                    c.action(m, content);
                     return;
                 }
+                else if(c.pattern instanceof RegExp){
+                    let result = c.pattern.exec(content);
+                    if(result != null){
+                        c.action(m, content, result);
+                        return;
+                    }
+                }
             }
 
             if (trigger(directMessageActions, m, lowerCaseContent))
@@ -84,9 +91,10 @@ function main() {
 
         let obj = require(path.resolve(commandsPath, file));
         if (obj.commands) {
-            for (let command in obj.commands) {
-                if (obj.commands.hasOwnProperty(command))
-                    commands[command] = obj.commands[command];
+            for (let command of obj.commands) {
+                // if (obj.commands.hasOwnProperty(command))
+                    // commands[command] = obj.commands[command];
+                commands.push(command);
             }
         }