Solved Extending CraftPlayer

Discussion in 'Plugin Development' started by _Filip, Jul 22, 2014.

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

    _Filip

    How would I extend CraftPlayer? It's implementation of Damageable makes it have conflicting return types. Thanks.
     
  2. Offline

    Garris0n

    Build against Bukkit.

    Edit: Are you saying it's a problem with extending the class, or you're trying to extend the class to fix the problem? Because it sounds like the latter, but that doesn't make much sense.
     
  3. Offline

    _Filip

    Garris0n I am trying to extend the class.
     
  4. Offline

    Garris0n

    Why would you need to extend it?
     
  5. Offline

    _Filip

    Garris0n In order to create custom events that are not in the bukkit API, such as a ban event.

    Im just trying to proxy it.

    I read that you can fork bukkit, and compile, and it would still work. I am not sure if this would work though.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  6. Offline

    jthort

    TheSpherret Why not listen to the kick event then get the reason, that way you can decide if they were banned or not rather than creating a whole new event?
     
  7. Offline

    _Filip

    jthort Because any plugin can change the kick reason?
     
  8. Offline

    jthort

    TheSpherret Then read it according to what you changed it too?

    Edit: I guess I see your point now, I really don't know I've tried extending the class before also. I would be interested in how you figure this out
     
  9. Offline

    _Filip

    jthort I think the compilation will work if I use maven for it. I will try in a few hours. I will get back to you.
     
  10. Offline

    jthort

    You could also create your own player object then cast all the players to that object, so for example
    Code:
    MyPlayer myPlayer = (MYPlayer) player;
    Then just insert your code inside the myPlayer class, that's how I solved it
     
  11. Offline

    thecrystalflame


    How would maven solve that error?..
     
  12. Offline

    Wingzzz

    Gonna be completely honest, you have no need to extend CraftPlayer. Simply create a wrapper class such as CustomPlayer that holds a UUID and(or) name in order to do a Player lookup with Bukkit.getPlayer(uuid/name) if you need them. This way all you need to do is store the players on join, and remove them on quit, then you can manually fire your custom events and pass in your new CustomPlayer object and since it's a different event altogether other plugins shouldn't really mess with it especially if the plugin is private.
     
  13. Offline

    PandazNWafflez

    TheSpherret If you want to extend CraftPlayer and put your own methods in, then replace all the CraftPlayer objects on the server with objects of your CraftPlayer extension, you would need to follow a few steps.
    1. Build against craftbukkit, not bukkit
    2. Create your class extending CraftPlayer and edit it to your liking
    3. Use reflection to modify the stored player objects within Bukkit into your objects.
    In order to replace the Bukkit entity with your new player object, the code would look like this.
    Code:java
    1. CraftPlayer cp = (CraftPlayer) bukkitPlayer;
    2. EntityPlayer ep = cp.getHandle();
    3.  
    4. Field bukkitEntity;
    5. try {
    6. bukkitEntity = Entity.class.getDeclaredField("bukkitEntity");
    7. bukkitEntity.setAccessible(true);
    8. org.bukkit.entity.Entity e = (org.bukkit.entity.Entity) bukkitEntity.get(ep);
    9. if (e == null || !(e.getClass().equals(MyPlayerObject.class)) {
    10. bukkitEntity.set(ep, new MyPlayerObject((CraftServer) Bukkit.getServer(), ep));
    11. }
    12. } catch (Exception e) {
    13. e.printStackTrace();
    14. }


    (Code slightly modified version of SpoutPlugin's method to be less specific to SpoutPlugin's system)
     
  14. Offline

    Garris0n

    For the record, you wouldn't want to watch setBanned() for a ban event as it's outdated and has been replaced by a new system.
     
  15. Offline

    jthort

    PandazNWafflez Wingzzz All of these guys are with me, it seems like the simplest way is what we all suggested. The only annoying thing is that you have to keep casting the Player to MyPlayer
     
  16. Offline

    PandazNWafflez

    jthort It's not exactly hard.... Especially if you create a variable when you are using it.
     
  17. Offline

    jthort

    I never said it was hard, it's just that your going to have to, as I said, cast it every time you need to use a method inside the MyPlayer class (AKA "create a new variable")

    Not only that, but this wasn't specifically what the OP wanted, but it works none the less.
     
  18. Offline

    PandazNWafflez

    jthort Wait, what did the OP want in that case? He asked how to extend CraftPlayer.
     
  19. Offline

    jthort

    Yeah, although we figured this out I would be interested in another way around this so you can directly use the Player object rather than creating yet another wrapper.

    A library would also be very interesting to create.
     
  20. Offline

    PandazNWafflez

    jthort If all you're doing is overriding existing methods, you don't actually have to cast it.

    If the MyPlayer object overrides getName() to just return "lol" it will still do that without casting the Player object to MyPlayer. The only time you need to cast it is to use new methods in the class, which seems incredibly pointless unless they are there to modify protected variables or similar.

    tl;dr most of the time you don't need to cast
     
  21. Offline

    jthort

    Yeah that's what I was saying
     
  22. Offline

    PandazNWafflez

    jthort You also mentioned that you wanted a way to just use the Player object.
    There's no way you can write NEW methods into the Player object unless you either:
    1. Modify Bukkit AND CraftBukkit OR
    2. Inject code using ASM or similar, which is much more hassle than just using a new object.
    So I assumed you meant existing methods, seeing as it would be completely implausible otherwise.
     
  23. Offline

    jthort

    PandazNWafflez No I meant what I said, I just didn't know if those two points are the only way. Thanks for clearing that up, I was asking if their was an alternative.

    Edit: If someone was to write a library that injects code, that would be modifying the jar file which is not allowed as far as I know
     
    PandazNWafflez likes this.
  24. Offline

    PandazNWafflez

    jthort likes this.
  25. Offline

    _Filip

  26. Offline

    PandazNWafflez

    TheSpherret Ah, I see. Did you try compiling with maven? I'd imagine that would work if you were to add their plugin that they created for this purpose to your project.
     
  27. Offline

    _LB

    There is no way to determine if or when a player has become banned. Any plugin can decide to suddenly kick a player and cancel their join events.
     
  28. Offline

    _Filip

    I am done.
    I will post the code on bitbucket.
    I am not very good at maven, but I figured it out, and have created a PlayerBanEvent.

    _LB I have never seen someone be so incorrect. CraftPlayer has an isBanned() method, which is made for the explicit purpose of checking if a player is banned.
     
  29. Offline

    _LB

    So if I make a plugin that cancels your player join event, what will that method return? ;p
     
  30. Offline

    _Filip

    _LB That is not a ban though. That is cancelling the PlayerJoinEvent.
    A ban is when the player is added to the GameProfileBanList.
     
Thread Status:
Not open for further replies.

Share This Page