Fixed ConcurrentModificationException on PaperSpigot/SportsBukkit.
This commit is contained in:
		| @@ -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)) { | ||||||
|   | |||||||
| @@ -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] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user