diff --git a/Dockerfile b/Dockerfile index 19776ae..f49d878 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ WORKDIR /app RUN apt update && apt install -y zabbix-sender && rm -rf /var/lib/apt/lists/* -COPY --from=builder /app/build/libs/JdrBot-all.jar /app/JdrBot.jar +COPY --from=builder /app/build/libs/JdrBot.jar /app/JdrBot.jar COPY start.sh /app CMD ["/bin/bash","./start.sh"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index 367701a..0a33f79 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,12 @@ application { mainClassName = 'fr.Skydust.JdrBot.JdrBot' } +shadowJar { + archiveFileName = "${project.name}.jar" +} + jar { manifest { - attributes 'Main-Class': 'fr.Skydust.JdrBot.JdrBot' + attributes 'Main-Class': 'fr.Skydust.JdrBot.JdrBot', 'Implementation-Version': version } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..37575ea --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +version=4.1 \ No newline at end of file diff --git a/src/main/java/fr/Skydust/JdrBot/JdrBot.java b/src/main/java/fr/Skydust/JdrBot/JdrBot.java index 6157512..d0dc5c6 100755 --- a/src/main/java/fr/Skydust/JdrBot/JdrBot.java +++ b/src/main/java/fr/Skydust/JdrBot/JdrBot.java @@ -1,54 +1,26 @@ package fr.Skydust.JdrBot; -import java.lang.reflect.InvocationTargetException; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; import java.util.Timer; -import fr.Skydust.JdrBot.bases.command.Command; -import fr.Skydust.JdrBot.bases.command.CommandSpec; import fr.Skydust.JdrBot.tasks.HeartbeatTask; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Activity; import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.utils.cache.CacheFlag; -import org.reflections.Reflections; +import fr.Skydust.JdrBot.bases.CommandManager.CommandsManager; public class JdrBot { - public static String Version = "4.0"; + public static String Version = JdrBot.class.getPackage().getImplementationVersion(); public static JDA jda; public static LocalDateTime basedate; - public static List commandList; - - public static String startcmdchar = "!|:"; public static boolean debugMode = false; public static void main(String[] args) { - for (int i=0;i(); - Reflections reflections = new Reflections("fr.Skydust.JdrBot.cmds"); - Set> annotated = reflections.getTypesAnnotatedWith(CommandSpec.class); + private static void parseArgs(String[] args) { + for (int i=0;i command: annotated) { - try { - Command cmd = (Command) command.getDeclaredConstructor().newInstance(); - commandList.add(cmd); + switch (currentArgument) { + case "--heartbeat" -> { + if (i == args.length - 1) { // Check for an argument after heartbeat + System.out.println("USAGE: --heartbeat [Command({ping})]"); + return; // Quits the program + } + //Example: "zabbix_sender -z localhost -s \"Lustricru\" -k discordBots.potatos.ping -o {ping}" + String command = args[i + 1]; - System.out.println("Registered command "+ cmd.cmdName); - } catch (InstantiationException | NoSuchMethodException | InvocationTargetException | - IllegalAccessException e) { - throw new RuntimeException(e); + //Skip next arg + i++; + + new Timer().scheduleAtFixedRate(new HeartbeatTask(command), 1000, 60000); + System.out.println("Registered Heartbeat Command: " + command); + } + case "--debug" -> { + debugMode = true; + System.out.println("Warning: the bot is in debug mode"); + } } - } + } } } diff --git a/src/main/java/fr/Skydust/JdrBot/JdrBotListener.java b/src/main/java/fr/Skydust/JdrBot/JdrBotListener.java index 6b05da2..e24abd3 100755 --- a/src/main/java/fr/Skydust/JdrBot/JdrBotListener.java +++ b/src/main/java/fr/Skydust/JdrBot/JdrBotListener.java @@ -1,45 +1,22 @@ package fr.Skydust.JdrBot; -import fr.Skydust.JdrBot.bases.command.Command; import fr.Skydust.JdrBot.cmds.LastTimeOnline; import fr.Skydust.JdrBot.cmds.playmusic.StopMusic; import fr.Skydust.JdrBot.menu.MenuSystem; import fr.Skydust.JdrBot.tasks.HeartbeatTask; import net.dv8tion.jda.api.events.GatewayPingEvent; import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; import net.dv8tion.jda.api.events.user.update.UserUpdateOnlineStatusEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.jetbrains.annotations.NotNull; public class JdrBotListener extends ListenerAdapter { - @Override - public void onMessageReceived(MessageReceivedEvent e) { - // IF it doesn't start with the startcmdchar, ignore for optimization - if (!e.getMessage().getContentRaw().matches("^("+ JdrBot.startcmdchar+").*$") || e.getMessage().getAuthor().isBot()) - return; - - // Go through all cmds and call the one corresponding - for (Command cmd : JdrBot.commandList) { - if (isACommand(e.getMessage().getContentRaw(), cmd.cmdName)) { - cmd.call(e); - return; - } - } - - if (isACommand(e.getMessage().getContentRaw(), "yay")) - { - e.getChannel().sendMessage("Bien joue! Tu as su surpasse toutes les epreuves pour en arriver la! Woo !").queue(); - } - } - /* LastTimeOnline listener */ @Override public void onUserUpdateOnlineStatus(@NotNull UserUpdateOnlineStatusEvent e) { LastTimeOnline.onUserUpdateOnlineStatus(e); } - /* Empty voice channel listener */ @Override public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent e) { @@ -51,8 +28,4 @@ public class JdrBotListener extends ListenerAdapter { /* Heartbeat command listener */ @Override public void onGatewayPing(@NotNull GatewayPingEvent e) { HeartbeatTask.HeartbeatUpdateEvent(e); } - - public boolean isACommand(String message, String cmd) { - return message.matches("^("+ JdrBot.startcmdchar +")("+ cmd +")( .*|)$"); - } } \ No newline at end of file diff --git a/src/main/java/fr/Skydust/JdrBot/bases/CommandManager/CommandsManager.java b/src/main/java/fr/Skydust/JdrBot/bases/CommandManager/CommandsManager.java new file mode 100644 index 0000000..eafb13c --- /dev/null +++ b/src/main/java/fr/Skydust/JdrBot/bases/CommandManager/CommandsManager.java @@ -0,0 +1,113 @@ +package fr.Skydust.JdrBot.bases.CommandManager; + +import fr.Skydust.JdrBot.bases.command.Command; +import fr.Skydust.JdrBot.bases.command.CommandSpec; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import org.reflections.Reflections; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class CommandsManager { + private static List commandList; + + private static String startCmdChar = ""; + + /** + * Retrieves the main package name from the stacktrace. + * @return The application's root package name. + */ + public static String getMainClassPackageName() + { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + if (trace.length > 0) { + String mainClassName = trace[trace.length - 1].getClassName(); + return mainClassName.split("\\.")[0]; + } + return null; + } + + /** + * Finds every class annotated with CommandSpec and registers them as a command. + * @param jda The instance to register commands for. + * @param startChar The regex to use for the start character. + */ + public static void registerCommands(JDA jda, String startChar) { + if(commandList != null) + throw new RuntimeException("Tried to call registerCommands twice !"); + + if(startChar == null || startChar.isEmpty()) + throw new RuntimeException("The starting character of the bot cannot be empty !"); + + String packageName = getMainClassPackageName(); + if(packageName == null || packageName.isEmpty()) + throw new RuntimeException("Could not determine the main package name."); + + commandList = new ArrayList(); + startCmdChar = startChar; + + Reflections reflections = new Reflections(packageName); + Set> annotated = reflections.getTypesAnnotatedWith(CommandSpec.class); + + for (Class command: annotated) { + try { + Command cmd = (Command) command.getDeclaredConstructor().newInstance(); + commandList.add(cmd); + + System.out.println("Registered command "+ cmd.cmdName); + } catch (InstantiationException | NoSuchMethodException | InvocationTargetException | + IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + jda.addEventListener(new CommandsManagerListener()); + } + + /** + * Retrieve the command list. + * @return A list of commands. + */ + public static List getCommandList() { + return commandList; + } + + /** + * Get the start character of commands. + * @return A regex containing every cmd chars. + */ + public static String getCmdChar() { + return startCmdChar; + } + + /** + * Goes through the command list and runs it if it exists. + * @param e The message received event from JDA. + */ + public static void runCmd(MessageReceivedEvent e) { + // IF it doesn't start with the startcmdchar, ignore for optimization + if (!e.getMessage().getContentRaw().matches("^("+startCmdChar+").*$")) + return; + + // Go through all cmds and call the one corresponding + for (Command cmd : CommandsManager.getCommandList()) { + if (isACommand(e.getMessage().getContentRaw(), cmd.cmdName)) { + cmd.call(e); + return; + } + } + } + + /** + * Returns if a message is a valid command. + * @param message The original raw message to test. + * @param cmd A specific command to check. + * @return A boolean if the command is valid. + */ + public static boolean isACommand(String message, String cmd) { + return message.matches("^("+ startCmdChar +")("+ cmd +")( .*|)$"); + } +} diff --git a/src/main/java/fr/Skydust/JdrBot/bases/CommandManager/CommandsManagerListener.java b/src/main/java/fr/Skydust/JdrBot/bases/CommandManager/CommandsManagerListener.java new file mode 100644 index 0000000..c735e76 --- /dev/null +++ b/src/main/java/fr/Skydust/JdrBot/bases/CommandManager/CommandsManagerListener.java @@ -0,0 +1,14 @@ +package fr.Skydust.JdrBot.bases.CommandManager; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class CommandsManagerListener extends ListenerAdapter { + @Override + public void onMessageReceived(MessageReceivedEvent e) { + if (e.getMessage().getAuthor().isBot()) + return; + + CommandsManager.runCmd(e); + } +} diff --git a/src/main/java/fr/Skydust/JdrBot/cmds/Aide.java b/src/main/java/fr/Skydust/JdrBot/cmds/Aide.java index e4e28c4..5262ac9 100755 --- a/src/main/java/fr/Skydust/JdrBot/cmds/Aide.java +++ b/src/main/java/fr/Skydust/JdrBot/cmds/Aide.java @@ -1,6 +1,6 @@ package fr.Skydust.JdrBot.cmds; -import fr.Skydust.JdrBot.JdrBot; +import fr.Skydust.JdrBot.bases.CommandManager.CommandsManager; import fr.Skydust.JdrBot.bases.command.Command; import fr.Skydust.JdrBot.bases.command.CommandSpec; import net.dv8tion.jda.api.EmbedBuilder; @@ -12,7 +12,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @CommandSpec( - name = "aide", + name = "aide|help", description = "Pour avoir de l'aide !" ) public class Aide extends Command { @@ -20,14 +20,17 @@ public class Aide extends Command { public void call(MessageReceivedEvent e) { StringBuilder sb = new StringBuilder(); - for (int i = 0; i < JdrBot.commandList.size(); i++) + for (int currentCommandCount = 0; currentCommandCount < CommandsManager.getCommandList().size(); currentCommandCount++) { - Command cmd = JdrBot.commandList.get(i); + Command cmd = CommandsManager.getCommandList().get(currentCommandCount); if(!cmd.hidden) { - sb.append("`"+cmd.cmdName - + ((cmd.cmdUsage.isEmpty()) ? "" : " "+cmd.cmdUsage) - +"` - *"+cmd.cmdDesc+"*" - + ((i != JdrBot.commandList.size()-1) ? "\n" : "")); + sb.append("`") + .append(cmd.cmdName) + .append((cmd.cmdUsage.isEmpty()) ? "" : " " + cmd.cmdUsage) + .append("` - *") + .append(cmd.cmdDesc) + .append("*") + .append((currentCommandCount != CommandsManager.getCommandList().size() - 1) ? "\n" : ""); } }