diff --git a/nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/LightType.java b/common/src/main/java/ru/beykerykt/lightapi/LightType.java similarity index 77% rename from nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/LightType.java rename to common/src/main/java/ru/beykerykt/lightapi/LightType.java index 7b724bd6..d5dfda06 100644 --- a/nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/LightType.java +++ b/common/src/main/java/ru/beykerykt/lightapi/LightType.java @@ -1,8 +1,9 @@ /* * The MIT License (MIT) * - * Copyright (c) 2015 Vladimir Mikhailov + * Copyright (c) 2016 Vladimir Mikhailov * Copyright (c) 2016-2017 The ImplexDevOne Project + * Copyright (c) 2019 Qveshn * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,27 +23,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package ru.beykerykt.lightapi.server.nms.craftbukkit; +package ru.beykerykt.lightapi; public enum LightType { - - /** - * Light emanates from the block (torch, glowstone, etc.) - */ - BLOCK(0), - - /** - * N/A - */ - SKY(1); - - private final int id; - - private LightType(int id) { - this.id = id; - } - - public int getId() { - return id; - } + SKY, + BLOCK } diff --git a/common/src/main/java/ru/beykerykt/lightapi/chunks/ChunkInfo.java b/common/src/main/java/ru/beykerykt/lightapi/chunks/ChunkInfo.java index ea2f911f..c5f029da 100644 --- a/common/src/main/java/ru/beykerykt/lightapi/chunks/ChunkInfo.java +++ b/common/src/main/java/ru/beykerykt/lightapi/chunks/ChunkInfo.java @@ -45,7 +45,7 @@ public ChunkInfo(World world, int chunkX, int chunkZ, Collection players) { this.world = world; this.x = chunkX; - this.y = chunk_y_height; + this.y = chunk_y_height >> 4; this.z = chunkZ; this.receivers = players; } @@ -58,15 +58,20 @@ public int getChunkX() { return x; } + public int getChunkY() { + return y; + } + public int getChunkZ() { return z; } + @Deprecated public int getChunkYHeight() { - return y; + return y << 4; } - @SuppressWarnings("unused") + @Deprecated public void setChunkYHeight(int y) { this.y = y; } diff --git a/common/src/main/java/ru/beykerykt/lightapi/server/nms/INMSHandler.java b/common/src/main/java/ru/beykerykt/lightapi/server/nms/INMSHandler.java index 39ac100b..a44f80fc 100644 --- a/common/src/main/java/ru/beykerykt/lightapi/server/nms/INMSHandler.java +++ b/common/src/main/java/ru/beykerykt/lightapi/server/nms/INMSHandler.java @@ -30,28 +30,40 @@ import org.bukkit.World; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.chunks.ChunkInfo; public interface INMSHandler { // Lights... + @Deprecated void createLight(World world, int x, int y, int z, int light); + void createLight(World world, int x, int y, int z, LightType lightType, int light); + + @Deprecated void deleteLight(World world, int x, int y, int z); + void deleteLight(World world, int x, int y, int z, LightType lightType); + @Deprecated void recalculateLight(World world, int x, int y, int z); // Chunks... - List collectChunks(World world, int blockX, int blockY, int blockZ, int lightLevel); - @Deprecated List collectChunks(World world, int x, int y, int z); + @Deprecated + List collectChunks(World world, int blockX, int blockY, int blockZ, int lightLevel); + + List collectChunks(World world, int blockX, int blockY, int blockZ, LightType lightType, int lightLevel); + + @Deprecated void sendChunkSectionsUpdate( World world, int chunkX, int chunkZ, int sectionsMask, Collection players ); + @Deprecated void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player); @Deprecated @@ -66,6 +78,24 @@ void sendChunkSectionsUpdate( @Deprecated void sendChunkUpdate(World world, int chunkX, int y, int chunkZ, Player player); + void sendChunkSectionsUpdate( + World world, + int chunkX, + int chunkZ, + int sectionsMaskSky, + int sectionsMaskBlock, + Collection players + ); + + void sendChunkSectionsUpdate( + World world, + int chunkX, + int chunkZ, + int sectionsMaskSky, + int sectionsMaskBlock, + Player player + ); + // Utils... boolean isValidSectionY(int sectionY); diff --git a/common/src/main/java/ru/beykerykt/lightapi/server/nms/NmsHandlerBase.java b/common/src/main/java/ru/beykerykt/lightapi/server/nms/NmsHandlerBase.java index 1bb3eae6..a0d16ef8 100644 --- a/common/src/main/java/ru/beykerykt/lightapi/server/nms/NmsHandlerBase.java +++ b/common/src/main/java/ru/beykerykt/lightapi/server/nms/NmsHandlerBase.java @@ -27,6 +27,7 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.chunks.ChunkInfo; import java.util.ArrayList; @@ -70,13 +71,30 @@ public Collection filterVisiblePlayers( return result; } - private int getDeltaLight(int x, int dx) { - return (((x ^ ((-dx >> 4) & 15)) + 1) & (-(dx & 1))); + @Deprecated + @Override + public void createLight(World world, int x, int y, int z, int light) { + createLight(world, x, y, z, LightType.BLOCK, light); + } + + @Deprecated + @Override + public void deleteLight(World world, int x, int y, int z) { + deleteLight(world, x, y, z, LightType.BLOCK); } @Override - public List collectChunks(World world, int blockX, int blockY, int blockZ, int lightLevel) { + public List collectChunks(World world, int blockX, int blockY, int blockZ, int lightLevel + ) { + return collectChunks(world, blockX, blockY, blockZ, LightType.BLOCK, lightLevel); + } + + @Override + public List collectChunks( + World world, int blockX, int blockY, int blockZ, LightType lightType, int lightLevel + ) { List list = new ArrayList(); + Collection players = null; if (lightLevel > 0) { for (int dx = -1; dx <= 1; dx++) { int lightLevelX = lightLevel - getDeltaLight(blockX & 15, dx); @@ -85,18 +103,17 @@ public List collectChunks(World world, int blockX, int blockY, int bl int lightLevelZ = lightLevelX - getDeltaLight(blockZ & 15, dz); if (lightLevelZ > 0) { for (int dy = -1; dy <= 1; dy++) { - int lightLevelY = lightLevelZ - getDeltaLight(blockY & 15, dy); - if (lightLevelY > 0) { - int sectionY = blockY >> 4; + if (lightLevelZ > getDeltaLight(blockY & 15, dy)) { + int sectionY = (blockY >> 4) + dy; if (isValidSectionY(sectionY)) { int chunkX = blockX >> 4; int chunkZ = blockZ >> 4; ChunkInfo cCoord = new ChunkInfo( world, chunkX + dx, - ((sectionY + dy) << 4) + 15, + sectionY << 4, chunkZ + dz, - world.getPlayers()); + players != null ? players : (players = world.getPlayers())); list.add(cCoord); } } @@ -109,58 +126,81 @@ public List collectChunks(World world, int blockX, int blockY, int bl return list; } + private int getDeltaLight(int x, int dx) { + return (((x ^ ((-dx >> 4) & 15)) + 1) & (-(dx & 1))); + } + + @Deprecated @Override public void sendChunkSectionsUpdate( World world, int chunkX, int chunkZ, int sectionsMask, Collection players + ) { + sendChunkSectionsUpdate(world, chunkX, chunkZ, 0, sectionsMask, players); + } + + @Override + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, + int sectionsMaskSky, int sectionsMaskBlock, Collection players ) { for (Player player : players) { - sendChunkSectionsUpdate(world, chunkX, chunkZ, sectionsMask, player); + sendChunkSectionsUpdate(world, chunkX, chunkZ, sectionsMaskSky, sectionsMaskBlock, player); } } - protected void recalculateLighting(World world, int x, int y, int z) { - throw new UnsupportedOperationException("recalculateLighting not implemented"); + @Deprecated + @Override + public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + sendChunkSectionsUpdate(world, chunkX, chunkZ, 0, sectionsMask, player); } - protected void recalculateNeighbour(World world, int x, int y, int z) { - recalculateLighting(world, x - 1, y, z); - recalculateLighting(world, x + 1, y, z); - recalculateLighting(world, x, y - 1, z); - recalculateLighting(world, x, y + 1, z); - recalculateLighting(world, x, y, z - 1); - recalculateLighting(world, x, y, z + 1); + @Deprecated + @Override + public void recalculateLight(World world, int x, int y, int z) { + recalculateLighting(world, x, y, z, LightType.BLOCK); + } + + protected abstract void recalculateLighting(World world, int x, int y, int z, LightType lightType); + + protected void recalculateNeighbours(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x - 1, y, z, lightType); + recalculateLighting(world, x + 1, y, z, lightType); + recalculateLighting(world, x, y - 1, z, lightType); + recalculateLighting(world, x, y + 1, z, lightType); + recalculateLighting(world, x, y, z - 1, lightType); + recalculateLighting(world, x, y, z + 1, lightType); } @Deprecated @Override public List collectChunks(World world, int x, int y, int z) { - return collectChunks(world, x, y, z, 15); + return collectChunks(world, x, y, z, LightType.BLOCK, 15); } @Deprecated @Override public void sendChunkUpdate(World world, int chunkX, int chunkZ, Collection players) { - sendChunkUpdate(world, chunkX, chunkZ, isValidSectionY(-1) ? 0x3ffff : 0xffff, players); + sendChunkSectionsUpdate(world, chunkX, chunkZ, 0, isValidSectionY(-1) ? 0x3ffff : 0xffff, players); } @Deprecated @Override public void sendChunkUpdate(World world, int chunkX, int chunkZ, Player player) { - sendChunkSectionsUpdate(world, chunkX, chunkZ, isValidSectionY(-1) ? 0x3ffff : 0xffff, player); + sendChunkSectionsUpdate(world, chunkX, chunkZ, 0, isValidSectionY(-1) ? 0x3ffff : 0xffff, player); } @Deprecated @Override public void sendChunkUpdate(World world, int chunkX, int y, int chunkZ, Collection players) { int mask = getThreeSectionsMask(y); - if (mask != 0) sendChunkUpdate(world, chunkX, chunkZ, mask, players); + if (mask != 0) sendChunkSectionsUpdate(world, chunkX, chunkZ, 0, mask, players); } @Deprecated @Override public void sendChunkUpdate(World world, int chunkX, int y, int chunkZ, Player player) { int mask = getThreeSectionsMask(y); - if (mask != 0) sendChunkSectionsUpdate(world, chunkX, chunkZ, mask, player); + if (mask != 0) sendChunkSectionsUpdate(world, chunkX, chunkZ, 0, mask, player); } private int getThreeSectionsMask(int y) { diff --git a/nms/v1_10_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_10_R1.java b/nms/v1_10_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_10_R1.java index 9c6bf997..8e2f5223 100644 --- a/nms/v1_10_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_10_R1.java +++ b/nms/v1_10_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_10_R1.java @@ -29,36 +29,36 @@ import org.bukkit.craftbukkit.v1_10_R1.CraftWorld; import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_10_R1 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_11_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_11_R1.java b/nms/v1_11_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_11_R1.java index 28d62b3e..4fc52a3e 100644 --- a/nms/v1_11_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_11_R1.java +++ b/nms/v1_11_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_11_R1.java @@ -29,36 +29,36 @@ import org.bukkit.craftbukkit.v1_11_R1.CraftWorld; import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_11_R1 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_12_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_12_R1.java b/nms/v1_12_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_12_R1.java index 84953db9..9cb0edc5 100644 --- a/nms/v1_12_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_12_R1.java +++ b/nms/v1_12_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_12_R1.java @@ -29,36 +29,36 @@ import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_12_R1 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_13_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R1.java b/nms/v1_13_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R1.java index 0a37eb15..a0023d45 100644 --- a/nms/v1_13_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R1.java +++ b/nms/v1_13_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R1.java @@ -28,36 +28,36 @@ import org.bukkit.craftbukkit.v1_13_R1.CraftWorld; import org.bukkit.craftbukkit.v1_13_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_13_R1 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_13_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R2.java b/nms/v1_13_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R2.java index 42f10fea..110ba18d 100644 --- a/nms/v1_13_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R2.java +++ b/nms/v1_13_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_13_R2.java @@ -28,36 +28,36 @@ import org.bukkit.craftbukkit.v1_13_R2.CraftWorld; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_13_R2 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_14_R1.java b/nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_14_R1.java index f2f20b71..95e95993 100644 --- a/nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_14_R1.java +++ b/nms/v1_14_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_14_R1.java @@ -30,31 +30,59 @@ import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.chunks.ChunkInfo; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; import ru.beykerykt.lightapi.utils.Debug; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class CraftBukkit_v1_14_R1 extends NmsHandlerBase { - private boolean reflectionInited = false; private Field lightEngine_ThreadedMailbox; private Field threadedMailbox_State; private Method threadedMailbox_DoLoopStep; + private Field lightEngineLayer_c; + private Method lightEngineStorage_c; + private Method lightEngineGraph_a; + + public CraftBukkit_v1_14_R1() { + try { + threadedMailbox_DoLoopStep = ThreadedMailbox.class.getDeclaredMethod("f"); + threadedMailbox_DoLoopStep.setAccessible(true); + threadedMailbox_State = ThreadedMailbox.class.getDeclaredField("c"); + threadedMailbox_State.setAccessible(true); + lightEngine_ThreadedMailbox = LightEngineThreaded.class.getDeclaredField("b"); + lightEngine_ThreadedMailbox.setAccessible(true); + + lightEngineLayer_c = LightEngineLayer.class.getDeclaredField("c"); + lightEngineLayer_c.setAccessible(true); + lightEngineStorage_c = LightEngineStorage.class.getDeclaredMethod("c"); + lightEngineStorage_c.setAccessible(true); + lightEngineGraph_a = LightEngineGraph.class.getDeclaredMethod( + "a", long.class, long.class, int.class, boolean.class); + lightEngineGraph_a.setAccessible(true); + } catch (Exception e) { + throw toRuntimeException(e); + } + } @Override - public void createLight(World world, int x, int y, int z, int light) { - setRawLightLevel(world, LightType.BLOCK, x, y, z, light); - recalculateLighting(world, LightType.BLOCK, x, y, z); + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { + setRawLightLevel(world, lightType, x, y, z, light); + recalculateLighting(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - setRawLightLevel(world, LightType.BLOCK, x, y, z, 0); - recalculateLighting(world, LightType.BLOCK, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + setRawLightLevel(world, lightType, x, y, z, 0); + recalculateLighting(world, x, y, z, lightType); } @SuppressWarnings("SameParameterValue") @@ -67,33 +95,37 @@ private void setRawLightLevel(World world, final LightType type, int blockX, int executeSync(lightEngine, new Runnable() { @Override public void run() { - if (type == LightType.BLOCK) { - LightEngineBlock leb = (LightEngineBlock) lightEngine.a(EnumSkyBlock.BLOCK); + if (type == LightType.SKY) { + LightEngineSky les = (LightEngineSky) lightEngine.a(EnumSkyBlock.SKY); if (finalLightLevel == 0) { - leb.a(position); - } else if (leb.a(SectionPosition.a(position)) != null) { - leb.a(position, finalLightLevel); + les.a(position); + } else if (les.a(SectionPosition.a(position)) != null) { + try { + lightEngineLayer_a(les, position, finalLightLevel); + } catch (NullPointerException ignore) { + // To prevent problems with the absence of the NibbleArray, even + // if les.a(SectionPosition.a(position)) returns non-null value (corrupted data) + } } } else { - LightEngineSky les = (LightEngineSky) lightEngine.a(EnumSkyBlock.SKY); + LightEngineBlock leb = (LightEngineBlock) lightEngine.a(EnumSkyBlock.BLOCK); if (finalLightLevel == 0) { - les.a(position); - } else { - les.a(position, finalLightLevel); + leb.a(position); + } else if (leb.a(SectionPosition.a(position)) != null) { + try { + leb.a(position, finalLightLevel); + } catch (NullPointerException ignore) { + // To prevent problems with the absence of the NibbleArray, even + // if leb.a(SectionPosition.a(position)) returns non-null value (corrupted data) + } } } } }); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, LightType.BLOCK, x, y, z); - } - - @SuppressWarnings({"SameParameterValue", "unused"}) - private void recalculateLighting(World world, final LightType type, int blockX, int blockY, int blockZ) { + protected void recalculateLighting(World world, int blockX, int blockY, int blockZ, final LightType type) { WorldServer worldServer = ((CraftWorld) world).getHandle(); final LightEngineThreaded lightEngine = worldServer.getChunkProvider().getLightEngine(); @@ -105,19 +137,21 @@ private void recalculateLighting(World world, final LightType type, int blockX, executeSync(lightEngine, new Runnable() { @Override public void run() { - if (type == LightType.BLOCK) { - LightEngineBlock leb = (LightEngineBlock) lightEngine.a(EnumSkyBlock.BLOCK); - leb.a(Integer.MAX_VALUE, true, true); - } else { + if (type == LightType.SKY) { LightEngineSky les = (LightEngineSky) lightEngine.a(EnumSkyBlock.SKY); les.a(Integer.MAX_VALUE, true, true); + } else { + LightEngineBlock leb = (LightEngineBlock) lightEngine.a(EnumSkyBlock.BLOCK); + leb.a(Integer.MAX_VALUE, true, true); } } }); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // https://wiki.vg/index.php?title=Pre-release_protocol&oldid=14804#Update_Light // https://github.com/flori-schwa/VarLight/blob/b9349499f9c9fb995c320f95eae9698dd85aad5c/v1_14_R1/src/me/florian/varlight/nms/v1_14_R1/NmsAdapter_1_14_R1.java#L451 @@ -126,7 +160,8 @@ public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sec // 18 bits, with the lowest bit corresponding to chunk section -1 (in the void, // y=-16 to y=-1) and the highest bit for chunk section 16 (above the world, // y=256 to y=271). - PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunk.getPos(), chunk.e(), 0, sectionsMask); + PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate( + chunk.getPos(), chunk.e(), sectionsMaskSky, sectionsMaskBlock); ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); } @@ -148,16 +183,6 @@ protected int getViewDistance(Player player) { @SuppressWarnings({"StatementWithEmptyBody", "unchecked"}) private void executeSync(LightEngineThreaded lightEngine, Runnable task) { try { - if (!reflectionInited) { - threadedMailbox_DoLoopStep = ThreadedMailbox.class.getDeclaredMethod("f"); - threadedMailbox_DoLoopStep.setAccessible(true); - threadedMailbox_State = ThreadedMailbox.class.getDeclaredField("c"); - threadedMailbox_State.setAccessible(true); - lightEngine_ThreadedMailbox = LightEngineThreaded.class.getDeclaredField("b"); - lightEngine_ThreadedMailbox.setAccessible(true); - reflectionInited = true; - } - // ##### STEP 1: Pause light engine mailbox to process its tasks. ##### ThreadedMailbox threadedMailbox = (ThreadedMailbox) lightEngine_ThreadedMailbox .get(lightEngine); @@ -200,14 +225,86 @@ private void executeSync(LightEngineThreaded lightEngine, Runnable task) { // Otherwise, the main server thread may be frozen due to tasks stuck in the queue. threadedMailbox_DoLoopStep.invoke(threadedMailbox); } + } catch (InvocationTargetException e) { + throw toRuntimeException(e.getCause()); } catch (IllegalAccessException e) { - throw new UnsupportedOperationException("Something went wrong: access denied", e); - } catch (NoSuchFieldException e) { - throw new UnsupportedOperationException("Something went wrong: no such field", e); - } catch (NoSuchMethodException e) { - throw new UnsupportedOperationException("Something went wrong: no such method", e); + throw toRuntimeException(e); + } + } + + private void lightEngineLayer_a(LightEngineLayer les, BlockPosition var0, int var1) { + try { + LightEngineStorage ls = (LightEngineStorage) lightEngineLayer_c.get(les); + lightEngineStorage_c.invoke(ls); + lightEngineGraph_a.invoke(les, 9223372036854775807L, var0.asLong(), 15 - var1, true); } catch (InvocationTargetException e) { - throw new UnsupportedOperationException("Something went wrong: invocation target", e); + throw toRuntimeException(e.getCause()); + } catch (IllegalAccessException e) { + throw toRuntimeException(e); + } + } + + private static RuntimeException toRuntimeException(Throwable e) { + if (e instanceof RuntimeException) { + return (RuntimeException) e; + } + Class cls = e.getClass(); + return new RuntimeException( + String.format("(%s) %s", RuntimeException.class.getPackage().equals(cls.getPackage()) + ? cls.getSimpleName() : cls.getName(), e.getMessage()), + e); + } + + private int getDeltaLight(int x, int dx) { + return (((x ^ ((-dx >> 4) & 15)) + 1) & (-(dx & 1))); + } + + @Override + public List collectChunks( + World world, int blockX, int blockY, int blockZ, LightType lightType, int lightLevel + ) { + if (lightType != LightType.SKY || lightLevel < 15) { + return super.collectChunks(world, blockX, blockY, blockZ, lightType, lightLevel); + } + List list = new ArrayList(); + Collection players = null; + for (int dx = -1; dx <= 1; dx++) { + int lightLevelX = lightLevel - getDeltaLight(blockX & 15, dx); + if (lightLevelX > 0) { + for (int dz = -1; dz <= 1; dz++) { + int lightLevelZ = lightLevelX - getDeltaLight(blockZ & 15, dz); + if (lightLevelZ > 0) { + if (lightLevelZ > getDeltaLight(blockY & 15, 1)) { + int sectionY = (blockY >> 4) + 1; + if (isValidSectionY(sectionY)) { + int chunkX = blockX >> 4; + int chunkZ = blockZ >> 4; + ChunkInfo cCoord = new ChunkInfo( + world, + chunkX + dx, + sectionY << 4, + chunkZ + dz, + players != null ? players : (players = world.getPlayers())); + list.add(cCoord); + } + } + for (int sectionY = blockY >> 4; sectionY >= -1; sectionY--) { + if (isValidSectionY(sectionY)) { + int chunkX = blockX >> 4; + int chunkZ = blockZ >> 4; + ChunkInfo cCoord = new ChunkInfo( + world, + chunkX + dx, + sectionY << 4, + chunkZ + dz, + players != null ? players : (players = world.getPlayers())); + list.add(cCoord); + } + } + } + } + } } + return list; } } diff --git a/nms/v1_8_R3/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_8_R3.java b/nms/v1_8_R3/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_8_R3.java index f98886da..1cdf11ed 100644 --- a/nms/v1_8_R3/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_8_R3.java +++ b/nms/v1_8_R3/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_8_R3.java @@ -29,36 +29,36 @@ import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_8_R3 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_9_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R1.java b/nms/v1_9_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R1.java index d48f91a7..d8db63c8 100644 --- a/nms/v1_9_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R1.java +++ b/nms/v1_9_R1/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R1.java @@ -29,36 +29,36 @@ import org.bukkit.craftbukkit.v1_9_R1.CraftWorld; import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_9_R1 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/nms/v1_9_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R2.java b/nms/v1_9_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R2.java index ccd03ed0..c552f315 100644 --- a/nms/v1_9_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R2.java +++ b/nms/v1_9_R2/src/main/java/ru/beykerykt/lightapi/server/nms/craftbukkit/CraftBukkit_v1_9_R2.java @@ -29,36 +29,36 @@ import org.bukkit.craftbukkit.v1_9_R2.CraftWorld; import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.server.nms.NmsHandlerBase; public class CraftBukkit_v1_9_R2 extends NmsHandlerBase { @Override - public void createLight(World world, int x, int y, int z, int light) { + public void createLight(World world, int x, int y, int z, LightType lightType, int light) { WorldServer worldServer = ((CraftWorld) world).getHandle(); - worldServer.a(EnumSkyBlock.BLOCK, new BlockPosition(x, y, z), light); - recalculateNeighbour(world, x, y, z); + worldServer.a(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, + new BlockPosition(x, y, z), light); + recalculateNeighbours(world, x, y, z, lightType); } @Override - public void deleteLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); + public void deleteLight(World world, int x, int y, int z, LightType lightType) { + recalculateLighting(world, x, y, z, lightType); } - @Deprecated @Override - public void recalculateLight(World world, int x, int y, int z) { - recalculateLighting(world, x, y, z); - } - - protected void recalculateLighting(World world, int x, int y, int z) { + protected void recalculateLighting(World world, int x, int y, int z, LightType lightType) { WorldServer worldServer = ((CraftWorld) world).getHandle(); BlockPosition position = new BlockPosition(x, y, z); - worldServer.c(EnumSkyBlock.BLOCK, position); + worldServer.c(lightType == LightType.SKY ? EnumSkyBlock.SKY : EnumSkyBlock.BLOCK, position); } @Override - public void sendChunkSectionsUpdate(World world, int chunkX, int chunkZ, int sectionsMask, Player player) { + public void sendChunkSectionsUpdate( + World world, int chunkX, int chunkZ, int sectionsMaskSky, int sectionsMaskBlock, Player player + ) { + int sectionsMask = sectionsMaskSky | sectionsMaskBlock; Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(chunkX, chunkZ); // The last argument is bit-mask what chunk sections to update. Mask containing // 16 bits, with the lowest bit corresponding to chunk section 0 (y=0 to y=15) diff --git a/plugin/pom.xml b/plugin/pom.xml index fc25e09f..65bae082 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -6,7 +6,7 @@ ru.beykerykt LightAPI-fork - 3.3.2 + 3.4.0 1.6 diff --git a/plugin/src/main/java/ru/beykerykt/lightapi/LightAPI.java b/plugin/src/main/java/ru/beykerykt/lightapi/LightAPI.java index b2e0a39a..a4a2578a 100644 --- a/plugin/src/main/java/ru/beykerykt/lightapi/LightAPI.java +++ b/plugin/src/main/java/ru/beykerykt/lightapi/LightAPI.java @@ -234,21 +234,35 @@ public static LightAPI getInstance() { return plugin; } + @Deprecated @SuppressWarnings("unused") public static boolean createLight(Location location, int lightlevel, boolean async) { + return createLight(location, LightType.BLOCK, lightlevel, async); + } + + @SuppressWarnings("WeakerAccess") + public static boolean createLight(Location location, LightType lightType, int lightlevel, boolean async) { return createLight( location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), - lightlevel, async); + lightType, + lightlevel, + async); } - @SuppressWarnings("WeakerAccess") + @Deprecated public static boolean createLight( World world, int x, final int y, final int z, final int lightlevel, boolean async) { + return createLight(world, x, y, z, LightType.BLOCK, lightlevel, async); + } + + @SuppressWarnings("WeakerAccess") + public static boolean createLight( + World world, int x, final int y, final int z, LightType lightType, final int lightlevel, boolean async) { if (getInstance().isEnabled()) { - final SetLightEvent event = new SetLightEvent(world, x, y, z, lightlevel, async); + final SetLightEvent event = new SetLightEvent(world, x, y, z, lightType, lightlevel, async); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { @@ -261,6 +275,7 @@ public void run() { event.getX(), event.getY(), event.getZ(), + event.getLightType(), event.getLightLevel()); } } @@ -276,20 +291,34 @@ public void run() { return false; } + @Deprecated @SuppressWarnings("unused") public static boolean deleteLight(Location location, boolean async) { + return deleteLight(location, LightType.BLOCK, async); + } + + @SuppressWarnings("WeakerAccess") + public static boolean deleteLight(Location location, LightType lightType, boolean async) { return deleteLight( location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), + lightType, async); } - @SuppressWarnings("WeakerAccess") + @Deprecated public static boolean deleteLight(final World world, final int x, final int y, final int z, boolean async) { + return deleteLight(world, x, y, z, LightType.BLOCK, async); + } + + @SuppressWarnings("WeakerAccess") + public static boolean deleteLight( + final World world, final int x, final int y, final int z, LightType lightType, boolean async + ) { if (getInstance().isEnabled()) { - final DeleteLightEvent event = new DeleteLightEvent(world, x, y, z, async); + final DeleteLightEvent event = new DeleteLightEvent(world, x, y, z, lightType, async); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { @@ -300,7 +329,8 @@ public void run() { event.getWorld(), event.getX(), event.getY(), - event.getZ()); + event.getZ(), + event.getLightType()); } }; if (event.isAsync()) { @@ -316,33 +346,40 @@ public void run() { @Deprecated public static List collectChunks(Location location) { - return collectChunks( - location.getWorld(), - location.getBlockX(), - location.getBlockY(), - location.getBlockZ(), - 15); + return collectChunks(location, LightType.BLOCK, 15); } @Deprecated - public static List collectChunks(final World world, final int x, final int y, final int z) { - return collectChunks(world, x, y, z, 15); - } - @SuppressWarnings("unused") public static List collectChunks(Location location, int lightLevel) { + return collectChunks(location, LightType.BLOCK, lightLevel); + } + + @SuppressWarnings("WeakerAccess") + public static List collectChunks(Location location, LightType lightType, int lightLevel) { return collectChunks( location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), + lightType, lightLevel); } - @SuppressWarnings("WeakerAccess") + @Deprecated + public static List collectChunks(final World world, final int x, final int y, final int z) { + return collectChunks(world, x, y, z, LightType.BLOCK, 15); + } + + @Deprecated public static List collectChunks(World world, int x, int y, int z, int lightLevel) { + return collectChunks(world, x, y, z, LightType.BLOCK, lightLevel); + } + + @SuppressWarnings("WeakerAccess") + public static List collectChunks(World world, int x, int y, int z, LightType lightType, int lightLevel) { if (getInstance().isEnabled()) { - return ServerModManager.getNMSHandler().collectChunks(world, x, y, z, lightLevel); + return ServerModManager.getNMSHandler().collectChunks(world, x, y, z, lightType, lightLevel); } return new ArrayList(); } @@ -352,18 +389,28 @@ public static boolean updateChunks(ChunkInfo info) { return updateChunk(info); } - @SuppressWarnings("WeakerAccess") + @Deprecated public static boolean updateChunk(ChunkInfo info) { - return updateChunk(info, null); + return updateChunk(info, LightType.BLOCK); } @SuppressWarnings("WeakerAccess") + public static boolean updateChunk(ChunkInfo info, LightType lightType) { + return updateChunk(info, lightType, null); + } + + @Deprecated public static boolean updateChunk(ChunkInfo info, Collection players) { + return updateChunk(info, LightType.BLOCK, players); + } + + @SuppressWarnings("WeakerAccess") + public static boolean updateChunk(ChunkInfo info, LightType lightType, Collection players) { if (getInstance().isEnabled()) { - UpdateChunkEvent event = new UpdateChunkEvent(info); + UpdateChunkEvent event = new UpdateChunkEvent(info, lightType); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { - machine.addChunkToUpdate(info, players); + machine.addChunkToUpdate(info, lightType, players); return true; } } @@ -405,9 +452,9 @@ public static boolean updateChunk(Location location, Collection players) { if (getInstance().isEnabled()) { - updateChunk(new ChunkInfo(world, x, y - 1, z, players)); + updateChunk(new ChunkInfo(world, x, y - 16, z, players)); updateChunk(new ChunkInfo(world, x, y, z, players)); - updateChunk(new ChunkInfo(world, x, y + 1, z, players)); + updateChunk(new ChunkInfo(world, x, y + 16, z, players)); return true; } return false; diff --git a/plugin/src/main/java/ru/beykerykt/lightapi/chunks/ChunkUpdateInfo.java b/plugin/src/main/java/ru/beykerykt/lightapi/chunks/ChunkUpdateInfo.java index 4bd1dfa8..4325d985 100644 --- a/plugin/src/main/java/ru/beykerykt/lightapi/chunks/ChunkUpdateInfo.java +++ b/plugin/src/main/java/ru/beykerykt/lightapi/chunks/ChunkUpdateInfo.java @@ -24,17 +24,23 @@ package ru.beykerykt.lightapi.chunks; import org.bukkit.entity.Player; +import ru.beykerykt.lightapi.LightType; import java.util.Collection; import java.util.HashSet; public class ChunkUpdateInfo { - private int sectionMask = 0; + private int sectionMaskSky = 0; + private int sectionMaskBlock = 0; private Collection players = new HashSet(); - public void add(int sectionMask, Collection players) { - this.sectionMask |= sectionMask; + public void add(LightType lightType, int sectionMask, Collection players) { + if (lightType == LightType.SKY) { + this.sectionMaskSky |= sectionMask; + } else { + this.sectionMaskBlock |= sectionMask; + } add(players); } @@ -46,7 +52,11 @@ public Collection getPlayers() { return players; } - public int getSectionMask() { - return sectionMask; + public int getSectionMaskSky() { + return sectionMaskSky; + } + + public int getSectionMaskBlock() { + return sectionMaskBlock; } } diff --git a/plugin/src/main/java/ru/beykerykt/lightapi/events/DeleteLightEvent.java b/plugin/src/main/java/ru/beykerykt/lightapi/events/DeleteLightEvent.java index effc20d9..9719466e 100644 --- a/plugin/src/main/java/ru/beykerykt/lightapi/events/DeleteLightEvent.java +++ b/plugin/src/main/java/ru/beykerykt/lightapi/events/DeleteLightEvent.java @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2016 Vladimir Mikhailov + * Copyright (c) 2019 Qveshn * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,6 +28,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import ru.beykerykt.lightapi.LightType; public class DeleteLightEvent extends Event implements Cancellable { @@ -36,13 +38,20 @@ public class DeleteLightEvent extends Event implements Cancellable { private int x; private int y; private int z; + private LightType lightType; private boolean async; + @Deprecated public DeleteLightEvent(World world, int x, int y, int z, boolean async) { + this(world, x, y, z, LightType.BLOCK, async); + } + + public DeleteLightEvent(World world, int x, int y, int z, LightType lightType, boolean async) { this.world = world; this.x = x; this.y = y; this.z = z; + this.lightType = lightType; this.async = async; } @@ -104,4 +113,12 @@ public boolean isAsync() { public void setAsync(boolean flag) { this.async = flag; } + + public LightType getLightType() { + return lightType; + } + + public void setLightType(LightType lightType) { + this.lightType = lightType; + } } diff --git a/plugin/src/main/java/ru/beykerykt/lightapi/events/SetLightEvent.java b/plugin/src/main/java/ru/beykerykt/lightapi/events/SetLightEvent.java index bda61fec..76da96e8 100644 --- a/plugin/src/main/java/ru/beykerykt/lightapi/events/SetLightEvent.java +++ b/plugin/src/main/java/ru/beykerykt/lightapi/events/SetLightEvent.java @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2016 Vladimir Mikhailov + * Copyright (c) 2019 Qveshn * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,6 +28,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import ru.beykerykt.lightapi.LightType; public class SetLightEvent extends Event implements Cancellable { @@ -36,14 +38,21 @@ public class SetLightEvent extends Event implements Cancellable { private int x; private int y; private int z; + private LightType lightType; private int level; private boolean async; + @Deprecated public SetLightEvent(World world, int x, int y, int z, int level, boolean async) { + this(world, x, y, z, LightType.BLOCK, level, async); + } + + public SetLightEvent(World world, int x, int y, int z, LightType lightType, int level, boolean async) { this.world = world; this.x = x; this.y = y; this.z = z; + this.lightType = lightType; this.level = level; this.async = async; } @@ -114,4 +123,12 @@ public boolean isAsync() { public void setAsync(boolean flag) { this.async = flag; } + + public LightType getLightType() { + return lightType; + } + + public void setLightType(LightType lightType) { + this.lightType = lightType; + } } diff --git a/plugin/src/main/java/ru/beykerykt/lightapi/events/UpdateChunkEvent.java b/plugin/src/main/java/ru/beykerykt/lightapi/events/UpdateChunkEvent.java index 0f18c992..699b115e 100644 --- a/plugin/src/main/java/ru/beykerykt/lightapi/events/UpdateChunkEvent.java +++ b/plugin/src/main/java/ru/beykerykt/lightapi/events/UpdateChunkEvent.java @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2016 Vladimir Mikhailov + * Copyright (c) 2019 Qveshn * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,15 +29,22 @@ import org.bukkit.event.HandlerList; import ru.beykerykt.lightapi.chunks.ChunkInfo; +import ru.beykerykt.lightapi.LightType; public class UpdateChunkEvent extends Event implements Cancellable { private boolean cancel; private static final HandlerList handlers = new HandlerList(); private ChunkInfo cCoord; + private LightType lightType; public UpdateChunkEvent(ChunkInfo cCoord) { + this(cCoord, LightType.BLOCK); + } + + public UpdateChunkEvent(ChunkInfo cCoord, LightType lightType) { this.cCoord = cCoord; + this.lightType = lightType; } @Override @@ -65,4 +73,12 @@ public ChunkInfo getChunkInfo() { public void setChunkInfo(ChunkInfo cCoord) { this.cCoord = cCoord; } + + public LightType getLightType() { + return lightType; + } + + public void setLightType(LightType lightType) { + this.lightType = lightType; + } } diff --git a/plugin/src/main/java/ru/beykerykt/lightapi/request/RequestSteamMachine.java b/plugin/src/main/java/ru/beykerykt/lightapi/request/RequestSteamMachine.java index 61051319..baf8e6a9 100644 --- a/plugin/src/main/java/ru/beykerykt/lightapi/request/RequestSteamMachine.java +++ b/plugin/src/main/java/ru/beykerykt/lightapi/request/RequestSteamMachine.java @@ -30,6 +30,7 @@ import ru.beykerykt.lightapi.chunks.ChunkUpdateInfo; import ru.beykerykt.lightapi.server.ServerModManager; import ru.beykerykt.lightapi.server.nms.INMSHandler; +import ru.beykerykt.lightapi.LightType; import ru.beykerykt.lightapi.utils.Debug; import java.util.*; @@ -77,8 +78,8 @@ public boolean addToQueue(Runnable request) { return false; } - public void addChunkToUpdate(final ChunkInfo info, Collection receivers) { - int SectionY = info.getChunkYHeight() >> 4; + public void addChunkToUpdate(final ChunkInfo info, final LightType lightType, Collection receivers) { + int SectionY = info.getChunkY(); INMSHandler nmsHandler = ServerModManager.getNMSHandler(); if (nmsHandler.isValidSectionY(SectionY)) { final ChunkLocation chunk = new ChunkLocation(info.getWorld(), info.getChunkX(), info.getChunkZ()); @@ -93,7 +94,7 @@ public void run() { if (chunkUpdateInfo == null) { chunksToUpdate.put(chunk, chunkUpdateInfo = new ChunkUpdateInfo()); } - chunkUpdateInfo.add(sectionYMask, players); + chunkUpdateInfo.add(lightType, sectionYMask, players); } }); } @@ -122,13 +123,15 @@ public void run() { for (Map.Entry item : chunksToUpdate.entrySet()) { ChunkLocation chunk = item.getKey(); ChunkUpdateInfo chunkUpdateInfo = item.getValue(); - int sectionMask = chunkUpdateInfo.getSectionMask(); + int sectionMaskSky = chunkUpdateInfo.getSectionMaskSky(); + int sectionMaskBlock = chunkUpdateInfo.getSectionMaskBlock(); Collection players = nmsHandler.filterVisiblePlayers( chunk.getWorld(), chunk.getX(), chunk.getZ(), chunkUpdateInfo.getPlayers()); - nmsHandler.sendChunkSectionsUpdate(chunk.getWorld(), chunk.getX(), chunk.getZ(), sectionMask, players); + nmsHandler.sendChunkSectionsUpdate(chunk.getWorld(), chunk.getX(), chunk.getZ(), + sectionMaskSky, sectionMaskBlock, players); if (debug) { totalSends += players.size(); - totalSections += Integer.bitCount(sectionMask); + totalSections += Integer.bitCount(sectionMaskSky | sectionMaskBlock); usedPlayers.addAll(players); } }