예제 #1
0
        protected void HandleInitializeFactions(InPacket packet)
        {
            var count = packet.ReadInt32();// ("Count");

            for (var i = 0; i < count; i++)
            {
                FactionFlag NpcFlags = (FactionFlag)packet.ReadByte();
                //var flag = packet.ReadByte(); // ("Faction Flags", i);
                var fac = packet.ReadUInt32(); //("Faction Standing", i);
            }
        }
예제 #2
0
        protected void HandleServerAuthResponse(InPacket packet)
        {
            CommandDetail detail = (CommandDetail)packet.ReadByte();

            uint billingTimeRemaining = packet.ReadUInt32();
            byte billingFlags         = packet.ReadByte();
            uint billingTimeRested    = packet.ReadUInt32();
            byte expansion            = packet.ReadByte();

            if (detail == CommandDetail.AuthSuccess)
            {
                OutPacket request = new OutPacket(WorldCommand.CMSG_CHAR_ENUM);
                Send(request);
            }
            else
            {
                Game.UI.LogLine(string.Format("Authentication succeeded, but received response {0}", detail));
                Game.UI.Exit();
            }
        }
예제 #3
0
        protected void HandleServerAuthResponse(InPacket packet)
        {
            CommandDetail detail = (CommandDetail)packet.ReadByte();

            uint billingTimeRemaining = packet.ReadUInt32();
            byte billingFlags = packet.ReadByte();
            uint billingTimeRested = packet.ReadUInt32();
            byte expansion = packet.ReadByte();

            if (detail == CommandDetail.AUTH_OK)
            {
                OutPacket request = new OutPacket(WorldCommand.CMSG_CHAR_ENUM);
                Send(request);
            }
            else
            {
                Game.UI.LogLine(string.Format("Authentication succeeded, but received response {0}", detail));
                Game.UI.Exit();
            }
        }
예제 #4
0
        protected void HandleServerAuthResponse(InPacket packet)
        {
            CommandDetail detail = (CommandDetail)packet.ReadByte();

            uint billingTimeRemaining = packet.ReadUInt32();
            byte billingFlags         = packet.ReadByte();
            uint billingTimeRested    = packet.ReadUInt32();
            byte expansion            = packet.ReadByte();

            if (detail == CommandDetail.AUTH_OK)
            {
                OutPacket request = new OutPacket(WorldCommand.CMSG_CHAR_ENUM);
                Send(request);
                AuthFrame.ShowCharacterUI = true;
                Exchange.AuthMessage      = "Retrieving character list...";
            }
            else
            {
                Exchange.AuthMessage = "Authentication succeeded, but received response " + detail;
            }
        }
예제 #5
0
        public Character(InPacket packet)
        {
            GUID = packet.ReadUInt64();
            Name = packet.ReadCString();
            Race = (Race)packet.ReadByte();
            Class = (Class)packet.ReadByte();
            Gender = (Gender)packet.ReadByte();
            Bytes = packet.ReadBytes(5);
            Level = packet.ReadByte();
            ZoneId = packet.ReadUInt32();
            MapId = packet.ReadUInt32();
            X = packet.ReadSingle();
            Y = packet.ReadSingle();
            Z = packet.ReadSingle();
            GuildId = packet.ReadUInt32();
            Flags = packet.ReadUInt32();
            packet.ReadUInt32();	// customize (rename, etc)
            packet.ReadByte();		// first login
            PetInfoId = packet.ReadUInt32();
            PetLevel = packet.ReadUInt32();
            PetFamilyId = packet.ReadUInt32();

            // read items
            for (int i = 0; i < Items.Length - 1; ++i)
                Items[i] = new Item(packet);

            // read bags
            for (int i = 0; i < 4; ++i)
            {
                packet.ReadUInt32();
                packet.ReadByte();
                packet.ReadUInt32();
            }
        }
예제 #6
0
        protected void HandleNameQueryResponse(InPacket packet)
        {
            var pguid = packet.ReadPackedGuid();
            var ukn   = packet.ReadByte();
            var name  = packet.ReadCString();

            WorldObject[] worldObjects = new WorldObject[Exchange.gameClient.Objects.Count];
            Exchange.gameClient.Objects.Values.CopyTo(worldObjects, 0);

            foreach (WorldObject obj in worldObjects)
            {
                if (obj.GUID == pguid)
                {
                    obj.Name = name;
                }
            }


            if (!Game.World.PlayerNameLookup.ContainsKey(pguid))
            {
                //! Add name definition per GUID
                Game.World.PlayerNameLookup.Add(pguid, name);
                //! See if any queued messages for this GUID are stored
                Queue <ChatMessage> messageQueue = null;
                if (Game.World.QueuedChatMessages.TryGetValue(pguid, out messageQueue))
                {
                    ChatMessage m;
                    while (messageQueue.GetEnumerator().MoveNext())
                    {
                        //! Print with proper name and remove from queue
                        m = messageQueue.Dequeue();
                        m.Sender.Sender = name;
                        //Game.UI.PresentChatMessage(m);
                    }
                }
            }

            /*
             * var realmName = packet.ReadCString();
             * var race = (Race)packet.ReadByte();
             * var gender = (Gender)packet.ReadByte();
             * var cClass = (Class)packet.ReadByte();
             * var decline = packet.ReadBoolean();
             *
             * if (!decline)
             *  return;
             *
             * for (var i = 0; i < 5; i++)
             *  var declinedName = packet.ReadCString();
             */
        }
예제 #7
0
        void HandleCharEnum(InPacket packet)
        {
            byte count = packet.ReadByte();

            if (count == 0)
            {
                Game.UI.LogLine("No characters found!");
            }
            else
            {
                Character[] characters = new Character[count];
                for (byte i = 0; i < count; ++i)
                    characters[i] = new Character(packet);

                Game.UI.PresentCharacterList(characters);
            }
        }
예제 #8
0
        void HandleCharEnum(InPacket packet)
        {
            byte count = packet.ReadByte();

            if (count == 0)
            {
                Game.UI.LogLine("No characters found!");
            }
            else
            {
                Character[] characters = new Character[count];
                for (byte i = 0; i < count; ++i)
                {
                    characters[i] = new Character(packet);
                }

                Game.UI.PresentCharacterList(characters);
            }
        }
예제 #9
0
 public void HandleMonsterMovementPacket(InPacket packet)
 {
     ResetData();
     updateType = ObjectUpdateType.UPDATETYPE_MOVEMENT;
     guid = packet.ReadPackedGuid();
     byte unk = packet.ReadByte();
     WorldObject worldObject = game.Objects[guid];
     worldObject.Set(packet.ReadVector3());
 }
예제 #10
0
            public void HandleUpdatePacket(InPacket packet)
            {
                blockCount = packet.ReadUInt32();
                for (int blockIndex = 0; blockIndex < blockCount; blockIndex++)
                {
                    ResetData();

                    updateType = (ObjectUpdateType)packet.ReadByte();

                    switch (updateType)
                    {
                        case ObjectUpdateType.UPDATETYPE_VALUES:
                            guid = packet.ReadPackedGuid();
                            ReadValuesUpdateData(packet);
                            break;
                        case ObjectUpdateType.UPDATETYPE_MOVEMENT:
                            guid = packet.ReadPackedGuid();
                            ReadMovementUpdateData(packet);
                            break;
                        case ObjectUpdateType.UPDATETYPE_CREATE_OBJECT:
                        case ObjectUpdateType.UPDATETYPE_CREATE_OBJECT2:
                            guid = packet.ReadPackedGuid();
                            objectType = (TypeID)packet.ReadByte();
                            ReadMovementUpdateData(packet);
                            ReadValuesUpdateData(packet);
                            break;
                        case ObjectUpdateType.UPDATETYPE_OUT_OF_RANGE_OBJECTS:
                            var guidCount = packet.ReadUInt32();
                            for (var guidIndex = 0; guidIndex < guidCount; guidIndex++)
                                outOfRangeGuids.Add(packet.ReadPackedGuid());
                            break;
                        case ObjectUpdateType.UPDATETYPE_NEAR_OBJECTS:
                            break;
                    }

                    HandleUpdateData();
                }
            }
예제 #11
0
        protected void HandleLogoutResponse(InPacket packet)
        {
            bool logoutOk = packet.ReadUInt32() == 0;
            bool instant = packet.ReadByte() != 0;

            if(instant || !logoutOk)
            {
                Connected = false;
                LoggedIn = false;
                Running = false;
            }
        }
예제 #12
0
 protected void HandleCharCreate(InPacket packet)
 {
     var response = (CommandDetail)packet.ReadByte();
     if (response == CommandDetail.CHAR_CREATE_SUCCESS)
         SendPacket(new OutPacket(WorldCommand.CMSG_CHAR_ENUM));
     else
         NoCharactersFound();
 }
예제 #13
0
        public MovementInfo(InPacket packet)
        {
            Flags = (MovementFlags)packet.ReadUInt32();
            Flags2 = (MovementFlags2)packet.ReadUInt16();
            Time = packet.ReadUInt32();
            Position = packet.ReadVector3();
            O = packet.ReadSingle();

            if (Flags.HasFlag(MovementFlags.MOVEMENTFLAG_ONTRANSPORT))
            {
                TransportGuid = packet.ReadPackedGuid();
                TransportPosition = packet.ReadVector3();
                TransportO = packet.ReadSingle();
                TransportTime = packet.ReadUInt32();
                TransportSeat = packet.ReadByte();
                if (Flags2.HasFlag(MovementFlags2.MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
                    TransportTime2 = packet.ReadUInt32();
            }

            if (Flags.HasFlag(MovementFlags.MOVEMENTFLAG_SWIMMING) || Flags.HasFlag(MovementFlags.MOVEMENTFLAG_FLYING)
                || Flags2.HasFlag(MovementFlags2.MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
                Pitch = packet.ReadSingle();

            FallTime = packet.ReadUInt32();

            if (Flags.HasFlag(MovementFlags.MOVEMENTFLAG_FALLING))
            {
                JumpZSpeed = packet.ReadSingle();
                JumpSinAngle = packet.ReadSingle();
                JumpCosAngle = packet.ReadSingle();
                JumpXYSpeed = packet.ReadSingle();
            }

            if (Flags.HasFlag(MovementFlags.MOVEMENTFLAG_SPLINE_ELEVATION))
                SplineElevation = packet.ReadSingle();
        }
예제 #14
0
 protected void HandlePartyList(InPacket packet)
 {
     GroupType groupType = (GroupType)packet.ReadByte();
     packet.ReadByte();
     packet.ReadByte();
     packet.ReadByte();
     if (groupType.HasFlag(GroupType.GROUPTYPE_LFG))
     {
         packet.ReadByte();
         packet.ReadUInt32();
     }
     packet.ReadUInt64();
     packet.ReadUInt32();
     uint membersCount = packet.ReadUInt32();
     GroupMembersGuids.Clear();
     for (uint index = 0; index < membersCount; index++)
     {
         packet.ReadCString();
         UInt64 memberGuid = packet.ReadUInt64();
         GroupMembersGuids.Add(memberGuid);
         packet.ReadByte();
         packet.ReadByte();
         packet.ReadByte();
         packet.ReadByte();
     }
     GroupLeaderGuid = packet.ReadUInt64();
 }
예제 #15
0
            private void ReadValuesUpdateData(InPacket packet)
            {
                byte blockCount = packet.ReadByte();
                int[] updateMask = new int[blockCount];
                for (var i = 0; i < blockCount; i++)
                    updateMask[i] = packet.ReadInt32();
                var mask = new BitArray(updateMask);

                for (var i = 0; i < mask.Count; ++i)
                {
                    if (!mask[i])
                        continue;

                    updateFields[i] = packet.ReadUInt32();
                }
            }
예제 #16
0
 public Item(InPacket packet)
 {
     DisplayId = packet.ReadUInt32();
     InventoryType = packet.ReadByte();
     packet.ReadUInt32();	// ???
 }
예제 #17
0
        void HandleServerAuthResponse(InPacket packet)
        {
            CommandDetail detail = (CommandDetail)packet.ReadByte();

            uint billingTimeRemaining = packet.ReadUInt32();
            byte billingFlags = packet.ReadByte();
            uint billingTimeRested = packet.ReadUInt32();
            byte expansion = packet.ReadByte();

            if (detail == CommandDetail.AuthSuccess)
            {
                OutPacket request = new OutPacket(WorldCommand.ClientEnumerateCharacters);
                Send(request);
            }
            else
            {
                Game.UI.Log(string.Format("Authentication succeeded, but received response {0}", detail));
                Game.UI.Exit();
            }
        }
예제 #18
0
            void ReadMovementUpdateData(InPacket packet)
            {
                flags = (ObjectUpdateFlags)packet.ReadUInt16();
                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_LIVING))
                {
                    ReadMovementInfo(packet);

                    movementSpeeds = new Dictionary<UnitMoveType,float>();
                    movementSpeeds[UnitMoveType.MOVE_WALK] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_RUN] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_RUN_BACK] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_SWIM] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_SWIM_BACK] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_FLIGHT] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_FLIGHT_BACK] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_TURN_RATE] = packet.ReadSingle();
                    movementSpeeds[UnitMoveType.MOVE_PITCH_RATE] = packet.ReadSingle();

                    if (movementInfo.Flags.HasFlag(MovementFlags.MOVEMENTFLAG_SPLINE_ENABLED))
                    {
                        splineFlags = (SplineFlags)packet.ReadUInt32();
                        if (splineFlags.HasFlag(SplineFlags.Final_Angle))
                            splineFacingAngle = packet.ReadSingle();
                        else if (splineFlags.HasFlag(SplineFlags.Final_Target))
                            splineFacingTargetGuid = packet.ReadUInt64();
                        else if (splineFlags.HasFlag(SplineFlags.Final_Point))
                            splineFacingPointX = packet.ReadVector3();

                        splineTimePassed = packet.ReadInt32();
                        splineDuration = packet.ReadInt32();
                        splineId = packet.ReadUInt32();
                        packet.ReadSingle();
                        packet.ReadSingle();
                        splineVerticalAcceleration = packet.ReadSingle();
                        splineEffectStartTime = packet.ReadInt32();
                        uint splineCount = packet.ReadUInt32();
                        for (uint index = 0; index < splineCount; index++)
                            splinePoints.Add(packet.ReadVector3());
                        splineEvaluationMode = (SplineEvaluationMode)packet.ReadByte();
                        splineEndPoint = packet.ReadVector3();
                    }
                }
                else if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_POSITION))
                {
                    transportGuid = packet.ReadPackedGuid();
                    position = packet.ReadVector3();
                    transportOffset = packet.ReadVector3();
                    o = packet.ReadSingle();
                    corpseOrientation = packet.ReadSingle();
                }
                else if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_STATIONARY_POSITION))
                {
                    position = packet.ReadVector3();
                    o = packet.ReadSingle();
                }

                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_UNKNOWN))
                    packet.ReadUInt32();

                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_LOWGUID))
                    lowGuid = packet.ReadUInt32();

                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_HAS_TARGET))
                    targetGuid = packet.ReadPackedGuid();

                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_TRANSPORT))
                    transportTimer = packet.ReadUInt32();

                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_VEHICLE))
                {
                    vehicledID = packet.ReadUInt32();
                    vehicleOrientation = packet.ReadSingle();
                }

                if (flags.HasFlag(ObjectUpdateFlags.UPDATEFLAG_ROTATION))
                    goRotation = packet.ReadInt64();
            }
예제 #19
0
        protected void HandleMessageChat(InPacket packet)
        {
            var type   = (ChatMessageType)packet.ReadByte();
            var lang   = (Language)packet.ReadInt32();
            var guid   = packet.ReadUInt64();
            var unkInt = packet.ReadInt32();

            switch (type)
            {
            case ChatMessageType.Say:
            case ChatMessageType.Yell:
            case ChatMessageType.Party:
            case ChatMessageType.PartyLeader:
            case ChatMessageType.Raid:
            case ChatMessageType.RaidLeader:
            case ChatMessageType.RaidWarning:
            case ChatMessageType.Guild:
            case ChatMessageType.Officer:
            case ChatMessageType.Emote:
            case ChatMessageType.TextEmote:
            case ChatMessageType.Whisper:
            case ChatMessageType.WhisperInform:
            case ChatMessageType.System:
            case ChatMessageType.Channel:
            case ChatMessageType.Battleground:
            case ChatMessageType.BattlegroundNeutral:
            case ChatMessageType.BattlegroundAlliance:
            case ChatMessageType.BattlegroundHorde:
            case ChatMessageType.BattlegroundLeader:
            case ChatMessageType.Achievement:
            case ChatMessageType.GuildAchievement:
            {
                ChatChannel channel = new ChatChannel();
                channel.Type = type;

                if (type == ChatMessageType.Channel)
                {
                    channel.ChannelName = packet.ReadCString();
                }

                var sender = packet.ReadUInt64();

                ChatMessage message = new ChatMessage();
                var         textLen = packet.ReadInt32();
                message.Message  = packet.ReadCString();
                message.Language = lang;
                message.ChatTag  = (ChatTag)packet.ReadByte();
                message.Sender   = channel;

                //! If we know the name of the sender GUID, use it
                //! For system messages sender GUID is 0, don't need to do anything fancy
                string senderName = null;
                if (type == ChatMessageType.System ||
                    Game.World.PlayerNameLookup.TryGetValue(sender, out senderName))
                {
                    message.Sender.Sender = senderName;
                    Game.UI.PresentChatMessage(message);
                    return;
                }

                //! If not we place the message in the queue,
                //! .. either existent
                Queue <ChatMessage> messageQueue = null;
                if (Game.World.QueuedChatMessages.TryGetValue(sender, out messageQueue))
                {
                    messageQueue.Enqueue(message);
                }
                //! or non existent
                else
                {
                    messageQueue = new Queue <ChatMessage>();
                    messageQueue.Enqueue(message);
                    Game.World.QueuedChatMessages.Add(sender, messageQueue);
                }

                //! Furthermore we send CMSG_NAME_QUERY to the server to retrieve the name of the sender
                OutPacket response = new OutPacket(NetworkOperationCode.CMSG_NAME_QUERY);
                response.Write(sender);
                Game.SendPacket(response);

                //! Enqueued chat will be printed when we receive SMSG_NAME_QUERY_RESPONSE

                break;
            }

            default:
                return;
            }
        }
예제 #20
0
        void HandleMessageChat(InPacket packet)
        {
            var type = (ChatMessageType)packet.ReadByte();
            var lang = (Language)packet.ReadInt32();
            var guid = packet.ReadUInt64();
            var unkInt = packet.ReadInt32();

            switch (type)
            {
                case ChatMessageType.Say:
                case ChatMessageType.Yell:
                case ChatMessageType.Party:
                case ChatMessageType.PartyLeader:
                case ChatMessageType.Raid:
                case ChatMessageType.RaidLeader:
                case ChatMessageType.RaidWarning:
                case ChatMessageType.Guild:
                case ChatMessageType.Officer:
                case ChatMessageType.Emote:
                case ChatMessageType.TextEmote:
                case ChatMessageType.Whisper:
                case ChatMessageType.WhisperInform:
                case ChatMessageType.System:
                case ChatMessageType.Channel:
                case ChatMessageType.Battleground:
                case ChatMessageType.BattlegroundNeutral:
                case ChatMessageType.BattlegroundAlliance:
                case ChatMessageType.BattlegroundHorde:
                case ChatMessageType.BattlegroundLeader:
                case ChatMessageType.Achievement:
                case ChatMessageType.GuildAchievement:
                    {
                        ChatChannel channel = new ChatChannel();
                        channel.Type = type;

                        if (type == ChatMessageType.Channel)
                            channel.ChannelName = packet.ReadCString();

                        var sender = packet.ReadUInt64();

                        ChatMessage message = new ChatMessage();
                        var textLen = packet.ReadInt32();
                        message.Message = packet.ReadCString();
                        message.Language = lang;
                        message.ChatTag = (ChatTag)packet.ReadByte();
                        message.Sender = channel;

                        //! If we know the name of the sender GUID, use it
                        //! For system messages sender GUID is 0, don't need to do anything fancy
                        string senderName = null;
                        if (type == ChatMessageType.System ||
                            Game.World.PlayerNameLookup.TryGetValue(sender, out senderName))
                        {
                            message.Sender.Sender = senderName;
                            Game.UI.PresentChatMessage(message);
                            return;
                        }

                        //! If not we place the message in the queue,
                        //! .. either existent
                        Queue<ChatMessage> messageQueue = null;
                        if (Game.World.QueuedChatMessages.TryGetValue(sender, out messageQueue))
                            messageQueue.Enqueue(message);
                        //! or non existent
                        else
                        {
                            messageQueue = new Queue<ChatMessage>();
                            messageQueue.Enqueue(message);
                            Game.World.QueuedChatMessages.Add(sender, messageQueue);
                        }

                        //! Furthermore we send CMSG_NAME_QUERY to the server to retrieve the name of the sender
                        OutPacket response = new OutPacket(WorldCommand.CMSG_NAME_QUERY);
                        response.Write(sender);
                        Game.SendPacket(response);

                        //! Enqueued chat will be printed when we receive SMSG_NAME_QUERY_RESPONSE

                        break;
                    }
                default:
                    return;
            }
        }
예제 #21
0
        protected void HandleMessageChat(InPacket packet)
        {
            var    chatType   = (ChatMessageType)packet.ReadByte();
            var    language   = (Language)packet.ReadInt32();
            UInt64 senderGuid = packet.ReadUInt64();
            var    unkInt     = packet.ReadUInt32();

            UInt32 senderNameLen   = 0;
            string senderName      = null;
            UInt64 receiverGuid    = 0;
            UInt32 receiverNameLen = 0;
            string receiverName    = null;
            string channelName     = null;

            switch (chatType)
            {
            case ChatMessageType.MonsterSay:
            case ChatMessageType.MonsterParty:
            case ChatMessageType.MonsterYell:
            case ChatMessageType.MonsterWhisper:
            case ChatMessageType.MonsterEmote:
            case ChatMessageType.RaidBossEmote:
            case ChatMessageType.RaidBossWhisper:
            case ChatMessageType.BattleNet:
                senderNameLen = packet.ReadUInt32();
                senderName    = packet.ReadCString();
                receiverGuid  = packet.ReadUInt64();
                if (receiverGuid != 0 && !receiverGuid.IsPlayer() && !receiverGuid.IsPet())
                {
                    receiverNameLen = packet.ReadUInt32();
                    receiverName    = packet.ReadCString();
                }
                break;

            case ChatMessageType.WhisperForeign:
                senderNameLen = packet.ReadUInt32();
                senderName    = packet.ReadCString();
                receiverGuid  = packet.ReadUInt64();
                break;

            case ChatMessageType.BattlegroundNeutral:
            case ChatMessageType.BattlegroundAlliance:
            case ChatMessageType.BattlegroundHorde:
                receiverGuid = packet.ReadUInt64();
                if (receiverGuid != 0 && !receiverGuid.IsPlayer())
                {
                    receiverNameLen = packet.ReadUInt32();
                    receiverName    = packet.ReadCString();
                }
                break;

            case ChatMessageType.Achievement:
            case ChatMessageType.GuildAchievement:
                receiverGuid = packet.ReadUInt64();
                break;

            default:
                if (packet.Header.Command == WorldCommand.SMSG_GM_MESSAGECHAT)
                {
                    senderNameLen = packet.ReadUInt32();
                    senderName    = packet.ReadCString();
                }

                if (chatType == ChatMessageType.Channel)
                {
                    channelName = packet.ReadCString();
                }

                receiverGuid = packet.ReadUInt64();
                break;
            }

            UInt32 messageLen = packet.ReadUInt32();
            string message    = packet.ReadCString();
            var    chatTag    = (ChatTag)packet.ReadByte();

            if (chatType == ChatMessageType.Achievement || chatType == ChatMessageType.GuildAchievement)
            {
                var achievementId = packet.ReadUInt32();
            }

            ChatChannel channel = new ChatChannel();

            channel.Type = chatType;

            if (chatType == ChatMessageType.Channel)
            {
                channel.ChannelName = channelName;
            }

            ChatMessage chatMessage = new ChatMessage();

            chatMessage.Message  = message;
            chatMessage.Language = language;
            chatMessage.ChatTag  = chatTag;
            chatMessage.Sender   = channel;

            //! If we know the name of the sender GUID, use it
            //! For system messages sender GUID is 0, don't need to do anything fancy
            if (senderGuid == 0 || !string.IsNullOrEmpty(senderName) ||
                Game.World.PlayerNameLookup.TryGetValue(senderGuid, out senderName))
            {
                chatMessage.Sender.Sender = senderName;
                Game.UI.PresentChatMessage(chatMessage);
                return;
            }

            //! If not we place the message in the queue,
            //! .. either existent
            Queue <ChatMessage> messageQueue = null;

            if (Game.World.QueuedChatMessages.TryGetValue(senderGuid, out messageQueue))
            {
                messageQueue.Enqueue(chatMessage);
            }
            //! or non existent
            else
            {
                messageQueue = new Queue <ChatMessage>();
                messageQueue.Enqueue(chatMessage);
                Game.World.QueuedChatMessages.Add(senderGuid, messageQueue);
            }

            //! Furthermore we send CMSG_NAME_QUERY to the server to retrieve the name of the sender
            OutPacket response = new OutPacket(WorldCommand.CMSG_NAME_QUERY);

            response.Write(senderGuid);
            Game.SendPacket(response);

            //! Enqueued chat will be printed when we receive SMSG_NAME_QUERY_RESPONSE
        }