LibJF/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/JfConfigCommand.java

149 lines
8.0 KiB
Java
Raw Normal View History

package io.gitlab.jfronny.libjf.config.impl;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.*;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
2022-04-29 15:48:27 +02:00
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import io.gitlab.jfronny.commons.throwable.ThrowingRunnable;
import io.gitlab.jfronny.commons.throwable.ThrowingSupplier;
import io.gitlab.jfronny.libjf.LibJf;
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
2022-04-29 15:48:27 +02:00
import io.gitlab.jfronny.libjf.config.api.EntryInfo;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import java.util.function.Consumer;
import java.util.function.Function;
import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;
public class JfConfigCommand implements ModInitializer {
@Override
public void onInitialize() {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> {
LiteralArgumentBuilder<ServerCommandSource> c_libjf = literal(LibJf.MOD_ID);
LiteralArgumentBuilder<ServerCommandSource> c_config = literal("config")
.requires((serverCommandSource) -> serverCommandSource.hasPermissionLevel(4))
.executes(context -> {
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Loaded configs for:"), false);
ConfigHolder.getInstance().getRegistered().forEach((s, config) -> {
context.getSource().sendFeedback(new LiteralText("- " + s), false);
});
return Command.SINGLE_SUCCESS;
});
LiteralArgumentBuilder<ServerCommandSource> c_reload = literal("reload").executes(context -> {
ConfigHolder.getInstance().getRegistered().forEach((mod, config) -> config.load());
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Reloaded configs"), true);
return Command.SINGLE_SUCCESS;
});
LiteralArgumentBuilder<ServerCommandSource> c_reset = literal("reset").executes(context -> {
context.getSource().sendError(new LiteralText("[libjf-config-v0] Please specify a config to reset"));
return Command.SINGLE_SUCCESS;
});
ConfigHolder.getInstance().getRegistered().forEach((id, config) -> {
registerEntries(config, id, c_config, c_reload, c_reset, cns -> {
LiteralArgumentBuilder<ServerCommandSource> c_instance = literal(id);
cns.accept(c_instance);
return c_instance;
});
});
dispatcher.register(c_libjf.then(c_config.then(c_reload).then(c_reset)));
});
}
private void registerEntries(ConfigInstance config, String subpath, LiteralArgumentBuilder<ServerCommandSource> c_config, LiteralArgumentBuilder<ServerCommandSource> c_reload, LiteralArgumentBuilder<ServerCommandSource> c_reset, Function<Consumer<LiteralArgumentBuilder<ServerCommandSource>>, LiteralArgumentBuilder<ServerCommandSource>> pathGen) {
c_config.then(pathGen.apply(cns -> {
cns.executes(context -> {
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] " + subpath + " is a category"), false);
return Command.SINGLE_SUCCESS;
});
2022-04-29 15:48:27 +02:00
for (EntryInfo<?> entry : config.getEntries()) {
registerEntry(config, subpath, cns, entry);
}
}));
c_reload.then(pathGen.apply(cns -> cns.executes(context -> {
config.load();
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Reloaded config for " + subpath), true);
return Command.SINGLE_SUCCESS;
})));
c_reset.then(pathGen.apply(cns -> {
cns.executes(context -> {
config.getPresets().get(ConfigInstanceAbstract.CONFIG_PRESET_DEFAULT).run();
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Reset config for " + subpath), true);
return Command.SINGLE_SUCCESS;
});
config.getPresets().forEach((id2, preset) -> {
cns.then(literal(id2).executes(context -> {
preset.run();
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Loaded preset " + id2 + " for " + subpath), true);
return Command.SINGLE_SUCCESS;
}));
});
}));
config.getCategories().forEach((id2, cfg) -> {
registerEntries(cfg, cfg.getCategoryPath(), c_config, c_reload, c_reset, cns -> {
return pathGen.apply(cns1 -> {
LiteralArgumentBuilder<ServerCommandSource> c_instance2 = literal(id2);
cns.accept(c_instance2);
cns1.then(c_instance2);
});
});
});
}
2022-04-29 15:48:27 +02:00
private final DynamicCommandExceptionType eType = new DynamicCommandExceptionType(o -> {
if (o instanceof Throwable throwable) {
return new LiteralText("Could not execute command: " + throwable.getMessage());
} else return new LiteralText("Could not execute command");
});
private <T> void registerEntry(ConfigInstance config, String subpath, LiteralArgumentBuilder<ServerCommandSource> cns, EntryInfo<T> entry) {
LiteralArgumentBuilder<ServerCommandSource> c_entry = literal(entry.getName()).executes(context -> {
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] The value of " + subpath + entry.getName() + " is " + tryRun(entry::getValue)), false);
return Command.SINGLE_SUCCESS;
});
ArgumentType<?> type = getType(entry);
if (type != null) {
c_entry.then(argument("value", type).executes(context -> {
T value = context.getArgument("value", entry.getValueType());
tryRun(() -> entry.setValue(value));
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Set " + subpath + entry.getName() + " to " + value), true);
return Command.SINGLE_SUCCESS;
}));
}
else if (entry.getValueType().isEnum()) {
for (T enumConstant : entry.getValueType().getEnumConstants()) {
c_entry.then(literal(enumConstant.toString()).executes(context -> {
tryRun(() -> entry.setValue(enumConstant));
context.getSource().sendFeedback(new LiteralText("[libjf-config-v0] Set " + subpath + entry.getName() + " to " + enumConstant), true);
return Command.SINGLE_SUCCESS;
}));
}
}
cns.then(c_entry);
}
private <T> ArgumentType<?> getType(EntryInfo<T> info) {
Class<T> type = info.getValueType();
2022-04-29 16:07:12 +02:00
if (type == int.class || type == Integer.class) return IntegerArgumentType.integer((int) info.getMinValue(), (int) info.getMaxValue());
else if (type == float.class || type == Float.class) return FloatArgumentType.floatArg((float) info.getMinValue(), (float) info.getMaxValue());
else if (type == double.class || type == Double.class) return DoubleArgumentType.doubleArg(info.getMinValue(), info.getMaxValue());
else if (type == String.class) return StringArgumentType.greedyString();
else if (type == boolean.class || type == Boolean.class) return BoolArgumentType.bool();
else return null;
}
2022-04-29 15:48:27 +02:00
private <T> T tryRun(ThrowingSupplier<T, ?> supplier) throws CommandSyntaxException {
return supplier.orThrow(eType::create).get();
}
private void tryRun(ThrowingRunnable<?> supplier) throws CommandSyntaxException {
supplier.orThrow(eType::create).run();
}
}