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\$
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.

| improve this answer | |
\$\endgroup\$
  • 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\$ – Jonny Henly Oct 15 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 Oct 15 at 10:08
  • 2
    \$\begingroup\$ @JonnyHenly is it still a valid colour code though? \$\endgroup\$ – user253751 Oct 15 at 14:33
  • \$\begingroup\$ But the message is not coloured, therefore the method shall return false :) \$\endgroup\$ – monamona Oct 15 at 17:57
  • \$\begingroup\$ @monamona Then your method is wrong. It would return true for &a , &a&b, &a &b etc. \$\endgroup\$ – xehpuk Oct 15 at 18:29
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.

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Is there a typo? charAt[] vs. charAt() \$\endgroup\$ – slepic Oct 15 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\$ – Jonny Henly Oct 15 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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