From f05582baaf848cb2445056e8884e635ec308681f Mon Sep 17 00:00:00 2001 From: thmsdy Date: Thu, 4 Jun 2020 23:37:10 -0500 Subject: [PATCH] Emote filter, Chat filter improvements, Disable commands, and custom commands --- .settings/org.eclipse.core.resources.prefs | 2 + dependency-reduced-pom.xml | 13 +- pom.xml | 18 +- src/main/java/com/fpghoti/biscuit/Main.java | 2 - .../fpghoti/biscuit/commands/BaseCommand.java | 6 + .../biscuit/commands/CommandManager.java | 25 +++ .../biscuit/commands/CustomCommand.java | 53 ++++++ .../commands/client/ChnameCommand.java | 31 ---- .../biscuit/commands/client/HelpCommand.java | 36 ++-- .../biscuit/config/ConfigRetrieval.java | 5 + .../biscuit/config/PropertiesRetrieval.java | 19 +++ .../listener/MessageReceiveListener.java | 6 +- .../timer/task/FastMsgRemoveTimer.java | 3 +- .../com/fpghoti/biscuit/util/ChatFilter.java | 157 ++++++++++++++---- .../java/com/fpghoti/biscuit/util/Util.java | 9 + src/main/resources/config.properties | 25 ++- 16 files changed, 331 insertions(+), 79 deletions(-) create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 src/main/java/com/fpghoti/biscuit/commands/CustomCommand.java delete mode 100644 src/main/java/com/fpghoti/biscuit/commands/client/ChnameCommand.java diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..4824b80 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index fa715cd..e83832a 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.fpghoti Biscuit - 1.2.2 + 1.3 src/main/java @@ -17,6 +17,7 @@ maven-compiler-plugin 3.5.1 + UTF-8 1.8 1.8 @@ -25,6 +26,7 @@ maven-jar-plugin 2.4 + UTF-8 com.fpghoti.biscuit.Main @@ -42,6 +44,7 @@ shade + UTF-8 true @@ -74,6 +77,10 @@ soluvas-public-thirdparty http://nexus.bippo.co.id/nexus/content/repositories/soluvas-public-thirdparty/ + + jitpack.io + https://jitpack.io + @@ -214,5 +221,9 @@ compile + + UTF-8 + UTF-8 + diff --git a/pom.xml b/pom.xml index 992ba04..acfbbbd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.fpghoti Biscuit - 1.2.3 + 1.3 src/main/java @@ -19,6 +19,7 @@ maven-compiler-plugin 3.5.1 + UTF-8 1.8 1.8 @@ -28,6 +29,7 @@ maven-jar-plugin 2.4 + UTF-8 com.fpghoti.biscuit.Main @@ -46,6 +48,7 @@ shade + UTF-8 true @@ -53,6 +56,10 @@ + + UTF-8 + UTF-8 + spigot-repo @@ -78,8 +85,17 @@ false + + jitpack.io + https://jitpack.io + + + com.github.CrabMustard + emoji-java + v5.1.1-fixed + org.apache.commons commons-configuration2 diff --git a/src/main/java/com/fpghoti/biscuit/Main.java b/src/main/java/com/fpghoti/biscuit/Main.java index 25b848f..32f1c5b 100644 --- a/src/main/java/com/fpghoti/biscuit/Main.java +++ b/src/main/java/com/fpghoti/biscuit/Main.java @@ -10,7 +10,6 @@ import com.fpghoti.biscuit.commands.BaseCommand; import com.fpghoti.biscuit.commands.CommandListener; import com.fpghoti.biscuit.commands.client.AddCommand; import com.fpghoti.biscuit.commands.client.ChanIDCommand; -import com.fpghoti.biscuit.commands.client.ChnameCommand; import com.fpghoti.biscuit.commands.client.DivideCommand; import com.fpghoti.biscuit.commands.client.ToggleRoleCommand; import com.fpghoti.biscuit.commands.client.HelpCommand; @@ -97,7 +96,6 @@ public class Main { commands.add(new RecentSpammersCommand()); commands.add(new ChanIDCommand()); commands.add(new UIDCommand()); - commands.add(new ChnameCommand()); commands.add(new ToggleRoleCommand()); commands.add(new SquareRootCommand()); commands.add(new AddCommand()); diff --git a/src/main/java/com/fpghoti/biscuit/commands/BaseCommand.java b/src/main/java/com/fpghoti/biscuit/commands/BaseCommand.java index 7b3bf8c..94010cd 100644 --- a/src/main/java/com/fpghoti/biscuit/commands/BaseCommand.java +++ b/src/main/java/com/fpghoti/biscuit/commands/BaseCommand.java @@ -13,6 +13,12 @@ public abstract class BaseCommand{ protected List identifiers; protected List notes; + public BaseCommand(String name, String description, String usage) { + this.name = name; + this.description = description; + this.usage = usage; + } + public BaseCommand() { this.identifiers = new ArrayList(); this.notes = new ArrayList(); diff --git a/src/main/java/com/fpghoti/biscuit/commands/CommandManager.java b/src/main/java/com/fpghoti/biscuit/commands/CommandManager.java index 2524185..6712f71 100644 --- a/src/main/java/com/fpghoti/biscuit/commands/CommandManager.java +++ b/src/main/java/com/fpghoti/biscuit/commands/CommandManager.java @@ -6,6 +6,8 @@ import java.util.List; import com.fpghoti.biscuit.Biscuit; import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.config.PropertiesRetrieval; +import com.fpghoti.biscuit.util.PermUtil; +import com.fpghoti.biscuit.util.Util; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; @@ -33,6 +35,18 @@ public class CommandManager { } public boolean dispatch(MessageReceivedEvent e, String label, String[] args) { + + if(e != null) { + + if(Util.contains(PropertiesRetrieval.disabledCommands(), label)) { + return false; + } + if(!PermUtil.isAdmin(e.getMember()) && Util.contains(PropertiesRetrieval.disabledUserCommands(), label)) { + return false; + } + + } + String input = label + " "; for (String s : args) { input += s + " "; @@ -68,6 +82,17 @@ public class CommandManager { ((ConsoleCommand)match).execute(trimmedArgs); } } + }else { + if(Util.contains(PropertiesRetrieval.getCustomCmds(), label)) { + CustomCommand cc = new CustomCommand(label); + if(args.length >= 1) { + commandReply(e, "``Command:" + " " + cc.getName() + "``"); + commandReply(e, "``Description:" + " " + cc.getDescription() + "``"); + commandReply(e, "``Usage:" + " " + cc.getUsage() + "``"); + }else { + commandReply(e, CustomCommand.fixPlaceholders(e, cc.getMessage())); + } + } } return true; } diff --git a/src/main/java/com/fpghoti/biscuit/commands/CustomCommand.java b/src/main/java/com/fpghoti/biscuit/commands/CustomCommand.java new file mode 100644 index 0000000..c851a06 --- /dev/null +++ b/src/main/java/com/fpghoti/biscuit/commands/CustomCommand.java @@ -0,0 +1,53 @@ +package com.fpghoti.biscuit.commands; + +import com.fpghoti.biscuit.config.ConfigRetrieval; +import com.fpghoti.biscuit.config.PropertiesRetrieval; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; + +public class CustomCommand extends BaseCommand { + + public static String fixPlaceholders(MessageReceivedEvent event, String msg) { + msg = msg.replace("", event.getAuthor().getAsMention()); + return msg; + } + + private String name; + + public CustomCommand(String name) { + this.name = name; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getUsage() { + return PropertiesRetrieval.getCommandSignifier() + name; + } + + @Override + public String getDescription() { + String desc = ConfigRetrieval.getFromConfig("cc-" + name + "-description"); + if(desc == null) { + return "null"; + } + return desc; + } + + @Override + public CommandType getType() { + return null; + } + + public String getMessage() { + String msg = ConfigRetrieval.getFromConfig("cc-" + name + "-message"); + if(msg == null) { + return "null"; + } + return msg; + } + +} diff --git a/src/main/java/com/fpghoti/biscuit/commands/client/ChnameCommand.java b/src/main/java/com/fpghoti/biscuit/commands/client/ChnameCommand.java deleted file mode 100644 index 4fc632c..0000000 --- a/src/main/java/com/fpghoti/biscuit/commands/client/ChnameCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.fpghoti.biscuit.commands.client; - -import com.fpghoti.biscuit.Biscuit; -import com.fpghoti.biscuit.Main; -import com.fpghoti.biscuit.commands.ClientCommand; -import com.fpghoti.biscuit.config.PropertiesRetrieval; -import com.fpghoti.biscuit.util.PermUtil; - -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; - -public class ChnameCommand extends ClientCommand{ - - public ChnameCommand() { - name = "Channel Name"; - description = "Retrieves the channel name."; - usage = PropertiesRetrieval.getCommandSignifier() + "chname"; - minArgs = 0; - maxArgs = 0; - identifiers.add("chname"); - } - - @Override - public void execute(String[] args, MessageReceivedEvent event) { - Biscuit b = Main.getBiscuit(); - b.log(event.getAuthor().getName() + " issued a command: -chname"); - if(PermUtil.isMod(event.getMember()) || PermUtil.canMute(event.getMember())) { - event.getTextChannel().sendMessage("DEBUG: " + event.getTextChannel().getName()).queue(); - } - } - -} diff --git a/src/main/java/com/fpghoti/biscuit/commands/client/HelpCommand.java b/src/main/java/com/fpghoti/biscuit/commands/client/HelpCommand.java index cea7f62..caaa4bd 100644 --- a/src/main/java/com/fpghoti/biscuit/commands/client/HelpCommand.java +++ b/src/main/java/com/fpghoti/biscuit/commands/client/HelpCommand.java @@ -1,11 +1,13 @@ package com.fpghoti.biscuit.commands.client; +import java.util.ArrayList; import java.util.List; import com.fpghoti.biscuit.Biscuit; import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.commands.BaseCommand; import com.fpghoti.biscuit.commands.ClientCommand; +import com.fpghoti.biscuit.commands.CustomCommand; import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.util.Util; @@ -14,17 +16,17 @@ import net.dv8tion.jda.api.events.message.MessageReceivedEvent; public class HelpCommand extends ClientCommand { public HelpCommand() { - name = "Help"; - description = "Pulls up help menu"; - usage = PropertiesRetrieval.getCommandSignifier() + "help [Page #]"; - minArgs = 0; - maxArgs = 1; - identifiers.add("help"); - } + name = "Help"; + description = "Pulls up help menu"; + usage = PropertiesRetrieval.getCommandSignifier() + "help [Page #]"; + minArgs = 0; + maxArgs = 1; + identifiers.add("help"); + } @Override public void execute(String[] args, MessageReceivedEvent event) { - + Biscuit biscuit = Main.getBiscuit(); int pg = 1; @@ -36,13 +38,27 @@ public class HelpCommand extends ClientCommand { } } - List commands = biscuit.getCommandManager().getCommands(); + List commands = new ArrayList(); + String[] ccs = PropertiesRetrieval.getCustomCmds(); + for(String s : ccs) { + if(!Util.contains(PropertiesRetrieval.disabledCommands(), s)) { + CustomCommand cc = new CustomCommand(s); + commands.add(cc); + } + } + for(BaseCommand bc : biscuit.getCommandManager().getCommands()) { + String bclabel = bc.getUsage().split(" ")[0]; + if(!Util.contains(PropertiesRetrieval.disabledCommands(), bclabel.replace(PropertiesRetrieval.getCommandSignifier(), ""))) { + commands.add(bc); + } + } int pageCount = (int) Math.ceil((double) commands.size() / 8); if (pg > pageCount) { pg = pageCount; } - + + event.getTextChannel().sendMessage("**Use " + PropertiesRetrieval.getCommandSignifier() + "help [Page #] to navigate the different pages.**").queue(); event.getTextChannel().sendMessage("[" + Integer.toString(pg) + "/" + Integer.toString(pageCount) + "] **Bot Commands:**").queue(); String msg = ""; for (int i = 0; i < 8; i++) { diff --git a/src/main/java/com/fpghoti/biscuit/config/ConfigRetrieval.java b/src/main/java/com/fpghoti/biscuit/config/ConfigRetrieval.java index c26088e..e502d9c 100644 --- a/src/main/java/com/fpghoti/biscuit/config/ConfigRetrieval.java +++ b/src/main/java/com/fpghoti/biscuit/config/ConfigRetrieval.java @@ -90,6 +90,11 @@ public class ConfigRetrieval { added = addProperty("Captcha-Reward-Role", "cleared", prop, added); added = addProperty("No-Captcha-Kick", "false", prop, added); added = addProperty("No-Captcha-Kick-Time", "10", prop, added); + added = addProperty("Block-Unicode-Emotes", "baby,snake,squid", prop, added); + added = addProperty("Block-Custom-Emotes", "badfish,fix,bigleaf", prop, added); + added = addProperty("Custom-Command-Names", "", prop, added); + added = addProperty("DisabledCommands", "cmd1,cmd2,cmd3", prop, added); + added = addProperty("DisabledUserCommands", "cmd4,cmd5,cmd6", prop, added); return added; } diff --git a/src/main/java/com/fpghoti/biscuit/config/PropertiesRetrieval.java b/src/main/java/com/fpghoti/biscuit/config/PropertiesRetrieval.java index 2e796d6..ade95bd 100644 --- a/src/main/java/com/fpghoti/biscuit/config/PropertiesRetrieval.java +++ b/src/main/java/com/fpghoti/biscuit/config/PropertiesRetrieval.java @@ -72,5 +72,24 @@ public class PropertiesRetrieval { public static String[] getToggleRoles(){ return ConfigRetrieval.getFromConfig("ToggleRoles").replace(" ", "").split(","); } + + public static String[] blockedUnicodeEmotes(){ + return ConfigRetrieval.getFromConfig("Block-Unicode-Emotes").replace(" ", "").split(","); + } + public static String[] blockedCustomEmotes(){ + return ConfigRetrieval.getFromConfig("Block-Custom-Emotes").replace(" ", "").split(","); + } + + public static String[] getCustomCmds(){ + return ConfigRetrieval.getFromConfig("Custom-Command-Names").replace(" ", "").split(","); + } + + public static String[] disabledCommands(){ + return ConfigRetrieval.getFromConfig("DisabledCommands").replace(" ", "").split(","); + } + + public static String[] disabledUserCommands(){ + return ConfigRetrieval.getFromConfig("DisabledUserCommands").replace(" ", "").split(","); + } } diff --git a/src/main/java/com/fpghoti/biscuit/listener/MessageReceiveListener.java b/src/main/java/com/fpghoti/biscuit/listener/MessageReceiveListener.java index ea81d91..e7acd97 100644 --- a/src/main/java/com/fpghoti/biscuit/listener/MessageReceiveListener.java +++ b/src/main/java/com/fpghoti/biscuit/listener/MessageReceiveListener.java @@ -31,14 +31,12 @@ public class MessageReceiveListener extends ListenerAdapter{ } } - if(event.getAuthor().isBot() && event.getMessage().getContentRaw().contains("This message contains words not appropriate for this channel.") || (ChatFilter.isNaughty(event.getMessage().getContentDisplay()))){ + if(event.getAuthor().isBot() && event.getMessage().getContentRaw().contains("This message contains words not appropriate for this channel.") || (ChatFilter.filter(event))){ MessageQueue.removemessages.put(event.getMessage().getId(), event.getTextChannel()); } //staff channels do not need filtering, as the filter could actually be a hinderance - if(!event.getChannel().getName().toLowerCase().contains("staff") && ChatFilter.isNaughty(event.getMessage().getContentDisplay())){ - String text = event.getMessage().getContentDisplay(); - log.info("Removed Msg - REASON NAUGHTY WORD(S) - by " + event.getAuthor().getName() + ": " + text); + if(!event.getChannel().getName().toLowerCase().contains("staff") && ChatFilter.filter(event, false)){ event.getTextChannel().sendMessage(event.getAuthor().getAsMention() + " This message contains words not appropriate for this channel.").complete(); MessageQueue.fastremovemessages.put(event.getMessage().getId(), event.getTextChannel()); } diff --git a/src/main/java/com/fpghoti/biscuit/timer/task/FastMsgRemoveTimer.java b/src/main/java/com/fpghoti/biscuit/timer/task/FastMsgRemoveTimer.java index 68c87f0..68fb2fc 100644 --- a/src/main/java/com/fpghoti/biscuit/timer/task/FastMsgRemoveTimer.java +++ b/src/main/java/com/fpghoti/biscuit/timer/task/FastMsgRemoveTimer.java @@ -9,7 +9,8 @@ public class FastMsgRemoveTimer extends BiscuitTimer{ public FastMsgRemoveTimer(){ delay = (long) 0; - period = (long) 1*1000; + //period = (long) 1*1000; + period = (long) 250; } public void run() { diff --git a/src/main/java/com/fpghoti/biscuit/util/ChatFilter.java b/src/main/java/com/fpghoti/biscuit/util/ChatFilter.java index f9c81cc..79ecdf1 100644 --- a/src/main/java/com/fpghoti/biscuit/util/ChatFilter.java +++ b/src/main/java/com/fpghoti/biscuit/util/ChatFilter.java @@ -1,47 +1,148 @@ package com.fpghoti.biscuit.util; +import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.config.PropertiesRetrieval; +import com.vdurmont.emoji.EmojiParser; + +import net.dv8tion.jda.api.entities.Emote; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; public class ChatFilter { - //CHAT FILTER + public static String[] suffixes = {"ing","s","ed","er","es","y","ers","ier","iest","ies","ys"}; - public static Boolean isNaughty(String sentence){ + public static boolean filter(MessageReceivedEvent event) { + return filter(event, true); + } + + public static boolean filter(MessageReceivedEvent event, boolean silent) { + String msg = event.getMessage().getContentDisplay(); + + //Message removal priority occurs in this order + + boolean found = false; + + //Naughty word check + boolean filter = (filter(msg)); + if(filter) { + if(!silent) { + Main.log.info("Removed Msg - REASON NAUGHTY WORD(S) - by " + event.getAuthor().getName() + ": " + msg); + } + return true; + } + + //Custom emote check + for(Emote e : event.getMessage().getEmotes()) { + String name = e.getName(); + + for(String s : PropertiesRetrieval.blockedCustomEmotes()) { + if(s.equals(name)) { + found = true; + } + } + } + + if(found) { + if(!silent) { + Main.log.info("Removed Msg - REASON BLOCKED CUSTOM EMOTE(S) - by " + event.getAuthor().getName() + ": " + msg); + } + return true; + } + + //Unicode emote check + for(String u : EmojiParser.extractEmojis(msg)) { + u = EmojiParser.parseToAliases(u).replace(":",""); + for(String s : PropertiesRetrieval.blockedUnicodeEmotes()) { + if(s.equalsIgnoreCase(u)) { + found = true; + } + } + } + + if(found) { + if(!silent) { + Main.log.info("Removed Msg - REASON BLOCKED UNICODE EMOTE(S) - by " + event.getAuthor().getName() + ": " + msg); + } + return true; + } + + return false; + } + + public static boolean filter(String sentence){ for(String s : sentence.split(" ")){ - if(isNaughtyWord(s)){ + if(filterWord(s)){ return true; } } return false; } - public static Boolean isNaughtyWord(String word){ - String wordp = ""; - String word2 = word.toLowerCase(); - if(word2.length() >= 2 && word2.charAt(word2.length() -1) == '!'){ - for(int i = 0; i < word2.length() -1; i++ ){ - wordp += word2.charAt(i); - } - word2 = wordp; + public static boolean filterWord(String word) { + String[] match = findMatchPair(word); + if(match != null) { + return true; } - wordp = ""; - for(int i = 0; i < word2.length(); i++ ){ - if(word2.charAt(i) != '!'){ - wordp += word2.charAt(i); - }else{ - wordp += 'i'; - } - } - word2 = wordp; - word2 = word2.replaceAll("\\p{Punct}+", "").replaceAll("1", "i").replaceAll("5", "s").replaceAll("6", "g").replaceAll("3", "e"); - String[] list = PropertiesRetrieval.getNaughtyWords(); - for(String item : list){ - if(word.equalsIgnoreCase(item) || word.equalsIgnoreCase(item + "s")){ - return true; - } - } - word2 = null; return false; } + public static String findMatch(String word) { + String[] match = findMatchPair(word); + if(match == null || match[0] == null) { + return null; + } + return match[0]; + } + + public static String[] findMatchPair(String word) { + String cleaned = ""; + word = word.toLowerCase(); + if(word.length() >= 2 && word.charAt(word.length() -1) == '!'){ + for(int i = 0; i < word.length() -1; i++ ){ + cleaned += word.charAt(i); + } + word = cleaned; + } + cleaned = ""; + for(int i = 0; i < word.length(); i++ ){ + if(word.charAt(i) != '!'){ + cleaned += word.charAt(i); + }else{ + cleaned += 'i'; + } + } + cleaned = cleaned.replace(" ", ""); + cleaned = cleaned.replaceAll("\\p{Punct}+", "").replaceAll("1", "i").replaceAll("5", "s").replaceAll("6", "g").replaceAll("3", "e").replaceAll("0", "o").replaceAll("9", "g").replaceAll("8", "b"); + if(cleaned.equals("")) { + return null; + } + String[] wordSuf = {null,null}; + for(String item : PropertiesRetrieval.getNaughtyWords()) { + if(cleaned.equalsIgnoreCase(item)){ + wordSuf[0] = item; + return wordSuf; + } + for(String suffix : suffixes) { + if(cleaned.equalsIgnoreCase(item + suffix)){ + wordSuf[0] = item; + wordSuf[1] = suffix; + return wordSuf; + } + String last = item.substring(item.length() - 1); + if(cleaned.equalsIgnoreCase(item + last + suffix)){ + wordSuf[0] = item; + wordSuf[1] = last + suffix; + return wordSuf; + } + if(cleaned.equalsIgnoreCase(item + last + last + suffix)){ + wordSuf[0] = item; + wordSuf[1] = last + last + suffix; + return wordSuf; + } + } + + } + return null; + } + } diff --git a/src/main/java/com/fpghoti/biscuit/util/Util.java b/src/main/java/com/fpghoti/biscuit/util/Util.java index 805ff1a..7e037c5 100644 --- a/src/main/java/com/fpghoti/biscuit/util/Util.java +++ b/src/main/java/com/fpghoti/biscuit/util/Util.java @@ -31,6 +31,15 @@ public class Util { public static boolean isDigit(String s){ return s.matches("[0-9]+"); } + + public static boolean contains(String[] list, String s) { + for(String l : list) { + if(s.equals(l)) { + return true; + } + } + return false; + } public static boolean isDeciDigit(String s){ int i = 0; diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index 196f42b..45cee97 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -48,4 +48,27 @@ No-Captcha-Kick = false #Kick user after this number of minutes has passed without captcha clear #Due to the way the countdown works, the kick may not happen until at most one minute after -No-Captcha-Kick-Time = 10 \ No newline at end of file +No-Captcha-Kick-Time = 10 + +#Messages with these unicode emotes will be removed +Block-Unicode-Emotes = baby,snake,squid + +#Messages with these custom emotes will be removed +Block-Custom-Emotes = badfish,fix,bigleaf + +#Disable these commands for ALL users +DisabledCommands = cmd1,cmd2,cmd3 + +#Disabled these commands for normal users +DisabledUserCommands = cmd4,cmd5,cmd6 + +#List your custom commands here. This line will always generate blank. +#Example - Custom-Command-Names = hello,botcheck,apple +Custom-Command-Names = + +#Placeholder(s): +# - Mentions the sender +#Setting up custom commands works like this: +# +#cc-hello-message = Hello, ! +#cc-hello-description = Greets the sender. \ No newline at end of file