Refactor code structure
This commit is contained in:
parent
325e52bc19
commit
6ca46fc562
15 changed files with 306 additions and 271 deletions
|
@ -1,39 +1,26 @@
|
|||
package cc.reconnected.server;
|
||||
|
||||
import cc.reconnected.server.commands.*;
|
||||
import cc.reconnected.server.core.*;
|
||||
import cc.reconnected.server.database.PlayerData;
|
||||
import cc.reconnected.server.events.PlayerActivityEvents;
|
||||
import cc.reconnected.server.events.PlayerWelcome;
|
||||
import cc.reconnected.server.events.Ready;
|
||||
import cc.reconnected.server.http.ServiceServer;
|
||||
import cc.reconnected.server.struct.ServerPosition;
|
||||
import cc.reconnected.server.tablist.TabList;
|
||||
import cc.reconnected.server.trackers.AfkTracker;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
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.ServerTickEvents;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.kyori.adventure.platform.fabric.FabricServerAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
|
||||
public class RccServer implements ModInitializer {
|
||||
|
@ -42,20 +29,14 @@ public class RccServer implements ModInitializer {
|
|||
|
||||
public static final cc.reconnected.server.RccServerConfig CONFIG = cc.reconnected.server.RccServerConfig.createAndLoad();
|
||||
|
||||
private static float currentTps = 0;
|
||||
private static float currentMspt = 0;
|
||||
private static int currentPlayerCount = 0;
|
||||
|
||||
private static RccServer INSTANCE;
|
||||
|
||||
public static RccServer getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ServiceServer serviceServer;
|
||||
|
||||
public ServiceServer serviceServer() {
|
||||
return serviceServer;
|
||||
public RccServer() {
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
private LuckPerms luckPerms;
|
||||
|
@ -64,28 +45,6 @@ public class RccServer implements ModInitializer {
|
|||
return luckPerms;
|
||||
}
|
||||
|
||||
private AfkTracker afkTracker;
|
||||
|
||||
public AfkTracker afkTracker() {
|
||||
return afkTracker;
|
||||
}
|
||||
|
||||
public static float getTPS() {
|
||||
return currentTps;
|
||||
}
|
||||
|
||||
public static float getMSPT() {
|
||||
return currentMspt;
|
||||
}
|
||||
|
||||
public static int getPlayerCount() {
|
||||
return currentPlayerCount;
|
||||
}
|
||||
|
||||
public RccServer() {
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
private volatile FabricServerAudiences adventure;
|
||||
|
||||
public FabricServerAudiences adventure() {
|
||||
|
@ -96,9 +55,6 @@ public class RccServer implements ModInitializer {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static final ConcurrentHashMap<UUID, ConcurrentLinkedDeque<TeleportAskCommand.TeleportRequest>> teleportRequests = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentHashMap<UUID, ServerPosition> lastPlayerPositions = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LOGGER.info("Starting rcc-server");
|
||||
|
@ -120,46 +76,18 @@ public class RccServer implements ModInitializer {
|
|||
GodCommand.register(dispatcher, registryAccess, environment);
|
||||
});
|
||||
|
||||
AfkTracker.register();
|
||||
TeleportTracker.register();
|
||||
BackTracker.register();
|
||||
TabList.register();
|
||||
HttpApiServer.register();
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
luckPerms = LuckPermsProvider.get();
|
||||
afkTracker = new AfkTracker();
|
||||
Ready.READY.invoker().ready(server, luckPerms);
|
||||
|
||||
if (CONFIG.enableHttpApi()) {
|
||||
try {
|
||||
serviceServer = new ServiceServer();
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Unable to start HTTP server", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
currentMspt = server.getTickTime();
|
||||
if (currentMspt != 0) {
|
||||
currentTps = Math.min(20, 1000 / currentMspt);
|
||||
}
|
||||
|
||||
teleportRequests.forEach((recipient, requestList) -> {
|
||||
requestList.forEach(request -> {
|
||||
if (request.remainingTicks-- == 0) {
|
||||
requestList.remove(request);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register(server -> {
|
||||
if (CONFIG.enableHttpApi()) {
|
||||
LOGGER.info("Stopping HTTP services");
|
||||
serviceServer.httpServer().stop(0);
|
||||
}
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
currentPlayerCount = server.getCurrentPlayerCount() + 1;
|
||||
var player = handler.getPlayer();
|
||||
var playerData = PlayerData.getPlayer(player.getUuid());
|
||||
playerData.set(PlayerData.KEYS.username, player.getName().getString());
|
||||
|
@ -173,45 +101,6 @@ public class RccServer implements ModInitializer {
|
|||
PlayerWelcome.PLAYER_WELCOME.invoker().playerWelcome(player, playerData, server);
|
||||
LOGGER.info("Player {} joined for the first time!", player.getName().getString());
|
||||
}
|
||||
|
||||
teleportRequests.put(player.getUuid(), new ConcurrentLinkedDeque<>());
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||
currentPlayerCount = server.getCurrentPlayerCount() - 1;
|
||||
|
||||
teleportRequests.remove(handler.getPlayer().getUuid());
|
||||
lastPlayerPositions.remove(handler.getPlayer().getUuid());
|
||||
});
|
||||
|
||||
PlayerActivityEvents.AFK.register((player, server) -> {
|
||||
LOGGER.info("{} is AFK. Active time: {} seconds.", player.getGameProfile().getName(), afkTracker.getActiveTime(player));
|
||||
|
||||
var displayNameJson = Text.Serializer.toJson(player.getDisplayName());
|
||||
var displayName = JSONComponentSerializer.json().deserialize(displayNameJson);
|
||||
|
||||
var message = MiniMessage.miniMessage().deserialize(CONFIG.afkMessage(),
|
||||
Placeholder.component("displayname", displayName),
|
||||
Placeholder.unparsed("username", player.getGameProfile().getName()),
|
||||
Placeholder.unparsed("uuid", player.getUuid().toString())
|
||||
);
|
||||
|
||||
broadcastMessage(server, message);
|
||||
});
|
||||
|
||||
PlayerActivityEvents.AFK_RETURN.register((player, server) -> {
|
||||
LOGGER.info("{} is no longer AFK. Active time: {} seconds.", player.getGameProfile().getName(), afkTracker.getActiveTime(player));
|
||||
|
||||
var displayNameJson = Text.Serializer.toJson(player.getDisplayName());
|
||||
var displayName = JSONComponentSerializer.json().deserialize(displayNameJson);
|
||||
|
||||
var message = MiniMessage.miniMessage().deserialize(CONFIG.afkReturnMessage(),
|
||||
Placeholder.component("displayname", displayName),
|
||||
Placeholder.unparsed("username", player.getGameProfile().getName()),
|
||||
Placeholder.unparsed("uuid", player.getUuid().toString())
|
||||
);
|
||||
|
||||
broadcastMessage(server, message);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -226,16 +115,4 @@ public class RccServer implements ModInitializer {
|
|||
player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlayerAfk(PlayerEntity player) {
|
||||
return afkTracker.isPlayerAfk(player.getUuid());
|
||||
}
|
||||
|
||||
public void setPlayerAfk(ServerPlayerEntity player, boolean afk) {
|
||||
afkTracker.setPlayerAfk(player, afk);
|
||||
}
|
||||
|
||||
public int getActiveTime(ServerPlayerEntity player) {
|
||||
return afkTracker().getActiveTime(player);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.core.AfkTracker;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
|
@ -22,7 +22,7 @@ public class AfkCommand {
|
|||
}
|
||||
|
||||
var player = context.getSource().getPlayer();
|
||||
RccServer.getInstance().setPlayerAfk(player, true);
|
||||
AfkTracker.getInstance().setPlayerAfk(player, true);
|
||||
|
||||
return 1;
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.core.BackTracker;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
|
@ -23,7 +23,7 @@ public class BackCommand {
|
|||
|
||||
var player = context.getSource().getPlayer();
|
||||
|
||||
var lastPosition = RccServer.lastPlayerPositions.get(player.getUuid());
|
||||
var lastPosition = BackTracker.lastPlayerPositions.get(player.getUuid());
|
||||
if (lastPosition == null) {
|
||||
context.getSource().sendFeedback(() -> Text.literal("There is no position to return back to.").formatted(Formatting.RED), false);
|
||||
return 1;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.core.TeleportTracker;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
|
@ -23,7 +23,7 @@ public class TeleportAcceptCommand {
|
|||
}
|
||||
|
||||
var playerUuid = context.getSource().getPlayer().getUuid();
|
||||
var playerRequests = RccServer.teleportRequests.get(playerUuid);
|
||||
var playerRequests = TeleportTracker.teleportRequests.get(playerUuid);
|
||||
|
||||
|
||||
var request = playerRequests.pollLast();
|
||||
|
@ -46,7 +46,7 @@ public class TeleportAcceptCommand {
|
|||
|
||||
var uuid = UuidArgumentType.getUuid(context, "uuid");
|
||||
var playerUuid = context.getSource().getPlayer().getUuid();
|
||||
var playerRequests = RccServer.teleportRequests.get(playerUuid);
|
||||
var playerRequests = TeleportTracker.teleportRequests.get(playerUuid);
|
||||
|
||||
var request = playerRequests.stream().filter(req -> req.requestId.equals(uuid)).findFirst().orElse(null);
|
||||
if (request == null) {
|
||||
|
@ -62,7 +62,7 @@ public class TeleportAcceptCommand {
|
|||
dispatcher.register(literal("tpyes").redirect(node));
|
||||
}
|
||||
|
||||
private static void execute(CommandContext<ServerCommandSource> context, TeleportAskCommand.TeleportRequest request) {
|
||||
private static void execute(CommandContext<ServerCommandSource> context, TeleportTracker.TeleportRequest request) {
|
||||
var source = context.getSource();
|
||||
request.expire();
|
||||
|
||||
|
@ -88,6 +88,6 @@ public class TeleportAcceptCommand {
|
|||
targetPlayer.sendMessage(Text.empty().append(player.getDisplayName()).append(Text.literal(" accepted your teleport request.").formatted(Formatting.GREEN)), false);
|
||||
}
|
||||
|
||||
TeleportAskCommand.teleport(sourcePlayer, targetPlayer);
|
||||
TeleportTracker.teleport(sourcePlayer, targetPlayer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.struct.ServerPosition;
|
||||
import cc.reconnected.server.core.TeleportTracker;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.*;
|
||||
|
||||
public class TeleportAskCommand {
|
||||
|
@ -60,8 +51,8 @@ public class TeleportAskCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
var request = new TeleportRequest(player.getUuid(), target.getUuid());
|
||||
var targetRequests = RccServer.teleportRequests.get(target.getUuid());
|
||||
var request = new TeleportTracker.TeleportRequest(player.getUuid(), target.getUuid());
|
||||
var targetRequests = TeleportTracker.teleportRequests.get(target.getUuid());
|
||||
targetRequests.addLast(request);
|
||||
|
||||
var requestMessage = Component.empty()
|
||||
|
@ -69,53 +60,13 @@ public class TeleportAskCommand {
|
|||
.appendSpace()
|
||||
.append(Component.text("requested to teleport to you.", NamedTextColor.GOLD))
|
||||
.appendNewline().appendSpace()
|
||||
.append(makeButton(Component.text("Accept", NamedTextColor.GREEN), Component.text("Click to accept request"), "/tpaccept " + request.requestId))
|
||||
.append(TeleportTracker.makeButton(Component.text("Accept", NamedTextColor.GREEN), Component.text("Click to accept request"), "/tpaccept " + request.requestId))
|
||||
.appendSpace()
|
||||
.append(makeButton(Component.text("Refuse", NamedTextColor.RED), Component.text("Click to refuse request"), "/tpdeny " + request.requestId));
|
||||
.append(TeleportTracker.makeButton(Component.text("Refuse", NamedTextColor.RED), Component.text("Click to refuse request"), "/tpdeny " + request.requestId));
|
||||
|
||||
target.sendMessage(requestMessage);
|
||||
|
||||
source.sendFeedback(() -> Text.literal("Teleport request sent.").setStyle(Style.EMPTY.withColor(Formatting.GREEN)), false);
|
||||
}
|
||||
|
||||
public static Component makeButton(ComponentLike text, ComponentLike hoverText, String command) {
|
||||
return Component.empty()
|
||||
.append(Component.text("["))
|
||||
.append(text)
|
||||
.append(Component.text("]"))
|
||||
.color(NamedTextColor.AQUA)
|
||||
.hoverEvent(HoverEvent.showText(hoverText))
|
||||
.clickEvent(ClickEvent.runCommand(command));
|
||||
}
|
||||
|
||||
public static void teleport(ServerPlayerEntity sourcePlayer, ServerPlayerEntity targetPlayer) {
|
||||
RccServer.lastPlayerPositions.put(sourcePlayer.getUuid(), new ServerPosition(sourcePlayer));
|
||||
sourcePlayer.teleport(
|
||||
targetPlayer.getServerWorld(),
|
||||
targetPlayer.getX(),
|
||||
targetPlayer.getY(),
|
||||
targetPlayer.getZ(),
|
||||
targetPlayer.getYaw(),
|
||||
targetPlayer.getPitch()
|
||||
);
|
||||
}
|
||||
|
||||
public static class TeleportRequest {
|
||||
public UUID requestId = UUID.randomUUID();
|
||||
public UUID player;
|
||||
public UUID target;
|
||||
public int remainingTicks;
|
||||
|
||||
public TeleportRequest(UUID player, UUID target) {
|
||||
this.player = player;
|
||||
this.target = target;
|
||||
// Seconds in config per 20 ticks
|
||||
this.remainingTicks = RccServer.CONFIG.teleportRequestTimeout() * 20;
|
||||
}
|
||||
|
||||
public void expire() {
|
||||
remainingTicks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.core.TeleportTracker;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
|
@ -52,8 +52,8 @@ public class TeleportAskHereCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
var request = new TeleportAskCommand.TeleportRequest(target.getUuid(), player.getUuid());
|
||||
var targetRequests = RccServer.teleportRequests.get(target.getUuid());
|
||||
var request = new TeleportTracker.TeleportRequest(target.getUuid(), player.getUuid());
|
||||
var targetRequests = TeleportTracker.teleportRequests.get(target.getUuid());
|
||||
targetRequests.addLast(request);
|
||||
|
||||
var requestMessage = Component.empty()
|
||||
|
@ -61,9 +61,9 @@ public class TeleportAskHereCommand {
|
|||
.appendSpace()
|
||||
.append(Component.text("requested you to teleport to them.", NamedTextColor.GOLD))
|
||||
.appendNewline().appendSpace()
|
||||
.append(TeleportAskCommand.makeButton(Component.text("Accept", NamedTextColor.GREEN), Component.text("Click to accept request"), "/tpaccept " + request.requestId))
|
||||
.append(TeleportTracker.makeButton(Component.text("Accept", NamedTextColor.GREEN), Component.text("Click to accept request"), "/tpaccept " + request.requestId))
|
||||
.appendSpace()
|
||||
.append(TeleportAskCommand.makeButton(Component.text("Refuse", NamedTextColor.RED), Component.text("Click to refuse request"), "/tpdeny " + request.requestId));
|
||||
.append(TeleportTracker.makeButton(Component.text("Refuse", NamedTextColor.RED), Component.text("Click to refuse request"), "/tpdeny " + request.requestId));
|
||||
|
||||
target.sendMessage(requestMessage);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.core.TeleportTracker;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
|
@ -25,7 +25,7 @@ public class TeleportDenyCommand {
|
|||
}
|
||||
|
||||
var playerUuid = context.getSource().getPlayer().getUuid();
|
||||
var playerRequests = RccServer.teleportRequests.get(playerUuid);
|
||||
var playerRequests = TeleportTracker.teleportRequests.get(playerUuid);
|
||||
|
||||
var request = playerRequests.pollLast();
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class TeleportDenyCommand {
|
|||
|
||||
var uuid = UuidArgumentType.getUuid(context, "uuid");
|
||||
var playerUuid = context.getSource().getPlayer().getUuid();
|
||||
var playerRequests = RccServer.teleportRequests.get(playerUuid);
|
||||
var playerRequests = TeleportTracker.teleportRequests.get(playerUuid);
|
||||
|
||||
var request = playerRequests.stream().filter(req -> req.requestId.equals(uuid)).findFirst().orElse(null);
|
||||
if (request == null) {
|
||||
|
@ -64,7 +64,7 @@ public class TeleportDenyCommand {
|
|||
dispatcher.register(literal("tprefuse").redirect(node));
|
||||
}
|
||||
|
||||
private static void execute(CommandContext<ServerCommandSource> context, TeleportAskCommand.TeleportRequest request) {
|
||||
private static void execute(CommandContext<ServerCommandSource> context, TeleportTracker.TeleportRequest request) {
|
||||
var source = context.getSource();
|
||||
request.expire();
|
||||
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
package cc.reconnected.server.trackers;
|
||||
package cc.reconnected.server.core;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.data.StateSaverAndLoader;
|
||||
import cc.reconnected.server.database.PlayerData;
|
||||
import cc.reconnected.server.events.PlayerActivityEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.event.player.*;
|
||||
import net.fabricmc.fabric.api.message.v1.ServerMessageEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||
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.TypedActionResult;
|
||||
|
||||
|
@ -22,7 +25,44 @@ public class AfkTracker {
|
|||
|
||||
private final HashMap<UUID, PlayerState> playerStates = new HashMap<>();
|
||||
|
||||
public AfkTracker() {
|
||||
private static final AfkTracker instance = new AfkTracker();
|
||||
public static AfkTracker getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
PlayerActivityEvents.AFK.register((player, server) -> {
|
||||
RccServer.LOGGER.info("{} is AFK. Active time: {} seconds.", player.getGameProfile().getName(), getInstance().getActiveTime(player));
|
||||
|
||||
var displayNameJson = Text.Serializer.toJson(player.getDisplayName());
|
||||
var displayName = JSONComponentSerializer.json().deserialize(displayNameJson);
|
||||
|
||||
var message = MiniMessage.miniMessage().deserialize(RccServer.CONFIG.afkMessage(),
|
||||
Placeholder.component("displayname", displayName),
|
||||
Placeholder.unparsed("username", player.getGameProfile().getName()),
|
||||
Placeholder.unparsed("uuid", player.getUuid().toString())
|
||||
);
|
||||
|
||||
RccServer.getInstance().broadcastMessage(server, message);
|
||||
});
|
||||
|
||||
PlayerActivityEvents.AFK_RETURN.register((player, server) -> {
|
||||
RccServer.LOGGER.info("{} is no longer AFK. Active time: {} seconds.", player.getGameProfile().getName(), getInstance().getActiveTime(player));
|
||||
|
||||
var displayNameJson = Text.Serializer.toJson(player.getDisplayName());
|
||||
var displayName = JSONComponentSerializer.json().deserialize(displayNameJson);
|
||||
|
||||
var message = MiniMessage.miniMessage().deserialize(RccServer.CONFIG.afkReturnMessage(),
|
||||
Placeholder.component("displayname", displayName),
|
||||
Placeholder.unparsed("username", player.getGameProfile().getName()),
|
||||
Placeholder.unparsed("uuid", player.getUuid().toString())
|
||||
);
|
||||
|
||||
RccServer.getInstance().broadcastMessage(server, message);
|
||||
});
|
||||
}
|
||||
|
||||
private AfkTracker() {
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
if (server.getTicks() % cycleDelay == 0) {
|
||||
updatePlayers(server);
|
||||
|
@ -83,7 +123,6 @@ public class AfkTracker {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
private void updatePlayer(ServerPlayerEntity player, MinecraftServer server) {
|
||||
var currentTick = server.getTicks();
|
||||
var playerState = playerStates.computeIfAbsent(player.getUuid(), uuid -> new PlayerState(player, currentTick));
|
||||
|
@ -202,5 +241,4 @@ public class AfkTracker {
|
|||
var worldPlayerData = StateSaverAndLoader.getPlayerState(player);
|
||||
return worldPlayerData.activeTime;
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/cc/reconnected/server/core/BackTracker.java
Normal file
27
src/main/java/cc/reconnected/server/core/BackTracker.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package cc.reconnected.server.core;
|
||||
|
||||
import cc.reconnected.server.events.PlayerTeleport;
|
||||
import cc.reconnected.server.struct.ServerPosition;
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BackTracker {
|
||||
public static final ConcurrentHashMap<UUID, ServerPosition> lastPlayerPositions = new ConcurrentHashMap<>();
|
||||
|
||||
public static void register() {
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||
BackTracker.lastPlayerPositions.remove(handler.getPlayer().getUuid());
|
||||
});
|
||||
|
||||
PlayerTeleport.EVENT.register((player, origin, destination) -> {
|
||||
lastPlayerPositions.put(player.getUuid(), origin);
|
||||
});
|
||||
|
||||
ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> {
|
||||
lastPlayerPositions.put(oldPlayer.getUuid(), new ServerPosition(oldPlayer));
|
||||
});
|
||||
}
|
||||
}
|
104
src/main/java/cc/reconnected/server/core/HttpApiServer.java
Normal file
104
src/main/java/cc/reconnected/server/core/HttpApiServer.java
Normal file
|
@ -0,0 +1,104 @@
|
|||
package cc.reconnected.server.core;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import cc.reconnected.server.RccServer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class HttpApiServer {
|
||||
private static HttpApiServer instance;
|
||||
|
||||
public static HttpApiServer getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static float currentTps = 0;
|
||||
private static float currentMspt = 0;
|
||||
private static int currentPlayerCount = 0;
|
||||
|
||||
public static void register() {
|
||||
if (!RccServer.CONFIG.enableHttpApi())
|
||||
return;
|
||||
|
||||
try {
|
||||
instance = new HttpApiServer();
|
||||
} catch (IOException e) {
|
||||
RccServer.LOGGER.error("Could not start HTTP API server", e);
|
||||
return;
|
||||
}
|
||||
new Thread(() -> instance.httpServer().start());
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register(server -> {
|
||||
RccServer.LOGGER.info("Stopping HTTP services");
|
||||
instance.httpServer().stop(0);
|
||||
});
|
||||
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
currentMspt = server.getTickTime();
|
||||
if (currentMspt != 0) {
|
||||
currentTps = Math.min(20, 1000 / currentMspt);
|
||||
}
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
currentPlayerCount = server.getCurrentPlayerCount() + 1;
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||
currentPlayerCount = server.getCurrentPlayerCount() - 1;
|
||||
});
|
||||
}
|
||||
|
||||
private final HttpServer server;
|
||||
|
||||
public HttpServer httpServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
private HttpApiServer() throws IOException {
|
||||
server = HttpServer.create(new InetSocketAddress(RccServer.CONFIG.httpPort()), 0);
|
||||
server.createContext("/tps", new TPSHandler());
|
||||
server.createContext("/mspt", new MSPTHandler());
|
||||
server.createContext("/player", new PlayerCountHandler());
|
||||
server.setExecutor(null);
|
||||
}
|
||||
|
||||
static class TPSHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
var tps = String.valueOf(currentTps);
|
||||
t.sendResponseHeaders(200, tps.length());
|
||||
var body = t.getResponseBody();
|
||||
body.write(tps.getBytes());
|
||||
body.close();
|
||||
}
|
||||
}
|
||||
|
||||
static class MSPTHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
var tps = String.valueOf(currentTps);
|
||||
t.sendResponseHeaders(200, tps.length());
|
||||
var body = t.getResponseBody();
|
||||
body.write(tps.getBytes());
|
||||
body.close();
|
||||
}
|
||||
}
|
||||
|
||||
static class PlayerCountHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
var tps = String.valueOf(currentPlayerCount);
|
||||
t.sendResponseHeaders(200, tps.length());
|
||||
var body = t.getResponseBody();
|
||||
body.write(tps.getBytes());
|
||||
body.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cc.reconnected.server.tablist;
|
||||
package cc.reconnected.server.core;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import eu.pb4.placeholders.api.PlaceholderContext;
|
|
@ -0,0 +1,82 @@
|
|||
package cc.reconnected.server.core;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.events.PlayerTeleport;
|
||||
import cc.reconnected.server.struct.ServerPosition;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
public class TeleportTracker {
|
||||
public static final ConcurrentHashMap<UUID, ConcurrentLinkedDeque<TeleportRequest>> teleportRequests = new ConcurrentHashMap<>();
|
||||
|
||||
public static void register() {
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
teleportRequests.forEach((recipient, requestList) -> {
|
||||
requestList.forEach(request -> {
|
||||
if (request.remainingTicks-- == 0) {
|
||||
requestList.remove(request);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||
teleportRequests.put(handler.getPlayer().getUuid(), new ConcurrentLinkedDeque<>());
|
||||
});
|
||||
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||
TeleportTracker.teleportRequests.remove(handler.getPlayer().getUuid());
|
||||
});
|
||||
}
|
||||
|
||||
public static Component makeButton(ComponentLike text, ComponentLike hoverText, String command) {
|
||||
return Component.empty()
|
||||
.append(Component.text("["))
|
||||
.append(text)
|
||||
.append(Component.text("]"))
|
||||
.color(NamedTextColor.AQUA)
|
||||
.hoverEvent(HoverEvent.showText(hoverText))
|
||||
.clickEvent(ClickEvent.runCommand(command));
|
||||
}
|
||||
|
||||
public static void teleport(ServerPlayerEntity sourcePlayer, ServerPlayerEntity targetPlayer) {
|
||||
PlayerTeleport.EVENT.invoker().teleport(sourcePlayer, new ServerPosition(sourcePlayer), new ServerPosition(targetPlayer));
|
||||
|
||||
sourcePlayer.teleport(
|
||||
targetPlayer.getServerWorld(),
|
||||
targetPlayer.getX(),
|
||||
targetPlayer.getY(),
|
||||
targetPlayer.getZ(),
|
||||
targetPlayer.getYaw(),
|
||||
targetPlayer.getPitch()
|
||||
);
|
||||
}
|
||||
|
||||
public static class TeleportRequest {
|
||||
public UUID requestId = UUID.randomUUID();
|
||||
public UUID player;
|
||||
public UUID target;
|
||||
public int remainingTicks;
|
||||
|
||||
public TeleportRequest(UUID player, UUID target) {
|
||||
this.player = player;
|
||||
this.target = target;
|
||||
// Seconds in config per 20 ticks
|
||||
this.remainingTicks = RccServer.CONFIG.teleportRequestTimeout() * 20;
|
||||
}
|
||||
|
||||
public void expire() {
|
||||
remainingTicks = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package cc.reconnected.server.events;
|
||||
|
||||
import cc.reconnected.server.struct.ServerPosition;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
public interface PlayerTeleport {
|
||||
Event<PlayerTeleport> EVENT = EventFactory.createArrayBacked(PlayerTeleport.class,
|
||||
(listeners) -> (player, origin, destination) -> {
|
||||
for (PlayerTeleport listener : listeners) {
|
||||
listener.teleport(player, origin, destination);
|
||||
}
|
||||
});
|
||||
|
||||
void teleport(ServerPlayerEntity player, ServerPosition origin, ServerPosition destination);
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package cc.reconnected.server.http;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import cc.reconnected.server.RccServer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class ServiceServer {
|
||||
private final HttpServer server;
|
||||
|
||||
public HttpServer httpServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
public ServiceServer() throws IOException {
|
||||
server = HttpServer.create(new InetSocketAddress(RccServer.CONFIG.httpPort()), 0);
|
||||
server.createContext("/tps", new TPSHandler());
|
||||
server.createContext("/mspt", new MSPTHandler());
|
||||
server.createContext("/player", new PlayerCountHandler());
|
||||
server.setExecutor(null);
|
||||
|
||||
var httpThread = new Thread(server::start);
|
||||
httpThread.start();
|
||||
}
|
||||
|
||||
static class TPSHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
var tps = String.valueOf(RccServer.getTPS());
|
||||
t.sendResponseHeaders(200, tps.length());
|
||||
var body = t.getResponseBody();
|
||||
body.write(tps.getBytes());
|
||||
body.close();
|
||||
}
|
||||
}
|
||||
|
||||
static class MSPTHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
var tps = String.valueOf(RccServer.getMSPT());
|
||||
t.sendResponseHeaders(200, tps.length());
|
||||
var body = t.getResponseBody();
|
||||
body.write(tps.getBytes());
|
||||
body.close();
|
||||
}
|
||||
}
|
||||
|
||||
static class PlayerCountHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
var tps = String.valueOf(RccServer.getPlayerCount());
|
||||
t.sendResponseHeaders(200, tps.length());
|
||||
var body = t.getResponseBody();
|
||||
body.write(tps.getBytes());
|
||||
body.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package cc.reconnected.server.struct;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import cc.reconnected.server.core.BackTracker;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class ServerPosition {
|
|||
|
||||
public void teleport(ServerPlayerEntity player) {
|
||||
var currentPosition = new ServerPosition(player);
|
||||
RccServer.lastPlayerPositions.put(player.getUuid(), currentPosition);
|
||||
BackTracker.lastPlayerPositions.put(player.getUuid(), currentPosition);
|
||||
|
||||
player.teleport(
|
||||
this.world,
|
||||
|
|
Loading…
Add table
Reference in a new issue