Author: gilbert-guest
Date: 2010-01-08 02:18:43 +0000 (Fri, 08 Jan 2010)
New Revision: 10673

Added:
   packages/trunk/alien-arena/debian/patches/debian-changes-7.33-1
Log:
include changes file

Added: packages/trunk/alien-arena/debian/patches/debian-changes-7.33-1
===================================================================
--- packages/trunk/alien-arena/debian/patches/debian-changes-7.33-1             
                (rev 0)
+++ packages/trunk/alien-arena/debian/patches/debian-changes-7.33-1     
2010-01-08 02:18:43 UTC (rev 10673)
@@ -0,0 +1,1485 @@
+Description: Upstream changes introduced in version 7.33-1
+ This patch has been created by dpkg-source during the package build.
+ Here's the last changelog entry, hopefully it gives details on why
+ those changes were made:
+ .
+ alien-arena (7.33-1) unstable; urgency=high
+ .
+   * New upstream release with many feature enhancments
+     (closes: #592770, #467387, #437461).
+   * Fixes CVE-2009-3637 remote arbitrary code execution (closes: #552038).
+   * Eliminated bashisms from launcher scripts (closes: #530040).
+   * Add support for new upstream file naming scheme to watch file
+     (closes: #513659).
+   * Server browser is now in-game.
+   * Updated to use source format version 3.0.
+   * Config directory has been moved to '~/.config/alien-arena' to adhere
+     to the latest freedesktop standards.
+   * Updated to standards version 3.8.3.
+ .
+ The person named in the Author field signed this changelog entry.
+Author: Michael Gilbert <[email protected]>
+Bug-Debian: http://bugs.debian.org/437461
+Bug-Debian: http://bugs.debian.org/467387
+Bug-Debian: http://bugs.debian.org/513659
+Bug-Debian: http://bugs.debian.org/530040
+Bug-Debian: http://bugs.debian.org/552038
+Bug-Debian: http://bugs.debian.org/592770
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- /dev/null
++++ alien-arena-7.33/out
+@@ -0,0 +1,11 @@
++--- source/server/sv_main.c.bak       2010-01-07 20:53:47.000000000 -0500
+++++ source/server/sv_main.c   2010-01-07 20:54:07.000000000 -0500
++@@ -166,7 +166,7 @@
++ #endif
++                      //s = NET_AdrToString ( cl->netchan.remote_address); 
//fuck you Luigi
++                      Com_sprintf (player, sizeof(player), "%i %i \"%s\" 
\"127.0.0.1\"\n",
++-                             cl->edict->client->ps.stats[STAT_FRAGS], 
cl->ping, nametxt);
+++                             cl->edict->client->ps.stats[STAT_FRAGS], 
cl->ping, nametxt, "suppressed");
++                      playerLength = strlen(player);
++                      if (statusLength + playerLength >= sizeof(status) )
++                              break;          // can't hold any more
+--- /dev/null
++++ alien-arena-7.33/sv_main.c.new
+@@ -0,0 +1,1428 @@
++/*
++Copyright (C) 1997-2001 Id Software, Inc.
++
++This program is free software; you can redistribute it and/or
++modify it under the terms of the GNU General Public License
++as published by the Free Software Foundation; either version 2
++of the License, or (at your option) any later version.
++
++This program is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++
++See the GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with this program; if not, write to the Free Software
++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++
++*/
++
++#include "server.h"
++
++master_sv_t   master_status[MAX_MASTERS];     // status of master servers
++
++client_t      *sv_client;                     // current client
++
++cvar_t        *sv_paused;
++cvar_t        *sv_timedemo;
++
++cvar_t        *sv_enforcetime;
++
++cvar_t        *timeout;                               // seconds without any 
message
++cvar_t        *zombietime;                    // seconds to sink messages 
after disconnect
++
++cvar_t        *rcon_password;                 // password for remote server 
commands
++
++cvar_t        *allow_download;
++cvar_t        *allow_download_players;
++cvar_t        *allow_download_models;
++cvar_t        *allow_download_sounds;
++cvar_t        *allow_download_maps;
++
++cvar_t        *sv_airaccelerate;
++
++cvar_t        *sv_joustmode;
++
++cvar_t        *sv_noreload;                   // don't reload level state 
when reentering
++
++cvar_t        *maxclients;                    // FIXME: rename sv_maxclients
++cvar_t        *sv_showclamp;
++
++cvar_t        *hostname;
++cvar_t        *public_server;                 // should heartbeats be sent
++
++cvar_t        *sv_reconnect_limit;    // minimum seconds between connect 
messages
++
++cvar_t        *sv_ratelimit_status;   //new security measures
++cvar_t        *sv_iplimit;
++
++cvar_t        *sv_downloadurl;
++
++int           sv_numbots;
++
++void Master_Shutdown (void);
++
++short   ShortSwap (short l);
++
++//============================================================================
++
++
++/*
++=====================
++SV_DropClient
++
++Called when the player is totally leaving the server, either willingly
++or unwillingly.  This is NOT called if the entire server is quiting
++or crashing.
++=====================
++*/
++void SV_DropClient (client_t *drop)
++{
++      // add the disconnect
++
++      MSG_WriteByte (&drop->netchan.message, svc_disconnect);
++
++      if (drop->state == cs_spawned)
++      {
++              // call the prog function for removing a client
++              // this will remove the body, among other things
++              ge->ClientDisconnect (drop->edict);
++      }
++
++      if (drop->download)
++      {
++              FS_FreeFile (drop->download);
++              drop->download = NULL;
++      }
++
++      drop->state = cs_zombie;                // become free in a few seconds
++      drop->name[0] = 0;
++}
++
++
++
++/*
++==============================================================================
++
++CONNECTIONLESS COMMANDS
++
++==============================================================================
++*/
++
++/*
++===============
++SV_StatusString
++
++Builds the string that is sent as heartbeats and status replies
++===============
++*/
++char  *SV_StatusString (void)
++{
++      char    player[1024];
++      static char     status[MAX_MSGLEN - 16];
++      int             i;
++#ifdef NOTUSED
++      int j, k;
++#endif
++      client_t        *cl;
++      int             statusLength;
++      int             playerLength;
++      char *name;
++      //char *s;
++      char nametxt[MAX_INFO_STRING];
++
++      strcpy (status, Cvar_Serverinfo());
++      strcat (status, "\n");
++      statusLength = strlen(status);
++
++      for (i=0 ; i<maxclients->value ; i++)
++      {
++              cl = &svs.clients[i];
++              if (cl->state == cs_connected || cl->state == cs_spawned )
++              {
++                      name = cl->name; 
++#ifdef NOTUSED
++                      //handle color chars
++                      nametxt[0] = 0;
++                      k = 0;
++                      while(j = *name) {
++                              if ( Q_IsColorString( name ) ) {
++                                      name +=2;
++                                      continue;
++                              }
++                              nametxt[k] = j;
++                              name++;
++                              k++;
++                              //failsafe - break at 32 chars
++                              if(k>30)
++                                      break;
++                      }
++                      nametxt[k]=0;
++#else         
++                      //allow color chars to be sent
++                      strcpy(nametxt, name);
++                      nametxt[31] = '\0'; //failsafe
++#endif
++                      //s = NET_AdrToString ( cl->netchan.remote_address); 
//fuck you Luigi
++                      Com_sprintf (player, sizeof(player), "%i %i \"%s\" 
\"127.0.0.1\"\n",
++                              cl->edict->client->ps.stats[STAT_FRAGS], 
cl->ping, nametxt, "suppressed");
++                      playerLength = strlen(player);
++                      if (statusLength + playerLength >= sizeof(status) )
++                              break;          // can't hold any more
++                      strcpy (status + statusLength, player);
++                      statusLength += playerLength;
++
++              }
++      }
++      //bot score info
++      cl = &svs.clients[0]; //get the bots info from the first client
++      if(cl->edict->client->ps.botnum) {
++              for(i = 0; i < cl->edict->client->ps.botnum; i++) {
++
++                      name = cl->edict->client->ps.bots[i].name; 
++#ifdef NOTUSED
++                      //handle color chars
++                      nametxt[0] = 0;
++                      k = 0;
++                      while(j = *name) {
++                              if ( Q_IsColorString( name ) ) {
++                                      name +=2;
++                                      continue;
++                              }
++                              nametxt[k] = j;
++                              name++;
++                              k++;
++                              //failsafe - break at 32 chars
++                              if(k>30)
++                                      break;
++                      }
++                      nametxt[k]=0;
++#else
++                      //allow color chars to be sent
++                      strcpy(nametxt, name);
++                      nametxt[31] = '\0'; //failsafe
++#endif
++
++                      Com_sprintf (player, sizeof(player), "%i %i \"%s\" 
\"127.0.0.1\"\n",
++                              cl->edict->client->ps.bots[i].score, 0, 
nametxt);
++                      playerLength = strlen(player);
++                      if (statusLength + playerLength >= sizeof(status) )
++                              break;          // can't hold any more
++                      strcpy (status + statusLength, player);
++                      statusLength += playerLength;
++              }
++      }
++      //end bot score info
++      return status;
++}
++
++/*
++================
++SVC_Status
++
++Responds with all the info that qplug or qspy can see
++================
++*/
++/*void SVC_Status (void)
++{
++      Netchan_OutOfBandPrint (NS_SERVER, net_from, "print\n%s", 
SV_StatusString());
++#if 0
++      Com_BeginRedirect (RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, 
SV_FlushRedirect);
++      Com_Printf (SV_StatusString());
++      Com_EndRedirect ();
++#endif
++}*/
++static qboolean RateLimited (ratelimit_t *limit, int maxCount)
++{
++      int diff;
++
++      diff = sv.time - limit->time;
++
++      //a new sampling period
++      if (diff > limit->period || diff < 0)
++      {
++              limit->time = sv.time;
++              limit->count = 0;
++      }
++      else
++      {
++              if (limit->count >= maxCount)
++                      return true;
++      }
++
++      return false;
++}
++
++static void RateSample (ratelimit_t *limit)
++{
++      int diff;
++
++      diff = sv.time - limit->time;
++
++      //a new sampling period
++      if (diff > limit->period || diff < 0)
++      {
++              limit->time = sv.time;
++              limit->count = 1;
++      }
++      else
++      {
++              limit->count++;
++      }
++}
++
++static void SVC_Status (void)
++{
++
++      RateSample (&svs.ratelimit_status);
++
++      if (RateLimited (&svs.ratelimit_status, sv_ratelimit_status->integer))
++      {
++              Com_DPrintf ("SVC_Status: Dropped status request from %s\n", 
NET_AdrToString (net_from));
++              return;
++      }
++
++      Netchan_OutOfBandPrint (NS_SERVER, net_from, "print\n%s", 
SV_StatusString());
++}
++
++/*
++================
++SVC_Ack
++
++================
++*/
++void SVC_Ack (void)
++{
++      int             i;
++      Com_Printf ("Ping acknowledge from %s\n", NET_AdrToString(net_from));
++      for ( i = 0 ; i < MAX_MASTERS ; i ++ ) {
++              if ( master_status[i].name[0] == 0 )
++                      break;
++
++              if ( master_status[i].addr.port == 0 )
++                      continue;
++
++              if ( NET_CompareAdr (master_status[i].addr, net_from) )
++                      master_status[i].last_ping_ack = 2;
++      }
++}
++
++/*
++================
++SVC_Info
++
++Responds with short info for broadcast scans
++The second parameter should be the current protocol version number.
++================
++*/
++void SVC_Info (void)
++{
++      char    string[64];
++      int             i, count;
++      int             version;
++      client_t        *cl;
++
++      if (maxclients->value == 1)
++              return;         // ignore in single player
++
++      version = atoi (Cmd_Argv(1));
++
++      if (version != PROTOCOL_VERSION) {
++              Com_sprintf (string, sizeof(string), "%s: wrong version\n", 
hostname->string, sizeof(string));
++              //r1: return instead of sending another packet. prevents 
spoofed udp packet
++              //    causing server <-> server info loops.
++              return;
++      }
++      else
++      {
++              count = 0;
++              for (i=0 ; i<maxclients->value ; i++)
++                      if (svs.clients[i].state >= cs_connected)
++                              count++;
++              //bot score info
++              cl = &svs.clients[0];
++              if(cl->edict->client->ps.botnum > 0)
++                      count += cl->edict->client->ps.botnum; //add the bots
++              //end bot score info
++
++              Com_sprintf (string, sizeof(string), "%16s %8s %2i/%2i\n", 
hostname->string, sv.name, count, (int)maxclients->value);
++      }
++
++      Netchan_OutOfBandPrint (NS_SERVER, net_from, "info\n%s", string);
++}
++
++/*
++================
++SVC_Ping
++
++Just responds with an acknowledgement
++================
++*/
++void SVC_Ping (void)
++{
++      Netchan_OutOfBandPrint (NS_SERVER, net_from, "ack");
++}
++
++void SV_KickClient (client_t *cl, const char /*...@null@*/*reason, const char 
/*...@null@*/*cprintf)
++{
++      if (reason && cl->state == cs_spawned && cl->name[0])
++              SV_BroadcastPrintf (PRINT_HIGH, "%s was dropped: %s\n", 
cl->name, reason);
++      if (cprintf)
++              SV_ClientPrintf (cl, PRINT_HIGH, "%s", cprintf);
++      Com_Printf ("Dropping %s, %s.\n", cl->name, reason ? reason : 
"SV_KickClient");
++      SV_DropClient (cl);
++}
++
++/*
++=================
++SVC_GetChallenge
++
++Returns a challenge number that can be used
++in a subsequent client_connect command.
++We do this to prevent denial of service attacks that
++flood the server with invalid connection IPs.  With a
++challenge, they must give a valid IP address.
++=================
++*/
++void SVC_GetChallenge (void)
++{
++      int             i;
++      int             oldest;
++      int             oldestTime;
++
++      oldest = 0;
++      oldestTime = 0x7fffffff;
++
++      // see if we already have a challenge for this ip
++      for (i = 0 ; i < MAX_CHALLENGES ; i++)
++      {
++              if (NET_CompareBaseAdr (net_from, svs.challenges[i].adr))
++                      break;
++              if (svs.challenges[i].time < oldestTime)
++              {
++                      oldestTime = svs.challenges[i].time;
++                      oldest = i;
++              }
++      }
++
++      if (i == MAX_CHALLENGES)
++      {
++              // overwrite the oldest
++              svs.challenges[oldest].challenge = rand() & 0x7fff;
++              svs.challenges[oldest].adr = net_from;
++              svs.challenges[oldest].time = curtime;
++              i = oldest;
++      }
++
++      // send it back
++      Netchan_OutOfBandPrint (NS_SERVER, net_from, "challenge %i", 
svs.challenges[i].challenge);
++}
++
++/*
++==================
++SVC_DirectConnect
++
++A connection request that did not come from the master
++==================
++*/
++void SVC_DirectConnect (void)
++{
++      char            userinfo[MAX_INFO_STRING];
++      netadr_t        adr;
++      int                     i;
++      client_t        *cl, *newcl;
++      client_t        temp;
++      edict_t         *ent;
++      int                     edictnum;
++      int                     version;
++      int                     qport;
++      int                     challenge;
++      int                     previousclients;
++      int                     botnum, botkick;
++
++      adr = net_from;
++
++      Com_DPrintf ("SVC_DirectConnect ()\n");
++
++      version = atoi(Cmd_Argv(1));
++      if (version != PROTOCOL_VERSION)
++      {
++              Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nServer is 
version %4.2f.\n", VERSION);
++              Com_DPrintf ("    rejected connect from version %i\n", version);
++              return;
++      }
++
++      qport = atoi(Cmd_Argv(2));
++
++      challenge = atoi(Cmd_Argv(3));
++
++      //security, overflow fixes
++
++      //limit connections from a single IP
++      previousclients = 0;
++      for (i=0,cl=svs.clients ; i<maxclients->integer ; i++,cl++)
++      {
++              if (cl->state == cs_free)
++                      continue;
++              if (NET_CompareBaseAdr (adr, cl->netchan.remote_address))
++              {
++                      //zombies are less dangerous
++                      if (cl->state == cs_zombie)
++                              previousclients++;
++                      else
++                              previousclients += 2;
++              }
++      }
++
++      if (previousclients >= sv_iplimit->integer * 2)
++      {
++              Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nToo many 
connections from your host.\n");
++              Com_DPrintf ("    too many connections\n");
++              return;
++      }
++
++      // sku - reserve 32 bytes for the IP address
++      strncpy (userinfo, Cmd_Argv(4), sizeof(userinfo)-32);
++      userinfo[sizeof(userinfo) - 32] = 0;
++
++      //check it is not overflowed, save enough bytes for 
/ip/111.222.333.444:55555
++      if (strlen(userinfo) + 25 >= sizeof(userinfo)-1)
++      {
++              Com_DPrintf ("    userinfo length exceeded\n");
++              Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nUserinfo string 
length exceeded.\n");
++              return;
++      }
++      else if (!userinfo[0])
++      {
++              Com_DPrintf ("    empty userinfo string\n");
++              Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nBad userinfo 
string.\n");
++              return;
++      }
++
++      //block anyone trying to use the end-of-message-in-string exploit
++      if (strchr(userinfo, '\xFF'))
++      {
++              char            *ptr;
++              ptr = strchr (userinfo, '\xFF');
++              ptr -= 8;
++              if (ptr < userinfo)
++                      ptr = userinfo;
++              Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nConnection 
refused due to attempted exploit!\n");
++              return;
++      }
++      if (Info_KeyExists (userinfo, "ip"))
++      {
++              char    *p;
++              p = Info_ValueForKey(userinfo, "ip");
++              Com_Printf ("EXPLOIT: Client %s attempted to spoof IP address: 
%s\n", Info_ValueForKey (userinfo, "name"), NET_AdrToString(adr));
++              return;
++      }
++
++      // force the IP key/value pair so the game can filter based on ip
++      Info_SetValueForKey (userinfo, "ip", NET_AdrToString(net_from));
++
++      // attractloop servers are ONLY for local clients
++      if (sv.attractloop)
++      {
++              if (!NET_IsLocalAddress (adr))
++              {
++                      Com_Printf ("Remote connect in attract loop.  
Ignored.\n");
++                      Netchan_OutOfBandPrint (NS_SERVER, adr, 
"print\nConnection refused.\n");
++                      return;
++              }
++      }
++
++      // see if the challenge is valid
++      if (!NET_IsLocalAddress (adr))
++      {
++              for (i=0 ; i<MAX_CHALLENGES ; i++)
++              {
++                      if (NET_CompareBaseAdr (net_from, 
svs.challenges[i].adr))
++                      {
++                              if (challenge == svs.challenges[i].challenge)
++                                      break;          // good
++                              Netchan_OutOfBandPrint (NS_SERVER, adr, 
"print\nBad challenge.\n");
++                              return;
++                      }
++              }
++              if (i == MAX_CHALLENGES)
++              {
++                      Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nNo 
challenge for address.\n");
++                      return;
++              }
++      }
++
++      newcl = &temp;
++      memset (newcl, 0, sizeof(client_t));
++
++      // if there is already a slot for this ip, reuse it
++      for (i=0,cl=svs.clients ; i<maxclients->value ; i++,cl++)
++      {
++              if (cl->state == cs_free)
++                      continue;
++
++              if (NET_CompareAdr (adr, cl->netchan.remote_address))
++              {
++
++                      //r1: !! fix nasty bug where non-disconnected clients 
(from dropped disconnect
++                      //packets) could be overwritten!
++                      if (cl->state != cs_zombie)
++                      {
++                              Com_DPrintf ("    client already found\n");
++                              Netchan_OutOfBandPrint (NS_SERVER, adr, 
"print\nPlayer '%s' is already connected from %s.\n", cl->name, 
NET_AdrToString(adr));
++                              return;
++                      }
++
++                      if (!NET_IsLocalAddress (adr) && (svs.realtime - 
cl->lastconnect) < ((int)sv_reconnect_limit->integer * 1000))
++                      {
++                              Com_DPrintf ("%s:reconnect rejected : too 
soon\n", NET_AdrToString (adr));
++                              return;
++                      }
++                      Com_Printf ("%s:reconnect\n", NET_AdrToString (adr));
++
++                      newcl = cl;
++                      goto gotnewcl;
++              }
++      }
++
++      // find a client slot
++      cl = &svs.clients[0]; //get the active bots info from the first client
++      botnum = cl->edict->client->ps.botnum;
++      //still need to reserve one slot
++      newcl = NULL;
++
++      //are we using botkickthreshold?
++      botkick = Cvar_VariableValue("sv_botkickthreshold");
++
++      //prevent client slot overwrites with bots rejoining after map change
++      if(botkick) {
++              
++              if(botkick < sv_numbots)
++                      botnum = botkick;
++              else
++                      botnum = sv_numbots;
++      }
++
++      for (i=0,cl=svs.clients ; i<maxclients->value-botnum; i++,cl++)
++      {
++              if (cl->state == cs_free)
++              {
++                      newcl = cl;
++                      break;
++              }
++      }
++      if (!newcl)
++      {
++              Netchan_OutOfBandPrint (NS_SERVER, adr, "print\nServer is 
full.\n");
++              Com_DPrintf ("Rejected a connection.\n");
++              return;
++      }
++
++gotnewcl:
++      // build a new connection
++      // accept the new client
++      // this is the only place a client_t is ever initialized
++      *newcl = temp;
++      sv_client = newcl;
++      edictnum = (newcl-svs.clients)+1;
++      ent = EDICT_NUM(edictnum);
++      newcl->edict = ent;
++      newcl->challenge = challenge; // save challenge for checksumming
++
++      // get the game a chance to reject this connection or modify the 
userinfo
++
++      if (!(ge->ClientConnect (ent, userinfo)))
++      {
++
++              if (*Info_ValueForKey (userinfo, "rejmsg"))
++                      Netchan_OutOfBandPrint (NS_SERVER, adr, 
"print\n%s\nConnection refused.\n",
++                              Info_ValueForKey (userinfo, "rejmsg"));
++              else
++                      Netchan_OutOfBandPrint (NS_SERVER, adr, 
"print\nConnection refused.\n" );
++              Com_DPrintf ("Game rejected a connection.\n");
++              return;
++      }
++
++      // parse some info from the info strings
++      strncpy (newcl->userinfo, userinfo, sizeof(newcl->userinfo)-1);
++      SV_UserinfoChanged (newcl);
++
++      // send the connect packet to the client
++      Netchan_OutOfBandPrint(NS_SERVER, adr, "client_connect %s", 
sv_downloadurl->string);
++
++      Netchan_Setup (NS_SERVER, &newcl->netchan , adr, qport);
++
++      newcl->state = cs_connected;
++
++      SZ_Init (&newcl->datagram, newcl->datagram_buf, 
sizeof(newcl->datagram_buf) );
++      SZ_SetName (&newcl->datagram, va("Datagram buffer %s", 
NET_AdrToString(adr)), true);
++
++      newcl->datagram.allowoverflow = true;
++      newcl->lastmessage = svs.realtime;      // don't timeout
++      newcl->lastconnect = svs.realtime;
++}
++
++int Rcon_Validate (void)
++{
++      if (!strlen (rcon_password->string))
++              return 0;
++
++      if (strcmp (Cmd_Argv(1), rcon_password->string) )
++              return 0;
++
++      return 1;
++}
++
++/*
++===============
++SVC_RemoteCommand
++
++A client issued an rcon command.
++Shift down the remaining args
++Redirect all printfs
++===============
++*/
++void SVC_RemoteCommand (void)
++{
++      int             i;
++      char    remaining[1024];
++
++      i = Rcon_Validate ();
++
++      if (i == 0)
++              Com_Printf ("Bad rcon from %s:\n%s\n", NET_AdrToString 
(net_from), net_message.data+4);
++      else
++              Com_Printf ("Rcon from %s:\n%s\n", NET_AdrToString (net_from), 
net_message.data+4);
++
++      Com_BeginRedirect (RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, 
SV_FlushRedirect);
++
++      if (!Rcon_Validate ())
++      {
++              Com_Printf ("Bad rcon_password.\n");
++      }
++      else
++      {
++              remaining[0] = 0;
++
++              for (i=2 ; i<Cmd_Argc() ; i++)
++              {
++                      /* If spaces present in args, quote them in the 
remaining string */
++                      if(strchr(Cmd_Argv(i), ' '))
++                      {
++                              strcat (remaining, "\"");
++                              strcat (remaining, Cmd_Argv(i) );
++                              strcat (remaining, "\"");
++                      }
++                      else
++                      {
++                              strcat (remaining, Cmd_Argv(i) );
++                      }
++                      strcat (remaining, " ");
++              }
++
++              Cmd_ExecuteString (remaining);
++      }
++
++      Com_EndRedirect ();
++}
++
++/*
++=================
++SV_ConnectionlessPacket
++
++A connectionless packet has four leading 0xff
++characters to distinguish it from a game channel.
++Clients that are in the game can still send
++connectionless packets.
++=================
++*/
++void SV_ConnectionlessPacket (void)
++{
++      char    *s;
++      char    *c;
++
++      //r1: make sure we never talk to ourselves
++      if (NET_IsLocalAddress (net_from) && !NET_IsLocalHost(&net_from) && 
ShortSwap(net_from.port) == server_port)
++      {
++              Com_DPrintf ("dropped %d byte connectionless packet from self! 
(spoofing attack?)\n", net_message.cursize);
++              return;
++      }
++
++
++      MSG_BeginReading (&net_message);
++      MSG_ReadLong (&net_message);            // skip the -1 marker
++
++      s = MSG_ReadStringLine (&net_message);
++
++      Cmd_TokenizeString (s, false);
++
++      c = Cmd_Argv(0);
++      Com_DPrintf ("Packet %s : %s\n", NET_AdrToString(net_from), c);
++
++      if (!strcmp(c, "ping"))
++              SVC_Ping ();
++      else if (!strcmp(c, "ack"))
++              SVC_Ack ();
++      else if (!strcmp(c,"status"))
++              SVC_Status ();
++      else if (!strcmp(c,"info"))
++              SVC_Info ();
++      else if (!strcmp(c,"getchallenge"))
++              SVC_GetChallenge ();
++      else if (!strcmp(c,"connect"))
++              SVC_DirectConnect ();
++      else if (!strcmp(c, "rcon"))
++              SVC_RemoteCommand ();
++      else
++              Com_Printf ("bad connectionless packet from %s:\n%s\n"
++              , NET_AdrToString (net_from), s);
++}
++
++
++//============================================================================
++
++/*
++===================
++SV_CalcPings
++
++Updates the cl->ping variables
++===================
++*/
++void SV_CalcPings (void)
++{
++      int                     i, j;
++      client_t        *cl;
++      int                     total, count;
++
++      for (i=0 ; i<maxclients->value ; i++)
++      {
++              cl = &svs.clients[i];
++              if (cl->state != cs_spawned )
++                      continue;
++
++#if 0
++              if (cl->lastframe > 0)
++                      cl->frame_latency[sv.framenum&(LATENCY_COUNTS-1)] = 
sv.framenum - cl->lastframe + 1;
++              else
++                      cl->frame_latency[sv.framenum&(LATENCY_COUNTS-1)] = 0;
++#endif
++
++              total = 0;
++              count = 0;
++              for (j=0 ; j<LATENCY_COUNTS ; j++)
++              {
++                      if (cl->frame_latency[j] > 0)
++                      {
++                              count++;
++                              total += cl->frame_latency[j];
++                      }
++              }
++              if (!count)
++                      cl->ping = 0;
++              else
++#if 0
++                      cl->ping = total*100/count - 100;
++#else
++                      cl->ping = total / count;
++#endif
++
++              // let the game dll know about the ping
++              cl->edict->client->ping = cl->ping;
++      }
++}
++
++
++/*
++===================
++SV_GiveMsec
++
++Every few frames, gives all clients an allotment of milliseconds
++for their command moves.  If they exceed it, assume cheating.
++===================
++*/
++void SV_GiveMsec (void)
++{
++      int                     i;
++      client_t        *cl;
++
++      if (sv.framenum & 15)
++              return;
++
++      for (i=0 ; i<maxclients->value ; i++)
++      {
++              cl = &svs.clients[i];
++              if (cl->state == cs_free )
++                      continue;
++
++              cl->commandMsec = 1800;         // 1600 + some slop
++      }
++}
++
++
++/*
++=================
++SV_ReadPackets
++=================
++*/
++void SV_ReadPackets (void)
++{
++      int                     i;
++      client_t        *cl;
++      int                     qport;
++
++      while (NET_GetPacket (NS_SERVER, &net_from, &net_message))
++      {
++              // check for connectionless packet (0xffffffff) first
++              if (*(int *)net_message.data == -1)
++              {
++                      SV_ConnectionlessPacket ();
++                      continue;
++              }
++
++              // read the qport out of the message so we can fix up
++              // stupid address translating routers
++              MSG_BeginReading (&net_message);
++              MSG_ReadLong (&net_message);            // sequence number
++              MSG_ReadLong (&net_message);            // sequence number
++              qport = MSG_ReadShort (&net_message) & 0xffff;
++
++              // check for packets from connected clients
++              for (i=0, cl=svs.clients ; i<maxclients->value ; i++,cl++)
++              {
++                      if (cl->state == cs_free)
++                              continue;
++
++                      if (!NET_CompareBaseAdr (net_from, 
cl->netchan.remote_address))
++                              continue;
++                      if (cl->netchan.qport != qport)
++                              continue;
++                      if (cl->netchan.remote_address.port != net_from.port)
++                      {
++                              Com_Printf ("SV_ReadPackets: fixing up a 
translated port\n");
++                              cl->netchan.remote_address.port = net_from.port;
++                      }
++
++                      if (Netchan_Process(&cl->netchan, &net_message))
++                      {       // this is a valid, sequenced packet, so 
process it
++                              if (cl->state != cs_zombie)
++                              {
++                                      cl->lastmessage = svs.realtime; // 
don't timeout
++                                      SV_ExecuteClientMessage (cl);
++                              }
++                      }
++                      break;
++              }
++
++              if (i != maxclients->value)
++                      continue;
++      }
++}
++
++/*
++==================
++SV_CheckTimeouts
++
++If a packet has not been received from a client for timeout->value
++seconds, drop the conneciton.  Server frames are used instead of
++realtime to avoid dropping the local client while debugging.
++
++When a client is normally dropped, the client_t goes into a zombie state
++for a few seconds to make sure any final reliable message gets resent
++if necessary
++==================
++*/
++void SV_CheckTimeouts (void)
++{
++      int             i;
++      client_t        *cl;
++      int                     droppoint;
++      int                     zombiepoint;
++
++      droppoint = svs.realtime - 1000*timeout->value;
++      zombiepoint = svs.realtime - 1000*zombietime->value;
++
++      for (i=0,cl=svs.clients ; i<maxclients->value ; i++,cl++)
++      {
++
++
++              // message times may be wrong across a changelevel
++              if (cl->lastmessage > svs.realtime)
++                      cl->lastmessage = svs.realtime;
++
++              if (cl->state == cs_zombie
++              && cl->lastmessage < zombiepoint)
++              {
++                      cl->state = cs_free;    // can now be reused
++                      continue;
++              }
++              if ( (cl->state == cs_connected || cl->state == cs_spawned)
++                      && cl->lastmessage < droppoint)
++              {
++                      SV_BroadcastPrintf (PRINT_HIGH, "%s timed out\n", 
cl->name);
++                      SV_DropClient (cl);
++                      cl->state = cs_free;    // don't bother with zombie 
state
++              }
++      }
++}
++
++/*
++================
++SV_PrepWorldFrame
++
++This has to be done before the world logic, because
++player processing happens outside RunWorldFrame
++================
++*/
++void SV_PrepWorldFrame (void)
++{
++      edict_t *ent;
++      int             i;
++
++      for (i=0 ; i<ge->num_edicts ; i++, ent++)
++      {
++              ent = EDICT_NUM(i);
++              // events only last for a single message
++              ent->s.event = 0;
++      }
++
++}
++
++
++/*
++=================
++SV_RunGameFrame
++=================
++*/
++void SV_RunGameFrame (void)
++{
++      if (host_speeds->value)
++              time_before_game = Sys_Milliseconds ();
++
++      // we always need to bump framenum, even if we
++      // don't run the world, otherwise the delta
++      // compression can get confused when a client
++      // has the "current" frame
++      sv.framenum++;
++      sv.time = sv.framenum*100;
++
++      // don't run if paused
++      if (!sv_paused->value || maxclients->value > 1)
++      {
++              ge->RunFrame ();
++
++              // never get more than one tic behind
++              if (sv.time < svs.realtime)
++              {
++                      if (sv_showclamp->value)
++                              Com_Printf ("sv highclamp\n");
++                      svs.realtime = sv.time;
++              }
++      }
++
++      if (host_speeds->value)
++              time_after_game = Sys_Milliseconds ();
++
++}
++
++/*
++==================
++SV_Frame
++
++==================
++*/
++void SV_Frame (int msec)
++{
++      time_before_game = time_after_game = 0;
++
++      // if server is not active, do nothing
++      if (!svs.initialized)
++              return;
++
++    svs.realtime += msec;
++
++      // keep the random time dependent
++      rand ();
++
++      // check timeouts
++      SV_CheckTimeouts ();
++
++      // get packets from clients
++      SV_ReadPackets ();
++
++      // move autonomous things around if enough time has passed
++      if (!sv_timedemo->value && svs.realtime < sv.time)
++      {
++              // never let the time get too far off
++              if (sv.time - svs.realtime > 100)
++              {
++                      if (sv_showclamp->value)
++                              Com_Printf ("sv lowclamp\n");
++                      svs.realtime = sv.time - 100;
++              }
++              NET_Sleep(sv.time - svs.realtime);
++              return;
++      }
++
++      // update ping based on the last known frame from all clients
++      SV_CalcPings ();
++
++      // give the clients some timeslices
++      SV_GiveMsec ();
++
++      // let everything in the world think and move
++      SV_RunGameFrame ();
++
++      // send messages back to the clients that had packets read this frame
++      SV_SendClientMessages ();
++
++      // save the entire world state if recording a serverdemo
++      SV_RecordDemoMessage ();
++
++      // send a heartbeat to the master if needed
++      Master_Heartbeat ();
++
++      // clear teleport flags, etc for next frame
++      SV_PrepWorldFrame ();
++
++}
++
++//============================================================================
++
++/*
++================
++Master_Heartbeat
++
++Send a message to the master every few minutes to
++let it know we are alive, and log information
++================
++*/
++#define       HEARTBEAT_SECONDS       300
++void Master_Heartbeat (void)
++{
++      char            string[MAX_MSGLEN];
++
++      // pgm post3.19 change, cvar pointer not validated before dereferencing
++
++      if(!public_server || !public_server->value)
++              return;
++
++      // check for time wraparound
++      if (svs.last_heartbeat > svs.realtime)
++              svs.last_heartbeat = svs.realtime;
++
++      if (svs.realtime - svs.last_heartbeat < HEARTBEAT_SECONDS*1000)
++              return;         // not time to send yet
++
++      svs.last_heartbeat = svs.realtime;
++
++      // send the same string that we would give for a status OOB command
++      Com_sprintf (string, MAX_MSGLEN, "heartbeat\n%s", SV_StatusString ());
++      SV_HandleMasters (string, "heartbeat");
++}
++
++/*
++=================
++Master_Shutdown
++
++Informs all masters that this server is going down
++=================
++*/
++void Master_Shutdown (void)
++{
++
++      // pgm post3.19 change, cvar pointer not validated before dereferencing
++      if (!public_server || !public_server->value)
++              return;         // a private dedicated game
++
++      SV_HandleMasters ("shutdown", "shutdown");
++}
++
++
++/*
++=================
++SV_HandleMasters
++
++Sends a message to all master servers, looking up the
++master servers' addresses if appropriate.
++=================
++*/
++void SV_HandleMasters (const char *message, const char *console_message)
++{
++      int             i;
++      qboolean        updated_master;
++
++      // if the server is not dedicated, we need to check cl_master
++      if ( !( dedicated && dedicated->value ) )
++      {
++              if ( !sv_master )
++              {
++                      sv_master = Cvar_Get ("cl_master", 
"master.corservers.com", CVAR_ARCHIVE);
++                      updated_master = true;
++              }
++              else if ( sv_master->modified )
++              {
++                      sv_master->modified = false;
++                      updated_master = true;
++              }
++              else
++              {
++                      updated_master = false;
++              }
++
++              if ( updated_master )
++              {
++                      memset (&master_status[0], 0, sizeof(master_sv_t));
++                      strncpy (master_status[0].name, sv_master->string, 
MAX_MASTER_LEN);
++              }
++      }
++
++      // first we need to loop through the master servers
++      // in order to find the ones that need (re-)resolving
++      for ( i = 0; i < MAX_MASTERS ; i ++ )
++      {
++              if ( master_status[i].name[0] == 0 )
++                      break;
++
++              // if we already sent a ping and didn't get
++              // any acknowledgement packet, we need to try
++              // re-resolving
++              if ( master_status[i].resolved && 
master_status[i].last_ping_sent > master_status[i].last_ping_ack )
++              {
++                      Com_Printf ("No acknowledgement from %s - 
re-resolving\n", master_status[i].name);
++                      master_status[i].resolved = false;
++              }
++
++              if ( master_status[i].resolved )
++                      continue;
++
++              if (!NET_StringToAdr (master_status[i].name, 
&master_status[i].addr))
++              {
++                      // resolution failed, did we say so already?
++                      if ( !master_status[i].failed )
++                      {
++                              Com_Printf ("Bad master address: %s\n", 
master_status[i].name);
++                              master_status[i].failed = true;
++                      }
++                      master_status[i].addr.port = 0;
++              }
++              else
++              {
++                      master_status[i].failed = false;
++                      master_status[i].resolved = true;
++
++                      if (master_status[i].addr.port == 0)
++                              master_status[i].addr.port = BigShort 
(PORT_MASTER);
++
++                      Com_Printf ("Master server at %s\n", NET_AdrToString 
(master_status[i].addr));
++              }
++      }
++
++      // send the message we needed to send
++      for ( i = 0 ; i < MAX_MASTERS ; i ++ )
++      {
++              if ( master_status[i].name[0] == 0 )
++                      break;
++
++              if ( master_status[i].addr.port == 0 )
++                      continue;
++
++              Com_Printf ("Sending %s to %s\n", console_message, 
NET_AdrToString (master_status[i].addr));
++              Netchan_OutOfBandPrint (NS_SERVER, master_status[i].addr, "%s", 
message);
++              master_status[i].last_ping_sent = 1;
++              master_status[i].last_ping_ack = 0;
++      }
++}
++
++
++//============================================================================
++
++
++/*
++=================
++SV_UserinfoChanged
++
++Pull specific info from a newly changed userinfo string
++into a more C freindly form.
++=================
++*/
++void SV_UserinfoChanged (client_t *cl)
++{
++      char    *val;
++      int             i;
++
++      // call prog code to allow overrides
++      ge->ClientUserinfoChanged (cl->edict, cl->userinfo, 0);
++
++      // name for C code
++      strncpy (cl->name, Info_ValueForKey (cl->userinfo, "name"), 
sizeof(cl->name)-1);
++      // mask off high bit
++      for (i=0 ; i<sizeof(cl->name) ; i++)
++              cl->name[i] &= 127;
++
++      // rate command
++      val = Info_ValueForKey (cl->userinfo, "rate");
++      if (strlen(val))
++      {
++              i = atoi(val);
++              cl->rate = i;
++              if (cl->rate < 100)
++                      cl->rate = 100;
++              if (cl->rate > 15000)
++                      cl->rate = 15000;
++      }
++      else
++              cl->rate = 5000;
++
++      // msg command
++      val = Info_ValueForKey (cl->userinfo, "msg");
++      if (strlen(val))
++      {
++              cl->messagelevel = atoi(val);
++      }
++
++}
++
++
++//============================================================================
++
++/*
++===============
++SV_Init
++
++Only called at quake2.exe startup, not for each game
++===============
++*/
++void SV_Init (void)
++{
++      SV_InitOperatorCommands ();
++
++      rcon_password = Cvar_Get ("rcon_password", "", 0);
++      Cvar_Get ("skill", "1", 0);
++      Cvar_Get ("deathmatch", "1", CVAR_LATCH); //Alien Arena is *always* 
deathmatch
++      Cvar_Get ("ctf", "0", CVAR_LATCH);
++      Cvar_Get ("dmflags", va("%i", DF_INSTANT_ITEMS), CVAR_SERVERINFO);
++      Cvar_Get ("fraglimit", "0", CVAR_SERVERINFO);
++      Cvar_Get ("timelimit", "0", CVAR_SERVERINFO);
++      Cvar_Get ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
++      Cvar_Get ("protocol", va("%i", PROTOCOL_VERSION), 
CVAR_SERVERINFO|CVAR_NOSET);;
++      maxclients = Cvar_Get ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
++      hostname = Cvar_Get ("hostname", "noname", CVAR_SERVERINFO | 
CVAR_ARCHIVE);
++      timeout = Cvar_Get ("timeout", "125", 0);
++      zombietime = Cvar_Get ("zombietime", "2", 0);
++      sv_showclamp = Cvar_Get ("showclamp", "0", 0);
++      sv_paused = Cvar_Get ("paused", "0", 0);
++      sv_timedemo = Cvar_Get ("timedemo", "0", 0);
++      sv_enforcetime = Cvar_Get ("sv_enforcetime", "0", 0);
++      allow_download = Cvar_Get ("allow_download", "1", CVAR_ARCHIVE);
++      allow_download_players  = Cvar_Get ("allow_download_players", "0", 
CVAR_ARCHIVE);
++      allow_download_models = Cvar_Get ("allow_download_models", "1", 
CVAR_ARCHIVE);
++      allow_download_sounds = Cvar_Get ("allow_download_sounds", "1", 
CVAR_ARCHIVE);
++      allow_download_maps       = Cvar_Get ("allow_download_maps", "1", 
CVAR_ARCHIVE);
++      sv_downloadurl = Cvar_Get("sv_downloadurl", 
"http://icculus.org/alienarena/sv_downloadurl";, CVAR_SERVERINFO);
++
++      sv_noreload = Cvar_Get ("sv_noreload", "0", 0);
++
++      sv_airaccelerate = Cvar_Get("sv_airaccelerate", "0", CVAR_LATCH);
++
++      sv_joustmode = Cvar_Get("sv_joustmode", "0", CVAR_SERVERINFO);
++
++      public_server = Cvar_Get ("sv_public", "1", 0);
++
++      sv_reconnect_limit = Cvar_Get ("sv_reconnect_limit", "3", CVAR_ARCHIVE);
++
++      sv_ratelimit_status = Cvar_Get ("sv_ratelimit_status", "15", 0);
++
++      sv_iplimit = Cvar_Get ("sv_iplimit", "3", 0);
++
++      SZ_Init (&net_message, net_message_buffer, sizeof(net_message_buffer));
++      SZ_SetName (&net_message, "Net message buffer", true);
++}
++
++/*
++==================
++SV_FinalMessage
++
++Used by SV_Shutdown to send a final message to all
++connected clients before the server goes down.  The messages are sent 
immediately,
++not just stuck on the outgoing message list, because the server is going
++to totally exit after returning from this function.
++==================
++*/
++void SV_FinalMessage (char *message, qboolean reconnect)
++{
++      int                     i;
++      client_t        *cl;
++
++      SZ_Clear (&net_message);
++      MSG_WriteByte (&net_message, svc_print);
++      MSG_WriteByte (&net_message, PRINT_HIGH);
++      MSG_WriteString (&net_message, message);
++
++      if (reconnect)
++              MSG_WriteByte (&net_message, svc_reconnect);
++      else
++              MSG_WriteByte (&net_message, svc_disconnect);
++
++      // send it twice
++      // stagger the packets to crutch operating system limited buffers
++
++      for (i=0, cl = svs.clients ; i<maxclients->value ; i++, cl++)
++
++              if (cl->state >= cs_connected)
++                      Netchan_Transmit (&cl->netchan, net_message.cursize
++                      , net_message.data);
++
++      for (i=0, cl = svs.clients ; i<maxclients->value ; i++, cl++)
++
++              if (cl->state >= cs_connected)
++                      Netchan_Transmit (&cl->netchan, net_message.cursize
++                      , net_message.data);
++}
++
++
++
++/*
++================
++SV_Shutdown
++
++Called when each game quits,
++before Sys_Quit or Sys_Error
++================
++*/
++void SV_Shutdown (char *finalmsg, qboolean reconnect)
++{
++      extern void Con_Clear_f (void);
++
++      if (svs.clients)
++              SV_FinalMessage (finalmsg, reconnect);
++
++      Master_Shutdown ();
++      SV_ShutdownGameProgs ();
++
++      // free current level
++      if (sv.demofile)
++              fclose (sv.demofile);
++      memset (&sv, 0, sizeof(sv));
++      Com_SetServerState (sv.state);
++
++      // free server static data
++      if (svs.clients)
++              Z_Free (svs.clients);
++      if (svs.client_entities)
++              Z_Free (svs.client_entities);
++      if (svs.demofile)
++              fclose (svs.demofile);
++      memset (&svs, 0, sizeof(svs));
++}
++
++qboolean IsVisible(vec3_t org1,vec3_t org2)
++{
++      trace_t trace;
++
++      trace = SV_Trace2 (org1, NULL, NULL, org2, NULL, MASK_VISIBILILITY);
++
++      if (trace.fraction != 1)
++              return false;
++      return true;
++}


_______________________________________________
Pkg-games-commits mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/pkg-games-commits

Reply via email to