Unify Rcc events into a single class, safe guards against math crimes, add AFK tag

This commit is contained in:
Alessandro Proto 2024-10-26 11:30:41 +02:00
parent 77cb5719e1
commit 0690947612
11 changed files with 104 additions and 66 deletions

View file

@ -1,5 +1,6 @@
package cc.reconnected.server; package cc.reconnected.server;
import cc.reconnected.server.api.events.RccEvents;
import cc.reconnected.server.commands.home.*; import cc.reconnected.server.commands.home.*;
import cc.reconnected.server.commands.misc.*; import cc.reconnected.server.commands.misc.*;
import cc.reconnected.server.commands.spawn.*; 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.commands.warp.*;
import cc.reconnected.server.core.*; import cc.reconnected.server.core.*;
import cc.reconnected.server.data.StateManager; 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.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
@ -111,7 +109,7 @@ public class RccServer implements ModInitializer {
ServerLifecycleEvents.SERVER_STARTED.register(server -> { ServerLifecycleEvents.SERVER_STARTED.register(server -> {
luckPerms = LuckPermsProvider.get(); luckPerms = LuckPermsProvider.get();
Ready.READY.invoker().ready(server, luckPerms); RccEvents.READY.invoker().onReady(server, luckPerms);
}); });
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
@ -121,7 +119,7 @@ public class RccServer implements ModInitializer {
if (playerState.firstJoinedDate == null) { if (playerState.firstJoinedDate == null) {
LOGGER.info("Player {} joined for the first time!", player.getGameProfile().getName()); LOGGER.info("Player {} joined for the first time!", player.getGameProfile().getName());
playerState.firstJoinedDate = new Date(); playerState.firstJoinedDate = new Date();
PlayerWelcome.PLAYER_WELCOME.invoker().playerWelcome(player, server); RccEvents.WELCOME.invoker().onWelcome(player, server);
var serverState = state.getServerState(); var serverState = state.getServerState();
var spawnPosition = serverState.spawn; var spawnPosition = serverState.spawn;
@ -132,7 +130,7 @@ public class RccServer implements ModInitializer {
if (playerState.username != null && !playerState.username.equals(player.getGameProfile().getName())) { if (playerState.username != null && !playerState.username.equals(player.getGameProfile().getName())) {
LOGGER.info("Player {} has changed their username from {}", player.getGameProfile().getName(), playerState.username); 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(); playerState.username = player.getGameProfile().getName();
state.savePlayerState(player.getUuid(), playerState); state.savePlayerState(player.getUuid(), playerState);

View file

@ -14,6 +14,7 @@ public class RccServerConfigModel {
public String afkMessage = "<gray><displayname> is now AFK</gray>"; public String afkMessage = "<gray><displayname> is now AFK</gray>";
public String afkReturnMessage = "<gray><displayname> is no longer AFK</gray>"; public String afkReturnMessage = "<gray><displayname> is no longer AFK</gray>";
public String afkTag = "<gray>[AFK]</gray> ";
public String tellMessage = "<gold>[</gold><source> <gray>→</gray> <target><gold>]</gold> <message>"; public String tellMessage = "<gold>[</gold><source> <gray>→</gray> <target><gold>]</gold> <message>";
public String tellMessageSpy = "\uD83D\uDC41 <gray>[<source> → <target>]</gray> <message>"; public String tellMessageSpy = "\uD83D\uDC41 <gray>[<source> → <target>]</gray> <message>";
@ -21,8 +22,8 @@ public class RccServerConfigModel {
public int teleportRequestTimeout = 120; public int teleportRequestTimeout = 120;
public boolean enableTabList = true; public boolean enableTabList = true;
public int tabListTickDelay = 2; public int tabListTickDelay = 5;
public double tabPhaseFrequency = 40; public double tabPhasePeriod = 300;
public ArrayList<String> tabHeader = new ArrayList<>(List.of( public ArrayList<String> tabHeader = new ArrayList<>(List.of(
"<gradient:#DEDE6C:#CC4C4C:{phase}><st> </st></gradient>" "<gradient:#DEDE6C:#CC4C4C:{phase}><st> </st></gradient>"
)); ));
@ -31,5 +32,5 @@ public class RccServerConfigModel {
"<gradient:#DEDE6C:#CC4C4C:{phase}><st> </st></gradient>" "<gradient:#DEDE6C:#CC4C4C:{phase}><st> </st></gradient>"
)); ));
public String playerTabName = "%player:displayname_visual% %player:playtime%"; public String playerTabName = "%rcc-server:afk%%player:displayname_visual%";
} }

View file

@ -5,10 +5,10 @@ import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
public interface PlayerTeleport { public interface PlayerTeleportEvent {
Event<PlayerTeleport> EVENT = EventFactory.createArrayBacked(PlayerTeleport.class, Event<PlayerTeleportEvent> EVENT = EventFactory.createArrayBacked(PlayerTeleportEvent.class,
(listeners) -> (player, origin, destination) -> { (listeners) -> (player, origin, destination) -> {
for (PlayerTeleport listener : listeners) { for (PlayerTeleportEvent listener : listeners) {
listener.teleport(player, origin, destination); listener.teleport(player, origin, destination);
} }
}); });

View file

@ -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<PlayerUsernameChange> PLAYER_USERNAME_CHANGE = EventFactory.createArrayBacked(PlayerUsernameChange.class,
(listeners) -> (player, previousUsername) -> {
for (PlayerUsernameChange listener : listeners) {
listener.changeUsername(player, previousUsername);
}
});
void changeUsername(ServerPlayerEntity player, String previousUsername);
}

View file

@ -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<PlayerWelcome> PLAYER_WELCOME = EventFactory.createArrayBacked(PlayerWelcome.class,
(listeners) -> (player, server) -> {
for (PlayerWelcome listener : listeners) {
listener.playerWelcome(player, server);
}
});
void playerWelcome(ServerPlayerEntity player, MinecraftServer server);
}

View file

@ -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> READY = EventFactory.createArrayBacked(Ready.class, callbacks ->
(server, luckPerms) -> {
for (Ready callback : callbacks) {
callback.onReady(server, luckPerms);
}
});
public static final Event<Reload> RELOAD = EventFactory.createArrayBacked(Reload.class, callbacks ->
(instance) -> {
for (Reload callback : callbacks) {
callback.onReload(instance);
}
});
public static final Event<Welcome> WELCOME = EventFactory.createArrayBacked(Welcome.class, callbacks ->
(player, server) -> {
for (Welcome callback : callbacks) {
callback.onWelcome(player, server);
}
});
public static final Event<UsernameChange> 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);
}
}

View file

@ -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> READY = EventFactory.createArrayBacked(Ready.class,
(listeners) -> (server, luckPerms) -> {
for (Ready listener : listeners) {
listener.ready(server, luckPerms);
}
});
void ready(MinecraftServer server, LuckPerms luckPerms);
}

View file

@ -1,6 +1,7 @@
package cc.reconnected.server.commands.misc; package cc.reconnected.server.commands.misc;
import cc.reconnected.server.RccServer; import cc.reconnected.server.RccServer;
import cc.reconnected.server.api.events.RccEvents;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import me.lucko.fabric.api.permissions.v0.Permissions; import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandRegistryAccess;
@ -26,6 +27,8 @@ public class RccCommand {
return 1; return 1;
} }
RccEvents.RELOAD.invoker().onReload(RccServer.getInstance());
context.getSource().sendFeedback(() -> Text.of("Reloaded RCC config"), true); context.getSource().sendFeedback(() -> Text.of("Reloaded RCC config"), true);
return 1; return 1;

View file

@ -2,6 +2,10 @@ package cc.reconnected.server.core;
import cc.reconnected.server.RccServer; import cc.reconnected.server.RccServer;
import cc.reconnected.server.api.events.PlayerActivityEvents; 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.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.*; import net.fabricmc.fabric.api.event.player.*;
import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; 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.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Identifier;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
import java.util.UUID; import java.util.UUID;
@ -30,7 +35,22 @@ public class AfkTracker {
return instance; return instance;
} }
public static Text afkTag;
public static void register() { 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) -> { PlayerActivityEvents.AFK.register((player, server) -> {
RccServer.LOGGER.info("{} is AFK. Active time: {} seconds.", player.getGameProfile().getName(), getInstance().getActiveTime(player)); 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); 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() { private AfkTracker() {

View file

@ -1,6 +1,6 @@
package cc.reconnected.server.core; 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 cc.reconnected.server.struct.ServerPosition;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
@ -17,7 +17,7 @@ public class BackTracker {
lastPlayerPositions.remove(handler.getPlayer().getUuid()); lastPlayerPositions.remove(handler.getPlayer().getUuid());
}); });
PlayerTeleport.EVENT.register((player, origin, destination) -> { PlayerTeleportEvent.EVENT.register((player, origin, destination) -> {
lastPlayerPositions.put(player.getUuid(), origin); lastPlayerPositions.put(player.getUuid(), origin);
}); });

View file

@ -16,9 +16,11 @@ public class TabList {
var minimessage = MiniMessage.miniMessage(); var minimessage = MiniMessage.miniMessage();
ServerTickEvents.END_SERVER_TICK.register(server -> { 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 -> { server.getPlayerManager().getPlayerList().forEach(player -> {
var playerContext = PlaceholderContext.of(player); var playerContext = PlaceholderContext.of(player);