diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java b/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java
index 2e289f7..8999949 100644
--- a/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java
+++ b/src/main/java/com/github/zly2006/carpetslsaddition/ServerMain.java
@@ -2,6 +2,7 @@ package com.github.zly2006.carpetslsaddition;
import carpet.CarpetExtension;
import carpet.CarpetServer;
+import com.github.zly2006.carpetslsaddition.command.BotAllCommand;
import com.github.zly2006.carpetslsaddition.command.BotCommand;
import com.github.zly2006.carpetslsaddition.command.HatCommand;
import com.github.zly2006.carpetslsaddition.command.SitCommand;
@@ -81,6 +82,7 @@ public class ServerMain implements ModInitializer, CarpetExtension {
HatCommand.register(dispatcher);
SitCommand.register(dispatcher);
BotCommand.register(dispatcher);
+ BotAllCommand.register(dispatcher);
LOGGER.info("[SLSA] commands registered: hat/sit/bot");
} catch (Throwable t) {
LOGGER.error("[SLSA] failed to register commands", t);
diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/command/BotAllCommand.java b/src/main/java/com/github/zly2006/carpetslsaddition/command/BotAllCommand.java
new file mode 100644
index 0000000..d0b6afe
--- /dev/null
+++ b/src/main/java/com/github/zly2006/carpetslsaddition/command/BotAllCommand.java
@@ -0,0 +1,84 @@
+package com.github.zly2006.carpetslsaddition.command;
+
+import carpet.patches.EntityPlayerMPFake;
+import carpet.utils.Messenger;
+import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
+import com.github.zly2006.carpetslsaddition.util.access.SLSBotAccessor;
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerPlayer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static net.minecraft.commands.Commands.literal;
+
+/**
+ * /botall —— 批量控制本模组生成的所有假人。
+ *
+ *
与 {@link BotCommand} 的区别:{@code /bot } 操作单个指定玩家,
+ * 而 {@code /botall} 操作所有由本模组(Carpet SLS Addition)生成的假人(即 isBot() 为 true 的 EntityPlayerMPFake)。
+ */
+public class BotAllCommand {
+
+ public static void register(CommandDispatcher dispatcher) {
+ LiteralArgumentBuilder command = literal("botall")
+ .requires(source -> source.hasPermission(4) || me.lucko.fabric.api.permissions.v0.Permissions.check(source, "slsaddition.command.bot"))
+ .then(literal("sit").executes(BotAllCommand::sitAll))
+ .then(literal("stand").executes(BotAllCommand::standAll));
+ dispatcher.register(command);
+ }
+
+ /** 收集所有本模组生成的假人。 */
+ private static List collectBots(CommandSourceStack source) {
+ MinecraftServer server = source.getServer();
+ List bots = new ArrayList<>();
+ for (ServerPlayer player : server.getPlayerList().getPlayers()) {
+ if (player instanceof EntityPlayerMPFake && ((SLSBotAccessor) player).carpet_SLS_Addition$isBot()) {
+ bots.add(player);
+ }
+ }
+ return bots;
+ }
+
+ /** 批量坐下。 */
+ private static int sitAll(com.mojang.brigadier.context.CommandContext context) {
+ if (!SLSCarpetSettings.canUseSitCommand) {
+ Messenger.m(context.getSource(), "r 坐下功能未启用(canUseSitCommand)");
+ return 0;
+ }
+ List bots = collectBots(context.getSource());
+ int ok = 0;
+ for (ServerPlayer bot : bots) {
+ if (SitCommand.sitPlayer(bot)) {
+ ok++;
+ }
+ }
+ final int done = ok;
+ context.getSource().sendSuccess(
+ () -> net.minecraft.network.chat.Component.literal(
+ "[SLSA] 已让 " + done + "/" + bots.size() + " 个假人坐下"),
+ false);
+ return ok;
+ }
+
+ /** 批量站起(下坐骑)。 */
+ private static int standAll(com.mojang.brigadier.context.CommandContext context) {
+ List bots = collectBots(context.getSource());
+ int ok = 0;
+ for (ServerPlayer bot : bots) {
+ if (bot.getVehicle() != null) {
+ bot.stopRiding();
+ ok++;
+ }
+ }
+ final int done = ok;
+ context.getSource().sendSuccess(
+ () -> net.minecraft.network.chat.Component.literal(
+ "[SLSA] 已让 " + done + "/" + bots.size() + " 个假人站起"),
+ false);
+ return ok;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/zly2006/carpetslsaddition/command/SitCommand.java b/src/main/java/com/github/zly2006/carpetslsaddition/command/SitCommand.java
index 5406532..13aae54 100644
--- a/src/main/java/com/github/zly2006/carpetslsaddition/command/SitCommand.java
+++ b/src/main/java/com/github/zly2006/carpetslsaddition/command/SitCommand.java
@@ -20,21 +20,27 @@ public class SitCommand {
if (player == null) {
return 0;
}
-
- if (player.getVehicle() != null || !player.onGround()) { // 防止错误的坐下行为
- return 1;
- }
-
- ServerLevel world = (ServerLevel) player.level();
-
- ArmorStand armorStandEntity = new ArmorStand(world, player.getX(), player.getY(), player.getZ());
- ((SitEntity) armorStandEntity).setSitEntity(true);
- world.addFreshEntity(armorStandEntity);
- player.setShiftKeyDown(false);
- player.startRiding(armorStandEntity);
-
+ sitPlayer(player);
return 1;
})
);
}
+
+ /**
+ * 让指定玩家原地坐下(生成一个标记为 SitEntity 的 ArmorStand 并骑乘)。
+ *
+ * @return 若成功坐下返回 true,否则返回 false(如已在骑乘/不在地面)。
+ */
+ public static boolean sitPlayer(ServerPlayer player) {
+ if (player.getVehicle() != null || !player.onGround()) { // 防止错误的坐下行为
+ return false;
+ }
+ ServerLevel world = (ServerLevel) player.level();
+ ArmorStand armorStandEntity = new ArmorStand(world, player.getX(), player.getY(), player.getZ());
+ ((SitEntity) armorStandEntity).setSitEntity(true);
+ world.addFreshEntity(armorStandEntity);
+ player.setShiftKeyDown(false);
+ player.startRiding(armorStandEntity);
+ return true;
+ }
}
\ No newline at end of file