home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / server / sv_user.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  43KB  |  1,703 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // sv_user.c -- server code for moving users
  21.  
  22. #include "qwsvdef.h"
  23.  
  24. edict_t *sv_player;
  25.  
  26. usercmd_t cmd;
  27.  
  28. cvar_t  cl_rollspeed = {"cl_rollspeed", "200"};
  29. cvar_t  cl_rollangle = {"cl_rollangle", "2.0"};
  30. cvar_t  sv_spectalk = {"sv_spectalk", "1"};
  31.  
  32. cvar_t  sv_mapcheck = {"sv_mapcheck", "1"};
  33.  
  34. extern  vec3_t  player_mins;
  35.  
  36. extern int fp_messages, fp_persecond, fp_secondsdead;
  37. extern char fp_msg[];
  38. extern cvar_t pausable;
  39.  
  40. /*
  41. ============================================================
  42.  
  43. USER STRINGCMD EXECUTION
  44.  
  45. host_client and sv_player will be valid.
  46. ============================================================
  47. */
  48.  
  49. /*
  50. ================
  51. SV_New_f
  52.  
  53. Sends the first message from the server to a connected client.
  54. This will be sent on the initial connection and upon each server load.
  55. ================
  56. */
  57. void SV_New_f (void)
  58. {
  59.   char    *gamedir;
  60.   int     playernum;
  61.  
  62.   if (host_client->state == cs_spawned)
  63.     return;
  64.  
  65.   host_client->state = cs_connected;
  66.   host_client->connection_started = realtime;
  67.  
  68.   // send the info about the new client to all connected clients
  69. //  SV_FullClientUpdate (host_client, &sv.reliable_datagram);
  70. //  host_client->sendinfo = true;
  71.  
  72.   gamedir = Info_ValueForKey (svs.info, "*gamedir");
  73.   if (!gamedir[0])
  74.     gamedir = "qw";
  75.  
  76. //NOTE:  This doesn't go through ClientReliableWrite since it's before the user
  77. //spawns.  These functions are written to not overflow
  78.   if (host_client->num_backbuf) {
  79.     Con_Printf("WARNING %s: [SV_New] Back buffered (%d0, clearing", host_client->name, host_client->netchan.message.cursize); 
  80.     host_client->num_backbuf = 0;
  81.     SZ_Clear(&host_client->netchan.message);
  82.   }
  83.  
  84.   // send the serverdata
  85.   MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
  86.   MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION);
  87.   MSG_WriteLong (&host_client->netchan.message, svs.spawncount);
  88.   MSG_WriteString (&host_client->netchan.message, gamedir);
  89.  
  90.   playernum = NUM_FOR_EDICT(host_client->edict)-1;
  91.   if (host_client->spectator)
  92.     playernum |= 128;
  93.   MSG_WriteByte (&host_client->netchan.message, playernum);
  94.  
  95.   // send full levelname
  96.   MSG_WriteString (&host_client->netchan.message, PR_GetString(sv.edicts->v.message));
  97.  
  98.   // send the movevars
  99.   MSG_WriteFloat(&host_client->netchan.message, movevars.gravity);
  100.   MSG_WriteFloat(&host_client->netchan.message, movevars.stopspeed);
  101.   MSG_WriteFloat(&host_client->netchan.message, movevars.maxspeed);
  102.   MSG_WriteFloat(&host_client->netchan.message, movevars.spectatormaxspeed);
  103.   MSG_WriteFloat(&host_client->netchan.message, movevars.accelerate);
  104.   MSG_WriteFloat(&host_client->netchan.message, movevars.airaccelerate);
  105.   MSG_WriteFloat(&host_client->netchan.message, movevars.wateraccelerate);
  106.   MSG_WriteFloat(&host_client->netchan.message, movevars.friction);
  107.   MSG_WriteFloat(&host_client->netchan.message, movevars.waterfriction);
  108.   MSG_WriteFloat(&host_client->netchan.message, movevars.entgravity);
  109.  
  110.   // send music
  111.   MSG_WriteByte (&host_client->netchan.message, svc_cdtrack);
  112.   MSG_WriteByte (&host_client->netchan.message, sv.edicts->v.sounds);
  113.  
  114.   // send server info string
  115.   MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
  116.   MSG_WriteString (&host_client->netchan.message, va("fullserverinfo \"%s\"\n", svs.info) );
  117. }
  118.  
  119. /*
  120. ==================
  121. SV_Soundlist_f
  122. ==================
  123. */
  124. void SV_Soundlist_f (void)
  125. {
  126.   char    **s;
  127.   int     n;
  128.  
  129.   if (host_client->state != cs_connected)
  130.   {
  131.     Con_Printf ("soundlist not valid -- allready spawned\n");
  132.     return;
  133.   }
  134.  
  135.   // handle the case of a level changing while a client was connecting
  136.   if ( atoi(Cmd_Argv(1)) != svs.spawncount )
  137.   {
  138.     Con_Printf ("SV_Soundlist_f from different level\n");
  139.     SV_New_f ();
  140.     return;
  141.   }
  142.  
  143.   n = atoi(Cmd_Argv(2));
  144.   
  145. //NOTE:  This doesn't go through ClientReliableWrite since it's before the user
  146. //spawns.  These functions are written to not overflow
  147.   if (host_client->num_backbuf) {
  148.     Con_Printf("WARNING %s: [SV_Soundlist] Back buffered (%d0, clearing", host_client->name, host_client->netchan.message.cursize); 
  149.     host_client->num_backbuf = 0;
  150.     SZ_Clear(&host_client->netchan.message);
  151.   }
  152.  
  153.   MSG_WriteByte (&host_client->netchan.message, svc_soundlist);
  154.   MSG_WriteByte (&host_client->netchan.message, n);
  155.   for (s = sv.sound_precache+1 + n ; 
  156.     *s && host_client->netchan.message.cursize < (MAX_MSGLEN/2); 
  157.     s++, n++)
  158.     MSG_WriteString (&host_client->netchan.message, *s);
  159.  
  160.   MSG_WriteByte (&host_client->netchan.message, 0);
  161.  
  162.   // next msg
  163.   if (*s)
  164.     MSG_WriteByte (&host_client->netchan.message, n);
  165.   else
  166.     MSG_WriteByte (&host_client->netchan.message, 0);
  167. }
  168.  
  169. /*
  170. ==================
  171. SV_Modellist_f
  172. ==================
  173. */
  174. void SV_Modellist_f (void)
  175. {
  176.   char    **s;
  177.   int     n;
  178.  
  179.   if (host_client->state != cs_connected)
  180.   {
  181.     Con_Printf ("modellist not valid -- allready spawned\n");
  182.     return;
  183.   }
  184.   
  185.   // handle the case of a level changing while a client was connecting
  186.   if ( atoi(Cmd_Argv(1)) != svs.spawncount )
  187.   {
  188.     Con_Printf ("SV_Modellist_f from different level\n");
  189.     SV_New_f ();
  190.     return;
  191.   }
  192.  
  193.   n = atoi(Cmd_Argv(2));
  194.  
  195. //NOTE:  This doesn't go through ClientReliableWrite since it's before the user
  196. //spawns.  These functions are written to not overflow
  197.   if (host_client->num_backbuf) {
  198.     Con_Printf("WARNING %s: [SV_Modellist] Back buffered (%d0, clearing", host_client->name, host_client->netchan.message.cursize); 
  199.     host_client->num_backbuf = 0;
  200.     SZ_Clear(&host_client->netchan.message);
  201.   }
  202.  
  203.   MSG_WriteByte (&host_client->netchan.message, svc_modellist);
  204.   MSG_WriteByte (&host_client->netchan.message, n);
  205.   for (s = sv.model_precache+1+n ; 
  206.     *s && host_client->netchan.message.cursize < (MAX_MSGLEN/2); 
  207.     s++, n++)
  208.     MSG_WriteString (&host_client->netchan.message, *s);
  209.   MSG_WriteByte (&host_client->netchan.message, 0);
  210.  
  211.   // next msg
  212.   if (*s)
  213.     MSG_WriteByte (&host_client->netchan.message, n);
  214.   else
  215.     MSG_WriteByte (&host_client->netchan.message, 0);
  216. }
  217.  
  218. /*
  219. ==================
  220. SV_PreSpawn_f
  221. ==================
  222. */
  223. void SV_PreSpawn_f (void)
  224. {
  225.   unsigned  buf;
  226.   unsigned  check;
  227.  
  228.   if (host_client->state != cs_connected)
  229.   {
  230.     Con_Printf ("prespawn not valid -- allready spawned\n");
  231.     return;
  232.   }
  233.   
  234.   // handle the case of a level changing while a client was connecting
  235.   if ( atoi(Cmd_Argv(1)) != svs.spawncount )
  236.   {
  237.     Con_Printf ("SV_PreSpawn_f from different level\n");
  238.     SV_New_f ();
  239.     return;
  240.   }
  241.   
  242.   buf = atoi(Cmd_Argv(2));
  243.   if (buf >= sv.num_signon_buffers)
  244.     buf = 0;
  245.  
  246.   if (!buf) {
  247.     // should be three numbers following containing checksums
  248.     check = atoi(Cmd_Argv(3));
  249.  
  250. //    Con_DPrintf("Client check = %d\n", check);
  251.  
  252.     if (sv_mapcheck.value && check != sv.worldmodel->checksum &&
  253.       check != sv.worldmodel->checksum2) {
  254.       SV_ClientPrintf (host_client, PRINT_HIGH, 
  255.         "Map model file does not match (%s), %i != %i/%i.\n"
  256.         "You may need a new version of the map, or the proper install files.\n",
  257.         sv.modelname, check, sv.worldmodel->checksum, sv.worldmodel->checksum2);
  258.       SV_DropClient (host_client); 
  259.       return;
  260.     }
  261.     host_client->checksum = check;
  262.   }
  263.  
  264. //NOTE:  This doesn't go through ClientReliableWrite since it's before the user
  265. //spawns.  These functions are written to not overflow
  266.   if (host_client->num_backbuf) {
  267.     Con_Printf("WARNING %s: [SV_PreSpawn] Back buffered (%d0, clearing", host_client->name, host_client->netchan.message.cursize); 
  268.     host_client->num_backbuf = 0;
  269.     SZ_Clear(&host_client->netchan.message);
  270.   }
  271.  
  272.   SZ_Write (&host_client->netchan.message, 
  273.     sv.signon_buffers[buf],
  274.     sv.signon_buffer_size[buf]);
  275.  
  276.   buf++;
  277.   if (buf == sv.num_signon_buffers)
  278.   { // all done prespawning
  279.     MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
  280.     MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i 0\n",svs.spawncount) );
  281.   }
  282.   else
  283.   { // need to prespawn more
  284.     MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
  285.     MSG_WriteString (&host_client->netchan.message, 
  286.       va("cmd prespawn %i %i\n", svs.spawncount, buf) );
  287.   }
  288. }
  289.  
  290. /*
  291. ==================
  292. SV_Spawn_f
  293. ==================
  294. */
  295. void SV_Spawn_f (void)
  296. {
  297.   int   i;
  298.   client_t  *client;
  299.   edict_t *ent;
  300.   eval_t *val;
  301.   int n;
  302.  
  303.   if (host_client->state != cs_connected)
  304.   {
  305.     Con_Printf ("Spawn not valid -- allready spawned\n");
  306.     return;
  307.   }
  308.  
  309. // handle the case of a level changing while a client was connecting
  310.   if ( atoi(Cmd_Argv(1)) != svs.spawncount )
  311.   {
  312.     Con_Printf ("SV_Spawn_f from different level\n");
  313.     SV_New_f ();
  314.     return;
  315.   }
  316.  
  317.   n = atoi(Cmd_Argv(2));
  318.  
  319.   // make sure n is valid
  320.   if ( n < 0 || n > MAX_CLIENTS )
  321.   {
  322.     Con_Printf ("SV_Spawn_f invalid client start\n");
  323.     SV_New_f ();
  324.     return;
  325.   }
  326.  
  327.  
  328.   
  329. // send all current names, colors, and frag counts
  330.   // FIXME: is this a good thing?
  331.   SZ_Clear (&host_client->netchan.message);
  332.  
  333. // send current status of all other players
  334.  
  335.   // normally this could overflow, but no need to check due to backbuf
  336.   for (i=n, client = svs.clients + n ; i<MAX_CLIENTS ; i++, client++)
  337.     SV_FullClientUpdateToClient (client, host_client);
  338.   
  339. // send all current light styles
  340.   for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
  341.   {
  342.     ClientReliableWrite_Begin (host_client, svc_lightstyle, 
  343.       3 + (sv.lightstyles[i] ? strlen(sv.lightstyles[i]) : 1));
  344.     ClientReliableWrite_Byte (host_client, (char)i);
  345.     ClientReliableWrite_String (host_client, sv.lightstyles[i]);
  346.   }
  347.  
  348.   // set up the edict
  349.   ent = host_client->edict;
  350.  
  351.   memset (&ent->v, 0, progs->entityfields * 4);
  352.   ent->v.colormap = NUM_FOR_EDICT(ent);
  353.   ent->v.team = 0;  // FIXME
  354.   ent->v.netname = PR_SetString(host_client->name);
  355.  
  356.   host_client->entgravity = 1.0;
  357.   val = GetEdictFieldValue(ent, "gravity");
  358.   if (val)
  359.     val->_float = 1.0;
  360.   host_client->maxspeed = sv_maxspeed.value;
  361.   val = GetEdictFieldValue(ent, "maxspeed");
  362.   if (val)
  363.     val->_float = sv_maxspeed.value;
  364.  
  365. //
  366. // force stats to be updated
  367. //
  368.   memset (host_client->stats, 0, sizeof(host_client->stats));
  369.  
  370.   ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
  371.   ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS);
  372.   ClientReliableWrite_Long (host_client, pr_global_struct->total_secrets);
  373.  
  374.   ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
  375.   ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS);
  376.   ClientReliableWrite_Long (host_client, pr_global_struct->total_monsters);
  377.  
  378.   ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
  379.   ClientReliableWrite_Byte (host_client, STAT_SECRETS);
  380.   ClientReliableWrite_Long (host_client, pr_global_struct->found_secrets);
  381.  
  382.   ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
  383.   ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
  384.   ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters);
  385.  
  386.   // get the client to check and download skins
  387.   // when that is completed, a begin command will be issued
  388.   ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
  389.   ClientReliableWrite_String (host_client, "skins\n" );
  390.  
  391. }
  392.  
  393. /*
  394. ==================
  395. SV_SpawnSpectator
  396. ==================
  397. */
  398. void SV_SpawnSpectator (void)
  399. {
  400.   int   i;
  401.   edict_t *e;
  402.  
  403.   VectorCopy (vec3_origin, sv_player->v.origin);
  404.   VectorCopy (vec3_origin, sv_player->v.view_ofs);
  405.   sv_player->v.view_ofs[2] = 22;
  406.  
  407.   // search for an info_playerstart to spawn the spectator at
  408.   for (i=MAX_CLIENTS-1 ; i<sv.num_edicts ; i++)
  409.   {
  410.     e = EDICT_NUM(i);
  411.     if (!strcmp(PR_GetString(e->v.classname), "info_player_start"))
  412.     {
  413.       VectorCopy (e->v.origin, sv_player->v.origin);
  414.       return;
  415.     }
  416.   }
  417.  
  418. }
  419.  
  420. /*
  421. ==================
  422. SV_Begin_f
  423. ==================
  424. */
  425. void SV_Begin_f (void)
  426. {
  427.   unsigned pmodel = 0, emodel = 0;
  428.   int   i;
  429.  
  430.   if (host_client->state == cs_spawned)
  431.     return; // don't begin again
  432.  
  433.   host_client->state = cs_spawned;
  434.   
  435.   // handle the case of a level changing while a client was connecting
  436.   if ( atoi(Cmd_Argv(1)) != svs.spawncount )
  437.   {
  438.     Con_Printf ("SV_Begin_f from different level\n");
  439.     SV_New_f ();
  440.     return;
  441.   }
  442.  
  443.   if (host_client->spectator)
  444.   {
  445.     SV_SpawnSpectator ();
  446.  
  447.     if (SpectatorConnect) {
  448.       // copy spawn parms out of the client_t
  449.       for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
  450.         (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
  451.   
  452.       // call the spawn function
  453.       pr_global_struct->time = sv.time;
  454.       pr_global_struct->self = EDICT_TO_PROG(sv_player);
  455.       PR_ExecuteProgram (SpectatorConnect);
  456.     }
  457.   }
  458.   else
  459.   {
  460.     // copy spawn parms out of the client_t
  461.     for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
  462.       (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
  463.  
  464.     // call the spawn function
  465.     pr_global_struct->time = sv.time;
  466.     pr_global_struct->self = EDICT_TO_PROG(sv_player);
  467.     PR_ExecuteProgram (pr_global_struct->ClientConnect);
  468.  
  469.     // actually spawn the player
  470.     pr_global_struct->time = sv.time;
  471.     pr_global_struct->self = EDICT_TO_PROG(sv_player);
  472.     PR_ExecuteProgram (pr_global_struct->PutClientInServer);  
  473.   }
  474.  
  475.   // clear the net statistics, because connecting gives a bogus picture
  476.   host_client->netchan.frame_latency = 0;
  477.   host_client->netchan.frame_rate = 0;
  478.   host_client->netchan.drop_count = 0;
  479.   host_client->netchan.good_count = 0;
  480.  
  481.   //check he's not cheating
  482.  
  483.   pmodel = atoi(Info_ValueForKey (host_client->userinfo, "pmodel"));
  484.   emodel = atoi(Info_ValueForKey (host_client->userinfo, "emodel"));
  485.  
  486.   if (pmodel != sv.model_player_checksum ||
  487.     emodel != sv.eyes_player_checksum)
  488.     SV_BroadcastPrintf (PRINT_HIGH, "%s WARNING: non standard player/eyes model detected\n", host_client->name);
  489.  
  490.   // if we are paused, tell the client
  491.   if (sv.paused) {
  492.     ClientReliableWrite_Begin (host_client, svc_setpause, 2);
  493.     ClientReliableWrite_Byte (host_client, sv.paused);
  494.     SV_ClientPrintf(host_client, PRINT_HIGH, "Server is paused.\n");
  495.   }
  496.  
  497. #if 0
  498. //
  499. // send a fixangle over the reliable channel to make sure it gets there
  500. // Never send a roll angle, because savegames can catch the server
  501. // in a state where it is expecting the client to correct the angle
  502. // and it won't happen if the game was just loaded, so you wind up
  503. // with a permanent head tilt
  504.   ent = EDICT_NUM( 1 + (host_client - svs.clients) );
  505.   MSG_WriteByte (&host_client->netchan.message, svc_setangle);
  506.   for (i=0 ; i < 2 ; i++)
  507.     MSG_WriteAngle (&host_client->netchan.message, ent->v.angles[i] );
  508.   MSG_WriteAngle (&host_client->netchan.message, 0 );
  509. #endif
  510. }
  511.  
  512. //=============================================================================
  513.  
  514. /*
  515. ==================
  516. SV_NextDownload_f
  517. ==================
  518. */
  519. void SV_NextDownload_f (void)
  520. {
  521.   byte  buffer[1024];
  522.   int   r;
  523.   int   percent;
  524.   int   size;
  525.  
  526.   if (!host_client->download)
  527.     return;
  528.  
  529.   r = host_client->downloadsize - host_client->downloadcount;
  530.   if (r > 768)
  531.     r = 768;
  532.   r = fread (buffer, 1, r, host_client->download);
  533.   ClientReliableWrite_Begin (host_client, svc_download, 6+r);
  534.   ClientReliableWrite_Short (host_client, r);
  535.  
  536.   host_client->downloadcount += r;
  537.   size = host_client->downloadsize;
  538.   if (!size)
  539.     size = 1;
  540.   percent = host_client->downloadcount*100/size;
  541.   ClientReliableWrite_Byte (host_client, percent);
  542.   ClientReliableWrite_SZ (host_client, buffer, r);
  543.  
  544.   if (host_client->downloadcount != host_client->downloadsize)
  545.     return;
  546.  
  547.   fclose (host_client->download);
  548.   host_client->download = NULL;
  549.  
  550. }
  551.  
  552. void OutofBandPrintf(netadr_t where, char *fmt, ...)
  553. {
  554.   va_list   argptr;
  555.   char  send[1024];
  556.   
  557.   send[0] = 0xff;
  558.   send[1] = 0xff;
  559.   send[2] = 0xff;
  560.   send[3] = 0xff;
  561.   send[4] = A2C_PRINT;
  562.   va_start (argptr, fmt);
  563.   vsprintf (send+5, fmt, argptr);
  564.   va_end (argptr);
  565.  
  566.   NET_SendPacket (strlen(send)+1, send, where);
  567. }
  568.  
  569. /*
  570. ==================
  571. SV_NextUpload
  572. ==================
  573. */
  574. void SV_NextUpload (void)
  575. {
  576.   byte  buffer[1024];
  577.   int   r;
  578.   int   percent;
  579.   int   size;
  580.   client_t *client;
  581.  
  582.   if (!*host_client->uploadfn) {
  583.     SV_ClientPrintf(host_client, PRINT_HIGH, "Upload denied\n");
  584.     ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
  585.     ClientReliableWrite_String (host_client, "stopul");
  586.  
  587.     // suck out rest of packet
  588.     size = MSG_ReadShort ();  MSG_ReadByte ();
  589.     msg_readcount += size;
  590.     return;
  591.   }
  592.  
  593.   size = MSG_ReadShort ();
  594.   percent = MSG_ReadByte ();
  595.  
  596.   if (!host_client->upload)
  597.   {
  598.     host_client->upload = fopen(host_client->uploadfn, "wb");
  599.     if (!host_client->upload) {
  600.       Sys_Printf("Can't create %s\n", host_client->uploadfn);
  601.       ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
  602.       ClientReliableWrite_String (host_client, "stopul");
  603.       *host_client->uploadfn = 0;
  604.       return;
  605.     }
  606.     Sys_Printf("Receiving %s from %d...\n", host_client->uploadfn, host_client->userid);
  607.     if (host_client->remote_snap)
  608.       OutofBandPrintf(host_client->snap_from, "Server receiving %s from %d...\n", host_client->uploadfn, host_client->userid);
  609.   }
  610.  
  611.   fwrite (net_message.data + msg_readcount, 1, size, host_client->upload);
  612.   msg_readcount += size;
  613.  
  614. Con_DPrintf ("UPLOAD: %d received\n", size);
  615.  
  616.   if (percent != 100) {
  617.     ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
  618.     ClientReliableWrite_String (host_client, "nextul\n");
  619.   } else {
  620.     fclose (host_client->upload);
  621.     host_client->upload = NULL;
  622.  
  623.     Sys_Printf("%s upload completed.\n", host_client->uploadfn);
  624.  
  625.     if (host_client->remote_snap) {
  626.       char *p;
  627.  
  628.       if ((p = strchr(host_client->uploadfn, '/')) != NULL)
  629.         p++;
  630.       else
  631.         p = host_client->uploadfn;
  632.       OutofBandPrintf(host_client->snap_from, "%s upload completed.\nTo download, enter:\ndownload %s\n", 
  633.         host_client->uploadfn, p);
  634.     }
  635.   }
  636.  
  637. }
  638.  
  639. /*
  640. ==================
  641. SV_BeginDownload_f
  642. ==================
  643. */
  644. void SV_BeginDownload_f(void)
  645. {
  646.   char  *name;
  647.   extern  cvar_t  allow_download;
  648.   extern  cvar_t  allow_download_skins;
  649.   extern  cvar_t  allow_download_models;
  650.   extern  cvar_t  allow_download_sounds;
  651.   extern  cvar_t  allow_download_maps;
  652.   extern  int   file_from_pak; // ZOID did file come from pak?
  653.  
  654.   name = Cmd_Argv(1);
  655. // hacked by zoid to allow more conrol over download
  656.     // first off, no .. or global allow check
  657.   if (strstr (name, "..") || !allow_download.value
  658.     // leading dot is no good
  659.     || *name == '.' 
  660.     // leading slash bad as well, must be in subdir
  661.     || *name == '/'
  662.     // next up, skin check
  663.     || (strncmp(name, "skins/", 6) == 0 && !allow_download_skins.value)
  664.     // now models
  665.     || (strncmp(name, "progs/", 6) == 0 && !allow_download_models.value)
  666.     // now sounds
  667.     || (strncmp(name, "sound/", 6) == 0 && !allow_download_sounds.value)
  668.     // now maps (note special case for maps, must not be in pak)
  669.     || (strncmp(name, "maps/", 6) == 0 && !allow_download_maps.value)
  670.     // MUST be in a subdirectory  
  671.     || !strstr (name, "/") )  
  672.   { // don't allow anything with .. path
  673.     ClientReliableWrite_Begin (host_client, svc_download, 4);
  674.     ClientReliableWrite_Short (host_client, -1);
  675.     ClientReliableWrite_Byte (host_client, 0);
  676.     return;
  677.   }
  678.  
  679.   if (host_client->download) {
  680.     fclose (host_client->download);
  681.     host_client->download = NULL;
  682.   }
  683.  
  684.   // lowercase name (needed for casesen file systems)
  685.   {
  686.     char *p;
  687.  
  688.     for (p = name; *p; p++)
  689.       *p = (char)tolower(*p);
  690.   }
  691.  
  692.  
  693.   host_client->downloadsize = COM_FOpenFile (name, &host_client->download);
  694.   host_client->downloadcount = 0;
  695.  
  696.   if (!host_client->download
  697.     // special check for maps, if it came from a pak file, don't allow
  698.     // download  ZOID
  699.     || (strncmp(name, "maps/", 5) == 0 && file_from_pak))
  700.   {
  701.     if (host_client->download) {
  702.       fclose(host_client->download);
  703.       host_client->download = NULL;
  704.     }
  705.  
  706.     Sys_Printf ("Couldn't download %s to %s\n", name, host_client->name);
  707.     ClientReliableWrite_Begin (host_client, svc_download, 4);
  708.     ClientReliableWrite_Short (host_client, -1);
  709.     ClientReliableWrite_Byte (host_client, 0);
  710.     return;
  711.   }
  712.  
  713.   SV_NextDownload_f ();
  714.   Sys_Printf ("Downloading %s to %s\n", name, host_client->name);
  715. }
  716.  
  717. //=============================================================================
  718.  
  719. /*
  720. ==================
  721. SV_Say
  722. ==================
  723. */
  724. void SV_Say (qboolean team)
  725. {
  726.   client_t *client;
  727.   int   j, tmp;
  728.   char  *p;
  729.   char  text[2048];
  730.   char  t1[32], *t2;
  731.  
  732.   if (Cmd_Argc () < 2)
  733.     return;
  734.  
  735.   if (team)
  736.   {
  737.     strncpy (t1, Info_ValueForKey (host_client->userinfo, "team"), 31);
  738.     t1[31] = 0;
  739.   }
  740.  
  741.   if (host_client->spectator && (!sv_spectalk.value || team))
  742.     sprintf (text, "[SPEC] %s: ", host_client->name);
  743.   else if (team)
  744.     sprintf (text, "(%s): ", host_client->name);
  745.   else {
  746.     sprintf (text, "%s: ", host_client->name);
  747.   }
  748.  
  749.   if (fp_messages) {
  750.     if (!sv.paused && realtime<host_client->lockedtill) {
  751.       SV_ClientPrintf(host_client, PRINT_CHAT,
  752.         "You can't talk for %d more seconds\n", 
  753.           (int) (host_client->lockedtill - realtime));
  754.       return;
  755.     }
  756.     tmp = host_client->whensaidhead - fp_messages + 1;
  757.     if (tmp < 0)
  758.       tmp = 10+tmp;
  759.     if (!sv.paused &&
  760.       host_client->whensaid[tmp] && (realtime-host_client->whensaid[tmp] < fp_persecond)) {
  761.       host_client->lockedtill = realtime + fp_secondsdead;
  762.       if (fp_msg[0])
  763.         SV_ClientPrintf(host_client, PRINT_CHAT,
  764.           "FloodProt: %s\n", fp_msg);
  765.       else
  766.         SV_ClientPrintf(host_client, PRINT_CHAT,
  767.           "FloodProt: You can't talk for %d seconds.\n", fp_secondsdead);
  768.       return;
  769.     }
  770.     host_client->whensaidhead++;
  771.     if (host_client->whensaidhead > 9)
  772.       host_client->whensaidhead = 0;
  773.     host_client->whensaid[host_client->whensaidhead] = realtime;
  774.   }
  775.  
  776.   p = Cmd_Args();
  777.  
  778.   if (*p == '"')
  779.   {
  780.     p++;
  781.     p[Q_strlen(p)-1] = 0;
  782.   }
  783.  
  784.   Q_strcat(text, p);
  785.   Q_strcat(text, "\n");
  786.  
  787.   Sys_Printf ("%s", text);
  788.  
  789.   for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
  790.   {
  791.     if (client->state != cs_spawned)
  792.       continue;
  793.     if (host_client->spectator && !sv_spectalk.value)
  794.       if (!client->spectator)
  795.         continue;
  796.  
  797.     if (team)
  798.     {
  799.       // the spectator team
  800.       if (host_client->spectator) {
  801.         if (!client->spectator)
  802.           continue;
  803.       } else {
  804.         t2 = Info_ValueForKey (client->userinfo, "team");
  805.         if (strcmp(t1, t2) || client->spectator)
  806.           continue; // on different teams
  807.       }
  808.     }
  809.     SV_ClientPrintf(client, PRINT_CHAT, "%s", text);
  810.   }
  811. }
  812.  
  813.  
  814. /*
  815. ==================
  816. SV_Say_f
  817. ==================
  818. */
  819. void SV_Say_f(void)
  820. {
  821.   SV_Say (false);
  822. }
  823. /*
  824. ==================
  825. SV_Say_Team_f
  826. ==================
  827. */
  828. void SV_Say_Team_f(void)
  829. {
  830.   SV_Say (true);
  831. }
  832.  
  833.  
  834.  
  835. //============================================================================
  836.  
  837. /*
  838. =================
  839. SV_Pings_f
  840.  
  841. The client is showing the scoreboard, so send new ping times for all
  842. clients
  843. =================
  844. */
  845. void SV_Pings_f (void)
  846. {
  847.   client_t *client;
  848.   int   j;
  849.  
  850.   for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
  851.   {
  852.     if (client->state != cs_spawned)
  853.       continue;
  854.  
  855.     ClientReliableWrite_Begin (host_client, svc_updateping, 4);
  856.     ClientReliableWrite_Byte (host_client, j);
  857.     ClientReliableWrite_Short (host_client, SV_CalcPing(client));
  858.     ClientReliableWrite_Begin (host_client, svc_updatepl, 4);
  859.     ClientReliableWrite_Byte (host_client, j);
  860.     ClientReliableWrite_Byte (host_client, client->lossage);
  861.   }
  862. }
  863.  
  864.  
  865.  
  866. /*
  867. ==================
  868. SV_Kill_f
  869. ==================
  870. */
  871. void SV_Kill_f (void)
  872. {
  873.   if (sv_player->v.health <= 0)
  874.   {
  875.     SV_ClientPrintf (host_client, PRINT_HIGH, "Can't suicide -- allready dead!\n");
  876.     return;
  877.   }
  878.   
  879.   pr_global_struct->time = sv.time;
  880.   pr_global_struct->self = EDICT_TO_PROG(sv_player);
  881.   PR_ExecuteProgram (pr_global_struct->ClientKill);
  882. }
  883.  
  884. /*
  885. ==================
  886. SV_TogglePause
  887. ==================
  888. */
  889. void SV_TogglePause (const char *msg)
  890. {
  891.   int i;
  892.   client_t *cl;
  893.  
  894.   sv.paused ^= 1;
  895.  
  896.   if (msg)
  897.     SV_BroadcastPrintf (PRINT_HIGH, "%s", msg);
  898.  
  899.   // send notification to all clients
  900.   for (i=0, cl = svs.clients ; i<MAX_CLIENTS ; i++, cl++)
  901.   {
  902.     if (!cl->state)
  903.       continue;
  904.     ClientReliableWrite_Begin (cl, svc_setpause, 2);
  905.     ClientReliableWrite_Byte (cl, sv.paused);
  906.   }
  907. }
  908.  
  909.  
  910. /*
  911. ==================
  912. SV_Pause_f
  913. ==================
  914. */
  915. void SV_Pause_f (void)
  916. {
  917.   int i;
  918.   client_t *cl;
  919.   char st[sizeof(host_client->name) + 32];
  920.  
  921.   if (!pausable.value) {
  922.     SV_ClientPrintf (host_client, PRINT_HIGH, "Pause not allowed.\n");
  923.     return;
  924.   }
  925.  
  926.   if (host_client->spectator) {
  927.     SV_ClientPrintf (host_client, PRINT_HIGH, "Spectators can not pause.\n");
  928.     return;
  929.   }
  930.  
  931.   if (sv.paused)
  932.     sprintf (st, "%s paused the game\n", host_client->name);
  933.   else
  934.     sprintf (st, "%s unpaused the game\n", host_client->name);
  935.  
  936.   SV_TogglePause(st);
  937. }
  938.  
  939.  
  940. /*
  941. =================
  942. SV_Drop_f
  943.  
  944. The client is going to disconnect, so remove the connection immediately
  945. =================
  946. */
  947. void SV_Drop_f (void)
  948. {
  949.   SV_EndRedirect ();
  950.   if (!host_client->spectator)
  951.     SV_BroadcastPrintf (PRINT_HIGH, "%s dropped\n", host_client->name);
  952.   SV_DropClient (host_client);  
  953. }
  954.  
  955. /*
  956. =================
  957. SV_PTrack_f
  958.  
  959. Change the bandwidth estimate for a client
  960. =================
  961. */
  962. void SV_PTrack_f (void)
  963. {
  964.   int   i;
  965.   edict_t *ent, *tent;
  966.   
  967.   if (!host_client->spectator)
  968.     return;
  969.  
  970.   if (Cmd_Argc() != 2)
  971.   {
  972.     // turn off tracking
  973.     host_client->spec_track = 0;
  974.     ent = EDICT_NUM(host_client - svs.clients + 1);
  975.     tent = EDICT_NUM(0);
  976.     ent->v.goalentity = EDICT_TO_PROG(tent);
  977.     return;
  978.   }
  979.   
  980.   i = atoi(Cmd_Argv(1));
  981.   if (i < 0 || i >= MAX_CLIENTS || svs.clients[i].state != cs_spawned ||
  982.     svs.clients[i].spectator) {
  983.     SV_ClientPrintf (host_client, PRINT_HIGH, "Invalid client to track\n");
  984.     host_client->spec_track = 0;
  985.     ent = EDICT_NUM(host_client - svs.clients + 1);
  986.     tent = EDICT_NUM(0);
  987.     ent->v.goalentity = EDICT_TO_PROG(tent);
  988.     return;
  989.   }
  990.   host_client->spec_track = i + 1; // now tracking
  991.  
  992.   ent = EDICT_NUM(host_client - svs.clients + 1);
  993.   tent = EDICT_NUM(i + 1);
  994.   ent->v.goalentity = EDICT_TO_PROG(tent);
  995. }
  996.  
  997.  
  998. /*
  999. =================
  1000. SV_Rate_f
  1001.  
  1002. Change the bandwidth estimate for a client
  1003. =================
  1004. */
  1005. void SV_Rate_f (void)
  1006. {
  1007.   int   rate;
  1008.   
  1009.   if (Cmd_Argc() != 2)
  1010.   {
  1011.     SV_ClientPrintf (host_client, PRINT_HIGH, "Current rate is %i\n",
  1012.       (int)(1.0/host_client->netchan.rate + 0.5));
  1013.     return;
  1014.   }
  1015.   
  1016.   rate = atoi(Cmd_Argv(1));
  1017.   if (rate < 500)
  1018.     rate = 500;
  1019.   if (rate > 10000)
  1020.     rate = 10000;
  1021.  
  1022.   SV_ClientPrintf (host_client, PRINT_HIGH, "Net rate set to %i\n", rate);
  1023.   host_client->netchan.rate = 1.0/rate;
  1024. }
  1025.  
  1026.  
  1027. /*
  1028. =================
  1029. SV_Msg_f
  1030.  
  1031. Change the message level for a client
  1032. =================
  1033. */
  1034. void SV_Msg_f (void)
  1035.   if (Cmd_Argc() != 2)
  1036.   {
  1037.     SV_ClientPrintf (host_client, PRINT_HIGH, "Current msg level is %i\n",
  1038.       host_client->messagelevel);
  1039.     return;
  1040.   }
  1041.   
  1042.   host_client->messagelevel = atoi(Cmd_Argv(1));
  1043.  
  1044.   SV_ClientPrintf (host_client, PRINT_HIGH, "Msg level set to %i\n", host_client->messagelevel);
  1045. }
  1046.  
  1047. /*
  1048. ==================
  1049. SV_SetInfo_f
  1050.  
  1051. Allow clients to change userinfo
  1052. ==================
  1053. */
  1054. void SV_SetInfo_f (void)
  1055. {
  1056.   int i;
  1057.   char oldval[MAX_INFO_STRING];
  1058.  
  1059.  
  1060.   if (Cmd_Argc() == 1)
  1061.   {
  1062.     Con_Printf ("User info settings:\n");
  1063.     Info_Print (host_client->userinfo);
  1064.     return;
  1065.   }
  1066.  
  1067.   if (Cmd_Argc() != 3)
  1068.   {
  1069.     Con_Printf ("usage: setinfo [ <key> <value> ]\n");
  1070.     return;
  1071.   }
  1072.  
  1073.   if (Cmd_Argv(1)[0] == '*')
  1074.     return;   // don't set priveledged values
  1075.  
  1076.   strcpy(oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)));
  1077.  
  1078.   Info_SetValueForKey (host_client->userinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_INFO_STRING);
  1079. // name is extracted below in ExtractFromUserInfo
  1080. //  strncpy (host_client->name, Info_ValueForKey (host_client->userinfo, "name")
  1081. //    , sizeof(host_client->name)-1); 
  1082. //  SV_FullClientUpdate (host_client, &sv.reliable_datagram);
  1083. //  host_client->sendinfo = true;
  1084.  
  1085.   if (!strcmp(Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)), oldval))
  1086.     return; // key hasn't changed
  1087.  
  1088.   // process any changed values
  1089.   SV_ExtractFromUserinfo (host_client);
  1090.  
  1091.   i = host_client - svs.clients;
  1092.   MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
  1093.   MSG_WriteByte (&sv.reliable_datagram, i);
  1094.   MSG_WriteString (&sv.reliable_datagram, Cmd_Argv(1));
  1095.   MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)));
  1096. }
  1097.  
  1098. /*
  1099. ==================
  1100. SV_ShowServerinfo_f
  1101.  
  1102. Dumps the serverinfo info string
  1103. ==================
  1104. */
  1105. void SV_ShowServerinfo_f (void)
  1106. {
  1107.   Info_Print (svs.info);
  1108. }
  1109.  
  1110. void SV_NoSnap_f(void)
  1111. {
  1112.   if (*host_client->uploadfn) {
  1113.     *host_client->uploadfn = 0;
  1114.     SV_BroadcastPrintf (PRINT_HIGH, "%s refused remote screenshot\n", host_client->name);
  1115.   }
  1116. }
  1117.  
  1118. typedef struct
  1119. {
  1120.   char  *name;
  1121.   void  (*func) (void);
  1122. } ucmd_t;
  1123.  
  1124. ucmd_t ucmds[] =
  1125. {
  1126.   {"new", SV_New_f},
  1127.   {"modellist", SV_Modellist_f},
  1128.   {"soundlist", SV_Soundlist_f},
  1129.   {"prespawn", SV_PreSpawn_f},
  1130.   {"spawn", SV_Spawn_f},
  1131.   {"begin", SV_Begin_f},
  1132.  
  1133.   {"drop", SV_Drop_f},
  1134.   {"pings", SV_Pings_f},
  1135.  
  1136. // issued by hand at client consoles  
  1137.   {"rate", SV_Rate_f},
  1138.   {"kill", SV_Kill_f},
  1139.   {"pause", SV_Pause_f},
  1140.   {"msg", SV_Msg_f},
  1141.  
  1142.   {"say", SV_Say_f},
  1143.   {"say_team", SV_Say_Team_f},
  1144.  
  1145.   {"setinfo", SV_SetInfo_f},
  1146.  
  1147.   {"serverinfo", SV_ShowServerinfo_f},
  1148.  
  1149.   {"download", SV_BeginDownload_f},
  1150.   {"nextdl", SV_NextDownload_f},
  1151.  
  1152.   {"ptrack", SV_PTrack_f}, //ZOID - used with autocam
  1153.  
  1154.   {"snap", SV_NoSnap_f},
  1155.   
  1156.   {NULL, NULL}
  1157. };
  1158.  
  1159. /*
  1160. ==================
  1161. SV_ExecuteUserCommand
  1162. ==================
  1163. */
  1164. void SV_ExecuteUserCommand (char *s)
  1165. {
  1166.   ucmd_t  *u;
  1167.   
  1168.   Cmd_TokenizeString (s);
  1169.   sv_player = host_client->edict;
  1170.  
  1171.   SV_BeginRedirect (RD_CLIENT);
  1172.  
  1173.   for (u=ucmds ; u->name ; u++)
  1174.     if (!strcmp (Cmd_Argv(0), u->name) )
  1175.     {
  1176.       u->func ();
  1177.       break;
  1178.     }
  1179.  
  1180.   if (!u->name)
  1181.     Con_Printf ("Bad user command: %s\n", Cmd_Argv(0));
  1182.  
  1183.   SV_EndRedirect ();
  1184. }
  1185.  
  1186. /*
  1187. ===========================================================================
  1188.  
  1189. USER CMD EXECUTION
  1190.  
  1191. ===========================================================================
  1192. */
  1193.  
  1194. /*
  1195. ===============
  1196. V_CalcRoll
  1197.  
  1198. Used by view and sv_user
  1199. ===============
  1200. */
  1201. float V_CalcRoll (vec3_t angles, vec3_t velocity)
  1202. {
  1203.   vec3_t  forward, right, up;
  1204.   float sign;
  1205.   float side;
  1206.   float value;
  1207.   
  1208.   AngleVectors (angles, forward, right, up);
  1209.   side = DotProduct (velocity, right);
  1210.   sign = side < 0 ? -1 : 1;
  1211.   side = fabs(side);
  1212.   
  1213.   value = cl_rollangle.value;
  1214.  
  1215.   if (side < cl_rollspeed.value)
  1216.     side = side * value / cl_rollspeed.value;
  1217.   else
  1218.     side = value;
  1219.   
  1220.   return side*sign;
  1221.   
  1222. }
  1223.  
  1224.  
  1225.  
  1226.  
  1227. //============================================================================
  1228.  
  1229. vec3_t  pmove_mins, pmove_maxs;
  1230.  
  1231. /*
  1232. ====================
  1233. AddLinksToPmove
  1234.  
  1235. ====================
  1236. */
  1237. void AddLinksToPmove ( areanode_t *node )
  1238. {
  1239.   link_t    *l, *next;
  1240.   edict_t   *check;
  1241.   int     pl;
  1242.   int     i;
  1243.   physent_t *pe;
  1244.  
  1245.   pl = EDICT_TO_PROG(sv_player);
  1246.  
  1247.   // touch linked edicts
  1248.   for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next)
  1249.   {
  1250.     next = l->next;
  1251.     check = EDICT_FROM_AREA(l);
  1252.  
  1253.     if (check->v.owner == pl)
  1254.       continue;   // player's own missile
  1255.     if (check->v.solid == SOLID_BSP 
  1256.       || check->v.solid == SOLID_BBOX 
  1257.       || check->v.solid == SOLID_SLIDEBOX)
  1258.     {
  1259.       if (check == sv_player)
  1260.         continue;
  1261.  
  1262.       for (i=0 ; i<3 ; i++)
  1263.         if (check->v.absmin[i] > pmove_maxs[i]
  1264.         || check->v.absmax[i] < pmove_mins[i])
  1265.           break;
  1266.       if (i != 3)
  1267.         continue;
  1268.       if (pmove.numphysent == MAX_PHYSENTS)
  1269.         return;
  1270.       pe = &pmove.physents[pmove.numphysent];
  1271.       pmove.numphysent++;
  1272.  
  1273.       VectorCopy (check->v.origin, pe->origin);
  1274.       pe->info = NUM_FOR_EDICT(check);
  1275.       if (check->v.solid == SOLID_BSP)
  1276.         pe->model = sv.models[(int)(check->v.modelindex)];
  1277.       else
  1278.       {
  1279.         pe->model = NULL;
  1280.         VectorCopy (check->v.mins, pe->mins);
  1281.         VectorCopy (check->v.maxs, pe->maxs);
  1282.       }
  1283.     }
  1284.   }
  1285.   
  1286. // recurse down both sides
  1287.   if (node->axis == -1)
  1288.     return;
  1289.  
  1290.   if ( pmove_maxs[node->axis] > node->dist )
  1291.     AddLinksToPmove ( node->children[0] );
  1292.   if ( pmove_mins[node->axis] < node->dist )
  1293.     AddLinksToPmove ( node->children[1] );
  1294. }
  1295.  
  1296.  
  1297. /*
  1298. ================
  1299. AddAllEntsToPmove
  1300.  
  1301. For debugging
  1302. ================
  1303. */
  1304. void AddAllEntsToPmove (void)
  1305. {
  1306.   int     e;
  1307.   edict_t   *check;
  1308.   int     i;
  1309.   physent_t *pe;
  1310.   int     pl;
  1311.  
  1312.   pl = EDICT_TO_PROG(sv_player);
  1313.   check = NEXT_EDICT(sv.edicts);
  1314.   for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
  1315.   {
  1316.     if (check->free)
  1317.       continue;
  1318.     if (check->v.owner == pl)
  1319.       continue;
  1320.     if (check->v.solid == SOLID_BSP 
  1321.       || check->v.solid == SOLID_BBOX 
  1322.       || check->v.solid == SOLID_SLIDEBOX)
  1323.     {
  1324.       if (check == sv_player)
  1325.         continue;
  1326.  
  1327.       for (i=0 ; i<3 ; i++)
  1328.         if (check->v.absmin[i] > pmove_maxs[i]
  1329.         || check->v.absmax[i] < pmove_mins[i])
  1330.           break;
  1331.       if (i != 3)
  1332.         continue;
  1333.       pe = &pmove.physents[pmove.numphysent];
  1334.  
  1335.       VectorCopy (check->v.origin, pe->origin);
  1336.       pmove.physents[pmove.numphysent].info = e;
  1337.       if (check->v.solid == SOLID_BSP)
  1338.         pe->model = sv.models[(int)(check->v.modelindex)];
  1339.       else
  1340.       {
  1341.         pe->model = NULL;
  1342.         VectorCopy (check->v.mins, pe->mins);
  1343.         VectorCopy (check->v.maxs, pe->maxs);
  1344.       }
  1345.  
  1346.       if (++pmove.numphysent == MAX_PHYSENTS)
  1347.         break;
  1348.     }
  1349.   }
  1350. }
  1351.  
  1352. /*
  1353. ===========
  1354. SV_PreRunCmd
  1355. ===========
  1356. Done before running a player command.  Clears the touch array
  1357. */
  1358. byte playertouch[(MAX_EDICTS+7)/8];
  1359.  
  1360. void SV_PreRunCmd(void)
  1361. {
  1362.   memset(playertouch, 0, sizeof(playertouch));
  1363. }
  1364.  
  1365. /*
  1366. ===========
  1367. SV_RunCmd
  1368. ===========
  1369. */
  1370. void SV_RunCmd (usercmd_t *ucmd)
  1371. {
  1372.   edict_t   *ent;
  1373.   int     i, n;
  1374.   int     oldmsec;
  1375.  
  1376.   cmd = *ucmd;
  1377.  
  1378.   // chop up very long commands
  1379.   if (cmd.msec > 50)
  1380.   {
  1381.     oldmsec = ucmd->msec;
  1382.     cmd.msec = oldmsec/2;
  1383.     SV_RunCmd (&cmd);
  1384.     cmd.msec = oldmsec/2;
  1385.     cmd.impulse = 0;
  1386.     SV_RunCmd (&cmd);
  1387.     return;
  1388.   }
  1389.  
  1390.   if (!sv_player->v.fixangle)
  1391.     VectorCopy (ucmd->angles, sv_player->v.v_angle);
  1392.  
  1393.   sv_player->v.button0 = ucmd->buttons & 1;
  1394.   sv_player->v.button2 = (ucmd->buttons & 2)>>1;
  1395.   if (ucmd->impulse)
  1396.     sv_player->v.impulse = ucmd->impulse;
  1397.  
  1398. //
  1399. // angles
  1400. // show 1/3 the pitch angle and all the roll angle  
  1401.   if (sv_player->v.health > 0)
  1402.   {
  1403.     if (!sv_player->v.fixangle)
  1404.     {
  1405.       sv_player->v.angles[PITCH] = -sv_player->v.v_angle[PITCH]/3;
  1406.       sv_player->v.angles[YAW] = sv_player->v.v_angle[YAW];
  1407.     }
  1408.     sv_player->v.angles[ROLL] = 
  1409.       V_CalcRoll (sv_player->v.angles, sv_player->v.velocity)*4;
  1410.   }
  1411.  
  1412.   host_frametime = ucmd->msec * 0.001;
  1413.   if (host_frametime > 0.1)
  1414.     host_frametime = 0.1;
  1415.  
  1416.   if (!host_client->spectator)
  1417.   {
  1418.     pr_global_struct->frametime = host_frametime;
  1419.  
  1420.     pr_global_struct->time = sv.time;
  1421.     pr_global_struct->self = EDICT_TO_PROG(sv_player);
  1422.     PR_ExecuteProgram (pr_global_struct->PlayerPreThink);
  1423.  
  1424.     SV_RunThink (sv_player);
  1425.   }
  1426.  
  1427.   for (i=0 ; i<3 ; i++)
  1428.     pmove.origin[i] = sv_player->v.origin[i] + (sv_player->v.mins[i] - player_mins[i]);
  1429.   VectorCopy (sv_player->v.velocity, pmove.velocity);
  1430.   VectorCopy (sv_player->v.v_angle, pmove.angles);
  1431.  
  1432.   pmove.spectator = host_client->spectator;
  1433.   pmove.waterjumptime = sv_player->v.teleport_time;
  1434.   pmove.numphysent = 1;
  1435.   pmove.physents[0].model = sv.worldmodel;
  1436.   pmove.cmd = *ucmd;
  1437.   pmove.dead = sv_player->v.health <= 0;
  1438.   pmove.oldbuttons = host_client->oldbuttons;
  1439.  
  1440.   movevars.entgravity = host_client->entgravity;
  1441.   movevars.maxspeed = host_client->maxspeed;
  1442.  
  1443.   for (i=0 ; i<3 ; i++)
  1444.   {
  1445.     pmove_mins[i] = pmove.origin[i] - 256;
  1446.     pmove_maxs[i] = pmove.origin[i] + 256;
  1447.   }
  1448. #if 1
  1449.   AddLinksToPmove ( sv_areanodes );
  1450. #else
  1451.   AddAllEntsToPmove ();
  1452. #endif
  1453.  
  1454. #if 0
  1455. {
  1456.   int before, after;
  1457.  
  1458. before = PM_TestPlayerPosition (pmove.origin);
  1459.   PlayerMove ();
  1460. after = PM_TestPlayerPosition (pmove.origin);
  1461.  
  1462. if (sv_player->v.health > 0 && before && !after )
  1463.   Con_Printf ("player %s got stuck in playermove!!!!\n", host_client->name);
  1464. }
  1465. #else
  1466.   PlayerMove ();
  1467. #endif
  1468.  
  1469.   host_client->oldbuttons = pmove.oldbuttons;
  1470.   sv_player->v.teleport_time = pmove.waterjumptime;
  1471.   sv_player->v.waterlevel = waterlevel;
  1472.   sv_player->v.watertype = watertype;
  1473.   if (onground != -1)
  1474.   {
  1475.     sv_player->v.flags = (int)sv_player->v.flags | FL_ONGROUND;
  1476.     sv_player->v.groundentity = EDICT_TO_PROG(EDICT_NUM(pmove.physents[onground].info));
  1477.   }
  1478.   else
  1479.     sv_player->v.flags = (int)sv_player->v.flags & ~FL_ONGROUND;
  1480.   for (i=0 ; i<3 ; i++)
  1481.     sv_player->v.origin[i] = pmove.origin[i] - (sv_player->v.mins[i] - player_mins[i]);
  1482.  
  1483. #if 0
  1484.   // truncate velocity the same way the net protocol will
  1485.   for (i=0 ; i<3 ; i++)
  1486.     sv_player->v.velocity[i] = (int)pmove.velocity[i];
  1487. #else
  1488.   VectorCopy (pmove.velocity, sv_player->v.velocity);
  1489. #endif
  1490.  
  1491.   VectorCopy (pmove.angles, sv_player->v.v_angle);
  1492.  
  1493.   if (!host_client->spectator)
  1494.   {
  1495.     // link into place and touch triggers
  1496.     SV_LinkEdict (sv_player, true);
  1497.  
  1498.     // touch other objects
  1499.     for (i=0 ; i<pmove.numtouch ; i++)
  1500.     {
  1501.       n = pmove.physents[pmove.touchindex[i]].info;
  1502.       ent = EDICT_NUM(n);
  1503.       if (!ent->v.touch || (playertouch[n/8]&(1<<(n%8))))
  1504.         continue;
  1505.       pr_global_struct->self = EDICT_TO_PROG(ent);
  1506.       pr_global_struct->other = EDICT_TO_PROG(sv_player);
  1507.       PR_ExecuteProgram (ent->v.touch);
  1508.       playertouch[n/8] |= 1 << (n%8);
  1509.     }
  1510.   }
  1511. }
  1512.  
  1513. /*
  1514. ===========
  1515. SV_PostRunCmd
  1516. ===========
  1517. Done after running a player command.
  1518. */
  1519. void SV_PostRunCmd(void)
  1520. {
  1521.   // run post-think
  1522.  
  1523.   if (!host_client->spectator) {
  1524.     pr_global_struct->time = sv.time;
  1525.     pr_global_struct->self = EDICT_TO_PROG(sv_player);
  1526.     PR_ExecuteProgram (pr_global_struct->PlayerPostThink);
  1527.     SV_RunNewmis ();
  1528.   } else if (SpectatorThink) {
  1529.     pr_global_struct->time = sv.time;
  1530.     pr_global_struct->self = EDICT_TO_PROG(sv_player);
  1531.     PR_ExecuteProgram (SpectatorThink);
  1532.   }
  1533. }
  1534.  
  1535.  
  1536. /*
  1537. ===================
  1538. SV_ExecuteClientMessage
  1539.  
  1540. The current net_message is parsed for the given client
  1541. ===================
  1542. */
  1543. void SV_ExecuteClientMessage (client_t *cl)
  1544. {
  1545.   int   c;
  1546.   char  *s;
  1547.   usercmd_t oldest, oldcmd, newcmd;
  1548.   client_frame_t  *frame;
  1549.   vec3_t o;
  1550.   qboolean  move_issued = false; //only allow one move command
  1551.   int   checksumIndex;
  1552.   byte  checksum, calculatedChecksum;
  1553.   int   seq_hash;
  1554.  
  1555.   // calc ping time
  1556.   frame = &cl->frames[cl->netchan.incoming_acknowledged & UPDATE_MASK];
  1557.   frame->ping_time = realtime - frame->senttime;
  1558.  
  1559.   // make sure the reply sequence number matches the incoming
  1560.   // sequence number 
  1561.   if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence)
  1562.     cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence;
  1563.   else
  1564.     cl->send_message = false; // don't reply, sequences have slipped    
  1565.  
  1566.   // save time for ping calculations
  1567.   cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].senttime = realtime;
  1568.   cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].ping_time = -1;
  1569.  
  1570.   host_client = cl;
  1571.   sv_player = host_client->edict;
  1572.  
  1573. //  seq_hash = (cl->netchan.incoming_sequence & 0xffff) ; // ^ QW_CHECK_HASH;
  1574.   seq_hash = cl->netchan.incoming_sequence;
  1575.   
  1576.   // mark time so clients will know how much to predict
  1577.   // other players
  1578.   cl->localtime = sv.time;
  1579.   cl->delta_sequence = -1;  // no delta unless requested
  1580.   while (1)
  1581.   {
  1582.     if (msg_badread)
  1583.     {
  1584.       Con_Printf ("SV_ReadClientMessage: badread\n");
  1585.       SV_DropClient (cl);
  1586.       return;
  1587.     } 
  1588.  
  1589.     c = MSG_ReadByte ();
  1590.     if (c == -1)
  1591.       break;
  1592.         
  1593.     switch (c)
  1594.     {
  1595.     default:
  1596.       Con_Printf ("SV_ReadClientMessage: unknown command char\n");
  1597.       SV_DropClient (cl);
  1598.       return;
  1599.             
  1600.     case clc_nop:
  1601.       break;
  1602.  
  1603.     case clc_delta:
  1604.       cl->delta_sequence = MSG_ReadByte ();
  1605.       break;
  1606.  
  1607.     case clc_move:
  1608.       if (move_issued)
  1609.         return;   // someone is trying to cheat...
  1610.  
  1611.       move_issued = true;
  1612.  
  1613.       checksumIndex = MSG_GetReadCount();
  1614.       checksum = (byte)MSG_ReadByte ();
  1615.  
  1616.       // read loss percentage
  1617.       cl->lossage = MSG_ReadByte();
  1618.  
  1619.       MSG_ReadDeltaUsercmd (&nullcmd, &oldest);
  1620.       MSG_ReadDeltaUsercmd (&oldest, &oldcmd);
  1621.       MSG_ReadDeltaUsercmd (&oldcmd, &newcmd);
  1622.  
  1623.       if ( cl->state != cs_spawned )
  1624.         break;
  1625.  
  1626.       // if the checksum fails, ignore the rest of the packet
  1627.       calculatedChecksum = COM_BlockSequenceCRCByte(
  1628.         net_message.data + checksumIndex + 1,
  1629.         MSG_GetReadCount() - checksumIndex - 1,
  1630.         seq_hash);
  1631.  
  1632.       if (calculatedChecksum != checksum)
  1633.       {
  1634.         Con_DPrintf ("Failed command checksum for %s(%d) (%d != %d)\n", 
  1635.           cl->name, cl->netchan.incoming_sequence, checksum, calculatedChecksum);
  1636.         return;
  1637.       }
  1638.  
  1639.       if (!sv.paused) {
  1640.         SV_PreRunCmd();
  1641.  
  1642.         if (net_drop < 20)
  1643.         {
  1644.           while (net_drop > 2)
  1645.           {
  1646.             SV_RunCmd (&cl->lastcmd);
  1647.             net_drop--;
  1648.           }
  1649.           if (net_drop > 1)
  1650.             SV_RunCmd (&oldest);
  1651.           if (net_drop > 0)
  1652.             SV_RunCmd (&oldcmd);
  1653.         }
  1654.         SV_RunCmd (&newcmd);
  1655.  
  1656.         SV_PostRunCmd();
  1657.       }
  1658.  
  1659.       cl->lastcmd = newcmd;
  1660.       cl->lastcmd.buttons = 0; // avoid multiple fires on lag
  1661.       break;
  1662.  
  1663.  
  1664.     case clc_stringcmd: 
  1665.       s = MSG_ReadString ();
  1666.       SV_ExecuteUserCommand (s);
  1667.       break;
  1668.  
  1669.     case clc_tmove:
  1670.       o[0] = MSG_ReadCoord();
  1671.       o[1] = MSG_ReadCoord();
  1672.       o[2] = MSG_ReadCoord();
  1673.       // only allowed by spectators
  1674.       if (host_client->spectator) {
  1675.         VectorCopy(o, sv_player->v.origin);
  1676.         SV_LinkEdict(sv_player, false);
  1677.       }
  1678.       break;
  1679.  
  1680.     case clc_upload:
  1681.       SV_NextUpload();
  1682.       break;
  1683.  
  1684.     }
  1685.   }
  1686. }
  1687.  
  1688. /*
  1689. ==============
  1690. SV_UserInit
  1691. ==============
  1692. */
  1693. void SV_UserInit (void)
  1694. {
  1695.   Cvar_RegisterVariable (&cl_rollspeed);
  1696.   Cvar_RegisterVariable (&cl_rollangle);
  1697.   Cvar_RegisterVariable (&sv_spectalk);
  1698.   Cvar_RegisterVariable (&sv_mapcheck);
  1699. }
  1700.  
  1701.  
  1702.