diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonUtils.java b/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonUtils.java index 3218fdd..f61c8f7 100644 --- a/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonUtils.java +++ b/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonUtils.java @@ -1,14 +1,23 @@ package fr.firstmegagame4.env.json.impl; +import fr.firstmegagame4.env.json.api.EnvJson; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.tag.TagKey; +import net.minecraft.resource.InputSupplier; import net.minecraft.util.Identifier; import org.jetbrains.annotations.ApiStatus; +import java.io.IOException; +import java.io.InputStream; + @ApiStatus.Internal public class EnvJsonUtils { + public static final EnvJson ENV_JSON_NONE = null; + + public static final InputSupplier ENV_JSON_NONE_SUPPLIER = () -> EnvJsonUtils.ENV_JSON_NONE; + private EnvJsonUtils() { throw new RuntimeException("Class EnvJsonUtils only contains static definitions"); } @@ -21,4 +30,38 @@ public static TagKey tryParse(RegistryKey> registry throw new IllegalArgumentException("Not a valid tag representation"); } } + + public static boolean isEnvJson(Identifier identifier) { + return identifier.getPath().endsWith(".env.json"); + } + + public static String getFileExtension(Identifier identifier) { + return identifier.getPath().substring(identifier.getPath().lastIndexOf(".")); + } + + public static Identifier getEnvJsonFileName(Identifier identifier) { + return identifier.withPath(identifier.getPath().substring(0, identifier.getPath().length() - ".env.json".length())); + } + + public static Identifier getEnvJsonPath(Identifier identifier) { + String path; + if (identifier.getPath().contains(".")) { + path = identifier.getPath().substring(0, identifier.getPath().lastIndexOf(".")); + } + else { + path = identifier.getPath(); + } + return identifier.withPath(path + ".env.json"); + } + + public static InputSupplier getEnvJsonSupplier(InputSupplier supplier) { + return () -> EnvJsonUtils.loadEnvJson(supplier); + } + + public static EnvJson loadEnvJson(InputSupplier supplier) throws IOException { + InputStream inputStream = supplier.get(); + EnvJson envJson = EnvJson.parse(inputStream); + inputStream.close(); + return envJson; + } } diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/resource/EntryListDuckInterface.java b/src/main/java/fr/firstmegagame4/env/json/impl/resource/EntryListDuckInterface.java new file mode 100644 index 0000000..f668a34 --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/impl/resource/EntryListDuckInterface.java @@ -0,0 +1,17 @@ +package fr.firstmegagame4.env.json.impl.resource; + +import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.ResourcePack; +import net.minecraft.util.Identifier; + +import java.io.InputStream; +import java.util.Map; + +public interface EntryListDuckInterface { + + Identifier env_json$getEnvJsonIdentifier(); + + Map> env_json$getEnvJsonResources(); + + void env_json$putEnvJsonSource(ResourcePack resourcePack, InputSupplier inputSupplier); +} diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/resource/ExtendedResourceImpl.java b/src/main/java/fr/firstmegagame4/env/json/impl/resource/ExtendedResourceImpl.java index 0496e50..e991130 100644 --- a/src/main/java/fr/firstmegagame4/env/json/impl/resource/ExtendedResourceImpl.java +++ b/src/main/java/fr/firstmegagame4/env/json/impl/resource/ExtendedResourceImpl.java @@ -18,11 +18,12 @@ public class ExtendedResourceImpl extends Resource implements ExtendedResource { public static ExtendedResource of(Resource resource) { ResourceAccessor accessor = (ResourceAccessor) resource; ResourceDuckInterface ducked = (ResourceDuckInterface) resource; - return new ExtendedResourceImpl(accessor.getPack(), accessor.getInputSupplier(), accessor.getMetadataSupplier(), ducked.env_json$getEnvJsonSupplier(), accessor.getMetadata(), ducked.env_json$getEnvJson()); + return new ExtendedResourceImpl(accessor.getPack(), accessor.getInputSupplier(), accessor.getMetadataSupplier(), ducked.env_json$getEnvJsonSupplier(), accessor.getRawMetadata(), ducked.env_json$getEnvJson()); } private ExtendedResourceImpl(ResourcePack pack, InputSupplier inputSupplier, InputSupplier metadataSupplier, InputSupplier envJsonSupplier, ResourceMetadata resourceMetadata, EnvJson envJson) { super(pack, inputSupplier, metadataSupplier); + ((ResourceAccessor) this).setRawMetaData(resourceMetadata); ResourceDuckInterface ducked = (ResourceDuckInterface) this; ducked.env_json$initEnvJsonSupplier(envJsonSupplier); ducked.env_json$initEnvJson(envJson); diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/resource/ResourceResult.java b/src/main/java/fr/firstmegagame4/env/json/impl/resource/ResourceResult.java new file mode 100644 index 0000000..dc87f9b --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/impl/resource/ResourceResult.java @@ -0,0 +1,11 @@ +package fr.firstmegagame4.env.json.impl.resource; + +import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.ResourcePack; +import org.jetbrains.annotations.ApiStatus; + +import java.io.InputStream; + +@ApiStatus.Internal +public record ResourceResult(ResourcePack pack, InputSupplier supplier, int packIndex) { +} diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/resource/ResultAccess.java b/src/main/java/fr/firstmegagame4/env/json/impl/resource/ResultAccess.java new file mode 100644 index 0000000..b80d392 --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/impl/resource/ResultAccess.java @@ -0,0 +1,17 @@ +package fr.firstmegagame4.env.json.impl.resource; + +import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.ResourcePack; +import org.jetbrains.annotations.ApiStatus; + +import java.io.InputStream; + +@ApiStatus.Internal +public interface ResultAccess { + + ResourcePack invokePack(); + + InputSupplier invokeSupplier(); + + int invokePackIndex(); +} diff --git a/src/main/java/fr/firstmegagame4/env/json/mixin/EntryListMixin.java b/src/main/java/fr/firstmegagame4/env/json/mixin/EntryListMixin.java new file mode 100644 index 0000000..3bcbada --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/mixin/EntryListMixin.java @@ -0,0 +1,54 @@ +package fr.firstmegagame4.env.json.mixin; + +import fr.firstmegagame4.env.json.impl.EnvJsonUtils; +import fr.firstmegagame4.env.json.impl.resource.EntryListDuckInterface; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.NamespaceResourceManager; +import net.minecraft.resource.ResourcePack; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.InputStream; +import java.util.Map; + +@Mixin(NamespaceResourceManager.EntryList.class) +public class EntryListMixin implements EntryListDuckInterface { + + @Unique + @Final + @Mutable + private Identifier envJsonIdentifier; + + @Unique + @Final + @Mutable + private Map> envJsonSources; + + @Inject(method = "(Lnet/minecraft/util/Identifier;)V", at = @At("TAIL")) + private void envJsonInit(Identifier id, CallbackInfo ci) { + this.envJsonIdentifier = EnvJsonUtils.getEnvJsonPath(id); + this.envJsonSources = new Object2ObjectArrayMap<>(); + } + + @Override + public Identifier env_json$getEnvJsonIdentifier() { + return this.envJsonIdentifier; + } + + @Override + public Map> env_json$getEnvJsonResources() { + return this.envJsonSources; + } + + @Override + public void env_json$putEnvJsonSource(ResourcePack resourcePack, InputSupplier inputSupplier) { + this.envJsonSources.put(resourcePack, inputSupplier); + } +} diff --git a/src/main/java/fr/firstmegagame4/env/json/mixin/GroupResourcePackMixin.java b/src/main/java/fr/firstmegagame4/env/json/mixin/GroupResourcePackMixin.java new file mode 100644 index 0000000..b9f9f60 --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/mixin/GroupResourcePackMixin.java @@ -0,0 +1,46 @@ +package fr.firstmegagame4.env.json.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import fr.firstmegagame4.env.json.api.EnvJson; +import fr.firstmegagame4.env.json.impl.EnvJsonUtils; +import fr.firstmegagame4.env.json.impl.resource.ResourceDuckInterface; +import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack; +import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.ResourcePack; +import net.minecraft.resource.ResourceType; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.io.InputStream; + +// I know I shouldn't use an impl class, but I have no choice +// Should try to load it with QSL when this one will be available for 1.20.4 +@SuppressWarnings("UnstableApiUsage") +@Mixin(value = GroupResourcePack.class, remap = false) +public class GroupResourcePackMixin { + + @WrapOperation(method = "appendResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePack;open(Lnet/minecraft/resource/ResourceType;Lnet/minecraft/util/Identifier;)Lnet/minecraft/resource/InputSupplier;")) + private InputSupplier onResourceAdd(ResourcePack instance, ResourceType resourceType, Identifier identifier, Operation> original, @Share("envJsonInputSupplier") LocalRef> ref) { + InputSupplier inputSupplier = original.call(instance, resourceType, identifier); + Identifier envJsonPath = EnvJsonUtils.getEnvJsonPath(identifier); + if (inputSupplier != null) { + InputSupplier envJsonInputSupplier = () -> { + InputSupplier supplier = instance.open(resourceType, envJsonPath); + return supplier != null ? EnvJsonUtils.loadEnvJson(supplier) : EnvJsonUtils.ENV_JSON_NONE; + }; + ref.set(envJsonInputSupplier); + } + return inputSupplier; + } + + @ModifyArg(method = "appendResources", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z")) + private E onResourceCreated(E e, @Share("envJsonInputSupplier") LocalRef> ref) { + ((ResourceDuckInterface) e).env_json$initEnvJsonSupplier(ref.get()); + return e; + } +} diff --git a/src/main/java/fr/firstmegagame4/env/json/mixin/NamespaceResourceManagerMixin.java b/src/main/java/fr/firstmegagame4/env/json/mixin/NamespaceResourceManagerMixin.java index 2996131..23ee11f 100644 --- a/src/main/java/fr/firstmegagame4/env/json/mixin/NamespaceResourceManagerMixin.java +++ b/src/main/java/fr/firstmegagame4/env/json/mixin/NamespaceResourceManagerMixin.java @@ -1,5 +1,6 @@ package fr.firstmegagame4.env.json.mixin; +import com.google.common.collect.Iterators; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; @@ -7,24 +8,31 @@ import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; import fr.firstmegagame4.env.json.api.EnvJson; +import fr.firstmegagame4.env.json.impl.EnvJsonInitializer; +import fr.firstmegagame4.env.json.impl.EnvJsonUtils; +import fr.firstmegagame4.env.json.impl.resource.EntryListDuckInterface; import fr.firstmegagame4.env.json.impl.resource.ResourceDuckInterface; +import fr.firstmegagame4.env.json.impl.resource.ResourceResult; +import fr.firstmegagame4.env.json.impl.resource.ResultAccess; import net.minecraft.resource.*; +import net.minecraft.resource.metadata.ResourceMetadata; import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.io.IOException; import java.io.InputStream; -import java.util.List; +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Predicate; @Mixin(NamespaceResourceManager.class) -public class NamespaceResourceManagerMixin { - - @Unique - private static final EnvJson ENV_JSON_NONE = null; +public abstract class NamespaceResourceManagerMixin { @Shadow @Final @@ -34,6 +42,21 @@ public class NamespaceResourceManagerMixin { @Final private ResourceType type; + @Shadow + private static Resource createResource(ResourcePack pack, Identifier id, InputSupplier supplier, InputSupplier metadataSupplier) { + throw new AssertionError(); + } + + @Shadow + static Identifier getMetadataPath(Identifier id) { + throw new AssertionError(); + } + + @Shadow + private static InputSupplier getMetadataSupplier(InputSupplier supplier) { + throw new AssertionError(); + } + @ModifyExpressionValue(method = "getResource", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/NamespaceResourceManager;createResource(Lnet/minecraft/resource/ResourcePack;Lnet/minecraft/util/Identifier;Lnet/minecraft/resource/InputSupplier;Lnet/minecraft/resource/InputSupplier;)Lnet/minecraft/resource/Resource;")) private Resource onResourceCreated(Resource original, Identifier identifier, @Local(ordinal = 0) int i) { ((ResourceDuckInterface) original).env_json$initEnvJsonSupplier(this.createEnvJsonSupplier(identifier, i)); @@ -41,9 +64,9 @@ private Resource onResourceCreated(Resource original, Identifier identifier, @Lo } @WrapOperation(method = "getAllResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePack;open(Lnet/minecraft/resource/ResourceType;Lnet/minecraft/util/Identifier;)Lnet/minecraft/resource/InputSupplier;")) - private InputSupplier onResourceAdd(ResourcePack instance, ResourceType resourceType, Identifier identifier, Operation> original, @Local(ordinal = 0) boolean bl, @Share("envJsonInputSupplier") LocalRef> ref) { + private InputSupplier onResourceAdd(ResourcePack instance, ResourceType resourceType, Identifier identifier, Operation> original, @Local boolean bl, @Share("envJsonInputSupplier") LocalRef> ref) { InputSupplier inputSupplier = original.call(instance, resourceType, identifier); - Identifier envJsonPath = this.getEnvJsonPath(identifier); + Identifier envJsonPath = EnvJsonUtils.getEnvJsonPath(identifier); if (inputSupplier != null) { InputSupplier envJsonInputSupplier; if (bl) { @@ -52,7 +75,7 @@ private InputSupplier onResourceAdd(ResourcePack instance, Resource else { envJsonInputSupplier = () -> { InputSupplier supplier = instance.open(resourceType, envJsonPath); - return supplier != null ? this.loadEnvJson(supplier) : NamespaceResourceManagerMixin.ENV_JSON_NONE; + return supplier != null ? EnvJsonUtils.loadEnvJson(supplier) : EnvJsonUtils.ENV_JSON_NONE; }; } ref.set(envJsonInputSupplier); @@ -60,22 +83,105 @@ private InputSupplier onResourceAdd(ResourcePack instance, Resource return inputSupplier; } - @WrapOperation(method = "getAllResources", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z")) - private boolean onResourceCreated(List instance, E e, Operation original, @Share("envJsonInputSupplier") LocalRef> ref) { + @ModifyArg(method = "getAllResources", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z")) + private E onResourceCreated(E e, @Share("envJsonInputSupplier") LocalRef> ref) { ((ResourceDuckInterface) e).env_json$initEnvJsonSupplier(ref.get()); - // noinspection MixinExtrasOperationParameters - return original.call(instance, e); + return e; } - @Unique - private Identifier getEnvJsonPath(Identifier identifier) { - return identifier.withPath(identifier.getPath() + ".env.json"); + @Inject(method = "findResources", at = @At(value = "INVOKE", target = "Ljava/util/HashMap;()V", shift = At.Shift.AFTER, ordinal = 1)) + private void createEnvJsonMap(String startingPath, Predicate allowedPathPredicate, CallbackInfoReturnable> cir, @Share("envJsonMap") LocalRef> envJsonMap) { + envJsonMap.set(new HashMap<>()); + } + + @Inject(method = "findResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/NamespaceResourceManager$FilterablePack;removeFiltered(Ljava/util/Collection;)V", shift = At.Shift.AFTER, ordinal = 1)) + private void removeFilteredEnvJson(String startingPath, Predicate allowedPathPredicate, CallbackInfoReturnable> cir, @Local NamespaceResourceManager.FilterablePack filterablePack, @Share("envJsonMap") LocalRef> envJsonMap) { + filterablePack.removeFiltered(envJsonMap.get().keySet()); + } + + @ModifyArg(method = "findResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePack;findResources(Lnet/minecraft/resource/ResourceType;Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/resource/ResourcePack$ResultConsumer;)V"), index = 3) + private ResourcePack.ResultConsumer mutateBiConsumer(ResourcePack.ResultConsumer consumer, @Local(ordinal = 0) Predicate allowedPathPredicate, @Local(ordinal = 0) ResourcePack resourcePack, @Local(ordinal = 2) int k, @Share("envJsonMap") LocalRef> envJsonMap) { + return (identifier, supplier) -> { + if (EnvJsonUtils.isEnvJson(identifier)) { + if (allowedPathPredicate.test(EnvJsonUtils.getEnvJsonFileName(identifier))) { + envJsonMap.get().put(identifier, new ResourceResult(resourcePack, supplier, k)); + } + } + else { + consumer.accept(identifier, supplier); + } + }; + } + + @ModifyArg(method = "findResources", at = @At(value = "INVOKE", target = "Ljava/util/Map;forEach(Ljava/util/function/BiConsumer;)V")) + private BiConsumer mutateForEach(BiConsumer action, @Local(ordinal = 1) Map results, @Local(ordinal = 2) Map resources, @Share("envJsonMap") LocalRef> envJsonMap) { + return (identifier, result) -> { + Identifier envJsonIdentifier = EnvJsonUtils.getEnvJsonPath(identifier); + ResourceResult resourceResult = envJsonMap.get().get(envJsonIdentifier); + if (resourceResult != null && resourceResult.packIndex() >= result.invokePackIndex()) { + Identifier metadataIdentifier = NamespaceResourceManagerMixin.getMetadataPath(identifier); + ResultAccess access = (ResultAccess) results.get(identifier); + InputSupplier metadataSupplier; + if (access != null && access.invokePackIndex() >= result.invokePackIndex()) { + metadataSupplier = NamespaceResourceManagerMixin.getMetadataSupplier(access.invokeSupplier()); + } else { + metadataSupplier = ResourceMetadata.NONE_SUPPLIER; + } + ResourceDuckInterface ducked = (ResourceDuckInterface) NamespaceResourceManagerMixin.createResource(result.invokePack(), identifier, result.invokeSupplier(), metadataSupplier); + ducked.env_json$initEnvJsonSupplier(EnvJsonUtils.getEnvJsonSupplier(resourceResult.supplier())); + resources.put(metadataIdentifier, (Resource) ducked); + } + else { + action.accept(identifier, result); + } + }; + } + + @ModifyExpressionValue(method = "applyFilter", at = @At(value = "INVOKE", target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;")) + private static Iterator mutateIterator(Iterator original, NamespaceResourceManager.FilterablePack pack) { + Iterator iterator = Iterators.filter( + original, + object -> !pack.isFiltered(((NamespaceResourceManager.EntryList) object).id()) && !pack.isFiltered(((NamespaceResourceManager.EntryList) object).metadataId()) + ); + iterator.forEachRemaining(object -> { + EntryListDuckInterface ducked = (EntryListDuckInterface) object; + if (pack.isFiltered(ducked.env_json$getEnvJsonIdentifier())) { + ducked.env_json$getEnvJsonResources().clear(); + } + }); + return Iterators.filter( + original, + object -> pack.isFiltered(((NamespaceResourceManager.EntryList) object).id()) || pack.isFiltered(((NamespaceResourceManager.EntryList) object).metadataId()) + ); + } + + @ModifyArg(method = "findAndAdd", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePack;findResources(Lnet/minecraft/resource/ResourceType;Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/resource/ResourcePack$ResultConsumer;)V"), index = 3) + private ResourcePack.ResultConsumer mutateBiConsumer(ResourcePack.ResultConsumer consumer, @Local(ordinal = 0) ResourcePack resourcePack, @Local(ordinal = 0) Predicate allowedPathPredicate, @Local(ordinal = 0) Map idToEntryList) { + return (identifier, supplier) -> { + if (EnvJsonUtils.isEnvJson(identifier)) { + Identifier envJsonIdentifier = EnvJsonUtils.getEnvJsonFileName(identifier); + if (allowedPathPredicate.test(envJsonIdentifier)) { + ((EntryListDuckInterface) (Object) idToEntryList.computeIfAbsent(identifier, NamespaceResourceManager.EntryList::new)) + .env_json$putEnvJsonSource(resourcePack, supplier); + } + } + else { + consumer.accept(identifier, supplier); + } + }; + } + + @ModifyArg(method = "findAllResources", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z")) + private E mutateResource(E e, @Local(ordinal = 0) InputSupplier inputSupplier) { + InputSupplier envJsonSupplier = inputSupplier != null ? EnvJsonUtils.getEnvJsonSupplier(inputSupplier) : EnvJsonUtils.ENV_JSON_NONE_SUPPLIER; + ((ResourceDuckInterface) e).env_json$initEnvJsonSupplier(envJsonSupplier); + return e; } @Unique private InputSupplier createEnvJsonSupplier(Identifier identifier, int index) { return () -> { - Identifier envJsonPath = this.getEnvJsonPath(identifier); + Identifier envJsonPath = EnvJsonUtils.getEnvJsonPath(identifier); // noinspection OverflowingLoopIndex for (int i = this.packList.size() - 1; i >= index; i++) { NamespaceResourceManager.FilterablePack filterablePack = this.packList.get(i); @@ -83,22 +189,14 @@ private InputSupplier createEnvJsonSupplier(Identifier identifier, int if (resourcePack != null) { InputSupplier inputSupplier = resourcePack.open(this.type, envJsonPath); if (inputSupplier != null) { - return this.loadEnvJson(inputSupplier); + return EnvJsonUtils.loadEnvJson(inputSupplier); } } if (filterablePack.isFiltered(envJsonPath)) { break; } } - return null; + return EnvJsonUtils.ENV_JSON_NONE; }; } - - @Unique - private EnvJson loadEnvJson(InputSupplier supplier) throws IOException { - InputStream inputStream = supplier.get(); - EnvJson envJson = EnvJson.parse(inputStream); - inputStream.close(); - return envJson; - } } diff --git a/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceAccessor.java b/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceAccessor.java index 5cb610c..7e3cd79 100644 --- a/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceAccessor.java +++ b/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceAccessor.java @@ -23,6 +23,9 @@ public interface ResourceAccessor { InputSupplier getMetadataSupplier(); @Nullable - @Accessor - ResourceMetadata getMetadata(); + @Accessor("metadata") + ResourceMetadata getRawMetadata(); + + @Accessor("metadata") + void setRawMetaData(ResourceMetadata metadata); } diff --git a/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceMixin.java b/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceMixin.java index 3e434fa..e494c0a 100644 --- a/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceMixin.java +++ b/src/main/java/fr/firstmegagame4/env/json/mixin/ResourceMixin.java @@ -1,6 +1,7 @@ package fr.firstmegagame4.env.json.mixin; import fr.firstmegagame4.env.json.api.EnvJson; +import fr.firstmegagame4.env.json.impl.EnvJsonUtils; import fr.firstmegagame4.env.json.impl.resource.ResourceDuckInterface; import net.minecraft.resource.InputSupplier; import net.minecraft.resource.Resource; @@ -13,10 +14,10 @@ public class ResourceMixin implements ResourceDuckInterface { @Unique - private InputSupplier envJsonSupplier = null; + private InputSupplier envJsonSupplier = EnvJsonUtils.ENV_JSON_NONE_SUPPLIER; @Unique - private EnvJson envJson = null; + private EnvJson envJson = EnvJsonUtils.ENV_JSON_NONE; @Override public void env_json$initEnvJsonSupplier(InputSupplier envJsonSupplier) { diff --git a/src/main/java/fr/firstmegagame4/env/json/mixin/ResultAccessor.java b/src/main/java/fr/firstmegagame4/env/json/mixin/ResultAccessor.java new file mode 100644 index 0000000..039f198 --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/mixin/ResultAccessor.java @@ -0,0 +1,22 @@ +package fr.firstmegagame4.env.json.mixin; + +import fr.firstmegagame4.env.json.impl.resource.ResultAccess; +import net.minecraft.resource.InputSupplier; +import net.minecraft.resource.ResourcePack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.io.InputStream; + +@Mixin(targets = "net.minecraft.resource.NamespaceResourceManager$Result") +public interface ResultAccessor extends ResultAccess { + + @Invoker("pack") + ResourcePack invokePack(); + + @Invoker("supplier") + InputSupplier invokeSupplier(); + + @Invoker("packIndex") + int invokePackIndex(); +} diff --git a/src/main/resources/env_json.accesswidener b/src/main/resources/env_json.accesswidener index 07a0b76..435357f 100644 --- a/src/main/resources/env_json.accesswidener +++ b/src/main/resources/env_json.accesswidener @@ -1,3 +1,7 @@ accessWidener v1 named -accessible class net/minecraft/resource/NamespaceResourceManager$FilterablePack \ No newline at end of file +accessible class net/minecraft/resource/NamespaceResourceManager$EntryList +accessible class net/minecraft/resource/NamespaceResourceManager$FileSource +accessible class net/minecraft/resource/NamespaceResourceManager$FilterablePack + +accessible method net/minecraft/resource/NamespaceResourceManager$EntryList (Lnet/minecraft/util/Identifier;)V \ No newline at end of file diff --git a/src/main/resources/env_json.mixins.json b/src/main/resources/env_json.mixins.json index 8800771..75591fe 100644 --- a/src/main/resources/env_json.mixins.json +++ b/src/main/resources/env_json.mixins.json @@ -3,9 +3,12 @@ "package": "fr.firstmegagame4.env.json.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ + "EntryListMixin", + "GroupResourcePackMixin", "NamespaceResourceManagerMixin", "ResourceAccessor", - "ResourceMixin" + "ResourceMixin", + "ResultAccessor" ], "client": [], "injectors": { diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index bb1537b..cf2aed1 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -19,6 +19,10 @@ "fr.firstmegagame4.env.json.impl.EnvJsonInitializer" ] }, + "accessWidener": "env_json.accesswidener", + "mixins": [ + "env_json.mixins.json" + ], "depends": { "fabricloader": ">=0.15.2", "minecraft": "~1.20.4",