4
\$\begingroup\$

I've written a simple util-method in my spigot plugin to check if a message contains a valid minecraft colour code. A valid minecraft colour code consists of a & followed by a hex digit: 0 to f. Minecraft itself exchanges all & by a §, for reasons that would take too long to explain, it's not possible for the users to send messages to the server directly. Therefore & is generally used as a replacement.

I now have to check at some point, if the message the user sent to the server is coloured, which is the reason this method exists. Here are some quick examples, how it does work:

string value - return value

"Simple String" - false
"Smith&Wesson" - false
"&4This would be red." - true
"%aGreen &2Darker Green &0 Darkest Green" - true
"&& Omega &&" - false

Here's my code. It does what it's supposed to do, but for some reason it still seems unneccesary clunky to me. Any improvement is welcome :)

    public static boolean isMessageColoured(String message) {
        char[] arr = message.toCharArray();
        for (int i = 0; i < message.length() - 2; i++) {
            if (arr[i] == '&' && "0123456789abcdef".contains(Character.toString(arr[i + 1]))) {
                return true;
            }
        }
        return false;
    }
\$\endgroup\$

2 Answers 2

8
\$\begingroup\$

Welcome to Code Review.

  • Your code returns false for the message "hello&9", because the method doesn't check the last character. Change the condition in the for-loop to message.length() - 1.

An alternative is to use a regular expression:

public static boolean isMessageColoured(String message) {
    return message.matches(".*&[a-f0-9].*");
}

This regular expression matches at least one occurrence of &[a-f0-9] in the message.

\$\endgroup\$
5
  • 4
    \$\begingroup\$ I think OP is saying that writing a message that includes &9 would mean every character after &9 would be displayed in the color that &9 represents, therefor ending a message with &9 wouldn't mean anything. \$\endgroup\$ Commented Oct 15, 2020 at 9:40
  • 1
    \$\begingroup\$ Exactly as @JonnyHenly said - everything after a colour code is displayed colourful. The codes themselves are not visible in the displayed message. But thanks for the suggestion with the regex :D \$\endgroup\$
    – monamona
    Commented Oct 15, 2020 at 10:08
  • \$\begingroup\$ But the message is not coloured, therefore the method shall return false :) \$\endgroup\$
    – monamona
    Commented Oct 15, 2020 at 17:57
  • \$\begingroup\$ @monamona Then your method is wrong. It would return true for &a , &a&b, &a &b etc. \$\endgroup\$
    – xehpuk
    Commented Oct 15, 2020 at 18:29
  • \$\begingroup\$ Those messages are actually considered to be coloured spaces ^^, and Indeed, combining two colour codes is also considered a valid message ^^ - also a coloured space ^^ \$\endgroup\$
    – monamona
    Commented Oct 15, 2020 at 18:48
6
\$\begingroup\$

There is no need to convert String to char[] array. Individual characters are accessible via String.charAt method.

There is also no need to explicitly spell out the hexadecimals. Consider Character.digit(message.charAt[i+1], 16) != -1.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Is there a typo? charAt[] vs. charAt() \$\endgroup\$
    – slepic
    Commented Oct 15, 2020 at 6:14
  • \$\begingroup\$ Is Character.digit(message.charAt(i + 1), 16) != -1 not bulky (a lot more going on than just Character.digit)? The way I see it, you're expecting an ASCII why not just stick with the char array and bounds check the index after '&' in the loop -- char next = arr[i+1]; if(arr[i] == '&' && (('0' <= next && next <= '9') || ('a' <= next && next <= 'f')) -- is there an upside or downside to doing it this way? \$\endgroup\$ Commented Oct 15, 2020 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.