├── settings.gradle ├── src ├── resources │ └── config.xml └── java │ └── com │ └── scorchhost │ ├── Main.java │ ├── Discord.java │ └── Config.java ├── README.md └── examples └── configs └── KG └── config.xml /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'my-discord-bot' -------------------------------------------------------------------------------- /src/resources/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is just a test reply. 6 | 7 | 8 | 9 | LOLOLOLOL 10 | 11 | 12 | 13 | Tagging staff - 14 | 10 15 | 16 | 17 | 18 | funcTest 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/java/com/scorchhost/Main.java: -------------------------------------------------------------------------------- 1 | package com.scorchhost; 2 | 3 | import net.dv8tion.jda.api.JDABuilder; 4 | import net.dv8tion.jda.api.JDA; 5 | import net.dv8tion.jda.api.hooks.ListenerAdapter; 6 | import javax.security.auth.login.LoginException; 7 | 8 | public class Main 9 | { 10 | public static void main(String[] args) throws LoginException 11 | { 12 | String configFile; 13 | 14 | // Set config file. 15 | if (args.length > 0) 16 | { 17 | configFile = args[0]; 18 | } 19 | else 20 | { 21 | configFile = "config.xml"; 22 | } 23 | 24 | //Specify the token 25 | String sToken = ""; 26 | 27 | // Initialize JDA. 28 | JDA jda = new JDABuilder(sToken).build(); 29 | jda.addEventListener(new Discord(configFile)); 30 | } 31 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Discord Bot V2 2 | 3 | ## Description 4 | This is a simple Discord bot I made for fun in Java. It is currently used on KG's Discord server. It offers an easy way to create commands along with options like a cool down and the ability to execute a custom function. Everything is handled in an XML config file. You may specify the path to the config file via command-line (argument #1). 5 | 6 | ## JAR File 7 | There is currently no JAR file included. I've built one on my own, but since the Discord API token is hard-coded into the project, I cannot provide a JAR file. Feel free to use my project and compile your own JAR file. 8 | 9 | ## To Do 10 | * Have the Discord API token be handled in the config file. 11 | * Once the above task is done, include a JAR file. 12 | * Optimizations + better support. 13 | * Add custom functions. 14 | 15 | ## Run In Java Via JAR 16 | Here is the command line I use for my Linux server: 17 | 18 | ``` 19 | /usr/bin/java -jar /home/roy/my-discord-bot.jar "/etc/discordbot/config.xml" 20 | ``` 21 | 22 | The config file is located at `/etc/discordbot/config.xml` in this case. 23 | 24 | ## Credits 25 | * [Christian Deacon](https://www.linkedin.com/in/christian-deacon-902042186/) - Creator. -------------------------------------------------------------------------------- /examples/configs/KG/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | **Rules** 6 | 1. Please be respectful of others. 7 | 2. Please do not spam. 8 | 3. No Racism. 9 | 4. No NSFW content of any kind. 10 | 5. Memes MUST be dank. 11 | 6. No being rude to other players, or the staff. 12 | 7. If you have any issues with a player/staff member. Please let a higher up know. 13 | 8. No rape jokes or memes of any kind. 14 | 9. NO TALK OF POLITICS EVER. 15 | 10. No talk about religion. 16 | 10 17 | 18 | 19 | 20 | **Website** 21 | https://kyantiegaming.com/ 22 | 10 23 | 24 | 25 | 26 | **Servers** 27 | Garry's Mod Murder - 158.69.123.8:27019 28 | Garry's Mod Prop Hunt - 158.69.123.8:27018 29 | 10 30 | 31 | 32 | 33 | **Owners** 34 | - <@472444248747409420> 35 | 60 36 | 37 | 38 | 39 | **About** 40 | The KG Bot (V2) is a badass Discord bot developed in Java by <@196425012670889984> and <@472444248747409420>. Everything is configurable in an XML file. There is a continuous development to this bot to add new features along with improving the already-existing features. Feel free to message the KG Staff if you have a suggestion! 41 | 60 42 | 43 | 44 | 45 | kgv2Rules 46 | 10 47 | 48 | 49 | 50 | Christian and Angel are both noobs! 51 | 52 | 53 | 54 | This feature is currently a work-in-progress. <@196425012670889984> will be developing this feature into the bot. Expected release date is February 27th, 2019. We will provide updates as time goes on! 55 | 10 56 | 57 | 58 | 59 | **Member Application** 60 | Here is where you sign up to be a Member - https://kyantiegaming.com/showthread.php?tid=2 61 | 10 62 | 63 | 64 | 65 | **KG Murder Server Trello Board** 66 | https://trello.com/b/It4rAt5F/murder 67 | 10 68 | 69 | 70 | 71 | **Staff Report** 72 | https://kyantiegaming.com/showthread.php?tid=3 73 | 74 | **Report a Player** 75 | https://kyantiegaming.com/showthread.php?tid=4 76 | 10 77 | 78 | 79 | 80 | **A list of downloads for all of our servers** 81 | https://steamcommunity.com/sharedfiles/filedetails/?id=1586423114 82 | 10 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/java/com/scorchhost/Discord.java: -------------------------------------------------------------------------------- 1 | package com.scorchhost; 2 | 3 | import net.dv8tion.jda.api.events.message.MessageReceivedEvent; 4 | import net.dv8tion.jda.api.hooks.ListenerAdapter; 5 | 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.Timer; 10 | import java.util.TimerTask; 11 | 12 | public class Discord extends ListenerAdapter 13 | { 14 | protected Map coolDownList = new HashMap<>(); 15 | 16 | protected Config cfg; 17 | protected Map cmdsMap; 18 | 19 | public Discord(String configFile) 20 | { 21 | // Initialize the config and get the hash maps. 22 | this.cfg = new Config(configFile); 23 | this.cfg.initializeConfig(); 24 | this.cmdsMap = this.cfg.getCmdsMap(); 25 | } 26 | 27 | public void onMessageReceived(MessageReceivedEvent event) 28 | { 29 | // Check if owner is a bot. 30 | if (event.getAuthor().isBot()) 31 | { 32 | return; 33 | } 34 | 35 | // Check if user is on cooldown. 36 | if (coolDownList.get(event.getAuthor().getIdLong()) != null) 37 | { 38 | if (coolDownList.get(event.getAuthor().getIdLong()).booleanValue()) 39 | { 40 | return; 41 | } 42 | } 43 | 44 | cmdTemplate temp = (cmdTemplate) this.cmdsMap.get(event.getMessage().getContentRaw()); 45 | 46 | // Check to see if it's a valid command. 47 | if (temp != null) 48 | { 49 | // Send message. 50 | if (!temp.getReply().toString().isEmpty()) 51 | { 52 | event.getChannel().sendMessage(temp.getReply().toString()).queue(); 53 | } 54 | 55 | //System.out.println((int) temp.getCoolDown()); 56 | 57 | // Set cool down if any. 58 | if ((int) temp.getCoolDown() > 0) 59 | { 60 | // Set user to cooldown. 61 | coolDownList.put(event.getAuthor().getIdLong(), true); 62 | 63 | // Create Timer Task. 64 | TimerTask tt = new TimerTask() 65 | { 66 | public void run() 67 | { 68 | coolDownList.put(event.getAuthor().getIdLong(), false); 69 | //System.out.println("Reset user for cooldown " + event.getAuthor().getIdLong()); 70 | } 71 | }; 72 | 73 | // Create timer. 74 | Timer timer = new Timer(); 75 | 76 | timer.schedule(tt, (int) temp.getCoolDown() * 1000); 77 | } 78 | 79 | // Execute function if any. 80 | if (!temp.getFunc().toString().isEmpty()) 81 | { 82 | //Discord main = new Discord(null); 83 | 84 | try 85 | { 86 | java.lang.reflect.Method Method = getClass().getDeclaredMethod(temp.getFunc().toString(), MessageReceivedEvent.class); 87 | Method.invoke(this, event); 88 | } 89 | catch (NoSuchMethodException e) 90 | { 91 | System.out.println(temp.getFunc().toString() + " doesn't exist?"); 92 | e.printStackTrace(); 93 | } 94 | catch (IllegalAccessException e) 95 | { 96 | e.printStackTrace(); 97 | } 98 | catch (InvocationTargetException e) 99 | { 100 | e.printStackTrace(); 101 | } 102 | } 103 | } 104 | } 105 | 106 | public void funcTest(MessageReceivedEvent event) 107 | { 108 | System.out.println("Message function sent from " + event.getAuthor().getAsTag()); 109 | } 110 | } -------------------------------------------------------------------------------- /src/java/com/scorchhost/Config.java: -------------------------------------------------------------------------------- 1 | package com.scorchhost; 2 | 3 | import java.io.File; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import javax.xml.parsers.DocumentBuilderFactory; 7 | import javax.xml.parsers.DocumentBuilder; 8 | import org.w3c.dom.Document; 9 | import org.w3c.dom.NodeList; 10 | import org.w3c.dom.Element; 11 | 12 | class cmdTemplate 13 | { 14 | Reply reply; 15 | Func func; 16 | CoolDown coolDown; 17 | 18 | public cmdTemplate(Reply r, Func f, CoolDown cd) 19 | { 20 | this.reply = r; 21 | this.func = f; 22 | this.coolDown = cd; 23 | } 24 | 25 | public Reply getReply() 26 | { 27 | return this.reply; 28 | } 29 | 30 | public Func getFunc() 31 | { 32 | return this.func; 33 | } 34 | 35 | public CoolDown getCoolDown() 36 | { 37 | return this.coolDown; 38 | } 39 | 40 | public void setReply(Reply t) 41 | { 42 | this.reply = t; 43 | } 44 | 45 | public void setFunc(Func t) 46 | { 47 | this.func = t; 48 | } 49 | 50 | public void setCoolDown(CoolDown t) 51 | { 52 | this.coolDown = t; 53 | } 54 | } 55 | 56 | public class Config 57 | { 58 | protected Document doc = null; 59 | 60 | // Create the hash maps. 61 | protected Map> cmdsMap = new HashMap<>(); 62 | protected Map configMap = new HashMap<>(); 63 | 64 | public Config(String sConfigFile) 65 | { 66 | // Build the config. 67 | try 68 | { 69 | // Read the config file. 70 | File configFile = new File(sConfigFile); 71 | DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 72 | DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 73 | this.doc = dBuilder.parse(configFile); 74 | 75 | this.doc.getDocumentElement().normalize(); 76 | } 77 | catch (Exception e) 78 | { 79 | e.printStackTrace(); 80 | } 81 | 82 | // Map all the configs. 83 | this.initializeConfig(); 84 | } 85 | 86 | public Document getDoc() 87 | { 88 | return this.doc; 89 | } 90 | 91 | public Map getCmdsMap() 92 | { 93 | return this.cmdsMap; 94 | } 95 | 96 | public Map getConfigMap() 97 | { 98 | return this.configMap; 99 | } 100 | 101 | public void initializeConfig() 102 | { 103 | NodeList cmds = this.doc.getElementsByTagName("Commands").item(0).getChildNodes(); 104 | 105 | for (int i = 0; i < cmds.getLength(); i++) 106 | { 107 | // We've determine if it's a command. 108 | if (cmds.item(i).getNodeName().equals("command")) 109 | { 110 | Element cmdEle = (Element) cmds.item(i); 111 | String replyWith = ""; 112 | String func = ""; 113 | int cooldown = 0; 114 | 115 | NodeList details = cmds.item(i).getChildNodes(); 116 | 117 | // Gain the details. 118 | for (int o = 0; o < details.getLength(); o++) 119 | { 120 | if (details.item(o).getNodeName().equals("reply")) 121 | { 122 | replyWith = details.item(o).getTextContent(); 123 | } 124 | else if (details.item(o).getNodeName().equals("function")) 125 | { 126 | func = details.item(o).getTextContent(); 127 | } 128 | else if (details.item(o).getNodeName().equals("cooldown")) 129 | { 130 | cooldown = Integer.parseInt(details.item(o).getTextContent()); 131 | } 132 | } 133 | 134 | this.cmdsMap.putIfAbsent(cmdEle.getAttribute("name"), new cmdTemplate<>(replyWith, func, cooldown)); 135 | } 136 | } 137 | } 138 | } --------------------------------------------------------------------------------