Archiviert
13
0

Update asynchronous manager and handle static senders in reports.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-07-06 07:51:02 +02:00
Ursprung 6847283fb3
Commit a4f81e5e9f
6 geänderte Dateien mit 623 neuen und 582 gelöschten Zeilen

Datei anzeigen

@ -217,7 +217,7 @@ public class ProtocolLibrary extends JavaPlugin {
@Override @Override
protected Report filterReport(Object sender, Report report, boolean detailed) { protected Report filterReport(Object sender, Report report, boolean detailed) {
String canonicalName = ReportType.getReportName(sender.getClass(), report.getType()); String canonicalName = ReportType.getReportName(sender, report.getType());
String reportName = Iterables.getLast(Splitter.on("#").split(canonicalName)).toUpperCase(); String reportName = Iterables.getLast(Splitter.on("#").split(canonicalName)).toUpperCase();
if (config != null && config.getModificationCount() != lastModCount) { if (config != null && config.getModificationCount() != lastModCount) {

Datei anzeigen

@ -1,80 +1,80 @@
package com.comphenix.protocol.error; package com.comphenix.protocol.error;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.error.Report.ReportBuilder; import com.comphenix.protocol.error.Report.ReportBuilder;
/** /**
* Construct an error reporter that delegates to another error reporter. * Construct an error reporter that delegates to another error reporter.
* @author Kristian * @author Kristian
*/ */
public class DelegatedErrorReporter implements ErrorReporter { public class DelegatedErrorReporter implements ErrorReporter {
private final ErrorReporter delegated; private final ErrorReporter delegated;
/** /**
* Construct a new error reporter that forwards all reports to a given reporter. * Construct a new error reporter that forwards all reports to a given reporter.
* @param delegated - the delegated reporter. * @param delegated - the delegated reporter.
*/ */
public DelegatedErrorReporter(ErrorReporter delegated) { public DelegatedErrorReporter(ErrorReporter delegated) {
this.delegated = delegated; this.delegated = delegated;
} }
/** /**
* Retrieve the underlying error reporter. * Retrieve the underlying error reporter.
* @return Underlying error reporter. * @return Underlying error reporter.
*/ */
public ErrorReporter getDelegated() { public ErrorReporter getDelegated() {
return delegated; return delegated;
} }
@Override @Override
public void reportMinimal(Plugin sender, String methodName, Throwable error) { public void reportMinimal(Plugin sender, String methodName, Throwable error) {
delegated.reportMinimal(sender, methodName, error); delegated.reportMinimal(sender, methodName, error);
} }
@Override @Override
public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) { public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) {
delegated.reportMinimal(sender, methodName, error, parameters); delegated.reportMinimal(sender, methodName, error, parameters);
} }
@Override @Override
public void reportWarning(Object sender, Report report) { public void reportWarning(Object sender, Report report) {
Report transformed = filterReport(sender, report, false); Report transformed = filterReport(sender, report, false);
if (transformed != null) { if (transformed != null) {
delegated.reportWarning(sender, transformed); delegated.reportWarning(sender, transformed);
} }
} }
@Override @Override
public void reportDetailed(Object sender, Report report) { public void reportDetailed(Object sender, Report report) {
Report transformed = filterReport(sender, report, true); Report transformed = filterReport(sender, report, true);
if (transformed != null) { if (transformed != null) {
delegated.reportDetailed(sender, transformed); delegated.reportDetailed(sender, transformed);
} }
} }
/** /**
* Invoked before an error report is passed on to the underlying error reporter. * Invoked before an error report is passed on to the underlying error reporter.
* <p> * <p>
* To cancel a report, return NULL. * To cancel a report, return NULL.
* @param sender - the sender component. * @param sender - the sender instance or class.
* @param report - the error report. * @param report - the error report.
* @param detailed - whether or not the report will be displayed in detail. * @param detailed - whether or not the report will be displayed in detail.
* @return The report to pass on, or NULL to cancel it. * @return The report to pass on, or NULL to cancel it.
*/ */
protected Report filterReport(Object sender, Report report, boolean detailed) { protected Report filterReport(Object sender, Report report, boolean detailed) {
return report; return report;
} }
@Override @Override
public void reportWarning(Object sender, ReportBuilder reportBuilder) { public void reportWarning(Object sender, ReportBuilder reportBuilder) {
reportWarning(sender, reportBuilder.build()); reportWarning(sender, reportBuilder.build());
} }
@Override @Override
public void reportDetailed(Object sender, ReportBuilder reportBuilder) { public void reportDetailed(Object sender, ReportBuilder reportBuilder) {
reportDetailed(sender, reportBuilder.build()); reportDetailed(sender, reportBuilder.build());
} }
} }

Datei anzeigen

@ -1,499 +1,499 @@
/* /*
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland * Copyright (C) 2012 Kristian S. Stangeland
* *
* This program is free software; you can redistribute it and/or modify it under the terms of the * This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of * GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version. * the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along with this program; * You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA * 02111-1307 USA
*/ */
package com.comphenix.protocol.error; package com.comphenix.protocol.error;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.lang.builder.ToStringStyle;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.error.Report.ReportBuilder; import com.comphenix.protocol.error.Report.ReportBuilder;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.reflect.PrettyPrinter; import com.comphenix.protocol.reflect.PrettyPrinter;
import com.google.common.primitives.Primitives; import com.google.common.primitives.Primitives;
/** /**
* Internal class used to handle exceptions. * Internal class used to handle exceptions.
* *
* @author Kristian * @author Kristian
*/ */
public class DetailedErrorReporter implements ErrorReporter { public class DetailedErrorReporter implements ErrorReporter {
/** /**
* Report format for printing the current exception count. * Report format for printing the current exception count.
*/ */
public static final ReportType REPORT_EXCEPTION_COUNT = new ReportType("Internal exception count: %s!"); public static final ReportType REPORT_EXCEPTION_COUNT = new ReportType("Internal exception count: %s!");
public static final String SECOND_LEVEL_PREFIX = " "; public static final String SECOND_LEVEL_PREFIX = " ";
public static final String DEFAULT_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 DEFAULT_SUPPORT_URL = "http://dev.bukkit.org/server-mods/protocollib/";
// Users that are informed about errors in the chat // Users that are informed about errors in the chat
public static final String ERROR_PERMISSION = "protocol.info"; public static final String ERROR_PERMISSION = "protocol.info";
// We don't want to spam the server // We don't want to spam the server
public static final int DEFAULT_MAX_ERROR_COUNT = 20; public static final int DEFAULT_MAX_ERROR_COUNT = 20;
// Prevent spam per plugin too // Prevent spam per plugin too
private ConcurrentMap<String, AtomicInteger> warningCount = new ConcurrentHashMap<String, AtomicInteger>(); private ConcurrentMap<String, AtomicInteger> warningCount = new ConcurrentHashMap<String, AtomicInteger>();
protected String prefix; protected String prefix;
protected String supportURL; protected String supportURL;
protected AtomicInteger internalErrorCount = new AtomicInteger(); protected AtomicInteger internalErrorCount = new AtomicInteger();
protected int maxErrorCount; protected int maxErrorCount;
protected Logger logger; protected Logger logger;
protected WeakReference<Plugin> pluginReference; protected WeakReference<Plugin> pluginReference;
protected String pluginName; protected String pluginName;
// Whether or not Apache Commons is not present // Whether or not Apache Commons is not present
protected boolean apacheCommonsMissing; protected boolean apacheCommonsMissing;
// Map of global objects // Map of global objects
protected Map<String, Object> globalParameters = new HashMap<String, Object>(); protected Map<String, Object> globalParameters = new HashMap<String, Object>();
/** /**
* Create a default error reporting system. * Create a default error reporting system.
*/ */
public DetailedErrorReporter(Plugin plugin) { public DetailedErrorReporter(Plugin plugin) {
this(plugin, DEFAULT_PREFIX, DEFAULT_SUPPORT_URL); this(plugin, DEFAULT_PREFIX, DEFAULT_SUPPORT_URL);
} }
/** /**
* Create a central error reporting system. * Create a central error reporting system.
* @param plugin - the plugin owner. * @param plugin - the plugin owner.
* @param prefix - default line prefix. * @param prefix - default line prefix.
* @param supportURL - URL to report the error. * @param supportURL - URL to report the error.
*/ */
public DetailedErrorReporter(Plugin plugin, String prefix, String supportURL) { public DetailedErrorReporter(Plugin plugin, String prefix, String supportURL) {
this(plugin, prefix, supportURL, DEFAULT_MAX_ERROR_COUNT, getBukkitLogger()); this(plugin, prefix, supportURL, DEFAULT_MAX_ERROR_COUNT, getBukkitLogger());
} }
/** /**
* Create a central error reporting system. * Create a central error reporting system.
* @param plugin - the plugin owner. * @param plugin - the plugin owner.
* @param prefix - default line prefix. * @param prefix - default line prefix.
* @param supportURL - URL to report the error. * @param supportURL - URL to report the error.
* @param maxErrorCount - number of errors to print before giving up. * @param maxErrorCount - number of errors to print before giving up.
* @param logger - current logger. * @param logger - current logger.
*/ */
public DetailedErrorReporter(Plugin plugin, String prefix, String supportURL, int maxErrorCount, Logger logger) { public DetailedErrorReporter(Plugin plugin, String prefix, String supportURL, int maxErrorCount, Logger logger) {
if (plugin == null) if (plugin == null)
throw new IllegalArgumentException("Plugin cannot be NULL."); throw new IllegalArgumentException("Plugin cannot be NULL.");
this.pluginReference = new WeakReference<Plugin>(plugin); this.pluginReference = new WeakReference<Plugin>(plugin);
this.pluginName = plugin.getName(); this.pluginName = plugin.getName();
this.prefix = prefix; this.prefix = prefix;
this.supportURL = supportURL; this.supportURL = supportURL;
this.maxErrorCount = maxErrorCount; this.maxErrorCount = maxErrorCount;
this.logger = logger; this.logger = logger;
} }
// Attempt to get the logger. // Attempt to get the logger.
private static Logger getBukkitLogger() { private static Logger getBukkitLogger() {
try { try {
return Bukkit.getLogger(); return Bukkit.getLogger();
} catch (Throwable e) { } catch (Throwable e) {
return Logger.getLogger("Minecraft"); return Logger.getLogger("Minecraft");
} }
} }
@Override @Override
public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) { public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) {
if (reportMinimalNoSpam(sender, methodName, error)) { if (reportMinimalNoSpam(sender, methodName, error)) {
// Print parameters, if they are given // Print parameters, if they are given
if (parameters != null && parameters.length > 0) { if (parameters != null && parameters.length > 0) {
logger.log(Level.SEVERE, printParameters(parameters)); logger.log(Level.SEVERE, printParameters(parameters));
} }
} }
} }
@Override @Override
public void reportMinimal(Plugin sender, String methodName, Throwable error) { public void reportMinimal(Plugin sender, String methodName, Throwable error) {
reportMinimalNoSpam(sender, methodName, error); reportMinimalNoSpam(sender, methodName, error);
} }
/** /**
* Report a problem with a given method and plugin, ensuring that we don't exceed the maximum number of error reports. * Report a problem with a given method and plugin, ensuring that we don't exceed the maximum number of error reports.
* @param sender - the component that observed this exception. * @param sender - the component that observed this exception.
* @param methodName - the method name. * @param methodName - the method name.
* @param error - the error itself. * @param error - the error itself.
* @return TRUE if the error was printed, FALSE if it was suppressed. * @return TRUE if the error was printed, FALSE if it was suppressed.
*/ */
public boolean reportMinimalNoSpam(Plugin sender, String methodName, Throwable error) { public boolean reportMinimalNoSpam(Plugin sender, String methodName, Throwable error) {
String pluginName = PacketAdapter.getPluginName(sender); String pluginName = PacketAdapter.getPluginName(sender);
AtomicInteger counter = warningCount.get(pluginName); AtomicInteger counter = warningCount.get(pluginName);
// Thread safe pattern // Thread safe pattern
if (counter == null) { if (counter == null) {
AtomicInteger created = new AtomicInteger(); AtomicInteger created = new AtomicInteger();
counter = warningCount.putIfAbsent(pluginName, created); counter = warningCount.putIfAbsent(pluginName, created);
if (counter == null) { if (counter == null) {
counter = created; counter = created;
} }
} }
final int errorCount = counter.incrementAndGet(); final int errorCount = counter.incrementAndGet();
// See if we should print the full error // See if we should print the full error
if (errorCount < getMaxErrorCount()) { if (errorCount < getMaxErrorCount()) {
logger.log(Level.SEVERE, "[" + pluginName + "] Unhandled exception occured in " + logger.log(Level.SEVERE, "[" + pluginName + "] Unhandled exception occured in " +
methodName + " for " + pluginName, error); methodName + " for " + pluginName, error);
return true; return true;
} else { } else {
// Nope - only print the error count occationally // Nope - only print the error count occationally
if (isPowerOfTwo(errorCount)) { if (isPowerOfTwo(errorCount)) {
logger.log(Level.SEVERE, "[" + pluginName + "] Unhandled exception number " + errorCount + " occured in " + logger.log(Level.SEVERE, "[" + pluginName + "] Unhandled exception number " + errorCount + " occured in " +
methodName + " for " + pluginName, error); methodName + " for " + pluginName, error);
} }
return false; return false;
} }
} }
/** /**
* Determine if a given number is a power of two. * Determine if a given number is a power of two.
* <p> * <p>
* That is, if there exists an N such that 2^N = number. * That is, if there exists an N such that 2^N = number.
* @param number - the number to check. * @param number - the number to check.
* @return TRUE if the given number is a power of two, FALSE otherwise. * @return TRUE if the given number is a power of two, FALSE otherwise.
*/ */
private boolean isPowerOfTwo(int number) { private boolean isPowerOfTwo(int number) {
return (number & (number - 1)) == 0; return (number & (number - 1)) == 0;
} }
@Override @Override
public void reportWarning(Object sender, ReportBuilder reportBuilder) { public void reportWarning(Object sender, ReportBuilder reportBuilder) {
if (reportBuilder == null) if (reportBuilder == null)
throw new IllegalArgumentException("reportBuilder cannot be NULL."); throw new IllegalArgumentException("reportBuilder cannot be NULL.");
reportWarning(sender, reportBuilder.build()); reportWarning(sender, reportBuilder.build());
} }
@Override @Override
public void reportWarning(Object sender, Report report) { public void reportWarning(Object sender, Report report) {
String message = "[" + pluginName + "] [" + getSenderName(sender) + "] " + report.getReportMessage(); String message = "[" + pluginName + "] [" + getSenderName(sender) + "] " + report.getReportMessage();
// Print the main warning // Print the main warning
if (report.getException() != null) { if (report.getException() != null) {
logger.log(Level.WARNING, message, report.getException()); logger.log(Level.WARNING, message, report.getException());
} else { } else {
logger.log(Level.WARNING, message); logger.log(Level.WARNING, message);
} }
// Parameters? // Parameters?
if (report.hasCallerParameters()) { if (report.hasCallerParameters()) {
// Write it // Write it
logger.log(Level.WARNING, printParameters(report.getCallerParameters())); logger.log(Level.WARNING, printParameters(report.getCallerParameters()));
} }
} }
/** /**
* Retrieve the name of a sender class. * Retrieve the name of a sender class.
* @param sender - sender object. * @param sender - sender object.
* @return The name of the sender's class. * @return The name of the sender's class.
*/ */
private String getSenderName(Object sender) { private String getSenderName(Object sender) {
if (sender != null) if (sender != null)
return sender.getClass().getSimpleName(); return ReportType.getSenderClass(sender).getSimpleName();
else else
return "NULL"; return "NULL";
} }
@Override @Override
public void reportDetailed(Object sender, ReportBuilder reportBuilder) { public void reportDetailed(Object sender, ReportBuilder reportBuilder) {
reportDetailed(sender, reportBuilder.build()); reportDetailed(sender, reportBuilder.build());
} }
@Override @Override
public void reportDetailed(Object sender, Report report) { public void reportDetailed(Object sender, Report report) {
final Plugin plugin = pluginReference.get(); final Plugin plugin = pluginReference.get();
final int errorCount = internalErrorCount.incrementAndGet(); final int errorCount = internalErrorCount.incrementAndGet();
// Do not overtly spam the server! // Do not overtly spam the server!
if (errorCount > getMaxErrorCount()) { if (errorCount > getMaxErrorCount()) {
// Only allow the error count at rare occations // Only allow the error count at rare occations
if (isPowerOfTwo(errorCount)) { if (isPowerOfTwo(errorCount)) {
// Permit it - but print the number of exceptions first // Permit it - but print the number of exceptions first
reportWarning(this, Report.newBuilder(REPORT_EXCEPTION_COUNT).messageParam(errorCount).build()); reportWarning(this, Report.newBuilder(REPORT_EXCEPTION_COUNT).messageParam(errorCount).build());
} else { } else {
// NEVER SPAM THE CONSOLE // NEVER SPAM THE CONSOLE
return; return;
} }
} }
StringWriter text = new StringWriter(); StringWriter text = new StringWriter();
PrintWriter writer = new PrintWriter(text); PrintWriter writer = new PrintWriter(text);
// Helpful message // Helpful message
writer.println("[" + pluginName + "] INTERNAL ERROR: " + report.getReportMessage()); writer.println("[" + pluginName + "] INTERNAL ERROR: " + report.getReportMessage());
writer.println("If this problem hasn't already been reported, please open a ticket"); writer.println("If this problem hasn't already been reported, please open a ticket");
writer.println("at " + supportURL + " with the following data:"); writer.println("at " + supportURL + " with the following data:");
// Now, let us print important exception information // Now, let us print important exception information
writer.println(" ===== STACK TRACE ====="); writer.println(" ===== STACK TRACE =====");
if (report.getException() != null) { if (report.getException() != null) {
report.getException().printStackTrace(writer); report.getException().printStackTrace(writer);
} }
// Data dump! // Data dump!
writer.println(" ===== DUMP ====="); writer.println(" ===== DUMP =====");
// Relevant parameters // Relevant parameters
if (report.hasCallerParameters()) { if (report.hasCallerParameters()) {
printParameters(writer, report.getCallerParameters()); printParameters(writer, report.getCallerParameters());
} }
// Global parameters // Global parameters
for (String param : globalParameters()) { for (String param : globalParameters()) {
writer.println(SECOND_LEVEL_PREFIX + param + ":"); writer.println(SECOND_LEVEL_PREFIX + param + ":");
writer.println(addPrefix(getStringDescription(getGlobalParameter(param)), writer.println(addPrefix(getStringDescription(getGlobalParameter(param)),
SECOND_LEVEL_PREFIX + SECOND_LEVEL_PREFIX)); SECOND_LEVEL_PREFIX + SECOND_LEVEL_PREFIX));
} }
// Now, for the sender itself // Now, for the sender itself
writer.println("Sender:"); writer.println("Sender:");
writer.println(addPrefix(getStringDescription(sender), SECOND_LEVEL_PREFIX)); writer.println(addPrefix(getStringDescription(sender), SECOND_LEVEL_PREFIX));
// And plugin // And plugin
if (plugin != null) { if (plugin != null) {
writer.println("Version:"); writer.println("Version:");
writer.println(addPrefix(plugin.toString(), SECOND_LEVEL_PREFIX)); writer.println(addPrefix(plugin.toString(), SECOND_LEVEL_PREFIX));
} }
// Add the server version too // Add the server version too
if (Bukkit.getServer() != null) { if (Bukkit.getServer() != null) {
writer.println("Server:"); writer.println("Server:");
writer.println(addPrefix(Bukkit.getServer().getVersion(), SECOND_LEVEL_PREFIX)); writer.println(addPrefix(Bukkit.getServer().getVersion(), SECOND_LEVEL_PREFIX));
// Inform of this occurrence // Inform of this occurrence
if (ERROR_PERMISSION != null) { if (ERROR_PERMISSION != null) {
Bukkit.getServer().broadcast( Bukkit.getServer().broadcast(
String.format("Error %s (%s) occured in %s.", report.getReportMessage(), report.getException(), sender), String.format("Error %s (%s) occured in %s.", report.getReportMessage(), report.getException(), sender),
ERROR_PERMISSION ERROR_PERMISSION
); );
} }
} }
// Make sure it is reported // Make sure it is reported
logger.severe(addPrefix(text.toString(), prefix)); logger.severe(addPrefix(text.toString(), prefix));
} }
private String printParameters(Object... parameters) { private String printParameters(Object... parameters) {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
// Print and retrieve the string buffer // Print and retrieve the string buffer
printParameters(new PrintWriter(writer), parameters); printParameters(new PrintWriter(writer), parameters);
return writer.toString(); return writer.toString();
} }
private void printParameters(PrintWriter writer, Object[] parameters) { private void printParameters(PrintWriter writer, Object[] parameters) {
writer.println("Parameters: "); writer.println("Parameters: ");
// We *really* want to get as much information as possible // We *really* want to get as much information as possible
for (Object param : parameters) { for (Object param : parameters) {
writer.println(addPrefix(getStringDescription(param), SECOND_LEVEL_PREFIX)); writer.println(addPrefix(getStringDescription(param), SECOND_LEVEL_PREFIX));
} }
} }
/** /**
* Adds the given prefix to every line in the text. * Adds the given prefix to every line in the text.
* @param text - text to modify. * @param text - text to modify.
* @param prefix - prefix added to every line in the text. * @param prefix - prefix added to every line in the text.
* @return The modified text. * @return The modified text.
*/ */
protected String addPrefix(String text, String prefix) { protected String addPrefix(String text, String prefix) {
return text.replaceAll("(?m)^", prefix); return text.replaceAll("(?m)^", prefix);
} }
/** /**
* Retrieve a string representation of the given object. * Retrieve a string representation of the given object.
* @param value - object to convert. * @param value - object to convert.
* @return String representation. * @return String representation.
*/ */
protected String getStringDescription(Object value) { protected String getStringDescription(Object value) {
// We can't only rely on toString. // We can't only rely on toString.
if (value == null) { if (value == null) {
return "[NULL]"; return "[NULL]";
} if (isSimpleType(value)) { } if (isSimpleType(value) || value instanceof Class<?>) {
return value.toString(); return value.toString();
} else { } else {
try { try {
if (!apacheCommonsMissing) if (!apacheCommonsMissing)
return (ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null)); return (ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null));
} catch (Throwable ex) { } catch (Throwable ex) {
// Apache is probably missing // Apache is probably missing
apacheCommonsMissing = true; apacheCommonsMissing = true;
} }
// Use our custom object printer instead // Use our custom object printer instead
try { try {
return PrettyPrinter.printObject(value, value.getClass(), Object.class); return PrettyPrinter.printObject(value, value.getClass(), Object.class);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
return "[Error: " + e.getMessage() + "]"; return "[Error: " + e.getMessage() + "]";
} }
} }
} }
/** /**
* Determine if the given object is a wrapper for a primitive/simple type or not. * Determine if the given object is a wrapper for a primitive/simple type or not.
* @param test - the object to test. * @param test - the object to test.
* @return TRUE if this object is simple enough to simply be printed, FALSE othewise. * @return TRUE if this object is simple enough to simply be printed, FALSE othewise.
*/ */
protected boolean isSimpleType(Object test) { protected boolean isSimpleType(Object test) {
return test instanceof String || Primitives.isWrapperType(test.getClass()); return test instanceof String || Primitives.isWrapperType(test.getClass());
} }
/** /**
* Retrieve the current number of errors printed through {@link #reportDetailed(Object, Report)}. * Retrieve the current number of errors printed through {@link #reportDetailed(Object, Report)}.
* @return Number of errors printed. * @return Number of errors printed.
*/ */
public int getErrorCount() { public int getErrorCount() {
return internalErrorCount.get(); return internalErrorCount.get();
} }
/** /**
* Set the number of errors printed. * Set the number of errors printed.
* @param errorCount - new number of errors printed. * @param errorCount - new number of errors printed.
*/ */
public void setErrorCount(int errorCount) { public void setErrorCount(int errorCount) {
internalErrorCount.set(errorCount); internalErrorCount.set(errorCount);
} }
/** /**
* Retrieve the maximum number of errors we can print before we begin suppressing errors. * Retrieve the maximum number of errors we can print before we begin suppressing errors.
* @return Maximum number of errors. * @return Maximum number of errors.
*/ */
public int getMaxErrorCount() { public int getMaxErrorCount() {
return maxErrorCount; return maxErrorCount;
} }
/** /**
* Set the maximum number of errors we can print before we begin suppressing errors. * Set the maximum number of errors we can print before we begin suppressing errors.
* @param maxErrorCount - new max count. * @param maxErrorCount - new max count.
*/ */
public void setMaxErrorCount(int maxErrorCount) { public void setMaxErrorCount(int maxErrorCount) {
this.maxErrorCount = maxErrorCount; this.maxErrorCount = maxErrorCount;
} }
/** /**
* Adds the given global parameter. It will be included in every error report. * Adds the given global parameter. It will be included in every error report.
* <p> * <p>
* Both key and value must be non-null. * Both key and value must be non-null.
* @param key - name of parameter. * @param key - name of parameter.
* @param value - the global parameter itself. * @param value - the global parameter itself.
*/ */
public void addGlobalParameter(String key, Object value) { public void addGlobalParameter(String key, Object value) {
if (key == null) if (key == null)
throw new IllegalArgumentException("key cannot be NULL."); throw new IllegalArgumentException("key cannot be NULL.");
if (value == null) if (value == null)
throw new IllegalArgumentException("value cannot be NULL."); throw new IllegalArgumentException("value cannot be NULL.");
globalParameters.put(key, value); globalParameters.put(key, value);
} }
/** /**
* Retrieve a global parameter by its key. * Retrieve a global parameter by its key.
* @param key - key of the parameter to retrieve. * @param key - key of the parameter to retrieve.
* @return The value of the global parameter, or NULL if not found. * @return The value of the global parameter, or NULL if not found.
*/ */
public Object getGlobalParameter(String key) { public Object getGlobalParameter(String key) {
if (key == null) if (key == null)
throw new IllegalArgumentException("key cannot be NULL."); throw new IllegalArgumentException("key cannot be NULL.");
return globalParameters.get(key); return globalParameters.get(key);
} }
/** /**
* Reset all global parameters. * Reset all global parameters.
*/ */
public void clearGlobalParameters() { public void clearGlobalParameters() {
globalParameters.clear(); globalParameters.clear();
} }
/** /**
* Retrieve a set of every registered global parameter. * Retrieve a set of every registered global parameter.
* @return Set of all registered global parameters. * @return Set of all registered global parameters.
*/ */
public Set<String> globalParameters() { public Set<String> globalParameters() {
return globalParameters.keySet(); return globalParameters.keySet();
} }
/** /**
* Retrieve the support URL that will be added to all detailed reports. * Retrieve the support URL that will be added to all detailed reports.
* @return Support URL. * @return Support URL.
*/ */
public String getSupportURL() { public String getSupportURL() {
return supportURL; return supportURL;
} }
/** /**
* Set the support URL that will be added to all detailed reports. * Set the support URL that will be added to all detailed reports.
* @param supportURL - the new support URL. * @param supportURL - the new support URL.
*/ */
public void setSupportURL(String supportURL) { public void setSupportURL(String supportURL) {
this.supportURL = supportURL; this.supportURL = supportURL;
} }
/** /**
* Retrieve the prefix to apply to every line in the error reports. * Retrieve the prefix to apply to every line in the error reports.
* @return Error report prefix. * @return Error report prefix.
*/ */
public String getPrefix() { public String getPrefix() {
return prefix; return prefix;
} }
/** /**
* Set the prefix to apply to every line in the error reports. * Set the prefix to apply to every line in the error reports.
* @param prefix - new prefix. * @param prefix - new prefix.
*/ */
public void setPrefix(String prefix) { public void setPrefix(String prefix) {
this.prefix = prefix; this.prefix = prefix;
} }
/** /**
* Retrieve the current logger that is used to print all reports. * Retrieve the current logger that is used to print all reports.
* @return The current logger. * @return The current logger.
*/ */
public Logger getLogger() { public Logger getLogger() {
return logger; return logger;
} }
/** /**
* Set the current logger that is used to print all reports. * Set the current logger that is used to print all reports.
* @param logger - new logger. * @param logger - new logger.
*/ */
public void setLogger(Logger logger) { public void setLogger(Logger logger) {
this.logger = logger; this.logger = logger;
} }
} }

Datei anzeigen

@ -46,6 +46,39 @@ public class ReportType {
return errorFormat; return errorFormat;
} }
/**
* Retrieve the class of the given sender.
* <p>
* If the sender is already a Class, we return it.
* @param sender - the sender to look up.
* @return The class of the sender.
*/
public static Class<?> getSenderClass(Object sender) {
if (sender == null)
throw new IllegalArgumentException("sender cannot be NUll.");
else if (sender instanceof Class<?>)
return (Class<?>) sender;
else
return sender.getClass();
}
/**
* Retrieve the full canonical name of a given report type.
* <p>
* Note that the sender may be a class (for static callers), in which
* case it will be used directly instead of its getClass() method.
* <p>
* It is thus not advisable for class classes to report reports.
* @param sender - the sender, or its class.
* @param type - the report type.
* @return The full canonical name.
*/
public static String getReportName(Object sender, ReportType type) {
if (sender == null)
throw new IllegalArgumentException("sender cannot be NUll.");
return getReportName(getSenderClass(sender), type);
}
/** /**
* Retrieve the full canonical name of a given report type. * Retrieve the full canonical name of a given report type.
* <p> * <p>
@ -54,7 +87,7 @@ public class ReportType {
* @param type - the report instance. * @param type - the report instance.
* @return The full canonical name. * @return The full canonical name.
*/ */
public static String getReportName(Class<?> sender, ReportType type) { private static String getReportName(Class<?> sender, ReportType type) {
if (sender == null) if (sender == null)
throw new IllegalArgumentException("sender cannot be NUll."); throw new IllegalArgumentException("sender cannot be NUll.");

Datei anzeigen

@ -362,6 +362,10 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
return asyncManager; return asyncManager;
} }
/**
* Update the asynchronous manager. This must be set.
* @param asyncManager - the asynchronous manager.
*/
public void setAsynchronousManager(AsynchronousManager asyncManager) { public void setAsynchronousManager(AsynchronousManager asyncManager) {
this.asyncManager = asyncManager; this.asyncManager = asyncManager;
} }

Datei anzeigen

@ -268,6 +268,10 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// We need to delay this until we know if Netty is enabled // We need to delay this until we know if Netty is enabled
final DelayedPacketManager delayed = new DelayedPacketManager(reporter); final DelayedPacketManager delayed = new DelayedPacketManager(reporter);
// They must reference each other
delayed.setAsynchronousManager(asyncManager);
asyncManager.setManager(delayed);
Futures.addCallback(BukkitFutures.nextEvent(library, WorldInitEvent.class), new FutureCallback<WorldInitEvent>() { Futures.addCallback(BukkitFutures.nextEvent(library, WorldInitEvent.class), new FutureCallback<WorldInitEvent>() {
@Override @Override
public void onSuccess(WorldInitEvent event) { public void onSuccess(WorldInitEvent event) {
@ -297,7 +301,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
@Override @Override
public void onFailure(Throwable error) { public void onFailure(Throwable error) {
reporter.reportWarning(this, Report.newBuilder(REPORT_TEMPORARY_EVENT_ERROR).error(error)); reporter.reportWarning(PacketFilterManager.class, Report.newBuilder(REPORT_TEMPORARY_EVENT_ERROR).error(error));
} }
}); });