public GeneratorManager(IGenerator generator) { _CurrentEntities = new Dictionary <long, EncounterDisplayInfo.Entity>(); generator.EncounterDataChanged += (sender, args) => { var newStepCount = args.Current.Steps.Count - (_CurrentEncounter?.Steps?.Count ?? 0); var newSteps = args.Current.Steps.Skip(args.Current.Steps.Count - newStepCount); foreach (var s in newSteps) { _HandleStep(s); } _CurrentEncounter = args.Current; // TODO: extra encounter display info data will require caching EncounterInfoChanged?.Invoke(this, new EncounterDisplayInfo { Entities = _CurrentEntities.Values }); }; }
public async Task RunAsync(CancellationToken ct) { await _Socket.ConnectAsync(new Uri("ws://localhost:48480"), ct); var messageBuffer = new List <byte>(); var buffer = new ArraySegment <byte>(new byte[2048]); while (true) { ct.ThrowIfCancellationRequested(); var receive = await _Socket.ReceiveAsync(buffer, ct); messageBuffer.AddRange(buffer.Take(receive.Count)); if (!receive.EndOfMessage) { continue; } var messageString = Encoding.UTF8.GetString(messageBuffer.ToArray()); messageBuffer.Clear(); var message = JsonConvert.DeserializeObject <PSRTMessage>(messageString); switch (message.Identifier) { case "pso2.character_info": { var characterInfoMessage = JsonConvert.DeserializeObject <CharacterInfoMessage>(message.Message.ToString()); if (!_CharacterCache.ContainsKey(characterInfoMessage.Account)) { _CharacterCache[characterInfoMessage.Account] = new EncounterPlayer { Account = characterInfoMessage.Account, Name = characterInfoMessage.Name }; } else { _CharacterCache[characterInfoMessage.Account].Name = characterInfoMessage.Name; } } break; case "pso2.damage": { var damageMessage = JsonConvert.DeserializeObject <DamageMessage>(message.Message.ToString()); if (_CurrentEncounter == null) { _CurrentEncounter = new PartialEncounter { Start = DateTime.UtcNow, Steps = new List <EncounterStep>() } } ; // create new encounter instance to avoid race conditions var encounterSteps = new List <EncounterStep>(_CurrentEncounter.Steps); _CurrentEncounter = new PartialEncounter { Start = _CurrentEncounter.Start, Steps = encounterSteps }; if (!_CharacterCache.ContainsKey(damageMessage.Account)) { _CharacterCache[damageMessage.Account] = new EncounterPlayer { Account = damageMessage.Account, Name = damageMessage.Account.ToString() } } ; encounterSteps.Add(new EncounterStep { Offset = DateTime.UtcNow - _CurrentEncounter.Start, Source = _CharacterCache[damageMessage.Account], Ability = new EncounterAbility { Account = damageMessage.Action, Name = "Todo", AbilityType = damageMessage.Value < 0 ? EncounterAbilityType.Heal : EncounterAbilityType.Damage, Value = Math.Abs(damageMessage.Value), IsJustAttack = (damageMessage.Flags & DamageMessage.DamageFlags.JustAttack) != 0, IsCriticalAttack = (damageMessage.Flags & DamageMessage.DamageFlags.Critical) != 0, } }); EncounterDataChanged?.Invoke(this, new GeneratorEncounterDataChangedEventArgs { Current = _CurrentEncounter }); } break; default: return; } } }