/// <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; } }
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); }
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; } }