From 6e211078fdb72bf0f185ccfa09b256d5d0e79fd2 Mon Sep 17 00:00:00 2001 From: Spoike Date: Thu, 30 Aug 2007 20:45:01 +0000 Subject: [PATCH] Added sv_minping git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2623 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/server/server.h | 13 ++++++- engine/server/sv_main.c | 86 +++++++++++++++++++++++++++++++++++++++-- engine/server/sv_user.c | 21 ++++++++++ 3 files changed, 116 insertions(+), 4 deletions(-) diff --git a/engine/server/server.h b/engine/server/server.h index 42e4f3b85..32d80a0d1 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -80,7 +80,13 @@ typedef struct { #define CTE_CHANNELFADE 16 #define CTE_ISBEAM 128 - +typedef struct laggedpacket_s +{ + double time; + struct laggedpacket_s *next; + int length; + unsigned char data[MAX_QWMSGLEN]; +} laggedpacket_t; typedef struct { @@ -524,6 +530,10 @@ typedef struct client_s int realip_status; int realip_num; int realip_ping; + + float delay; + laggedpacket_t *laggedpacket; + laggedpacket_t *laggedpacket_last; } client_t; #define ISQWCLIENT(cl) ((cl)->protocol == SCP_QUAKEWORLD) @@ -746,6 +756,7 @@ typedef struct qboolean msgfromdemo; int language; //the server operators language + laggedpacket_t *free_lagged_packet; levelcache_t *levcache; } server_static_t; diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 3f67969ac..b45197ec8 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -122,6 +122,7 @@ cvar_t sv_highchars = SCVAR("sv_highchars", "1"); cvar_t sv_loadentfiles = SCVAR("sv_loadentfiles", "1"); cvar_t sv_maxrate = SCVAR("sv_maxrate", "10000"); cvar_t sv_maxdrate = SCVAR("sv_maxdrate", "10000"); +cvar_t sv_minping = SCVARF("sv_minping", "0", CVAR_SERVERINFO); cvar_t sv_bigcoords = SCVARF("sv_bigcoords", "", CVAR_SERVERINFO); @@ -350,6 +351,7 @@ or crashing. */ void SV_DropClient (client_t *drop) { + laggedpacket_t *lp; if (drop->controller) { SV_DropClient(drop->controller); @@ -500,6 +502,14 @@ void SV_DropClient (client_t *drop) memset (drop->userinfo, 0, sizeof(drop->userinfo)); memset (drop->userinfobasic, 0, sizeof(drop->userinfobasic)); + while ((lp = drop->laggedpacket)) + { + drop->laggedpacket = lp->next; + lp->next = svs.free_lagged_packet; + svs.free_lagged_packet = lp; + } + drop->laggedpacket_last = NULL; + if (drop->frameunion.frames) //union of the same sort of structure { Z_Free(drop->frameunion.frames); @@ -2529,10 +2539,46 @@ void SV_ReadPackets (void) { int i; client_t *cl; - qboolean good; int qport; + laggedpacket_t *lp; + + for (i = 0; i < MAX_CLIENTS; i++) //fixme: shouldn't we be using svs.allocated_client_slots ? + { + cl = &svs.clients[i]; + while (cl->laggedpacket && cl->laggedpacket->time < realtime) + { + lp = cl->laggedpacket; + cl->laggedpacket = lp->next; + if (cl->laggedpacket_last == lp) + cl->laggedpacket_last = lp->next; + + lp->next = svs.free_lagged_packet; + svs.free_lagged_packet = lp; + + SZ_Clear(&net_message); + memcpy(net_message.data, lp->data, lp->length); + net_message.cursize = lp->length; + + net_from = cl->netchan.remote_address; //not sure if anything depends on this, but lets not screw them up willynilly + + if (Netchan_Process(&cl->netchan)) + { // this is a valid, sequenced packet, so process it + svs.stats.packets++; + if (cl->state > cs_zombie) + { //make sure they didn't already disconnect + cl->send_message = true; // reply at end of frame + +#ifdef Q2SERVER + if (cl->protocol == SCP_QUAKE2) + SVQ2_ExecuteClientMessage(cl); + else +#endif + SV_ExecuteClientMessage (cl); + } + } + } + } - good = false; while (SV_GetPacket ()) { if (SV_FilterPacket (&net_from)) @@ -2588,10 +2634,37 @@ void SV_ReadPackets (void) Con_DPrintf ("SV_ReadPackets: fixing up a translated port\n"); cl->netchan.remote_address.port = net_from.port; } + + if (cl->delay > 0) + { + if (cl->state == cs_zombie) + break; + if (net_message.cursize > sizeof(svs.free_lagged_packet->data)) + { + Con_Printf("minping code is screwy\n"); + break; //drop this packet + } + + if (!svs.free_lagged_packet) //kinda nasty + svs.free_lagged_packet = Z_Malloc(sizeof(*svs.free_lagged_packet)); + + if (!cl->laggedpacket) + cl->laggedpacket_last = cl->laggedpacket = svs.free_lagged_packet; + else + cl->laggedpacket_last = cl->laggedpacket_last->next = svs.free_lagged_packet; + cl->laggedpacket_last->next = NULL; + svs.free_lagged_packet = svs.free_lagged_packet->next; + + cl->laggedpacket_last->time = realtime + cl->delay; + memcpy(cl->laggedpacket_last->data, net_message.data, net_message.cursize); + cl->laggedpacket_last->length = net_message.cursize; + break; + } + + if (Netchan_Process(&cl->netchan)) { // this is a valid, sequenced packet, so process it svs.stats.packets++; - good = true; if (cl->state != cs_zombie) { cl->send_message = true; // reply at end of frame @@ -3176,6 +3249,7 @@ void SV_InitLocal (void) Cvar_Register (&sv_voicechat, cvargroup_servercontrol); Cvar_Register (&sv_maxrate, cvargroup_servercontrol); Cvar_Register (&sv_maxdrate, cvargroup_servercontrol); + Cvar_Register (&sv_minping, cvargroup_servercontrol); Cvar_Register (&sv_nailhack, cvargroup_servercontrol); @@ -3288,6 +3362,12 @@ void SV_InitLocal (void) svs.log[1].cursize = 0; svs.log[1].allowoverflow = true; + + svs.free_lagged_packet = Hunk_Alloc(1024*sizeof(*svs.free_lagged_packet)); + for (i = 0; i < 1024-1; i++) + svs.free_lagged_packet[i].next = &svs.free_lagged_packet[i+1]; + svs.free_lagged_packet[i].next = 0; + // parse params for cvars p = COM_CheckParm ("-port"); if (!p) diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index bfaaabc96..39cd50626 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -71,6 +71,7 @@ cvar_t votepercent = SCVAR("votepercent", "-1"); cvar_t votetime = SCVAR("votetime", "10"); cvar_t pr_allowbutton1 = SCVARF("pr_allowbutton1", "1", CVAR_LATCH); +extern cvar_t sv_minping; extern cvar_t pm_bunnyspeedcap; @@ -4805,7 +4806,27 @@ void SV_ExecuteClientMessage (client_t *cl) frame = &cl->frameunion.frames[cl->netchan.incoming_acknowledged & UPDATE_MASK]; if (cl->lastsequence_acknoledged + UPDATE_BACKUP > cl->netchan.incoming_acknowledged) + { frame->ping_time = realtime - frame->senttime; //no more phenomanally low pings please + + if (cl->spectator) + cl->delay = 0; + else + { + if (frame->ping_time*1000 > sv_minping.value+1) + { + cl->delay -= 0.001; + if (cl->delay < 0) + cl->delay = 0; + } + if (frame->ping_time*1000 < sv_minping.value) + { + cl->delay += 0.001; + if (cl->delay > 1) + cl->delay = 1; + } + } + } #ifdef PEXT_CSQC if (cl->lastsequence_acknoledged + UPDATE_BACKUP > cl->netchan.incoming_acknowledged) {