From 180606eea107a7d05a69e82883e8bdbed8c70ed6 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 13 Jun 2024 21:32:42 -0400 Subject: [PATCH] Remove upgraded structure caching Performance improvement is minimal with rewritten DFU and it breaks structure generation on 1.21 for some reason --- .../modernfix/command/ModernFixCommands.java | 49 ------- .../StructureManagerMixin.java | 46 ------ .../structure/CachingStructureManager.java | 134 ------------------ 3 files changed, 229 deletions(-) delete mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java delete mode 100644 common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java diff --git a/common/src/main/java/org/embeddedt/modernfix/command/ModernFixCommands.java b/common/src/main/java/org/embeddedt/modernfix/command/ModernFixCommands.java index 3c5039c4..cafbe0af 100644 --- a/common/src/main/java/org/embeddedt/modernfix/command/ModernFixCommands.java +++ b/common/src/main/java/org/embeddedt/modernfix/command/ModernFixCommands.java @@ -2,58 +2,9 @@ package org.embeddedt.modernfix.command; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.packs.resources.Resource; -import net.minecraft.server.packs.resources.ResourceManager; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.structure.CachingStructureManager; - -import java.io.InputStream; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static net.minecraft.commands.Commands.literal; public class ModernFixCommands { public static void register(CommandDispatcher dispatcher) { - dispatcher.register(literal("modernfix") - .then(literal("upgradeStructures") - .requires(source -> source.hasPermission(3)) - .executes(context -> { - ServerLevel level = context.getSource().getLevel(); - if(level == null) { - context.getSource().sendFailure(Component.literal("Couldn't find server level")); - return 0; - } - ResourceManager manager = level.getServer().resources.resourceManager(); - Map structures = manager.listResources("structures", p -> p.getPath().endsWith(".nbt")); - int upgradedNum = 0; - Pattern pathPattern = Pattern.compile("^structures/(.*)\\.nbt$"); - for(Map.Entry entry : structures.entrySet()) { - upgradedNum++; - ResourceLocation found = entry.getKey(); - Matcher matcher = pathPattern.matcher(found.getPath()); - if(!matcher.matches()) - continue; - ResourceLocation structureLocation = ResourceLocation.fromNamespaceAndPath(found.getNamespace(), matcher.group(1)); - try(InputStream resource = entry.getValue().open()) { - CachingStructureManager.readStructureTag(structureLocation, level.getServer().getFixerUpper(), resource); - Component msg = Component.literal("checked " + structureLocation + " (" + upgradedNum + "/" + structures.size() + ")"); - context.getSource().sendSuccess(() -> msg, false); - } catch(Throwable e) { - ModernFix.LOGGER.error("Couldn't upgrade structure " + found, e); - context.getSource().sendFailure(Component.literal("error reading " + structureLocation + " (" + upgradedNum + "/" + structures.size() + ")")); - } - } - - context.getSource().sendSuccess(() -> Component.literal("All structures upgraded"), false); - - return 1; - })) - ); } } diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java deleted file mode 100644 index 150af0f7..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/cache_upgraded_structures/StructureManagerMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.cache_upgraded_structures; - -import com.mojang.datafixers.DataFixer; -import net.minecraft.core.HolderGetter; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.structure.CachingStructureManager; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; - -@Mixin(StructureTemplateManager.class) -public class StructureManagerMixin { - @Shadow @Final private DataFixer fixerUpper; - - @Shadow private ResourceManager resourceManager; - - @Shadow @Final private HolderGetter blockLookup; - - /** - * @author embeddedt - * @reason use our own manager to avoid needless DFU updates - */ - @Overwrite - private Optional loadFromResource(ResourceLocation id) { - ResourceLocation arg = ResourceLocation.fromNamespaceAndPath(id.getNamespace(), "structures/" + id.getPath() + ".nbt"); - try(InputStream stream = this.resourceManager.open(arg)) { - return Optional.of(CachingStructureManager.readStructure(id, this.fixerUpper, stream, this.blockLookup)); - } catch(FileNotFoundException e) { - return Optional.empty(); - } catch(IOException e) { - ModernFix.LOGGER.error("Can't read structure", e); - return Optional.empty(); - } - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java b/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java deleted file mode 100644 index bf5152d2..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.embeddedt.modernfix.structure; - -import com.mojang.datafixers.DataFixer; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import net.minecraft.SharedConstants; -import net.minecraft.core.HolderGetter; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtAccounter; -import net.minecraft.nbt.NbtIo; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.datafix.DataFixTypes; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; -import org.embeddedt.modernfix.util.FileUtil; - -import java.io.*; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Set; - -public class CachingStructureManager { - private static ThreadLocal digestThreadLocal = ThreadLocal.withInitial(() -> { - try { - return MessageDigest.getInstance("SHA-256"); - } catch(NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - }); - private static final File STRUCTURE_CACHE_FOLDER = FileUtil.childFile(ModernFixPlatformHooks.INSTANCE.getGameDirectory().resolve("modernfix").resolve("structureCacheV1").toFile()); - - static { - STRUCTURE_CACHE_FOLDER.mkdirs(); - } - - public static StructureTemplate readStructure(ResourceLocation location, DataFixer datafixer, InputStream stream, HolderGetter blockGetter) throws IOException { - CompoundTag tag = readStructureTag(location, datafixer, stream); - StructureTemplate template = new StructureTemplate(); - template.load(blockGetter, tag); - return template; - } - - private static String encodeHex(byte[] byteArray) { - StringBuilder sb = new StringBuilder(); - for(byte b : byteArray) { - sb.append(String.format("%02x", b)); - } - return sb.toString(); - } - - private static final Set laggyStructureMods = new ObjectOpenHashSet<>(); - - private static final int MAX_HASH_LENGTH = 9; - - private static String truncateHash(String hash) { - return hash.substring(0, MAX_HASH_LENGTH + 1); - } - - public static CompoundTag readStructureTag(ResourceLocation location, DataFixer datafixer, InputStream stream) throws IOException { - byte[] structureBytes = toBytes(stream); - CompoundTag currentTag = NbtIo.readCompressed(new ByteArrayInputStream(structureBytes), NbtAccounter.unlimitedHeap()); - if (!currentTag.contains("DataVersion", 99)) { - currentTag.putInt("DataVersion", 500); - } - int currentDataVersion = currentTag.getInt("DataVersion"); - int requiredMinimumDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); - if(currentDataVersion < requiredMinimumDataVersion) { - /* Needs upgrade, try looking up from cache */ - MessageDigest hasher = digestThreadLocal.get(); - hasher.reset(); - String hash = encodeHex(hasher.digest(structureBytes)); - CompoundTag cachedUpgraded = getCachedUpgraded(location, truncateHash(hash)); - if(cachedUpgraded == null) - cachedUpgraded = getCachedUpgraded(location, hash); /* pick up old cache */ - if(cachedUpgraded != null && cachedUpgraded.getInt("DataVersion") == requiredMinimumDataVersion) { - ModernFix.LOGGER.debug("Using cached upgraded version of {}", location); - currentTag = cachedUpgraded; - } else { - /* - synchronized (laggyStructureMods) { - if(laggyStructureMods.add(location.getNamespace())) { - ModernFix.LOGGER.warn("The namespace {} contains an outdated structure file, which can cause worldgen lag. Please view debug.log for the full filename, determine which mod provides the structure, and report to the mod/datapack author, including the debug log.", location.getNamespace()); - } - } - */ - ModernFix.LOGGER.debug("Structure {} is being run through DFU (hash {}), this will cause launch time delays", location, hash); - currentTag = DataFixTypes.STRUCTURE.update(datafixer, currentTag, currentDataVersion, - SharedConstants.getCurrentVersion().getDataVersion().getVersion()); - currentTag.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); - saveCachedUpgraded(location, hash, currentTag); - } - } - return currentTag; - } - - private static File getCachePath(ResourceLocation location, String hash) { - String fileName = location.getNamespace() + "_" + location.getPath().replace('/', '_') + "_" + hash + ".nbt"; - return new File(STRUCTURE_CACHE_FOLDER, fileName); - } - - private static synchronized CompoundTag getCachedUpgraded(ResourceLocation location, String hash) { - File theFile = getCachePath(location, hash); - try(FileInputStream stream = new FileInputStream(theFile)) { - return NbtIo.readCompressed(stream, NbtAccounter.unlimitedHeap()); - } catch(FileNotFoundException e) { - return null; - } catch(IOException e) { - e.printStackTrace(); - return null; - } - } - - private static synchronized void saveCachedUpgraded(ResourceLocation location, String hash, CompoundTag tagToSave) { - File theFile = getCachePath(location, truncateHash(hash)); - try(FileOutputStream stream = new FileOutputStream(theFile)) { - NbtIo.writeCompressed(tagToSave, stream); - } catch(IOException e) { - e.printStackTrace(); - } - } - - private static byte[] toBytes(InputStream stream) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - byte[] tmp = new byte[16384]; - int n; - while ((n = stream.read(tmp, 0, tmp.length)) != -1) { - buffer.write(tmp, 0, n); - } - - return buffer.toByteArray(); - } -}