Warn if exceptions are caused by broken plugins

This commit is contained in:
Dan Mulloy 2015-02-14 21:57:45 -05:00
parent a3784b3cf1
commit 66be4900a3
3 changed files with 54 additions and 7 deletions

View File

@ -34,6 +34,7 @@ public final class PluginContext {
return caller;
}
}
return null;
}
@ -41,25 +42,25 @@ public final class PluginContext {
* Lookup the plugin that this method invocation belongs to, and return its file name.
* @param element - the method invocation.
* @return Plugin name, or NULL if not found.
*
*/
public static String getPluginName(StackTraceElement element) {
try {
if (Bukkit.getServer() == null)
if (Bukkit.getServer() == null) {
return null;
CodeSource codeSource = Class.forName(element.getClassName()).getProtectionDomain().getCodeSource();
}
CodeSource codeSource = Class.forName(element.getClassName()).getProtectionDomain().getCodeSource();
if (codeSource != null) {
String encoding = codeSource.getLocation().getPath();
File path = new File(URLDecoder.decode(encoding, "UTF-8"));
File plugins = getPluginFolder();
if (plugins != null && folderContains(plugins, path)) {
return path.getName();
return path.getName().replaceAll(".jar", "");
}
}
return null; // Cannot find it
return null; // Cannot find it
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Cannot lookup plugin name.", e);
} catch (ClassNotFoundException e) {
@ -86,6 +87,7 @@ public final class PluginContext {
return true;
file = file.getParentFile();
}
return false;
}
@ -104,6 +106,7 @@ public final class PluginContext {
pluginFolder = folder;
}
}
return folder;
}
}

View File

@ -24,12 +24,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.error.PluginContext;
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
import com.comphenix.protocol.reflect.instances.BannedGenerator;
import com.comphenix.protocol.reflect.instances.DefaultInstances;
import com.comphenix.protocol.reflect.instances.InstanceProvider;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.Util;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@ -179,14 +183,30 @@ public class StructureModifier<TField> {
this.useStructureCompiler = useStructureCompiler;
}
private static final List<String> BROKEN_PLUGINS = Util.asList("TagAPI");
/**
* Reads the value of a field given its index.
* @param fieldIndex - index of the field.
* @return Value of the field.
* @throws FieldAccessException The field doesn't exist, or it cannot be accessed under the current security contraints.
*/
@SuppressWarnings("unchecked")
public TField read(int fieldIndex) throws FieldAccessException {
try {
return readInternal(fieldIndex);
} catch (FieldAccessException ex) {
String plugin = PluginContext.getPluginCaller(ex);
if (BROKEN_PLUGINS.contains(plugin)) {
ProtocolLibrary.log(Level.WARNING, "Encountered an exception caused by broken plugin {0}.", plugin);
ProtocolLibrary.log(Level.WARNING, "It is advised that you remove it.");
}
throw ex;
}
}
@SuppressWarnings("unchecked")
private TField readInternal(int fieldIndex) throws FieldAccessException {
if (target == null)
throw new IllegalStateException("Cannot read from a null target!");
@ -288,6 +308,20 @@ public class StructureModifier<TField> {
* @throws FieldAccessException The field doesn't exist, or it cannot be accessed under the current security contraints.
*/
public StructureModifier<TField> write(int fieldIndex, TField value) throws FieldAccessException {
try {
return writeInternal(fieldIndex, value);
} catch (FieldAccessException ex) {
String plugin = PluginContext.getPluginCaller(ex);
if (BROKEN_PLUGINS.contains(plugin)) {
ProtocolLibrary.log(Level.WARNING, "Encountered an exception caused by broken plugin {0}.", plugin);
ProtocolLibrary.log(Level.WARNING, "It is advised that you remove it.");
}
throw ex;
}
}
private StructureModifier<TField> writeInternal(int fieldIndex, TField value) throws FieldAccessException {
if (target == null)
throw new IllegalStateException("Cannot read from a null target!");

View File

@ -1,6 +1,7 @@
package com.comphenix.protocol.utility;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@ -45,4 +46,13 @@ public class Util {
return (List<Player>) Bukkit.getOnlinePlayers();
}
public static <E> List<E> asList(E... elements) {
List<E> list = new ArrayList<E>();
for (E element : elements) {
list.add(element);
}
return list;
}
}