Fix some issues with csprogs embedded inside mvd files.

This commit is contained in:
Shpoike 2023-04-14 02:50:19 +01:00
parent d37b8d07ff
commit 2b17f90b28
5 changed files with 96 additions and 13 deletions

View File

@ -2240,6 +2240,7 @@ static void DL_Completed(qdownload_t *dl, qofs_t start, qofs_t end)
static float chunkrate;
static int CL_CountQueuedDownloads(void);
static void CL_ParseChunkedDownload(qdownload_t *dl)
{
qbyte *svname;
@ -2263,7 +2264,41 @@ static void CL_ParseChunkedDownload(qdownload_t *dl)
svname = MSG_ReadString();
if (cls.demoplayback)
return;
{ //downloading in demos is allowed ONLY for csprogs.dat
extern cvar_t cl_downloads, cl_download_csprogs;
if (!cls.download && !dl &&
!strcmp(svname, "csprogs.dat") && filesize && filesize == strtoul(InfoBuf_ValueForKey(&cl.serverinfo, "*csprogssize"), NULL, 0) &&
cl_downloads.ival && cl_download_csprogs.ival)
{
//FIXME: should probably save this to memory instead of bloating it on disk.
dl = Z_Malloc(sizeof(*dl));
Q_strncpyz(dl->remotename, svname, sizeof(dl->remotename));
Q_strncpyz(dl->localname, va("csprogsvers/%x.dat", (unsigned int)strtoul(InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs"), NULL, 0)), sizeof(dl->localname));
// download to a temp name, and only rename
// to the real name when done, so if interrupted
// a runt file wont be left
COM_StripExtension (dl->localname, dl->tempname, sizeof(dl->tempname)-5);
Q_strncatz (dl->tempname, ".tmp", sizeof(dl->tempname));
dl->method = DL_QWPENDING;
dl->percent = 0;
dl->sizeunknown = true;
dl->flags = DLLF_OVERWRITE;
if (COM_FCheckExists(dl->localname))
{
Con_DPrintf("Demo embeds redundant %s\n", dl->localname);
Z_Free(dl);
return;
}
cls.download = dl;
Con_Printf("Saving recorded file %s (%lu bytes)\n", dl->localname, (unsigned long)filesize);
}
else
return;
}
if (!*svname)
{
@ -2367,6 +2402,7 @@ static void CL_ParseChunkedDownload(qdownload_t *dl)
dl->method = DL_QWCHUNKS;
dl->percent = 0;
dl->size = filesize;
dl->sizeunknown = false;
dl->starttime = Sys_DoubleTime();
@ -2391,7 +2427,8 @@ static void CL_ParseChunkedDownload(qdownload_t *dl)
if (!dl)
{
Con_Printf("ignoring download data packet\n");
if (!cls.demoplayback) //mute it in demos.
Con_Printf("ignoring download data packet\n");
return;
}
@ -2401,11 +2438,6 @@ static void CL_ParseChunkedDownload(qdownload_t *dl)
if (!dl->file)
return;
if (cls.demoplayback)
{ //err, yeah, when playing demos we don't actually pay any attention to this.
return;
}
VFS_SEEK(dl->file, chunknum*DLBLOCKSIZE);
if (dl->size - chunknum*DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve.
VFS_WRITE(dl->file, data, dl->size - chunknum*DLBLOCKSIZE);
@ -2417,6 +2449,9 @@ static void CL_ParseChunkedDownload(qdownload_t *dl)
dl->percent = dl->completedbytes/(float)dl->size*100;
chunkrate += 1;
if (dl->completedbytes == dl->size)
CL_DownloadFinished(dl);
}
static int CL_CountQueuedDownloads(void)

View File

@ -959,6 +959,8 @@ float CL_GetPredictionRealtime(playerview_t *pv)
return simtime;
}
qboolean CSQC_GetSSQCEntityOrigin(unsigned int ssqcent, float *out);
/*
==============
CL_PredictMove
@ -1060,7 +1062,8 @@ void CL_PredictMovePNum (int seat)
if (pv->cam_state == CAM_PENDING && pv->cam_spec_track >= 0 && pv->cam_spec_track < cl.allocated_client_slots && pv->viewentity != pv->cam_spec_track+1)
{
if ((cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[pv->cam_spec_track].messagenum == cl.validsequence) ||
(pv->cam_spec_track+1 < cl.maxlerpents && cl.lerpents[pv->cam_spec_track+1].sequence == cl.lerpentssequence))
(pv->cam_spec_track+1 < cl.maxlerpents && cl.lerpents[pv->cam_spec_track+1].sequence == cl.lerpentssequence) ||
CSQC_GetSSQCEntityOrigin(pv->cam_spec_track+1, NULL))
{
pv->cam_state = CAM_EYECAM;
pv->viewentity = pv->cam_spec_track+1;

View File

@ -2870,7 +2870,7 @@ entity_t *CL_NewTempEntity (void)
return ent;
}
void CSQC_GetEntityOrigin(unsigned int csqcent, float *out);
qboolean CSQC_GetEntityOrigin(unsigned int csqcent, float *out);
/*
=================

View File

@ -8310,7 +8310,11 @@ qboolean CSQC_Init (qboolean anycsqc, const char *csprogsname, unsigned int chec
}
if (cl_nocsqc.value)
{
if (checksum || progssize)
Con_Printf(CON_WARNING"Server is using csqc, but its disabled via %s\n", cl_nocsqc.name);
return false;
}
if (cls.state == ca_disconnected)
{
@ -8430,6 +8434,8 @@ qboolean CSQC_Init (qboolean anycsqc, const char *csprogsname, unsigned int chec
csprogsnum = PR_LoadProgs(csqcprogs, csprogs_checkname);
if (csprogsnum >= 0)
Con_DPrintf("Loaded csprogs.dat\n");
else if (csprogs_checksum || csprogs_checksize)
Con_Printf(CON_WARNING"Unable to load \"csprogsvers/%x.dat\"\n", csprogs_checksum);
}
if (csqc_singlecheats || anycsqc)
@ -9725,13 +9731,29 @@ int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float
return false;
}
void CSQC_GetEntityOrigin(unsigned int csqcent, float *out)
qboolean CSQC_GetEntityOrigin(unsigned int csqcent, float *out)
{
wedict_t *ent;
if (!csqcprogs)
return;
return false;
ent = WEDICT_NUM_UB(csqcprogs, csqcent);
VectorCopy(ent->v->origin, out);
return true;
}
qboolean CSQC_GetSSQCEntityOrigin(unsigned int ssqcent, float *out)
{
csqcedict_t *ent;
if (csqcprogs && ssqcent < maxcsqcentities)
{
ent = csqcent[ssqcent];
if (ent)
{
if (out)
VectorCopy(ent->v->origin, out);
return true;
}
}
return false;
}
void CSQC_ParseEntities(qboolean sized)
@ -9744,7 +9766,23 @@ void CSQC_ParseEntities(qboolean sized)
qboolean removeflag;
if (!csqcprogs)
Host_EndGame("CSQC needs to be initialized for this server.\n");
{
const char *fname = va("csprogsvers/%x.dat", (unsigned int)strtoul(InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs"), NULL, 0));
const char *msg;
if (cl_nocsqc.value)
msg = "blocked by cl_nocsqc.\n";
else if (!COM_FCheckExists(fname))
{
extern cvar_t cl_downloads, cl_download_csprogs;
if (!cl_downloads.ival || !cl_download_csprogs.ival)
msg = "downloading blocked by cl_downloads or cl_download_csprogs.\n";
else
msg = "unable to download.\n";
}
else
msg = "not initialised.\n";
Host_EndGame("%s required, but %s", fname, msg);
}
if (!csqcg.CSQC_Ent_Update || !csqcg.self)
Host_EndGame("CSQC has no CSQC_Ent_Update function\n");
@ -9858,6 +9896,13 @@ void CSQC_ParseEntities(qboolean sized)
if (cl_csqcdebug.ival)
Con_Printf("Update %i\n", entnum);
}
#ifdef QUAKESTATS
if (entnum-1 < cl.allocated_client_slots && cls.findtrack && cl.players[entnum-1].stats[STAT_HEALTH] > 0)
{ //FIXME: is this still needed with the autotrack stuff?
Cam_Lock(&cl.playerview[0], entnum-1);
cls.findtrack = false;
}
#endif
*csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent);
csqc_mayread = true;

View File

@ -1633,7 +1633,7 @@ qboolean SV_MVD_Record (mvddest_t *dest)
else if (sv_demoExtensions.ival)
{ /*everything*/
extern cvar_t pext_replacementdeltas;
demo.recorder.fteprotocolextensions = PEXT_CSQC | PEXT_COLOURMOD | PEXT_DPFLAGS | PEXT_CUSTOMTEMPEFFECTS | PEXT_ENTITYDBL | PEXT_ENTITYDBL2 | PEXT_FATNESS | PEXT_HEXEN2 | PEXT_HULLSIZE | PEXT_LIGHTSTYLECOL | PEXT_MODELDBL | PEXT_SCALE | PEXT_SETATTACHMENT | PEXT_SETVIEW | PEXT_SOUNDDBL | PEXT_SPAWNSTATIC2 | PEXT_TRANS;
demo.recorder.fteprotocolextensions = PEXT_CHUNKEDDOWNLOADS | PEXT_CSQC | PEXT_COLOURMOD | PEXT_DPFLAGS | PEXT_CUSTOMTEMPEFFECTS | PEXT_ENTITYDBL | PEXT_ENTITYDBL2 | PEXT_FATNESS | PEXT_HEXEN2 | PEXT_HULLSIZE | PEXT_LIGHTSTYLECOL | PEXT_MODELDBL | PEXT_SCALE | PEXT_SETATTACHMENT | PEXT_SETVIEW | PEXT_SOUNDDBL | PEXT_SPAWNSTATIC2 | PEXT_TRANS;
#ifdef PEXT_VIEW2
demo.recorder.fteprotocolextensions |= PEXT_VIEW2;
#endif