Add custom tab
This commit is contained in:
parent
5530b3b430
commit
325e52bc19
4 changed files with 125 additions and 0 deletions
|
@ -7,6 +7,7 @@ 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;
|
||||
|
@ -14,6 +15,7 @@ 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;
|
||||
|
@ -84,6 +86,16 @@ public class RccServer implements ModInitializer {
|
|||
INSTANCE = this;
|
||||
}
|
||||
|
||||
private volatile FabricServerAudiences adventure;
|
||||
|
||||
public FabricServerAudiences adventure() {
|
||||
FabricServerAudiences ret = this.adventure;
|
||||
if (ret == null) {
|
||||
throw new IllegalStateException("Tried to access Adventure without a running server!");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static final ConcurrentHashMap<UUID, ConcurrentLinkedDeque<TeleportAskCommand.TeleportRequest>> teleportRequests = new ConcurrentHashMap<>();
|
||||
public static final ConcurrentHashMap<UUID, ServerPosition> lastPlayerPositions = new ConcurrentHashMap<>();
|
||||
|
||||
|
@ -91,7 +103,11 @@ public class RccServer implements ModInitializer {
|
|||
public void onInitialize() {
|
||||
LOGGER.info("Starting rcc-server");
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(server -> this.adventure = FabricServerAudiences.of(server));
|
||||
ServerLifecycleEvents.SERVER_STOPPED.register(server -> this.adventure = null);
|
||||
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||
RccCommand.register(dispatcher, registryAccess, environment);
|
||||
AfkCommand.register(dispatcher, registryAccess, environment);
|
||||
TellCommand.register(dispatcher, registryAccess, environment);
|
||||
ReplyCommand.register(dispatcher, registryAccess, environment);
|
||||
|
@ -104,6 +120,8 @@ public class RccServer implements ModInitializer {
|
|||
GodCommand.register(dispatcher, registryAccess, environment);
|
||||
});
|
||||
|
||||
TabList.register();
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
luckPerms = LuckPermsProvider.get();
|
||||
afkTracker = new AfkTracker();
|
||||
|
|
|
@ -2,6 +2,9 @@ package cc.reconnected.server;
|
|||
|
||||
import io.wispforest.owo.config.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Config(name = "rcc-server-config", wrapperName = "RccServerConfig")
|
||||
public class RccServerConfigModel {
|
||||
public boolean enableHttpApi = true;
|
||||
|
@ -16,4 +19,13 @@ public class RccServerConfigModel {
|
|||
public String tellMessageSpy = "\uD83D\uDC41 <gray>[<source> → <target>]</gray> <message>";
|
||||
|
||||
public int teleportRequestTimeout = 120;
|
||||
|
||||
public boolean enableTabList = true;
|
||||
public ArrayList<String> tabHeader = new ArrayList<>(List.of(
|
||||
"<gradient:#DEDE6C:#CC4C4C:{phase}><st> </st></gradient>"
|
||||
));
|
||||
|
||||
public ArrayList<String> tabFooter = new ArrayList<>(List.of(
|
||||
"<gradient:#DEDE6C:#CC4C4C:{phase}><st> </st></gradient>"
|
||||
));
|
||||
}
|
||||
|
|
36
src/main/java/cc/reconnected/server/commands/RccCommand.java
Normal file
36
src/main/java/cc/reconnected/server/commands/RccCommand.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package cc.reconnected.server.commands;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
public class RccCommand {
|
||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) {
|
||||
var rootCommand = literal("rcc")
|
||||
.requires(Permissions.require("rcc.command.afk", 3))
|
||||
.then(literal("reload")
|
||||
.executes(context -> {
|
||||
context.getSource().sendFeedback(() -> Text.of("Reloading RCC config..."), true);
|
||||
|
||||
try {
|
||||
RccServer.CONFIG.load();
|
||||
} catch(Exception e) {
|
||||
RccServer.LOGGER.error("Failed to load RCC config", e);
|
||||
context.getSource().sendFeedback(() -> Text.of("Failed to load RCC config. Check console for more info."), true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
context.getSource().sendFeedback(() -> Text.of("Reloaded RCC config"), true);
|
||||
|
||||
return 1;
|
||||
}));
|
||||
|
||||
dispatcher.register(rootCommand);
|
||||
}
|
||||
}
|
59
src/main/java/cc/reconnected/server/tablist/TabList.java
Normal file
59
src/main/java/cc/reconnected/server/tablist/TabList.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
package cc.reconnected.server.tablist;
|
||||
|
||||
import cc.reconnected.server.RccServer;
|
||||
import eu.pb4.placeholders.api.PlaceholderContext;
|
||||
import eu.pb4.placeholders.api.Placeholders;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class TabList {
|
||||
public static void register() {
|
||||
if (!RccServer.CONFIG.enableTabList())
|
||||
return;
|
||||
|
||||
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||
var phase = (Math.sin((server.getTicks() * Math.PI) / 20) + 1) / 2d;
|
||||
var minimessage = MiniMessage.miniMessage();
|
||||
|
||||
server.getPlayerManager().getPlayerList().forEach(player -> {
|
||||
var playerContext = PlaceholderContext.of(player);
|
||||
Component headerComponent = Component.empty();
|
||||
for (int i = 0; i < RccServer.CONFIG.tabHeader().size(); i++) {
|
||||
var line = RccServer.CONFIG.tabHeader().get(i);
|
||||
line = line.replace("{phase}", String.valueOf(phase));
|
||||
if (i > 0) {
|
||||
headerComponent = headerComponent.appendNewline();
|
||||
}
|
||||
|
||||
headerComponent = headerComponent.append(minimessage.deserialize(line));
|
||||
}
|
||||
|
||||
Component footerComponent = Component.empty();
|
||||
for (int i = 0; i < RccServer.CONFIG.tabFooter().size(); i++) {
|
||||
var line = RccServer.CONFIG.tabFooter().get(i);
|
||||
line = line.replace("{phase}", String.valueOf(phase));
|
||||
if (i > 0) {
|
||||
footerComponent = footerComponent.appendNewline();
|
||||
}
|
||||
|
||||
footerComponent = footerComponent.append(minimessage.deserialize(line));
|
||||
}
|
||||
|
||||
var parsedHeader = Placeholders.parseText(toText(headerComponent), playerContext);
|
||||
var parsedFooter = Placeholders.parseText(toText(footerComponent), playerContext);
|
||||
|
||||
var audience = RccServer.getInstance().adventure().player(player.getUuid());
|
||||
audience.sendPlayerListHeaderAndFooter(parsedHeader, parsedFooter);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static Text toText(Component component) {
|
||||
var json = JSONComponentSerializer.json().serialize(component);
|
||||
return Text.Serializer.fromJson(json);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue