Fix sponge packet sending

This commit is contained in:
Jesse Boyd 2016-05-21 02:05:16 +10:00
parent cf3dd6eb31
commit 408f690d80
3 changed files with 173 additions and 71 deletions

View File

@ -436,39 +436,27 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
}
}
}
for (EntityPlayer player : players) {
player.playerConnection.networkManager.a();
}
// Send chunks
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65535);
for (EntityPlayer player : players) {
player.playerConnection.sendPacket(packet);
}
// send ents
for (List<Entity> slice : entitieSlices) {
if (slice == null) {
continue;
}
for (Entity ent : slice) {
EntityTrackerEntry entry = tracker.trackedEntities.get(ent.getId());
if (entry == null) {
continue;
}
try {
TaskManager.IMP.later(new Runnable() {
@Override
public void run() {
for (EntityPlayer player : players) {
boolean result = entry.trackedPlayers.remove(player);
if (result && ent != player) {
entry.updatePlayer(player);
}
for (EntityTrackerEntry entry : entities) {
try {
TaskManager.IMP.later(new Runnable() {
@Override
public void run() {
for (EntityPlayer player : players) {
boolean result = entry.trackedPlayers.remove(player);
if (result && entry.tracker != player) {
entry.updatePlayer(player);
}
}
}, 2);
} catch (Throwable e) {
MainUtil.handleError(e);
}
}
}, 2);
} catch (Throwable e) {
MainUtil.handleError(e);
}
}
} catch (Throwable e) {

View File

@ -11,6 +11,7 @@ import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag;
@ -28,24 +29,27 @@ import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityTracker;
import net.minecraft.entity.EntityTrackerEntry;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.play.server.S13PacketDestroyEntities;
import net.minecraft.network.play.server.S21PacketChunkData;
import net.minecraft.server.management.PlayerManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ClassInheritanceMultiMap;
import net.minecraft.util.IntHashMap;
import net.minecraft.util.LongHashMap;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.gen.ChunkProviderServer;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.world.chunk.Chunk, ExtendedBlockStorage[], char[]> {
@ -96,29 +100,81 @@ public class SpongeQueue_1_8 extends NMSMappedFaweQueue<World, net.minecraft.wor
}
@Override
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk chunk) {
if (!chunk.isLoaded()) {
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk nmsChunk) {
if (!nmsChunk.isLoaded()) {
return;
}
int cx = chunk.xPosition;
int cz = chunk.zPosition;
for (Player player : Sponge.getServer().getOnlinePlayers()) {
if (!player.getWorld().equals(world)) {
continue;
try {
ChunkCoordIntPair pos = nmsChunk.getChunkCoordIntPair();
WorldServer w = (WorldServer) nmsChunk.getWorld();
PlayerManager chunkMap = w.getPlayerManager();
int x = pos.chunkXPos;
int z = pos.chunkZPos;
if (!chunkMap.hasPlayerInstance(x, z)) {
return;
}
int view = player.getViewDistance();
EntityPlayerMP nmsPlayer = (EntityPlayerMP) player;
Location<World> loc = player.getLocation();
int px = loc.getBlockX() >> 4;
int pz = loc.getBlockZ() >> 4;
int dx = Math.abs(cx - (loc.getBlockX() >> 4));
int dz = Math.abs(cz - (loc.getBlockZ() >> 4));
if ((dx > view) || (dz > view)) {
continue;
EntityTracker tracker = w.getEntityTracker();
HashSet<EntityPlayerMP> players = new HashSet<>();
for (EntityPlayer player : w.playerEntities) {
if (player instanceof EntityPlayerMP) {
if (chunkMap.isPlayerWatchingChunk((EntityPlayerMP) player, x, z)) {
players.add((EntityPlayerMP) player);
}
}
}
NetHandlerPlayServer con = nmsPlayer.playerNetServerHandler;
net.minecraft.world.chunk.Chunk nmsChunk = (net.minecraft.world.chunk.Chunk) chunk;
con.sendPacket(new S21PacketChunkData(chunk, false, 65535));
if (players.size() == 0) {
return;
}
HashSet<EntityTrackerEntry> entities = new HashSet<>();
ClassInheritanceMultiMap<Entity>[] entitieSlices = nmsChunk.getEntityLists();
IntHashMap<EntityTrackerEntry> entries = null;
for (Field field : tracker.getClass().getDeclaredFields()) {
if (field.getType() == IntHashMap.class) {
field.setAccessible(true);
entries = (IntHashMap<EntityTrackerEntry>) field.get(tracker);
}
}
for (ClassInheritanceMultiMap<Entity> slice : entitieSlices) {
if (slice == null) {
continue;
}
for (Entity ent : slice) {
EntityTrackerEntry entry = entries != null ? entries.lookup(ent.getEntityId()) : null;
if (entry == null) {
continue;
}
entities.add(entry);
S13PacketDestroyEntities packet = new S13PacketDestroyEntities(ent.getEntityId());
for (EntityPlayerMP player : players) {
player.playerNetServerHandler.sendPacket(packet);
}
}
}
// Send chunks
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65535);
for (EntityPlayerMP player : players) {
player.playerNetServerHandler.sendPacket(packet);
}
// send ents
for (EntityTrackerEntry entry : entities) {
try {
TaskManager.IMP.later(new Runnable() {
@Override
public void run() {
for (EntityPlayerMP player : players) {
boolean result = entry.trackingPlayers.remove(player);
if (result && entry.trackedEntity != player) {
entry.updatePlayerEntity(player);
}
}
}
}, 2);
} catch (Throwable e) {
MainUtil.handleError(e);
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}
}

View File

@ -9,25 +9,35 @@ import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.PseudoRandom;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityTracker;
import net.minecraft.entity.EntityTrackerEntry;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.play.server.S13PacketDestroyEntities;
import net.minecraft.network.play.server.S21PacketChunkData;
import net.minecraft.server.management.PlayerManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ClassInheritanceMultiMap;
import net.minecraft.util.IntHashMap;
import net.minecraft.util.LongHashMap;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
@ -35,9 +45,7 @@ import net.minecraft.world.gen.ChunkProviderServer;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.Chunk;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.extent.UnmodifiableBlockVolume;
import org.spongepowered.api.world.extent.worker.MutableBlockVolumeWorker;
@ -58,31 +66,81 @@ public class SpongeQueue_ALL extends NMSMappedFaweQueue<World, net.minecraft.wor
}
@Override
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk chunk) {
if (!chunk.isLoaded()) {
public void refreshChunk(World world, net.minecraft.world.chunk.Chunk nmsChunk) {
if (!nmsChunk.isLoaded()) {
return;
}
int cx = chunk.xPosition;
int cz = chunk.zPosition;
for (Player player : Sponge.getServer().getOnlinePlayers()) {
if (!player.getWorld().equals(world)) {
continue;
try {
ChunkCoordIntPair pos = nmsChunk.getChunkCoordIntPair();
WorldServer w = (WorldServer) nmsChunk.getWorld();
PlayerManager chunkMap = w.getPlayerManager();
int x = pos.chunkXPos;
int z = pos.chunkZPos;
if (!chunkMap.hasPlayerInstance(x, z)) {
return;
}
int view = player.getViewDistance();
EntityPlayerMP nmsPlayer = (EntityPlayerMP) player;
Location<World> loc = player.getLocation();
int px = loc.getBlockX() >> 4;
int pz = loc.getBlockZ() >> 4;
int dx = Math.abs(cx - (loc.getBlockX() >> 4));
int dz = Math.abs(cz - (loc.getBlockZ() >> 4));
if ((dx > view) || (dz > view)) {
continue;
EntityTracker tracker = w.getEntityTracker();
HashSet<EntityPlayerMP> players = new HashSet<>();
for (EntityPlayer player : w.playerEntities) {
if (player instanceof EntityPlayerMP) {
if (chunkMap.isPlayerWatchingChunk((EntityPlayerMP) player, x, z)) {
players.add((EntityPlayerMP) player);
}
}
}
NetHandlerPlayServer con = nmsPlayer.playerNetServerHandler;
net.minecraft.world.chunk.Chunk nmsChunk = (net.minecraft.world.chunk.Chunk) chunk;
con.sendPacket(new S21PacketChunkData(nmsChunk, false, 65535));
// Try sending true, 0 first
// Try bulk chunk packet
if (players.size() == 0) {
return;
}
HashSet<EntityTrackerEntry> entities = new HashSet<>();
ClassInheritanceMultiMap<Entity>[] entitieSlices = nmsChunk.getEntityLists();
IntHashMap<EntityTrackerEntry> entries = null;
for (Field field : tracker.getClass().getDeclaredFields()) {
if (field.getType() == IntHashMap.class) {
field.setAccessible(true);
entries = (IntHashMap<EntityTrackerEntry>) field.get(tracker);
}
}
for (ClassInheritanceMultiMap<Entity> slice : entitieSlices) {
if (slice == null) {
continue;
}
for (Entity ent : slice) {
EntityTrackerEntry entry = entries != null ? entries.lookup(ent.getEntityId()) : null;
if (entry == null) {
continue;
}
entities.add(entry);
S13PacketDestroyEntities packet = new S13PacketDestroyEntities(ent.getEntityId());
for (EntityPlayerMP player : players) {
player.playerNetServerHandler.sendPacket(packet);
}
}
}
// Send chunks
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65535);
for (EntityPlayerMP player : players) {
player.playerNetServerHandler.sendPacket(packet);
}
// send ents
for (EntityTrackerEntry entry : entities) {
try {
TaskManager.IMP.later(new Runnable() {
@Override
public void run() {
for (EntityPlayerMP player : players) {
boolean result = entry.trackingPlayers.remove(player);
if (result && entry.trackedEntity != player) {
entry.updatePlayerEntity(player);
}
}
}
}, 2);
} catch (Throwable e) {
MainUtil.handleError(e);
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}
}