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