From c79c41c16ffc9faf30ceb99bf7839371d74be85f Mon Sep 17 00:00:00 2001 From: Jozsef Date: Fri, 2 Jul 2021 13:12:33 -0700 Subject: [PATCH] Crash fix and refactor - Check that sectionY is within the bounds of the chunk's section array, fixes #2 - Refactor usages of Tile and Entity InstanceManagers to refer to the base class InstanceManager<> --- build.gradle | 1 + .../instancing/InstancedRenderDispatcher.java | 12 ++++++------ .../flywheel/mixin/TileWorldHookMixin.java | 3 ++- .../flywheel/mixin/light/LightUpdateMixin.java | 16 ++++++++++++---- .../mixin/light/NetworkLightUpdateMixin.java | 10 ++++++++-- .../com/jozufozu/flywheel/util/ChunkUtil.java | 18 ++++++++++++++++++ 6 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/util/ChunkUtil.java diff --git a/build.gradle b/build.gradle index 5d6daea06..5a9e3670f 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,7 @@ minecraft { property 'forge.logging.markers', '' property 'forge.logging.console.level', 'debug' + property 'fml.earlyprogresswindow', 'false' arg "-mixin.config=flywheel.mixins.json" diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index e39363f04..883fbd228 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -50,8 +50,8 @@ import net.minecraftforge.fml.common.Mod; @Mod.EventBusSubscriber(Dist.CLIENT) public class InstancedRenderDispatcher { - private static final WorldAttached entityInstanceManager = new WorldAttached<>(world -> new EntityInstanceManager(Contexts.WORLD.getMaterialManager(world))); - private static final WorldAttached tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(Contexts.WORLD.getMaterialManager(world))); + private static final WorldAttached> entityInstanceManager = new WorldAttached<>(world -> new EntityInstanceManager(Contexts.WORLD.getMaterialManager(world))); + private static final WorldAttached> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(Contexts.WORLD.getMaterialManager(world))); private static final LazyValue> blockBreaking = new LazyValue<>(() -> { Vector renderers = new Vector<>(10); @@ -62,12 +62,12 @@ public class InstancedRenderDispatcher { }); @Nonnull - public static TileInstanceManager getTiles(IWorld world) { + public static InstanceManager getTiles(IWorld world) { return tileInstanceManager.get(world); } @Nonnull - public static EntityInstanceManager getEntities(IWorld world) { + public static InstanceManager getEntities(IWorld world) { return entityInstanceManager.get(world); } @@ -190,10 +190,10 @@ public class InstancedRenderDispatcher { Contexts.WORLD.getMaterialManager(world) .delete(); - TileInstanceManager tiles = tileInstanceManager.replace(world); + InstanceManager tiles = tileInstanceManager.replace(world); world.loadedTileEntityList.forEach(tiles::add); - EntityInstanceManager entities = entityInstanceManager.replace(world); + InstanceManager entities = entityInstanceManager.replace(world); world.getAllEntities() .forEach(entities::add); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/TileWorldHookMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/TileWorldHookMixin.java index 790485990..33b86d182 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/TileWorldHookMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/TileWorldHookMixin.java @@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; @@ -46,7 +47,7 @@ public class TileWorldHookMixin { @Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities") private void onChunkUnload(CallbackInfo ci) { if (isRemote) { - TileInstanceManager kineticRenderer = InstancedRenderDispatcher.getTiles(self); + InstanceManager kineticRenderer = InstancedRenderDispatcher.getTiles(self); for (TileEntity tile : tileEntitiesToBeRemoved) { kineticRenderer.remove(tile); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java index 19eaa061a..8168e7d46 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java @@ -7,11 +7,17 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager; +import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; import com.jozufozu.flywheel.light.LightUpdater; +import com.jozufozu.flywheel.util.ChunkUtil; import net.minecraft.client.multiplayer.ClientChunkProvider; import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.SectionPos; import net.minecraft.world.LightType; import net.minecraft.world.chunk.AbstractChunkProvider; @@ -38,17 +44,19 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider { int sectionY = pos.getSectionY(); - if (chunk != null) { + if (ChunkUtil.isValidSection(chunk, sectionY)) { + InstanceManager tiles = InstancedRenderDispatcher.getTiles(world); + InstanceManager entities = InstancedRenderDispatcher.getEntities(world); + chunk.getTileEntityMap() .entrySet() .stream() .filter(entry -> SectionPos.toChunk(entry.getKey() .getY()) == sectionY) .map(Map.Entry::getValue) - .forEach(InstancedRenderDispatcher.getTiles(world)::onLightUpdate); + .forEach(tiles::onLightUpdate); - if (sectionY >= 0) // TODO: 1.17 - chunk.getEntityLists()[sectionY].forEach(InstancedRenderDispatcher.getEntities(world)::onLightUpdate); + chunk.getEntityLists()[sectionY].forEach(entities::onLightUpdate); } LightUpdater.getInstance() diff --git a/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java index b2ebc20e6..a026e4698 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java @@ -8,13 +8,16 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.jozufozu.flywheel.backend.RenderWork; +import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.light.LightUpdater; import net.minecraft.client.Minecraft; import net.minecraft.client.network.play.ClientPlayNetHandler; import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; import net.minecraft.network.play.server.SUpdateLightPacket; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ClassInheritanceMultiMap; import net.minecraft.world.chunk.Chunk; @@ -35,13 +38,16 @@ public class NetworkLightUpdateMixin { .getChunk(chunkX, chunkZ, false); if (chunk != null) { + InstanceManager tiles = InstancedRenderDispatcher.getTiles(world); + InstanceManager entities = InstancedRenderDispatcher.getEntities(world); + chunk.getTileEntityMap() .values() - .forEach(InstancedRenderDispatcher.getTiles(world)::onLightUpdate); + .forEach(tiles::onLightUpdate); Arrays.stream(chunk.getEntityLists()) .flatMap(ClassInheritanceMultiMap::stream) - .forEach(InstancedRenderDispatcher.getEntities(world)::onLightUpdate); + .forEach(entities::onLightUpdate); } LightUpdater.getInstance() diff --git a/src/main/java/com/jozufozu/flywheel/util/ChunkUtil.java b/src/main/java/com/jozufozu/flywheel/util/ChunkUtil.java new file mode 100644 index 000000000..2adea96e6 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/util/ChunkUtil.java @@ -0,0 +1,18 @@ +package com.jozufozu.flywheel.util; + +import javax.annotation.Nullable; + +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkSection; + +public class ChunkUtil { + + public static boolean isValidSection(@Nullable Chunk chunk, int sectionY) { + if (chunk == null) return false; + + // TODO: 1.17 + ChunkSection[] sections = chunk.getSections(); + + return sectionY >= 0 && sectionY < sections.length; + } +}