Files
MidnightLib/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java
2025-04-05 12:10:11 +02:00

86 lines
4.5 KiB
Java

package eu.midnightdust.lib.config;
import com.mojang.brigadier.arguments.*;
import com.mojang.brigadier.context.CommandContext;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import static eu.midnightdust.lib.config.MidnightConfig.Entry;
public class AutoCommand {
final static String VALUE = "value";
final Field field;
final Class<?> type;
final String modid;
final boolean isList;
public AutoCommand(Field field, String modid) {
this.field = field; this.modid = modid;
this.type = MidnightConfig.getUnderlyingType(field);
this.isList = field.getType() == List.class;
var command = 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 : new String[]{"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(CommandManager.literal("midnightconfig").requires(source -> source.hasPermissionLevel(2)).then(CommandManager.literal(modid).then(command)));
}
public ArgumentType<?> getArgType() {
Entry entry = field.getAnnotation(Entry.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 (type == boolean.class) return BoolArgumentType.bool();
return StringArgumentType.string();
}
public int setValueFromArg(CommandContext<ServerCommandSource> context, String action) {
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 (!isList) field.set(null, value);
else {
@SuppressWarnings("unchecked") var list = (List<Object>) 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(isList ? "Could not %s %s %s %s: %s".formatted(add ? "add" : "remove", value, add ? "to" : "from", field.getName(), e) : "Could not set %s to value %s: %s".formatted(field.getName(), value, e)));
return 0;
}
source.sendFeedback(() -> Text.literal(isList ? "Successfully %s %s %s %s".formatted(add ? "added" : "removed", value, add ? "to" : "from", field.getName()) :
"Successfully set %s to %s".formatted(field.getName(), value)), true);
return 1;
}
private int getValue(CommandContext<ServerCommandSource> context) {
context.getSource().sendFeedback(() -> {
try { return Text.literal("The value of %s is %s".formatted(field.getName(), field.get(null)));
} catch (IllegalAccessException e) {throw new RuntimeException(e);}
}, true);
return 0;
}
}