Getting parts of a String

Discussion in 'Spigot Plugin Development' started by MrFishCakes, Feb 9, 2018.

  1. Hello,
    For my server, I want a message to be sent before a player is punished:
    • /ban Steeve Hacking (KillAura)
    • Messages sent: Click to confirm the ban for 'Steve' for the reason 'Hacking (KillAura)'
    • *Message clicked* & *Command Executed*
    However, I would be doing this via the PlayerCommandProcessEvent so if anyone could give me some direction it would be much appreciated!

    Thanks,
    MrFishCakes
     
  2. First you need to check if the messages starts with "/" then split with one space " " and get the args.
     
  3. Okay, how would I sort out the reason part as that needs to be a whole string?
     
  4. To split strings by words, use this:

    Code (Text):

    String str = "This is a short sentence";
    String[] words = str.split(" ");
     
     
  5. To get a String[] to a String, iterate over each element in the String[] and use a StringBuilder object to append the bit of a message to your string. Don't forget to add a " " character too.

    Sample:
    Code (Java):
    StringBuilder sb = new StringBuilder();
    for (String arg : args) {
       sb.append(arg).append(" ");
    }
    String finalString = sb.toString();
     
  6. Why do you even need this? Isn't it just a command? Cause if so then you can just use...
    Code (Text):
    if (args.length == 3) {
                        if (Bukkit.getPlayer(args[1]) != null) {
                            if (args[2].equalsIgnoreCase("Hacking")) {
                                String reason = args[3];
                            }
                        }
                    }
    But you would of course need to make an error message if the player is null or args[2] isn't "Hacking".
     
  7. To append more than 1 word in a ban message? Imagine "/ban McJeffr Hacking is not allowed by our policies.", you aren't going to manually get args[1] + args[2] + args[3] + args[4] + etc...

    I replied to
     
  8. I thought he was only looking for having 1 reason and not a whole string. Cause if so then it's also possible to just use...
    Code (Text):
    String message = "";
                                for (int i = 3; i < args.length; i++) {
                                    message += args[i] + " ";
                                }
                                message = message.trim();
    So the "reason" is the variable "message".
     
  9. So I recently made a message command, here's my code that iterates through all args after a certain arg (args[0] is the player, just read the code and try to figure out what it means)
    Code (Text):

    package com.lyzone.Test;

    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;

    import net.md_5.bungee.api.ChatColor;

    public class Message implements CommandExecutor {

        @SuppressWarnings("deprecation")
        @Override
        public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
            String cmd = command.getName();
            if (cmd.equalsIgnoreCase("msg")) {
                if (!(sender instanceof Player)) {
                    sender.sendMessage(ChatColor.GOLD + "You must be online to perform that command.");
                    return true;
                }
                if (args.length == 0) {
                    sender.sendMessage(ChatColor.GOLD + "You must specify a player and a message.");
                    return true;
                }
                if (args.length == 1) {
                    sender.sendMessage(ChatColor.GOLD + "You must specify a message.");
                    return true;
                }
                if (args.length >= 2) {
                    Player target = Bukkit.getServer().getPlayer(args[0]);
                    Player send = (Player) sender;
                    if (target == null || !(target.isOnline())) {
                        sender.sendMessage(ChatColor.GOLD + "Player not found.");
                        return true;
                    }
                    String msgFormat = ChatColor.DARK_GRAY.toString() + ChatColor.BOLD + send.getName() + ChatColor.GOLD
                            + " to " + ChatColor.DARK_GRAY.toString() + ChatColor.BOLD + target.getName()
                            + ChatColor.GOLD + " \u00BB ";
                    for (int i = 1; i < args.length; i++) {
                        msgFormat = msgFormat + args[i] + " ";
                    }
                    target.sendMessage(msgFormat);
                    sender.sendMessage(msgFormat);
                    return true;
                }
            }
            return true;
        }

    }
     
  10. I’m not sure of this is exactly what you want, but
    Code (Text):
    String.split("\\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
    may work. This should keep the reason as one argument. Eg, in /ban PiggyPiglet “pls don’t hack kthx”, “pls don’t hack kthx” would be one argument.

    Note: untested
     
    #10 PiggyPiglet, Feb 10, 2018
    Last edited: Feb 10, 2018
  11. Strahan

    Benefactor

    Personally, the way I'd do it is if the multi-word argument starts at, say, args[1] then I'd do String content = StringUtils.join(args, " ", 1, args.length);
     
  12. Yes and no. A String cannot be mutated. When you do String newString += args[e], you are actually making a completely new String. This isn't very effective, though it's on a small scale, concatenating strings using the + operator should be avoided if it's a lot. StringBuilder was made to solve this problem of assigning things and then immediately discarding them. I recommend you read a bit about how Strings exactly work in Java (and C#, for that matter) to learn how you can optimize your code a bit.

    The solution of @Strahan would be even easier.
     
  13. Dude I made it a year ago where I started coding and it was from an old tutorial. I will admit it's not the most effective way of doing it but it works. But okay that is just my solution to the problem. I don't say it's the best it was just what I could find in one of my old plugins.
     

Share This Page