]> git.lizzy.rs Git - LightOverlay.git/commitdiff
2.8.0 Cubic Chunk calculation, using glList during caching
authorshedaniel <daniel@shedaniel.me>
Tue, 16 Feb 2021 08:59:41 +0000 (16:59 +0800)
committershedaniel <daniel@shedaniel.me>
Wed, 17 Feb 2021 13:17:08 +0000 (21:17 +0800)
Signed-off-by: shedaniel <daniel@shedaniel.me>
common/src/main/java/me/shedaniel/lightoverlay/common/ChunkData.java [new file with mode: 0644]
common/src/main/java/me/shedaniel/lightoverlay/common/ClothScreen.java
common/src/main/java/me/shedaniel/lightoverlay/common/CubicChunkPos.java [new file with mode: 0644]
common/src/main/java/me/shedaniel/lightoverlay/common/LightOverlay.java
common/src/main/resources/assets/lightoverlay/lang/en_us.json
fabric/build.gradle
fabric/src/main/java/me/shedaniel/lightoverlay/fabric/mixin/MixinClientConnection.java
forge/build.gradle
forge/src/main/java/me/shedaniel/lightoverlay/forge/mixin/MixinClientConnection.java
gradle.properties

diff --git a/common/src/main/java/me/shedaniel/lightoverlay/common/ChunkData.java b/common/src/main/java/me/shedaniel/lightoverlay/common/ChunkData.java
new file mode 100644 (file)
index 0000000..e4278a1
--- /dev/null
@@ -0,0 +1,131 @@
+package me.shedaniel.lightoverlay.common;
+
+import it.unimi.dsi.fastutil.longs.Long2ByteMap;
+import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.phys.shapes.CollisionContext;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import org.lwjgl.opengl.GL11;
+
+import java.io.Closeable;
+
+import static me.shedaniel.lightoverlay.common.LightOverlay.*;
+
+public class ChunkData implements Closeable {
+    private static final IllegalStateException WRONG_TYPE = new IllegalStateException("Wrong type accessed!");
+    private Long2ByteMap data;
+    private int glListIndex = 0;
+    private boolean generatedList = false;
+    
+    public ChunkData() {
+        this(new Long2ByteOpenHashMap());
+    }
+    
+    public ChunkData(Long2ByteMap data) {
+        this.data = data;
+    }
+    
+    public Long2ByteMap data() {
+        return data;
+    }
+    
+    private void compileList(Level level, CollisionContext collisionContext) {
+        generatedList = true;
+        
+        if (data().isEmpty()) {
+            glListIndex = 0;
+            return;
+        }
+        
+        glListIndex = GL11.glGenLists(3);
+        GL11.glNewList(glListIndex, GL11.GL_COMPILE);
+        GL11.glBegin(GL11.GL_LINES);
+        color(redColor);
+        
+        BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
+        for (Long2ByteMap.Entry objectEntry : data().long2ByteEntrySet()) {
+            byte crossType = objectEntry.getByteValue();
+            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+            if (crossType == CROSS_RED) {
+                renderCross(level, mutable, collisionContext);
+            }
+        }
+        
+        GL11.glEnd();
+        GL11.glEndList();
+        
+        GL11.glNewList(glListIndex + 1, GL11.GL_COMPILE);
+        GL11.glBegin(GL11.GL_LINES);
+        color(yellowColor);
+        
+        for (Long2ByteMap.Entry objectEntry : data().long2ByteEntrySet()) {
+            byte crossType = objectEntry.getByteValue();
+            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+            if (crossType == CROSS_YELLOW) {
+                renderCross(level, mutable, collisionContext);
+            }
+        }
+        
+        GL11.glEnd();
+        GL11.glEndList();
+        
+        GL11.glNewList(glListIndex + 2, GL11.GL_COMPILE);
+        GL11.glBegin(GL11.GL_LINES);
+        color(secondaryColor);
+        
+        for (Long2ByteMap.Entry objectEntry : data().long2ByteEntrySet()) {
+            byte crossType = objectEntry.getByteValue();
+            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+            if (crossType == CROSS_SECONDARY) {
+                renderCross(level, mutable, collisionContext);
+            }
+        }
+        
+        GL11.glEnd();
+        GL11.glEndList();
+    }
+    
+    public void renderList(Level level, CollisionContext collisionContext) {
+        if (!generatedList) {
+            compileList(level, collisionContext);
+        }
+        
+        if (glListIndex != 0) {
+            GL11.glCallList(glListIndex);
+            GL11.glCallList(glListIndex + 1);
+            GL11.glCallList(glListIndex + 2);
+        }
+    }
+    
+    private static void color(int color) {
+        int red = (color >> 16) & 255;
+        int green = (color >> 8) & 255;
+        int blue = color & 255;
+        GL11.glColor4f(red / 255f, green / 255f, blue / 255f, 1f);
+    }
+    
+    public static void renderCross(Level level, BlockPos pos, CollisionContext collisionContext) {
+        double blockOffset = 0;
+        VoxelShape upperOutlineShape = level.getBlockState(pos).getShape(level, pos, collisionContext);
+        if (!upperOutlineShape.isEmpty())
+            blockOffset += upperOutlineShape.max(Direction.Axis.Y);
+        
+        
+        int x = pos.getX();
+        int y = pos.getY();
+        int z = pos.getZ();
+        GL11.glVertex3d(x + .01, y + blockOffset, z + .01);
+        GL11.glVertex3d(x - .01 + 1, y + blockOffset, z - .01 + 1);
+        GL11.glVertex3d(x - .01 + 1, y + blockOffset, z + .01);
+        GL11.glVertex3d(x + .01, y + blockOffset, z - .01 + 1);
+    }
+    
+    @Override
+    public void close() {
+        if (glListIndex != 0) {
+            GL11.glDeleteLists(glListIndex, 3);
+        }
+    }
+}
index 71753438c159b4e71689ef2ecaffb8002ae0539a..1a71dca31bdcf67eec44d139897a18d5aa0d7400 100644 (file)
@@ -34,6 +34,7 @@ public class ClothScreen {
         general.addEntry(eb.startBooleanToggle(new TranslatableComponent("config.lightoverlay.smoothLines"), LightOverlay.smoothLines).setDefaultValue(true).setSaveConsumer(bool -> LightOverlay.smoothLines = bool).build());
         general.addEntry(eb.startBooleanToggle(new TranslatableComponent("config.lightoverlay.underwater"), LightOverlay.underwater).setDefaultValue(false).setSaveConsumer(bool -> LightOverlay.underwater = bool).build());
         general.addEntry(eb.startBooleanToggle(new TranslatableComponent("config.lightoverlay.mushroom"), LightOverlay.mushroom).setDefaultValue(false).setSaveConsumer(bool -> LightOverlay.mushroom = bool).build());
+        general.addEntry(eb.startBooleanToggle(new TranslatableComponent("config.lightoverlay.useListWhileCaching"), LightOverlay.useListWhileCaching).setDefaultValue(true).setSaveConsumer(bool -> LightOverlay.useListWhileCaching = bool).build());
         general.addEntry(eb.startIntSlider(new TranslatableComponent("config.lightoverlay.lineWidth"), Mth.floor(LightOverlay.lineWidth * 100), 100, 700).setDefaultValue(100).setTextGetter(integer -> new TextComponent("Light Width: " + LightOverlay.FORMAT.format(integer / 100d))).setSaveConsumer(integer -> LightOverlay.lineWidth = integer / 100f).build());
         general.addEntry(eb.startColorField(new TranslatableComponent("config.lightoverlay.yellowColor"), LightOverlay.yellowColor).setDefaultValue(0xFFFF00).setSaveConsumer(color -> LightOverlay.yellowColor = color).build());
         general.addEntry(eb.startColorField(new TranslatableComponent("config.lightoverlay.redColor"), LightOverlay.redColor).setDefaultValue(0xFF0000).setSaveConsumer(color -> LightOverlay.redColor = color).build());
diff --git a/common/src/main/java/me/shedaniel/lightoverlay/common/CubicChunkPos.java b/common/src/main/java/me/shedaniel/lightoverlay/common/CubicChunkPos.java
new file mode 100644 (file)
index 0000000..576724e
--- /dev/null
@@ -0,0 +1,87 @@
+package me.shedaniel.lightoverlay.common;
+
+import net.minecraft.core.BlockPos;
+
+import java.util.Objects;
+
+public class CubicChunkPos {
+    public final int x;
+    public final int y;
+    public final int z;
+    
+    public CubicChunkPos(int x, int y, int z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+    
+    public CubicChunkPos(long l) {
+        this.x = getX(l);
+        this.y = getY(l);
+        this.z = getZ(l);
+    }
+    
+    public CubicChunkPos(BlockPos blockPos) {
+        this.x = blockPos.getX() >> 4;
+        this.y = blockPos.getY() >> 4;
+        this.z = blockPos.getZ() >> 4;
+    }
+    
+    public long toLong() {
+        return asLong(this.x, this.y, this.z);
+    }
+    
+    // Allocate 24 bits to x, 12 bits to y, 24 bits to z
+    public static long asLong(int x, int y, int z) {
+        return ((x & 0xffffffL) << 36) | ((y & 0xfffL) << 24) | (z & 0xffffffL);
+    }
+    
+    public static int getX(long l) {
+        return (int) (l >> 36 & 0xffffffL);
+    }
+    
+    public static int getY(long l) {
+        return (int) (l >> 24 & 0xfffL);
+    }
+    
+    public static int getZ(long l) {
+        return (int) (l & 0xffffffL);
+    }
+    
+    public int getMinBlockX() {
+        return this.x << 4;
+    }
+    
+    public int getMinBlockY() {
+        return this.y << 4;
+    }
+    
+    public int getMinBlockZ() {
+        return this.z << 4;
+    }
+    
+    public int getMaxBlockX() {
+        return (this.x << 4) + 15;
+    }
+    
+    public int getMaxBlockY() {
+        return (this.y << 4) + 15;
+    }
+    
+    public int getMaxBlockZ() {
+        return (this.z << 4) + 15;
+    }
+    
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        CubicChunkPos that = (CubicChunkPos) o;
+        return x == that.x && y == that.y && z == that.z;
+    }
+    
+    @Override
+    public int hashCode() {
+        return Objects.hash(x, y, z);
+    }
+}
index 28ee75d37f1d08f8d7aed480d22008e40e1c25ab..d3eb13195f6b5f13022ea6b840d480482383eef8 100644 (file)
@@ -6,8 +6,7 @@ import com.mojang.blaze3d.platform.InputConstants;
 import com.mojang.blaze3d.systems.RenderSystem;
 import com.mojang.blaze3d.vertex.Tesselator;
 import com.mojang.math.Transformation;
-import it.unimi.dsi.fastutil.longs.Long2ReferenceMap;
-import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
+import it.unimi.dsi.fastutil.longs.Long2ByteMap;
 import me.shedaniel.architectury.event.events.GuiEvent;
 import me.shedaniel.architectury.event.events.client.ClientTickEvent;
 import me.shedaniel.architectury.platform.Platform;
@@ -30,7 +29,6 @@ import net.minecraft.world.entity.Entity;
 import net.minecraft.world.entity.EntityType;
 import net.minecraft.world.entity.MobCategory;
 import net.minecraft.world.level.BlockGetter;
-import net.minecraft.world.level.ChunkPos;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.LightLayer;
 import net.minecraft.world.level.biome.Biome;
@@ -70,10 +68,11 @@ public class LightOverlay {
     public static boolean smoothLines = true;
     public static boolean underwater = false;
     public static boolean mushroom = false;
+    public static boolean useListWhileCaching = true;
     public static float lineWidth = 1.0F;
     public static int yellowColor = 0xFFFF00, redColor = 0xFF0000, secondaryColor = 0x0000FF;
     public static File configFile;
-
+    
     private static KeyMapping enableOverlay;
     private static boolean enabled = false;
     private static final LazyLoadedValue<EntityType<Entity>> TESTING_ENTITY_TYPE = new LazyLoadedValue<>(() ->
@@ -85,9 +84,9 @@ public class LightOverlay {
         thread.setDaemon(true);
         return thread;
     });
-    private static final Set<ChunkPos> POS = Collections.synchronizedSet(new HashSet<>());
-    private static final Set<ChunkPos> CALCULATING_POS = Collections.synchronizedSet(new HashSet<>());
-    private static final Map<ChunkPos, Long2ReferenceMap<Object>> CHUNK_MAP = Maps.newConcurrentMap();
+    private static final Set<CubicChunkPos> POS = Collections.synchronizedSet(new HashSet<>());
+    private static final Set<CubicChunkPos> CALCULATING_POS = Collections.synchronizedSet(new HashSet<>());
+    private static final Map<CubicChunkPos, ChunkData> CHUNK_MAP = Maps.newConcurrentMap();
     private static final Minecraft CLIENT = Minecraft.getInstance();
     private static long ticks = 0;
     
@@ -114,56 +113,67 @@ public class LightOverlay {
                     RenderSystem.depthMask(true);
                     BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
                     BlockPos.MutableBlockPos downMutable = new BlockPos.MutableBlockPos();
-                    for (Map.Entry<ChunkPos, Long2ReferenceMap<Object>> entry : CHUNK_MAP.entrySet()) {
+                    for (Map.Entry<CubicChunkPos, ChunkData> entry : CHUNK_MAP.entrySet()) {
                         if (caching && (Mth.abs(entry.getKey().x - playerPosX) > getChunkRange() || Mth.abs(entry.getKey().z - playerPosZ) > getChunkRange())) {
                             continue;
                         }
-                        for (Long2ReferenceMap.Entry<Object> objectEntry : entry.getValue().long2ReferenceEntrySet()) {
-                            if (objectEntry.getValue() instanceof Byte) {
-                                mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
-                                if (mutable.closerThan(playerPos, reach)) {
-                                    if (frustum == null || isFrustumVisible(frustum, mutable.getX(), mutable.getY(), mutable.getZ(), mutable.getX() + 1, mutable.getX() + 1, mutable.getX() + 1)) {
-                                        downMutable.set(mutable.getX(), mutable.getY() - 1, mutable.getZ());
-                                        renderLevel(CLIENT, camera, world, mutable, downMutable, (Byte) objectEntry.getValue(), collisionContext);
-                                    }
+                        for (Long2ByteMap.Entry objectEntry : entry.getValue().data().long2ByteEntrySet()) {
+                            mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
+                            if (mutable.closerThan(playerPos, reach)) {
+                                if (frustum == null || isFrustumVisible(frustum, mutable.getX(), mutable.getY(), mutable.getZ(), mutable.getX() + 1, mutable.getX() + 1, mutable.getX() + 1)) {
+                                    downMutable.set(mutable.getX(), mutable.getY() - 1, mutable.getZ());
+                                    renderLevel(CLIENT, camera, world, mutable, downMutable, objectEntry.getByteValue(), collisionContext);
                                 }
                             }
                         }
                     }
                     RenderSystem.enableDepthTest();
                 } else {
+                    boolean useList = useListWhileCaching && caching;
                     RenderSystem.enableDepthTest();
                     RenderSystem.disableTexture();
                     RenderSystem.enableBlend();
+                    RenderSystem.enableCull();
                     RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
                     if (smoothLines) GL11.glEnable(GL11.GL_LINE_SMOOTH);
                     GL11.glLineWidth(lineWidth);
-                    GL11.glBegin(GL11.GL_LINES);
+                    if (!useList) GL11.glBegin(GL11.GL_LINES);
+                    
                     BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
-                    for (Map.Entry<ChunkPos, Long2ReferenceMap<Object>> entry : CHUNK_MAP.entrySet()) {
-                        if (caching && (Mth.abs(entry.getKey().x - playerPosX) > getChunkRange() || Mth.abs(entry.getKey().z - playerPosZ) > getChunkRange())) {
+                    
+                    if (useList) GL11.glTranslated(-camera.getPosition().x, -camera.getPosition().y + .01D, -camera.getPosition().z);
+                    for (Map.Entry<CubicChunkPos, ChunkData> entry : CHUNK_MAP.entrySet()) {
+                        CubicChunkPos chunkPos = entry.getKey();
+                        if (caching && (Mth.abs(chunkPos.x - playerPosX) > getChunkRange() || Mth.abs(chunkPos.z - playerPosZ) > getChunkRange())) {
                             continue;
                         }
-                        for (Long2ReferenceMap.Entry<Object> objectEntry : entry.getValue().long2ReferenceEntrySet()) {
-                            if (objectEntry.getValue() instanceof CrossType) {
+                        
+                        if (useList) {
+                            if (frustum == null || isFrustumVisible(frustum, chunkPos.getMinBlockX(), chunkPos.getMinBlockY(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), chunkPos.getMaxBlockY(), chunkPos.getMaxBlockZ())) {
+                                entry.getValue().renderList(world, collisionContext);
+                            }
+                        } else {
+                            for (Long2ByteMap.Entry objectEntry : entry.getValue().data().long2ByteEntrySet()) {
+                                byte crossType = objectEntry.getByteValue();
                                 mutable.set(BlockPos.getX(objectEntry.getLongKey()), BlockPos.getY(objectEntry.getLongKey()), BlockPos.getZ(objectEntry.getLongKey()));
                                 if (mutable.closerThan(playerPos, reach)) {
                                     if (frustum == null || isFrustumVisible(frustum, mutable.getX(), mutable.getY(), mutable.getZ(), mutable.getX() + 1, mutable.getX() + 1, mutable.getX() + 1)) {
-                                        int color = objectEntry.getValue() == CrossType.RED ? redColor : objectEntry.getValue() == CrossType.YELLOW ? yellowColor : secondaryColor;
+                                        int color = crossType == CROSS_RED ? redColor : crossType == CROSS_YELLOW ? yellowColor : secondaryColor;
                                         renderCross(camera, world, mutable, color, collisionContext);
                                     }
                                 }
                             }
                         }
                     }
-                    GL11.glEnd();
+                    
+                    if (!useList) GL11.glEnd();
                     RenderSystem.disableBlend();
                     RenderSystem.enableTexture();
                     if (smoothLines) GL11.glDisable(GL11.GL_LINE_SMOOTH);
                 }
             }
         });
-    
+        
         GuiEvent.DEBUG_TEXT_LEFT.register(list -> {
             if (enabled) {
                 if (caching) {
@@ -171,16 +181,16 @@ public class LightOverlay {
                 } else {
                     list.add("[Light Overlay] Enabled");
                 }
-            }else {
+            } else {
                 list.add("[Light Overlay] Disabled");
             }
         });
         ClientTickEvent.CLIENT_POST.register(LightOverlay::tick);
     }
     
-    private static void processChunk(ChunkPos pos, int playerPosX, int playerPosZ, CollisionContext context) {
+    private static void processChunk(CubicChunkPos pos, int playerPosX, int playerPosY, int playerPosZ, CollisionContext context) {
         CALCULATING_POS.remove(pos);
-        if (Mth.abs(pos.x - playerPosX) > getChunkRange() || Mth.abs(pos.z - playerPosZ) > getChunkRange() || POS.contains(pos)) {
+        if (Mth.abs(pos.x - playerPosX) > getChunkRange() || Mth.abs(pos.y - playerPosY) > getChunkRange() || Mth.abs(pos.z - playerPosZ) > getChunkRange() || POS.contains(pos)) {
             return;
         }
         try {
@@ -190,15 +200,17 @@ public class LightOverlay {
         }
     }
     
-    public static void queueChunkAndNear(ChunkPos pos) {
+    public static void queueChunkAndNear(CubicChunkPos pos) {
         for (int xOffset = -1; xOffset <= 1; xOffset++) {
-            for (int zOffset = -1; zOffset <= 1; zOffset++) {
-                queueChunk(new ChunkPos(pos.x + xOffset, pos.z + zOffset));
+            for (int yOffset = -1; yOffset <= 1; yOffset++) {
+                for (int zOffset = -1; zOffset <= 1; zOffset++) {
+                    queueChunk(new CubicChunkPos(pos.x + xOffset, pos.y + yOffset, pos.z + zOffset));
+                }
             }
         }
     }
     
-    public static void queueChunk(ChunkPos pos) {
+    public static void queueChunk(CubicChunkPos pos) {
         if (enabled && caching && !CALCULATING_POS.contains(pos)) {
             POS.add(pos);
         }
@@ -208,61 +220,65 @@ public class LightOverlay {
         return Math.max(Mth.ceil(reach / 16f), 1);
     }
     
-    private static void calculateChunk(LevelChunk chunk, Level world, ChunkPos chunkPos, CollisionContext entityContext) {
+    private static void calculateChunk(LevelChunk chunk, Level world, CubicChunkPos chunkPos, CollisionContext collisionContext) {
         if (world != null && chunk != null) {
-            Long2ReferenceMap<Object> map = new Long2ReferenceOpenHashMap<>();
+            ChunkData chunkData = new ChunkData();
             LayerLightEventListener block = world.getLightEngine().getLayerListener(LightLayer.BLOCK);
             LayerLightEventListener sky = showNumber ? null : world.getLightEngine().getLayerListener(LightLayer.SKY);
-            for (BlockPos pos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), 0, chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), 256, chunkPos.getMaxBlockZ())) {
+            for (BlockPos pos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), chunkPos.getMinBlockY(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), chunkPos.getMaxBlockY(), chunkPos.getMaxBlockZ())) {
                 BlockPos down = pos.below();
                 if (showNumber) {
-                    int level = getCrossLevel(pos, down, chunk, block, entityContext);
+                    int level = getCrossLevel(pos, down, chunk, block, collisionContext);
                     if (level >= 0) {
-                        map.put(pos.asLong(), Byte.valueOf((byte) level));
+                        chunkData.data().put(pos.asLong(), (byte) level);
                     }
                 } else {
-                    Biome biome = mushroom ? world.getBiome(pos) : null;
-                    CrossType type = getCrossType(pos, biome,down, chunk, block, sky, entityContext);
-                    if (type != CrossType.NONE) {
-                        map.put(pos.asLong(), type);
+                    Biome biome = !mushroom ? world.getBiome(pos) : null;
+                    byte type = getCrossType(pos, biome, down, chunk, block, sky, collisionContext);
+                    if (type != CROSS_NONE) {
+                        chunkData.data().put(pos.asLong(), type);
                     }
                 }
             }
-            CHUNK_MAP.put(chunkPos, map);
+            CHUNK_MAP.put(chunkPos, chunkData);
         } else {
-            CHUNK_MAP.remove(chunkPos);
+            ChunkData data = CHUNK_MAP.remove(chunkPos);
+            
+            if (data != null) {
+                data.close();
+            }
         }
     }
     
-    public static CrossType getCrossType(BlockPos pos, Biome biome, BlockPos down, BlockGetter world, LayerLightEventListener block, LayerLightEventListener sky, CollisionContext entityContext) {
+    public static byte getCrossType(BlockPos pos, Biome biome, BlockPos down, BlockGetter world, LayerLightEventListener block, LayerLightEventListener sky, CollisionContext entityContext) {
         BlockState blockBelowState = world.getBlockState(down);
         BlockState blockUpperState = world.getBlockState(pos);
         VoxelShape upperCollisionShape = blockUpperState.getCollisionShape(world, pos, entityContext);
         if (!underwater && !blockUpperState.getFluidState().isEmpty())
-            return CrossType.NONE;
+            return CROSS_NONE;
         // Check if the outline is full
         if (Block.isFaceFull(upperCollisionShape, Direction.UP))
-            return CrossType.NONE;
+            return CROSS_NONE;
         // TODO: Not to hard code no redstone
         if (blockUpperState.isSignalSource())
-            return CrossType.NONE;
+            return CROSS_NONE;
         // Check if the collision has a bump
         if (upperCollisionShape.max(Direction.Axis.Y) > 0)
-            return CrossType.NONE;
+            return CROSS_NONE;
         if (blockUpperState.getBlock().is(BlockTags.RAILS))
-            return CrossType.NONE;
+            return CROSS_NONE;
         // Check block state allow spawning (excludes bedrock and barriers automatically)
         if (!blockBelowState.isValidSpawn(world, down, TESTING_ENTITY_TYPE.get()))
-            return CrossType.NONE;
+            return CROSS_NONE;
         if (!mushroom && Biome.BiomeCategory.MUSHROOM == biome.getBiomeCategory())
-            return CrossType.NONE;
+            return CROSS_NONE;
         int blockLightLevel = block.getLightValue(pos);
         int skyLightLevel = sky.getLightValue(pos);
         if (blockLightLevel > higherCrossLevel)
-            return CrossType.NONE;
+            return CROSS_NONE;
         if (skyLightLevel > higherCrossLevel)
-            return CrossType.YELLOW;
-        return lowerCrossLevel >= 0 && blockLightLevel > lowerCrossLevel ? CrossType.SECONDARY : CrossType.RED;
+            return CROSS_YELLOW;
+        return lowerCrossLevel >= 0 && blockLightLevel > lowerCrossLevel ? CROSS_SECONDARY : CROSS_RED;
     }
     
     public static int getCrossLevel(BlockPos pos, BlockPos down, BlockGetter world, LayerLightEventListener view, CollisionContext collisionContext) {
@@ -282,12 +298,13 @@ public class LightOverlay {
     }
     
     public static void renderCross(Camera camera, Level world, BlockPos pos, int color, CollisionContext collisionContext) {
-        double d0 = camera.getPosition().x;
-        double d1 = camera.getPosition().y - .005D;
+        double cameraX = camera.getPosition().x;
+        double cameraY = camera.getPosition().y - .005D;
+        double blockOffset = 0;
         VoxelShape upperOutlineShape = world.getBlockState(pos).getShape(world, pos, collisionContext);
         if (!upperOutlineShape.isEmpty())
-            d1 -= upperOutlineShape.max(Direction.Axis.Y);
-        double d2 = camera.getPosition().z;
+            blockOffset += upperOutlineShape.max(Direction.Axis.Y);
+        double cameraZ = camera.getPosition().z;
         
         int red = (color >> 16) & 255;
         int green = (color >> 8) & 255;
@@ -296,33 +313,33 @@ public class LightOverlay {
         int y = pos.getY();
         int z = pos.getZ();
         RenderSystem.color4f(red / 255f, green / 255f, blue / 255f, 1f);
-        GL11.glVertex3d(x + .01 - d0, y - d1, z + .01 - d2);
-        GL11.glVertex3d(x - .01 + 1 - d0, y - d1, z - .01 + 1 - d2);
-        GL11.glVertex3d(x - .01 + 1 - d0, y - d1, z + .01 - d2);
-        GL11.glVertex3d(x + .01 - d0, y - d1, z - .01 + 1 - d2);
+        GL11.glVertex3d(x + .01 - cameraX, y - cameraY + blockOffset, z + .01 - cameraZ);
+        GL11.glVertex3d(x - .01 + 1 - cameraX, y - cameraY + blockOffset, z - .01 + 1 - cameraZ);
+        GL11.glVertex3d(x - .01 + 1 - cameraX, y - cameraY + blockOffset, z + .01 - cameraZ);
+        GL11.glVertex3d(x + .01 - cameraX, y - cameraY + blockOffset, z - .01 + 1 - cameraZ);
     }
     
     @SuppressWarnings("deprecation")
-    public static void renderLevel(Minecraft client, Camera camera, Level world, BlockPos pos, BlockPos down, int level, CollisionContext collisionContext) {
+    public static void renderLevel(Minecraft client, Camera camera, Level world, BlockPos pos, BlockPos down, byte level, CollisionContext collisionContext) {
         String text = String.valueOf(level);
-        Font textRenderer_1 = client.font;
-        double double_4 = camera.getPosition().x;
-        double double_5 = camera.getPosition().y;
+        Font font = client.font;
+        double cameraX = camera.getPosition().x;
+        double cameraY = camera.getPosition().y;
         VoxelShape upperOutlineShape = world.getBlockState(down).getShape(world, down, collisionContext);
         if (!upperOutlineShape.isEmpty())
-            double_5 += 1 - upperOutlineShape.max(Direction.Axis.Y);
-        double double_6 = camera.getPosition().z;
+            cameraY += 1 - upperOutlineShape.max(Direction.Axis.Y);
+        double cameraZ = camera.getPosition().z;
         RenderSystem.pushMatrix();
-        RenderSystem.translatef((float) (pos.getX() + 0.5f - double_4), (float) (pos.getY() - double_5) + 0.005f, (float) (pos.getZ() + 0.5f - double_6));
+        RenderSystem.translatef((float) (pos.getX() + 0.5f - cameraX), (float) (pos.getY() - cameraY) + 0.005f, (float) (pos.getZ() + 0.5f - cameraZ));
         RenderSystem.rotatef(90, 1, 0, 0);
         RenderSystem.normal3f(0.0F, 1.0F, 0.0F);
         float size = 0.07F;
         RenderSystem.scalef(-size, -size, size);
-        float float_3 = (float) (-textRenderer_1.width(text)) / 2.0F + 0.4f;
+        float float_3 = (float) (-font.width(text)) / 2.0F + 0.4f;
         RenderSystem.enableAlphaTest();
-        MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
-        textRenderer_1.drawInBatch(text, float_3, -3.5f, level > higherCrossLevel ? 0xff042404 : (lowerCrossLevel >= 0 && level > lowerCrossLevel ? 0xff0066ff : 0xff731111), false, Transformation.identity().getMatrix(), immediate, false, 0, 15728880);
-        immediate.endBatch();
+        MultiBufferSource.BufferSource source = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
+        font.drawInBatch(text, float_3, -3.5f, level > higherCrossLevel ? 0xff042404 : (lowerCrossLevel >= 0 && level > lowerCrossLevel ? 0xff0066ff : 0xff731111), false, Transformation.identity().getMatrix(), source, false, 0, 15728880);
+        source.endBatch();
         RenderSystem.popMatrix();
     }
     
@@ -344,6 +361,8 @@ public class LightOverlay {
             showNumber = ((String) properties.computeIfAbsent("showNumber", a -> "false")).equalsIgnoreCase("true");
             smoothLines = ((String) properties.computeIfAbsent("smoothLines", a -> "true")).equalsIgnoreCase("true");
             underwater = ((String) properties.computeIfAbsent("underwater", a -> "false")).equalsIgnoreCase("true");
+            mushroom = ((String) properties.computeIfAbsent("mushroom", a -> "false")).equalsIgnoreCase("true");
+            useListWhileCaching = ((String) properties.computeIfAbsent("useListWhileCaching", a -> "true")).equalsIgnoreCase("true");
             lineWidth = Float.parseFloat((String) properties.computeIfAbsent("lineWidth", a -> "1"));
             {
                 int r, g, b;
@@ -380,6 +399,8 @@ public class LightOverlay {
             showNumber = false;
             smoothLines = true;
             underwater = false;
+            mushroom = false;
+            useListWhileCaching = true;
             try {
                 saveConfig(file);
             } catch (IOException ex) {
@@ -389,6 +410,9 @@ public class LightOverlay {
         if (secondaryLevel >= crossLevel) System.err.println("[Light Overlay] Secondary Level is higher than Cross Level");
         lowerCrossLevel = Math.min(crossLevel, secondaryLevel);
         higherCrossLevel = Math.max(crossLevel, secondaryLevel);
+        for (ChunkData data : CHUNK_MAP.values()) {
+            data.close();
+        }
         CHUNK_MAP.clear();
         POS.clear();
     }
@@ -411,6 +435,10 @@ public class LightOverlay {
         fos.write("\n".getBytes());
         fos.write(("underwater=" + underwater).getBytes());
         fos.write("\n".getBytes());
+        fos.write(("mushroom=" + mushroom).getBytes());
+        fos.write("\n".getBytes());
+        fos.write(("useListWhileCaching=" + useListWhileCaching).getBytes());
+        fos.write("\n".getBytes());
         fos.write(("lineWidth=" + FORMAT.format(lineWidth)).getBytes());
         fos.write("\n".getBytes());
         fos.write(("yellowColorRed=" + ((yellowColor >> 16) & 255)).getBytes());
@@ -465,22 +493,28 @@ public class LightOverlay {
     private static void tick(Minecraft minecraft) {
         while (enableOverlay.consumeClick())
             enabled = !enabled;
-    
+        
         try {
             ticks++;
             if (CLIENT.player == null || !enabled) {
                 POS.clear();
                 CALCULATING_POS.clear();
                 EXECUTOR.getQueue().clear();
+                for (ChunkData data : CHUNK_MAP.values()) {
+                    data.close();
+                }
                 CHUNK_MAP.clear();
             } else {
                 LocalPlayer player = CLIENT.player;
                 ClientLevel world = CLIENT.level;
                 CollisionContext collisionContext = CollisionContext.of(player);
-            
+                
                 if (!caching) {
                     CALCULATING_POS.clear();
                     POS.clear();
+                    for (ChunkData data : CHUNK_MAP.values()) {
+                        data.close();
+                    }
                     CHUNK_MAP.clear();
                     BlockPos playerPos = player.blockPosition();
                     LayerLightEventListener block = world.getLightEngine().getLayerListener(LightLayer.BLOCK);
@@ -488,50 +522,54 @@ public class LightOverlay {
                     BlockPos.MutableBlockPos downPos = new BlockPos.MutableBlockPos();
                     Iterable<BlockPos> iterate = BlockPos.betweenClosed(playerPos.getX() - reach, playerPos.getY() - reach, playerPos.getZ() - reach,
                             playerPos.getX() + reach, playerPos.getY() + reach, playerPos.getZ() + reach);
-                    Long2ReferenceMap<Object> map = new Long2ReferenceOpenHashMap<>();
-                    CHUNK_MAP.put(new ChunkPos(0, 0), map);
+                    ChunkData chunkData = new ChunkData();
+                    CHUNK_MAP.put(new CubicChunkPos(0, 0, 0), chunkData);
                     for (BlockPos blockPos : iterate) {
                         downPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ());
                         if (showNumber) {
                             int level = getCrossLevel(blockPos, downPos, world, block, collisionContext);
                             if (level >= 0) {
-                                map.put(blockPos.asLong(), Byte.valueOf((byte) level));
+                                chunkData.data().put(blockPos.asLong(), (byte) level);
                             }
                         } else {
-                            Biome biome = mushroom ? world.getBiome(blockPos) : null;
-                            CrossType type = getCrossType(blockPos, biome, downPos, world, block, sky, collisionContext);
-                            if (type != CrossType.NONE) {
-                                map.put(blockPos.asLong(), type);
+                            Biome biome = !mushroom ? world.getBiome(blockPos) : null;
+                            byte type = getCrossType(blockPos, biome, downPos, world, block, sky, collisionContext);
+                            if (type != CROSS_NONE) {
+                                chunkData.data().put(blockPos.asLong(), type);
                             }
                         }
                     }
                 } else {
                     int playerPosX = ((int) player.getX()) >> 4;
+                    int playerPosY = ((int) player.getY()) >> 4;
                     int playerPosZ = ((int) player.getZ()) >> 4;
                     for (int chunkX = playerPosX - getChunkRange(); chunkX <= playerPosX + getChunkRange(); chunkX++) {
-                        for (int chunkZ = playerPosZ - getChunkRange(); chunkZ <= playerPosZ + getChunkRange(); chunkZ++) {
-                            if (Mth.abs(chunkX - playerPosX) > getChunkRange() || Mth.abs(chunkZ - playerPosZ) > getChunkRange())
-                                continue;
-                            ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
-                            if (!CHUNK_MAP.containsKey(chunkPos))
-                                queueChunk(chunkPos);
+                        for (int chunkY = Math.max(playerPosY - getChunkRange(), 0); chunkY <= playerPosY + getChunkRange() && chunkY <= 15; chunkY++) {
+                            for (int chunkZ = playerPosZ - getChunkRange(); chunkZ <= playerPosZ + getChunkRange(); chunkZ++) {
+                                if (Mth.abs(chunkX - playerPosX) > getChunkRange() || Mth.abs(chunkY - playerPosY) > getChunkRange() || Mth.abs(chunkZ - playerPosZ) > getChunkRange())
+                                    continue;
+                                CubicChunkPos chunkPos = new CubicChunkPos(chunkX, chunkY, chunkZ);
+                                if (!CHUNK_MAP.containsKey(chunkPos))
+                                    queueChunk(chunkPos);
+                            }
                         }
                     }
                     for (int p = 0; p < 3; p++) {
                         if (EXECUTOR.getQueue().size() >= Runtime.getRuntime().availableProcessors()) break;
                         double d1 = Double.MAX_VALUE, d2 = Double.MAX_VALUE, d3 = Double.MAX_VALUE;
-                        ChunkPos c1 = null, c2 = null, c3 = null;
+                        CubicChunkPos c1 = null, c2 = null, c3 = null;
                         synchronized (POS) {
-                            Iterator<ChunkPos> iterator = POS.iterator();
+                            Iterator<CubicChunkPos> iterator = POS.iterator();
                             while (iterator.hasNext()) {
-                                ChunkPos pos = iterator.next();
-                                if (Mth.abs(pos.x - playerPosX) > getChunkRange() || Mth.abs(pos.z - playerPosZ) > getChunkRange() || CALCULATING_POS.contains(pos)) {
+                                CubicChunkPos pos = iterator.next();
+                                if (Mth.abs(pos.x - playerPosX) > getChunkRange() || Mth.abs(pos.y - playerPosY) > getChunkRange() || Mth.abs(pos.z - playerPosZ) > getChunkRange() || CALCULATING_POS.contains(pos)) {
                                     iterator.remove();
                                 } else {
-                                    if (isFrustumVisible(frustum, pos.getMinBlockX(), 0, pos.getMinBlockZ(), pos.getMaxBlockX(), 256, pos.getMaxBlockZ())) {
+                                    if (isFrustumVisible(frustum, pos.getMinBlockX(), pos.getMinBlockY(), pos.getMinBlockZ(), pos.getMaxBlockX(), pos.getMaxBlockY(), pos.getMaxBlockZ())) {
                                         int i = Math.abs(pos.x - playerPosX);
-                                        int j = Math.abs(pos.z - playerPosZ);
-                                        double distance = Math.sqrt(i * i + j * j);
+                                        int j = Math.abs(pos.y - playerPosY);
+                                        int k = Math.abs(pos.z - playerPosZ);
+                                        double distance = Math.sqrt(i * i + j * j + k * k);
                                         if (distance < d1) {
                                             d3 = d2;
                                             d2 = d1;
@@ -555,9 +593,9 @@ public class LightOverlay {
                                 }
                             }
                         }
-                        ChunkPos finalC1 = c1;
-                        ChunkPos finalC2 = c2;
-                        ChunkPos finalC3 = c3;
+                        CubicChunkPos finalC1 = c1;
+                        CubicChunkPos finalC2 = c2;
+                        CubicChunkPos finalC3 = c3;
                         if (finalC1 != null) {
                             CALCULATING_POS.add(finalC1);
                             if (finalC2 != null) {
@@ -568,15 +606,23 @@ public class LightOverlay {
                             }
                             EXECUTOR.submit(() -> {
                                 int playerPosX1 = ((int) CLIENT.player.getX()) >> 4;
+                                int playerPosY1 = ((int) CLIENT.player.getY()) >> 4;
                                 int playerPosZ1 = ((int) CLIENT.player.getZ()) >> 4;
-                                if (finalC1 != null) processChunk(finalC1, playerPosX1, playerPosZ1, collisionContext);
-                                if (finalC2 != null) processChunk(finalC2, playerPosX1, playerPosZ1, collisionContext);
-                                if (finalC3 != null) processChunk(finalC3, playerPosX1, playerPosZ1, collisionContext);
+                                if (finalC1 != null) processChunk(finalC1, playerPosX1, playerPosY1, playerPosZ1, collisionContext);
+                                if (finalC2 != null) processChunk(finalC2, playerPosX1, playerPosY1, playerPosZ1, collisionContext);
+                                if (finalC3 != null) processChunk(finalC3, playerPosX1, playerPosY1, playerPosZ1, collisionContext);
                             });
                         }
                     }
                     if (ticks % 50 == 0) {
-                        CHUNK_MAP.entrySet().removeIf(pos -> Mth.abs(pos.getKey().x - playerPosX) > getChunkRange() * 2 || Mth.abs(pos.getKey().z - playerPosZ) > getChunkRange() * 2);
+                        Iterator<Map.Entry<CubicChunkPos, ChunkData>> iterator = CHUNK_MAP.entrySet().iterator();
+                        while (iterator.hasNext()) {
+                            Map.Entry<CubicChunkPos, ChunkData> entry = iterator.next();
+                            if (Mth.abs(entry.getKey().x - playerPosX) > getChunkRange() * 2 || Mth.abs(entry.getKey().y - playerPosY) > getChunkRange() * 2 || Mth.abs(entry.getKey().z - playerPosZ) > getChunkRange() * 2) {
+                                entry.getValue().close();
+                                iterator.remove();
+                            }
+                        }
                     }
                 }
             }
@@ -585,10 +631,8 @@ public class LightOverlay {
         }
     }
     
-    private enum CrossType {
-        YELLOW,
-        RED,
-        SECONDARY,
-        NONE
-    }
+    public static final byte CROSS_YELLOW = 0;
+    public static final byte CROSS_RED = 1;
+    public static final byte CROSS_SECONDARY = 2;
+    public static final byte CROSS_NONE = 2;
 }
index 201186b05e551c2efa52875ef35447f5a95570f8..d07f5a6260e5660890dc8148d33cc4cad3c63653 100755 (executable)
@@ -15,5 +15,6 @@
   "config.lightoverlay.secondaryColor": "Secondary Color:",
   "config.lightoverlay.redColor": "Red Color:",
   "config.lightoverlay.invalidColor": "Invalid Color",
-  "config.lightoverlay.mushroom": "Display in Mushroom Biomes:"
+  "config.lightoverlay.mushroom": "Display in Mushroom Biomes:",
+  "config.lightoverlay.useListWhileCaching": "Use glList while caching:"
 }
\ No newline at end of file
index 4a3be61a2c6ba9c687f463f2c1120c49fb11ec4e..b8a902a25d5821ba4d06014b871fe02791db85c0 100755 (executable)
@@ -7,6 +7,7 @@ minecraft {
 }
 
 architectury {
+    transformerVersion = "2.0.9999"
     platformSetupLoomIde()
     fabric()
 }
@@ -22,6 +23,10 @@ configurations {
     shadow
 }
 
+repositories {
+    mavenLocal()
+}
+
 dependencies {
     minecraft "com.mojang:minecraft:${rootProject.architectury.minecraft}"
     mappings minecraft.officialMojangMappings()
index 5320e78ae4471d73073a289cf16e0a7202cd5594..ac553e6e78157b1917fbd353d243864bf4dac8d4 100644 (file)
@@ -1,5 +1,6 @@
 package me.shedaniel.lightoverlay.fabric.mixin;
 
+import me.shedaniel.lightoverlay.common.CubicChunkPos;
 import me.shedaniel.lightoverlay.common.LightOverlay;
 import net.minecraft.network.Connection;
 import net.minecraft.network.PacketListener;
@@ -8,7 +9,6 @@ import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
 import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
 import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
 import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket;
-import net.minecraft.world.level.ChunkPos;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Inject;
@@ -19,13 +19,19 @@ public class MixinClientConnection {
     @Inject(method = "genericsFtw", at = @At("HEAD"))
     private static void handlePacket(Packet packet, PacketListener listener, CallbackInfo ci) {
         if (packet instanceof ClientboundBlockUpdatePacket) {
-            LightOverlay.queueChunkAndNear(new ChunkPos(((ClientboundBlockUpdatePacket) packet).getPos()));
+            LightOverlay.queueChunkAndNear(new CubicChunkPos(((ClientboundBlockUpdatePacket) packet).getPos()));
         } else if (packet instanceof ClientboundSetChunkCacheCenterPacket) {
-            LightOverlay.queueChunkAndNear(new ChunkPos(((ClientboundSetChunkCacheCenterPacket) packet).getX(), ((ClientboundSetChunkCacheCenterPacket) packet).getZ()));
+            for (int y = 0; y <= 15; y++) {
+                LightOverlay.queueChunkAndNear(new CubicChunkPos(((ClientboundSetChunkCacheCenterPacket) packet).getX(), y, ((ClientboundSetChunkCacheCenterPacket) packet).getZ()));
+            }
         } else if (packet instanceof ClientboundSectionBlocksUpdatePacket) {
-            LightOverlay.queueChunkAndNear(new ChunkPos(((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getX(), ((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getZ()));
+            for (int y = 0; y <= 15; y++) {
+                LightOverlay.queueChunkAndNear(new CubicChunkPos(((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getX(), y, ((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getZ()));
+            }
         } else if (packet instanceof ClientboundLightUpdatePacket) {
-            LightOverlay.queueChunk(new ChunkPos(((ClientboundLightUpdatePacket) packet).getX(), ((ClientboundLightUpdatePacket) packet).getZ()));
+            for (int y = 0; y <= 15; y++) {
+                LightOverlay.queueChunk(new CubicChunkPos(((ClientboundLightUpdatePacket) packet).getX(), y, ((ClientboundLightUpdatePacket) packet).getZ()));
+            }
         }
     }
 }
index 36ed12af138add49c346af028769952f0b538bc5..95ece2e25052c79de9a263f62ac8dbeed1cb46c6 100644 (file)
@@ -7,6 +7,7 @@ configurations {
 }
 
 architectury {
+    transformerVersion = "2.0.9999"
     platformSetupLoomIde()
     forge()
 }
@@ -15,11 +16,6 @@ loom {
     mixinConfig "lightoverlay-forge.mixins.json"
 }
 
-repositories {
-    jcenter()
-    maven { url "https://dl.bintray.com/shedaniel/cloth-config-2" }
-}
-
 processResources {
     filesMatching("META-INF/mods.toml") {
         expand "version": project.version
@@ -27,6 +23,10 @@ processResources {
     inputs.property "META-INF/mods.toml", project.version
 }
 
+repositories {
+    mavenLocal()
+}
+
 dependencies {
     minecraft("com.mojang:minecraft:${rootProject.architectury.minecraft}")
     mappings(minecraft.officialMojangMappings())
index b6c82746e32d9f3fb09ec686d884ddd77d72dfb1..02f46debc4b81a21200f7446fbda208629220010 100644 (file)
@@ -1,5 +1,6 @@
 package me.shedaniel.lightoverlay.forge.mixin;
 
+import me.shedaniel.lightoverlay.common.CubicChunkPos;
 import me.shedaniel.lightoverlay.common.LightOverlay;
 import net.minecraft.network.Connection;
 import net.minecraft.network.PacketListener;
@@ -8,7 +9,6 @@ import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
 import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
 import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
 import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket;
-import net.minecraft.world.level.ChunkPos;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Inject;
@@ -19,13 +19,19 @@ public class MixinClientConnection {
     @Inject(method = "genericsFtw", at = @At("HEAD"))
     private static void handlePacket(Packet packet, PacketListener listener, CallbackInfo ci) {
         if (packet instanceof ClientboundBlockUpdatePacket) {
-            LightOverlay.queueChunkAndNear(new ChunkPos(((ClientboundBlockUpdatePacket) packet).getPos()));
+            LightOverlay.queueChunkAndNear(new CubicChunkPos(((ClientboundBlockUpdatePacket) packet).getPos()));
         } else if (packet instanceof ClientboundSetChunkCacheCenterPacket) {
-            LightOverlay.queueChunkAndNear(new ChunkPos(((ClientboundSetChunkCacheCenterPacket) packet).getX(), ((ClientboundSetChunkCacheCenterPacket) packet).getZ()));
+            for (int y = 0; y <= 15; y++) {
+                LightOverlay.queueChunkAndNear(new CubicChunkPos(((ClientboundSetChunkCacheCenterPacket) packet).getX(), y, ((ClientboundSetChunkCacheCenterPacket) packet).getZ()));
+            }
         } else if (packet instanceof ClientboundSectionBlocksUpdatePacket) {
-            LightOverlay.queueChunkAndNear(new ChunkPos(((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getX(), ((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getZ()));
+            for (int y = 0; y <= 15; y++) {
+                LightOverlay.queueChunkAndNear(new CubicChunkPos(((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getX(), y, ((ClientboundSectionBlocksUpdatePacket) packet).sectionPos.getZ()));
+            }
         } else if (packet instanceof ClientboundLightUpdatePacket) {
-            LightOverlay.queueChunk(new ChunkPos(((ClientboundLightUpdatePacket) packet).getX(), ((ClientboundLightUpdatePacket) packet).getZ()));
+            for (int y = 0; y <= 15; y++) {
+                LightOverlay.queueChunk(new CubicChunkPos(((ClientboundLightUpdatePacket) packet).getX(), y, ((ClientboundLightUpdatePacket) packet).getZ()));
+            }
         }
     }
 }
index ca7eb3d2900c541f31f0d24b99e866ad801390ba..20a9ef39fe67d18f0e1f51b7d49b977f541167f1 100755 (executable)
@@ -1,7 +1,7 @@
 org.gradle.jvmargs=-Xmx3G
 org.gradle.daemon=false
 
-mod_version=5.7.0
+mod_version=5.8.0
 minecraft_version=1.16.4
 
 architectury_version=1.5.112