mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-23 19:16:14 +01:00
Added support for at least Beta 1.8.
This involved a bunch of reflection magic, along with the removal of every Apache Commons reference, in addition to every internal Guava class.
This commit is contained in:
parent
f372b247f9
commit
035277bdeb
@ -4,6 +4,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
@ -19,19 +20,27 @@ public interface ProtocolManager {
|
||||
* Retrieves a list of every registered packet listener.
|
||||
* @return Every registered packet listener.
|
||||
*/
|
||||
public abstract ImmutableSet<PacketListener> getPacketListeners();
|
||||
public ImmutableSet<PacketListener> getPacketListeners();
|
||||
|
||||
/**
|
||||
* Adds a packet listener.
|
||||
* @param listener - new packet listener.
|
||||
*/
|
||||
public abstract void addPacketListener(PacketListener listener);
|
||||
public void addPacketListener(PacketListener listener);
|
||||
|
||||
/**
|
||||
* Removes a given packet listener.
|
||||
* @param listener - the packet listener to remove.
|
||||
*/
|
||||
public abstract void removePacketListener(PacketListener listener);
|
||||
public void removePacketListener(PacketListener listener);
|
||||
|
||||
/**
|
||||
* Removes every listener associated with the given plugin.
|
||||
* <p>
|
||||
* Note that this only works for listeners that derive from PacketAdapter.
|
||||
* @param plugin - the plugin to unload.
|
||||
*/
|
||||
public void removePacketAdapters(Plugin plugin);
|
||||
|
||||
/**
|
||||
* Send a packet to the given player.
|
||||
|
@ -2,9 +2,9 @@ package com.comphenix.protocol.events;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
@ -14,7 +14,7 @@ import com.google.common.collect.Sets;
|
||||
*/
|
||||
public abstract class PacketAdapter implements PacketListener {
|
||||
|
||||
protected JavaPlugin plugin;
|
||||
protected Plugin plugin;
|
||||
protected Set<Integer> packetsID;
|
||||
protected ConnectionSide connectionSide;
|
||||
|
||||
@ -24,7 +24,7 @@ public abstract class PacketAdapter implements PacketListener {
|
||||
* @param connectionSide - the packet type the listener is looking for.
|
||||
* @param packets - the packet IDs the listener is looking for.
|
||||
*/
|
||||
public PacketAdapter(JavaPlugin plugin, ConnectionSide connectionSide, Integer... packets) {
|
||||
public PacketAdapter(Plugin plugin, ConnectionSide connectionSide, Integer... packets) {
|
||||
this.plugin = plugin;
|
||||
this.connectionSide = connectionSide;
|
||||
this.packetsID = Sets.newHashSet(packets);
|
||||
@ -50,11 +50,28 @@ public abstract class PacketAdapter implements PacketListener {
|
||||
return packetsID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the plugin associated with this listener.
|
||||
* @return The associated plugin.
|
||||
*/
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = "";
|
||||
|
||||
// Try to get the plugin name
|
||||
try {
|
||||
name = plugin.getName();
|
||||
} catch (NoSuchMethodError e) {
|
||||
name = plugin.toString();
|
||||
}
|
||||
|
||||
// This is used by the error reporter
|
||||
return String.format("PacketAdapter[plugin=%s, side=%s, packets=%s]",
|
||||
plugin.getName(), getConnectionSide().name(),
|
||||
StringUtils.join(packetsID, ", "));
|
||||
name, getConnectionSide().name(),
|
||||
Joiner.on(", ").join(packetsID));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.comphenix.protocol.events;
|
||||
|
||||
import org.apache.commons.lang.NullArgumentException;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -48,7 +47,7 @@ public class PacketContainer {
|
||||
*/
|
||||
public PacketContainer(int id, Packet handle, StructureModifier<Object> structure) {
|
||||
if (handle == null)
|
||||
throw new NullArgumentException("handle");
|
||||
throw new IllegalArgumentException("handle cannot be null.");
|
||||
|
||||
this.id = id;
|
||||
this.handle = handle;
|
||||
|
@ -4,12 +4,11 @@ import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Static registries in Minecraft.
|
||||
@ -78,7 +77,7 @@ class MinecraftRegistry {
|
||||
|
||||
// Will most likely not be used
|
||||
for (Map.Entry<Class, Integer> entry : getPacketToID().entrySet()) {
|
||||
if (ObjectUtils.equals(entry.getValue(), packetID)) {
|
||||
if (Objects.equal(entry.getValue(), packetID)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.comphenix.protocol.injector;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -11,8 +12,10 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import org.apache.commons.lang.NullArgumentException;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -24,9 +27,11 @@ import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ConnectionSide;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
@ -47,6 +52,9 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
// Whether or not this class has been closed
|
||||
private boolean hasClosed;
|
||||
|
||||
// The default class loader
|
||||
private ClassLoader classLoader;
|
||||
|
||||
// Error logger
|
||||
private Logger logger;
|
||||
|
||||
@ -55,12 +63,13 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
*/
|
||||
public PacketFilterManager(ClassLoader classLoader, Logger logger) {
|
||||
if (logger == null)
|
||||
throw new NullArgumentException("logger");
|
||||
throw new IllegalArgumentException("logger cannot be NULL.");
|
||||
if (classLoader == null)
|
||||
throw new NullArgumentException("classLoader");
|
||||
throw new IllegalArgumentException("classLoader cannot be NULL.");
|
||||
|
||||
try {
|
||||
// Initialize values
|
||||
this.classLoader = classLoader;
|
||||
this.logger = logger;
|
||||
this.packetInjector = new PacketInjector(classLoader, this, connectionLookup);
|
||||
} catch (IllegalAccessException e) {
|
||||
@ -80,7 +89,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
@Override
|
||||
public void addPacketListener(PacketListener listener) {
|
||||
if (listener == null)
|
||||
throw new NullArgumentException("listener");
|
||||
throw new IllegalArgumentException("listener cannot be NULL.");
|
||||
|
||||
packetListeners.add(listener);
|
||||
enablePacketFilters(listener.getConnectionSide(),
|
||||
@ -90,13 +99,29 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
@Override
|
||||
public void removePacketListener(PacketListener listener) {
|
||||
if (listener == null)
|
||||
throw new NullArgumentException("listener");
|
||||
throw new IllegalArgumentException("listener cannot be NULL");
|
||||
|
||||
packetListeners.remove(listener);
|
||||
disablePacketFilters(listener.getConnectionSide(),
|
||||
listener.getPacketsID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePacketAdapters(Plugin plugin) {
|
||||
|
||||
// Iterate through every packet listener
|
||||
for (Object listener : packetListeners.toArray()) {
|
||||
if (listener instanceof PacketAdapter) {
|
||||
PacketAdapter adapter = (PacketAdapter) listener;
|
||||
|
||||
// Remove the listener
|
||||
if (adapter.getPlugin().equals(plugin)) {
|
||||
packetListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given packet event for every registered listener.
|
||||
* @param event - the packet event to invoke.
|
||||
@ -150,7 +175,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
*/
|
||||
private void enablePacketFilters(ConnectionSide side, Set<Integer> packets) {
|
||||
if (side == null)
|
||||
throw new NullArgumentException("side");
|
||||
throw new IllegalArgumentException("side cannot be NULL.");
|
||||
|
||||
for (int packetID : packets) {
|
||||
if (side.isForServer())
|
||||
@ -167,7 +192,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
*/
|
||||
private void disablePacketFilters(ConnectionSide side, Set<Integer> packets) {
|
||||
if (side == null)
|
||||
throw new NullArgumentException("side");
|
||||
throw new IllegalArgumentException("side cannot be NULL.");
|
||||
|
||||
for (int packetID : packets) {
|
||||
if (side.isForServer())
|
||||
@ -185,9 +210,9 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
@Override
|
||||
public void sendServerPacket(Player reciever, PacketContainer packet, boolean filters) throws InvocationTargetException {
|
||||
if (reciever == null)
|
||||
throw new NullArgumentException("reciever");
|
||||
throw new IllegalArgumentException("reciever cannot be NULL.");
|
||||
if (packet == null)
|
||||
throw new NullArgumentException("packet");
|
||||
throw new IllegalArgumentException("packet cannot be NULL.");
|
||||
|
||||
getInjector(reciever).sendServerPacket(packet.getHandle(), filters);
|
||||
}
|
||||
@ -201,9 +226,9 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
public void recieveClientPacket(Player sender, PacketContainer packet, boolean filters) throws IllegalAccessException, InvocationTargetException {
|
||||
|
||||
if (sender == null)
|
||||
throw new NullArgumentException("sender");
|
||||
throw new IllegalArgumentException("sender cannot be NULL.");
|
||||
if (packet == null)
|
||||
throw new NullArgumentException("packet");
|
||||
throw new IllegalArgumentException("packet cannot be NULL.");
|
||||
|
||||
PlayerInjector injector = getInjector(sender);
|
||||
Packet mcPacket = packet.getHandle();
|
||||
@ -277,18 +302,90 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
* @param plugin - the parent plugin.
|
||||
*/
|
||||
public void registerEvents(PluginManager manager, Plugin plugin) {
|
||||
manager.registerEvents(new Listener() {
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
injectPlayer(event.getPlayer());
|
||||
}
|
||||
try {
|
||||
manager.registerEvents(new Listener() {
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
uninjectPlayer(event.getPlayer());
|
||||
}
|
||||
}, plugin);
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
injectPlayer(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
uninjectPlayer(event.getPlayer());
|
||||
}
|
||||
}, plugin);
|
||||
|
||||
} catch (NoSuchMethodError e) {
|
||||
// Oh wow! We're running on 1.0.0 or older.
|
||||
registerOld(manager, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
// Yes, this is crazy.
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void registerOld(PluginManager manager, Plugin plugin) {
|
||||
|
||||
try {
|
||||
ClassLoader loader = manager.getClass().getClassLoader();
|
||||
|
||||
// The different enums we are going to need
|
||||
Class eventTypes = loader.loadClass("org.bukkit.event.Event$Type");
|
||||
Class eventPriority = loader.loadClass("org.bukkit.event.Event$Priority");
|
||||
|
||||
// Get the priority
|
||||
Object priorityNormal = Enum.valueOf(eventPriority, "Normal");
|
||||
|
||||
// Get event types
|
||||
Object playerJoinType = Enum.valueOf(eventTypes, "PLAYER_JOIN");
|
||||
Object playerQuitType = Enum.valueOf(eventTypes, "PLAYER_QUIT");
|
||||
|
||||
// The player listener! Good times.
|
||||
Class<?> playerListener = loader.loadClass("org.bukkit.event.player.PlayerListener");
|
||||
|
||||
// Find the register event method
|
||||
Method registerEvent = FuzzyReflection.fromObject(manager).getMethodByParameters("registerEvent",
|
||||
eventTypes, Listener.class, eventPriority, Plugin.class);
|
||||
|
||||
Enhancer ex = new Enhancer();
|
||||
ex.setSuperclass(playerListener);
|
||||
ex.setClassLoader(classLoader);
|
||||
ex.setCallback(new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
|
||||
// Must have a parameter
|
||||
if (args.length == 1) {
|
||||
Object event = args[0];
|
||||
|
||||
// Check for the correct event
|
||||
if (event instanceof PlayerJoinEvent)
|
||||
injectPlayer(((PlayerJoinEvent) event).getPlayer());
|
||||
else if (event instanceof PlayerQuitEvent)
|
||||
injectPlayer(((PlayerQuitEvent) event).getPlayer());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Create our listener
|
||||
Object proxy = ex.create();
|
||||
|
||||
registerEvent.invoke(manager, playerJoinType, proxy, priorityNormal, plugin);
|
||||
registerEvent.invoke(manager, playerQuitType, proxy, priorityNormal, plugin);
|
||||
|
||||
// A lot can go wrong
|
||||
} catch (ClassNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void uninjectPlayer(Player player) {
|
||||
|
@ -15,6 +15,7 @@ import net.sf.cglib.proxy.Enhancer;
|
||||
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
|
||||
/**
|
||||
@ -49,10 +50,10 @@ class PacketInjector {
|
||||
private void initialize() throws IllegalAccessException {
|
||||
if (intHashMap == null) {
|
||||
// We're looking for the first static field with a Minecraft-object. This should be a IntHashMap.
|
||||
Field intHashMapField = FuzzyReflection.fromClass(Packet.class).getFieldByType(FuzzyReflection.MINECRAFT_OBJECT);
|
||||
Field intHashMapField = FuzzyReflection.fromClass(Packet.class, true).getFieldByType(FuzzyReflection.MINECRAFT_OBJECT);
|
||||
|
||||
try {
|
||||
intHashMap = intHashMapField.get(null);
|
||||
intHashMap = FieldUtils.readField(intHashMapField, (Object) null, true);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new RuntimeException("Minecraft is incompatible.", e);
|
||||
}
|
||||
|
@ -2,10 +2,9 @@ package com.comphenix.protocol.injector;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
@ -55,7 +54,7 @@ class ReadPacketModifier implements MethodInterceptor {
|
||||
|
||||
// Is this a readPacketData method?
|
||||
if (returnValue == null &&
|
||||
ArrayUtils.isEquals(method.getParameterTypes(), parameters)) {
|
||||
Arrays.equals(method.getParameterTypes(), parameters)) {
|
||||
|
||||
// We need this in order to get the correct player
|
||||
DataInputStream input = (DataInputStream) args[0];
|
||||
|
@ -6,11 +6,9 @@ import java.util.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
|
||||
import com.google.common.base.Defaults;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.gson.internal.Primitives;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Used to construct default instances of any type.
|
||||
@ -91,7 +89,7 @@ public class DefaultInstances {
|
||||
// Note that we don't allow recursive types - that is, types that
|
||||
// require itself in the constructor.
|
||||
if (types.length < lastCount) {
|
||||
if (!ArrayUtils.contains(types, type)) {
|
||||
if (!contains(types, type)) {
|
||||
minimum = candidate;
|
||||
lastCount = types.length;
|
||||
|
||||
@ -124,6 +122,15 @@ public class DefaultInstances {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static <T> boolean contains(T[] elements, T elementToFind) {
|
||||
// Search for the given element in the array
|
||||
for (T element : elements) {
|
||||
if (Objects.equal(elementToFind, element))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides constructors for primtive types, wrappers, arrays and strings.
|
||||
* @author Kristian
|
||||
@ -133,10 +140,10 @@ public class DefaultInstances {
|
||||
@Override
|
||||
public Object apply(@Nullable Class<?> type) {
|
||||
|
||||
if (Primitives.isPrimitive(type)) {
|
||||
if (PrimitiveUtils.isPrimitive(type)) {
|
||||
return Defaults.defaultValue(type);
|
||||
} else if (Primitives.isWrapperType(type)) {
|
||||
return Defaults.defaultValue(Primitives.unwrap(type));
|
||||
} else if (PrimitiveUtils.isWrapperType(type)) {
|
||||
return Defaults.defaultValue(PrimitiveUtils.unwrap(type));
|
||||
} else if (type.isArray()) {
|
||||
Class<?> arrayType = type.getComponentType();
|
||||
return Array.newInstance(arrayType, 0);
|
||||
|
@ -21,9 +21,9 @@ import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.lang.ClassUtils;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utilities for working with fields by reflection. Adapted and refactored from
|
||||
@ -119,11 +119,11 @@ public class FieldUtils {
|
||||
}
|
||||
}
|
||||
// check the public interface case. This must be manually searched for
|
||||
// incase there is a public supersuperclass field hidden by a
|
||||
// in case there is a public supersuperclass field hidden by a
|
||||
// private/package
|
||||
// superclass field.
|
||||
Field match = null;
|
||||
for (Iterator intf = ClassUtils.getAllInterfaces(cls).iterator(); intf.hasNext();) {
|
||||
for (Iterator intf = getAllInterfaces(cls).iterator(); intf.hasNext();) {
|
||||
try {
|
||||
Field test = ((Class) intf.next()).getField(fieldName);
|
||||
if (match != null) {
|
||||
@ -139,6 +139,44 @@ public class FieldUtils {
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets a <code>List</code> of all interfaces implemented by the given
|
||||
* class and its superclasses.</p>
|
||||
*
|
||||
* <p>The order is determined by looking through each interface in turn as
|
||||
* declared in the source file and following its hierarchy up. Then each
|
||||
* superclass is considered in the same way. Later duplicates are ignored,
|
||||
* so the order is maintained.</p>
|
||||
*
|
||||
* @param cls the class to look up, may be <code>null</code>
|
||||
* @return the <code>List</code> of interfaces in order,
|
||||
* <code>null</code> if null input
|
||||
*/
|
||||
private static List getAllInterfaces(Class cls) {
|
||||
if (cls == null) {
|
||||
return null;
|
||||
}
|
||||
List<Class> list = new ArrayList<Class>();
|
||||
|
||||
while (cls != null) {
|
||||
Class[] interfaces = cls.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
if (list.contains(interfaces[i]) == false) {
|
||||
list.add(interfaces[i]);
|
||||
}
|
||||
List superInterfaces = getAllInterfaces(interfaces[i]);
|
||||
for (Iterator it = superInterfaces.iterator(); it.hasNext();) {
|
||||
Class intface = (Class) it.next();
|
||||
if (list.contains(intface) == false) {
|
||||
list.add(intface);
|
||||
}
|
||||
}
|
||||
}
|
||||
cls = cls.getSuperclass();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an accessible static Field.
|
||||
*
|
||||
|
@ -2,12 +2,11 @@ package com.comphenix.protocol.reflect;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
|
||||
/**
|
||||
* Retrieves fields and methods by signature, not just name.
|
||||
*
|
||||
@ -106,7 +105,7 @@ public class FuzzyReflection {
|
||||
|
||||
// Find the correct method to call
|
||||
for (Method method : getMethods()) {
|
||||
if (ArrayUtils.isEquals(method.getParameterTypes(), args)) {
|
||||
if (Arrays.equals(method.getParameterTypes(), args)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,124 @@
|
||||
package com.comphenix.protocol.reflect;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Contains static utility methods pertaining to primitive types and their
|
||||
* corresponding wrapper types.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
*/
|
||||
public final class PrimitiveUtils {
|
||||
private PrimitiveUtils() {
|
||||
}
|
||||
|
||||
/** A map from primitive types to their corresponding wrapper types. */
|
||||
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
|
||||
|
||||
/** A map from wrapper types to their corresponding primitive types. */
|
||||
private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
|
||||
|
||||
// Sad that we can't use a BiMap. :(
|
||||
static {
|
||||
Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
|
||||
Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
|
||||
|
||||
add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
|
||||
add(primToWrap, wrapToPrim, byte.class, Byte.class);
|
||||
add(primToWrap, wrapToPrim, char.class, Character.class);
|
||||
add(primToWrap, wrapToPrim, double.class, Double.class);
|
||||
add(primToWrap, wrapToPrim, float.class, Float.class);
|
||||
add(primToWrap, wrapToPrim, int.class, Integer.class);
|
||||
add(primToWrap, wrapToPrim, long.class, Long.class);
|
||||
add(primToWrap, wrapToPrim, short.class, Short.class);
|
||||
add(primToWrap, wrapToPrim, void.class, Void.class);
|
||||
|
||||
PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);
|
||||
WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);
|
||||
}
|
||||
|
||||
private static void add(Map<Class<?>, Class<?>> forward,
|
||||
Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value) {
|
||||
forward.put(key, value);
|
||||
backward.put(value, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this type is a primitive.
|
||||
*/
|
||||
public static boolean isPrimitive(Type type) {
|
||||
return PRIMITIVE_TO_WRAPPER_TYPE.containsKey(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code type} is one of the nine primitive-wrapper
|
||||
* types, such as {@link Integer}.
|
||||
*
|
||||
* @see Class#isPrimitive
|
||||
*/
|
||||
public static boolean isWrapperType(Type type) {
|
||||
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding wrapper type of {@code type} if it is a
|
||||
* primitive type; otherwise returns {@code type} itself. Idempotent.
|
||||
*
|
||||
* <pre>
|
||||
* wrap(int.class) == Integer.class
|
||||
* wrap(Integer.class) == Integer.class
|
||||
* wrap(String.class) == String.class
|
||||
* </pre>
|
||||
*/
|
||||
public static <T> Class<T> wrap(Class<T> type) {
|
||||
// cast is safe: long.class and Long.class are both of type Class<Long>
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE
|
||||
.get(checkNotNull(type));
|
||||
return (wrapped == null) ? type : wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding primitive type of {@code type} if it is a
|
||||
* wrapper type; otherwise returns {@code type} itself. Idempotent.
|
||||
*
|
||||
* <pre>
|
||||
* unwrap(Integer.class) == int.class
|
||||
* unwrap(int.class) == int.class
|
||||
* unwrap(String.class) == String.class
|
||||
* </pre>
|
||||
*/
|
||||
public static <T> Class<T> unwrap(Class<T> type) {
|
||||
// cast is safe: long.class and Long.class are both of type Class<Long>
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE
|
||||
.get(checkNotNull(type));
|
||||
return (unwrapped == null) ? type : unwrapped;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj) {
|
||||
if (obj == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
@ -11,7 +11,6 @@ import java.util.Set;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.internal.Primitives;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
@ -287,7 +286,7 @@ public class StructureModifier<TField> {
|
||||
Class<?> type = field.getType();
|
||||
|
||||
// First, ignore primitive fields
|
||||
if (!Primitives.isPrimitive(type)) {
|
||||
if (!PrimitiveUtils.isPrimitive(type)) {
|
||||
// Next, see if we actually can generate a default value
|
||||
if (DefaultInstances.getDefault(type) != null) {
|
||||
// If so, require it
|
||||
|
Loading…
Reference in New Issue
Block a user