package cc.util.bossshop;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;

import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;

public class ClassHelper{

    public static String mTestVersion="v1_7_R4";
    /**
     * MC版本,请勿直接获取,请使用{@link ClassHelper#getServerVersion()}来获取
     */
    @Deprecated
    private static String mMCVersion;

    /**
     * 获取服务的Bukkit版本
     */
    public static String getServerVersion(){
        if(mMCVersion==null){
            if(Bukkit.getServer()!=null){
                String className=Bukkit.getServer().getClass().getPackage().getName();
                mMCVersion=className.substring(className.lastIndexOf('.')+1);
            }else mMCVersion=mTestVersion;
        }
        return mMCVersion;
    }

    /**
     * 查看指定类名是否加载,不会报错
     * @param name 类完整名字
     */
    public static boolean isClassLoaded(String name){
        try{
            Class.forName(name);
            return true;
        }catch(Throwable e){
            return false;
        }
    }

    /**
     * 获取org.bukkit.craftbukkit类的全名
     * @param pName 短名字
     * @return 完整名字
     */
    public static String getCBTName(String pName){
        return "org.bukkit.craftbukkit."+ClassHelper.getServerVersion()+"."+pName;
    }

    /**
     * 获取NMS类的{@link Class}对象
     * @param pClazz NMS类短名字
     */
    public static Class<?> getNMSClass(String pClazz){
        return ClassHelper.getClass(getNMSName(pClazz));
    }
    
    /**
     * 获取NMS类的全名
     * @param pName 短名字
     * @return 完整名字
     */
    public static String getNMSName(String pName){
        return "net.minecraft.server."+ClassHelper.getServerVersion()+"."+pName;
    }

    /**
     * 获取craftbukkit类的{@link Class}对象
     * @param pClazz craftbukkit类短名字,(org.bukkit.craftbukkit.version后的名字)
     */
    public static Class<?> getCBTClass(String pClazz){
        return ClassHelper.getClass(getCBTName(pClazz));
    }

    /**
     * 取出指定Object中的指定名字的值域
     * @param pObj 要取数据的实例
     * @param pField 值域名
     * @return 值域的值
     */
    public static Object getFieldValue(Object pObj,String pField){
        Validate.notNull(pObj,"要获取值域的对象不能为null对象");
        Class<?> tClazz=pObj.getClass();
        Field tField=null;
        try{
            tField=tClazz.getDeclaredField(pField);
            tField.setAccessible(true);
            return tField.get(pObj);
        }catch(NoSuchFieldException|SecurityException|IllegalArgumentException|IllegalAccessException e){
            FBukkit.severe("获取"+tClazz.getName()+"的类的实例对象的值域"+pField+"时发生了错误",e);
        }
        return null;
    }

    /**
     * 设置指定对象实例的指定名字的值域的值
     * @param pObj 对象实例
     * @param pField 值域名
     * @param pValue 要设置成的值
     */
    public static void setFieldValue(Object pObj,String pField,Object pValue){
        Validate.notNull(pObj,"要获取值域的对象不能为null对象");
        Class<?> tClazz=pObj.getClass();
        Field tField=null;
        try{
            tField=tClazz.getDeclaredField(pField);
            tField.setAccessible(true);
            tField.set(pObj,pValue);
        }catch(NoSuchFieldException|SecurityException|IllegalArgumentException|IllegalAccessException e){
            FBukkit.severe("设置"+tClazz.getName()+"的类的实例对象的值域"+pField+"时发生了错误",e);
        }
    }

    /**
     * 获取指定对象实例指定值域的值
     * @param pObj 对象
     * @param pField 值域
     */
    public static Object getFieldValue(Object pObj,Field pField){
        try{
            Validate.notNull(pObj,"要获取值域的对象不能为null对象");
            pField.setAccessible(true);
            return pField.get(pObj);
        }catch(IllegalArgumentException|IllegalAccessException e){
            FBukkit.severe("获取"+pObj.getClass().getName()+"的类的实例对象的值域"+pField+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 设置指定对象实例的指定名字的值域的值
     * @param pObj 对象实例
     * @param pField 值域名
     * @param pValue 要设置成的值
     */
    public static void setFieldValue(Object pObj,Field pField,Object pValue){
        try{
            pField.setAccessible(true);
            pField.set(pObj,pValue);
        }catch(IllegalArgumentException|IllegalAccessException e){
            FBukkit.severe("设置"+pObj.getClass().getName()+"的类的实例对象的值域"+pField+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 获取指定对象实例,指定类型,指定前缀修饰符的值域的值
     * @param pObj 对象实例
     * @param pFieldType 值域类型
     * @param modifier 值域修饰符,如果不限制则为-1
     */
    public static <T> T getFieldValue(Object pObj,Class<T> pFieldType,int modifier){
        Field tField=ClassHelper.getField(pObj.getClass(),pFieldType,modifier).get(0);
        try{
            tField.setAccessible(true);
            return (T)tField.get(pObj);
        }catch(IllegalArgumentException|IllegalAccessException e){
            FBukkit.severe("获取"+pObj.getClass().getName()+"的类实例的指定类型"+pFieldType+"值域时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 设置指定对象实例,指定类型,指定前缀修饰符的值域的值
     * @param pObj 对象实例
     * @param pFieldType 值域类型
     * @param pValue 要设置成的值
     * @param modifier 值域修饰符,如果不限制则为-1
     */
    public static <T> void setFiledValue(Object pObj,Class<T> pFieldType,Object pValue,int modifier){
        Field tField=ClassHelper.getField(pObj.getClass(),pFieldType,modifier).get(0);
        try{
            if(tField!=null){
                tField.setAccessible(true);
                tField.set(pObj,pValue);
            }
        }catch(IllegalArgumentException|IllegalAccessException e){
            FBukkit.severe("设置"+pObj.getClass().getName()+"的类实例的指定类型"+pFieldType+"值域时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 获取指定对象实例,指定类型,指定前缀修饰符的值域
     * @param pClazz 对象实例
     * @param pFieldClassShorName 值域类型短名字
     * @param modifier 值域修饰符,如果不限制则为-1
     */
    public static Field getFieldByClassName(Class<?> pClazz,String pFieldClassShorName,int modifier){
        try{
            Field[] tFields=pClazz.getDeclaredFields();
            for(Field sField : tFields){
                if(sField.getType().getSimpleName().equals(pFieldClassShorName)&&(sField.getModifiers()==modifier||modifier<0)) return sField;
            }
            throw new NoSuchFieldException("类"+pClazz.getName()+"不存在值域类型短名字为: "+pFieldClassShorName+",且类型修饰符为: "+modifier+"的值域");
        }catch(SecurityException|IllegalArgumentException|NoSuchFieldException e){
            FBukkit.severe("获取"+pClazz.getName()+"类的值域类型短名字为"+pFieldClassShorName+"的值域时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 获取指定对象实例,指定类型,指定前缀修饰符的值域
     * @param pClazz 对象实例
     * @param pFieldName 值域类型短名字
     * @param modifier 值域修饰符,如果不限制则为-1
     */
    public static Field getFieldByFieldName(Class<?> pClazz,String pFieldName,int modifier){
        try{
            Field[] tFields=pClazz.getDeclaredFields();
            for(Field sField : tFields){
                if(sField.getName().equals(pFieldName)&&(sField.getModifiers()==modifier||modifier<0)) return sField;
            }
            throw new NoSuchFieldException("类"+pClazz.getName()+"不存在名字为: "+pFieldName+",且类型修饰符为: "+modifier+"的值域");
        }catch(SecurityException|IllegalArgumentException|NoSuchFieldException e){
            FBukkit.severe("获取"+pClazz.getName()+"类的值域名字为"+pFieldName+"的值域时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 获取指定对象实例,指定类型,指定前缀修饰符的值域
     * @param pClazz 对象实例
     * @param pFieldType 值域类型
     * @param modifier 值域修饰符,如果不限制则为-1
     */
    public static ArrayList<Field> getField(Class<?> pClazz,Class<?> pFieldClazz,int modifier){
        try{
            ArrayList<Field> findFields=new ArrayList<>();
            Field[] tFields=pClazz.getDeclaredFields();
            for(Field sField : tFields)
                if(isSameClazz(sField.getType(),pFieldClazz)&&(sField.getModifiers()==modifier||modifier<0)) findFields.add(sField);
            if(!findFields.isEmpty()) return findFields;
            throw new NoSuchFieldException("类"+pClazz.getName()+"不存在类型为: "+pFieldClazz.getName()+",且类型修饰符为: "+modifier+"的值域");
        }catch(SecurityException|IllegalArgumentException|NoSuchFieldException e){
            FBukkit.severe("获取"+pClazz.getName()+"的类的值域"+pFieldClazz+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定对象实例的无参数方法,并返回结果
     * @param pObj          对象实例
     * @param pMethod       方法名
     */
    public static Object invokeMethod(Object pObj,String pMethod){
        return invokeMethod(pObj,pMethod,new Class<?>[]{},new Object[]{});
    }

    /**
     * 执行指定实例的单参数方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法名
     * @param pArgClazz    参数类型
     * @param pArg          参数
     */
    public static Object invokeMethod(Object pObj,String pMethod,Class<?> pArgClazz,Object pArg){
        return invokeMethod(pObj,pMethod,new Class<?>[]{pArgClazz},new Object[]{pArg});
    }

    /**
     * 执行指定实例的指定方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法名
     * @param pArgsClazzs   参数类型
     * @param pArgs         参数
     */
    public static Object invokeMethod(Object pObj,String pMethod,Class<?>[] pArgsClazzs,Object[] pArgs){
        if(pObj==null) return null;
        if(pMethod==null) return null;
        Class<?> tClazz=pObj.getClass();
        Method tMethod=null;
        try{
            if(pArgsClazzs==null||pArgsClazzs.length==0) tMethod=tClazz.getDeclaredMethod(pMethod);
            else tMethod=tClazz.getDeclaredMethod(pMethod,pArgsClazzs);
            tMethod.setAccessible(true);
            return tMethod.invoke(pObj,pArgs);
        }catch(IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException e){
            FBukkit.severe("执行"+tClazz.getName()+"的类的方法: "+pMethod+",参数: "+Arrays.asList(pArgsClazzs)+" "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定对象实例的无参数方法,并返回结果
     * @param pObj          对象实例
     * @param pMethod       方法
     */
    public static Object invokeMethod(Object pObj,Method pMethod){
        return invokeMethod(pObj,pMethod,new Object[]{});
    }

    /**
     * 执行指定实例的单参数方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法
     * @param pArgClazz    参数类型
     * @param pArg          参数
     */
    public static Object invokeMethod(Object pObj,Method pMethod,Object pArg){
        return invokeMethod(pObj,pMethod,new Object[]{pArg});
    }

    /**
     * 执行指定实例的指定方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法
     * @param pArgsClazzs   参数类型
     * @param pArgs         参数
     */
    public static Object invokeMethod(Object pObj,Method pMethod,Object[] pArgs){
        if(pObj==null) return null;
        if(pMethod==null) return null;
        Class<?> tClazz=pObj.getClass();
        try{
            pMethod.setAccessible(true);
            return pMethod.invoke(pObj,pArgs);
        }catch(IllegalAccessException|IllegalArgumentException|InvocationTargetException|SecurityException e){
            FBukkit.severe("执行"+tClazz.getName()+"的类的方法: "+pMethod+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定实例且返回类型特定的的无参数方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法名
     */
    public static <T> T invokeMethod(Object pObj,Class<T> pReturnType){
        return invokeMethod(pObj,pReturnType,new Class<?>[]{},new Object[]{});
    }

    /**
     * 执行指定实例且返回类型特定的单参数方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法名
     * @param pArgClazz    参数类型
     * @param pArg          参数
     */
    public static <T> T invokeMethod(Object pObj,Class<T> pReturnType,Class<?> pArgClazz,Object pArg){
        return invokeMethod(pObj,pReturnType,new Class<?>[]{pArgClazz},new Object[]{pArg});
    }

    /**
     * 执行指定实例的指定方法,并返回结果
     * @param pObj          实例对象
     * @param pMethod       方法名
     * @param pArgsClazzs   参数类型
     * @param pArgs         参数
     */
    public static <T> T invokeMethod(Object pObj,Class<T> pReturnType,Class<?>[] pArgsClazzs,Object[] pArgs){
        Validate.notNull(pObj,"要执行方法的对象不能为null对象");
        Class<?> tClazz=pObj.getClass();
        try{
            Method tMethod=ClassHelper.getUnknowMethod(tClazz,pReturnType,pArgsClazzs).get(0);
            tMethod.setAccessible(true);
            return (T)tMethod.invoke(pObj,pArgs);
        }catch(IllegalAccessException|IllegalArgumentException|InvocationTargetException|SecurityException e){
            FBukkit.severe("执行"+tClazz.getName()+"的类的未知方法,返回类型: "+pReturnType.getName()+"[参数: "+pArgsClazzs+"] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定对象名指定的无参静态方法,并返回结果
     * @param pClazz        对象
     * @param pMethod       方法名
     */
    public static Object invokeStaticMethod(String pClazz,String pMethod){
        return invokeStaticMethod(pClazz,pMethod,new Class<?>[]{},new Object[]{});
    }

    /**
     * 执行指定对象名指定的单参数参静态方法,并返回结果
     * @param pClazz        对象
     * @param pMethod       方法名
     * @param pArgClazz 参数类型
     * @param pArg 参数
     */
    public static Object invokeStaticMethod(String pClazz,String pMethod,Class<?> pArgClazz,Object pArg){
        return invokeStaticMethod(pClazz,pMethod,new Class<?>[]{pArgClazz},new Object[]{pArg});
    }

    /**
     * 执行指定对象名指定的静态方法,并返回结果
     * @param pClazz        对象
     * @param pMethod       方法名
     * @param pArgsClazzs 参数类型
     * @param pArgs 参数
     */
    public static Object invokeStaticMethod(String pClazz,String pMethod,Class<?>[] pArgsClazzs,Object[] pArgs){
        try{
            Class<?> tClazz=Class.forName(pClazz);
            return ClassHelper.invokeStaticMethod(tClazz,pMethod,pArgsClazzs,pArgs);
        }catch(IllegalArgumentException|SecurityException|ClassNotFoundException e){
            FBukkit.severe("执行"+pClazz+"的类的方法: "+pMethod+",[参数: "+pArgsClazzs+"] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定对象指定的无参静态方法,并返回结果
     * @param pClazz        对象
     * @param pMethod       方法名
     */
    public static Object invokeStaticMethod(Class<?> pClazz,String pMethod){
        return invokeStaticMethod(pClazz,pMethod,new Class<?>[]{},new Object[]{});
    }

    /**
     * 执行指定对象名指定的单参数参静态方法,并返回结果
     * @param pClazz        对象
     * @param pMethod       方法名
     * @param pArgClazz 参数类型
     * @param pArg 参数
     */
    public static Object invokeStaticMethod(Class<?> pClazz,String pMethod,Class<?> pArgClazz,Object pArg){
        return invokeStaticMethod(pClazz,pMethod,new Class<?>[]{pArgClazz},new Object[]{pArg});
    }

    /**
     * 执行指定对象名指定的静态方法,并返回结果
     * @param pClazz        对象
     * @param pMethod       方法名
     * @param pArgsClazzs 参数类型
     * @param pArgs 参数
     */
    public static Object invokeStaticMethod(Class<?> pClazz,String pMethod,Class<?>[] pArgClazz,Object[] pArgs){
        Method tMethod=null;
        try{
            if(pArgClazz==null||pArgClazz.length==0) tMethod=pClazz.getDeclaredMethod(pMethod);
            else tMethod=pClazz.getDeclaredMethod(pMethod,pArgClazz);
            return invokeStaticMethod(tMethod,pArgs);
        }catch(IllegalArgumentException|NoSuchMethodException|SecurityException e){
            FBukkit.severe("执行"+pClazz+"的类的方法: +pMethod,[参数: "+pArgClazz+"] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定的无参静态方法
     * @param pMethod 方法
     */
    public static Object invokeStaticMethod(Method pMethod){
        try{
            pMethod.setAccessible(true);
            return pMethod.invoke(null);
        }catch(IllegalAccessException|IllegalArgumentException|InvocationTargetException e){
            FBukkit.severe("执行方法: "+pMethod+",[参数: 无] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定的单参静态方法
     * @param pMethod 方法
     * @param pArg 参数
     */
    public static Object invokeStaticMethod(Method pMethod,Object pArg){
        try{
            pMethod.setAccessible(true);
            return invokeStaticMethod(pMethod,new Object[]{pArg});
        }catch(IllegalArgumentException e){
            FBukkit.severe("执行方法: "+pMethod+",[参数: "+pArg+"] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行指定的单参静态方法
     * @param pMethod 方法
     * @param pArgs 参数
     */
    public static Object invokeStaticMethod(Method pMethod,Object[] pArgs){
        try{
            pMethod.setAccessible(true);
            return pMethod.invoke(null,pArgs);
        }catch(IllegalAccessException|IllegalArgumentException|InvocationTargetException e){
            FBukkit.severe("执行方法: "+pMethod+",[参数: "+pArgs+"] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行类的无参构造函数,并返回结果
     * @param pClazz 类全名
     */
    public static Object getInstance(String pClazz){
        return getInstance(pClazz,new Class<?>[]{},new Object[]{});
    }

    /**
     * 执行类的单参构造函数,并返回结果
     * @param pClazz 类全名
     * @param pArgClazz 参数类型
     * @param pArg 参数
     */
    public static Object getInstance(String pClazz,Class<?> pArgClazz,Object pArg){
        return getInstance(pClazz,new Class<?>[]{pArgClazz},new Object[]{pArg});
    }

    /**
     * 执行类的指定参数构造函数,并返回结果
     * @param pClazz 类全名
     * @param pArgsClazzs 参数类型
     * @param pArgs 参数
     */
    public static Object getInstance(String pClazz,Class<?>[] pArgsClazzs,Object[] pArgs){
        try{
            Class<?> tClazz=Class.forName(pClazz);
            return ClassHelper.getInstance(tClazz,pArgsClazzs,pArgs);
        }catch(ClassNotFoundException|SecurityException|IllegalArgumentException e){
            FBukkit.severe("使用参数"+pArgsClazzs+"实例化类"+pClazz+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 执行类的无参构造函数,并返回结果
     * @param pClazz 类
     */
    public static Object getInstance(Class<?> pClazz){
        return getInstance(pClazz,new Class<?>[]{},new Object[]{});
    }

    /**
     * 执行类的单参构造函数,并返回结果
     * @param pClazz 类
     * @param pArgClazz 参数类型
     * @param pArg 参数
     */
    public static Object getInstance(Class<?> pClazz,Class<?> pArgsClazzs,Object pArgs){
        return getInstance(pClazz,new Class<?>[]{pArgsClazzs},new Object[]{pArgs});
    }

    /**
     * 执行类指定参数的构造函数,并返回结果
     * @param pClazz 类全名
     * @param pArgsClazzs 参数类型
     * @param pArgs 参数
     */
    public static Object getInstance(Class<?> pClazz,Class<?>[] pArgsClazzs,Object[] pArgs){
        try{
            Constructor<?> tcons=null;
            if(pArgsClazzs==null||pArgsClazzs.length==0) tcons=pClazz.getConstructor();
            else tcons=pClazz.getConstructor(pArgsClazzs);
            tcons.setAccessible(true);
            return tcons.newInstance(pArgs);
        }catch(NoSuchMethodException|SecurityException|InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e){
            FBukkit.severe("使用参数"+pArgsClazzs+"实例化类"+pClazz+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 获取类
     * @param pClazz 类全名
     */
    public static Class<?> getClass(String pClazz){
        try{
            return Class.forName(pClazz);
        }catch(ClassNotFoundException e){
            FBukkit.severe("获取类"+pClazz+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 获取类指定名字的无参方法
     * @param pClass 类
     * @param pMethodName 方法名
     */
    public static Method getMethod(Class<?> pClass,String pMethodName){
        return getMethod(pClass,pMethodName,new Class<?>[]{});
    }

    /**
     * 获取类指定名字的单参方法
     * @param pClass 类
     * @param pMethodName 方法名
     * @param pArgClass 参数类型
     */
    public static Method getMethod(Class<?> pClass,String pMethodName,Class<?> pArgClass){
        return getMethod(pClass,pMethodName,new Class<?>[]{pArgClass});
    }

    /**
     * 获取类指定名字的指定参数的方法
     * @param pClass 类
     * @param pMethodName 方法名
     * @param pArgsClass 参数类型
     */
    public static Method getMethod(Class<?> pClass,String pMethodName,Class<?>[] pArgsClazzs){
        Method tMethod=null;
        try{
            if(pArgsClazzs==null||pArgsClazzs.length==0) tMethod=pClass.getDeclaredMethod(pMethodName);
            else tMethod=pClass.getDeclaredMethod(pMethodName,pArgsClazzs);
            return tMethod;
        }catch(IllegalArgumentException|NoSuchMethodException|SecurityException e){
            FBukkit.severe("获取"+pClass.getName()+"的类的方法: "+pMethodName+",[参数: "+pArgsClazzs+"] "+"时发生了错误",e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 根据返回类型的短名字获取指定类的无参数方法
     * @param pClass 类
     * @param pReturnTypeSimpleName 类短名字
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,String pReturnTypeSimpleName){
        return ClassHelper.getUnknowMethod(pClass,pReturnTypeSimpleName,new Class<?>[]{});
    }

    /**
     * 根据返回类型的短名字获取指定类的单参数方法
     * @param pClass 类
     * @param pReturnTypeSimpleName 类短名字
     * @param pArgClazz 参数类型
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,String pReturnTypeSimpleName,Class<?> pArgClazz){
        return ClassHelper.getUnknowMethod(pClass,pReturnTypeSimpleName,new Class<?>[]{pArgClazz});
    }

    /**
     * 根据返回类型的短名字和参数类型来获取自定类的多参数方法
     * @param pClass 类
     * @param pReturnTypeSimpleName 类短名字
     * @param pArgsClazzs 参数类型
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,String pReturnTypeSimpleName,Class<?>[] pArgsClazzs){
        if(pReturnTypeSimpleName==null||pReturnTypeSimpleName.equals("null")) pReturnTypeSimpleName=void.class.getSimpleName();
        Method[] tMethods=pClass.getDeclaredMethods();
        ArrayList<Method> findMethodes=new ArrayList<Method>();
        for(Method sMethod : tMethods){
            Class<?> tReturn=sMethod.getReturnType();
            if(tReturn.getSimpleName().equals(pReturnTypeSimpleName)&&isSameClazzs(sMethod.getParameterTypes(),pArgsClazzs)) findMethodes.add(sMethod);
        }
        if(!findMethodes.isEmpty()) return findMethodes;
        String tArgsStr="";
        for(int i=0;i<pArgsClazzs.length;i++){
            tArgsStr+=pArgsClazzs[i].getSimpleName()+",";
        }
        if(tArgsStr.length()>0) tArgsStr=tArgsStr.substring(0,tArgsStr.length()-1);
        else tArgsStr="无";
        try{
            throw new NoSuchMethodException("未发现类"+pClass.getName()+"返回类型名为: "+pReturnTypeSimpleName+",且参数为: "+tArgsStr+"的方法");
        }catch(NoSuchMethodException e){
            FBukkit.severe(e.getMessage(),e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 根据返回类型来获取指定类的无参数方法
     * @param pClass 类
     * @param pReturnType 返回类型
     * @param pArgClazz 参数类型
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,Class<?> pReturnType){
        return getUnknowMethod(pClass,pReturnType,new Class<?>[]{});
    }

    /**
     * 根据返回类型和单参数来获取指定类的单参数方法
     * @param pClass 类
     * @param pReturnType 返回类型
     * @param pArgClazz 参数类型
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,Class<?> pReturnType,Class<?> pArgClazz){
        return getUnknowMethod(pClass,pReturnType,new Class<?>[]{pArgClazz});
    }

    /**
     * 根据返回类型和参数来获取指定类的多参数方法
     * @param pClass 类
     * @param pReturnType 返回类型
     * @param pArgsClazzs 参数类型
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,Class<?> pReturnType,Class<?>[] pArgsClazzs){
        Method[] tMethods=pClass.getDeclaredMethods();
        ArrayList<Method> findMethodes=new ArrayList<Method>();
        for(Method sMethod : tMethods){
            Class<?> tReturn=sMethod.getReturnType();
            if(isSameClazz(tReturn,pReturnType)&&isSameClazzs(sMethod.getParameterTypes(),pArgsClazzs)) findMethodes.add(sMethod);
        }
        if(!findMethodes.isEmpty()) return findMethodes;
        String tArgsStr="";
        for(int i=0;i<pArgsClazzs.length;i++){
            tArgsStr+=pArgsClazzs[i].getSimpleName()+",";
        }
        if(tArgsStr.length()>0) tArgsStr=tArgsStr.substring(0,tArgsStr.length()-1);
        else tArgsStr="无";
        try{
            throw new NoSuchMethodException("未发现类"+pClass.getName()+"返回类型名为: "+pReturnType+",且参数为: "+tArgsStr+"的方法");
        }catch(NoSuchMethodException e){
            FBukkit.severe(e.getMessage(),e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 根据返回类型和单参数来获取指定类的单参数方法
     * @param pClass 类
     * @param pReturnType 返回类型
     * @param pArgClassShortName 参数类型
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,Class<?> pReturnType,String pArgClassShortName){
        return getUnknowMethod(pClass,pReturnType,new String[]{pArgClassShortName});
    }

    /**
     * 根据返回类型和参数来获取指定类的多参数方法
     * @param pClass 类
     * @param pReturnType 返回类型
     * @param pArgsClassShortName 参数短类型名
     */
    public static ArrayList<Method> getUnknowMethod(Class<?> pClass,Class<?> pReturnType,String[] pArgsClassShortName){
        Method[] tMethods=pClass.getDeclaredMethods();
        ArrayList<Method> findMethodes=new ArrayList<Method>();
        for(Method sMethod : tMethods){
            Class<?> tReturn=sMethod.getReturnType();
            if(isSameClazz(tReturn,pReturnType)&&isSameClazzs(sMethod.getParameterTypes(),pArgsClassShortName)) findMethodes.add(sMethod);
        }
        if(!findMethodes.isEmpty()) return findMethodes;
        String tArgsStr="";
        for(int i=0;i<pArgsClassShortName.length;i++){
            tArgsStr+=pArgsClassShortName[i]+",";
        }
        if(tArgsStr.length()>0) tArgsStr=tArgsStr.substring(0,tArgsStr.length()-1);
        else tArgsStr="无";
        try{
            throw new NoSuchMethodException("未发现类"+pClass.getName()+"返回类型名为: "+pReturnType+",且参数为: "+tArgsStr+"的方法");
        }catch(NoSuchMethodException e){
            FBukkit.severe(e.getMessage(),e);
            throw new IllegalStateException(e);
        }
    }

    /**
     * 比较两个类数组是不是包含切顺序相同的类
     */
    private static boolean isSameClazzs(Class<?>[] pClazzs1,Class<?>[] pClazzs2){
        if(pClazzs1==pClazzs2) return true;
        if((pClazzs1==null&&pClazzs2.length==0)||(pClazzs1.length==0&&pClazzs2==null)) return true;
        if(pClazzs1==null||pClazzs2==null) return false;
        if(pClazzs1.length!=pClazzs2.length) return false;
        for(int i=0;i<pClazzs1.length;i++){
            if(pClazzs1[i]!=pClazzs2[i]) return false;
        }
        return true;
    }

    /**
     * 比较两个类数组是不是包含切顺序相同的类
     */
    private static boolean isSameClazzs(Class<?>[] pClazzs1,String[] pClazzsShortName){
        if(pClazzs1==null&&pClazzsShortName==null) return true;
        if((pClazzs1==null&&pClazzsShortName.length==0)||(pClazzs1.length==0&&pClazzsShortName==null)) return true;

        if(pClazzs1.length!=pClazzsShortName.length) return false;
        for(int i=0;i<pClazzs1.length;i++){
            if(!pClazzs1[i].getSimpleName().equals(pClazzsShortName[i])) return false;
        }
        return true;
    }

    /**
     * 比较两个类是不是包含切顺序相同的类
     */
    private static boolean isSameClazz(Class<?> pClazz1,Class<?> pClazz2){
        if(pClazz1==pClazz2) return true;
        if((pClazz1==void.class&&pClazz2==null)||(pClazz1==null&&pClazz2==void.class)) return true;
        return false;
    }

    /**
     * 打印一个类所有的方法
     * @param pClass 类
     */
    public static void printfMethod(Class<?> pClass){
        Method[] tMethods=pClass.getDeclaredMethods();
        for(Method sMethod : tMethods){
            System.out.println(sMethod);
        }
    }

}
