From 7eac32bbb4a1d62e6411c0cbaf3505e910f856e3 Mon Sep 17 00:00:00 2001 From: Daniel Svensson Date: Sat, 1 Feb 2025 19:06:33 +0100 Subject: [PATCH] QVM: Correct sendflags & result of QVM_SendEntity. (#298) The lower bits are used for engine metadata and was not trimmed when SendEntity was invoked in the QVM case. Additionally the result of SendEntity was fetched with the assumption of a traditional QC VM running which caused a crash. Result is now propagated from either QVM or QC. --- engine/server/pr_q1qvm.c | 6 +++--- engine/server/progs.h | 2 +- engine/server/sv_ents.c | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/engine/server/pr_q1qvm.c b/engine/server/pr_q1qvm.c index e3efa231f..fc95e83ee 100755 --- a/engine/server/pr_q1qvm.c +++ b/engine/server/pr_q1qvm.c @@ -2070,7 +2070,7 @@ static qintptr_t QVM_pointerstat (void *offset, quintptr_t mask, const qintptr_t static qintptr_t QVM_SetSendNeeded(void *offset, quintptr_t mask, const qintptr_t *arg) { unsigned int subject = VM_LONG(arg[0]); - quint64_t fl = arg[1]; + quint64_t fl = arg[1] << SENDFLAGS_SHIFT; unsigned int to = VM_LONG(arg[2]); if (!to) { //broadcast @@ -2852,9 +2852,9 @@ void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes) VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000), botsarespecialsnowflakes, 0, 0); } -void Q1QVM_SendEntity(quint64_t sendflags) +qboolean Q1QVM_SendEntity(quint64_t sendflags) { - VM_Call(q1qvm, GAME_EDICT_CSQCSEND, sendflags, 0, 0, 0); + return VM_Call(q1qvm, GAME_EDICT_CSQCSEND, sendflags, 0, 0, 0) > 0; } void Q1QVM_Blocked(void) diff --git a/engine/server/progs.h b/engine/server/progs.h index b0d1020de..100c8cac4 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -154,7 +154,7 @@ void Q1QVM_RunPlayerThink(void); void Q1QVM_PostThink(void); void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes); void Q1QVM_Blocked(void); -void Q1QVM_SendEntity(quint64_t sendflags); +qboolean Q1QVM_SendEntity(quint64_t sendflags); void Q1QVM_SetNewParms(void); void Q1QVM_SetChangeParms(void); qboolean Q1QVM_ClientCommand(void); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index a7eafee0b..6c58ebaf2 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -335,6 +335,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) for (en = 0, entnum = 0; en < csqcnuments; en++, entnum++) { + int mod_result = 0; ent = csqcent[en]; //add any entity removes on ents leading up to this entity @@ -400,7 +401,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) if (svs.gametype == GT_Q1QVM) { pr_global_struct->other = viewerent; - Q1QVM_SendEntity(bits); + mod_result = Q1QVM_SendEntity(bits >> SENDFLAGS_SHIFT); } else #endif @@ -411,9 +412,10 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) G_FLOAT(OFS_PARM1+1) = (int)((bits>>(SENDFLAGS_SHIFT+24)) & 0xffffff); G_FLOAT(OFS_PARM1+2) = (int)((bits>>(SENDFLAGS_SHIFT+48)) & 0xffffff); PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity); + mod_result = G_INT(OFS_RETURN); } - if (G_INT(OFS_RETURN)) //0 means not to tell the client about it. + if (mod_result) //0 means not to tell the client about it. { //FIXME: don't overflow MAX_DATAGRAM... unless its too big anyway... if (msg->cursize + csqcmsgbuffer.cursize+5 >= msg->maxsize)