private void WriteDamageLog(DamageMeterRow a) { SortableBindingList <DamageMeterRow> updateList; // if we got new combat data, and we clicked reset, reset the meter if (!watch.IsRunning) { totalDamage = 0; updateList = new SortableBindingList <DamageMeterRow>(); watch.Restart(); } else { updateList = new SortableBindingList <DamageMeterRow>(AttackerList.ToList()); } totalDamage += a.DamageSum; // adding to the total damage of the parser bool found = false; foreach (var attacker in updateList) { if (attacker.Name == a.Name) { found = true; attacker.DamageSum += a.DamageSum; if (attacker.highestDamage < a.DamageSum) { attacker.highestDamage = a.DamageSum; attacker.skillId = a.skillId; } } attacker.DamagePercent = attacker.DamageSum / totalDamage; } if (!found) { var row = new DamageMeterRow { Name = a.Name, DamageSum = a.DamageSum, highestDamage = a.DamageSum, entityId = a.entityId, skillId = a.skillId, DamagePercent = a.DamageSum / totalDamage }; updateList.Add(row); } // sorting the list as descending AttackerList = new SortableBindingList <DamageMeterRow>(updateList.OrderByDescending(x => x.DamagePercent).ToList()); this.InvokeIfRequired((MethodInvoker) delegate { // total damage display label2.Text = $"- {totalDamage:n0} DMG"; encounterDataGridView.DataSource = AttackerList; }); }
private void ProcessCombatPacket(Msg msg) { int id = msg.Packet.GetInt(); if (packetIdSet.Contains(id)) { return; } else { packetIdSet.Add(id); } int prevId = msg.Packet.GetInt(); byte hit = msg.Packet.GetByte(); if (hit == 0) { return; } byte maxHits = msg.Packet.GetByte(); msg.Packet.GetByte(); msg.Packet.GetByte(); var count = msg.Packet.GetInt(); var payload = new CombatActionPayload(); for (int i = 0; i < count; ++i) { var len = msg.Packet.GetInt(); if (msg.Packet.Peek() != PacketElementType.Bin) { msg.Packet.GetLong(); count = msg.Packet.GetInt(); len = msg.Packet.GetInt(); } var buff = msg.Packet.GetBin(); var actionPacket = new Packet(buff, 0); actionPacket.GetInt(); var creatureEntityId = actionPacket.GetLong(); payload.CreatureEntityId = creatureEntityId; var type = (CombatActionType)actionPacket.GetByte(); payload.Type = type; var attackeraction = len < 86 && type != 0; // Hot fix, TODO: Proper check of type. payload.IsAttackerAction = attackeraction; short stun = actionPacket.GetShort(); ushort skillId = actionPacket.GetUShort(); actionPacket.GetShort(); if (actionPacket.Peek() == PacketElementType.Short) { actionPacket.GetShort(); // [200300, NA258 (2017-08-19)] ? } // AttackerAction if (attackeraction) { payload.SkillId = (SkillId)skillId; if (actionPacket.Peek() != PacketElementType.None) { long target = actionPacket.GetLong(); var options = new List <uint>(); var topt = actionPacket.GetInt(); for (uint foo2 = 1; foo2 < 0x80000000;) { if ((topt & foo2) != 0) { options.Add(foo2); } foo2 <<= 1; } var strOptions = string.Join(", ", options.Select(a => { var en = (AttackerOptions)a; return("0x" + a.ToString("X2") + (en.ToString() != a.ToString() ? "(" + en + ")" : "")); })); actionPacket.GetByte(); actionPacket.GetByte(); actionPacket.GetInt(); int x = actionPacket.GetInt(); int y = actionPacket.GetInt(); long prop = 0L; if (actionPacket.NextIs(PacketElementType.Long)) { prop = actionPacket.GetLong(); } } } // TargetAction else { // Target actions might end here, widnessed with a packet // that had "97" as the previous short. if (actionPacket.Peek() != PacketElementType.None) { // Target used Defense or Counter if (type.HasFlag(CombatActionType.Unk) || type.HasFlag(CombatActionType.Defended) || type.HasFlag(CombatActionType.CounteredHit) || type.HasFlag((CombatActionType)0x73) || type.HasFlag((CombatActionType)0x13)) { var attackerEntityId = actionPacket.GetLong(); actionPacket.GetInt(); actionPacket.GetByte(); actionPacket.GetByte(); actionPacket.GetInt(); var x = actionPacket.GetInt(); var y = actionPacket.GetInt(); } if (actionPacket.Peek() == PacketElementType.Long) // fighter counter ? { actionPacket.GetLong(); } var options = new List <uint>(); var topt = actionPacket.GetInt(); for (uint foo2 = 1; foo2 < 0x80000000;) { if ((topt & foo2) != 0) { options.Add(foo2); } foo2 <<= 1; } payload.TargetOptions = new List <TargetOptions>(); foreach (TargetOptions option in options) { payload.TargetOptions.Add(option); } var strOptions = string.Join(", ", options.Select(a => { var en = (TargetOptions)a; return("0x" + a.ToString("X2") + (en.ToString() != a.ToString() ? "(" + en + ")" : "")); })); float damage = actionPacket.GetFloat(); payload.Damage = damage; float woundDamage = actionPacket.GetFloat(); payload.WoundDamage = woundDamage; int manaDamage = actionPacket.GetInt(); payload.ManaDamage = manaDamage; if (actionPacket.NextIs(PacketElementType.Int)) { actionPacket.GetInt(); // [210100, NA280 (2018-06-14)] } float xDiff = actionPacket.GetFloat(); float yDiff = actionPacket.GetFloat(); if (actionPacket.NextIs(PacketElementType.Float)) { float newX = actionPacket.GetFloat(); float newY = actionPacket.GetFloat(); // [190200, NA203 (22.04.2015)] if (actionPacket.Peek() == PacketElementType.Int) { actionPacket.GetInt(); } } while (actionPacket.NextIs(PacketElementType.Int)) { // ?? actionPacket.GetInt(); } byte effectiveFlags = actionPacket.GetByte(); int delay = actionPacket.GetInt(); long attacker = actionPacket.GetLong(); payload.Attacker = attacker; } } // pushing payload to logfile if (payload.SkillId != SkillId.None && characters.ContainsKey(payload.Attacker)) { string name = characters.SafeGet(payload.Attacker); if (name == null) { return; } var attacker = new DamageMeterRow { entityId = payload.Attacker, Name = name, DamageSum = payload.Damage, skillId = SkillIdHelper.GetSkillName((ushort)payload.SkillId), }; WriteDamageLog(attacker); } } }