/** * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. * * Gameplay event interface */ class GameplayEvents extends Object abstract native; `include(Engine\Classes\GameStats.uci); // Bitmasks for flags stored on the MCP header const HeaderFlags_NoEventStrings = 1; /** Stat verbosity level */ enum EGameStatGroups { GSG_EngineStats, GSG_Game, GSG_Team, GSG_Player, GSG_Weapon, GSG_Damage, GSG_Projectile, GSG_Pawn, GSG_GameSpecific, GSG_Aggregate }; struct native GameStatGroup { /** Group stat belongs to*/ var EGameStatGroups Group; /** Level of the stat */ var int Level; structcpptext { friend FArchive& operator<<( FArchive& Ar, FGameStatGroup& T ); } }; /** Basic file header when writing to disk */ struct native GameplayEventsHeader { /** Version of engine at the time of writing the file */ var const int EngineVersion; /** Version of the stats format at the time of writing the file */ var const int StatsWriterVersion; /** Offset into the file for the stream data */ var const int StreamOffset; /** Offset into the file for aggregate data */ var const int AggregateOffset; /** Offset into the file where the metadata is written */ var const int FooterOffset; /** Amount of data in the stream (not including header/footer data) */ var const int TotalStreamSize; /** File size on disk */ var const int FileSize; /** What filter class is being used on the data, if any */ var string FilterClass; /** Various settings */ var int Flags; }; /** Game stats session information recorded at log start */ struct native GameSessionInformation { /** Unique title identifier */ var int AppTitleID; /** Platform the session was run on */ var int PlatformType; /** Language the session was run in */ var string Language; /** Time this session was begun (real time) */ var const string GameplaySessionTimestamp; /** Time this session was started (game time) */ var const float GameplaySessionStartTime; /** Time this session was ended (game time) */ var const float GameplaySessionEndTime; /** Is a session currently in progress */ var const bool bGameplaySessionInProgress; /** Unique session ID */ var const string GameplaySessionID; /** Name of the game class used */ var const string GameClassName; /** Name of map at time of session */ var const string MapName; /** Game URL at time of session */ var const string MapURL; /** Value used to distinguish between contiguous sections */ var const int SessionInstance; /** Gametype ID */ var const int GameTypeId; /** UniqueID of player logging stats */ var const UniqueNetId OwningNetId; /** ID of the playlist in use */ var int PlaylistId; structcpptext { /** Constructors */ FGameSessionInformation() {} FGameSessionInformation(EEventParm) { appMemzero(this, sizeof(FGameSessionInformation)); } /** Return the unique key for this session */ const FString GetSessionID() const { return FString::Printf(TEXT("%s:%d"), *GameplaySessionID, SessionInstance); } } }; /** List of team information cached during the play session */ struct native TeamInformation { /** Index of the team in game */ var int TeamIndex; /** Name of the team */ var string TeamName; /** Color of the team */ var color TeamColor; /** Max size during the game */ var int MaxSize; structcpptext { friend FArchive& operator<<( FArchive& Ar, FTeamInformation& T ); } }; /** List of player information cached in case the player logs out and GC collects the objects */ struct native PlayerInformation { /** Name of Controller object */ var name ControllerName; /** Controller.PlayerReplicationInfo.PlayerName */ var string PlayerName; /** UniqueID of the player */ var UniqueNetId UniqueId; /** Whether the player is a bot or not */ var bool bIsBot; structcpptext { friend FArchive& operator<<( FArchive& Ar, FPlayerInformation& T ); } }; /** Holds the information describing a gameplay event */ struct native GameplayEventMetaData { /** The unique id of the event (16 bits clamped) */ var const int EventID; /** Human readable name of the event */ var const name EventName; /** Group that this stat belongs to, for filtering */ var const GameStatGroup StatGroup; /** Type of data associated with this event */ var const int EventDataType; structcpptext { friend FArchive& operator<<( FArchive& Ar, FGameplayEventMetaData& T ); } }; /** Metadata describing the weapon classes recorded during gameplay */ struct native WeaponClassEventData { /** Name of the weapon class used **/ var name WeaponClassName; structcpptext { friend FArchive& operator<<( FArchive& Ar, FWeaponClassEventData& T ); } }; /** Metadata describing the damage classes recorded during gameplay */ struct native DamageClassEventData { /** Name of the damage class used **/ var name DamageClassName; structcpptext { friend FArchive& operator<<( FArchive& Ar, FDamageClassEventData& T ); } }; /** Metadata describing the projectile classes recorded during gameplay */ struct native ProjectileClassEventData { /** name of the projectile class used **/ var name ProjectileClassName; structcpptext { friend FArchive& operator<<( FArchive& Ar, FProjectileClassEventData& T ); } }; /** Metadata describing the pawn classes recorded during gameplay */ struct native PawnClassEventData { /** Name of the pawn class used **/ var name PawnClassName; structcpptext { friend FArchive& operator<<( FArchive& Ar, FPawnClassEventData& T ); } }; cpptext { /** Access the current session info */ const FGameSessionInformation& GetSessionInfo() const { return CurrentSessionInfo; } /** Returns the metadata associated with the given index */ virtual const FGameplayEventMetaData& GetEventMetaData(INT EventID) const; /** Returns the metadata associated with the given index */ const FTeamInformation& GetTeamMetaData(INT TeamIndex) const; /** Returns the metadata associated with the given index */ const FPlayerInformation& GetPlayerMetaData(INT PlayerIndex) const; /** Returns the metadata associated with the given index */ const FPawnClassEventData& GetPawnMetaData(INT PawnClassIndex) const; /** Returns the metadata associated with the given index */ const FWeaponClassEventData& GetWeaponMetaData(INT WeaponClassIndex) const; /** Returns the metadata associated with the given index */ const FDamageClassEventData& GetDamageMetaData(INT DamageClassIndex) const; /** Returns the metadata associated with the given index */ const FProjectileClassEventData& GetProjectileMetaData(INT ProjectileClassIndex) const; /** * Returns the metadata associated with the given index * @param ActorIndex the index of the actor being looked up * @return the name of the actor at that index */ const FString& GetActorMetaData(INT ActorIndex) const { return ActorArray(ActorIndex); } /** * Returns the metadata associated with the given index * @param SoundIndex the index of the soundcue being looked up * @return the name of the actor at that index */ const FString& GetSoundMetaData(INT SoundIndex) const { return SoundCueArray(SoundIndex); } }; /** FArchive pointer to serialize the data to/from disk */ var const native pointer Archive{FArchive}; /** The name of the file we are writing the data to (const so set only upon create natively) */ var const private string StatsFileName; /** Header of the gameplay events file */ var GameplayEventsHeader Header; /** Information specific to the session when it was run */ var GameSessionInformation CurrentSessionInfo; /** Array of all players 'seen' by the game in this session **/ var const array PlayerList; /** Array of all teams 'seen' by the game in this session **/ var const array TeamList; /** The set of events that the game supports writing to disk */ var array SupportedEvents; /** The set of weapons recorded during gameplay */ var array WeaponClassArray; /** The set of damage types recorded during gameplay */ var array DamageClassArray; /** The set of projectiles recorded during gameplay */ var array ProjectileClassArray; /** The set of pawns recorded during gameplay */ var array PawnClassArray; /** The set of actors recorded during gameplay */ var array ActorArray; /** The set of sound cues encountered during gameplay */ var array SoundCueArray; /** * Creates the archive that we are going to be manipulating * @param Filename - name of the file that will be open for serialization * @return TRUE if successful, else FALSE */ function bool OpenStatsFile(string Filename); /** * Closes and deletes the archive created * clearing all data stored within */ function CloseStatsFile(); /** Retrieve the name of the file last in use by the gameplay event serializer, possibly empty */ event string GetFilename() { return StatsFileName; } defaultproperties { SupportedEvents.Empty() //Must leave this first as a fallback for failed event retrieval SupportedEvents(0)={(EventID=-1,EventName="UNKNOWN",StatGroup=(Group=GSG_EngineStats,Level=999),EventDataType=1)} //Real events start here SupportedEvents.Add((EventID=GAMEEVENT_MATCH_STARTED,EventName="Match Started",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_MATCH_ENDED,EventName="Match Ended",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_ROUND_STARTED,EventName="Round Started",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_ROUND_ENDED,EventName="Round Ended",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_GAME_CLASS,EventName="Game Class",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameString)) SupportedEvents.Add((EventID=GAMEEVENT_GAME_OPTION_URL,EventName="Game Options",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameString)) SupportedEvents.Add((EventID=GAMEEVENT_GAME_MAPNAME,EventName="Map Name",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameString)) SupportedEvents.Add((EventID=GAMEEVENT_TEAM_CREATED,EventName="Team Created",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) SupportedEvents.Add((EventID=GAMEEVENT_TEAM_GAME_SCORE,EventName="Team Score",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) SupportedEvents.Add((EventID=GAMEEVENT_TEAM_MATCH_WON,EventName="Match Won",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) SupportedEvents.Add((EventID=GAMEEVENT_TEAM_ROUND_WON,EventName="Round Won",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) SupportedEvents.Add((EventID=GAMEEVENT_TEAM_ROUND_STALEMATE,EventName="Round Stalemate",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_LOGIN,EventName="Player Login",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerLogin)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_LOGOUT,EventName="Player Logout",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerLogin)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_KILL,EventName="Player Killed",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerKillDeath)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_DEATH,EventName="Player Death",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerKillDeath)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_TEAMCHANGE,EventName="Player Team Change",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_SPAWN,EventName="Player Spawn",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerSpawn)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_LOCATION_POLL,EventName="Player Locations",StatGroup=(Group=GSG_Player,Level=10),EventDataType=`GET_PlayerLocationPoll)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_KILL_STREAK,EventName="Kill Streak",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_MATCH_WON,EventName="Player Match Won",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_ROUND_WON,EventName="Player Round Won",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_ROUND_STALEMATE,EventName="Player Round Stalemate",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) SupportedEvents.Add((EventID=GAMEEVENT_WEAPON_DAMAGE,EventName="Weapon Damage",StatGroup=(Group=GSG_Weapon,Level=10),EventDataType=`GET_DamageInt)) SupportedEvents.Add((EventID=GAMEEVENT_WEAPON_DAMAGE_MELEE,EventName="Melee Damage",StatGroup=(Group=GSG_Weapon,Level=10),EventDataType=`GET_DamageInt)) SupportedEvents.Add((EventID=GAMEEVENT_WEAPON_FIRED,EventName="Weapon Fired",StatGroup=(Group=GSG_Weapon,Level=10),EventDataType=`GET_WeaponInt)) SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_KILL_NORMAL,EventName="Normal Kill",StatGroup=(Group=GSG_Weapon,Level=1),EventDataType=`GET_PlayerKillDeath)) SupportedEvents.Add((EventID=GAMEEVENT_MEMORYUSAGE_POLL,EventName="Memory Usage",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_NETWORKUSAGEIN_POLL,EventName="Network Usage IN",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_NETWORKUSAGEOUT_POLL,EventName="Network Usage OUT",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_PING_POLL,EventName="Ping",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_FRAMERATE_POLL,EventName="Frame Rate",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) SupportedEvents.Add((EventID=GAMEEVENT_GAMETHREAD_POLL,EventName="Game thread time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) SupportedEvents.Add((EventID=GAMEEVENT_RENDERTHREAD_POLL,EventName="Render thread time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) SupportedEvents.Add((EventID=GAMEEVENT_GPUFRAMETIME_POLL,EventName="GPU render time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) SupportedEvents.Add((EventID=GAMEEVENT_FRAMETIME_POLL,EventName="Total frame time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) SupportedEvents.Add((EventID=`GAMEEVENT_AI_PATH_FAILURE,EventName="AI Path Failure",StatGroup=(Group=GSG_Game,Level=10),EventDataType=`GET_GenericParamList)) SupportedEvents.Add((EventID=`GAMEEVENT_AI_FIRELINK,EventName="AI Firelink",StatGroup=(Group=GSG_Game,Level=10),EventDataType=`GET_GenericParamList)) }