[Urgent] How to assign a PlayerListener to CommandExecutor!

Discussion in 'Plugin Development' started by user_90599104, Sep 17, 2012.

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

    user_90599104

    Hello Bukkit community!
    Over the summer, I took some Java lessons to learn how to mod "Minecraft"! I have been playing this game since Alpha so I am not a noob...

    I am new to the "Bukkit" API so could you please help me? How do you assign a PlayerListener to a CommandExecutor... If you need my code, feel free to ask me. I am developing a Essentials like plugin BUT my own code; uses less CPU; and removes the useless junk that is not needed.

    Thank you very much for reading!

    ~Le Odie Six Cent Quatre-Vingts

    Really guys :( 6 views ._.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  2. Offline

    CorrieKay

    public class <yourclassname> implements Listener, CommandExecutor{
    //your class here.
    }

    You can use this class as both a command executor, and a listner.

    If you'd like, i can show you the superclass framework my essentials replacement uses :D
     
  3. Offline

    user_90599104

    Can you show me the framework that your essentials replacement uses... Not going to steal the code, just take a look at it to have a idea :p

    And I am using the PlayerListener for HashMaps. Could you show me a example? I have a seperate Main, CommandExecutor and Listener class so could you show me a small example?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
  4. Offline

    CorrieKay

    Sure, no problem! In fact, if you want, feel free to use the code as much as you want, as long as you give credit where credit is due!

    I should warn you however, that the plugin source i am about to show you is the result of learning java for an entire year. Its a tad messy, poorly documented, and it bypasses the bukkit api once or twice. anyways, heres how my it works:

    Github: This is the location of the plugin source code
    Mane: this is my main plugin class. everything starts from here.
    PSCmdExe: this is my command executor framwork i was talking about. Ill explain it in a little more detail afterwards.
    ConfigHandler: this is my abstract/static class that deals with grabbing player configuration files. All other configuration files however, (such as the permissions, various configs, etc) are grabbed by their known file path. (included because i know some people need additional configs, and how to write/create/save them)

    PSCmdExe
    As i stated before, this is the basic superclass framework i had set up for my plugin. I call the subclasses "Handlers" (not to be confused with the handlers that bukkit deals with)

    The superclass has a bunch of methods that assist the handlers in doing their job. the main focus however, are in the constructor, and two additional methods

    The Constructor:
    The constructor for the PSCmdExe takes three arguments. String name (what is the handlers name?), boolean listener (is it a listener? do we need to register it for listener methods?), and String[] cmds (any commands that we need to bind to this handler)

    The actual constructor for the handler does not need any parameters, just put whatever you need into the superconstructor. It looks like this

    public class Handler extends PSCmdExe{
    public Handler(){
    super("Handler Name", true, new String[]{"command1","command2"});
    }
    }
    this will register the handler as "Handler name", as a listener, with commands command1 and command2.

    You need to take note however, if you decide to register your listeners with the special way i did mine, that its not 100% bug free. it doesnt like registering two similar listeners, and you'll have to derp around to fix that, if need be. The reason i do my listeners like this, will be explained in the event method explination.

    Method 1: onCommand

    This method adds a sort of wrapper around the actual method i use to execute commands (handleCommand). It surrounds the method with a try/catch statement. The purpose of this is purely for development and debug issues. Basically, it will catch any uncaught exceptions that occur in your command exection, and then it will log them. pretty cool, imo. It logs who executed the command, what they were trying to do, and what exception occured, plus the stack trace pointing to the line. I love this!

    So how do you actually execute a command? by overriding the handleCommand method.

    @Override
    public boolean handleCommand(CommandSender sender, Command cmd, String label, String[] args){
    //TODO handle your command
    }
    Simple!

    Method 2: execute

    This method is where all of your events go to get processed. I dont personally know your level of java, but judging that you started learning during the summer, it may be just a little over your head. But hey, thats what learning is all about right?

    This method works in tandem with something called "Reflection". Basically, think of reflection as java coding, but in the meta sense. Classes, methods, and the actual fields (not the values of the variables) are objects themselves. Back in the constructor, we registered the listener methods. Basically, we stuck them in a hashmap with a key of the event class type, and a value of the method that is listening to that event. Pretty snazzy, if i do say so myself.

    Now, when the event is called, it goes into the execute method. The event is passed in, and we grab the method by the events class type. Then we take the method, use a method called "invoke" (which is basically a method that calls the method, lol) and we pass in the listener first, which is the object that has the method that we wish to use, and then we pass in the event. (note: the event is passed into it as an event class, however, it doesnt throw an exception for not being the right parameter type, because it IS the right parameter type. its a fragile system at first glance, but it works flawlessly, hasnt failed me yet, and i use this class over about 15-20 handlers, all running at the same time on a midsized production server :p)

    This invokes the method of the subclass/handler that is listening for the event.

    Please note, that there are some bugs i have yet to work out with this code, for instance: Lets say you need to listen to two events. EntityDamageEvent, and EntityDamageByEntityEvent. the EDBEE event extends the EDE event. To my register event method, these are completely seperate methods, and have nothing to do with eachother. Unfortunately, when you register with bukkit, it thinks youre asking for EDE and EDBEE for the EDE event, and the EDBEE event for the EDBEE method. This results in some issues, and even more. again, for instance, lets say you have JUST the EDE listener method. It will pass in the EDBEE event type into execute(). But because the hashmap containing the listener methods doesnt contain a key of the EDBEE class type, it returns a null method. The counter to this that i have found, is by manually adding the classtype to the method hashmap, like so.


    FINALLY

    I know its a lot to take in at once, but i do believe that this is a very awesome tool to use. Again, feel free to use it (you'll need to create your own, as this one is proprietary and has methods you wont need/cant use) or to ignore it. But it can hopefully give you some ideas!

    do you mean you need to be able to use the hashmap outside of the player listener?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 28, 2016
    user_90599104 likes this.
  5. Offline

    user_90599104

    Let me make this straight:
    I am making a plugin with my Command-Executor with its separate class. I am coding a command where it uses a Hash Map. So I made a new class: Player Listener. So now I got these classes':
    1- Main
    2- Command-Executor
    3- Player Listener
    I am putting the command that I want to use in Command Executor and I want to make it use the Player Listener from the Command Executor.
    I already tried using the Player Listener from the main class (it worked) but I like being organized so I am making a separate class for the commands.
    Thank you for your time!
    ~Odie680
     
  6. Offline

    user_90599104

    Le -Sigh- :'(
    I will give the person who solves this 1000 [cake] =3
     
  7. Offline

    XbannisherX

    okay, so you want it like this?
    1: player does command
    2: with that command he activates a listener
    3: profit
     
  8. Offline

    user_90599104

    Close, I have seperate class files for each of commands.
    I have a class called PlayerListener for the eventhandler (hashmap)
    I want to point the PlayerListener in each of the command classes.
    If possible, may you please make a mini example using PasiteBin?
    Thank you! Ill give you 1 cake for now :p [cake]

    I am just going to eat the 999 cakes my self ._. [cake] I am going to be a fatty =3

    998 cakes left.

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

    CorrieKay

    Well if it worked, why dont you just use that method?

    An alternative way to do this is to hold a static instance of the listener in the class field
     
Thread Status:
Not open for further replies.

Share This Page