public static void WriteCharacterData(this IPacketWriter p, Character c, CharacterDataFlags flags = CharacterDataFlags.All) { p.WriteLong((long)flags); p.WriteByte(0); p.WriteByte(0); if (flags.HasFlag(CharacterDataFlags.Character)) { p.WriteCharacterStats(c); p.WriteByte(250); // nFriendMax p.WriteBool(false); } if (flags.HasFlag(CharacterDataFlags.Money)) p.WriteInt(c.Money); if (flags.HasFlag(CharacterDataFlags.InventorySize)) { if (flags.HasFlag(CharacterDataFlags.ItemSlotEquip)) p.WriteByte((byte)c.Inventories[ItemInventoryType.Equip].SlotMax); if (flags.HasFlag(CharacterDataFlags.ItemSlotConsume)) p.WriteByte((byte)c.Inventories[ItemInventoryType.Consume].SlotMax); if (flags.HasFlag(CharacterDataFlags.ItemSlotInstall)) p.WriteByte((byte)c.Inventories[ItemInventoryType.Install].SlotMax); if (flags.HasFlag(CharacterDataFlags.ItemSlotEtc)) p.WriteByte((byte)c.Inventories[ItemInventoryType.Etc].SlotMax); if (flags.HasFlag(CharacterDataFlags.ItemSlotCash)) p.WriteByte((byte)c.Inventories[ItemInventoryType.Cash].SlotMax); } if (flags.HasFlag(CharacterDataFlags.AdminShopCount)) { p.WriteInt(0); p.WriteInt(0); } if (flags.HasFlag(CharacterDataFlags.ItemSlotEquip)) { var inventory = c.Inventories[ItemInventoryType.Equip].Items; var equip = inventory.Where(kv => kv.Key >= 0); var equipped = inventory.Where(kv => kv.Key >= -100 && kv.Key < 0); var equipped2 = inventory.Where(kv => kv.Key >= -1000 && kv.Key < -100); var dragonEquipped = inventory.Where(kv => kv.Key >= -1100 && kv.Key < -1000); var mechanicEquipped = inventory.Where(kv => kv.Key >= -1200 && kv.Key < -1100); new List<IEnumerable<KeyValuePair<short, AbstractItemSlot>>> { equipped, equipped2, equip, dragonEquipped, mechanicEquipped } .ForEach(e => { e.ForEach(kv => { p.WriteShort((short)(Math.Abs(kv.Key) % 100)); p.WriteItemData(kv.Value); }); p.WriteShort(0); }); } new List<(CharacterDataFlags, ItemInventoryType)> { (CharacterDataFlags.ItemSlotConsume, ItemInventoryType.Consume), (CharacterDataFlags.ItemSlotInstall, ItemInventoryType.Install), (CharacterDataFlags.ItemSlotEtc, ItemInventoryType.Etc), (CharacterDataFlags.ItemSlotCash, ItemInventoryType.Cash) } .Where(t => flags.HasFlag(t.Item1)) .ForEach(t => { var inventory = c.Inventories[t.Item2].Items; inventory.ForEach(kv => { p.WriteByte((byte)kv.Key); p.WriteItemData(kv.Value); }); p.WriteByte(0); }); if (flags.HasFlag(CharacterDataFlags.SkillRecord)) { p.WriteShort((short)c.SkillRecord.Count); c.SkillRecord.ForEach(kv => { p.WriteInt(kv.Key); p.WriteInt(kv.Value.Level); p.WriteDateTime(kv.Value.DateExpire ?? GameConstants.Permanent); if (GameConstants.IsSkillNeedMasterLevel(kv.Key)) p.WriteInt(kv.Value.MasterLevel ?? 0); }); } if (flags.HasFlag(CharacterDataFlags.SkillCooltime)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.QuestRecord)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.QuestComplete)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.MinigameRecord)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.CoupleRecord)) { p.WriteShort(0); // Couple p.WriteShort(0); // Friend p.WriteShort(0); // Marriage } if (flags.HasFlag(CharacterDataFlags.MapTransfer)) { for (var i = 0; i < 5; i++) p.WriteInt(0); for (var i = 0; i < 10; i++) p.WriteInt(0); } if (flags.HasFlag(CharacterDataFlags.NewYearCard)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.QuestRecordEx)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.WildHunterInfo)) { if (c.Job / 100 == 33) { p.WriteByte(0); for (var i = 0; i < 5; i++) p.WriteInt(0); } } if (flags.HasFlag(CharacterDataFlags.QuestCompleteOld)) { p.WriteShort(0); } if (flags.HasFlag(CharacterDataFlags.VisitorLog)) { p.WriteShort(0); } }