diff options
8 files changed, 328 insertions, 528 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index c5f4317e..e530809a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -37,7 +37,6 @@ import io.github.moulberry.notenoughupdates.commands.profile.CataCommand; import io.github.moulberry.notenoughupdates.commands.profile.PeekCommand; import io.github.moulberry.notenoughupdates.commands.profile.PvCommand; import io.github.moulberry.notenoughupdates.commands.profile.ViewProfileCommand; -import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour; import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; import io.github.moulberry.notenoughupdates.miscgui.NEUOverlayPlacements; @@ -47,12 +46,6 @@ import net.minecraftforge.fml.common.Loader; public class Commands { public Commands() { - // Help Commands - - // Dev Commands - ClientCommandHandler.instance.registerCommand(new PackDevCommand()); - ClientCommandHandler.instance.registerCommand(new DiagCommand()); - // Profile Commands ClientCommandHandler.instance.registerCommand(new PeekCommand()); ClientCommandHandler.instance.registerCommand(new ViewProfileCommand()); @@ -76,8 +69,5 @@ public class Commands { ClientCommandHandler.instance.registerCommand(new CalendarCommand()); ClientCommandHandler.instance.registerCommand(new UpdateCommand(NotEnoughUpdates.INSTANCE)); ClientCommandHandler.instance.registerCommand(new PronounsCommand()); - - // Fairy Soul Commands - ClientCommandHandler.instance.registerCommand(new FairySouls.FairySoulsCommand()); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java deleted file mode 100644 index fb546efb..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.commands.dev; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver; -import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver; -import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.EnumChatFormatting; - -public class DiagCommand extends ClientCommandBase { - public DiagCommand() { - super("neudiag"); - } - - private static final String USAGE_TEXT = EnumChatFormatting.WHITE + - "Usage: /neudiag <metal | wishing | debug>\n\n" + - "/neudiag metal Metal Detector Solver diagnostics\n" + - " <no sub-command> Show current solution diags\n" + - " center=<off | on> Disable / enable using center\n" + - "/neudiag wishing Wishing Compass Solver diagnostics\n" + - "/neudiag debug\n" + - " <no sub-command> Show all enabled flags\n" + - " <list> Show all flags\n"+ - " <enable | disable> <flag> Enable/disable flag\n"; - - private void showUsage(ICommandSender sender) { - sender.addChatMessage(new ChatComponentText(USAGE_TEXT)); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (args.length == 0) { - showUsage(sender); - return; - } - - String command = args[0].toLowerCase(); - switch (command) { - case "metal": - if (args.length == 1) { - CrystalMetalDetectorSolver.logDiagnosticData(true); - return; - } - - String subCommand = args[1].toLowerCase(); - if (subCommand.equals("center=off")) { - CrystalMetalDetectorSolver.setDebugDoNotUseCenter(true); - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "Center coordinates-based solutions disabled")); - } else if (subCommand.equals("center=on")) { - CrystalMetalDetectorSolver.setDebugDoNotUseCenter(false); - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "Center coordinates-based solutions enabled")); - } else { - showUsage(sender); - return; - } - - break; - case "wishing": - CrystalWishingCompassSolver.getInstance().logDiagnosticData(true); - break; - case "debug": - if (args.length > 1) { - boolean enablingFlag = true; - String action = args[1]; - switch (action) { - case "list": - sender.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "Here are all flags:\n" + NEUDebugFlag.getFlagList())); - return; - case "disable": - enablingFlag = false; - // falls through - case "enable": - if (args.length != 3) { - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "You must specify a flag:\n" + - NEUDebugFlag.getFlagList())); - return; - } - - String flagName = args[2].toUpperCase(); - try { - NEUDebugFlag debugFlag = NEUDebugFlag.valueOf(flagName); - if (enablingFlag) { - NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.add(debugFlag); - } else { - NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.remove(debugFlag); - } - } catch (IllegalArgumentException e) { - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - flagName + " is invalid. Valid flags are:\n" + - NEUDebugFlag.getFlagList())); - return; - } - break; - default: - showUsage(sender); - return; - } - } - - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: \n" + - NEUDebugFlag.getEnabledFlags())); - break; - default: - showUsage(sender); - return; - } - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java deleted file mode 100644 index 1d30a15f..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.commands.dev; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import io.github.moulberry.notenoughupdates.core.util.MiscUtils; -import io.github.moulberry.notenoughupdates.util.Utils; -import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.AbstractClientPlayer; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityArmorStand; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.EnumChatFormatting; - -import java.util.HashMap; -import java.util.List; -import java.util.function.Supplier; - -public class PackDevCommand extends ClientCommandBase { - static Minecraft mc = Minecraft.getMinecraft(); - - public PackDevCommand() { - super("neupackdev"); - } - - private static final HashMap<String, Command<?, ?>> commands = new HashMap<String, Command<?, ?>>() {{ - put( - "getnpc", - new Command<>( - "NPC", - () -> mc.theWorld.playerEntities, - true, - AbstractClientPlayer.class - ) - ); - put( - "getnpcs", - new Command<>( - "NPC", - () -> mc.theWorld.playerEntities, - false, - AbstractClientPlayer.class - ) - ); - put( - "getmob", - new Command<>( - "mob", - () -> mc.theWorld.loadedEntityList, - true, - EntityLiving.class - ) - ); - put( - "getmobs", - new Command<>( - "mob", - () -> mc.theWorld.loadedEntityList, - false, - EntityLiving.class - ) - ); - put( - "getarmorstand", - new Command<>( - "armor stand", - () -> mc.theWorld.loadedEntityList, - true, - EntityArmorStand.class - ) - ); - put( - "getarmorstands", - new Command<>( - "armor stand", - () -> mc.theWorld.loadedEntityList, - false, - EntityArmorStand.class - ) - ); - }}; - - @Override - public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { - return args.length == 1 ? getListOfStringsMatchingLastWord(args, commands.keySet()) : null; - } - - public static void togglePackDeveloperMode(ICommandSender sender) { - NotEnoughUpdates.INSTANCE.packDevEnabled = !NotEnoughUpdates.INSTANCE.packDevEnabled; - if (NotEnoughUpdates.INSTANCE.packDevEnabled) { - sender.addChatMessage(new ChatComponentText( - EnumChatFormatting.GREEN + "Enabled pack developer mode.")); - } else { - sender.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Disabled pack developer mode.")); - } - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (args.length == 0) { - togglePackDeveloperMode(sender); - return; - } - - double dist = 5.0; - if (args.length >= 2) { - try { - dist = Double.parseDouble(args[1]); - } catch (NumberFormatException e) { - sender.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Invalid distance! Must be a number, defaulting to a radius of 5.")); - } - } - - StringBuilder output; - String subCommand = args[0].toLowerCase(); - if (commands.containsKey(subCommand)) { - Command<?, ?> command = commands.get(subCommand); - output = command.getData(dist); - } else if (subCommand.equals("getall")) { - output = getAll(dist); - } else if (subCommand.equals("getallclose")) { - output = getAllClose(dist); - } else { - sender.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Invalid sub-command.")); - return; - } - - if (output.length() != 0) { - MiscUtils.copyToClipboard(output.toString()); - } - } - - private static StringBuilder getAllClose(Double dist) { - StringBuilder sb = new StringBuilder(); - sb.append(commands.get("getmob").getData(dist)); - sb.append(commands.get("getarmorstand").getData(dist)); - sb.append(commands.get("getnpc").getData(dist)); - return sb; - } - - private static StringBuilder getAll(Double dist) { - StringBuilder sb = new StringBuilder(); - sb.append(commands.get("getmobs").getData(dist)); - sb.append(commands.get("getarmorstands").getData(dist)); - sb.append(commands.get("getnpcs").getData(dist)); - return sb; - } - - public static <T extends EntityLivingBase> StringBuilder livingBaseDataBuilder(T entity, Class<T> clazz) { - StringBuilder entityData = new StringBuilder(); - if (EntityPlayer.class.isAssignableFrom(entity.getClass())) { - EntityPlayer entityPlayer = (EntityPlayer) entity; - - // NPC Information - String skinResourcePath = ((AbstractClientPlayer) entityPlayer).getLocationSkin().getResourcePath(); - entityData - .append("Player Id: ") - .append(entityPlayer.getUniqueID() != null ? entityPlayer.getUniqueID().toString() : "null") - .append(entityPlayer.getCustomNameTag() != null ? entityPlayer.getCustomNameTag() : "null") - .append("\nEntity Texture Id: ") - .append(skinResourcePath != null ? skinResourcePath.replace("skins/", "") : "null"); - } - - if (!clazz.isAssignableFrom(entity.getClass())) { - return entityData; - } - - //Entity Information - entityData - .append("Entity Id: ") - .append(entity.getEntityId()) - .append("\nMob: ") - .append(entity.getName() != null ? entity.getName() : "null") - .append("\nCustom Name: ") - .append(entity.getCustomNameTag() != null ? entity.getCustomNameTag() : "null"); - - //Held Item - if (entity.getHeldItem() != null) { - entityData - .append("\nItem: ") - .append(entity.getHeldItem()) - .append("\nItem Display Name: ") - .append(entity.getHeldItem().getDisplayName() != null - ? entity.getHeldItem().getDisplayName() - : "null") - .append("\nItem Tag Compound: "); - NBTTagCompound heldItemTagCompound = entity.getHeldItem().getTagCompound(); - if (heldItemTagCompound != null) { - String heldItemString = heldItemTagCompound.toString(); - NBTBase extraAttrTag = heldItemTagCompound.getTag("ExtraAttributes"); - entityData - .append(heldItemString != null ? heldItemString : "null") - .append("\nItem Tag Compound Extra Attributes: ") - .append(extraAttrTag != null ? extraAttrTag : "null"); - } else { - entityData.append("null"); - } - - } else { - entityData.append("\nItem: null"); - } - - entityData.append(armorDataBuilder(entity)).append("\n\n"); - - return entityData; - } - - private static final String[] armorPieceTypes = {"Boots", "Leggings", "Chestplate", "Helmet"}; - - public static <T extends EntityLivingBase> StringBuilder armorDataBuilder(T entity) { - StringBuilder armorData = new StringBuilder(); - for (int i = 0; i < 4; i++) { - ItemStack currentArmor = entity.getCurrentArmor(0); - armorData.append(String.format("\n%s: ", armorPieceTypes[i])); - if (currentArmor == null) { - armorData.append("null"); - } else { - armorData.append(currentArmor.getTagCompound() != null ? currentArmor.getTagCompound().toString() : "null"); - } - } - return armorData; - } - - static class Command<T extends EntityLivingBase, U extends Entity> { - String typeFriendlyName; - Supplier<List<U>> entitySupplier; - Class<T> clazz; - boolean single; - - Command( - String typeFriendlyName, - Supplier<List<U>> entitySupplier, - boolean single, - Class<T> clazz - ) { - this.typeFriendlyName = typeFriendlyName; - this.entitySupplier = entitySupplier; - this.single = single; - this.clazz = clazz; - } - - @SuppressWarnings("unchecked") - public StringBuilder getData(double dist) { - StringBuilder result = new StringBuilder(); - double distSq = dist * dist; - T closest = null; - for (Entity entity : entitySupplier.get()) { - if (!clazz.isAssignableFrom(entity.getClass()) || entity == mc.thePlayer) { - continue; - } - T entityT = (T) entity; - double entityDistanceSq = entity.getDistanceSq(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ); - if (entityDistanceSq < distSq) { - if (single) { - distSq = entityDistanceSq; - closest = entityT; - } else { - result.append(livingBaseDataBuilder(entityT, clazz)); - } - } - } - - if ((single && closest == null) || (!single && result.length() == 0)) { - Utils.addChatMessage(EnumChatFormatting.RED + "No " + typeFriendlyName + "s found within " + dist + " blocks."); - } else { - Utils.addChatMessage( - EnumChatFormatting.GREEN + "Copied " + typeFriendlyName + " data to clipboard"); - return single ? livingBaseDataBuilder(closest, clazz) : result; - } - - return result; - } - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java index 5a611178..97aa25d4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java @@ -26,7 +26,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.util.Constants; @@ -34,8 +33,6 @@ import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import lombok.var; import net.minecraft.client.Minecraft; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.client.event.ClientChatReceivedEvent; @@ -56,7 +53,6 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -87,6 +83,14 @@ public class FairySouls { return instance; } + public boolean isTrackSouls() { + return trackSouls; + } + + public boolean isShowSouls() { + return showSouls; + } + @SubscribeEvent public void onWorldLoad(WorldEvent.Load event) { currentLocation = null; @@ -379,25 +383,6 @@ public class FairySouls { Utils.addChatMessage(s); } - private static void printHelp() { - print(""); - print(EnumChatFormatting.DARK_PURPLE.toString() + EnumChatFormatting.BOLD + " NEU Fairy Soul Waypoint Guide"); - print(EnumChatFormatting.LIGHT_PURPLE + "Shows waypoints for every fairy soul in your world"); - print(EnumChatFormatting.LIGHT_PURPLE + "Clicking a fairy soul automatically removes it from the list"); - if (!NotEnoughUpdates.INSTANCE.config.hidden.dev) { - print(EnumChatFormatting.DARK_RED + "" + EnumChatFormatting.OBFUSCATED + "Ab" + EnumChatFormatting.RESET + - EnumChatFormatting.DARK_RED + "!" + EnumChatFormatting.RESET + EnumChatFormatting.RED + - " This feature cannot and will not work in Dungeons. " + EnumChatFormatting.DARK_RED + "!" + - EnumChatFormatting.OBFUSCATED + "Ab"); - } - print(EnumChatFormatting.GOLD.toString() + EnumChatFormatting.BOLD + " Commands:"); - print(EnumChatFormatting.YELLOW + "/neusouls help - Display this message"); - print(EnumChatFormatting.YELLOW + "/neusouls on/off - Enable/disable showing waypoint markers"); - print(EnumChatFormatting.YELLOW + - "/neusouls clear/unclear - Marks every waypoint in your current world as completed/uncompleted"); - print(""); - } - @SubscribeEvent(priority = EventPriority.HIGHEST, receiveCanceled = true) public void onChatReceived(ClientChatReceivedEvent event) { if (!trackSouls || event.type == 2) return; @@ -407,53 +392,4 @@ public class FairySouls { markClosestSoulFound(); } } - - public static class FairySoulsCommand extends ClientCommandBase { - public FairySoulsCommand() { - super("neusouls"); - } - - @Override - public List<String> getCommandAliases() { - return Collections.singletonList("fairysouls"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (args.length != 1) { - printHelp(); - return; - } - - String subcommand = args[0].toLowerCase(); - switch (subcommand) { - case "help": - printHelp(); - break; - case "on": - case "enable": - if (!FairySouls.instance.trackSouls) { - print( - EnumChatFormatting.RED + "Fairy soul tracking is off, enable it using /neu before using this command"); - return; - } - print(EnumChatFormatting.DARK_PURPLE + "Enabled fairy soul waypoints"); - FairySouls.getInstance().setShowFairySouls(true); - break; - case "off": - case "disable": - FairySouls.getInstance().setShowFairySouls(false); - print(EnumChatFormatting.DARK_PURPLE + "Disabled fairy soul waypoints"); - break; - case "clear": - FairySouls.getInstance().markAllAsFound(); - break; - case "unclear": - FairySouls.getInstance().markAllAsMissing(); - break; - default: - print(EnumChatFormatting.RED + "Unknown subcommand: " + subcommand); - } - } - } } diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.kt new file mode 100644 index 00000000..67765b9d --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.kt @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.commands.dev + +import com.mojang.brigadier.arguments.BoolArgumentType.bool +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent +import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver +import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver +import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag +import io.github.moulberry.notenoughupdates.util.brigadier.* +import io.github.moulberry.notenoughupdates.util.brigadier.EnumArgumentType.Companion.enum +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +// Why is this not merged into /neudevtest +@NEUAutoSubscribe +class DiagCommand { + @SubscribeEvent + fun onCommands(event: RegisterBrigadierCommandEvent) { + event.command("neudiag") { + thenLiteral("metal") { + thenExecute { + CrystalMetalDetectorSolver.logDiagnosticData(true) + reply("Enabled metal detector diagnostic logging.") + } + thenLiteral("center") { + thenArgumentExecute("usecenter", bool()) { useCenter -> + CrystalMetalDetectorSolver.setDebugDoNotUseCenter(this[useCenter]) + reply("Center coordinates-based solutions ${if (this[useCenter]) "enabled" else "disabled"}") + } + } + } + thenLiteralExecute("wishing") { + CrystalWishingCompassSolver.getInstance().logDiagnosticData(true) + reply("Enabled wishing compass diagnostic logging") + } + thenLiteral("debug") { + thenExecute { + reply("Effective debug flags: \n${NEUDebugFlag.getEnabledFlags()}") + } + thenLiteralExecute("list") { + reply("Here are all flags:\n${NEUDebugFlag.getFlagList()}") + } + thenLiteral("setflag") { + thenArgument("flag", enum<NEUDebugFlag>()) { flag -> + thenArgumentExecute("enable", bool()) { enable -> + val debugFlags = NotEnoughUpdates.INSTANCE.config.hidden.debugFlags + if (this[enable]) { + debugFlags.add(this[flag]) + } else { + debugFlags.remove(this[flag]) + } + reply("${if(this[enable]) "Enabled" else "Disabled"} the flag ${this[flag]}.") + } + } + } + } + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt new file mode 100644 index 00000000..6c1fa371 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.commands.dev + +import com.mojang.brigadier.arguments.DoubleArgumentType.doubleArg +import com.mojang.brigadier.builder.ArgumentBuilder +import io.github.moulberry.notenoughupdates.NotEnoughUpdates +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.core.util.MiscUtils +import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent +import io.github.moulberry.notenoughupdates.util.brigadier.* +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.AbstractClientPlayer +import net.minecraft.command.ICommandSender +import net.minecraft.entity.Entity +import net.minecraft.entity.EntityLiving +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.util.EnumChatFormatting + +@NEUAutoSubscribe +class PackDevCommand { + + fun <T : EntityLivingBase, U : ArgumentBuilder<ICommandSender, U>> U.npcListCommand( + name: String, + singleCommand: String, + multipleCommand: String, + clazz: Class<T>, + provider: () -> List<Entity> + ) { + fun getEntities(distance: Double): List<T> { + val distanceSquared = distance * distance + val thePlayer = Minecraft.getMinecraft().thePlayer + return provider() + .asSequence() + .filterIsInstance(clazz) + .filter { it != thePlayer } + .filter { it.getDistanceSqToEntity(thePlayer) < distanceSquared } + .toList() + } + + thenLiteral(singleCommand) { + thenArgumentExecute("distance", doubleArg(0.0)) { dist -> + val dist = this[dist] + val entity = getEntities(dist).firstOrNull() + if (entity == null) { + reply("No $name found within $dist blocks") + return@thenArgumentExecute + } + MiscUtils.copyToClipboard(StringBuilder().appendEntityData(entity).toString().trim()) + reply("Copied data to clipboard") + } + } + thenLiteral(multipleCommand) { + thenArgumentExecute("distance", doubleArg(0.0)) { dist -> + val dist = this[dist] + val entity = getEntities(dist) + val sb = StringBuilder() + reply("Found ${entity.size} ${name}s") + if (entity.isNotEmpty()) { + entity.forEach { + sb.appendEntityData(it) + } + MiscUtils.copyToClipboard(sb.toString().trim()) + + reply("Copied data to clipboard") + } + } + } + } + + fun StringBuilder.appendEntityData(entity: EntityLivingBase) { + if (entity is EntityPlayer) { + append("Player UUID: ") + appendLine(entity.uniqueID) + if (entity is AbstractClientPlayer) { + append("Entity Texture Id: ") + appendLine(entity.locationSkin.resourcePath?.replace("skins/", "")) + } + } + append("Custom Name Tag: ") + appendLine(entity.customNameTag ?: "null") + append("Mob: ") + appendLine(entity.name) + append("Entity Id: ") + appendLine(entity.entityId) + + appendItemData("Item", entity.heldItem) + + for ((slot, name) in listOf("Boots", "Leggings", "Chestplate", "Helmet").withIndex()) { + val armorPiece = entity.getCurrentArmor(slot) + appendItemData(name, armorPiece) + } + appendLine() + appendLine() + } + + fun StringBuilder.appendItemData(name: String, item: ItemStack?) { + append("$name: ") + if (item != null) { + appendLine(item) + append("$name Display Name") + appendLine(item.displayName) + append("$name Tag Compound: ") + val compound = item.tagCompound + if (compound == null) { + appendLine("null") + } else { + appendLine(compound) + append("$name Tag Compound Extra Attributes") + appendLine(compound.getTag("ExtraAttributes")) + } + } else { + appendLine("null") + } + + } + + + fun onCommands(event: RegisterBrigadierCommandEvent) { + event.command("neupackdev") { + thenExecute { + NotEnoughUpdates.INSTANCE.packDevEnabled = !NotEnoughUpdates.INSTANCE.packDevEnabled + if (NotEnoughUpdates.INSTANCE.packDevEnabled) { + reply("${EnumChatFormatting.GREEN}Enabled pack developer mode.") + } else { + reply("${EnumChatFormatting.RED}Disabled pack developer mode.") + } + } + npcListCommand("Player", "getplayer", "getplayers", AbstractClientPlayer::class.java) { + Minecraft.getMinecraft().theWorld.playerEntities + } + npcListCommand("NPC", "getnpc", "getnpcs", AbstractClientPlayer::class.java) { + Minecraft.getMinecraft().theWorld.playerEntities.filter { it.uniqueID?.version() != 4 } + } + npcListCommand("mob", "getmob", "getmobs", EntityLiving::class.java) { + Minecraft.getMinecraft().theWorld.loadedEntityList + } + npcListCommand("armor stand", "getarmorstand", "getarmorstands", EntityArmorStand::class.java) { + Minecraft.getMinecraft().theWorld.loadedEntityList + } + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt new file mode 100644 index 00000000..9edb36f1 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.commands.misc + +import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe +import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent +import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls +import io.github.moulberry.notenoughupdates.util.brigadier.literal +import io.github.moulberry.notenoughupdates.util.brigadier.reply +import io.github.moulberry.notenoughupdates.util.brigadier.thenLiteral +import io.github.moulberry.notenoughupdates.util.brigadier.thenLiteralExecute +import net.minecraft.util.EnumChatFormatting.DARK_PURPLE +import net.minecraft.util.EnumChatFormatting.RED +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@NEUAutoSubscribe +class FairySoulsCommand { + + @SubscribeEvent + fun onCommands(event: RegisterBrigadierCommandEvent) { + event.command("neusouls", "fairysouls") { + val enable = thenLiteralExecute("enable") { + if (!FairySouls.getInstance().isTrackSouls) { + reply("${RED}Fairy soul tracking is off, enable it using /neu before using this command") + return@thenLiteralExecute + } + reply("${DARK_PURPLE}Enabled fairy soul waypoints") + FairySouls.getInstance().setShowFairySouls(true) + } + thenLiteral("on") { redirect(enable) } + val disable = thenLiteralExecute("disable") { + FairySouls.getInstance().setShowFairySouls(false) + reply("${DARK_PURPLE}Disabled fairy soul waypoints") + } + thenLiteral("off") { redirect(disable) } + val clear = thenLiteralExecute("clear") { + FairySouls.getInstance().markAllAsFound() + // Reply handled by mark all as found + } + thenLiteral("markfound") { redirect(clear) } + val unclear = thenLiteralExecute("unclear") { + FairySouls.getInstance().markAllAsMissing() + // Reply handled by mark all as missing + } + thenLiteral("marknotfound") { redirect(unclear) } + } + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt index 5c802c64..96efd1aa 100644 --- a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt @@ -24,6 +24,9 @@ import com.mojang.brigadier.builder.ArgumentBuilder import com.mojang.brigadier.builder.LiteralArgumentBuilder import com.mojang.brigadier.builder.RequiredArgumentBuilder import com.mojang.brigadier.context.CommandContext +import com.mojang.brigadier.tree.ArgumentCommandNode +import com.mojang.brigadier.tree.CommandNode +import com.mojang.brigadier.tree.LiteralCommandNode import io.github.moulberry.notenoughupdates.util.iterate import net.minecraft.command.ICommandSender import net.minecraft.util.ChatComponentText @@ -103,13 +106,13 @@ fun <T : ArgumentBuilder<DefaultSource, T>, AT : Any> T.thenArgument( name: String, argument: ArgumentType<AT>, block: RequiredArgumentBuilder<DefaultSource, AT>.(TypeSafeArg<AT>) -> Unit -): T = then(argument(name, argument, block)) +): ArgumentCommandNode<DefaultSource, AT> = argument(name, argument, block).build().also(::then) fun <T : ArgumentBuilder<DefaultSource, T>, AT : Any> T.thenArgumentExecute( name: String, argument: ArgumentType<AT>, block: CommandContext<DefaultSource>.(TypeSafeArg<AT>) -> Unit -): T = thenArgument(name, argument) { +): ArgumentCommandNode<DefaultSource, AT> = thenArgument(name, argument) { thenExecute { block(it) } @@ -117,27 +120,30 @@ fun <T : ArgumentBuilder<DefaultSource, T>, AT : Any> T.thenArgumentExecute( fun literal( name: String, - block: LiteralArgumentBuilder<DefaultSource>.() -> Unit + block: LiteralArgumentBuilder<DefaultSource>.() -> Unit = {} ): LiteralArgumentBuilder<DefaultSource> = LiteralArgumentBuilder.literal<DefaultSource>(name).also(block) fun <T : ArgumentBuilder<DefaultSource, T>> T.thenLiteral( name: String, block: LiteralArgumentBuilder<DefaultSource>.() -> Unit -): T = - then(literal(name, block)) +): LiteralCommandNode<DefaultSource> = + then(literal(name), block) as LiteralCommandNode<DefaultSource> fun <T : ArgumentBuilder<DefaultSource, T>> T.thenLiteralExecute( name: String, block: CommandContext<DefaultSource>.() -> Unit -): T = +): LiteralCommandNode<DefaultSource> = thenLiteral(name) { thenExecute(block) } -fun <T : ArgumentBuilder<DefaultSource, T>> T.then(node: ArgumentBuilder<DefaultSource, *>, block: T.() -> Unit): T = - then(node).also(block) +fun <T : ArgumentBuilder<DefaultSource, T>, U : ArgumentBuilder<DefaultSource, U>> T.then( + node: U, + block: U.() -> Unit +): CommandNode<DefaultSource> = + node.also(block).build().also(::then) fun <T : ArgumentBuilder<DefaultSource, T>> T.thenExecute(block: CommandContext<DefaultSource>.() -> Unit): T = executes { |