[Tutorial] Updating player entities to 1.6

Discussion in 'Resources' started by Jogy34, Jul 2, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Jogy34

    I just finished updating the player entities in one of my plugins to 1.6 and I ran into really annoying problems which would throw errors that didn't make sense to me and didn't print out any useful information so I've decided to write this tutorial on what I did to get them to work in case other people are running into this problem.

    First of all after I updated the basic package calls and the changed methods, my server kept crashing and throwing the following error after everything has been enabled:
    Code:
    Exception in server tick loop
    java.lang.NullPointerException at net.minecraft.server.v1_6_R1
    at net.minecraft.server.v1_6_R1.EntityTrackerEntry.broadcastIncludingSelf(EntityTrackerEntry.java:273)
    at net.minecraft.server.v1_6_R1.EntityTrackerEntry.b(EntityTrackerEntry.java:245)
    at net.minecraft.server.v1_6_R1.EntityTrackerEntry.track(EntityTrackerEntry.java:171)
    at net.minecraft.server.v1_6_R1.EntityTracker.updatePlayers(EntityTracker.java:151)
    at net.minecraft.server.v1_6_R1.MinecraftServer.t(MinecraftServer.java:582)
    at net.minecraft.server.v1_6_R1.DedicatedServer.t(DedicatedServer.java:226)
    at net.minecraft.server.v1_6_R1.MinecraftServer.s(MinecraftServer.java:487)
    at net.minecraft.server.v1_6_R1.MinecraftServer.run(MinecraftServer.java:420)
    at net.minecraft.server.v1_6_R1.ThreadServerApplication.run(SourceFile:582)
    
    This led me to look at the code for the EntityTrackerEntry and it turns out that Players now have (or had but wasn't that important before) a PlayerConnection object that the EntityTrackerEntry uses. This object takes in a MinecraftServer, an INetworkManager, and an EntityPlayer. This doesn't seem like all that big of a deal but this variable isn't initialized in the super constructor of EntityPlayer and the NetworkManager takes in 5 obscure objects that I wasn't able to supply it. To fix this what I did was to create a SudoPlayerConnection and a SudoNetworkManager that are as follows:
    Code:java
    1.  
    2. public class SudoPlayerConnection extends PlayerConnection
    3. {
    4. public SudoPlayerConnection(EntityPlayer entityplayer)
    5. {
    6. super(MinecraftServer.getServer(), new SudoNetworkManager(), entityplayer);
    7. }
    8.  
    9. @Override
    10. public boolean a()
    11. {
    12. return true;
    13. }
    14.  
    15. @Override
    16. public void a(double d0, double d1, double d2, float f, float f1)
    17. {
    18. }
    19.  
    20. //A LOT of a(somePacket) methods went here
    21.  
    22. @Override
    23. public boolean b()
    24. {
    25. return false;
    26. }
    27.  
    28. @Override
    29. public CraftPlayer getPlayer()
    30. {
    31. return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
    32. }
    33.  
    34. @Override
    35. public void onUnhandledPacket(Packet packet) {}
    36.  
    37. @Override
    38. public void sendPacket(Packet arg0) {}
    39.  
    40. @Override
    41. public int lowPriorityCount()
    42. {
    43. return 0;
    44. }
    45. }
    46.  

    I was originally going to override every method in the PlayerConnection except I hadn't realized that there were upwards of 50 (estimating) methods that took in a specific packet. I believe the most important ones to override are onUnhandledPacket, sendPacket, and lowPriorityCount.
    Code:java
    1.  
    2. public class SudoNetworkManager implements INetworkManager
    3. {
    4. @Override
    5. public void a() {}
    6. @Override
    7. public void a(Connection arg0) {}
    8. @Override
    9. public void a(String arg0, Object... arg1){}
    10. @Override
    11. public void b() {}
    12. @Override
    13. public void d() {}
    14. @Override
    15. public int e()
    16. {
    17. return 0;
    18. }
    19. @Override
    20. public SocketAddress getSocketAddress()
    21. {
    22. return null;
    23. }
    24. @Override
    25. public void queue(Packet arg0) {}
    26. }
    27.  

    All of these methods came from the INetworkManager interface but the place it was crashing all the time was when the PlayerConnection called the a() method which interrupts two threads.
    After I had created those classes I just had to add this to my custom EntityPlayer's constructor:
    Code:
    playerConnection = new SudoPlayerConnection(this);
    //playerConnection is a variable of EntityPlayer
    
    At this point my custom player would show up except when I told it to look at something it's head wouldn't move. This was a simple fix that I did with guess and check. The previous variable that controlled this was 'aA' and it was just changed to 'aP'
    After this I ran into the problem that I could no longer change the player's name which I wanted to so that I could change the player's name. Unfortunately to fix this I had to use reflection to make the name variable accessible. Here's my code for that:
    Code:java
    1.  
    2. protected Field nameField;
    3. //in constructor
    4. try
    5. {
    6. nameField = EntityHuman.class.getDeclaredField("name");
    7. nameField.setAccessible(true);
    8. }
    9. catch (Exception e)
    10. {
    11. e.printStackTrace();
    12. }
    13. //My setName() method
    14. public void setName(String name)
    15. {
    16. try
    17. {
    18. nameField.set(this, name);
    19. }
    20. catch (Exception e)
    21. {
    22. e.printStackTrace();
    23. }
    24. }
    25.  

    I hope this helps.
     
Thread Status:
Not open for further replies.

Share This Page