From 9d507f684f625a0469fd8f6efde377d7a23a873c Mon Sep 17 00:00:00 2001 From: LOOHP Date: Sat, 4 Dec 2021 18:56:57 +0000 Subject: [PATCH] Fill chunks outside of world (schematic) with empty chunks --- pom.xml | 2 +- .../limbo/player/PlayerInteractManager.java | 63 ++++++++------- .../loohp/limbo/utils/ForwardingUtils.java | 11 +-- .../com/loohp/limbo/world/ChunkPosition.java | 81 +++++++++++++++++++ .../java/com/loohp/limbo/world/World.java | 38 +++++---- 5 files changed, 147 insertions(+), 48 deletions(-) create mode 100644 src/main/java/com/loohp/limbo/world/ChunkPosition.java diff --git a/pom.xml b/pom.xml index e3c9a2b..2d52788 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.loohp Limbo Limbo - 0.6.6-ALPHA + 0.6.7-ALPHA Standalone Limbo Minecraft Server. https://github.com/LOOHP/Limbo diff --git a/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java b/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java index d9de954..2134269 100644 --- a/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java +++ b/src/main/java/com/loohp/limbo/player/PlayerInteractManager.java @@ -13,12 +13,13 @@ import java.util.stream.Collectors; import com.loohp.limbo.Limbo; import com.loohp.limbo.entity.Entity; import com.loohp.limbo.location.Location; +import com.loohp.limbo.server.packets.ClientboundLevelChunkWithLightPacket; import com.loohp.limbo.server.packets.PacketPlayOutEntityDestroy; import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata; -import com.loohp.limbo.server.packets.ClientboundLevelChunkWithLightPacket; import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntity; import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntityLiving; import com.loohp.limbo.server.packets.PacketPlayOutUnloadChunk; +import com.loohp.limbo.world.ChunkPosition; import com.loohp.limbo.world.World; import net.querz.mca.Chunk; @@ -28,12 +29,12 @@ public class PlayerInteractManager { private Player player; private Set entities; - private Map chunks; + private Map currentViewing; public PlayerInteractManager() { this.player = null; this.entities = new HashSet<>(); - this.chunks = new HashMap<>(); + this.currentViewing = new HashMap<>(); } protected void setPlayer(Player player) { @@ -87,47 +88,53 @@ public class PlayerInteractManager { int playerChunkZ = (int) location.getZ() >> 4; World world = location.getWorld(); - Set chunksInRange = new HashSet<>(); + Map chunksInRange = new HashMap<>(); for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) { for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) { Chunk chunk = world.getChunkAt(x, z); if (chunk != null) { - chunksInRange.add(chunk); + chunksInRange.put(new ChunkPosition(world, x, z), chunk); + } else { + chunksInRange.put(new ChunkPosition(world, x, z), World.EMPTY_CHUNK); } } } - for (Entry entry : chunks.entrySet()) { - Chunk chunk = entry.getKey(); - if (location.getWorld().getChunkXZ(chunk) == null) { - World world0 = entry.getValue(); - int[] chunkPos = world0.getChunkXZ(chunk); - PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]); - player.clientConnection.sendPacket(packet0); + for (Entry entry : currentViewing.entrySet()) { + ChunkPosition chunkPos = entry.getKey(); + if (!chunksInRange.containsKey(chunkPos)) { + PacketPlayOutUnloadChunk packet = new PacketPlayOutUnloadChunk(chunkPos.getChunkX(), chunkPos.getChunkZ()); + player.clientConnection.sendPacket(packet); } } - for (Chunk chunk : chunksInRange) { - if (!chunks.containsKey(chunk)) { - int[] chunkPos = world.getChunkXZ(chunk); - List blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]); - if (blockChunk == null) { - blockChunk = new ArrayList<>(); + for (Entry entry : chunksInRange.entrySet()) { + ChunkPosition chunkPos = entry.getKey(); + if (!currentViewing.containsKey(chunkPos)) { + Chunk chunk = chunkPos.getWorld().getChunkAt(chunkPos.getChunkX(), chunkPos.getChunkZ()); + if (chunk == null) { + ClientboundLevelChunkWithLightPacket chunkdata = new ClientboundLevelChunkWithLightPacket(chunkPos.getChunkX(), chunkPos.getChunkZ(), entry.getValue(), world.getEnvironment(), true, new ArrayList<>(), new ArrayList<>()); + player.clientConnection.sendPacket(chunkdata); + } else { + List blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos.getChunkX(), chunkPos.getChunkZ()); + if (blockChunk == null) { + blockChunk = new ArrayList<>(); + } + List skyChunk = null; + if (world.hasSkyLight()) { + skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos.getChunkX(), chunkPos.getChunkZ()); + } + if (skyChunk == null) { + skyChunk = new ArrayList<>(); + } + ClientboundLevelChunkWithLightPacket chunkdata = new ClientboundLevelChunkWithLightPacket(chunkPos.getChunkX(), chunkPos.getChunkZ(), chunk, world.getEnvironment(), true, skyChunk, blockChunk); + player.clientConnection.sendPacket(chunkdata); } - List skyChunk = null; - if (world.hasSkyLight()) { - skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]); - } - if (skyChunk == null) { - skyChunk = new ArrayList<>(); - } - ClientboundLevelChunkWithLightPacket chunkdata = new ClientboundLevelChunkWithLightPacket(chunkPos[0], chunkPos[1], chunk, world.getEnvironment(), true, skyChunk, blockChunk); - player.clientConnection.sendPacket(chunkdata); } } - chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world)); + currentViewing = chunksInRange; } } diff --git a/src/main/java/com/loohp/limbo/utils/ForwardingUtils.java b/src/main/java/com/loohp/limbo/utils/ForwardingUtils.java index 192a6c7..ad3e474 100644 --- a/src/main/java/com/loohp/limbo/utils/ForwardingUtils.java +++ b/src/main/java/com/loohp/limbo/utils/ForwardingUtils.java @@ -1,10 +1,5 @@ package com.loohp.limbo.utils; -import com.loohp.limbo.Limbo; - -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; @@ -14,6 +9,12 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.UUID; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import com.loohp.limbo.Limbo; + public class ForwardingUtils { public static final NamespacedKey VELOCITY_FORWARDING_CHANNEL = new NamespacedKey("velocity", "player_info"); diff --git a/src/main/java/com/loohp/limbo/world/ChunkPosition.java b/src/main/java/com/loohp/limbo/world/ChunkPosition.java new file mode 100644 index 0000000..dcab886 --- /dev/null +++ b/src/main/java/com/loohp/limbo/world/ChunkPosition.java @@ -0,0 +1,81 @@ +package com.loohp.limbo.world; + +import com.loohp.limbo.location.Location; + +import net.querz.mca.Chunk; + +public class ChunkPosition { + + private World world; + private int x; + private int z; + + public ChunkPosition(World world, int chunkX, int chunkZ) { + this.world = world; + this.x = chunkX; + this.z = chunkZ; + } + + public ChunkPosition(Location location) { + this(location.getWorld(), (int) location.getX() >> 4, (int) location.getZ() >> 4); + } + + public ChunkPosition(World world, Chunk chunk) { + this(world, world.getChunkX(chunk), world.getChunkZ(chunk)); + } + + public World getWorld() { + return world; + } + + public int getChunkX() { + return x; + } + + public int getChunkZ() { + return z; + } + + public Chunk getChunk() { + return getWorld().getChunkAt(x, z); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((world == null) ? 0 : world.hashCode()); + result = prime * result + x; + result = prime * result + z; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ChunkPosition other = (ChunkPosition) obj; + if (world == null) { + if (other.world != null) { + return false; + } + } else if (!world.equals(other.world)) { + return false; + } + if (x != other.x) { + return false; + } + if (z != other.z) { + return false; + } + return true; + } + +} diff --git a/src/main/java/com/loohp/limbo/world/World.java b/src/main/java/com/loohp/limbo/world/World.java index bef2b1d..f9fe639 100644 --- a/src/main/java/com/loohp/limbo/world/World.java +++ b/src/main/java/com/loohp/limbo/world/World.java @@ -27,7 +27,29 @@ import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.ListTag; public class World { - + + public static final CompoundTag HEIGHT_MAP = new CompoundTag(); + public static final Chunk EMPTY_CHUNK = Chunk.newChunk(); + + static { + HEIGHT_MAP.putLongArray("MOTION_BLOCKING", + new long[] {1371773531765642314L, 1389823183635651148L, 1371738278539598925L, + 1389823183635388492L, 1353688558756731469L, 1389823114781694027L, 1317765589597723213L, + 1371773531899860042L, 1389823183635651149L, 1371773462911685197L, 1389823183635650636L, + 1353688626805119565L, 1371773531900123211L, 1335639250618849869L, 1371738278674077258L, + 1389823114781694028L, 1353723811310638154L, 1371738278674077259L, 1335674228429068364L, + 1335674228429067338L, 1335674228698027594L, 1317624576693539402L, 1335709481520370249L, + 1299610178184057417L, 1335638906349064264L, 1299574993811968586L, 1299574924958011464L, + 1299610178184056904L, 1299574924958011464L, 1299610109330100296L, 1299574924958011464L, + 1299574924823793736L, 1299574924958011465L, 1281525273222484040L, 1299574924958011464L, + 1281525273222484040L, 9548107335L}); + + EMPTY_CHUNK.cleanupPalettesAndBlockStates(); + EMPTY_CHUNK.setHeightMaps(HEIGHT_MAP.clone()); + EMPTY_CHUNK.setBiomes(new int[256]); + EMPTY_CHUNK.setTileEntities(new ListTag(CompoundTag.class)); + } + private String name; private Environment environment; private Chunk[][] chunks; @@ -49,19 +71,7 @@ public class World { chunks[x][z] = Chunk.newChunk(); Chunk chunk = chunks[x][z]; chunk.cleanupPalettesAndBlockStates(); - CompoundTag heightMap = new CompoundTag(); - heightMap.putLongArray("MOTION_BLOCKING", - new long[] {1371773531765642314L, 1389823183635651148L, 1371738278539598925L, - 1389823183635388492L, 1353688558756731469L, 1389823114781694027L, 1317765589597723213L, - 1371773531899860042L, 1389823183635651149L, 1371773462911685197L, 1389823183635650636L, - 1353688626805119565L, 1371773531900123211L, 1335639250618849869L, 1371738278674077258L, - 1389823114781694028L, 1353723811310638154L, 1371738278674077259L, 1335674228429068364L, - 1335674228429067338L, 1335674228698027594L, 1317624576693539402L, 1335709481520370249L, - 1299610178184057417L, 1335638906349064264L, 1299574993811968586L, 1299574924958011464L, - 1299610178184056904L, 1299574924958011464L, 1299610109330100296L, 1299574924958011464L, - 1299574924823793736L, 1299574924958011465L, 1281525273222484040L, 1299574924958011464L, - 1281525273222484040L, 9548107335L}); - chunk.setHeightMaps(heightMap); + chunk.setHeightMaps(HEIGHT_MAP.clone()); chunk.setBiomes(new int[256]); chunk.setTileEntities(new ListTag(CompoundTag.class)); }