From 367cc372c27fb21cd07dfc80536d394ce8091604 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 5 May 2023 11:27:07 -0400 Subject: [PATCH 1/3] Workaround for runtime resource packs that aren't thread safe Related: https://github.com/Fuzss/diagonalfences/issues/38 --- .../dynamicresources/ModelBakeryHelpers.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java index 12ef8d8b..e0df2a26 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java @@ -26,6 +26,7 @@ import net.minecraft.world.level.block.state.properties.Property; import org.embeddedt.modernfix.ModernFix; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.*; @@ -97,6 +98,12 @@ public class ModelBakeryHelpers { List allPackResources = new ArrayList<>(manager.listPacks().collect(Collectors.toList())); Collections.reverse(allPackResources); ObjectOpenHashSet allAvailableModels = new ObjectOpenHashSet<>(), allAvailableStates = new ObjectOpenHashSet<>(); + /* try to fix CME in some runtime packs by forcing generation */ + for(PackResources pack : allPackResources) { + try(InputStream stream = pack.getResource(PackType.CLIENT_RESOURCES, new ResourceLocation("modernfix", "dummy.json"))) { + } catch(Exception ignored) { + } + } allPackResources.removeIf(pack -> { if(isTrustedPack.test(pack)) { for(String namespace : pack.getNamespaces(PackType.CLIENT_RESOURCES)) { @@ -124,10 +131,18 @@ public class ModelBakeryHelpers { ConcurrentLinkedQueue> blockStateLoadedFiles = new ConcurrentLinkedQueue<>(); List> blockStateData = new ArrayList<>(); for(ResourceLocation blockstate : blockStateFiles) { + ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), "blockstates/" + blockstate.getPath() + ".json"); + List resources; + try { + resources = manager.getResources(fileLocation); + if(resources.isEmpty()) + continue; + } catch(IOException e) { + logOrSuppressError(blockstateErrors, "blockstate", blockstate, e); + continue; + } blockStateData.add(CompletableFuture.runAsync(() -> { - ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), "blockstates/" + blockstate.getPath() + ".json"); try { - List resources = manager.getResources(fileLocation); for(Resource resource : resources) { JsonParser parser = new JsonParser(); try { From 9677eb6c02f3a0090be5eb606b9d1ccbecb1e075 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 5 May 2023 12:02:52 -0400 Subject: [PATCH 2/3] Provide more debug information if entity renderer is missing --- .../safety/EntityRenderDispatcherMixin.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java new file mode 100644 index 00000000..421919f4 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java @@ -0,0 +1,73 @@ +package org.embeddedt.modernfix.forge.mixin.safety; + +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +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.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Mixin(value = EntityRenderDispatcher.class, priority = 1500) +public class EntityRenderDispatcherMixin { + + @Shadow @Final @Mutable private Map, EntityRenderer> renderers; + private static Map, IRenderFactory> RENDER_FACTORIES; + + static { + RenderingRegistry instance = ObfuscationReflectionHelper.getPrivateValue(RenderingRegistry.class, null, "INSTANCE"); + RENDER_FACTORIES = ObfuscationReflectionHelper.getPrivateValue(RenderingRegistry.class, instance, "entityRenderers"); + } + + @Inject(method = "", at = @At("RETURN")) + private void makeRenderersConcurrent(CallbackInfo ci) { + renderers = new ConcurrentHashMap<>(renderers); + } + + @Inject(method = "getRenderer", at = @At("RETURN"), cancellable = true) + private void checkRenderer(T entity, CallbackInfoReturnable> cir) { + if(cir.getReturnValue() == null) { + synchronized (EntityRenderDispatcher.class) { + EntityType type = entity.getType(); + if(type == null) { + throw new IllegalStateException("Entity with class " + entity.getClass().getName() + " UUID " + entity.getName() + " has no type???"); + } + ResourceLocation key = Registry.ENTITY_TYPE.getKey(type); + EntityRenderer renderer = null; + if(RENDER_FACTORIES != null) { + IRenderFactory factory = RENDER_FACTORIES.get(type); + if(factory != null) { + try { + renderer = factory.createRenderFor((EntityRenderDispatcher)(Object)this); + } catch(RuntimeException e) { + ModernFix.LOGGER.error("Failed to create fallback renderer", e); + } + if(renderer != null) { + this.renderers.put(type, renderer); + ModernFix.LOGGER.warn("Entity renderer for {} was somehow not registered, injecting.", key); + cir.setReturnValue(renderer); + } + } + } + if(cir.getReturnValue() == null) { + ModernFix.LOGGER.error("Backing renderer map is a " + renderers.getClass().getName()); + throw new IllegalStateException("No renderer for entity with type " + key); + } + } + } + } +} From 8996d4e09bc6c30d0ac281d2b373ff310331c1dd Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 5 May 2023 12:03:22 -0400 Subject: [PATCH 3/3] Remove entity renderer mixin as it's not needed on 1.18 --- .../safety/EntityRenderDispatcherMixin.java | 73 ------------------- 1 file changed, 73 deletions(-) delete mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java deleted file mode 100644 index 421919f4..00000000 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/safety/EntityRenderDispatcherMixin.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.embeddedt.modernfix.forge.mixin.safety; - -import net.minecraft.client.renderer.entity.EntityRenderDispatcher; -import net.minecraft.client.renderer.entity.EntityRenderer; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraftforge.fml.client.registry.IRenderFactory; -import net.minecraftforge.fml.client.registry.RenderingRegistry; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import org.embeddedt.modernfix.ModernFix; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -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.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -@Mixin(value = EntityRenderDispatcher.class, priority = 1500) -public class EntityRenderDispatcherMixin { - - @Shadow @Final @Mutable private Map, EntityRenderer> renderers; - private static Map, IRenderFactory> RENDER_FACTORIES; - - static { - RenderingRegistry instance = ObfuscationReflectionHelper.getPrivateValue(RenderingRegistry.class, null, "INSTANCE"); - RENDER_FACTORIES = ObfuscationReflectionHelper.getPrivateValue(RenderingRegistry.class, instance, "entityRenderers"); - } - - @Inject(method = "", at = @At("RETURN")) - private void makeRenderersConcurrent(CallbackInfo ci) { - renderers = new ConcurrentHashMap<>(renderers); - } - - @Inject(method = "getRenderer", at = @At("RETURN"), cancellable = true) - private void checkRenderer(T entity, CallbackInfoReturnable> cir) { - if(cir.getReturnValue() == null) { - synchronized (EntityRenderDispatcher.class) { - EntityType type = entity.getType(); - if(type == null) { - throw new IllegalStateException("Entity with class " + entity.getClass().getName() + " UUID " + entity.getName() + " has no type???"); - } - ResourceLocation key = Registry.ENTITY_TYPE.getKey(type); - EntityRenderer renderer = null; - if(RENDER_FACTORIES != null) { - IRenderFactory factory = RENDER_FACTORIES.get(type); - if(factory != null) { - try { - renderer = factory.createRenderFor((EntityRenderDispatcher)(Object)this); - } catch(RuntimeException e) { - ModernFix.LOGGER.error("Failed to create fallback renderer", e); - } - if(renderer != null) { - this.renderers.put(type, renderer); - ModernFix.LOGGER.warn("Entity renderer for {} was somehow not registered, injecting.", key); - cir.setReturnValue(renderer); - } - } - } - if(cir.getReturnValue() == null) { - ModernFix.LOGGER.error("Backing renderer map is a " + renderers.getClass().getName()); - throw new IllegalStateException("No renderer for entity with type " + key); - } - } - } - } -}