public static bool HandlePM(string nick, string userNick, string rawMessage)
        {
            nick = nick.ToLower();
            if (!(rawMessage[0] == '@' || rawMessage.CaselessStarts(nick + " @")))
            {
                return(false);
            }
            if (DateTime.UtcNow.Subtract(lastIrcCommand).TotalSeconds <= 5)
            {
                return(true);
            }

            int start = rawMessage[0] == '@' ? 1 : nick.Length + 2;

            rawMessage = rawMessage.Substring(start);
            string[] parts = rawMessage.Split(trimChars, 2);
            if (parts.Length == 1)
            {
                IRC.SendChannelMessage("Please specify a message to send."); return(true);
            }
            string name = parts[0], contents = parts[1];

            // first, find ALL players (visible and hidden)
            Player[] matches = Server.FindPlayers(name, SearchOptions.IncludeHidden);

            // if there is more than 1 target player, exclude hidden players
            if (matches.Length > 1)
            {
                matches = Server.FindPlayers(name, SearchOptions.Default);
            }

            if (matches.Length == 1)
            {
                Player target = matches[0];
                if (target.Info.ReadIRC && !target.IsDeaf)
                {
                    Chat.IRCSendPM(userNick, target, contents);
                    lastIrcCommand = DateTime.UtcNow;
                }

                if (target.Info.IsHidden)
                {
                    // message was sent to a hidden player
                    IRC.SendChannelMessage("No players found matching \"" +
                                           Bold + name + Reset + "\"");
                    lastIrcCommand = DateTime.UtcNow;
                }
                else
                {
                    // message was sent normally
                    if (!target.Info.ReadIRC)
                    {
                        if (!target.Info.IsHidden)
                        {
                            IRC.SendChannelMessage("&WCannot PM " + Bold +
                                                   target.ClassyName + Reset +
                                                   "&W: they have IRC ignored.");
                        }
                    }
                    else if (target.IsDeaf)
                    {
                        IRC.SendChannelMessage("&WCannot PM " + Bold +
                                               target.ClassyName +
                                               Reset + "&W: they are currently deaf.");
                    }
                    else
                    {
                        IRC.SendChannelMessage("to " + Bold + target.Name + Reset + ": " +
                                               contents);
                    }
                    lastIrcCommand = DateTime.UtcNow;
                }
            }
            else if (matches.Length == 0)
            {
                IRC.SendChannelMessage("No players found matching \"" + Bold + name + Reset + "\"");
            }
            else
            {
                string list = matches.Take(15).JoinToString(", ", p => p.ClassyName);
                if (matches.Length > 15)
                {
                    IRC.SendChannelMessage("More than " + Bold + matches.Length + Reset +
                                           " players matched: " + list);
                }
                else
                {
                    IRC.SendChannelMessage("More than one player matched: " + list);
                }
                lastIrcCommand = DateTime.UtcNow;
            }
            return(true);
        }