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.

312 lines
11 KiB

  1. //===== Copyright � 1996-2009, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "mm_title.h"
  7. #include "mm_title_richpresence.h"
  8. #include "vstdlib/random.h"
  9. #include "fmtstr.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. class CMatchTitleGameSettingsMgr : public IMatchTitleGameSettingsMgr
  13. {
  14. public:
  15. // Extends server game details
  16. virtual void ExtendServerDetails( KeyValues *pDetails, KeyValues *pRequest );
  17. // Adds the essential part of game details to be broadcast
  18. virtual void ExtendLobbyDetailsTemplate( KeyValues *pDetails, char const *szReason, KeyValues *pFullSettings );
  19. // Extends game settings update packet for lobby transition,
  20. // either due to a migration or due to an endgame condition
  21. virtual void ExtendGameSettingsForLobbyTransition( KeyValues *pSettings, KeyValues *pSettingsUpdate, bool bEndGame );
  22. // Rolls up game details for matches grouping
  23. virtual KeyValues * RollupGameDetails( KeyValues *pDetails, KeyValues *pRollup, KeyValues *pQuery );
  24. // Defines session search keys for matchmaking
  25. virtual KeyValues * DefineSessionSearchKeys( KeyValues *pSettings );
  26. // Defines dedicated server search key
  27. virtual KeyValues * DefineDedicatedSearchKeys( KeyValues *pSettings );
  28. // Initializes full game settings from potentially abbreviated game settings
  29. virtual void InitializeGameSettings( KeyValues *pSettings );
  30. // Extends game settings update packet before it gets merged with
  31. // session settings and networked to remote clients
  32. virtual void ExtendGameSettingsUpdateKeys( KeyValues *pSettings, KeyValues *pUpdateDeleteKeys );
  33. // Prepares system for session creation
  34. virtual KeyValues * PrepareForSessionCreate( KeyValues *pSettings );
  35. // Executes the command on the session settings, this function on host
  36. // is allowed to modify Members/Game subkeys and has to fill in modified players KeyValues
  37. // When running on a remote client "ppPlayersUpdated" is NULL and players cannot
  38. // be modified
  39. virtual void ExecuteCommand( KeyValues *pCommand, KeyValues *pSessionSystemData, KeyValues *pSettings, KeyValues **ppPlayersUpdated );
  40. // Prepares the lobby for game or adjust settings of new players who
  41. // join a game in progress, this function is allowed to modify
  42. // Members/Game subkeys and has to fill in modified players KeyValues
  43. virtual void PrepareLobbyForGame( KeyValues *pSettings, KeyValues **ppPlayersUpdated );
  44. // Prepares the host team lobby for game adjusting the game settings
  45. // this function is allowed to prepare modification package to update
  46. // Game subkeys.
  47. // Returns the update/delete package to be applied to session settings
  48. // and pushed to dependent two sesssion of the two teams.
  49. virtual KeyValues * PrepareTeamLinkForGame( KeyValues *pSettingsLocal, KeyValues *pSettingsRemote );
  50. };
  51. CMatchTitleGameSettingsMgr g_MatchTitleGameSettingsMgr;
  52. IMatchTitleGameSettingsMgr *g_pIMatchTitleGameSettingsMgr = &g_MatchTitleGameSettingsMgr;
  53. //
  54. // Implementation of CMatchTitleGameSettingsMgr
  55. //
  56. // Extends server game details
  57. void CMatchTitleGameSettingsMgr::ExtendServerDetails( KeyValues *pDetails, KeyValues *pRequest )
  58. {
  59. // Query server info
  60. INetSupport::ServerInfo_t si;
  61. g_pMatchExtensions->GetINetSupport()->GetServerInfo( &si );
  62. // Server is always in game
  63. pDetails->SetString( "game/state", "game" );
  64. //
  65. // Determine map info
  66. //
  67. {
  68. pDetails->SetString( "game/bspname", CFmtStr( "%s", si.m_szMapName ) );
  69. }
  70. }
  71. // Adds the essential part of game details to be broadcast
  72. void CMatchTitleGameSettingsMgr::ExtendLobbyDetailsTemplate( KeyValues *pDetails, char const *szReason, KeyValues *pFullSettings )
  73. {
  74. static KeyValues *pkvExt = KeyValues::FromString(
  75. "settings",
  76. " game { "
  77. " bspname #empty# "
  78. " } "
  79. );
  80. pDetails->MergeFrom( pkvExt, KeyValues::MERGE_KV_UPDATE );
  81. }
  82. // Extends game settings update packet for lobby transition,
  83. // either due to a migration or due to an endgame condition
  84. void CMatchTitleGameSettingsMgr::ExtendGameSettingsForLobbyTransition( KeyValues *pSettings, KeyValues *pSettingsUpdate, bool bEndGame )
  85. {
  86. pSettingsUpdate->SetString( "game/state", "lobby" );
  87. }
  88. // Rolls up game details for matches grouping
  89. KeyValues * CMatchTitleGameSettingsMgr::RollupGameDetails( KeyValues *pDetails, KeyValues *pRollup, KeyValues *pQuery )
  90. {
  91. return NULL;
  92. }
  93. // Defines dedicated server search key
  94. KeyValues * CMatchTitleGameSettingsMgr::DefineDedicatedSearchKeys( KeyValues *pSettings )
  95. {
  96. if ( IsPC() )
  97. {
  98. static ConVarRef sv_search_key( "sv_search_key" );
  99. KeyValues *pKeys = new KeyValues( "SearchKeys" );
  100. pKeys->SetString( "gametype", CFmtStr( "%s,sv_search_key_%s%d",
  101. "empty",
  102. sv_search_key.GetString(),
  103. g_pMatchExtensions->GetINetSupport()->GetEngineBuildNumber() ) );
  104. return pKeys;
  105. }
  106. else
  107. {
  108. return NULL;
  109. }
  110. }
  111. // Defines session search keys for matchmaking
  112. KeyValues * CMatchTitleGameSettingsMgr::DefineSessionSearchKeys( KeyValues *pSettings )
  113. {
  114. MEM_ALLOC_CREDIT();
  115. KeyValues *pResult = new KeyValues( "SessionSearch" );
  116. pResult->SetInt( "numPlayers", pSettings->GetInt( "members/numPlayers", XBX_GetNumGameUsers() ) );
  117. /*
  118. char const *szGameMode = pSettings->GetString( "game/mode", "" );
  119. if ( IsX360() )
  120. {
  121. if ( char const *szValue = pSettings->GetString( "game/mode", NULL ) )
  122. {
  123. static ContextValue_t values[] = {
  124. { "versus", SESSION_MATCH_QUERY_PUBLIC_STATE_C___SORT___CHAPTER },
  125. { "teamversus", SESSION_MATCH_QUERY_TEAM_STATE_C_CHAPTER },
  126. { "scavenge", SESSION_MATCH_QUERY_PUBLIC_STATE_C_CHAPTER___SORT___ROUNDS },
  127. { "teamscavenge", SESSION_MATCH_QUERY_TEAM_STATE_C_CHAPTER_ROUNDS },
  128. { "survival", SESSION_MATCH_QUERY_PUBLIC_STATE_C_CHAPTER },
  129. { "coop", SESSION_MATCH_QUERY_PUBLIC_STATE_C_DIFF___SORT___CHAPTER },
  130. { "realism", SESSION_MATCH_QUERY_PUBLIC_STATE_C_DIFF___SORT___CHAPTER },
  131. { NULL, 0xFFFF },
  132. };
  133. pResult->SetInt( "rule", values->ScanValues( szValue ) );
  134. }
  135. // Set the matchmaking version
  136. pResult->SetInt( CFmtStr( "Properties/%d", PROPERTY_MMVERSION ), mm_matchmaking_version.GetInt() );
  137. #ifdef _X360
  138. // Set the installed DLCs masks
  139. uint64 uiDlcsMask = MatchSession_GetDlcInstalledMask();
  140. for ( int k = 1; k <= mm_matchmaking_dlcsquery.GetInt(); ++ k )
  141. {
  142. pResult->SetInt( CFmtStr( "Properties/%d", PROPERTY_MMVERSION + k ), !!( uiDlcsMask & ( 1ull << k ) ) );
  143. }
  144. pResult->SetInt( "dlc1", PROPERTY_MMVERSION + 1 );
  145. pResult->SetInt( "dlcN", PROPERTY_MMVERSION + mm_matchmaking_dlcsquery.GetInt() );
  146. #endif
  147. // X_CONTEXT_GAME_TYPE
  148. pResult->SetInt( CFmtStr( "Contexts/%d", X_CONTEXT_GAME_TYPE ), X_CONTEXT_GAME_TYPE_STANDARD );
  149. // X_CONTEXT_GAME_MODE
  150. if ( char const *szValue = pSettings->GetString( "game/mode", NULL ) )
  151. {
  152. pResult->SetInt( CFmtStr( "Contexts/%d", X_CONTEXT_GAME_MODE ), g_pcv_CONTEXT_GAME_MODE->ScanValues( szValue ) );
  153. }
  154. if ( char const *szValue = pSettings->GetString( "game/state", NULL ) )
  155. {
  156. pResult->SetInt( CFmtStr( "Contexts/%d", CONTEXT_STATE ), g_pcv_CONTEXT_STATE->ScanValues( szValue ) );
  157. }
  158. if ( char const *szValue = pSettings->GetString( "game/difficulty", NULL ) )
  159. {
  160. if ( !Q_stricmp( "coop", szGameMode ) || !Q_stricmp( "realism", szGameMode ) )
  161. {
  162. pResult->SetInt( CFmtStr( "Contexts/%d", CONTEXT_DIFFICULTY ), g_pcv_CONTEXT_DIFFICULTY->ScanValues( szValue ) );
  163. }
  164. }
  165. if ( int val = pSettings->GetInt( "game/maxrounds" ) )
  166. {
  167. if ( !Q_stricmp( "scavenge", szGameMode ) || !Q_stricmp( "teamscavenge", szGameMode ) )
  168. {
  169. pResult->SetInt( CFmtStr( "Properties/%d", PROPERTY_MAXROUNDS ), val );
  170. }
  171. }
  172. char const *szCampaign = pSettings->GetString( "game/campaign" );
  173. if ( *szCampaign )
  174. {
  175. DWORD dwContext = CONTEXT_CAMPAIGN_UNKNOWN;
  176. if ( KeyValues *pAllMissions = g_pMatchExtL4D->GetAllMissions() )
  177. {
  178. if ( KeyValues *pMission = pAllMissions->FindKey( szCampaign ) )
  179. {
  180. dwContext = pMission->GetInt( "x360ctx", dwContext );
  181. }
  182. }
  183. if ( dwContext != CONTEXT_CAMPAIGN_UNKNOWN )
  184. {
  185. pResult->SetInt( CFmtStr( "Contexts/%d", CONTEXT_CAMPAIGN ), dwContext );
  186. }
  187. }
  188. if ( int val = pSettings->GetInt( "game/chapter" ) )
  189. {
  190. pResult->SetInt( CFmtStr( "Properties/%d", PROPERTY_CHAPTER ), val );
  191. }
  192. }
  193. else
  194. */
  195. {
  196. if ( char const *szValue = pSettings->GetString( "game/bspname", NULL ) )
  197. {
  198. pResult->SetString( "Filter=/game:bspname", szValue );
  199. }
  200. }
  201. return pResult;
  202. }
  203. // Initializes full game settings from potentially abbreviated game settings
  204. void CMatchTitleGameSettingsMgr::InitializeGameSettings( KeyValues *pSettings )
  205. {
  206. char const *szNetwork = pSettings->GetString( "system/network", "LIVE" );
  207. if ( KeyValues *kv = pSettings->FindKey( "game", true ) )
  208. {
  209. kv->SetString( "state", "lobby" );
  210. }
  211. // Offline games don't need slots and player setup
  212. if ( !Q_stricmp( "offline", szNetwork ) )
  213. return;
  214. //
  215. // Set the number of slots
  216. //
  217. int numSlots = 2;
  218. pSettings->SetInt( "members/numSlots", numSlots );
  219. }
  220. // Extends game settings update packet before it gets merged with
  221. // session settings and networked to remote clients
  222. void CMatchTitleGameSettingsMgr::ExtendGameSettingsUpdateKeys( KeyValues *pSettings, KeyValues *pUpdateDeleteKeys )
  223. {
  224. }
  225. // Prepares system for session creation
  226. KeyValues * CMatchTitleGameSettingsMgr::PrepareForSessionCreate( KeyValues *pSettings )
  227. {
  228. return MM_Title_RichPresence_PrepareForSessionCreate( pSettings );
  229. }
  230. // Prepares the lobby for game or adjust settings of new players who
  231. // join a game in progress, this function is allowed to modify
  232. // Members/Game subkeys and has to write modified players XUIDs
  233. void CMatchTitleGameSettingsMgr::PrepareLobbyForGame( KeyValues *pSettings, KeyValues **ppPlayersUpdated )
  234. {
  235. // set player avatar/teams, etc
  236. }
  237. // Prepares the host team lobby for game adjusting the game settings
  238. // this function is allowed to prepare modification package to update
  239. // Game subkeys.
  240. // Returns the update/delete package to be applied to session settings
  241. // and pushed to dependent two sesssion of the two teams.
  242. KeyValues * CMatchTitleGameSettingsMgr::PrepareTeamLinkForGame( KeyValues *pSettingsLocal, KeyValues *pSettingsRemote )
  243. {
  244. return NULL;
  245. }
  246. // Executes the command on the session settings, this function on host
  247. // is allowed to modify Members/Game subkeys and has to fill in modified players KeyValues
  248. // When running on a remote client "ppPlayersUpdated" is NULL and players cannot
  249. // be modified
  250. void CMatchTitleGameSettingsMgr::ExecuteCommand( KeyValues *pCommand, KeyValues *pSessionSystemData, KeyValues *pSettings, KeyValues **ppPlayersUpdated )
  251. {
  252. //char const *szCommand = pCommand->GetName();
  253. }