summaryrefslogtreecommitdiff
path: root/game/shared/steamworks_gamestats.h
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/steamworks_gamestats.h')
-rw-r--r--game/shared/steamworks_gamestats.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/game/shared/steamworks_gamestats.h b/game/shared/steamworks_gamestats.h
new file mode 100644
index 0000000..a1c3d61
--- /dev/null
+++ b/game/shared/steamworks_gamestats.h
@@ -0,0 +1,193 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Uploads gamestats via the SteamWorks API.
+//
+//=============================================================================//
+
+#ifndef STEAMWORKS_GAMESTATS_H
+#define STEAMWORKS_GAMESTATS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "igamesystem.h"
+#include "GameEventListener.h"
+#include "steam/steam_api.h"
+#include "utlvector.h"
+
+#ifndef _X360
+#include "steam/isteamgamestats.h"
+#endif
+
+// Container to hold all the KeyValue stats to send only if the convar "steamworks_immediate_upload" is set to 0.
+// Otherwise, the stats are uploaded as they are received.
+typedef CUtlVector< KeyValues* > KeyValueStatList;
+
+struct ClientServerSession_t
+{
+ uint64 m_ServerSessionID;
+ RTime32 m_ConnectTime;
+ RTime32 m_DisconnectTime;
+
+ void Reset()
+ {
+ m_ServerSessionID = 0;
+ m_ConnectTime = 0;
+ m_DisconnectTime = 0;
+ }
+};
+
+//used to drive most of the game stat event handlers as well as track basic stats under the hood of CBaseGameStats
+class CSteamWorksGameStatsUploader : public CAutoGameSystemPerFrame, public CGameEventListener
+{
+public:
+
+#ifdef CLIENT_DLL
+ // Called before rendering
+ virtual void PreRender() {}
+
+ // Gets called each frame
+ virtual void Update( float frametime ) {}
+
+ // Called after rendering
+ virtual void PostRender() {}
+
+ void AddClientPerfData( KeyValues *pKV );
+ void SetServerSessionID( uint64 serverID );
+ int GetFriendCountInGame();
+
+#ifndef NO_STEAM
+ STEAM_CALLBACK_MANUAL( CSteamWorksGameStatsUploader, Steam_OnSteamSessionInfoIssued, GameStatsSessionIssued_t, m_CallbackSteamSessionInfoIssued );
+ STEAM_CALLBACK_MANUAL( CSteamWorksGameStatsUploader, Steam_OnSteamSessionInfoClosed, GameStatsSessionClosed_t, m_CallbackSteamSessionInfoClosed );
+#endif
+
+#endif
+
+#ifdef GAME_DLL
+#ifndef NO_STEAM
+ STEAM_GAMESERVER_CALLBACK( CSteamWorksGameStatsUploader, Steam_OnSteamSessionInfoIssued, GameStatsSessionIssued_t, m_CallbackSteamSessionInfoIssued );
+ STEAM_GAMESERVER_CALLBACK( CSteamWorksGameStatsUploader, Steam_OnSteamSessionInfoClosed, GameStatsSessionClosed_t, m_CallbackSteamSessionInfoClosed );
+#endif
+#endif
+
+ // Called each frame before entities think
+ virtual void FrameUpdatePreEntityThink() {}
+ // called after entities think
+ virtual void FrameUpdatePostEntityThink();
+ virtual void PreClientUpdate() {}
+
+ void StartSession();
+ void EndSession();
+
+ void WriteSessionRow();
+
+#ifdef GAME_DLL
+ void WriteHostsRow();
+#endif
+
+#ifdef CLIENT_DLL
+ void ClientDisconnect();
+ void ClearServerSessionID() { m_ServerSessionID = 0 ;}
+ int GetNumServerConnects() { return m_iServerConnectCount; }
+#endif
+
+ bool IsCollectingDetails() { return m_bCollectingDetails; }
+ bool IsCollectingAnyData() { return m_bCollectingAny; }
+
+ CSteamWorksGameStatsUploader();
+
+ // Init, shutdown
+ // return true on success. false to abort DLL init!
+ virtual bool Init();
+ virtual void PostInit() {}
+ virtual void Shutdown() {}
+
+ // Level init, shutdown
+ virtual void LevelInitPreEntity() {}
+ virtual void LevelInitPostEntity() {}
+ virtual void LevelShutdown();
+
+ virtual void OnSave() {}
+ virtual void OnRestore() {}
+ virtual void SafeRemoveIfDesired() {}
+
+ virtual bool IsPerFrame() { return true; }
+
+ virtual void FireGameEvent( IGameEvent *event );
+ EResult AddStatsForUpload( KeyValues *pKV, bool bSendImmediately=true );
+ time_t GetTimeSinceEpoch();
+ void FlushStats();
+
+ uint32 GetServerIP() { return m_iServerIP; }
+ const char* GetHostName() { return m_pzHostName; }
+ bool IsPassworded() { return m_bPassword; }
+ RTime32 GetStartTime() { return m_StartTime; }
+ RTime32 GetEndTime() { return m_EndTime; }
+
+#ifdef CLIENT_DLL
+ uint64 GetServerSessionID() { return m_ServerSessionID; }
+#endif
+
+ uint64 GetSessionID() { return m_SessionID; }
+ void ClearSessionID();
+
+private:
+ void UploadCvars();
+ void Reset();
+ bool VerifyInterface();
+ int GetHumanCountInGame();
+
+ EResult RequestSessionID();
+
+ bool AccessToSteamAPI();
+ EResult WriteIntToTable( const int value, uint64 iTableID, const char *pzRow );
+ EResult WriteInt64ToTable( const uint64 value, uint64 iTableID, const char *pzRow );
+ EResult WriteFloatToTable( const float value, uint64 iTableID, const char *pzRow );
+ EResult WriteStringToTable( const char *pzValue, uint64 iTableID, const char *pzRow );
+ EResult WriteOptionalFloatToTable( KeyValues *pKV, const char* keyName, uint64 iTableID, const char *pzRow);
+ EResult WriteOptionalIntToTable( KeyValues *pKV, const char* keyName, uint64 iTableID, const char *pzRow );
+
+ ISteamGameStats* GetInterface( void );
+ EResult ParseKeyValuesAndSendStats( KeyValues *pKV, bool bIncludeClientsServerSessionID = true );
+ void ServerAddressToInt();
+
+ ISteamGameStats* m_SteamWorksInterface;
+
+ uint64 m_UserID;
+ uint32 m_iAppID;
+ uint32 m_iServerIP;
+ int m_nClientJoinMethod;
+ char m_pzServerIP[MAX_PATH];
+ char m_pzMapStart[MAX_PATH];
+ char m_pzHostName[MAX_PATH];
+ RTime32 m_StartTime;
+ RTime32 m_EndTime;
+ int m_HumanCntInGame;
+ int m_FriendCntInGame;
+ bool m_bPassword;
+
+ // Session IDs
+ uint64 m_SessionID;
+ bool m_SessionIDRequestUnsent;
+ bool m_SessionIDRequestPending;
+ bool m_bCollectingAny;
+ bool m_bCollectingDetails;
+
+#ifdef CLIENT_DLL
+ uint64 m_ServerSessionID;
+#endif
+
+ bool m_ServiceTicking;
+ float m_LastServiceTick;
+
+ bool m_UploadedStats;
+
+ KeyValueStatList m_StatsToSend;
+
+ ClientServerSession_t m_ActiveSession;
+ int m_iServerConnectCount;
+};
+
+CSteamWorksGameStatsUploader& GetSteamWorksSGameStatsUploader();
+
+#endif // STEAMWORKS_GAMESTATS_H