Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config Data Fixer #701

Merged
merged 8 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/de/hysky/skyblocker/SkyblockerMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import de.hysky.skyblocker.config.datafixer.ConfigDataFixer;
import de.hysky.skyblocker.config.ImageRepoLoader;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.debug.Debug;
Expand Down Expand Up @@ -101,6 +102,7 @@ public static SkyblockerMod getInstance() {
@Override
public void onInitializeClient() {
ClientTickEvents.END_CLIENT_TICK.register(this::tick);
ConfigDataFixer.apply();
Utils.init();
SkyblockerConfigManager.init();
SkyblockerScreen.initClass();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public class SkyblockerConfig {
@SerialEntry
public int version = 2;
public int version = SkyblockerConfigManager.CONFIG_VERSION;

@SerialEntry
public GeneralConfig general = new GeneralConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
import java.nio.file.Path;

public class SkyblockerConfigManager {
private static final Path PATH = FabricLoader.getInstance().getConfigDir().resolve("skyblocker-2.json");
public static final int CONFIG_VERSION = 2;
private static final Path CONFIG_FILE = FabricLoader.getInstance().getConfigDir().resolve("skyblocker.json");
private static final ConfigClassHandler<SkyblockerConfig> HANDLER = ConfigClassHandler.createBuilder(SkyblockerConfig.class)
.serializer(config -> GsonConfigSerializerBuilder.create(config)
.setPath(PATH)
.setPath(CONFIG_FILE)
.setJson5(false)
.appendGsonBuilder(builder -> builder
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public class QuickNavigationConfig {
*/
@SerialEntry
public QuickNavItem button4 = new QuickNavItem(true,
new ItemData("leather_chestplate", 1, "tag:{display:{color:8991416}}"), "Wardrobe \\([12]/2\\)",
new ItemData("leather_chestplate", 1, "[minecraft:dyed_color={rgb:8991416}]"), "Wardrobe \\([12]/2\\)",
"/wardrobe");

@SerialEntry
public QuickNavItem button5 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;-2081424676,-57521078,-2073572414,158072763],Properties:{textures:[{Value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}}}"),
"[minecraft:profile={id:[I;-2081424676,-57521078,-2073572414,158072763],name:\"\",properties:[{name:\"textures\",value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}]"),
"Sack of Sacks", "/sacks");

/* REGEX Explanation
Expand All @@ -44,17 +44,17 @@ public class QuickNavigationConfig {

@SerialEntry
public QuickNavItem button7 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;-300151517,-631415889,-1193921967,-1821784279],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}}}"),
"[minecraft:profile={id:[I;-300151517,-631415889,-1193921967,-1821784279],name:\"\",properties:[{name:\"textures\",value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}]"),
"none", "/hub");

@SerialEntry
public QuickNavItem button8 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;1605800870,415127827,-1236127084,15358548],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}}}"),
"[minecraft:profile={id:[I;1605800870,415127827,-1236127084,15358548],name:\"\",properties:[{name:\"textures\",value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}]"),
"none", "/warp dungeon_hub");

@SerialEntry
public QuickNavItem button9 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;-562285948,532499670,-1705302742,775653035],Properties:{textures:[{Value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}}}"),
"[minecraft:profile={id:[I;-562285948,532499670,-1705302742,775653035],name:\"\",properties:[{name:\"textures\",value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}]"),
"Visit prtl", "/visit prtl");

@SerialEntry
Expand All @@ -68,73 +68,6 @@ public class QuickNavigationConfig {
@SerialEntry
public QuickNavItem button12 = new QuickNavItem(true, new ItemData("crafting_table"), "Craft Item", "/craft");

public static class QuickNav {
@SerialEntry
public boolean enableQuickNav = true;

@SerialEntry
public QuickNavItem button1 = new QuickNavItem(true, new ItemData("diamond_sword"), "Your Skills", "/skills");

@SerialEntry
public QuickNavItem button2 = new QuickNavItem(true, new ItemData("painting"), "Collections", "/collection");

/* REGEX Explanation
* "Pets" : simple match on letters
* "(?: \\(\\d+\\/\\d+\\))?" : optional match on the non-capturing group for the page in the format " ($number/$number)"
*/
@SerialEntry
public QuickNavItem button3 = new QuickNavItem(true, new ItemData("bone"), "Pets(:? \\(\\d+\\/\\d+\\))?", "/pets");

/* REGEX Explanation
* "Wardrobe" : simple match on letters
* " \\([12]\\/2\\)" : match on the page either " (1/2)" or " (2/2)"
*/
@SerialEntry
public QuickNavItem button4 = new QuickNavItem(true,
new ItemData("leather_chestplate", 1, "tag:{display:{color:8991416}}"), "Wardrobe \\([12]/2\\)",
"/wardrobe");

@SerialEntry
public QuickNavItem button5 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;-2081424676,-57521078,-2073572414,158072763],Properties:{textures:[{Value:\"ewogICJ0aW1lc3RhbXAiIDogMTU5MTMxMDU4NTYwOSwKICAicHJvZmlsZUlkIiA6ICI0MWQzYWJjMmQ3NDk0MDBjOTA5MGQ1NDM0ZDAzODMxYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNZWdha2xvb24iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBhMDc3ZTI0OGQxNDI3NzJlYTgwMDg2NGY4YzU3OGI5ZDM2ODg1YjI5ZGFmODM2YjY0YTcwNjg4MmI2ZWMxMCIKICAgIH0KICB9Cn0=\"}]}}}"),
"Sack of Sacks", "/sacks");

/* REGEX Explanation
* "(?:Rift )?" : optional match on the non-capturing group "Rift "
* "Storage" : simple match on letters
* "(?: \\([12]\\/2\\))?" : optional match on the non-capturing group " (1/2)" or " (2/2)"
*/
@SerialEntry
public QuickNavItem button6 = new QuickNavItem(true, new ItemData("ender_chest"),
"(?:Rift )?Storage(?: \\(1/2\\))?", "/storage");

@SerialEntry
public QuickNavItem button7 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;-300151517,-631415889,-1193921967,-1821784279],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDdjYzY2ODc0MjNkMDU3MGQ1NTZhYzUzZTA2NzZjYjU2M2JiZGQ5NzE3Y2Q4MjY5YmRlYmVkNmY2ZDRlN2JmOCJ9fX0=\"}]}}}"),
"none", "/hub");

@SerialEntry
public QuickNavItem button8 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;1605800870,415127827,-1236127084,15358548],Properties:{textures:[{Value:\"e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg5MWQ1YjI3M2ZmMGJjNTBjOTYwYjJjZDg2ZWVmMWM0MGExYjk0MDMyYWU3MWU3NTQ3NWE1NjhhODI1NzQyMSJ9fX0=\"}]}}}"),
"none", "/warp dungeon_hub");

@SerialEntry
public QuickNavItem button9 = new QuickNavItem(true, new ItemData("player_head", 1,
"tag:{SkullOwner:{Id:[I;-562285948,532499670,-1705302742,775653035],Properties:{textures:[{Value:\"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjVkZjU1NTkyNjQzMGQ1ZDc1YWRlZDIxZGQ5NjE5Yjc2YzViN2NhMmM3ZjU0MDE0NDA1MjNkNTNhOGJjZmFhYiJ9fX0=\"}]}}}"),
"Visit prtl", "/visit prtl");

@SerialEntry
public QuickNavItem button10 = new QuickNavItem(true, new ItemData("enchanting_table"), "Enchant Item",
"/etable");


@SerialEntry
public QuickNavItem button11 = new QuickNavItem(true, new ItemData("anvil"), "Anvil", "/anvil");

@SerialEntry
public QuickNavItem button12 = new QuickNavItem(true, new ItemData("crafting_table"), "Craft Item", "/craft");
}

public static class QuickNavItem {
public QuickNavItem(Boolean render, ItemData itemData, String uiTitle, String clickEvent) {
this.render = render;
Expand All @@ -157,16 +90,16 @@ public QuickNavItem(Boolean render, ItemData itemData, String uiTitle, String cl
}

public static class ItemData {
public ItemData(String id, int count, String nbt) {
public ItemData(String id, int count, String components) {
this.id = id;
this.count = count;
this.nbt = nbt;
this.components = components;
}

public ItemData(String id) {
this.id = id;
this.count = 1;
this.nbt = "";
this.components = "[]";
}

@SerialEntry
Expand All @@ -176,6 +109,6 @@ public ItemData(String id) {
public int count;

@SerialEntry
public String nbt;
public String components;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package de.hysky.skyblocker.config.datafixer;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.DataFixerBuilder;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.JsonOps;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.datafixer.JsonHelper;
import net.fabricmc.loader.api.FabricLoader;
import org.slf4j.Logger;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.nio.file.Files;
import java.nio.file.Path;

public class ConfigDataFixer {
protected static final Logger LOGGER = LogUtils.getLogger();
private static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir();
public static final DSL.TypeReference CONFIG_TYPE = () -> "config";

public static void apply() {
apply(CONFIG_DIR.resolve("skyblocker.json"), CONFIG_DIR.resolve("skyblocker.json.old"));
}

public static void apply(Path configDir, Path backupDir) {
//User is new - has no config file (or maybe config folder)
if (!Files.exists(CONFIG_DIR) || !Files.exists(configDir)) return;

//Should never be null if the file exists unless its malformed JSON or something in which case well it gets reset
JsonObject oldConfig = loadConfig(configDir);
if (oldConfig == null || JsonHelper.getInt(oldConfig, "version").orElse(1) == SkyblockerConfigManager.CONFIG_VERSION) return;

JsonObject newConfig = apply(oldConfig);

//Write the updated file
if (!writeConfig(configDir, newConfig)) {
LOGGER.error(LogUtils.FATAL_MARKER, "[Skyblocker Config Data Fixer] Failed to fix up config file!");
writeConfig(backupDir, oldConfig);
}
}

public static JsonObject apply(JsonObject oldConfig) {
long start = System.currentTimeMillis();

JsonObject newConfig = build().update(CONFIG_TYPE, new Dynamic<>(JsonOps.INSTANCE, oldConfig), JsonHelper.getInt(oldConfig, "version").orElse(1), SkyblockerConfigManager.CONFIG_VERSION).getValue().getAsJsonObject();

long end = System.currentTimeMillis();
LOGGER.info("[Skyblocker Config Data Fixer] Applied datafixers in {} ms!", end - start);
return newConfig;
}

private static DataFixer build() {
DataFixerBuilder builder = new DataFixerBuilder(SkyblockerConfigManager.CONFIG_VERSION);

builder.addSchema(1, ConfigSchema::new);
Schema schema2 = builder.addSchema(2, Schema::new);
builder.addFixer(new ConfigFix1(schema2, true));

return builder.buildUnoptimized();
}

private static JsonObject loadConfig(Path path) {
try (BufferedReader reader = Files.newBufferedReader(path)) {
return JsonParser.parseReader(reader).getAsJsonObject();
} catch (Throwable t) {
LOGGER.error("[Skyblocker Config Data Fixer] Failed to load config file!", t);
}

return null;
}

private static boolean writeConfig(Path path, JsonObject config) {
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
SkyblockerMod.GSON.toJson(config, writer);

return true;
} catch (Throwable t) {
LOGGER.error("[Skyblocker Config Data Fixer] Failed to save config file at {}!", path, t);
}

return false;
}
}
Loading