Added the same NULL check to the generic Bukkit unwrapper.
Dieser Commit ist enthalten in:
Ursprung
57add8e26f
Commit
768d169f27
@ -1,113 +1,115 @@
|
|||||||
/*
|
/*
|
||||||
* 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.injector;
|
package com.comphenix.protocol.injector;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.comphenix.protocol.injector.PacketConstructor.Unwrapper;
|
import com.comphenix.protocol.injector.PacketConstructor.Unwrapper;
|
||||||
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an object capable of converting wrapped Bukkit objects into NMS objects.
|
* Represents an object capable of converting wrapped Bukkit objects into NMS objects.
|
||||||
* <p>
|
* <p>
|
||||||
* Typical conversions include:
|
* Typical conversions include:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>org.bukkit.entity.Player -> net.minecraft.server.EntityPlayer</li>
|
* <li>org.bukkit.entity.Player -> net.minecraft.server.EntityPlayer</li>
|
||||||
* <li>org.bukkit.World -> net.minecraft.server.WorldServer</li>
|
* <li>org.bukkit.World -> net.minecraft.server.WorldServer</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class BukkitUnwrapper implements Unwrapper {
|
public class BukkitUnwrapper implements Unwrapper {
|
||||||
|
|
||||||
private static Map<Class<?>, Method> cache = new ConcurrentHashMap<Class<?>, Method>();
|
private static Map<Class<?>, Method> cache = new ConcurrentHashMap<Class<?>, Method>();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Object unwrapItem(Object wrappedObject) {
|
public Object unwrapItem(Object wrappedObject) {
|
||||||
|
|
||||||
// Special case
|
// Special cases
|
||||||
if (wrappedObject instanceof Collection) {
|
if (wrappedObject == null) {
|
||||||
return handleCollection((Collection<Object>) wrappedObject);
|
return null;
|
||||||
}
|
} else if (wrappedObject instanceof Collection) {
|
||||||
|
return handleCollection((Collection<Object>) wrappedObject);
|
||||||
Class<?> currentClass = wrappedObject.getClass();
|
}
|
||||||
Method cachedMethod = initializeCache(currentClass);
|
|
||||||
|
Class<?> currentClass = wrappedObject.getClass();
|
||||||
try {
|
Method cachedMethod = initializeCache(currentClass);
|
||||||
// Retrieve the handle
|
|
||||||
if (cachedMethod != null)
|
try {
|
||||||
return cachedMethod.invoke(wrappedObject);
|
// Retrieve the handle
|
||||||
else
|
if (cachedMethod != null)
|
||||||
return null;
|
return cachedMethod.invoke(wrappedObject);
|
||||||
|
else
|
||||||
} catch (IllegalArgumentException e) {
|
return null;
|
||||||
// Impossible
|
|
||||||
return null;
|
} catch (IllegalArgumentException e) {
|
||||||
} catch (IllegalAccessException e) {
|
// Impossible
|
||||||
return null;
|
return null;
|
||||||
} catch (InvocationTargetException e) {
|
} catch (IllegalAccessException e) {
|
||||||
// This is REALLY bad
|
return null;
|
||||||
throw new RuntimeException("Minecraft error.", e);
|
} catch (InvocationTargetException e) {
|
||||||
}
|
// This is REALLY bad
|
||||||
}
|
throw new RuntimeException("Minecraft error.", e);
|
||||||
|
}
|
||||||
private Object handleCollection(Collection<Object> wrappedObject) {
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private Object handleCollection(Collection<Object> wrappedObject) {
|
||||||
Collection<Object> copy = DefaultInstances.DEFAULT.getDefault(wrappedObject.getClass());
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
if (copy != null) {
|
Collection<Object> copy = DefaultInstances.DEFAULT.getDefault(wrappedObject.getClass());
|
||||||
// Unwrap every element
|
|
||||||
for (Object element : wrappedObject) {
|
if (copy != null) {
|
||||||
copy.add(unwrapItem(element));
|
// Unwrap every element
|
||||||
}
|
for (Object element : wrappedObject) {
|
||||||
return copy;
|
copy.add(unwrapItem(element));
|
||||||
|
}
|
||||||
} else {
|
return copy;
|
||||||
// Impossible
|
|
||||||
return null;
|
} else {
|
||||||
}
|
// Impossible
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
private Method initializeCache(Class<?> type) {
|
}
|
||||||
|
|
||||||
// See if we're already determined this
|
private Method initializeCache(Class<?> type) {
|
||||||
if (cache.containsKey(type)) {
|
|
||||||
// We will never remove from the cache, so this ought to be thread safe
|
// See if we're already determined this
|
||||||
return cache.get(type);
|
if (cache.containsKey(type)) {
|
||||||
}
|
// We will never remove from the cache, so this ought to be thread safe
|
||||||
|
return cache.get(type);
|
||||||
try {
|
}
|
||||||
Method find = type.getMethod("getHandle");
|
|
||||||
|
try {
|
||||||
// It's thread safe, as getMethod should return the same handle
|
Method find = type.getMethod("getHandle");
|
||||||
cache.put(type, find);
|
|
||||||
return find;
|
// It's thread safe, as getMethod should return the same handle
|
||||||
|
cache.put(type, find);
|
||||||
} catch (SecurityException e) {
|
return find;
|
||||||
return null;
|
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (SecurityException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
} catch (NoSuchMethodException e) {
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren