package com.tiedup.remake.commands; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.tiedup.remake.cells.CampOwnership; import com.tiedup.remake.cells.CellDataV2; import com.tiedup.remake.cells.CellRegistryV2; import com.tiedup.remake.prison.PrisonerManager; import com.tiedup.remake.prison.PrisonerRecord; import java.util.List; import java.util.UUID; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.EntityArgument; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; /** * Debug commands for the unified captivity system. * * Commands: * /tiedup debug prisoner - Show captivity state for a player * /tiedup debug validate - Validate captivity system consistency * /tiedup debug repair - Repair inconsistencies (WARNING: modifies data) * /tiedup debug camp - Show camp info and indexed cells */ public class CaptivityDebugCommand { /** * Create the /tiedup debug command tree. */ public static LiteralArgumentBuilder< CommandSourceStack > createDebugCommand() { return Commands.literal("debug") .requires(CommandHelper.REQUIRES_OP) // Admin only // /tiedup debug prisoner .then( Commands.literal("prisoner").then( Commands.argument( "player", EntityArgument.player() ).executes(CaptivityDebugCommand::debugPrisoner) ) ) // /tiedup debug validate .then( Commands.literal("validate").executes( CaptivityDebugCommand::validateSystem ) ) // /tiedup debug repair .then( Commands.literal("repair").executes( CaptivityDebugCommand::repairSystem ) ) // /tiedup debug camp .then( Commands.literal("camp").then( Commands.argument( "campIdPrefix", StringArgumentType.string() ).executes(CaptivityDebugCommand::debugCamp) ) ); } /** * Show captivity state for a player. * /tiedup debug prisoner */ private static int debugPrisoner(CommandContext ctx) { try { ServerPlayer target = EntityArgument.getPlayer(ctx, "player"); ServerLevel level = target.serverLevel(); PrisonerManager manager = PrisonerManager.get(level); PrisonerRecord record = manager.getRecord(target.getUUID()); StringBuilder debugInfo = new StringBuilder(); debugInfo .append("Player: ") .append(target.getName().getString()) .append("\n"); debugInfo.append("State: ").append(record.getState()).append("\n"); debugInfo .append("Camp ID: ") .append(record.getCampId()) .append("\n"); debugInfo .append("Cell ID: ") .append(record.getCellId()) .append("\n"); debugInfo .append("Captor ID: ") .append(record.getCaptorId()) .append("\n"); debugInfo .append("Protection Expiry: ") .append(record.getProtectionExpiry()) .append("\n"); debugInfo .append("Is Protected: ") .append(record.isProtected(level.getGameTime())) .append("\n"); debugInfo .append("Is Captive: ") .append(record.isCaptive()) .append("\n"); // Send debug info to command executor ctx .getSource() .sendSuccess( () -> Component.translatable( "command.tiedup.debug.prisoner_header" ).append(Component.literal("\n" + debugInfo)).withStyle(ChatFormatting.YELLOW), false ); return 1; // Success } catch (Exception e) { ctx .getSource() .sendFailure( Component.translatable("command.tiedup.debug.error", e.getMessage()).withStyle( ChatFormatting.RED ) ); return 0; // Failure } } /** * Validate captivity system consistency. * /tiedup debug validate * NOTE: CaptivitySystemValidator was removed. This now shows a summary of the prison system. */ private static int validateSystem(CommandContext ctx) { try { ServerLevel level = ctx.getSource().getLevel(); ctx .getSource() .sendSuccess( () -> Component.translatable( "command.tiedup.debug.validate_checking" ).withStyle(ChatFormatting.YELLOW), true ); // Show PrisonerManager stats instead PrisonerManager manager = PrisonerManager.get(level); String debugInfo = manager.toDebugString(); ctx .getSource() .sendSuccess( () -> Component.literal(debugInfo).withStyle(ChatFormatting.GREEN), true ); return 1; // Success } catch (Exception e) { ctx .getSource() .sendFailure( Component.translatable( "command.tiedup.debug.error", e.getMessage() ).withStyle(ChatFormatting.RED) ); return 0; // Failure } } /** * Repair captivity system inconsistencies. * /tiedup debug repair * NOTE: CaptivitySystemValidator was removed. This command is now a placeholder. */ private static int repairSystem(CommandContext ctx) { try { ctx .getSource() .sendSuccess( () -> Component.translatable( "command.tiedup.debug.repair_simplified" ).withStyle(ChatFormatting.YELLOW), true ); ctx .getSource() .sendSuccess( () -> Component.translatable( "command.tiedup.debug.repair_auto" ).withStyle(ChatFormatting.GREEN), true ); return 1; // Success } catch (Exception e) { ctx .getSource() .sendFailure( Component.translatable("command.tiedup.debug.error", e.getMessage()).withStyle( ChatFormatting.RED ) ); return 0; // Failure } } /** * Debug camp information and indexed cells. * /tiedup debug camp */ private static int debugCamp(CommandContext ctx) { try { ServerLevel level = ctx.getSource().getLevel(); String campIdPrefix = StringArgumentType.getString( ctx, "campIdPrefix" ); CampOwnership ownership = CampOwnership.get(level); CellRegistryV2 cellRegistry = CellRegistryV2.get(level); // Find camps matching prefix UUID matchingCamp = null; for (CampOwnership.CampData camp : ownership.getAllCamps()) { String campIdStr = camp.getCampId().toString(); if (campIdStr.startsWith(campIdPrefix)) { matchingCamp = camp.getCampId(); break; } } if (matchingCamp == null) { ctx .getSource() .sendFailure( Component.translatable( "command.tiedup.debug.camp_not_found", campIdPrefix ).withStyle(ChatFormatting.RED) ); return 0; } // Get camp info CampOwnership.CampData campData = ownership.getCamp(matchingCamp); StringBuilder sb = new StringBuilder(); sb.append( String.format( "=== Camp %s ===\n", matchingCamp.toString().substring(0, 8) ) ); sb.append(String.format("Trader: %s\n", campData.getTraderUUID())); sb.append(String.format("Maid: %s\n", campData.getMaidUUID())); sb.append(String.format("Alive: %s\n", campData.isAlive())); sb.append(String.format("Center: %s\n", campData.getCenter())); // Get indexed cells List cells = cellRegistry.getCellsByCamp(matchingCamp); sb.append( String.format("\n=== Indexed Cells (%d) ===\n", cells.size()) ); if (cells.isEmpty()) { sb.append("⚠ NO CELLS INDEXED for this camp!\n"); } else { for (CellDataV2 cell : cells.subList( 0, Math.min(cells.size(), 10) )) { sb.append( String.format( "- Cell %s at %s (type=%s, owner=%s, interior=%d, walls=%d)\n", cell.getId().toString().substring(0, 8), cell.getCorePos().toShortString(), cell.isCampOwned() ? "CAMP" : "PLAYER", cell.getOwnerId() != null ? cell.getOwnerId().toString().substring(0, 8) : "null", cell.getInteriorBlocks().size(), cell.getWallBlocks().size() ) ); } if (cells.size() > 10) { sb.append( String.format("... and %d more\n", cells.size() - 10) ); } } final String campInfo = sb.toString(); ctx .getSource() .sendSuccess( () -> Component.literal(campInfo).withStyle( ChatFormatting.YELLOW ), false ); return 1; // Success } catch (Exception e) { ctx .getSource() .sendFailure( Component.translatable("command.tiedup.debug.error", e.getMessage()).withStyle( ChatFormatting.RED ) ); return 0; // Failure } } }