diff --git a/src/main/java/cc/reconnected/server/RccServer.java b/src/main/java/cc/reconnected/server/RccServer.java index 140f3de..4aee8d1 100644 --- a/src/main/java/cc/reconnected/server/RccServer.java +++ b/src/main/java/cc/reconnected/server/RccServer.java @@ -1,5 +1,6 @@ package cc.reconnected.server; +import cc.reconnected.server.api.events.RccEvents; import cc.reconnected.server.commands.home.*; import cc.reconnected.server.commands.misc.*; import cc.reconnected.server.commands.spawn.*; @@ -8,9 +9,6 @@ import cc.reconnected.server.commands.tell.*; import cc.reconnected.server.commands.warp.*; import cc.reconnected.server.core.*; import cc.reconnected.server.data.StateManager; -import cc.reconnected.server.api.events.PlayerUsernameChange; -import cc.reconnected.server.api.events.PlayerWelcome; -import cc.reconnected.server.api.events.Ready; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; @@ -111,7 +109,7 @@ public class RccServer implements ModInitializer { ServerLifecycleEvents.SERVER_STARTED.register(server -> { luckPerms = LuckPermsProvider.get(); - Ready.READY.invoker().ready(server, luckPerms); + RccEvents.READY.invoker().onReady(server, luckPerms); }); ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { @@ -121,7 +119,7 @@ public class RccServer implements ModInitializer { if (playerState.firstJoinedDate == null) { LOGGER.info("Player {} joined for the first time!", player.getGameProfile().getName()); playerState.firstJoinedDate = new Date(); - PlayerWelcome.PLAYER_WELCOME.invoker().playerWelcome(player, server); + RccEvents.WELCOME.invoker().onWelcome(player, server); var serverState = state.getServerState(); var spawnPosition = serverState.spawn; @@ -132,7 +130,7 @@ public class RccServer implements ModInitializer { if (playerState.username != null && !playerState.username.equals(player.getGameProfile().getName())) { LOGGER.info("Player {} has changed their username from {}", player.getGameProfile().getName(), playerState.username); - PlayerUsernameChange.PLAYER_USERNAME_CHANGE.invoker().changeUsername(player, playerState.username); + RccEvents.USERNAME_CHANGE.invoker().onUsernameChange(player, playerState.username); } playerState.username = player.getGameProfile().getName(); state.savePlayerState(player.getUuid(), playerState); diff --git a/src/main/java/cc/reconnected/server/RccServerConfigModel.java b/src/main/java/cc/reconnected/server/RccServerConfigModel.java index 9840a58..eb67d2c 100644 --- a/src/main/java/cc/reconnected/server/RccServerConfigModel.java +++ b/src/main/java/cc/reconnected/server/RccServerConfigModel.java @@ -14,6 +14,7 @@ public class RccServerConfigModel { public String afkMessage = " is now AFK"; public String afkReturnMessage = " is no longer AFK"; + public String afkTag = "[AFK] "; public String tellMessage = "[ ] "; public String tellMessageSpy = "\uD83D\uDC41 [] "; @@ -21,8 +22,8 @@ public class RccServerConfigModel { public int teleportRequestTimeout = 120; public boolean enableTabList = true; - public int tabListTickDelay = 2; - public double tabPhaseFrequency = 40; + public int tabListTickDelay = 5; + public double tabPhasePeriod = 300; public ArrayList tabHeader = new ArrayList<>(List.of( " " )); @@ -31,5 +32,5 @@ public class RccServerConfigModel { " " )); - public String playerTabName = "%player:displayname_visual% %player:playtime%"; + public String playerTabName = "%rcc-server:afk%%player:displayname_visual%"; } diff --git a/src/main/java/cc/reconnected/server/api/events/PlayerTeleport.java b/src/main/java/cc/reconnected/server/api/events/PlayerTeleportEvent.java similarity index 71% rename from src/main/java/cc/reconnected/server/api/events/PlayerTeleport.java rename to src/main/java/cc/reconnected/server/api/events/PlayerTeleportEvent.java index bd1fafe..f5ce697 100644 --- a/src/main/java/cc/reconnected/server/api/events/PlayerTeleport.java +++ b/src/main/java/cc/reconnected/server/api/events/PlayerTeleportEvent.java @@ -5,10 +5,10 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.server.network.ServerPlayerEntity; -public interface PlayerTeleport { - Event EVENT = EventFactory.createArrayBacked(PlayerTeleport.class, +public interface PlayerTeleportEvent { + Event EVENT = EventFactory.createArrayBacked(PlayerTeleportEvent.class, (listeners) -> (player, origin, destination) -> { - for (PlayerTeleport listener : listeners) { + for (PlayerTeleportEvent listener : listeners) { listener.teleport(player, origin, destination); } }); diff --git a/src/main/java/cc/reconnected/server/api/events/PlayerUsernameChange.java b/src/main/java/cc/reconnected/server/api/events/PlayerUsernameChange.java deleted file mode 100644 index 4716144..0000000 --- a/src/main/java/cc/reconnected/server/api/events/PlayerUsernameChange.java +++ /dev/null @@ -1,16 +0,0 @@ -package cc.reconnected.server.api.events; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.server.network.ServerPlayerEntity; - -public interface PlayerUsernameChange { - Event PLAYER_USERNAME_CHANGE = EventFactory.createArrayBacked(PlayerUsernameChange.class, - (listeners) -> (player, previousUsername) -> { - for (PlayerUsernameChange listener : listeners) { - listener.changeUsername(player, previousUsername); - } - }); - - void changeUsername(ServerPlayerEntity player, String previousUsername); -} diff --git a/src/main/java/cc/reconnected/server/api/events/PlayerWelcome.java b/src/main/java/cc/reconnected/server/api/events/PlayerWelcome.java deleted file mode 100644 index f02fb94..0000000 --- a/src/main/java/cc/reconnected/server/api/events/PlayerWelcome.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.reconnected.server.api.events; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerPlayerEntity; - -public interface PlayerWelcome { - Event PLAYER_WELCOME = EventFactory.createArrayBacked(PlayerWelcome.class, - (listeners) -> (player, server) -> { - for (PlayerWelcome listener : listeners) { - listener.playerWelcome(player, server); - } - }); - - void playerWelcome(ServerPlayerEntity player, MinecraftServer server); -} diff --git a/src/main/java/cc/reconnected/server/api/events/RccEvents.java b/src/main/java/cc/reconnected/server/api/events/RccEvents.java new file mode 100644 index 0000000..22af397 --- /dev/null +++ b/src/main/java/cc/reconnected/server/api/events/RccEvents.java @@ -0,0 +1,58 @@ +package cc.reconnected.server.api.events; + +import cc.reconnected.server.RccServer; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.luckperms.api.LuckPerms; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; + +public final class RccEvents { + public static final Event READY = EventFactory.createArrayBacked(Ready.class, callbacks -> + (server, luckPerms) -> { + for (Ready callback : callbacks) { + callback.onReady(server, luckPerms); + } + }); + + public static final Event RELOAD = EventFactory.createArrayBacked(Reload.class, callbacks -> + (instance) -> { + for (Reload callback : callbacks) { + callback.onReload(instance); + } + }); + + public static final Event WELCOME = EventFactory.createArrayBacked(Welcome.class, callbacks -> + (player, server) -> { + for (Welcome callback : callbacks) { + callback.onWelcome(player, server); + } + }); + + public static final Event USERNAME_CHANGE = EventFactory.createArrayBacked(UsernameChange.class, callbacks -> + (player, previousUsername) -> { + for (UsernameChange callback : callbacks) { + callback.onUsernameChange(player, previousUsername); + } + }); + + @FunctionalInterface + public interface Ready { + void onReady(MinecraftServer server, LuckPerms luckPerms); + } + + @FunctionalInterface + public interface Reload { + void onReload(RccServer instance); + } + + @FunctionalInterface + public interface Welcome { + void onWelcome(ServerPlayerEntity player, MinecraftServer server); + } + + @FunctionalInterface + public interface UsernameChange { + void onUsernameChange(ServerPlayerEntity player, String previousUsername); + } +} diff --git a/src/main/java/cc/reconnected/server/api/events/Ready.java b/src/main/java/cc/reconnected/server/api/events/Ready.java deleted file mode 100644 index 4ba3a79..0000000 --- a/src/main/java/cc/reconnected/server/api/events/Ready.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.reconnected.server.api.events; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.luckperms.api.LuckPerms; -import net.minecraft.server.MinecraftServer; - -public interface Ready { - Event READY = EventFactory.createArrayBacked(Ready.class, - (listeners) -> (server, luckPerms) -> { - for (Ready listener : listeners) { - listener.ready(server, luckPerms); - } - }); - - void ready(MinecraftServer server, LuckPerms luckPerms); -} diff --git a/src/main/java/cc/reconnected/server/commands/misc/RccCommand.java b/src/main/java/cc/reconnected/server/commands/misc/RccCommand.java index 948e66c..ca47643 100644 --- a/src/main/java/cc/reconnected/server/commands/misc/RccCommand.java +++ b/src/main/java/cc/reconnected/server/commands/misc/RccCommand.java @@ -1,6 +1,7 @@ package cc.reconnected.server.commands.misc; import cc.reconnected.server.RccServer; +import cc.reconnected.server.api.events.RccEvents; import com.mojang.brigadier.CommandDispatcher; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.command.CommandRegistryAccess; @@ -26,6 +27,8 @@ public class RccCommand { return 1; } + RccEvents.RELOAD.invoker().onReload(RccServer.getInstance()); + context.getSource().sendFeedback(() -> Text.of("Reloaded RCC config"), true); return 1; diff --git a/src/main/java/cc/reconnected/server/core/AfkTracker.java b/src/main/java/cc/reconnected/server/core/AfkTracker.java index b248952..9928430 100644 --- a/src/main/java/cc/reconnected/server/core/AfkTracker.java +++ b/src/main/java/cc/reconnected/server/core/AfkTracker.java @@ -2,6 +2,10 @@ package cc.reconnected.server.core; import cc.reconnected.server.RccServer; import cc.reconnected.server.api.events.PlayerActivityEvents; +import cc.reconnected.server.api.events.RccEvents; +import cc.reconnected.server.util.Components; +import eu.pb4.placeholders.api.PlaceholderResult; +import eu.pb4.placeholders.api.Placeholders; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.player.*; import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; @@ -13,6 +17,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; +import net.minecraft.util.Identifier; import net.minecraft.util.TypedActionResult; import java.util.UUID; @@ -30,7 +35,22 @@ public class AfkTracker { return instance; } + public static Text afkTag; + public static void register() { + loadAfkTag(); + + Placeholders.register(new Identifier(RccServer.MOD_ID, "afk"), (context, argument) -> { + if(!context.hasPlayer()) + return PlaceholderResult.invalid("No player!"); + var player = context.player(); + if(instance.isPlayerAfk(player.getUuid())) { + return PlaceholderResult.value(afkTag); + } else { + return PlaceholderResult.value(""); + } + }); + PlayerActivityEvents.AFK.register((player, server) -> { RccServer.LOGGER.info("{} is AFK. Active time: {} seconds.", player.getGameProfile().getName(), getInstance().getActiveTime(player)); @@ -60,6 +80,12 @@ public class AfkTracker { RccServer.getInstance().broadcastMessage(server, message); }); + + RccEvents.RELOAD.register(inst -> loadAfkTag()); + } + + private static void loadAfkTag() { + afkTag = Components.toText(MiniMessage.miniMessage().deserialize(RccServer.CONFIG.afkTag())); } private AfkTracker() { diff --git a/src/main/java/cc/reconnected/server/core/BackTracker.java b/src/main/java/cc/reconnected/server/core/BackTracker.java index 37754ba..498ca62 100644 --- a/src/main/java/cc/reconnected/server/core/BackTracker.java +++ b/src/main/java/cc/reconnected/server/core/BackTracker.java @@ -1,6 +1,6 @@ package cc.reconnected.server.core; -import cc.reconnected.server.api.events.PlayerTeleport; +import cc.reconnected.server.api.events.PlayerTeleportEvent; import cc.reconnected.server.struct.ServerPosition; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; @@ -17,7 +17,7 @@ public class BackTracker { lastPlayerPositions.remove(handler.getPlayer().getUuid()); }); - PlayerTeleport.EVENT.register((player, origin, destination) -> { + PlayerTeleportEvent.EVENT.register((player, origin, destination) -> { lastPlayerPositions.put(player.getUuid(), origin); }); diff --git a/src/main/java/cc/reconnected/server/core/TabList.java b/src/main/java/cc/reconnected/server/core/TabList.java index b59e47a..d4e84cd 100644 --- a/src/main/java/cc/reconnected/server/core/TabList.java +++ b/src/main/java/cc/reconnected/server/core/TabList.java @@ -16,9 +16,11 @@ public class TabList { var minimessage = MiniMessage.miniMessage(); ServerTickEvents.END_SERVER_TICK.register(server -> { - if(server.getTicks() % RccServer.CONFIG.tabListTickDelay() == 0) { + var delay = Math.max(RccServer.CONFIG.tabListTickDelay(), 1); + if(server.getTicks() % delay == 0) { + var period = Math.max(RccServer.CONFIG.tabPhasePeriod(), 1); - var phase = (Math.sin((server.getTicks() * Math.PI * 2) / RccServer.CONFIG.tabPhaseFrequency()) + 1) / 2d; + var phase = (Math.sin((server.getTicks() * Math.PI * 2) / period) + 1) / 2d; server.getPlayerManager().getPlayerList().forEach(player -> { var playerContext = PlaceholderContext.of(player);