From a69a294e7b0abaadb23989a3b24dd502e5cb6771 Mon Sep 17 00:00:00 2001 From: SHsuperCM Date: Tue, 7 Sep 2021 12:18:42 +0300 Subject: Added support for packs with broken paths(config) --- .../shcm/shsupercm/fabric/citresewn/CITResewn.java | 3 ++ .../fabric/citresewn/config/CITResewnConfig.java | 1 + .../config/CITResewnConfigScreenFactory.java | 11 +++++ .../mixin/AbstractFileResourcePackMixin.java | 50 ++++++++++++++++++++++ .../fabric/citresewn/mixin/IdentifierMixin.java | 17 ++++++++ .../mixin/ReloadableResourceManagerImplMixin.java | 32 ++++++++++++++ .../mixin/ResourcePackCompatibilityMixin.java | 26 +++++++++++ 7 files changed, 140 insertions(+) create mode 100644 src/main/java/shcm/shsupercm/fabric/citresewn/mixin/AbstractFileResourcePackMixin.java create mode 100644 src/main/java/shcm/shsupercm/fabric/citresewn/mixin/IdentifierMixin.java create mode 100644 src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ReloadableResourceManagerImplMixin.java create mode 100644 src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ResourcePackCompatibilityMixin.java (limited to 'src/main/java/shcm') diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/CITResewn.java b/src/main/java/shcm/shsupercm/fabric/citresewn/CITResewn.java index 0eb4ec5..68ecbe5 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/CITResewn.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/CITResewn.java @@ -17,6 +17,9 @@ public class CITResewn implements ClientModInitializer { public CITResewnConfig config = null; + + public boolean processingBrokenPaths = false; + @Override public void onInitializeClient() { INSTANCE = this; diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfig.java b/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfig.java index d933e84..5bc059e 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfig.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfig.java @@ -13,6 +13,7 @@ public class CITResewnConfig { public boolean enabled = true; public boolean mute_errors = false; public boolean mute_warns = false; + public boolean broken_paths = false; private static final File FILE = new File("config/citresewn.json"); public static CITResewnConfig INSTANCE() { diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfigScreenFactory.java b/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfigScreenFactory.java index a47e6d4..b85a55c 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfigScreenFactory.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnConfigScreenFactory.java @@ -43,6 +43,17 @@ public class CITResewnConfigScreenFactory { .setDefaultValue(defaultConfig.mute_warns) .build()); + category.addEntry(entryBuilder.startBooleanToggle(new TranslatableText("config.citresewn.broken_paths.title"), currentConfig.broken_paths) + .setTooltip(new TranslatableText("config.citresewn.broken_paths.tooltip")) + .setSaveConsumer(newConfig -> { + if (currentConfig.broken_paths != newConfig) { + currentConfig.broken_paths = newConfig; + MinecraftClient.getInstance().reloadResources(); + } + }) + .setDefaultValue(defaultConfig.broken_paths) + .build()); + return builder.build(); } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/AbstractFileResourcePackMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/AbstractFileResourcePackMixin.java new file mode 100644 index 0000000..acc0f38 --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/AbstractFileResourcePackMixin.java @@ -0,0 +1,50 @@ +package shcm.shsupercm.fabric.citresewn.mixin; + +import net.minecraft.resource.AbstractFileResourcePack; +import net.minecraft.resource.DirectoryResourcePack; +import net.minecraft.resource.ResourcePack; +import net.minecraft.resource.ZipResourcePack; +import net.minecraft.resource.metadata.PackResourceMetadata; +import net.minecraft.resource.metadata.ResourceMetadataReader; +import net.minecraft.util.Identifier; +import net.minecraft.util.InvalidIdentifierException; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.zip.ZipFile; + +@Mixin(AbstractFileResourcePack.class) +public abstract class AbstractFileResourcePackMixin implements ResourcePack { + @Shadow @Final protected File base; + + @SuppressWarnings({"unchecked", "ConstantConditions", "EqualsBetweenInconvertibleTypes"}) + @Inject(method = "parseMetadata(Lnet/minecraft/resource/metadata/ResourceMetadataReader;)Ljava/lang/Object;", cancellable = true, at = @At("RETURN")) + public void parseMetadata(ResourceMetadataReader metaReader, CallbackInfoReturnable cir) { + if (CITResewnConfig.INSTANCE().broken_paths && cir.getReturnValue() != null) + try { + if (this.getClass().equals(ZipResourcePack.class)) { + try (ZipFile zipFile = new ZipFile(base)) { + zipFile.stream() + .forEach(entry -> { + if (entry.getName().startsWith("assets")) + new Identifier("minecraft", entry.getName()); + }); + } + } else if (this.getClass().equals(DirectoryResourcePack.class)) { + final Path assets = new File(base, "assets").toPath(); + Files.walk(assets) + .forEach(path -> new Identifier("minecraft", assets.relativize(path).toString().replace('\\', '/'))); + } + } catch (InvalidIdentifierException e) { + cir.setReturnValue((T) new PackResourceMetadata(cir.getReturnValue().getDescription(), Integer.MAX_VALUE - 53)); + } catch (Exception ignored) {} + } +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/IdentifierMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/IdentifierMixin.java new file mode 100644 index 0000000..4892abc --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/IdentifierMixin.java @@ -0,0 +1,17 @@ +package shcm.shsupercm.fabric.citresewn.mixin; + +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.CITResewn; + +@Mixin(Identifier.class) +public class IdentifierMixin { + @Inject(method = "isPathValid", cancellable = true, at = @At("HEAD")) + private static void processBrokenPaths(String path, CallbackInfoReturnable cir) { + if (CITResewn.INSTANCE != null && CITResewn.INSTANCE.processingBrokenPaths) + cir.setReturnValue(true); + } +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ReloadableResourceManagerImplMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ReloadableResourceManagerImplMixin.java new file mode 100644 index 0000000..8ee0498 --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ReloadableResourceManagerImplMixin.java @@ -0,0 +1,32 @@ +package shcm.shsupercm.fabric.citresewn.mixin; + +import net.minecraft.resource.ReloadableResourceManagerImpl; +import net.minecraft.resource.ResourcePack; +import net.minecraft.resource.ResourceReload; +import net.minecraft.resource.ResourceType; +import net.minecraft.util.Unit; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import shcm.shsupercm.fabric.citresewn.CITResewn; +import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +@Mixin(ReloadableResourceManagerImpl.class) +public class ReloadableResourceManagerImplMixin { + @Shadow @Final private ResourceType type; + + @Inject(method = "reload", at = @At("RETURN")) + public void onReload(Executor prepareExecutor, Executor applyExecutor, CompletableFuture initialStage, List packs, CallbackInfoReturnable cir) { + if (CITResewn.INSTANCE.processingBrokenPaths = (this.type == ResourceType.CLIENT_RESOURCES && CITResewnConfig.INSTANCE().broken_paths)) + cir.getReturnValue().whenComplete().thenRun(() -> { + CITResewn.INSTANCE.processingBrokenPaths = false; + }); + } +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ResourcePackCompatibilityMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ResourcePackCompatibilityMixin.java new file mode 100644 index 0000000..c41ddad --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ResourcePackCompatibilityMixin.java @@ -0,0 +1,26 @@ +package shcm.shsupercm.fabric.citresewn.mixin; + +import net.minecraft.resource.ResourcePackCompatibility; +import net.minecraft.resource.ResourceType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ResourcePackCompatibility.class) +public abstract class ResourcePackCompatibilityMixin { + private static final ResourcePackCompatibility BROKEN_PATHS = ResourcePackCompatibility("BROKEN_PATHS", -1, "broken_paths"); + + @SuppressWarnings("InvokerTarget") + @Invoker("") + public static ResourcePackCompatibility ResourcePackCompatibility(String internalName, int internalId, String translationSuffix) { + throw new AssertionError(); + } + + @Inject(method = "from(ILnet/minecraft/resource/ResourceType;)Lnet/minecraft/resource/ResourcePackCompatibility;", cancellable = true, at = @At("HEAD")) + private static void redirectBrokenPathsCompatibility(int packVersion, ResourceType type, CallbackInfoReturnable cir) { + if (packVersion == Integer.MAX_VALUE - 53) + cir.setReturnValue(BROKEN_PATHS); + } +} -- cgit