public void ReadAddonsInfo(byte[] data, int size) { uint Size = BitConverter.ToUInt32(data, 0); byte[] Data = new byte[size]; Array.Copy(data, 4, Data, 0, size); if (Size == 0) { return; } if (Size > 0xFFFFF) { Log.outError("ReadAddonsInfo addon info too big, size {0}", size); return; } PacketReader addonInfo = new PacketReader(ZlibStream.UncompressBuffer(Data), false); if (addonInfo != null) { uint addonsCount = addonInfo.ReadUInt32(); for (uint i = 0; i < addonsCount; ++i) { // check next addon data format correctness if ((addonInfo.BaseStream.Position) + 1 > addonInfo.BaseStream.Length) { return; } string addonName = addonInfo.ReadCString(); byte enabled = addonInfo.ReadByte(); uint crc = addonInfo.ReadUInt32(); uint unk1 = addonInfo.ReadUInt32(); Log.outDebug("ADDON: Name: {0}, Enabled: 0x{1}, CRC: 0x{2}, Unknown2: 0x{3}", addonName, enabled, crc, unk1); AddonInfo addon = new AddonInfo(addonName, enabled, crc, 2, true); SavedAddon savedAddon = Addon.GetAddonInfo(addonName); if (savedAddon != null) { bool match = true; if (addon.CRC != savedAddon.CRC) { match = false; } if (!match) { Log.outWarn("ADDON: {0} was known, but didn't match known CRC (0x{1})!", addon.Name, savedAddon.CRC); } } else { Addon.SaveAddon(addon); Log.outWarn("ADDON: {0} (0x{1}) was not known, saving...", addon.Name, addon.CRC); } // TODO: Find out when to not use CRC/pubkey, and other possible states. addonsList.Add(addon); } uint currentTime = addonInfo.ReadUInt32(); Log.outDebug("ADDON: CurrentTime: {0}", currentTime); //if (addonInfo.rpos() != addonInfo.size()) //sLog->outDebug(LOG_FILTER_NETWORKIO, "packet under-read!"); } else { Log.outError("Addon packet uncompress error!"); } }