diff options
| author | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2024-05-10 02:58:16 -0400 | 
|---|---|---|
| committer | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2024-05-10 03:16:53 -0400 | 
| commit | 7d5b40352c6680820c18c63a35d506b69a15d036 (patch) | |
| tree | a1c7b7fbe16ccf9263fe401032d8f98d9f829760 /src/main/java/de/hysky/skyblocker/config | |
| parent | 5eb9d273d2eb56cebaf0be0f90716b362916400b (diff) | |
| download | Skyblocker-7d5b40352c6680820c18c63a35d506b69a15d036.tar.gz Skyblocker-7d5b40352c6680820c18c63a35d506b69a15d036.tar.bz2 Skyblocker-7d5b40352c6680820c18c63a35d506b69a15d036.zip | |
Config Data Fixer
Skyblocker's Version of DFU
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/config')
4 files changed, 520 insertions, 149 deletions
| diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigDatafixer.java b/src/main/java/de/hysky/skyblocker/config/ConfigDatafixer.java new file mode 100644 index 00000000..5eecfe89 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/ConfigDatafixer.java @@ -0,0 +1,438 @@ +package de.hysky.skyblocker.config; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Locale; +import java.util.stream.Stream; + +import org.slf4j.Logger; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.logging.LogUtils; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; +import de.hysky.skyblocker.utils.datafixer.JsonHelper; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.StringNbtReader; + +public class ConfigDatafixer { +	private static final Logger LOGGER = LogUtils.getLogger(); +	private static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir(); + +	public static void apply() { +		//User is new - has no config file (or maybe config folder) +		if (!Files.exists(CONFIG_DIR) || !Files.exists(CONFIG_DIR.resolve("skyblocker.json"))) 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(); +		if (oldConfig == null || JsonHelper.getInt(oldConfig, "version").orElse(1) != 1) return; + +		try { +			JsonObject newConfig = prepareNewFormat(); + +			DataFixer[] generalFixers = getGeneralDataFixerRules(); +			DataFixer[] uiAndVisualsDataFixers = getUIAndVisualsDataFixerRules(); +			DataFixer[] dungeonsFixers = getDungeonsDataFixerRules(); +			DataFixer[] helpersFixers = getHelpersDataFixerRules(); +			DataFixer[] crimsonFixer = getCrimsonIsleDataFixerRule(); +			DataFixer[] miningFixers = getMiningDataFixerRules(); +			DataFixer[] farmingFixers = getFarmingDataFixerRules(); +			DataFixer[] otherLocationsFixers = getOtherLocationsDataFixerRules(); +			DataFixer[] slayersFixers = getSlayersDataFixerRules(); +			DataFixer[] chatFixers = getChatDataFixerRules(); +			DataFixer[] quickNavFixers = getQuickNavDataFixerRules(); +			DataFixer[] miscFixers = getMiscDataFixerRules(); + +			//Combine into 1 array +			DataFixer[] fixers = Stream.of(generalFixers, uiAndVisualsDataFixers, dungeonsFixers, helpersFixers, crimsonFixer, miningFixers, farmingFixers, otherLocationsFixers, slayersFixers, chatFixers, quickNavFixers, miscFixers) +					.flatMap(Arrays::stream) +					.toArray(DataFixer[]::new); + +			long start = System.currentTimeMillis(); + +			for (DataFixer fixer : fixers) { +				fixer.apply(oldConfig, newConfig); +			} + +			//Write the updated file +			boolean success = writeConfig(CONFIG_DIR.resolve("skyblocker.json"), newConfig); + +			if (!success) throw new IllegalStateException(); + +			long end = System.currentTimeMillis(); +			LOGGER.info("[Skyblocker Config Data Fixer] Applied {} datafixers in {} ms!", fixers.length, (end - start)); +		} catch (Throwable t) { +			LOGGER.error(LogUtils.FATAL_MARKER, "[Skyblocker Config Data Fixer] Failed to fix up config file!", t); +			writeConfig(CONFIG_DIR.resolve("skyblocker-1.json"), oldConfig); +		} +	} + +	private static JsonObject loadConfig() { +		try (BufferedReader reader = Files.newBufferedReader(CONFIG_DIR.resolve("skyblocker.json"))) { +			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; +	} + +	private static JsonObject prepareNewFormat() { +		JsonObject root = new JsonObject(); + +		root.addProperty("version", 2); +		root.add("general", new JsonObject()); +		root.add("uiAndVisuals", new JsonObject()); +		root.add("helpers", new JsonObject()); +		root.add("dungeons", new JsonObject()); +		root.add("crimsonIsle", new JsonObject()); +		root.add("mining", new JsonObject()); +		root.add("farming", new JsonObject()); +		root.add("otherLocations", new JsonObject()); +		root.add("slayers", new JsonObject()); +		root.add("chat", new JsonObject()); +		root.add("quickNav", new JsonObject()); +		root.add("misc", new JsonObject()); + +		return root; +	} + +	private static DataFixer[] getGeneralDataFixerRules() { +		//Individual Fields +		DataFixer tips = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").addProperty("enableTips", JsonHelper.getBoolean(oldFmt, "general.enableTips").orElse(true)); +		DataFixer acceptReparty = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("acceptReparty", oldFmt.getAsJsonObject("general").get("acceptReparty")); + +		//Category Copies +		DataFixer shortcuts = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("shortcuts", oldFmt.getAsJsonObject("general").getAsJsonObject("shortcuts")); +		DataFixer quiverWarning = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("quiverWarning", oldFmt.getAsJsonObject("general").getAsJsonObject("quiverWarning")); +		DataFixer itemList = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("itemList", oldFmt.getAsJsonObject("general").getAsJsonObject("itemList")); +		DataFixer itemTooltip = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("itemTooltip", oldFmt.getAsJsonObject("general").getAsJsonObject("itemTooltip")); +		DataFixer itemInfoDisplay = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("itemInfoDisplay", oldFmt.getAsJsonObject("general").getAsJsonObject("itemInfoDisplay")); +		DataFixer itemProtection = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("itemProtection")) { +				newFmt.getAsJsonObject("general").add("itemProtection", oldFmt.getAsJsonObject("general").get("itemProtection")); +			} +		};		 +		DataFixer wikiLookup = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("wikiLookup")) { +				newFmt.getAsJsonObject("general").add("wikiLookup", oldFmt.getAsJsonObject("general").get("wikiLookup")); +			} +		}; +		DataFixer specialEffects = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("specialEffects", oldFmt.getAsJsonObject("general").getAsJsonObject("specialEffects")); +		DataFixer hitbox = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("hitbox", oldFmt.getAsJsonObject("general").getAsJsonObject("hitbox")); + +		//Moved Field +		DataFixer dungeonQuality = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").getAsJsonObject("itemTooltip").addProperty("dungeonQuality", JsonHelper.getBoolean(oldFmt, "general.dungeonQuality").orElse(true)); + +		//Data stuff +		DataFixer lockedSlots = (oldFmt, newFmt) -> newFmt.getAsJsonObject("general").add("lockedSlots", oldFmt.getAsJsonObject("general").get("lockedSlots")); +		DataFixer protectedItems = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("protectedItems")) { +				newFmt.getAsJsonObject("general").add("protectedItems", oldFmt.getAsJsonObject("general").get("protectedItems")); +			} +		}; +		DataFixer customItemNames = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("customItemNames")) { +				newFmt.getAsJsonObject("general").add("customItemNames", oldFmt.getAsJsonObject("general").get("customItemNames")); +			} +		}; +		DataFixer customDyeColors = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("customDyeColors")) { +				newFmt.getAsJsonObject("general").add("customDyeColors", oldFmt.getAsJsonObject("general").get("customDyeColors")); +			} +		}; +		DataFixer customArmorTrims = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("customArmorTrims")) { +				newFmt.getAsJsonObject("general").add("customArmorTrims", oldFmt.getAsJsonObject("general").get("customArmorTrims")); +			} +		}; +		DataFixer customAnimatedDyes = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("customAnimatedDyes")) { +				newFmt.getAsJsonObject("general").add("customAnimatedDyes", oldFmt.getAsJsonObject("general").get("customAnimatedDyes")); +			} +		}; + +		return new DataFixer[] { tips, acceptReparty, shortcuts, quiverWarning, itemList, itemTooltip, itemInfoDisplay, itemProtection, wikiLookup, specialEffects, hitbox, dungeonQuality, +				lockedSlots, protectedItems, customItemNames, customDyeColors, customArmorTrims, customAnimatedDyes }; +	} + +	private static DataFixer[] getUIAndVisualsDataFixerRules() { +		DataFixer compactorDeletorPreview = (oldFmt, newFmt) -> newFmt.getAsJsonObject("uiAndVisuals").addProperty("compactorDeletorPreview", JsonHelper.getBoolean(oldFmt, "general.compactorDeletorPreview").orElse(true)); +		DataFixer dontStripSkinAlphaValues = (oldFmt, newFmt) -> newFmt.getAsJsonObject("uiAndVisuals").addProperty("dontStripSkinAlphaValues", JsonHelper.getBoolean(oldFmt, "general.dontStripSkinAlphaValues").orElse(true)); +		DataFixer backpackPreviewWithoutShift = (oldFmt, newFmt) -> newFmt.getAsJsonObject("uiAndVisuals").addProperty("backpackPreviewWithoutShift", JsonHelper.getBoolean(oldFmt, "general.backpackPreviewWithoutShift").orElse(false)); +		DataFixer hideEmptyItemTooltips = (oldFmt, newFmt) -> newFmt.getAsJsonObject("uiAndVisuals").add("hideEmptyTooltips", oldFmt.getAsJsonObject("general").get("hideEmptyTooltips")); +		DataFixer fancyCraftingTable = (oldFmt, newFmt) -> newFmt.getAsJsonObject("uiAndVisuals").addProperty("fancyCraftingTable", JsonHelper.getBoolean(oldFmt, "general.fancyCraftingTable").orElse(true)); +		DataFixer hideStatusEffectOverlay = (oldFmt, newFmt) -> newFmt.getAsJsonObject("uiAndVisuals").addProperty("hideStatusEffectOverlay", JsonHelper.getBoolean(oldFmt, "general.hideStatusEffectOverlay").orElse(false)); +		DataFixer chestValue = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("chestValue")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("chestValue", oldFmt.getAsJsonObject("general").get("chestValue")); +			} +		}; +		DataFixer itemCooldown = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("itemCooldown")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("itemCooldown", oldFmt.getAsJsonObject("general").get("itemCooldown")); +			} +		}; +		DataFixer titleContainer = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("titleContainer")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("titleContainer", oldFmt.getAsJsonObject("general").get("titleContainer")); +			} +		}; +		DataFixer tabHud = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("tabHud")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("tabHud", oldFmt.getAsJsonObject("general").get("tabHud")); +			} +		}; +		DataFixer fancyAuctionHouse = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("fancyAuctionHouse")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("fancyAuctionHouse", oldFmt.getAsJsonObject("general").get("fancyAuctionHouse")); +			} +		}; +		DataFixer bars = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("bars")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("bars", oldFmt.getAsJsonObject("general").get("bars")); +			} +		}; +		DataFixer waypoints = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("waypoints")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("waypoints", oldFmt.getAsJsonObject("general").get("waypoints")); +			} +		}; +		DataFixer teleportOverlay = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("teleportOverlay")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("teleportOverlay", oldFmt.getAsJsonObject("general").get("teleportOverlay")); +			} +		}; +		DataFixer searchOverlay = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("searchOverlay")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("searchOverlay", oldFmt.getAsJsonObject("general").get("searchOverlay")); +			} +		}; + +		DataFixer flameOverlay = (oldFmt, newFmt) -> { +			if (oldFmt.getAsJsonObject("general").has("flameOverlay")) { +				newFmt.getAsJsonObject("uiAndVisuals").add("flameOverlay", oldFmt.getAsJsonObject("general").get("flameOverlay")); +			} +		}; + +		return new DataFixer[] { compactorDeletorPreview, dontStripSkinAlphaValues, backpackPreviewWithoutShift, fancyCraftingTable, hideStatusEffectOverlay, chestValue, itemCooldown, titleContainer, +				tabHud, fancyAuctionHouse, bars, waypoints, teleportOverlay, searchOverlay, flameOverlay, hideEmptyItemTooltips }; +	} + +	private static DataFixer[] getHelpersDataFixerRules() { +		DataFixer newYearCakesHelper = (oldFmt, newFmt) -> newFmt.getAsJsonObject("helpers").addProperty("enableNewYearCakesHelper", JsonHelper.getBoolean(oldFmt, "general.enableNewYearCakesHelper").orElse(true)); +		DataFixer mythologicalRitual = (oldFmt, newFmt) -> newFmt.getAsJsonObject("helpers").add("mythologicalRitual", oldFmt.getAsJsonObject("general").getAsJsonObject("mythologicalRitual")); +		DataFixer experiments = (oldFmt, newFmt) -> newFmt.getAsJsonObject("helpers").add("experiments", oldFmt.getAsJsonObject("general").getAsJsonObject("experiments")); +		DataFixer fishing = (oldFmt, newFmt) -> newFmt.getAsJsonObject("helpers").add("fishing", oldFmt.getAsJsonObject("general").getAsJsonObject("fishing")); +		DataFixer fairySouls = (oldFmt, newFmt) -> newFmt.getAsJsonObject("helpers").add("fairySouls", oldFmt.getAsJsonObject("general").getAsJsonObject("fairySouls")); + +		return new DataFixer[] { newYearCakesHelper, mythologicalRitual, experiments, fishing, fairySouls }; +	} + +	private static DataFixer[] getDungeonsDataFixerRules() { +		DataFixer uncategorized = (oldFmt, newFmt) -> { +			JsonObject dungeonsOld = oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons"); +			JsonObject dungeonsNew = newFmt.getAsJsonObject("dungeons"); + +			dungeonsNew.addProperty("fancyPartyFinder", JsonHelper.getBoolean(oldFmt, "general.betterPartyFinder").orElse(true)); +			dungeonsNew.add("croesusHelper", dungeonsOld.get("croesusHelper")); +			dungeonsNew.addProperty("playerSecretsTracker", JsonHelper.getBoolean(dungeonsOld, "playerSecretsTracker").orElse(false)); +			dungeonsNew.add("starredMobGlow", dungeonsOld.get("starredMobGlow")); +			dungeonsNew.addProperty("starredMobBoudingBoxes", JsonHelper.getBoolean(dungeonsOld, "starredMobBoudingBoxes").orElse(true)); +			dungeonsNew.add("allowDroppingProtectedItems", dungeonsOld.get("allowDroppingProtectedItems")); +		}; + +		DataFixer map = (oldFmt, newFmt) -> { +			JsonObject dungeonsOld = oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons"); +			JsonObject mapConfig = new JsonObject(); + +			mapConfig.add("enableMap", dungeonsOld.get("enableMap")); +			mapConfig.add("mapScaling", dungeonsOld.get("mapScaling")); +			mapConfig.add("mapX", dungeonsOld.get("mapX")); +			mapConfig.add("mapY", dungeonsOld.get("mapY")); + +			newFmt.getAsJsonObject("dungeons").add("dungeonMap", mapConfig); +		}; + +		DataFixer puzzleSolvers = (oldFmt, newFmt) -> { +			JsonObject dungeonsOld = oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons"); +			JsonObject solverConfig = new JsonObject(); + +			solverConfig.add("solveThreeWeirdos", dungeonsOld.get("solveThreeWeirdos")); +			solverConfig.add("blazeSolver", dungeonsOld.get("blazeSolver")); +			solverConfig.add("creeperSolver", dungeonsOld.get("creeperSolver")); +			solverConfig.add("solveTrivia", dungeonsOld.get("solveTrivia")); +			solverConfig.add("solveTicTacToe", dungeonsOld.get("solveTicTacToe")); +			solverConfig.add("solveWaterboard", dungeonsOld.get("solveWaterboard")); +			solverConfig.add("solveBoulder", dungeonsOld.get("solveBoulder")); +			solverConfig.add("solveIceFill", dungeonsOld.get("solveIceFill")); +			solverConfig.add("solveSilverfish", dungeonsOld.get("solveSilverfish")); + +			newFmt.getAsJsonObject("dungeons").add("puzzleSolvers", solverConfig); +		}; + +		DataFixer professor = (oldFmt, newFmt) -> { +			JsonObject dungeonsOld = oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons"); +			JsonObject professorConfig = new JsonObject(); + +			professorConfig.addProperty("fireFreezeStaffTimer", JsonHelper.getBoolean(dungeonsOld, "fireFreezeStaffTimer").orElse(true)); +			professorConfig.addProperty("floor3GuardianHealthDisplay", JsonHelper.getBoolean(dungeonsOld, "floor3GuardianHealthDisplay").orElse(true)); + +			newFmt.getAsJsonObject("dungeons").add("theProfessor", professorConfig); +		}; + +		DataFixer livid = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("livid", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("lividColor")); +		DataFixer terminalSolvers = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("terminals", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("terminals")); +		DataFixer secrets = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("secretWaypoints", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("secretWaypoints")); +		DataFixer mimicMessage = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("mimicMessage", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("mimicMessage")); +		DataFixer doorHighlight = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("doorHighlight", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("doorHighlight")); +		DataFixer dungeonScore = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("dungeonScore", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("dungeonScore")); +		DataFixer dungeonChestProfit = (oldFmt, newFmt) -> newFmt.getAsJsonObject("dungeons").add("dungeonChestProfit", oldFmt.getAsJsonObject("locations").getAsJsonObject("dungeons").get("dungeonChestProfit")); + +		return new DataFixer[] { uncategorized, map, puzzleSolvers, professor, livid, terminalSolvers, secrets, mimicMessage, doorHighlight, dungeonScore, dungeonChestProfit }; +	} + +	private static DataFixer[] getCrimsonIsleDataFixerRule() { +		return new DataFixer[] { (oldFmt, newFmt) -> newFmt.add("crimsonIsle", oldFmt.getAsJsonObject("locations").get("crimsonIsle").deepCopy()) }; +	} + +	private static DataFixer[] getMiningDataFixerRules() { +		DataFixer drillFuel = (oldFmt, newFmt) -> newFmt.getAsJsonObject("mining").addProperty("enableDrillFuel", JsonHelper.getBoolean(oldFmt, "locations.dwarvenMines.enableDrillFuel").orElse(false)); +		DataFixer dwarvenMines = (oldFmt, newFmt) -> { +			JsonObject dwarvenOld = oldFmt.getAsJsonObject("locations").getAsJsonObject("dwarvenMines"); +			JsonObject dwarvenConfig = new JsonObject(); + +			dwarvenConfig.add("solveFetchur", dwarvenOld.get("solveFetchur")); +			dwarvenConfig.add("solvePuzzler", dwarvenOld.get("solvePuzzler")); + +			newFmt.getAsJsonObject("mining").add("dwarvenMines", dwarvenConfig); +		}; + +		DataFixer dwarvenHud = (oldFmt, newFmt) -> { +			JsonObject dwarvenHudConfig = new JsonObject(); + +			dwarvenHudConfig.addProperty("enabledCommissions", JsonHelper.getBoolean(oldFmt, "locations.dwarvenMines.dwarvenHud.enabledCommissions").orElse(false)); +			dwarvenHudConfig.addProperty("enabledPowder", JsonHelper.getBoolean(oldFmt, "locations.dwarvenMines.dwarvenHud.enabledPowder").orElse(false)); +			dwarvenHudConfig.addProperty("style", JsonHelper.getString(oldFmt, "locations.dwarvenMines.dwarvenHud.style").orElse("SIMPLE")); +			dwarvenHudConfig.addProperty("commissionsX", JsonHelper.getInt(oldFmt, "locations.dwarvenMines.dwarvenHud.x").orElse(10)); +			dwarvenHudConfig.addProperty("commissionsY", JsonHelper.getInt(oldFmt, "locations.dwarvenMines.dwarvenHud.y").orElse(10)); +			dwarvenHudConfig.addProperty("powderX", JsonHelper.getInt(oldFmt, "locations.dwarvenMines.dwarvenHud.powderX").orElse(10)); +			dwarvenHudConfig.addProperty("powderY", JsonHelper.getInt(oldFmt, "locations.dwarvenMines.dwarvenHud.powderY").orElse(70)); + +			newFmt.getAsJsonObject("mining").add("dwarvenHud", dwarvenHudConfig); +		}; +		DataFixer crystalHollowsMap = (oldFmt, newFmt) -> newFmt.getAsJsonObject("mining").add("crystalsHud", oldFmt.getAsJsonObject("locations").getAsJsonObject("dwarvenMines").get("crystalsHud")); +		DataFixer crystalHollowsWaypoints = (oldFmt, newFmt) -> newFmt.getAsJsonObject("mining").add("crystalsWaypoints", oldFmt.getAsJsonObject("locations").getAsJsonObject("dwarvenMines").get("crystalsWaypoints")); +		DataFixer metalDetectorHelper = (oldFmt, newFmt) -> { +			newFmt.getAsJsonObject("mining").add("crystalHollows", new JsonObject());  +			newFmt.getAsJsonObject("mining").getAsJsonObject("crystalHollows").addProperty("metalDetectorHelper", JsonHelper.getBoolean(oldFmt, "locations.dwarvenMines.metalDetectorHelper").orElse(false)); +		}; + +		return new DataFixer[] { drillFuel, dwarvenMines, dwarvenHud, crystalHollowsMap, crystalHollowsWaypoints, metalDetectorHelper }; +	} + +	private static DataFixer[] getFarmingDataFixerRules() { +		DataFixer garden = (oldFmt, newFmt) -> newFmt.getAsJsonObject("farming").add("garden", oldFmt.getAsJsonObject("locations").get("garden")); + +		return new DataFixer[] { garden }; +	} + +	private static DataFixer[] getOtherLocationsDataFixerRules() { +		DataFixer barn = (oldFmt, newFmt) -> newFmt.getAsJsonObject("otherLocations").add("barn", oldFmt.getAsJsonObject("locations").get("barn")); +		DataFixer rift = (oldFmt, newFmt) -> newFmt.getAsJsonObject("otherLocations").add("rift", oldFmt.getAsJsonObject("locations").get("rift")); +		DataFixer end = (oldFmt, newFmt) -> newFmt.getAsJsonObject("otherLocations").add("end", oldFmt.getAsJsonObject("locations").get("end")); +		DataFixer spidersDen = (oldFmt, newFmt) -> newFmt.getAsJsonObject("otherLocations").add("spidersDen", oldFmt.getAsJsonObject("locations").get("spidersDen")); + +		return new DataFixer[] { barn, rift, end, spidersDen }; +	} + +	private static DataFixer[] getSlayersDataFixerRules() { +		DataFixer enderman = (oldFmt, newFmt) -> newFmt.getAsJsonObject("slayers").add("endermanSlayer", oldFmt.getAsJsonObject("slayer").get("endermanSlayer")); +		DataFixer vampire = (oldFmt, newFmt) -> newFmt.getAsJsonObject("slayers").add("vampireSlayer", oldFmt.getAsJsonObject("slayer").get("vampireSlayer")); + +		return new DataFixer[] { enderman, vampire }; +	} + +	private static DataFixer[] getChatDataFixerRules() { +		DataFixer mainFixer = (oldFmt, newFmt) -> newFmt.add("chat", oldFmt.get("messages")); + +		return new DataFixer[] { mainFixer }; +	} + + +	private static DataFixer[] getQuickNavDataFixerRules() { +		DataFixer toggle = (oldFmt, newFmt) -> newFmt.getAsJsonObject("quickNav").add("enableQuickNav", oldFmt.getAsJsonObject("quickNav").get("enableQuickNav")); +		DataFixer buttonFixer = (oldFmt, newFmt) -> { +			for (int i = 1; i < 13; i++) { +				JsonObject oldButton = oldFmt.getAsJsonObject("quickNav").getAsJsonObject("button" + i); +				JsonObject newButton = new JsonObject(); + +				newButton.add("render", oldButton.get("render")); +				newButton.add("uiTitle", oldButton.get("uiTitle")); +				newButton.add("clickEvent", oldButton.get("clickEvent")); + +				//Item +				JsonObject oldItem = oldButton.getAsJsonObject("item"); +				JsonObject newItem = new JsonObject(); + +				newItem.addProperty("id", oldItem.get("itemName").getAsString()); +				newItem.addProperty("count", oldItem.get("count").getAsInt()); +				newItem.addProperty("components", nbtToComponents(newItem.get("id").getAsString(), 1, oldItem.get("nbt").getAsString())); + +				newButton.add("item", newItem); +				newFmt.getAsJsonObject("quickNav").add("button" + i, newButton); +			} +		}; + +		return new DataFixer[] { toggle, buttonFixer }; +	} + +	private static DataFixer[] getMiscDataFixerRules() { +		DataFixer richPresence = (oldFmt, newFmt) -> newFmt.getAsJsonObject("misc").add("richPresence", oldFmt.getAsJsonObject("richPresence")); + +		return new DataFixer[] { richPresence }; +	} + +	private static String nbtToComponents(String id, int count, String nbt) { +		try { +			String nbtString = "{id:\"minecraft:" + id.toLowerCase(Locale.ROOT) + "\",Count:1"; +			if (nbt.length() > 2) nbtString += "," + nbt; +			nbtString += "}"; + +			ItemStack fixed = ItemStackComponentizationFixer.fixUpItem(StringNbtReader.parse(nbtString)); + +			return ItemStackComponentizationFixer.componentsAsString(fixed); +		} catch (Throwable t) { +			LOGGER.error(LogUtils.FATAL_MARKER, "[Skyblocker Config Data Fixer] Failed to convert nbt to components!", t); +		} + +		return "[]"; +	} + +	/** +	 * Represents a data fixer rule. +	 */ +	//Could be moved to the data fixer package if multiple classes come to need this +	@FunctionalInterface +	interface DataFixer { +		void apply(JsonObject oldFmt, JsonObject newFmt); +	} +} diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index 4b8e56df..c85e0bb4 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -26,7 +26,7 @@ import java.lang.StackWalker.Option;  import java.nio.file.Path;  public class SkyblockerConfigManager { -    private static final Path PATH = FabricLoader.getInstance().getConfigDir().resolve("skyblocker-2.json"); +    private static final Path PATH = FabricLoader.getInstance().getConfigDir().resolve("skyblocker.json");      private static final ConfigClassHandler<SkyblockerConfig> HANDLER = ConfigClassHandler.createBuilder(SkyblockerConfig.class)              .serializer(config -> GsonConfigSerializerBuilder.create(config)                      .setPath(PATH) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java index 1200261d..64c67417 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java @@ -48,14 +48,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button1.item.count,                                          () -> config.quickNav.button1.item.count,                                          newValue -> config.quickNav.button1.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button1.item.nbt, -                                        () -> config.quickNav.button1.item.nbt, -                                        newValue -> config.quickNav.button1.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button1.item.components, +                                        () -> config.quickNav.button1.item.components, +                                        newValue -> config.quickNav.button1.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -97,14 +97,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button2.item.count,                                          () -> config.quickNav.button2.item.count,                                          newValue -> config.quickNav.button2.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button2.item.nbt, -                                        () -> config.quickNav.button2.item.nbt, -                                        newValue -> config.quickNav.button2.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button2.item.components, +                                        () -> config.quickNav.button2.item.components, +                                        newValue -> config.quickNav.button2.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -146,14 +146,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button3.item.count,                                          () -> config.quickNav.button3.item.count,                                          newValue -> config.quickNav.button3.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button3.item.nbt, -                                        () -> config.quickNav.button3.item.nbt, -                                        newValue -> config.quickNav.button3.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button3.item.components, +                                        () -> config.quickNav.button3.item.components, +                                        newValue -> config.quickNav.button3.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -195,14 +195,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button4.item.count,                                          () -> config.quickNav.button4.item.count,                                          newValue -> config.quickNav.button4.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button4.item.nbt, -                                        () -> config.quickNav.button4.item.nbt, -                                        newValue -> config.quickNav.button4.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button4.item.components, +                                        () -> config.quickNav.button4.item.components, +                                        newValue -> config.quickNav.button4.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -244,14 +244,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button5.item.count,                                          () -> config.quickNav.button5.item.count,                                          newValue -> config.quickNav.button5.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button5.item.nbt, -                                        () -> config.quickNav.button5.item.nbt, -                                        newValue -> config.quickNav.button5.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button5.item.components, +                                        () -> config.quickNav.button5.item.components, +                                        newValue -> config.quickNav.button5.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -293,14 +293,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button6.item.count,                                          () -> config.quickNav.button6.item.count,                                          newValue -> config.quickNav.button6.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button6.item.nbt, -                                        () -> config.quickNav.button6.item.nbt, -                                        newValue -> config.quickNav.button6.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button6.item.components, +                                        () -> config.quickNav.button6.item.components, +                                        newValue -> config.quickNav.button6.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -342,14 +342,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button7.item.count,                                          () -> config.quickNav.button7.item.count,                                          newValue -> config.quickNav.button7.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button7.item.nbt, -                                        () -> config.quickNav.button7.item.nbt, -                                        newValue -> config.quickNav.button7.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button7.item.components, +                                        () -> config.quickNav.button7.item.components, +                                        newValue -> config.quickNav.button7.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -391,14 +391,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button8.item.count,                                          () -> config.quickNav.button8.item.count,                                          newValue -> config.quickNav.button8.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button8.item.nbt, -                                        () -> config.quickNav.button8.item.nbt, -                                        newValue -> config.quickNav.button8.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button8.item.components, +                                        () -> config.quickNav.button8.item.components, +                                        newValue -> config.quickNav.button8.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -440,14 +440,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button9.item.count,                                          () -> config.quickNav.button9.item.count,                                          newValue -> config.quickNav.button9.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button9.item.nbt, -                                        () -> config.quickNav.button9.item.nbt, -                                        newValue -> config.quickNav.button9.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button9.item.components, +                                        () -> config.quickNav.button9.item.components, +                                        newValue -> config.quickNav.button9.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -489,14 +489,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button10.item.count,                                          () -> config.quickNav.button10.item.count,                                          newValue -> config.quickNav.button10.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button10.item.nbt, -                                        () -> config.quickNav.button10.item.nbt, -                                        newValue -> config.quickNav.button10.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button10.item.components, +                                        () -> config.quickNav.button10.item.components, +                                        newValue -> config.quickNav.button10.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -538,14 +538,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button11.item.count,                                          () -> config.quickNav.button11.item.count,                                          newValue -> config.quickNav.button11.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button11.item.nbt, -                                        () -> config.quickNav.button11.item.nbt, -                                        newValue -> config.quickNav.button11.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button11.item.components, +                                        () -> config.quickNav.button11.item.components, +                                        newValue -> config.quickNav.button11.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() @@ -587,14 +587,14 @@ public class QuickNavigationCategory {                                  .binding(defaults.quickNav.button12.item.count,                                          () -> config.quickNav.button12.item.count,                                          newValue -> config.quickNav.button12.item.count = newValue) -                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 64)) +                                .controller(opt -> IntegerFieldControllerBuilder.create(opt).range(1, 99))                                  .build())                          .option(Option.<String>createBuilder() -                                .name(Text.translatable("skyblocker.config.quickNav.button.item.nbt")) -                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.nbt.@Tooltip"))) -                                .binding(defaults.quickNav.button12.item.nbt, -                                        () -> config.quickNav.button12.item.nbt, -                                        newValue -> config.quickNav.button12.item.nbt = newValue) +                                .name(Text.translatable("skyblocker.config.quickNav.button.item.components")) +                                .description(OptionDescription.of(Text.translatable("skyblocker.config.quickNav.button.item.components.@Tooltip"))) +                                .binding(defaults.quickNav.button12.item.components, +                                        () -> config.quickNav.button12.item.components, +                                        newValue -> config.quickNav.button12.item.components = newValue)                                  .controller(StringControllerBuilder::create)                                  .build())                          .option(Option.<String>createBuilder() diff --git a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java index 2c4347b6..ba863e33 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java @@ -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 @@ -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 @@ -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; @@ -157,16 +90,16 @@ public class QuickNavigationConfig {      }      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 @@ -176,6 +109,6 @@ public class QuickNavigationConfig {          public int count;          @SerialEntry -        public String nbt; +        public String components;      }  } | 
