forked from BLOCKFANTASY/LOOHP-Limbo
Fill chunks outside of world (schematic) with empty chunks
This commit is contained in:
parent
abc5a83b48
commit
9d507f684f
2
pom.xml
2
pom.xml
|
|
@ -5,7 +5,7 @@
|
||||||
<groupId>com.loohp</groupId>
|
<groupId>com.loohp</groupId>
|
||||||
<artifactId>Limbo</artifactId>
|
<artifactId>Limbo</artifactId>
|
||||||
<name>Limbo</name>
|
<name>Limbo</name>
|
||||||
<version>0.6.6-ALPHA</version>
|
<version>0.6.7-ALPHA</version>
|
||||||
|
|
||||||
<description>Standalone Limbo Minecraft Server.</description>
|
<description>Standalone Limbo Minecraft Server.</description>
|
||||||
<url>https://github.com/LOOHP/Limbo</url>
|
<url>https://github.com/LOOHP/Limbo</url>
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ import java.util.stream.Collectors;
|
||||||
import com.loohp.limbo.Limbo;
|
import com.loohp.limbo.Limbo;
|
||||||
import com.loohp.limbo.entity.Entity;
|
import com.loohp.limbo.entity.Entity;
|
||||||
import com.loohp.limbo.location.Location;
|
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.PacketPlayOutEntityDestroy;
|
||||||
import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata;
|
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.PacketPlayOutSpawnEntity;
|
||||||
import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntityLiving;
|
import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntityLiving;
|
||||||
import com.loohp.limbo.server.packets.PacketPlayOutUnloadChunk;
|
import com.loohp.limbo.server.packets.PacketPlayOutUnloadChunk;
|
||||||
|
import com.loohp.limbo.world.ChunkPosition;
|
||||||
import com.loohp.limbo.world.World;
|
import com.loohp.limbo.world.World;
|
||||||
|
|
||||||
import net.querz.mca.Chunk;
|
import net.querz.mca.Chunk;
|
||||||
|
|
@ -28,12 +29,12 @@ public class PlayerInteractManager {
|
||||||
private Player player;
|
private Player player;
|
||||||
|
|
||||||
private Set<Entity> entities;
|
private Set<Entity> entities;
|
||||||
private Map<Chunk, World> chunks;
|
private Map<ChunkPosition, Chunk> currentViewing;
|
||||||
|
|
||||||
public PlayerInteractManager() {
|
public PlayerInteractManager() {
|
||||||
this.player = null;
|
this.player = null;
|
||||||
this.entities = new HashSet<>();
|
this.entities = new HashSet<>();
|
||||||
this.chunks = new HashMap<>();
|
this.currentViewing = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setPlayer(Player player) {
|
protected void setPlayer(Player player) {
|
||||||
|
|
@ -87,47 +88,53 @@ public class PlayerInteractManager {
|
||||||
int playerChunkZ = (int) location.getZ() >> 4;
|
int playerChunkZ = (int) location.getZ() >> 4;
|
||||||
World world = location.getWorld();
|
World world = location.getWorld();
|
||||||
|
|
||||||
Set<Chunk> chunksInRange = new HashSet<>();
|
Map<ChunkPosition, Chunk> chunksInRange = new HashMap<>();
|
||||||
|
|
||||||
for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) {
|
for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) {
|
||||||
for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) {
|
for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) {
|
||||||
Chunk chunk = world.getChunkAt(x, z);
|
Chunk chunk = world.getChunkAt(x, z);
|
||||||
if (chunk != null) {
|
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<Chunk, World> entry : chunks.entrySet()) {
|
for (Entry<ChunkPosition, Chunk> entry : currentViewing.entrySet()) {
|
||||||
Chunk chunk = entry.getKey();
|
ChunkPosition chunkPos = entry.getKey();
|
||||||
if (location.getWorld().getChunkXZ(chunk) == null) {
|
if (!chunksInRange.containsKey(chunkPos)) {
|
||||||
World world0 = entry.getValue();
|
PacketPlayOutUnloadChunk packet = new PacketPlayOutUnloadChunk(chunkPos.getChunkX(), chunkPos.getChunkZ());
|
||||||
int[] chunkPos = world0.getChunkXZ(chunk);
|
player.clientConnection.sendPacket(packet);
|
||||||
PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]);
|
|
||||||
player.clientConnection.sendPacket(packet0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Chunk chunk : chunksInRange) {
|
for (Entry<ChunkPosition, Chunk> entry : chunksInRange.entrySet()) {
|
||||||
if (!chunks.containsKey(chunk)) {
|
ChunkPosition chunkPos = entry.getKey();
|
||||||
int[] chunkPos = world.getChunkXZ(chunk);
|
if (!currentViewing.containsKey(chunkPos)) {
|
||||||
List<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]);
|
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<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos.getChunkX(), chunkPos.getChunkZ());
|
||||||
if (blockChunk == null) {
|
if (blockChunk == null) {
|
||||||
blockChunk = new ArrayList<>();
|
blockChunk = new ArrayList<>();
|
||||||
}
|
}
|
||||||
List<Byte[]> skyChunk = null;
|
List<Byte[]> skyChunk = null;
|
||||||
if (world.hasSkyLight()) {
|
if (world.hasSkyLight()) {
|
||||||
skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]);
|
skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos.getChunkX(), chunkPos.getChunkZ());
|
||||||
}
|
}
|
||||||
if (skyChunk == null) {
|
if (skyChunk == null) {
|
||||||
skyChunk = new ArrayList<>();
|
skyChunk = new ArrayList<>();
|
||||||
}
|
}
|
||||||
ClientboundLevelChunkWithLightPacket chunkdata = new ClientboundLevelChunkWithLightPacket(chunkPos[0], chunkPos[1], chunk, world.getEnvironment(), true, skyChunk, blockChunk);
|
ClientboundLevelChunkWithLightPacket chunkdata = new ClientboundLevelChunkWithLightPacket(chunkPos.getChunkX(), chunkPos.getChunkZ(), chunk, world.getEnvironment(), true, skyChunk, blockChunk);
|
||||||
player.clientConnection.sendPacket(chunkdata);
|
player.clientConnection.sendPacket(chunkdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world));
|
currentViewing = chunksInRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,5 @@
|
||||||
package com.loohp.limbo.utils;
|
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.ByteArrayInputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -14,6 +9,12 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.UUID;
|
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 class ForwardingUtils {
|
||||||
|
|
||||||
public static final NamespacedKey VELOCITY_FORWARDING_CHANNEL = new NamespacedKey("velocity", "player_info");
|
public static final NamespacedKey VELOCITY_FORWARDING_CHANNEL = new NamespacedKey("velocity", "player_info");
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,28 @@ import net.querz.nbt.tag.ListTag;
|
||||||
|
|
||||||
public class World {
|
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>(CompoundTag.class));
|
||||||
|
}
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Environment environment;
|
private Environment environment;
|
||||||
private Chunk[][] chunks;
|
private Chunk[][] chunks;
|
||||||
|
|
@ -49,19 +71,7 @@ public class World {
|
||||||
chunks[x][z] = Chunk.newChunk();
|
chunks[x][z] = Chunk.newChunk();
|
||||||
Chunk chunk = chunks[x][z];
|
Chunk chunk = chunks[x][z];
|
||||||
chunk.cleanupPalettesAndBlockStates();
|
chunk.cleanupPalettesAndBlockStates();
|
||||||
CompoundTag heightMap = new CompoundTag();
|
chunk.setHeightMaps(HEIGHT_MAP.clone());
|
||||||
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.setBiomes(new int[256]);
|
chunk.setBiomes(new int[256]);
|
||||||
chunk.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class));
|
chunk.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue