Exemplo n.º 1
0
        public void ParseLine(string line)
        {
            string[] lineContents = line.Split('|');

            int.TryParse(lineContents[0], out int messageType);

            if ((LogMessageType)messageType != LogMessageType.NetworkAOEAbility)
            {
                firstAOELine = true;
            }

            switch ((LogMessageType)messageType)
            {
            case LogMessageType.LogLine:
                break;

            case LogMessageType.ChangeZone:

                zoneName = lineContents[3];

                if (ZoneData.zoneInfo.ContainsKey(zoneName))
                {
                    bossInformation           = ZoneData.zoneInfo[zoneName];
                    currentEncounter.zoneName = zoneName;
                    currentEncounter.bosses   = bossInformation;
                    currentEncounter.combatants.Clear();

                    Debug.WriteLine($"Entered {zoneName}...");
                }
                else
                {
                    Debug.WriteLine($"Entered {zoneName}...");

                    currentEncounter = new Encounter(zoneName);
                }

                break;

            case LogMessageType.ChangePrimaryPlayer:
                break;

            case LogMessageType.AddCombatant:
                Combatant addCombatant = ReadCombatant(lineContents);

                currentEncounter.combatants.Add(addCombatant);

                if (addCombatant.ID.ToString("X8").StartsWith("10"))
                {
                    if (!currentEncounter.partyMemberIDs.Contains(addCombatant.ID))
                    {
                        currentEncounter.partyMemberIDs.Add(addCombatant.ID);
                    }
                }

                foreach (BossInfo boss in currentEncounter.bosses)
                {
                    if (boss.Name == addCombatant.Name && boss.Level == addCombatant.Level && (boss.MaxHP == addCombatant.Health.MaxHP || boss.MaxHP == addCombatant.Health.CurrentHP))
                    {
                        currentEncounter.endedEncounter = false;
                    }
                }

                break;

            case LogMessageType.RemoveCombatant:
                Combatant removeCombatant = ReadCombatant(lineContents);

                currentEncounter.combatants.Remove(removeCombatant);
                break;

            case LogMessageType.AddBuff:
                break;

            case LogMessageType.RemoveBuff:
                break;

            case LogMessageType.FlyingText:
                break;

            case LogMessageType.OutgoingAbility:
                break;

            case LogMessageType.IncomingAbility:
                break;

            case LogMessageType.PartyList:

                //If the encounter hasnt started yet form the party memebers
                //This is to avoid the struggles of someone dcing and changing the party size which could end up crashing this algorithm
                if (!string.IsNullOrEmpty(currentEncounter.zoneName) && !currentEncounter.startedEncounter)
                {
                    currentEncounter.partyMemberIDs.Clear();

                    uint.TryParse(lineContents[2], out uint size);

                    int start = 3;     //Start of first memeber and going to start + size

                    try
                    {
                        for (int i = 0; i < size; i++)
                        {
                            currentEncounter.partyMemberIDs.Add(Convert.ToUInt32(lineContents[start + i], 16));
                        }
                    }
                    catch (OverflowException ex)
                    {
                        Debug.WriteLine("Someone seemed to have disconnected!");
                    }
                }

                break;

            case LogMessageType.PlayerStats:
                break;

            case LogMessageType.CombatantHP:
                break;

            case LogMessageType.ParsedPartyMember:
                break;

            case LogMessageType.NetworkStartsCasting:
                NetworkAbilityCast networkAbilityCast = ReadNetworkCast(lineContents);

                currentEncounter.networkCastingAbilities.Add(networkAbilityCast);

                Combatant combatant = currentEncounter.GetCombatantFromID(networkAbilityCast.ActorID);

                //They started casting so we count this as a skill usage even if cancelled or interruped

                if (combatant != null && !currentEncounter.startedEncounter && currentEncounter.bosses.Any(boss => boss.Name == networkAbilityCast.TargetName))
                {
                    currentEncounter.events.Add(new ReportEvent
                    {
                        EventTime        = networkAbilityCast.Timestamp.TimeOfDay,
                        EventDescription = $"{networkAbilityCast.ActorName} casts {networkAbilityCast.SkillName} on {networkAbilityCast.TargetName}",
                        EventType        = EventType.Summary | EventType.DamageDone
                    });
                }

                if (combatant != null)
                {
                    if (!combatant.AbilityInfo.ContainsKey(networkAbilityCast.SkillName))
                    {
                        combatant.AbilityInfo.Add(networkAbilityCast.SkillName, new AbilityInfo());
                    }

                    combatant.AbilityInfo[networkAbilityCast.SkillName].CastAmount++;
                }


                break;

            case LogMessageType.NetworkAbility:
            case LogMessageType.NetworkAOEAbility:
                if (bossInformation.Count == 0)
                {
                    break;
                }

                NetworkAbility ability = ReadAbilityUsed(lineContents);

                combatant = currentEncounter.GetCombatantFromID(ability.ActorID);

                //Check if the ability used is a new skill if it is lets keep track of it from the combatant side
                //Itll be updated in the NetworkEffectResult since thats when the information is able to be deteced
                if (combatant != null)
                {
                    if (!combatant.AbilityInfo.ContainsKey(ability.SkillName))
                    {
                        combatant.AbilityInfo.Add(ability.SkillName, new AbilityInfo());
                    }

                    if (((LogMessageType)messageType == LogMessageType.NetworkAOEAbility && firstAOELine) || (LogMessageType)messageType == LogMessageType.NetworkAbility)
                    {
                        combatant.AbilityInfo[ability.SkillName].CastAmount++;
                        firstAOELine = false;
                    }
                }

                if (!currentEncounter.startedEncounter && bossInformation.Any(boss => boss.Name == ability.TargetName))
                {
                    currentEncounter.startTime = ability.Timestamp;
                    Debug.WriteLine($"Start of fight: {ability.Timestamp}");
                    currentEncounter.startedEncounter = true;

                    currentEncounter.AdjustTimeSpans();     //Makes time negative since actions happened before the start
                }

                if (currentEncounter.startedEncounter)
                {
                    currentEncounter.events.Add(new ReportEvent
                    {
                        EventTime        = ability.Timestamp.Subtract(currentEncounter.startTime),
                        EventDescription = $"{ability.ActorName} prepares {ability.SkillName} on {ability.TargetName} {ability.GetAbilityDamageInformation()}",
                        EventType        = EventType.Summary | (ability.AbilityState == AbilityState.Damage? EventType.DamageDone : EventType.Healing)
                    });

                    currentEncounter.abilities.Add(ability);
                }

                break;

            case LogMessageType.NetworkCancelAbility:
                NetworkAbilityCancel networkAbilityCancel = ReadNetworkSkillCancel(lineContents);
                break;

            case LogMessageType.NetworkDoT:
                break;

            case LogMessageType.NetworkDeath:
                NetworkDeath death = ReadNetworkDeath(lineContents);

                if (currentEncounter.startedEncounter)
                {
                    currentEncounter.events.Add(new ReportEvent
                    {
                        EventTime        = death.Timestamp.Subtract(currentEncounter.startTime),
                        EventDescription = $"{death.ActorName} dies."
                    });
                }

                break;

            case LogMessageType.NetworkBuff:
                NetworkBuff networkBuff = ReadNetworkBuff(lineContents);

                if (currentEncounter.startedEncounter)
                {
                    currentEncounter.events.Add(new ReportEvent
                    {
                        EventTime        = networkBuff.Timestamp.Subtract(currentEncounter.startTime),
                        EventDescription = $"{networkBuff.TargetName} gains {networkBuff.SkillName} from {networkBuff.ActorName}",
                        EventType        = EventType.Summary
                    });
                }

                break;

            case LogMessageType.NetworkTargetIcon:
                break;

            case LogMessageType.NetworkTargetMarker:
                break;

            case LogMessageType.NetworkBuffRemove:
                break;

            case LogMessageType.NetworkGauge:
                break;

            case LogMessageType.NetworkWorld:
                break;

            case LogMessageType.Network6D:

                if (currentEncounter.startedEncounter)
                {
                    if (lineContents[3] == "40000010")    //Ending Wipe
                    {
                        currentEncounter.endedEncounter = true;
                        currentEncounter.endTime        = DateTime.Parse(lineContents[1]);

                        encounters.Add(currentEncounter);

                        Debug.WriteLine($"A wipe has occurred... It took {currentEncounter.endTime.Subtract(currentEncounter.startTime)}");

                        currentEncounter.DumpSummaryToFile(encounterDirectoryInfo);

                        currentEncounter = (Encounter)currentEncounter.Clone();
                    }
                }

                break;

            case LogMessageType.NetworkNameToggle:
                break;

            case LogMessageType.NetworkTether:
                break;

            case LogMessageType.NetworkLimitBreak:
                LimitBreak limitBreak = ReadLimitBreak(lineContents);

                if (currentEncounter.startedEncounter)
                {
                    currentEncounter.events.Add(new ReportEvent
                    {
                        EventTime        = limitBreak.Timestamp.Subtract(currentEncounter.startTime),
                        EventDescription = $"The limit break guage has been updated to {limitBreak.LimitBreakGuage}. {limitBreak.MaxLimitBreakNumber} bars are available.",
                        EventType        = EventType.Summary
                    });
                }

                break;

            case LogMessageType.NetworkEffectResult:
                NetworkEffectResult result = ReadNetworkEffectResult(lineContents);

                foreach (BossInfo boss in currentEncounter.bosses)
                {
                    if (result.ActorName == boss.Name && result.Health.CurrentHP == 0 && boss.HasToDie)
                    {
                        boss.IsDead = true;
                    }
                }

                //Figure out the damage the skill inflicted and then go back and credit the ability for that damage

                if (currentEncounter.startedEncounter && !currentEncounter.endedEncounter && currentEncounter.AreRequiredBossesDead())
                {
                    currentEncounter.endedEncounter = true;
                    currentEncounter.endTime        = result.Timestamp;
                    currentEncounter.isCleared      = true;

                    encounters.Add(currentEncounter);

                    Debug.WriteLine($"Encounter cleared!!! It took {currentEncounter.endTime.Subtract(currentEncounter.startTime)}");

                    currentEncounter.DumpSummaryToFile(encounterDirectoryInfo);

                    currentEncounter = (Encounter)currentEncounter.Clone();
                }

                if (currentEncounter.startedEncounter)
                {
                    combatant = currentEncounter.GetCombatantFromID(result.ActorID);

                    if (combatant != null)
                    {
                        int healthChange = combatant.Health - result.Health;

                        combatant.Health.CurrentHP -= (uint)healthChange;

                        NetworkAbility networkAbility = currentEncounter.abilities.Where(ability => ability.Damage == (uint)Math.Abs(healthChange)).FirstOrDefault();

                        if (networkAbility != null)
                        {
                            currentEncounter.events.Add(new ReportEvent
                            {
                                EventTime        = result.Timestamp.Subtract(currentEncounter.startTime),
                                EventDescription = $"{networkAbility.ActorName} {networkAbility.SkillName} {networkAbility.TargetName} {networkAbility.Damage}",
                                EventType        = EventType.Summary | (networkAbility.AbilityState == AbilityState.Damage ? EventType.DamageDone : EventType.Healing)
                            });

                            currentEncounter.abilities.Remove(networkAbility);

                            Combatant caster = currentEncounter.GetCombatantFromID(networkAbility.ActorID);

                            AbilityInfo abilityInfo = caster.AbilityInfo[networkAbility.SkillName];

                            abilityInfo.HitCount++;

                            if (networkAbility.AbilityState == AbilityState.Damage)
                            {
                                abilityInfo.DamageInformation.TotalDamageDone += (uint)healthChange;
                                abilityInfo.DamageInformation.DPS              = abilityInfo.DamageInformation.TotalDamageDone / (result.Timestamp.Subtract(currentEncounter.startTime).TotalSeconds);
                            }
                            else if (networkAbility.AbilityState == AbilityState.Healing)
                            {
                                abilityInfo.HealingInformation.TotalHealingDone += (uint)Math.Abs(healthChange);
                                abilityInfo.HealingInformation.HPS = abilityInfo.HealingInformation.TotalHealingDone / (result.Timestamp.Subtract(currentEncounter.startTime).TotalSeconds);
                            }
                        }
                    }
                }

                break;

            case LogMessageType.NetworkStatusList:
                NetworkStatusList networkStatusList = ReadNetworkStatusList(lineContents);

                if (currentEncounter.startedEncounter)
                {
                    combatant = currentEncounter.GetCombatantFromID(networkStatusList.TargetID);

                    if (combatant != null)
                    {
                        int healthChange = combatant.Health - networkStatusList.Health;

                        combatant.Health.CurrentHP -= (uint)healthChange;
                    }
                }


                foreach (BossInfo boss in currentEncounter.bosses)
                {
                    if (networkStatusList.TargetName == boss.Name && networkStatusList.Health.CurrentHP == 0 && boss.HasToDie)
                    {
                        boss.IsDead = true;
                    }
                }

                //Figure out the damage the skill inflicted and then go back and credit the ability for that damage

                if (currentEncounter.startedEncounter && !currentEncounter.endedEncounter && currentEncounter.AreRequiredBossesDead())
                {
                    currentEncounter.endedEncounter = true;
                    currentEncounter.endTime        = networkStatusList.Timestamp;
                    currentEncounter.isCleared      = true;

                    encounters.Add(currentEncounter);

                    Debug.WriteLine($"Encounter cleared!!! It took {currentEncounter.endTime.Subtract(currentEncounter.startTime)}");

                    currentEncounter.DumpSummaryToFile(encounterDirectoryInfo);

                    currentEncounter = (Encounter)currentEncounter.Clone();
                }

                break;

            case LogMessageType.NetworkUpdateHp:
                combatant = ReadNetworkUpdateHP(lineContents);

                if (currentEncounter.startedEncounter)
                {
                    Combatant oldCombatant = currentEncounter.GetCombatantFromID(combatant.ID);
                    if (oldCombatant != null)
                    {
                        oldCombatant.Health = combatant.Health;
                    }
                }

                break;

            case LogMessageType.Settings:
                string[] settings = lineContents[2].Split(',');

                //Debug.WriteLine("ACT Settings:");
                foreach (string setting in settings)
                {
                    //Debug.WriteLine(setting.Trim());
                }

                break;

            case LogMessageType.Process:
                break;

            case LogMessageType.Debug:
                break;

            case LogMessageType.PacketDump:
                break;

            case LogMessageType.Version:
                //Debug.WriteLine($"You are using {lineContents[2]}");
                break;

            case LogMessageType.Error:
                break;

            case LogMessageType.Timer:
                break;
            }
        }