Reflection errors

Discussion in 'Spigot Plugin Development' started by JackboyPlay, May 13, 2017.

  1. Hello, if I use reflection, I'll get some errors:
    Code (Text):

    [16:10:09] [Server thread/WARN]: java.lang.IllegalArgumentException: Can not set int field net.minecraft.server.v1_8_R1.PacketPlayOutNamedEntitySpawn.a to java.lang.Class
    [16:10:09] [Server thread/WARN]:     at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    [16:10:09] [Server thread/WARN]:     at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    [16:10:09] [Server thread/WARN]:     at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
    [16:10:09] [Server thread/WARN]:     at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:75)
    [16:10:09] [Server thread/WARN]:     at java.lang.reflect.Field.set(Field.java:764)
    [16:10:09] [Server thread/WARN]:     at me.JackboyPlay.Quake.Mechaniken.Reflection.setValue(Reflection.java:25)
    [16:10:09] [Server thread/WARN]:     at me.JackboyPlay.Quake.Mechaniken.Tops.sendNPCS(Tops.java:68)
    [16:10:09] [Server thread/WARN]:     at me.JackboyPlay.Quake.Listener.PlayerJoin.onJoin(PlayerJoin.java:33)
    [16:10:09] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [16:10:09] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    [16:10:09] [Server thread/WARN]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [16:10:09] [Server thread/WARN]:     at java.lang.reflect.Method.invoke(Method.java:498)
    [16:10:09] [Server thread/WARN]:     at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:301)
    [16:10:09] [Server thread/WARN]:     at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    [16:10:09] [Server thread/WARN]:     at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502)
    [16:10:09] [Server thread/WARN]:     at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.PlayerList.onPlayerJoin(PlayerList.java:272)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.PlayerList.a(PlayerList.java:156)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.LoginListener.b(LoginListener.java:109)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.LoginListener.c(LoginListener.java:41)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.NetworkManager.a(NetworkManager.java:159)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.ServerConnection.c(ServerConnection.java:82)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:800)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:316)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:634)
    [16:10:09] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:537)
    [16:10:09] [Server thread/WARN]:     at java.lang.Thread.run(Thread.java:745)

    //And so on.... for each field
     
    Code:
    PHP:

    public class Reflection {

        public static Class<?> getClass(String claz) {
            try {
                return Class.forName(Quake.getReflectionVersion() + "." + claz);
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();
            }
            return null;
        }
       
        public static void setValue(String field, Class<?> clazz, Object value){
            try {
                Field feld = clazz.getDeclaredField(field);
                feld.setAccessible(true);
                feld.set(clazz, value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
       
        public static Object getValue(String field, Object clazz){
            try {
                Field feld = clazz.getClass().getDeclaredField(field);
                feld.setAccessible(true);
                return feld.get(field);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
       
        public static Method getMethod(String method, Class<?> clazz, Class<?>... args){
            try {
                return clazz.getMethod(method, args);
            } catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }

    }

    public class Tops {
       
        public static void sendNPCS(Player player, Location loc, String name, ItemStack item){
            Class<?> clazz = Reflection.getClass("PacketPlayOutNamedEntitySpawn");
            //Generieren der EntityID
            Random rand = new Random();
            int r = rand.nextInt(10000 - 5000) + 10000;
            Reflection.setValue("a", clazz, r); //EntityID
            try {
                Reflection.setValue("b", clazz, GameProfileBuilder(name));
            } catch (IOException e1) {
                e1.printStackTrace();
            } //Gameprofile
            Reflection.setValue("c", clazz, loc.getX()); //X
            Reflection.setValue("d", clazz, loc.getY()); //Y
            Reflection.setValue("e", clazz, loc.getZ()); //Z
            Reflection.setValue("f", clazz, loc.getYaw()); //Yaw
            Reflection.setValue("g", clazz, loc.getPitch()); //Pitch
            Reflection.setValue("h", clazz, item); //Handitem
            Class<?> datawatcher = Reflection.getClass("DataWatcher");
            Method m = Reflection.getMethod("a", datawatcher, int.class, Object.class);
            try {
                m.invoke(datawatcher, 6, 20F);
                m.invoke(datawatcher, 10, (byte) 127);
            } catch (Exception e){
                e.printStackTrace();
            }
            Reflection.setValue("i", clazz, datawatcher); //Datawatcher
            try {
                Reflection.sendPacket(player, clazz);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
     
     
  2. Basically you also need to pass the instance when setting the value:
    Code (Java):

        //Add instance parameter
        public static void setValue(String field, Class<?> clazz, Object instance, Object value){
            try {
                Field feld = clazz.getDeclaredField(field);
                feld.setAccessible(true);
                feld.set(instance, value); //Change clazz to instance
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
    Or you can just use the Object.getClass() method and have only 1 paremeter and not 2. I would define those methods in a static field so it works faster.
     
  3. This?
    PHP:

    public static void setValue(String field, Class<?> clazz, Object value){
            try {
                Field feld = clazz.getDeclaredField(field);
                feld.setAccessible(true);
                feld.set(clazz.newInstance(), value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
     
  4. No ? You have to provide the instance of the class you want to modify with reflection. If it was an static field then you wouldn't have to, but in this case it isn't a static field so you have to use the instance of the class you want to modify.
     
  5. But clazz is the class, that I want to modify :D
     
    • Funny Funny x 1
  6. Yeah, but the class isn't an instance, you can't modify the value of an non-static field from just a class, you need an actual Object instance. So you need to pass the instance of the object you want to modify. If you don't know how to use Reflection you should search some tutorials before jumping in.
     
    #6 MaTaMoR_, May 13, 2017
    Last edited: May 13, 2017
  7. You need a better understanding of basic OOP principles. Different object instances have different values, so you need the object whose field value you want to set to be passed to Field#set
     
    • Agree Agree x 1
  8. I've tested a bit for myself without minecraft and realised a bit more, how it works.
    Now I found the error for myself :)
     
  9. Before doing ANYTHING with Minecraft/Bukkit/Spigot or even Reflection, learn Java and learn how OOP works.
    I have seen so many people asking questions here simply because they didn't take the time to learn Java and if everyone would just properly learn Java and OOP the amount of questions in this forum would be reduced significantly.
    You must learn Java and OOP first. After that, you can start experimenting with Minecraft and things like Reflection.
     
    • Agree Agree x 1
  10. I think it's my choice what I'm doing...

    I'Ve rewritten a bit the code to:
    PHP:

    public static void sendNPCS(Player player, Location loc, String name, ItemStack item) throws Exception{
            Class<?> claz = Reflection.getClass("PacketPlayOutNamedEntitySpawn");
            Object instanz = claz.newInstance();
            Class<?> clazz = instanz.getClass();
            //Generieren der EntityID
            Random rand = new Random();
            int r = rand.nextInt(10000 - 5000) + 10000;
            Reflection.setValue(instanz, "a", clazz.getClass(), r); //EntityID
            Reflection.setValue(instanz, "b", clazz.getClass(), GameProfileBuilder(name));
            Reflection.setValue(instanz, "c", clazz.getClass(), Reflection.MathHelperFloor(loc.getX() * 32.0D)); //X
            Reflection.setValue(instanz, "d", clazz.getClass(), Reflection.MathHelperFloor(loc.getX() * 32.0D)); //Y
            Reflection.setValue(instanz, "e", clazz.getClass(), Reflection.MathHelperFloor(loc.getX() * 32.0D)); //Z
            Reflection.setValue(instanz, "f", clazz.getClass(), (byte) ((int) (loc.getYaw() * 256.0F / 360.0F))); //Yaw
            Reflection.setValue(instanz, "g", clazz.getClass(), (byte) ((int) (loc.getPitch() * 256.0F / 360.0F))); //Pitch
            Reflection.setValue(instanz, "h", clazz.getClass(), item); //Handitem
            Object datawatcher = Reflection.getClass("DataWatcher").newInstance();
            Method m = Reflection.getMethod("a", datawatcher.getClass(), int.class, Object.class);
            m.invoke(datawatcher, "a", 6, (float) 20);
            m.invoke(datawatcher, "a", 10, (byte) 127);
            Reflection.setValue(instanz, "i", clazz.getClass(), datawatcher); //Datawatcher
            Reflection.sendPacket(player, clazz);
        }
     
    Now I'll get the following errors:
    Code (Text):

    [13:24:48] [Server thread/WARN]: java.lang.NoSuchFieldException: a
    [13:24:48] [Server thread/WARN]:     at java.lang.Class.getDeclaredField(Class.java:2070)
    [13:24:48] [Server thread/WARN]:     at me.JackboyPlay.Quake.Mechaniken.Reflection.setValue(Reflection.java:23)
    [13:24:48] [Server thread/WARN]:     at me.JackboyPlay.Quake.Mechaniken.Tops.sendNPCS(Tops.java:92)
    [13:24:48] [Server thread/WARN]:     at me.JackboyPlay.Quake.Listener.PlayerJoin.onJoin(PlayerJoin.java:34)
    [13:24:48] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [13:24:48] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    [13:24:48] [Server thread/WARN]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [13:24:48] [Server thread/WARN]:     at java.lang.reflect.Method.invoke(Method.java:498)
    [13:24:48] [Server thread/WARN]:     at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:301)
    [13:24:48] [Server thread/WARN]:     at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    [13:24:48] [Server thread/WARN]:     at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502)
    [13:24:48] [Server thread/WARN]:     at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.PlayerList.onPlayerJoin(PlayerList.java:272)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.PlayerList.a(PlayerList.java:156)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.LoginListener.b(LoginListener.java:109)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.LoginListener.c(LoginListener.java:41)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.NetworkManager.a(NetworkManager.java:159)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.ServerConnection.c(ServerConnection.java:82)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:800)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:316)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:634)
    [13:24:48] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:537)
    [13:24:48] [Server thread/WARN]:     at java.lang.Thread.run(Thread.java:745)
    //And ---
    [13:24:49] [Server thread/WARN]: java.lang.InstantiationException: net.minecraft.server.v1_8_R1.DataWatcher
    [13:24:49] [Server thread/WARN]:     at java.lang.Class.newInstance(Class.java:427)
    [13:24:49] [Server thread/WARN]:     at me.JackboyPlay.Quake.Mechaniken.Tops.sendNPCS(Tops.java:100)
    [13:24:49] [Server thread/WARN]:     at me.JackboyPlay.Quake.Listener.PlayerJoin.onJoin(PlayerJoin.java:34)
    [13:24:49] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [13:24:49] [Server thread/WARN]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    [13:24:49] [Server thread/WARN]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [13:24:49] [Server thread/WARN]:     at java.lang.reflect.Method.invoke(Method.java:498)
    [13:24:49] [Server thread/WARN]:     at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:301)
    [13:24:49] [Server thread/WARN]:     at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    [13:24:49] [Server thread/WARN]:     at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502)
    [13:24:49] [Server thread/WARN]:     at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.PlayerList.onPlayerJoin(PlayerList.java:272)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.PlayerList.a(PlayerList.java:156)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.LoginListener.b(LoginListener.java:109)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.LoginListener.c(LoginListener.java:41)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.NetworkManager.a(NetworkManager.java:159)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.ServerConnection.c(ServerConnection.java:82)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:800)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:316)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:634)
    [13:24:49] [Server thread/WARN]:     at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:537)
    [13:24:49] [Server thread/WARN]:     at java.lang.Thread.run(Thread.java:745)
    [13:24:49] [Server thread/WARN]: Caused by: java.lang.NoSuchMethodException: net.minecraft.server.v1_8_R1.DataWatcher.<init>()
    [13:24:49] [Server thread/WARN]:     at java.lang.Class.getConstructor0(Class.java:3082)
    [13:24:49] [Server thread/WARN]:     at java.lang.Class.newInstance(Class.java:412)
    [13:24:49] [Server thread/WARN]:     ... 21 more
     
    If you want to leave a bad comment like "learn ..." let it be...
     
    #10 JackboyPlay, May 13, 2017
    Last edited by a moderator: May 16, 2017
    • Funny Funny x 1
  11. Stop making new instances and set it on the object you need to change.
     
  12. Sorry, I'm to incompetent at the moment... First time that I'm using reflection in a plugin. I've made a few tests before with reflection (Not in a minecraft plugin). Can you explain it a bit more in detail for me? :D
     
  13. Why are you using reflection for packet manip? Just use the packet constructor, or ProtocolLib..

    Reflection as a method of bypassing version dependency is fundamentally flawed and a bad idea.
     
  14. I want to use it :)
     
  15. It just adds complexity, performance overhead and potentially breaks your plugin, for no reason..
     
  16.  
  17. You are calling #newInstance

    This will make a new instance of the object

    Anything you set on that instance is completely discarded anyhow because you aren't storing/saving it.

    You cannot send a Class<?> as a packet

    You need an instance of the Packet to begin with

    In order to modify that instance, that's where you use the Field#set calls

    You then send that instance of the packet

    Please learn some OOP principles and work on Java before working with spigot/bukkit: http://docs.oracle.com/javase/tutorial/java/index.html
     
    • Like Like x 1
  18. why are you using the php tag use the Java one
     
  19. How? xD

    Thank you!!!
     
    #19 JackboyPlay, May 15, 2017
    Last edited by a moderator: May 16, 2017
  20. Not here. If you don't even know how OOP works, nobody is going to use your plugins.