Preventing sendMessage

Discussion in 'Spigot Plugin Development' started by sirNikolas, Jun 6, 2017.

  1. So I know chat is handled well enough in AsyncPlayerChatEvent but I am wondering if there is an efficient way of blocking broadcasts for certain players?
    I don't believe there is a built event or easy access to the sendMessage methods, and currently the only hacky way I have is using ProtocolLib and listening for PacketType.Play.Server.CHAT, then preventing set player from receiving it if it doesn't contain a player name (which is chat). But there is an obvious caveat that if broadcasts contain player names then they get bypassed to the player. Also having to iterate over all online players to check if a name is in there is very inefficient especially as player count goes up. I don't believe the packet itself gives any notice if the message sent is from player of from plugin/server.

    Any ideas are welcome.
     
  2. If you only want specific players to not see the message, you could check to see if they have a permission and if they don't then just return.

    Here's an example from my ClearChat plugin:
    Code (Text):
    if (!player.hasPermission("cc.admin")) {
      for (Player players : Bukkit.getServer().getOnlinePlayers()) {
        for(int i = 0; i < getConfig().getInt("settings.lines_to_clear"); i++){
            players.sendMessage("");
         }
         Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("messages.chat_cleared").replace("%player%", player.getName())));
         return true;
           }
      } else {
        Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("messages.chat_cleared").replace("%player%", player.getName())));
        return true;
      }
    Not exactly sure if this is what you would be looking for, but you said any ideas are welcome. :p
     
  3. Not quite. What I'm looking for is to stop the sendMessage method from being sent to certain players from external plugins e.g) stopping an essentials broadcast (which I believe loops over players and does sendMessage rather than Bukkit.getServer().broadcastMessage(...)).

    Also I'm not sure if that's a full excerpt but it appears that it'll only work for one player anyway as your return in the if(){} is inside the for loop (as is the broadcast so it'll be spammed).
     
  4. Oh, I've never tried anything like that before, but perhaps you could use a try catch and listen for the broadcast (it that is even possible) and then use a return statement. Permissions might have to play a role in this method. If it is for specific players, then permissions would help.

    P.S. That is an excerpt and I think you may be on to something. I've only tested it by myself and don't have a public place to test it. It is supposed to spam players with blank messages, but I think that the for every player may broadcast the player cleared the chat more than once.
     
  5. Unfortunately there is no Event fired when any message is sent to a player, so you may have to catch Packets :(
     
  6. Yeah I agree but I was thinking maybe if I was looking at the wrong packet or if there was a different method in differentiating chat messages from messages from plugins.