Closed Theoya closed 1 month ago
I got curious, because I tried to listen to some pretty obvious events like BreakBreakable
or ItemPickup
. Surely these happen all the time.
But it appears that a LOT of the events don't actually trigger at all. So I created a custom EventHappenedListener
class to simply check if an event happened or not:
public class EventHappensListener
{
public bool eventHappened = false;
public string eventName;
public EventHappensListener(string eventName, Dictionary<String, EventHappensListener> eventList)
{
this.eventName = eventName;
eventList[eventName] = this;
}
public void EventHappens(Source1GameEventBase someEvent)
{
eventHappened = true;
}
public override string ToString()
{
return $"{eventName}: {eventHappened}";
}
}
And I attached it to every event in the game:
demoParser.Source1GameEvents.AchievementEvent += new EventHappensListener("AchievementEvent", eventHappens).EventHappens;
demoParser.Source1GameEvents.AbilityAdded += new EventHappensListener("AbilityAdded", eventHappens).EventHappens;
demoParser.Source1GameEvents.AbilityRemoved += new EventHappensListener("AbilityRemoved", eventHappens).EventHappens;
demoParser.Source1GameEvents.AchievementEarned += new EventHappensListener("AchievementEarned", eventHappens).EventHappens;
demoParser.Source1GameEvents.AbilityCastFailed += new EventHappensListener("AbilityCastFailed", eventHappens).EventHappens;
demoParser.Source1GameEvents.AbilityCastSucceeded += new EventHappensListener("AbilityCastSucceeded", eventHappens).EventHappens;
demoParser.Source1GameEvents.AbilityLevelChanged += new EventHappensListener("AbilityLevelChanged", eventHappens).EventHappens;
demoParser.Source1GameEvents.AchievementWriteFailed += new EventHappensListener("AchievementWriteFailed", eventHappens).EventHappens;
demoParser.Source1GameEvents.BonusUpdated += new EventHappensListener("BonusUpdated", eventHappens).EventHappens;
demoParser.Source1GameEvents.BossDamaged += new EventHappensListener("BossDamaged", eventHappens).EventHappens;
demoParser.Source1GameEvents.BossKilled += new EventHappensListener("BossKilled", eventHappens).EventHappens;
demoParser.Source1GameEvents.BreakBreakable += new EventHappensListener("BreakBreakable", eventHappens).EventHappens;
demoParser.Source1GameEvents.BreakProp += new EventHappensListener("BreakProp", eventHappens).EventHappens;
// Etc....
This is the result:
AchievementEvent: False AbilityAdded: False AbilityRemoved: False AchievementEarned: False AbilityCastFailed: False AbilityCastSucceeded: False AbilityLevelChanged: False AchievementWriteFailed: False BonusUpdated: False BossDamaged: False BossKilled: False BreakBreakable: False BreakProp: False BrokenBreakable: False BotPlayerReplace: False BreakPieceSpawned: False BrokeEnemyShield: False CurrencyMissed: False CurrencyDenied: False CitadelPauseEvent: False CartUpdated: False ClientDisconnect: False CrateSpawn: False CitadelHintChanged: False CitadeltvChaseHero: True CitadeltvUnitEvent: False ClientsideLessonClosed: False CrateSpawnNotification: False ClientPlayerCurrencyChange: False ClientPlayerHeroChanged: False DemoStop: False DifficultyChanged: False DoorClose: False DropRateModified: False DynamicShadowLightChanged: False EventTicketModified: False EntityKilled: False EntityVisible: False FinaleStart: False FlareIgniteNpc: False GameNewmap: False GameMessage: False GameinstructorDraw: False GameinstructorNodraw: False GameuiActivated: False GameuiHidden: False GcConnected: False GrenadeBounce: False GameStateChanged: False GameuiFreeCursorChanged: False HltvCameraman: False HltvChase: False HltvChat: False HltvFixed: False HltvMessage: False HltvReplay: False HltvStatus: False HltvTitle: False HltvVersioninfo: True HostnameChanged: False HltvRankCamera: False HltvRankEntity: False HltvReplayStatus: False HelicopterGrenadePuntMiss: False HeroAssignedLaneChanged: False HeroDraftOrderChanged: False ItemPickup: False InventoryUpdated: False InstructorCloseLesson: False ItemFileReloaded: False InstructorStartLesson: False ItemSchemaInitialized: False InstructorServerHintCreate: False InstructorServerHintStop: False LocalPlayerTeam: False LaneTestStateUpdated: False LocalPlayerControllerTeam: False LocalPlayerPawnChanged: False LocalPlayerShotHit: False LocalPlayerWeaponsChanged: False LocalPlayerAbilitiesVdataChanged: False LocalPlayerUnitStatesChanged: False LocalPlayerAbilityCooldownEndChanged: False MapShutdown: False MapTransition: False MatchClock: True MidBossSpawned: False NonPlayerUsedAbility: False PlayerDeath: True PlayerConnect: False PlayerSpawn: False PartyUpdated: False PersonaUpdated: False PhysgunPickup: False PlayerActivate: False PlayerChangename: False PlayerChat: False PlayerDisconnect: False PlayerFootstep: False PlayerHealed: False PlayerHintmessage: False PlayerInfo: False PlayerRespawned: False PlayerTeam: False PlayerAbilityUpgraded: False PlayerAmmoFull: False PlayerAmmoIncreased: False PlayerBotReplace: False PlayerConnectFull: False PlayerDamageIncreased: False PlayerDraftingChanged: False PlayerFullUpdate: False PlayerGivenShield: False PlayerHealPrevented: False PlayerHeroChanged: False PlayerHeroReset: False PlayerItemsChanged: False PlayerKillStreak: False PlayerLevelChanged: False PlayerMaxhealthIncreased: False PlayerModifiersChanged: False PlayerRezIncoming: False PlayerStatsChanged: False PlayerStatsUpdated: False PlayerUsedAbility: True PlayerUsedItem: False PlayerWeaponSwitched: False PlayerClosedItemShop: False PlayerDataAbilitiesChanged: False PlayerGuidedSandboxStarted: False PlayerInfoIndividualUpdated: False PlayerItemPriceChanged: False PlayerKillStreakNew: False PlayerLaneChallengeEnded: False PlayerOpenedHeroSelect: False PlayerLaneChallengeStarted: False PlayerOpenedItemShop: False PlayerRespawnTimeChanged: False PlayerShopZoneChanged: False PlayerAbilityBonusCounterChanged: False PlayerAbilityUpgradeSellPriceChanged: False RoundEnd: False RagdollDissolved: False RoundStart: False RejuvStatusMsg: False RoundFreezeEnd: False ReloadFailedNoAmmo: False RoundStartPostNav: False RoundStartPreEntity: False Source1GameEvent: True ServerSpawn: False ServerCvar: False ServerMessage: False ServerShutdown: False SandboxPlayerMoved: False ServerPreShutdown: False SpecModeUpdated: False SpecTargetUpdated: False StorePricesheetUpdated: False SetInstructorGroupEnabled: False SpectateHomeTeamChanged: False TeamInfo: False TeamMsg: False TeamScore: False TeamplayBroadcastAudio: False TeamplayRoundStart: False TitanTransformingComplete: False ToolsContentChanged: False TitanTransformingStart: False UserDataDownloaded: False VoteChanged: False VoteFailed: False VotePassed: False VoteStarted: False VoteCastNo: False VoteCastYes: False WeaponReloadComplete: False WeaponReloadStarted: False WeaponZoomStarted: False ZiplinePlayerAttached: False ZiplinePlayerDetached: False
So for people who are curious, currently only the following events are firing:
CitadeltvChaseHero: True HltvVersioninfo: True MatchClock: True PlayerDeath: True PlayerUsedAbility: True Source1GameEvent: True
Source1GameEvent: True
The thing is, the sub events for this arent firing either
@saul
I'm in a discord about this and this was from the discord. Maybe relevant to this discussion:
You need to capture events to get data Once it reads that data won't be there anymore
demo.PacketEvents.SvcCreateStringTable += (e) =>
{
foreach (var v in demo.PlayerInfos)
{
if (v == null) continue;
using (var db = new DemDbContext())
{
if (!db.Players.Any(x => x.UserId == v.Userid))
{
db.Players.Add(new Player()
{
Name = v.Name,
SteamId = v.Steamid,
UserId = v.Userid,
Xuid = $"{v.Xuid}"
});
db.SaveChanges();
}
}
}
};
IE this is what I am doing to capture the player inf, could also interogate after each update
I'm in a discord about this and this was from the discord. Maybe relevant to this discussion:
You need to capture events to get data Once it reads that data won't be there anymore
demo.PacketEvents.SvcCreateStringTable += (e) => { foreach (var v in demo.PlayerInfos) { if (v == null) continue; using (var db = new DemDbContext()) { if (!db.Players.Any(x => x.UserId == v.Userid)) { db.Players.Add(new Player() { Name = v.Name, SteamId = v.Steamid, UserId = v.Userid, Xuid = $"{v.Xuid}" }); db.SaveChanges(); } } } };
IE this is what I am doing to capture the player inf, could also interogate after each update
@QuinnBast could you hook me up with the discord?
And would i run something like this in a parser or while a game is running?
Deadlock Developer Community Discord
And would i run something like this in a parser or while a game is running?
I think you'd run this while parsing a demofile but I have no idea, I haven't tried it. Might be worth asking more details in the discord. I think what they are doing is some raw packet parsing of the events.
A property of demo files for both Source 1, Source 2, CS2 and Deadlock etc, is that not all Source1GameEvents are available in demo files.
The game defines many events (e.g. player spawn) that may not be recorded in the demo. Some events are available on the game server only, and never sent to clients, or if they are sent to clients, not then recorded in demo files.
Keep in mind that Valve store demo files for public matchmaking matches for some time, so they only want to store the absolute bare minimum information to replay the game from the game client. This means that any data that isn't necessary for that won't be recorded in the demo file.
I'm in a discord about this and this was from the discord. Maybe relevant to this discussion:
You need to capture events to get data
Once it reads that data won't be there anymore
IE this is what I am doing to capture the player inf, could also interogate after each update
This isn't true. The contents of string tables (e.g. userinfo) is persistent, and the data remains even after the event is fired. You can even access it from the player controller with the PlayerInfo
property.
However when Source1GameEvents fire, the game event data is not persisted. For example on PlayerDeath
, that information is not stored by the library. If you want to keep track of it, you'll have to store it yourself.
Hope that makes sense.
If you want to know when a player respawns, you can use:
demo.EntityEvents.CCitadelPlayerPawn.AddChangeCallback(x => x.IsAlive, (pawn, old, newLife) =>
{
Console.WriteLine($"{pawn.Controller?.PlayerName} {(old ? "alive" : "dead")} -> {(newLife ? "alive" : "dead")}");
});
Research
Description
The event is never being triggered
Code to reproduce
Affected demos
No response