sv_ccmds.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. // leave this as first line for PCH reasons...
  2. //
  3. #include "../server/exe_headers.h"
  4. #include "server.h"
  5. #include "..\game\weapons.h"
  6. #include "..\game\g_items.h"
  7. #include "..\game\statindex.h"
  8. /*
  9. ===============================================================================
  10. OPERATOR CONSOLE ONLY COMMANDS
  11. These commands can only be entered from stdin or by a remote operator datagram
  12. ===============================================================================
  13. */
  14. qboolean qbLoadTransition = qfalse;
  15. /*
  16. ==================
  17. SV_SetPlayer
  18. Returns the player
  19. ==================
  20. */
  21. static client_t *SV_SetPlayer( void ) {
  22. client_t *cl;
  23. cl = &svs.clients[0];
  24. if ( !cl->state ) {
  25. Com_Printf( "Client is not active\n" );
  26. return NULL;
  27. }
  28. return cl;
  29. }
  30. //=========================================================
  31. // don't call this directly, it should only be called from SV_Map_f() or SV_MapTransition_f()
  32. //
  33. static void SV_Map_( ForceReload_e eForceReload )
  34. {
  35. char *map;
  36. // char expanded[MAX_QPATH];
  37. map = Cmd_Argv(1);
  38. if ( !*map ) {
  39. return;
  40. }
  41. // make sure the level exists before trying to change, so that
  42. // a typo at the server console won't end the game
  43. if (strchr (map, '\\') ) {
  44. Com_Printf ("Can't have mapnames with a \\\n");
  45. return;
  46. }
  47. #ifndef _XBOX // Could check for maps/%s/brushes.mle or something...
  48. Com_sprintf (expanded, sizeof(expanded), "maps/%s.bsp", map);
  49. if ( FS_ReadFile (expanded, NULL) == -1 ) {
  50. Com_Printf ("Can't find map %s\n", expanded);
  51. extern cvar_t *com_buildScript;
  52. if (com_buildScript && com_buildScript->integer)
  53. {//yes, it's happened, someone deleted a map during my build...
  54. Com_Error( ERR_FATAL, "Can't find map %s\n", expanded );
  55. }
  56. return;
  57. }
  58. #endif
  59. if (map[0]!='_')
  60. {
  61. SG_WipeSavegame("Checkpoint");
  62. }
  63. SV_SpawnServer( map, eForceReload, qtrue ); // start up the map
  64. }
  65. // Save out some player data for later restore if this is a spawn point with KEEP_PREV (spawnflags&1) set...
  66. //
  67. // (now also called by auto-save code to setup the cvars correctly
  68. void SV_Player_EndOfLevelSave(void)
  69. {
  70. int i;
  71. // I could just call GetClientState() but that's in sv_bot.cpp, and I'm not sure if that's going to be deleted for
  72. // the single player build, so here's the guts again...
  73. //
  74. client_t* cl = &svs.clients[0]; // 0 because only ever us as a player
  75. if (cl
  76. &&
  77. cl->gentity && cl->gentity->client // crash fix for voy4->brig transition when you kill Foster.
  78. // Shouldn't happen, but does sometimes...
  79. )
  80. {
  81. Cvar_Set( sCVARNAME_PLAYERSAVE, ""); // default to blank
  82. // clientSnapshot_t* pFrame = &cl->frames[cl->netchan.outgoingSequence & PACKET_MASK];
  83. playerState_t* pState = cl->gentity->client;
  84. const char *s2;
  85. // |general info |-force powers |-saber 1 |-saber 2 |-general saber
  86. const char *s = va("%i %i %i %i %i %i %i %f %f %f %i %i %i %i %i %s %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %s %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
  87. pState->stats[STAT_HEALTH],
  88. pState->stats[STAT_ARMOR],
  89. pState->stats[STAT_WEAPONS],
  90. pState->stats[STAT_ITEMS],
  91. pState->weapon,
  92. pState->weaponstate,
  93. pState->batteryCharge,
  94. pState->viewangles[0],
  95. pState->viewangles[1],
  96. pState->viewangles[2],
  97. //force power data
  98. pState->forcePowersKnown,
  99. pState->forcePower,
  100. pState->forcePowerMax,
  101. pState->forcePowerRegenRate,
  102. pState->forcePowerRegenAmount,
  103. //saber 1 data
  104. pState->saber[0].name,
  105. pState->saber[0].blade[0].active,
  106. pState->saber[0].blade[1].active,
  107. pState->saber[0].blade[2].active,
  108. pState->saber[0].blade[3].active,
  109. pState->saber[0].blade[4].active,
  110. pState->saber[0].blade[5].active,
  111. pState->saber[0].blade[6].active,
  112. pState->saber[0].blade[7].active,
  113. pState->saber[0].blade[0].color,
  114. pState->saber[0].blade[1].color,
  115. pState->saber[0].blade[2].color,
  116. pState->saber[0].blade[3].color,
  117. pState->saber[0].blade[4].color,
  118. pState->saber[0].blade[5].color,
  119. pState->saber[0].blade[6].color,
  120. pState->saber[0].blade[7].color,
  121. //saber 2 data
  122. pState->saber[1].name,
  123. pState->saber[1].blade[0].active,
  124. pState->saber[1].blade[1].active,
  125. pState->saber[1].blade[2].active,
  126. pState->saber[1].blade[3].active,
  127. pState->saber[1].blade[4].active,
  128. pState->saber[1].blade[5].active,
  129. pState->saber[1].blade[6].active,
  130. pState->saber[1].blade[7].active,
  131. pState->saber[1].blade[0].color,
  132. pState->saber[1].blade[1].color,
  133. pState->saber[1].blade[2].color,
  134. pState->saber[1].blade[3].color,
  135. pState->saber[1].blade[4].color,
  136. pState->saber[1].blade[5].color,
  137. pState->saber[1].blade[6].color,
  138. pState->saber[1].blade[7].color,
  139. //general saber data
  140. pState->saberStylesKnown,
  141. pState->saberAnimLevel,
  142. pState->saberLockEnemy,
  143. pState->saberLockTime
  144. );
  145. Cvar_Set( sCVARNAME_PLAYERSAVE, s );
  146. //ammo
  147. s2 = "";
  148. for (i=0;i< AMMO_MAX; i++)
  149. {
  150. s2 = va("%s %i",s2, pState->ammo[i]);
  151. }
  152. Cvar_Set( "playerammo", s2 );
  153. //inventory
  154. s2 = "";
  155. for (i=0;i< INV_MAX; i++)
  156. {
  157. s2 = va("%s %i",s2, pState->inventory[i]);
  158. }
  159. Cvar_Set( "playerinv", s2 );
  160. // the new JK2 stuff - force powers, etc...
  161. //
  162. s2 = "";
  163. for (i=0;i< NUM_FORCE_POWERS; i++)
  164. {
  165. s2 = va("%s %i",s2, pState->forcePowerLevel[i]);
  166. }
  167. Cvar_Set( "playerfplvl", s2 );
  168. }
  169. }
  170. // Restart the server on a different map
  171. //
  172. //extern void SCR_PrecacheScreenshot(); //scr_scrn.cpp
  173. static void SV_MapTransition_f(void)
  174. {
  175. char *spawntarget;
  176. // SCR_PrecacheScreenshot();
  177. SV_Player_EndOfLevelSave();
  178. spawntarget = Cmd_Argv(2);
  179. if ( *spawntarget != NULL )
  180. {
  181. Cvar_Set( "spawntarget", spawntarget );
  182. }
  183. else
  184. {
  185. Cvar_Set( "spawntarget", "" );
  186. }
  187. SV_Map_( eForceReload_NOTHING );
  188. }
  189. /*
  190. ==================
  191. SV_Map_f
  192. Restart the server on a different map, but clears a cvar so that typing "map blah" doesn't try and preserve
  193. player weapons/ammo/etc from the previous level that you haven't really exited (ie ignores KEEP_PREV on spawn points)
  194. ==================
  195. */
  196. //void SCR_UnprecacheScreenshot(); //scr_scrn.cpp
  197. static void SV_Map_f( void )
  198. {
  199. Cvar_Set( sCVARNAME_PLAYERSAVE, "");
  200. Cvar_Set( "spawntarget", "" );
  201. Cvar_Set("tier_storyinfo", "0");
  202. Cvar_Set("tiers_complete", "");
  203. // SCR_UnprecacheScreenshot();
  204. ForceReload_e eForceReload = eForceReload_NOTHING; // default for normal load
  205. if ( !Q_stricmp( Cmd_Argv(0), "devmapbsp") ) {
  206. eForceReload = eForceReload_BSP;
  207. }
  208. else
  209. if ( !Q_stricmp( Cmd_Argv(0), "devmapmdl") ) {
  210. eForceReload = eForceReload_MODELS;
  211. }
  212. else
  213. if ( !Q_stricmp( Cmd_Argv(0), "devmapall") ) {
  214. eForceReload = eForceReload_ALL;
  215. }
  216. SV_Map_( eForceReload );
  217. // set the cheat value
  218. // if the level was started with "map <levelname>", then
  219. // cheats will not be allowed. If started with "devmap <levelname>"
  220. // then cheats will be allowed
  221. if ( !Q_stricmpn( Cmd_Argv(0), "devmap", 6 ) ) {
  222. Cvar_Set( "helpUsObi", "1" );
  223. } else {
  224. #ifdef _XBOX
  225. Cvar_Set( "helpUsObi", "1" );
  226. #else
  227. Cvar_Set( "helpUsObi", "0" );
  228. #endif
  229. }
  230. }
  231. /*
  232. ==================
  233. SV_LoadTransition_f
  234. ==================
  235. */
  236. void SV_LoadTransition_f(void)
  237. {
  238. char *map;
  239. char *spawntarget;
  240. map = Cmd_Argv(1);
  241. if ( !*map ) {
  242. return;
  243. }
  244. qbLoadTransition = qtrue;
  245. // SCR_PrecacheScreenshot();
  246. SV_Player_EndOfLevelSave();
  247. //Save the full current state of the current map so we can return to it later
  248. SG_WriteSavegame( va("hub/%s", sv_mapname->string), qfalse );
  249. //set the spawntarget if there is one
  250. spawntarget = Cmd_Argv(2);
  251. if ( *spawntarget != NULL )
  252. {
  253. Cvar_Set( "spawntarget", spawntarget );
  254. }
  255. else
  256. {
  257. Cvar_Set( "spawntarget", "" );
  258. }
  259. if ( !SV_TryLoadTransition( map ) )
  260. {//couldn't load a savegame
  261. SV_Map_( eForceReload_NOTHING );
  262. }
  263. qbLoadTransition = qfalse;
  264. }
  265. //===============================================================
  266. /*
  267. ================
  268. SV_Status_f
  269. ================
  270. */
  271. static void SV_Status_f( void ) {
  272. int i, j, l;
  273. client_t *cl;
  274. const char *s;
  275. int ping;
  276. // make sure server is running
  277. if ( !com_sv_running->integer ) {
  278. Com_Printf( "Server is not running.\n" );
  279. return;
  280. }
  281. Com_Printf ("map: %s\n", sv_mapname->string );
  282. Com_Printf ("num score ping name lastmsg address qport rate\n");
  283. Com_Printf ("--- ----- ---- --------------- ------- --------------------- ----- -----\n");
  284. for (i=0,cl=svs.clients ; i < 1 ; i++,cl++)
  285. {
  286. if (!cl->state)
  287. continue;
  288. Com_Printf ("%3i ", i);
  289. Com_Printf ("%5i ", cl->gentity->client->persistant[PERS_SCORE]);
  290. if (cl->state == CS_CONNECTED)
  291. Com_Printf ("CNCT ");
  292. else if (cl->state == CS_ZOMBIE)
  293. Com_Printf ("ZMBI ");
  294. else
  295. {
  296. ping = cl->ping < 9999 ? cl->ping : 9999;
  297. Com_Printf ("%4i ", ping);
  298. }
  299. Com_Printf ("%s", cl->name);
  300. l = 16 - strlen(cl->name);
  301. for (j=0 ; j<l ; j++)
  302. Com_Printf (" ");
  303. Com_Printf ("%7i ", sv.time - cl->lastPacketTime );
  304. s = NET_AdrToString( cl->netchan.remoteAddress );
  305. Com_Printf ("%s", s);
  306. l = 22 - strlen(s);
  307. for (j=0 ; j<l ; j++)
  308. Com_Printf (" ");
  309. Com_Printf ("%5i", cl->netchan.qport);
  310. Com_Printf (" %5i", cl->rate);
  311. Com_Printf ("\n");
  312. }
  313. Com_Printf ("\n");
  314. }
  315. /*
  316. ===========
  317. SV_Serverinfo_f
  318. Examine the serverinfo string
  319. ===========
  320. */
  321. static void SV_Serverinfo_f( void ) {
  322. Com_Printf ("Server info settings:\n");
  323. Info_Print ( Cvar_InfoString( CVAR_SERVERINFO ) );
  324. }
  325. /*
  326. ===========
  327. SV_Systeminfo_f
  328. Examine or change the serverinfo string
  329. ===========
  330. */
  331. static void SV_Systeminfo_f( void ) {
  332. Com_Printf ("System info settings:\n");
  333. Info_Print ( Cvar_InfoString( CVAR_SYSTEMINFO ) );
  334. }
  335. /*
  336. ===========
  337. SV_DumpUser_f
  338. Examine all a users info strings FIXME: move to game
  339. ===========
  340. */
  341. static void SV_DumpUser_f( void ) {
  342. client_t *cl;
  343. // make sure server is running
  344. if ( !com_sv_running->integer ) {
  345. Com_Printf( "Server is not running.\n" );
  346. return;
  347. }
  348. if ( Cmd_Argc() != 2 ) {
  349. Com_Printf ("Usage: info <userid>\n");
  350. return;
  351. }
  352. cl = SV_SetPlayer();
  353. if ( !cl ) {
  354. return;
  355. }
  356. Com_Printf( "userinfo\n" );
  357. Com_Printf( "--------\n" );
  358. Info_Print( cl->userinfo );
  359. }
  360. //===========================================================
  361. /*
  362. ==================
  363. SV_AddOperatorCommands
  364. ==================
  365. */
  366. void SV_AddOperatorCommands( void ) {
  367. static qboolean initialized;
  368. if ( initialized ) {
  369. return;
  370. }
  371. initialized = qtrue;
  372. Cmd_AddCommand ("status", SV_Status_f);
  373. Cmd_AddCommand ("serverinfo", SV_Serverinfo_f);
  374. Cmd_AddCommand ("systeminfo", SV_Systeminfo_f);
  375. Cmd_AddCommand ("dumpuser", SV_DumpUser_f);
  376. Cmd_AddCommand ("sectorlist", SV_SectorList_f);
  377. Cmd_AddCommand ("map", SV_Map_f);
  378. Cmd_AddCommand ("devmap", SV_Map_f);
  379. Cmd_AddCommand ("devmapbsp", SV_Map_f);
  380. Cmd_AddCommand ("devmapmdl", SV_Map_f);
  381. Cmd_AddCommand ("devmapsnd", SV_Map_f);
  382. Cmd_AddCommand ("devmapall", SV_Map_f);
  383. Cmd_AddCommand ("maptransition", SV_MapTransition_f);
  384. Cmd_AddCommand ("load", SV_LoadGame_f);
  385. Cmd_AddCommand ("loadtransition", SV_LoadTransition_f);
  386. Cmd_AddCommand ("save", SV_SaveGame_f);
  387. Cmd_AddCommand ("wipe", SV_WipeGame_f);
  388. //#ifdef _DEBUG
  389. // extern void UI_Dump_f(void);
  390. // Cmd_AddCommand ("ui_dump", UI_Dump_f);
  391. //#endif
  392. }
  393. /*
  394. ==================
  395. SV_RemoveOperatorCommands
  396. ==================
  397. */
  398. void SV_RemoveOperatorCommands( void ) {
  399. #if 0
  400. // removing these won't let the server start again
  401. Cmd_RemoveCommand ("status");
  402. Cmd_RemoveCommand ("serverinfo");
  403. Cmd_RemoveCommand ("systeminfo");
  404. Cmd_RemoveCommand ("dumpuser");
  405. Cmd_RemoveCommand ("serverrecord");
  406. Cmd_RemoveCommand ("serverstop");
  407. Cmd_RemoveCommand ("sectorlist");
  408. #endif
  409. }