From fc7324485ef03e1fc1bd4c05d82e64a1a6e887fc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 4 Mar 2003 03:35:12 +0000 Subject: [PATCH] implement SV_AllocClient and SV_FreeClient builtins --- qw/include/server.h | 2 ++ qw/source/sv_main.c | 20 +++++++++----------- qw/source/sv_pr_cmds.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/qw/include/server.h b/qw/include/server.h index f9173a2e2..c8e4efefd 100644 --- a/qw/include/server.h +++ b/qw/include/server.h @@ -451,6 +451,8 @@ extern struct clip_hull_s *pf_hull_list[]; // sv_main.c // +client_t *SV_AllocClient (int spectator, int server); + void SV_SavePenaltyFilter (client_t *cl, filtertype_t type, double pentime); double SV_RestorePenaltyFilter (client_t *cl, filtertype_t type); diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index c8da8376b..d7058559d 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -721,11 +721,12 @@ SVC_GetChallenge (void) svs.challenges[i].challenge, extended); } -static client_t * -SVC_AllocClient (int spectator) +client_t * +SV_AllocClient (int spectator, int server) { client_t *cl; int i, clients, spectators, free; + static int userid; // count up the clients and spectators clients = 0; @@ -741,13 +742,16 @@ SVC_AllocClient (int spectator) } // if at server limits, refuse connection - if (!free || (spectator && spectators >= maxspectators->int_val) - || (!spectator && clients >= maxclients->int_val)) { + if (!free || + (!server && ((spectator && spectators >= maxspectators->int_val) + || (!spectator && clients >= maxclients->int_val)))) { return 0; } // find a client slot for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) { if (cl->state == cs_free) { + svs.num_clients++; + cl->userid = userid++; // so every client gets a unique id return cl; } } @@ -769,7 +773,6 @@ SVC_DirectConnect (void) client_t temp; edict_t *ent; int challenge, edictnum, qport, version, i; - static int userid; netadr_t adr; qboolean spectator; @@ -862,13 +865,10 @@ SVC_DirectConnect (void) } adr = net_from; - userid++; // so every client gets a unique id newcl = &temp; memset (newcl, 0, sizeof (client_t)); - newcl->userid = userid; - newcl->userinfo = userinfo; // if there is already a slot for this ip, drop it @@ -880,7 +880,6 @@ SVC_DirectConnect (void) || adr.port == cl->netchan.remote_address.port)) { if (cl->state == cs_connected) { SV_Printf ("%s:dup connect\n", NET_AdrToString (adr)); - userid--; return; } @@ -889,7 +888,7 @@ SVC_DirectConnect (void) break; } } - if (!(newcl = SVC_AllocClient (spectator))) { + if (!(newcl = SV_AllocClient (spectator, 0))) { SV_Printf ("%s:full connect\n", NET_AdrToString (adr)); Netchan_OutOfBandPrint (adr, "%c\nserver is full\n\n", A2C_PRINT); return; @@ -913,7 +912,6 @@ SVC_DirectConnect (void) newcl->state = cs_connected; newcl->prespawned = false; newcl->spawned = false; - svs.num_clients++; newcl->datagram.allowoverflow = true; newcl->datagram.data = newcl->datagram_buf; diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index 5726ef069..630c885d0 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -50,6 +50,7 @@ static __attribute__ ((unused)) const char rcsid[] = #include "crudefile.h" #include "server.h" #include "sv_demo.h" +#include "sv_gib.h" #include "sv_pr_cmds.h" #include "sv_progs.h" #include "world.h" @@ -1718,6 +1719,42 @@ PF_sv_cvar (progs_t *pr) } } +static void +PF_SV_AllocClient (progs_t *pr) +{ + client_t *cl = SV_AllocClient (0, 1); + edict_t *ent; + + if (!cl) { + R_var (pr, entity) = 0; + return; + } + memset (cl, 0, sizeof (*cl)); + cl->userinfo = Info_ParseString ("", 1023, !sv_highchars->int_val); + //XXX netchan? Netchan_Setup (&newcl->netchan, adr, qport); + cl->state = cs_server; + cl->spectator = 0; + ent = EDICT_NUM (&sv_pr_state, (cl - svs.clients) + 1); + SV_ExtractFromUserinfo (cl); + RETURN_EDICT (pr, ent); +} + +static void +PF_SV_FreeClient (progs_t *pr) +{ + int entnum = P_EDICTNUM (pr, 0); + client_t *cl = svs.clients + entnum - 1; + + if (cl->state != cs_server) + PR_RunError (pr, "not a server client"); + if (cl->userinfo) + Info_Destroy (cl->userinfo); + SV_FullClientUpdate (cl, &sv.reliable_datagram); + if (sv_client_disconnect_e->func) + GIB_Event_Callback (sv_client_disconnect_e, 2, va("%u", cl->userid), + "server"); +} + void SV_PR_Cmds_Init () { @@ -1792,4 +1829,7 @@ SV_PR_Cmds_Init () PR_AddBuiltin (&sv_pr_state, "cfwrite", PF_cfwrite, 106); // float (float desc, string buf) cfwrite PR_AddBuiltin (&sv_pr_state, "cfeof", PF_cfeof, 107); // float (float desc) cfeof PR_AddBuiltin (&sv_pr_state, "cfquota", PF_cfquota, 108); // float () cfquota + + PR_AddBuiltin (&sv_pr_state, "SV_AllocClient", PF_SV_AllocClient, -1); + PR_AddBuiltin (&sv_pr_state, "SV_FreeClient", PF_SV_FreeClient, -1); };