From 3faec0166c50f60c8ec4f3ae5a2d4262377a4c8f Mon Sep 17 00:00:00 2001 From: Jonas_Jones <91549607+J-onasJones@users.noreply.github.com> Date: Tue, 14 Nov 2023 20:14:45 +0100 Subject: [PATCH] Port to JDA and bug fixes --- build.gradle | 24 ++- .../yadcl/YetAnotherDiscordChatLink.java | 10 +- .../jonasjones/yadcl/config/ModConfigs.java | 6 +- .../jonasjones/yadcl/dcbot/DiscordBot.java | 145 +++++++++--------- .../yadcl/dcbot/MessageListener.java | 22 +++ 5 files changed, 125 insertions(+), 82 deletions(-) create mode 100644 src/main/java/dev/jonasjones/yadcl/dcbot/MessageListener.java diff --git a/build.gradle b/build.gradle index afbe524..4a73acd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,9 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + plugins { id 'fabric-loom' version '1.4-SNAPSHOT' id 'maven-publish' + id 'com.github.johnrengelman.shadow' version '8.1.1' } version = project.mod_version @@ -46,9 +49,28 @@ dependencies { // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" - implementation 'org.javacord:javacord:3.8.0' + implementation('net.dv8tion:JDA:5.0.0-beta.17') { + exclude module: 'opus-java' + } + shadow 'net.dv8tion:JDA:5.0.0-beta.17' } +tasks.withType(ShadowJar).configureEach { + it.minimize() + it.configurations = [project.configurations.shadow] + it.enableRelocation = true + it.relocationPrefix = "dev.jonasjones.yadacl.vendor" +} + + +remapJar { + from('LICENSE') // Include license + + inputFile.set shadowJar.archiveFile + dependsOn shadowJar +} + + processResources { inputs.property "version", project.version diff --git a/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java b/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java index ca7843c..ec089de 100644 --- a/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java +++ b/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java @@ -15,17 +15,17 @@ public class YetAnotherDiscordChatLink implements ModInitializer { public static final String MOD_ID = "yadcl"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public static DiscordBot discordBot; + public static final long startTime = System.currentTimeMillis(); + @Override public void onInitialize() { // Register the config ModConfigs.registerConfigs(); - // Set the token and channel id - DiscordBot.setToken(ModConfigs.TOKEN); - DiscordBot.setTargetChannelId(ModConfigs.CHANNEL_ID); - // Start the bot - DiscordBot.startBot(); + discordBot = new DiscordBot(ModConfigs.TOKEN, ModConfigs.CHANNEL_ID); + discordBot.startBot(); // send starting message sendToDiscord("Server is starting up."); } diff --git a/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java b/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java index 3afae6a..a301a3b 100644 --- a/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java +++ b/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java @@ -17,7 +17,7 @@ public class ModConfigs { //public static Boolean PLAYER_COMMAND_MSG; public static Boolean SERVER_START_STOP_MSG; - //public static String BOT_STATUS; + public static String BOT_STATUS; public static void registerConfigs() { configs = new ModConfigProvider(); @@ -37,7 +37,7 @@ public class ModConfigs { configs.addKeyValuePair(new Pair<>("bot.player_chat_msgs", true), "Should the bot send a message when a player sends a chat message"); //configs.addKeyValuePair(new Pair<>("bot.player_command_msgs", true), "Should the bot send a message when a player sends a command"); configs.addKeyValuePair(new Pair<>("bot.server_start_stop_msgs", true), "Should the bot send a message when the server starts or stops"); - //configs.addKeyValuePair(new Pair<>("bot.status", "PlayerCount"), "What status should the bot display [None, PlayerCount, IP, Uptime]"); + configs.addKeyValuePair(new Pair<>("bot.status", "PlayerCount"), "What status should the bot display [None, PlayerCount, IP, Uptime]"); } private static void assignConfigs() { @@ -49,7 +49,7 @@ public class ModConfigs { PLAYER_CHAT_MSG = CONFIG.getOrDefault("bot.player_chat_msgs", true); //PLAYER_COMMAND_MSG = CONFIG.getOrDefault("bot.player_command_msgs", true); SERVER_START_STOP_MSG = CONFIG.getOrDefault("bot.server_start_stop_msgs", true); - //BOT_STATUS = CONFIG.getOrDefault("bot.status", "PlayerCount"); + BOT_STATUS = CONFIG.getOrDefault("bot.status", "PlayerCount"); YetAnotherDiscordChatLink.LOGGER.info("All " + configs.getConfigsList().size() + " Configs have been set properly"); } diff --git a/src/main/java/dev/jonasjones/yadcl/dcbot/DiscordBot.java b/src/main/java/dev/jonasjones/yadcl/dcbot/DiscordBot.java index 2455088..18249de 100644 --- a/src/main/java/dev/jonasjones/yadcl/dcbot/DiscordBot.java +++ b/src/main/java/dev/jonasjones/yadcl/dcbot/DiscordBot.java @@ -1,54 +1,55 @@ package dev.jonasjones.yadcl.dcbot; import dev.jonasjones.yadcl.config.ModConfigs; -import lombok.Setter; +import lombok.Getter; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; +import net.dv8tion.jda.api.entities.Activity; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.requests.GatewayIntent; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.minecraft.server.MinecraftServer; -import net.minecraft.text.Text; -import org.javacord.api.DiscordApi; -import org.javacord.api.DiscordApiBuilder; -import org.javacord.api.entity.channel.TextChannel; import java.util.concurrent.TimeUnit; import static dev.jonasjones.yadcl.YetAnotherDiscordChatLink.LOGGER; +import static dev.jonasjones.yadcl.YetAnotherDiscordChatLink.startTime; -public class DiscordBot { - @Setter +public class DiscordBot extends ListenerAdapter { private static String token; - @Setter + @Getter private static String targetChannelId; - private static DiscordApi api; + private static JDA jda; + @Getter private static MinecraftServer minecraftServer; + @Getter private static Boolean isBotRunning = false; + public DiscordBot(String token, String targetChannelId) { + this.token = token; + this.targetChannelId = targetChannelId; + // Register Minecraft Server events + registerEvents(); + } + public static void startBot() { if (isBotRunning) { return; } try { - registerEvents(); - api = new DiscordApiBuilder().setToken(token).setAllIntents().login().join(); - api.addMessageCreateListener(event -> { - // Check if the message is from the specific channel by comparing channel IDs - if (String.valueOf(event.getChannel().getId()).equals(targetChannelId)) { - //check if message author is the bot - if (event.getMessageAuthor().isBotUser()) { - return; - } - String discordMessage = "[" + event.getMessageAuthor().getDisplayName() + "] " + event.getMessageContent(); - // Broadcast the message to Minecraft chat - // You can implement a method to broadcast messages to Minecraft players - minecraftServer.getPlayerManager().broadcast(Text.of(discordMessage), false); - } - }); + // Create the bot + jda = JDABuilder.createDefault(token) + .addEventListeners(new MessageListener()) + .enableIntents(GatewayIntent.MESSAGE_CONTENT) + .build(); // Set the bot status - /*if (ModConfigs.BOT_STATUS.equals("Uptime")) { + if (ModConfigs.BOT_STATUS.equals("Uptime") || ModConfigs.BOT_STATUS.equals("PlayerCount")) { new Thread(() -> { while (isBotRunning) { - botStatus(ModConfigs.BOT_STATUS); + setBotStatus(ModConfigs.BOT_STATUS); try { Thread.sleep(60000); } catch (InterruptedException e) { @@ -57,8 +58,8 @@ public class DiscordBot { } }).start(); } else { - botStatus(ModConfigs.BOT_STATUS); - }*/ + setBotStatus(ModConfigs.BOT_STATUS); + } } catch (Exception e) { LOGGER.error("Failed to start Discord bot. Check the provided discord token in the config file."); return; @@ -70,7 +71,7 @@ public class DiscordBot { if (!isBotRunning) { return; } - api.disconnect(); + jda.shutdown(); isBotRunning = false; } @@ -80,12 +81,12 @@ public class DiscordBot { } // Get the text channel by its ID try { - TextChannel channel = api.getTextChannelById(targetChannelId).orElse(null); + TextChannel channel = jda.getTextChannelById(targetChannelId); // Check if the channel exists and send the message if (channel != null) { - channel.sendMessage(message); + channel.sendMessage(message).queue(); } else { - throw new Exception("Discord Channel does not exist!"); + //throw new Exception("Discord Channel does not exist!"); } } catch (Exception e) { LOGGER.error("Discord Channel does not exist!"); @@ -95,7 +96,7 @@ public class DiscordBot { private static void registerEvents() { ServerTickEvents.START_SERVER_TICK.register(server -> { // This code is executed on every server tick - minecraftServer = server; + DiscordBot.minecraftServer = server; }); ServerLifecycleEvents.SERVER_STARTED.register(server -> { @@ -104,57 +105,55 @@ public class DiscordBot { ServerLifecycleEvents.SERVER_STOPPED.register(server -> { sendToDiscord("Server is stopped!"); - //wait for 2 seconds to make sure the message is sent - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } stopBot(); }); } - /*public static void botStatus(String status) { - if (!isBotRunning) { + public static void setBotStatus(String statusType) { + if (!isBotRunning || DiscordBot.minecraftServer == null) { return; } - switch (status) { - case "None" -> api.updateActivity(""); - case "PlayerCount" -> - api.updateActivity("Player Count: " + minecraftServer.getCurrentPlayerCount() + "/" + minecraftServer.getMaxPlayerCount()); - case "IP" -> api.updateActivity("IP: " + minecraftServer.getServerIp()); - case "Uptime" -> api.updateActivity("Uptime: " + calculateUptime()); - default -> api.updateActivity(null); + switch (statusType) { + case "PlayerCount" -> jda.getPresence().setActivity(Activity.playing("with " + DiscordBot.minecraftServer.getCurrentPlayerCount() + "/"+ DiscordBot.minecraftServer.getMaxPlayerCount() + " Players")); + case "Uptime" -> jda.getPresence().setActivity(Activity.playing("for " + calculateUptime())); } } private static String calculateUptime() { - long secs = System.currentTimeMillis() - minecraftServer.getTicks() / 20; - long days = TimeUnit.SECONDS.toDays(secs); - secs -= TimeUnit.DAYS.toMillis(days); - long hours = TimeUnit.SECONDS.toHours(secs); - secs -= TimeUnit.HOURS.toMillis(hours); - long minutes = TimeUnit.SECONDS.toMinutes(secs); + try { + long secs = (System.currentTimeMillis() - startTime) / 1000; + long days = TimeUnit.SECONDS.toDays(secs); + secs -= TimeUnit.DAYS.toMillis(days); + long hours = TimeUnit.SECONDS.toHours(secs); + secs -= TimeUnit.HOURS.toMillis(hours); + long minutes = TimeUnit.SECONDS.toMinutes(secs); - StringBuilder duration = new StringBuilder(); - if (days > 0) { - duration.append(days).append(" Days, "); - } - if (hours > 0 || days > 0) { - if (hours == 1) { - duration.append(hours).append(" Hour, "); - } else { - duration.append(hours).append(" Hours, "); + StringBuilder duration = new StringBuilder(); + if (days > 0) { + duration.append(days).append(" Days, "); } - } - if (minutes > 0 || hours > 0 || days > 0) { - if (minutes == 1) { - duration.append(minutes).append(" Minute, "); - } else { - duration.append(minutes).append(" Minutes, "); + if (hours > 0 || days > 0) { + if (hours == 1) { + duration.append(hours).append(" Hour, "); + } else { + duration.append(hours).append(" Hours, "); + } + } + if (minutes > 0 || hours > 0 || days > 0) { + if (minutes == 1) { + duration.append(minutes).append(" Minute"); + } else { + duration.append(minutes).append(" Minutes"); + } } - } - return duration.toString(); - }*/ -} + if (duration.isEmpty()) { + return "less than a minute"; + } + + return duration.toString(); + } catch (Exception e) { + return "-"; + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/jonasjones/yadcl/dcbot/MessageListener.java b/src/main/java/dev/jonasjones/yadcl/dcbot/MessageListener.java new file mode 100644 index 0000000..121a2ad --- /dev/null +++ b/src/main/java/dev/jonasjones/yadcl/dcbot/MessageListener.java @@ -0,0 +1,22 @@ +package dev.jonasjones.yadcl.dcbot; + +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.minecraft.text.Text; + +import static dev.jonasjones.yadcl.YetAnotherDiscordChatLink.discordBot; + +public class MessageListener extends ListenerAdapter { + @Override + public void onMessageReceived(MessageReceivedEvent event) { + if (!DiscordBot.getIsBotRunning()) return; // Ignore messages if the bot is not running + if (event.getAuthor().isBot()) return; // Ignore messages from other bots + + // Check if the message was sent in the trigger channel + if (event.getChannel().getId().equals(DiscordBot.getTargetChannelId())) { + // Send the message to the server + DiscordBot.getMinecraftServer().getPlayerManager().broadcast(Text.of("[" +event.getAuthor().getName() + "]: " + event.getMessage().getContentRaw()), false); + } + } +} \ No newline at end of file