diff --git a/ProtocolLib/dependency-reduced-pom.xml b/ProtocolLib/dependency-reduced-pom.xml
index 7019dfad..5fb86ef9 100644
--- a/ProtocolLib/dependency-reduced-pom.xml
+++ b/ProtocolLib/dependency-reduced-pom.xml
@@ -4,7 +4,7 @@
com.comphenix.protocol
ProtocolLib
ProtocolLib
- 1.4.4-SNAPSHOT
+ 1.5.0
Provides read/write access to the Minecraft protocol.
http://dev.bukkit.org/server-mods/protocollib/
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/AsynchronousManager.java b/ProtocolLib/src/main/java/com/comphenix/protocol/AsynchronousManager.java
index a16f5db5..a449b1ca 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/AsynchronousManager.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/AsynchronousManager.java
@@ -18,11 +18,11 @@
package com.comphenix.protocol;
import java.util.Set;
-import java.util.logging.Logger;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.async.AsyncListenerHandler;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
@@ -81,10 +81,10 @@ public interface AsynchronousManager {
public abstract PacketStream getPacketStream();
/**
- * Retrieve the default error logger.
- * @return Default logger.
+ * Retrieve the default error reporter.
+ * @return Default reporter.
*/
- public abstract Logger getLogger();
+ public abstract ErrorReporter getErrorReporter();
/**
* Remove listeners, close threads and transmit every delayed packet.
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/CleanupStaticMembers.java b/ProtocolLib/src/main/java/com/comphenix/protocol/CleanupStaticMembers.java
index b3b5e118..269345f9 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/CleanupStaticMembers.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/CleanupStaticMembers.java
@@ -4,10 +4,9 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import com.comphenix.protocol.async.AsyncListenerHandler;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.injector.BukkitUnwrapper;
@@ -30,11 +29,11 @@ import com.comphenix.protocol.reflect.instances.PrimitiveGenerator;
class CleanupStaticMembers {
private ClassLoader loader;
- private Logger logger;
+ private ErrorReporter reporter;
- public CleanupStaticMembers(ClassLoader loader, Logger logger) {
+ public CleanupStaticMembers(ClassLoader loader, ErrorReporter reporter) {
this.loader = loader;
- this.logger = logger;
+ this.reporter = reporter;
}
/**
@@ -90,8 +89,8 @@ class CleanupStaticMembers {
try {
setFinalStatic(field, null);
} catch (IllegalAccessException e) {
- // Just inform us
- logger.warning("Unable to reset field " + field.getName() + ": " + e.getMessage());
+ // Just inform the player
+ reporter.reportWarning(this, "Unable to reset field " + field.getName() + ": " + e.getMessage(), e);
}
}
}
@@ -126,7 +125,7 @@ class CleanupStaticMembers {
output.add(loader.loadClass(name));
} catch (ClassNotFoundException e) {
// Warn the user
- logger.log(Level.WARNING, "Unable to unload class " + name, e);
+ reporter.reportWarning(this, "Unable to unload class " + name, e);
}
}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java
index 85e00881..c17b84d9 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java
@@ -18,7 +18,6 @@
package com.comphenix.protocol;
import java.io.IOException;
-import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Server;
@@ -26,6 +25,8 @@ import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import com.comphenix.protocol.async.AsyncFilterManager;
+import com.comphenix.protocol.error.DetailedErrorReporter;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.ConnectionSide;
import com.comphenix.protocol.events.MonitorAdapter;
import com.comphenix.protocol.events.PacketEvent;
@@ -44,9 +45,12 @@ public class ProtocolLibrary extends JavaPlugin {
// There should only be one protocol manager, so we'll make it static
private static PacketFilterManager protocolManager;
- // Error logger
+ // Information logger
private Logger logger;
+ // Error reporter
+ private ErrorReporter reporter;
+
// Metrics and statistisc
private Statistics statistisc;
@@ -67,39 +71,55 @@ public class ProtocolLibrary extends JavaPlugin {
@Override
public void onLoad() {
- logger = getLoggerSafely();
- unhookTask = new DelayedSingleTask(this);
- protocolManager = new PacketFilterManager(getClassLoader(), getServer(), unhookTask, logger);
+ // Add global parameters
+ DetailedErrorReporter reporter = new DetailedErrorReporter();
+
+ try {
+ logger = getLoggerSafely();
+ unhookTask = new DelayedSingleTask(this);
+ protocolManager = new PacketFilterManager(getClassLoader(), getServer(), unhookTask, reporter);
+ reporter.addGlobalParameter("manager", protocolManager);
+
+ } catch (Throwable e) {
+ reporter.reportDetailed(this, "Cannot load ProtocolLib.", e, protocolManager);
+ }
}
@Override
public void onEnable() {
- Server server = getServer();
- PluginManager manager = server.getPluginManager();
-
- // Initialize background compiler
- if (backgroundCompiler == null) {
- backgroundCompiler = new BackgroundCompiler(getClassLoader());
- BackgroundCompiler.setInstance(backgroundCompiler);
- }
-
- // Notify server managers of incompatible plugins
- checkForIncompatibility(manager);
-
- // Player login and logout events
- protocolManager.registerEvents(manager, this);
+ try {
+ Server server = getServer();
+ PluginManager manager = server.getPluginManager();
+
+ // Initialize background compiler
+ if (backgroundCompiler == null) {
+ backgroundCompiler = new BackgroundCompiler(getClassLoader());
+ BackgroundCompiler.setInstance(backgroundCompiler);
+ }
+
+ // Notify server managers of incompatible plugins
+ checkForIncompatibility(manager);
- // Worker that ensures that async packets are eventually sent
- createAsyncTask(server);
- //toggleDebugListener();
+ // Player login and logout events
+ protocolManager.registerEvents(manager, this);
+
+ // Worker that ensures that async packets are eventually sent
+ createAsyncTask(server);
+ //toggleDebugListener();
+
+ } catch (Throwable e) {
+ reporter.reportDetailed(this, "Cannot enable ProtocolLib.", e);
+ disablePlugin();
+ return;
+ }
// Try to enable statistics
try {
statistisc = new Statistics(this);
} catch (IOException e) {
- logger.log(Level.SEVERE, "Unable to enable metrics.", e);
+ reporter.reportDetailed(this, "Unable to enable metrics.", e, statistisc);
} catch (Throwable e) {
- logger.log(Level.SEVERE, "Metrics cannot be enabled. Incompatible Bukkit version.", e);
+ reporter.reportDetailed(this, "Metrics cannot be enabled. Incompatible Bukkit version.", e, statistisc);
}
}
@@ -136,6 +156,13 @@ public class ProtocolLibrary extends JavaPlugin {
debugListener = !debugListener;
}
+ /**
+ * Disable the current plugin.
+ */
+ private void disablePlugin() {
+ getServer().getPluginManager().disablePlugin(this);
+ }
+
private void createAsyncTask(Server server) {
try {
if (asyncPacketTask >= 0)
@@ -154,7 +181,7 @@ public class ProtocolLibrary extends JavaPlugin {
} catch (Throwable e) {
if (asyncPacketTask == -1) {
- logger.log(Level.SEVERE, "Unable to create packet timeout task.", e);
+ reporter.reportDetailed(this, "Unable to create packet timeout task.", e);
}
}
}
@@ -166,7 +193,7 @@ public class ProtocolLibrary extends JavaPlugin {
for (String plugin : incompatiblePlugins) {
if (manager.getPlugin(plugin) != null) {
// Check for versions, ect.
- logger.severe("Detected incompatible plugin: " + plugin);
+ reporter.reportWarning(this, "Detected incompatible plugin: " + plugin);
}
}
}
@@ -192,7 +219,7 @@ public class ProtocolLibrary extends JavaPlugin {
statistisc = null;
// Leaky ClassLoader begone!
- CleanupStaticMembers cleanup = new CleanupStaticMembers(getClassLoader(), logger);
+ CleanupStaticMembers cleanup = new CleanupStaticMembers(getClassLoader(), reporter);
cleanup.resetAll();
}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncFilterManager.java b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncFilterManager.java
index e0707229..7b5744e7 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncFilterManager.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncFilterManager.java
@@ -21,7 +21,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Logger;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
@@ -29,6 +28,7 @@ import org.bukkit.scheduler.BukkitScheduler;
import com.comphenix.protocol.AsynchronousManager;
import com.comphenix.protocol.PacketStream;
import com.comphenix.protocol.ProtocolManager;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
@@ -49,7 +49,7 @@ public class AsyncFilterManager implements AsynchronousManager {
private PacketProcessingQueue clientProcessingQueue;
private PacketSendingQueue clientQueue;
- private Logger logger;
+ private ErrorReporter reporter;
// The likely main thread
private Thread mainThread;
@@ -66,7 +66,7 @@ public class AsyncFilterManager implements AsynchronousManager {
// Whether or not we're currently cleaning up
private volatile boolean cleaningUp;
- public AsyncFilterManager(Logger logger, BukkitScheduler scheduler, ProtocolManager manager) {
+ public AsyncFilterManager(ErrorReporter reporter, BukkitScheduler scheduler, ProtocolManager manager) {
// Server packets are synchronized already
this.serverQueue = new PacketSendingQueue(false);
@@ -80,7 +80,7 @@ public class AsyncFilterManager implements AsynchronousManager {
this.scheduler = scheduler;
this.manager = manager;
- this.logger = logger;
+ this.reporter = reporter;
this.mainThread = Thread.currentThread();
}
@@ -267,10 +267,10 @@ public class AsyncFilterManager implements AsynchronousManager {
}
@Override
- public Logger getLogger() {
- return logger;
+ public ErrorReporter getErrorReporter() {
+ return reporter;
}
-
+
@Override
public void cleanupAll() {
cleaningUp = true;
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java
index 9f77400f..96d04db3 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/async/AsyncListenerHandler.java
@@ -442,8 +442,7 @@ public class AsyncListenerHandler {
} catch (Throwable e) {
// Minecraft doesn't want your Exception.
- filterManager.getLogger().log(Level.SEVERE,
- "Unhandled exception occured in onAsyncPacket() for " + getPluginName(), e);
+ filterManager.getErrorReporter().reportMinimal(listener.getPlugin(), "onAsyncPacket()", e);
}
// Now, get the next non-cancelled listener
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java b/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java
new file mode 100644
index 00000000..13f0a5eb
--- /dev/null
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/error/DetailedErrorReporter.java
@@ -0,0 +1,268 @@
+package com.comphenix.protocol.error;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.Plugin;
+
+import com.comphenix.protocol.events.PacketAdapter;
+import com.google.common.primitives.Primitives;
+
+/**
+ * Internal class used to handle exceptions.
+ *
+ * @author Kristian
+ */
+public class DetailedErrorReporter implements ErrorReporter {
+
+ public static final String SECOND_LEVEL_PREFIX = " ";
+ public static final String DEFAULT_PREFIX = " ";
+ public static final String DEFAULT_SUPPORT_URL = "http://dev.bukkit.org/server-mods/protocollib/";
+ public static final String PLUGIN_NAME = "ProtocolLib";
+
+ // We don't want to spam the server
+ public static final int DEFAULT_MAX_ERROR_COUNT = 20;
+
+ protected String prefix;
+ protected String supportURL;
+
+ protected int errorCount;
+ protected int maxErrorCount;
+ protected Logger logger;
+
+ // Whether or not Apache Commons is not present
+ protected boolean apacheCommonsMissing;
+
+ // Map of global objects
+ protected Map globalParameters = new HashMap();
+
+ /**
+ * Create a default error reporting system.
+ */
+ public DetailedErrorReporter() {
+ this(DEFAULT_PREFIX, DEFAULT_SUPPORT_URL);
+ }
+
+ /**
+ * Create a central error reporting system.
+ * @param prefix - default line prefix.
+ * @param supportURL - URL to report the error.
+ */
+ public DetailedErrorReporter(String prefix, String supportURL) {
+ this(prefix, supportURL, DEFAULT_MAX_ERROR_COUNT, getBukkitLogger());
+ }
+
+ // Attempt to get the logger.
+ private static Logger getBukkitLogger() {
+ try {
+ return Bukkit.getLogger();
+ } catch (Throwable e) {
+ return Logger.getLogger("Minecraft");
+ }
+ }
+
+ /**
+ * Create a central error reporting system.
+ * @param prefix - default line prefix.
+ * @param supportURL - URL to report the error.
+ * @param maxErrorCount - number of errors to print before giving up.
+ * @param logger - current logger.
+ */
+ public DetailedErrorReporter(String prefix, String supportURL, int maxErrorCount, Logger logger) {
+ this.prefix = prefix;
+ this.supportURL = supportURL;
+ this.maxErrorCount = maxErrorCount;
+ this.logger = logger;
+ }
+
+ @Override
+ public void reportMinimal(Plugin sender, String methodName, Throwable error) {
+ logger.log(Level.SEVERE, "[" + PLUGIN_NAME + "] Unhandled exception occured in " + methodName + " for " +
+ PacketAdapter.getPluginName(sender), error);
+ }
+
+ @Override
+ public void reportWarning(Object sender, String message) {
+ logger.log(Level.WARNING, "[" + PLUGIN_NAME + "] [" + getSenderName(sender) + "] " + message);
+ }
+
+ @Override
+ public void reportWarning(Object sender, String message, Throwable error) {
+ logger.log(Level.WARNING, "[" + PLUGIN_NAME + "] [" + getSenderName(sender) + "] " + message, error);
+ }
+
+ private String getSenderName(Object sender) {
+ if (sender != null)
+ return sender.getClass().getSimpleName();
+ else
+ return "NULL";
+ }
+
+ @Override
+ public void reportDetailed(Object sender, String message, Throwable error, Object... parameters) {
+
+ // 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);
+ logger.severe(maxReached);
+ return;
+ }
+
+ StringWriter text = new StringWriter();
+ PrintWriter writer = new PrintWriter(text);
+
+ // Helpful message
+ writer.println("[ProtocolLib] INTERNAL ERROR: " + message);
+ writer.println("If this problem hasn't already been reported, please open a ticket");
+ writer.println("at " + supportURL + " with the following data:");
+
+ // Now, let us print important exception information
+ writer.println(" ===== STACK TRACE =====");
+
+ if (error != null)
+ error.printStackTrace(writer);
+
+ // Data dump!
+ writer.println(" ===== DUMP =====");
+
+ // Relevant parameters
+ if (parameters != null && parameters.length > 0) {
+ writer.println("Parameters:");
+
+ // We *really* want to get as much information as possible
+ for (Object param : parameters) {
+ writer.println(addPrefix(getStringDescription(param), SECOND_LEVEL_PREFIX));
+ }
+ }
+
+ // Global parameters
+ for (String param : globalParameters()) {
+ writer.println(SECOND_LEVEL_PREFIX + param + ":");
+ writer.println(addPrefix(getStringDescription(getGlobalParameter(param)),
+ SECOND_LEVEL_PREFIX + SECOND_LEVEL_PREFIX));
+ }
+
+ // Now, for the sender itself
+ writer.println("Sender:");
+ writer.println(addPrefix(getStringDescription(sender), SECOND_LEVEL_PREFIX));
+
+ // Add the server version too
+ if (Bukkit.getServer() != null) {
+ writer.println("Server:");
+ writer.println(addPrefix(Bukkit.getServer().getVersion(), SECOND_LEVEL_PREFIX));
+ }
+
+ // Make sure it is reported
+ logger.severe(addPrefix(text.toString(), prefix));
+ }
+
+ /**
+ * Adds the given prefix to every line in the text.
+ * @param text - text to modify.
+ * @param prefix - prefix added to every line in the text.
+ * @return The modified text.
+ */
+ protected String addPrefix(String text, String prefix) {
+ return text.replaceAll("(?m)^", prefix);
+ }
+
+ protected String getStringDescription(Object value) {
+
+ // We can't only rely on toString.
+ if (value == null) {
+ return "[NULL]";
+ } if (isSimpleType(value)) {
+ return value.toString();
+ } else {
+ try {
+ if (!apacheCommonsMissing)
+ return (ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null));
+ } catch (Throwable ex) {
+ // Apache is probably missing
+ logger.warning("Cannot find Apache Commons. Object introspection disabled.");
+ apacheCommonsMissing = true;
+ }
+
+ // Just use toString()
+ return String.format("%s", value);
+ }
+ }
+
+ /**
+ * Determine if the given object is a wrapper for a primitive/simple type or not.
+ * @param test - the object to test.
+ * @return TRUE if this object is simple enough to simply be printed, FALSE othewise.
+ */
+ protected boolean isSimpleType(Object test) {
+ return test instanceof String || Primitives.isWrapperType(test.getClass());
+ }
+
+ public int getErrorCount() {
+ return errorCount;
+ }
+
+ public void setErrorCount(int errorCount) {
+ this.errorCount = errorCount;
+ }
+
+ public int getMaxErrorCount() {
+ return maxErrorCount;
+ }
+
+ public void setMaxErrorCount(int maxErrorCount) {
+ this.maxErrorCount = maxErrorCount;
+ }
+
+ /**
+ * Adds the given global parameter. It will be included in every error report.
+ * @param key - name of parameter.
+ * @param value - the global parameter itself.
+ */
+ public void addGlobalParameter(String key, Object value) {
+ globalParameters.put(key, value);
+ }
+
+ public Object getGlobalParameter(String key) {
+ return globalParameters.get(key);
+ }
+
+ public void clearGlobalParameters() {
+ globalParameters.clear();
+ }
+
+ public Set globalParameters() {
+ return globalParameters.keySet();
+ }
+
+ public String getSupportURL() {
+ return supportURL;
+ }
+
+ public void setSupportURL(String supportURL) {
+ this.supportURL = supportURL;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public Logger getLogger() {
+ return logger;
+ }
+
+ public void setLogger(Logger logger) {
+ this.logger = logger;
+ }
+}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/error/ErrorReporter.java b/ProtocolLib/src/main/java/com/comphenix/protocol/error/ErrorReporter.java
new file mode 100644
index 00000000..de6e1e36
--- /dev/null
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/error/ErrorReporter.java
@@ -0,0 +1,39 @@
+package com.comphenix.protocol.error;
+
+import org.bukkit.plugin.Plugin;
+
+public interface ErrorReporter {
+
+ /**
+ * Prints a small minimal error report about an exception from another plugin.
+ * @param sender - the other plugin.
+ * @param methodName - name of the caller method.
+ * @param error - the exception itself.
+ */
+ public abstract void reportMinimal(Plugin sender, String methodName, Throwable error);
+
+ /**
+ * Prints a warning message from the current plugin.
+ * @param sender - the object containing the caller method.
+ * @param message - error message.
+ */
+ public abstract void reportWarning(Object sender, String message);
+
+ /**
+ * Prints a warning message from the current plugin.
+ * @param sender - the object containing the caller method.
+ * @param message - error message.
+ * @param error - the exception that was thrown.
+ */
+ public abstract void reportWarning(Object sender, String message, Throwable error);
+
+ /**
+ * Prints a detailed error report about an unhandled exception.
+ * @param sender - the object containing the caller method.
+ * @param message - an error message to include.
+ * @param error - the exception that was thrown in the caller method.
+ * @param parameters - parameters from the caller method.
+ */
+ public abstract void reportDetailed(Object sender, String message, Throwable error, Object... parameters);
+
+}
\ No newline at end of file
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketAdapter.java b/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketAdapter.java
index fbe14775..056fe089 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketAdapter.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketAdapter.java
@@ -168,12 +168,20 @@ public abstract class PacketAdapter implements PacketListener {
/**
* Retrieves the name of the plugin that has been associated with the listener.
+ * @param listener - the listener.
* @return Name of the associated plugin.
*/
public static String getPluginName(PacketListener listener) {
-
- Plugin plugin = listener.getPlugin();
-
+ return getPluginName(listener.getPlugin());
+ }
+
+ /**
+ * Retrieves the name of the given plugin.
+ * @param plugin - the plugin.
+ * @return Name of the given plugin.
+ */
+ public static String getPluginName(Plugin plugin) {
+
// Try to get the plugin name
try {
if (plugin == null)
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java
index afbb5fcd..63473dd2 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java
@@ -25,8 +25,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.annotation.Nullable;
@@ -51,6 +49,8 @@ import com.comphenix.protocol.AsynchronousManager;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.async.AsyncFilterManager;
import com.comphenix.protocol.async.AsyncMarker;
+import com.comphenix.protocol.error.DetailedErrorReporter;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.*;
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
import com.comphenix.protocol.reflect.FieldAccessException;
@@ -118,8 +118,8 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// The default class loader
private ClassLoader classLoader;
- // Error logger
- private Logger logger;
+ // Error repoter
+ private ErrorReporter reporter;
// The current server
private Server server;
@@ -142,9 +142,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
* Only create instances of this class if protocol lib is disabled.
* @param unhookTask
*/
- public PacketFilterManager(ClassLoader classLoader, Server server, DelayedSingleTask unhookTask, Logger logger) {
- if (logger == null)
- throw new IllegalArgumentException("logger cannot be NULL.");
+ public PacketFilterManager(ClassLoader classLoader, Server server, DelayedSingleTask unhookTask, DetailedErrorReporter reporter) {
+ if (reporter == null)
+ throw new IllegalArgumentException("reporter cannot be NULL.");
if (classLoader == null)
throw new IllegalArgumentException("classLoader cannot be NULL.");
@@ -155,7 +155,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
this.unhookTask = unhookTask;
this.server = server;
this.classLoader = classLoader;
- this.logger = logger;
+ this.reporter = reporter;
// Used to determine if injection is needed
Predicate isInjectionNecessary = new Predicate() {
@@ -174,20 +174,20 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
try {
// Initialize injection mangers
- this.playerInjection = new PlayerInjectionHandler(classLoader, logger, isInjectionNecessary, this, server);
+ this.playerInjection = new PlayerInjectionHandler(classLoader, reporter, isInjectionNecessary, this, server);
this.packetInjector = new PacketInjector(classLoader, this, playerInjection);
- this.asyncFilterManager = new AsyncFilterManager(logger, server.getScheduler(), this);
+ this.asyncFilterManager = new AsyncFilterManager(reporter, server.getScheduler(), this);
// Attempt to load the list of server and client packets
try {
this.serverPackets = MinecraftRegistry.getServerPackets();
this.clientPackets = MinecraftRegistry.getClientPackets();
} catch (FieldAccessException e) {
- logger.log(Level.WARNING, "Cannot load server and client packet list.", e);
+ reporter.reportWarning(this, "Cannot load server and client packet list.", e);
}
} catch (IllegalAccessException e) {
- logger.log(Level.SEVERE, "Unable to initialize packet injector.", e);
+ reporter.reportWarning(this, "Unable to initialize packet injector.", e);
}
}
@@ -215,10 +215,6 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
playerInjection.checkListener(packetListeners);
}
- public Logger getLogger() {
- return logger;
- }
-
@Override
public ImmutableSet getPacketListeners() {
return ImmutableSet.copyOf(packetListeners);
@@ -398,9 +394,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// Process synchronous events
if (sending)
- packetListeners.invokePacketSending(logger, event);
+ packetListeners.invokePacketSending(reporter, event);
else
- packetListeners.invokePacketRecieving(logger, event);
+ packetListeners.invokePacketRecieving(reporter, event);
// To cancel asynchronous processing, use the async marker
if (!event.isCancelled() && !hasAsyncCancelled(event.getAsyncMarker())) {
@@ -438,7 +434,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
if (serverPackets != null && serverPackets.contains(packetID))
playerInjection.addPacketHandler(packetID);
else
- logger.warning(String.format(
+ reporter.reportWarning(this, String.format(
"[%s] Unsupported server packet ID in current Minecraft version: %s",
PacketAdapter.getPluginName(listener), packetID
));
@@ -449,7 +445,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
if (clientPackets != null && clientPackets.contains(packetID))
packetInjector.addPacketHandler(packetID);
else
- logger.warning(String.format(
+ reporter.reportWarning(this, String.format(
"[%s] Unsupported client packet ID in current Minecraft version: %s",
PacketAdapter.getPluginName(listener), packetID
));
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java
index 94662c9b..5a1ef288 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/SortedPacketListenerList.java
@@ -18,11 +18,9 @@
package com.comphenix.protocol.injector;
import java.util.Collection;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import com.comphenix.protocol.concurrency.AbstractConcurrentListenerMultimap;
-import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
@@ -35,10 +33,10 @@ class SortedPacketListenerList extends AbstractConcurrentListenerMultimap> list = getListener(event.getPacketID());
if (list == null)
@@ -50,19 +48,17 @@ class SortedPacketListenerList extends AbstractConcurrentListenerMultimap> list = getListener(event.getPacketID());
if (list == null)
@@ -73,9 +69,7 @@ class SortedPacketListenerList extends AbstractConcurrentListenerMultimap();
this.replacedLists = new ArrayList>();
- this.logger = logger;
+ this.reporter = reporter;
this.server = server;
this.netLoginInjector = netLoginInjector;
}
@@ -83,7 +82,7 @@ class InjectedServerConnection {
try {
minecraftServer = FieldUtils.readField(minecraftServerField, server, true);
} catch (IllegalAccessException e1) {
- logger.log(Level.WARNING, "Cannot extract minecraft server from Bukkit.");
+ reporter.reportWarning(this, "Cannot extract minecraft server from Bukkit.");
return;
}
@@ -95,15 +94,13 @@ class InjectedServerConnection {
injectServerConnection();
} catch (IllegalArgumentException e) {
- // DEBUG
- logger.log(Level.WARNING, "Reverting to old 1.2.5 server connection injection.", e);
-
+
// Minecraft 1.2.5 or lower
injectListenerThread();
} catch (Exception e) {
// Oh damn - inform the player
- logger.log(Level.SEVERE, "Cannot inject into server connection. Bad things will happen.", e);
+ reporter.reportDetailed(this, "Cannot inject into server connection. Bad things will happen.", e);
}
}
@@ -115,7 +112,7 @@ class InjectedServerConnection {
listenerThreadField = FuzzyReflection.fromObject(minecraftServer).
getFieldByType(".*NetworkListenThread");
} catch (RuntimeException e) {
- logger.log(Level.SEVERE, "Cannot find listener thread in MinecraftServer.", e);
+ reporter.reportDetailed(this, "Cannot find listener thread in MinecraftServer.", e, minecraftServer);
return;
}
@@ -125,7 +122,7 @@ class InjectedServerConnection {
try {
listenerThread = listenerThreadField.get(minecraftServer);
} catch (Exception e) {
- logger.log(Level.WARNING, "Unable to read the listener thread.", e);
+ reporter.reportWarning(this, "Unable to read the listener thread.", e);
return;
}
@@ -142,7 +139,7 @@ class InjectedServerConnection {
try {
serverConnection = serverConnectionMethod.invoke(minecraftServer);
} catch (Exception ex) {
- logger.log(Level.WARNING, "Unable to retrieve server connection", ex);
+ reporter.reportDetailed(this, "Unable to retrieve server connection", ex, minecraftServer);
return;
}
@@ -154,7 +151,7 @@ class InjectedServerConnection {
// Verify the field count
if (matches.size() != 1)
- logger.log(Level.WARNING, "Unexpected number of threads in " + serverConnection.getClass().getName());
+ reporter.reportWarning(this, "Unexpected number of threads in " + serverConnection.getClass().getName());
else
dedicatedThreadField = matches.get(0);
}
@@ -164,7 +161,7 @@ class InjectedServerConnection {
if (dedicatedThreadField != null)
injectEveryListField(FieldUtils.readField(dedicatedThreadField, serverConnection, true), 1);
} catch (IllegalAccessException e) {
- logger.log(Level.WARNING, "Unable to retrieve net handler thread.", e);
+ reporter.reportWarning(this, "Unable to retrieve net handler thread.", e);
}
injectIntoList(serverConnection, listField);
@@ -186,7 +183,7 @@ class InjectedServerConnection {
// Warn about unexpected errors
if (lists.size() < minimum) {
- logger.log(Level.WARNING, "Unable to inject " + minimum + " lists in " + container.getClass().getName());
+ reporter.reportWarning(this, "Unable to inject " + minimum + " lists in " + container.getClass().getName());
}
}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java
index 0bc8981a..b5fc924b 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java
@@ -4,12 +4,11 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import org.bukkit.Server;
import org.bukkit.entity.Player;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.injector.GamePhase;
import com.comphenix.protocol.injector.player.TemporaryPlayerFactory.InjectContainer;
import com.google.common.collect.Maps;
@@ -27,16 +26,16 @@ class NetLoginInjector {
private PlayerInjectionHandler injectionHandler;
private Server server;
- // The current logger
- private Logger logger;
+ // The current error rerporter
+ private ErrorReporter reporter;
private ReadWriteLock injectionLock = new ReentrantReadWriteLock();
// Used to create fake players
private TemporaryPlayerFactory tempPlayerFactory = new TemporaryPlayerFactory();
- public NetLoginInjector(Logger logger, PlayerInjectionHandler injectionHandler, Server server) {
- this.logger = logger;
+ public NetLoginInjector(ErrorReporter reporter, PlayerInjectionHandler injectionHandler, Server server) {
+ this.reporter = reporter;
this.injectionHandler = injectionHandler;
this.server = server;
}
@@ -71,7 +70,7 @@ class NetLoginInjector {
} catch (Throwable e) {
// Minecraft can't handle this, so we'll deal with it here
- logger.log(Level.WARNING, "Unable to hook NetLoginHandler.", e);
+ reporter.reportDetailed(this, "Unable to hook NetLoginHandler.", e, inserting);
return inserting;
} finally {
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java
index 19104e74..2f414f2c 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java
@@ -24,11 +24,11 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
import org.bukkit.entity.Player;
import com.comphenix.protocol.Packets;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.GamePhase;
@@ -73,10 +73,10 @@ class NetworkFieldInjector extends PlayerInjector {
// Used to construct proxy objects
private ClassLoader classLoader;
- public NetworkFieldInjector(ClassLoader classLoader, Logger logger, Player player,
+ public NetworkFieldInjector(ClassLoader classLoader, ErrorReporter reporter, Player player,
ListenerInvoker manager, IntegerSet sendingFilters) throws IllegalAccessException {
- super(logger, player, manager);
+ super(reporter, player, manager);
this.classLoader = classLoader;
this.sendingFilters = sendingFilters;
}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java
index 4f98d3cd..6635744d 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java
@@ -28,11 +28,11 @@ import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
-import java.util.logging.Logger;
import org.bukkit.entity.Player;
import com.comphenix.protocol.Packets;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.GamePhase;
@@ -54,9 +54,9 @@ class NetworkObjectInjector extends PlayerInjector {
// Shared callback filter - avoid creating a new class every time
private static CallbackFilter callbackFilter;
- public NetworkObjectInjector(ClassLoader classLoader, Logger logger, Player player,
+ public NetworkObjectInjector(ClassLoader classLoader, ErrorReporter reporter, Player player,
ListenerInvoker invoker, IntegerSet sendingFilters) throws IllegalAccessException {
- super(logger, player, invoker);
+ super(reporter, player, invoker);
this.sendingFilters = sendingFilters;
this.classLoader = classLoader;
}
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 9ad93166..70ed7a3f 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
@@ -20,8 +20,6 @@ package com.comphenix.protocol.injector.player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import net.minecraft.server.Packet;
import net.sf.cglib.proxy.Callback;
@@ -34,6 +32,7 @@ import net.sf.cglib.proxy.NoOp;
import org.bukkit.entity.Player;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.GamePhase;
import com.comphenix.protocol.injector.ListenerInvoker;
@@ -68,11 +67,11 @@ public class NetworkServerInjector extends PlayerInjector {
private boolean hasDisconnected;
public NetworkServerInjector(
- ClassLoader classLoader, Logger logger, Player player,
+ ClassLoader classLoader, ErrorReporter reporter, Player player,
ListenerInvoker invoker, IntegerSet sendingFilters,
InjectedServerConnection serverInjection) throws IllegalAccessException {
- super(logger, player, invoker);
+ super(reporter, player, invoker);
this.classLoader = classLoader;
this.sendingFilters = sendingFilters;
this.serverInjection = serverInjection;
@@ -295,9 +294,9 @@ public class NetworkServerInjector extends PlayerInjector {
FieldUtils.writeField(disconnectField, handler, value);
} catch (IllegalArgumentException e) {
- logger.log(Level.WARNING, "Unable to find disconnect field. Is ProtocolLib up to date?");
+ reporter.reportDetailed(this, "Unable to find disconnect field. Is ProtocolLib up to date?", e, handler);
} catch (IllegalAccessException e) {
- logger.log(Level.WARNING, "Unable to update disconnected field. Player quit event may be sent twice.");
+ reporter.reportWarning(this, "Unable to update disconnected field. Player quit event may be sent twice.");
}
}
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 afc432b9..215fc3c7 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
@@ -24,14 +24,13 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import net.minecraft.server.Packet;
import org.bukkit.Server;
import org.bukkit.entity.Player;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketListener;
@@ -72,8 +71,8 @@ public class PlayerInjectionHandler {
private volatile PlayerInjectHooks loginPlayerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
private volatile PlayerInjectHooks playingPlayerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
- // Error logger
- private Logger logger;
+ // Error reporter
+ private ErrorReporter reporter;
// Whether or not we're closing
private boolean hasClosed;
@@ -90,15 +89,15 @@ public class PlayerInjectionHandler {
// Used to filter injection attempts
private Predicate injectionFilter;
- public PlayerInjectionHandler(ClassLoader classLoader, Logger logger, Predicate injectionFilter,
+ public PlayerInjectionHandler(ClassLoader classLoader, ErrorReporter reporter, Predicate injectionFilter,
ListenerInvoker invoker, Server server) {
this.classLoader = classLoader;
- this.logger = logger;
+ this.reporter = reporter;
this.invoker = invoker;
this.injectionFilter = injectionFilter;
- this.netLoginInjector = new NetLoginInjector(logger, this, server);
- this.serverInjection = new InjectedServerConnection(logger, server, netLoginInjector);
+ this.netLoginInjector = new NetLoginInjector(reporter, this, server);
+ this.serverInjection = new InjectedServerConnection(reporter, server, netLoginInjector);
serverInjection.injectList();
}
@@ -173,11 +172,11 @@ public class PlayerInjectionHandler {
// Construct the correct player hook
switch (hook) {
case NETWORK_HANDLER_FIELDS:
- return new NetworkFieldInjector(classLoader, logger, player, invoker, sendingFilters);
+ return new NetworkFieldInjector(classLoader, reporter, player, invoker, sendingFilters);
case NETWORK_MANAGER_OBJECT:
- return new NetworkObjectInjector(classLoader, logger, player, invoker, sendingFilters);
+ return new NetworkObjectInjector(classLoader, reporter, player, invoker, sendingFilters);
case NETWORK_SERVER_OBJECT:
- return new NetworkServerInjector(classLoader, logger, player, invoker, sendingFilters, serverInjection);
+ return new NetworkServerInjector(classLoader, reporter, player, invoker, sendingFilters, serverInjection);
default:
throw new IllegalArgumentException("Cannot construct a player injector.");
}
@@ -198,7 +197,7 @@ public class PlayerInjectionHandler {
if (injector != null) {
return injector.getPlayer();
} else {
- logger.warning("Unable to find stream: " + inputStream);
+ reporter.reportWarning(this, "Unable to find stream: " + inputStream);
return null;
}
@@ -310,7 +309,8 @@ public class PlayerInjectionHandler {
} catch (Exception e) {
// Mark this injection attempt as a failure
- logger.log(Level.SEVERE, "Player hook " + tempHook.toString() + " failed.", e);
+ reporter.reportDetailed(this, "Player hook " + tempHook.toString() + " failed.",
+ e, player, injectionPoint, phase);
hookFailed = true;
}
@@ -318,7 +318,7 @@ public class PlayerInjectionHandler {
tempHook = PlayerInjectHooks.values()[tempHook.ordinal() - 1];
if (hookFailed)
- logger.log(Level.INFO, "Switching to " + tempHook.toString() + " instead.");
+ reporter.reportWarning(this, "Switching to " + tempHook.toString() + " instead.");
// Check for UTTER FAILURE
if (tempHook == PlayerInjectHooks.NONE) {
@@ -353,8 +353,8 @@ public class PlayerInjectionHandler {
try {
if (injector != null)
injector.cleanupAll();
- } catch (Exception e2) {
- logger.log(Level.WARNING, "Cleaing up after player hook failed.", e2);
+ } catch (Exception ex) {
+ reporter.reportDetailed(this, "Cleaing up after player hook failed.", ex, injector);
}
}
@@ -415,7 +415,7 @@ public class PlayerInjectionHandler {
} catch (IllegalAccessException e) {
// Let the user know
- logger.log(Level.WARNING, "Unable to fully revert old injector. May cause conflicts.", e);
+ reporter.reportWarning(this, "Unable to fully revert old injector. May cause conflicts.", e);
}
}
@@ -470,7 +470,7 @@ public class PlayerInjectionHandler {
if (injector != null)
injector.sendServerPacket(packet.getHandle(), filters);
else
- logger.log(Level.WARNING, String.format(
+ reporter.reportWarning(this, String.format(
"Unable to send packet %s (%s): Player %s has logged out.",
packet.getID(), packet, reciever.getName()
));
@@ -491,7 +491,7 @@ public class PlayerInjectionHandler {
if (injector != null)
injector.processPacket(mcPacket);
else
- logger.log(Level.WARNING, String.format(
+ reporter.reportWarning(this, String.format(
"Unable to receieve packet %s. Player %s has logged out.",
mcPacket, player.getName()
));
@@ -537,7 +537,7 @@ public class PlayerInjectionHandler {
try {
checkListener(listener);
} catch (IllegalStateException e) {
- logger.log(Level.WARNING, "Unsupported listener.", e);
+ reporter.reportWarning(this, "Unsupported listener.", e);
}
}
}
@@ -565,14 +565,6 @@ public class PlayerInjectionHandler {
return sendingFilters.toSet();
}
- /**
- * Retrieve the current logger.
- * @return Error logger.
- */
- public Logger getLogger() {
- return logger;
- }
-
public void close() {
// Guard
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java
index a4c2d605..31b2eeda 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java
@@ -24,8 +24,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.net.SocketAddress;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.NetLoginHandler;
@@ -36,6 +34,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import com.comphenix.protocol.Packets;
+import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
@@ -100,7 +99,7 @@ abstract class PlayerInjector {
protected DataInputStream cachedInput;
// Handle errors
- protected Logger logger;
+ protected ErrorReporter reporter;
// Scheduled action on the next packet event
protected Runnable scheduledAction;
@@ -112,8 +111,8 @@ abstract class PlayerInjector {
boolean updateOnLogin;
Player updatedPlayer;
- public PlayerInjector(Logger logger, Player player, ListenerInvoker invoker) throws IllegalAccessException {
- this.logger = logger;
+ public PlayerInjector(ErrorReporter reporter, Player player, ListenerInvoker invoker) throws IllegalAccessException {
+ this.reporter = reporter;
this.player = player;
this.invoker = invoker;
}
@@ -303,19 +302,24 @@ abstract class PlayerInjector {
disconnect.invoke(handler, message);
return;
} catch (IllegalArgumentException e) {
- logger.log(Level.WARNING, "Invalid argument passed to disconnect method: " + message, e);
+ reporter.reportDetailed(this, "Invalid argument passed to disconnect method: " + message, e, handler);
} catch (IllegalAccessException e) {
- logger.log(Level.SEVERE, "Unable to access disconnect method.", e);
+ reporter.reportWarning(this, "Unable to access disconnect method.", e);
}
}
-
+
// Fuck it
try {
- getSocket().close();
- } catch (IOException e) {
- logger.log(Level.SEVERE, "Unable to close socket.", e);
+ Socket socket = getSocket();
+
+ try {
+ socket.close();
+ } catch (IOException e) {
+ reporter.reportDetailed(this, "Unable to close socket.", e, socket);
+ }
+
} catch (IllegalAccessException e) {
- logger.log(Level.SEVERE, "Insufficient permissions. Cannot close socket.", e);
+ reporter.reportWarning(this, "Insufficient permissions. Cannot close socket.", e);
}
}
@@ -332,7 +336,7 @@ abstract class PlayerInjector {
return null;
hasProxyType = true;
- logger.log(Level.WARNING, "Detected server handler proxy type by another plugin. Conflict may occur!");
+ reporter.reportWarning(this, "Detected server handler proxy type by another plugin. Conflict may occur!");
// No? Is it a Proxy type?
try {
@@ -347,7 +351,7 @@ abstract class PlayerInjector {
}
} catch (IllegalAccessException e) {
- logger.warning("Unable to load server handler from proxy type.");
+ reporter.reportWarning(this, "Unable to load server handler from proxy type.");
}
// Nope, just go with it
@@ -511,7 +515,7 @@ abstract class PlayerInjector {
try {
updatedPlayer = getEntityPlayer(getNetHandler()).getBukkitEntity();
} catch (IllegalAccessException e) {
- logger.log(Level.WARNING, "Cannot update player in PlayerEvent.", e);
+ reporter.reportDetailed(this, "Cannot update player in PlayerEvent.", e, packet);
}
}