summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/ohmyvanillamc
diff options
context:
space:
mode:
authorKeuin <[email protected]>2021-01-16 15:34:15 +0800
committerkeuin <[email protected]>2021-01-16 15:34:15 +0800
commitc96ce10cdcf75cf642101b00cc9572304d276851 (patch)
treedd1adaa56fe890e3e6f9b790ed654d2f33a1a0a2 /src/main/java/com/keuin/ohmyvanillamc
parent9aeb1b613329cc201766e5d97e5853c879a5d2fe (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.java219
-rw-r--r--src/main/java/com/keuin/ohmyvanillamc/ReflectionUtils.java32
-rw-r--r--src/main/java/com/keuin/ohmyvanillamc/config/ImmutableOmvmConfiguration.java45
-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.java1
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) {