Reflection help

Discussion in 'Plugin Development' started by CaptainBern, Sep 1, 2013.

  1. Online

    CaptainBern BukkitDev Staff

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    Hello,
    I'm trying to send packets using Reflection so my plugin will be version independant. (Don't suggest ProtocolLib please, It's an awesome lib, but I don't want to use it, don't ask why I don't want to use it)
    So what I did:
    Code:java
    1.  
    2. Object packet = ReflectionUtil.getClass("Packet40EntityMetadata"); //reflectionutil is just a little class that has a set of utils.
    3. //then set the values for the packet
    4. Field a = packet.getClass().getDeclaredField("a");
    5. a.setAccesible(true);
    6. a.set(packet, player.getEntityId());
    7.  


    Now as you all, or some of you know, this packet requires 2 params . a = the entityId and b = getDataWatcher().c();

    But I have no idea on how to set the 'b' field in the packet. I first need to invoke the "getDataWatcher" method and then, from within the datawatcher class invoke the "c" method and set that as the "b" field.
    I know, this is not very well explained so here is the github link: https://github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/Packet40EntityMetadata.java#L14

    Don't start asking "whats your packet send method?" or "How did you obtain the EntityPlayer?" because I know I'm doing those things right. The only think I need to know is how I can set the "b" field to the correct thing.

    Thanks.
    (Sorry @Icyene but since you're a reflection-pro? Mayeb you can help me?)

    This post has been edited 4 times. It was last edited by CaptainBern Sep 1, 2013.
  2. Offline

    Icyene

    dev.bukkit.org profile:
    CFUSERNAME
    My Plugins (CFCOUNT)
    Minecraft account:
    MCUSERNAME
    What you are doing is relatively simple. You already got part of it: you have the field reflection down. You just need to extend that knowledge to include methods, but its not a great leap.

    I put together a simple code snippet to illustrate what you are trying to do (providing I understood your question correctly):

    Code:Java
    1.  
    2. Object holder = ...; // This is the object that has the getDataWatcher method
    3. Object packetHandle = ...; // Reference to the packet you created
    4. Object watcherHandle = Reflection.declaredMethod("getDataWatcher").in(holder).invoke(); // This is a handle to the DataWatcher instance
    5. Object c = Reflection.declaredMethod("c").in(watcherHandle).invoke(); // Get the return value from the c method
    6. Reflection.field("b").in(packetHandle).set(c); // Set b to the gotten c
    7.  


    It uses a little one-file library I wrote a while back: ReflectionHelper, but the intent is clear and should be easy to separate from the helper class.

    If my code doesn't work, or I missed something or misunderstood the question, don't hesitate to tag me.

    This post has been edited 2 times. It was last edited by Icyene Sep 3, 2013.

Share This Page