From 7c322147e2dfcaabe9e9911b3f46b4b66d26071b Mon Sep 17 00:00:00 2001 From: Cloudwalk Date: Mon, 19 Oct 2020 01:29:37 -0400 Subject: [PATCH] Implement protocol 666 (Fitzquake/Quakespasm) server support. Quakespasm clients can now connect to Darkplaces Quake servers if sv_protocolname is set to FITZQUAKE --- netconn.c | 2 +- progs.h | 2 ++ protocol.c | 2 +- sv_ents5.c | 4 ++-- sv_ents_nq.c | 45 +++++++++++++++++++++++++-------------- sv_main.c | 60 +++++++++++++++++++++++++++++++++++++--------------- sv_phys.c | 21 ++++++++++++++++-- sv_send.c | 55 ++++++++++++++++++++++++++++++++++++++++------- sv_user.c | 6 +++--- svvm_cmds.c | 45 ++++++++++++++++++++++++++++++--------- 10 files changed, 182 insertions(+), 60 deletions(-) diff --git a/netconn.c b/netconn.c index 1fd4c04d..26115189 100755 --- a/netconn.c +++ b/netconn.c @@ -3319,7 +3319,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat // protocol // (this protects more modern protocols against being used for // Quake packet flood Denial Of Service attacks) - if (length >= 5 && (i = BuffBigLong(data)) && (i & (~NETFLAG_LENGTH_MASK)) == (int)NETFLAG_CTL && (i & NETFLAG_LENGTH_MASK) == length && (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3) && !ENCRYPTION_REQUIRED) + if (length >= 5 && (i = BuffBigLong(data)) && (i & (~NETFLAG_LENGTH_MASK)) == (int)NETFLAG_CTL && (i & NETFLAG_LENGTH_MASK) == length && (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_fitzquake) && !ENCRYPTION_REQUIRED) { int c; int protocolnumber; diff --git a/progs.h b/progs.h index fd8d109c..ea764cbc 100644 --- a/progs.h +++ b/progs.h @@ -113,6 +113,8 @@ typedef struct edict_engineprivate_s frameblend_t frameblend[MAX_FRAMEBLENDS]; skeleton_t skeleton; + qbool sendinterval; // PROTOCOL_FITZQUAKE + // physics parameters qbool ode_physics; void *ode_body; diff --git a/protocol.c b/protocol.c index d8e616c5..e7249d6d 100644 --- a/protocol.c +++ b/protocol.c @@ -273,7 +273,7 @@ protocol_t protocol_fitzquake = .ReadAngle = MSG_ReadAngle8i, .ReadVector = MSG_ReadVector13i, .svc = &netmsg_fq_svc, - //.clc = &netmsg_base_clc + .clc = &netmsg_base_clc }; protocol_t *protocols[] = diff --git a/sv_ents5.c b/sv_ents5.c index d0b04031..0f549a23 100644 --- a/sv_ents5.c +++ b/sv_ents5.c @@ -516,7 +516,7 @@ qbool EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database packetlog = NULL; // write stat updates - if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5) + if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5 && sv.protocol != &protocol_fitzquake) { for (i = 0;i < MAX_CL_STATS && msg->cursize + 6 + 11 <= maxsize;i++) { @@ -569,7 +569,7 @@ qbool EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database d->latestframenum = framenum; MSG_WriteByte(msg, svc_entities); MSG_WriteLong(msg, framenum); - if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5 && sv.protocol != &protocol_dpp6) + if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5 && sv.protocol != &protocol_dpp6 && sv.protocol != &protocol_fitzquake) MSG_WriteLong(msg, movesequence); for (priority = ENTITYFRAME5_PRIORITYLEVELS - 1;priority >= 0 && packetlog->numstates < ENTITYFRAME5_MAXSTATES;priority--) { diff --git a/sv_ents_nq.c b/sv_ents_nq.c index 1d645417..6d041672 100644 --- a/sv_ents_nq.c +++ b/sv_ents_nq.c @@ -60,30 +60,32 @@ qbool EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates, co { bits |= U_FRAME; if (s->frame & 0xFF00) - bits |= U_FRAME2; + bits |= (sv.protocol != &protocol_fitzquake) ? U_FRAME2 : U_FRAME2_FQ; } if (baseline.effects != s->effects) { bits |= U_EFFECTS; - if (s->effects & 0xFF00) + if (sv.protocol != &protocol_fitzquake && s->effects & 0xFF00) bits |= U_EFFECTS2; } if (baseline.modelindex != s->modelindex) { bits |= U_MODEL; if ((s->modelindex & 0xFF00) && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3) - bits |= U_MODEL2; + bits |= (sv.protocol != &protocol_fitzquake) ? U_MODEL2 : U_MODEL2_FQ; } if (baseline.alpha != s->alpha) - bits |= U_ALPHA; - if (baseline.scale != s->scale) + bits |= (sv.protocol != &protocol_fitzquake) ? U_ALPHA : U_ALPHA_FQ; + if (sv.protocol != &protocol_fitzquake && baseline.scale != s->scale) bits |= U_SCALE; - if (baseline.glowsize != s->glowsize) + if (sv.protocol != &protocol_fitzquake && baseline.glowsize != s->glowsize) bits |= U_GLOWSIZE; - if (baseline.glowcolor != s->glowcolor) + if (sv.protocol != &protocol_fitzquake && baseline.glowcolor != s->glowcolor) bits |= U_GLOWCOLOR; - if (!VectorCompare(baseline.colormod, s->colormod)) + if (sv.protocol != &protocol_fitzquake && !VectorCompare(baseline.colormod, s->colormod)) bits |= U_COLORMOD; + if (sv.protocol == &protocol_fitzquake && PRVM_EDICT_NUM(s->number)->priv.server->sendinterval) + bits |= U_LERPFINISH_FQ; // if extensions are disabled, clear the relevant update flags if (sv.protocol == &protocol_netquake || sv.protocol == &protocol_nehahramovie) @@ -131,14 +133,25 @@ qbool EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates, co if (bits & U_ANGLE2) sv.protocol->WriteAngle(&buf, s->angles[1]); if (bits & U_ORIGIN3) sv.protocol->WriteCoord(&buf, s->origin[2]); if (bits & U_ANGLE3) sv.protocol->WriteAngle(&buf, s->angles[2]); - if (bits & U_ALPHA) MSG_WriteByte(&buf, s->alpha); - if (bits & U_SCALE) MSG_WriteByte(&buf, s->scale); - if (bits & U_EFFECTS2) MSG_WriteByte(&buf, s->effects >> 8); - if (bits & U_GLOWSIZE) MSG_WriteByte(&buf, s->glowsize); - if (bits & U_GLOWCOLOR) MSG_WriteByte(&buf, s->glowcolor); - if (bits & U_COLORMOD) {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[2] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);} - if (bits & U_FRAME2) MSG_WriteByte(&buf, s->frame >> 8); - if (bits & U_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8); + + if(sv.protocol != &protocol_fitzquake) + { + if (bits & U_ALPHA) MSG_WriteByte(&buf, s->alpha); + if (bits & U_SCALE) MSG_WriteByte(&buf, s->scale); + if (bits & U_EFFECTS2) MSG_WriteByte(&buf, s->effects >> 8); + if (bits & U_GLOWSIZE) MSG_WriteByte(&buf, s->glowsize); + if (bits & U_GLOWCOLOR) MSG_WriteByte(&buf, s->glowcolor); + if (bits & U_COLORMOD) {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[2] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);} + if (bits & U_FRAME2) MSG_WriteByte(&buf, s->frame >> 8); + if (bits & U_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8); + } + else + { + if (bits & U_ALPHA_FQ) MSG_WriteByte(&buf, s->alpha); + if (bits & U_FRAME2_FQ) MSG_WriteByte(&buf, (int)s->frame >> 8); + if (bits & U_MODEL2_FQ) MSG_WriteByte(&buf, (int)s->modelindex >> 8); + if (bits & U_LERPFINISH_FQ) MSG_WriteByte(&buf, (uint8_t) (Q_rint((PRVM_serveredictfloat(PRVM_EDICT_NUM(s->number), nextthink) - sv.time) * 255))); + } // the nasty protocol if ((bits & U_EXTEND1) && sv.protocol == &protocol_nehahramovie) diff --git a/sv_main.c b/sv_main.c index eab2b77e..4a455ed4 100644 --- a/sv_main.c +++ b/sv_main.c @@ -772,7 +772,7 @@ void SV_SendServerinfo (client_t *client) memset(client->stats, 0, sizeof(client->stats)); memset(client->statsdeltabits, 0, sizeof(client->statsdeltabits)); - if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3) + if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_fitzquake) { if (sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3) client->entitydatabase = EntityFrame_AllocDatabase(sv_mempool); @@ -1391,7 +1391,7 @@ int SV_ModelIndex(const char *s, int precachemode) { if (precachemode) { - if (sv.state != ss_loading && (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5)) + if (sv.state != ss_loading && (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5 || sv.protocol == &protocol_fitzquake)) { Con_Printf("SV_ModelIndex(\"%s\"): precache_model can only be done in spawn functions\n", filename); return 0; @@ -1454,7 +1454,7 @@ int SV_SoundIndex(const char *s, int precachemode) { if (precachemode) { - if (sv.state != ss_loading && (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5)) + if (sv.state != ss_loading && (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5 || sv.protocol == &protocol_fitzquake)) { Con_Printf("SV_SoundIndex(\"%s\"): precache_sound can only be done in spawn functions\n", filename); return 0; @@ -1595,7 +1595,7 @@ SV_CreateBaseline static void SV_CreateBaseline (void) { prvm_prog_t *prog = SVVM_prog; - int i, entnum, large; + int i, entnum, bits; prvm_edict_t *svent; // LadyHavoc: clear *all* baselines (not just active ones) @@ -1621,32 +1621,53 @@ static void SV_CreateBaseline (void) { svent->priv.server->baseline.colormap = entnum; svent->priv.server->baseline.modelindex = SV_ModelIndex("progs/player.mdl", 1); + if(sv.protocol == &protocol_fitzquake) + svent->priv.server->baseline.alpha = ENTALPHA_DEFAULT; } else { svent->priv.server->baseline.colormap = 0; svent->priv.server->baseline.modelindex = (int)PRVM_serveredictfloat(svent, modelindex); + if(sv.protocol == &protocol_fitzquake) + svent->priv.server->baseline.alpha = PRVM_serveredictfloat(svent, alpha); } + bits = 0; + if (svent->priv.server->baseline.modelindex & 0xFF00) + bits |= B_LARGEMODEL; + if (svent->priv.server->baseline.frame & 0xFF00) + bits |= B_LARGEFRAME; + if (sv.protocol == &protocol_fitzquake && svent->priv.server->baseline.alpha != ENTALPHA_DEFAULT) + bits |= B_ALPHA; + if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) + bits = 0; - large = false; - if (svent->priv.server->baseline.modelindex & 0xFF00 || svent->priv.server->baseline.frame & 0xFF00) + // add to the message + if (bits) { - large = true; - if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) - large = false; + if(sv.protocol == &protocol_fitzquake) + MSG_WriteByte (&sv.signon, svc_spawnbaseline2_fq); + else + MSG_WriteByte (&sv.signon, svc_spawnbaseline2); } - - // add to the message - if (large) - MSG_WriteByte (&sv.signon, svc_spawnbaseline2); else MSG_WriteByte (&sv.signon, svc_spawnbaseline); + MSG_WriteShort (&sv.signon, entnum); - if (large) + if (bits) { - MSG_WriteShort (&sv.signon, svent->priv.server->baseline.modelindex); - MSG_WriteShort (&sv.signon, svent->priv.server->baseline.frame); + if(sv.protocol == &protocol_fitzquake) + MSG_WriteByte (&sv.signon, bits); + + if(sv.protocol != &protocol_fitzquake || bits & B_LARGEMODEL) + MSG_WriteShort (&sv.signon, svent->priv.server->baseline.modelindex); + else + MSG_WriteByte (&sv.signon, svent->priv.server->baseline.modelindex); + + if(sv.protocol != &protocol_fitzquake || bits & B_LARGEFRAME) + MSG_WriteShort (&sv.signon, svent->priv.server->baseline.frame); + else + MSG_WriteByte (&sv.signon, svent->priv.server->baseline.frame); } else if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) { @@ -1665,6 +1686,9 @@ static void SV_CreateBaseline (void) sv.protocol->WriteCoord(&sv.signon, svent->priv.server->baseline.origin[i]); sv.protocol->WriteAngle(&sv.signon, svent->priv.server->baseline.angles[i]); } + + if (sv.protocol == &protocol_fitzquake && bits & B_ALPHA) + MSG_WriteByte (&sv.signon, svent->priv.server->baseline.alpha); } } @@ -1886,6 +1910,8 @@ void SV_SpawnServer (const char *map) Con_Printf(CON_ERROR "Unknown sv_protocolname \"%s\", valid values are:\n%s\n", sv_protocolname.string, buffer); sv.protocol = &protocol_netquake; } + else if (sv.protocol == &protocol_fitzquake) + Cvar_SetValueQuick(&pr_checkextension, 0); SV_VM_Setup(); @@ -2019,7 +2045,7 @@ void SV_SpawnServer (const char *map) Mod_PurgeUnused(); // create a baseline for more efficient communications - if (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) + if (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_fitzquake) SV_CreateBaseline (); sv.state = ss_active; // LadyHavoc: workaround for svc_precache bug diff --git a/sv_phys.c b/sv_phys.c index a72a7ca6..40ed6a85 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -1082,16 +1082,24 @@ Returns false if the entity removed itself. static qbool SV_RunThink (prvm_edict_t *ent) { prvm_prog_t *prog = SVVM_prog; + float thinktime; + float oldframe; int iterations; // don't let things stay in the past. // it is possible to start that way by a trigger with a local time. - if (PRVM_serveredictfloat(ent, nextthink) <= 0 || PRVM_serveredictfloat(ent, nextthink) > sv.time + sv.frametime) + thinktime = PRVM_serveredictfloat(ent, nextthink); + if (thinktime <= 0 || thinktime > sv.time + sv.frametime) return true; + if (thinktime < sv.time) + thinktime = sv.time; + + oldframe = PRVM_serveredictfloat(ent, frame); + for (iterations = 0;iterations < 128 && !ent->priv.server->free;iterations++) { - PRVM_serverglobalfloat(time) = max(sv.time, PRVM_serveredictfloat(ent, nextthink)); + PRVM_serverglobalfloat(time) = thinktime; PRVM_serveredictfloat(ent, nextthink) = 0; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent); PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts); @@ -1103,6 +1111,15 @@ static qbool SV_RunThink (prvm_edict_t *ent) if (PRVM_serveredictfloat(ent, nextthink) <= PRVM_serverglobalfloat(time) || PRVM_serveredictfloat(ent, nextthink) > sv.time + sv.frametime || !sv_gameplayfix_multiplethinksperframe.integer) break; } + //capture interval to nextthink here and send it to client for better + //lerp timing, but only if interval is not 0.1 (which client assumes) + ent->priv.server->sendinterval = false; + if (!ent->priv.server->free && PRVM_serveredictfloat(ent, nextthink) && (PRVM_serveredictfloat(ent, movetype) == MOVETYPE_STEP || PRVM_serveredictfloat(ent, frame) != oldframe)) + { + int i = Q_rint((PRVM_serveredictfloat(ent, nextthink)-thinktime)*255); + if (i >= 0 && i < 256 && i != 25 && i != 26) //25 and 26 are close enough to 0.1 to not send + ent->priv.server->sendinterval = true; + } return !ent->priv.server->free; } diff --git a/sv_send.c b/sv_send.c index e1ae5d34..1d078686 100644 --- a/sv_send.c +++ b/sv_send.c @@ -913,7 +913,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s) // always send world submodels in newer protocols because they don't // generate much traffic (in old protocols they hog bandwidth) // but only if sv_cullentities_nevercullbmodels is off - else if (!(s->effects & EF_NODEPTHTEST) && (!isbmodel || !sv_cullentities_nevercullbmodels.integer || sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie)) + else if (!(s->effects & EF_NODEPTHTEST) && (!isbmodel || !sv_cullentities_nevercullbmodels.integer || sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_fitzquake)) { // entity has survived every check so far, check if visible ed = PRVM_EDICT_NUM(s->number); @@ -1173,7 +1173,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t { if (PRVM_serveredictvector(ent, punchangle)[i]) bits |= (SU_PUNCH1<= 65536) bits |= SU_EXTEND1; if (bits >= 16777216) @@ -1284,12 +1297,12 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t { if (bits & (SU_PUNCH1<> 8); + if (bits & SU_ARMOR2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, armorvalue) >> 8); + if (bits & SU_AMMO2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, currentammo) >> 8); + if (bits & SU_SHELLS2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, ammo_shells) >> 8); + if (bits & SU_NAILS2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, ammo_nails) >> 8); + if (bits & SU_ROCKETS2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, ammo_rockets) >> 8); + if (bits & SU_CELLS2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, ammo_cells) >> 8); + if (bits & SU_WEAPONFRAME2) + MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, weaponframe) >> 8); + if (bits & SU_WEAPONALPHA) + MSG_WriteByte (msg, PRVM_serveredictfloat(ent, alpha)); //for now, weaponalpha = client entity alpha + //johnfitz + } } } @@ -1459,6 +1497,7 @@ static void SV_SendClientDatagram (client_t *client) case PROTOCOL_DARKPLACES2: case PROTOCOL_DARKPLACES3: case PROTOCOL_DARKPLACES4: + case PROTOCOL_FITZQUAKE: // no packet size limit support on DP1-4 protocols because they kick // the client off if they overflow, and miss effects // packets are simply sent less often to obey the rate limit diff --git a/sv_user.c b/sv_user.c index 8219c461..b44bd90a 100644 --- a/sv_user.c +++ b/sv_user.c @@ -653,7 +653,7 @@ void SV_ReadClientMove (void) if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__); // read ping time - if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5 && sv.protocol != &protocol_dpp6) + if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5 && sv.protocol != &protocol_dpp6 && sv.protocol != &protocol_fitzquake) move->sequence = MSG_ReadLong(&sv_message); move->time = move->clienttime = MSG_ReadFloat(&sv_message); if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__); @@ -689,7 +689,7 @@ void SV_ReadClientMove (void) // read buttons // be sure to bitwise OR them into the move->buttons because we want to // accumulate button presses from multiple packets per actual move - if (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5) + if (sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3 || sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5 || sv.protocol == &protocol_fitzquake) move->buttons = MSG_ReadByte(&sv_message); else move->buttons = MSG_ReadLong(&sv_message); @@ -700,7 +700,7 @@ void SV_ReadClientMove (void) if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__); // PRYDON_CLIENTCURSOR - if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5) + if (sv.protocol != &protocol_netquake && sv.protocol != &protocol_quakedp && sv.protocol != &protocol_nehahramovie && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3 && sv.protocol != &protocol_dpp1 && sv.protocol != &protocol_dpp2 && sv.protocol != &protocol_dpp3 && sv.protocol != &protocol_dpp4 && sv.protocol != &protocol_dpp5 && sv.protocol != &protocol_fitzquake) { // 30 bytes move->cursor_screen[0] = MSG_ReadShort(&sv_message) * (1.0f / 32767.0f); diff --git a/svvm_cmds.c b/svvm_cmds.c index 55608982..11831273 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -485,7 +485,7 @@ static void VM_SV_ambientsound(prvm_prog_t *prog) return; large = false; - if (soundnum >= 256) + if (soundnum > 255) large = true; if(sv.protocol == &protocol_nehahrabjp) @@ -494,7 +494,12 @@ static void VM_SV_ambientsound(prvm_prog_t *prog) // add an svc_spawnambient command to the level signon packet if (large) - MSG_WriteByte (&sv.signon, svc_spawnstaticsound2); + { + if(sv.protocol == &protocol_fitzquake) + MSG_WriteByte (&sv.signon, svc_spawnstaticsound2_fq); + else + MSG_WriteByte (&sv.signon, svc_spawnstaticsound2); + } else MSG_WriteByte (&sv.signon, svc_spawnstaticsound); @@ -505,8 +510,8 @@ static void VM_SV_ambientsound(prvm_prog_t *prog) else MSG_WriteByte (&sv.signon, soundnum); - MSG_WriteByte (&sv.signon, (int)(vol*255)); - MSG_WriteByte (&sv.signon, (int)(attenuation*64)); + MSG_WriteByte (&sv.signon, (vol*255)); + MSG_WriteByte (&sv.signon, (attenuation*64)); } @@ -1520,7 +1525,7 @@ static void VM_SV_WritePicture(prvm_prog_t *prog) static void VM_SV_makestatic(prvm_prog_t *prog) { prvm_edict_t *ent; - int i, large; + int i, bits; // allow 0 parameters due to an id1 qc bug in which this function is used // with no parameters (but directly after setmodel with self in OFS_PARM0) @@ -1541,17 +1546,34 @@ static void VM_SV_makestatic(prvm_prog_t *prog) return; } - large = false; - if (PRVM_serveredictfloat(ent, modelindex) >= 256 || PRVM_serveredictfloat(ent, frame) >= 256) - large = true; - + bits = 0; + if (PRVM_serveredictfloat(ent, modelindex) >= 256) + bits |= B_LARGEMODEL; + if (PRVM_serveredictfloat(ent, frame) >= 256) + bits |= B_LARGEFRAME; + if (sv.protocol == &protocol_fitzquake && PRVM_serveredictfloat(ent, alpha) != ENTALPHA_DEFAULT) + bits |= B_ALPHA; if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) { MSG_WriteByte (&sv.signon,svc_spawnstatic); MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex)); MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, frame)); } - else if (large) + else if (bits && sv.protocol == &protocol_fitzquake) + { + MSG_WriteByte (&sv.signon, svc_spawnstatic2_fq); + MSG_WriteByte (&sv.signon, bits); + if (bits & B_LARGEMODEL) + MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex)); + else + MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex)); + + if (bits & B_LARGEFRAME) + MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, frame)); + else + MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, frame)); + } + else if (bits) { MSG_WriteByte (&sv.signon,svc_spawnstatic2); MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex)); @@ -1572,6 +1594,9 @@ static void VM_SV_makestatic(prvm_prog_t *prog) sv.protocol->WriteAngle(&sv.signon, PRVM_serveredictvector(ent, angles)[i]); } + if(sv.protocol == &protocol_fitzquake && bits & B_ALPHA) + MSG_WriteByte(&sv.signon, (int)PRVM_serveredictfloat(ent, alpha)); + // throw the entity away now PRVM_ED_Free(prog, ent); } -- 2.39.2