diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Command.java b/src/main/java/meteordevelopment/meteorclient/commands/Command.java index 10c63e133a..6b3ea7699c 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Command.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Command.java @@ -24,8 +24,8 @@ public abstract class Command { protected static final CommandRegistryAccess REGISTRY_ACCESS = CommandManager.createRegistryAccess(BuiltinRegistries.createWrapperLookup()); - protected static final int SINGLE_SUCCESS = com.mojang.brigadier.Command.SINGLE_SUCCESS; protected static final MinecraftClient mc = MeteorClient.mc; + public static final int SINGLE_SUCCESS = com.mojang.brigadier.Command.SINGLE_SUCCESS; private final String name; private final String title; @@ -40,11 +40,11 @@ public Command(String name, String description, String... aliases) { } // Helper methods to painlessly infer the CommandSource generic type argument - protected static RequiredArgumentBuilder argument(final String name, final ArgumentType type) { + public static RequiredArgumentBuilder argument(final String name, final ArgumentType type) { return RequiredArgumentBuilder.argument(name, type); } - protected static LiteralArgumentBuilder literal(final String name) { + public static LiteralArgumentBuilder literal(final String name) { return LiteralArgumentBuilder.literal(name); } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/SettingCommandRegistry.java b/src/main/java/meteordevelopment/meteorclient/commands/SettingCommandRegistry.java new file mode 100644 index 0000000000..ada635c5be --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/SettingCommandRegistry.java @@ -0,0 +1,537 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands; + +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.DoubleArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import meteordevelopment.meteorclient.commands.arguments.*; +import meteordevelopment.meteorclient.renderer.text.FontFace; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.misc.Keybind; +import meteordevelopment.meteorclient.utils.misc.Names; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.command.CommandSource; +import net.minecraft.command.argument.BlockPosArgumentType; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.item.Item; +import net.minecraft.particle.ParticleType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.util.math.BlockPos; + +import java.util.function.Consumer; + +import static meteordevelopment.meteorclient.commands.Command.*; + +public class SettingCommandRegistry { + private static final Reference2ObjectMap>, Factory> REGISTRY = new Reference2ObjectOpenHashMap<>(); + + @SuppressWarnings("unchecked") + public static > void register(Class settingClass, Factory factory) { + REGISTRY.put(settingClass, + // cast from Setting to concrete implementation + (builder, setting, output) -> factory.build(builder, (T) setting, output) + ); + } + + @SuppressWarnings("unchecked") + public static > Factory get(T setting) { + return (Factory) REGISTRY.get(setting.getClass()); + } + + @FunctionalInterface + public interface Factory> { + void build(LiteralArgumentBuilder builder, T setting, Consumer output); + } + + static { + REGISTRY.defaultReturnValue((builder, setting, output) -> {}); + + //register(BlockDataSetting.class, (builder, setting, output) -> {}); // todo + register(BlockListSetting.class, (builder, setting, output) -> { + builder.then(literal("remove") + .then(argument("block", new CollectionItemArgumentType<>(setting::get, t -> Registries.BLOCK.getId(t).toString())) + .executes(context -> { + Block block = context.getArgument("block", Block.class); + if (setting.get().remove(block)) { + String blockName = Registries.BLOCK.getId(block).toString(); + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", blockName, setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("add") + .then(argument("block", RegistryEntryArgumentType.block()).executes(context -> { + Block block = RegistryEntryArgumentType.getBlock(context, "block").value(); + String blockName = Registries.BLOCK.getId(block).toString(); + if ((setting.filter == null || setting.filter.test(block)) && !setting.get().contains(block)) { + setting.get().add(block); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", blockName, setting.title)); + setting.onChanged(); + } else { + output.accept(String.format("Could not add (highlight)%s(default) to (highlight)%s(default).", blockName, setting.title)); + } + return SINGLE_SUCCESS; + })) + ); + }); + register(BlockPosSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("pos", BlockPosArgumentType.blockPos()) + .executes(context -> { + BlockPos pos = context.getArgument("pos", BlockPos.class); // todo i know this is broken, i dont care. + setting.set(pos); + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default), (highlight)%s(default), (highlight)%s(default).", setting.title, pos.getX(), pos.getY(), pos.getZ())); + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(BlockSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("block", RegistryEntryArgumentType.block()) + .executes(context -> { + RegistryEntry blockEntry = RegistryEntryArgumentType.getBlock(context, "block"); + if (setting.set(blockEntry.value())) { + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, blockEntry.getIdAsString())); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(BoolSetting.class, (builder, setting, output) -> { + builder.then(literal("toggle").executes(context -> { + setting.set(!setting.get()); + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, setting.get())); + return SINGLE_SUCCESS; + })); + + builder.then(literal("set") + .then(argument("value", BoolArgumentType.bool()) + .executes(context -> { + setting.set(BoolArgumentType.getBool(context, "value")); + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, setting.get())); + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(ColorListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("color", ColorArgumentType.color()) + .executes(context -> { + SettingColor color = ColorArgumentType.get(context, "color"); + setting.get().add(color); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", color, setting.title)); + setting.onChanged(); + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("color", new CollectionItemArgumentType<>(setting::get)) + .executes(context -> { + SettingColor color = context.getArgument("color", SettingColor.class); + if (setting.get().remove(color)) { + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", color, setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(ColorSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("color", ColorArgumentType.color()) + .executes(context -> { + SettingColor color = ColorArgumentType.get(context, "color"); + setting.set(color); + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, setting.get())); + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(DoubleSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("value", DoubleArgumentType.doubleArg(setting.min, setting.max)) + .executes(context -> { + if (setting.set(DoubleArgumentType.getDouble(context, "value"))) { + String formatStr = "%." + setting.decimalPlaces + "f"; + output.accept(String.format("Set (highlight)%s(default) to (hightlight)" + formatStr + "(default).", setting.title, setting.get())); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(EnchantmentListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("enchantment", RegistryEntryReferenceArgumentType.enchantment()) + .executes(context -> { + RegistryEntry entry = RegistryEntryReferenceArgumentType.getEnchantment(context, "enchantment"); + if (setting.get().add(entry.getKey().orElseThrow())) { + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", Names.get(entry), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("enchantment", new CollectionItemArgumentType<>(setting::get, Names::get)) + .executes(context -> { + @SuppressWarnings("unchecked") + RegistryKey entry = context.getArgument("enchantment", RegistryKey.class); + if (setting.get().remove(entry)) { + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", Names.get(entry), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(EntityTypeListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("entity", RegistryEntryArgumentType.entityType()) + .executes(context -> { + RegistryEntry.Reference> entry = RegistryEntryArgumentType.getEntityType(context, "entity"); + if ((setting.filter == null || setting.filter.test(entry.value()) && setting.get().add(entry.value()))) { + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", Names.get(entry.value()), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("entity", new CollectionItemArgumentType<>(setting::get, Names::get)) + .executes(context -> { + EntityType entityType = context.getArgument("entity", EntityType.class); + if (setting.get().remove(entityType)) { + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", Names.get(entityType), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + //register(EnumSetting.class, (builder, setting, output) -> {}); // todo + register(FontFaceSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("font", FontFaceArgumentType.fontFace()) + .executes(context -> { + FontFace fontFace = FontFaceArgumentType.get(context, "font"); + if (setting.set(fontFace)) { + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, fontFace)); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + //register(GenericSetting.class, (builder, setting, output) -> {}); // todo + register(IntSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("value", IntegerArgumentType.integer(setting.min, setting.max)) + .executes(context -> { + int value = IntegerArgumentType.getInteger(context, "value"); + if (setting.set(value)) { + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, value)); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(ItemListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("item", RegistryEntryArgumentType.item()) + .executes(context -> { + RegistryEntry entry = RegistryEntryArgumentType.getItem(context, "item"); + if ((setting.filter == null || setting.filter.test(entry.value())) && !setting.get().contains(entry.value())) { + setting.get().add(entry.value()); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", Names.get(entry.value()), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("item", new CollectionItemArgumentType<>(setting::get, Names::get)) + .executes(context -> { + Item item = context.getArgument("item", Item.class); + if (setting.get().remove(item)) { + setting.onChanged(); + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", Names.get(item), setting.title)); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(ItemSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("item", RegistryEntryArgumentType.item()) + .executes(context -> { + Item item = RegistryEntryArgumentType.getItem(context, "item").value(); + if (setting.set(item)) { + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, Names.get(item))); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(KeybindSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("keybind", IntegerArgumentType.integer()) + .executes(context -> { + int value = IntegerArgumentType.getInteger(context, "keybind"); + setting.set(Keybind.fromKey(value)); + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, setting.get())); + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(ModuleListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("module", ModuleArgumentType.create()) + .executes(context -> { + Module module = ModuleArgumentType.get(context); + if (!setting.get().contains(module)) { + setting.get().add(module); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", module.title, setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("module", new CollectionItemArgumentType<>(setting::get, module -> module.name)) + .executes(context -> { + Module module = context.getArgument("module", Module.class); + if (setting.get().remove(module)) { + setting.onChanged(); + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", module.title, setting.title)); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + //register(PacketListSetting.class, (builder, setting, output) -> {}); // todo + register(ParticleTypeListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("particle", RegistryEntryArgumentType.particleType()) + .executes(context -> { + RegistryEntry> entry = RegistryEntryArgumentType.getParticleType(context, "particle"); + if (!setting.get().contains(entry.value())) { + setting.get().add(entry.value()); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", Names.get(entry.value()), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("particle", new CollectionItemArgumentType<>(setting::get, Names::get)) + .executes(context -> { + ParticleType particleType = context.getArgument("particle", ParticleType.class); + if (setting.get().remove(particleType)) { + setting.onChanged(); + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", Names.get(particleType), setting.title)); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + //register(PotionSetting.class, (builder, setting, output) -> {}); // todo + //register(ProvidedStringSetting.class, (builder, setting, output) -> {}); // todo + register(ScreenHandlerListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("screenHandler", RegistryEntryArgumentType.screenHandler()) + .executes(context -> { + RegistryEntry.Reference> entry = RegistryEntryArgumentType.getScreenHandler(context, "screenHandler"); + setting.get().add(entry.value()); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", entry.getIdAsString(), setting.title)); + setting.onChanged(); + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("screenHandler", new CollectionItemArgumentType<>(setting::get)) + .executes(context -> { + ScreenHandlerType screenHandler = context.getArgument("screenHandler", ScreenHandlerType.class); + if (setting.get().remove(screenHandler)) { + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", screenHandler, setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + //register(SoundEventListSetting.class, (builder, setting, output) -> {}); // todo + register(StatusEffectAmplifierMapSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("effect", RegistryEntryArgumentType.statusEffect()) + .then(argument("amplifier", IntegerArgumentType.integer(0)) + .executes(context -> { + StatusEffect effect = RegistryEntryArgumentType.getStatusEffect(context, "effect").value(); + int amplifier = IntegerArgumentType.getInteger(context, "amplifier"); + setting.get().put(effect, amplifier); + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", Names.get(effect), amplifier)); + setting.onChanged(); + return SINGLE_SUCCESS; + }) + ) + ) + ); + + builder.then(literal("remove") + .then(argument("effect", new CollectionItemArgumentType<>(() -> setting.get().keySet(), Names::get)) + .executes(context -> { + StatusEffect effect = context.getArgument("effect", StatusEffect.class); + if (setting.get().containsKey(effect)) { + setting.get().removeInt(effect); + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", Names.get(effect), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(StatusEffectListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("effect", RegistryEntryArgumentType.statusEffect()) + .executes(context -> { + StatusEffect effect = RegistryEntryArgumentType.getStatusEffect(context, "effect").value(); + if (!setting.get().contains(effect)) { + setting.get().add(effect); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", Names.get(effect), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("effect", new CollectionItemArgumentType<>(setting::get, Names::get)) + .executes(context -> { + StatusEffect effect = context.getArgument("effect", StatusEffect.class); + if (setting.get().remove(effect)) { + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", Names.get(effect), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(StorageBlockListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("blockEntity", RegistryEntryArgumentType.blockEntityType()) + .executes(context -> { + RegistryEntry> entry = RegistryEntryArgumentType.getBlockEntityType(context, "blockEntity"); + if (!setting.get().contains(entry.value())) { + setting.get().add(entry.value()); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", entry.getIdAsString(), setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("blockEntity", new CollectionItemArgumentType<>(setting::get)) + .executes(context -> { + BlockEntityType blockEntityType = context.getArgument("effect", BlockEntityType.class); + if (setting.get().remove(blockEntityType)) { + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", blockEntityType, setting.title)); + setting.onChanged(); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(StringListSetting.class, (builder, setting, output) -> { + builder.then(literal("add") + .then(argument("string", StringArgumentType.string()) + .executes(context -> { + String string = StringArgumentType.getString(context, "string"); + setting.get().add(string); + output.accept(String.format("Added (highlight)%s(default) to (highlight)%s(default).", string, setting.title)); + setting.onChanged(); + return SINGLE_SUCCESS; + }) + ) + ); + + builder.then(literal("remove") + .then(argument("string", new CollectionItemArgumentType<>(setting::get)) + .executes(context -> { + String string = context.getArgument("string", String.class); + if (setting.get().remove(string)) { + setting.onChanged(); + output.accept(String.format("Removed (highlight)%s(default) from (highlight)%s(default).", string, setting.title)); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + register(StringSetting.class, (builder, setting, output) -> { + builder.then(literal("set") + .then(argument("string", StringArgumentType.string()) + .executes(context -> { + if (setting.set(StringArgumentType.getString(context, "string"))) { + output.accept(String.format("Set (highlight)%s(default) to (highlight)%s(default).", setting.title, setting.get())); + } + return SINGLE_SUCCESS; + }) + ) + ); + }); + //register(Vector3dSetting.class, (builder, setting, output) -> {}); // todo + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/CollectionItemArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/CollectionItemArgumentType.java new file mode 100644 index 0000000000..16a7217e43 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/CollectionItemArgumentType.java @@ -0,0 +1,62 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.arguments; + +import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.command.CommandSource; + +import java.util.Collection; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.function.Supplier; + +public class CollectionItemArgumentType implements ArgumentType { + private static final DynamicCommandExceptionType NO_SUCH_ITEM_EXCEPTION = new DynamicCommandExceptionType(o -> new LiteralMessage("No such item '" + o + "'.")); + private final Supplier> collection; + private final StringFunction stringFunction; + + public CollectionItemArgumentType(Supplier> collection, StringFunction stringFunction) { + this.collection = collection; + this.stringFunction = stringFunction; + } + + public CollectionItemArgumentType(Supplier> collection) { + this(collection, Object::toString); + } + + @Override + public T parse(StringReader stringReader) throws CommandSyntaxException { + String value = stringReader.readString(); + + Optional itemResult = this.collection.get().stream() + .filter(item -> this.stringFunction.apply(item).equals(value)) + .findAny(); + + if (itemResult.isPresent()) { + return itemResult.get(); + } else { + throw NO_SUCH_ITEM_EXCEPTION.create(value); + } + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + return CommandSource.suggestMatching(this.collection.get().stream().map(this.stringFunction), builder); + } + + @FunctionalInterface + public interface StringFunction extends Function { + String apply(T value); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/ColorArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/ColorArgumentType.java new file mode 100644 index 0000000000..58a43275c9 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/ColorArgumentType.java @@ -0,0 +1,69 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.arguments; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import meteordevelopment.meteorclient.settings.ColorSetting; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; + +import java.util.Collection; + +public class ColorArgumentType implements ArgumentType { + private static final ColorArgumentType INSTANCE = new ColorArgumentType(); + + private ColorArgumentType() {} + + public static ColorArgumentType color() { + return INSTANCE; + } + + public static SettingColor get(CommandContext context, String name) { + return context.getArgument(name, SettingColor.class); + } + + @Override + public SettingColor parse(StringReader stringReader) throws CommandSyntaxException { + int cursor = stringReader.getCursor(); + + try { + if (stringReader.readString().equals("rainbow")) { + return new SettingColor().rainbow(true); + } + } catch (CommandSyntaxException ignored) {} + stringReader.setCursor(cursor); + + int red = readInt(stringReader); + int green = readInt(stringReader); + int blue = readInt(stringReader); + int alpha = 255; + + if (stringReader.canRead() && StringReader.isAllowedNumber(stringReader.peek())) { + alpha = readInt(stringReader); + } + + return new SettingColor(red, green, blue, alpha); + } + + private static int readInt(StringReader reader) throws CommandSyntaxException { + int i = reader.readInt(); + reader.skipWhitespace(); + if (i < 0) { + throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.integerTooLow().createWithContext(reader, i, 0); + } else if (i > 255) { + throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.integerTooHigh().createWithContext(reader, i, 255); + } else { + return i; + } + } + + @Override + public Collection getExamples() { + return ColorSetting.SUGGESTIONS; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/FontFaceArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/FontFaceArgumentType.java new file mode 100644 index 0000000000..9f2533d7a3 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/FontFaceArgumentType.java @@ -0,0 +1,88 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.arguments; + +import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import meteordevelopment.meteorclient.renderer.Fonts; +import meteordevelopment.meteorclient.renderer.text.FontFace; +import meteordevelopment.meteorclient.renderer.text.FontFamily; +import meteordevelopment.meteorclient.renderer.text.FontInfo; +import meteordevelopment.meteorclient.settings.FontFaceSetting; +import net.minecraft.command.CommandSource; + +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +public class FontFaceArgumentType implements ArgumentType { + private static final FontFaceArgumentType INSTANCE = new FontFaceArgumentType(); + private static final DynamicCommandExceptionType NO_SUCH_FONT_FACE_EXCEPTION = new DynamicCommandExceptionType(o -> new LiteralMessage("No such font face: ' " + o + "'")); + + private FontFaceArgumentType() {} + + public static FontFaceArgumentType fontFace() { + return INSTANCE; + } + + public static FontFace get(CommandContext context, String name) { + return context.getArgument(name, FontFace.class); + } + + @Override + public FontFace parse(StringReader stringReader) throws CommandSyntaxException { + String value = stringReader.readString(); + + String[] split = value.split("-"); + if (split.length != 2) throw NO_SUCH_FONT_FACE_EXCEPTION.createWithContext(stringReader, value); + + for (FontFamily family : Fonts.FONT_FAMILIES) { + if (family.getName().replace(" ", "").equals(split[0])) { + try { + return family.get(FontInfo.Type.valueOf(split[1])); + } + catch (IllegalArgumentException ignored) { + throw NO_SUCH_FONT_FACE_EXCEPTION.createWithContext(stringReader, value); + } + } + } + + throw NO_SUCH_FONT_FACE_EXCEPTION.createWithContext(stringReader, value); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + BiConsumer> mapper = (family, c) -> { + for (FontInfo.Type type : FontInfo.Type.values()) { + @Nullable FontFace font = family.get(type); + if (font != null) { + c.accept(font); + } + } + }; + + return CommandSource.suggestMatching(Fonts.FONT_FAMILIES.stream().mapMulti(mapper).map(FontFaceArgumentType::stringify), builder); + } + + private static String stringify(FontFace fontFace) { + String family = fontFace.info.family().replace(" ", ""); + String type = fontFace.info.type().toString().replace(" ", ""); + return family + "-" + type; + } + + @Override + public Collection getExamples() { + return FontFaceSetting.EXAMPLES; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryArgumentType.java new file mode 100644 index 0000000000..5c957fe5df --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryArgumentType.java @@ -0,0 +1,143 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.arguments; + +import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.Dynamic3CommandExceptionType; +import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.block.Block; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.command.CommandSource; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.item.Item; +import net.minecraft.particle.ParticleType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.sound.SoundEvent; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.util.concurrent.CompletableFuture; + +public class RegistryEntryArgumentType implements ArgumentType> { + private static final RegistryEntryArgumentType BLOCK = new RegistryEntryArgumentType<>(Registries.BLOCK); + private static final RegistryEntryArgumentType> BLOCK_ENTITY_TYPE = new RegistryEntryArgumentType<>(Registries.BLOCK_ENTITY_TYPE); + private static final RegistryEntryArgumentType> ENTITY_TYPE = new RegistryEntryArgumentType<>(Registries.ENTITY_TYPE); + private static final RegistryEntryArgumentType ITEM = new RegistryEntryArgumentType<>(Registries.ITEM); + private static final RegistryEntryArgumentType> PARTICLE_TYPE = new RegistryEntryArgumentType<>(Registries.PARTICLE_TYPE); + private static final RegistryEntryArgumentType> SCREEN_HANDLER = new RegistryEntryArgumentType<>(Registries.SCREEN_HANDLER); + private static final RegistryEntryArgumentType SOUND_EVENT = new RegistryEntryArgumentType<>(Registries.SOUND_EVENT); + private static final RegistryEntryArgumentType STATUS_EFFECT = new RegistryEntryArgumentType<>(Registries.STATUS_EFFECT); + + public static final DynamicCommandExceptionType NOT_FOUND_EXCEPTION = new DynamicCommandExceptionType( + element -> new LiteralMessage("Not found exception type shii " + element) + ); + public static final Dynamic3CommandExceptionType INVALID_TYPE_EXCEPTION = new Dynamic3CommandExceptionType( + (element, type, expectedType) -> Text.stringifiedTranslatable("argument.resource.invalid_type", element, type, expectedType) + ); + private final Registry registry; + + private RegistryEntryArgumentType(Registry registry) { + this.registry = registry; + } + + public static RegistryEntryArgumentType block() { + return BLOCK; + } + + public static RegistryEntryArgumentType> blockEntityType() { + return BLOCK_ENTITY_TYPE; + } + + public static RegistryEntryArgumentType> entityType() { + return ENTITY_TYPE; + } + + public static RegistryEntryArgumentType item() { + return ITEM; + } + + public static RegistryEntryArgumentType> particleType() { + return PARTICLE_TYPE; + } + + public static RegistryEntryArgumentType> screenHandler() { + return SCREEN_HANDLER; + } + + public static RegistryEntryArgumentType soundEvent() { + return SOUND_EVENT; + } + + public static RegistryEntryArgumentType statusEffect() { + return STATUS_EFFECT; + } + + public static RegistryEntry.Reference getBlock(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.BLOCK); + } + + public static RegistryEntry.Reference> getBlockEntityType(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.BLOCK_ENTITY_TYPE); + } + + public static RegistryEntry.Reference> getEntityType(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.ENTITY_TYPE); + } + + public static RegistryEntry.Reference getItem(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.ITEM); + } + + public static RegistryEntry.Reference> getParticleType(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.PARTICLE_TYPE); + } + + public static RegistryEntry.Reference> getScreenHandler(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.SCREEN_HANDLER); + } + + public static RegistryEntry.Reference getSoundEvent(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.SOUND_EVENT); + } + + public static RegistryEntry.Reference getStatusEffect(CommandContext context, String name) throws CommandSyntaxException { + return getRegistryEntry(context, name, RegistryKeys.STATUS_EFFECT); + } + + private static RegistryEntry.Reference getRegistryEntry(CommandContext context, String name, RegistryKey> registryRef) throws CommandSyntaxException { + RegistryEntry.Reference reference = context.getArgument(name, RegistryEntry.Reference.class); + RegistryKey registryKey = reference.registryKey(); + if (registryKey.isOf(registryRef)) { + return reference; + } else { + throw INVALID_TYPE_EXCEPTION.create(registryKey.getValue(), registryKey.getRegistry(), registryRef.getValue()); + } + } + + @Override + public RegistryEntry.Reference parse(StringReader stringReader) throws CommandSyntaxException { + Identifier identifier = Identifier.fromCommandInput(stringReader); + return this.registry.getEntry(identifier) + .orElseThrow(() -> NOT_FOUND_EXCEPTION.createWithContext(stringReader, identifier)); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + return CommandSource.suggestMatching(this.registry.streamKeys().map(RegistryKey::getValue).map(Object::toString), builder); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryReferenceArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryReferenceArgumentType.java index 7db6039a51..2e64512787 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryReferenceArgumentType.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/RegistryEntryReferenceArgumentType.java @@ -14,6 +14,7 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.command.CommandSource; import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.EntityType; @@ -31,6 +32,10 @@ import java.util.Collection; import java.util.concurrent.CompletableFuture; +/** + * An {@link ArgumentType} for dynamic registries, e.g. those available at runtime through {@link ClientPlayNetworkHandler#getRegistryManager()}. + * @author Crosby + */ public class RegistryEntryReferenceArgumentType implements ArgumentType> { private static final RegistryEntryReferenceArgumentType ENCHANTMENT = new RegistryEntryReferenceArgumentType<>(RegistryKeys.ENCHANTMENT); private static final RegistryEntryReferenceArgumentType ENTITY_ATTRIBUTE = new RegistryEntryReferenceArgumentType<>(RegistryKeys.ATTRIBUTE); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/SettingCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/SettingCommand.java index ec95761519..b9f81df9ea 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/SettingCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/SettingCommand.java @@ -6,19 +6,24 @@ package meteordevelopment.meteorclient.commands.commands; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import meteordevelopment.meteorclient.commands.Command; +import meteordevelopment.meteorclient.commands.SettingCommandRegistry; import meteordevelopment.meteorclient.commands.arguments.ModuleArgumentType; -import meteordevelopment.meteorclient.commands.arguments.SettingArgumentType; -import meteordevelopment.meteorclient.commands.arguments.SettingValueArgumentType; import meteordevelopment.meteorclient.gui.GuiThemes; import meteordevelopment.meteorclient.gui.WidgetScreen; import meteordevelopment.meteorclient.gui.tabs.TabScreen; import meteordevelopment.meteorclient.gui.tabs.Tabs; import meteordevelopment.meteorclient.settings.Setting; +import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.Settings; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.utils.Utils; import net.minecraft.command.CommandSource; +import java.util.Set; + public class SettingCommand extends Command { public SettingCommand() { super("settings", "Allows you to view and change module settings.", "s"); @@ -52,33 +57,73 @@ public void build(LiteralArgumentBuilder builder) { ); // View or change settings - builder.then( - argument("module", ModuleArgumentType.create()) - .then( - argument("setting", SettingArgumentType.create()) - .executes(context -> { - // Get setting value - Setting setting = SettingArgumentType.get(context); - - ModuleArgumentType.get(context).info("Setting (highlight)%s(default) is (highlight)%s(default).", setting.title, setting.get()); - - return SINGLE_SUCCESS; - }) - .then( - argument("value", SettingValueArgumentType.create()) - .executes(context -> { - // Set setting value - Setting setting = SettingArgumentType.get(context); - String value = SettingValueArgumentType.get(context); - - if (setting.parse(value)) { - ModuleArgumentType.get(context).info("Setting (highlight)%s(default) changed to (highlight)%s(default).", setting.title, value); - } - - return SINGLE_SUCCESS; - }) - ) - ) - ); + for (Module module : Modules.get().getAll()) { + LiteralArgumentBuilder moduleBuilder = literal(module.name); + + if (hasDuplicateSettingNames(module.settings)) { + for (SettingGroup settingGroup : module.settings) { + LiteralArgumentBuilder settingGroupBuilder = literal(Utils.titleToName(settingGroup.name)); + + for (Setting setting : settingGroup) { + buildSetting(settingGroupBuilder, setting, module); + } + + moduleBuilder.then(settingGroupBuilder); + } + } else { + for (SettingGroup settingGroup : module.settings) { + for (Setting setting : settingGroup) { + buildSetting(moduleBuilder, setting, module); + } + } + } + + builder.then(moduleBuilder); + } + } + + private void buildSetting(LiteralArgumentBuilder parentBuilder, Setting setting, Module module) { + LiteralArgumentBuilder builder = literal(setting.name); + + builder.then(literal("reset").executes(context -> { + setting.reset(); + module.info("Setting (highlight)%s(default) reset.", setting.title); + return SINGLE_SUCCESS; + })); + + builder.then(literal("get").executes(context -> { + module.info("Setting (highlight)%s(default) is (highlight)%s(default).", setting.title, setting.get()); + return SINGLE_SUCCESS; + })); + + SettingCommandRegistry.get(setting).build(builder, setting, module::info); + + parentBuilder.then(builder); + } + + private static boolean hasDuplicateSettingNames(Settings settings) { + int groups = settings.sizeGroups(); + if (groups <= 1) { + return false; + } + + Set settingNames = new ObjectOpenHashSet<>(); + + for (int i = 0; i < groups - 1; i++) { + SettingGroup group = settings.groups.get(i); + for (Setting setting : group) { + if (!settingNames.add(setting.name)) { + return true; + } + } + } + + for (Setting setting : settings.groups.getLast()) { + if (settingNames.contains(setting.name)) { + return true; + } + } + + return false; } } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/BlockDataSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/BlockDataSetting.java index 3e1da1351c..74c3f921c1 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/BlockDataSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/BlockDataSetting.java @@ -32,16 +32,6 @@ public void resetImpl() { value = new HashMap<>(defaultValue); } - @Override - protected Map parseImpl(String str) { - return new HashMap<>(0); - } - - @Override - protected boolean isValueValid(Map value) { - return true; - } - @Override protected NbtCompound save(NbtCompound tag) { NbtCompound valueTag = new NbtCompound(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java index 8bd8419bc8..faccb5910f 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java @@ -33,26 +33,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List blocks = new ArrayList<>(values.length); - - try { - for (String value : values) { - Block block = parseId(Registries.BLOCK, value); - if (block != null && (filter == null || filter.test(block))) blocks.add(block); - } - } catch (Exception ignored) {} - - return blocks; - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.BLOCK.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/BlockPosSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/BlockPosSetting.java index 17608a601c..19137648ee 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/BlockPosSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/BlockPosSetting.java @@ -8,7 +8,6 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.util.math.BlockPos; -import java.util.List; import java.util.function.Consumer; public class BlockPosSetting extends Setting { @@ -16,24 +15,6 @@ public BlockPosSetting(String name, String description, BlockPos defaultValue, C super(name, description, defaultValue, onChanged, onModuleActivated, visible); } - @Override - protected BlockPos parseImpl(String str) { - List values = List.of(str.split(",")); - if (values.size() != 3) return null; - - BlockPos bp = null; - try { - bp = new BlockPos(Integer.parseInt(values.get(0)), Integer.parseInt(values.get(1)), Integer.parseInt(values.get(2))); - } - catch (NumberFormatException ignored) {} - return bp; - } - - @Override - protected boolean isValueValid(BlockPos value) { - return true; - } - @Override protected NbtCompound save(NbtCompound tag) { tag.putIntArray("value", new int[] {value.getX(), value.getY(), value.getZ()}); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/BlockSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/BlockSetting.java index 9500e14260..1607080fb8 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/BlockSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/BlockSetting.java @@ -22,11 +22,6 @@ public BlockSetting(String name, String description, Block defaultValue, Consume this.filter = filter; } - @Override - protected Block parseImpl(String str) { - return parseId(Registries.BLOCK, str); - } - @Override protected boolean isValueValid(Block value) { return filter == null || filter.test(value); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/BoolSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/BoolSetting.java index e42351541a..20604edc00 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/BoolSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/BoolSetting.java @@ -17,19 +17,6 @@ private BoolSetting(String name, String description, Boolean defaultValue, Consu super(name, description, defaultValue, onChanged, onModuleActivated, visible); } - @Override - protected Boolean parseImpl(String str) { - if (str.equalsIgnoreCase("true") || str.equalsIgnoreCase("1")) return true; - else if (str.equalsIgnoreCase("false") || str.equalsIgnoreCase("0")) return false; - else if (str.equalsIgnoreCase("toggle")) return !get(); - return null; - } - - @Override - protected boolean isValueValid(Boolean value) { - return true; - } - @Override public List getSuggestions() { return SUGGESTIONS; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java index eb5c3c2fdc..dda83651a0 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java @@ -19,25 +19,6 @@ public ColorListSetting(String name, String description, List defa super(name, description, defaultValue, onChanged, onModuleActivated, visible); } - @Override - protected List parseImpl(String str) { - List colors = new ArrayList<>(); - try { - String[] colorsStr = str.replaceAll("\\s+", "").split(";"); - for (String colorStr : colorsStr) { - String[] strs = colorStr.split(","); - colors.add(new SettingColor(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2]), Integer.parseInt(strs[3]))); - } - } catch (IndexOutOfBoundsException | NumberFormatException ignored) { - } - return colors; - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override protected void resetImpl() { value = new ArrayList<>(defaultValue.size()); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ColorSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ColorSetting.java index 47ef146303..d84c2a5357 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ColorSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ColorSetting.java @@ -13,22 +13,12 @@ import java.util.function.Consumer; public class ColorSetting extends Setting { - private static final List SUGGESTIONS = List.of("0 0 0 255", "225 25 25 255", "25 225 25 255", "25 25 225 255", "255 255 255 255"); + public static final List SUGGESTIONS = List.of("0 0 0 255", "225 25 25 255", "25 225 25 255", "25 25 225 255", "255 255 255 255"); public ColorSetting(String name, String description, SettingColor defaultValue, Consumer onChanged, Consumer> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } - @Override - protected SettingColor parseImpl(String str) { - try { - String[] strs = str.split(" "); - return new SettingColor(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2]), Integer.parseInt(strs[3])); - } catch (IndexOutOfBoundsException | NumberFormatException ignored) { - return null; - } - } - @Override public void resetImpl() { if (value == null) value = new SettingColor(defaultValue); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/DoubleSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/DoubleSetting.java index c52ba26132..9711b5c192 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/DoubleSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/DoubleSetting.java @@ -28,15 +28,6 @@ private DoubleSetting(String name, String description, double defaultValue, Cons this.noSlider = noSlider; } - @Override - protected Double parseImpl(String str) { - try { - return Double.parseDouble(str.trim()); - } catch (NumberFormatException ignored) { - return null; - } - } - @Override protected boolean isValueValid(Double value) { return value >= min && value <= max; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java index 295d39fb77..c208fd3886 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java @@ -33,29 +33,6 @@ public void resetImpl() { value = new ObjectOpenHashSet<>(defaultValue); } - @Override - protected Set> parseImpl(String str) { - String[] values = str.split(","); - Set> enchs = new ObjectOpenHashSet<>(values.length); - - for (String value : values) { - String name = value.trim(); - - Identifier id; - if (name.contains(":")) id = Identifier.of(name); - else id = Identifier.ofVanilla(name); - - enchs.add(RegistryKey.of(RegistryKeys.ENCHANTMENT, id)); - } - - return enchs; - } - - @Override - protected boolean isValueValid(Set> value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Optional.ofNullable(MinecraftClient.getInstance().getNetworkHandler()) diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java index edc48908e0..fa58d532d9 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java @@ -8,7 +8,6 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import net.minecraft.entity.EntityType; -import net.minecraft.entity.SpawnGroup; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; @@ -38,55 +37,6 @@ public void resetImpl() { value = new ObjectOpenHashSet<>(defaultValue); } - @Override - protected Set> parseImpl(String str) { - String[] values = str.split(","); - Set> entities = new ObjectOpenHashSet<>(values.length); - - try { - for (String value : values) { - EntityType entity = parseId(Registries.ENTITY_TYPE, value); - if (entity != null) entities.add(entity); - else { - String lowerValue = value.trim().toLowerCase(); - if (!groups.contains(lowerValue)) continue; - - for (EntityType entityType : Registries.ENTITY_TYPE) { - if (filter != null && !filter.test(entityType)) continue; - - switch (lowerValue) { - case "animal" -> { - if (entityType.getSpawnGroup() == SpawnGroup.CREATURE) entities.add(entityType); - } - case "wateranimal" -> { - if (entityType.getSpawnGroup() == SpawnGroup.WATER_AMBIENT - || entityType.getSpawnGroup() == SpawnGroup.WATER_CREATURE - || entityType.getSpawnGroup() == SpawnGroup.UNDERGROUND_WATER_CREATURE - || entityType.getSpawnGroup() == SpawnGroup.AXOLOTLS) entities.add(entityType); - } - case "monster" -> { - if (entityType.getSpawnGroup() == SpawnGroup.MONSTER) entities.add(entityType); - } - case "ambient" -> { - if (entityType.getSpawnGroup() == SpawnGroup.AMBIENT) entities.add(entityType); - } - case "misc" -> { - if (entityType.getSpawnGroup() == SpawnGroup.MISC) entities.add(entityType); - } - } - } - } - } - } catch (Exception ignored) {} - - return entities; - } - - @Override - protected boolean isValueValid(Set> value) { - return true; - } - @Override public List getSuggestions() { if (suggestions == null) { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EnumSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EnumSetting.java index 28a400061b..79e194d1ce 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/EnumSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/EnumSetting.java @@ -24,7 +24,6 @@ public EnumSetting(String name, String description, T defaultValue, Consumer for (T value : values) suggestions.add(value.toString()); } - @Override protected T parseImpl(String str) { for (T possibleValue : values) { if (str.equalsIgnoreCase(possibleValue.toString())) return possibleValue; @@ -33,11 +32,6 @@ protected T parseImpl(String str) { return null; } - @Override - protected boolean isValueValid(T value) { - return true; - } - @Override public List getSuggestions() { return suggestions; @@ -52,9 +46,7 @@ public NbtCompound save(NbtCompound tag) { @Override public T load(NbtCompound tag) { - parse(tag.getString("value")); - - return get(); + return parseImpl(tag.getString("value")); // todo } public static class Builder> extends SettingBuilder, T, EnumSetting> { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/FontFaceSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/FontFaceSetting.java index 40e0ad8474..5bfbc98176 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/FontFaceSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/FontFaceSetting.java @@ -15,32 +15,15 @@ import java.util.function.Consumer; public class FontFaceSetting extends Setting { + public static final List EXAMPLES = List.of("JetBrainsMono-Regular", "Arial-Bold"); + public FontFaceSetting(String name, String description, FontFace defaultValue, Consumer onChanged, Consumer> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } - @Override - protected FontFace parseImpl(String str) { - String[] split = str.replace(" ", "").split("-"); - if (split.length != 2) return null; - - for (FontFamily family : Fonts.FONT_FAMILIES) { - if (family.getName().replace(" ", "").equals(split[0])) { - try { - return family.get(FontInfo.Type.valueOf(split[1])); - } - catch (IllegalArgumentException ignored) { - return null; - } - } - } - - return null; - } - @Override public List getSuggestions() { - return List.of("JetBrainsMono-Regular", "Arial-Bold"); + return EXAMPLES; } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/settings/GenericSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/GenericSetting.java index efaf28f9be..901713a54c 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/GenericSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/GenericSetting.java @@ -23,16 +23,6 @@ public void resetImpl() { value.set(defaultValue); } - @Override - protected T parseImpl(String str) { - return defaultValue.copy(); - } - - @Override - protected boolean isValueValid(T value) { - return true; - } - @Override public NbtCompound save(NbtCompound tag) { tag.put("value", get().toTag()); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/IntSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/IntSetting.java index fd44155ff1..f72ae69aee 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/IntSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/IntSetting.java @@ -24,15 +24,6 @@ private IntSetting(String name, String description, int defaultValue, Consumer= min && value <= max; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java index e9f0c4b4a3..6f3e4964cd 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java @@ -30,31 +30,11 @@ public ItemListSetting(String name, String description, List defaultValue, this.bypassFilterWhenSavingAndLoading = bypassFilterWhenSavingAndLoading; } - @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List items = new ArrayList<>(values.length); - - try { - for (String value : values) { - Item item = parseId(Registries.ITEM, value); - if (item != null && (filter == null || filter.test(item))) items.add(item); - } - } catch (Exception ignored) {} - - return items; - } - @Override public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.ITEM.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ItemSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ItemSetting.java index 10db4d513c..7201e09edb 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ItemSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ItemSetting.java @@ -22,11 +22,6 @@ public ItemSetting(String name, String description, Item defaultValue, Consumer< this.filter = filter; } - @Override - protected Item parseImpl(String str) { - return parseId(Registries.ITEM, str); - } - @Override protected boolean isValueValid(Item value) { return filter == null || filter.test(value); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/KeybindSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/KeybindSetting.java index 8bee87d929..e3dfa03bdd 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/KeybindSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/KeybindSetting.java @@ -63,20 +63,6 @@ public void resetImpl() { if (widget != null) widget.reset(); } - @Override - protected Keybind parseImpl(String str) { - try { - return Keybind.fromKey(Integer.parseInt(str.trim())); - } catch (NumberFormatException ignored) { - return null; - } - } - - @Override - protected boolean isValueValid(Keybind value) { - return true; - } - @Override public NbtCompound save(NbtCompound tag) { tag.put("value", get().toTag()); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java index 9eb5e1005a..39f6dcabad 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java @@ -28,26 +28,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List modules = new ArrayList<>(values.length); - - try { - for (String value : values) { - Module module = Modules.get().get(value.trim()); - if (module != null) modules.add(module); - } - } catch (Exception ignored) {} - - return modules; - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override public List getSuggestions() { if (suggestions == null) { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java index a115af1dee..7ebbcb8163 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java @@ -34,26 +34,6 @@ public void resetImpl() { value = new ObjectOpenHashSet<>(defaultValue); } - @Override - protected Set>> parseImpl(String str) { - String[] values = str.split(","); - Set>> packets = new ObjectOpenHashSet<>(values.length); - - try { - for (String value : values) { - Class> packet = PacketUtils.getPacket(value.trim()); - if (packet != null && (filter == null || filter.test(packet))) packets.add(packet); - } - } catch (Exception ignored) {} - - return packets; - } - - @Override - protected boolean isValueValid(Set>> value) { - return true; - } - @Override public List getSuggestions() { if (suggestions == null) { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java index 8fe6fc8097..34b822785d 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java @@ -9,7 +9,6 @@ import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtString; -import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleType; import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; @@ -29,26 +28,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List> parseImpl(String str) { - String[] values = str.split(","); - List> particleTypes = new ArrayList<>(values.length); - - try { - for (String value : values) { - ParticleType particleType = parseId(Registries.PARTICLE_TYPE, value); - if (particleType instanceof ParticleEffect) particleTypes.add(particleType); - } - } catch (Exception ignored) {} - - return particleTypes; - } - - @Override - protected boolean isValueValid(List> value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.PARTICLE_TYPE.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java index c4e55d3134..46ce654a91 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java @@ -28,27 +28,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List> parseImpl(String str) { - String[] values = str.split(","); - List> handlers = new ArrayList<>(values.length); - - try { - for (String value : values) { - ScreenHandlerType handler = parseId(Registries.SCREEN_HANDLER, value); - if (handler != null) handlers.add(handler); - } - } catch (Exception ignored) { - } - - return handlers; - } - - @Override - protected boolean isValueValid(List> value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.SCREEN_HANDLER.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/Setting.java b/src/main/java/meteordevelopment/meteorclient/settings/Setting.java index cbe2437111..f102a7bfa0 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/Setting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/Setting.java @@ -71,19 +71,6 @@ public T getDefaultValue() { return defaultValue; } - public boolean parse(String str) { - T newValue = parseImpl(str); - - if (newValue != null) { - if (isValueValid(newValue)) { - value = newValue; - onChanged(); - } - } - - return newValue != null; - } - public boolean wasChanged() { return !Objects.equals(value, defaultValue); } @@ -100,9 +87,9 @@ public boolean isVisible() { return visible == null || visible.isVisible(); } - protected abstract T parseImpl(String str); - - protected abstract boolean isValueValid(T value); + protected boolean isValueValid(T value) { + return true; + } public Iterable getIdentifierSuggestions() { return null; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java index 7b79c9acf9..cba0b15524 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java @@ -28,26 +28,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List sounds = new ArrayList<>(values.length); - - try { - for (String value : values) { - SoundEvent sound = parseId(Registries.SOUND_EVENT, value); - if (sound != null) sounds.add(sound); - } - } catch (Exception ignored) {} - - return sounds; - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.SOUND_EVENT.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java index 682a55f822..4cfab6eea5 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java @@ -27,30 +27,6 @@ public void resetImpl() { value = new Reference2IntOpenHashMap<>(defaultValue); } - @Override - protected Reference2IntMap parseImpl(String str) { - String[] values = str.split(","); - Reference2IntMap effects = new Reference2IntOpenHashMap<>(EMPTY_STATUS_EFFECT_MAP); - - try { - for (String value : values) { - String[] split = value.split(" "); - - StatusEffect effect = parseId(Registries.STATUS_EFFECT, split[0]); - int level = Integer.parseInt(split[1]); - - effects.put(effect, level); - } - } catch (Exception ignored) {} - - return effects; - } - - @Override - protected boolean isValueValid(Reference2IntMap value) { - return true; - } - @Override public NbtCompound save(NbtCompound tag) { NbtCompound valueTag = new NbtCompound(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java index 268f7325ab..55c0f29641 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java @@ -28,26 +28,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List effects = new ArrayList<>(values.length); - - try { - for (String value : values) { - StatusEffect effect = parseId(Registries.STATUS_EFFECT, value); - if (effect != null) effects.add(effect); - } - } catch (Exception ignored) {} - - return effects; - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.STATUS_EFFECT.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java index 194dce2392..f40bb908e9 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java @@ -58,27 +58,6 @@ public void resetImpl() { value = new ArrayList<>(defaultValue); } - @Override - protected List> parseImpl(String str) { - String[] values = str.split(","); - List> blocks = new ArrayList<>(values.length); - - try { - for (String value : values) { - BlockEntityType block = parseId(Registries.BLOCK_ENTITY_TYPE, value); - if (block != null) blocks.add(block); - } - } catch (Exception ignored) { - } - - return blocks; - } - - @Override - protected boolean isValueValid(List> value) { - return true; - } - @Override public Iterable getIdentifierSuggestions() { return Registries.BLOCK_ENTITY_TYPE.getIds(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java index a7f834f534..ada15d069c 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java @@ -33,16 +33,6 @@ public StringListSetting(String name, String description, List defaultVa this.filter = filter; } - @Override - protected List parseImpl(String str) { - return Arrays.asList(str.split(",")); - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - @Override public NbtCompound save(NbtCompound tag) { NbtList valueTag = new NbtList(); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StringSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StringSetting.java index 382df1b480..05aa5ef324 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StringSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StringSetting.java @@ -24,16 +24,6 @@ public StringSetting(String name, String description, String defaultValue, Consu this.wide = wide; } - @Override - protected String parseImpl(String str) { - return str; - } - - @Override - protected boolean isValueValid(String value) { - return true; - } - @Override public NbtCompound save(NbtCompound tag) { tag.putString("value", get()); diff --git a/src/main/java/meteordevelopment/meteorclient/settings/Vector3dSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/Vector3dSetting.java index 10f9aba317..93958f05b8 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/Vector3dSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/Vector3dSetting.java @@ -40,16 +40,6 @@ protected void resetImpl() { value.set(defaultValue); } - @Override - protected Vector3d parseImpl(String str) { - try { - String[] strs = str.split(" "); - return new Vector3d(Double.parseDouble(strs[0]), Double.parseDouble(strs[1]), Double.parseDouble(strs[2])); - } catch (IndexOutOfBoundsException | NumberFormatException ignored) { - return null; - } - } - @Override protected boolean isValueValid(Vector3d value) { return value.x >= min && value.x <= max && value.y >= min && value.y <= max && value.z >= min && value.z <= max;