Beispiel #1
0
        public void SendTalk(MessageModeType mode, int channelId, string receiver, string text)
        {
            var message = _packetWriter.CreateMessage();

            message.WriteEnum(GameclientMessageType.Talk);
            message.WriteUnsignedByte(TranslateMessageModeToServer(mode));

            switch (mode)
            {
            case MessageModeType.PrivateTo:
            case MessageModeType.GamemasterPrivateTo:
            case MessageModeType.RVRAnswer:
                message.WriteString(receiver);
                break;

            case MessageModeType.Channel:
            case MessageModeType.ChannelHighlight:
            case MessageModeType.ChannelManagement:
            case MessageModeType.GamemasterChannel:
                message.WriteUnsignedShort((ushort)channelId);
                break;

            default:
                break;
            }

            message.WriteString(text);
            _packetWriter.FinishMessage();
        }
Beispiel #2
0
 internal OnscreenMessageBox(Vector3Int?position, string speaker, int speakerLevel, MessageModeType mode, int messagesSize, TMPro.TextMeshProUGUI textMesh = null)
 {
     m_Position     = position;
     Speaker        = speaker;
     m_SpeakerLevel = speakerLevel;
     Mode           = mode;
     m_Messages     = new Utility.RingBuffer <OnscreenMessage>(messagesSize);
     m_TextMesh     = textMesh;
 }
Beispiel #3
0
        public MessageMode GetMessageMode(MessageModeType mode)
        {
            if (!MessageMode.s_CheckMode((int)mode))
            {
                throw new System.ArgumentException("MessageModeSet.getMessageMode: Invalid mode: " + (int)mode + ".");
            }

            return(_messageModes[(int)mode]);
        }
Beispiel #4
0
 public OnscreenMessageBox(Vector3Int?position, string speaker, int speakerLevel, MessageModeType mode, int messagesSize, TMPro.TextMeshProUGUI textMesh = null)
 {
     _position     = position;
     Speaker       = speaker;
     _speakerLevel = speakerLevel;
     Mode          = mode;
     _messages     = new Utils.RingBuffer <OnscreenMessage>(messagesSize);
     _textMesh     = textMesh;
 }
Beispiel #5
0
 internal Channel(Utility.UnionStrInt ID, string name, MessageModeType sendMode)
 {
     m_ID            = ID;
     m_Name          = name;
     m_SendMode      = sendMode;
     m_Closable      = true;
     m_SendAllowed   = true;
     m_NicklistItems = new List <object>();
     m_Messages      = new List <ChannelMessage>(MessagesSize);
 }
Beispiel #6
0
 public MessageModeProperties(MessageModeType mode, bool showOnscreen, bool showChannel, uint textARGB, uint highlightARGB, bool editable, bool ignoreNameFilter, MessageScreenTargets screenTarget = MessageScreenTargets.None, MessageModeHeaders header = MessageModeHeaders.None, MessageModePrefixes prefix = MessageModePrefixes.None)
 {
     Mode             = mode;
     ShowOnscreen     = showOnscreen;
     ShowChannel      = showChannel;
     TextARGB         = textARGB;
     HighlightARGB    = highlightARGB;
     Editable         = editable;
     IgnoreNameFilter = ignoreNameFilter;
     ScreenTarget     = screenTarget;
     Header           = header;
     Prefix           = prefix;
 }
Beispiel #7
0
        private byte TranslateMessageModeToServer(MessageModeType mode)
        {
            if (mode < 0 || mode >= MessageModeType.LastMessage)
            {
                return((int)MessageModeType.Invalid);
            }

            foreach (var p in _messageModesDict)
            {
                if (p.Key == mode)
                {
                    return((byte)p.Value);
                }
            }
            return((int)MessageModeType.Invalid);
        }
Beispiel #8
0
        internal Channel AddChannel(Utility.UnionStrInt channelID, string name, MessageModeType mode)
        {
            Channel channel = GetChannel(channelID);

            if (channel != null)
            {
                channel.Name        = name;
                channel.SendAllowed = true;
            }
            else
            {
                channel = new Channel(channelID, name, mode);
                m_Channels.Add(channel);
                onAddChannel.Invoke(channel);

                switch ((int)channelID)
                {
                case HelpChannelID:
                    if (OpenTibiaUnity.GameManager.ClientVersion >= 854)
                    {
                        AddChannelMessage(channelID, -1, null, 0, MessageModeType.ChannelManagement, TextResources.CHANNEL_MSG_HELP);
                    }
                    else
                    {
                        AddChannelMessage(channelID, -1, null, 0, MessageModeType.GamemasterChannel, TextResources.CHANNEL_MSG_HELP_LEGACY);
                    }
                    break;

                case MainAdvertisingChannelID:
                case RookAdvertisingChannelID:
                    AddChannelMessage(channelID, -1, null, 0, MessageModeType.ChannelManagement, TextResources.CHANNEL_MSG_ADVERTISING);
                    break;

                default:
                    break;
                }
            }

            var player = OpenTibiaUnity.Player;

            if (!!player && player.Name != null)
            {
                channel.PlayerJoined(player.Name);
            }

            return(channel);
        }
Beispiel #9
0
        internal OnscreenMessage(int statementID, string speaker, int speakerLevel, MessageModeType mode, string text)
        {
            if (statementID <= 0)
            {
                m_ID = --s_NextID;
            }
            else
            {
                m_ID = statementID;
            }

            m_Speaker      = speaker;
            m_SpeakerLevel = speakerLevel;
            m_Mode         = mode;
            m_Text         = text;
            m_VisibleSince = int.MaxValue;
            m_TTL          = (30 + m_Text.Length / 3) * 100;
        }
Beispiel #10
0
        // [TODO] Allowment to have custom filter sets (changing the default colors of anything)
        public MessageFilterSet(int id)
        {
            _id           = id;
            _messageModes = new MessageMode[(int)MessageModeType.Invalid];

            for (MessageModeType i = MessageModeType.None; i < MessageModeType.BeyondLast; i++)
            {
                AddMessageMode(new MessageMode(i));
            }

            AddMessageMode(new MessageMode(MessageModeType.MonsterYell));
            AddMessageMode(new MessageMode(MessageModeType.MonsterSay));
            AddMessageMode(new MessageMode(MessageModeType.Red));
            AddMessageMode(new MessageMode(MessageModeType.Blue));
            AddMessageMode(new MessageMode(MessageModeType.RVRChannel));
            AddMessageMode(new MessageMode(MessageModeType.RVRAnswer));
            AddMessageMode(new MessageMode(MessageModeType.RVRContinue));
            AddMessageMode(new MessageMode(MessageModeType.GameHighlight));
            AddMessageMode(new MessageMode(MessageModeType.NpcFromStartBlock));
        }
        public void AddText(string text)
        {
            if (text == null)
            {
                throw new System.ArgumentNullException("MessageBlock.AddText: text is null.");
            }

            _textPieces.Add(text);
            MessageModeType mode = _nextOnscreenMessageIndex == 0 ? MessageModeType.NpcFromStartBlock : MessageModeType.NpcFrom;

            OpenTibiaUnity.ChatStorage.AddChannelMessage(ChatStorage.NpcChannelId, 0, _speaker, 0, mode, text);
            if (_nextOnscreenMessageIndex == 0 || _nextOnscreenMessageIndex > 0 && OpenTibiaUnity.TicksMillis > _minTimeForNextOnscreenMessage)
            {
                ShowNextOnscreenMessage();
            }
            else if (!_timerEventRegistered)
            {
                OpenTibiaUnity.GameManager.AddSecondaryTimerListener(OnSecondaryTimer);
                _timerEventRegistered = true;
            }
        }
Beispiel #12
0
        internal bool AcceptMessage(MessageModeType mode, string speaker, string message)
        {
            if (string.IsNullOrEmpty(speaker))
            {
                return(false);
            }

            if (WhitelistEnabled)
            {
                if (WhitelistBuddies)
                {
                    // TODO, this should cast on BuddySets that are white.
                }

                if (IndexOf(speaker, m_WhiteItems) != -1)
                {
                    return(true);
                }
            }

            if (BlacklistEnabled)
            {
                if (BlacklistPrivate && mode == MessageModeType.PrivateFrom)
                {
                    return(false);
                }

                if (BlacklistYelling && mode == MessageModeType.Yell)
                {
                    return(false);
                }

                if (IndexOf(speaker, m_BlackItems) != -1)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #13
0
        public OnscreenMessageBox AddOnscreenMessage(UnityEngine.Vector3Int?absolutePosition, int statementId, string speaker, int speakerLevel, MessageModeType mode, Utils.UnionStrInt text, int color)
        {
            var messageFilterSet = OpenTibiaUnity.OptionStorage.GetMessageFilterSet(Chat.MessageFilterSet.DefaultSet);
            var messageMode      = messageFilterSet.GetMessageMode(mode);

            if (messageMode == null || !messageMode.ShowOnScreen || messageMode.ScreenTarget == MessageScreenTargets.None)
            {
                return(null);
            }

            var nameFilterSet = OpenTibiaUnity.OptionStorage.GetNameFilterSet(Chat.NameFilterSet.DefaultSet);

            if (!messageMode.IgnoreNameFilter && (nameFilterSet == null || !nameFilterSet.AcceptMessage(mode, speaker, text)))
            {
                return(null);
            }

            var screenTarget = messageMode.ScreenTarget;

            if (screenTarget == MessageScreenTargets.EffectCoordinate)
            {
                if (!absolutePosition.HasValue)
                {
                    throw new System.Exception("WorldMapStorage.AddOnscreenMessage: Missing co-ordinate.");
                }

                if (text.IsInt)
                {
                    AddTextualEffect(absolutePosition.Value, color, ((int)text).ToString());
                }
                return(null);
            }

            OnscreenMessageBox messageBox = null;
            OnscreenMessage    message    = null;

            if (screenTarget == MessageScreenTargets.BoxCoordinate)
            {
                if (!absolutePosition.HasValue)
                {
                    throw new System.Exception("WorldMapStorage.AddOnscreenMessage: Missing co-ordinate.");
                }

                bool visible = true;

                for (int i = (int)screenTarget; i < MessageBoxes.Count; i++)
                {
                    var tmpMessageBox = MessageBoxes[i];
                    if (tmpMessageBox.Position == null || tmpMessageBox.Position == absolutePosition.Value)
                    {
                        if (tmpMessageBox.Speaker == speaker && tmpMessageBox.Mode == mode)
                        {
                            messageBox = tmpMessageBox;
                            break;
                        }

                        visible = false;
                    }
                }

                if (messageBox == null)
                {
                    messageBox = new OnscreenMessageBox(absolutePosition, speaker, speakerLevel, mode, Constants.NumOnscreenMessages)
                    {
                        Visible = visible
                    };

                    var tmpMessage = messageMode.GetOnscreenMessageHeader(speaker, speakerLevel);
                    if (tmpMessage != null)
                    {
                        message = new OnscreenMessage(-1, speaker, speakerLevel, mode, tmpMessage);
                        message.FormatMessage(null, messageMode.TextARGB, messageMode.HighlightARGB);
                        message.TTL = int.MaxValue;
                        messageBox.AppendMessage(message);
                    }

                    MessageBoxes.Add(messageBox);
                }
            }
            else
            {
                messageBox = MessageBoxes[(int)screenTarget];
            }

            message = new OnscreenMessage(statementId, speaker, speakerLevel, mode, text);
            message.FormatMessage(messageMode.GetOnscreenMessagePrefix(speaker, speakerLevel), messageMode.TextARGB, messageMode.HighlightARGB);
            messageBox.AppendMessage(message);
            messageBox.Visible = true;
            InvalidateOnscreenMessages();
            return(messageBox);
        }
Beispiel #14
0
 public OnscreenMessageBox AddOnscreenMessage(UnityEngine.Vector3Int?absolutePosition, int statementId, string speaker, int speakerLevel, MessageModeType mode, string text)
 {
     return(AddOnscreenMessage(absolutePosition, statementId, speaker, speakerLevel, mode, text, int.MaxValue));
 }
Beispiel #15
0
 public OnscreenMessageBox AddOnscreenMessage(MessageModeType mode, string text)
 {
     return(AddOnscreenMessage(null, -1, null, 0, mode, text, int.MaxValue));
 }
Beispiel #16
0
        internal string SendChannelMessage(string text, Channel channel, MessageModeType mode)
        {
            var protocolGame = OpenTibiaUnity.ProtocolGame;
            var player       = OpenTibiaUnity.Player;

            if (protocolGame == null || !protocolGame.IsGameRunning)
            {
                return("");
            }

            text = text.Trim();
            if (text.Length > Constants.MaxTalkLength)
            {
                text = text.Substring(0, Constants.MaxTalkLength);
            }

            if (text.Length == 0)
            {
                return("");
            }

            mode = mode != MessageModeType.None ? mode : channel.SendMode;

            Utility.UnionStrInt channelID = null;
            if ((!channel.ID.IsInt || (channel.ID != DebugChannelID && channel.ID != LocalChannelID && channel.ID != ServerChannelID)) && channel.SendAllowed)
            {
                channelID = channel.ID;
            }

            string channelName = null;

            var regex1 = new System.Text.RegularExpressions.Regex(@"^#([sywbixc])\s+(.*)");
            var regex2 = new System.Text.RegularExpressions.Regex(@"^([*@$])([^\1]+?)\1\s*(.*)");

            string externalCommand = null;

            System.Text.RegularExpressions.Match match;
            if ((match = regex1.Match(text)) != null && match.Success)
            {
                externalCommand = match.Groups[1].ToString().ToLower();
                if (externalCommand == "b")
                {
                    mode = MessageModeType.GamemasterBroadcast;
                }
                else if (externalCommand == "c")
                {
                    mode = MessageModeType.GamemasterChannel;
                }
                else if (externalCommand == "i")
                {
                    mode = MessageModeType.None;
                }
                else if (externalCommand == "s")
                {
                    mode = MessageModeType.Say;
                }
                else if (externalCommand == "w")
                {
                    mode = MessageModeType.Whisper;
                }
                else if (externalCommand == "x")
                {
                    mode = MessageModeType.None;
                }
                else if (externalCommand == "y")
                {
                    mode = MessageModeType.Yell;
                }

                text = match.Groups[2].ToString();
            }
            else if ((match = regex2.Match(text)) != null && match.Success)
            {
                externalCommand = match.Groups[1].ToString().ToLower();
                if (externalCommand == "*")
                {
                    mode = MessageModeType.PrivateTo;
                }
                else if (externalCommand == "@")
                {
                    mode = MessageModeType.GamemasterPrivateTo;
                }

                channelID   = match.Groups[2].ToString();
                channelName = channelID;
                if (channelName.Length > Constants.MaxChannelLength)
                {
                    channelName = channelName.Substring(0, Constants.MaxChannelLength);
                }

                text = match.Groups[3].ToString();
            }

            if (mode == MessageModeType.GamemasterChannel && (!channelID.IsInt || channelID == NpcChannelID))
            {
                OpenTibiaUnity.WorldMapStorage.AddOnscreenMessage(MessageModeType.Failure, TextResources.MSG_CHANNEL_NO_ANONYMOUS);
                return("");
            }

            if (HasOwnPrivateChannel)
            {
                if (externalCommand == "i")
                {
                    protocolGame.SendInviteToChannel(text, OwnPrivateChannelID);
                }
                else if (externalCommand == "x")
                {
                    protocolGame.SendExcludeFromChannel(text, OwnPrivateChannelID);
                }
            }

            switch (mode)
            {
            case MessageModeType.None: break;

            case MessageModeType.Say:
            case MessageModeType.Whisper:
            case MessageModeType.Yell:
                protocolGame.SendTalk(mode, 0, null, text);
                break;

            case MessageModeType.Channel:
                protocolGame.SendTalk(mode, channelID, null, text);
                break;

            case MessageModeType.PrivateTo:
                AddChannelMessage(channelID, -1, player.Name, (ushort)player.Level, mode, text);
                if (channelID != player.Name.ToLower())
                {
                    protocolGame.SendTalk(mode, 0, channelID, text);
                }
                break;
            }

            if (channelID != channel.ID && (mode == MessageModeType.PrivateTo || mode == MessageModeType.GamemasterPrivateTo))
            {
                return("*" + channelName + "* ");
            }

            return("");
        }
Beispiel #17
0
        internal ChannelMessage AddChannelMessage(Utility.UnionStrInt channelID, int statementID, string speaker, int speakerLevel, MessageModeType mode, string text)
        {
            var messageFilterSet = OpenTibiaUnity.OptionStorage.GetMessageFilterSet(MessageFilterSet.DefaultSet);
            var messageMode      = messageFilterSet.GetMessageMode(mode);

            if (messageMode == null || !messageMode.ShowChannelMessage)
            {
                return(null);
            }

            var nameFilterSet = OpenTibiaUnity.OptionStorage.GetNameFilterSet(NameFilterSet.DefaultSet);

            if (!messageMode.IgnoreNameFilter && (nameFilterSet == null || !nameFilterSet.AcceptMessage(mode, speaker, text)))
            {
                return(null);
            }

            bool           isReportName      = speaker != null && channelID.IsInt && ((int)channelID == ChatStorage.HelpChannelID || speakerLevel > 0);
            bool           isReportStatement = statementID > 0;
            Channel        channel           = null;
            ChannelMessage channelMessage    = new ChannelMessage(statementID, speaker, speakerLevel, mode, text);

            channelMessage.FormatMessage(messageFilterSet.ShowTimeStamps, messageFilterSet.ShowLevels, messageMode.TextARGB, messageMode.HighlightARGB);

            switch (mode)
            {
            case MessageModeType.Say:
            case MessageModeType.Yell:
            case MessageModeType.Whisper:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channelMessage.SetReportTypeAllowed(ReportTypes.Statement, isReportStatement);
                channel = GetChannel(ChatStorage.LocalChannelID);
                break;

            case MessageModeType.PrivateFrom:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channelMessage.SetReportTypeAllowed(ReportTypes.Statement, isReportStatement);
                channel = GetChannel(channelID);
                if (channel == null)
                {
                    channel = GetChannel(ChatStorage.LocalChannelID);
                }
                break;

            case MessageModeType.PrivateTo:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channelMessage.SetReportTypeAllowed(ReportTypes.Statement, isReportStatement);
                channel = GetChannel(channelID);
                if (channel == null)
                {
                    channel = GetChannel(ChatStorage.LocalChannelID);
                }
                break;

            case MessageModeType.ChannelManagement:
                channel = GetChannel(channelID);
                if (channel == null)
                {
                    channel = GetChannel(ChatStorage.LocalChannelID);
                }
                break;

            case MessageModeType.Channel:
            case MessageModeType.ChannelHighlight:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channelMessage.SetReportTypeAllowed(ReportTypes.Statement, isReportStatement);
                channel = GetChannel(channelID);
                break;

            case MessageModeType.Spell:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channel = GetChannel(ChatStorage.LocalChannelID);
                break;

            case MessageModeType.NpcFromStartBlock:
            case MessageModeType.NpcFrom:
            case MessageModeType.NpcTo:
                channel = AddChannel(ChatStorage.NpcChannelID, "NPCs", MessageModeType.NpcTo);
                break;

            case MessageModeType.GamemasterBroadcast:
                channel = GetChannel(ChatStorage.ServerChannelID);
                break;

            case MessageModeType.GamemasterChannel:
                channel = GetChannel(channelID);
                break;

            case MessageModeType.GamemasterPrivateFrom:
            case MessageModeType.GamemasterPrivateTo:
                channel = GetChannel(ChatStorage.ServerChannelID);
                break;

            case MessageModeType.Login:
            case MessageModeType.Admin:
            case MessageModeType.Game:
            case MessageModeType.GameHighlight:
            case MessageModeType.Look:
            case MessageModeType.DamageDealed:
            case MessageModeType.DamageReceived:
            case MessageModeType.Heal:
            case MessageModeType.Mana:
            case MessageModeType.Exp:
            case MessageModeType.DamageOthers:
            case MessageModeType.HealOthers:
            case MessageModeType.ExpOthers:
            case MessageModeType.Status:
            case MessageModeType.Loot:
            case MessageModeType.TradeNpc:
            case MessageModeType.Report:
            case MessageModeType.HotkeyUse:
            case MessageModeType.TutorialHint:
            case MessageModeType.Thankyou:
                if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameServerLog))
                {
                    channel = GetChannel(ChatStorage.ServerChannelID);
                }
                else
                {
                    channel = GetChannel(ChatStorage.LocalChannelID);
                }
                break;

            case MessageModeType.Guild:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channelMessage.SetReportTypeAllowed(ReportTypes.Statement, isReportStatement);
                channel = GetChannel(channelID);
                if (channel == null)
                {
                    if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameServerLog))
                    {
                        channel = GetChannel(ChatStorage.ServerChannelID);
                    }
                    else
                    {
                        channel = GetChannel(ChatStorage.LocalChannelID);
                    }
                }
                break;

            case MessageModeType.PartyManagement:
            case MessageModeType.Party:
                channelMessage.SetReportTypeAllowed(ReportTypes.Name, isReportName);
                channelMessage.SetReportTypeAllowed(ReportTypes.Statement, isReportStatement);
                channel = GetChannel(channelID);
                if (channel == null)
                {
                    if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameServerLog))
                    {
                        channel = GetChannel(ChatStorage.ServerChannelID);
                    }
                    else
                    {
                        channel = GetChannel(ChatStorage.LocalChannelID);
                    }
                }
                break;

            case MessageModeType.BarkLow:
            case MessageModeType.BarkLoud:
                if (channel == null)
                {
                    if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameServerLog))
                    {
                        channel = GetChannel(ChatStorage.ServerChannelID);
                    }
                    else
                    {
                        channel = GetChannel(ChatStorage.LocalChannelID);
                    }
                }
                break;

            case MessageModeType.MonsterSay:
            case MessageModeType.MonsterYell:
                break;

            case MessageModeType.Blue:
            case MessageModeType.Red:
                if (channel == null)
                {
                    channel = GetChannel(ChatStorage.LocalChannelID);
                }
                break;

            default:
                AddDebugMessage(string.Format("ChatStorage.AddChannelMessage: Unhandled MessageMode ({0}).", mode));
                break;
            }

            if (channel != null)
            {
                channel.AppendMessage(channelMessage);
                return(channelMessage);
            }

            return(null);
        }
Beispiel #18
0
        private void ParseTalk(Internal.ByteArray message)
        {
            uint statementId = 0;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameMessageStatements))
            {
                statementId = message.ReadUnsignedInt();
            }

            string speaker      = message.ReadString();
            ushort speakerLevel = 0;

            if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameMessageLevel))
            {
                speakerLevel = message.ReadUnsignedShort();
            }

            int             rawMode = message.ReadUnsignedByte();
            MessageModeType mode    = TranslateMessageModeFromServer(rawMode);

            Vector3Int?absolutePosition = null;

            Utils.UnionStrInt channelId = null;

            switch (mode)
            {
            case MessageModeType.Say:
            case MessageModeType.Whisper:
            case MessageModeType.Yell:
                absolutePosition = message.ReadPosition();
                channelId        = Chat.ChatStorage.LocalChannelId;
                break;

            case MessageModeType.PrivateFrom:
                channelId = speaker;
                break;

            case MessageModeType.Channel:
            case MessageModeType.ChannelManagement:
            case MessageModeType.ChannelHighlight:
                channelId = message.ReadUnsignedShort();
                break;

            case MessageModeType.Spell:
                absolutePosition = message.ReadPosition();
                channelId        = Chat.ChatStorage.LocalChannelId;
                break;

            case MessageModeType.NpcFromStartBlock:
                absolutePosition = message.ReadPosition();
                break;

            case MessageModeType.NpcFrom:
                break;

            case MessageModeType.GamemasterBroadcast:
                break;

            case MessageModeType.GamemasterChannel:
                channelId = message.ReadUnsignedShort();
                break;

            case MessageModeType.GamemasterPrivateFrom:
                channelId = speaker;
                break;

            case MessageModeType.BarkLow:
            case MessageModeType.BarkLoud:
            case MessageModeType.MonsterSay:
            case MessageModeType.MonsterYell:
                absolutePosition = message.ReadPosition();
                channelId        = -1;
                break;

            case MessageModeType.Game:
                break;

            case MessageModeType.RVRAnswer:
            case MessageModeType.RVRContinue:
                channelId = Chat.ChatStorage.RVRChannelId;
                break;

            case MessageModeType.RVRChannel:
                message.ReadUnsignedInt();
                channelId = Chat.ChatStorage.RVRChannelId;
                break;

            default:
                throw new System.Exception(string.Format("ProtocolGame.ParseTalk: invalid message mode (raw = {0}, mode = {1})", rawMode, mode));
            }

            string text = message.ReadString();

            if (mode != MessageModeType.NpcFromStartBlock && mode != MessageModeType.NpcFrom)
            {
                try {
                    WorldMapStorage.AddOnscreenMessage(absolutePosition, (int)statementId, speaker, speakerLevel, mode, text);
                    ChatStorage.AddChannelMessage(channelId, (int)statementId, speaker, speakerLevel, mode, text);
                } catch (System.Exception e) {
                    throw new System.Exception("ProtocolGame.ParseTalk: Failed to add message: " + e.Message + "\n" + e.StackTrace);
                }
            }
            else if (mode == MessageModeType.NpcFromStartBlock)
            {
                MessageStorage.StartMessageBlock(speaker, absolutePosition, text);
            }
            else if (mode == MessageModeType.NpcFrom)
            {
                MessageStorage.AddTextToBlock(speaker, text);
            }
        }