Add support for the new JSON chat message format. FIXES Ticket-109
In addition, the PacketConstructor can now handle non-wrapped objects, along with Class types instead of instances in withPacket().
Dieser Commit ist enthalten in:
Ursprung
0b56df20d5
Commit
6054d559e1
@ -1,96 +1,96 @@
|
|||||||
package com.comphenix.protocol.error;
|
package com.comphenix.protocol.error;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
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.reflect.PrettyPrinter;
|
import com.comphenix.protocol.reflect.PrettyPrinter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a basic error reporter that prints error reports to the standard error stream.
|
* Represents a basic error reporter that prints error reports to the standard error stream.
|
||||||
* <p>
|
* <p>
|
||||||
* Note that this implementation doesn't distinguish between {@link #reportWarning(Object, Report)}
|
* Note that this implementation doesn't distinguish between {@link #reportWarning(Object, Report)}
|
||||||
* and {@link #reportDetailed(Object, Report)} - they both have the exact same behavior.
|
* and {@link #reportDetailed(Object, Report)} - they both have the exact same behavior.
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class BasicErrorReporter implements ErrorReporter {
|
public class BasicErrorReporter implements ErrorReporter {
|
||||||
private final PrintStream output;
|
private final PrintStream output;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new basic error reporter that prints directly the standard error stream.
|
* Construct a new basic error reporter that prints directly the standard error stream.
|
||||||
*/
|
*/
|
||||||
public BasicErrorReporter() {
|
public BasicErrorReporter() {
|
||||||
this(System.err);
|
this(System.err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a error reporter that prints to the given output stream.
|
* Construct a error reporter that prints to the given output stream.
|
||||||
* @param output - the output stream.
|
* @param output - the output stream.
|
||||||
*/
|
*/
|
||||||
public BasicErrorReporter(PrintStream output) {
|
public BasicErrorReporter(PrintStream output) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportMinimal(Plugin sender, String methodName, Throwable error) {
|
public void reportMinimal(Plugin sender, String methodName, Throwable error) {
|
||||||
output.println("Unhandled exception occured in " + methodName + " for " + sender.getName());
|
output.println("Unhandled exception occured in " + methodName + " for " + sender.getName());
|
||||||
error.printStackTrace(output);
|
error.printStackTrace(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) {
|
public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) {
|
||||||
reportMinimal(sender, methodName, error);
|
reportMinimal(sender, methodName, error);
|
||||||
|
|
||||||
// Also print parameters
|
// Also print parameters
|
||||||
printParameters(parameters);
|
printParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportWarning(Object sender, Report report) {
|
public void reportWarning(Object sender, Report report) {
|
||||||
// Basic warning
|
// Basic warning
|
||||||
output.println("[" + sender.getClass().getSimpleName() + "] " + report.getReportMessage());
|
output.println("[" + sender.getClass().getSimpleName() + "] " + report.getReportMessage());
|
||||||
|
|
||||||
if (report.getException() != null) {
|
if (report.getException() != null) {
|
||||||
report.getException().printStackTrace(output);
|
report.getException().printStackTrace(output);
|
||||||
}
|
}
|
||||||
printParameters(report.getCallerParameters());
|
printParameters(report.getCallerParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
@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, Report report) {
|
public void reportDetailed(Object sender, Report report) {
|
||||||
// No difference from warning
|
// No difference from warning
|
||||||
reportWarning(sender, report);
|
reportWarning(sender, report);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportDetailed(Object sender, ReportBuilder reportBuilder) {
|
public void reportDetailed(Object sender, ReportBuilder reportBuilder) {
|
||||||
reportWarning(sender, reportBuilder);
|
reportWarning(sender, reportBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print the given parameters to the standard error stream.
|
* Print the given parameters to the standard error stream.
|
||||||
* @param parameters - the output parameters.
|
* @param parameters - the output parameters.
|
||||||
*/
|
*/
|
||||||
private void printParameters(Object[] parameters) {
|
private void printParameters(Object[] parameters) {
|
||||||
if (parameters != null && parameters.length > 0) {
|
if (parameters != null && parameters.length > 0) {
|
||||||
output.println("Parameters: ");
|
output.println("Parameters: ");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (Object parameter : parameters) {
|
for (Object parameter : parameters) {
|
||||||
if (parameter == null)
|
if (parameter == null)
|
||||||
output.println("[NULL]");
|
output.println("[NULL]");
|
||||||
else
|
else
|
||||||
output.println(PrettyPrinter.printObject(parameter));
|
output.println(PrettyPrinter.printObject(parameter));
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
// Damn it
|
// Damn it
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,74 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
* 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 org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import com.comphenix.protocol.error.Report.ReportBuilder;
|
import com.comphenix.protocol.error.Report.ReportBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an object that can forward an error {@link Report} to the display and permanent storage.
|
* Represents an object that can forward an error {@link Report} to the display and permanent storage.
|
||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public interface ErrorReporter {
|
public interface ErrorReporter {
|
||||||
/**
|
/**
|
||||||
* Prints a small minimal error report regarding an exception from another plugin.
|
* Prints a small minimal error report regarding an exception from another plugin.
|
||||||
* @param sender - the other plugin.
|
* @param sender - the other plugin.
|
||||||
* @param methodName - name of the caller method.
|
* @param methodName - name of the caller method.
|
||||||
* @param error - the exception itself.
|
* @param error - the exception itself.
|
||||||
*/
|
*/
|
||||||
public abstract void reportMinimal(Plugin sender, String methodName, Throwable error);
|
public abstract void reportMinimal(Plugin sender, String methodName, Throwable error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a small minimal error report regarding an exception from another plugin.
|
* Prints a small minimal error report regarding an exception from another plugin.
|
||||||
* @param sender - the other plugin.
|
* @param sender - the other plugin.
|
||||||
* @param methodName - name of the caller method.
|
* @param methodName - name of the caller method.
|
||||||
* @param error - the exception itself.
|
* @param error - the exception itself.
|
||||||
* @param parameters - any relevant parameters to print.
|
* @param parameters - any relevant parameters to print.
|
||||||
*/
|
*/
|
||||||
public abstract void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters);
|
public abstract void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a warning message from the current plugin.
|
* Prints a warning message from the current plugin.
|
||||||
* @param sender - the object containing the caller method.
|
* @param sender - the object containing the caller method.
|
||||||
* @param report - an error report to include.
|
* @param report - an error report to include.
|
||||||
*/
|
*/
|
||||||
public abstract void reportWarning(Object sender, Report report);
|
public abstract void reportWarning(Object sender, Report report);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a warning message from the current plugin.
|
* Prints a warning message from the current plugin.
|
||||||
* @param sender - the object containing the caller method.
|
* @param sender - the object containing the caller method.
|
||||||
* @param reportBuilder - an error report builder that will be used to get the report.
|
* @param reportBuilder - an error report builder that will be used to get the report.
|
||||||
*/
|
*/
|
||||||
public abstract void reportWarning(Object sender, ReportBuilder reportBuilder);
|
public abstract void reportWarning(Object sender, ReportBuilder reportBuilder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a detailed error report about an unhandled exception.
|
* Prints a detailed error report about an unhandled exception.
|
||||||
* @param sender - the object containing the caller method.
|
* @param sender - the object containing the caller method.
|
||||||
* @param report - an error report to include.
|
* @param report - an error report to include.
|
||||||
*/
|
*/
|
||||||
public abstract void reportDetailed(Object sender, Report report);
|
public abstract void reportDetailed(Object sender, Report report);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a detailed error report about an unhandled exception.
|
* Prints a detailed error report about an unhandled exception.
|
||||||
* @param sender - the object containing the caller method.
|
* @param sender - the object containing the caller method.
|
||||||
* @param reportBuilder - an error report builder that will be used to get the report.
|
* @param reportBuilder - an error report builder that will be used to get the report.
|
||||||
*/
|
*/
|
||||||
public abstract void reportDetailed(Object sender, ReportBuilder reportBuilder);
|
public abstract void reportDetailed(Object sender, ReportBuilder reportBuilder);
|
||||||
}
|
}
|
@ -1,162 +1,162 @@
|
|||||||
package com.comphenix.protocol.error;
|
package com.comphenix.protocol.error;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a error or warning report.
|
* Represents a error or warning report.
|
||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class Report {
|
public class Report {
|
||||||
private final ReportType type;
|
private final ReportType type;
|
||||||
private final Throwable exception;
|
private final Throwable exception;
|
||||||
private final Object[] messageParameters;
|
private final Object[] messageParameters;
|
||||||
private final Object[] callerParameters;
|
private final Object[] callerParameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be constructed through the factory method in Report.
|
* Must be constructed through the factory method in Report.
|
||||||
*/
|
*/
|
||||||
public static class ReportBuilder {
|
public static class ReportBuilder {
|
||||||
private ReportType type;
|
private ReportType type;
|
||||||
private Throwable exception;
|
private Throwable exception;
|
||||||
private Object[] messageParameters;
|
private Object[] messageParameters;
|
||||||
private Object[] callerParameters;
|
private Object[] callerParameters;
|
||||||
|
|
||||||
private ReportBuilder() {
|
private ReportBuilder() {
|
||||||
// Don't allow
|
// Don't allow
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current report type. Cannot be NULL.
|
* Set the current report type. Cannot be NULL.
|
||||||
* @param type - report type.
|
* @param type - report type.
|
||||||
* @return This builder, for chaining.
|
* @return This builder, for chaining.
|
||||||
*/
|
*/
|
||||||
public ReportBuilder type(ReportType type) {
|
public ReportBuilder type(ReportType type) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new IllegalArgumentException("Report type cannot be set to NULL.");
|
throw new IllegalArgumentException("Report type cannot be set to NULL.");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current exception that occured.
|
* Set the current exception that occured.
|
||||||
* @param exception - exception that occured.
|
* @param exception - exception that occured.
|
||||||
* @return This builder, for chaining.
|
* @return This builder, for chaining.
|
||||||
*/
|
*/
|
||||||
public ReportBuilder error(@Nullable Throwable exception) {
|
public ReportBuilder error(@Nullable Throwable exception) {
|
||||||
this.exception = exception;
|
this.exception = exception;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the message parameters that are used to construct a message text.
|
* Set the message parameters that are used to construct a message text.
|
||||||
* @param messageParameters - parameters for the report type.
|
* @param messageParameters - parameters for the report type.
|
||||||
* @return This builder, for chaining.
|
* @return This builder, for chaining.
|
||||||
*/
|
*/
|
||||||
public ReportBuilder messageParam(@Nullable Object... messageParameters) {
|
public ReportBuilder messageParam(@Nullable Object... messageParameters) {
|
||||||
this.messageParameters = messageParameters;
|
this.messageParameters = messageParameters;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the parameters in the caller method. This is optional.
|
* Set the parameters in the caller method. This is optional.
|
||||||
* @param callerParameters - parameters of the caller method.
|
* @param callerParameters - parameters of the caller method.
|
||||||
* @return This builder, for chaining.
|
* @return This builder, for chaining.
|
||||||
*/
|
*/
|
||||||
public ReportBuilder callerParam(@Nullable Object... callerParameters) {
|
public ReportBuilder callerParam(@Nullable Object... callerParameters) {
|
||||||
this.callerParameters = callerParameters;
|
this.callerParameters = callerParameters;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new report with the provided input.
|
* Construct a new report with the provided input.
|
||||||
* @return A new report.
|
* @return A new report.
|
||||||
*/
|
*/
|
||||||
public Report build() {
|
public Report build() {
|
||||||
return new Report(type, exception, messageParameters, callerParameters);
|
return new Report(type, exception, messageParameters, callerParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new report builder.
|
* Construct a new report builder.
|
||||||
* @param type - the initial report type.
|
* @param type - the initial report type.
|
||||||
* @return Report builder.
|
* @return Report builder.
|
||||||
*/
|
*/
|
||||||
public static ReportBuilder newBuilder(ReportType type) {
|
public static ReportBuilder newBuilder(ReportType type) {
|
||||||
return new ReportBuilder().type(type);
|
return new ReportBuilder().type(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new report with the given type and parameters.
|
* Construct a new report with the given type and parameters.
|
||||||
* @param exception - exception that occured in the caller method.
|
* @param exception - exception that occured in the caller method.
|
||||||
* @param type - the report type that will be used to construct the message.
|
* @param type - the report type that will be used to construct the message.
|
||||||
* @param messageParameters - parameters used to construct the report message.
|
* @param messageParameters - parameters used to construct the report message.
|
||||||
* @param callerParameters - parameters from the caller method.
|
* @param callerParameters - parameters from the caller method.
|
||||||
*/
|
*/
|
||||||
protected Report(ReportType type, @Nullable Throwable exception, @Nullable Object[] messageParameters, @Nullable Object[] callerParameters) {
|
protected Report(ReportType type, @Nullable Throwable exception, @Nullable Object[] messageParameters, @Nullable Object[] callerParameters) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
throw new IllegalArgumentException("type cannot be NULL.");
|
throw new IllegalArgumentException("type cannot be NULL.");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.exception = exception;
|
this.exception = exception;
|
||||||
this.messageParameters = messageParameters;
|
this.messageParameters = messageParameters;
|
||||||
this.callerParameters = callerParameters;
|
this.callerParameters = callerParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format the current report type with the provided message parameters.
|
* Format the current report type with the provided message parameters.
|
||||||
* @return The formated report message.
|
* @return The formated report message.
|
||||||
*/
|
*/
|
||||||
public String getReportMessage() {
|
public String getReportMessage() {
|
||||||
return type.getMessage(messageParameters);
|
return type.getMessage(messageParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the message parameters that will be used to construc the report message.
|
* Retrieve the message parameters that will be used to construc the report message.
|
||||||
* <p<
|
* <p<
|
||||||
* This should not be confused with the method parameters of the caller method.
|
* This should not be confused with the method parameters of the caller method.
|
||||||
* @return Message parameters.
|
* @return Message parameters.
|
||||||
*/
|
*/
|
||||||
public Object[] getMessageParameters() {
|
public Object[] getMessageParameters() {
|
||||||
return messageParameters;
|
return messageParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the parameters of the caller method. Optional - may be NULL.
|
* Retrieve the parameters of the caller method. Optional - may be NULL.
|
||||||
* @return Parameters or the caller method.
|
* @return Parameters or the caller method.
|
||||||
*/
|
*/
|
||||||
public Object[] getCallerParameters() {
|
public Object[] getCallerParameters() {
|
||||||
return callerParameters;
|
return callerParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the report type.
|
* Retrieve the report type.
|
||||||
* @return Report type.
|
* @return Report type.
|
||||||
*/
|
*/
|
||||||
public ReportType getType() {
|
public ReportType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the associated exception, or NULL if not found.
|
* Retrieve the associated exception, or NULL if not found.
|
||||||
* @return Associated exception, or NULL.
|
* @return Associated exception, or NULL.
|
||||||
*/
|
*/
|
||||||
public Throwable getException() {
|
public Throwable getException() {
|
||||||
return exception;
|
return exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if we have any message parameters.
|
* Determine if we have any message parameters.
|
||||||
* @return TRUE if there are any message parameters, FALSE otherwise.
|
* @return TRUE if there are any message parameters, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean hasMessageParameters() {
|
public boolean hasMessageParameters() {
|
||||||
return messageParameters != null && messageParameters.length > 0;
|
return messageParameters != null && messageParameters.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if we have any caller parameters.
|
* Determine if we have any caller parameters.
|
||||||
* @return TRUE if there are any caller parameters, FALSE otherwise.
|
* @return TRUE if there are any caller parameters, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean hasCallerParameters() {
|
public boolean hasCallerParameters() {
|
||||||
return callerParameters != null && callerParameters.length > 0;
|
return callerParameters != null && callerParameters.length > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.comphenix.protocol.error;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.error.Report.ReportBuilder;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an error reporter that rethrows every exception instead.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public class RethrowErrorReporter implements ErrorReporter {
|
||||||
|
@Override
|
||||||
|
public void reportMinimal(Plugin sender, String methodName, Throwable error) {
|
||||||
|
throw new RuntimeException("Minimal error by " + sender + " in " + methodName, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportMinimal(Plugin sender, String methodName, Throwable error, Object... parameters) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Minimal error by " + sender + " in " + methodName + " with " + Joiner.on(",").join(parameters), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportWarning(Object sender, ReportBuilder reportBuilder) {
|
||||||
|
reportWarning(sender, reportBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportWarning(Object sender, Report report) {
|
||||||
|
throw new RuntimeException("Warning by " + sender + ": " + report);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportDetailed(Object sender, ReportBuilder reportBuilder) {
|
||||||
|
reportDetailed(sender, reportBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportDetailed(Object sender, Report report) {
|
||||||
|
throw new RuntimeException("Detailed error " + sender + ": " + report, report.getException());
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.error.RethrowErrorReporter;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||||
@ -51,15 +52,19 @@ public class PacketConstructor {
|
|||||||
// Used to unwrap Bukkit objects
|
// Used to unwrap Bukkit objects
|
||||||
private List<Unwrapper> unwrappers;
|
private List<Unwrapper> unwrappers;
|
||||||
|
|
||||||
|
// Parameters that need to be unwrapped
|
||||||
|
private boolean[] unwrappable;
|
||||||
|
|
||||||
private PacketConstructor(Constructor<?> constructorMethod) {
|
private PacketConstructor(Constructor<?> constructorMethod) {
|
||||||
this.constructorMethod = constructorMethod;
|
this.constructorMethod = constructorMethod;
|
||||||
this.unwrappers = Lists.newArrayList((Unwrapper) new BukkitUnwrapper());
|
this.unwrappers = Lists.newArrayList((Unwrapper) new BukkitUnwrapper(new RethrowErrorReporter() ));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketConstructor(int packetID, Constructor<?> constructorMethod, List<Unwrapper> unwrappers) {
|
private PacketConstructor(int packetID, Constructor<?> constructorMethod, List<Unwrapper> unwrappers, boolean[] unwrappable) {
|
||||||
this.packetID = packetID;
|
this.packetID = packetID;
|
||||||
this.constructorMethod = constructorMethod;
|
this.constructorMethod = constructorMethod;
|
||||||
this.unwrappers = unwrappers;
|
this.unwrappers = unwrappers;
|
||||||
|
this.unwrappable = unwrappable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableList<Unwrapper> getUnwrappers() {
|
public ImmutableList<Unwrapper> getUnwrappers() {
|
||||||
@ -80,31 +85,41 @@ public class PacketConstructor {
|
|||||||
* @return A constructor with a different set of unwrappers.
|
* @return A constructor with a different set of unwrappers.
|
||||||
*/
|
*/
|
||||||
public PacketConstructor withUnwrappers(List<Unwrapper> unwrappers) {
|
public PacketConstructor withUnwrappers(List<Unwrapper> unwrappers) {
|
||||||
return new PacketConstructor(packetID, constructorMethod, unwrappers);
|
return new PacketConstructor(packetID, constructorMethod, unwrappers, unwrappable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a packet constructor that creates packets using the given types.
|
* Create a packet constructor that creates packets using the given types.
|
||||||
|
* <p>
|
||||||
|
* Note that if you pass a Class<?> as a value, it will use its type directly.
|
||||||
* @param id - packet ID.
|
* @param id - packet ID.
|
||||||
* @param values - types to create.
|
* @param values - the values that will match each parameter in the desired constructor.
|
||||||
* @return A packet constructor with these types.
|
* @return A packet constructor with these types.
|
||||||
* @throws IllegalArgumentException If no packet constructor could be created with these types.
|
* @throws IllegalArgumentException If no packet constructor could be created with these types.
|
||||||
*/
|
*/
|
||||||
public PacketConstructor withPacket(int id, Object[] values) {
|
public PacketConstructor withPacket(int id, Object[] values) {
|
||||||
|
|
||||||
Class<?>[] types = new Class<?>[values.length];
|
Class<?>[] types = new Class<?>[values.length];
|
||||||
|
Throwable lastException = null;
|
||||||
|
boolean[] unwrappable = new boolean[values.length];
|
||||||
|
|
||||||
for (int i = 0; i < types.length; i++) {
|
for (int i = 0; i < types.length; i++) {
|
||||||
// Default type
|
// Default type
|
||||||
if (values[i] != null) {
|
if (values[i] != null) {
|
||||||
types[i] = values[i].getClass();
|
types[i] = (values[i] instanceof Class) ? (Class<?>)values[i] : values[i].getClass();
|
||||||
|
|
||||||
for (Unwrapper unwrapper : unwrappers) {
|
for (Unwrapper unwrapper : unwrappers) {
|
||||||
Object result = unwrapper.unwrapItem(values[i]);
|
Object result = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = unwrapper.unwrapItem(values[i]);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
lastException = e;
|
||||||
|
}
|
||||||
|
|
||||||
// Update type we're searching for
|
// Update type we're searching for
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
types[i] = result.getClass();
|
types[i] = result.getClass();
|
||||||
|
unwrappable[i] = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,11 +141,11 @@ public class PacketConstructor {
|
|||||||
|
|
||||||
if (isCompatible(types, params)) {
|
if (isCompatible(types, params)) {
|
||||||
// Right, we've found our type
|
// Right, we've found our type
|
||||||
return new PacketConstructor(id, constructor, unwrappers);
|
return new PacketConstructor(id, constructor, unwrappers, unwrappable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("No suitable constructor could be found.");
|
throw new IllegalArgumentException("No suitable constructor could be found.", lastException);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,14 +158,16 @@ public class PacketConstructor {
|
|||||||
*/
|
*/
|
||||||
public PacketContainer createPacket(Object... values) throws FieldAccessException {
|
public PacketContainer createPacket(Object... values) throws FieldAccessException {
|
||||||
try {
|
try {
|
||||||
// Convert types
|
// Convert types that needs to be converted
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
for (Unwrapper unwrapper : unwrappers) {
|
if (unwrappable[i]) {
|
||||||
Object converted = unwrapper.unwrapItem(values[i]);
|
for (Unwrapper unwrapper : unwrappers) {
|
||||||
|
Object converted = unwrapper.unwrapItem(values[i]);
|
||||||
if (converted != null) {
|
|
||||||
values[i] = converted;
|
if (converted != null) {
|
||||||
break;
|
values[i] = converted;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,11 @@
|
|||||||
|
|
||||||
package com.comphenix.protocol.utility;
|
package com.comphenix.protocol.utility;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -26,8 +30,13 @@ import org.bukkit.entity.Player;
|
|||||||
import com.comphenix.protocol.Packets;
|
import com.comphenix.protocol.Packets;
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
import com.comphenix.protocol.injector.PacketConstructor;
|
import com.comphenix.protocol.injector.PacketConstructor;
|
||||||
|
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||||
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers;
|
||||||
|
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for sending chat messages.
|
* Utility methods for sending chat messages.
|
||||||
@ -35,11 +44,14 @@ import com.google.common.base.Strings;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class ChatExtensions {
|
public class ChatExtensions {
|
||||||
|
|
||||||
// Used to sent chat messages
|
// Used to sent chat messages
|
||||||
private PacketConstructor chatConstructor;
|
private PacketConstructor chatConstructor;
|
||||||
private ProtocolManager manager;
|
private ProtocolManager manager;
|
||||||
|
|
||||||
|
// Whether or not we have to use the post-1.6.1 chat format
|
||||||
|
private static Constructor<?> jsonConstructor = getJsonFormatConstructor();
|
||||||
|
private static Method messageFactory;
|
||||||
|
|
||||||
public ChatExtensions(ProtocolManager manager) {
|
public ChatExtensions(ProtocolManager manager) {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
}
|
}
|
||||||
@ -68,10 +80,59 @@ public class ChatExtensions {
|
|||||||
* Send a message without invoking the packet listeners.
|
* Send a message without invoking the packet listeners.
|
||||||
* @param player - the player to send it to.
|
* @param player - the player to send it to.
|
||||||
* @param message - the message to send.
|
* @param message - the message to send.
|
||||||
* @return TRUE if the message was sent successfully, FALSE otherwise.
|
|
||||||
* @throws InvocationTargetException If we were unable to send the message.
|
* @throws InvocationTargetException If we were unable to send the message.
|
||||||
*/
|
*/
|
||||||
private void sendMessageSilently(Player player, String message) throws InvocationTargetException {
|
private void sendMessageSilently(Player player, String message) throws InvocationTargetException {
|
||||||
|
if (jsonConstructor != null) {
|
||||||
|
sendMessageAsJson(player, message);
|
||||||
|
} else {
|
||||||
|
sendMessageAsString(player, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message using the new JSON format in 1.6.1.
|
||||||
|
* @param player - the player to send it to.
|
||||||
|
* @param message - the message to send.
|
||||||
|
* @throws InvocationTargetException InvocationTargetException If we were unable to send the message.
|
||||||
|
*/
|
||||||
|
private void sendMessageAsJson(Player player, String message) throws InvocationTargetException {
|
||||||
|
Object messageObject = null;
|
||||||
|
|
||||||
|
if (chatConstructor == null) {
|
||||||
|
Class<?> messageClass = jsonConstructor.getParameterTypes()[0];
|
||||||
|
chatConstructor = manager.createPacketConstructor(Packets.Server.CHAT, messageClass);
|
||||||
|
|
||||||
|
// Try one of the string constructors
|
||||||
|
messageFactory = FuzzyReflection.fromClass(messageClass).getMethod(
|
||||||
|
FuzzyMethodContract.newBuilder().
|
||||||
|
requireModifier(Modifier.STATIC).
|
||||||
|
parameterCount(1).
|
||||||
|
parameterExactType(String.class).
|
||||||
|
returnTypeMatches(FuzzyMatchers.matchParent()).
|
||||||
|
build());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
messageObject = messageFactory.invoke(null, message);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvocationTargetException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
manager.sendServerPacket(player, chatConstructor.createPacket(messageObject), false);
|
||||||
|
} catch (FieldAccessException e) {
|
||||||
|
throw new InvocationTargetException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message as a pure string.
|
||||||
|
* @param player - the player.
|
||||||
|
* @param message - the message to send.
|
||||||
|
* @throws InvocationTargetException If anything went wrong.
|
||||||
|
*/
|
||||||
|
private void sendMessageAsString(Player player, String message) throws InvocationTargetException {
|
||||||
if (chatConstructor == null)
|
if (chatConstructor == null)
|
||||||
chatConstructor = manager.createPacketConstructor(Packets.Server.CHAT, message);
|
chatConstructor = manager.createPacketConstructor(Packets.Server.CHAT, message);
|
||||||
|
|
||||||
@ -143,4 +204,21 @@ public class ChatExtensions {
|
|||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a constructor for post-1.6.1 chat packets.
|
||||||
|
* @return A constructor for JSON-based packets.
|
||||||
|
*/
|
||||||
|
static Constructor<?> getJsonFormatConstructor() {
|
||||||
|
Class<?> chatPacket = PacketRegistry.getPacketClassFromID(3, true);
|
||||||
|
List<Constructor<?>> list = FuzzyReflection.fromClass(chatPacket).getConstructorList(
|
||||||
|
FuzzyMethodContract.newBuilder().
|
||||||
|
parameterCount(1).
|
||||||
|
parameterMatches(MinecraftReflection.getMinecraftObjectMatcher()).
|
||||||
|
build()
|
||||||
|
);
|
||||||
|
|
||||||
|
// First element or NULL
|
||||||
|
return Iterables.getFirst(list, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren