Can you make a second recipient list for chat events?

Discussion in 'Plugin Development' started by TechBug2012, Jan 30, 2016.

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

    teej107

    @TechBug2012 First of all, what are the sentences you are testing like? Because the first String argument you are passing in your replace method would be bypassed like this:
    The underlined word being the one to censor.
     
    Last edited: Feb 14, 2016
  2. Offline

    TechBug2012

    @teej107 Yes! Thanks for pointing that out! I was testing simple sentences like "You're a noob"... but there's no space after "noob" in that sentence. I removed the spaces in the code and it works!

    So, now that this 60-comment long thread is finally resolved, I had another question in the back of my mind. How do I set the number of stars to match the length of the banned word?
     
    Last edited: Feb 15, 2016
  3. Offline

    teej107

    @TechBug2012 Count the number of characters in the banned word. Then create a new String appending a star for each character in the word. You can do this by using a StringBuilder or a more simple solution would to use
    StringUtils.repeat() from the ApacheCommons library. It is already packed in with the Bukkit API.
     
  4. Offline

    TechBug2012

    @teej107
    False alarm. The server throws a ConcurrentModificationException.
    Code:
            Iterator<Player> it = event.getRecipients().iterator();
            while (it.hasNext()) {
                Player p = it.next();
                if (usernameList.contains(p.getName())) {
                    event.getRecipients().remove(p);
                    filteredPlayers.add(p);
                }
            }
    
    Show Spoiler
    14.02 22:13:09 [Server] INFO ... 11 more 14.02 22:13:09 [Server] INFO at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_72] 14.02 22:13:09 [Server] INFO at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_72] 14.02 22:13:09 [Server] INFO at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) ~[?:?] 14.02 22:13:09 [Server] INFO at net.extrillius.sweartoggle.SwearToggle.onChat(SwearToggle.java:78) ~[?:?] 14.02 22:13:09 [Server] INFO at java.util.HashMap$KeyIterator.next(Unknown Source) ~[?:1.7.0_72] 14.02 22:13:09 [Server] INFO at java.util.HashMap$HashIterator.nextEntry(Unknown Source) ~[?:1.7.0_72] 14.02 22:13:09 [Server] INFO Caused by: java.util.ConcurrentModificationException 14.02 22:13:09 [Server] INFO at java.lang.Thread.run(Unknown Source) [?:1.7.0_72] 14.02 22:13:09 [Server] INFO at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.7.0_72] 14.02 22:13:09 [Server] INFO at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.7.0_72] 14.02 22:13:09 [Server] INFO at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.7.0_72] 14.02 22:13:09 [Server] INFO at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.7.0_72] 14.02 22:13:09 [Server] INFO at net.minecraft.server.v1_8_R3.PacketPlayInChat$1.run(PacketPlayInChat.java:39) [Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:1022) [Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at net.minecraft.server.v1_8_R3.PlayerConnection.chat(PlayerConnection.java:1084) [Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:484) [Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[Spigot188.jar:git-Spigot-db6de12-d3e0b6f] 14.02 22:13:09 [Server] INFO org.bukkit.event.EventException 14.02 22:13:09 [Server] ERROR Could not pass event AsyncPlayerChatEvent to SwearToggle v1.0


    Also, the loop to check the words is case-sensitive. If someone types "Kill" with a capital K, it won't censor. How do I fix that?
     
  5. Offline

    WolfMage1

    Using .equals: use .equalsIgnoreCase
    Seeing if a list contains a word: Force the message to upper/lower case then see if it contains it.
     
  6. Offline

    TechBug2012

    Where am I using .equals? I'm looping through the words.
    How do I send it normally if I force it to lower case? Should I introduce a temporary filteredMessage String?
     
  7. Offline

    WolfMage1

    Code:
    String myUpperCaseString = word.toUpperCase();
    if(myListOfWords.contains(myUpperCaseString){
        //what you want to do.
    }
    @TechBug2012
     
  8. Offline

    TechBug2012

    Code:
        @EventHandler
        public void onChat(AsyncPlayerChatEvent event) {
            Set<Player> filteredPlayers = new HashSet<>();
            String newMessage = event.getMessage();
            for (String word : wordList) {
                String filteredWord = word.toLowerCase();
                if (wordList.contains(filteredWord)) {
                    newMessage = newMessage.replace(word, "****");
                }
            }
    
    This doesn't work. What did I do wrong?
     
  9. Offline

    WolfMage1

    are the words in lower case in your list?
     
  10. Offline

    TechBug2012

    @WolfMage1
    Yes.
    Code:
    banned-words:
      - noob
      - kill
    
     
  11. Offline

    teej107

    You'll need to split the message and compare each word with each banned word with equalsIgnoreCase.
     
  12. Offline

    TechBug2012

    Code:
            for (String word : wordList) {
                if (newMessage.split(" ").toString().contains(word)) {
                    newMessage = newMessage.replace(word, "****");
                }
            }
    
    Like this?

    Also, something's wrong with the iterator if a ConcurrentModificationException is thrown, but I don't know what.
     
    Last edited: Feb 15, 2016
  13. Offline

    teej107

  14. Offline

    TechBug2012

    @teej107
    Then how do I get the data from .split? Should I introduce a filteredWord variable?

    And what's wrong with the iterator if the console sometimes throws a ConcurrentModificationException and sometimes it doesn't?
     
  15. Offline

    teej107

    This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
    This most commonly happens when removing from the Collection while iterating over it. You should remove from the Iterator because you actually have declared one and are somewhat using it AND it'll fix this problem.

    The first problem it is better to split the String outside of the loop and create nested loops comparing the words. The second problem is you are splitting the String but then you are calling toString() on it again which was kind of counter productive especially since that value returned won't be what you expected.

    To make things A LOT more simple, let's just have StringUtils come to the rescue.
    https://commons.apache.org/proper/c...va.lang.CharSequence, java.lang.CharSequence)
     
  16. Offline

    TechBug2012

    So I've been looking at these docs and trying out some things, and I'm wondering why what I'm doing doesn't work. From my understanding, if I use containsIgnoreCase, the parameters should be (newMessage, word), because,

    Parameters:
    str - the CharSequence to check, may be null
    searchStr - the CharSequence to find, may be null

    So, then, why doesn't this work?
    Code:
            for (String word : wordList) {
                if (StringUtils.containsIgnoreCase(newMessage, word)) {
                    newMessage = newMessage.replace(word, "****");
                }
            }
    
     
  17. Offline

    teej107

  18. Offline

    TechBug2012

    That says to use (?i) inside the parentheses, but it only works with quotes.
    Code:
    newMessage = newMessage.replace(word, "****");
    So how would that work in this situation?

    Also, I made a pardoned-words list because words like glass are being censored. How can I fix this if statement? Or, basically, how do I tell it "don't censor"?
    Code:
                for (String pardoned : pardonedList) {
                    if (pardoned.contains(word)) {
                        break;
                    }
                }
    Main class updated: http://pastebin.com/WKf99TAA
    I'll try some rubber duck debugging, but maybe you can help along the way of my rubber duck debugging.
     
  19. Offline

    teej107

    @TechBug2012 Word censoring plugins will always get bypassed or else you'll start to get unplanned restrictions like glass.
    The simple and best way is to split the String by spaces and replace each banned word with the censoring in the array returned. Then you append each String in the array into a single String again.
     
Thread Status:
Not open for further replies.

Share This Page