From d831199e2c28ac499c60c4b1121bb8a839671643 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 4 Dec 2018 08:57:29 +0000 Subject: [PATCH] Fix savegame quirk that was trying to force spprogs.dat. Add developer==1 warnings from writebytes out of range. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5354 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/server/pr_cmds.c | 41 +++++++++++++++++++++++++++++++++++----- engine/server/savegame.c | 23 +++++++++++++--------- engine/server/sv_main.c | 12 ++++++------ engine/server/sv_user.c | 4 ++++ engine/server/world.c | 4 ++-- 5 files changed, 62 insertions(+), 22 deletions(-) diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index ce54a54d4..ed8fbbc85 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -5052,11 +5052,28 @@ client_t *Write_GetClient(void) return &svs.clients[entnum-1]; } +static int PF_Write_BoundForNetwork(pubprogfuncs_t *prinst, int minv, int v, int maxv) +{ + if (v > maxv) + { + if (developer.ival) + PR_RunWarning(prinst, "Write*: value %i is outside of the required %i to %i range\n", v, minv, maxv); + v = maxv; + } + if (v < minv) + { + if (developer.ival) + PR_RunWarning(prinst, "Write*: value %i is outside of the required %i to %i range\n", v, minv, maxv); + v = minv; + } + return v; +} + extern sizebuf_t csqcmsgbuffer; void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); - qbyte val = 0xff & (int)G_FLOAT(OFS_PARM1); + qbyte val = PF_Write_BoundForNetwork(prinst, 0, G_FLOAT(OFS_PARM1), 255); if (dest == MSG_CSQC) { //csqc buffers are always written. MSG_WriteByte(&csqcmsgbuffer, val); @@ -5107,7 +5124,7 @@ void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); - char val = 0xff & (int)G_FLOAT(OFS_PARM1); + char val = PF_Write_BoundForNetwork(prinst, -128, G_FLOAT(OFS_PARM1), 127); if (dest == MSG_CSQC) { //csqc buffers are always written. MSG_WriteChar(&csqcmsgbuffer, val); @@ -5157,7 +5174,7 @@ void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); - short val = (((int)G_FLOAT(OFS_PARM1))&0xffff); + short val = PF_Write_BoundForNetwork(prinst, -32768, G_FLOAT(OFS_PARM1), 32767); if (dest == MSG_CSQC) { //csqc buffers are always written. MSG_WriteShort(&csqcmsgbuffer, val); @@ -5308,6 +5325,20 @@ void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); + if (developer.ival && sv.reliable_datagram.prim.coordsize == 2) + { + int v = G_FLOAT(OFS_PARM1)*8; + if (v > 32767) + { + if (developer.ival) + PR_RunWarning(prinst, "WriteCoord: value %g is outside of the required -4096 to 4095.875 range\n", G_FLOAT(OFS_PARM1)); + } + if (v < -32768) + { + if (developer.ival) + PR_RunWarning(prinst, "WriteCoord: value %g is outside of the required 4096 to 4095.875 range\n", G_FLOAT(OFS_PARM1)); + } + } if (dest == MSG_CSQC) { //csqc buffers are always written. MSG_WriteCoord(&csqcmsgbuffer, G_FLOAT(OFS_PARM1)); @@ -12191,8 +12222,8 @@ void PR_DumpPlatform_f(void) {"PVSF_NORMALPVS", "const float", QW|NQ, D("Filter first by PVS, then filter this entity using tracelines if sv_cullentities is enabled."), PVSF_NORMALPVS}, {"PVSF_NOTRACECHECK", "const float", QW|NQ, D("Filter strictly by PVS."), PVSF_NOTRACECHECK}, {"PVSF_USEPHS", "const float", QW|NQ, D("Send if we're close enough to be able to hear this entity."), PVSF_USEPHS}, - {"PVSF_IGNOREPVS", "const float", QW|NQ, D("Ignores pvs. This entity is visible whereever you are on the map."), PVSF_IGNOREPVS}, - {"PVSF_NOREMOVE", "const float", QW|NQ, D("Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses."), PVSF_NOREMOVE}, + {"PVSF_IGNOREPVS", "const float", QW|NQ, D("Ignores pvs. This entity is visible whereever you are on the map. Updates will be sent regardless of pvs or phs"), PVSF_IGNOREPVS}, + {"PVSF_NOREMOVE", "const float", QW|NQ, D("Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses. While this flag is set, no CSQC_Remove events will be sent for the entity, but this does NOT mean that it will still receive further updates while outside of the pvs."), PVSF_NOREMOVE}, //most of these are there for documentation rather than anything else. {"INFOKEY_P_IP", "const string", QW|NQ, D("The apparent ip address of the client. This may be a proxy's ip address."), 0, "\"ip\""}, diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 82d23db42..99726a1f6 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -316,7 +316,7 @@ static qboolean SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version) else { progstype = PROG_QW; - Cvar_Set (&pr_ssqc_progs, "spprogs.dat"); //zquake's single player qw progs. + Cvar_Set (&pr_ssqc_progs, "spprogs"); //zquake's single player qw progs. } pt = 0; } @@ -469,7 +469,7 @@ static qboolean SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version) return true; } -static qboolean SV_LegacySavegame (const char *savename) +static qboolean SV_LegacySavegame (const char *savename, qboolean verbose) { size_t len; char *s = NULL; @@ -486,14 +486,16 @@ static qboolean SV_LegacySavegame (const char *savename) if (sv.state != ss_active) { - Con_TPrintf("Can't apply: Server isn't running or is still loading\n"); + if (verbose) + Con_TPrintf("Can't apply: Server isn't running or is still loading\n"); return false; } if (sv.allocated_client_slots != 1 || svs.clients->state != cs_spawned) { //we don't care about fte-format legacy. - Con_TPrintf("Unable to use legacy savegame format to save multiplayer games\n"); + if (verbose) + Con_TPrintf("Unable to use legacy savegame format to save multiplayer games\n"); return false; } @@ -505,7 +507,8 @@ static qboolean SV_LegacySavegame (const char *savename) f = FS_OpenVFS(name, "wbp", FS_GAMEONLY); if (!f) { - Con_TPrintf ("ERROR: couldn't open %s.\n", name); + if (verbose) + Con_TPrintf ("ERROR: couldn't open %s.\n", name); return false; } @@ -1399,15 +1402,16 @@ void SV_Savegame (const char *savename, qboolean mapchange) #ifndef QUAKETC { int savefmt = sv_savefmt.ival; - if (!*sv_savefmt.string && (svs.gametype != GT_PROGS || progstype == PROG_H2 || svs.levcache)) + if (!*sv_savefmt.string && (svs.gametype != GT_PROGS || progstype == PROG_H2 || svs.levcache || (progstype == PROG_QW && strcmp(pr_ssqc_progs.string, "spprogs")))) savefmt = 1; //hexen2+q2/etc must not use the legacy format by default. can't use it when using any kind of hub system either (harder to detect upfront, which might give confused saved game naming but will at least work). else savefmt = sv_savefmt.ival; if (!savefmt && !mapchange) { - if (SV_LegacySavegame(savename)) + if (SV_LegacySavegame(savename, *sv_savefmt.string)) return; - Con_Printf("Unable to use legacy saved game format\n"); + if (*sv_savefmt.string) + Con_Printf("Unable to use legacy saved game format\n"); } } #endif @@ -1673,9 +1677,10 @@ void SV_Savegame_f (void) #ifndef QUAKETC if (!Q_strcasecmp(Cmd_Argv(0), "savegame_legacy")) { - if (SV_LegacySavegame(savename)) + if (SV_LegacySavegame(savename, true)) return; Con_Printf("Unable to use legacy save format\n"); + return; } #endif SV_Savegame(savename, false); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 9adc60a76..1e3d6f9d5 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -3323,17 +3323,17 @@ static int dehex(int i) else return (i-'a'+10); } -int Rcon_Validate (void) +static qboolean Rcon_Validate (void) { const char *realpass = rcon_password.string; const char *pass = Cmd_Argv(1); if (!strlen (realpass)) - return 0; + return false; - if (!sv_crypt_rcon.ival) + if (!sv_crypt_rcon.ival || !*sv_crypt_rcon.string) { //vanilla-compatible if (!strcmp (pass, realpass) ) - return 1; + return true; } if (sv_crypt_rcon.ival || !*sv_crypt_rcon.string) { //ezquake-compatible @@ -3379,7 +3379,7 @@ int Rcon_Validate (void) for (i = 0;;i++) { if (i == digestsize) - return 1; + return true; if (!pass[i*2+0] || !pass[i*2+1]) break; //premature termination b = dehex(pass[i*2+0])*16+dehex(pass[i*2+1]); @@ -3390,7 +3390,7 @@ int Rcon_Validate (void) } } } - return 0; + return false; } /* diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index a61b6de02..bbf5911de 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -7609,6 +7609,8 @@ done: rname = MSG_ReadString(); if (i) fname = va("CSEv_%s_%s", rname, args); + else if (strchr(rname, '_')) //this is awkward, as not forcing an underscore would allow people to mis-call things with lingering data (the alternative is to block underscores entirely). + fname = va("CSEv_%s_", rname); else fname = va("CSEv_%s", rname); f = PR_FindFunction(svprogfuncs, fname, PR_ANY); @@ -7620,6 +7622,8 @@ done: else rname = va("Cmd_%s", rname); f = PR_FindFunction(svprogfuncs, rname, PR_ANY); + if (f) + SV_ClientPrintf(host_client, PRINT_HIGH, "the name \"%s\" is deprecated\n", rname); } #endif if (host_client->drop) diff --git a/engine/server/world.c b/engine/server/world.c index 40d49807e..b524fe40d 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -1403,7 +1403,7 @@ int World_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, wedict_t **list, int if (count == maxcount) { - Con_Printf ("World_AreaEdicts: MAXCOUNT\n"); + Con_DPrintf ("World_AreaEdicts: MAXCOUNT\n"); return count; } @@ -1899,7 +1899,7 @@ static void World_ClipToEverything (world_t *w, moveclip_t *clip) void World_TouchAllLinks (world_t *w, wedict_t *ent) { - wedict_t *touchedicts[512], *touch; + wedict_t *touchedicts[2048], *touch; int num; num = World_AreaEdicts(w, ent->v->absmin, ent->v->absmax, touchedicts, countof(touchedicts), AREA_TRIGGER); while (num-- > 0)