public static string Hotfixes()
        {
            var stringBuilder = new StringBuilder();

            if (ClientLocale.PacketLocale == LocaleConstant.enUS)
            {
                // ReSharper disable once LoopCanBePartlyConvertedToQuery
                foreach (DB2Hash hashValue in Enum.GetValues(typeof(DB2Hash)))
                {
                    if (HotfixSettings.Instance.ShouldLog(hashValue))
                    {
                        HotfixStoreMgr.GetStore(hashValue)?.Serialize(stringBuilder, null);
                    }
                }
            }
            else
            {
                var emptyStringBuilder = new StringBuilder();

                foreach (DB2Hash hashValue in Enum.GetValues(typeof(DB2Hash)))
                {
                    if (!HotfixSettings.Instance.ShouldLog(hashValue))
                    {
                        continue;
                    }

                    var localeBuilder = new StringBuilder();
                    HotfixStoreMgr.GetStore(hashValue)?.Serialize(stringBuilder, localeBuilder);
                    emptyStringBuilder.Append(localeBuilder);
                }
                return(emptyStringBuilder.ToString());
            }

            return(stringBuilder.ToString());
        }
        public static void HandleDBReply(Packet packet)
        {
            var type      = packet.ReadUInt32E <DB2Hash>("TableHash");
            var entry     = packet.ReadInt32("RecordID");
            var timeStamp = packet.ReadUInt32("Timestamp");
            var allow     = packet.ReadBit("Allow");

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer,
                                     packet.FileName);

            if (entry < 0 || !allow)
            {
                packet.WriteLine("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
                Storage.AddHotfixData(entry, type, true, timeStamp);
            }
            else
            {
                packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                HotfixStoreMgr.AddRecord(type, entry, db2File);
                Storage.AddHotfixData(entry, type, false, timeStamp);
                db2File.ClosePacket(false);
            }
        }
Example #3
0
        public static void HandleDBReply(Packet packet)
        {
            var dbReply = packet.Holder.DbReply = new();
            var type    = packet.ReadUInt32E <DB2Hash>("TableHash");

            dbReply.TableHash = (uint)type;
            var entry     = dbReply.RecordId = packet.ReadInt32("RecordID");
            var allow     = true;
            var timeStamp = packet.ReadUInt32();
            var time      = packet.AddValue("Timestamp", Utilities.GetDateTimeFromUnixTime(timeStamp));

            dbReply.Time = Timestamp.FromDateTime(DateTime.SpecifyKind(time, DateTimeKind.Utc));
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V6_2_0_20173))
            {
                allow = packet.ReadBit("Allow");
            }

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if (entry < 0 || !allow)
            {
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusRecordRemoved;
                packet.WriteLine("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusValid;
                packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                HotfixStoreMgr.AddRecord(type, entry, db2File);
                db2File.ClosePacket(false);
            }
        }
Example #4
0
        static UnitMisc()
        {
            HotfixStoreMgr.OnRecordReceived += (hash, recordKey, added) =>
            {
                if (!added || hash != DB2Hash.BroadcastText)
                {
                    return;
                }

                var record = HotfixStoreMgr.GetStore(hash).GetRecord(recordKey) as IBroadcastTextEntry;
                if (record == null)
                {
                    return;
                }

                if (!SQLDatabase.BroadcastTexts.ContainsKey(record.Text))
                {
                    SQLDatabase.BroadcastTexts[record.Text] = new List <int>();
                }
                SQLDatabase.BroadcastTexts[record.Text].Add(recordKey);

                if (!SQLDatabase.BroadcastText1s.ContainsKey(record.Text1))
                {
                    SQLDatabase.BroadcastText1s[record.Text1] = new List <int>();
                }
                SQLDatabase.BroadcastText1s[record.Text1].Add(recordKey);
            };
        }
Example #5
0
        public static void HandleDBReply(Packet packet)
        {
            var type      = packet.ReadUInt32E <DB2Hash>("TableHash");
            var entry     = packet.ReadInt32("RecordID");
            var allow     = true;
            var timeStamp = packet.ReadUInt32();

            packet.AddValue("Timestamp", Utilities.GetDateTimeFromUnixTime(timeStamp));
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V6_2_0_20173))
            {
                allow = packet.ReadBit("Allow");
            }

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Formatter, packet.FileName);

            if (entry < 0 || !allow)
            {
                packet.Formatter.AppendItem("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
                Storage.AddHotfixData(entry, type, true, timeStamp);
            }
            else
            {
                packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                HotfixStoreMgr.AddRecord(type, entry, db2File);
                Storage.AddHotfixData(entry, type, false, timeStamp);
                db2File.ClosePacket(false);
            }
        }
Example #6
0
        static void ReadHotfixData(Packet packet, params object[] indexes)
        {
            packet.ResetBitReader();

            var id       = packet.ReadUInt64();
            var hotfixId = packet.AddValue("HotfixID", Utilities.PAIR64_LOPART(id), indexes);
            var type     = packet.AddValue("TableHash", (DB2Hash)Utilities.PAIR64_HIPART(id), indexes);

            var entry = packet.ReadInt32("RecordID", indexes);

            packet.ResetBitReader();
            var allow    = packet.ReadBit("Allow", indexes);
            var dataSize = packet.ReadInt32("Size", indexes);
            var data     = packet.ReadBytes(dataSize);
            var db2File  = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if (!allow)
            {
                packet.WriteLine($"Row {entry} has been removed.");
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                HotfixStoreMgr.AddRecord(type, entry, db2File);

                if (HotfixStoreMgr.GetStore(type) == null)
                {
                    db2File.WriteLine($"(Entry: {entry} TableHash: {type}) has missing structure. HotfixBlob entry generated!");
                    db2File.AsHex();

                    HotfixBlob hotfixBlob = new HotfixBlob
                    {
                        TableHash = type,
                        RecordID  = entry,
                        Blob      = "0x" + Utilities.ByteArrayToHexString(data)
                    };

                    Storage.HotfixBlobs.Add(hotfixBlob);
                }
                else if (db2File.Position != db2File.Length)
                {
                    db2File.WriteLine($"(Entry: {entry} TableHash: {type}) has incorrect structure");
                    db2File.AsHex();
                }

                db2File.ClosePacket(false);
            }

            HotfixData hotfixData = new HotfixData
            {
                ID        = hotfixId,
                TableHash = type,
                RecordID  = entry,
                Deleted   = !allow
            };

            Storage.HotfixDatas.Add(hotfixData);
        }
Example #7
0
        static void ReadHotfixData810(Packet packet, List <HotfixRecord> records, params object[] indexes)
        {
            int count = 0;

            foreach (var record in records)
            {
                var hotfixId = packet.AddValue("HotfixID", record.HotfixId, count, indexes, "HotfixRecord");
                var type     = packet.AddValue("TableHash", record.Type, count, indexes, "HotfixRecord");
                var entry    = packet.AddValue("RecordID", record.RecordId, count, indexes, "HotfixRecord");
                var dataSize = packet.AddValue("Size", record.HotfixDataSize, count, indexes, "HotfixRecord");
                var allow    = packet.AddValue("Allow", record.Allow, count, indexes, "HotfixRecord");
                var data     = packet.ReadBytes(dataSize);
                var db2File  = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

                if (!allow)
                {
                    packet.WriteLine($"Row {entry} has been removed.");
                    HotfixStoreMgr.RemoveRecord(type, entry);
                }
                else
                {
                    packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                    HotfixStoreMgr.AddRecord(type, entry, db2File);

                    if (HotfixStoreMgr.GetStore(type) == null)
                    {
                        db2File.WriteLine($"(Entry: {entry} TableHash: {type}) has missing structure. HotfixBlob entry generated!");
                        db2File.AsHex();

                        HotfixBlob hotfixBlob = new HotfixBlob
                        {
                            TableHash = type,
                            RecordID  = entry,
                            Blob      = "0x" + Utilities.ByteArrayToHexString(data)
                        };

                        Storage.HotfixBlobs.Add(hotfixBlob);
                    }
                    else if (db2File.Position != db2File.Length)
                    {
                        db2File.WriteLine($"(Entry: {entry} TableHash: {type}) has incorrect structure");
                        db2File.AsHex();
                    }

                    db2File.ClosePacket(false);
                }

                HotfixData hotfixData = new HotfixData
                {
                    ID        = hotfixId,
                    TableHash = type,
                    RecordID  = entry,
                    Deleted   = !allow
                };

                Storage.HotfixDatas.Add(hotfixData);
                count++;
            }
        }
Example #8
0
        public static void SetVersion(ClientVersionBuild version)
        {
            if (Build == version)
            {
                return;
            }

            Build      = version;
            _expansion = GetExpansion(version);

            Opcodes.InitializeOpcodeDictionary();
            Handler.ResetHandlers();
            UpdateFields.ResetUFDictionaries();

            ClientVersionBuild tmpFallback = FallbackVersionDefiningBuild(VersionDefiningBuild);

            while (tmpFallback != ClientVersionBuild.Zero)
            {
                try
                {
                    var asm = Assembly.Load($"WowPacketParserModule.{tmpFallback}");
                    Trace.WriteLine($"Loading module WowPacketParserModule.{tmpFallback}.dll (fallback)");

                    Handler.LoadHandlers(asm, tmpFallback);
                }
                catch (FileNotFoundException)
                {
                }
                tmpFallback = FallbackVersionDefiningBuild(tmpFallback);
            }

            try
            {
                var asm = Assembly.Load($"WowPacketParserModule.{VersionDefiningBuild}");
                Trace.WriteLine($"Loading module WowPacketParserModule.{VersionDefiningBuild}.dll");

                HotfixStoreMgr.LoadStores(asm);
                Handler.LoadHandlers(asm, VersionDefiningBuild);
                BattlenetHandler.LoadBattlenetHandlers(asm);

                // This is a huge hack to handle the abnormal situation that appeared with builds 6.0 and 6.1 having mostly the same packet structures
                if (!UpdateFields.LoadUFDictionaries(asm, version))
                {
                    UpdateFields.LoadUFDictionaries(asm, VersionDefiningBuild);
                }
            }
            catch (FileNotFoundException)
            {
                // No dll found, try to load the data in the executable itself
                UpdateFields.LoadUFDictionaries(Assembly.GetExecutingAssembly(), Build);
            }
        }
        static void ReadHotfixRecord(Packet packet, int hotfixId, params object[] indexes)
        {
            packet.ResetBitReader();
            var type     = packet.ReadUInt32E <DB2Hash>("TableHash", indexes);
            var entry    = packet.ReadInt32("RecordID", indexes);
            var allow    = packet.ReadBit("Allow", indexes);
            var dataSize = packet.ReadInt32("Size", indexes);
            var data     = packet.ReadBytes(dataSize);
            var db2File  = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if (!allow)
            {
                packet.WriteLine($"Row {entry} has been removed.");
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                HotfixStoreMgr.AddRecord(type, entry, db2File);

                if (db2File.Position != db2File.Length)
                {
                    db2File.WriteLine($"(Entry: {entry} TableHash: {type}) has missing structure");
                    db2File.AsHex();
                }

                db2File.ClosePacket(false);
            }

            HotfixData hotfixData = new HotfixData
            {
                ID        = (uint)hotfixId,
                TableHash = type,
                RecordID  = entry,
                Deleted   = !allow
            };

            Storage.HotfixDatas.Add(hotfixData);
        }
Example #10
0
        public static void HandleDBReply(Packet packet)
        {
            var entry = packet.ReadInt32("Entry");
            packet.ReadTime("Hotfix date");

            var size = packet.ReadInt32("Size");
            var data = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            var type = packet.ReadUInt32E<DB2Hash>("DB2 File");
            if (entry < 0)
            {
                packet.WriteLine("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                HotfixStoreMgr.AddRecord(type, entry, db2File);
                db2File.ClosePacket(false);
            }
        }
Example #11
0
        public static void HandleDBReply(Packet packet)
        {
            var type      = packet.ReadUInt32E <DB2Hash>("TableHash");
            var entry     = packet.ReadInt32("RecordID");
            var timeStamp = packet.ReadUInt32();

            packet.AddValue("Timestamp", Utilities.GetDateTimeFromUnixTime(timeStamp));
            var allow = packet.ReadBit("Allow");

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if (entry < 0 || !allow)
            {
                packet.WriteLine("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                switch (type)
                {
                case DB2Hash.BroadcastText:
                {
                    var bct = new BroadcastText()
                    {
                        Text  = db2File.ReadCString("Text"),
                        Text1 = db2File.ReadCString("Text1"),
                    };

                    bct.ID                   = db2File.ReadUInt32("ID");
                    bct.LanguageID           = db2File.ReadByte("LanguageID");
                    bct.ConditionID          = db2File.ReadUInt32("ConditionID");
                    bct.EmotesID             = db2File.ReadUInt16("EmotesID");
                    bct.Flags                = db2File.ReadByte("Flags");
                    bct.ChatBubbleDurationMs = db2File.ReadUInt32("ChatBubbleDurationMs");

                    bct.SoundEntriesID = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                    {
                        bct.SoundEntriesID[i] = db2File.ReadUInt32("SoundEntriesID", i);
                    }

                    bct.EmoteID    = new ushort?[3];
                    bct.EmoteDelay = new ushort?[3];
                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteID[i] = db2File.ReadUInt16("EmoteID", i);
                    }
                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteDelay[i] = db2File.ReadUInt16("EmoteDelay", i);
                    }

                    Storage.BroadcastTexts.Add(bct, packet.TimeSpan);

                    if (ClientLocale.PacketLocale != LocaleConstant.enUS)
                    {
                        BroadcastTextLocale lbct = new BroadcastTextLocale
                        {
                            ID        = bct.ID,
                            TextLang  = bct.Text,
                            Text1Lang = bct.Text1
                        };
                        Storage.BroadcastTextLocales.Add(lbct, packet.TimeSpan);
                    }
                    break;
                }

                default:
                    HotfixStoreMgr.AddRecord(type, entry, db2File);
                    break;
                }

                db2File.ClosePacket(false);
            }
        }
        public static void HandleDBReply(Packet packet)
        {
            var dbReply = packet.Holder.DbReply = new();
            var type    = packet.ReadUInt32E <DB2Hash>("TableHash");

            dbReply.TableHash = (uint)type;
            var entry     = dbReply.RecordId = packet.ReadInt32("RecordID");
            var timeStamp = packet.ReadUInt32();
            var time      = packet.AddValue("Timestamp", Utilities.GetDateTimeFromUnixTime(timeStamp));

            dbReply.Time = Timestamp.FromDateTime(DateTime.SpecifyKind(time, DateTimeKind.Utc));
            int statusBits = ClientVersion.AddedInVersion(ClientVersionBuild.V9_1_0_39185) ? 3 : 2;
            var status     = packet.ReadBitsE <HotfixStatus>("Status", statusBits);

            switch (status)
            {
            case HotfixStatus.Valid:
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusValid;
                break;

            case HotfixStatus.RecordRemoved:
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusRecordRemoved;
                break;

            case HotfixStatus.Invalid:
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusInvalid;
                break;

            case HotfixStatus.NotPublic:
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusNotPublic;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            switch (status)
            {
            case HotfixStatus.Valid:
            {
                switch (type)
                {
                case DB2Hash.BroadcastText:
                {
                    var bct = new BroadcastText()
                    {
                        Text  = db2File.ReadCString("Text"),
                        Text1 = db2File.ReadCString("Text1"),
                    };

                    bct.ID                   = db2File.ReadUInt32("ID");
                    bct.LanguageID           = db2File.ReadInt32("LanguageID");
                    bct.ConditionID          = db2File.ReadUInt32("ConditionID");
                    bct.EmotesID             = db2File.ReadUInt16("EmotesID");
                    bct.Flags                = db2File.ReadByte("Flags");
                    bct.ChatBubbleDurationMs = db2File.ReadUInt32("ChatBubbleDurationMs");

                    bct.SoundEntriesID = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                    {
                        bct.SoundEntriesID[i] = db2File.ReadUInt32("SoundEntriesID", i);
                    }

                    bct.EmoteID    = new ushort?[3];
                    bct.EmoteDelay = new ushort?[3];
                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteID[i] = db2File.ReadUInt16("EmoteID", i);
                    }
                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteDelay[i] = db2File.ReadUInt16("EmoteDelay", i);
                    }

                    Storage.BroadcastTexts.Add(bct, packet.TimeSpan);

                    if (ClientLocale.PacketLocale != LocaleConstant.enUS)
                    {
                        BroadcastTextLocale lbct = new BroadcastTextLocale
                        {
                            ID        = bct.ID,
                            TextLang  = bct.Text,
                            Text1Lang = bct.Text1
                        };
                        Storage.BroadcastTextLocales.Add(lbct, packet.TimeSpan);
                    }

                    dbReply.BroadcastText = new PacketDbReplyBroadcastText()
                    {
                        Id                 = bct.ID.Value,
                        Text0              = bct.Text,
                        Text1              = bct.Text1,
                        Language           = bct.LanguageID.Value,
                        ConditionId        = bct.ConditionID.Value,
                        EmotesId           = bct.EmotesID.Value,
                        Flags              = bct.Flags.Value,
                        ChatBubbleDuration = bct.ChatBubbleDurationMs.Value,
                    };
                    for (int i = 0; i < 2; ++i)
                    {
                        dbReply.BroadcastText.Sounds.Add(bct.SoundEntriesID[i] ?? 0);
                    }
                    for (int i = 0; i < 3; ++i)
                    {
                        dbReply.BroadcastText.Emotes.Add(new BroadcastTextEmote()
                                {
                                    EmoteId = bct.EmoteID[i] ?? 0, Delay = bct.EmoteDelay[i] ?? 0
                                });
                    }
                    break;
                }

                default:
                    HotfixStoreMgr.AddRecord(type, entry, db2File);
                    break;
                }

                if (db2File.Position != db2File.Length)
                {
                    HandleHotfixOptionalData(packet, type, entry, db2File);
                }

                db2File.ClosePacket(false);
                break;
            }

            case HotfixStatus.RecordRemoved:
            {
                packet.WriteLine($"Row {entry} has been removed.");
                HotfixStoreMgr.RemoveRecord(type, entry);
                break;
            }

            case HotfixStatus.Invalid:
            {
                // sniffs from others may have the data
                packet.WriteLine($"Row {entry} is invalid.");
                break;
            }

            case HotfixStatus.NotPublic:
            {
                packet.WriteLine($"Row {entry} is not public.");
                break;
            }

            default:
            {
                packet.WriteLine($"Unhandled status: {status}");
                break;
            }
            }
        }
        static void ReadHotfixData(Packet packet, List <HotfixRecord> records, params object[] indexes)
        {
            int count = 0;

            foreach (var record in records)
            {
                var hotfixId = packet.AddValue("HotfixID", record.HotfixId, count, indexes, "HotfixRecord");
                var uniqueId = packet.AddValue("UniqueID", record.UniqueId, count, indexes, "HotfixRecord");
                var type     = packet.AddValue("TableHash", record.Type, count, indexes, "HotfixRecord");
                var entry    = packet.AddValue("RecordID", record.RecordId, count, indexes, "HotfixRecord");
                var dataSize = packet.AddValue("Size", record.HotfixDataSize, count, indexes, "HotfixRecord");
                var status   = packet.AddValue("Status", record.Status, count, indexes, "HotfixRecord");
                var data     = packet.ReadBytes(dataSize);
                var db2File  = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

                switch (status)
                {
                case HotfixStatus.Valid:
                {
                    packet.AddSniffData(StoreNameType.None, entry, type.ToString());
                    HotfixStoreMgr.AddRecord(type, entry, db2File);

                    if (HotfixStoreMgr.GetStore(type) == null)
                    {
                        db2File.WriteLine($"(Entry: {entry} TableHash: {type}) has missing structure. HotfixBlob entry generated!");
                        db2File.AsHex();

                        HotfixBlob hotfixBlob = new HotfixBlob
                        {
                            TableHash = type,
                            RecordID  = entry,
                            Blob      = new Blob(data)
                        };

                        Storage.HotfixBlobs.Add(hotfixBlob);
                    }
                    else if (db2File.Position != db2File.Length)
                    {
                        HandleHotfixOptionalData(packet, type, entry, db2File);
                    }

                    db2File.ClosePacket(false);
                    break;
                }

                case HotfixStatus.RecordRemoved:
                {
                    packet.WriteLine($"Row {entry} has been removed.");
                    HotfixStoreMgr.RemoveRecord(type, entry);
                    break;
                }

                case HotfixStatus.Invalid:
                {
                    // sniffs from others may have the data
                    packet.WriteLine($"Row {entry} is invalid.");
                    break;
                }

                default:
                {
                    packet.WriteLine($"Unhandled status: {status}");
                    break;
                }
                }

                HotfixData hotfixData = new HotfixData
                {
                    ID        = hotfixId,
                    UniqueID  = uniqueId,
                    TableHash = type,
                    RecordID  = entry,
                    Status    = status
                };

                Storage.HotfixDatas.Add(hotfixData);
                count++;
            }
        }
Example #14
0
        public static void HandleDBReply(Packet packet)
        {
            var dbReply = packet.Holder.DbReply = new();
            var type    = packet.ReadUInt32E <DB2Hash>("TableHash");

            dbReply.TableHash = (uint)type;
            var entry     = dbReply.RecordId = packet.ReadInt32("RecordID");
            var timeStamp = packet.ReadUInt32();
            var time      = packet.AddValue("Timestamp", Utilities.GetDateTimeFromUnixTime(timeStamp));

            dbReply.Time = Timestamp.FromDateTime(DateTime.SpecifyKind(time, DateTimeKind.Utc));
            var allow = packet.ReadBit("Allow");

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if (entry < 0 || !allow)
            {
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusRecordRemoved;
                packet.WriteLine("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                dbReply.Status = PacketDbReplyRecordStatus.RecordStatusValid;
                switch (type)
                {
                case DB2Hash.BroadcastText:
                {
                    var bct = new BroadcastText()
                    {
                        ID    = (uint)entry,
                        Text  = db2File.ReadCString("Text"),
                        Text1 = db2File.ReadCString("Text1"),
                    };

                    bct.EmoteID    = new ushort?[3];
                    bct.EmoteDelay = new ushort?[3];

                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteID[i] = db2File.ReadUInt16("EmoteID", i);
                    }
                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteDelay[i] = db2File.ReadUInt16("EmoteDelay", i);
                    }

                    bct.EmotesID   = db2File.ReadUInt16("EmotesID");
                    bct.LanguageID = db2File.ReadByte("LanguageID");
                    bct.Flags      = db2File.ReadByte("Flags");

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V7_3_5_25848))
                    {
                        bct.ConditionID = db2File.ReadUInt32("ConditionID");
                    }

                    bct.SoundEntriesID = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                    {
                        bct.SoundEntriesID[i] = db2File.ReadUInt32("SoundEntriesID", i);
                    }

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V7_0_3_22248) && ClientVersion.RemovedInVersion(ClientVersionBuild.V7_3_5_25848))
                    {
                        bct.ConditionID = db2File.ReadUInt32("ConditionID");
                    }

                    Storage.BroadcastTexts.Add(bct, packet.TimeSpan);

                    if (ClientLocale.PacketLocale != LocaleConstant.enUS)
                    {
                        BroadcastTextLocale lbct = new BroadcastTextLocale
                        {
                            ID        = bct.ID,
                            TextLang  = bct.Text,
                            Text1Lang = bct.Text1
                        };
                        Storage.BroadcastTextLocales.Add(lbct, packet.TimeSpan);
                    }

                    dbReply.BroadcastText = new PacketDbReplyBroadcastText()
                    {
                        Id                 = bct.ID.Value,
                        Text0              = bct.Text,
                        Text1              = bct.Text1,
                        Language           = bct.LanguageID.Value,
                        ConditionId        = bct.ConditionID ?? 0,
                        EmotesId           = bct.EmotesID.Value,
                        Flags              = bct.Flags.Value,
                        ChatBubbleDuration = 0,
                    };
                    dbReply.BroadcastText.Sounds.Add(bct.SoundEntriesID1 ?? 0);
                    dbReply.BroadcastText.Sounds.Add(bct.SoundEntriesID2 ?? 0);
                    for (int i = 0; i < 3; ++i)
                    {
                        dbReply.BroadcastText.Emotes.Add(new BroadcastTextEmote()
                            {
                                EmoteId = bct.EmoteID[i] ?? 0, Delay = bct.EmoteDelay[i] ?? 0
                            });
                    }
                    break;
                }

                default:
                    HotfixStoreMgr.AddRecord(type, entry, db2File);
                    break;
                }

                db2File.ClosePacket(false);
            }
        }
Example #15
0
        public static void HandleDBReply(Packet packet)
        {
            var type      = packet.ReadUInt32E <DB2Hash>("TableHash");
            var entry     = packet.ReadInt32("RecordID");
            var timeStamp = packet.ReadUInt32();

            packet.AddValue("Timestamp", Utilities.GetDateTimeFromUnixTime(timeStamp));
            var allow = packet.ReadBit("Allow");

            var size    = packet.ReadInt32("Size");
            var data    = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if (entry < 0 || !allow)
            {
                packet.WriteLine("Row {0} has been removed.", -entry);
                HotfixStoreMgr.RemoveRecord(type, entry);
            }
            else
            {
                switch (type)
                {
                case DB2Hash.BroadcastText:
                {
                    var bct = new BroadcastText()
                    {
                        ID         = (uint)entry,
                        MaleText   = db2File.ReadCString("MaleText"),
                        FemaleText = db2File.ReadCString("FemaleText"),
                    };

                    bct.EmoteID    = new ushort?[3];
                    bct.EmoteDelay = new ushort?[3];

                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteID[i] = db2File.ReadUInt16("EmoteID", i);
                    }
                    for (int i = 0; i < 3; ++i)
                    {
                        bct.EmoteDelay[i] = db2File.ReadUInt16("EmoteDelay", i);
                    }

                    bct.UnkEmoteID = db2File.ReadUInt16("UnkEmoteID");
                    bct.Language   = db2File.ReadByte("Language");
                    bct.Type       = db2File.ReadByte("Type");

                    bct.SoundID = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                    {
                        bct.SoundID[i] = db2File.ReadUInt32("SoundID", i);
                    }

                    bct.PlayerConditionID = db2File.ReadUInt32("PlayerConditionID");

                    Storage.BroadcastTexts.Add(bct, packet.TimeSpan);
                    break;
                }

                default:
                    HotfixStoreMgr.AddRecord(type, entry, db2File);
                    break;
                }

                db2File.ClosePacket(false);
            }
        }
Example #16
0
        static void ReadHotfixData(Packet packet, List <HotfixRecord> records, params object[] indexes)
        {
            for (var i = 0; i < records.Count; ++i)
            {
                var record = records[i];

                packet.AddValue("HotfixId", record.HotfixId, i, indexes, "HotfixRecord");
                packet.AddValue("UniqueId", record.UniqueId, i, indexes, "HotfixRecord");
                packet.AddValue("RecordId", record.RecordId, i, indexes, "HotfixRecord");
                packet.AddValue("TableHash", record.Type, i, indexes, "HotfixRecord");
                packet.AddValue("Status", record.Status, i, indexes, "HotfixRecord");
                packet.AddValue("Size", record.HotfixDataSize, i, indexes, "HotfixRecord");

                switch (record.Status)
                {
                case HotfixStatus.Valid:
                {
                    packet.AddSniffData(StoreNameType.None, record.RecordId, record.Type.ToString());

                    var data = packet.ReadBytes(record.HotfixDataSize);
                    using (var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction,
                                                    packet.Number, packet.Writer, packet.FileName))
                    {
                        HotfixStoreMgr.AddRecord(record.Type, record.RecordId, db2File);

                        if (HotfixStoreMgr.GetStore(record.Type) == null)
                        {
                            db2File.WriteLine($"(RecordID: {record.RecordId} TableHash: {record.Type}) has missing structure. HotfixBlob entry generated!");
                            db2File.AsHex();

                            var hotfixBlob = new HotfixBlob
                            {
                                TableHash = record.Type,
                                RecordID  = record.RecordId,
                                Blob      = new Blob(data)
                            };

                            Storage.HotfixBlobs.Add(hotfixBlob);
                        }
                        else if (db2File.Position != db2File.Length)
                        {
                            HandleHotfixOptionalData(packet, record.Type, record.RecordId, db2File);
                        }
                    }

                    break;
                }

                case HotfixStatus.Invalid:
                {
                    packet.WriteLine($"Row {record.RecordId} is invalid.");
                    break;
                }

                case HotfixStatus.RecordRemoved:
                {
                    packet.WriteLine($"Row {record.RecordId} has been deleted.");
                    HotfixStoreMgr.RemoveRecord(record.Type, record.RecordId);
                    break;
                }

                default:
                {
                    packet.WriteLine($"Row: {record.RecordId} TableHash: {record.Type} has unknown Status: {record.Status}");
                    break;
                }
                }

                var hotfixData = new HotfixData
                {
                    ID        = record.HotfixId,
                    TableHash = record.Type,
                    RecordID  = record.RecordId,
                    Status    = record.Status
                };
                Storage.HotfixDatas.Add(hotfixData);
            }
        }