diff --git a/src/main/java/com/livingworld/commands/LivingWorldCommandRoot.java b/src/main/java/com/livingworld/commands/LivingWorldCommandRoot.java new file mode 100644 index 0000000..4faf132 --- /dev/null +++ b/src/main/java/com/livingworld/commands/LivingWorldCommandRoot.java @@ -0,0 +1,94 @@ +package com.livingworld.commands; + +import java.util.stream.Collectors; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.IntegerArgumentType; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; + +import com.livingworld.core.simulation.SimulationManager; +import com.livingworld.modules.ModuleRegistry; +import com.livingworld.regions.RegionManager; + +/** + * Registers the root Living World debug command tree. + */ +public final class LivingWorldCommandRoot { + + private static final int OPERATOR_PERMISSION_LEVEL = 2; + + private LivingWorldCommandRoot() { + } + + public static void register( + CommandDispatcher dispatcher, + RegionManager regionManager, + ModuleRegistry moduleRegistry, + SimulationManager simulationManager) { + if (dispatcher == null) { + throw new IllegalArgumentException("dispatcher must not be null"); + } + if (regionManager == null) { + throw new IllegalArgumentException("regionManager must not be null"); + } + if (moduleRegistry == null) { + throw new IllegalArgumentException("moduleRegistry must not be null"); + } + if (simulationManager == null) { + throw new IllegalArgumentException("simulationManager must not be null"); + } + + dispatcher.register(Commands.literal("lw") + .requires(source -> source.hasPermission(OPERATOR_PERMISSION_LEVEL)) + .then(Commands.literal("status") + .executes(context -> showStatus( + context.getSource(), regionManager, moduleRegistry, simulationManager))) + .then(Commands.literal("region") + .then(Commands.literal("info") + .executes(context -> placeholder( + context.getSource(), "Region inspection is not connected yet.")))) + .then(Commands.literal("modules") + .then(Commands.literal("list") + .executes(context -> listModules( + context.getSource(), moduleRegistry)))) + .then(Commands.literal("simulate") + .then(Commands.argument("ticks", IntegerArgumentType.integer(1, 1000)) + .executes(context -> placeholder( + context.getSource(), "Forced simulation is not connected yet."))))); + } + + private static int showStatus( + CommandSourceStack source, + RegionManager regionManager, + ModuleRegistry moduleRegistry, + SimulationManager simulationManager) { + String message = "Living World status: activeRegions=" + regionManager.getActiveRegions().size() + + ", enabledModules=" + moduleRegistry.getEnabledModules().size() + + ", simulationTick=" + simulationManager.getSimulationTickCounter(); + source.sendSuccess(() -> Component.literal(message), false); + return 1; + } + + private static int listModules( + CommandSourceStack source, + ModuleRegistry moduleRegistry) { + String moduleIds = moduleRegistry.getAllModules().stream() + .map(module -> module.getModuleId() + + (module.getMetadata().defaultEnabled() ? " [enabled]" : " [disabled]")) + .collect(Collectors.joining(", ")); + if (moduleIds.isEmpty()) { + moduleIds = "none"; + } + String message = "Living World modules: " + moduleIds; + source.sendSuccess(() -> Component.literal(message), false); + return 1; + } + + private static int placeholder(CommandSourceStack source, String message) { + source.sendFailure(Component.literal(message)); + return 0; + } +}