package com.tiedup.remake.commands; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import com.tiedup.remake.client.gltf.diagnostic.GlbDiagnostic; import com.tiedup.remake.client.gltf.diagnostic.GlbDiagnosticRegistry; import com.tiedup.remake.client.gltf.diagnostic.GlbValidationResult; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; /** * Client-only command: /tiedup validate [item_id] * * Displays GLB validation diagnostics in chat. * Registered via {@link net.minecraftforge.client.event.RegisterClientCommandsEvent} * on the FORGE bus (never on the server). */ @OnlyIn(Dist.CLIENT) public final class ValidateGlbCommand { private ValidateGlbCommand() {} public static void register(CommandDispatcher dispatcher) { dispatcher.register( Commands.literal("tiedup") .then(Commands.literal("validate") .executes(ctx -> validateAll(ctx.getSource())) .then(Commands.argument("item_id", StringArgumentType.string()) .executes(ctx -> validateOne( ctx.getSource(), StringArgumentType.getString(ctx, "item_id") )) ) ) ); } private static int validateAll(CommandSourceStack source) { var all = GlbDiagnosticRegistry.getAll(); if (all.isEmpty()) { source.sendSuccess( () -> Component.literal( "[TiedUp] No GLB validation results. " + "Try reloading resources (F3+T)." ).withStyle(ChatFormatting.YELLOW), false ); return 0; } int totalDiags = 0; for (GlbValidationResult result : all) { if (result.diagnostics().isEmpty()) continue; source.sendSuccess( () -> Component.literal("--- " + result.source() + " ---") .withStyle( result.passed() ? ChatFormatting.GREEN : ChatFormatting.RED ), false ); for (GlbDiagnostic d : result.diagnostics()) { source.sendSuccess(() -> formatDiagnostic(d), false); totalDiags++; } } int count = totalDiags; source.sendSuccess( () -> Component.literal( "[TiedUp] " + count + " diagnostic(s) across " + GlbDiagnosticRegistry.size() + " GLBs" ).withStyle(ChatFormatting.GRAY), false ); return 1; } private static int validateOne(CommandSourceStack source, String itemId) { ResourceLocation loc = ResourceLocation.tryParse(itemId); if (loc == null) { source.sendFailure( Component.literal("Invalid resource location: " + itemId) ); return 0; } for (GlbValidationResult result : GlbDiagnosticRegistry.getAll()) { boolean match = result.source().equals(loc); if (!match) { match = result.diagnostics().stream() .anyMatch(d -> loc.equals(d.itemDef())); } if (match) { source.sendSuccess( () -> Component.literal("--- " + result.source() + " ---") .withStyle( result.passed() ? ChatFormatting.GREEN : ChatFormatting.RED ), false ); for (GlbDiagnostic d : result.diagnostics()) { source.sendSuccess(() -> formatDiagnostic(d), false); } return 1; } } source.sendFailure( Component.literal("No validation results for: " + itemId) ); return 0; } private static Component formatDiagnostic(GlbDiagnostic d) { ChatFormatting color = switch (d.severity()) { case ERROR -> ChatFormatting.RED; case WARNING -> ChatFormatting.YELLOW; case INFO -> ChatFormatting.GRAY; }; return Component.literal( " [" + d.severity() + "] " + d.code() + ": " + d.message() ).withStyle(color); } }