mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 02:20:01 +03:00
200 lines
9.3 KiB
Diff
200 lines
9.3 KiB
Diff
--- ../src-base/minecraft/net/minecraft/server/management/PlayerChunkMapEntry.java
|
|
+++ ../src-work/minecraft/net/minecraft/server/management/PlayerChunkMapEntry.java
|
|
@@ -23,21 +23,30 @@
|
|
{
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
private final PlayerChunkMap playerChunkMap;
|
|
- private final List<EntityPlayerMP> players = Lists.<EntityPlayerMP>newArrayList();
|
|
+ public final List<EntityPlayerMP> players = Lists.<EntityPlayerMP>newArrayList();
|
|
private final ChunkPos pos;
|
|
private short[] changedBlocks = new short[64];
|
|
@Nullable
|
|
- private Chunk chunk;
|
|
+ public Chunk chunk;
|
|
private int changes;
|
|
private int changedSectionFilter;
|
|
private long lastUpdateInhabitedTime;
|
|
private boolean sentToPlayers;
|
|
+ private Runnable loadedRunnable = new Runnable()
|
|
+ {
|
|
+ public void run()
|
|
+ {
|
|
+ PlayerChunkMapEntry.this.chunk = PlayerChunkMapEntry.this.playerChunkMap.getWorldServer().getChunkProvider().loadChunk(PlayerChunkMapEntry.this.pos.x, PlayerChunkMapEntry.this.pos.z);
|
|
+ PlayerChunkMapEntry.this.loading = false;
|
|
+ }
|
|
+ };
|
|
+ private boolean loading = true;
|
|
|
|
public PlayerChunkMapEntry(PlayerChunkMap mapIn, int chunkX, int chunkZ)
|
|
{
|
|
this.playerChunkMap = mapIn;
|
|
this.pos = new ChunkPos(chunkX, chunkZ);
|
|
- this.chunk = mapIn.getWorldServer().getChunkProvider().loadChunk(chunkX, chunkZ);
|
|
+ mapIn.getWorldServer().getChunkProvider().loadChunk(chunkX, chunkZ, this.loadedRunnable);
|
|
}
|
|
|
|
public ChunkPos getPos()
|
|
@@ -63,6 +72,8 @@
|
|
if (this.sentToPlayers)
|
|
{
|
|
this.sendToPlayer(player);
|
|
+ // chunk watch event - the chunk is ready
|
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.Watch(this.chunk, player));
|
|
}
|
|
}
|
|
}
|
|
@@ -71,6 +82,20 @@
|
|
{
|
|
if (this.players.contains(player))
|
|
{
|
|
+ // If we haven't loaded yet don't load the chunk just so we can clean it up
|
|
+ if (this.chunk == null)
|
|
+ {
|
|
+ this.players.remove(player);
|
|
+
|
|
+ if (this.players.isEmpty())
|
|
+ {
|
|
+ if (this.loading) net.minecraftforge.common.chunkio.ChunkIOExecutor.dropQueuedChunkLoad(this.playerChunkMap.getWorldServer(), this.pos.x, this.pos.z, this.loadedRunnable);
|
|
+ this.playerChunkMap.removeEntry(this);
|
|
+ }
|
|
+
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (this.sentToPlayers)
|
|
{
|
|
player.connection.sendPacket(new SPacketUnloadChunk(this.pos.x, this.pos.z));
|
|
@@ -78,6 +103,8 @@
|
|
|
|
this.players.remove(player);
|
|
|
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.UnWatch(this.chunk, player));
|
|
+
|
|
if (this.players.isEmpty())
|
|
{
|
|
this.playerChunkMap.removeEntry(this);
|
|
@@ -87,6 +114,7 @@
|
|
|
|
public boolean providePlayerChunk(boolean canGenerate)
|
|
{
|
|
+ if (this.loading) return false;
|
|
if (this.chunk != null)
|
|
{
|
|
return true;
|
|
@@ -125,12 +153,15 @@
|
|
this.changes = 0;
|
|
this.changedSectionFilter = 0;
|
|
this.sentToPlayers = true;
|
|
+ if (this.players.isEmpty()) return true; // Forge: fix MC-120780
|
|
Packet<?> packet = new SPacketChunkData(this.chunk, 65535);
|
|
|
|
for (EntityPlayerMP entityplayermp : this.players)
|
|
{
|
|
entityplayermp.connection.sendPacket(packet);
|
|
this.playerChunkMap.getWorldServer().getEntityTracker().sendLeashedEntitiesInChunk(entityplayermp, this.chunk);
|
|
+ // chunk watch event - delayed to here as the chunk wasn't ready in addPlayer
|
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkWatchEvent.Watch(this.chunk, entityplayermp));
|
|
}
|
|
|
|
return true;
|
|
@@ -169,7 +200,7 @@
|
|
|
|
this.changedSectionFilter |= 1 << (y >> 4);
|
|
|
|
- if (this.changes < 64)
|
|
+ //Forge; Cache everything, so always run
|
|
{
|
|
short short1 = (short)(x << 12 | z << 8 | y);
|
|
|
|
@@ -180,7 +211,8 @@
|
|
return;
|
|
}
|
|
}
|
|
-
|
|
+ if (this.changes == this.changedBlocks.length)
|
|
+ this.changedBlocks = java.util.Arrays.copyOf(this.changedBlocks, this.changedBlocks.length << 1);
|
|
this.changedBlocks[this.changes++] = short1;
|
|
}
|
|
}
|
|
@@ -197,6 +229,7 @@
|
|
}
|
|
}
|
|
|
|
+ @SuppressWarnings("unused")
|
|
public void update()
|
|
{
|
|
if (this.sentToPlayers && this.chunk != null)
|
|
@@ -210,28 +243,57 @@
|
|
int k = (this.changedBlocks[0] >> 8 & 15) + this.pos.z * 16;
|
|
BlockPos blockpos = new BlockPos(i, j, k);
|
|
this.sendPacket(new SPacketBlockChange(this.playerChunkMap.getWorldServer(), blockpos));
|
|
+ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos);
|
|
|
|
- if (this.playerChunkMap.getWorldServer().getBlockState(blockpos).getBlock().hasTileEntity())
|
|
+ if (state.getBlock().hasTileEntity(state))
|
|
{
|
|
this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos));
|
|
}
|
|
}
|
|
- else if (this.changes == 64)
|
|
+ else if (this.changes >= net.minecraftforge.common.ForgeModContainer.clumpingThreshold)
|
|
{
|
|
- this.sendPacket(new SPacketChunkData(this.chunk, this.changedSectionFilter));
|
|
+ //TODO: FDix Mojang's fuckup to modded by combining all TE data into the chunk data packet... seriously... packet size explosion!
|
|
+ try {
|
|
+ this.sendPacket(new SPacketChunkData(this.chunk, this.changedSectionFilter));
|
|
+ }catch (Throwable throwable) { // If out of buffer, try resend packet;
|
|
+ try {
|
|
+ this.sendPacket(new SPacketMultiBlockChange(this.changes, this.changedBlocks, this.chunk));
|
|
+ //} Keep this in the else until we figure out a fix for mojang's derpitude on the data packet so we don't double send crap.
|
|
+ //{// Forge: Send only the tile entities that are updated, Adding this brace lets us keep the indent and the patch small
|
|
+ for (int l = 0; l < this.changes; ++l)
|
|
+ {
|
|
+ int i1 = (this.changedBlocks[l] >> 12 & 15) + this.pos.x * 16;
|
|
+ int j1 = this.changedBlocks[l] & 255;
|
|
+ int k1 = (this.changedBlocks[l] >> 8 & 15) + this.pos.z * 16;
|
|
+ BlockPos blockpos1 = new BlockPos(i1, j1, k1);
|
|
+ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos1);
|
|
+
|
|
+ if (state.getBlock().hasTileEntity(state))
|
|
+ {
|
|
+ this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos1));
|
|
+ }
|
|
+ }
|
|
+ }catch (Throwable throwable1) {
|
|
+ throwable1.printStackTrace();
|
|
+ return;
|
|
+ //Don't Reset the change blocks. next tick send it
|
|
+ }
|
|
+ }
|
|
}
|
|
else
|
|
{
|
|
this.sendPacket(new SPacketMultiBlockChange(this.changes, this.changedBlocks, this.chunk));
|
|
-
|
|
+ //} Keep this in the else until we figure out a fix for mojang's derpitude on the data packet so we don't double send crap.
|
|
+ //{// Forge: Send only the tile entities that are updated, Adding this brace lets us keep the indent and the patch small
|
|
for (int l = 0; l < this.changes; ++l)
|
|
{
|
|
int i1 = (this.changedBlocks[l] >> 12 & 15) + this.pos.x * 16;
|
|
int j1 = this.changedBlocks[l] & 255;
|
|
int k1 = (this.changedBlocks[l] >> 8 & 15) + this.pos.z * 16;
|
|
BlockPos blockpos1 = new BlockPos(i1, j1, k1);
|
|
+ net.minecraft.block.state.IBlockState state = this.playerChunkMap.getWorldServer().getBlockState(blockpos1);
|
|
|
|
- if (this.playerChunkMap.getWorldServer().getBlockState(blockpos1).getBlock().hasTileEntity())
|
|
+ if (state.getBlock().hasTileEntity(state))
|
|
{
|
|
this.sendBlockEntity(this.playerChunkMap.getWorldServer().getTileEntity(blockpos1));
|
|
}
|
|
@@ -311,4 +373,9 @@
|
|
|
|
return d0;
|
|
}
|
|
+
|
|
+ public List<EntityPlayerMP> getWatchingPlayers()
|
|
+ {
|
|
+ return isSentToPlayers() ? java.util.Collections.unmodifiableList(players) : java.util.Collections.emptyList();
|
|
+ }
|
|
}
|