diff options
Diffstat (limited to 'public/gcsdk/gcsession.h')
| -rw-r--r-- | public/gcsdk/gcsession.h | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/public/gcsdk/gcsession.h b/public/gcsdk/gcsession.h new file mode 100644 index 0000000..e2ff636 --- /dev/null +++ b/public/gcsdk/gcsession.h @@ -0,0 +1,236 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Holds the CGCSession class +// +//============================================================================= + +#ifndef GCSESSION_H +#define GCSESSION_H +#ifdef _WIN32 +#pragma once +#endif + +#include "scheduledfunction.h" +#include "framefunction.h" +#include "gcsdk/gc_sharedobjectcache.h" + +namespace GCSDK +{ + +class CGCGSSession; + +// Spew group for anything related to sessions +extern CGCEmitGroup g_EGSessions; + +//----------------------------------------------------------------------------- +// Utility class to handle rate limiting based upon a steam ID and message using two console variables to control rate +//----------------------------------------------------------------------------- + +//utility class to handle rate limiting based upon a steam ID +class CSteamIDRateLimit +{ +public: + CSteamIDRateLimit( const GCConVar& cvNumPerPeriod, const GCConVar* pcvPeriodS = NULL ); + ~CSteamIDRateLimit(); + //given a steam ID, this will determine if it should be rate limited + bool BIsRateLimited( CSteamID steamID, uint32 unMsgType ); + //frame function to clear the list after a period of time + bool OnFrameFn( const CLimitTimer& timer ); +private: + //the last time we cleared our list + RTime32 m_LastClear; + //the frame function so we can detect when we need to clear + CFrameFunction< CSteamIDRateLimit> m_FrameFunction; + //the map of messages we have tracked for each user + CUtlHashMapLarge< CSteamID, uint32 > m_Msgs; + //the console variables that track the time window and the messages allowed + const GCConVar& m_cvNumPerPeriod; + const GCConVar* m_pcvPeriodS; +}; + +//------------------------------------------------------------------------------------------ +// CMsgRateLimitTracker +// A utility class to track when messages go over so that we can see users/msgs that are being spammed +//------------------------------------------------------------------------------------------ +class CMsgRateLimitTracker +{ +public: + + CMsgRateLimitTracker(); + + //called to track a message that was rate limited + void TrackRateLimitedMsg( const CSteamID steamID, MsgType_t eMsgType ); + + //called to report the collected rate limiting stats + void ReportMsgStats() const; + void ReportTopUsers( uint32 nMinMsgs, uint32 nListTop ) const; + void ReportUserStats() const; + + //called to clear all collected stats + void ClearStats(); + +private: + + //the time we started collecting stats at + RTime32 m_StartTime; + + //map detailing the number of messages of each type that have been dropped + CUtlHashMapLarge< MsgType_t, uint32 > m_MsgStats; + CUtlHashMapLarge< CSteamID, uint32 > m_UserStats; +}; +extern CMsgRateLimitTracker g_RateLimitTracker; + +//----------------------------------------------------------------------------- +// Purpose: Base class for sessions in the GC +//----------------------------------------------------------------------------- +class CGCSession +{ +public: + CGCSession( const CSteamID & steamID, CGCSharedObjectCache *pCache ); + virtual ~CGCSession(); + + const CSteamID & GetSteamID() const { return m_steamID; } + + const CGCSharedObjectCache *GetSOCache() const { return m_pSOCache; } + CGCSharedObjectCache *GetSOCache() { return m_pSOCache; } + void RemoveSOCache() { m_pSOCache = NULL; } + + EOSType GetOSType() const { return m_osType; }; + bool IsTestSession() const { return m_bIsTestSession; } + uint32 GetIPPublic() const { return m_unIPPublic; } + bool IsSecure() const { return m_bIsSecure; } + + bool BIsShuttingDown() const { return m_bIsShuttingDown; } + void SetIsShuttingDown( bool bIsShuttingDown ) { m_bIsShuttingDown = bIsShuttingDown; } + + virtual void Dump( bool bFull = true ) const = 0; + + bool BRateLimitMessage( MsgType_t unMsgType ); + + CJobTime GetLastPingSendTime() const { return m_jtTimeSentPing; } + CJobTime GetLastMessageReceiveTime() const { return m_jtLastMessageReceived; } + void SendPing() const; + + virtual void MarkAccess() { } + virtual void Run(); + virtual void YieldingSOCacheReloaded() {} +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ); +#endif // DBGFLAG_VALIDATE + + // Geolocation + bool HasGeoLocation() const { return m_haveGeoLocation; } + bool GetGeoLocation( float &latitude, float &longittude ) const; + virtual void SetGeoLocation( float latitude, float longittude ); + + //track whether or not this session has been initialized or not + bool BIsInitialized() const { return m_bInitialized; } + void SetInitialized( bool b ) { m_bInitialized = b; } + +private: + CSteamID m_steamID; + CGCSharedObjectCache *m_pSOCache; + + // Tracks how many messages we've gotten this second so we can block attacks + RTime32 m_rtLastMessageReceived; + uint32 m_unMessagesRecievedThisSecond; + CJobTime m_jtLastMessageReceived; + + // This is mutable because we update it when we send pings, but sending a + // ping to a user/server isn't really a session changing event, so we don't + // want to require locking the session to ping it and update its last + // sent ping time. + mutable CJobTime m_jtTimeSentPing; + + EOSType m_osType : 16; + bool m_bIsShuttingDown : 1; + bool m_bIsTestSession : 1; + bool m_bIsSecure : 1; + bool m_bInitialized : 1; +protected: + bool m_haveGeoLocation : 1; + + float m_flLatitude; + float m_flLongitude; + + uint32 m_unIPPublic; + + friend class CGCBase; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Base class for user sessions in the GC +//----------------------------------------------------------------------------- +class CGCUserSession : public CGCSession +{ +public: + CGCUserSession( const CSteamID & steamID, CGCSharedObjectCache *pCache ) : CGCSession( steamID, pCache ) { } + virtual ~CGCUserSession(); + + virtual bool BInit(); + + const CSteamID &GetSteamIDGS() const { return m_steamIDGS; } + const CSteamID &GetSteamIDGSPrev() const { return m_steamIDGSPrev; } + + virtual bool BSetServer( const CSteamID &steamIDGS ); + virtual bool BLeaveServer(); + virtual void Dump( bool bFull = true ) const; + +private: + CSteamID m_steamIDGS; + CSteamID m_steamIDGSPrev; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Base class for gameserver sessions in the GC +//----------------------------------------------------------------------------- +class CGCGSSession : public CGCSession +{ +public: + + CGCGSSession( const CSteamID & steamID, CGCSharedObjectCache *pCache, uint32 unServerAddr, uint16 usServerPort ) ; + virtual ~CGCGSSession(); + + uint32 GetAddr() const { return m_unServerAddr; } + uint16 GetPort() const { return m_usServerPort; } + void SetIPAndPort( uint32 unServerAddr, uint16 usServerPort ); + int GetUserCount() const { return m_vecUsers.Count(); } + CSteamID GetUserID( int nIndex ) const { return m_vecUsers[nIndex]; } + + // Manages users on the server. It is very important that these are not + // virtual and not yielding. For custom behavior override the Pre*() hooks below + bool BAddUser( const CSteamID &steamIDUser ); + bool BRemoveUser( const CSteamID &steamIDUser ); + void RemoveAllUsers(); + + virtual void Dump( bool bFull = true ) const; + +protected: + // Hooks to trigger custom behavior when users are added and removed. It is + // very important that these do not yield. If you need to yield, start a job instead + virtual void PreAddUser( const CSteamID &steamIDUser ) {} + virtual void PostAddUser( const CSteamID &steamIDUser ) {} + virtual void PreRemoveUser( const CSteamID &steamIDUser ) {} + virtual void PostRemoveUser( const CSteamID &steamIDUser ) {} + virtual void PreRemoveAllUsers() {} + virtual void PostRemoveAllUsers() {} + +public: + float m_lastUpdateTime; // Last time we received a message from the server + +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ); +#endif // DBGFLAG_VALIDATE +protected: + CUtlVector<CSteamID> m_vecUsers; + + // These are the address of the server as connected to Steam + uint32 m_unServerAddr; + uint16 m_usServerPort; +}; + +} // namespace GCSDK + +#endif // GCSESSION_H |