diff options
Diffstat (limited to 'src/main/java/net/minecraft/server/PlayerChunk.java')
-rw-r--r-- | src/main/java/net/minecraft/server/PlayerChunk.java | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java new file mode 100644 index 00000000..53506443 --- /dev/null +++ b/src/main/java/net/minecraft/server/PlayerChunk.java @@ -0,0 +1,167 @@ +package net.minecraft.server; + +import java.util.ArrayList; +import java.util.List; + +class PlayerChunk { + + private final List b; + private final ChunkCoordIntPair location; + private short[] dirtyBlocks; + private int dirtyCount; + private int f; + private boolean loaded = false; // CraftBukkit + + final PlayerChunkMap playerChunkMap; + + public PlayerChunk(PlayerChunkMap playerchunkmap, int i, int j) { + this.playerChunkMap = playerchunkmap; + this.b = new ArrayList(); + this.dirtyBlocks = new short[64]; + this.dirtyCount = 0; + this.location = new ChunkCoordIntPair(i, j); + // CraftBukkit start + playerchunkmap.a().chunkProviderServer.getChunkAt(i, j, new Runnable() { + public void run() { + PlayerChunk.this.loaded = true; + } + }); + } + + public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument + if (this.b.contains(entityplayer)) { + throw new IllegalStateException("Failed to add player. " + entityplayer + " already is in chunk " + this.location.x + ", " + this.location.z); + } else { + this.b.add(entityplayer); + + // CraftBukkit start + if (this.loaded) { + entityplayer.chunkCoordIntPairQueue.add(this.location); + } else { + // Abuse getChunkAt to add another callback + this.playerChunkMap.a().chunkProviderServer.getChunkAt(this.location.x, this.location.z, new Runnable() { + public void run() { + entityplayer.chunkCoordIntPairQueue.add(PlayerChunk.this.location); + } + }); + } + // CraftBukkit end + } + } + + public void b(EntityPlayer entityplayer) { + if (this.b.contains(entityplayer)) { + entityplayer.playerConnection.sendPacket(new Packet51MapChunk(PlayerChunkMap.a(this.playerChunkMap).getChunkAt(this.location.x, this.location.z), true, 0)); + this.b.remove(entityplayer); + entityplayer.chunkCoordIntPairQueue.remove(this.location); + if (this.b.isEmpty()) { + long i = (long) this.location.x + 2147483647L | (long) this.location.z + 2147483647L << 32; + + PlayerChunkMap.b(this.playerChunkMap).remove(i); + if (this.dirtyCount > 0) { + PlayerChunkMap.c(this.playerChunkMap).remove(this); + } + + this.playerChunkMap.a().chunkProviderServer.queueUnload(this.location.x, this.location.z); + } + } + } + + public void a(int i, int j, int k) { + if (this.dirtyCount == 0) { + PlayerChunkMap.c(this.playerChunkMap).add(this); + } + + this.f |= 1 << (j >> 4); + if (this.dirtyCount < 64) { + short short1 = (short) (i << 12 | k << 8 | j); + + for (int l = 0; l < this.dirtyCount; ++l) { + if (this.dirtyBlocks[l] == short1) { + return; + } + } + + this.dirtyBlocks[this.dirtyCount++] = short1; + } + } + + public void sendAll(Packet packet) { + for (int i = 0; i < this.b.size(); ++i) { + EntityPlayer entityplayer = (EntityPlayer) this.b.get(i); + + if (!entityplayer.chunkCoordIntPairQueue.contains(this.location)) { + entityplayer.playerConnection.sendPacket(packet); + } + } + } + + public void a() { + if (this.dirtyCount != 0) { + int i; + int j; + int k; + + if (this.dirtyCount == 1) { + i = this.location.x * 16 + (this.dirtyBlocks[0] >> 12 & 15); + j = this.dirtyBlocks[0] & 255; + k = this.location.z * 16 + (this.dirtyBlocks[0] >> 8 & 15); + this.sendAll(new Packet53BlockChange(i, j, k, PlayerChunkMap.a(this.playerChunkMap))); + if (PlayerChunkMap.a(this.playerChunkMap).isTileEntity(i, j, k)) { + this.sendTileEntity(PlayerChunkMap.a(this.playerChunkMap).getTileEntity(i, j, k)); + } + } else { + int l; + + if (this.dirtyCount == 64) { + i = this.location.x * 16; + j = this.location.z * 16; + this.sendAll(new Packet51MapChunk(PlayerChunkMap.a(this.playerChunkMap).getChunkAt(this.location.x, this.location.z), (this.f == 0xFFFF), this.f)); // CraftBukkit - send everything (including biome) if all sections flagged + + for (k = 0; k < 16; ++k) { + if ((this.f & 1 << k) != 0) { + l = k << 4; + List list = PlayerChunkMap.a(this.playerChunkMap).getTileEntities(i, l, j, i + 16, l + 16, j + 16); + + for (int i1 = 0; i1 < list.size(); ++i1) { + this.sendTileEntity((TileEntity) list.get(i1)); + } + } + } + } else { + this.sendAll(new Packet52MultiBlockChange(this.location.x, this.location.z, this.dirtyBlocks, this.dirtyCount, PlayerChunkMap.a(this.playerChunkMap))); + + for (i = 0; i < this.dirtyCount; ++i) { + j = this.location.x * 16 + (this.dirtyBlocks[i] >> 12 & 15); + k = this.dirtyBlocks[i] & 255; + l = this.location.z * 16 + (this.dirtyBlocks[i] >> 8 & 15); + if (PlayerChunkMap.a(this.playerChunkMap).isTileEntity(j, k, l)) { + this.sendTileEntity(PlayerChunkMap.a(this.playerChunkMap).getTileEntity(j, k, l)); + } + } + } + } + + this.dirtyCount = 0; + this.f = 0; + } + } + + private void sendTileEntity(TileEntity tileentity) { + if (tileentity != null) { + Packet packet = tileentity.getUpdatePacket(); + + if (packet != null) { + this.sendAll(packet); + } + } + } + + static ChunkCoordIntPair a(PlayerChunk playerchunk) { + return playerchunk.location; + } + + static List b(PlayerChunk playerchunk) { + return playerchunk.b; + } +} |