Fixed ConcurrentModificationException on PaperSpigot/SportsBukkit.

This commit is contained in:
NavidK0 2015-12-29 15:44:19 -05:00
parent e7a5d0763f
commit 66ab7ac3ef
2 changed files with 20 additions and 28 deletions

View File

@ -255,9 +255,7 @@ public class DisguiseUtilities {
entityTrackerEntry); entityTrackerEntry);
Object trackedPlayersObj = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry); Object trackedPlayersObj = ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
// If the tracker exists. Remove himself from his tracker // If the tracker exists. Remove himself from his tracker
if (isHashSet(trackedPlayersObj)) { trackedPlayers = new HashSet(trackedPlayers); //Copy before iterating to prevent ConcurrentModificationException
trackedPlayers = (Set) ((HashSet<Object>)trackedPlayers).clone();
}
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, new int[]{disguise.getEntity().getEntityId()}); destroyPacket.getIntegerArrays().write(0, new int[]{disguise.getEntity().getEntityId()});
for (Object p : trackedPlayers) { for (Object p : trackedPlayers) {
@ -443,8 +441,8 @@ public class DisguiseUtilities {
try { try {
Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity()); Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) { if (entityTrackerEntry != null) {
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get( Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
entityTrackerEntry); trackedPlayers = new HashSet(trackedPlayers); //Copy before iterating to prevent ConcurrentModificationException
for (Object p : trackedPlayers) { for (Object p : trackedPlayers) {
Player player = (Player) ReflectionManager.getBukkitEntity(p); Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (((TargetedDisguise) disguise).canSee(player)) { if (((TargetedDisguise) disguise).canSee(player)) {
@ -479,6 +477,19 @@ public class DisguiseUtilities {
}); });
} }
/**
* Pass in a set, check if it's a hashset.
* If it's not, return false.
* If you pass in something else, you failed.
* @param obj
* @return
*/
private static boolean isHashSet(Object obj) {
if (obj instanceof HashSet) return true; //It's Spigot/Bukkit
if (obj instanceof Set) return false; //It's PaperSpigot/SportsBukkit
throw new IllegalArgumentException("Object passed was not either a hashset or set!");
}
/** /**
* Thread safe to use. This returns a GameProfile. And if its GameProfile doesn't have a skin blob. Then it does a lookup using schedulers. The runnable is run once the GameProfile has been successfully dealt with * Thread safe to use. This returns a GameProfile. And if its GameProfile doesn't have a skin blob. Then it does a lookup using schedulers. The runnable is run once the GameProfile has been successfully dealt with
*/ */
@ -648,9 +659,7 @@ public class DisguiseUtilities {
ReflectionManager.getNmsClass("EntityPlayer")); ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer", final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer")); ReflectionManager.getNmsClass("EntityPlayer"));
if (isHashSet(trackedPlayers)) { trackedPlayers = new HashSet(trackedPlayers); //Copy before iterating to prevent ConcurrentModificationException
trackedPlayers = (Set) ((HashSet<Object>)trackedPlayers).clone();
}
for (final Object p : trackedPlayers) { for (final Object p : trackedPlayers) {
Player pl = (Player) ReflectionManager.getBukkitEntity(p); Player pl = (Player) ReflectionManager.getBukkitEntity(p);
if (player.equalsIgnoreCase((pl).getName())) { if (player.equalsIgnoreCase((pl).getName())) {
@ -692,9 +701,7 @@ public class DisguiseUtilities {
ReflectionManager.getNmsClass("EntityPlayer")); ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer", final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer")); ReflectionManager.getNmsClass("EntityPlayer"));
if (isHashSet(trackedPlayers)) { trackedPlayers = new HashSet(trackedPlayers); //Copy before iterating to prevent ConcurrentModificationException
trackedPlayers = (Set) ((HashSet<Object>)trackedPlayers).clone();
}
for (final Object p : trackedPlayers) { for (final Object p : trackedPlayers) {
Player player = (Player) ReflectionManager.getBukkitEntity(p); Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (player != entity) { if (player != entity) {
@ -748,9 +755,7 @@ public class DisguiseUtilities {
ReflectionManager.getNmsClass("EntityPlayer")); ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer", final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer")); ReflectionManager.getNmsClass("EntityPlayer"));
if (isHashSet(trackedPlayers)) { trackedPlayers = new HashSet(trackedPlayers); //Copy before iterating to prevent ConcurrentModificationException
trackedPlayers = (Set) ((HashSet<Object>)trackedPlayers).clone();
}
for (final Object p : trackedPlayers) { for (final Object p : trackedPlayers) {
Player player = (Player) ReflectionManager.getBukkitEntity(p); Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (disguise.getEntity() != player && disguise.canSee(player)) { if (disguise.getEntity() != player && disguise.canSee(player)) {
@ -775,19 +780,6 @@ public class DisguiseUtilities {
} }
} }
/**
* Pass in a set, check if it's a hashset.
* If it's not, return false.
* If you pass in something else, you failed.
* @param obj
* @return
*/
private static boolean isHashSet(Object obj) {
if (obj instanceof HashSet) return true; //It's Spigot/Bukkit
if (obj instanceof Set) return false; //It's PaperSpigot/SportsBukkit
throw new IllegalArgumentException("Object passed was not either a hashset or set!");
}
public static boolean removeDisguise(TargetedDisguise disguise) { public static boolean removeDisguise(TargetedDisguise disguise) {
UUID entityId = disguise.getEntity().getUniqueId(); UUID entityId = disguise.getEntity().getUniqueId();
if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) { if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) {

View File

@ -1,6 +1,6 @@
name: LibsDisguises name: LibsDisguises
main: me.libraryaddict.disguise.LibsDisguises main: me.libraryaddict.disguise.LibsDisguises
version: 8.6.6 version: 8.6.7
author: libraryaddict author: libraryaddict
authors: [Byteflux, Navid K.] authors: [Byteflux, Navid K.]
depend: [ProtocolLib] depend: [ProtocolLib]