Remove upgraded structure caching

Performance improvement is minimal with rewritten DFU and it
breaks structure generation on 1.21 for some reason
This commit is contained in:
embeddedt 2024-06-13 21:32:42 -04:00
parent a6e0785252
commit 180606eea1
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
3 changed files with 0 additions and 229 deletions

View File

@ -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<CommandSourceStack> 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<ResourceLocation, Resource> structures = manager.listResources("structures", p -> p.getPath().endsWith(".nbt"));
int upgradedNum = 0;
Pattern pathPattern = Pattern.compile("^structures/(.*)\\.nbt$");
for(Map.Entry<ResourceLocation, Resource> 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;
}))
);
}
}

View File

@ -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<Block> blockLookup;
/**
* @author embeddedt
* @reason use our own manager to avoid needless DFU updates
*/
@Overwrite
private Optional<StructureTemplate> 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();
}
}
}

View File

@ -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<MessageDigest> 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<Block> 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<String> 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();
}
}