From 4fe235cdbd9ef58870ab260489c6bc45e2fec510 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:14:38 -0400 Subject: [PATCH] Workaround for mods instantiating PathResourcePack incorrectly --- .../forge/load/ModResourcePackPathFixer.java | 21 +++++++++++++++++++ .../ModFileResourcePackMixin.java | 17 +++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/load/ModResourcePackPathFixer.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/load/ModResourcePackPathFixer.java b/forge/src/main/java/org/embeddedt/modernfix/forge/load/ModResourcePackPathFixer.java new file mode 100644 index 00000000..d9e9f7c7 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/load/ModResourcePackPathFixer.java @@ -0,0 +1,21 @@ +package org.embeddedt.modernfix.forge.load; + +import net.minecraftforge.fml.ModList; +import net.minecraftforge.forgespi.language.IModFileInfo; +import net.minecraftforge.forgespi.locating.IModFile; + +import java.nio.file.Path; +import java.util.IdentityHashMap; + +public class ModResourcePackPathFixer { + private static final IdentityHashMap modFileByPath = new IdentityHashMap<>(); + + public static synchronized IModFile getModFileByRootPath(Path path) { + if(modFileByPath.size() == 0) { + for(IModFileInfo info : ModList.get().getModFiles()) { + modFileByPath.put(info.getFile().getFilePath(), info.getFile()); + } + } + return modFileByPath.get(path); + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/resourcepacks/ModFileResourcePackMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/resourcepacks/ModFileResourcePackMixin.java index ff0046d2..a095389c 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/resourcepacks/ModFileResourcePackMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/resourcepacks/ModFileResourcePackMixin.java @@ -2,7 +2,10 @@ package org.embeddedt.modernfix.forge.mixin.perf.resourcepacks; import net.minecraft.server.packs.PackType; import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.forgespi.locating.IModFile; import net.minecraftforge.resource.PathResourcePack; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.forge.load.ModResourcePackPathFixer; import org.embeddedt.modernfix.resources.ICachingResourcePack; import org.embeddedt.modernfix.resources.PackResourcesCacheEngine; import org.embeddedt.modernfix.util.PackTypeHelper; @@ -25,12 +28,26 @@ public abstract class ModFileResourcePackMixin implements ICachingResourcePack { private PackResourcesCacheEngine cacheEngine; + private IModFile mfix$resolveFileOverride; + @Inject(method = "", at = @At("TAIL")) private void cacheResources(String packName, Path source, CallbackInfo ci) { + // handle buggy mods instantiating at the root path, but only if they didn't override at all + // (otherwise they may have handled resolve() already) + if(((Object)this).getClass() == PathResourcePack.class) + this.mfix$resolveFileOverride = ModResourcePackPathFixer.getModFileByRootPath(source); + if(this.mfix$resolveFileOverride != null) + ModernFix.LOGGER.warn("PathResourcePack base class instantiated with root path of mod file {}. This probably means a mod should be calling ResourcePackLoader.createPackForMod instead. Applying workaround.", mfix$resolveFileOverride.getFileName()); invalidateCache(); PackResourcesCacheEngine.track(this); } + @Inject(method = "resolve", at = @At("HEAD"), cancellable = true, remap = false) + private void resolveViaModFile(String[] paths, CallbackInfoReturnable cir) { + if(this.mfix$resolveFileOverride != null) + cir.setReturnValue(this.mfix$resolveFileOverride.findResource(paths)); + } + private PackResourcesCacheEngine generateResourceCache() { synchronized (this) { PackResourcesCacheEngine engine = this.cacheEngine;