Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

[resolved]KCauldron reflection

Тема в разделе "Разработка плагинов для новичков", создана пользователем MOR_IV, 17 фев 2016.

Статус темы:
Закрыта.
  1. Автор темы
    MOR_IV

    MOR_IV Активный участник Пользователь

    Баллы:
    88
    Имя в Minecraft:
    MOR_IV
    Значит имеем следующее:
    Код:
    public class ReflectionAPI {
        private boolean error;
        private String server = "net.minecraft.server.";
        private String craftbukkit = "org.bukkit.craftbukkit.";
        private Class<?> CraftWorld;
        private Class<?> CraftItemStack;
     
        private Class<?> ItemStack;
        private Class<?> NBTTagCompound;
        private Class<?> TileEntity;
        private boolean forge = false;
     
        public ReflectionAPI() {
            error = false;
            load();
        }
     
        private void load() {
            String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
            ggg();
            loadClass();
            loadMethods();
        }
    
        private void ggg() {
            if(Bukkit.getServer()!=null) {
                if(Bukkit.getVersion().contains("MCPC")||Bukkit.getVersion().contains("Forge")) forge = true;
                Server server = Bukkit.getServer();
                Class<?> bukkitServerClass = server.getClass();
                String[] pas = bukkitServerClass.getName().split("\\.");
                if (pas.length == 5) {
                    String verB = pas[3];
                    craftbukkit += verB;
                }
                try {
                    Method getHandle = bukkitServerClass.getDeclaredMethod("getHandle");
                    Object handle = getHandle.invoke(server);
                    Class<? extends Object> handleServerClass = handle.getClass();
                    pas = handleServerClass.getName().split("\\.");
                    if (pas.length == 5) {
                        String verM = pas[3];
                        this.server += verM;
                    }
                    Bukkit.getLogger().info(this.server);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void loadClass() {
            String name;
            name = craftbukkit + ".CraftWorld";
            CraftWorld = getNMSClass(name);
            name = craftbukkit + ".inventory.CraftItemStack";
            CraftItemStack = getNMSClass(name);
           
            name = server + ".ItemStack";
            ItemStack = getNMSClass(name);
            name = server + ".NBTTagCompound";
            NBTTagCompound = getNMSClass(name);
            name = server + ".TileEntity";
            TileEntity = getNMSClass(name);
        }
        private Class<?> getNMSClass(String name){
            Bukkit.getLogger().info("-------------------------   " + name);
            Class<?> nmsClass = null;
            try {
                nmsClass = Class.forName(name);
            } catch (ClassNotFoundException e) {
                Bukkit.getLogger().info("+++++++++++++++++++++++   " + name);
                e.printStackTrace();
                error = true;
            }
            if(nmsClass != null)
                Bukkit.getLogger().info(nmsClass.getName());
            return nmsClass;
        }
    }
    

    Это тестовый код, поэтому не судить строго.
    Так вот прикол в том, что на spigot все работает отлично.
    а вот на KCaudron у меня дебаг пишет что срабатывает getNMSClass(String name) со значением name = net.minecraft.server.dedicated.ItemSrack
    далее NullPointerExceprion и даже трасировку не дает. Могу предположить что
    catch (ClassNotFoundException e) {
    Bukkit.getLogger().info("+++++++++++++++++++++++ " + name);
    e.printStackTrace();
    не выполняется...
    Помогите разобраться
     
    Последнее редактирование: 18 фев 2016
  2. Хостинг MineCraft
    <
  3. Автор темы
    MOR_IV

    MOR_IV Активный участник Пользователь

    Баллы:
    88
    Имя в Minecraft:
    MOR_IV
    Написал Это. Опять же на спиготе робит нормально.
    На KCauldron говорит java.lang.NoSuchMethodException: net.minecraft.item.ItemStack.getTag()
    То есть CraftItemStack.asNMSCopy(org.bukkit.inventory.ItemStack) возвращает экземпляр класса net.minecraft.item.ItemStack, в котором отсутствует метод getTag();
    Почему так - не понятно.
    Код:
    public String getTags(org.bukkit.inventory.ItemStack item){
            if(item == null | item.getType().equals(Material.AIR)) return Strings.NULL_NBT;
            String s = Strings.NULL_NBT;
            try {
                Object craftStack = asNMSCopy.invoke(CraftItemStack, new Object[] {item});
                Object tag = getMethod(craftStack.getClass(), "getTag", new Class[] {}).invoke(craftStack, new Object[] {});
                if(tag == null) return Strings.NULL_NBT;
                Bukkit.getLogger().info(tag.getClass().getName());
                Method toString = getMethod(tag.getClass(), "toString", new Class[] {});
            
                s = (String) toString.invoke(tag,  new Object[] {});
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
            return s;
        }
     
    Последнее редактирование: 18 фев 2016
  4. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Приведи полный stack trace из консоли во время ошибки.
    И да, пользуйся, пожалуйста, тегов CODE=Java для корректной подсветки синтаксиса блока с кодом. Спасибо :)
     
    Последнее редактирование: 19 фев 2016
  5. Автор темы
    MOR_IV

    MOR_IV Активный участник Пользователь

    Баллы:
    88
    Имя в Minecraft:
    MOR_IV
    Ок, но через сутки. Я на работе[DOUBLEPOST=1455840305,1455770400][/DOUBLEPOST]Так вот как обещал:
    Код:
    package ru.mor.iv.mineblocker.reflection;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.Server;
    import org.bukkit.entity.Player;
    
    import ru.mor.iv.mineblocker.utils.Strings;
    
    public class ReflectionAPI {
        private boolean error;
        private String server = "net.minecraft.server.";
        private String craftbukkit = "org.bukkit.craftbukkit.";
    
        public ReflectionAPI() {
            error = false;
            load();
        }
    
        private void load() {
            if(Bukkit.getServer()!=null) {
                Server server = Bukkit.getServer();
                Class<?> bukkitServerClass = server.getClass();
                String[] pas = bukkitServerClass.getName().split("\\.");
                if (pas.length == 5) {
                    String verB = pas[3];
                    craftbukkit += verB;
                }
                try {
                    Method getHandle = bukkitServerClass.getDeclaredMethod("getHandle");
                    Object handle = getHandle.invoke(server);
                    Class<? extends Object> handleServerClass = handle.getClass();
                    pas = handleServerClass.getName().split("\\.");
                    if (pas.length == 5) {
                        String verM = pas[3];
                        this.server += verM;
                    }
                    Bukkit.getLogger().info(this.server);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        public String getTags(org.bukkit.inventory.ItemStack item){
            if(item == null | item.getType().equals(Material.AIR)) return Strings.NULL_NBT;
            String s = Strings.NULL_NBT;
            /**/    log(org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack.class.getName());
            net.minecraft.server.v1_7_R4.ItemStack is = org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack.asNMSCopy(item);
       
            /**/    log(is.getClass().getName());
            net.minecraft.server.v1_7_R4.NBTTagCompound nbt = is.getTag();
            /**/        log(nbt.getClass().getName());
            if(nbt !=null){
                /**/    log(nbt.toString());
            }
            try {
                String name = craftbukkit + ".inventory.CraftItemStack";
                Class<?> craftItemStack = Class.forName(name);
                /**/    log("ref " + craftItemStack.getName());
                Class[] paramTypes = new Class[] { org.bukkit.inventory.ItemStack.class };
           
                Object craftStack = craftItemStack.getMethod("asNMSCopy",  paramTypes).invoke(craftItemStack, new Object[] {item});
                /**/    log("ref " + craftStack.getClass().getName());
                Object tag = craftStack.getClass().getMethod("getTag", new Class[] {}).invoke(craftStack, new Object[] {});
                if(tag == null) return Strings.NULL_NBT;
                /**/    log("ref " + tag.getClass().getName());
                Method toString = tag.getClass().getMethod("toString", new Class[] {});
                s = (String) toString.invoke(tag,  new Object[] {});
            } catch (NoSuchMethodException | SecurityException | ClassNotFoundException |
                    IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
       
       
       
            return "ref " + s;
        }
    
    Код:
    [10:06:26] [Server thread/INFO]: org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack
    [10:06:26] [Server thread/INFO]: net.minecraft.server.v1_7_R4.ItemStack
    [10:06:26] [Server thread/INFO]: net.minecraft.server.v1_7_R4.NBTTagCompound
    [10:06:26] [Server thread/INFO]: {ench:[0:{lvl:1s,id:32s,},],}
    [10:06:26] [Server thread/INFO]: ref org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack
    [10:06:26] [Server thread/INFO]: ref net.minecraft.server.v1_7_R4.ItemStack
    [10:06:26] [Server thread/INFO]: ref net.minecraft.server.v1_7_R4.NBTTagCompound
    
    Код:
    [09:47:31] [Server thread/INFO]: org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack
    [09:47:31] [Server thread/INFO]: net.minecraft.item.ItemStack
    [09:47:31] [Server thread/INFO]: net.minecraft.nbt.NBTTagCompound
    [09:47:31] [Server thread/INFO]: {laserSetting:1,charge:294000.0d}
    [09:47:31] [Server thread/INFO]: ref org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack
    [09:47:31] [Server thread/INFO]: ref net.minecraft.item.ItemStack
    [09:47:31] [Server thread/WARN]: java.lang.NoSuchMethodException: net.minecraft.item.ItemStack.getTag()
    [09:47:31] [Server thread/WARN]:     at java.lang.Class.getMethod(Unknown Source)
    [09:47:31] [Server thread/WARN]:     at ru.mor.iv.mineblocker.reflection.ReflectionAPI.getTags(ReflectionAPI.java:67)
    [09:47:31] [Server thread/WARN]:     at ru.mor.iv.mineblocker.command.CommandMB.onCommand(CommandMB.java:44)
    [09:47:31] [Server thread/WARN]:     at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
    [09:47:31] [Server thread/WARN]:     at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:181)
    [09:47:31] [Server thread/WARN]:     at org.bukkit.craftbukkit.v1_7_R4.CraftServer.dispatchCommand(CraftServer.java:717)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.network.NetHandlerPlayServer.func_147361_d(NetHandlerPlayServer.java:1317)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.network.NetHandlerPlayServer.func_147354_a(NetHandlerPlayServer.java:1099)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.network.play.client.C01PacketChatMessage.func_148833_a(C01PacketChatMessage.java:38)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.network.play.client.C01PacketChatMessage.func_148833_a(C01PacketChatMessage.java:53)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:245)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:173)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:991)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:431)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:809)
    [09:47:31] [Server thread/WARN]:     at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:669)
    [09:47:31] [Server thread/WARN]:     at java.lang.Thread.run(Unknown Source)
    

    Так вот забава - если внимательно вчитаться в коде я сначала вызываю прямую ссылку на net.minecraft.server.v1_7_R4, а калдрон говорит это классы net.minecraft, причем по прямой ссылке он отлично выполняет getTag() у net.minecraft.item.ItemStack, а через ref говорит такого нет.[DOUBLEPOST=1455841102][/DOUBLEPOST]Я пробежался по методам, сделал toString к каждому. Так вот смотрим:
    Spigot:
    Код:
    net.minecraft.server.v1_7_R4.ItemStack
    public net.minecraft.server.v1_7_R4.NBTTagCompound net.minecraft.server.v1_7_R4.ItemStack.getTag()
    То есть метод getTag() возвращает NBTTagCompound. Все ок.

    KCauldron:
    Код:
    net.minecraft.item.ItemStack
    public net.minecraft.nbt.NBTTagCompound net.minecraft.item.ItemStack.func_77978_p()
    То есть единственный(проверил внимательно) метод аналог, который возвращает NBTTagCompound - это func_77978_p().
    Как так?
     
  6. Shevchik

    Shevchik Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    А вот так, основа nms kcauldron - forge, соответственно названия Nms классов и методов mcpшные. В котле есть какой-никакой ремаппер обращения к спайготовскому nms, но работает он только для прямого обращения, не через рефлексию.
     
  7. Автор темы
    MOR_IV

    MOR_IV Активный участник Пользователь

    Баллы:
    88
    Имя в Minecraft:
    MOR_IV
    Как быть в моем случае? Есть идеи? Ручками писать проверку путей на наличие класса для каждой версии?[DOUBLEPOST=1455847521,1455841701][/DOUBLEPOST]Я выкрутился частично из ситуации.
    Берем одну известную, а именно класс CraftItemStack по имени. Потом при вызове метода getTags(ItemStack item) исследуем все классы, методы, возвращаемые значения по пути следования, сохраняя все в переменные значения классов и методов.
    Ну вопрос еще решен не полностью. Мне еще много работать.[DOUBLEPOST=1455918298][/DOUBLEPOST]Вопрос решен. Я осилил рефлекцию для NBT block & stack
    Спасибо.
     
Статус темы:
Закрыта.

Поделиться этой страницей