reverted the massive svs.connectedclients change, now back to svs.clients and svs...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 30 Aug 2003 01:54:31 +0000 (01:54 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 30 Aug 2003 01:54:31 +0000 (01:54 +0000)
this fixes mods detecting singleplayer as multiplayer
this fixes frikbot frags updates on the scoreboard
added most of the capability necessary for botclient extension

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3428 d7cf8633-e32d-0410-b094-e92efae38249

host.c
host_cmd.c
menu.c
netconn.c
pr_cmds.c
pr_edict.c
server.h
sv_main.c
sv_phys.c
sv_user.c
todo

diff --git a/host.c b/host.c
index 69e3836..e6401a0 100644 (file)
--- a/host.c
+++ b/host.c
@@ -96,8 +96,6 @@ cvar_t temp1 = {0, "temp1","0"};
 cvar_t timestamps = {CVAR_SAVE, "timestamps", "0"};
 cvar_t timeformat = {CVAR_SAVE, "timeformat", "[%b %e %X] "};
 
-cvar_t sv_maxplayers = {0, "maxplayers", "8"};
-
 /*
 ================
 Host_EndGame
@@ -182,6 +180,8 @@ void Host_Error (const char *error, ...)
        longjmp (host_abortserver, 1);
 }
 
+mempool_t *sv_clients_mempool = NULL;
+
 void Host_ServerOptions (void)
 {
        int i, numplayers;
@@ -241,7 +241,9 @@ void Host_ServerOptions (void)
        if (numplayers > 1 && !deathmatch.integer)
                Cvar_SetValueQuick(&deathmatch, 1);
 
-       Cvar_SetValueQuick(&sv_maxplayers, numplayers);
+       svs.maxclients = numplayers;
+       sv_clients_mempool = Mem_AllocPool("server clients");
+       svs.clients = Mem_Alloc(sv_clients_mempool, sizeof(client_t) * svs.maxclients);
 }
 
 /*
@@ -283,8 +285,6 @@ void Host_InitLocal (void)
        Cvar_RegisterVariable (&timestamps);
        Cvar_RegisterVariable (&timeformat);
 
-       Cvar_RegisterVariable(&sv_maxplayers);
-
        Host_ServerOptions ();
 }
 
@@ -358,9 +358,9 @@ void SV_BroadcastPrintf(const char *fmt, ...)
        vsnprintf(string, sizeof(string), fmt,argptr);
        va_end(argptr);
 
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if ((client = svs.connectedclients[i]) && client->spawned)
+               if (client->spawned)
                {
                        MSG_WriteByte(&client->message, svc_print);
                        MSG_WriteString(&client->message, string);
@@ -436,9 +436,9 @@ void SV_DropClient(qboolean crash)
        }
 
        // send notification to all clients
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if (!(client = svs.connectedclients[i]))
+               if (!client->active)
                        continue;
                MSG_WriteByte(&client->message, svc_updatename);
                MSG_WriteByte(&client->message, host_client->number);
@@ -456,9 +456,8 @@ void SV_DropClient(qboolean crash)
        // free the client now
        if (host_client->entitydatabase4)
                EntityFrame4_FreeDatabase(host_client->entitydatabase4);
-       // remove the index reference
-       svs.connectedclients[host_client->number] = NULL;
-       Mem_Free(host_client);
+       // clear the client struct (this sets active to false)
+       memset(host_client, 0, sizeof(*host_client));
 }
 
 /*
@@ -473,7 +472,6 @@ void Host_ShutdownServer(qboolean crash)
        int i, count;
        sizebuf_t buf;
        char message[4];
-       double start;
 
        if (!sv.active)
                return;
@@ -489,32 +487,6 @@ void Host_ShutdownServer(qboolean crash)
        NetConn_Heartbeat(2);
        NetConn_Heartbeat(2);
 
-// flush any pending messages - like the score!!!
-       start = Sys_DoubleTime();
-       do
-       {
-               count = 0;
-               NetConn_ClientFrame();
-               NetConn_ServerFrame();
-               for (i = 0;i < MAX_SCOREBOARD;i++)
-               {
-                       host_client = svs.connectedclients[i];
-                       if (host_client && host_client->message.cursize)
-                       {
-                               if (NetConn_CanSendMessage(host_client->netconnection))
-                               {
-                                       NetConn_SendReliableMessage(host_client->netconnection, &host_client->message);
-                                       SZ_Clear(&host_client->message);
-                               }
-                               else
-                                       count++;
-                       }
-               }
-               if ((Sys_DoubleTime() - start) > 3.0)
-                       break;
-       }
-       while(count);
-
 // make sure all the clients know we're disconnecting
        buf.data = message;
        buf.maxsize = 4;
@@ -524,8 +496,8 @@ void Host_ShutdownServer(qboolean crash)
        if (count)
                Con_Printf("Host_ShutdownServer: NetConn_SendToAll failed for %u clients\n", count);
 
-       for (i = 0;i < MAX_SCOREBOARD;i++)
-               if ((host_client = svs.connectedclients[i]))
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+               if (host_client->active)
                        SV_DropClient(crash); // server shutdown
 
        NetConn_CloseServerPorts();
@@ -534,6 +506,7 @@ void Host_ShutdownServer(qboolean crash)
 // clear structures
 //
        memset(&sv, 0, sizeof(sv));
+       memset(svs.clients, 0, svs.maxclients*sizeof(client_t));
 }
 
 
@@ -835,9 +808,11 @@ void Host_Frame (float time)
        timecount = 0;
        timetotal = 0;
        c = 0;
-       for (i = 0;i < MAX_SCOREBOARD;i++)
-               if (svs.connectedclients[i])
+       for (i=0 ; i<svs.maxclients ; i++)
+       {
+               if (svs.clients[i].active)
                        c++;
+       }
 
        Con_Printf ("serverprofile: %2i clients %2i msec\n",  c,  m);
 }
index 6ef5247..d8a5266 100644 (file)
@@ -69,16 +69,16 @@ void Host_Status_f (void)
        else
                print = SV_ClientPrintf;
 
-       for (players = 0, j = 0;j < MAX_SCOREBOARD;j++)
-               if (svs.connectedclients[j])
+       for (players = 0, j = 0;j < svs.maxclients;j++)
+               if (svs.clients[j].active)
                        players++;
        print ("host:    %s\n", Cvar_VariableString ("hostname"));
        print ("version: %s build %s\n", gamename, buildstring);
        print ("map:     %s\n", sv.name);
-       print ("players: %i active (%i max)\n\n", players, min(sv_maxplayers.integer, MAX_SCOREBOARD));
-       for (j = 0;j < MAX_SCOREBOARD;j++)
+       print ("players: %i active (%i max)\n\n", players, svs.maxclients);
+       for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
        {
-               if (!(client = svs.connectedclients[j]))
+               if (!client->active)
                        continue;
                seconds = (int)(realtime - client->netconnection->connecttime);
                minutes = seconds / 60;
@@ -241,9 +241,9 @@ void Host_Ping_f (void)
        }
 
        SV_ClientPrintf ("Client ping times:\n");
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if (!(client = svs.connectedclients[i]))
+               if (!client->active)
                        continue;
                total = 0;
                for (j=0 ; j<NUM_PING_TIMES ; j++)
@@ -411,7 +411,7 @@ void Host_Savegame_f (void)
        if (cmd_source != src_command)
                return;
 
-       if (!sv.active)
+       if (cls.state != ca_connected || !sv.active)
        {
                Con_Printf ("Not playing a local game.\n");
                return;
@@ -423,16 +423,16 @@ void Host_Savegame_f (void)
                return;
        }
 
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0;i < svs.maxclients;i++)
        {
-               if (svs.connectedclients[i])
+               if (svs.clients[i].active)
                {
                        if (i > 0)
                        {
                                Con_Printf("Can't save multiplayer games.\n");
                                return;
                        }
-                       if (svs.connectedclients[i]->edict->v->deadflag)
+                       if (svs.clients[i].edict->v->deadflag)
                        {
                                Con_Printf("Can't savegame with a dead player\n");
                                return;
@@ -468,7 +468,7 @@ void Host_Savegame_f (void)
        Host_SavegameComment (comment);
        FS_Printf (f, "%s\n", comment);
        for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
-               FS_Printf (f, "%f\n", svs.connectedclients[0]->spawn_parms[i]);
+               FS_Printf (f, "%f\n", svs.clients[0].spawn_parms[i]);
        FS_Printf (f, "%d\n", current_skill);
        FS_Printf (f, "%s\n", sv.name);
        FS_Printf (f, "%f\n",sv.time);
@@ -649,7 +649,7 @@ void Host_PerformLoadGame(char *name)
        FS_Close (f);
 
        for (i = 0;i < NUM_SPAWN_PARMS;i++)
-               svs.connectedclients[0]->spawn_parms[i] = spawn_parms[i];
+               svs.clients[0].spawn_parms[i] = spawn_parms[i];
 
        // make sure we're connected to loopback
        if (cls.state == ca_disconnected || !(cls.state == ca_connected && cls.netcon != NULL && LHNETADDRESS_GetAddressType(&cls.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP))
@@ -768,8 +768,8 @@ void Host_Say(qboolean teamonly)
        text[j++] = '\n';
        text[j++] = 0;
 
-       for (j = 0;j < MAX_SCOREBOARD;j++)
-               if ((host_client = svs.connectedclients[j]) && host_client->spawned && (!teamplay.integer || host_client->edict->v->team == save->edict->v->team))
+       for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
+               if (host_client->spawned && (!teamplay.integer || host_client->edict->v->team == save->edict->v->team))
                        SV_ClientPrintf("%s", text);
        host_client = save;
 
@@ -845,8 +845,8 @@ void Host_Tell_f(void)
        text[j++] = 0;
 
        save = host_client;
-       for (j = 0;j < MAX_SCOREBOARD;j++)
-               if ((host_client = svs.connectedclients[j]) && host_client->spawned && !strcasecmp(host_client->name, Cmd_Argv(1)))
+       for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
+               if (host_client->spawned && !strcasecmp(host_client->name, Cmd_Argv(1)))
                        SV_ClientPrintf("%s", text);
        host_client = save;
 }
@@ -1115,9 +1115,9 @@ void Host_Spawn_f (void)
        MSG_WriteByte (&host_client->message, svc_time);
        MSG_WriteFloat (&host_client->message, sv.time);
 
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if (!(client = svs.connectedclients[i]))
+               if (!client->active)
                        continue;
                MSG_WriteByte (&host_client->message, svc_updatename);
                MSG_WriteByte (&host_client->message, i);
@@ -1214,22 +1214,22 @@ void Host_Kick_f (void)
        if (Cmd_Argc() > 2 && strcmp(Cmd_Argv(1), "#") == 0)
        {
                i = atof(Cmd_Argv(2)) - 1;
-               if (i < 0 || i >= MAX_SCOREBOARD || !(host_client = svs.connectedclients[i]))
+               if (i < 0 || i >= svs.maxclients || !(host_client = svs.clients + i)->active)
                        return;
                byNumber = true;
        }
        else
        {
-               for (i = 0;i < MAX_SCOREBOARD;i++)
+               for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                {
-                       if (!(host_client = svs.connectedclients[i]))
+                       if (!host_client->active)
                                continue;
                        if (strcasecmp(host_client->name, Cmd_Argv(1)) == 0)
                                break;
                }
        }
 
-       if (i < MAX_SCOREBOARD)
+       if (i < svs.maxclients)
        {
                if (cmd_source == src_command)
                {
@@ -1659,6 +1659,36 @@ void Host_PerformSpawnServerAndLoadGame(void)
                Cbuf_AddText ("connect local");
 }
 
+static void MaxPlayers_f(void)
+{
+       int n;
+
+       if (Cmd_Argc() != 2)
+       {
+               Con_Printf("\"maxplayers\" is \"%u\"\n", svs.maxclients);
+               return;
+       }
+
+       if (sv.active)
+       {
+               Con_Printf("maxplayers can not be changed while a server is running.\n");
+               return;
+       }
+
+       n = atoi(Cmd_Argv(1));
+       n = bound(1, n, MAX_SCOREBOARD);
+       Con_Printf ("\"maxplayers\" set to \"%u\"\n", n);
+
+       if (svs.clients)
+               Mem_Free(svs.clients);
+       svs.maxclients = n;
+       svs.clients = Mem_Alloc(sv_clients_mempool, sizeof(client_t) * svs.maxclients);
+       if (n == 1)
+               Cvar_Set ("deathmatch", "0");
+       else
+               Cvar_Set ("deathmatch", "1");
+}
+
 //=============================================================================
 
 /*
@@ -1723,6 +1753,7 @@ void Host_InitCommands (void)
        Cmd_AddCommand ("prespawn", Host_PreSpawn_f);
        Cmd_AddCommand ("spawn", Host_Spawn_f);
        Cmd_AddCommand ("begin", Host_Begin_f);
+       Cmd_AddCommand ("maxplayers", MaxPlayers_f);
 
        Cvar_RegisterVariable(&sv_cheats);
 }
diff --git a/menu.c b/menu.c
index f01dda9..1ad5cf0 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -2970,7 +2970,7 @@ void M_Menu_GameOptions_f (void)
        m_state = m_gameoptions;
        m_entersound = true;
        if (maxplayers == 0)
-               maxplayers = sv_maxplayers.integer;
+               maxplayers = svs.maxclients;
        if (maxplayers < 2)
                maxplayers = min(8, MAX_SCOREBOARD);
 }
index 08ab2a0..90d6d40 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -621,15 +621,8 @@ void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peer
 
 int NetConn_IsLocalGame(void)
 {
-       int i;
-       if (cls.state == ca_connected && sv.active/* && LHNETADDRESS_GetAddressType(cl.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP*/)
-       {
-               // make sure there are no other connected clients
-               for (i = 1;i < MAX_SCOREBOARD;i++)
-                       if (svs.connectedclients[i])
-                               return false;
+       if (cls.state == ca_connected && sv.active && cl.maxclients == 1)
                return true;
-       }
        return false;
 }
 
@@ -987,7 +980,7 @@ static void NetConn_BuildChallengeString(char *buffer, int bufferlength)
 extern void SV_ConnectClient(int clientnum, netconn_t *netconnection);
 int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, lhnetaddress_t *peeraddress)
 {
-       int i, n, ret, clientnum, responselength, best, clientcount;
+       int i, n, ret, clientnum, responselength, best;
        double besttime;
        client_t *client;
        netconn_t *conn;
@@ -1057,10 +1050,10 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                                else
                                                {
                                                        // see if this is a duplicate connection request
-                                                       for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-                                                               if ((client = svs.connectedclients[clientnum]) && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
+                                                       for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+                                                               if (client->netconnection && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
                                                                        break;
-                                                       if (clientnum < MAX_SCOREBOARD)
+                                                       if (clientnum < svs.maxclients)
                                                        {
                                                                // duplicate connection request
                                                                if (realtime - client->netconnection->connecttime < 2.0)
@@ -1081,39 +1074,27 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                                        else
                                                        {
                                                                // this is a new client, find a slot
-                                                               for (clientcount = 0, clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-                                                                       if (svs.connectedclients[clientnum])
-                                                                               clientcount++;
-                                                               for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-                                                                       if (!svs.connectedclients[clientnum])
+                                                               for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+                                                                       if (!client->active)
                                                                                break;
-                                                               if (clientcount < max(1, sv_maxplayers.integer) && clientnum < MAX_SCOREBOARD)
+                                                               if (clientnum < svs.maxclients)
                                                                {
-                                                                       // allocate and prepare the client struct
-                                                                       if ((client = Mem_Alloc(sv_clients_mempool, sizeof(client_t))))
+                                                                       // prepare the client struct
+                                                                       if ((client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool)))
                                                                        {
-                                                                               if ((client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool)))
+                                                                               if ((conn = NetConn_Open(mysocket, peeraddress)))
                                                                                {
-                                                                                       if ((conn = NetConn_Open(mysocket, peeraddress)))
-                                                                                       {
-                                                                                               // allocated connection
-                                                                                               LHNETADDRESS_ToString(peeraddress, conn->address, sizeof(conn->address), true);
-                                                                                               if (developer.integer)
-                                                                                                       Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address);
-                                                                                               NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
-                                                                                               // now set up the client struct
-                                                                                               svs.connectedclients[clientnum] = client;
-                                                                                               SV_ConnectClient(clientnum, conn);
-                                                                                               NetConn_Heartbeat(1);
-                                                                                       }
-                                                                                       else
-                                                                                       {
-                                                                                               EntityFrame4_FreeDatabase(client->entitydatabase4);
-                                                                                               Mem_Free(client);
-                                                                                       }
+                                                                                       // allocated connection
+                                                                                       LHNETADDRESS_ToString(peeraddress, conn->address, sizeof(conn->address), true);
+                                                                                       if (developer.integer)
+                                                                                               Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address);
+                                                                                       NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
+                                                                                       // now set up the client
+                                                                                       SV_ConnectClient(clientnum, conn);
+                                                                                       NetConn_Heartbeat(1);
                                                                                }
                                                                                else
-                                                                                       Mem_Free(client);
+                                                                                       EntityFrame4_FreeDatabase(client->entitydatabase4);
                                                                        }
                                                                }
                                                                else
@@ -1135,13 +1116,13 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                // If there was a challenge in the getinfo message
                                if (length > 8 && string[7] == ' ')
                                        challenge = string + 8;
-                               for (i = 0, n = 0;i < MAX_SCOREBOARD;i++)
-                                       if (svs.connectedclients[i])
+                               for (i = 0, n = 0;i < svs.maxclients;i++)
+                                       if (svs.clients[i].active)
                                                n++;
                                responselength = snprintf(response, sizeof(response), "\377\377\377\377infoResponse\x0A"
                                                        "\\gamename\\%s\\modname\\%s\\sv_maxclients\\%d"
                                                        "\\clients\\%d\\mapname\\%s\\hostname\\%s\\protocol\\%d%s%s",
-                                                       gamename, com_modname, min(sv_maxplayers.integer, MAX_SCOREBOARD), n,
+                                                       gamename, com_modname, svs.maxclients, n,
                                                        sv.name, hostname.string, NET_PROTOCOL_VERSION, challenge ? "\\challenge\\" : "", challenge ? challenge : "");
                                // does it fit in the buffer?
                                if (responselength < (int)sizeof(response))
@@ -1201,10 +1182,10 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                                else
                                                {
                                                        // see if this is a duplicate connection request
-                                                       for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-                                                               if ((client = svs.connectedclients[clientnum]) && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
+                                                       for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+                                                               if (client->netconnection && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
                                                                        break;
-                                                       if (clientnum < MAX_SCOREBOARD)
+                                                       if (clientnum < svs.maxclients)
                                                        {
                                                                // duplicate connection request
                                                                if (realtime - client->netconnection->connecttime < 2.0)
@@ -1233,11 +1214,10 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                                        else
                                                        {
                                                                // this is a new client, find a slot
-                                                               for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-                                                                       if (!(client = svs.connectedclients[clientnum]))
+                                                               for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+                                                                       if (!client->active)
                                                                                break;
-                                                               // WARNING: this is broken code
-                                                               if (clientnum < MAX_SCOREBOARD && (client->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL)
+                                                               if (clientnum < svs.maxclients && (client->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL)
                                                                {
                                                                        // connect to the client
                                                                        // everything is allocated, just fill in the details
@@ -1292,7 +1272,7 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                                MSG_WriteString(&net_message, hostname.string);
                                                MSG_WriteString(&net_message, sv.name);
                                                MSG_WriteByte(&net_message, net_activeconnections);
-                                               MSG_WriteByte(&net_message, min(sv_maxplayers.integer, MAX_SCOREBOARD));
+                                               MSG_WriteByte(&net_message, svs.maxclients);
                                                MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
                                                *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
                                                NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
@@ -1367,25 +1347,14 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                        }
                }
 #endif
-               for (i = 0;i < MAX_SCOREBOARD;i++)
+               for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                {
-                       if ((host_client = svs.connectedclients[i]))
+                       if (host_client->netconnection && host_client->netconnection->mysocket == mysocket && !LHNETADDRESS_Compare(&host_client->netconnection->peeraddress, peeraddress))
                        {
-                               if (host_client->netconnection)
-                               {
-                                       if (host_client->netconnection->mysocket == mysocket && !LHNETADDRESS_Compare(&host_client->netconnection->peeraddress, peeraddress))
-                                       {
-                                               sv_player = host_client->edict;
-                                               if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length)) == 2)
-                                                       SV_ReadClientMessage();
-                                               return ret;
-                                       }
-                               }
-                               else
-                               {
-                                       Con_Printf("Removing client with no netconnection!\n");
-                                       SV_DropClient(true);
-                               }
+                               sv_player = host_client->edict;
+                               if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length)) == 2)
+                                       SV_ReadClientMessage();
+                               return ret;
                        }
                }
        }
@@ -1401,9 +1370,9 @@ void NetConn_ServerFrame(void)
        for (i = 0;i < sv_numsockets;i++)
                while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
                        NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
-               if ((host_client = svs.connectedclients[i]) && realtime > host_client->netconnection->timeout)
+               if (host_client->netconnection && realtime > host_client->netconnection->timeout)
                {
                        Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
                        sv_player = host_client->edict;
@@ -1478,7 +1447,7 @@ void NetConn_Heartbeat(int priority)
 
        // make advertising optional and don't advertise singleplayer games, and
        // only send a heartbeat as often as the admin wants
-       if (sv.active && sv_public.integer && (!cl.islocalgame || sv_maxplayers.integer >= 2) && (priority > 1 || realtime > nextheartbeattime))
+       if (sv.active && sv_public.integer && svs.maxclients >= 2 && (priority > 1 || realtime > nextheartbeattime))
        {
                nextheartbeattime = realtime + sv_heartbeatperiod.value;
                for (masternum = 0;sv_masters[masternum].name;masternum++)
@@ -1505,9 +1474,9 @@ int NetConn_SendToAll(sizebuf_t *data, double blocktime)
                count = 0;
                NetConn_ClientFrame();
                NetConn_ServerFrame();
-               for (i = 0;i < MAX_SCOREBOARD;i++)
+               for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                {
-                       if ((host_client = svs.connectedclients[i]))
+                       if (host_client->netconnection)
                        {
                                if (NetConn_CanSendMessage(host_client->netconnection))
                                {
index b45bdcc..3ee8a18 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -372,13 +372,15 @@ void PF_sprint (void)
        entnum = G_EDICTNUM(OFS_PARM0);
        s = PF_VarString(1);
 
-       if (entnum < 1 || entnum > MAX_SCOREBOARD || !svs.connectedclients[entnum-1])
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
                Con_Printf ("tried to sprint to a non-client\n");
                return;
        }
 
-       client = svs.connectedclients[entnum-1];
+       client = svs.clients + entnum-1;
+       if (!client->netconnection)
+               return;
        MSG_WriteChar(&client->message,svc_print);
        MSG_WriteString(&client->message, s );
 }
@@ -402,13 +404,15 @@ void PF_centerprint (void)
        entnum = G_EDICTNUM(OFS_PARM0);
        s = PF_VarString(1);
 
-       if (entnum < 1 || entnum > MAX_SCOREBOARD || !svs.connectedclients[entnum-1])
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
                Con_Printf ("tried to sprint to a non-client\n");
                return;
        }
 
-       client = svs.connectedclients[entnum-1];
+       client = svs.clients + entnum-1;
+       if (!client->netconnection)
+               return;
        MSG_WriteChar(&client->message,svc_centerprint);
        MSG_WriteString(&client->message, s );
 }
@@ -829,8 +833,8 @@ int PF_newcheckclient (int check)
 
 // cycle to the next one
 
-       check = bound(1, check, MAX_SCOREBOARD);
-       if (check == MAX_SCOREBOARD)
+       check = bound(1, check, svs.maxclients);
+       if (check == svs.maxclients)
                i = 1;
        else
                i = check + 1;
@@ -840,7 +844,7 @@ int PF_newcheckclient (int check)
                // count the cost
                pr_xfunction->builtinsprofile++;
                // wrap around
-               if (i == MAX_SCOREBOARD+1)
+               if (i == svs.maxclients+1)
                        i = 1;
                // look up the client's edict
                ent = EDICT_NUM(i);
@@ -930,12 +934,15 @@ void PF_stuffcmd (void)
        client_t        *old;
 
        entnum = G_EDICTNUM(OFS_PARM0);
-       if (entnum < 1 || entnum > MAX_SCOREBOARD)
-               Host_Error ("Parm 0 not a client");
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+       {
+               Con_Printf("Can't stuffcmd to a non-client");
+               return;
+       }
        str = G_STRING(OFS_PARM1);
 
        old = host_client;
-       if ((host_client = svs.connectedclients[entnum-1]))
+       if ((host_client = svs.clients + entnum-1) && host_client->netconnection)
                Host_ClientCommands ("%s", str);
        host_client = old;
 }
@@ -951,10 +958,7 @@ localcmd (string)
 */
 void PF_localcmd (void)
 {
-       char    *str;
-
-       str = G_STRING(OFS_PARM0);
-       Cbuf_AddText (str);
+       Cbuf_AddText(G_STRING(OFS_PARM0));
 }
 
 /*
@@ -966,11 +970,7 @@ float cvar (string)
 */
 void PF_cvar (void)
 {
-       char    *str;
-
-       str = G_STRING(OFS_PARM0);
-
-       G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
+       G_FLOAT(OFS_RETURN) = Cvar_VariableValue(G_STRING(OFS_PARM0));
 }
 
 /*
@@ -982,12 +982,7 @@ float cvar (string)
 */
 void PF_cvar_set (void)
 {
-       char    *var, *val;
-
-       var = G_STRING(OFS_PARM0);
-       val = G_STRING(OFS_PARM1);
-
-       Cvar_Set (var, val);
+       Cvar_Set(G_STRING(OFS_PARM0), G_STRING(OFS_PARM1));
 }
 
 /*
@@ -1116,7 +1111,7 @@ void PF_Remove (void)
        ed = G_EDICT(OFS_PARM0);
        if (ed == sv.edicts)
                Host_Error("remove: tried to remove world\n");
-       if (NUM_FOR_EDICT(ed) <= MAX_SCOREBOARD)
+       if (NUM_FOR_EDICT(ed) <= svs.maxclients)
                Host_Error("remove: tried to remove a client\n");
        ED_Free (ed);
 }
@@ -1440,9 +1435,9 @@ void PF_lightstyle (void)
        if (sv.state != ss_active)
                return;
 
-       for (j = 0;j < MAX_SCOREBOARD;j++)
+       for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
        {
-               if ((client = svs.connectedclients[j]))
+               if (client->netconnection)
                {
                        MSG_WriteChar (&client->message, svc_lightstyle);
                        MSG_WriteChar (&client->message,style);
@@ -1729,9 +1724,9 @@ sizebuf_t *WriteDest (void)
        case MSG_ONE:
                ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
                entnum = NUM_FOR_EDICT(ent);
-               if (entnum < 1 || entnum > MAX_SCOREBOARD || svs.connectedclients[entnum-1] == NULL)
-                       Host_Error("WriteDest: not a client");
-               return &svs.connectedclients[entnum-1]->message;
+               if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+                       Con_Printf("WriteDest: tried to write to non-client\n");
+               return &svs.clients[entnum-1].message;
 
        case MSG_ALL:
                return &sv.reliable_datagram;
@@ -1841,11 +1836,14 @@ void PF_setspawnparms (void)
 
        ent = G_EDICT(OFS_PARM0);
        i = NUM_FOR_EDICT(ent);
-       if (i < 1 || i > MAX_SCOREBOARD || !svs.connectedclients[i-1])
-               Host_Error ("Entity is not a client");
+       if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
+       {
+               Con_Printf("tried to setspawnparms on a non-client\n");
+               return;
+       }
 
        // copy spawn parms out of the client_t
-       client = svs.connectedclients[i-1];
+       client = svs.clients + i-1;
        for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
                (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
 }
@@ -2084,12 +2082,13 @@ void PF_setcolor (void)
        entnum = G_EDICTNUM(OFS_PARM0);
        i = G_FLOAT(OFS_PARM1);
 
-       if (entnum < 1 || entnum > MAX_SCOREBOARD || !(client = svs.connectedclients[entnum-1]))
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
                Con_Printf ("tried to setcolor a non-client\n");
                return;
        }
 
+       client = svs.clients + entnum-1;
        if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
                val->_float = i;
        client->colors = i;
@@ -2887,11 +2886,14 @@ void PF_clientcommand (void)
 
        //find client for this entity
        i = (NUM_FOR_EDICT(G_EDICT(OFS_PARM0)) - 1);
-       if (i < 0 || i >= MAX_SCOREBOARD || !svs.connectedclients[i])
-               Host_Error("PF_clientcommand: entity is not a client");
+       if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
+       {
+               Con_Printf("PF_clientcommand: entity is not a client");
+               return;
+       }
 
        temp_client = host_client;
-       host_client = svs.connectedclients[i];
+       host_client = svs.clients + i;
        Cmd_ExecuteString (G_STRING(OFS_PARM1), src_client);
        host_client = temp_client;
 }
index 3c3b31e..445e044 100644 (file)
@@ -199,11 +199,11 @@ void ED_ClearEdict (edict_t *e)
        e->e->free = false;
        // LordHavoc: for consistency set these here
        num = NUM_FOR_EDICT(e) - 1;
-       if (num >= 0 && num < MAX_SCOREBOARD && svs.connectedclients[num])
+       if (num >= 0 && num < svs.maxclients)
        {
                e->v->colormap = num + 1;
-               e->v->team = (svs.connectedclients[num]->colors & 15) + 1;
-               e->v->netname = PR_SetString(svs.connectedclients[num]->name);
+               e->v->team = (svs.clients[num].colors & 15) + 1;
+               e->v->netname = PR_SetString(svs.clients[num].name);
        }
 }
 
@@ -223,7 +223,7 @@ edict_t *ED_Alloc (void)
        int                     i;
        edict_t         *e;
 
-       for (i = MAX_SCOREBOARD + 1;i < sv.num_edicts;i++)
+       for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
        {
                e = EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
index 490dd52..fdc94cd 100644 (file)
--- a/server.h
+++ b/server.h
@@ -24,8 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 typedef struct
 {
-       // NULL pointers are non-existent clients
-       struct client_s *connectedclients[MAX_SCOREBOARD];
+       // number of svs.clients slots (updated by maxplayers command)
+       int maxclients;
+       // client slots
+       struct client_s *clients;
        // episode completion information
        int serverflags;
        // cleared when at SV_SpawnServer
@@ -99,6 +101,8 @@ typedef struct
 
 typedef struct client_s
 {
+       // false = empty client slot
+       qboolean active;
        // false = don't send datagrams
        qboolean spawned;
        // has been told to go to another level
@@ -107,7 +111,7 @@ typedef struct client_s
        qboolean sendsignon;
        // remove this client immediately
        qboolean deadsocket;
-       // index of this client in the svs.connectedclients pointer array
+       // index of this client in the svs.clients array
        int number;
 
        // reliable messages must be sent periodically
@@ -247,7 +251,6 @@ extern cvar_t sv_idealpitchscale;
 extern cvar_t sv_aim;
 extern cvar_t sv_stepheight;
 extern cvar_t sv_jumpstep;
-extern cvar_t sv_maxplayers;
 
 extern mempool_t *sv_clients_mempool;
 extern mempool_t *sv_edicts_mempool;
index ada5adb..8810480 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -32,7 +32,6 @@ server_static_t svs;
 static char localmodels[MAX_MODELS][5];                        // inline model names for precache
 
 mempool_t *sv_edicts_mempool = NULL;
-mempool_t *sv_clients_mempool = NULL;
 
 //============================================================================
 
@@ -71,7 +70,6 @@ void SV_Init (void)
                sprintf (localmodels[i], "*%i", i);
 
        sv_edicts_mempool = Mem_AllocPool("server edicts");
-       sv_clients_mempool = Mem_AllocPool("server clients");
 }
 
 /*
@@ -261,7 +259,7 @@ void SV_SendServerinfo (client_t *client)
 
        MSG_WriteByte (&client->message, svc_serverinfo);
        MSG_WriteLong (&client->message, DPPROTOCOL_VERSION4);
-       MSG_WriteByte (&client->message, MAX_SCOREBOARD);
+       MSG_WriteByte (&client->message, svs.maxclients);
 
        if (!coop.integer && deathmatch.integer)
                MSG_WriteByte (&client->message, GAME_DEATHMATCH);
@@ -308,12 +306,13 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
        int                             i;
        float                   spawn_parms[NUM_SPAWN_PARMS];
 
-       client = svs.connectedclients[clientnum];
+       client = svs.clients + clientnum;
 
 // set up the client_t
        if (sv.loadgame)
                memcpy (spawn_parms, client->spawn_parms, sizeof(spawn_parms));
        memset (client, 0, sizeof(*client));
+       client->active = true;
        client->netconnection = netconnection;
 
        Con_DPrintf("Client %s connected\n", client->netconnection->address);
@@ -822,7 +821,7 @@ void SV_PrepareEntitiesForSending(void)
                // we can omit invisible entities with no effects that are not clients
                // LordHavoc: this could kill tags attached to an invisible entity, I
                // just hope we never have to support that case
-               if (cs.number > MAX_SCOREBOARD && ((cs.effects & EF_NODRAW) || (!cs.modelindex && !cs.specialvisibilityradius)))
+               if (cs.number > svs.maxclients && ((cs.effects & EF_NODRAW) || (!cs.modelindex && !cs.specialvisibilityradius)))
                        continue;
                sendentitiesindex[e] = sendentities + numsendentities;
                sendentities[numsendentities++] = cs;
@@ -1345,71 +1344,67 @@ void SV_UpdateToReliableMessages (void)
        char *s;
 
 // check for changes to be sent over the reliable streams
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
-               // only update the client fields if they've spawned in
-               if ((host_client = svs.connectedclients[i]) && host_client->spawned)
+               // update the host_client fields we care about according to the entity fields
+               sv_player = host_client->edict;
+               s = PR_GetString(sv_player->v->netname);
+               if (s != host_client->name)
                {
-                       // update the host_client fields we care about according to the entity fields
-                       sv_player = host_client->edict;
-                       s = PR_GetString(sv_player->v->netname);
-                       if (s != host_client->name)
-                       {
-                               if (s == NULL)
-                                       s = "";
-                               // point the string back at host_client->name to keep it safe
-                               strncpy(host_client->name, s, sizeof(host_client->name) - 1);
-                               sv_player->v->netname = PR_SetString(host_client->name);
-                       }
-                       if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)) && host_client->colors != val->_float)
-                               host_client->colors = val->_float;
-                       host_client->frags = sv_player->v->frags;
-                       if (gamemode == GAME_NEHAHRA)
-                               if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)) && host_client->pmodel != val->_float)
-                                       host_client->pmodel = val->_float;
-
-                       // if the fields changed, send messages about the changes
-                       if (strcmp(host_client->old_name, host_client->name))
+                       if (s == NULL)
+                               s = "";
+                       // point the string back at host_client->name to keep it safe
+                       strncpy(host_client->name, s, sizeof(host_client->name) - 1);
+                       sv_player->v->netname = PR_SetString(host_client->name);
+               }
+               if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)) && host_client->colors != val->_float)
+                       host_client->colors = val->_float;
+               host_client->frags = sv_player->v->frags;
+               if (gamemode == GAME_NEHAHRA)
+                       if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)) && host_client->pmodel != val->_float)
+                               host_client->pmodel = val->_float;
+
+               // if the fields changed, send messages about the changes
+               if (strcmp(host_client->old_name, host_client->name))
+               {
+                       strcpy(host_client->old_name, host_client->name);
+                       for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
                        {
-                               strcpy(host_client->old_name, host_client->name);
-                               for (j = 0;j < MAX_SCOREBOARD;j++)
-                               {
-                                       if (!(client = svs.connectedclients[j]) || !client->spawned)
-                                               continue;
-                                       MSG_WriteByte (&client->message, svc_updatename);
-                                       MSG_WriteByte (&client->message, i);
-                                       MSG_WriteString (&client->message, host_client->name);
-                               }
+                               if (!client->spawned || !client->netconnection)
+                                       continue;
+                               MSG_WriteByte (&client->message, svc_updatename);
+                               MSG_WriteByte (&client->message, i);
+                               MSG_WriteString (&client->message, host_client->name);
                        }
-                       if (host_client->old_colors != host_client->colors)
+               }
+               if (host_client->old_colors != host_client->colors)
+               {
+                       host_client->old_colors = host_client->colors;
+                       for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
                        {
-                               host_client->old_colors = host_client->colors;
-                               for (j = 0;j < MAX_SCOREBOARD;j++)
-                               {
-                                       if (!(client = svs.connectedclients[j]) || !client->spawned)
-                                               continue;
-                                       MSG_WriteByte (&client->message, svc_updatecolors);
-                                       MSG_WriteByte (&client->message, i);
-                                       MSG_WriteByte (&client->message, host_client->colors);
-                               }
+                               if (!client->spawned || !client->netconnection)
+                                       continue;
+                               MSG_WriteByte (&client->message, svc_updatecolors);
+                               MSG_WriteByte (&client->message, i);
+                               MSG_WriteByte (&client->message, host_client->colors);
                        }
-                       if (host_client->old_frags != host_client->frags)
+               }
+               if (host_client->old_frags != host_client->frags)
+               {
+                       host_client->old_frags = host_client->frags;
+                       for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
                        {
-                               host_client->old_frags = host_client->frags;
-                               for (j = 0;j < MAX_SCOREBOARD;j++)
-                               {
-                                       if (!(client = svs.connectedclients[j]) || !client->spawned)
-                                               continue;
-                                       MSG_WriteByte (&client->message, svc_updatefrags);
-                                       MSG_WriteByte (&client->message, i);
-                                       MSG_WriteShort (&client->message, host_client->frags);
-                               }
+                               if (!client->spawned || !client->netconnection)
+                                       continue;
+                               MSG_WriteByte (&client->message, svc_updatefrags);
+                               MSG_WriteByte (&client->message, i);
+                               MSG_WriteShort (&client->message, host_client->frags);
                        }
                }
        }
 
-       for (j = 0;j < MAX_SCOREBOARD;j++)
-               if ((client = svs.connectedclients[j]))
+       for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
+               if (client->netconnection)
                        SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
 
        SZ_Clear (&sv.reliable_datagram);
@@ -1453,12 +1448,17 @@ void SV_SendClientMessages (void)
        SV_UpdateToReliableMessages();
 
 // build individual updates
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
-               if (!(host_client = svs.connectedclients[i]))
+               if (!host_client->active)
                        continue;
+               if (!host_client->netconnection)
+               {
+                       SZ_Clear(&host_client->message);
+                       continue;
+               }
 
-               if (host_client->deadsocket || !host_client->netconnection || host_client->message.overflowed)
+               if (host_client->deadsocket || host_client->message.overflowed)
                {
                        SV_DropClient (true);   // if the message couldn't send, kick off
                        continue;
@@ -1565,7 +1565,7 @@ void SV_CreateBaseline (void)
 
                if (svent->e->free)
                        continue;
-               if (entnum > MAX_SCOREBOARD && !svent->v->modelindex)
+               if (entnum > svs.maxclients && !svent->v->modelindex)
                        continue;
 
                // create entity baseline
@@ -1573,7 +1573,7 @@ void SV_CreateBaseline (void)
                VectorCopy (svent->v->angles, svent->e->baseline.angles);
                svent->e->baseline.frame = svent->v->frame;
                svent->e->baseline.skin = svent->v->skin;
-               if (entnum > 0 && entnum <= MAX_SCOREBOARD)
+               if (entnum > 0 && entnum <= svs.maxclients)
                {
                        svent->e->baseline.colormap = entnum;
                        svent->e->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
@@ -1656,9 +1656,9 @@ void SV_SaveSpawnparms (void)
 
        svs.serverflags = pr_global_struct->serverflags;
 
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
-               if (!(host_client = svs.connectedclients[i]))
+               if (!host_client->active)
                        continue;
 
        // call the progs to get default spawn parms for the new client
@@ -1766,7 +1766,7 @@ void SV_SpawnServer (const char *server)
 
 // allocate server memory
        // start out with just enough room for clients and a reasonable estimate of entities
-       sv.max_edicts = max(MAX_SCOREBOARD + 1, 512);
+       sv.max_edicts = max(svs.maxclients + 1, 512);
        sv.max_edicts = min(sv.max_edicts, MAX_EDICTS);
 
        // clear the edict memory pool
@@ -1799,7 +1799,7 @@ void SV_SpawnServer (const char *server)
        sv.signon.data = sv.signon_buf;
 
 // leave slots at start for clients only
-       sv.num_edicts = MAX_SCOREBOARD+1;
+       sv.num_edicts = svs.maxclients+1;
 
        sv.state = ss_loading;
        sv.paused = false;
@@ -1892,8 +1892,8 @@ void SV_SpawnServer (const char *server)
 #endif
 
 // send serverinfo to all connected clients
-       for (i = 0;i < MAX_SCOREBOARD;i++)
-               if ((host_client = svs.connectedclients[i]))
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+               if (host_client->netconnection)
                        SV_SendServerinfo(host_client);
 
        Con_DPrintf ("Server spawned.\n");
index 6cfa187..83ba354 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -1314,9 +1314,9 @@ void SV_Physics (void)
                if (pr_global_struct->force_retouch)
                        SV_LinkEdict (ent, true);       // force retouch even for stationary
 
-               if (i > 0 && i <= MAX_SCOREBOARD)
+               if (i > 0 && i <= svs.maxclients)
                {
-                       if (!svs.connectedclients[i-1] || !svs.connectedclients[i-1]->spawned)
+                       if (!svs.clients[i-1].spawned)
                                continue;
                        // connected slot
                        // call standard client pre-think
@@ -1349,7 +1349,7 @@ void SV_Physics (void)
                                VectorMA(ent->v->angles, sv.frametime, ent->v->avelocity, ent->v->angles);
                        }
                        // relink normal entities here, players always get relinked so don't relink twice
-                       if (!(i > 0 && i <= MAX_SCOREBOARD))
+                       if (!(i > 0 && i <= svs.maxclients))
                                SV_LinkEdict(ent, false);
                        break;
                case MOVETYPE_STEP:
@@ -1372,7 +1372,7 @@ void SV_Physics (void)
                        SV_Physics_Toss (ent);
                        break;
                case MOVETYPE_FLY:
-                       if (i > 0 && i <= MAX_SCOREBOARD)
+                       if (i > 0 && i <= svs.maxclients)
                        {
                                if (SV_RunThink (ent))
                                {
@@ -1388,7 +1388,7 @@ void SV_Physics (void)
                        break;
                }
 
-               if (i > 0 && i <= MAX_SCOREBOARD && !ent->e->free)
+               if (i > 0 && i <= svs.maxclients && !ent->e->free)
                {
                        SV_CheckVelocity (ent);
 
index 05624d8..a0be108 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -665,14 +665,14 @@ SV_ReadClientMessage
 extern void SV_SendServerinfo(client_t *client);
 void SV_ReadClientMessage(void)
 {
-       int cmd, clientnum = host_client->number;
+       int cmd;
        char *s;
 
        //MSG_BeginReading ();
 
        for(;;)
        {
-               if (!(host_client = svs.connectedclients[clientnum]))
+               if (!host_client->active)
                {
                        // a command caused an error
                        SV_DropClient (false);
@@ -761,13 +761,11 @@ void SV_RunClients (void)
 {
        int i;
 
-       for (i = 0;i < MAX_SCOREBOARD;i++)
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
-               if (!(host_client = svs.connectedclients[i]))
+               if (!host_client->active)
                        continue;
 
-               sv_player = host_client->edict;
-
                if (!host_client->spawned)
                {
                        // clear client movement until a new packet is received
@@ -777,6 +775,8 @@ void SV_RunClients (void)
 
                if (sv.frametime)
                {
+                       sv_player = host_client->edict;
+
                        // LordHavoc: QuakeC replacement for SV_ClientThink (player movement)
                        if (SV_PlayerPhysicsQC)
                        {
diff --git a/todo b/todo
index fcbb4a4..df45c3f 100644 (file)
--- a/todo
+++ b/todo
@@ -4,6 +4,7 @@
 -n darkplaces: make LHNET_Read print out the names of read errors (yummyluv)
 -n darkplaces: revert noclip movement to match nq for compatibility with mods that trap movement as input (MauveBib)
 -n dpmod: make grapple off-hand (joe hill)
+0 darkplaces: clean up the DrawQ_ blendfunc handling, instead of taking DRAWFLAG_ADDITIVE they should take blendfunc values (Black)
 0 darkplaces: ability to disable fopen builtin access to read /, read data/, write data/, or disable fopen builtin entirely
 0 darkplaces: add DP_GFX_QUAKE3MODELTAGS, DP_GFX_SKINFILES, and any other new extensions to the wiki
 0 darkplaces: add DP_LITSUPPORT extension