ahahaha
This commit is contained in:
parent
762263ebe8
commit
40f1bec4cb
|
@ -1,111 +0,0 @@
|
||||||
package com.elevatemc.spigot.visuals;
|
|
||||||
|
|
||||||
import net.minecraft.server.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a custom entity tracker made for the cannoning entities tnt and sand.
|
|
||||||
* The goal behind this is to reduce packets and logic without hiding entities.
|
|
||||||
* It may not completely replicate the original behavior, but it should make up
|
|
||||||
* for that with it's advantages.
|
|
||||||
* Source: IonSpigot
|
|
||||||
*/
|
|
||||||
public class CannonTrackerEntry extends EntityTrackerEntry {
|
|
||||||
|
|
||||||
private boolean movingX;
|
|
||||||
private boolean movingY;
|
|
||||||
private boolean movingZ;
|
|
||||||
|
|
||||||
private double updateX;
|
|
||||||
private double updateY;
|
|
||||||
private double updateZ;
|
|
||||||
|
|
||||||
public CannonTrackerEntry(Entity entity, int i, int j, boolean flag) {
|
|
||||||
super(entity, i, j, flag);
|
|
||||||
this.movingX = entity.motX != 0.0;
|
|
||||||
this.movingY = true;
|
|
||||||
this.movingZ = entity.motZ != 0.0;
|
|
||||||
this.updateX = entity.locX;
|
|
||||||
this.updateY = entity.locY;
|
|
||||||
this.updateZ = entity.locZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void track(List<EntityHuman> list) {
|
|
||||||
boolean motionX = this.tracker.motX != 0.0;
|
|
||||||
boolean motionY = this.tracker.motY != 0.0;
|
|
||||||
boolean motionZ = this.tracker.motZ != 0.0;
|
|
||||||
|
|
||||||
// This tracked entities motion has changed or an explosion has occurred, update it!
|
|
||||||
if (!this.tracker.ai && motionX == movingX && motionY == movingY && motionZ == movingZ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This entity has moved 4 blocks since the last update, search for players
|
|
||||||
if (this.tracker.e(updateX, updateY, updateZ) > 16.0D) {
|
|
||||||
this.scanPlayers(list);
|
|
||||||
this.updateX = this.tracker.locX;
|
|
||||||
this.updateY = this.tracker.locY;
|
|
||||||
this.updateZ = this.tracker.locZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update nearby players, only resynchronise when motion is updated
|
|
||||||
if (motionX || motionY || motionZ) {
|
|
||||||
this.broadcastUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep what of which axis the entity is moving on
|
|
||||||
this.tracker.ai = false;
|
|
||||||
this.movingX = motionX;
|
|
||||||
this.movingY = motionY;
|
|
||||||
this.movingZ = motionZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void broadcastUpdate() {
|
|
||||||
DataWatcher datawatcher = this.tracker.getDataWatcher();
|
|
||||||
|
|
||||||
if (datawatcher.a()) {
|
|
||||||
this.broadcastIncludingSelf(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only update location on movement
|
|
||||||
if (this.tracker.lastX != this.tracker.locX || this.tracker.lastY != this.tracker.locY || this.tracker.lastZ != this.tracker.locZ) {
|
|
||||||
this.broadcast(new PacketPlayOutEntityTeleport(this.tracker));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.broadcast(new PacketPlayOutEntityVelocity(this.tracker));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePlayer(EntityPlayer entityplayer) {
|
|
||||||
// Check configurable distance as a cube then visible distance.
|
|
||||||
if (this.c(entityplayer) && this.tracker.h(entityplayer) < 4096.0D) {
|
|
||||||
if (this.trackedPlayers.contains(entityplayer) || (!this.e(entityplayer) && !this.tracker.attachedToPlayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entityplayer.removeQueue.remove(this.tracker.getId());
|
|
||||||
|
|
||||||
this.trackedPlayerMap.put(entityplayer, true); // Paper
|
|
||||||
Packet packet = this.c(); // IonSpigot
|
|
||||||
if (packet == null) return; // IonSpigot - If it's null don't update the client!
|
|
||||||
|
|
||||||
entityplayer.playerConnection.sendPacket(packet);
|
|
||||||
|
|
||||||
if (this.tracker.getCustomNameVisible()) {
|
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(this.tracker.getId(), this.tracker.getDataWatcher(), true));
|
|
||||||
}
|
|
||||||
|
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.tracker.motX, this.tracker.motY, this.tracker.motZ));
|
|
||||||
|
|
||||||
if (this.tracker.vehicle != null) {
|
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle));
|
|
||||||
}
|
|
||||||
} else if (this.trackedPlayers.contains(entityplayer)) {
|
|
||||||
this.trackedPlayers.remove(entityplayer);
|
|
||||||
entityplayer.d(this.tracker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -247,75 +247,54 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.chunkCoordIntPairQueue.isEmpty()) {
|
if (!this.chunkCoordIntPairQueue.isEmpty()) {
|
||||||
ArrayList<Chunk> chunkList = Lists.newArrayList();
|
ArrayList arraylist = Lists.newArrayList();
|
||||||
Iterator<ChunkCoordIntPair> chunksToLoad = this.chunkCoordIntPairQueue.iterator();
|
Iterator iterator1 = this.chunkCoordIntPairQueue.iterator();
|
||||||
ArrayList<TileEntity> tileEntities = Lists.newArrayList();
|
ArrayList arraylist1 = Lists.newArrayList();
|
||||||
|
|
||||||
Chunk chunk = null;
|
Chunk chunk;
|
||||||
|
|
||||||
while (chunksToLoad.hasNext() && chunkList.size() < this.world.spigotConfig.maxBulkChunk) { // Spigot
|
while (iterator1.hasNext() && arraylist.size() < this.world.spigotConfig.maxBulkChunk) { // Spigot
|
||||||
ChunkCoordIntPair chunkcoordintpair = chunksToLoad.next();
|
ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator1.next();
|
||||||
|
|
||||||
if (chunkcoordintpair != null) {
|
if (chunkcoordintpair != null) {
|
||||||
if (this.world.isLoaded(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)) {// [Nacho-0024] Do not create new BlockPosition when loading chunk
|
if (this.world.isLoaded(new BlockPosition(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4))) {
|
||||||
chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z);
|
chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z);
|
||||||
if (chunk.isReady()) {
|
if (chunk.isReady()) {
|
||||||
chunkList.add(chunk);
|
arraylist.add(chunk);
|
||||||
tileEntities.addAll(chunk.tileEntities.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world
|
arraylist1.addAll(chunk.tileEntities.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world
|
||||||
chunksToLoad.remove();
|
iterator1.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chunksToLoad.remove();
|
iterator1.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chunkList.isEmpty()) {
|
if (!arraylist.isEmpty()) {
|
||||||
if (chunkList.size() == 1) {
|
if (arraylist.size() == 1) {
|
||||||
this.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunkList.get(0), true, '\uffff'));
|
this.playerConnection.sendPacket(new PacketPlayOutMapChunk((Chunk) arraylist.get(0), true, '\uffff'));
|
||||||
} else {
|
} else {
|
||||||
this.playerConnection.sendPacket(new PacketPlayOutMapChunkBulk(chunkList));
|
this.playerConnection.sendPacket(new PacketPlayOutMapChunkBulk(arraylist));
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator<TileEntity> tileEntitiesIterator = tileEntities.iterator();
|
Iterator iterator2 = arraylist1.iterator();
|
||||||
|
|
||||||
while (tileEntitiesIterator.hasNext()) {
|
while (iterator2.hasNext()) {
|
||||||
TileEntity tileentity = tileEntitiesIterator.next();
|
TileEntity tileentity = (TileEntity) iterator2.next();
|
||||||
|
|
||||||
this.a(tileentity);
|
this.a(tileentity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// //Nacho - if there are a lot of entities, we end up scanning the WHOLE list of entities multiple times
|
iterator2 = arraylist.iterator();
|
||||||
// // Which isn't the best if we have 100 players doing that
|
|
||||||
// So instead of updating all entities by chunk, we update all entities at once with a hashset of chunks
|
|
||||||
// This means we don't have to pass over the list x chunks
|
|
||||||
// o(chunk * entityList) => o(entitylist)
|
|
||||||
|
|
||||||
// Iterator<Chunk> chunkIterator = chunkList.iterator();
|
while (iterator2.hasNext()) {
|
||||||
// while (chunkIterator.hasNext())
|
chunk = (Chunk) iterator2.next();
|
||||||
// {
|
this.u().getTracker().a(this, chunk);
|
||||||
// chunk = (Chunk) chunkIterator.next();
|
|
||||||
// this.u().getTracker().a(this, chunk);
|
|
||||||
// }
|
|
||||||
// Nacho - end
|
|
||||||
|
|
||||||
LongOpenHashSet chunkPosSet = new LongOpenHashSet(chunkList.size());
|
|
||||||
for (Chunk newChunk : chunkList)
|
|
||||||
chunkPosSet.add(this.chunkToLong(newChunk.locX, newChunk.locZ));
|
|
||||||
|
|
||||||
Iterator<EntityTrackerEntry> trackerEntryIterator = this.u().getTracker().getEntityTrackerEntries();
|
|
||||||
while (trackerEntryIterator.hasNext())
|
|
||||||
{
|
|
||||||
EntityTrackerEntry entitytrackerentry = trackerEntryIterator.next();
|
|
||||||
|
|
||||||
if (entitytrackerentry.tracker != this && chunkPosSet.contains(this.chunkToLong(entitytrackerentry.tracker.ae, entitytrackerentry.tracker.ag)))
|
|
||||||
{
|
|
||||||
entitytrackerentry.updatePlayer(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Entity entity = this.C();
|
Entity entity = this.C();
|
||||||
|
|
||||||
if (entity != this) {
|
if (entity != this) {
|
||||||
|
|
|
@ -1,34 +1,21 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
import com.elevatemc.spigot.config.eSpigotConfig;
|
|
||||||
import com.elevatemc.spigot.visuals.CannonTrackerEntry;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import com.elevatemc.spigot.util.SynchronizedIntHashMap;
|
|
||||||
import com.elevatemc.spigot.util.task.Task;
|
|
||||||
import com.elevatemc.spigot.util.task.impl.ThreadTaskExecutor;
|
|
||||||
|
|
||||||
public class EntityTracker {
|
public class EntityTracker {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final Logger a = LogManager.getLogger();
|
||||||
private static final ThreadTaskExecutor TASK_EXECUTOR = new ThreadTaskExecutor("EntityTracker");
|
private final WorldServer world;
|
||||||
|
private Set<EntityTrackerEntry> c = Sets.newConcurrentHashSet();
|
||||||
static {
|
public IntHashMap<EntityTrackerEntry> trackedEntities = new IntHashMap();
|
||||||
TASK_EXECUTOR.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private WorldServer world;
|
|
||||||
private Set<EntityTrackerEntry> c = Sets.newConcurrentHashSet(); // eSpigot - ConcurrentHashSet
|
|
||||||
public IntHashMap<EntityTrackerEntry> trackedEntities = new SynchronizedIntHashMap<>(); // eSpigot - Thread safe implementation of IntHashMap (SynchronizedIntHashMap)
|
|
||||||
private int e;
|
private int e;
|
||||||
|
|
||||||
public EntityTracker(WorldServer worldserver) {
|
public EntityTracker(WorldServer worldserver) {
|
||||||
|
@ -39,6 +26,16 @@ public class EntityTracker {
|
||||||
public void track(Entity entity) {
|
public void track(Entity entity) {
|
||||||
if (entity instanceof EntityPlayer) {
|
if (entity instanceof EntityPlayer) {
|
||||||
this.addEntity(entity, 512, 2);
|
this.addEntity(entity, 512, 2);
|
||||||
|
EntityPlayer entityplayer = (EntityPlayer) entity;
|
||||||
|
Iterator iterator = this.c.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||||
|
|
||||||
|
if (entitytrackerentry.tracker != entityplayer) {
|
||||||
|
entitytrackerentry.updatePlayerFor(entityplayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (entity instanceof EntityFishingHook) {
|
} else if (entity instanceof EntityFishingHook) {
|
||||||
this.addEntity(entity, 64, 5, true);
|
this.addEntity(entity, 64, 5, true);
|
||||||
} else if (entity instanceof EntityArrow) {
|
} else if (entity instanceof EntityArrow) {
|
||||||
|
@ -98,204 +95,161 @@ public class EntityTracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntity(Entity entity, int i, final int j, boolean flag) {
|
public void addEntity(Entity entity, int i, final int j, boolean flag) {
|
||||||
|
org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot
|
||||||
i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
|
i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
|
||||||
if (i > this.e) {
|
if (i > this.e) {
|
||||||
i = this.e;
|
i = this.e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.trackedEntities.b(entity.getId())) { // IntHashMap already contains entity id
|
try {
|
||||||
throw new IllegalStateException("Entity is already tracked!");
|
if (this.trackedEntities.b(entity.getId())) {
|
||||||
}
|
throw new IllegalStateException("Entity is already tracked!");
|
||||||
|
|
||||||
final int finalI = i; // CraftBukkit - fix decompile error
|
|
||||||
|
|
||||||
EntityTrackerEntry entitytrackerentry = createTracker(entity, i, j, flag); // IonSpigot
|
|
||||||
|
|
||||||
// We want to add them to these collections directly to ensure compatibility with plugins like Citizens
|
|
||||||
|
|
||||||
this.c.add(entitytrackerentry); // Add entity to entity tracker entries set
|
|
||||||
this.trackedEntities.a(entity.getId(), entitytrackerentry); // Add entity to trackedEntities collection
|
|
||||||
|
|
||||||
TASK_EXECUTOR.submit(executor -> {
|
|
||||||
try {
|
|
||||||
entitytrackerentry.scanPlayers(this.world.players); // Update all players in world,
|
|
||||||
// essentially the only method that would
|
|
||||||
// be heavy in this method is this method (EntityTrackerEntry#scanPlayers)
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
CrashReport crashreport = CrashReport.a(throwable, "Adding entity to track");
|
|
||||||
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track");
|
|
||||||
|
|
||||||
crashreportsystemdetails.a("Tracking range", finalI + " blocks");
|
|
||||||
crashreportsystemdetails.a("Update interval", new Callable() {
|
|
||||||
public String a() throws Exception {
|
|
||||||
String s = "Once per " + finalI + " ticks"; // CraftBukkit
|
|
||||||
|
|
||||||
if (finalI == Integer.MAX_VALUE) { // CraftBukkit
|
|
||||||
s = "Maximum (" + s + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object call() throws Exception {
|
|
||||||
return this.a();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
entity.appendEntityCrashDetails(crashreportsystemdetails);
|
|
||||||
CrashReportSystemDetails crashreportsystemdetails1 = crashreport.a("Entity That Is Already Tracked");
|
|
||||||
|
|
||||||
this.trackedEntities.get(entity.getId()).tracker.appendEntityCrashDetails(crashreportsystemdetails1);
|
|
||||||
|
|
||||||
try {
|
|
||||||
throw new ReportedException(crashreport);
|
|
||||||
} catch (ReportedException reportedexception) {
|
|
||||||
EntityTracker.LOGGER.error("\"Silently\" catching entity tracking error.", reportedexception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// IonSpigot start
|
EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(entity, i, j, flag);
|
||||||
private EntityTrackerEntry createTracker(Entity entity, int i, int j, boolean flag) {
|
|
||||||
if (entity.isCannoningEntity && eSpigotConfig.cannonTracker) {
|
this.c.add(entitytrackerentry);
|
||||||
return new CannonTrackerEntry(entity, i, j, flag);
|
this.trackedEntities.a(entity.getId(), entitytrackerentry);
|
||||||
} else {
|
entitytrackerentry.scanPlayers(this.world.players);
|
||||||
return new EntityTrackerEntry(entity, i, j, flag);
|
} catch (Throwable throwable) {
|
||||||
|
CrashReport crashreport = CrashReport.a(throwable, "Adding entity to track");
|
||||||
|
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track");
|
||||||
|
|
||||||
|
crashreportsystemdetails.a("Tracking range", (Object) (i + " blocks"));
|
||||||
|
final int finalI = i; // CraftBukkit - fix decompile error
|
||||||
|
crashreportsystemdetails.a("Update interval", new Callable() {
|
||||||
|
public String a() throws Exception {
|
||||||
|
String s = "Once per " + finalI + " ticks"; // CraftBukkit
|
||||||
|
|
||||||
|
if (finalI == Integer.MAX_VALUE) { // CraftBukkit
|
||||||
|
s = "Maximum (" + s + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object call() throws Exception {
|
||||||
|
return this.a();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
entity.appendEntityCrashDetails(crashreportsystemdetails);
|
||||||
|
CrashReportSystemDetails crashreportsystemdetails1 = crashreport.a("Entity That Is Already Tracked");
|
||||||
|
|
||||||
|
((EntityTrackerEntry) this.trackedEntities.get(entity.getId())).tracker.appendEntityCrashDetails(crashreportsystemdetails1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
throw new ReportedException(crashreport);
|
||||||
|
} catch (ReportedException reportedexception) {
|
||||||
|
EntityTracker.a.error("\"Silently\" catching entity tracking error.", reportedexception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// IonSpigot end
|
|
||||||
|
|
||||||
public void untrackEntity(Entity entity) {
|
public void untrackEntity(Entity entity) {
|
||||||
//org.spigotmc.AsyncCatcher.catchOp( "entity untrack"); // Spigot
|
org.spigotmc.AsyncCatcher.catchOp( "entity untrack"); // Spigot
|
||||||
boolean mainThread = Thread.currentThread() == MinecraftServer.getServer().primaryThread;
|
|
||||||
|
|
||||||
if (entity instanceof EntityPlayer) {
|
if (entity instanceof EntityPlayer) {
|
||||||
EntityPlayer entityplayer = (EntityPlayer) entity;
|
EntityPlayer entityplayer = (EntityPlayer) entity;
|
||||||
// The best way to go around reducing load on this method is by fully doing the iteration asynchronously
|
Iterator iterator = this.c.iterator();
|
||||||
// We honestly don't need to handle this asynchronously if the size of the entity tracker entry set
|
|
||||||
// Iterate through all entity tracker entries
|
|
||||||
|
|
||||||
if (this.c.size() < 20 || !mainThread)
|
while (iterator.hasNext()) {
|
||||||
for (EntityTrackerEntry entitytrackerentry : this.c)
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||||
entitytrackerentry.a(entityplayer); // Untrack entity
|
|
||||||
else {
|
entitytrackerentry.a(entityplayer);
|
||||||
TASK_EXECUTOR.submit(executor ->
|
|
||||||
{for(EntityTrackerEntry entityTrackerEntry : this.c){entityTrackerEntry.a(entityplayer);}});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTrackerEntry entitytrackerentry1 = this.trackedEntities.d(entity.getId());
|
EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) this.trackedEntities.d(entity.getId());
|
||||||
|
|
||||||
if (entitytrackerentry1 != null) {
|
if (entitytrackerentry1 != null) {
|
||||||
this.c.remove(entitytrackerentry1);
|
this.c.remove(entitytrackerentry1);
|
||||||
TASK_EXECUTOR.submit(executor -> entitytrackerentry1.a());
|
entitytrackerentry1.a();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Task updatePlayerTask = executor -> {
|
|
||||||
List<Entity> pending = Lists.newArrayList();
|
|
||||||
|
|
||||||
// Iterate through all entitytracker entries
|
|
||||||
for (EntityTrackerEntry entitytrackerentry : this.c) {
|
|
||||||
entitytrackerentry.track(this.world.players); // Ensure you're tracking them
|
|
||||||
if (entitytrackerentry.n && entitytrackerentry.tracker instanceof EntityPlayer) {
|
|
||||||
pending.add(entitytrackerentry.tracker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object o : pending) {
|
|
||||||
EntityPlayer entityplayer = (EntityPlayer) o;
|
|
||||||
|
|
||||||
for (EntityTrackerEntry entitytrackerentry1 : this.c) {
|
|
||||||
if (entitytrackerentry1.tracker != entityplayer) {
|
|
||||||
entitytrackerentry1.updatePlayer(entityplayer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void updatePlayers() {
|
public void updatePlayers() {
|
||||||
if (Bukkit.isPrimaryThread())
|
ArrayList arraylist = Lists.newArrayList();
|
||||||
TASK_EXECUTOR.submit(updatePlayerTask);
|
Iterator iterator = this.c.iterator();
|
||||||
else updatePlayerTask.onExecute(null); // It's already being ran async so no need to make sure it runs on a separate thread
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force update
|
while (iterator.hasNext()) {
|
||||||
public void a(EntityPlayer entityplayer) {
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||||
boolean mainThread = Thread.currentThread() == MinecraftServer.getServer().primaryThread;
|
|
||||||
|
|
||||||
Task task = executor -> {
|
entitytrackerentry.track(this.world.players);
|
||||||
for (EntityTrackerEntry entitytrackerentry : this.c) {
|
if (entitytrackerentry.n && entitytrackerentry.tracker instanceof EntityPlayer) {
|
||||||
if (entitytrackerentry.tracker == entityplayer) {
|
arraylist.add(entitytrackerentry.tracker);
|
||||||
entitytrackerentry.scanPlayers(this.world.players);
|
}
|
||||||
} else {
|
}
|
||||||
entitytrackerentry.updatePlayer(entityplayer);
|
|
||||||
|
for (int i = 0; i < arraylist.size(); ++i) {
|
||||||
|
EntityPlayer entityplayer = (EntityPlayer) arraylist.get(i);
|
||||||
|
Iterator iterator1 = this.c.iterator();
|
||||||
|
|
||||||
|
while (iterator1.hasNext()) {
|
||||||
|
EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) iterator1.next();
|
||||||
|
|
||||||
|
if (entitytrackerentry1.tracker != entityplayer) {
|
||||||
|
entitytrackerentry1.updatePlayerFor(entityplayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if (!mainThread)
|
|
||||||
task.onExecute(null);
|
|
||||||
else TASK_EXECUTOR.submit(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void a(Entity entity, Packet<?> packet) {
|
public void a(EntityPlayer entityplayer) {
|
||||||
// The packets being passed onto this method generally don't tend to make gameplay less smooth if it takes a 10L delay, so we can submit them to our TaskExecutor
|
Iterator iterator = this.c.iterator();
|
||||||
Task task = executor -> {
|
|
||||||
EntityTrackerEntry entitytrackerentry = this.trackedEntities.get(entity.getId());
|
|
||||||
|
|
||||||
if (entitytrackerentry != null) {
|
while (iterator.hasNext()) {
|
||||||
entitytrackerentry.broadcast(packet);
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||||
|
|
||||||
|
if (entitytrackerentry.tracker == entityplayer) {
|
||||||
|
entitytrackerentry.scanPlayers(this.world.players);
|
||||||
|
} else {
|
||||||
|
entitytrackerentry.updatePlayerFor(entityplayer);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if (!Bukkit.isPrimaryThread())
|
|
||||||
task.onExecute(null);
|
|
||||||
else TASK_EXECUTOR.submit(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendPacketToEntity(Entity entity, Packet<?> packet) { /* Used for entity animations & entity status packets, same reasoning for async as EntityTracker#a(Entity, Packet) method */
|
public void a(Entity entity, Packet packet) {
|
||||||
Task task = executor -> {
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) this.trackedEntities.get(entity.getId());
|
||||||
EntityTrackerEntry entitytrackerentry = this.trackedEntities.get(entity.getId());
|
|
||||||
|
|
||||||
if (entitytrackerentry != null)
|
if (entitytrackerentry != null) {
|
||||||
entitytrackerentry.broadcastIncludingSelf(packet);
|
entitytrackerentry.broadcast(packet);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendPacketToEntity(Entity entity, Packet packet) {
|
||||||
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) this.trackedEntities.get(entity.getId());
|
||||||
|
|
||||||
|
if (entitytrackerentry != null) {
|
||||||
|
entitytrackerentry.broadcastIncludingSelf(packet);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Bukkit.isPrimaryThread())
|
|
||||||
task.onExecute(null);
|
|
||||||
else TASK_EXECUTOR.submit(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void untrackPlayer(EntityPlayer entityplayer) {
|
public void untrackPlayer(EntityPlayer entityplayer) {
|
||||||
Task task = executor -> {
|
Iterator iterator = this.c.iterator();
|
||||||
for (EntityTrackerEntry entitytrackerentry : this.c)
|
|
||||||
entitytrackerentry.clear(entityplayer);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!Bukkit.isPrimaryThread())
|
while (iterator.hasNext()) {
|
||||||
task.onExecute(null);
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||||
else TASK_EXECUTOR.submit(task);
|
|
||||||
}
|
entitytrackerentry.clear(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
public Iterator<EntityTrackerEntry> getEntityTrackerEntries()
|
|
||||||
{
|
|
||||||
return this.c.iterator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void a(EntityPlayer entityplayer, Chunk chunk) {
|
public void a(EntityPlayer entityplayer, Chunk chunk) {
|
||||||
Task task = executor -> {
|
Iterator iterator = this.c.iterator();
|
||||||
for (EntityTrackerEntry entitytrackerentry : this.c) {
|
|
||||||
if (entitytrackerentry.tracker != entityplayer
|
while (iterator.hasNext()) {
|
||||||
&& entitytrackerentry.tracker.ae == chunk.locX
|
EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
|
||||||
&& entitytrackerentry.tracker.ag == chunk.locZ) {
|
|
||||||
entitytrackerentry.updatePlayer(entityplayer);
|
if (entitytrackerentry.tracker != entityplayer && entitytrackerentry.tracker.ae == chunk.locX && entitytrackerentry.tracker.ag == chunk.locZ) {
|
||||||
}
|
entitytrackerentry.updatePlayerFor(entityplayer);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if (!Bukkit.isPrimaryThread())
|
|
||||||
task.onExecute(null);
|
|
||||||
else TASK_EXECUTOR.submit(task);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,14 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.player.PlayerVelocityEvent;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.elevatemc.spigot.config.eSpigotConfig;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerVelocityEvent;
|
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
public class EntityTrackerEntry {
|
public class EntityTrackerEntry {
|
||||||
|
@ -41,7 +40,7 @@ public class EntityTrackerEntry {
|
||||||
// PaperSpigot start
|
// PaperSpigot start
|
||||||
// Replace trackedPlayers Set with a Map. The value is true until the player receives
|
// Replace trackedPlayers Set with a Map. The value is true until the player receives
|
||||||
// their first update (which is forced to have absolute coordinates), false afterward.
|
// their first update (which is forced to have absolute coordinates), false afterward.
|
||||||
public java.util.Map<EntityPlayer, Boolean> trackedPlayerMap = new ConcurrentHashMap<>(); // eSpigot - ConcurrentHashMap
|
public java.util.Map<EntityPlayer, Boolean> trackedPlayerMap = new ConcurrentHashMap<>();
|
||||||
public Set<EntityPlayer> trackedPlayers = trackedPlayerMap.keySet();
|
public Set<EntityPlayer> trackedPlayers = trackedPlayerMap.keySet();
|
||||||
// PaperSpigot end
|
// PaperSpigot end
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ public class EntityTrackerEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
return object instanceof EntityTrackerEntry && ((EntityTrackerEntry) object).tracker.getId() == this.tracker.getId();
|
return object instanceof EntityTrackerEntry ? ((EntityTrackerEntry) object).tracker.getId() == this.tracker.getId() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
@ -83,16 +82,17 @@ public class EntityTrackerEntry {
|
||||||
this.broadcast(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle));
|
this.broadcast(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tracker instanceof EntityItemFrame && this.m % 20 == 0) { // Paper
|
if (this.tracker instanceof EntityItemFrame /*&& this.m % 10 == 0*/) { // CraftBukkit - Moved below, should always enter this block
|
||||||
EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker;
|
EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker;
|
||||||
ItemStack itemstack = entityitemframe.getItem();
|
ItemStack itemstack = entityitemframe.getItem();
|
||||||
|
|
||||||
if (itemstack != null && itemstack.getItem() instanceof ItemWorldMap) { // Paper - moved back up
|
if (this.m % 10 == 0 && itemstack != null && itemstack.getItem() instanceof ItemWorldMap) { // CraftBukkit - Moved this.m % 10 logic here so item frames do not enter the other blocks
|
||||||
WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, this.tracker.world);
|
WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, this.tracker.world);
|
||||||
// CraftBukkit
|
Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit
|
||||||
|
|
||||||
for (EntityPlayer trackedPlayer : this.trackedPlayers) {
|
while (iterator.hasNext()) {
|
||||||
EntityPlayer entityplayer = trackedPlayer;
|
EntityHuman entityhuman = (EntityHuman) iterator.next();
|
||||||
|
EntityPlayer entityplayer = (EntityPlayer) entityhuman;
|
||||||
|
|
||||||
worldmap.a(entityplayer, itemstack);
|
worldmap.a(entityplayer, itemstack);
|
||||||
Packet packet = Items.FILLED_MAP.c(itemstack, this.tracker.world, entityplayer);
|
Packet packet = Items.FILLED_MAP.c(itemstack, this.tracker.world, entityplayer);
|
||||||
|
@ -112,16 +112,17 @@ public class EntityTrackerEntry {
|
||||||
|
|
||||||
if (this.tracker.vehicle == null) {
|
if (this.tracker.vehicle == null) {
|
||||||
++this.v;
|
++this.v;
|
||||||
i = MathHelper.floor(this.tracker.locX * 32.0D);
|
i = MathHelper.floor((this.tracker.locX) * 32.0D);
|
||||||
j = MathHelper.floor(this.tracker.locY * 32.0D);
|
j = MathHelper.floor(this.tracker.locY * 32.0D);
|
||||||
int k = MathHelper.floor(this.tracker.locZ * 32.0D);
|
int k = MathHelper.floor((this.tracker.locZ) * 32.0D);
|
||||||
int l = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F);
|
int l = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F);
|
||||||
int i1 = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F);
|
int i1 = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F);
|
||||||
|
//System.out.println(String.format("%s, %s, %s", this.tracker.locX, this.tracker.locY, this.tracker.locZ));
|
||||||
int j1 = i - this.xLoc;
|
int j1 = i - this.xLoc;
|
||||||
int k1 = j - this.yLoc;
|
int k1 = j - this.yLoc;
|
||||||
int l1 = k - this.zLoc;
|
int l1 = k - this.zLoc;
|
||||||
Object object = null;
|
Object object = null;
|
||||||
boolean flag = Math.abs(j1) >= 4 || Math.abs(k1) >= 4 || Math.abs(l1) >= 4 || this.m % 60 == 0;
|
boolean flag = Math.abs(j1) >= 2 || Math.abs(k1) >= 2 || Math.abs(l1) >= 2;
|
||||||
boolean flag1 = Math.abs(l - this.yRot) >= 4 || Math.abs(i1 - this.xRot) >= 4;
|
boolean flag1 = Math.abs(l - this.yRot) >= 4 || Math.abs(i1 - this.xRot) >= 4;
|
||||||
|
|
||||||
if (this.m > 0 || this.tracker instanceof EntityArrow) { // PaperSpigot - Moved up
|
if (this.m > 0 || this.tracker instanceof EntityArrow) { // PaperSpigot - Moved up
|
||||||
|
@ -138,26 +139,28 @@ public class EntityTrackerEntry {
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.v <= 100 && !this.x && this.y == this.tracker.onGround) { // Kohi - greatly reduce forced teleport interval - 400 -> 100
|
|
||||||
if ((!flag || !flag1) && !(this.tracker instanceof EntityArrow)) {
|
if (!(j1 == 0 && k1 == 0 && l1 == 0 && !flag1)) {
|
||||||
if (flag) {
|
if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.v <= 5 && !this.x && this.y == this.tracker.onGround) {
|
||||||
object = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(this.tracker.getId(), (byte) j1, (byte) k1, (byte) l1, this.tracker.onGround);
|
if ((!flag || !flag1) && !(this.tracker instanceof EntityArrow)) {
|
||||||
} else if (flag1) {
|
if (flag) {
|
||||||
object = new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) l, (byte) i1, this.tracker.onGround);
|
object = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(this.tracker.getId(), (byte) j1, (byte) k1, (byte) l1, this.tracker.onGround);
|
||||||
|
} else if (flag1) {
|
||||||
|
object = new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) l, (byte) i1, this.tracker.onGround);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
object = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.tracker.getId(), (byte) j1, (byte) k1, (byte) l1, (byte) l, (byte) i1, this.tracker.onGround);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.tracker.getId(), (byte) j1, (byte) k1, (byte) l1, (byte) l, (byte) i1, this.tracker.onGround);
|
this.y = this.tracker.onGround;
|
||||||
|
this.v = 0;
|
||||||
|
// CraftBukkit start - Refresh list of who can see a player before sending teleport packet
|
||||||
|
if (this.tracker instanceof EntityPlayer) {
|
||||||
|
this.scanPlayers(new ArrayList<>(this.trackedPlayers));
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
object = new PacketPlayOutEntityTeleport(this.tracker.getId(), i, j, k, (byte) l, (byte) i1, this.tracker.onGround);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.y = this.tracker.onGround;
|
|
||||||
this.v = 0;
|
|
||||||
// CraftBukkit start - Refresh list of who can see a player before sending teleport packet
|
|
||||||
if (this.tracker instanceof EntityPlayer) {
|
|
||||||
// SportPaper - Fix invisibility on teleport
|
|
||||||
this.scanPlayers(new ArrayList<EntityHuman>(this.tracker.world.players));
|
|
||||||
}
|
|
||||||
// CraftBukkit end
|
|
||||||
object = new PacketPlayOutEntityTeleport(this.tracker.getId(), i, j, k, (byte) l, (byte) i1, this.tracker.onGround);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,11 +264,7 @@ public class EntityTrackerEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
if (this.tracker instanceof EntityPlayer) {
|
this.broadcastIncludingSelf(new PacketPlayOutEntityVelocity(this.tracker));
|
||||||
((EntityPlayer) this.tracker).playerConnection.sendPacket(new PacketPlayOutEntityVelocity(this.tracker));
|
|
||||||
} else if (this.tracker instanceof EntityArrow || this.tracker instanceof EntityProjectile) {
|
|
||||||
this.broadcast(new PacketPlayOutEntityVelocity(this.tracker));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
this.tracker.velocityChanged = false;
|
this.tracker.velocityChanged = false;
|
||||||
|
@ -277,51 +276,20 @@ public class EntityTrackerEntry {
|
||||||
DataWatcher datawatcher = this.tracker.getDataWatcher();
|
DataWatcher datawatcher = this.tracker.getDataWatcher();
|
||||||
|
|
||||||
if (datawatcher.a()) {
|
if (datawatcher.a()) {
|
||||||
if (eSpigotConfig.obfuscatePlayerHealth && this.tracker instanceof EntityHuman) {
|
this.broadcastIncludingSelf(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
|
||||||
List<DataWatcher.WatchableObject> changedMetadata = datawatcher.c();
|
|
||||||
Iterator<DataWatcher.WatchableObject> iter = changedMetadata.iterator();
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
DataWatcher.WatchableObject watchable = iter.next();
|
|
||||||
if (watchable.a() == 6) {
|
|
||||||
iter.remove();
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
changedMetadata.add(new DataWatcher.WatchableObject(3, 6, 1.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
PacketPlayOutEntityMetadata modifiedPacket = new PacketPlayOutEntityMetadata(this.tracker.getId(), changedMetadata);
|
|
||||||
|
|
||||||
// Beanes - Broadcast the modified metadata packet to everyone and send the correct packet to the player
|
|
||||||
this.broadcast(modifiedPacket);
|
|
||||||
if (this.tracker instanceof EntityPlayer)
|
|
||||||
((EntityPlayer) this.tracker).playerConnection.sendPacket(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
|
|
||||||
} else {
|
|
||||||
this.broadcastIncludingSelf(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tracker instanceof EntityLiving) {
|
if (this.tracker instanceof EntityLiving) {
|
||||||
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
|
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
|
||||||
Set<AttributeInstance> set = attributemapserver.getAttributes();
|
Set set = attributemapserver.getAttributes();
|
||||||
|
|
||||||
if (!set.isEmpty()) {
|
if (!set.isEmpty()) {
|
||||||
// CraftBukkit start - Send scaled max health
|
// CraftBukkit start - Send scaled max health
|
||||||
if (this.tracker instanceof EntityPlayer) {
|
if (this.tracker instanceof EntityPlayer) {
|
||||||
((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(set, false);
|
((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(set, false);
|
||||||
((EntityPlayer) this.tracker).playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set)); // MineHQ
|
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
// MineHQ start
|
this.broadcastIncludingSelf(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set));
|
||||||
// this.broadcastIncludingSelf(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set)); // CraftBukkit
|
|
||||||
if (this.tracker.passenger instanceof EntityPlayer) {
|
|
||||||
((EntityPlayer) this.tracker.passenger).playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set));
|
|
||||||
}
|
|
||||||
// MineHQ end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set.clear();
|
set.clear();
|
||||||
|
@ -330,25 +298,35 @@ public class EntityTrackerEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void broadcast(Packet packet) {
|
public void broadcast(Packet packet) {
|
||||||
for (EntityPlayer entityplayer : this.trackedPlayers)
|
Iterator iterator = this.trackedPlayers.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
||||||
|
|
||||||
entityplayer.playerConnection.sendPacket(packet);
|
entityplayer.playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void broadcastIncludingSelf(Packet packet) {
|
public void broadcastIncludingSelf(Packet packet) {
|
||||||
this.broadcast(packet);
|
this.broadcast(packet);
|
||||||
if (this.tracker instanceof EntityPlayer)
|
if (this.tracker instanceof EntityPlayer) {
|
||||||
((EntityPlayer) this.tracker).playerConnection.sendPacket(packet);
|
((EntityPlayer) this.tracker).playerConnection.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void a() {
|
public void a() {
|
||||||
|
Iterator iterator = this.trackedPlayers.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
||||||
|
|
||||||
for (EntityPlayer entityplayer : this.trackedPlayers) {
|
|
||||||
entityplayer.d(this.tracker);
|
entityplayer.d(this.tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Untrack entity
|
|
||||||
public void a(EntityPlayer entityplayer) {
|
public void a(EntityPlayer entityplayer) {
|
||||||
if (this.trackedPlayers.contains(entityplayer)) {
|
if (this.trackedPlayers.contains(entityplayer)) {
|
||||||
entityplayer.d(this.tracker);
|
entityplayer.d(this.tracker);
|
||||||
|
@ -357,7 +335,8 @@ public class EntityTrackerEntry {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePlayer(EntityPlayer entityplayer) {
|
public void updatePlayerFor(EntityPlayer entityplayer) {
|
||||||
|
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||||
if (entityplayer != this.tracker) {
|
if (entityplayer != this.tracker) {
|
||||||
if (this.c(entityplayer)) {
|
if (this.c(entityplayer)) {
|
||||||
if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) {
|
if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) {
|
||||||
|
@ -385,8 +364,6 @@ public class EntityTrackerEntry {
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateEntityNBT(this.tracker.getId(), nbttagcompound));
|
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateEntityNBT(this.tracker.getId(), nbttagcompound));
|
||||||
}
|
}
|
||||||
|
|
||||||
// MineHQ start
|
|
||||||
/*
|
|
||||||
if (this.tracker instanceof EntityLiving) {
|
if (this.tracker instanceof EntityLiving) {
|
||||||
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
|
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap();
|
||||||
Collection collection = attributemapserver.c();
|
Collection collection = attributemapserver.c();
|
||||||
|
@ -401,8 +378,6 @@ public class EntityTrackerEntry {
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection));
|
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// MineHQ end
|
|
||||||
|
|
||||||
this.j = this.tracker.motX;
|
this.j = this.tracker.motX;
|
||||||
this.k = this.tracker.motY;
|
this.k = this.tracker.motY;
|
||||||
|
@ -438,22 +413,17 @@ public class EntityTrackerEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CraftBukkit start - Fix for nonsensical head yaw
|
// CraftBukkit start - Fix for nonsensical head yaw
|
||||||
if(this.tracker instanceof EntityLiving) { // SportPaper - avoid processing entities that can't change head rotation
|
this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
|
||||||
this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F);
|
this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i));
|
||||||
// SportPaper start
|
|
||||||
// This was originally introduced by CraftBukkit, though the implementation is wrong since it's broadcasting
|
|
||||||
// the packet again in a method that is already called for each player. This would create a very serious performance issue
|
|
||||||
// with high player and entity counts (each sendPacket call involves waking up the event loop and flushing the network stream).
|
|
||||||
// this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i));
|
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i));
|
|
||||||
// SportPaper end
|
|
||||||
}
|
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
if (this.tracker instanceof EntityLiving) {
|
if (this.tracker instanceof EntityLiving) {
|
||||||
EntityLiving entityliving = (EntityLiving) this.tracker;
|
EntityLiving entityliving = (EntityLiving) this.tracker;
|
||||||
|
Iterator iterator = entityliving.getEffects().iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
MobEffect mobeffect = (MobEffect) iterator.next();
|
||||||
|
|
||||||
for (MobEffect mobeffect : entityliving.getEffects()) {
|
|
||||||
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.tracker.getId(), mobeffect));
|
entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.tracker.getId(), mobeffect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,17 +445,18 @@ public class EntityTrackerEntry {
|
||||||
return d0 >= (double) (-this.b) && d0 <= (double) this.b && d1 >= (double) (-this.b) && d1 <= (double) this.b && this.tracker.a(entityplayer);
|
return d0 >= (double) (-this.b) && d0 <= (double) this.b && d1 >= (double) (-this.b) && d1 <= (double) this.b && this.tracker.a(entityplayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean e(EntityPlayer entityplayer) { // IonSpigot - private -> protected
|
private boolean e(EntityPlayer entityplayer) {
|
||||||
return entityplayer.u().getPlayerChunkMap().a(entityplayer, this.tracker.ae, this.tracker.ag);
|
return entityplayer.u().getPlayerChunkMap().a(entityplayer, this.tracker.ae, this.tracker.ag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scanPlayers(List<EntityHuman> list) {
|
public void scanPlayers(List<EntityHuman> list) {
|
||||||
for (EntityHuman entityHuman : list) {
|
for (int i = 0; i < list.size(); ++i) {
|
||||||
this.updatePlayer((EntityPlayer) entityHuman);
|
this.updatePlayerFor((EntityPlayer) list.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Packet c() {
|
private Packet c() {
|
||||||
if (this.tracker.dead) {
|
if (this.tracker.dead) {
|
||||||
// CraftBukkit start - Remove useless error spam, just return
|
// CraftBukkit start - Remove useless error spam, just return
|
||||||
// EntityTrackerEntry.p.warn("Fetching addPacket for removed entity");
|
// EntityTrackerEntry.p.warn("Fetching addPacket for removed entity");
|
||||||
|
@ -596,7 +567,11 @@ public class EntityTrackerEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(EntityPlayer entityplayer) {
|
public void clear(EntityPlayer entityplayer) {
|
||||||
if (this.trackedPlayers.remove(entityplayer)) // eSpigot - Directly remove
|
org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
||||||
|
if (this.trackedPlayers.contains(entityplayer)) {
|
||||||
|
this.trackedPlayers.remove(entityplayer);
|
||||||
entityplayer.d(this.tracker);
|
entityplayer.d(this.tracker);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1027,9 +1027,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
if (!eSpigotConfig.showHiddenPlayersInTab)
|
if (!eSpigotConfig.showHiddenPlayersInTab)
|
||||||
getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other));
|
getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other));
|
||||||
|
|
||||||
EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId());
|
EntityTrackerEntry entry = (EntityTrackerEntry) tracker.trackedEntities.get(other.getId());
|
||||||
if (entry != null && !entry.trackedPlayers.contains(getHandle())) {
|
if (entry != null && !entry.trackedPlayers.contains(getHandle())) {
|
||||||
entry.updatePlayer(getHandle());
|
entry.updatePlayerFor(getHandle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue