From 08fa0725d3f97dd8906d68ad0934370c0491b987 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:21:43 +1000 Subject: [PATCH] Beans --- .../me/cortex/voxy/common/util/MultiGson.java | 31 +++-- .../configuration/VoxyConfigStore.java | 121 ++++++++++++++++++ 2 files changed, 140 insertions(+), 12 deletions(-) create mode 100644 src/main/java/me/cortex/voxy/commonImpl/configuration/VoxyConfigStore.java diff --git a/src/main/java/me/cortex/voxy/common/util/MultiGson.java b/src/main/java/me/cortex/voxy/common/util/MultiGson.java index 6143686c..e7cb221a 100644 --- a/src/main/java/me/cortex/voxy/common/util/MultiGson.java +++ b/src/main/java/me/cortex/voxy/common/util/MultiGson.java @@ -7,13 +7,9 @@ import java.util.*; public class MultiGson { private final List> classes; - private final Gson GSON = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .setPrettyPrinting() - .excludeFieldsWithModifiers(Modifier.PRIVATE) - .create(); - - private MultiGson(List> classes) { + private final Gson gson; + private MultiGson(Gson gson, List> classes) { + this.gson = gson; this.classes = classes; } @@ -38,27 +34,38 @@ public class MultiGson { var json = new JsonObject(); for (Object entry : map) { - GSON.toJsonTree(entry).getAsJsonObject().asMap().forEach((i,j) -> { + this.gson.toJsonTree(entry).getAsJsonObject().asMap().forEach((i,j) -> { if (json.has(i)) { throw new IllegalArgumentException("Duplicate name inside unified json: " + i); } json.add(i, j); }); } - return GSON.toJson(json); + return this.gson.toJson(json); } public Map, Object> fromJson(String json) { - var obj = GSON.fromJson(json, JsonObject.class); + var obj = this.gson.fromJson(json, JsonObject.class); LinkedHashMap, Object> objects = new LinkedHashMap<>(); for (var cls : this.classes) { - objects.put(cls, GSON.fromJson(obj, cls)); + objects.put(cls, this.gson.fromJson(obj, cls)); } return objects; } public static class Builder { private final LinkedHashSet> classes = new LinkedHashSet<>(); + private final GsonBuilder gsonBuilder; + public Builder(GsonBuilder gsonBuilder) { + this.gsonBuilder = gsonBuilder; + } + public Builder() { + this(new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .setPrettyPrinting() + .excludeFieldsWithModifiers(Modifier.PRIVATE)); + } + public Builder add(Class clz) { if (!this.classes.add(clz)) { throw new IllegalArgumentException("Class has already been added"); @@ -67,7 +74,7 @@ public class MultiGson { } public MultiGson build() { - return new MultiGson(new ArrayList<>(this.classes)); + return new MultiGson(this.gsonBuilder.create(), new ArrayList<>(this.classes)); } } diff --git a/src/main/java/me/cortex/voxy/commonImpl/configuration/VoxyConfigStore.java b/src/main/java/me/cortex/voxy/commonImpl/configuration/VoxyConfigStore.java new file mode 100644 index 00000000..9b01a4a4 --- /dev/null +++ b/src/main/java/me/cortex/voxy/commonImpl/configuration/VoxyConfigStore.java @@ -0,0 +1,121 @@ +package me.cortex.voxy.commonImpl.configuration; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import me.cortex.voxy.client.config.VoxyConfig; +import me.cortex.voxy.common.Logger; +import me.cortex.voxy.common.util.MultiGson; +import me.cortex.voxy.common.util.cpu.CpuLayout; +import me.cortex.voxy.commonImpl.VoxyCommon; +import net.fabricmc.loader.api.FabricLoader; + +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +public class VoxyConfigStore { + private final MultiGson gson; + + private VoxyConfigStore(Object... defaultValues) { + var gb = new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .setPrettyPrinting() + .excludeFieldsWithModifiers(Modifier.PRIVATE); + Map, Object> defaultValueMap = new HashMap<>(); + var mgb = new MultiGson.Builder(gb); + for (var i : defaultValues) { + mgb.add(i.getClass()); + defaultValueMap.put(i.getClass(), i); + } + gb.registerTypeAdapterFactory(new TypeAdapterFactory() { + @Override + public TypeAdapter create(Gson gson, TypeToken typeToken) { + if (defaultValueMap.containsKey(typeToken.getRawType())) { + var defVal = (T)defaultValueMap.get(typeToken.getRawType()); + var adapter = gson.getDelegateAdapter(this, typeToken); + return new TypeAdapter() { + @Override + public void write(JsonWriter writer, T obj) throws IOException { + var defJson = adapter.toJsonTree(defVal).getAsJsonObject(); + var val = adapter.toJsonTree(obj).getAsJsonObject(); + for (var key : defJson.keySet()) { + if (val.has(key)) { + if (defJson.get(key).equals(val.get(key))) { + val.addProperty(key, "DEFAULT_VALUE"); + } + } + } + gson.toJson(val, writer); + } + + @Override + public T read(JsonReader reader) throws IOException { + var defJson = adapter.toJsonTree(defVal).getAsJsonObject(); + var val = ((JsonElement)gson.fromJson(reader, JsonElement.class)).getAsJsonObject(); + for (var key : defJson.keySet()) { + if (val.has(key)) { + if (val.get(key).equals(new JsonPrimitive("DEFAULT_VALUE"))) { + val.add(key, defJson.get(key)); + } + } + } + return adapter.fromJsonTree(val); + } + }; + } + return null; + } + }); + this.gson = mgb.build(); + } + + /* + private static void loadOrCreate() { + if (VoxyCommon.isAvailable()) { + var path = getConfigPath(); + if (Files.exists(path)) { + try (FileReader reader = new FileReader(path.toFile())) { + var conf = GSON.fromJson(reader, VoxyConfig.class); + if (conf != null) { + conf.save(); + return conf; + } else { + Logger.error("Failed to load voxy config, resetting"); + } + } catch (IOException e) { + Logger.error("Could not parse config", e); + } + } + var config = new VoxyConfig(); + config.save(); + return config; + } else { + var config = new VoxyConfig(); + config.enabled = false; + config.enableRendering = false; + return config; + } + } + + */ + + public void save() { + try { + Files.writeString(getConfigPath(), this.gson.toJson(this)); + } catch (IOException e) { + Logger.error("Failed to write config file", e); + } + } + + private static Path getConfigPath() { + return FabricLoader.getInstance() + .getConfigDir() + .resolve("voxy-config.json"); + } +}