diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncMarker.java b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncMarker.java index febbbbcf..694f55a8 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncMarker.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncMarker.java @@ -99,8 +99,8 @@ public class AsyncMarker implements Serializable, Comparable { private transient int workerID; // Determine if Minecraft processes this packet asynchronously - private static Method isMinecraftAsync; - private static boolean alwaysSync; + private volatile static Method isMinecraftAsync; + private volatile static boolean alwaysSync; /** * Create a container for asyncronous packets. diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java b/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java index 3e9aafa6..2257cbca 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java @@ -121,6 +121,8 @@ public class DetailedErrorReporter implements ErrorReporter { @Override public void reportDetailed(Object sender, String message, Throwable error, Object... parameters) { + final Plugin plugin = pluginReference.get(); + // Do not overtly spam the server! if (++errorCount > maxErrorCount) { String maxReached = String.format("Reached maxmimum error count. Cannot pass error %s from %s.", error, sender); @@ -167,8 +169,7 @@ public class DetailedErrorReporter implements ErrorReporter { writer.println(addPrefix(getStringDescription(sender), SECOND_LEVEL_PREFIX)); // And plugin - if (pluginReference.get() != null) { - Plugin plugin = pluginReference.get(); + if (plugin != null) { writer.println("Version:"); writer.println(addPrefix(plugin.toString(), SECOND_LEVEL_PREFIX)); } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java index c97d9f50..3a346dfd 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java @@ -53,8 +53,8 @@ public class NetworkServerInjector extends PlayerInjector { private volatile static CallbackFilter callbackFilter; - private static Field disconnectField; - private static Method sendPacketMethod; + private volatile static Field disconnectField; + private volatile static Method sendPacketMethod; private InjectedServerConnection serverInjection; // Determine if we're listening diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java index 373df511..fb2136b3 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java @@ -604,10 +604,11 @@ public class PlayerInjectionHandler { */ public void scheduleDataInputRefresh(Player player) { final PlayerInjector injector = getInjector(player); - final DataInputStream old = injector.getInputStream(true); - + // Update the DataInputStream if (injector != null) { + final DataInputStream old = injector.getInputStream(true); + injector.scheduleAction(new Runnable() { @Override public void run() { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/StructureModifier.java b/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/StructureModifier.java index 9323065d..81599064 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/StructureModifier.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/StructureModifier.java @@ -202,7 +202,7 @@ public class StructureModifier { */ public boolean isReadOnly(int fieldIndex) { if (fieldIndex < 0 || fieldIndex >= data.size()) - new IllegalArgumentException("Index parameter is not within [0 - " + data.size() + ")"); + throw new IllegalArgumentException("Index parameter is not within [0 - " + data.size() + ")"); return Modifier.isFinal(data.get(fieldIndex).getModifiers()); } @@ -219,7 +219,7 @@ public class StructureModifier { */ public void setReadOnly(int fieldIndex, boolean value) throws FieldAccessException { if (fieldIndex < 0 || fieldIndex >= data.size()) - new IllegalArgumentException("Index parameter is not within [0 - " + data.size() + ")"); + throw new IllegalArgumentException("Index parameter is not within [0 - " + data.size() + ")"); try { StructureModifier.setFinalState(data.get(fieldIndex), value); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java index c8bc5935..ce2af3e8 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java @@ -193,10 +193,11 @@ public class BukkitConverters { public Entity getSpecific(Object generic) { try { Integer id = (Integer) generic; + ProtocolManager manager = managerRef.get(); // Use the - if (id != null && managerRef.get() != null) { - return managerRef.get().getEntityFromID(container, id); + if (id != null && manager != null) { + return manager.getEntityFromID(container, id); } else { return null; } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java index 7290b036..5f39621e 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java @@ -8,6 +8,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -46,7 +47,7 @@ public class WrappedDataWatcher { private static Method getKeyValueMethod; // Entity methods - private static Field entityDataField; + private volatile static Field entityDataField; /** * Whether or not this class has already been initialized. @@ -275,12 +276,13 @@ public class WrappedDataWatcher { * @throws FieldAccessException If we're unable to read the underlying object. */ public Set indexSet() throws FieldAccessException { + Lock readLock = getReadWriteLock().readLock(); + readLock.lock(); + try { - getReadWriteLock().readLock().lock(); return new HashSet(getWatchableObjectMap().keySet()); - } finally { - getReadWriteLock().readLock().unlock(); + readLock.unlock(); } } @@ -290,12 +292,13 @@ public class WrappedDataWatcher { * @throws FieldAccessException If we're unable to read the underlying object. */ public int size() throws FieldAccessException { + Lock readLock = getReadWriteLock().readLock(); + readLock.lock(); + try { - getReadWriteLock().readLock().lock(); return getWatchableObjectMap().size(); - } finally { - getReadWriteLock().readLock().unlock(); + readLock.unlock(); } } @@ -337,18 +340,18 @@ public class WrappedDataWatcher { * @throws FieldAccessException Cannot read underlying field. */ private void setObjectRaw(int index, Object newValue, boolean update) throws FieldAccessException { - WatchableObject watchable; + // Aquire write lock + Lock writeLock = getReadWriteLock().writeLock(); + writeLock.lock(); try { - // Aquire write lock - getReadWriteLock().writeLock().lock(); - watchable = getWatchedObject(index); + WatchableObject watchable = getWatchedObject(index); if (watchable != null) { new WrappedWatchableObject(watchable).setValue(newValue, update); } } finally { - getReadWriteLock().writeLock().unlock(); + writeLock.unlock(); } }