AsyncNetwork.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "AsyncNetwork.h"
  23. idAsyncServer idAsyncNetwork::server;
  24. idAsyncClient idAsyncNetwork::client;
  25. idCVar idAsyncNetwork::verbose( "net_verbose", "0", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "1 = verbose output, 2 = even more verbose output", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
  26. idCVar idAsyncNetwork::allowCheats( "net_allowCheats", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_NETWORKSYNC, "Allow cheats in network game" );
  27. #ifdef ID_DEDICATED
  28. // dedicated executable can only have a value of 1 for net_serverDedicated
  29. idCVar idAsyncNetwork::serverDedicated( "net_serverDedicated", "1", CVAR_SERVERINFO | CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT | CVAR_ROM, "" );
  30. #else
  31. idCVar idAsyncNetwork::serverDedicated( "net_serverDedicated", "0", CVAR_SERVERINFO | CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "1 = text console dedicated server, 2 = graphical dedicated server", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
  32. #endif
  33. idCVar idAsyncNetwork::serverSnapshotDelay( "net_serverSnapshotDelay", "50", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "delay between snapshots in milliseconds" );
  34. idCVar idAsyncNetwork::serverMaxClientRate( "net_serverMaxClientRate", "16000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE | CVAR_NOCHEAT, "maximum rate to a client in bytes/sec" );
  35. idCVar idAsyncNetwork::clientMaxRate( "net_clientMaxRate", "16000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE | CVAR_NOCHEAT, "maximum rate requested by client from server in bytes/sec" );
  36. idCVar idAsyncNetwork::serverMaxUsercmdRelay( "net_serverMaxUsercmdRelay", "5", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "maximum number of usercmds from other clients the server relays to a client", 1, MAX_USERCMD_RELAY, idCmdSystem::ArgCompletion_Integer<1,MAX_USERCMD_RELAY> );
  37. idCVar idAsyncNetwork::serverZombieTimeout( "net_serverZombieTimeout", "5", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "disconnected client timeout in seconds" );
  38. idCVar idAsyncNetwork::serverClientTimeout( "net_serverClientTimeout", "40", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "client time out in seconds" );
  39. idCVar idAsyncNetwork::clientServerTimeout( "net_clientServerTimeout", "40", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "server time out in seconds" );
  40. idCVar idAsyncNetwork::serverDrawClient( "net_serverDrawClient", "-1", CVAR_SYSTEM | CVAR_INTEGER, "number of client for which to draw view on server" );
  41. idCVar idAsyncNetwork::serverRemoteConsolePassword( "net_serverRemoteConsolePassword", "", CVAR_SYSTEM | CVAR_NOCHEAT, "remote console password" );
  42. idCVar idAsyncNetwork::clientPrediction( "net_clientPrediction", "16", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "additional client side prediction in milliseconds" );
  43. idCVar idAsyncNetwork::clientMaxPrediction( "net_clientMaxPrediction", "1000", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "maximum number of milliseconds a client can predict ahead of server." );
  44. idCVar idAsyncNetwork::clientUsercmdBackup( "net_clientUsercmdBackup", "5", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "number of usercmds to resend" );
  45. idCVar idAsyncNetwork::clientRemoteConsoleAddress( "net_clientRemoteConsoleAddress", "localhost", CVAR_SYSTEM | CVAR_NOCHEAT, "remote console address" );
  46. idCVar idAsyncNetwork::clientRemoteConsolePassword( "net_clientRemoteConsolePassword", "", CVAR_SYSTEM | CVAR_NOCHEAT, "remote console password" );
  47. idCVar idAsyncNetwork::master0( "net_master0", IDNET_HOST ":" IDNET_MASTER_PORT, CVAR_SYSTEM | CVAR_ROM, "idnet master server address" );
  48. idCVar idAsyncNetwork::master1( "net_master1", "", CVAR_SYSTEM | CVAR_ARCHIVE, "1st master server address" );
  49. idCVar idAsyncNetwork::master2( "net_master2", "", CVAR_SYSTEM | CVAR_ARCHIVE, "2nd master server address" );
  50. idCVar idAsyncNetwork::master3( "net_master3", "", CVAR_SYSTEM | CVAR_ARCHIVE, "3rd master server address" );
  51. idCVar idAsyncNetwork::master4( "net_master4", "", CVAR_SYSTEM | CVAR_ARCHIVE, "4th master server address" );
  52. idCVar idAsyncNetwork::LANServer( "net_LANServer", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_NOCHEAT, "config LAN games only - affects clients and servers" );
  53. idCVar idAsyncNetwork::serverReloadEngine( "net_serverReloadEngine", "0", CVAR_SYSTEM | CVAR_INTEGER | CVAR_NOCHEAT, "perform a full reload on next map restart (including flushing referenced pak files) - decreased if > 0" );
  54. idCVar idAsyncNetwork::serverAllowServerMod( "net_serverAllowServerMod", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_NOCHEAT, "allow server-side mods" );
  55. idCVar idAsyncNetwork::idleServer( "si_idleServer", "0", CVAR_SYSTEM | CVAR_BOOL | CVAR_INIT | CVAR_SERVERINFO, "game clients are idle" );
  56. idCVar idAsyncNetwork::clientDownload( "net_clientDownload", "1", CVAR_SYSTEM | CVAR_INTEGER | CVAR_ARCHIVE, "client pk4 downloads policy: 0 - never, 1 - ask, 2 - always (will still prompt for binary code)" );
  57. int idAsyncNetwork::realTime;
  58. master_t idAsyncNetwork::masters[ MAX_MASTER_SERVERS ];
  59. /*
  60. ==================
  61. idAsyncNetwork::idAsyncNetwork
  62. ==================
  63. */
  64. idAsyncNetwork::idAsyncNetwork( void ) {
  65. }
  66. /*
  67. ==================
  68. idAsyncNetwork::Init
  69. ==================
  70. */
  71. void idAsyncNetwork::Init( void ) {
  72. realTime = 0;
  73. memset( masters, 0, sizeof( masters ) );
  74. masters[0].var = &master0;
  75. masters[1].var = &master1;
  76. masters[2].var = &master2;
  77. masters[3].var = &master3;
  78. masters[4].var = &master4;
  79. #ifndef ID_DEMO_BUILD
  80. cmdSystem->AddCommand( "spawnServer", SpawnServer_f, CMD_FL_SYSTEM, "spawns a server", idCmdSystem::ArgCompletion_MapName );
  81. cmdSystem->AddCommand( "nextMap", NextMap_f, CMD_FL_SYSTEM, "loads the next map on the server" );
  82. cmdSystem->AddCommand( "connect", Connect_f, CMD_FL_SYSTEM, "connects to a server" );
  83. cmdSystem->AddCommand( "reconnect", Reconnect_f, CMD_FL_SYSTEM, "reconnect to the last server we tried to connect to" );
  84. cmdSystem->AddCommand( "serverInfo", GetServerInfo_f, CMD_FL_SYSTEM, "shows server info" );
  85. cmdSystem->AddCommand( "LANScan", GetLANServers_f, CMD_FL_SYSTEM, "scans LAN for servers" );
  86. cmdSystem->AddCommand( "listServers", ListServers_f, CMD_FL_SYSTEM, "lists scanned servers" );
  87. cmdSystem->AddCommand( "rcon", RemoteConsole_f, CMD_FL_SYSTEM, "sends remote console command to server" );
  88. cmdSystem->AddCommand( "heartbeat", Heartbeat_f, CMD_FL_SYSTEM, "send a heartbeat to the the master servers" );
  89. cmdSystem->AddCommand( "kick", Kick_f, CMD_FL_SYSTEM, "kick a client by connection number" );
  90. cmdSystem->AddCommand( "checkNewVersion", CheckNewVersion_f, CMD_FL_SYSTEM, "check if a new version of the game is available" );
  91. cmdSystem->AddCommand( "updateUI", UpdateUI_f, CMD_FL_SYSTEM, "internal - cause a sync down of game-modified userinfo" );
  92. #endif
  93. }
  94. /*
  95. ==================
  96. idAsyncNetwork::GetMasterAddress
  97. ==================
  98. */
  99. netadr_t idAsyncNetwork::GetMasterAddress( void ) {
  100. netadr_t ret;
  101. GetMasterAddress( 0, ret );
  102. return masters[ 0 ].address;
  103. }
  104. /*
  105. ==================
  106. idAsyncNetwork::GetMasterAddress
  107. ==================
  108. */
  109. bool idAsyncNetwork::GetMasterAddress( int index, netadr_t &adr ) {
  110. if ( !masters[ index ].var ) {
  111. return false;
  112. }
  113. if ( masters[ index ].var->GetString()[0] == '\0' ) {
  114. return false;
  115. }
  116. if ( !masters[ index ].resolved || masters[ index ].var->IsModified() ) {
  117. masters[ index ].var->ClearModified();
  118. if ( !Sys_StringToNetAdr( masters[ index ].var->GetString(), &masters[ index ].address, true ) ) {
  119. common->Printf( "Failed to resolve master%d: %s\n", index, masters[ index ].var->GetString() );
  120. memset( &masters[ index ].address, 0, sizeof( netadr_t ) );
  121. masters[ index ].resolved = true;
  122. return false;
  123. }
  124. if ( masters[ index ].address.port == 0 ) {
  125. masters[ index ].address.port = atoi( IDNET_MASTER_PORT );
  126. }
  127. masters[ index ].resolved = true;
  128. }
  129. adr = masters[ index ].address;
  130. return true;
  131. }
  132. /*
  133. ==================
  134. idAsyncNetwork::Shutdown
  135. ==================
  136. */
  137. void idAsyncNetwork::Shutdown( void ) {
  138. client.serverList.Shutdown();
  139. client.DisconnectFromServer();
  140. client.ClearServers();
  141. client.ClosePort();
  142. server.Kill();
  143. server.ClosePort();
  144. }
  145. /*
  146. ==================
  147. idAsyncNetwork::RunFrame
  148. ==================
  149. */
  150. void idAsyncNetwork::RunFrame( void ) {
  151. if ( console->Active() ) {
  152. Sys_GrabMouseCursor( false );
  153. usercmdGen->InhibitUsercmd( INHIBIT_ASYNC, true );
  154. } else {
  155. Sys_GrabMouseCursor( true );
  156. usercmdGen->InhibitUsercmd( INHIBIT_ASYNC, false );
  157. }
  158. client.RunFrame();
  159. server.RunFrame();
  160. }
  161. /*
  162. ==================
  163. idAsyncNetwork::WriteUserCmdDelta
  164. ==================
  165. */
  166. void idAsyncNetwork::WriteUserCmdDelta( idBitMsg &msg, const usercmd_t &cmd, const usercmd_t *base ) {
  167. if ( base ) {
  168. msg.WriteDeltaLongCounter( base->gameTime, cmd.gameTime );
  169. msg.WriteDeltaByte( base->buttons, cmd.buttons );
  170. msg.WriteDeltaShort( base->mx, cmd.mx );
  171. msg.WriteDeltaShort( base->my, cmd.my );
  172. msg.WriteDeltaChar( base->forwardmove, cmd.forwardmove );
  173. msg.WriteDeltaChar( base->rightmove, cmd.rightmove );
  174. msg.WriteDeltaChar( base->upmove, cmd.upmove );
  175. msg.WriteDeltaShort( base->angles[0], cmd.angles[0] );
  176. msg.WriteDeltaShort( base->angles[1], cmd.angles[1] );
  177. msg.WriteDeltaShort( base->angles[2], cmd.angles[2] );
  178. return;
  179. }
  180. msg.WriteLong( cmd.gameTime );
  181. msg.WriteByte( cmd.buttons );
  182. msg.WriteShort( cmd.mx );
  183. msg.WriteShort( cmd.my );
  184. msg.WriteChar( cmd.forwardmove );
  185. msg.WriteChar( cmd.rightmove );
  186. msg.WriteChar( cmd.upmove );
  187. msg.WriteShort( cmd.angles[0] );
  188. msg.WriteShort( cmd.angles[1] );
  189. msg.WriteShort( cmd.angles[2] );
  190. }
  191. /*
  192. ==================
  193. idAsyncNetwork::ReadUserCmdDelta
  194. ==================
  195. */
  196. void idAsyncNetwork::ReadUserCmdDelta( const idBitMsg &msg, usercmd_t &cmd, const usercmd_t *base ) {
  197. memset( &cmd, 0, sizeof( cmd ) );
  198. if ( base ) {
  199. cmd.gameTime = msg.ReadDeltaLongCounter( base->gameTime );
  200. cmd.buttons = msg.ReadDeltaByte( base->buttons );
  201. cmd.mx = msg.ReadDeltaShort( base->mx );
  202. cmd.my = msg.ReadDeltaShort( base->my );
  203. cmd.forwardmove = msg.ReadDeltaChar( base->forwardmove );
  204. cmd.rightmove = msg.ReadDeltaChar( base->rightmove );
  205. cmd.upmove = msg.ReadDeltaChar( base->upmove );
  206. cmd.angles[0] = msg.ReadDeltaShort( base->angles[0] );
  207. cmd.angles[1] = msg.ReadDeltaShort( base->angles[1] );
  208. cmd.angles[2] = msg.ReadDeltaShort( base->angles[2] );
  209. return;
  210. }
  211. cmd.gameTime = msg.ReadLong();
  212. cmd.buttons = msg.ReadByte();
  213. cmd.mx = msg.ReadShort();
  214. cmd.my = msg.ReadShort();
  215. cmd.forwardmove = msg.ReadChar();
  216. cmd.rightmove = msg.ReadChar();
  217. cmd.upmove = msg.ReadChar();
  218. cmd.angles[0] = msg.ReadShort();
  219. cmd.angles[1] = msg.ReadShort();
  220. cmd.angles[2] = msg.ReadShort();
  221. }
  222. /*
  223. ==================
  224. idAsyncNetwork::DuplicateUsercmd
  225. ==================
  226. */
  227. bool idAsyncNetwork::DuplicateUsercmd( const usercmd_t &previousUserCmd, usercmd_t &currentUserCmd, int frame, int time ) {
  228. if ( currentUserCmd.gameTime <= previousUserCmd.gameTime ) {
  229. currentUserCmd = previousUserCmd;
  230. currentUserCmd.gameFrame = frame;
  231. currentUserCmd.gameTime = time;
  232. currentUserCmd.duplicateCount++;
  233. if ( currentUserCmd.duplicateCount > MAX_USERCMD_DUPLICATION ) {
  234. currentUserCmd.buttons &= ~BUTTON_ATTACK;
  235. if ( abs( currentUserCmd.forwardmove ) > 2 ) currentUserCmd.forwardmove >>= 1;
  236. if ( abs( currentUserCmd.rightmove ) > 2 ) currentUserCmd.rightmove >>= 1;
  237. if ( abs( currentUserCmd.upmove ) > 2 ) currentUserCmd.upmove >>= 1;
  238. }
  239. return true;
  240. }
  241. return false;
  242. }
  243. /*
  244. ==================
  245. idAsyncNetwork::UsercmdInputChanged
  246. ==================
  247. */
  248. bool idAsyncNetwork::UsercmdInputChanged( const usercmd_t &previousUserCmd, const usercmd_t &currentUserCmd ) {
  249. return previousUserCmd.buttons != currentUserCmd.buttons ||
  250. previousUserCmd.forwardmove != currentUserCmd.forwardmove ||
  251. previousUserCmd.rightmove != currentUserCmd.rightmove ||
  252. previousUserCmd.upmove != currentUserCmd.upmove ||
  253. previousUserCmd.angles[0] != currentUserCmd.angles[0] ||
  254. previousUserCmd.angles[1] != currentUserCmd.angles[1] ||
  255. previousUserCmd.angles[2] != currentUserCmd.angles[2];
  256. }
  257. /*
  258. ==================
  259. idAsyncNetwork::SpawnServer_f
  260. ==================
  261. */
  262. void idAsyncNetwork::SpawnServer_f( const idCmdArgs &args ) {
  263. if(args.Argc() > 1) {
  264. cvarSystem->SetCVarString("si_map", args.Argv(1));
  265. }
  266. // don't let a server spawn with singleplayer game type - it will crash
  267. if ( idStr::Icmp( cvarSystem->GetCVarString( "si_gameType" ), "singleplayer" ) == 0 ) {
  268. cvarSystem->SetCVarString( "si_gameType", "deathmatch" );
  269. }
  270. com_asyncInput.SetBool( false );
  271. // make sure the current system state is compatible with net_serverDedicated
  272. switch ( cvarSystem->GetCVarInteger( "net_serverDedicated" ) ) {
  273. case 0:
  274. case 2:
  275. if ( !renderSystem->IsOpenGLRunning() ) {
  276. common->Warning( "OpenGL is not running, net_serverDedicated == %d", cvarSystem->GetCVarInteger( "net_serverDedicated" ) );
  277. }
  278. break;
  279. case 1:
  280. if ( renderSystem->IsOpenGLRunning() ) {
  281. Sys_ShowConsole( 1, false );
  282. renderSystem->ShutdownOpenGL();
  283. }
  284. soundSystem->SetMute( true );
  285. soundSystem->ShutdownHW();
  286. break;
  287. }
  288. // use serverMapRestart if we already have a running server
  289. if ( server.IsActive() ) {
  290. cmdSystem->BufferCommandText( CMD_EXEC_NOW, "serverMapRestart" );
  291. } else {
  292. server.Spawn();
  293. }
  294. }
  295. /*
  296. ==================
  297. idAsyncNetwork::NextMap_f
  298. ==================
  299. */
  300. void idAsyncNetwork::NextMap_f( const idCmdArgs &args ) {
  301. server.ExecuteMapChange();
  302. }
  303. /*
  304. ==================
  305. idAsyncNetwork::Connect_f
  306. ==================
  307. */
  308. void idAsyncNetwork::Connect_f( const idCmdArgs &args ) {
  309. if ( server.IsActive() ) {
  310. common->Printf( "already running a server\n" );
  311. return;
  312. }
  313. if ( args.Argc() != 2 ) {
  314. common->Printf( "USAGE: connect <serverName>\n" );
  315. return;
  316. }
  317. com_asyncInput.SetBool( false );
  318. client.ConnectToServer( args.Argv( 1 ) );
  319. }
  320. /*
  321. ==================
  322. idAsyncNetwork::Reconnect_f
  323. ==================
  324. */
  325. void idAsyncNetwork::Reconnect_f( const idCmdArgs &args ) {
  326. client.Reconnect();
  327. }
  328. /*
  329. ==================
  330. idAsyncNetwork::GetServerInfo_f
  331. ==================
  332. */
  333. void idAsyncNetwork::GetServerInfo_f( const idCmdArgs &args ) {
  334. client.GetServerInfo( args.Argv( 1 ) );
  335. }
  336. /*
  337. ==================
  338. idAsyncNetwork::GetLANServers_f
  339. ==================
  340. */
  341. void idAsyncNetwork::GetLANServers_f( const idCmdArgs &args ) {
  342. client.GetLANServers();
  343. }
  344. /*
  345. ==================
  346. idAsyncNetwork::ListServers_f
  347. ==================
  348. */
  349. void idAsyncNetwork::ListServers_f( const idCmdArgs &args ) {
  350. client.ListServers();
  351. }
  352. /*
  353. ==================
  354. idAsyncNetwork::RemoteConsole_f
  355. ==================
  356. */
  357. void idAsyncNetwork::RemoteConsole_f( const idCmdArgs &args ) {
  358. client.RemoteConsole( args.Args() );
  359. }
  360. /*
  361. ==================
  362. idAsyncNetwork::Heartbeat_f
  363. ==================
  364. */
  365. void idAsyncNetwork::Heartbeat_f( const idCmdArgs &args ) {
  366. if ( !server.IsActive() ) {
  367. common->Printf( "server is not running\n" );
  368. return;
  369. }
  370. server.MasterHeartbeat( true );
  371. }
  372. /*
  373. ==================
  374. idAsyncNetwork::Kick_f
  375. ==================
  376. */
  377. void idAsyncNetwork::Kick_f( const idCmdArgs &args ) {
  378. idStr clientId;
  379. int iclient;
  380. if ( !server.IsActive() ) {
  381. common->Printf( "server is not running\n" );
  382. return;
  383. }
  384. clientId = args.Argv( 1 );
  385. if ( !clientId.IsNumeric() ) {
  386. common->Printf( "usage: kick <client number>\n" );
  387. return;
  388. }
  389. iclient = atoi( clientId );
  390. if ( server.GetLocalClientNum() == iclient ) {
  391. common->Printf( "can't kick the host\n" );
  392. return;
  393. }
  394. server.DropClient( iclient, "#str_07134" );
  395. }
  396. /*
  397. ==================
  398. idAsyncNetwork::GetNETServers
  399. ==================
  400. */
  401. void idAsyncNetwork::GetNETServers( ) {
  402. client.GetNETServers();
  403. }
  404. /*
  405. ==================
  406. idAsyncNetwork::CheckNewVersion_f
  407. ==================
  408. */
  409. void idAsyncNetwork::CheckNewVersion_f( const idCmdArgs &args ) {
  410. client.SendVersionCheck();
  411. }
  412. /*
  413. ==================
  414. idAsyncNetwork::ExecuteSessionCommand
  415. ==================
  416. */
  417. void idAsyncNetwork::ExecuteSessionCommand( const char *sessCmd ) {
  418. if ( sessCmd[ 0 ] ) {
  419. if ( !idStr::Icmp( sessCmd, "game_startmenu" ) ) {
  420. session->SetGUI( game->StartMenu(), NULL );
  421. }
  422. }
  423. }
  424. /*
  425. =================
  426. idAsyncNetwork::UpdateUI_f
  427. =================
  428. */
  429. void idAsyncNetwork::UpdateUI_f( const idCmdArgs &args ) {
  430. if ( args.Argc() != 2 ) {
  431. common->Warning( "idAsyncNetwork::UpdateUI_f: wrong arguments\n" );
  432. return;
  433. }
  434. if ( !server.IsActive() ) {
  435. common->Warning( "idAsyncNetwork::UpdateUI_f: server is not active\n" );
  436. return;
  437. }
  438. int clientNum = atoi( args.Args( 1 ) );
  439. server.UpdateUI( clientNum );
  440. }
  441. /*
  442. ===============
  443. idAsyncNetwork::BuildInvalidKeyMsg
  444. ===============
  445. */
  446. void idAsyncNetwork::BuildInvalidKeyMsg( idStr &msg, bool valid[ 2 ] ) {
  447. if ( !valid[ 0 ] ) {
  448. msg += common->GetLanguageDict()->GetString( "#str_07194" );
  449. }
  450. if ( fileSystem->HasD3XP() && !valid[ 1 ] ) {
  451. if ( msg.Length() ) {
  452. msg += "\n";
  453. }
  454. msg += common->GetLanguageDict()->GetString( "#str_07195" );
  455. }
  456. msg += "\n";
  457. msg += common->GetLanguageDict()->GetString( "#str_04304" );
  458. }