diff options
author | Keuin <[email protected]> | 2021-01-16 15:34:15 +0800 |
---|---|---|
committer | keuin <[email protected]> | 2021-01-16 15:34:15 +0800 |
commit | c96ce10cdcf75cf642101b00cc9572304d276851 (patch) | |
tree | dd1adaa56fe890e3e6f9b790ed654d2f33a1a0a2 /src/main/java/com/keuin/ohmyvanillamc | |
parent | 9aeb1b613329cc201766e5d97e5853c879a5d2fe (diff) |
Add runtime configuration editing command `/omvm set <key> <value>`. The set is temporary and will not be modified in disk.
Diffstat (limited to 'src/main/java/com/keuin/ohmyvanillamc')
-rw-r--r-- | src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java | 219 | ||||
-rw-r--r-- | src/main/java/com/keuin/ohmyvanillamc/ReflectionUtils.java | 32 | ||||
-rw-r--r-- | src/main/java/com/keuin/ohmyvanillamc/config/ImmutableOmvmConfiguration.java | 45 | ||||
-rw-r--r-- | src/main/java/com/keuin/ohmyvanillamc/config/OmvmConfiguration.java (renamed from src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java) | 47 | ||||
-rw-r--r-- | src/main/java/com/keuin/ohmyvanillamc/mixin/Mc113809BambooBlockMixin.java | 1 |
5 files changed, 248 insertions, 96 deletions
diff --git a/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java b/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java index 76936fa..e64708d 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java +++ b/src/main/java/com/keuin/ohmyvanillamc/OhMyVanillaMinecraft.java @@ -3,88 +3,171 @@ package com.keuin.ohmyvanillamc; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonIOException; +import com.keuin.ohmyvanillamc.config.ImmutableOmvmConfiguration; +import com.keuin.ohmyvanillamc.config.OmvmConfiguration; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.LiteralText; +import net.minecraft.text.Style; +import net.minecraft.util.Formatting; import java.io.*; import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.CompletableFuture; import java.util.logging.Logger; +import java.util.stream.Stream; + +import static com.keuin.ohmyvanillamc.ReflectionUtils.getFieldName; +import static com.keuin.ohmyvanillamc.ReflectionUtils.setPrivateField; public class OhMyVanillaMinecraft implements ModInitializer { - private static final Logger LOGGER = Logger.getLogger("OhMyVanillaMinecraft"); - - private static OmvmConfiguration configuration = null; - private static final OmvmConfiguration defaultConfiguration = new OmvmConfiguration(); - - public static OmvmConfiguration getConfiguration() { - return configuration != null ? configuration : defaultConfiguration; - } - - @Override - public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - LOGGER.info("Loading configuration..."); - - // load configuration - - final String fileName = "omvm.json"; - final File file = new File(fileName); - if (!file.exists()) { - LOGGER.info("Configuration file does not exist! Use default configuration."); - try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { - final String jsonString = (new GsonBuilder().setPrettyPrinting().create()).toJson(defaultConfiguration); - try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream)) { - outputStreamWriter.write(jsonString); - } - } catch (FileNotFoundException e) { - LOGGER.severe("Cannot write default configuration to file `" + fileName + "`: " + e); - } catch (IOException e) { - LOGGER.severe("Failed to write default configuration to file `" + fileName + "`: " + e); - } - } else { - try (FileInputStream fileInputStream = new FileInputStream(file)) { - try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8)) { - try (BufferedReader reader = new BufferedReader(inputStreamReader)) { - configuration = (new Gson()).fromJson(reader, OmvmConfiguration.class); - } - } - } catch (IOException e) { - LOGGER.severe("Failed to read config file `" + fileName + "`: " + e); - } catch (JsonIOException e) { - LOGGER.severe("Failed to decode config json file `" + fileName + "`: " + e); - } - } - - if (configuration == null) { - configuration = defaultConfiguration; - } - - LOGGER.info("Configuration: \n==========\n" + configuration + "\n=========="); - - CommandRegistrationCallback.EVENT.register(new CommandRegistrationCallback() { - @Override - public void register(CommandDispatcher<ServerCommandSource> commandDispatcher, boolean b) { - commandDispatcher.register(CommandManager.literal("omvm").executes(new Command<ServerCommandSource>() { - @Override - public int run(CommandContext<ServerCommandSource> context) throws CommandSyntaxException { - String text = "OhMyVanillaMinecraft\n==========\n" + getConfiguration() + "\n=========="; - context.getSource().sendFeedback(new LiteralText(text), false); - return 1; // 1: success, -1: fail - } - })); - } - }); - - } + private static final Logger LOGGER = Logger.getLogger("OhMyVanillaMinecraft"); + + private static final OmvmConfiguration defaultConfiguration = + new ImmutableOmvmConfiguration(true, true, true, true, true, true); + private static OmvmConfiguration configuration = null; + + public static OmvmConfiguration getConfiguration() { + return configuration; + } + + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + LOGGER.info("Loading configuration..."); + + // load configuration + + final String fileName = "omvm.json"; + final File file = new File(fileName); + if (!file.exists()) { + LOGGER.info("Configuration file does not exist! Use default configuration."); + try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { + final String jsonString = (new GsonBuilder().setPrettyPrinting().create()).toJson(defaultConfiguration); + try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream)) { + outputStreamWriter.write(jsonString); + } + } catch (FileNotFoundException e) { + LOGGER.severe("Cannot write default configuration to file `" + fileName + "`: " + e); + } catch (IOException e) { + LOGGER.severe("Failed to write default configuration to file `" + fileName + "`: " + e); + } + } else { + try (FileInputStream fileInputStream = new FileInputStream(file)) { + try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8)) { + try (BufferedReader reader = new BufferedReader(inputStreamReader)) { + configuration = (new Gson()).fromJson(reader, OmvmConfiguration.class); + } + } + } catch (IOException e) { + LOGGER.severe("Failed to read config file `" + fileName + "`: " + e); + } catch (JsonIOException e) { + LOGGER.severe("Failed to decode config json file `" + fileName + "`: " + e); + } + } + + if (configuration == null) { + configuration = new OmvmConfiguration(defaultConfiguration); + } + + LOGGER.info("Configuration: \n==========\n" + configuration + "\n=========="); + + CommandRegistrationCallback.EVENT.register(new CommandRegistrationCallback() { + @Override + public void register(CommandDispatcher<ServerCommandSource> commandDispatcher, boolean b) { + commandDispatcher.register(CommandManager.literal("omvm").executes(new Command<ServerCommandSource>() { + @Override + public int run(CommandContext<ServerCommandSource> context) throws CommandSyntaxException { + String text = "OhMyVanillaMinecraft\n==========\n" + getConfiguration() + "\n=========="; + context.getSource().sendFeedback(new LiteralText(text), false); + return 1; // 1: success, -1: fail + } + })); + } + }); + + + String[] keys = getFieldName(configuration); + final Set<String> keySet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(keys))); + + CommandRegistrationCallback.EVENT.register(new CommandRegistrationCallback() { + @Override + public void register(CommandDispatcher<ServerCommandSource> commandDispatcher, boolean b) { + commandDispatcher.register(CommandManager.literal("omvm") + .then(CommandManager.literal("set") + .then(CommandManager.argument("key", StringArgumentType.word()) + .suggests(new SuggestionProvider<ServerCommandSource>() { + @Override + public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) throws CommandSyntaxException { + String remaining = builder.getRemaining().toLowerCase(Locale.ROOT); + keySet.stream().filter(key -> key.toLowerCase().startsWith(remaining)).forEach(builder::suggest); + return builder.buildFuture(); + } + }) + .then(CommandManager.argument("value", StringArgumentType.word()).suggests(new SuggestionProvider<ServerCommandSource>() { + @Override + public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) throws CommandSyntaxException { + String remaining = builder.getRemaining().toLowerCase(Locale.ROOT); + Stream.of("true", "false").filter(key -> key.toLowerCase().startsWith(remaining)).forEach(builder::suggest); + return builder.buildFuture(); + } + }) + .executes(new Command<ServerCommandSource>() { + @Override + public int run(CommandContext<ServerCommandSource> context) throws CommandSyntaxException { + try { + String key = context.getArgument("key", String.class); + String value = context.getArgument("value", String.class); + + if (!keySet.contains(key)) { + StringBuilder sb = new StringBuilder(); + sb.append("Invalid key. Available keys:"); + keySet.forEach(k -> sb.append("\n- ").append(k)); + context.getSource().sendFeedback(new LiteralText(sb.toString()) + .setStyle(Style.EMPTY.withColor(Formatting.RED)), false); + return -1; + } + + if (!Arrays.asList("true", "false").contains(value)) { + context.getSource().sendFeedback(new LiteralText("Value must be `true` or `false`.") + .setStyle(Style.EMPTY.withColor(Formatting.RED)), false); + return -1; + } + + setPrivateField(configuration, key, Boolean.valueOf(value)); + context.getSource().sendFeedback( + new LiteralText("`" + key + "` has been temporarily set to `" + value + "`."), true + ); + + return 1; // 1: success, -1: fail + } catch (NoSuchFieldException | IllegalAccessException e) { + context.getSource().sendFeedback(new LiteralText("There is a bug. Tell trueKeuin.") + .setStyle(Style.EMPTY.withColor(Formatting.RED)), false); + return -1; + } + } + }) + ) + ))); + } + }); + + } + + } diff --git a/src/main/java/com/keuin/ohmyvanillamc/ReflectionUtils.java b/src/main/java/com/keuin/ohmyvanillamc/ReflectionUtils.java index 253c89d..a87632e 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/ReflectionUtils.java +++ b/src/main/java/com/keuin/ohmyvanillamc/ReflectionUtils.java @@ -3,9 +3,10 @@ package com.keuin.ohmyvanillamc; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; /** - * @Author 落叶飞翔的蜗牛 + * @Author 落叶飞翔的蜗牛 Keuin * @Date 2018/3/10 * @Description 常用反射函数 */ @@ -13,10 +14,6 @@ public final class ReflectionUtils { /** * 获取私有成员变量的值 - * - * @param instance - * @param filedName - * @return */ public static Object getPrivateField(Object instance, String filedName) throws NoSuchFieldException, IllegalAccessException { Field field = instance.getClass().getDeclaredField(filedName); @@ -26,12 +23,6 @@ public final class ReflectionUtils { /** * 设置私有成员的值 - * - * @param instance - * @param fieldName - * @param value - * @throws NoSuchFieldException - * @throws IllegalAccessException */ public static void setPrivateField(Object instance, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { Field field = instance.getClass().getDeclaredField(fieldName); @@ -41,19 +32,20 @@ public final class ReflectionUtils { /** * 访问私有方法 - * - * @param instance - * @param methodName - * @param classes - * @param args - * @return - * @throws NoSuchMethodException - * @throws InvocationTargetException - * @throws IllegalAccessException */ public static Object invokePrivateMethod(Object instance, String methodName, Class[] classes, Object... args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method method = instance.getClass().getDeclaredMethod(methodName, classes); method.setAccessible(true); return method.invoke(instance, args); } + + /** + * 获取所有成员变量的名字 + * + * @param o 要获取成员变量的对象实例 + * @return 所有成员变量名字数组 + */ + public static String[] getFieldName(Object o) { + return Arrays.stream(o.getClass().getDeclaredFields()).map(Field::getName).toArray(String[]::new); + } }
\ No newline at end of file diff --git a/src/main/java/com/keuin/ohmyvanillamc/config/ImmutableOmvmConfiguration.java b/src/main/java/com/keuin/ohmyvanillamc/config/ImmutableOmvmConfiguration.java new file mode 100644 index 0000000..e5a34e1 --- /dev/null +++ b/src/main/java/com/keuin/ohmyvanillamc/config/ImmutableOmvmConfiguration.java @@ -0,0 +1,45 @@ +package com.keuin.ohmyvanillamc.config; + +public class ImmutableOmvmConfiguration extends OmvmConfiguration { + + public ImmutableOmvmConfiguration() { + } + + public ImmutableOmvmConfiguration(OmvmConfiguration omvmConfiguration) { + super(omvmConfiguration); + } + + public ImmutableOmvmConfiguration(boolean fixEntityTrackerEntrySpamming, boolean disableFishSchooling, boolean disablePhantomSpawning, boolean disableWanderingTraderSpawning, boolean reintroduceLlamaItemDuplicating, boolean reintroduceZeroTickFarm) { + super(fixEntityTrackerEntrySpamming, disableFishSchooling, disablePhantomSpawning, disableWanderingTraderSpawning, reintroduceLlamaItemDuplicating, reintroduceZeroTickFarm); + } + + @Override + public void setFixEntityTrackerEntrySpamming(boolean fixEntityTrackerEntrySpamming) { + throw new UnsupportedOperationException(); + } + + @Override + public void setDisableFishSchooling(boolean disableFishSchooling) { + throw new UnsupportedOperationException(); + } + + @Override + public void setDisablePhantomSpawning(boolean disablePhantomSpawning) { + throw new UnsupportedOperationException(); + } + + @Override + public void setDisableWanderingTraderSpawning(boolean disableWanderingTraderSpawning) { + throw new UnsupportedOperationException(); + } + + @Override + public void setReintroduceLlamaItemDuplicating(boolean reintroduceLlamaItemDuplicating) { + throw new UnsupportedOperationException(); + } + + @Override + public void setReintroduceZeroTickFarm(boolean reintroduceZeroTickFarm) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java b/src/main/java/com/keuin/ohmyvanillamc/config/OmvmConfiguration.java index b3d7b83..70ce1a7 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/OmvmConfiguration.java +++ b/src/main/java/com/keuin/ohmyvanillamc/config/OmvmConfiguration.java @@ -1,20 +1,29 @@ -package com.keuin.ohmyvanillamc; +package com.keuin.ohmyvanillamc.config; import java.util.Objects; public class OmvmConfiguration { - private final boolean fixEntityTrackerEntrySpamming; - private final boolean disableFishSchooling; - private final boolean disablePhantomSpawning; - private final boolean disableWanderingTraderSpawning; - private final boolean reintroduceLlamaItemDuplicating; - private final boolean reintroduceZeroTickFarm; + private boolean fixEntityTrackerEntrySpamming; + private boolean disableFishSchooling; + private boolean disablePhantomSpawning; + private boolean disableWanderingTraderSpawning; + private boolean reintroduceLlamaItemDuplicating; + private boolean reintroduceZeroTickFarm; public OmvmConfiguration() { this(true, false, false, false, false, false); } + public OmvmConfiguration(OmvmConfiguration omvmConfiguration) { + this.fixEntityTrackerEntrySpamming = omvmConfiguration.fixEntityTrackerEntrySpamming; + this.disableFishSchooling = omvmConfiguration.disableFishSchooling; + this.disablePhantomSpawning = omvmConfiguration.disablePhantomSpawning; + this.disableWanderingTraderSpawning = omvmConfiguration.disableWanderingTraderSpawning; + this.reintroduceLlamaItemDuplicating = omvmConfiguration.reintroduceLlamaItemDuplicating; + this.reintroduceZeroTickFarm = omvmConfiguration.reintroduceZeroTickFarm; + } + public OmvmConfiguration(boolean fixEntityTrackerEntrySpamming, boolean disableFishSchooling, boolean disablePhantomSpawning, boolean disableWanderingTraderSpawning, boolean reintroduceLlamaItemDuplicating, boolean reintroduceZeroTickFarm) { this.fixEntityTrackerEntrySpamming = fixEntityTrackerEntrySpamming; this.disableFishSchooling = disableFishSchooling; @@ -48,6 +57,30 @@ public class OmvmConfiguration { return reintroduceZeroTickFarm; } + public void setFixEntityTrackerEntrySpamming(boolean fixEntityTrackerEntrySpamming) { + this.fixEntityTrackerEntrySpamming = fixEntityTrackerEntrySpamming; + } + + public void setDisableFishSchooling(boolean disableFishSchooling) { + this.disableFishSchooling = disableFishSchooling; + } + + public void setDisablePhantomSpawning(boolean disablePhantomSpawning) { + this.disablePhantomSpawning = disablePhantomSpawning; + } + + public void setDisableWanderingTraderSpawning(boolean disableWanderingTraderSpawning) { + this.disableWanderingTraderSpawning = disableWanderingTraderSpawning; + } + + public void setReintroduceLlamaItemDuplicating(boolean reintroduceLlamaItemDuplicating) { + this.reintroduceLlamaItemDuplicating = reintroduceLlamaItemDuplicating; + } + + public void setReintroduceZeroTickFarm(boolean reintroduceZeroTickFarm) { + this.reintroduceZeroTickFarm = reintroduceZeroTickFarm; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/com/keuin/ohmyvanillamc/mixin/Mc113809BambooBlockMixin.java b/src/main/java/com/keuin/ohmyvanillamc/mixin/Mc113809BambooBlockMixin.java index 2e0e274..ef4b9c1 100644 --- a/src/main/java/com/keuin/ohmyvanillamc/mixin/Mc113809BambooBlockMixin.java +++ b/src/main/java/com/keuin/ohmyvanillamc/mixin/Mc113809BambooBlockMixin.java @@ -74,7 +74,6 @@ public abstract class Mc113809BambooBlockMixin extends Block { } else { realGrow(state, world, pos, random); } - } private void realGrow(BlockState state, ServerWorld world, BlockPos pos, Random random) { |