private void HandlePlayerStateUpdates() { foreach (BasePlayerState stateUpdate in currentTick.PlayerStates) { PlayerStateType updateType = stateUpdate.Type; long steamId = Demo.SteamIDMappings[stateUpdate.SteamIDIndex]; Player p; //Get from or add current player to dict of known players if (currentPlayers.ContainsKey(steamId)) { p = currentPlayers[steamId]; } else { p = new Player() { SteamID = steamId, }; currentPlayers.Add(steamId, p); } //Update position if (updateType == PlayerStateType.Position || updateType == PlayerStateType.Full) { PositionPlayerState positionUpdate = (PositionPlayerState)stateUpdate; p.Position = positionUpdate.Position; p.ViewOffset = new Vector(0, 0, positionUpdate.ViewOffsetZ); p.Velocity = positionUpdate.Velocity; p.ViewDirectionX = positionUpdate.ViewDirectionX; p.ViewDirectionY = positionUpdate.ViewDirectionY; } //Update full if (updateType == PlayerStateType.Full) { FullPlayerState fullUpdate = (FullPlayerState)stateUpdate; p.Name = Demo.NameMappings[fullUpdate.NameIndex]; p.HP = fullUpdate.HP; p.Armor = fullUpdate.Armor; p.FlashDuration = fullUpdate.FlashDuration; p.Money = fullUpdate.Money; p.CurrentEquipmentValue = fullUpdate.CurrentEquipmentValue; p.FreezetimeEndEquipmentValue = fullUpdate.FreezetimeEndEquipmentValue; p.RoundStartEquipmentValue = fullUpdate.RoundStartEquipmentValue; p.IsDucking = fullUpdate.IsDucking; p.ActiveWeaponID = fullUpdate.ActiveWeaponID; p.Team = fullUpdate.Team; p.HasDefuseKit = fullUpdate.HasDefuseKit; p.HasHelmet = fullUpdate.HasHelmet; p.RawWeapons = fullUpdate.Weapons; p.IsScoped = fullUpdate.IsScoped; p.ShotsFired = fullUpdate.ShotsFired; p.AimPunchAngle = fullUpdate.AimPunchAngle; p.AmmoLeft = new int[32]; for (int i = 0; i < 32; i++) { if (fullUpdate.AmmoLeft.ContainsKey((byte)i)) { p.AmmoLeft[i] = fullUpdate.AmmoLeft[(byte)i]; } else { p.AmmoLeft[i] = 0; } } } } }
private void HandleTickDone(object sender, TickDoneEventArgs e) { CurrentTick.IngameTick = Parser.IngameTick; if (Parser.CTScore != lastCtScore || Parser.TScore != lastTScore || Parser.CTClanName != lastCtName || Parser.TClanName != lastTName || Parser.CTFlag != lastCtFlag || Parser.TFlag != lastTFlag) { TeanInfoUpdateEvent infoUpdate = new TeanInfoUpdateEvent() { CTScore = Parser.CTScore, TScore = Parser.TScore, CTName = Parser.CTClanName, TName = Parser.TClanName, CTFlag = Parser.CTFlag, TFlag = Parser.TFlag }; lastCtScore = Parser.CTScore; lastTScore = Parser.TScore; lastCtName = Parser.CTClanName; lastTName = Parser.TClanName; lastCtFlag = Parser.CTFlag; lastTFlag = Parser.TFlag; CurrentTick.Events.Add(infoUpdate); } //Store the names and steam IDs for every steam account in the server, including casters, bots and referees foreach (var participant in Parser.Participants) { byte NameIndex = 0; if (Demo.NameMappings.ContainsValue(participant.Name)) { NameIndex = Demo.NameMappings.FirstOrDefault(x => x.Value == participant.Name).Key; } else { NameIndex = CurrentNameIndex; Demo.NameMappings.Add(NameIndex, participant.Name); CurrentNameIndex++; } byte SteamIDIndex = 0; if (Demo.SteamIDMappings.ContainsValue(participant.SteamID)) { SteamIDIndex = Demo.SteamIDMappings.FirstOrDefault(x => x.Value == participant.SteamID).Key; } else { SteamIDIndex = CurrentSteamIDIndex; Demo.SteamIDMappings.Add(SteamIDIndex, participant.SteamID); CurrentSteamIDIndex++; } } //Loop though players that are actually playing the match foreach (var player in Parser.PlayingParticipants) { byte NameIndex = 0; if (Demo.NameMappings.ContainsValue(player.Name)) { NameIndex = Demo.NameMappings.FirstOrDefault(x => x.Value == player.Name).Key; } else { NameIndex = CurrentNameIndex; Demo.NameMappings.Add(NameIndex, player.Name); CurrentNameIndex++; } byte SteamIDIndex = 0; if (Demo.SteamIDMappings.ContainsValue(player.SteamID)) { SteamIDIndex = Demo.SteamIDMappings.FirstOrDefault(x => x.Value == player.SteamID).Key; } else { SteamIDIndex = CurrentSteamIDIndex; Demo.SteamIDMappings.Add(SteamIDIndex, player.SteamID); CurrentSteamIDIndex++; } Dictionary <byte, byte> AmmoLeft = new Dictionary <byte, byte>(); for (int i = 0; i < 32; i++) { if (player.AmmoLeft[i] != 0) { AmmoLeft.Add((byte)i, (byte)player.AmmoLeft[i]); } } Dictionary <short, Weapon> Weapons = new Dictionary <short, Weapon>(); foreach (var pair in player.rawWeapons) { Weapons.Add((short)pair.Key, new Weapon() { Equipment = (Models.EquipmentElement)((int)pair.Value.Weapon), OriginalString = pair.Value.OriginalString, AmmoInMagazine = (short)pair.Value.AmmoInMagazine, AmmoType = (short)pair.Value.AmmoType, ZoomLevel = (byte)pair.Value.ZoomLevel }); } FullPlayerState fullPlayerState = new FullPlayerState() { Type = PlayerStateType.Full, NameIndex = NameIndex, SteamIDIndex = SteamIDIndex, Position = new Models.Vector(player.Position.X, player.Position.Y, player.Position.Z), ViewOffsetZ = player.ViewOffset.Z, HP = (byte)player.HP, Armor = (byte)player.Armor, Velocity = new Models.Vector(player.Velocity.X, player.Velocity.Y, player.Velocity.Z), ViewDirectionX = player.ViewDirectionX, ViewDirectionY = player.ViewDirectionY, FlashDuration = player.FlashDuration, Money = (short)player.Money, CurrentEquipmentValue = (short)player.CurrentEquipmentValue, FreezetimeEndEquipmentValue = (short)player.FreezetimeEndEquipmentValue, RoundStartEquipmentValue = (short)player.RoundStartEquipmentValue, IsDucking = player.IsDucking, ActiveWeaponID = (byte)player.ActiveWeaponID, Team = (Models.Team)((int)player.Team), HasDefuseKit = player.HasDefuseKit, HasHelmet = player.HasHelmet, AmmoLeft = AmmoLeft, Weapons = Weapons, IsScoped = player.IsScoped, ShotsFired = player.ShotsFired, AimPunchAngle = new Models.Vector(player.AimPunchAngle.X, player.AimPunchAngle.Y, player.AimPunchAngle.Z), }; PositionPlayerState positionPlayerState = new PositionPlayerState(fullPlayerState); bool positionStateEqual = false; bool fullStateEqual = false; if (MostRecentPlayerStates.ContainsKey(SteamIDIndex)) { FullPlayerState mostRecentFullState = MostRecentPlayerStates[SteamIDIndex]; positionStateEqual = positionPlayerState.Equals(mostRecentFullState); fullStateEqual = fullPlayerState.Equals(mostRecentFullState); } if (fullStateEqual && positionStateEqual) { CurrentTick.PlayerStates.Add(new BasePlayerState() { Type = PlayerStateType.Base, SteamIDIndex = SteamIDIndex }); } else { MostRecentPlayerStates[SteamIDIndex] = fullPlayerState; if (fullStateEqual && !positionStateEqual) { CurrentTick.PlayerStates.Add(positionPlayerState); } else { CurrentTick.PlayerStates.Add(fullPlayerState); } } } foreach (var entity in Parser.Entities) { FullEntityState fullEntityState = new FullEntityState() { Type = EntityStateType.Full, ID = (short)entity.ID, EntityType = (Models.EntityType)((int)entity.Type), Position = new Models.Vector(entity.Position.X, entity.Position.Y, entity.Position.Z), Rotation = new Models.Vector(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z), ModelIndex = entity.ModelIndex, ModelLocation = entity.ModelLocation }; if (MostRecentEntityStates.ContainsKey(entity.ID)) { FullEntityState mostRecentFullState = MostRecentEntityStates[entity.ID]; bool fullStateEqual = fullEntityState.Equals(mostRecentFullState); if (fullStateEqual && !CurrentTick.Events.Any((evnt) => evnt.Type == EventType.RoundStart)) { CurrentTick.EntityStates.Add(new BaseEntityState(fullEntityState)); } else { CurrentTick.EntityStates.Add(fullEntityState); MostRecentEntityStates[entity.ID] = fullEntityState; } } else { MostRecentEntityStates[entity.ID] = fullEntityState; CurrentTick.EntityStates.Add(fullEntityState); } } Demo.Ticks.Add(CurrentTick); CurrentTick = new Tick(); }