Reflection help

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

  1. 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?)
     
  2. 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.
     

Share This Page