Disguises are now removed 30 ticks after death, and by sending entity remove packets
This commit is contained in:
parent
3709db548a
commit
f3b3c15685
@ -179,27 +179,35 @@ public abstract class Disguise {
|
|||||||
final TargetedDisguise disguise = (TargetedDisguise) this;
|
final TargetedDisguise disguise = (TargetedDisguise) this;
|
||||||
// A scheduler to clean up any unused disguises.
|
// A scheduler to clean up any unused disguises.
|
||||||
velocityRunnable = new BukkitRunnable() {
|
velocityRunnable = new BukkitRunnable() {
|
||||||
|
private int deadTicks = 0;
|
||||||
private int refreshDisguise = 0;
|
private int refreshDisguise = 0;
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
// If entity is no longer valid. Remove it.
|
// If entity is no longer valid. Remove it.
|
||||||
if (!getEntity().isValid()) {
|
if (!getEntity().isValid()) {
|
||||||
|
// If it has been dead for 30+ ticks
|
||||||
|
// This is to ensure that this disguise isn't removed while clients think its the real entity
|
||||||
|
// The delay is because if it sends the destroy entity packets straight away, then it means no death animation
|
||||||
|
// This is probably still a problem for wither and enderdragon deaths.
|
||||||
|
if (deadTicks++ > 30) {
|
||||||
|
|
||||||
if (getEntity() instanceof Player ?
|
if (getEntity() instanceof Player ?
|
||||||
|
|
||||||
(Bukkit.getPlayerExact(((Player) getEntity()).getName()) == null ? !isKeepDisguiseOnPlayerLogout()
|
(Bukkit.getPlayerExact(((Player) getEntity()).getName()) == null ? !isKeepDisguiseOnPlayerLogout()
|
||||||
: !isKeepDisguiseOnPlayerDeath())
|
: !isKeepDisguiseOnPlayerDeath())
|
||||||
|
|
||||||
:
|
:
|
||||||
|
|
||||||
(!isKeepDisguiseOnEntityDespawn() || getEntity().isDead())) {
|
(!isKeepDisguiseOnEntityDespawn() || getEntity().isDead())) {
|
||||||
removeDisguise();
|
removeDisguise();
|
||||||
} else {
|
} else {
|
||||||
entity = null;
|
entity = null;
|
||||||
watcher = getWatcher().clone(disguise);
|
watcher = getWatcher().clone(disguise);
|
||||||
cancel();
|
cancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
deadTicks = 0;
|
||||||
// If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
|
// If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
|
||||||
if (getType() == DisguiseType.PRIMED_TNT || getType() == DisguiseType.FIREWORK) {
|
if (getType() == DisguiseType.PRIMED_TNT || getType() == DisguiseType.FIREWORK) {
|
||||||
refreshDisguise++;
|
refreshDisguise++;
|
||||||
@ -400,7 +408,11 @@ public abstract class Disguise {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Better refresh the entity to undisguise it
|
// Better refresh the entity to undisguise it
|
||||||
DisguiseUtilities.refreshTrackers((TargetedDisguise) this);
|
if (getEntity().isValid()) {
|
||||||
|
DisguiseUtilities.refreshTrackers((TargetedDisguise) this);
|
||||||
|
} else {
|
||||||
|
DisguiseUtilities.destroyEntity((TargetedDisguise) this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Loop through the disguises because it could be used with a unknown entity id.
|
// Loop through the disguises because it could be used with a unknown entity id.
|
||||||
|
@ -142,6 +142,35 @@ public class DisguiseUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Sends
|
||||||
|
* entity removal packets, as this disguise was removed
|
||||||
|
*/
|
||||||
|
public static void destroyEntity(TargetedDisguise disguise) {
|
||||||
|
try {
|
||||||
|
Object world = ReflectionManager.getWorld(disguise.getEntity().getWorld());
|
||||||
|
Object tracker = world.getClass().getField("tracker").get(world);
|
||||||
|
Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker);
|
||||||
|
Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class)
|
||||||
|
.invoke(trackedEntities, disguise.getEntity().getEntityId());
|
||||||
|
if (entityTrackerEntry != null) {
|
||||||
|
HashSet trackedPlayers = (HashSet) entityTrackerEntry.getClass().getField("trackedPlayers")
|
||||||
|
.get(entityTrackerEntry);
|
||||||
|
HashSet cloned = (HashSet) trackedPlayers.clone();
|
||||||
|
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
|
||||||
|
destroyPacket.getIntegerArrays().write(0, new int[] { disguise.getEntity().getEntityId() });
|
||||||
|
for (Object p : cloned) {
|
||||||
|
Player player = (Player) ReflectionManager.getBukkitEntity(p);
|
||||||
|
if (disguise.canSee(player.getName())) {
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void doBoundingBox(TargetedDisguise disguise) {
|
public static void doBoundingBox(TargetedDisguise disguise) {
|
||||||
// TODO Slimes
|
// TODO Slimes
|
||||||
Entity entity = disguise.getEntity();
|
Entity entity = disguise.getEntity();
|
||||||
|
Loading…
Reference in New Issue
Block a user