From 9b8b57cf9f6ef3b37d33e37c583816a1e686918f Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Tue, 22 Oct 2019 11:29:03 +1300 Subject: [PATCH] Switch the underlying HashMap for disguises to Concurrent Map and Synchronized Set, fixes thread safety. --- .../libraryaddict/disguise/DisguiseListener.java | 2 +- .../disguise/utilities/DisguiseUtilities.java | 16 ++++++++-------- .../utilities/metrics/MetricsInitalizer.java | 11 ++++++----- .../packetlisteners/PacketListenerSounds.java | 6 ++---- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java index 81d483b5..71b42f77 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java @@ -304,7 +304,7 @@ public class DisguiseListener implements Listener { } } - for (HashSet disguiseList : DisguiseUtilities.getDisguises().values()) { + for (Set disguiseList : DisguiseUtilities.getDisguises().values()) { for (TargetedDisguise targetedDisguise : disguiseList) { if (targetedDisguise.getEntity() == null) continue; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index cc4514c8..d09c6118 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -7,6 +7,7 @@ import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.*; +import com.google.common.collect.ConcurrentHashMultiset; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mojang.authlib.properties.PropertyMap; @@ -48,6 +49,7 @@ import java.io.FileReader; import java.io.PrintWriter; import java.lang.reflect.*; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -58,7 +60,7 @@ public class DisguiseUtilities { /** * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use */ - private static HashMap> disguisesInUse = new HashMap<>(); + private static Map> disguisesInUse = new ConcurrentHashMap<>(); /** * Disguises which are stored ready for a entity to be seen by a player Preferably, disguises in this should only * stay in for @@ -133,7 +135,7 @@ public class DisguiseUtilities { getLogger().info("Now saving disguises.."); - for (HashSet list : disguisesInUse.values()) { + for (Set list : getDisguises().values()) { for (TargetedDisguise disg : list) { if (disg.getEntity() == null) continue; @@ -307,7 +309,7 @@ public class DisguiseUtilities { public static void addDisguise(UUID entityId, TargetedDisguise disguise) { if (!getDisguises().containsKey(entityId)) { - getDisguises().put(entityId, new HashSet()); + getDisguises().put(entityId, Collections.synchronizedSet(new HashSet<>())); } getDisguises().get(entityId).add(disguise); @@ -614,13 +616,13 @@ public class DisguiseUtilities { return null; } - public static HashMap> getDisguises() { + public static Map> getDisguises() { return disguisesInUse; } public static TargetedDisguise[] getDisguises(UUID entityId) { if (getDisguises().containsKey(entityId)) { - HashSet disguises = getDisguises().get(entityId); + Set disguises = getDisguises().get(entityId); return disguises.toArray(new TargetedDisguise[disguises.size()]); } @@ -1872,8 +1874,6 @@ public class DisguiseUtilities { entityId = observer.getEntityId(); } - // TODO Needs to be thread safe, not thread safe atm due to testing - if (getFutureDisguises().containsKey(entityId)) { HashSet hashSet = getFutureDisguises().get(entityId); @@ -1886,7 +1886,7 @@ public class DisguiseUtilities { } } - for (HashSet disguises : getDisguises().values()) { + for (Set disguises : getDisguises().values()) { for (TargetedDisguise dis : disguises) { if (dis.getEntity() == null || !dis.isDisguiseInUse()) { continue; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java b/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java index 01b011bc..ddef181d 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java @@ -11,6 +11,7 @@ import me.libraryaddict.disguise.utilities.plugin.PluginInformation; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Set; /** * Created by libraryaddict on 3/01/2019. @@ -93,7 +94,7 @@ public class MetricsInitalizer { metrics.addCustomChart(new Metrics.MultiLineChart("disguised_entities") { @Override public HashMap getValues(HashMap hashMap) { - for (HashSet list : DisguiseUtilities.getDisguises().values()) { + for (Set list : DisguiseUtilities.getDisguises().values()) { for (Disguise disg : list) { if (disg.getEntity() == null || !disg.isDisguiseInUse()) continue; @@ -111,7 +112,7 @@ public class MetricsInitalizer { metrics.addCustomChart(new Metrics.MultiLineChart("disguises_used") { @Override public HashMap getValues(HashMap hashMap) { - for (HashSet list : DisguiseUtilities.getDisguises().values()) { + for (Set list : DisguiseUtilities.getDisguises().values()) { for (Disguise disg : list) { if (disg.getEntity() == null || !disg.isDisguiseInUse()) continue; @@ -148,7 +149,7 @@ public class MetricsInitalizer { public String getValue() { int disgs = 0; - for (HashSet set : DisguiseUtilities.getDisguises().values()) { + for (Set set : DisguiseUtilities.getDisguises().values()) { disgs += set.size(); } @@ -231,12 +232,12 @@ public class MetricsInitalizer { return "Yes"; } - Collection> list = DisguiseUtilities.getDisguises().values(); + Collection> list = DisguiseUtilities.getDisguises().values(); if (list.isEmpty()) return "Unknown"; - for (HashSet dList : list) { + for (Set dList : list) { for (TargetedDisguise disg : dList) { if (disg.getObservers().isEmpty()) continue; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java index d27ee086..71e696fd 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerSounds.java @@ -7,7 +7,6 @@ import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.StructureModifier; -import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; @@ -17,14 +16,13 @@ import me.libraryaddict.disguise.utilities.DisguiseSound; import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; -import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.entity.*; import java.lang.reflect.InvocationTargetException; -import java.util.HashSet; +import java.util.Set; public class PacketListenerSounds extends PacketAdapter { /** @@ -71,7 +69,7 @@ public class PacketListenerSounds extends PacketAdapter { int[] soundCords = new int[]{(Integer) mods.read(2), (Integer) mods.read(3), (Integer) mods.read(4)}; loop: - for (HashSet disguises : DisguiseUtilities.getDisguises().values()) { + for (Set disguises : DisguiseUtilities.getDisguises().values()) { for (TargetedDisguise entityDisguise : disguises) { Entity entity = entityDisguise.getEntity();