Solved AsyncChat message changes made by low priority listener not reciprocated in higher priority listener

Discussion in 'Spigot Plugin Development' started by dordsor21, Sep 13, 2017.

  1. I edit an AsyncPlayerChatEvent's message [ e.getMessage() and e.setMessage() ] on an EventPriority.LOWEST listener, however these changes are not reciprocated in another plugin using EventPriority.MONITOR with e.getMessage()

    By my understanding, listeners with MONITOR priority are run last (i.e. after the LOWEST priority listener). I logically assume that the changes made to the message should be continued into the message read by the MONITOR priority listener, however these changes simply aren't there.

    Is this supposed to be the case? Or should I see the changes to the Chat Message in the second plugin.
  2. You should see the changes to the chat message in the second plugin.

    Have you tried it on a server with no other plugins interfering? Have you made sure that you don't have any other chat event handlers in one of those two plugins interfering?
    Have you debugged that both even handlers are called and in which order they are called? And you can also print debug messages when you modify the chat message and the content of the chat message of the event after you have modified it. Inside both event handlers.

    Basically: Add a bunch of debug output everywhere, post your two event handlers and the debug output of one chat event.
  3. Thanks for the reply.

    I've not yet tried a server that is as clean as it can be (there's a number of dependencies required for both plugins). I'd done all that debug stuff, and the string being used in setMessage(String message) was definitely correct every time, and the way the message is picked up in the second plugin allows for instantaneous "testing" when sending a chat message.

    I've tried both LOWEST and HIGHEST priority for the first plugin (both are executed before MONITOR priority, by my understanding) and neither have worked, which would likely negate anything another plugin is doing. I'll give it a test tomorrow regardless.
  4. do you know this other plugin? If so try unregistering it's listener for testing purposes. Also, HIGHEST is run last and LOWEST is run first. HIGHEST is run last because that has the final say on what happens in the event
    • Agree Agree x 2
    • Informative Informative x 1
  5. Yeah that's what I thought, and then MONITOR is run last after HIGHEST. (The second plugin is on MONITOR).

    The second plugin basically gets the chat messages and sends them across a Lilypad Network. I see no reason why it shouldn't work other than there being a bug somewhere.

    Code (Text):

        @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
        public void onAsyncPlayerChat(AsyncPlayerChatEvent event) {

            Packet_CHATMESSAGE packet = handler.sendChatMessage(
                    String.format(event.getFormat(), event.getPlayer().getDisplayName(), -->event.getMessage()<--)

            //no need to send it on the server that it's sent from.
  6. Are you sure nothing else is changing your event and that your lowest event is called before the monitor one? Check it by send debug messages and check whether they have the right order. You could try to inject your own asyncplayerchat event to print debug stuff if set message is called.
  7. The issue is that the changes aren't being applied. It's simply regex for words with all caps and lowercase them. The messages being sent have these words as upper case still. I've tried lower-casing words on either LOWEST or HIGHEST priority, which both ought to be executed before MONITOR priority, however these changes are not reciprocated in the getMessage on MONITOR priority,
  8. But are you sure there isn't any other plugin that might be changing the format ? Add soem debug messages where you change the message to be sure it was changed like you wanted.
  9. But why would formatting the message change it back from uppercase words being replaced to lowercase? I've already said earlier that I did so, and it was setting the correct message.
  10. When i said "changing format" was talking about any plugin modifying the plugin at all, also the event MONITOR shouldn't modify the event neither cancel it.
    • Agree Agree x 1
  11. But anything modifying it won't change lowercase words back to uppercase, that's my point. Also it has to do so, as the chat messages are then sent across the network. If it's not cancelled very last by the MONITOR event then the chat message could get sent twice to the server it was sent from.
  12. Offtopic, but: The point of not modifying / cancelling the event at monitor priority is: If there is another plugin listening on monitor priority as well, there is no guarantee whether your plugin is run first, or that other one. Assume the other plugin is a 'chat logging' plugin, which logs all uncancelled chat events on monitor priority. Now, in case the logging plugin runs first, everything works fine. But in case your plugin's event handler runs first, no chat events get logged by that other plugin, because you cancelled the event. As there is no guarantee in the order of those event handlers (influenced by plugin name, load order, reload behavior, ..), you can't be sure that you don't break that other plugin.

    Between, why are you manually sending the chat message anyways? You could also modify the chat event recipients to match whatever players are supposed to receive the message, in your case probably the players which are on the same server and the same channel as the chatting player. You only need to manually send the chat message for players which are connected to other servers in your case.

    See BungeeCoordSuite-Chat as an example:
    Also notice how he separated the chat event handling into LOWEST and MONITOR priority: He modifies the recipients on lowest to give other plugins a chance to react to it, and broadcasts the message to other servers on monitor priority.
  13. It's a Lilypad network, so using similar techniques to Bungee isn't particularly ideal at all. Also I'm not editing recipients, I'm making any word that is all uppercase to be all lowercase, editing the message, and sending it on its merry way. The reason monitor priority is used, is so that the event is definately cancelled (else as I said, there'd be duplicate chat messages sent on the server from which the player sends the chat message) and chat is sync'd across the whole network, i.e. everyone on every server sees this chat message.

    All of this stuff has nothing to do with my original question, which is, why, when editing a chat message, the changes are not seen to be reciprocated in further getMessage() methods from subsequent AsyncPlayerChatListeners on higher priorities, which to me seems like a bug.

    It wouldn't make sense to be that a Listener inbetween should be able to detect the fact that I've editted the message, and set it back to the default message, further supporting the fact it's a bug.

    What I wanted to originally confirm was that default behaviour is supposed to be such that message edits in lower priority listeners are persistent through higher priority listeners. I was told that this is indeed the case, in which case there is a bug. If there is not indeed the case, then I will need to use a different method of removing all uppercase words.

    Edit: I apologise if I've not been concise enough in earlier explanations, only really just fully woken up for the day!
  14. Offtopic: It shouldn't matter whether you are using BungeeCoord or Lilypad: In the end you run bukkit plugins and you cancel the chat event on monitor priority, potentially breaking other bukkit plugins. If that is no issue for your server, great, but it might be an issue if this should end up in a public plugin.

    Regarding your original question:
    I just tried to reproduce your issue and wasn't able to. For me the chat message is propagated just like expected from the event handler at lowest to the event handler at monitor priority. So the issue has to be something else, specific to your setup.

    Code (Text):

    @EventHandler(priority = EventPriority.LOWEST)
    public void onChatLowest(AsyncPlayerChatEvent event) {
        System.out.println("Original message (lowest):" + event.getMessage());
       String newMessage = event.getMessage().replace("test", "*replaced-test*");
       System.out.println("Modified message:" + newMessage);
       System.out.println("Modified message from event:" + event.getMessage());

    @EventHandler(priority = EventPriority.MONITOR)
    public void onChatMonitor(AsyncPlayerChatEvent event) {
       System.out.println("Original message (monitor):" + event.getMessage());
    [14:30:39 INFO]: Original message (lowest):this is a test
    [14:30:39 INFO]: Modified message:this is a *replaced-test*
    [14:30:39 INFO]: Modified message from event:this is a *replaced-test*
    [14:30:39 INFO]: Original message (monitor):this is a *replaced-test*
    [14:30:39 INFO]: <ninety8> this is a *replaced-test*

    Have you debugged your event handlers in the same way already, making sure that you are actually modifying the chat message in the way you expect it to?
    #14 blablubbabc, Sep 14, 2017
    Last edited: Sep 14, 2017
  15. Sorry for delayed response, been very busy. I've now isolated the issue, and it's something completely different.

    Code (Text):
        @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
        public void onAsyncPlayerChat(AsyncPlayerChatEvent event) {
            String message = event.getMessage();
            Player p = event.getPlayer();
            if (message.startsWith("!") && p.hasPermission("lilypadchat.emphasis.staff")) {
                message = ChatColor.GOLD.toString() + message.substring(1, message.length());
            String chatMessage = String.format(event.getFormat(), p.getDisplayName(), message);
    is some example/testing code I was using (part of something I've not bothered to make work for a while).

    The issue here is with
    Code (Text):
    String chatMessage = String.format(event.getFormat(), p.getDisplayName(), message);

    The first debug outputs "[Admin] dordsor21: !debug" when I send "!debug" in chat. Is there therefore something I'm missing when it comes to chat format? I.e. is there no default format for chat.

    Edit: thinking of it, it wouldn't make sense for the to be a default format. I'll make it work with regex and the event.getFormat() ;)
    #15 dordsor21, Sep 19, 2017 at 1:21 AM
    Last edited: Sep 19, 2017 at 11:33 AM
  16. You're not setting the message to lower case anywhere, is there a different problem now ?
  17. No, the issue was that (this was also the case in the first instance of the monitor priority listener) Event.getFormat() returns the originaly, exact, message sent including prefix, name, etc as there is not a format used. This is logical. It's now fixed by using Event.setFormat() as well as Event.setMessage() with the edited chat message.
  18. So since the post is maked as solved there still an problem, what it is ?
  19. How do I mark the thread as solved? Please tell me that wasn't some crazy passive aggressive way of telling me to mark it as solved.

    Edit: found it.
  20. No, i mean i thought you still had a problem, good to know you fixed it.

Share This Page