home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / server / sv_user.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  39.8 KB  |  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. {    
  1036.     if (Cmd_Argc() != 2)
  1037.     {
  1038.         SV_ClientPrintf (host_client, PRINT_HIGH, "Current msg level is %i\n",
  1039.             host_client->messagelevel);
  1040.         return;
  1041.     }
  1042.     
  1043.     host_client->messagelevel = atoi(Cmd_Argv(1));
  1044.  
  1045.     SV_ClientPrintf (host_client, PRINT_HIGH, "Msg level set to %i\n", host_client->messagelevel);
  1046. }
  1047.  
  1048. /*
  1049. ==================
  1050. SV_SetInfo_f
  1051.  
  1052. Allow clients to change userinfo
  1053. ==================
  1054. */
  1055. void SV_SetInfo_f (void)
  1056. {
  1057.     int i;
  1058.     char oldval[MAX_INFO_STRING];
  1059.  
  1060.  
  1061.     if (Cmd_Argc() == 1)
  1062.     {
  1063.         Con_Printf ("User info settings:\n");
  1064.         Info_Print (host_client->userinfo);
  1065.         return;
  1066.     }
  1067.  
  1068.     if (Cmd_Argc() != 3)
  1069.     {
  1070.         Con_Printf ("usage: setinfo [ <key> <value> ]\n");
  1071.         return;
  1072.     }
  1073.  
  1074.     if (Cmd_Argv(1)[0] == '*')
  1075.         return;        // don't set priveledged values
  1076.  
  1077.     strcpy(oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)));
  1078.  
  1079.     Info_SetValueForKey (host_client->userinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_INFO_STRING);
  1080. // name is extracted below in ExtractFromUserInfo
  1081. //    strncpy (host_client->name, Info_ValueForKey (host_client->userinfo, "name")
  1082. //        , sizeof(host_client->name)-1);    
  1083. //    SV_FullClientUpdate (host_client, &sv.reliable_datagram);
  1084. //    host_client->sendinfo = true;
  1085.  
  1086.     if (!strcmp(Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)), oldval))
  1087.         return; // key hasn't changed
  1088.  
  1089.     // process any changed values
  1090.     SV_ExtractFromUserinfo (host_client);
  1091.  
  1092.     i = host_client - svs.clients;
  1093.     MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
  1094.     MSG_WriteByte (&sv.reliable_datagram, i);
  1095.     MSG_WriteString (&sv.reliable_datagram, Cmd_Argv(1));
  1096.     MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)));
  1097. }
  1098.  
  1099. /*
  1100. ==================
  1101. SV_ShowServerinfo_f
  1102.  
  1103. Dumps the serverinfo info string
  1104. ==================
  1105. */
  1106. void SV_ShowServerinfo_f (void)
  1107. {
  1108.     Info_Print (svs.info);
  1109. }
  1110.  
  1111. void SV_NoSnap_f(void)
  1112. {
  1113.     if (*host_client->uploadfn) {
  1114.         *host_client->uploadfn = 0;
  1115.         SV_BroadcastPrintf (PRINT_HIGH, "%s refused remote screenshot\n", host_client->name);
  1116.     }
  1117. }
  1118.  
  1119. typedef struct
  1120. {
  1121.     char    *name;
  1122.     void    (*func) (void);
  1123. } ucmd_t;
  1124.  
  1125. ucmd_t ucmds[] =
  1126. {
  1127.     {"new", SV_New_f},
  1128.     {"modellist", SV_Modellist_f},
  1129.     {"soundlist", SV_Soundlist_f},
  1130.     {"prespawn", SV_PreSpawn_f},
  1131.     {"spawn", SV_Spawn_f},
  1132.     {"begin", SV_Begin_f},
  1133.  
  1134.     {"drop", SV_Drop_f},
  1135.     {"pings", SV_Pings_f},
  1136.  
  1137. // issued by hand at client consoles    
  1138.     {"rate", SV_Rate_f},
  1139.     {"kill", SV_Kill_f},
  1140.     {"pause", SV_Pause_f},
  1141.     {"msg", SV_Msg_f},
  1142.  
  1143.     {"say", SV_Say_f},
  1144.     {"say_team", SV_Say_Team_f},
  1145.  
  1146.     {"setinfo", SV_SetInfo_f},
  1147.  
  1148.     {"serverinfo", SV_ShowServerinfo_f},
  1149.  
  1150.     {"download", SV_BeginDownload_f},
  1151.     {"nextdl", SV_NextDownload_f},
  1152.  
  1153.     {"ptrack", SV_PTrack_f}, //ZOID - used with autocam
  1154.  
  1155.     {"snap", SV_NoSnap_f},
  1156.     
  1157.     {NULL, NULL}
  1158. };
  1159.  
  1160. /*
  1161. ==================
  1162. SV_ExecuteUserCommand
  1163. ==================
  1164. */
  1165. void SV_ExecuteUserCommand (char *s)
  1166. {
  1167.     ucmd_t    *u;
  1168.     
  1169.     Cmd_TokenizeString (s);
  1170.     sv_player = host_client->edict;
  1171.  
  1172.     SV_BeginRedirect (RD_CLIENT);
  1173.  
  1174.     for (u=ucmds ; u->name ; u++)
  1175.         if (!strcmp (Cmd_Argv(0), u->name) )
  1176.         {
  1177.             u->func ();
  1178.             break;
  1179.         }
  1180.  
  1181.     if (!u->name)
  1182.         Con_Printf ("Bad user command: %s\n", Cmd_Argv(0));
  1183.  
  1184.     SV_EndRedirect ();
  1185. }
  1186.  
  1187. /*
  1188. ===========================================================================
  1189.  
  1190. USER CMD EXECUTION
  1191.  
  1192. ===========================================================================
  1193. */
  1194.  
  1195. /*
  1196. ===============
  1197. V_CalcRoll
  1198.  
  1199. Used by view and sv_user
  1200. ===============
  1201. */
  1202. float V_CalcRoll (vec3_t angles, vec3_t velocity)
  1203. {
  1204.     vec3_t    forward, right, up;
  1205.     float    sign;
  1206.     float    side;
  1207.     float    value;
  1208.     
  1209.     AngleVectors (angles, forward, right, up);
  1210.     side = DotProduct (velocity, right);
  1211.     sign = side < 0 ? -1 : 1;
  1212.     side = fabs(side);
  1213.     
  1214.     value = cl_rollangle.value;
  1215.  
  1216.     if (side < cl_rollspeed.value)
  1217.         side = side * value / cl_rollspeed.value;
  1218.     else
  1219.         side = value;
  1220.     
  1221.     return side*sign;
  1222.     
  1223. }
  1224.  
  1225.  
  1226.  
  1227.  
  1228. //============================================================================
  1229.  
  1230. vec3_t    pmove_mins, pmove_maxs;
  1231.  
  1232. /*
  1233. ====================
  1234. AddLinksToPmove
  1235.  
  1236. ====================
  1237. */
  1238. void AddLinksToPmove ( areanode_t *node )
  1239. {
  1240.     link_t        *l, *next;
  1241.     edict_t        *check;
  1242.     int            pl;
  1243.     int            i;
  1244.     physent_t    *pe;
  1245.  
  1246.     pl = EDICT_TO_PROG(sv_player);
  1247.  
  1248.     // touch linked edicts
  1249.     for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next)
  1250.     {
  1251.         next = l->next;
  1252.         check = EDICT_FROM_AREA(l);
  1253.  
  1254.         if (check->v.owner == pl)
  1255.             continue;        // player's own missile
  1256.         if (check->v.solid == SOLID_BSP 
  1257.             || check->v.solid == SOLID_BBOX 
  1258.             || check->v.solid == SOLID_SLIDEBOX)
  1259.         {
  1260.             if (check == sv_player)
  1261.                 continue;
  1262.  
  1263.             for (i=0 ; i<3 ; i++)
  1264.                 if (check->v.absmin[i] > pmove_maxs[i]
  1265.                 || check->v.absmax[i] < pmove_mins[i])
  1266.                     break;
  1267.             if (i != 3)
  1268.                 continue;
  1269.             if (pmove.numphysent == MAX_PHYSENTS)
  1270.                 return;
  1271.             pe = &pmove.physents[pmove.numphysent];
  1272.             pmove.numphysent++;
  1273.  
  1274.             VectorCopy (check->v.origin, pe->origin);
  1275.             pe->info = NUM_FOR_EDICT(check);
  1276.             if (check->v.solid == SOLID_BSP)
  1277.                 pe->model = sv.models[(int)(check->v.modelindex)];
  1278.             else
  1279.             {
  1280.                 pe->model = NULL;
  1281.                 VectorCopy (check->v.mins, pe->mins);
  1282.                 VectorCopy (check->v.maxs, pe->maxs);
  1283.             }
  1284.         }
  1285.     }
  1286.     
  1287. // recurse down both sides
  1288.     if (node->axis == -1)
  1289.         return;
  1290.  
  1291.     if ( pmove_maxs[node->axis] > node->dist )
  1292.         AddLinksToPmove ( node->children[0] );
  1293.     if ( pmove_mins[node->axis] < node->dist )
  1294.         AddLinksToPmove ( node->children[1] );
  1295. }
  1296.  
  1297.  
  1298. /*
  1299. ================
  1300. AddAllEntsToPmove
  1301.  
  1302. For debugging
  1303. ================
  1304. */
  1305. void AddAllEntsToPmove (void)
  1306. {
  1307.     int            e;
  1308.     edict_t        *check;
  1309.     int            i;
  1310.     physent_t    *pe;
  1311.     int            pl;
  1312.  
  1313.     pl = EDICT_TO_PROG(sv_player);
  1314.     check = NEXT_EDICT(sv.edicts);
  1315.     for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
  1316.     {
  1317.         if (check->free)
  1318.             continue;
  1319.         if (check->v.owner == pl)
  1320.             continue;
  1321.         if (check->v.solid == SOLID_BSP 
  1322.             || check->v.solid == SOLID_BBOX 
  1323.             || check->v.solid == SOLID_SLIDEBOX)
  1324.         {
  1325.             if (check == sv_player)
  1326.                 continue;
  1327.  
  1328.             for (i=0 ; i<3 ; i++)
  1329.                 if (check->v.absmin[i] > pmove_maxs[i]
  1330.                 || check->v.absmax[i] < pmove_mins[i])
  1331.                     break;
  1332.             if (i != 3)
  1333.                 continue;
  1334.             pe = &pmove.physents[pmove.numphysent];
  1335.  
  1336.             VectorCopy (check->v.origin, pe->origin);
  1337.             pmove.physents[pmove.numphysent].info = e;
  1338.             if (check->v.solid == SOLID_BSP)
  1339.                 pe->model = sv.models[(int)(check->v.modelindex)];
  1340.             else
  1341.             {
  1342.                 pe->model = NULL;
  1343.                 VectorCopy (check->v.mins, pe->mins);
  1344.                 VectorCopy (check->v.maxs, pe->maxs);
  1345.             }
  1346.  
  1347.             if (++pmove.numphysent == MAX_PHYSENTS)
  1348.                 break;
  1349.         }
  1350.     }
  1351. }
  1352.  
  1353. /*
  1354. ===========
  1355. SV_PreRunCmd
  1356. ===========
  1357. Done before running a player command.  Clears the touch array
  1358. */
  1359. byte playertouch[(MAX_EDICTS+7)/8];
  1360.  
  1361. void SV_PreRunCmd(void)
  1362. {
  1363.     memset(playertouch, 0, sizeof(playertouch));
  1364. }
  1365.  
  1366. /*
  1367. ===========
  1368. SV_RunCmd
  1369. ===========
  1370. */
  1371. void SV_RunCmd (usercmd_t *ucmd)
  1372. {
  1373.     edict_t        *ent;
  1374.     int            i, n;
  1375.     int            oldmsec;
  1376.  
  1377.     cmd = *ucmd;
  1378.  
  1379.     // chop up very long commands
  1380.     if (cmd.msec > 50)
  1381.     {
  1382.         oldmsec = ucmd->msec;
  1383.         cmd.msec = oldmsec/2;
  1384.         SV_RunCmd (&cmd);
  1385.         cmd.msec = oldmsec/2;
  1386.         cmd.impulse = 0;
  1387.         SV_RunCmd (&cmd);
  1388.         return;
  1389.     }
  1390.  
  1391.     if (!sv_player->v.fixangle)
  1392.         VectorCopy (ucmd->angles, sv_player->v.v_angle);
  1393.  
  1394.     sv_player->v.button0 = ucmd->buttons & 1;
  1395.     sv_player->v.button2 = (ucmd->buttons & 2)>>1;
  1396.     if (ucmd->impulse)
  1397.         sv_player->v.impulse = ucmd->impulse;
  1398.  
  1399. //
  1400. // angles
  1401. // show 1/3 the pitch angle and all the roll angle    
  1402.     if (sv_player->v.health > 0)
  1403.     {
  1404.         if (!sv_player->v.fixangle)
  1405.         {
  1406.             sv_player->v.angles[PITCH] = -sv_player->v.v_angle[PITCH]/3;
  1407.             sv_player->v.angles[YAW] = sv_player->v.v_angle[YAW];
  1408.         }
  1409.         sv_player->v.angles[ROLL] = 
  1410.             V_CalcRoll (sv_player->v.angles, sv_player->v.velocity)*4;
  1411.     }
  1412.  
  1413.     host_frametime = ucmd->msec * 0.001;
  1414.     if (host_frametime > 0.1)
  1415.         host_frametime = 0.1;
  1416.  
  1417.     if (!host_client->spectator)
  1418.     {
  1419.         pr_global_struct->frametime = host_frametime;
  1420.  
  1421.         pr_global_struct->time = sv.time;
  1422.         pr_global_struct->self = EDICT_TO_PROG(sv_player);
  1423.         PR_ExecuteProgram (pr_global_struct->PlayerPreThink);
  1424.  
  1425.         SV_RunThink (sv_player);
  1426.     }
  1427.  
  1428.     for (i=0 ; i<3 ; i++)
  1429.         pmove.origin[i] = sv_player->v.origin[i] + (sv_player->v.mins[i] - player_mins[i]);
  1430.     VectorCopy (sv_player->v.velocity, pmove.velocity);
  1431.     VectorCopy (sv_player->v.v_angle, pmove.angles);
  1432.  
  1433.     pmove.spectator = host_client->spectator;
  1434.     pmove.waterjumptime = sv_player->v.teleport_time;
  1435.     pmove.numphysent = 1;
  1436.     pmove.physents[0].model = sv.worldmodel;
  1437.     pmove.cmd = *ucmd;
  1438.     pmove.dead = sv_player->v.health <= 0;
  1439.     pmove.oldbuttons = host_client->oldbuttons;
  1440.  
  1441.     movevars.entgravity = host_client->entgravity;
  1442.     movevars.maxspeed = host_client->maxspeed;
  1443.  
  1444.     for (i=0 ; i<3 ; i++)
  1445.     {
  1446.         pmove_mins[i] = pmove.origin[i] - 256;
  1447.         pmove_maxs[i] = pmove.origin[i] + 256;
  1448.     }
  1449. #if 1
  1450.     AddLinksToPmove ( sv_areanodes );
  1451. #else
  1452.     AddAllEntsToPmove ();
  1453. #endif
  1454.  
  1455. #if 0
  1456. {
  1457.     int before, after;
  1458.  
  1459. before = PM_TestPlayerPosition (pmove.origin);
  1460.     PlayerMove ();
  1461. after = PM_TestPlayerPosition (pmove.origin);
  1462.  
  1463. if (sv_player->v.health > 0 && before && !after )
  1464.     Con_Printf ("player %s got stuck in playermove!!!!\n", host_client->name);
  1465. }
  1466. #else
  1467.     PlayerMove ();
  1468. #endif
  1469.  
  1470.     host_client->oldbuttons = pmove.oldbuttons;
  1471.     sv_player->v.teleport_time = pmove.waterjumptime;
  1472.     sv_player->v.waterlevel = waterlevel;
  1473.     sv_player->v.watertype = watertype;
  1474.     if (onground != -1)
  1475.     {
  1476.         sv_player->v.flags = (int)sv_player->v.flags | FL_ONGROUND;
  1477.         sv_player->v.groundentity = EDICT_TO_PROG(EDICT_NUM(pmove.physents[onground].info));
  1478.     }
  1479.     else
  1480.         sv_player->v.flags = (int)sv_player->v.flags & ~FL_ONGROUND;
  1481.     for (i=0 ; i<3 ; i++)
  1482.         sv_player->v.origin[i] = pmove.origin[i] - (sv_player->v.mins[i] - player_mins[i]);
  1483.  
  1484. #if 0
  1485.     // truncate velocity the same way the net protocol will
  1486.     for (i=0 ; i<3 ; i++)
  1487.         sv_player->v.velocity[i] = (int)pmove.velocity[i];
  1488. #else
  1489.     VectorCopy (pmove.velocity, sv_player->v.velocity);
  1490. #endif
  1491.  
  1492.     VectorCopy (pmove.angles, sv_player->v.v_angle);
  1493.  
  1494.     if (!host_client->spectator)
  1495.     {
  1496.         // link into place and touch triggers
  1497.         SV_LinkEdict (sv_player, true);
  1498.  
  1499.         // touch other objects
  1500.         for (i=0 ; i<pmove.numtouch ; i++)
  1501.         {
  1502.             n = pmove.physents[pmove.touchindex[i]].info;
  1503.             ent = EDICT_NUM(n);
  1504.             if (!ent->v.touch || (playertouch[n/8]&(1<<(n%8))))
  1505.                 continue;
  1506.             pr_global_struct->self = EDICT_TO_PROG(ent);
  1507.             pr_global_struct->other = EDICT_TO_PROG(sv_player);
  1508.             PR_ExecuteProgram (ent->v.touch);
  1509.             playertouch[n/8] |= 1 << (n%8);
  1510.         }
  1511.     }
  1512. }
  1513.  
  1514. /*
  1515. ===========
  1516. SV_PostRunCmd
  1517. ===========
  1518. Done after running a player command.
  1519. */
  1520. void SV_PostRunCmd(void)
  1521. {
  1522.     // run post-think
  1523.  
  1524.     if (!host_client->spectator) {
  1525.         pr_global_struct->time = sv.time;
  1526.         pr_global_struct->self = EDICT_TO_PROG(sv_player);
  1527.         PR_ExecuteProgram (pr_global_struct->PlayerPostThink);
  1528.         SV_RunNewmis ();
  1529.     } else if (SpectatorThink) {
  1530.         pr_global_struct->time = sv.time;
  1531.         pr_global_struct->self = EDICT_TO_PROG(sv_player);
  1532.         PR_ExecuteProgram (SpectatorThink);
  1533.     }
  1534. }
  1535.  
  1536.  
  1537. /*
  1538. ===================
  1539. SV_ExecuteClientMessage
  1540.  
  1541. The current net_message is parsed for the given client
  1542. ===================
  1543. */
  1544. void SV_ExecuteClientMessage (client_t *cl)
  1545. {
  1546.     int        c;
  1547.     char    *s;
  1548.     usercmd_t    oldest, oldcmd, newcmd;
  1549.     client_frame_t    *frame;
  1550.     vec3_t o;
  1551.     qboolean    move_issued = false; //only allow one move command
  1552.     int        checksumIndex;
  1553.     byte    checksum, calculatedChecksum;
  1554.     int        seq_hash;
  1555.  
  1556.     // calc ping time
  1557.     frame = &cl->frames[cl->netchan.incoming_acknowledged & UPDATE_MASK];
  1558.     frame->ping_time = realtime - frame->senttime;
  1559.  
  1560.     // make sure the reply sequence number matches the incoming
  1561.     // sequence number 
  1562.     if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence)
  1563.         cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence;
  1564.     else
  1565.         cl->send_message = false;    // don't reply, sequences have slipped        
  1566.  
  1567.     // save time for ping calculations
  1568.     cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].senttime = realtime;
  1569.     cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].ping_time = -1;
  1570.  
  1571.     host_client = cl;
  1572.     sv_player = host_client->edict;
  1573.  
  1574. //    seq_hash = (cl->netchan.incoming_sequence & 0xffff) ; // ^ QW_CHECK_HASH;
  1575.     seq_hash = cl->netchan.incoming_sequence;
  1576.     
  1577.     // mark time so clients will know how much to predict
  1578.     // other players
  1579.      cl->localtime = sv.time;
  1580.     cl->delta_sequence = -1;    // no delta unless requested
  1581.     while (1)
  1582.     {
  1583.         if (msg_badread)
  1584.         {
  1585.             Con_Printf ("SV_ReadClientMessage: badread\n");
  1586.             SV_DropClient (cl);
  1587.             return;
  1588.         }    
  1589.  
  1590.         c = MSG_ReadByte ();
  1591.         if (c == -1)
  1592.             break;
  1593.                 
  1594.         switch (c)
  1595.         {
  1596.         default:
  1597.             Con_Printf ("SV_ReadClientMessage: unknown command char\n");
  1598.             SV_DropClient (cl);
  1599.             return;
  1600.                         
  1601.         case clc_nop:
  1602.             break;
  1603.  
  1604.         case clc_delta:
  1605.             cl->delta_sequence = MSG_ReadByte ();
  1606.             break;
  1607.  
  1608.         case clc_move:
  1609.             if (move_issued)
  1610.                 return;        // someone is trying to cheat...
  1611.  
  1612.             move_issued = true;
  1613.  
  1614.             checksumIndex = MSG_GetReadCount();
  1615.             checksum = (byte)MSG_ReadByte ();
  1616.  
  1617.             // read loss percentage
  1618.             cl->lossage = MSG_ReadByte();
  1619.  
  1620.             MSG_ReadDeltaUsercmd (&nullcmd, &oldest);
  1621.             MSG_ReadDeltaUsercmd (&oldest, &oldcmd);
  1622.             MSG_ReadDeltaUsercmd (&oldcmd, &newcmd);
  1623.  
  1624.             if ( cl->state != cs_spawned )
  1625.                 break;
  1626.  
  1627.             // if the checksum fails, ignore the rest of the packet
  1628.             calculatedChecksum = COM_BlockSequenceCRCByte(
  1629.                 net_message.data + checksumIndex + 1,
  1630.                 MSG_GetReadCount() - checksumIndex - 1,
  1631.                 seq_hash);
  1632.  
  1633.             if (calculatedChecksum != checksum)
  1634.             {
  1635.                 Con_DPrintf ("Failed command checksum for %s(%d) (%d != %d)\n", 
  1636.                     cl->name, cl->netchan.incoming_sequence, checksum, calculatedChecksum);
  1637.                 return;
  1638.             }
  1639.  
  1640.             if (!sv.paused) {
  1641.                 SV_PreRunCmd();
  1642.  
  1643.                 if (net_drop < 20)
  1644.                 {
  1645.                     while (net_drop > 2)
  1646.                     {
  1647.                         SV_RunCmd (&cl->lastcmd);
  1648.                         net_drop--;
  1649.                     }
  1650.                     if (net_drop > 1)
  1651.                         SV_RunCmd (&oldest);
  1652.                     if (net_drop > 0)
  1653.                         SV_RunCmd (&oldcmd);
  1654.                 }
  1655.                 SV_RunCmd (&newcmd);
  1656.  
  1657.                 SV_PostRunCmd();
  1658.             }
  1659.  
  1660.             cl->lastcmd = newcmd;
  1661.             cl->lastcmd.buttons = 0; // avoid multiple fires on lag
  1662.             break;
  1663.  
  1664.  
  1665.         case clc_stringcmd:    
  1666.             s = MSG_ReadString ();
  1667.             SV_ExecuteUserCommand (s);
  1668.             break;
  1669.  
  1670.         case clc_tmove:
  1671.             o[0] = MSG_ReadCoord();
  1672.             o[1] = MSG_ReadCoord();
  1673.             o[2] = MSG_ReadCoord();
  1674.             // only allowed by spectators
  1675.             if (host_client->spectator) {
  1676.                 VectorCopy(o, sv_player->v.origin);
  1677.                 SV_LinkEdict(sv_player, false);
  1678.             }
  1679.             break;
  1680.  
  1681.         case clc_upload:
  1682.             SV_NextUpload();
  1683.             break;
  1684.  
  1685.         }
  1686.     }
  1687. }
  1688.  
  1689. /*
  1690. ==============
  1691. SV_UserInit
  1692. ==============
  1693. */
  1694. void SV_UserInit (void)
  1695. {
  1696.     Cvar_RegisterVariable (&cl_rollspeed);
  1697.     Cvar_RegisterVariable (&cl_rollangle);
  1698.     Cvar_RegisterVariable (&sv_spectalk);
  1699.     Cvar_RegisterVariable (&sv_mapcheck);
  1700. }
  1701.  
  1702.  
  1703.