Custom PM command!

Discussion in 'Plugin Development' started by ajs333, Nov 12, 2013.

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

    ajs333

    Xacero
    There is an error that whenever a player types /r in doesn't display the message...
     
  2. Offline

    Xacero

    ajs333
    Because you haven't been actually reading what the code does. You've just been copy pasting my code. There might be formatting errors, or you may have put something where it doesn't belong.

    I wrote the commands from scratch and am testing them now, will give you the source when I know it works. Please try and do some work yourself instead of copy pasting what I give you
     
  3. Offline

    ajs333

    Xacero
    I'm not just copying and pasting your code because I know for sure that some of it isn't necessary or I might change one thing but thank you for helping me and when you know it works please just tell me... Thanks
     
  4. Offline

    Xacero

    ajs333

    Code:java
    1.  
    2. if (cmd.getName().equalsIgnoreCase("msg")) {
    3. // pm send
    4. Player sender = (Player) send;
    5. if (args.length < 2) {
    6. sender.sendMessage("Format is /msg [target] [message]");
    7. return true;
    8. }
    9. Player target = Bukkit.getServer().getPlayer(args[0]);
    10. if (target == null) {
    11. sender.sendMessage("That person is offline!");
    12. return true;
    13. }
    14. reply_list.put(target.getName(), sender.getName());
    15. String message = "";
    16. for (int i = 1; i < args.length; i++) {
    17. message += args[I]; // don't forget the index![/I]
    18. [I]if (i != (args.length - 1))[/I]
    19. [I]message += " ";[/I]
    20. [I]}[/I]
    21. [I]target.sendMessage("[" + sender.getName() + "] " + message);[/I]
    22. [I]sender.sendMessage("[" + sender.getName() + " -> " + target.getName() + "] " + message);[/I]
    23. [I]return true;[/I]
    24. [I]}[/I]
    25.  
    26. [I]if (cmd.getName().equalsIgnoreCase("reply")) {[/I]
    27. [I]// reply to pm[/I]
    28. [I]Player sender = (Player) send;[/I]
    29.  
    30. [I]if (args.length < 1) {[/I]
    31. [I]sender.sendMessage("You need to send a message!");[/I]
    32. [I]return true;[/I]
    33. [I]}[/I]
    34.  
    35. [I]if (!reply_list.containsKey(sender.getName())) {[/I]
    36. [I]sender.sendMessage("Nobody has messaged you.");[/I]
    37. [I]return true;[/I]
    38. [I]}[/I]
    39. [I]Player target = Bukkit.getServer().getPlayer(reply_list.get(sender.getName()));[/I]
    40. [I]if (target == null) {[/I]
    41. [I]sender.sendMessage("That player is offline");[/I]
    42. [I]return true;[/I]
    43. [I]}[/I]
    44.  
    45. [I]String message = "";[/I]
    46. [I]for (int i = 0; i < args.length; i++) {[/I]
    47. [I]message += args[I];[/I][/I]
    48. [I]if (i != (args.length - 1))[/I]
    49. [I]message += " ";[/I]
    50. [I]}[/I]
    51.  
    52. [I]target.sendMessage("[" + sender.getName() + "] " + message);[/I]
    53. [I]sender.sendMessage("[" + sender.getName() + " -> " + target.getName() + "] " + message);[/I]
    54. [I]return true;[/I]
    55. [I]}[/I]
    56. [I][/I]


    This is what all I've given you so far should look like. (complete with null checks for all target players to make sure they're online , and all checks to make sure that there IS a player to reply to.)

    Proof it works.

    [​IMG]

    Edit - Code is formatting wierd and including all those tags, not sure why... Just look at how it's done and you should be good :)

    Edit 2 - Nevermind!

    elementalgodz11

    Oh, thanks! That's strange - I don't see why it'd be in italics in the first place ._.

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

    ajs333

    Xacero
    Do I need this part? Player sender = (Player) send;
     
  6. Offline

    Xacero

    elementalgodz11

    Code:java
    1. public boolean onCommand(CommandSender send, Command cmd, String lbl, String[] args)


    This is the rest of the class. I actually made a new standalone project just for this .

    ajs333
    You can rename the CommandSender variable to sender instead and remove that variable all together.
    Look at what it's doing and how it's doing it, don't take it word for word :p Things like that are only relevant to my implementation. CommandSender also has a .sendMessage method so it'd work just fine. The reason I created a Player variable and cast the argument to it is for simplicity sake so you don't need to jump around to see where things came from.

    edit - also isn't /r a bukkit variable by default? You need to override that.
    PlayerCommandPreprocessEvent I think is what you want.
    You'll need to handle r in there instead, I think tell is also a pre registered command, though not sure. This may have been your problem.

    See my edit.
    r is not the name I gave in my demonstration, hence I didn't run into that problem.

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

    ajs333

    Xacero
    I'm getting mad because I can't fix my own issues... I feel so dumb asking you to fix everything....
    I yet again have another issue... When a player types /msg <name> <message> It never displays the message.
     
  8. Offline

    Xacero

    ajs333
    We've been over this, what does that mean? Is anything printed to console? Is anything sent to either the sender or recipient? Like I showed you, the snippet I sent you is guaranteed to work as-is, it's just up to you to implement it correctly.
     
  9. Offline

    ajs333

    Xacero
    Nothing is printed in the console and nothing is sent to either the player or the target player.
    I think the issue is the I used : publicboolean onCommand(CommandSender send, Command cmd, String lbl, String[] args) {

    instead of : publicboolean onCommand(final CommandSender sender, Command cmd, String commandLabel, final String[] args) {

    When I use the first one, nothing happens anywhere... and for the second one I get a lot of error in my coding...
     
  10. Offline

    Xacero

    elementalgodz11
    That actually describes how to do it...
    check if the command sent is the one you want to cancel, if it is event.setCancelled(true);
    // your code after that.

    ajs333
    You made CommandSender final and called it "sender" when they code assigns a new variable named "sender".
    You can't reassign a "final" value, but regardless, CommandSender shouldn't be final.

    Did you register the commands in your plugin.yml?

    elementalgodz11
    I don't know how to make it any clearer.

    YOU CAN NOT USE THE COMMAND "R" IN YOUR ONCOMMAND METHOD, IT IS PREREGISTERED BY BUKKIT!

    YOU NEED TO OVERRIDE IT USING THE EVENT PLAYERCOMMANDPREPROCESSEVENT

    OTHERWISE IT WILL EXECUTE THE BUKKIT COMMAND AND YOUR CODE WILL NEVER SEE THE LIGHT OF DAY.

    THERE IS NO OTHER WAY AROUND THIS.

    elementalgodz11
    iirc getMessage returns the command without the slash, also you don't want to disable it .. If you disable it all together your command wont execute either .. Adapt the command code to that method, and at the end of your execution cancel the event. Remove the old command code

    Please familiarize yourself with what that event actually does - or just rename your command from r - reply .

    ajs333
    Please rename the title and remove the solved tag, it's clear this isn't solved .

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

    ajs333

    Xacero
    Yea, I did... but still nothing happens on those commands... (Absolutely nothing...)
     
  12. Offline

    Xacero

    ajs333

    Then I will need you to post the relevant method. You aren't giving me enough information to help you .

    elementalgodz11
    I will use my original working example to tell you what the commands do.

    msg - Sends a message to specified player
    reply - Sends message to last person that used /msg [yourname], if nobody has used that it will say "You have nobody to reply to".

    My example worked. I wrote it from scratch, tested for errors, provided screenshot proof that it is working . I don't know what else to tell you.

    Adapt my code to work for you or consider familiarizing yourself better with how Bukkit works.

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

    ajs333

    Xacero
    Here is what I have done. Please note that I didn't change anything because you said it should work...

    Code:
    package sEssentialsCommands;
     
    import java.util.HashMap;
     
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
     
    public class CommandPrivateMessage implements CommandExecutor {
     
        HashMap<String, String> reply_list = new HashMap<String, String>();
     
        public boolean onCommand(CommandSender send, Command cmd, String lbl, String[] args) {
     
            if (cmd.getName().equalsIgnoreCase("msg")) {
             
                Player sender = (Player) send;
                    if (args.length < 2) {
                        sender.sendMessage("Format is /msg [target] [message]");
                        return true;
                }
                Player target = Bukkit.getServer().getPlayer(args[0]);
                    if (target == null) {
                        sender.sendMessage("That person is offline!");
                        return true;
                }
                if (!reply_list.containsKey(target.getName()))
                    reply_list.put(target.getName(), sender.getName());
                    String message = "";
                    for (int i = 1; i < args.length; i++) {
                        message += args;
                        if (i != (args.length - 1))
                            message += " ";
                    }
                target.sendMessage("[" + sender.getName() + "] " + message);
                sender.sendMessage("[" + sender.getName() + " -> " + target.getName() + "] " + message);
                                return true;
                }
             
            if (cmd.getName().equalsIgnoreCase("reply")) {
     
                Player sender = (Player) send;
             
                    if (args.length < 1) {
                        sender.sendMessage("You need to send a message!");
                        return true;
                    }
             
                if (!reply_list.containsKey(sender.getName())) {
                    sender.sendMessage("Nobody has messaged you.");
                        return true;
                    }
                Player target = Bukkit.getServer().getPlayer(reply_list.get(sender.getName()));
                    if (target == null) {
                        sender.sendMessage("That player is offline");
                        return true;
                    }
             
                String message = "";
                    for (int i = 0; i < args.length; i++) {
                        message += args;
                        if (i != (args.length - 1))
                            message += " ";
                }
             
                target.sendMessage("[" + sender.getName() + "] " + message);
                sender.sendMessage("[" + sender.getName() + " -> " + target.getName() + "] " + message);
                        return true;
                }
            return false;
        }
    }
    
     
  14. Offline

    Xacero

    ajs333
    Are you registering the command executor?

    use @Override public boolean onCommand(...) to ensure that is what the method is called in CommandExecutor.
     
  15. Offline

    ajs333

    Xacero
    I know that everything is working and I added the @Override and still nothing happens...
     
  16. Offline

    Xacero

    ajs333
    Code:
    if (cmd.getName().equalsIgnoreCase("msg")) {
            System.out.println("COMMAND CALLED");
                Player sender = (Player) send;
                    if (args.length < 2) {
                        sender.sendMessage("Format is /msg [target] [message]");
                        return true;
                }
                Player target = Bukkit.getServer().getPlayer(args[0]);
                    if (target == null) {
                        sender.sendMessage("That person is offline!");
                        return true;
                }
                if (!reply_list.containsKey(target.getName()))
                    reply_list.put(target.getName(), sender.getName());
                    String message = "";
                    for (int i = 1; i < args.length; i++) {
                        message += args;
                        if (i != (args.length - 1))
                            message += " ";
                    }
                target.sendMessage("[" + sender.getName() + "] " + message);
                sender.sendMessage("[" + sender.getName() + " -> " + target.getName() + "] " + message);
                                return true;
                }
    check the console for "COMMAND CALLED" , is it there?

    elementalgodz11
    Code:java
    1. @EventHandler
    2. public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
    3. if ((event.getMessage().toLowerCase().startsWith("/ver")) || (event.getMessage().toLowerCase().startsWith("/?")) || (event.getMessage().toLowerCase().startsWith("/version")))
    4. }


    That if statement is incomplete, it doesn't do anything... And are you sure getMessage() returns the value WITH the "/" ? I'm pretty sure it doesnt.

    There are no errors in my example. It is almost stand-alone, I don't know what you're doing.

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

    ajs333

    Xacero
    Nope, there isn't "COMMAND CALLED"
     
  18. Offline

    Xacero

    ajs333
    Then you are registering the commandexecutor wrong. It is not a problem with what I gave you. Your method is never being called.
     
  19. Offline

    ajs333

    Xacero
    This is what I need right?

    Code:
    getCommand("msg").setExecutor(new CommandPrivateMessage());
            getCommand("relpy").setExecutor(new CommandPrivateMessage());
    and
    Code:
    public class CommandPrivateMessage implements CommandExecutor {
     
  20. Offline

    Xacero

    elementalgodz11
    Notice nowhere in my code do I even touch "/r"
    You are modifying what I wrote and then complaining when it stops working. That is not something I can control.

    As for the java.lang.string
    Code:java
    1. for (int i = 1; i < args.length; i++) {
    2. message += args[i]; // you forgot the index[/i]



    edit - Appears it got removed in one of my edits. Must have been something to do with the italics formatting messing up my code, sorry about that. Still, easy issue to fix if you're familiar with arrays

    ajs333
    Code:java
    1.  
    2. getCommand("msg").setExecutor(new CommandPrivateMessage());
    3. getCommand("relpy").setExecutor(new CommandPrivateMessage());
    4.  
    5.  


    "relpy" should probably be "reply".
    Where are you calling this method from? It should be from your onEnable method
     
  21. Offline

    afistofirony

    ajs333 The issue you are having is because you don't register player names vice-versa.

    Code:
    reply_list.put(target.getName(), sender.getName());
    reply_list.put(sender.getName(), target.getName());
    Also, read this, this is important.
    Your registering code won't work properly because it refers to two separate instances which hold separate data.

    Therefore, you need to use something like this:
    Code:
    CommandPrivateMessage message = new CommandPrivateMessage();
    getCommand("msg").setExecutor(message);
    getCommand("reply").setExecutor(message);
     
  22. Offline

    Xacero

    elementalgodz11
    Like I said, you forgot the index. Read my edit above.

    Also sorry, the code I posted had the index removed when I got rid of the italics. (it thinks it's an italics tag and removes it as well) , but this shouldn't have happened if you knew how to work arrays It's good practice to not copy paste the code but rather understand what it does and how it does it and recreate it yourself

    afistofirony
    Code:java
    1. reply_list.put(target.getName(), sender.getName());


    What are you talking about? This is as it should be.

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

    afistofirony

    Xacero The reason why his code isn't working is because when a player runs the command, the code doesn't register him as one of the people who has sent a message (and whom to). This means that if he uses /r without the target player responding, the HashMap containing the data doesn't have a reply reference available for the original sender.

    Here's some context.

    Current code:
    Code:
    afistofirony: /msg Player Hi!
    (code): ok, when Player uses /r, send the message to afistofirony
    afistofirony: /r Hello?
    (code): no key detected for afistofirony: He hasn't sent a message
    New code:
    Code:
    afistofirony: /msg Player Hi!
    (code): ok, when Player uses /r, send the message to afistofirony.
        When afistofirony uses /r, send the message to Player
    afistofirony: /r Hello?
    (code): key detected for afistofirony: Send message to Player
     
  24. Offline

    Xacero

    afistofirony
    on message it registers it as (target name, sender name)

    it reads as (player, last player to message him)

    I don't understand what you're saying.


    I clearly stated a couple pages back my command would only work if somebody messaged you first. if you'd like to have it also work with whoever YOU messaged last you'd need to fuse two different methods provided, which is what I think you've done.

    This thread was originally only about creating a pm command, not an reply command. I provided a rough example and a clear method of doing it.

    My code does what I said it would, I stand by what I wrote :p

    elementalgodz11

    The usage message is sent on return false, if that's what you meant
     
  25. Offline

    afistofirony

    Xacero In that case, you didn't meet the criteria given; he asked if you could also make it work when the targeted player doesn't respond :p

    EDIT: elementalgodz11 Return true, not false. If you return false, the usage message is shown.
     
  26. Offline

    Xacero

    elementalgodz11
    Oh if you'd like to display your own usage then

    if (args.length < 1)
    //display custom usage message
    return true;

    afistofirony



    I must have missed where, could you link me to the post? Last I heard of that was a few pages back and I said to merge what I did with what sparkzz did.

    The issue he is having now if I'm not mistaken is the msg command isn't being called at all.

    There is a no entry check in the reply command that would notify him of what you're saying.
     
  27. Offline

    ajs333

    I'm really confused now so can someone please help... I confused about everything...
     
  28. Offline

    Xacero

    ajs333
    Sorry, what is your current problem?
     
  29. Offline

    ajs333

    Xacero
    When a player types /msg <name> <message> or /reply nothing happens...
     
  30. Offline

    The_Doctor_123

    Wow! What a fast thread! Over 100 replies in 24 hours! I believe that's about 1 reply/12 minutes.
     
    MrSparkzz likes this.
Thread Status:
Not open for further replies.

Share This Page