Issue with de-capitalizing a message (1.11 spigot)

Discussion in 'Spigot Plugin Development' started by Sonacabon, May 29, 2017.

  1. Hello, so I have been having an issue with this code not functioning as intended.
    Everytime the code passes the first check it returns null instead of the wanted message and there don't seem to be any console errors
    Code (Text):

    public class Main extends JavaPlugin implements Listener{
        @Override
        public void onEnable(){
            getServer().getPluginManager().registerEvents(this, this);
        }
        @EventHandler
        public void onPlayerChat(AsyncPlayerChatEvent e){
            if(e.getMessage().length() >= 15){
                String newMsg = null;
                int Counter = 0;
                for(int i = 0; i < e.getMessage().toCharArray().length; i++){
                    if(String.valueOf(e.getMessage().charAt(i)).matches("[A-Z]"))
                        Counter++;
                }
                if(Counter >= 15){
                    ArrayList<String> arrayA = new ArrayList<String>();
                    ArrayList<Character> arrayC = new ArrayList<Character>();
                    for(int a = 0; a > e.getMessage().toCharArray().length; a++){
                        if((String.valueOf(e.getMessage().charAt(a)).equalsIgnoreCase(" ")) || (a == e.getMessage().toCharArray().length)){
                            String item = null;
                            for(int crea = 0; crea > arrayC.size(); crea++)
                                item += arrayC.get(crea);
                            arrayA.add(item);
                        }else{
                            arrayC.add(e.getMessage().charAt(a));
                            Bukkit.broadcastMessage(arrayC.toString());
                        }
                    }
                    List<Integer> ignoreArg = new ArrayList<Integer>();
                    for(int b = 0; b > arrayA.size(); b++){
                        if(Bukkit.getPlayer(arrayA.get(b)) != null)
                            ignoreArg.add(b);
                    }
                    for(int c = 0; c > arrayA.size(); c++){
                        if(!ignoreArg.contains(c))
                            newMsg += arrayA.get(c) + " ";
                        else{
                            if(c == 0){
                                StringBuilder last = new StringBuilder();
                                for(int d = 1; d > arrayA.get(c).toCharArray().length; d++){
                                    if(String.valueOf(arrayA.get(c).charAt(d)).matches("[A-Z]"))
                                        last.append(String.valueOf(arrayA.get(c).charAt(d)).toLowerCase());
                                }
                                newMsg += arrayA.get(c).charAt(0) + String.valueOf(last) + " ";
                            }
                            newMsg += arrayA.get(c).toLowerCase() + " ";
                        }
                    }
                    e.setMessage(newMsg);
                }
            }
        }
    }
     
     
  2. Where is it null?
     
  3. Choco

    Moderator

    There is so much going on in this that I can't even comprehend what you're trying to do in the first place. What's your goal? I'm sure this can be improved upon immensely as well as fix the issue you're having
     
    • Agree Agree x 1
  4. basically if the message has > 15 capitalized letters it will keep the first letter as it is (capitalized or not) then de-capitalize everything else while ignoring player names.

    if the message contains over 15 capital letters it just replaces the message by null.
     
  5. Bump, still need help with this.
     
  6. I will spoonfeed you because this was a bit interesting.
    Code (Text):

    private static final int CC_LIMIT = 15;
    /**
    * Uncapitalizes message if it contains more than CC_LIMIT capital characters keeping 1st character and all online player names preserved.
    * @param message - Message to process
    * @return - Uncapitalized message if it meets the requirement or original message.
    */
    public String uncapitalizeMessage(String message)
    {
       if(message.length() > CC_LIMIT &&
           message.chars().filter(Character::isUpperCase).count() > CC_LIMIT)
       {
         Set<char[]> onlinePlayers = Bukkit.getOnlinePlayers().stream().map(Player::getName).map(String::toCharArray).collect(Collectors.toSet());
         char[] buffer = message.toCharArray();
         boolean[] uncapitalizeChar = new boolean[buffer.length];
         char[] word = new char[17]; // Max player name is 16, we will use length 17 to indicate that this word isn't player name;
         int newWordIterator = 0;
         for(int i = 0; i < buffer.length; i++)
         {
           //System.out.println(i + " __ " + buffer.length);
           if(!Character.isWhitespace(buffer[i]))
           {
             // Start new word until next whitespace;
             if(newWordIterator < 17)
             {
               word[newWordIterator] = buffer[i];
               newWordIterator++;
             }
           }
         
           // If we encounter whitespace or end of message check the word we have
           if(Character.isWhitespace(buffer[i]) || i == buffer.length - 1)
           {
             // Check old word first
             if(newWordIterator > 0 && newWordIterator < 17)
             {
               char[] wordCheck = Arrays.copyOfRange(word, 0, newWordIterator);
               // Check if this word equals any player name;
               long collisions = onlinePlayers.stream().filter(name -> Arrays.equals(name, wordCheck)).count();
               // This word doesn't contain any player names;
               if(collisions == 0)
               {
                 // Fill boolean array with true for all letters of this word
                 for(int startIndex = i - newWordIterator; startIndex < i; startIndex++)
                 {
                   uncapitalizeChar[startIndex] = true;
                 }
               }
               // Reset word iterator
               newWordIterator = 0;
               word = new char[17];
               //Arrays.fill
             }
           }
         }
       
         // Decapitalize buffer now
         uncapitalizeChar[0] = false;
         for(int i = 0; i < buffer.length; i++)
         {
           if(uncapitalizeChar.length > i && uncapitalizeChar[i] == true)
           {
             buffer[i] = Character.toLowerCase(buffer[i]);
           }
         }
         return new String(buffer);
       }
       return message;
    }
     
     
    • Informative Informative x 1
  7. Sorry for the late reply, thanks but I have just tested out this code it doesn't actually work completely, if the character limit is passed regardless of what the message contains it set everything to lowercase excluding the first and final characters.
     
  8. Well, This worked for me. Hopefully it solves ur issue. :D
    Code (Text):
    public static String getDeCapitalized(String m) {
            char[] ArCh = m.toCharArray();
            int count = 0;
            for (char c : ArCh) {
                if (Character.isUpperCase(c))
                    count++;
            }
            if (count < 15)
                return null;
            StringBuilder s = new StringBuilder();
            for (char c : ArCh) {
                if (c == ArCh[0]) {
                    c =Character.toUpperCase(c);
                } else {
                    c =Character.toLowerCase(c);
                }
                s.append(c);
            }
            return s.toString();
        }
     
  9. Choco

    Moderator

    WordUtils#capitalizeFully(String, char...)
    Code (Java):
    WordUtils.capitalizeFully("THIS IS A TEST. THIS SHOULD TEST THINGS. SENTENCES ARE NICE", '.');
    // Results in
    "This is a test. This should test things. Sentences are nice"
    The delimiter(s) provided at the end of the method will tell the method which character to start the next capitalization at. By default, null, it will do it for every whitespace character, but providing a period will do it for every sentence

    As for finding the amount of capital letters in a String:
    Code (Java):
    Arrays.stream(yourMessage.toCharArray())
        .filter(c -> !Character.isWhitespace(c))
        .filter(c -> Character.isUpperCase(c))
        .count();
    I love when things can be done in just a few lines ^-^
     
    #9 Choco, May 31, 2017
    Last edited: May 31, 2017
    • Agree Agree x 1