diff options
9 files changed, 151 insertions, 1 deletions
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 <T extends PackResourceMetadata> void parseMetadata(ResourceMetadataReader<T> metaReader, CallbackInfoReturnable<T> 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<Boolean> 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<Unit> initialStage, List<ResourcePack> packs, CallbackInfoReturnable<ResourceReload> 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("<init>") + 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<ResourcePackCompatibility> cir) { + if (packVersion == Integer.MAX_VALUE - 53) + cir.setReturnValue(BROKEN_PATHS); + } +} diff --git a/src/main/resources/assets/citresewn/lang/en_us.json b/src/main/resources/assets/citresewn/lang/en_us.json index 60f651c..565c4df 100644 --- a/src/main/resources/assets/citresewn/lang/en_us.json +++ b/src/main/resources/assets/citresewn/lang/en_us.json @@ -8,5 +8,11 @@ "config.citresewn.mute_errors.tooltip": "Should CIT Resewn not log cit errors", "config.citresewn.mute_warns.title": "Mute loading warnings", - "config.citresewn.mute_warns.tooltip": "Should CIT Resewn not log cit warnings" + "config.citresewn.mute_warns.tooltip": "Should CIT Resewn not log cit warnings", + + "config.citresewn.broken_paths.title": "Allow broken paths in resourcepacks", + "config.citresewn.broken_paths.tooltip": "Allows packs with illegal resource paths to load.\nMay cause issues!", + + "pack.incompatible.broken_paths": "(Contains broken paths)", + "pack.incompatible.confirm.broken_paths": "This pack contains broken paths and support for it may be dropped in the future. Contact pack author to remove this warning. (~ CIT Resewn)" }
\ No newline at end of file diff --git a/src/main/resources/citresewn.mixins.json b/src/main/resources/citresewn.mixins.json index 4c6a140..5753a8a 100644 --- a/src/main/resources/citresewn.mixins.json +++ b/src/main/resources/citresewn.mixins.json @@ -4,12 +4,16 @@ "package": "shcm.shsupercm.fabric.citresewn.mixin", "compatibilityLevel": "JAVA_16", "mixins": [ + "AbstractFileResourcePackMixin", "ArmorFeatureRendererMixin", "ElytraFeatureRendererMixin", + "IdentifierMixin", "ItemRendererMixin", "JsonUnbakedModelAccessor", "ModelLoaderMixin", "NbtCompoundAccessor", + "ReloadableResourceManagerImplMixin", + "ResourcePackCompatibilityMixin", "SpriteAtlasTextureMixin" ], "injectors": { |