From 768d169f2779b875816a16a2961f30bc59d9aee0 Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Fri, 12 Oct 2012 00:01:05 +0200 Subject: [PATCH] Added the same NULL check to the generic Bukkit unwrapper. --- .../protocol/injector/BukkitUnwrapper.java | 228 +++++++++--------- 1 file changed, 115 insertions(+), 113 deletions(-) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/BukkitUnwrapper.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/BukkitUnwrapper.java index 6ca4d332..147e2087 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/BukkitUnwrapper.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/BukkitUnwrapper.java @@ -1,113 +1,115 @@ -/* - * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. - * Copyright (C) 2012 Kristian S. Stangeland - * - * 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 - * 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; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * 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; - * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -package com.comphenix.protocol.injector; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import com.comphenix.protocol.injector.PacketConstructor.Unwrapper; -import com.comphenix.protocol.reflect.instances.DefaultInstances; - -/** - * Represents an object capable of converting wrapped Bukkit objects into NMS objects. - *

- * Typical conversions include: - *

- * - * @author Kristian - */ -public class BukkitUnwrapper implements Unwrapper { - - private static Map, Method> cache = new ConcurrentHashMap, Method>(); - - @SuppressWarnings("unchecked") - @Override - public Object unwrapItem(Object wrappedObject) { - - // Special case - if (wrappedObject instanceof Collection) { - return handleCollection((Collection) wrappedObject); - } - - Class currentClass = wrappedObject.getClass(); - Method cachedMethod = initializeCache(currentClass); - - try { - // Retrieve the handle - if (cachedMethod != null) - return cachedMethod.invoke(wrappedObject); - else - return null; - - } catch (IllegalArgumentException e) { - // Impossible - return null; - } catch (IllegalAccessException e) { - return null; - } catch (InvocationTargetException e) { - // This is REALLY bad - throw new RuntimeException("Minecraft error.", e); - } - } - - private Object handleCollection(Collection wrappedObject) { - - @SuppressWarnings("unchecked") - Collection copy = DefaultInstances.DEFAULT.getDefault(wrappedObject.getClass()); - - if (copy != null) { - // Unwrap every element - for (Object element : wrappedObject) { - copy.add(unwrapItem(element)); - } - return copy; - - } else { - // Impossible - return null; - } - } - - private Method initializeCache(Class type) { - - // See if we're already determined this - 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"); - - // It's thread safe, as getMethod should return the same handle - cache.put(type, find); - return find; - - } catch (SecurityException e) { - return null; - } catch (NoSuchMethodException e) { - return null; - } - } -} +/* + * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. + * Copyright (C) 2012 Kristian S. Stangeland + * + * 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 + * 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; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * 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; + * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ + +package com.comphenix.protocol.injector; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.comphenix.protocol.injector.PacketConstructor.Unwrapper; +import com.comphenix.protocol.reflect.instances.DefaultInstances; + +/** + * Represents an object capable of converting wrapped Bukkit objects into NMS objects. + *

+ * Typical conversions include: + *

    + *
  • org.bukkit.entity.Player -> net.minecraft.server.EntityPlayer
  • + *
  • org.bukkit.World -> net.minecraft.server.WorldServer
  • + *
+ * + * @author Kristian + */ +public class BukkitUnwrapper implements Unwrapper { + + private static Map, Method> cache = new ConcurrentHashMap, Method>(); + + @SuppressWarnings("unchecked") + @Override + public Object unwrapItem(Object wrappedObject) { + + // Special cases + if (wrappedObject == null) { + return null; + } else if (wrappedObject instanceof Collection) { + return handleCollection((Collection) wrappedObject); + } + + Class currentClass = wrappedObject.getClass(); + Method cachedMethod = initializeCache(currentClass); + + try { + // Retrieve the handle + if (cachedMethod != null) + return cachedMethod.invoke(wrappedObject); + else + return null; + + } catch (IllegalArgumentException e) { + // Impossible + return null; + } catch (IllegalAccessException e) { + return null; + } catch (InvocationTargetException e) { + // This is REALLY bad + throw new RuntimeException("Minecraft error.", e); + } + } + + private Object handleCollection(Collection wrappedObject) { + + @SuppressWarnings("unchecked") + Collection copy = DefaultInstances.DEFAULT.getDefault(wrappedObject.getClass()); + + if (copy != null) { + // Unwrap every element + for (Object element : wrappedObject) { + copy.add(unwrapItem(element)); + } + return copy; + + } else { + // Impossible + return null; + } + } + + private Method initializeCache(Class type) { + + // See if we're already determined this + 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"); + + // It's thread safe, as getMethod should return the same handle + cache.put(type, find); + return find; + + } catch (SecurityException e) { + return null; + } catch (NoSuchMethodException e) { + return null; + } + } +}