From 8039bf3fecb70dae52277104b8fc46871e4902c0 Mon Sep 17 00:00:00 2001 From: Martin Prokoph Date: Wed, 28 Aug 2024 11:38:35 +0200 Subject: [PATCH] Improved automatic command registration --- build.gradle | 2 +- .../eu/midnightdust/core/MidnightLib.java | 2 +- .../midnightdust/lib/config/AutoCommand.java | 147 ++++++++---------- .../lib/config/MidnightConfig.java | 2 +- gradle.properties | 2 +- 5 files changed, 67 insertions(+), 88 deletions(-) diff --git a/build.gradle b/build.gradle index b2bf9d9..98a36f7 100644 --- a/build.gradle +++ b/build.gradle @@ -50,7 +50,7 @@ allprojects { releaseChangelog = { def changes = new StringBuilder() changes << "## MidnightLib v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/TeamMidnightDust/MidnightLib/commits/)" - def proc = "git log --max-count=1 --pretty=format:%s".execute() + def proc = "git log --max-count=10 --pretty=format:%s".execute() proc.in.eachLine { line -> def processedLine = line.toString() if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) { diff --git a/common/src/main/java/eu/midnightdust/core/MidnightLib.java b/common/src/main/java/eu/midnightdust/core/MidnightLib.java index 2999bc2..ba6ae79 100755 --- a/common/src/main/java/eu/midnightdust/core/MidnightLib.java +++ b/common/src/main/java/eu/midnightdust/core/MidnightLib.java @@ -29,7 +29,7 @@ public class MidnightLib { MidnightConfig.configClass.forEach((modid, config) -> { for (Field field : config.getFields()) { if (field.isAnnotationPresent(MidnightConfig.Entry.class) && !field.isAnnotationPresent(MidnightConfig.Client.class) && !field.isAnnotationPresent(MidnightConfig.Hidden.class)) - new AutoCommand(field, modid).register(); + new AutoCommand(field, modid); } }); } diff --git a/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java b/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java index 5598308..93df235 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java +++ b/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java @@ -1,10 +1,8 @@ package eu.midnightdust.lib.config; -import com.mojang.brigadier.arguments.DoubleArgumentType; -import com.mojang.brigadier.arguments.FloatArgumentType; -import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.arguments.*; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; import eu.midnightdust.lib.util.PlatformFunctions; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; @@ -12,106 +10,87 @@ import net.minecraft.text.Text; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.Objects; -@SuppressWarnings("unchecked") public class AutoCommand { public static List> commands = new ArrayList<>(); - final Field entry; + final static String VALUE = "value"; + final Field field; + final Class type; final String modid; + final boolean isList; - public AutoCommand(Field entry, String modid) { - this.entry = entry; + public AutoCommand(Field field, String modid) { + this.field = field; this.modid = modid; + this.type = field.getType(); + this.isList = field.getType() == List.class; + + LiteralArgumentBuilder command = CommandManager.literal("midnightconfig").requires(source -> source.hasPermissionLevel(2)).then( + CommandManager.literal(modid).then(CommandManager.literal(field.getName()).executes(this::getValue))); + + if (type.isEnum()) { + for (Object enumValue : field.getType().getEnumConstants()) { + command = command.then(CommandManager.literal(enumValue.toString()).executes(ctx -> this.setValue(ctx.getSource(), enumValue, ""))); + } + } + else if (isList) { + for (String action : List.of("add", "remove")) { + command = command.then(CommandManager.literal(action).then( + CommandManager.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, action)))); + } + } + else command = command.then(CommandManager.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, ""))); + + PlatformFunctions.registerCommand(command); commands.add(command); } - public void register() { - LiteralArgumentBuilder command = CommandManager.literal(modid); - if (entry.getType() == int.class) - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( - CommandManager.argument("value", IntegerArgumentType.integer((int) entry.getAnnotation(MidnightConfig.Entry.class).min(),(int) entry.getAnnotation(MidnightConfig.Entry.class).max())) - .executes(ctx -> this.setValue(ctx.getSource(), IntegerArgumentType.getInteger(ctx, "value"))) - )); - else if (entry.getType() == double.class) - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( - CommandManager.argument("value", DoubleArgumentType.doubleArg(entry.getAnnotation(MidnightConfig.Entry.class).min(),entry.getAnnotation(MidnightConfig.Entry.class).max())) - .executes(ctx -> this.setValue(ctx.getSource(), DoubleArgumentType.getDouble(ctx, "value"))) - )); - else if (entry.getType() == float.class) - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( - CommandManager.argument("value", FloatArgumentType.floatArg((float) entry.getAnnotation(MidnightConfig.Entry.class).min(), (float) entry.getAnnotation(MidnightConfig.Entry.class).max())) - .executes(ctx -> this.setValue(ctx.getSource(), FloatArgumentType.getFloat(ctx, "value"))) - )); - else if (entry.getType() == boolean.class) { - for (int i = 0; i < 2; i++) { - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( - CommandManager.literal(i==0 ? "true":"false") - .executes(ctx -> this.setValue(ctx.getSource(), ctx.getInput().endsWith("true"))) - )); - } + public ArgumentType getArgType() { + MidnightConfig.Entry entry = type.getAnnotation(MidnightConfig.Entry.class); + if (type.isInstance(Number.class)) { + if (type == int.class) return IntegerArgumentType.integer((int) entry.min(), (int) entry.max()); + else if (type == double.class) return DoubleArgumentType.doubleArg(entry.min(), entry.max()); + else if (type == float.class) return FloatArgumentType.floatArg((float) entry.min(), (float) entry.max()); } - else if (entry.getType().isEnum()) { - for (int i = 0; i < entry.getType().getEnumConstants().length; ++i) { - Object enumValue = Arrays.stream(entry.getType().getEnumConstants()).toList().get(i); - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( - CommandManager.literal(enumValue.toString()) - .executes(ctx -> this.setValue(ctx.getSource(), enumValue)) - )); - } - } - else if (entry.getType() == List.class) { - for (int i = 0; i < 2; i++) { - int finalI = i; - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then(CommandManager.literal(i==0 ? "add":"remove").then( - CommandManager.argument("value", StringArgumentType.string()) - .executes(ctx -> this.setList(ctx.getSource(), StringArgumentType.getString(ctx, "value"), finalI==0)) - ))); - } - } - else { - command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( - CommandManager.argument("value", StringArgumentType.string()) - .executes(ctx -> this.setValue(ctx.getSource(), StringArgumentType.getString(ctx, "value"))) - )); - } - LiteralArgumentBuilder finalized = CommandManager.literal("midnightconfig").requires(source -> source.hasPermissionLevel(2)).then(command); - - PlatformFunctions.registerCommand(finalized); commands.add(finalized); + else if (type == boolean.class) return BoolArgumentType.bool(); + return StringArgumentType.string(); } - private int setValue(ServerCommandSource source, Object value) { + public int setValueFromArg(CommandContext context, String action) { + if (type.isInstance(Number.class)) { + if (type == int.class) return setValue(context.getSource(), IntegerArgumentType.getInteger(context, VALUE), action); + else if (type == double.class) return setValue(context.getSource(), DoubleArgumentType.getDouble(context, VALUE), action); + else if (type == float.class) return setValue(context.getSource(), FloatArgumentType.getFloat(context, VALUE), action); + } + else if (type == boolean.class) return setValue(context.getSource(), BoolArgumentType.getBool(context, VALUE), action); + return setValue(context.getSource(), StringArgumentType.getString(context, VALUE), action); + } + private int setValue(ServerCommandSource source, Object value, String action) { + boolean add = Objects.equals(action, "add"); try { - if (entry.getType() != List.class) entry.set(null,value); + if (!isList) field.set(null, value); + else { + @SuppressWarnings("unchecked") var list = (List) field.get(null); + if (add) list.add(value); + else if (!list.contains(value)) throw new IllegalArgumentException("List does not contain this string!"); + else list.remove(value); + } MidnightConfig.write(modid); } catch (Exception e) { - source.sendError(Text.literal("Could not set "+entry.getName()+" to value "+value+": " + e)); + if (!isList) source.sendError(Text.literal("Could not set "+field.getName()+" to value "+value+": " + e)); + else source.sendError(Text.literal((add ? "Could not add "+value+" to " : "Could not remove "+value+" from ")+field.getName() +": " + e)); return 0; } - - source.sendFeedback(() -> Text.literal("Successfully set " + entry.getName()+" to "+value), true); + if (!isList) source.sendFeedback(() -> Text.literal("Successfully set " + field.getName()+" to "+value), true); + else source.sendFeedback(() -> Text.literal((add ? "Successfully added " +value+" to " : "Successfully removed " +value+" from ") +field.getName()), true); return 1; } - private int setList(ServerCommandSource source, String value, boolean add) { - try { - List e = (List)entry.get(null); - if (add) e.add(value); - else if (!e.contains(value)) throw new IllegalArgumentException("List does not contain this string!"); - else e.remove(value); - MidnightConfig.write(modid); - } - catch (Exception e) { - source.sendError(Text.literal((add ? "Could not add "+value+" to " : "Could not remove "+value+" from ")+entry.getName() +": " + e)); - return 0; - } - source.sendFeedback(() -> Text.literal((add ? "Successfully added " +value+" to " : "Successfully removed " +value+" from ") +entry.getName()), true); - return 1; - } - private int getValue(ServerCommandSource source) { - source.sendFeedback(() -> { - try {return Text.literal("The value of "+entry.getName()+" is "+entry.get(null)); + private int getValue(CommandContext context) { + context.getSource().sendFeedback(() -> { + try { return Text.literal("The value of "+field.getName()+" is "+field.get(null)); } catch (IllegalAccessException e) {throw new RuntimeException(e);} }, true); return 0; } -} +} \ No newline at end of file diff --git a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java index da35c4c..76a18f8 100755 --- a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java +++ b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java @@ -351,7 +351,7 @@ public abstract class MidnightConfig { } catch (Exception ignored) {} info.actionButton = colorButton; } else if (e.selectionMode() > -1) { - ButtonWidget explorerButton = TextIconButtonWidget.builder(Text.of(""), + ButtonWidget explorerButton = TextIconButtonWidget.builder(Text.empty(), button -> new Thread(() -> { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(e.selectionMode()); fileChooser.setDialogType(e.fileChooserType()); diff --git a/gradle.properties b/gradle.properties index 3b3a7b5..49f0784 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ yarn_mappings=1.21+build.1 enabled_platforms=fabric,neoforge archives_base_name=midnightlib -mod_version=1.6.0 +mod_version=1.6.1 maven_group=eu.midnightdust release_type=release curseforge_id=488090