feat: 加slsBoardEnabled规则作榜单总开关(服务端规则控制客户端命令)
BoardTogglePayload同步开关状态;客户端/slsboard检查enabled,未开启则拒绝。ServerMain加轮询线程检测规则变化。
This commit is contained in:
1 parent
7366a8b244
commit
3fde7e2c1b
8 files changed
+99
-10
No files matched your search
@@ -80,4 +80,7 @@ public class SLSCarpetSettings {
|
||||
|
||||
@Rule(categories = {SLSA, RuleCategory.FEATURE})
|
||||
public static boolean stackableVehicles = false;
|
||||
|
||||
@Rule(categories = {SLSA, RuleCategory.FEATURE})
|
||||
public static boolean slsBoardEnabled = false;
|
||||
}
|
||||
@@ -44,6 +44,7 @@ public class ServerMain implements ModInitializer, CarpetExtension {
|
||||
INSTANCE = this;
|
||||
CarpetServer.manageExtension(this);
|
||||
com.github.zly2006.carpetslsaddition.net.BoardSyncPayload.register();
|
||||
com.github.zly2006.carpetslsaddition.net.BoardTogglePayload.register();
|
||||
// 玩家加入时同步榜单
|
||||
net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents.JOIN.register(
|
||||
(handler, sender, srv) ->
|
||||
@@ -60,6 +61,25 @@ public class ServerMain implements ModInitializer, CarpetExtension {
|
||||
ServerMain.server = server;
|
||||
com.github.zly2006.carpetslsaddition.util.BotListManager.load();
|
||||
com.github.zly2006.carpetslsaddition.util.BoardSyncManager.syncToAll(server);
|
||||
startBoardWatcher(server);
|
||||
}
|
||||
|
||||
/** 每秒检测 slsBoardEnabled 规则变化并同步给客户端。 */
|
||||
private void startBoardWatcher(MinecraftServer server) {
|
||||
Thread t = new Thread(() -> {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
try {
|
||||
com.github.zly2006.carpetslsaddition.util.BoardSyncManager.tick(server);
|
||||
Thread.sleep(1000L);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.debug("[SLSA] board watcher error: {}", ex.toString());
|
||||
}
|
||||
}
|
||||
}, "SLSA-BoardWatcher");
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.zly2006.carpetslsaddition.client;
|
||||
|
||||
import com.github.zly2006.carpetslsaddition.net.BoardSyncPayload;
|
||||
import com.github.zly2006.carpetslsaddition.net.BoardTogglePayload;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
@@ -38,24 +39,27 @@ public class BoardClient implements ClientModInitializer {
|
||||
context.client().execute(() -> BoardClientState.setBoard(payload.board(), entries));
|
||||
});
|
||||
|
||||
// 接收开关状态
|
||||
ClientPlayNetworking.registerGlobalReceiver(BoardTogglePayload.TYPE, (payload, context) -> {
|
||||
context.client().execute(() -> BoardClientState.enabled = payload.enabled());
|
||||
});
|
||||
|
||||
// 2) /slsboard 命令(纯客户端,非 OP 也能用)
|
||||
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
|
||||
dispatcher.register(
|
||||
ClientCommands.literal("slsboard")
|
||||
.then(ClientCommands.literal("deaths")
|
||||
.executes(c -> { BoardClientState.toggle("deaths"); feedback(c.getSource()); return 1; }))
|
||||
.executes(c -> run(c.getSource(), () -> BoardClientState.toggle("deaths"))))
|
||||
.then(ClientCommands.literal("mined")
|
||||
.executes(c -> { BoardClientState.toggle("mined"); feedback(c.getSource()); return 1; }))
|
||||
.executes(c -> run(c.getSource(), () -> BoardClientState.toggle("mined"))))
|
||||
.then(ClientCommands.literal("off")
|
||||
.executes(c -> { BoardClientState.set(""); feedback(c.getSource()); return 1; }))
|
||||
.executes(c -> run(c.getSource(), () -> BoardClientState.set(""))))
|
||||
.then(ClientCommands.argument("board", StringArgumentType.word())
|
||||
.suggests((c, b) -> SharedSuggestionProvider.suggest(
|
||||
new String[]{"deaths", "mined", "off"}, b))
|
||||
.executes(c -> {
|
||||
String v = StringArgumentType.getString(c, "board");
|
||||
BoardClientState.set("off".equals(v) ? "" : v);
|
||||
feedback(c.getSource());
|
||||
return 1;
|
||||
return run(c.getSource(), () -> BoardClientState.set("off".equals(v) ? "" : v));
|
||||
}))
|
||||
);
|
||||
});
|
||||
@@ -64,8 +68,15 @@ public class BoardClient implements ClientModInitializer {
|
||||
HudElementRegistry.addLast(HUD_ID, new BoardHudElement());
|
||||
}
|
||||
|
||||
private static void feedback(FabricClientCommandSource source) {
|
||||
/** 统一的命令入口:先检查服务端开关,再执行动作。 */
|
||||
private static int run(FabricClientCommandSource source, Runnable action) {
|
||||
if (!BoardClientState.enabled) {
|
||||
source.sendError(Component.literal("[SLSA] 榜单功能未开启(服务端 /carpet slsBoardEnabled true)"));
|
||||
return 0;
|
||||
}
|
||||
action.run();
|
||||
String d = BoardClientState.displaying;
|
||||
source.sendFeedback(Component.literal("[SLSA] 榜单显示:" + (d.isEmpty() ? "关闭" : d)));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@ public final class BoardClientState {
|
||||
/** 当前显示的榜:"" / "deaths" / "mined"。 */
|
||||
public static volatile String displaying = "";
|
||||
|
||||
/** 服务端 Carpet 规则 slsBoardEnabled 的状态(未开启则禁止使用)。 */
|
||||
public static volatile boolean enabled = false;
|
||||
|
||||
private static volatile List<Entry> deaths = Collections.emptyList();
|
||||
private static volatile List<Entry> mined = Collections.emptyList();
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.github.zly2006.carpetslsaddition.net;
|
||||
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
|
||||
/**
|
||||
* 服务端 → 客户端:榜单功能总开关状态(对应 Carpet 规则 {@code slsBoardEnabled})。
|
||||
*
|
||||
* <p>规则变化时下发;客户端收到后决定 {@code /slsboard} 是否可用。
|
||||
*/
|
||||
public record BoardTogglePayload(boolean enabled) implements CustomPacketPayload {
|
||||
|
||||
public static final CustomPacketPayload.Type<BoardTogglePayload> TYPE =
|
||||
CustomPacketPayload.createType("slsa:board_toggle");
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, BoardTogglePayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL, BoardTogglePayload::enabled,
|
||||
BoardTogglePayload::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public CustomPacketPayload.Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry.clientboundPlay().register(TYPE, CODEC);
|
||||
}
|
||||
}
|
||||
@@ -61,12 +61,18 @@ public final class BoardSyncManager {
|
||||
return list;
|
||||
}
|
||||
|
||||
/** 把两个榜单都同步给某玩家。 */
|
||||
/** 把两个榜单 + 开关状态同步给某玩家。 */
|
||||
public static void syncTo(ServerPlayer player) {
|
||||
MinecraftServer server = ServerMain.server;
|
||||
if (server == null) {
|
||||
return;
|
||||
}
|
||||
boolean enabled = com.github.zly2006.carpetslsaddition.SLSCarpetSettings.slsBoardEnabled;
|
||||
// 先发开关状态
|
||||
ServerPlayNetworking.send(player, new com.github.zly2006.carpetslsaddition.net.BoardTogglePayload(enabled));
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
ServerPlayNetworking.send(player, new BoardSyncPayload(BOARD_DEATHS, buildBoard(server, BOARD_DEATHS)));
|
||||
ServerPlayNetworking.send(player, new BoardSyncPayload(BOARD_MINED, buildBoard(server, BOARD_MINED)));
|
||||
}
|
||||
@@ -77,4 +83,15 @@ public final class BoardSyncManager {
|
||||
syncTo(player);
|
||||
}
|
||||
}
|
||||
|
||||
private static volatile Boolean lastEnabled = null;
|
||||
|
||||
/** 由轮询线程每秒调用:规则值变化时同步给所有玩家。 */
|
||||
public static void tick(MinecraftServer server) {
|
||||
boolean now = com.github.zly2006.carpetslsaddition.SLSCarpetSettings.slsBoardEnabled;
|
||||
if (lastEnabled == null || lastEnabled != now) {
|
||||
lastEnabled = now;
|
||||
syncToAll(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user