Avoid synchronizing layer list in LivingEntityRenderer

This commit is contained in:
embeddedt 2026-03-26 22:58:18 -04:00
parent 79d2b28d5b
commit ab8a8068e0
No known key found for this signature in database
GPG Key ID: A69433EC199B5613

View File

@ -1,28 +1,34 @@
package org.embeddedt.modernfix.common.mixin.safety;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.world.entity.Entity;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
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 java.util.Collections;
import java.util.List;
@Mixin(LivingEntityRenderer.class)
@ClientOnlyMixin
public class LivingEntityRendererMixin {
@Shadow @Final @Mutable
protected List<RenderLayer<?, ?>> layers;
public abstract class LivingEntityRendererMixin<T extends Entity, M extends EntityModel<T>> {
@Shadow
public abstract boolean addLayer(RenderLayer<T, M> layer);
@Inject(method = "<init>", at = @At("RETURN"))
private void synchronizeLayerList(CallbackInfo ci) {
/* allows buggy mods to call addLayer concurrently, order is not deterministic but can't fix that */
this.layers = Collections.synchronizedList(layers);
/**
* @author embeddedt
* @reason avoid CMEs from buggy mods calling addLayer on wrong thread
*/
@WrapMethod(method = "addLayer")
private boolean handleOffThreadLayerAdd(RenderLayer<T, M> layer, Operation<Boolean> original) {
if (!Minecraft.getInstance().isSameThread()) {
ModernFix.LOGGER.error("LivingEntityRenderer.addLayer called on wrong thread", new Exception());
Minecraft.getInstance().tell(() -> this.addLayer(layer));
return true;
}
return original.call(layer);
}
}