Helper class for handling player-generated chat.
Example #1
0
        /// <summary> Parses a message on behalf of this player. </summary>
        /// <param name="rawMessage"> Message to parse. </param>
        /// <param name="fromConsole"> Whether the message originates from console. </param>
        /// <exception cref="ArgumentNullException"> rawMessage is null. </exception>
        public void ParseMessage([NotNull] string rawMessage, bool fromConsole)
        {
            if (rawMessage == null)
            {
                throw new ArgumentNullException("rawMessage");
            }

            // handle canceling selections and partial messages
            if (rawMessage.StartsWith("/nvm", StringComparison.OrdinalIgnoreCase) ||
                rawMessage.StartsWith("/cancel", StringComparison.OrdinalIgnoreCase))
            {
                if (partialMessage != null)
                {
                    MessageNow("Partial message cancelled.");
                    partialMessage = null;
                }
                else if (IsMakingSelection)
                {
                    SelectionCancel();
                    MessageNow("Selection cancelled.");
                }
                else
                {
                    MessageNow("There is currently nothing to cancel.");
                }
                return;
            }

            if (partialMessage != null)
            {
                rawMessage     = partialMessage + rawMessage;
                partialMessage = null;
            }

            // replace %-codes with &-codes
            if (Can(Permission.UseColorCodes))
            {
                rawMessage = Chat.ReplacePercentColorCodes(rawMessage, true);
            }
            // replace emotes
            if (Can(Permission.UseEmotes))
            {
                rawMessage = Chat.ReplaceEmoteKeywords(rawMessage);
            }
            rawMessage = Chat.UnescapeBackslashes(rawMessage);

            switch (Chat.GetRawMessageType(rawMessage))
            {
            case RawMessageType.Chat:
                HandleChatMessage(rawMessage);
                break;

            case RawMessageType.Command:
                HandleCommandMessage(rawMessage, fromConsole);
                break;

            case RawMessageType.PrivateChat:
                HandlePrivateChatMessage(rawMessage);
                break;

            case RawMessageType.RankChat:
                HandleRankChatMessage(rawMessage);
                break;

            case RawMessageType.RepeatCommand:
                if (LastCommand == null)
                {
                    Message("No command to repeat.");
                }
                else
                {
                    if (Info.IsFrozen && (LastCommand.Descriptor == null ||
                                          !LastCommand.Descriptor.UsableByFrozenPlayers))
                    {
                        MessageNow("&WYou cannot use this command while frozen.");
                        return;
                    }
                    LastCommand.Rewind();
                    Logger.Log(LogType.UserCommand,
                               "{0} repeated: {1}",
                               Name,
                               LastCommand.RawMessage);
                    Message("Repeat: {0}", LastCommand.RawMessage);
                    SendToSpectators(LastCommand.RawMessage);
                    CommandManager.ParseCommand(this, LastCommand, fromConsole);
                }
                break;

            case RawMessageType.Confirmation:
                if (Info.IsFrozen)
                {
                    MessageNow("&WYou cannot use any commands while frozen.");
                    return;
                }
                if (ConfirmCallback != null)
                {
                    if (DateTime.UtcNow.Subtract(ConfirmRequestTime) < ConfirmationTimeout)
                    {
                        Logger.Log(LogType.UserCommand, "{0}: /ok", Name);
                        SendToSpectators("/ok");
                        ConfirmCallback(this, ConfirmParameter, fromConsole);
                        ConfirmCancel();
                    }
                    else
                    {
                        MessageNow("Confirmation timed out. Enter the command again.");
                    }
                }
                else
                {
                    MessageNow("There is no command to confirm.");
                }
                break;

            case RawMessageType.PartialMessage:
                partialMessage = rawMessage.Substring(0, rawMessage.Length - 1);
                MessageNow("Partial: &F{0}", partialMessage);
                break;

            case RawMessageType.Invalid:
                MessageNow("Could not parse message.");
                break;
            }
        }
Example #2
0
        static void TimerHandler(Player player, Command cmd)
        {
            string param = cmd.Next();

            // List timers
            if (param == null)
            {
                ChatTimer[] list = ChatTimer.TimerList.OrderBy(timer => timer.TimeLeft).ToArray();
                if (list.Length == 0)
                {
                    player.Message("No timers running.");
                }
                else
                {
                    player.Message("There are {0} timers running:", list.Length);
                    foreach (ChatTimer timer in list)
                    {
                        player.Message("  #{0} \"{1}&S\" (started by {2}, {3} left)",
                                       timer.Id, timer.Message, timer.StartedBy, timer.TimeLeft.ToMiniString());
                    }
                }
                return;
            }

            // Abort a timer
            if (param.Equals("abort", StringComparison.OrdinalIgnoreCase))
            {
                int timerId;
                if (cmd.NextInt(out timerId))
                {
                    ChatTimer timer = ChatTimer.FindTimerById(timerId);
                    if (timer == null || !timer.IsRunning)
                    {
                        player.Message("Given timer (#{0}) does not exist.", timerId);
                    }
                    else
                    {
                        timer.Stop();
                        string abortMsg = String.Format("&Y(Timer) {0}&Y aborted a timer with {1} left: {2}",
                                                        player.ClassyName, timer.TimeLeft.ToMiniString(), timer.Message);
                        Chat.SendSay(player, abortMsg);
                    }
                }
                else
                {
                    CdTimer.PrintUsage(player);
                }
                return;
            }

            // Start a timer
            if (player.Info.IsMuted)
            {
                player.MessageMuted();
                return;
            }
            if (player.DetectChatSpam())
            {
                return;
            }
            TimeSpan duration;

            if (!param.TryParseMiniTimespan(out duration))
            {
                CdTimer.PrintUsage(player);
                return;
            }
            if (duration > DateTimeUtil.MaxTimeSpan)
            {
                player.MessageMaxTimeSpan();
                return;
            }
            if (duration < ChatTimer.MinDuration)
            {
                player.Message("Timer: Must be at least 1 second.");
                return;
            }

            string sayMessage;
            string message = cmd.NextAll();

            if (String.IsNullOrEmpty(message))
            {
                sayMessage = String.Format("&Y(Timer) {0}&Y started a {1} timer",
                                           player.ClassyName,
                                           duration.ToMiniString());
            }
            else
            {
                sayMessage = String.Format("&Y(Timer) {0}&Y started a {1} timer: {2}",
                                           player.ClassyName,
                                           duration.ToMiniString(),
                                           message);
            }
            Chat.SendSay(player, sayMessage);
            ChatTimer.Start(duration, message, player.Name);
        }
Example #3
0
        void HandlePrivateChatMessage([NotNull] string rawMessage)
        {
            if (rawMessage == null)
            {
                throw new ArgumentNullException("rawMessage");
            }
            if (!Can(Permission.Chat))
            {
                return;
            }

            if (Info.IsMuted)
            {
                MessageMuted();
                return;
            }

            if (DetectChatSpam())
            {
                return;
            }

            if (rawMessage.EndsWith("//"))
            {
                rawMessage = rawMessage.Substring(0, rawMessage.Length - 1);
            }

            string otherPlayerName, messageText;

            if (rawMessage[1] == ' ')
            {
                otherPlayerName = rawMessage.Substring(2, rawMessage.IndexOf(' ', 2) - 2);
                messageText     = rawMessage.Substring(rawMessage.IndexOf(' ', 2) + 1);
            }
            else
            {
                otherPlayerName = rawMessage.Substring(1, rawMessage.IndexOf(' ') - 1);
                messageText     = rawMessage.Substring(rawMessage.IndexOf(' ') + 1);
            }

            if (otherPlayerName == "-")
            {
                if (LastUsedPlayerName != null)
                {
                    otherPlayerName = LastUsedPlayerName;
                }
                else
                {
                    Message("Cannot repeat player name: you haven't used any names yet.");
                    return;
                }
            }

            // first, find ALL players (visible and hidden)
            Player[] allPlayers = Server.FindPlayers(otherPlayerName, SearchOptions.Default);

            // if there is more than 1 target player, exclude hidden players
            if (allPlayers.Length > 1)
            {
                allPlayers = Server.FindPlayers(this, otherPlayerName, SearchOptions.ReturnSelfIfOnlyMatch);
            }

            switch (allPlayers.Length)
            {
            case 0:
                MessageNoPlayer(otherPlayerName);
                break;

            case 1: {
                Player target = allPlayers[0];
                if (target == this)
                {
                    Message("Trying to talk to yourself?");
                    return;
                }
                bool messageSent = false;
                if (target.CanHear(this))
                {
                    messageSent = Chat.SendPM(this, target, messageText);
                    // Echo this message to spectators,
                    // excluding the PM target, and anyone from whom the target is hiding.
                    Server.Players
                    .Where(p => p.spectatedPlayer == this && p != target && p.CanSee(target))
                    .Message("[Spectate]: &Fto {0}&F: {1}", target.ClassyName, messageText);
                }

                if (!CanSee(target))
                {
                    // message was sent to a hidden player
                    MessageNoPlayer(otherPlayerName);
                    if (messageSent)
                    {
                        Info.DecrementMessageWritten();
                    }
                }
                else
                {
                    // message was sent normally
                    LastUsedPlayerName = target.Name;
                    if (target.IsIgnoring(Info))
                    {
                        if (CanSee(target))
                        {
                            MessageNow("&WCannot PM {0}&W: you are ignored.", target.ClassyName);
                        }
                    }
                    else if (target.IsDeaf)
                    {
                        MessageNow("Cannot PM {0}&S: they are currently deaf.", target.ClassyName);
                    }
                    else
                    {
                        MessageNow("&Pto {0}: {1}",
                                   target.Name,
                                   messageText);
                    }
                }
            }
            break;

            default:
                MessageManyMatches("player", allPlayers);
                break;
            }
        }