diff --git a/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java b/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java index 877d2c2..ca7843c 100644 --- a/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java +++ b/src/main/java/dev/jonasjones/yadcl/YetAnotherDiscordChatLink.java @@ -28,7 +28,5 @@ public class YetAnotherDiscordChatLink implements ModInitializer { DiscordBot.startBot(); // send starting message sendToDiscord("Server is starting up."); - - } } \ No newline at end of file diff --git a/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java b/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java index 05e5609..a301a3b 100644 --- a/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java +++ b/src/main/java/dev/jonasjones/yadcl/config/ModConfigs.java @@ -10,6 +10,14 @@ public class ModConfigs { public static String TOKEN; public static String CHANNEL_ID; + public static Boolean PLAYER_JOIN_LEAVE_MSG; + //public static Boolean PLAYER_DEATH_MSG; + //public static Boolean PLAYER_ADVANCEMENT_MSG; + public static Boolean PLAYER_CHAT_MSG; + //public static Boolean PLAYER_COMMAND_MSG; + public static Boolean SERVER_START_STOP_MSG; + + public static String BOT_STATUS; public static void registerConfigs() { configs = new ModConfigProvider(); @@ -23,12 +31,25 @@ public class ModConfigs { private static void createConfigs() { configs.addKeyValuePair(new Pair<>("bot.token", "[Insert bot token here]"), "The Bot token from the discord developer dashboard"); configs.addKeyValuePair(new Pair<>("bot.channel", "1165690308185563216"), "The channel id of the channel the bot should listen and send to"); + configs.addKeyValuePair(new Pair<>("bot.player_join_leave_msgs", true), "Should the bot send a message when a player joins or leaves the server"); + //configs.addKeyValuePair(new Pair<>("bot.player_death_msgs", true), "Should the bot send a message when a player dies"); + //configs.addKeyValuePair(new Pair<>("bot.player_advancement_msgs", true), "Should the bot send a message when a player advances an advancement"); + 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]"); } private static void assignConfigs() { TOKEN = CONFIG.getOrDefault("bot.token", "default value"); CHANNEL_ID = CONFIG.getOrDefault("bot.channel", "1165690308185563216"); - + PLAYER_JOIN_LEAVE_MSG = CONFIG.getOrDefault("bot.player_join_leave_msgs", true); + //PLAYER_DEATH_MSG = CONFIG.getOrDefault("bot.player_death_msgs", true); + //PLAYER_ADVANCEMENT_MSG = CONFIG.getOrDefault("bot.player_advancement_msgs", true); + 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"); 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 d9fabdc..3a2d051 100644 --- a/src/main/java/dev/jonasjones/yadcl/dcbot/DiscordBot.java +++ b/src/main/java/dev/jonasjones/yadcl/dcbot/DiscordBot.java @@ -1,12 +1,13 @@ package dev.jonasjones.yadcl.dcbot; +import dev.jonasjones.yadcl.config.ModConfigs; import lombok.Setter; +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; @@ -25,7 +26,7 @@ public class DiscordBot { } try { - registerServerTickEvent(); + 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 @@ -40,8 +41,24 @@ public class DiscordBot { minecraftServer.getPlayerManager().broadcast(Text.of(discordMessage), false); } }); + // Set the bot status + if (ModConfigs.BOT_STATUS.equals("Uptime")) { + new Thread(() -> { + while (isBotRunning) { + botStatus(ModConfigs.BOT_STATUS); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); + } else { + botStatus(ModConfigs.BOT_STATUS); + } } catch (Exception e) { LOGGER.error("Failed to start Discord bot. Check the provided discord token in the config file."); + return; } isBotRunning = true; } @@ -59,21 +76,76 @@ public class DiscordBot { return; } // Get the text channel by its ID - TextChannel channel = api.getTextChannelById(targetChannelId).orElse(null); - - // Check if the channel exists and send the message - if (channel != null) { - channel.sendMessage(message); - } else { - // Handle the case where the channel does not exist + try { + TextChannel channel = api.getTextChannelById(targetChannelId).orElse(null); + // Check if the channel exists and send the message + if (channel != null) { + channel.sendMessage(message); + } else { + throw new Exception("Discord Channel does not exist!"); + } + } catch (Exception e) { LOGGER.error("Discord Channel does not exist!"); } } - private static void registerServerTickEvent() { + private static void registerEvents() { ServerTickEvents.START_SERVER_TICK.register(server -> { // This code is executed on every server tick minecraftServer = server; }); + + ServerLifecycleEvents.SERVER_STARTED.register(server -> { + sendToDiscord("Server is started!"); + }); + + ServerLifecycleEvents.SERVER_STOPPED.register(server -> { + sendToDiscord("Server is stopped!"); + stopBot(); + }); + } + + public static void botStatus(String status) { + if (!isBotRunning) { + 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); + } + } + + 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); + + 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, "); + } + } + if (minutes > 0 || hours > 0 || days > 0) { + if (minutes == 1) { + duration.append(minutes).append(" Minute, "); + } else { + duration.append(minutes).append(" Minutes, "); + } + } + + return duration.toString(); } } diff --git a/src/main/java/dev/jonasjones/yadcl/mixin/MixinServerPlayNetworkHandler.java b/src/main/java/dev/jonasjones/yadcl/mixin/MixinServerPlayNetworkHandler.java index 2d83732..a738e3c 100644 --- a/src/main/java/dev/jonasjones/yadcl/mixin/MixinServerPlayNetworkHandler.java +++ b/src/main/java/dev/jonasjones/yadcl/mixin/MixinServerPlayNetworkHandler.java @@ -1,5 +1,6 @@ package dev.jonasjones.yadcl.mixin; +import dev.jonasjones.yadcl.config.ModConfigs; import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayNetworkHandler; @@ -18,7 +19,9 @@ public abstract class MixinServerPlayNetworkHandler { @Inject(method = "onChatMessage", at = @At("HEAD"), cancellable = true) private void onChatMessage(ChatMessageC2SPacket packet, CallbackInfo ci) { - String messageContent = packet.chatMessage(); // Get the content of the chat message - sendToDiscord("<" + this.player.getDisplayName().getString() + "> " + messageContent); + if (ModConfigs.PLAYER_CHAT_MSG) { + String messageContent = packet.chatMessage(); // Get the content of the chat message + sendToDiscord("<" + this.player.getDisplayName().getString() + "> " + messageContent); + } } } \ No newline at end of file diff --git a/src/main/java/dev/jonasjones/yadcl/mixin/PlayerManagerMixin.java b/src/main/java/dev/jonasjones/yadcl/mixin/PlayerManagerMixin.java index cbc7d20..e7e2a29 100644 --- a/src/main/java/dev/jonasjones/yadcl/mixin/PlayerManagerMixin.java +++ b/src/main/java/dev/jonasjones/yadcl/mixin/PlayerManagerMixin.java @@ -1,5 +1,6 @@ package dev.jonasjones.yadcl.mixin; +import dev.jonasjones.yadcl.config.ModConfigs; import net.minecraft.network.ClientConnection; import net.minecraft.server.PlayerManager; import net.minecraft.server.network.ConnectedClientData; @@ -9,17 +10,28 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static dev.jonasjones.yadcl.dcbot.DiscordBot.botStatus; import static dev.jonasjones.yadcl.dcbot.DiscordBot.sendToDiscord; @Mixin(PlayerManager.class) public class PlayerManagerMixin { @Inject(at = @At("HEAD"), method = "onPlayerConnect") public void onPlayerConnect​(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) { - sendToDiscord(player.getDisplayName().getString() + " joined the game."); + if (ModConfigs.PLAYER_JOIN_LEAVE_MSG) { + sendToDiscord(player.getDisplayName().getString() + " joined the game"); + if (ModConfigs.BOT_STATUS.equals("PlayerCount")) { + botStatus(ModConfigs.BOT_STATUS); + } + } } @Inject(at = @At("HEAD"), method = "remove") public void remove(ServerPlayerEntity player, CallbackInfo ci) { - sendToDiscord(player.getDisplayName().getString() + " left the game."); + if (ModConfigs.PLAYER_JOIN_LEAVE_MSG) { + sendToDiscord(player.getDisplayName().getString() + " left the game"); + if (ModConfigs.BOT_STATUS.equals("PlayerCount")) { + botStatus(ModConfigs.BOT_STATUS); + } + } } } \ No newline at end of file diff --git a/src/main/java/dev/jonasjones/yadcl/mixin/ServerStopMixin.java b/src/main/java/dev/jonasjones/yadcl/mixin/ServerStopMixin.java index 0633e3f..15cad94 100644 --- a/src/main/java/dev/jonasjones/yadcl/mixin/ServerStopMixin.java +++ b/src/main/java/dev/jonasjones/yadcl/mixin/ServerStopMixin.java @@ -1,5 +1,6 @@ package dev.jonasjones.yadcl.mixin; +import dev.jonasjones.yadcl.config.ModConfigs; import net.minecraft.server.MinecraftServer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -13,13 +14,8 @@ import static dev.jonasjones.yadcl.dcbot.DiscordBot.stopBot; public class ServerStopMixin { @Inject(at = @At("HEAD"), method = "shutdown") private void init(CallbackInfo info) { - sendToDiscord("Server is shutting down."); - //wait 2 seconds for the message to send - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); + if (ModConfigs.SERVER_START_STOP_MSG) { + sendToDiscord("Server is shutting down."); } - stopBot(); } }