From d85dd91b0dfd6d9938ac3b81d6211b162f8ad05c Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:44:55 +1100 Subject: [PATCH] Fix Data Fixers not Applying on Chunks after First Load --- .../nomilabs/mixin/WorldLoadHandler.java | 2 +- .../remap/datafixer/DataFixerHandler.java | 55 +++++++++++++++---- .../nomilabs/remap/datafixer/LabsFixes.java | 11 ++-- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/nomiceu/nomilabs/mixin/WorldLoadHandler.java b/src/main/java/com/nomiceu/nomilabs/mixin/WorldLoadHandler.java index 803871aa..ac569ef3 100644 --- a/src/main/java/com/nomiceu/nomilabs/mixin/WorldLoadHandler.java +++ b/src/main/java/com/nomiceu/nomilabs/mixin/WorldLoadHandler.java @@ -27,7 +27,7 @@ private static void loadDataFixers(File file, DataFixer fixer, SaveHandler save, DataFixerHandler.onWorldLoad(save); - if (DataFixerHandler.fixNotAvailable()) return; + if (DataFixerHandler.hasNoNewFixes()) return; if (Loader.isModLoaded(LabsValues.ENDER_STORAGE_MODID) && LabsConfig.modIntegration.enableEnderStorageIntegration) DataFixerHandler.processEnderStorageInfo(fixer, save); diff --git a/src/main/java/com/nomiceu/nomilabs/remap/datafixer/DataFixerHandler.java b/src/main/java/com/nomiceu/nomilabs/remap/datafixer/DataFixerHandler.java index 7bfbf716..d39fc064 100644 --- a/src/main/java/com/nomiceu/nomilabs/remap/datafixer/DataFixerHandler.java +++ b/src/main/java/com/nomiceu/nomilabs/remap/datafixer/DataFixerHandler.java @@ -54,9 +54,16 @@ public class DataFixerHandler { public static LabsWorldFixData worldSavedData = null; public static boolean checked = false; + /* Fixes that should be applied */ public static Map>> neededFixes; + + /* Fixes that should be logged */ + public static Map>> neededNewFixes; + + /* Whether Mode is needed for New Fixes */ public static boolean modeNeeded = false; + private static Map mods; private static BiMap blockHelperMap; public static void preInit() { @@ -81,8 +88,24 @@ public static void preInit() { public static void onWorldLoad(SaveHandler save) { checked = false; modeNeeded = false; + neededFixes = null; + neededNewFixes = null; NomiLabs.LOGGER.info("Checking Data Fixers..."); + getModList(save); + if (mods.isEmpty()) return; + + LabsFixes.init(); + neededFixes = new Object2ObjectOpenHashMap<>(); + for (var fixType : LabsFixes.fixes.keySet()) { + for (var fix : LabsFixes.fixes.get(fixType)) { + if (fix.validModList.apply(mods)) { + if (!neededFixes.containsKey(fixType)) neededFixes.put(fixType, new ObjectArrayList<>()); + neededFixes.get(fixType).add(fix); + } + } + } + var mapFile = save.getMapFileFromName(LabsFixes.DATA_NAME); if (mapFile.exists()) { @@ -100,14 +123,13 @@ public static void onWorldLoad(SaveHandler save) { NomiLabs.LOGGER.info("This world was saved without a data version. New Version: {}.", LabsFixes.CURRENT); } - LabsFixes.init(); - determineNeededFixesAndLog(save); + determineNeededFixesAndLog(); // Clear Block Helper Map, the ids are different for some saves blockHelperMap = null; - if (neededFixes.isEmpty()) { - NomiLabs.LOGGER.info("This world does not need any data fixers, but it has no saved version, it is old, or this is a new world."); + if (neededNewFixes.isEmpty()) { + NomiLabs.LOGGER.info("This world does not need any new data fixers, but it has no saved version, it is old, or this is a new world."); LabsWorldFixData.save(mapFile, DataFixerHandler.worldSavedData); return; } @@ -138,8 +160,9 @@ public static void onWorldLoad(SaveHandler save) { LabsWorldFixData.save(mapFile, DataFixerHandler.worldSavedData); } - private static void determineNeededFixesAndLog(SaveHandler save) { - neededFixes = new Object2ObjectOpenHashMap<>(); + private static void getModList(SaveHandler save) { + mods = new HashMap<>(); + File levelDat = new File(save.getWorldDirectory(), "level.dat"); // If level.dat file does not exist, return. @@ -149,7 +172,6 @@ private static void determineNeededFixesAndLog(SaveHandler save) { if (!levelDat.exists()) return; - Map mods = new HashMap<>(); NBTTagList modList; try { NBTTagCompound nbt = CompressedStreamTools.readCompressed(new FileInputStream(levelDat)); @@ -161,13 +183,18 @@ private static void determineNeededFixesAndLog(SaveHandler save) { NomiLabs.LOGGER.fatal("Failed to read level.dat.", e); return; } - for (var mod : modList) { if (!(mod instanceof NBTTagCompound compound)) continue; if (!compound.hasKey("ModId", Constants.NBT.TAG_STRING) || !compound.hasKey("ModVersion", Constants.NBT.TAG_STRING)) continue; mods.put(compound.getString("ModId"), compound.getString("ModVersion")); } + } + + private static void determineNeededFixesAndLog() { + neededNewFixes = new Object2ObjectOpenHashMap<>(); + + if (mods.isEmpty()) return; // If Nomi Labs Version is same as current version, exit. // This normally means it is a new world. @@ -184,8 +211,8 @@ private static void determineNeededFixesAndLog(SaveHandler save) { var fixes = LabsFixes.fixes.get(fixType); for (var fix : fixes) { if (fix.validVersion.apply(DataFixerHandler.worldSavedData.savedVersion) && fix.validModList.apply(mods)) { - if (!neededFixes.containsKey(fixType)) neededFixes.put(fixType, new ObjectArrayList<>()); - neededFixes.get(fixType).add(fix); + if (!neededNewFixes.containsKey(fixType)) neededNewFixes.put(fixType, new ObjectArrayList<>()); + neededNewFixes.get(fixType).add(fix); if (fix.needsMode) modeNeeded = true; NomiLabs.LOGGER.info("- {}: {}", fix.name, fix.description); } @@ -236,12 +263,18 @@ public static void processEnderStorageInfo(DataFixer fixer, SaveHandler save) { NomiLabs.LOGGER.info("Finished Processing Ender Storage Info!"); } + public static boolean hasNoNewFixes() { + return worldSavedData == null || neededNewFixes == null || neededNewFixes.isEmpty(); + } + public static boolean fixNotAvailable() { - return worldSavedData == null; + return neededFixes == null || neededFixes.isEmpty(); } public static void close() { worldSavedData = null; checked = false; + neededFixes = null; + neededNewFixes = null; } } diff --git a/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java b/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java index 6169568c..5c03eb89 100644 --- a/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java +++ b/src/main/java/com/nomiceu/nomilabs/remap/datafixer/LabsFixes.java @@ -34,8 +34,9 @@ /** * Definitions for all values, and all data fixes. *

- * No Data Fixes are loaded if the 'FIX_VERSION' is below the version saved in the world, or the Nomi Labs Version in world - * is the same as the current Nomi Labs Version. + * When the modList matches, and the fix version the world was created with matches the fix, the fix is included. + * This is because items and blocks may not be loaded in the first load. + * However, only fixes where the previous version the world was loaded with matches will be included in Ender Storage Remapping. */ public class LabsFixes { /** @@ -133,7 +134,7 @@ public static void init() { * false, // Whether the correct mode is required for the change to work right * * (version) -> version <= DEFAULT_VERSION, // Whether the previous version in the save means that this fix must be applied. - * // Note that this is not applied if the previous version is equal to the current overall fix version. + * // Note that this is not included in the fix list if the previous version is equal to the current overall fix version. * * (modList) -> true, // Inputs the previous modlist the world was loaded with (map of modid to modversion), return whether it is valid. * // Note that the fix is only applied if the version AND the modlist is valid. @@ -284,7 +285,7 @@ public static void init() { * false, // Whether the correct mode is required for the change to work right * * (version) -> version <= DEFAULT_VERSION, // Whether the previous version in the save means that this fix must be applied. - * // Note that this is not applied if the previous version is equal to the current overall fix version. + * // Note that this is not included in the fix list if the previous version is equal to the current overall fix version. * * (modList) -> true, // Inputs the previous modlist the world was loaded with (map of modid to modversion), return whether it is valid. * // Note that the fix is only applied if the version AND the modlist is valid. @@ -342,7 +343,7 @@ public static void init() { * false, // Whether the correct mode is required for the change to work right * * (version) -> version <= DEFAULT_VERSION, // Whether the previous version in the save means that this fix must be applied. - * // Note that this is not applied if the previous version is equal to the current overall fix version. + * // Note that this is not included in the fix list if the previous version is equal to the current overall fix version. * * (modList) -> true, // Inputs the previous modlist the world was loaded with (map of modid to modversion), return whether it is valid. * // Note that the fix is only applied if the version AND the modlist is valid.