fabric-block-view-api-v2-1.0.34+e4fd1b926f.jar
Download file
package net.fabricmc.fabric.mixin.blockview.client;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.blockview.client.RenderDataMapConsumer;
import net.minecraft.class_1937;
import net.minecraft.class_2338;
import net.minecraft.class_2586;
import net.minecraft.class_2818;
import net.minecraft.class_4076;
import net.minecraft.class_6850;
import net.minecraft.class_853;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongepowered.asm.mixin.Mixin;
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.CallbackInfoReturnable;
@Environment(EnvType.CLIENT)
@Mixin({class_6850.class})
public abstract class ChunkRendererRegionBuilderMixin {
@Unique
private static final AtomicInteger ERROR_COUNTER = new AtomicInteger();
@Unique
private static final Logger LOGGER = LoggerFactory.getLogger(ChunkRendererRegionBuilderMixin.class);
@Inject(
method = {"method_39969(Lnet/minecraft/class_1937;J)Lnet/minecraft/class_853;"},
at = {@At(
value = "INVOKE",
target = "Lnet/minecraft/class_6850;method_72042(Lnet/minecraft/class_1937;III)Lnet/minecraft/class_6849;"
)}
)
private void copyDataForChunk(class_1937 world, long packedChunkPos, CallbackInfoReturnable<class_853> cir, @Share("dataMap") LocalRef<Long2ObjectOpenHashMap<Object>> mapRef, @Local(ordinal = 11) int x, @Local(ordinal = 10) int y, @Local(ordinal = 9) int z) {
while(true) {
try {
mapRef.set(mapChunk(world.method_8497(x, z), class_4076.method_18677(packedChunkPos), (Long2ObjectOpenHashMap)mapRef.get()));
return;
} catch (ConcurrentModificationException e) {
int count = ERROR_COUNTER.incrementAndGet();
if (count <= 5) {
LOGGER.warn("[Block Entity Render Data] Encountered CME during render region build. A mod is accessing or changing chunk data outside the main thread. Retrying.", e);
if (count == 5) {
LOGGER.info("[Block Entity Render Data] Subsequent exceptions will be suppressed.");
}
}
}
}
}
@Inject(
method = {"method_39969(Lnet/minecraft/class_1937;J)Lnet/minecraft/class_853;"},
at = {@At("RETURN")}
)
private void createDataMap(class_1937 world, long l, CallbackInfoReturnable<class_853> cir, @Share("dataMap") LocalRef<Long2ObjectOpenHashMap<Object>> mapRef) {
class_853 rendererRegion = (class_853)cir.getReturnValue();
Long2ObjectOpenHashMap<Object> map = (Long2ObjectOpenHashMap)mapRef.get();
if (map != null) {
((RenderDataMapConsumer)rendererRegion).fabric_acceptRenderDataMap(map);
}
}
@Unique
private static Long2ObjectOpenHashMap<Object> mapChunk(class_2818 chunk, class_4076 chunkSectionPos, Long2ObjectOpenHashMap<Object> map) {
if (chunk.method_12214().isEmpty()) {
return map;
} else {
int xMin = class_4076.method_18688(chunkSectionPos.method_18674() - 1);
int yMin = class_4076.method_18688(chunkSectionPos.method_18683() - 1);
int zMin = class_4076.method_18688(chunkSectionPos.method_18687() - 1);
int xMax = class_4076.method_18688(chunkSectionPos.method_18674() + 1);
int yMax = class_4076.method_18688(chunkSectionPos.method_18683() + 1);
int zMax = class_4076.method_18688(chunkSectionPos.method_18687() + 1);
for(Map.Entry<class_2338, class_2586> entry : chunk.method_12214().entrySet()) {
class_2338 pos = (class_2338)entry.getKey();
if (pos.method_10263() >= xMin && pos.method_10263() <= xMax && pos.method_10264() >= yMin && pos.method_10264() <= yMax && pos.method_10260() >= zMin && pos.method_10260() <= zMax) {
Object data = ((class_2586)entry.getValue()).getRenderData();
if (data != null) {
if (map == null) {
map = new Long2ObjectOpenHashMap();
}
map.put(pos.method_10063(), data);
}
}
}
return map;
}
}
}
Download file