Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
10 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: steam state machine that handles authenticating steam users
  4. //
  5. //=============================================================================//
  6. #ifdef _WIN32
  7. #if !defined( _X360 )
  8. #include "winlite.h"
  9. #include <winsock2.h> // INADDR_ANY defn
  10. #endif
  11. #elif POSIX
  12. #include <netinet/in.h>
  13. #endif
  14. #include "baseclient.h"
  15. #include "utlvector.h"
  16. #include "netadr.h"
  17. #include "cl_steamauth.h"
  18. #include "interface.h"
  19. #include "filesystem_engine.h"
  20. #include "tier0/icommandline.h"
  21. #include "tier0/vprof.h"
  22. #include "host.h"
  23. #include "cmd.h"
  24. #include "common.h"
  25. #include "inputsystem/iinputsystem.h"
  26. #include "materialsystem/imaterialsystem.h"
  27. #ifndef DEDICATED
  28. #include "vgui_baseui_interface.h"
  29. #include "server.h"
  30. #include "matchmaking/imatchframework.h"
  31. #endif
  32. // NOTE: This has to be the last file included!
  33. #include "tier0/memdbgon.h"
  34. #pragma warning( disable: 4355 ) // disables ' 'this' : used in base member initializer list'
  35. extern ConVar cl_hideserverip;
  36. //-----------------------------------------------------------------------------
  37. // Purpose: singleton accessor
  38. //-----------------------------------------------------------------------------
  39. static CSteam3Client s_Steam3Client;
  40. CSteam3Client &Steam3Client()
  41. {
  42. return s_Steam3Client;
  43. }
  44. static void Callback_SteamAPIWarningMessageHook( int n, const char *sz )
  45. {
  46. if ( n == 0 )
  47. {
  48. Msg( "[STEAM] %s\n", sz );
  49. }
  50. else
  51. {
  52. Warning( "[STEAM] %s\n", sz );
  53. }
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Purpose: Constructor
  57. //-----------------------------------------------------------------------------
  58. CSteam3Client::CSteam3Client()
  59. #if !defined(NO_STEAM)
  60. :
  61. m_CallbackClientGameServerDeny( this, &CSteam3Client::OnClientGameServerDeny ),
  62. m_CallbackGameServerChangeRequested( this, &CSteam3Client::OnGameServerChangeRequested ),
  63. m_CallbackGameOverlayActivated( this, &CSteam3Client::OnGameOverlayActivated ),
  64. m_CallbackPersonaStateChanged( this, &CSteam3Client::OnPersonaUpdated ),
  65. m_CallbackLowBattery( this, &CSteam3Client::OnLowBattery ),
  66. m_CallbackSteamSocketStatus( this, &CSteam3Client::OnSteamSocketStatus )
  67. #endif
  68. {
  69. m_bActive = false;
  70. m_bGSSecure = false;
  71. m_bGameOverlayActive = false;
  72. m_bInitialized = false;
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose: Destructor
  76. //-----------------------------------------------------------------------------
  77. CSteam3Client::~CSteam3Client()
  78. {
  79. Shutdown();
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Purpose: Unload the steam3 engine
  83. //-----------------------------------------------------------------------------
  84. void CSteam3Client::Shutdown()
  85. {
  86. if ( !m_bActive )
  87. return;
  88. m_bActive = false;
  89. #if !defined( NO_STEAM )
  90. if( m_bInitialized )
  91. {
  92. SteamAPI_Shutdown();
  93. m_bInitialized = false;
  94. }
  95. Clear(); // Steam API context shutdown
  96. #endif
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: Initialize the steam3 connection
  100. //-----------------------------------------------------------------------------
  101. void CSteam3Client::Activate()
  102. {
  103. if ( m_bActive )
  104. return;
  105. m_bActive = true;
  106. m_bGSSecure = false;
  107. #if !defined( NO_STEAM )
  108. #ifndef _PS3
  109. SteamAPI_InitSafe(); // ignore failure, that will fall out later when they don't get a valid logon cookie
  110. #else
  111. extern SteamPS3Params_t g_EngineSteamPS3Params;
  112. SteamAPI_Init( &g_EngineSteamPS3Params );
  113. #endif
  114. m_bInitialized = Init(); // Steam API context init
  115. if ( m_bInitialized )
  116. {
  117. SteamClient()->SetWarningMessageHook( Callback_SteamAPIWarningMessageHook );
  118. }
  119. #endif
  120. }
  121. //-----------------------------------------------------------------------------
  122. // Purpose: Get the steam3 logon cookie to use
  123. //-----------------------------------------------------------------------------
  124. void CSteam3Client::GetAuthSessionTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket, uint64 unGSSteamID, bool bSecure )
  125. {
  126. m_bGSSecure = bSecure;
  127. #if !defined( NO_STEAM )
  128. if ( !SteamUser() )
  129. return;
  130. Assert( m_hAuthTicket == k_HAuthTicketInvalid );
  131. CSteamID steamID = SteamUser()->GetSteamID();
  132. // prepend the steamID
  133. uint64 ulSteamID = steamID.ConvertToUint64();
  134. // use CUtlBuffer to stick 64 bit steamID into the ticket
  135. CUtlBuffer buffer( pTicket, cbMaxTicket, 0 );
  136. buffer.PutInt64( LittleQWord( ulSteamID ) );
  137. Assert( buffer.TellPut() == sizeof( uint64 ));
  138. pTicket = (uint8 *)buffer.PeekPut();
  139. m_hAuthTicket = SteamUser()->GetAuthSessionTicket( pTicket, cbMaxTicket-sizeof(uint64), pcbTicket );
  140. // include the size of the steamID
  141. (*pcbTicket) = (*pcbTicket) + sizeof(uint64);
  142. #else
  143. return;
  144. #endif
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Purpose: Tell steam that we are leaving a server
  148. //-----------------------------------------------------------------------------
  149. void CSteam3Client::CancelAuthTicket()
  150. {
  151. m_bGSSecure = false;
  152. if ( !SteamUser() )
  153. return;
  154. #if !defined( NO_STEAM )
  155. if ( m_hAuthTicket != k_HAuthTicketInvalid )
  156. SteamUser()->CancelAuthTicket( m_hAuthTicket );
  157. m_hAuthTicket = k_HAuthTicketInvalid;
  158. #endif
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Purpose: Process any callbacks we may have
  162. //-----------------------------------------------------------------------------
  163. void CSteam3Client::RunFrame()
  164. {
  165. #if !defined( NO_STEAM )
  166. VPROF_BUDGET( "CSteam3Client::RunFrame", VPROF_BUDGETGROUP_STEAM );
  167. SteamAPI_RunCallbacks();
  168. #endif
  169. }
  170. #if !defined(NO_STEAM)
  171. //-----------------------------------------------------------------------------
  172. // Purpose: Disconnect the user from their current server
  173. //-----------------------------------------------------------------------------
  174. void CSteam3Client::OnClientGameServerDeny( ClientGameServerDeny_t *pClientGameServerDeny )
  175. {
  176. if ( pClientGameServerDeny->m_uAppID == GetSteamAppID() )
  177. {
  178. const char *pszReason = "Unknown";
  179. switch ( pClientGameServerDeny->m_uReason )
  180. {
  181. case ( k_EDenyInvalidVersion ) : pszReason = "Invalid version"; break;
  182. case ( k_EDenyGeneric ) : pszReason = "Kicked"; break;
  183. case ( k_EDenyNotLoggedOn ) : pszReason = "Not logged on"; break;
  184. case ( k_EDenyNoLicense ) : pszReason = "No license"; break;
  185. case ( k_EDenyCheater ) : pszReason = "VAC banned "; break;
  186. case ( k_EDenyLoggedInElseWhere ) : pszReason = "Dropped from server"; break;
  187. case ( k_EDenyUnknownText ) : pszReason = "Unknown"; break;
  188. case ( k_EDenyIncompatibleAnticheat ) : pszReason = "Incompatible Anti Cheat"; break;
  189. case ( k_EDenyMemoryCorruption ) : pszReason = "Memory corruption"; break;
  190. case ( k_EDenyIncompatibleSoftware ) : pszReason = "Incompatible software"; break;
  191. case ( k_EDenySteamConnectionLost ) : pszReason = "Steam connection lost"; break;
  192. case ( k_EDenySteamConnectionError ) : pszReason = "Steam connection error"; break;
  193. case ( k_EDenySteamResponseTimedOut ) : pszReason = "Response timed out"; break;
  194. // k_EDenySteamValidationStalled is just an informative event, we will receive
  195. // a real validation result later, shouldn't kick client for validation stall!
  196. case ( k_EDenySteamValidationStalled ) : DevMsg( "Validation stalled\n" ); return;
  197. }
  198. Warning( "Disconnect: %s\n", pszReason );
  199. Host_Disconnect( true );
  200. }
  201. }
  202. extern ConVar password;
  203. //-----------------------------------------------------------------------------
  204. // Purpose: Disconnect the user from their current server
  205. //-----------------------------------------------------------------------------
  206. void CSteam3Client::OnGameServerChangeRequested( GameServerChangeRequested_t *pGameServerChangeRequested )
  207. {
  208. #ifdef PORTAL2
  209. if ( GetSteamUniverse() != k_EUniverseBeta && GetSteamUniverse() != k_EUniverseInternal )
  210. {
  211. // Portal 2 doesn't support joining pure servers from Steam Overlay
  212. return;
  213. }
  214. #endif
  215. #ifndef DEDICATED
  216. if ( g_pMatchFramework )
  217. {
  218. g_pMatchFramework->CloseSession(); // Make sure we disconnect from our old server
  219. }
  220. #endif
  221. password.SetValue( pGameServerChangeRequested->m_rgchPassword );
  222. Msg( "Connecting to %s\n", cl_hideserverip.GetInt()>0 ? "<hidden>" : pGameServerChangeRequested->m_rgchServer );
  223. Cbuf_AddText( Cbuf_GetCurrentPlayer(), va( "connect %s\n", pGameServerChangeRequested->m_rgchServer ) );
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Purpose:
  227. //-----------------------------------------------------------------------------
  228. void CSteam3Client::OnGameOverlayActivated( GameOverlayActivated_t *pGameOverlayActivated )
  229. {
  230. g_pInputSystem->ResetInputState();
  231. m_bGameOverlayActive = !!pGameOverlayActivated->m_bActive;
  232. if ( m_bGameOverlayActive )
  233. {
  234. #ifndef DEDICATED
  235. // Don't activate it if it's already active (a sub window may be active)
  236. // Multiplayer doesn't want the UI to appear, since it can't pause anyway
  237. if ( !EngineVGui()->IsGameUIVisible() && sv.IsActive() && sv.IsSinglePlayerGame() )
  238. {
  239. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "gameui_activate" );
  240. }
  241. #endif
  242. }
  243. }
  244. extern void UpdateNameFromSteamID( IConVar *pConVar, CSteamID *pSteamID );
  245. //-----------------------------------------------------------------------------
  246. // Purpose:
  247. //-----------------------------------------------------------------------------
  248. void CSteam3Client::OnPersonaUpdated( PersonaStateChange_t *pPersonaStateChanged )
  249. {
  250. if ( !SteamUtils() || !SteamFriends() || !SteamUser() || !pPersonaStateChanged )
  251. return;
  252. // Check that something changed about local user
  253. CSteamID steamID = SteamUser()->GetSteamID();
  254. if ( steamID.ConvertToUint64() == pPersonaStateChanged->m_ulSteamID )
  255. {
  256. if ( pPersonaStateChanged->m_nChangeFlags & k_EPersonaChangeName )
  257. {
  258. IConVar *pConVar = g_pCVar->FindVar( "name" );
  259. UpdateNameFromSteamID( pConVar, &steamID );
  260. }
  261. }
  262. }
  263. //-----------------------------------------------------------------------------
  264. // Purpose:
  265. //-----------------------------------------------------------------------------
  266. void CSteam3Client::OnLowBattery( LowBatteryPower_t *pLowBat )
  267. {
  268. // on the 9min, 5 min and 1 min warnings tell the engine to fire off a save
  269. switch( pLowBat->m_nMinutesBatteryLeft )
  270. {
  271. case 9:
  272. case 5:
  273. case 1:
  274. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "save LowBattery_AutoSave" );
  275. break;
  276. default:
  277. break;
  278. }
  279. }
  280. //-----------------------------------------------------------------------------
  281. // Purpose:
  282. //-----------------------------------------------------------------------------
  283. void CSteam3Client::OnSteamSocketStatus( SocketStatusCallback_t *pSocketStatus )
  284. {
  285. }
  286. #endif