// LadyHavoc: thanks to Fuh for bringing the pure evil of SZ_Print to my
// attention, it has been eradicated from here, its only (former) use in
// all of darkplaces.
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ if (cls.protocol == &protocol_quakeworld)
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
else
MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
if ((!strncmp(s, "say ", 4) || !strncmp(s, "say_team ", 9)) && cl_locs_enable.integer)
// update networking ports (this is mainly just needed at startup)
NetConn_UpdateSockets();
- cls.protocol = PROTOCOL_QUAKE;
+ cls.protocol = &protocol_netquake;
Con_Printf("Playing demo %s.\n", name);
cls.demofile = f;
void EntityState_ReadFields(entity_state_t *e, unsigned int bits)
{
- if (cls.protocol == PROTOCOL_DARKPLACES2)
+ if (cls.protocol == &protocol_dpp2)
{
if (bits & E_ORIGIN1)
e->origin[0] = MSG_ReadCoord16i(&cl_message);
e->origin[2] = MSG_ReadCoord32f(&cl_message);
}
}
- if ((cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6) && !(e->flags & RENDER_LOWPRECISION))
+ if ((cls.protocol == &protocol_dpp5 || cls.protocol == &protocol_dpp6) && !(e->flags & RENDER_LOWPRECISION))
{
if (bits & E_ANGLE1)
e->angles[0] = MSG_ReadAngle16i(&cl_message);
e->glowsize = MSG_ReadByte(&cl_message);
if (bits & E_GLOWCOLOR)
e->glowcolor = MSG_ReadByte(&cl_message);
- if (cls.protocol == PROTOCOL_DARKPLACES2)
+ if (cls.protocol == &protocol_dpp2)
if (bits & E_FLAGS)
e->flags = MSG_ReadByte(&cl_message);
if (bits & E_TAGATTACHMENT)
// read the number of this frame to echo back in next input packet
framenum = MSG_ReadLong(&cl_message);
CL_NewFrameReceived(framenum);
- if (cls.protocol != PROTOCOL_QUAKE && cls.protocol != PROTOCOL_QUAKEDP && cls.protocol != PROTOCOL_NEHAHRAMOVIE && cls.protocol != PROTOCOL_DARKPLACES1 && cls.protocol != PROTOCOL_DARKPLACES2 && cls.protocol != PROTOCOL_DARKPLACES3 && cls.protocol != PROTOCOL_DARKPLACES4 && cls.protocol != PROTOCOL_DARKPLACES5 && cls.protocol != PROTOCOL_DARKPLACES6)
+ if (cls.protocol != &protocol_netquake && cls.protocol != &protocol_quakedp && cls.protocol != &protocol_nehahramovie && cls.protocol != &protocol_dpp1 && cls.protocol != &protocol_dpp2 && cls.protocol != &protocol_dpp3 && cls.protocol != &protocol_dpp4 && cls.protocol != &protocol_dpp5 && cls.protocol != &protocol_dpp6)
cls.servermovesequence = MSG_ReadLong(&cl_message);
// read entity numbers until we find a 0x8000
// (which would be remove world entity, but is actually a terminator)
if (bits & U_MOREBITS)
bits |= (MSG_ReadByte(&cl_message)<<8);
- if ((bits & U_EXTEND1) && cls.protocol != PROTOCOL_NEHAHRAMOVIE)
+ if ((bits & U_EXTEND1) && cls.protocol != &protocol_nehahramovie)
{
bits |= MSG_ReadByte(&cl_message) << 16;
if (bits & U_EXTEND2)
s.flags = 0;
if (bits & U_MODEL)
{
- if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
+ if (cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3)
s.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
else
s.modelindex = (s.modelindex & 0xFF00) | MSG_ReadByte(&cl_message);
if (bits & U_COLORMAP) s.colormap = MSG_ReadByte(&cl_message);
if (bits & U_SKIN) s.skin = MSG_ReadByte(&cl_message);
if (bits & U_EFFECTS) s.effects = (s.effects & 0xFF00) | MSG_ReadByte(&cl_message);
- if (bits & U_ORIGIN1) s.origin[0] = MSG_ReadCoord(&cl_message, cls.protocol);
- if (bits & U_ANGLE1) s.angles[0] = MSG_ReadAngle(&cl_message, cls.protocol);
- if (bits & U_ORIGIN2) s.origin[1] = MSG_ReadCoord(&cl_message, cls.protocol);
- if (bits & U_ANGLE2) s.angles[1] = MSG_ReadAngle(&cl_message, cls.protocol);
- if (bits & U_ORIGIN3) s.origin[2] = MSG_ReadCoord(&cl_message, cls.protocol);
- if (bits & U_ANGLE3) s.angles[2] = MSG_ReadAngle(&cl_message, cls.protocol);
+ if (bits & U_ORIGIN1) s.origin[0] = cls.protocol->ReadCoord(&cl_message);
+ if (bits & U_ANGLE1) s.angles[0] = cls.protocol->ReadAngle(&cl_message);
+ if (bits & U_ORIGIN2) s.origin[1] = cls.protocol->ReadCoord(&cl_message);
+ if (bits & U_ANGLE2) s.angles[1] = cls.protocol->ReadAngle(&cl_message);
+ if (bits & U_ORIGIN3) s.origin[2] = cls.protocol->ReadCoord(&cl_message);
+ if (bits & U_ANGLE3) s.angles[2] = cls.protocol->ReadAngle(&cl_message);
if (bits & U_STEP) s.flags |= RENDER_STEP;
if (bits & U_ALPHA) s.alpha = MSG_ReadByte(&cl_message);
if (bits & U_SCALE) s.scale = MSG_ReadByte(&cl_message);
if (bits & U_EXTERIORMODEL) s.flags |= RENDER_EXTERIORMODEL;
// LadyHavoc: to allow playback of the Nehahra movie
- if (cls.protocol == PROTOCOL_NEHAHRAMOVIE && (bits & U_EXTEND1))
+ if (cls.protocol == &protocol_nehahramovie && (bits & U_EXTEND1))
{
// LadyHavoc: evil format
int i = (int)MSG_ReadFloat(&cl_message);
s->number = enumber;
s->colormap = enumber;
playerflags = MSG_ReadShort(&cl_message);
- MSG_ReadVector(&cl_message, s->origin, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, s->origin);
s->frame = MSG_ReadByte(&cl_message);
VectorClear(viewangles);
if (s->waterjumptime <= 0)
{
// water friction
- f = 1 - s->cmd.frametime * cl.movevars_waterfriction * (cls.protocol == PROTOCOL_QUAKEWORLD ? s->waterlevel : 1);
+ f = 1 - s->cmd.frametime * cl.movevars_waterfriction * (cls.protocol == &protocol_quakeworld ? s->waterlevel : 1);
f = bound(0, f, 1);
VectorScale(s->velocity, f, s->velocity);
// this mimics it for compatibility
VectorSet(neworigin2, s->origin[0] + s->velocity[0]*(16/f), s->origin[1] + s->velocity[1]*(16/f), s->origin[2] + s->mins[2]);
VectorSet(neworigin3, neworigin2[0], neworigin2[1], neworigin2[2] - 34);
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
trace = CL_TraceBox(neworigin2, s->mins, s->maxs, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true);
else
trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true, false);
else
s->velocity[2] -= gravity;
}
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
s->velocity[2] = 0;
if (VectorLength2(s->velocity))
CL_ClientMovement_Move(s);
extern cvar_t host_timescale;
void CL_UpdateMoveVars(void)
{
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
cl.moveflags = 0;
}
cl.cmd.msec = 100;
cl.cmd.frametime = cl.cmd.msec * (1.0 / 1000.0);
- switch(cls.protocol)
+ switch(cls.protocol->num)
{
case PROTOCOL_QUAKEWORLD:
// quakeworld uses a different cvar with opposite meaning, for compatibility
cl.cmd.jump = (cl.cmd.buttons & 2) != 0;
cl.cmd.crouch = 0;
- switch (cls.protocol)
+ switch (cls.protocol->num)
{
case PROTOCOL_QUAKEWORLD:
case PROTOCOL_QUAKE:
- case PROTOCOL_QUAKEDP:
case PROTOCOL_NEHAHRAMOVIE:
case PROTOCOL_NEHAHRABJP:
case PROTOCOL_NEHAHRABJP2:
}
// do not send 0ms packets because they mess up physics
- if(cl.cmd.msec == 0 && cl.time > cl.oldtime && (cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon == SIGNONS))
+ if(cl.cmd.msec == 0 && cl.time > cl.oldtime && (cls.protocol == &protocol_quakeworld || cls.signon == SIGNONS))
return;
// always send if buttons changed or an impulse is pending
// even if it violates the rate limit!
// set prydon cursor info
CL_UpdatePrydonCursor();
- if (cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon == SIGNONS)
+ if (cls.protocol == &protocol_quakeworld || cls.signon == SIGNONS)
{
- switch (cls.protocol)
+ switch (cls.protocol->num)
{
case PROTOCOL_QUAKEWORLD:
- MSG_WriteByte(&buf, qw_clc_move);
+ MSG_WriteByte(&buf, clc_move);
// save the position for a checksum byte
checksumindex = buf.cursize;
MSG_WriteByte(&buf, 0);
if (cl.qw_validsequence && !cl_nodelta.integer && cls.state == ca_connected && !cls.demorecording)
{
cl.qw_deltasequence[cls.netcon->outgoing_unreliable_sequence & QW_UPDATE_MASK] = cl.qw_validsequence;
- MSG_WriteByte(&buf, qw_clc_delta);
+ MSG_WriteByte(&buf, clc_delta);
MSG_WriteByte(&buf, cl.qw_validsequence & 255);
}
else
cl.qw_deltasequence[cls.netcon->outgoing_unreliable_sequence & QW_UPDATE_MASK] = -1;
break;
case PROTOCOL_QUAKE:
- case PROTOCOL_QUAKEDP:
case PROTOCOL_NEHAHRAMOVIE:
case PROTOCOL_NEHAHRABJP:
case PROTOCOL_NEHAHRABJP2:
continue;
// 5/9 bytes
MSG_WriteByte (&buf, clc_move);
- if (cls.protocol != PROTOCOL_DARKPLACES6)
+ if (cls.protocol != &protocol_dpp6)
MSG_WriteLong (&buf, cmd->predicted ? cmd->sequence : 0);
MSG_WriteFloat (&buf, cmd->time); // last server packet time
// 6 bytes
}
}
- if (cls.protocol != PROTOCOL_QUAKEWORLD && buf.cursize)
+ if (cls.protocol != &protocol_quakeworld && buf.cursize)
{
// ack entity frame numbers received since the last input was sent
// (redundent to improve handling of client->server packet loss)
InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), key, value);
if (cls.state == ca_connected && cls.netcon)
{
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "setinfo \"%s\" \"%s\"", key, value));
}
else if (!strcasecmp(key, "name"))
memset(&buf, 0, sizeof(buf));
buf.data = bufdata;
buf.maxsize = sizeof(bufdata);
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
Con_DPrint("Sending drop command\n");
- MSG_WriteByte(&buf, qw_clc_stringcmd);
+ MSG_WriteByte(&buf, clc_stringcmd);
MSG_WriteString(&buf, "drop");
}
else
return;
}
// if connected, do something based on protocol
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
// quakeworld can just re-login
if (cls.qw_downloadmemory) // don't change when downloading
if (cls.state == ca_connected)
{
Con_Printf("Server is changing level...\n");
- MSG_WriteChar(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteChar(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, "new");
}
}
if (!(e->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST))
&& (e->render.alpha >= 1)
&& !(e->render.flags & RENDER_VIEWMODEL)
- && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer)))
+ && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != &protocol_nehahramovie && !cl_noplayershadow.integer)))
e->render.flags |= RENDER_SHADOW;
if (e->render.flags & RENDER_VIEWMODEL)
e->render.flags |= RENDER_NOSELFSHADOW;
// cl_parse.c -- parse a message received from the server
#include "quakedef.h"
+#include "cl_parse.h"
#include "cdaudio.h"
#include "cl_collision.h"
#include "csprogs.h"
#endif
#include "cl_video.h"
-const char *svc_strings[128] =
-{
- "svc_bad",
- "svc_nop",
- "svc_disconnect",
- "svc_updatestat",
- "svc_version", // [int] server version
- "svc_setview", // [short] entity number
- "svc_sound", // <see code>
- "svc_time", // [float] server time
- "svc_print", // [string] null terminated string
- "svc_stufftext", // [string] stuffed into client's console buffer
- // the string should be \n terminated
- "svc_setangle", // [vec3] set the view angle to this absolute value
-
- "svc_serverinfo", // [int] version
- // [string] signon string
- // [string]..[0]model cache [string]...[0]sounds cache
- // [string]..[0]item cache
- "svc_lightstyle", // [byte] [string]
- "svc_updatename", // [byte] [string]
- "svc_updatefrags", // [byte] [short]
- "svc_clientdata", // <shortbits + data>
- "svc_stopsound", // <see code>
- "svc_updatecolors", // [byte] [byte]
- "svc_particle", // [vec3] <variable>
- "svc_damage", // [byte] impact [byte] blood [vec3] from
-
- "svc_spawnstatic",
- "OBSOLETE svc_spawnbinary",
- "svc_spawnbaseline",
-
- "svc_temp_entity", // <variable>
- "svc_setpause",
- "svc_signonnum",
- "svc_centerprint",
- "svc_killedmonster",
- "svc_foundsecret",
- "svc_spawnstaticsound",
- "svc_intermission",
- "svc_finale", // [string] music [string] text
- "svc_cdtrack", // [byte] track [byte] looptrack
- "svc_sellscreen",
- "svc_cutscene",
- "svc_showlmp", // [string] iconlabel [string] lmpfile [short] x [short] y
- "svc_hidelmp", // [string] iconlabel
- "svc_skybox", // [string] skyname
- "", // 38
- "", // 39
- "", // 40
- "", // 41
- "", // 42
- "", // 43
- "", // 44
- "", // 45
- "", // 46
- "", // 47
- "", // 48
- "", // 49
- "svc_downloaddata", // 50 // [int] start [short] size [variable length] data
- "svc_updatestatubyte", // 51 // [byte] stat [byte] value
- "svc_effect", // 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
- "svc_effect2", // 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
- "svc_sound2", // 54 // short soundindex instead of byte
- "svc_spawnbaseline2", // 55 // short modelindex instead of byte
- "svc_spawnstatic2", // 56 // short modelindex instead of byte
- "svc_entities", // 57 // [int] deltaframe [int] thisframe [float vector] eye [variable length] entitydata
- "svc_csqcentities", // 58 // [short] entnum [variable length] entitydata ... [short] 0x0000
- "svc_spawnstaticsound2", // 59 // [coord3] [short] samp [byte] vol [byte] aten
- "svc_trailparticles", // 60 // [short] entnum [short] effectnum [vector] start [vector] end
- "svc_pointparticles", // 61 // [short] effectnum [vector] start [vector] velocity [short] count
- "svc_pointparticles1", // 62 // [short] effectnum [vector] start, same as svc_pointparticles except velocity is zero and count is 1
-};
-
-const char *qw_svc_strings[128] =
-{
- "qw_svc_bad", // 0
- "qw_svc_nop", // 1
- "qw_svc_disconnect", // 2
- "qw_svc_updatestat", // 3 // [byte] [byte]
- "", // 4
- "qw_svc_setview", // 5 // [short] entity number
- "qw_svc_sound", // 6 // <see code>
- "", // 7
- "qw_svc_print", // 8 // [byte] id [string] null terminated string
- "qw_svc_stufftext", // 9 // [string] stuffed into client's console buffer
- "qw_svc_setangle", // 10 // [angle3] set the view angle to this absolute value
- "qw_svc_serverdata", // 11 // [long] protocol ...
- "qw_svc_lightstyle", // 12 // [byte] [string]
- "", // 13
- "qw_svc_updatefrags", // 14 // [byte] [short]
- "", // 15
- "qw_svc_stopsound", // 16 // <see code>
- "", // 17
- "", // 18
- "qw_svc_damage", // 19
- "qw_svc_spawnstatic", // 20
- "", // 21
- "qw_svc_spawnbaseline", // 22
- "qw_svc_temp_entity", // 23 // variable
- "qw_svc_setpause", // 24 // [byte] on / off
- "", // 25
- "qw_svc_centerprint", // 26 // [string] to put in center of the screen
- "qw_svc_killedmonster", // 27
- "qw_svc_foundsecret", // 28
- "qw_svc_spawnstaticsound", // 29 // [coord3] [byte] samp [byte] vol [byte] aten
- "qw_svc_intermission", // 30 // [vec3_t] origin [vec3_t] angle
- "qw_svc_finale", // 31 // [string] text
- "qw_svc_cdtrack", // 32 // [byte] track
- "qw_svc_sellscreen", // 33
- "qw_svc_smallkick", // 34 // set client punchangle to 2
- "qw_svc_bigkick", // 35 // set client punchangle to 4
- "qw_svc_updateping", // 36 // [byte] [short]
- "qw_svc_updateentertime", // 37 // [byte] [float]
- "qw_svc_updatestatlong", // 38 // [byte] [long]
- "qw_svc_muzzleflash", // 39 // [short] entity
- "qw_svc_updateuserinfo", // 40 // [byte] slot [long] uid
- "qw_svc_download", // 41 // [short] size [size bytes]
- "qw_svc_playerinfo", // 42 // variable
- "qw_svc_nails", // 43 // [byte] num [48 bits] xyzpy 12 12 12 4 8
- "qw_svc_chokecount", // 44 // [byte] packets choked
- "qw_svc_modellist", // 45 // [strings]
- "qw_svc_soundlist", // 46 // [strings]
- "qw_svc_packetentities", // 47 // [...]
- "qw_svc_deltapacketentities", // 48 // [...]
- "qw_svc_maxspeed", // 49 // maxspeed change, for prediction
- "qw_svc_entgravity", // 50 // gravity change, for prediction
- "qw_svc_setinfo", // 51 // setinfo on a client
- "qw_svc_serverinfo", // 52 // serverinfo
- "qw_svc_updatepl", // 53 // [byte] [byte]
-};
-
//=============================================================================
cvar_t cl_worldmessage = {CF_CLIENT | CF_READONLY, "cl_worldmessage", "", "title of current level"};
CL_ParseStartSoundPacket
==================
*/
-static void CL_ParseStartSoundPacket(int largesoundindex)
+void CL_ParseStartSoundPacket(int largesoundindex)
{
vec3_t pos;
int channel, ent;
float speed;
int fflags = CHANNELFLAG_NONE;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
channel = MSG_ReadShort(&cl_message);
channel &= 7;
}
- if (largesoundindex || (field_mask & SND_LARGESOUND) || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
+ if (largesoundindex || (field_mask & SND_LARGESOUND) || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3)
sound_num = (unsigned short) MSG_ReadShort(&cl_message);
else
sound_num = MSG_ReadByte(&cl_message);
}
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
if (sound_num < 0 || sound_num >= MAX_SOUNDS)
{
}
// no need if server is local and definitely not if this is a demo
- if (sv.active || !cls.netcon || cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon >= SIGNONS)
+ if (sv.active || !cls.netcon || cls.protocol == &protocol_quakeworld || cls.signon >= SIGNONS)
{
recursive = thisrecursive;
return;
cls.qw_downloadmemorymaxsize = 1024*1024; // start out with a 1MB buffer
}
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "download %s", filename));
cls.qw_downloadnumber++;
{
cls.signon = SIGNONS-1;
// we'll go to SIGNONS when the first entity update is received
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "begin %i", cl.qw_servercount));
}
break;
CL_SetInfo("emodel", va(vabuf, sizeof(vabuf), "%i", FS_CRCFile("progs/eyes.mdl", NULL)), true, true, true, true);
// done checking sounds and models, send a prespawn command now
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "prespawn %i 0 %i", cl.qw_servercount, cl.model_precache[1]->brush.qw_md4sum2));
if (cls.qw_downloadmemory)
Mem_CheckSentinelsGlobal();
// done with sound downloads, next we check models
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "modellist %i %i", cl.qw_servercount, 0));
break;
case dl_none:
}
}
-static void QW_CL_ParseDownload(void)
+void QW_CL_ParseDownload(void)
{
int size = (signed short)MSG_ReadShort(&cl_message);
int percent = MSG_ReadByte(&cl_message);
if (percent != 100)
{
// request next fragment
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, "nextdl");
}
else
}
}
-static void QW_CL_ParseModelList(void)
+void QW_CL_ParseModelList(void)
{
int n;
int nummodels = MSG_ReadByte(&cl_message);
n = MSG_ReadByte(&cl_message);
if (n)
{
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "modellist %i %i", cl.qw_servercount, n));
return;
}
QW_CL_RequestNextDownload();
}
-static void QW_CL_ParseSoundList(void)
+void QW_CL_ParseSoundList(void)
{
int n;
int numsounds = MSG_ReadByte(&cl_message);
if (n)
{
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "soundlist %i %i", cl.qw_servercount, n));
return;
}
size = min(1, cls.qw_uploadsize);
percent = (cls.qw_uploadpos+r)*100/size;
- MSG_WriteByte(&cls.netcon->message, qw_clc_upload);
+ MSG_WriteByte(&cls.netcon->message, clc_upload);
MSG_WriteShort(&cls.netcon->message, r);
MSG_WriteByte(&cls.netcon->message, percent);
SZ_Write(&cls.netcon->message, cls.qw_uploaddata + cls.qw_uploadpos, r);
// TODO: skin cache
}
-static void QW_CL_UpdateUserInfo(void)
+void QW_CL_UpdateUserInfo(void)
{
int slot;
slot = MSG_ReadByte(&cl_message);
QW_CL_ProcessUserInfo(slot);
}
-static void QW_CL_SetInfo(void)
+void QW_CL_SetInfo(void)
{
int slot;
char key[2048];
QW_CL_ProcessUserInfo(slot);
}
-static void QW_CL_ServerInfo(void)
+void QW_CL_ServerInfo(void)
{
char key[2048];
char value[2048];
cl.qw_teamplay = atoi(temp);
}
-static void QW_CL_ParseNails(void)
+void QW_CL_ParseNails(void)
{
int i, j;
int numnails = MSG_ReadByte(&cl_message);
}
}
-static void CL_UpdateItemsAndWeapon(void)
+void CL_UpdateItemsAndWeapon(void)
{
int j;
// check for important changes
{
char vabuf[1024];
// quakeworld works differently
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
return;
// this would be a good place to do curl downloads
cls.qw_downloadpercent = 0;
}
-static void CL_ParseDownload(void)
+void CL_ParseDownload(void)
{
int i, start, size;
static unsigned char data[NET_MAXMESSAGE];
An svc_signonnum has been received, perform a client side setup
=====================
*/
-static void CL_SignonReply (void)
+void CL_SignonReply (void)
{
Con_DPrintf("CL_SignonReply: %i\n", cls.signon);
CL_ParseServerInfo
==================
*/
-static void CL_ParseServerInfo (void)
+void CL_ParseServerInfo (void)
{
char *str;
int i;
- protocolversion_t protocol;
+ protocol_t *protocol;
int nummodels, numsounds;
char vabuf[1024];
// parse protocol version number
i = MSG_ReadLong(&cl_message);
- protocol = Protocol_EnumForNumber(i);
- if (protocol == PROTOCOL_UNKNOWN)
+ protocol = Protocol_ForNumber(i);
+ if (!protocol)
{
Host_Error("CL_ParseServerInfo: Server is unrecognized protocol number (%i)", i);
return;
}
// hack for unmarked Nehahra movie demos which had a custom protocol
- if (protocol == PROTOCOL_QUAKEDP && cls.demoplayback && gamemode == GAME_NEHAHRA)
- protocol = PROTOCOL_NEHAHRAMOVIE;
+ if (protocol == &protocol_quakedp && cls.demoplayback && gamemode == GAME_NEHAHRA)
+ protocol = &protocol_nehahramovie;
cls.protocol = protocol;
- Con_Printf("Server protocol is %s\n", Protocol_NameForEnum(cls.protocol));
+ Con_Printf("Server protocol is %s\n", protocol->name);
cl.num_entities = 1;
- if (protocol == PROTOCOL_QUAKEWORLD)
+ if (protocol == &protocol_quakeworld)
{
char gamedir[1][MAX_QPATH];
if (cls.netcon)
{
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, va(vabuf, sizeof(vabuf), "soundlist %i %i", cl.qw_servercount, 0));
}
cl.gametype = MSG_ReadByte(&cl_message);
// the original id singleplayer demos are bugged and contain
// GAME_DEATHMATCH even for singleplayer
- if (cl.maxclients == 1 && cls.protocol == PROTOCOL_QUAKE)
+ if (cl.maxclients == 1 && cls.protocol == &protocol_netquake)
cl.gametype = GAME_COOP;
// parse signon message
strlcpy (cl.worldmessage, str, sizeof(cl.worldmessage));
// seperate the printfs so the server message can have a color
- if (cls.protocol != PROTOCOL_NEHAHRAMOVIE) // no messages when playing the Nehahra movie
+ if (cls.protocol != &protocol_nehahramovie) // no messages when playing the Nehahra movie
Con_Printf("\n<===================================>\n\n\2%s\n", str);
// check memory integrity
Mem_CheckSentinelsGlobal();
// if cl_autodemo is set, automatically start recording a demo if one isn't being recorded already
- if (cl_autodemo.integer && cls.netcon && cls.protocol != PROTOCOL_QUAKEWORLD)
+ if (cl_autodemo.integer && cls.netcon && cls.protocol != &protocol_quakeworld)
{
char demofile[MAX_OSPATH];
CL_ParseBaseline
==================
*/
-static void CL_ParseBaseline (entity_t *ent, int large)
+void CL_ParseBaseline (entity_t *ent, int large)
{
int i;
ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
ent->state_baseline.frame = (unsigned short) MSG_ReadShort(&cl_message);
}
- else if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
+ else if (cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3)
{
ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort(&cl_message);
ent->state_baseline.frame = MSG_ReadByte(&cl_message);
ent->state_baseline.skin = MSG_ReadByte(&cl_message);
for (i = 0;i < 3;i++)
{
- ent->state_baseline.origin[i] = MSG_ReadCoord(&cl_message, cls.protocol);
- ent->state_baseline.angles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
+ ent->state_baseline.origin[i] = cls.protocol->ReadCoord(&cl_message);
+ ent->state_baseline.angles[i] = cls.protocol->ReadAngle(&cl_message);
}
ent->state_previous = ent->state_current = ent->state_baseline;
}
Server information pertaining to this client only
==================
*/
-static void CL_ParseClientdata (void)
+void CL_ParseClientdata (void)
{
int i, bits;
VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
cl.mviewzoom[1] = cl.mviewzoom[0];
- if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5)
+ if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5)
{
cl.stats[STAT_VIEWHEIGHT] = DEFAULT_VIEWHEIGHT;
cl.stats[STAT_ITEMS] = 0;
{
if (bits & (SU_PUNCH1<<i) )
{
- if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
+ if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3)
cl.mpunchangle[0][i] = MSG_ReadChar(&cl_message);
else
cl.mpunchangle[0][i] = MSG_ReadAngle16i(&cl_message);
}
if (bits & (SU_PUNCHVEC1<<i))
{
- if (cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
+ if (cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4)
cl.mpunchvector[0][i] = MSG_ReadCoord16i(&cl_message);
else
cl.mpunchvector[0][i] = MSG_ReadCoord32f(&cl_message);
}
if (bits & (SU_VELOCITY1<<i) )
{
- if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
+ if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4)
cl.mvelocity[0][i] = MSG_ReadChar(&cl_message)*16;
else
cl.mvelocity[0][i] = MSG_ReadCoord32f(&cl_message);
}
// LadyHavoc: hipnotic demos don't have this bit set but should
- if (bits & SU_ITEMS || cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5)
+ if (bits & SU_ITEMS || cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5)
cl.stats[STAT_ITEMS] = MSG_ReadLong(&cl_message);
cl.onground = (bits & SU_ONGROUND) != 0;
cl.inwater = (bits & SU_INWATER) != 0;
- if (cls.protocol == PROTOCOL_DARKPLACES5)
+ if (cls.protocol == &protocol_dpp5)
{
cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadShort(&cl_message) : 0;
cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadShort(&cl_message) : 0;
cl.stats[STAT_CELLS] = MSG_ReadShort(&cl_message);
cl.stats[STAT_ACTIVEWEAPON] = (unsigned short) MSG_ReadShort(&cl_message);
}
- else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
+ else if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4)
{
cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte(&cl_message) : 0;
cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte(&cl_message) : 0;
- if (cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3)
+ if (cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3)
cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? (unsigned short)MSG_ReadShort(&cl_message) : 0;
else
cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte(&cl_message) : 0;
if (bits & SU_VIEWZOOM)
{
- if (cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4)
+ if (cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4)
cl.stats[STAT_VIEWZOOM] = MSG_ReadByte(&cl_message);
else
cl.stats[STAT_VIEWZOOM] = (unsigned short) MSG_ReadShort(&cl_message);
CL_ParseStatic
=====================
*/
-static void CL_ParseStatic (int large)
+void CL_ParseStatic (int large)
{
entity_t *ent;
CL_ParseStaticSound
===================
*/
-static void CL_ParseStaticSound (int large)
+void CL_ParseStaticSound (int large)
{
vec3_t org;
int sound_num, vol, atten;
- MSG_ReadVector(&cl_message, org, cls.protocol);
- if (large || cls.protocol == PROTOCOL_NEHAHRABJP2)
+ cls.protocol->ReadVector(&cl_message, org);
+ if (large || cls.protocol == &protocol_nehahrabjp2)
sound_num = (unsigned short) MSG_ReadShort(&cl_message);
else
sound_num = MSG_ReadByte(&cl_message);
S_StaticSound (cl.sound_precache[sound_num], org, vol/255.0f, atten);
}
-static void CL_ParseEffect (void)
+void CL_ParseEffect (void)
{
vec3_t org;
int modelindex, startframe, framecount, framerate;
- MSG_ReadVector(&cl_message, org, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, org);
modelindex = MSG_ReadByte(&cl_message);
startframe = MSG_ReadByte(&cl_message);
framecount = MSG_ReadByte(&cl_message);
CL_Effect(org, CL_GetModelByIndex(modelindex), startframe, framecount, framerate);
}
-static void CL_ParseEffect2 (void)
+void CL_ParseEffect2 (void)
{
vec3_t org;
int modelindex, startframe, framecount, framerate;
- MSG_ReadVector(&cl_message, org, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, org);
modelindex = (unsigned short) MSG_ReadShort(&cl_message);
startframe = (unsigned short) MSG_ReadShort(&cl_message);
framecount = MSG_ReadByte(&cl_message);
vec3_t start, end;
ent = (unsigned short) MSG_ReadShort(&cl_message);
- MSG_ReadVector(&cl_message, start, cls.protocol);
- MSG_ReadVector(&cl_message, end, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, start);
+ cls.protocol->ReadVector(&cl_message, end);
if (ent >= MAX_EDICTS)
{
CL_NewBeam(ent, start, end, m, lightning);
}
-static void CL_ParseTempEntity(void)
+void CL_ParseTempEntity(void)
{
int type;
vec3_t pos, pos2;
unsigned char *tempcolor;
matrix4x4_t tempmatrix;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
type = MSG_ReadByte(&cl_message);
switch (type)
{
case QW_TE_WIZSPIKE:
// spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_wizhit, pos, 1, 1);
case QW_TE_KNIGHTSPIKE:
// spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_knighthit, pos, 1, 1);
case QW_TE_SPIKE:
// spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5)
break;
case QW_TE_SUPERSPIKE:
// super spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5)
case QW_TE_EXPLOSION:
// rocket explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
case QW_TE_TAREXPLOSION:
// tarbaby explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
break;
case QW_TE_LAVASPLASH:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case QW_TE_TELEPORT:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case QW_TE_GUNSHOT:
// bullet hitting wall
radius = MSG_ReadByte(&cl_message);
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
VectorSet(pos2, pos[0] + radius, pos[1] + radius, pos[2] + radius);
VectorSet(pos, pos[0] - radius, pos[1] - radius, pos[2] - radius);
case QW_TE_BLOOD:
count = MSG_ReadByte(&cl_message);
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_BLOOD, count, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case QW_TE_LIGHTNINGBLOOD:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_BLOOD, 2.5, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
{
case TE_WIZSPIKE:
// spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_wizhit, pos, 1, 1);
case TE_KNIGHTSPIKE:
// spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_knighthit, pos, 1, 1);
case TE_SPIKE:
// spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5)
break;
case TE_SPIKEQUAD:
// quad spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_SPIKEQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5)
break;
case TE_SUPERSPIKE:
// super spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5)
break;
case TE_SUPERSPIKEQUAD:
// quad super spike hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_SUPERSPIKEQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5)
// LadyHavoc: added for improved blood splatters
case TE_BLOOD:
// blood puff
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
dir[0] = MSG_ReadChar(&cl_message);
dir[1] = MSG_ReadChar(&cl_message);
break;
case TE_SPARK:
// spark shower
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
dir[0] = MSG_ReadChar(&cl_message);
dir[1] = MSG_ReadChar(&cl_message);
CL_ParticleEffect(EFFECT_TE_SPARK, count, pos, pos, dir, dir, NULL, 0);
break;
case TE_PLASMABURN:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
// LadyHavoc: added for improved gore
case TE_BLOODSHOWER:
// vaporized body
- MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
- MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
- velspeed = MSG_ReadCoord(&cl_message, cls.protocol); // speed
+ cls.protocol->ReadVector(&cl_message, pos); // mins
+ cls.protocol->ReadVector(&cl_message, pos2); // maxs
+ velspeed = cls.protocol->ReadCoord(&cl_message); // speed
count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
vel1[0] = -velspeed;
vel1[1] = -velspeed;
case TE_PARTICLECUBE:
// general purpose particle effect
- MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
- MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
- MSG_ReadVector(&cl_message, dir, cls.protocol); // dir
+ cls.protocol->ReadVector(&cl_message, pos); // mins
+ cls.protocol->ReadVector(&cl_message, pos2); // maxs
+ cls.protocol->ReadVector(&cl_message, dir); // dir
count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
colorStart = MSG_ReadByte(&cl_message); // color
colorLength = MSG_ReadByte(&cl_message); // gravity (1 or 0)
- velspeed = MSG_ReadCoord(&cl_message, cls.protocol); // randomvel
+ velspeed = cls.protocol->ReadCoord(&cl_message); // randomvel
CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength != 0, velspeed);
break;
case TE_PARTICLERAIN:
// general purpose particle effect
- MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
- MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
- MSG_ReadVector(&cl_message, dir, cls.protocol); // dir
+ cls.protocol->ReadVector(&cl_message, pos); // mins
+ cls.protocol->ReadVector(&cl_message, pos2); // maxs
+ cls.protocol->ReadVector(&cl_message, dir); // dir
count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
colorStart = MSG_ReadByte(&cl_message); // color
CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
case TE_PARTICLESNOW:
// general purpose particle effect
- MSG_ReadVector(&cl_message, pos, cls.protocol); // mins
- MSG_ReadVector(&cl_message, pos2, cls.protocol); // maxs
- MSG_ReadVector(&cl_message, dir, cls.protocol); // dir
+ cls.protocol->ReadVector(&cl_message, pos); // mins
+ cls.protocol->ReadVector(&cl_message, pos2); // maxs
+ cls.protocol->ReadVector(&cl_message, dir); // dir
count = (unsigned short) MSG_ReadShort(&cl_message); // number of particles
colorStart = MSG_ReadByte(&cl_message); // color
CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
case TE_GUNSHOT:
// bullet hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if(cl_sound_ric_gunshot.integer & RIC_GUNSHOT)
case TE_GUNSHOTQUAD:
// quad bullet hitting wall
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
if(cl_sound_ric_gunshot.integer & RIC_GUNSHOTQUAD)
case TE_EXPLOSION:
// rocket explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
case TE_EXPLOSIONQUAD:
// quad rocket explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_EXPLOSIONQUAD, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
case TE_EXPLOSION3:
// Nehahra movie colored lighting explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
- color[0] = MSG_ReadCoord(&cl_message, cls.protocol) * (2.0f / 1.0f);
- color[1] = MSG_ReadCoord(&cl_message, cls.protocol) * (2.0f / 1.0f);
- color[2] = MSG_ReadCoord(&cl_message, cls.protocol) * (2.0f / 1.0f);
+ color[0] = cls.protocol->ReadCoord(&cl_message) * (2.0f / 1.0f);
+ color[1] = cls.protocol->ReadCoord(&cl_message) * (2.0f / 1.0f);
+ color[2] = cls.protocol->ReadCoord(&cl_message) * (2.0f / 1.0f);
CL_ParticleExplosion(pos);
Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]);
CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
case TE_EXPLOSIONRGB:
// colored lighting explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleExplosion(pos);
color[0] = MSG_ReadByte(&cl_message) * (2.0f / 255.0f);
case TE_TAREXPLOSION:
// tarbaby explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
break;
case TE_SMALLFLASH:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_SMALLFLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case TE_CUSTOMFLASH:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 4);
radius = (MSG_ReadByte(&cl_message) + 1) * 8;
velspeed = (MSG_ReadByte(&cl_message) + 1) * (1.0 / 256.0);
break;
case TE_FLAMEJET:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
- MSG_ReadVector(&cl_message, dir, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
+ cls.protocol->ReadVector(&cl_message, dir);
count = MSG_ReadByte(&cl_message);
CL_ParticleEffect(EFFECT_TE_FLAMEJET, count, pos, pos, dir, dir, NULL, 0);
break;
break;
case TE_LAVASPLASH:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case TE_TELEPORT:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case TE_EXPLOSION2:
// color mapped explosion
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
colorStart = MSG_ReadByte(&cl_message);
colorLength = MSG_ReadByte(&cl_message);
break;
case TE_TEI_G3:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
- MSG_ReadVector(&cl_message, pos2, cls.protocol);
- MSG_ReadVector(&cl_message, dir, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
+ cls.protocol->ReadVector(&cl_message, pos2);
+ cls.protocol->ReadVector(&cl_message, dir);
CL_ParticleTrail(EFFECT_TE_TEI_G3, 1, pos, pos2, dir, dir, NULL, 0, true, true, NULL, NULL, 1);
break;
case TE_TEI_SMOKE:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
- MSG_ReadVector(&cl_message, dir, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
+ cls.protocol->ReadVector(&cl_message, dir);
count = MSG_ReadByte(&cl_message);
CL_FindNonSolidLocation(pos, pos, 4);
CL_ParticleEffect(EFFECT_TE_TEI_SMOKE, count, pos, pos, vec3_origin, vec3_origin, NULL, 0);
break;
case TE_TEI_BIGEXPLOSION:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
CL_FindNonSolidLocation(pos, pos, 10);
CL_ParticleEffect(EFFECT_TE_TEI_BIGEXPLOSION, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos, 1, 1);
break;
case TE_TEI_PLASMAHIT:
- MSG_ReadVector(&cl_message, pos, cls.protocol);
- MSG_ReadVector(&cl_message, dir, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, pos);
+ cls.protocol->ReadVector(&cl_message, dir);
count = MSG_ReadByte(&cl_message);
CL_FindNonSolidLocation(pos, pos, 5);
CL_ParticleEffect(EFFECT_TE_TEI_PLASMAHIT, count, pos, pos, vec3_origin, vec3_origin, NULL, 0);
}
}
-static void CL_ParseTrailParticles(void)
+void CL_ParseTrailParticles(void)
{
int entityindex;
int effectindex;
if (entityindex >= cl.max_entities)
CL_ExpandEntities(entityindex);
effectindex = (unsigned short)MSG_ReadShort(&cl_message);
- MSG_ReadVector(&cl_message, start, cls.protocol);
- MSG_ReadVector(&cl_message, end, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, start);
+ cls.protocol->ReadVector(&cl_message, end);
CL_ParticleTrail(effectindex, 1, start, end, vec3_origin, vec3_origin, entityindex > 0 ? cl.entities + entityindex : NULL, 0, true, true, NULL, NULL, 1);
}
-static void CL_ParsePointParticles(void)
+void CL_ParsePointParticles(void)
{
int effectindex, count;
vec3_t origin, velocity;
effectindex = (unsigned short)MSG_ReadShort(&cl_message);
- MSG_ReadVector(&cl_message, origin, cls.protocol);
- MSG_ReadVector(&cl_message, velocity, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, origin);
+ cls.protocol->ReadVector(&cl_message, velocity);
count = (unsigned short)MSG_ReadShort(&cl_message);
CL_ParticleEffect(effectindex, count, origin, origin, velocity, velocity, NULL, 0);
}
-static void CL_ParsePointParticles1(void)
+void CL_ParsePointParticles1(void)
{
int effectindex;
vec3_t origin;
effectindex = (unsigned short)MSG_ReadShort(&cl_message);
- MSG_ReadVector(&cl_message, origin, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, origin);
CL_ParticleEffect(effectindex, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0);
}
}
// look for anything interesting like player IP addresses or ping reports
-static qbool CL_ExaminePrintString(const char *text)
+qbool CL_ExaminePrintString(const char *text)
{
int len;
const char *t;
extern cvar_t host_timescale;
extern cvar_t cl_lerpexcess;
-static void CL_NetworkTimeReceived(double newtime)
+void CL_NetworkTimeReceived(double newtime)
{
double timehigh;
cl.mtime[1] = cl.mtime[0];
if (cl.time < newtime - 0.1)
cl.mtime[1] = cl.time = newtime;
}
- else if (cls.protocol != PROTOCOL_QUAKEWORLD)
+ else if (cls.protocol != &protocol_quakeworld)
{
cl.mtime[1] = max(cl.mtime[1], cl.mtime[0] - 0.1);
if (developer_extra.integer && vid_activewindow)
{
int cmd;
int i;
- protocolversion_t protocol;
+ protocol_t *protocol = cls.protocol;
unsigned char cmdlog[32];
const char *cmdlogname[32], *temp;
int cmdindex, cmdcount = 0;
- qbool qwplayerupdatereceived;
- qbool strip_pqc;
- char vabuf[1024];
// LadyHavoc: moved demo message writing from before the packet parse to
// after the packet parse so that CL_Stop_f can be called by cl_autodemo
parsingerror = true;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (protocol == &protocol_quakeworld)
{
CL_NetworkTimeReceived(host.realtime); // qw has no clock
cls.servermovesequence = cls.netcon->qw.incoming_sequence;
- qwplayerupdatereceived = false;
-
- while (1)
- {
- if (cl_message.badread)
- Host_Error ("CL_ParseServerMessage: Bad QW server message");
-
- cmd = MSG_ReadByte(&cl_message);
-
- if (cmd == -1)
- {
- SHOWNET("END OF MESSAGE");
- break; // end of message
- }
-
- cmdindex = cmdcount & 31;
- cmdcount++;
- cmdlog[cmdindex] = cmd;
-
- SHOWNET(qw_svc_strings[cmd]);
- cmdlogname[cmdindex] = qw_svc_strings[cmd];
- if (!cmdlogname[cmdindex])
- {
- // LadyHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
- const char *d = "<unknown>";
- cmdlogname[cmdindex] = d;
- }
-
- // other commands
- switch (cmd)
- {
- default:
- {
- char description[32*64], logtemp[64];
- int count;
- strlcpy(description, "packet dump: ", sizeof(description));
- i = cmdcount - 32;
- if (i < 0)
- i = 0;
- count = cmdcount - i;
- i &= 31;
- while(count > 0)
- {
- dpsnprintf(logtemp, sizeof(logtemp), "%3i:%s ", cmdlog[i], cmdlogname[i]);
- strlcat(description, logtemp, sizeof(description));
- count--;
- i++;
- i &= 31;
- }
- description[strlen(description)-1] = '\n'; // replace the last space with a newline
- Con_Print(description);
- Host_Error("CL_ParseServerMessage: Illegible server message");
- }
- break;
-
- case qw_svc_nop:
- //Con_Printf("qw_svc_nop\n");
- break;
-
- case qw_svc_disconnect:
- Con_Printf("Server disconnected\n");
- if (cls.demonum != -1)
- CL_NextDemo();
- else
- CL_Disconnect();
- return;
-
- case qw_svc_print:
- i = MSG_ReadByte(&cl_message);
- temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports
- {
- if (i == 3) // chat
- CSQC_AddPrintText(va(vabuf, sizeof(vabuf), "\1%s", temp)); //[515]: csqc
- else
- CSQC_AddPrintText(temp);
- }
- break;
-
- case qw_svc_centerprint:
- CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc
- break;
-
- case qw_svc_stufftext:
- CL_VM_Parse_StuffCmd(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc
- break;
-
- case qw_svc_damage:
- // svc_damage protocol is identical to nq
- V_ParseDamage ();
- break;
-
- case qw_svc_serverdata:
- //Cbuf_Execute(); // make sure any stuffed commands are done
- CL_ParseServerInfo();
- break;
-
- case qw_svc_setangle:
- for (i=0 ; i<3 ; i++)
- cl.viewangles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
- if (!cls.demoplayback)
- {
- cl.fixangle[0] = true;
- VectorCopy(cl.viewangles, cl.mviewangles[0]);
- // disable interpolation if this is new
- if (!cl.fixangle[1])
- VectorCopy(cl.viewangles, cl.mviewangles[1]);
- }
- break;
-
- case qw_svc_lightstyle:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.max_lightstyle)
- {
- Con_Printf ("svc_lightstyle >= MAX_LIGHTSTYLES");
- break;
- }
- strlcpy (cl.lightstyle[i].map, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.lightstyle[i].map));
- cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
- cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
- break;
-
- case qw_svc_sound:
- CL_ParseStartSoundPacket(false);
- break;
-
- case qw_svc_stopsound:
- i = (unsigned short) MSG_ReadShort(&cl_message);
- S_StopSound(i>>3, i&7);
- break;
-
- case qw_svc_updatefrags:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
- cl.scores[i].frags = (signed short) MSG_ReadShort(&cl_message);
- break;
-
- case qw_svc_updateping:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error("CL_ParseServerMessage: svc_updateping >= cl.maxclients");
- cl.scores[i].qw_ping = MSG_ReadShort(&cl_message);
- break;
-
- case qw_svc_updatepl:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error("CL_ParseServerMessage: svc_updatepl >= cl.maxclients");
- cl.scores[i].qw_packetloss = MSG_ReadByte(&cl_message);
- break;
-
- case qw_svc_updateentertime:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error("CL_ParseServerMessage: svc_updateentertime >= cl.maxclients");
- // seconds ago
- cl.scores[i].qw_entertime = cl.time - MSG_ReadFloat(&cl_message);
- break;
-
- case qw_svc_spawnbaseline:
- i = (unsigned short) MSG_ReadShort(&cl_message);
- if (i < 0 || i >= MAX_EDICTS)
- Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
- if (i >= cl.max_entities)
- CL_ExpandEntities(i);
- CL_ParseBaseline(cl.entities + i, false);
- break;
- case qw_svc_spawnstatic:
- CL_ParseStatic(false);
- break;
- case qw_svc_temp_entity:
- if(!CL_VM_Parse_TempEntity())
- CL_ParseTempEntity ();
- break;
-
- case qw_svc_killedmonster:
- cl.stats[STAT_MONSTERS]++;
- break;
-
- case qw_svc_foundsecret:
- cl.stats[STAT_SECRETS]++;
- break;
-
- case qw_svc_updatestat:
- i = MSG_ReadByte(&cl_message);
- if (i < 0 || i >= MAX_CL_STATS)
- Host_Error ("svc_updatestat: %i is invalid", i);
- cl.stats[i] = MSG_ReadByte(&cl_message);
- break;
-
- case qw_svc_updatestatlong:
- i = MSG_ReadByte(&cl_message);
- if (i < 0 || i >= MAX_CL_STATS)
- Host_Error ("svc_updatestatlong: %i is invalid", i);
- cl.stats[i] = MSG_ReadLong(&cl_message);
- break;
-
- case qw_svc_spawnstaticsound:
- CL_ParseStaticSound (false);
- break;
-
- case qw_svc_cdtrack:
- cl.cdtrack = cl.looptrack = MSG_ReadByte(&cl_message);
- if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
- CDAudio_Play ((unsigned char)cls.forcetrack, true);
- else
- CDAudio_Play ((unsigned char)cl.cdtrack, true);
- break;
-
- case qw_svc_intermission:
- if(!cl.intermission)
- cl.completed_time = cl.time;
- cl.intermission = 1;
- MSG_ReadVector(&cl_message, cl.qw_intermission_origin, cls.protocol);
- for (i = 0;i < 3;i++)
- cl.qw_intermission_angles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
- break;
-
- case qw_svc_finale:
- if(!cl.intermission)
- cl.completed_time = cl.time;
- cl.intermission = 2;
- SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
- break;
-
- case qw_svc_sellscreen:
- Cmd_ExecuteString(&cmd_client, "help", src_local, true);
- break;
-
- case qw_svc_smallkick:
- cl.qw_weaponkick = -2;
- break;
- case qw_svc_bigkick:
- cl.qw_weaponkick = -4;
- break;
-
- case qw_svc_muzzleflash:
- i = (unsigned short) MSG_ReadShort(&cl_message);
- // NOTE: in QW this only worked on clients
- if (i < 0 || i >= MAX_EDICTS)
- Host_Error("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
- if (i >= cl.max_entities)
- CL_ExpandEntities(i);
- cl.entities[i].persistent.muzzleflash = 1.0f;
- break;
-
- case qw_svc_updateuserinfo:
- QW_CL_UpdateUserInfo();
- break;
-
- case qw_svc_setinfo:
- QW_CL_SetInfo();
- break;
-
- case qw_svc_serverinfo:
- QW_CL_ServerInfo();
- break;
-
- case qw_svc_download:
- QW_CL_ParseDownload();
- break;
-
- case qw_svc_playerinfo:
- // slightly kill qw player entities now that we know there is
- // an update of player entities this frame...
- if (!qwplayerupdatereceived)
- {
- qwplayerupdatereceived = true;
- for (i = 1;i < cl.maxclients;i++)
- cl.entities_active[i] = false;
- }
- EntityStateQW_ReadPlayerUpdate();
- break;
-
- case qw_svc_nails:
- QW_CL_ParseNails();
- break;
-
- case qw_svc_chokecount:
- (void) MSG_ReadByte(&cl_message);
- // FIXME: apply to netgraph
- //for (j = 0;j < i;j++)
- // cl.frames[(cls.netcon->qw.incoming_acknowledged-1-j)&QW_UPDATE_MASK].receivedtime = -2;
- break;
-
- case qw_svc_modellist:
- QW_CL_ParseModelList();
- break;
-
- case qw_svc_soundlist:
- QW_CL_ParseSoundList();
- break;
-
- case qw_svc_packetentities:
- EntityFrameQW_CL_ReadFrame(false);
- // first update is the final signon stage
- if (cls.signon == SIGNONS - 1)
- {
- cls.signon = SIGNONS;
- CL_SignonReply ();
- }
- break;
-
- case qw_svc_deltapacketentities:
- EntityFrameQW_CL_ReadFrame(true);
- // first update is the final signon stage
- if (cls.signon == SIGNONS - 1)
- {
- cls.signon = SIGNONS;
- CL_SignonReply ();
- }
- break;
-
- case qw_svc_maxspeed:
- cl.movevars_maxspeed = MSG_ReadFloat(&cl_message);
- break;
-
- case qw_svc_entgravity:
- cl.movevars_entgravity = MSG_ReadFloat(&cl_message);
- if (!cl.movevars_entgravity)
- cl.movevars_entgravity = 1.0f;
- break;
-
- case qw_svc_setpause:
- cl.paused = MSG_ReadByte(&cl_message) != 0;
- if (cl.paused)
- CDAudio_Pause ();
- else
- CDAudio_Resume ();
- S_PauseGameSounds (cl.paused);
- break;
- }
- }
-
- if (qwplayerupdatereceived)
- {
- // fully kill any player entities that were not updated this frame
- for (i = 1;i <= cl.maxclients;i++)
- if (!cl.entities_active[i])
- cl.entities[i].state_current.active = false;
- }
+ cl.qwplayerupdatereceived = false;
}
- else
+
+ while (1)
{
- while (1)
- {
- if (cl_message.badread)
- Host_Error ("CL_ParseServerMessage: Bad server message");
+ if (cl_message.badread)
+ Host_Error ("CL_ParseServerMessage: Bad server message");
- cmd = MSG_ReadByte(&cl_message);
+ cmd = MSG_ReadByte(&cl_message);
- if (cmd == -1)
- {
+ if (cmd == -1)
+ {
// R_TimeReport("END OF MESSAGE");
- SHOWNET("END OF MESSAGE");
- break; // end of message
- }
+ SHOWNET("END OF MESSAGE");
+ break; // end of message
+ }
- cmdindex = cmdcount & 31;
- cmdcount++;
- cmdlog[cmdindex] = cmd;
+ cmdindex = cmdcount & 31;
+ cmdcount++;
+ cmdlog[cmdindex] = cmd;
+ if(protocol != &protocol_quakeworld)
+ {
// if the high bit of the command byte is set, it is a fast update
if (cmd & 128)
{
EntityFrameQuake_ReadEntity (cmd&127);
continue;
}
+ }
- SHOWNET(svc_strings[cmd]);
- cmdlogname[cmdindex] = svc_strings[cmd];
+ if(cmd <= protocol->max_svcmsg && protocol->svcmsg[cmd].func)
+ {
+ SHOWNET(protocol->svcmsg[cmd].name);
+ cmdlogname[cmdindex] = protocol->svcmsg[cmd].name;
if (!cmdlogname[cmdindex])
{
// LadyHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
const char *d = "<unknown>";
cmdlogname[cmdindex] = d;
}
-
- // other commands
- switch (cmd)
+ protocol->svcmsg[cmd].func(protocol);
+ }
+ else
+ {
+ char description[32*64], tempdesc[64];
+ int count;
+ strlcpy (description, "packet dump: ", sizeof(description));
+ i = cmdcount - 32;
+ if (i < 0)
+ i = 0;
+ count = cmdcount - i;
+ i &= 31;
+ while(count > 0)
{
- default:
- {
- char description[32*64], tempdesc[64];
- int count;
- strlcpy (description, "packet dump: ", sizeof(description));
- i = cmdcount - 32;
- if (i < 0)
- i = 0;
- count = cmdcount - i;
- i &= 31;
- while(count > 0)
- {
- dpsnprintf (tempdesc, sizeof (tempdesc), "%3i:%s ", cmdlog[i], cmdlogname[i]);
- strlcat (description, tempdesc, sizeof (description));
- count--;
- i++;
- i &= 31;
- }
- description[strlen(description)-1] = '\n'; // replace the last space with a newline
- Con_Print(description);
- Host_Error ("CL_ParseServerMessage: Illegible server message");
- }
- break;
-
- case svc_nop:
- if (cls.signon < SIGNONS)
- Con_Print("<-- server to client keepalive\n");
- break;
-
- case svc_time:
- CL_NetworkTimeReceived(MSG_ReadFloat(&cl_message));
- break;
-
- case svc_clientdata:
- CL_ParseClientdata();
- break;
-
- case svc_version:
- i = MSG_ReadLong(&cl_message);
- protocol = Protocol_EnumForNumber(i);
- if (protocol == PROTOCOL_UNKNOWN)
- Host_Error("CL_ParseServerMessage: Server is unrecognized protocol number (%i)", i);
- // hack for unmarked Nehahra movie demos which had a custom protocol
- if (protocol == PROTOCOL_QUAKEDP && cls.demoplayback && gamemode == GAME_NEHAHRA)
- protocol = PROTOCOL_NEHAHRAMOVIE;
- cls.protocol = protocol;
- break;
-
- case svc_disconnect:
- Con_Printf ("Server disconnected\n");
- if (cls.demonum != -1)
- CL_NextDemo ();
- else
- CL_Disconnect ();
- break;
-
- case svc_print:
- temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports
- CSQC_AddPrintText(temp); //[515]: csqc
- break;
-
- case svc_centerprint:
- CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc
- break;
-
- case svc_stufftext:
- temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- /* if(utf8_enable.integer)
- {
- strip_pqc = true;
- // we can safely strip and even
- // interpret these in utf8 mode
- }
- else */ switch(cls.protocol)
- {
- case PROTOCOL_QUAKE:
- case PROTOCOL_QUAKEDP:
- // maybe add other protocols if
- // so desired, but not DP7
- strip_pqc = true;
- break;
- case PROTOCOL_DARKPLACES7:
- default:
- // ProQuake does not support
- // these protocols
- strip_pqc = false;
- break;
- }
- if(strip_pqc)
- {
- // skip over ProQuake messages,
- // TODO actually interpret them
- // (they are sbar team score
- // updates), see proquake cl_parse.c
- if(*temp == 0x01)
- {
- ++temp;
- while(*temp >= 0x01 && *temp <= 0x1F)
- ++temp;
- }
- }
- CL_VM_Parse_StuffCmd(temp); //[515]: csqc
- break;
-
- case svc_damage:
- V_ParseDamage ();
- break;
-
- case svc_serverinfo:
- CL_ParseServerInfo ();
- break;
-
- case svc_setangle:
- for (i=0 ; i<3 ; i++)
- cl.viewangles[i] = MSG_ReadAngle(&cl_message, cls.protocol);
- if (!cls.demoplayback)
- {
- cl.fixangle[0] = true;
- VectorCopy(cl.viewangles, cl.mviewangles[0]);
- // disable interpolation if this is new
- if (!cl.fixangle[1])
- VectorCopy(cl.viewangles, cl.mviewangles[1]);
- }
- break;
-
- case svc_setview:
- cl.viewentity = (unsigned short)MSG_ReadShort(&cl_message);
- if (cl.viewentity >= MAX_EDICTS)
- Host_Error("svc_setview >= MAX_EDICTS");
- if (cl.viewentity >= cl.max_entities)
- CL_ExpandEntities(cl.viewentity);
- // LadyHavoc: assume first setview recieved is the real player entity
- if (!cl.realplayerentity)
- cl.realplayerentity = cl.viewentity;
- // update cl.playerentity to this one if it is a valid player
- if (cl.viewentity >= 1 && cl.viewentity <= cl.maxclients)
- cl.playerentity = cl.viewentity;
- break;
-
- case svc_lightstyle:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.max_lightstyle)
- {
- Con_Printf ("svc_lightstyle >= MAX_LIGHTSTYLES");
- break;
- }
- strlcpy (cl.lightstyle[i].map, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.lightstyle[i].map));
- cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
- cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
- break;
-
- case svc_sound:
- CL_ParseStartSoundPacket(false);
- break;
-
- case svc_precache:
- if (cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3)
- {
- // was svc_sound2 in protocols 1, 2, 3, removed in 4, 5, changed to svc_precache in 6
- CL_ParseStartSoundPacket(true);
- }
- else
- {
- char *s;
- i = (unsigned short)MSG_ReadShort(&cl_message);
- s = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- if (i < 32768)
- {
- if (i >= 1 && i < MAX_MODELS)
- {
- dp_model_t *model = Mod_ForName(s, false, false, s[0] == '*' ? cl.model_name[1] : NULL);
- if (!model)
- Con_DPrintf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
- cl.model_precache[i] = model;
- }
- else
- Con_Printf("svc_precache: index %i outside range %i...%i\n", i, 1, MAX_MODELS);
- }
- else
- {
- i -= 32768;
- if (i >= 1 && i < MAX_SOUNDS)
- {
- sfx_t *sfx = S_PrecacheSound (s, true, true);
- if (!sfx && snd_initialized.integer)
- Con_DPrintf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);
- cl.sound_precache[i] = sfx;
- }
- else
- Con_Printf("svc_precache: index %i outside range %i...%i\n", i, 1, MAX_SOUNDS);
- }
- }
- break;
-
- case svc_stopsound:
- i = (unsigned short) MSG_ReadShort(&cl_message);
- S_StopSound(i>>3, i&7);
- break;
-
- case svc_updatename:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
- strlcpy (cl.scores[i].name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.scores[i].name));
- break;
-
- case svc_updatefrags:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
- cl.scores[i].frags = (signed short) MSG_ReadShort(&cl_message);
- break;
-
- case svc_updatecolors:
- i = MSG_ReadByte(&cl_message);
- if (i >= cl.maxclients)
- Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
- cl.scores[i].colors = MSG_ReadByte(&cl_message);
- break;
-
- case svc_particle:
- CL_ParseParticleEffect ();
- break;
-
- case svc_effect:
- CL_ParseEffect ();
- break;
-
- case svc_effect2:
- CL_ParseEffect2 ();
- break;
-
- case svc_spawnbaseline:
- i = (unsigned short) MSG_ReadShort(&cl_message);
- if (i < 0 || i >= MAX_EDICTS)
- Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
- if (i >= cl.max_entities)
- CL_ExpandEntities(i);
- CL_ParseBaseline (cl.entities + i, false);
- break;
- case svc_spawnbaseline2:
- i = (unsigned short) MSG_ReadShort(&cl_message);
- if (i < 0 || i >= MAX_EDICTS)
- Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
- if (i >= cl.max_entities)
- CL_ExpandEntities(i);
- CL_ParseBaseline (cl.entities + i, true);
- break;
- case svc_spawnstatic:
- CL_ParseStatic (false);
- break;
- case svc_spawnstatic2:
- CL_ParseStatic (true);
- break;
- case svc_temp_entity:
- if(!CL_VM_Parse_TempEntity())
- CL_ParseTempEntity ();
- break;
-
- case svc_setpause:
- cl.paused = MSG_ReadByte(&cl_message) != 0;
- if (cl.paused)
- CDAudio_Pause ();
- else
- CDAudio_Resume ();
- S_PauseGameSounds (cl.paused);
- break;
-
- case svc_signonnum:
- i = MSG_ReadByte(&cl_message);
- // LadyHavoc: it's rude to kick off the client if they missed the
- // reconnect somehow, so allow signon 1 even if at signon 1
- if (i <= cls.signon && i != 1)
- Host_Error ("Received signon %i when at %i", i, cls.signon);
- cls.signon = i;
- CL_SignonReply ();
- break;
-
- case svc_killedmonster:
- cl.stats[STAT_MONSTERS]++;
- break;
-
- case svc_foundsecret:
- cl.stats[STAT_SECRETS]++;
- break;
-
- case svc_updatestat:
- i = MSG_ReadByte(&cl_message);
- if (i < 0 || i >= MAX_CL_STATS)
- Host_Error ("svc_updatestat: %i is invalid", i);
- cl.stats[i] = MSG_ReadLong(&cl_message);
- break;
-
- case svc_updatestatubyte:
- i = MSG_ReadByte(&cl_message);
- if (i < 0 || i >= MAX_CL_STATS)
- Host_Error ("svc_updatestat: %i is invalid", i);
- cl.stats[i] = MSG_ReadByte(&cl_message);
- break;
-
- case svc_spawnstaticsound:
- CL_ParseStaticSound (false);
- break;
-
- case svc_spawnstaticsound2:
- CL_ParseStaticSound (true);
- break;
-
- case svc_cdtrack:
- cl.cdtrack = MSG_ReadByte(&cl_message);
- cl.looptrack = MSG_ReadByte(&cl_message);
- if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
- CDAudio_Play ((unsigned char)cls.forcetrack, true);
- else
- CDAudio_Play ((unsigned char)cl.cdtrack, true);
- break;
-
- case svc_intermission:
- if(!cl.intermission)
- cl.completed_time = cl.time;
- cl.intermission = 1;
- CL_VM_UpdateIntermissionState(cl.intermission);
- break;
-
- case svc_finale:
- if(!cl.intermission)
- cl.completed_time = cl.time;
- cl.intermission = 2;
- CL_VM_UpdateIntermissionState(cl.intermission);
- SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
- break;
-
- case svc_cutscene:
- if(!cl.intermission)
- cl.completed_time = cl.time;
- cl.intermission = 3;
- CL_VM_UpdateIntermissionState(cl.intermission);
- SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
- break;
-
- case svc_sellscreen:
- Cmd_ExecuteString(&cmd_client, "help", src_local, true);
- break;
- case svc_hidelmp:
- if (gamemode == GAME_TENEBRAE)
- {
- // repeating particle effect
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- (void) MSG_ReadByte(&cl_message);
- MSG_ReadLong(&cl_message);
- MSG_ReadLong(&cl_message);
- MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- }
- else
- SHOWLMP_decodehide();
- break;
- case svc_showlmp:
- if (gamemode == GAME_TENEBRAE)
- {
- // particle effect
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- MSG_ReadCoord(&cl_message, cls.protocol);
- (void) MSG_ReadByte(&cl_message);
- MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- }
- else
- SHOWLMP_decodeshow();
- break;
- case svc_skybox:
- R_SetSkyBox(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
- break;
- case svc_entities:
- if (cls.signon == SIGNONS - 1)
- {
- // first update is the final signon stage
- cls.signon = SIGNONS;
- CL_SignonReply ();
- }
- if (cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3)
- EntityFrame_CL_ReadFrame();
- else if (cls.protocol == PROTOCOL_DARKPLACES4)
- EntityFrame4_CL_ReadFrame();
- else
- EntityFrame5_CL_ReadFrame();
- break;
- case svc_csqcentities:
- CSQC_ReadEntities();
- break;
- case svc_downloaddata:
- CL_ParseDownload();
- break;
- case svc_trailparticles:
- CL_ParseTrailParticles();
- break;
- case svc_pointparticles:
- CL_ParsePointParticles();
- break;
- case svc_pointparticles1:
- CL_ParsePointParticles1();
- break;
+ dpsnprintf (tempdesc, sizeof (tempdesc), "%3i:%s ", cmdlog[i], cmdlogname[i]);
+ strlcat (description, tempdesc, sizeof (description));
+ count--;
+ i++;
+ i &= 31;
}
-// R_TimeReport(svc_strings[cmd]);
+ description[strlen(description)-1] = '\n'; // replace the last space with a newline
+ Con_Print(description);
+ Host_Error ("CL_ParseServerMessage: Illegible server message");
}
}
+ if (cl.qwplayerupdatereceived)
+ {
+ // fully kill any player entities that were not updated this frame
+ for (i = 1;i <= cl.maxclients;i++)
+ if (!cl.entities_active[i])
+ cl.entities[i].state_current.active = false;
+ }
+// R_TimeReport(svc_strings[cmd]);
+
if (cls.signon == SIGNONS)
CL_UpdateItemsAndWeapon();
// R_TimeReport("UpdateItems");
--- /dev/null
+#include "quakedef.h"
+
+void CL_ParseBaseline (entity_t *ent, int large);
+void CL_ParseClientdata (void);
+void CL_ParseStatic (int large);
+void CL_ParseStaticSound (int large);
+void CL_ParseEffect (void);
+void CL_ParseEffect2 (void);
+void CL_ParseServerInfo (void);
+qbool CL_ExaminePrintString(const char *text);
+void CL_ParseStartSoundPacket(int largesoundindex);
+void CL_ParseTempEntity(void);
+void QW_CL_UpdateUserInfo(void);
+void QW_CL_SetInfo(void);
+void QW_CL_ServerInfo(void);
+void QW_CL_ParseDownload(void);
+void QW_CL_ParseModelList(void);
+void QW_CL_ParseNails(void);
+void CL_UpdateItemsAndWeapon(void);
+void QW_CL_ParseSoundList(void);
+void CL_SignonReply (void);
+void CL_NetworkTimeReceived(double newtime);
+void CL_ParseDownload(void);
+void CL_ParseTrailParticles(void);
+void CL_ParsePointParticles(void);
+void CL_ParsePointParticles1(void);
\ No newline at end of file
vec3_t org, dir;
int i, count, msgcount, color;
- MSG_ReadVector(&cl_message, org, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, org);
for (i=0 ; i<3 ; i++)
dir[i] = MSG_ReadChar(&cl_message) * (1.0 / 16.0);
msgcount = MSG_ReadByte(&cl_message);
--- /dev/null
+#include "quakedef.h"
+#include "client.h"
+#include "protocol.h"
+#include "cl_parse.h"
+#include "cdaudio.h"
+
+static void Netmsg_svc_nop (protocol_t *protocol)
+{
+ if (cls.signon < SIGNONS)
+ Con_Print("<-- server to client keepalive\n");
+
+}
+
+static void Netmsg_svc_disconnect (protocol_t *protocol)
+{
+ Con_Printf ("Server disconnected\n");
+ if (cls.demonum != -1)
+ CL_NextDemo ();
+ else
+ CL_Disconnect ();
+}
+
+static void Netmsg_svc_updatestat (protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i < 0 || i >= MAX_CL_STATS)
+ Host_Error ("svc_updatestat: %i is invalid", i);
+ cl.stats[i] = MSG_ReadLong(&cl_message);
+}
+
+static void Netmsg_svc_version (protocol_t *protocol) // [int] server version
+{
+ int i = MSG_ReadLong(&cl_message);
+ if (!Protocol_ForNumber(i))
+ Host_Error("CL_ParseServerMessage: Server is unrecognized protocol number (%i)", i);
+ // hack for unmarked Nehahra movie demos which had a custom protocol
+ if (protocol == &protocol_quakedp && cls.demoplayback && gamemode == GAME_NEHAHRA)
+ protocol = &protocol_nehahramovie;
+ cls.protocol = protocol;
+}
+
+static void Netmsg_svc_setview (protocol_t *protocol) // [short] entity number
+{
+ cl.viewentity = (unsigned short)MSG_ReadShort(&cl_message);
+ if (cl.viewentity >= MAX_EDICTS)
+ Host_Error("svc_setview >= MAX_EDICTS");
+ if (cl.viewentity >= cl.max_entities)
+ CL_ExpandEntities(cl.viewentity);
+ // LadyHavoc: assume first setview recieved is the real player entity
+ if (!cl.realplayerentity)
+ cl.realplayerentity = cl.viewentity;
+ // update cl.playerentity to this one if it is a valid player
+ if (cl.viewentity >= 1 && cl.viewentity <= cl.maxclients)
+ cl.playerentity = cl.viewentity;
+
+}
+
+static void Netmsg_svc_sound (protocol_t *protocol) // <see code>
+{
+ CL_ParseStartSoundPacket(false);
+}
+
+static void Netmsg_svc_time (protocol_t *protocol) // [float] server time
+{
+ CL_NetworkTimeReceived(MSG_ReadFloat(&cl_message));
+}
+
+static void Netmsg_svc_print (protocol_t *protocol) // [string] null terminated string
+{
+ const char *temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+ if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports
+ CSQC_AddPrintText(temp); //[515]: csqc
+}
+
+static void Netmsg_svc_stufftext (protocol_t *protocol) // [string] stuffed into client's console buffer
+{ // the string should be \n terminated
+ qbool strip_pqc;
+ const char *temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+ /* if(utf8_enable.integer)
+ {
+ strip_pqc = true;
+ // we can safely strip and even
+ // interpret these in utf8 mode
+ }
+ else */ switch(cls.protocol->num)
+ {
+ case PROTOCOL_QUAKE:
+ // maybe add other protocols if
+ // so desired, but not DP7
+ strip_pqc = true;
+ break;
+ default:
+ // ProQuake does not support
+ // these protocols
+ strip_pqc = false;
+ break;
+ }
+ if(strip_pqc)
+ {
+ // skip over ProQuake messages,
+ // TODO actually interpret them
+ // (they are sbar team score
+ // updates), see proquake cl_parse.c
+ if(*temp == 0x01)
+ {
+ ++temp;
+ while(*temp >= 0x01 && *temp <= 0x1F)
+ ++temp;
+ }
+ }
+ CL_VM_Parse_StuffCmd(temp); //[515]: csqc
+
+}
+
+static void Netmsg_svc_setangle (protocol_t *protocol) // [vec3] set the view angle to this absolute value
+{
+ int i;
+ for (i=0 ; i<3 ; i++)
+ cl.viewangles[i] = protocol->ReadAngle(&cl_message);
+ if (!cls.demoplayback)
+ {
+ cl.fixangle[0] = true;
+ VectorCopy(cl.viewangles, cl.mviewangles[0]);
+ // disable interpolation if this is new
+ if (!cl.fixangle[1])
+ VectorCopy(cl.viewangles, cl.mviewangles[1]);
+ }
+}
+
+static void Netmsg_svc_serverinfo (protocol_t *protocol) // [int] version
+ // [string] signon string
+ // [string]..[0]model cache [string]...[0]sounds cache
+ // [string]..[0]item cache
+{
+ CL_ParseServerInfo ();
+}
+
+static void Netmsg_svc_lightstyle (protocol_t *protocol) // [byte] [string]
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.max_lightstyle)
+ {
+ Con_Printf ("svc_lightstyle >= MAX_LIGHTSTYLES");
+ return;
+ }
+ strlcpy (cl.lightstyle[i].map, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.lightstyle[i].map));
+ cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
+ cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
+}
+
+static void Netmsg_svc_updatename (protocol_t *protocol) // [byte] [string]
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
+ strlcpy (cl.scores[i].name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.scores[i].name));
+}
+
+static void Netmsg_svc_updatefrags (protocol_t *protocol) // [byte] [short]
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
+ cl.scores[i].frags = (signed short) MSG_ReadShort(&cl_message);
+}
+
+static void Netmsg_svc_clientdata (protocol_t *protocol) // <shortbits + data>
+{
+ CL_ParseClientdata();
+}
+
+static void Netmsg_svc_stopsound (protocol_t *protocol) // <see code>
+{
+ int i = (unsigned short) MSG_ReadShort(&cl_message);
+ S_StopSound(i>>3, i&7);
+}
+
+static void Netmsg_svc_updatecolors (protocol_t *protocol) // [byte] [byte]
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
+ cl.scores[i].colors = MSG_ReadByte(&cl_message);
+
+}
+
+static void Netmsg_svc_particle (protocol_t *protocol) // [vec3] <variable>
+{
+ CL_ParseParticleEffect ();
+}
+
+static void Netmsg_svc_damage (protocol_t *protocol) // [byte] impact [byte] blood [vec3] from
+{
+ V_ParseDamage ();
+}
+
+static void Netmsg_svc_spawnstatic (protocol_t *protocol)
+{
+ CL_ParseStatic (false);
+}
+
+static void Netmsg_svc_spawnbaseline (protocol_t *protocol)
+{
+ int i = (unsigned short) MSG_ReadShort(&cl_message);
+ if (i < 0 || i >= MAX_EDICTS)
+ Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
+ if (i >= cl.max_entities)
+ CL_ExpandEntities(i);
+ CL_ParseBaseline (cl.entities + i, false);
+}
+
+static void Netmsg_svc_temp_entity (protocol_t *protocol) // <variable>
+{
+ if(!CL_VM_Parse_TempEntity())
+ CL_ParseTempEntity ();
+}
+
+static void Netmsg_svc_setpause (protocol_t *protocol)
+{
+ cl.paused = MSG_ReadByte(&cl_message) != 0;
+ if (cl.paused)
+ CDAudio_Pause ();
+ else
+ CDAudio_Resume ();
+ S_PauseGameSounds (cl.paused);
+}
+
+static void Netmsg_svc_signonnum (protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ // LadyHavoc: it's rude to kick off the client if they missed the
+ // reconnect somehow, so allow signon 1 even if at signon 1
+ if (i <= cls.signon && i != 1)
+ Host_Error ("Received signon %i when at %i", i, cls.signon);
+ cls.signon = i;
+ CL_SignonReply ();
+}
+
+static void Netmsg_svc_centerprint (protocol_t *protocol)
+{
+ CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc
+}
+
+static void Netmsg_svc_killedmonster (protocol_t *protocol)
+{
+ cl.stats[STAT_MONSTERS]++;
+}
+
+static void Netmsg_svc_foundsecret (protocol_t *protocol)
+{
+ cl.stats[STAT_SECRETS]++;
+}
+
+static void Netmsg_svc_spawnstaticsound (protocol_t *protocol)
+{
+ CL_ParseStaticSound (false);
+}
+
+static void Netmsg_svc_intermission (protocol_t *protocol)
+{
+ if(!cl.intermission)
+ cl.completed_time = cl.time;
+ cl.intermission = 1;
+ CL_VM_UpdateIntermissionState(cl.intermission);
+}
+
+static void Netmsg_svc_finale (protocol_t *protocol) // [string] music [string] text
+{
+ if(!cl.intermission)
+ cl.completed_time = cl.time;
+ cl.intermission = 2;
+ CL_VM_UpdateIntermissionState(cl.intermission);
+ SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
+}
+
+static void Netmsg_svc_cdtrack (protocol_t *protocol) // [byte] track [byte] looptrack
+{
+ cl.cdtrack = MSG_ReadByte(&cl_message);
+ cl.looptrack = MSG_ReadByte(&cl_message);
+ if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
+ CDAudio_Play ((unsigned char)cls.forcetrack, true);
+ else
+ CDAudio_Play ((unsigned char)cl.cdtrack, true);
+
+}
+
+static void Netmsg_svc_sellscreen (protocol_t *protocol)
+{
+ Cmd_ExecuteString(&cmd_client, "help", src_local, true);
+}
+
+static void Netmsg_svc_cutscene (protocol_t *protocol)
+{
+ if(!cl.intermission)
+ cl.completed_time = cl.time;
+ cl.intermission = 3;
+ CL_VM_UpdateIntermissionState(cl.intermission);
+ SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
+}
+
+#define NETMSG_BASENQ_SVC \
+ {"svc_bad", NULL}, \
+ {"svc_nop", Netmsg_svc_nop}, \
+ {"svc_disconnect", Netmsg_svc_disconnect}, \
+ {"svc_updatestat", Netmsg_svc_updatestat}, \
+ {"svc_version", Netmsg_svc_version}, \
+ {"svc_setview", Netmsg_svc_setview}, \
+ {"svc_sound", Netmsg_svc_sound}, \
+ {"svc_time", Netmsg_svc_time}, \
+ {"svc_print", Netmsg_svc_print}, \
+ {"svc_stufftext", Netmsg_svc_stufftext}, \
+ {"svc_setangle", Netmsg_svc_setangle}, \
+ {"svc_serverinfo", Netmsg_svc_serverinfo}, \
+ {"svc_lightstyle", Netmsg_svc_lightstyle}, \
+ {"svc_updatename", Netmsg_svc_updatename}, \
+ {"svc_updatefrags", Netmsg_svc_updatefrags}, \
+ {"svc_clientdata", Netmsg_svc_clientdata}, \
+ {"svc_stopsound", Netmsg_svc_stopsound}, \
+ {"svc_updatecolors", Netmsg_svc_updatecolors}, \
+ {"svc_particle", Netmsg_svc_particle}, \
+ {"svc_damage",Netmsg_svc_damage}, \
+ {"svc_spawnstatic", Netmsg_svc_spawnstatic}, \
+ {"OBSOLETE svc_spawnbinary", NULL}, \
+ {"svc_spawnbaseline", Netmsg_svc_spawnbaseline}, \
+ {"svc_temp_entity", Netmsg_svc_temp_entity}, \
+ {"svc_setpause", Netmsg_svc_setpause}, \
+ {"svc_signonnum", Netmsg_svc_signonnum}, \
+ {"svc_centerprint", Netmsg_svc_centerprint}, \
+ {"svc_killedmonster", Netmsg_svc_killedmonster}, \
+ {"svc_foundsecret", Netmsg_svc_foundsecret}, \
+ {"svc_spawnstaticsound", Netmsg_svc_spawnstaticsound}, \
+ {"svc_intermission", Netmsg_svc_intermission}, \
+ {"svc_finale", Netmsg_svc_finale}, \
+ {"svc_cdtrack", Netmsg_svc_cdtrack}, \
+ {"svc_sellscreen", Netmsg_svc_sellscreen}, \
+ {"svc_cutscene", Netmsg_svc_cutscene}
--- /dev/null
+#include "quakedef.h"
+#include "client.h"
+#include "protocol.h"
+#include "cl_parse.h"
+#include "cdaudio.h"
+
+static void Netmsg_svc_nop(protocol_t *protocol)
+{
+ //Con_Printf("qw_svc_nop\n");
+}
+
+static void Netmsg_svc_disconnect(protocol_t *protocol)
+{
+ Con_Printf("Server disconnected\n");
+ if (cls.demonum != -1)
+ CL_NextDemo();
+ else
+ CL_Disconnect();
+ return;
+}
+
+static void Netmsg_svc_print(protocol_t *protocol)
+{
+ char vabuf[1024];
+ int i = MSG_ReadByte(&cl_message);
+ char *temp = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+ if (CL_ExaminePrintString(temp)) // look for anything interesting like player IP addresses or ping reports
+ {
+ if (i == 3) // chat
+ CSQC_AddPrintText(va(vabuf, sizeof(vabuf), "\1%s", temp)); //[515]: csqc
+ else
+ CSQC_AddPrintText(temp);
+ }
+}
+
+static void Netmsg_svc_centerprint(protocol_t *protocol)
+{
+ CL_VM_Parse_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc
+}
+
+static void Netmsg_svc_stufftext(protocol_t *protocol)
+{
+ CL_VM_Parse_StuffCmd(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring))); //[515]: csqc
+}
+
+static void Netmsg_svc_damage(protocol_t *protocol)
+{
+ // svc_damage protocol is identical to nq
+ V_ParseDamage ();
+}
+
+static void Netmsg_svc_serverdata(protocol_t *protocol)
+{
+ //Cbuf_Execute(); // make sure any stuffed commands are done
+ CL_ParseServerInfo();
+}
+
+static void Netmsg_svc_setangle(protocol_t *protocol)
+{
+ int i;
+ for (i=0 ; i<3 ; i++)
+ cl.viewangles[i] = protocol->ReadAngle(&cl_message);
+ if (!cls.demoplayback)
+ {
+ cl.fixangle[0] = true;
+ VectorCopy(cl.viewangles, cl.mviewangles[0]);
+ // disable interpolation if this is new
+ if (!cl.fixangle[1])
+ VectorCopy(cl.viewangles, cl.mviewangles[1]);
+ }
+}
+
+static void Netmsg_svc_lightstyle(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.max_lightstyle)
+ {
+ Con_Printf ("svc_lightstyle >= MAX_LIGHTSTYLES");
+ return;
+ }
+ strlcpy (cl.lightstyle[i].map, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (cl.lightstyle[i].map));
+ cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
+ cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
+}
+
+static void Netmsg_svc_sound(protocol_t *protocol)
+{
+ CL_ParseStartSoundPacket(false);
+}
+
+static void Netmsg_svc_stopsound(protocol_t *protocol)
+{
+ int i = (unsigned short) MSG_ReadShort(&cl_message);
+ S_StopSound(i>>3, i&7);
+}
+
+static void Netmsg_svc_updatefrags(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
+ cl.scores[i].frags = (signed short) MSG_ReadShort(&cl_message);
+}
+
+static void Netmsg_svc_updateping(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error("CL_ParseServerMessage: svc_updateping >= cl.maxclients");
+ cl.scores[i].qw_ping = MSG_ReadShort(&cl_message);
+}
+
+static void Netmsg_svc_updatepl(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error("CL_ParseServerMessage: svc_updatepl >= cl.maxclients");
+ cl.scores[i].qw_packetloss = MSG_ReadByte(&cl_message);
+}
+
+static void Netmsg_svc_updateentertime(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i >= cl.maxclients)
+ Host_Error("CL_ParseServerMessage: svc_updateentertime >= cl.maxclients");
+ // seconds ago
+ cl.scores[i].qw_entertime = cl.time - MSG_ReadFloat(&cl_message);
+}
+
+static void Netmsg_svc_spawnbaseline(protocol_t *protocol)
+{
+ int i = (unsigned short) MSG_ReadShort(&cl_message);
+ if (i < 0 || i >= MAX_EDICTS)
+ Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
+ if (i >= cl.max_entities)
+ CL_ExpandEntities(i);
+ CL_ParseBaseline(cl.entities + i, false);
+}
+static void Netmsg_svc_spawnstatic(protocol_t *protocol)
+{
+ CL_ParseStatic(false);
+}
+static void Netmsg_svc_temp_entity(protocol_t *protocol)
+{
+ if(!CL_VM_Parse_TempEntity())
+ CL_ParseTempEntity ();
+}
+
+static void Netmsg_svc_killedmonster(protocol_t *protocol)
+{
+ cl.stats[STAT_MONSTERS]++;
+}
+
+static void Netmsg_svc_foundsecret(protocol_t *protocol)
+{
+ cl.stats[STAT_SECRETS]++;
+}
+
+static void Netmsg_svc_updatestat(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i < 0 || i >= MAX_CL_STATS)
+ Host_Error ("svc_updatestat: %i is invalid", i);
+ cl.stats[i] = MSG_ReadByte(&cl_message);
+}
+
+static void Netmsg_svc_updatestatlong(protocol_t *protocol)
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i < 0 || i >= MAX_CL_STATS)
+ Host_Error ("svc_updatestatlong: %i is invalid", i);
+ cl.stats[i] = MSG_ReadLong(&cl_message);
+}
+
+static void Netmsg_svc_spawnstaticsound(protocol_t *protocol)
+{
+ CL_ParseStaticSound (false);
+}
+
+static void Netmsg_svc_cdtrack(protocol_t *protocol)
+{
+ cl.cdtrack = cl.looptrack = MSG_ReadByte(&cl_message);
+#ifdef CONFIG_CD
+ if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
+ CDAudio_Play ((unsigned char)cls.forcetrack, true);
+ else
+ CDAudio_Play ((unsigned char)cl.cdtrack, true);
+#endif
+}
+
+static void Netmsg_svc_intermission(protocol_t *protocol)
+{
+ int i;
+ if(!cl.intermission)
+ cl.completed_time = cl.time;
+ cl.intermission = 1;
+ protocol->ReadVector(&cl_message, cl.qw_intermission_origin);
+ for (i = 0;i < 3;i++)
+ cl.qw_intermission_angles[i] = protocol->ReadAngle(&cl_message);
+}
+
+static void Netmsg_svc_finale(protocol_t *protocol)
+{
+ if(!cl.intermission)
+ cl.completed_time = cl.time;
+ cl.intermission = 2;
+ SCR_CenterPrint(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
+}
+
+static void Netmsg_svc_sellscreen(protocol_t *protocol)
+{
+ Cmd_ExecuteString (&cmd_client, "help", src_local, true);
+}
+
+static void Netmsg_svc_smallkick(protocol_t *protocol)
+{
+ cl.qw_weaponkick = -2;
+}
+static void Netmsg_svc_bigkick(protocol_t *protocol)
+{
+ cl.qw_weaponkick = -4;
+}
+
+static void Netmsg_svc_muzzleflash(protocol_t *protocol)
+{
+ int i = (unsigned short) MSG_ReadShort(&cl_message);
+ // NOTE: in QW this only worked on clients
+ if (i < 0 || i >= MAX_EDICTS)
+ Host_Error("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
+ if (i >= cl.max_entities)
+ CL_ExpandEntities(i);
+ cl.entities[i].persistent.muzzleflash = 1.0f;
+}
+
+static void Netmsg_svc_updateuserinfo(protocol_t *protocol)
+{
+ QW_CL_UpdateUserInfo();
+}
+
+static void Netmsg_svc_setinfo(protocol_t *protocol)
+{
+ QW_CL_SetInfo();
+}
+
+static void Netmsg_svc_serverinfo(protocol_t *protocol)
+{
+ QW_CL_ServerInfo();
+}
+
+static void Netmsg_svc_download(protocol_t *protocol)
+{
+ QW_CL_ParseDownload();
+}
+
+static void Netmsg_svc_playerinfo(protocol_t *protocol)
+{
+ int i;
+ // slightly kill qw player entities now that we know there is
+ // an update of player entities this frame...
+ if (!cl.qwplayerupdatereceived)
+ {
+ cl.qwplayerupdatereceived = true;
+ for (i = 1;i < cl.maxclients;i++)
+ cl.entities_active[i] = false;
+ }
+ EntityStateQW_ReadPlayerUpdate();
+}
+
+static void Netmsg_svc_nails(protocol_t *protocol)
+{
+ QW_CL_ParseNails();
+}
+
+static void Netmsg_svc_chokecount(protocol_t *protocol)
+{
+ (void) MSG_ReadByte(&cl_message);
+ // FIXME: apply to netgraph
+ //for (j = 0;j < i;j++)
+ // cl.frames[(cls.netcon->qw.incoming_acknowledged-1-j)&QW_UPDATE_MASK].receivedtime = -2;
+}
+
+static void Netmsg_svc_modellist(protocol_t *protocol)
+{
+ QW_CL_ParseModelList();
+}
+
+static void Netmsg_svc_soundlist(protocol_t *protocol)
+{
+ QW_CL_ParseSoundList();
+}
+
+static void Netmsg_svc_packetentities(protocol_t *protocol)
+{
+ EntityFrameQW_CL_ReadFrame(false);
+ // first update is the final signon stage
+ if (cls.signon == SIGNONS - 1)
+ {
+ cls.signon = SIGNONS;
+ CL_SignonReply ();
+ }
+}
+
+static void Netmsg_svc_deltapacketentities(protocol_t *protocol)
+{
+ EntityFrameQW_CL_ReadFrame(true);
+ // first update is the final signon stage
+ if (cls.signon == SIGNONS - 1)
+ {
+ cls.signon = SIGNONS;
+ CL_SignonReply ();
+ }
+}
+
+static void Netmsg_svc_maxspeed(protocol_t *protocol)
+{
+ cl.movevars_maxspeed = MSG_ReadFloat(&cl_message);
+}
+
+static void Netmsg_svc_entgravity(protocol_t *protocol)
+{
+ cl.movevars_entgravity = MSG_ReadFloat(&cl_message);
+ if (!cl.movevars_entgravity)
+ cl.movevars_entgravity = 1.0f;
+}
+
+static void Netmsg_svc_setpause(protocol_t *protocol)
+{
+ cl.paused = MSG_ReadByte(&cl_message) != 0;
+#ifdef CONFIG_CD
+ if (cl.paused)
+ CDAudio_Pause ();
+ else
+ CDAudio_Resume ();
+#endif
+ S_PauseGameSounds (cl.paused);
+}
\ No newline at end of file
--- /dev/null
+#include "quakedef.h"
+#include "cl_protocol_ext.h"
+
+protocol_netmsg_t netmsg_dpext_svc[] =
+{
+ NETMSG_DPEXT_SVC
+};
\ No newline at end of file
--- /dev/null
+#include "cl_protocol_basenq.h"
+
+static void Netmsg_svc_showlmp (protocol_t *protocol) // [string] iconlabel [string] lmpfile [short] x [short] y
+{
+ if (gamemode == GAME_TENEBRAE)
+ {
+ // particle effect
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ (void) MSG_ReadByte(&cl_message);
+ MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+ }
+ else
+ SHOWLMP_decodeshow();
+}
+
+static void Netmsg_svc_hidelmp (protocol_t *protocol) // [string] iconlabel
+{
+ if (gamemode == GAME_TENEBRAE)
+ {
+ // repeating particle effect
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ protocol->ReadCoord(&cl_message);
+ (void) MSG_ReadByte(&cl_message);
+ MSG_ReadLong(&cl_message);
+ MSG_ReadLong(&cl_message);
+ MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+ }
+ else
+ SHOWLMP_decodehide();
+}
+
+static void Netmsg_svc_skybox (protocol_t *protocol) // [string] skyname
+{
+ R_SetSkyBox(MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
+}
+
+static void Netmsg_svc_downloaddata (protocol_t *protocol) // 50 // [int] start [short] size [variable length] data
+{
+ CL_ParseDownload();
+}
+
+static void Netmsg_svc_updatestatubyte (protocol_t *protocol) // 51 // [byte] stat [byte] value
+{
+ int i = MSG_ReadByte(&cl_message);
+ if (i < 0 || i >= MAX_CL_STATS)
+ Host_Error ("svc_updatestat: %i is invalid", i);
+ cl.stats[i] = MSG_ReadByte(&cl_message);
+}
+
+static void Netmsg_svc_effect (protocol_t *protocol) // 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
+{
+ CL_ParseEffect ();
+}
+
+static void Netmsg_svc_effect2 (protocol_t *protocol) // 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
+{
+ CL_ParseEffect2 ();
+}
+
+// FIXME: Lazy
+static void Netmsg_svc_precache (protocol_t *protocol) // 54 // short soundindex instead of byte
+{
+ if (protocol->num == PROTOCOL_DARKPLACES1 || protocol->num == PROTOCOL_DARKPLACES2 || protocol->num == PROTOCOL_DARKPLACES3)
+ {
+ // was svc_sound2 in protocols 1, 2, 3, removed in 4, 5, changed to svc_precache in 6
+ CL_ParseStartSoundPacket(true);
+ }
+ else
+ {
+ // was svc_sound2 in protocols 1, 2, 3, removed in 4, 5, changed to svc_precache in 6
+ int i = (unsigned short)MSG_ReadShort(&cl_message);
+ char *s = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
+ if (i < 32768)
+ {
+ if (i >= 1 && i < MAX_MODELS)
+ {
+ dp_model_t *model = Mod_ForName(s, false, false, s[0] == '*' ? cl.model_name[1] : NULL);
+ if (!model)
+ Con_DPrintf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
+ cl.model_precache[i] = model;
+ }
+ else
+ Con_Printf("svc_precache: index %i outside range %i...%i\n", i, 1, MAX_MODELS);
+ }
+ else
+ {
+ i -= 32768;
+ if (i >= 1 && i < MAX_SOUNDS)
+ {
+ sfx_t *sfx = S_PrecacheSound (s, true, true);
+ if (!sfx && snd_initialized.integer)
+ Con_DPrintf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);
+ cl.sound_precache[i] = sfx;
+ }
+ else
+ Con_Printf("svc_precache: index %i outside range %i...%i\n", i, 1, MAX_SOUNDS);
+ }
+ }
+}
+
+static void Netmsg_svc_spawnbaseline2 (protocol_t *protocol) // 55 // short modelindex instead of byte
+{
+ int i = (unsigned short) MSG_ReadShort(&cl_message);
+ if (i < 0 || i >= MAX_EDICTS)
+ Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
+ if (i >= cl.max_entities)
+ CL_ExpandEntities(i);
+ CL_ParseBaseline (cl.entities + i, true);
+}
+
+static void Netmsg_svc_spawnstatic2 (protocol_t *protocol) // 56 // short modelindex instead of byte
+{
+ CL_ParseStatic (true);
+}
+
+static void Netmsg_svc_entities (protocol_t *protocol) // 57 // [int] deltaframe [int] thisframe [float vector] eye [variable length] entitydata
+{
+ if (cls.signon == SIGNONS - 1)
+ {
+ // first update is the final signon stage
+ cls.signon = SIGNONS;
+ CL_SignonReply ();
+ }
+ if (protocol == &protocol_dpp1 || protocol == &protocol_dpp2 || protocol == &protocol_dpp3)
+ EntityFrame_CL_ReadFrame();
+ else if (protocol == &protocol_dpp4)
+ EntityFrame4_CL_ReadFrame();
+ else
+ EntityFrame5_CL_ReadFrame();
+}
+
+static void Netmsg_svc_csqcentities (protocol_t *protocol) // 58 // [short] entnum [variable length] entitydata ... [short] 0x0000
+{
+ CSQC_ReadEntities();
+}
+
+static void Netmsg_svc_spawnstaticsound2 (protocol_t *protocol) // 59 // [coord3] [short] samp [byte] vol [byte] aten
+{
+ CL_ParseStaticSound (true);
+}
+
+static void Netmsg_svc_trailparticles (protocol_t *protocol) // 60 // [short] entnum [short] effectnum [vector] start [vector] end
+{
+ CL_ParseTrailParticles();
+}
+
+static void Netmsg_svc_pointparticles (protocol_t *protocol) // 61 // [short] effectnum [vector] start [vector] velocity [short] count
+{
+ CL_ParsePointParticles();
+}
+
+static void Netmsg_svc_pointparticles1 (protocol_t *protocol) // 62 // [short] effectnum [vector] start, same as Netmsg_svc_pointparticles except velocity is zero and count is 1
+{
+ CL_ParsePointParticles1();
+}
+#define NETMSG_DPEXT_SVC \
+ NETMSG_BASENQ_SVC, \
+ {"svc_showlmp", Netmsg_svc_showlmp}, \
+ {"svc_hidelmp", Netmsg_svc_hidelmp}, \
+ {"svc_skybox", Netmsg_svc_skybox}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"", NULL}, \
+ {"svc_downloaddata", Netmsg_svc_downloaddata}, \
+ {"svc_updatestatubyte", Netmsg_svc_updatestatubyte}, \
+ {"svc_effect", Netmsg_svc_effect}, \
+ {"svc_effect2", Netmsg_svc_effect2}, \
+ {"svc_sound2", Netmsg_svc_precache}, \
+ {"svc_spawnbaseline2", Netmsg_svc_spawnbaseline2}, \
+ {"svc_spawnstatic2", Netmsg_svc_spawnstatic2}, \
+ {"svc_entities", Netmsg_svc_entities}, \
+ {"svc_csqcentities", Netmsg_svc_csqcentities}, \
+ {"svc_spawnstaticsound2", Netmsg_svc_spawnstaticsound2}, \
+ {"svc_trailparticles", Netmsg_svc_trailparticles}, \
+ {"svc_pointparticles", Netmsg_svc_pointparticles}, \
+ {"svc_pointparticles1", Netmsg_svc_pointparticles1}
--- /dev/null
+#include "quakedef.h"
+#include "protocol.h"
+#include "cl_protocol_basenq.h"
+
+protocol_netmsg_t netmsg_nq_svc[] =
+{
+ NETMSG_BASENQ_SVC
+};
--- /dev/null
+#include "cl_protocol_baseqw.h"
+
+protocol_netmsg_t netmsg_qw_svc[] =
+{
+ {"svc_bad", NULL}, // 0
+ {"svc_nop", Netmsg_svc_nop}, // 1
+ {"svc_disconnect", Netmsg_svc_disconnect}, // 2
+ {"svc_updatestat", Netmsg_svc_updatestat}, // 3 // [byte] [byte]
+ {"", NULL}, // 4
+ {"svc_setview", NULL}, // 5 // [short] entity number
+ {"svc_sound", Netmsg_svc_sound}, // 6 // <see code>
+ {"", NULL}, // 7
+ {"svc_print", Netmsg_svc_print}, // 8 // [byte] id [string] null terminated string
+ {"svc_stufftext", Netmsg_svc_stufftext}, // 9 // [string] stuffed into client's console buffer
+ {"svc_setangle", Netmsg_svc_setangle}, // 10 // [angle3] set the view angle to this absolute value
+ {"svc_serverdata", Netmsg_svc_serverdata}, // 11 // [long] protocol ...
+ {"svc_lightstyle", Netmsg_svc_lightstyle}, // 12 // [byte] [string]
+ {"", NULL}, // 13
+ {"svc_updatefrags", Netmsg_svc_updatefrags}, // 14 // [byte] [short]
+ {"", NULL}, // 15
+ {"svc_stopsound", Netmsg_svc_stopsound}, // 16 // <see code>
+ {"", NULL}, // 17
+ {"", NULL}, // 18
+ {"svc_damage", Netmsg_svc_damage}, // 19
+ {"svc_spawnstatic", Netmsg_svc_spawnstatic}, // 20
+ {"", NULL}, // 21
+ {"svc_spawnbaseline", Netmsg_svc_spawnbaseline}, // 22
+ {"svc_temp_entity", Netmsg_svc_temp_entity}, // 23 // variable
+ {"svc_setpause", Netmsg_svc_setpause}, // 24 // [byte] on / off
+ {"", NULL}, // 25
+ {"svc_centerprint", Netmsg_svc_centerprint}, // 26 // [string] to put in center of the screen
+ {"svc_killedmonster", Netmsg_svc_killedmonster}, // 27
+ {"svc_foundsecret", Netmsg_svc_foundsecret}, // 28
+ {"svc_spawnstaticsound", Netmsg_svc_spawnstaticsound}, // 29 // [coord3] [byte] samp [byte] vol [byte] aten
+ {"svc_intermission", Netmsg_svc_intermission}, // 30 // [vec3_t] origin [vec3_t] angle
+ {"svc_finale", Netmsg_svc_finale}, // 31 // [string] text
+ {"svc_cdtrack", Netmsg_svc_cdtrack}, // 32 // [byte] track
+ {"svc_sellscreen", Netmsg_svc_sellscreen}, // 33
+ {"svc_smallkick", Netmsg_svc_smallkick}, // 34 // set client punchangle to 2
+ {"svc_bigkick", Netmsg_svc_bigkick}, // 35 // set client punchangle to 4
+ {"svc_updateping", Netmsg_svc_updateping}, // 36 // [byte] [short]
+ {"svc_updateentertime", Netmsg_svc_updateentertime}, // 37 // [byte] [float]
+ {"svc_updatestatlong", Netmsg_svc_updatestatlong}, // 38 // [byte] [long]
+ {"svc_muzzleflash", Netmsg_svc_muzzleflash}, // 39 // [short] entity
+ {"svc_updateuserinfo", Netmsg_svc_updateuserinfo}, // 40 // [byte] slot [long] uid
+ {"svc_download", Netmsg_svc_download}, // 41 // [short] size [size bytes]
+ {"svc_playerinfo", Netmsg_svc_playerinfo}, // 42 // variable
+ {"svc_nails", Netmsg_svc_nails}, // 43 // [byte] num [48 bits] xyzpy 12 12 12 4 8
+ {"svc_chokecount", Netmsg_svc_chokecount}, // 44 // [byte] packets choked
+ {"svc_modellist", Netmsg_svc_modellist}, // 45 // [strings]
+ {"svc_soundlist", Netmsg_svc_soundlist}, // 46 // [strings]
+ {"svc_packetentities", Netmsg_svc_packetentities}, // 47 // [...]
+ {"svc_deltapacketentities", Netmsg_svc_deltapacketentities}, // 48 // [...]
+ {"svc_maxspeed", Netmsg_svc_maxspeed}, // 49 // maxspeed change, for prediction
+ {"svc_entgravity", Netmsg_svc_entgravity}, // 50 // gravity change, for prediction
+ {"svc_setinfo", Netmsg_svc_setinfo}, // 51 // setinfo on a client
+ {"svc_serverinfo", Netmsg_svc_serverinfo}, // 52 // serverinfo
+ {"svc_updatepl", Netmsg_svc_updatepl} // 53 // [byte] [byte]
+};
cls.qw_downloadspeedtime = host.realtime;
cls.qw_downloadspeedcount = 0;
}
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
dpsnprintf(temp, sizeof(temp), "Downloading %s %3i%% (%i) at %i bytes/s", cls.qw_downloadname, cls.qw_downloadpercent, cls.qw_downloadmemorycursize, cls.qw_downloadspeedrate);
else
dpsnprintf(temp, sizeof(temp), "Downloading %s %3i%% (%i/%i) at %i bytes/s", cls.qw_downloadname, cls.qw_downloadpercent, cls.qw_downloadmemorycursize, cls.qw_downloadmemorymaxsize, cls.qw_downloadspeedrate);
lhnetaddress_t rcon_address;
// protocol version of the server we're connected to
// (kept outside client_state_t because it's used between levels)
- protocolversion_t protocol;
+ protocol_t *protocol;
#define MAX_RCONS 16
int rcon_trying;
// used by EntityState5_ReadUpdate
skeleton_t *engineskeletonobjects;
+
+ qbool qwplayerupdatereceived;
}
client_state_t;
static void VM_CL_ReadCoord (prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(0, VM_CL_ReadCoord);
- PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadCoord(&cl_message, cls.protocol);
+ PRVM_G_FLOAT(OFS_RETURN) = cls.protocol->ReadCoord(&cl_message);
}
//#365 float() readangle (EXT_CSQC)
static void VM_CL_ReadAngle (prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(0, VM_CL_ReadAngle);
- PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadAngle(&cl_message, cls.protocol);
+ PRVM_G_FLOAT(OFS_RETURN) = cls.protocol->ReadAngle(&cl_message);
}
//#366 string() readstring (EXT_CSQC)
MSG_WriteFloat (sb, f);
}
-void MSG_WriteCoord (sizebuf_t *sb, float f, protocolversion_t protocol)
-{
- if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
- MSG_WriteCoord13i (sb, f);
- else if (protocol == PROTOCOL_DARKPLACES1)
- MSG_WriteCoord32f (sb, f);
- else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
- MSG_WriteCoord16i (sb, f);
- else
- MSG_WriteCoord32f (sb, f);
+void MSG_WriteVector13i (sizebuf_t *sb, const vec3_t v)
+{
+ MSG_WriteCoord13i (sb, v[0]);
+ MSG_WriteCoord13i (sb, v[1]);
+ MSG_WriteCoord13i (sb, v[2]);
+}
+
+void MSG_WriteVector16i (sizebuf_t *sb, const vec3_t v)
+{
+ MSG_WriteCoord16i (sb, v[0]);
+ MSG_WriteCoord16i (sb, v[1]);
+ MSG_WriteCoord16i (sb, v[2]);
}
-void MSG_WriteVector (sizebuf_t *sb, const vec3_t v, protocolversion_t protocol)
+void MSG_WriteVector32f (sizebuf_t *sb, const vec3_t v)
{
- MSG_WriteCoord (sb, v[0], protocol);
- MSG_WriteCoord (sb, v[1], protocol);
- MSG_WriteCoord (sb, v[2], protocol);
+ MSG_WriteCoord32f (sb, v[0]);
+ MSG_WriteCoord32f (sb, v[1]);
+ MSG_WriteCoord32f (sb, v[2]);
}
// LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
MSG_WriteFloat (sb, f);
}
-void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol)
-{
- if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD)
- MSG_WriteAngle8i (sb, f);
- else
- MSG_WriteAngle16i (sb, f);
-}
-
//
// reading functions
//
return MSG_ReadLittleFloat(sb);
}
-float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol)
+void MSG_ReadVector13i (sizebuf_t *sb, vec3_t v)
{
- if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_QUAKEWORLD)
- return MSG_ReadCoord13i(sb);
- else if (protocol == PROTOCOL_DARKPLACES1)
- return MSG_ReadCoord32f(sb);
- else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
- return MSG_ReadCoord16i(sb);
- else
- return MSG_ReadCoord32f(sb);
+ v[0] = MSG_ReadCoord13i(sb);
+ v[1] = MSG_ReadCoord13i(sb);
+ v[2] = MSG_ReadCoord13i(sb);
}
-void MSG_ReadVector (sizebuf_t *sb, vec3_t v, protocolversion_t protocol)
+void MSG_ReadVector16i (sizebuf_t *sb, vec3_t v)
{
- v[0] = MSG_ReadCoord(sb, protocol);
- v[1] = MSG_ReadCoord(sb, protocol);
- v[2] = MSG_ReadCoord(sb, protocol);
+ v[0] = MSG_ReadCoord16i(sb);
+ v[1] = MSG_ReadCoord16i(sb);
+ v[2] = MSG_ReadCoord16i(sb);
+}
+
+void MSG_ReadVector32f (sizebuf_t *sb, vec3_t v)
+{
+ v[0] = MSG_ReadCoord32f(sb);
+ v[1] = MSG_ReadCoord32f(sb);
+ v[2] = MSG_ReadCoord32f(sb);
}
// LadyHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
float MSG_ReadAngle32f (sizebuf_t *sb)
{
return MSG_ReadFloat (sb);
-}
-
-float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol)
-{
- if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_NEHAHRABJP || protocol == PROTOCOL_NEHAHRABJP2 || protocol == PROTOCOL_NEHAHRABJP3 || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD)
- return MSG_ReadAngle8i (sb);
- else
- return MSG_ReadAngle16i (sb);
-}
+}
\ No newline at end of file
//============================================================================
-// these versions are purely for internal use, never sent in network protocol
-// (use Protocol_EnumForNumber and Protocol_NumberToEnum to convert)
-typedef enum protocolversion_e
-{
- PROTOCOL_UNKNOWN,
- PROTOCOL_DARKPLACES7, ///< added QuakeWorld-style movement protocol to allow more consistent prediction
- PROTOCOL_DARKPLACES6, ///< various changes
- PROTOCOL_DARKPLACES5, ///< uses EntityFrame5 entity snapshot encoder/decoder which is based on a Tribes networking article at http://www.garagegames.com/articles/networking1/
- PROTOCOL_DARKPLACES4, ///< various changes
- PROTOCOL_DARKPLACES3, ///< uses EntityFrame4 entity snapshot encoder/decoder which is broken, this attempted to do partial snapshot updates on a QuakeWorld-like protocol, but it is broken and impossible to fix
- PROTOCOL_DARKPLACES2, ///< various changes
- PROTOCOL_DARKPLACES1, ///< uses EntityFrame entity snapshot encoder/decoder which is a QuakeWorld-like entity snapshot delta compression method
- PROTOCOL_QUAKEDP, ///< darkplaces extended quake protocol (used by TomazQuake and others), backwards compatible as long as no extended features are used
- PROTOCOL_NEHAHRAMOVIE, ///< Nehahra movie protocol, a big nasty hack dating back to early days of the Quake Standards Group (but only ever used by neh_gl.exe), this is potentially backwards compatible with quake protocol as long as no extended features are used (but in actuality the neh_gl.exe which wrote this protocol ALWAYS wrote the extended information)
- PROTOCOL_QUAKE, ///< quake (aka netquake/normalquake/nq) protocol
- PROTOCOL_QUAKEWORLD, ///< quakeworld protocol
- PROTOCOL_NEHAHRABJP, ///< same as QUAKEDP but with 16bit modelindex
- PROTOCOL_NEHAHRABJP2, ///< same as NEHAHRABJP but with 16bit soundindex
- PROTOCOL_NEHAHRABJP3 ///< same as NEHAHRABJP2 but with some changes
-}
-protocolversion_t;
-
/*! \name Message IO functions.
* Handles byte ordering and avoids alignment errors
* @{
void MSG_WriteCoord13i (sizebuf_t *sb, vec_t f);
void MSG_WriteCoord16i (sizebuf_t *sb, vec_t f);
void MSG_WriteCoord32f (sizebuf_t *sb, vec_t f);
-void MSG_WriteCoord (sizebuf_t *sb, vec_t f, protocolversion_t protocol);
-void MSG_WriteVector (sizebuf_t *sb, const vec3_t v, protocolversion_t protocol);
-void MSG_WriteAngle (sizebuf_t *sb, vec_t f, protocolversion_t protocol);
+void MSG_WriteVector13i (sizebuf_t *sb, const vec3_t v);
+void MSG_WriteVector16i (sizebuf_t *sb, const vec3_t v);
+void MSG_WriteVector32f (sizebuf_t *sb, const vec3_t v);
void MSG_BeginReading (sizebuf_t *sb);
int MSG_ReadLittleShort (sizebuf_t *sb);
float MSG_ReadCoord13i (sizebuf_t *sb);
float MSG_ReadCoord16i (sizebuf_t *sb);
float MSG_ReadCoord32f (sizebuf_t *sb);
-float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol);
-void MSG_ReadVector (sizebuf_t *sb, vec3_t v, protocolversion_t protocol);
-float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol);
+void MSG_ReadVector13i (sizebuf_t *sb, vec3_t v);
+void MSG_ReadVector16i (sizebuf_t *sb, vec3_t v);
+void MSG_ReadVector32f (sizebuf_t *sb, vec3_t v);
//@}
//============================================================================
&& (entrender->alpha >= 1)
&& !(renderflags & RF_NOSHADOW)
&& !(entrender->flags & RENDER_VIEWMODEL)
- && (!(entrender->flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer)))
+ && (!(entrender->flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != &protocol_nehahramovie && !cl_noplayershadow.integer)))
entrender->flags |= RENDER_SHADOW;
if (entrender->flags & RENDER_VIEWMODEL)
entrender->flags |= RENDER_NOSELFSHADOW;
i = 0;
CL_CutDemo(&demobuf, &demofilesize);
- while(MakeDownloadPacket(csqc_progname.string, csprogsdata, (size_t)csprogsdatasize, csprogsdatacrc, i++, &sb, cls.protocol))
+ while(MakeDownloadPacket(csqc_progname.string, csprogsdata, (size_t)csprogsdatasize, csprogsdatacrc, i++, &sb, cls.protocol->num))
CL_WriteDemoMessage(&sb);
CL_PasteDemo(&demobuf, &demofilesize);
rsurface.skeleton = ent->skeleton;
memcpy(rsurface.userwavefunc_param, ent->userwavefunc_param, sizeof(rsurface.userwavefunc_param));
rsurface.ent_skinnum = ent->skinnum;
- rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1;
+ rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == &protocol_quakeworld && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1;
rsurface.ent_flags = ent->flags;
if (r_fullbright_directed.integer && (r_fullbright.integer || !model->lit))
rsurface.ent_flags |= RENDER_LIGHT | RENDER_DYNAMICMODELLIGHT;
cl_main.o \
cl_parse.o \
cl_particles.o \
+ cl_protocol_dpp7.o \
+ cl_protocol_nq.o \
+ cl_protocol_qw.o \
cl_screen.o \
cl_video.o \
cl_video_libavw.o \
sv_main.o \
sv_move.o \
sv_phys.o \
+ sv_protocol.o \
sv_save.o \
sv_send.o \
sv_user.o \
static void VM_M_WriteAngle (prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(1, VM_M_WriteAngle);
- MSG_WriteAngle (VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+ sv.protocol->WriteAngle (VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0));
}
static void VM_M_WriteCoord (prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(1, VM_M_WriteCoord);
- MSG_WriteCoord (VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+ sv.protocol->WriteCoord(VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0));
}
static void VM_M_WriteString (prvm_prog_t *prog)
*/
#include "quakedef.h"
+#include "protocol.h"
#include "thread.h"
#include "lhnet.h"
return flag;
}
-int NetConn_Transmit(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qbool quakesignon_suppressreliables)
+int NetConn_Transmit(netconn_t *conn, sizebuf_t *data, protocol_t *protocol, int rate, int burstsize, qbool quakesignon_suppressreliables)
{
int totallen = 0;
unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
conn->outgoing_netgraph[conn->outgoing_packetcounter].cleartime = conn->cleartime;
- if (protocol == PROTOCOL_QUAKEWORLD)
+ if (protocol == &protocol_quakeworld)
{
int packetLen;
qbool sendreliable;
}
}
-static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, size_t length, protocolversion_t protocol, double newtimeout)
+static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, size_t length, protocol_t *protocol, double newtimeout)
{
int originallength = (int)length;
unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
if (length < 8)
return 0;
- if (protocol == PROTOCOL_QUAKEWORLD)
+ if (protocol == &protocol_quakeworld)
{
unsigned int sequence, sequence_ack;
qbool reliable_ack, reliable_message;
return 0;
}
-static void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, protocolversion_t initialprotocol)
+static void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, protocol_t *initialprotocol)
{
crypto_t *crypto;
cls.connect_trying = false;
cls.protocol = initialprotocol;
// reset move sequence numbering on this new connection
cls.servermovesequence = 0;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
CL_ForwardToServer("new");
- if (cls.protocol == PROTOCOL_QUAKE)
+ if (cls.protocol == &protocol_netquake)
{
// write a keepalive (clc_nop) as it seems to greatly improve the
// chances of connecting to a netquake server
if (serverlist_consoleoutput && developer_networking.integer)
Con_Printf("Requesting info from DarkPlaces server %s\n", ipstring);
- if( !NetConn_ClientParsePacket_ServerList_PrepareQuery( PROTOCOL_DARKPLACES7, ipstring, false ) ) {
+ if( !NetConn_ClientParsePacket_ServerList_PrepareQuery( protocol_dpp7.num, ipstring, false ) ) {
break;
}
#ifdef CONFIG_MENU
M_Update_Return_Reason("Accepted");
#endif
- NetConn_ConnectionEstablished(mysocket, peeraddress, PROTOCOL_DARKPLACES3);
+ NetConn_ConnectionEstablished(mysocket, peeraddress, &protocol_dpp3);
return true;
}
if (length > 7 && !memcmp(string, "reject ", 7) && cls.connect_trying)
if (serverlist_consoleoutput && developer_networking.integer)
Con_Printf("Requesting info from QuakeWorld server %s\n", ipstring);
- if( !NetConn_ClientParsePacket_ServerList_PrepareQuery( PROTOCOL_QUAKEWORLD, ipstring, false ) ) {
+ if( !NetConn_ClientParsePacket_ServerList_PrepareQuery( protocol_quakeworld.num, ipstring, false ) ) {
break;
}
#ifdef CONFIG_MENU
M_Update_Return_Reason("QuakeWorld Accepted");
#endif
- NetConn_ConnectionEstablished(mysocket, peeraddress, PROTOCOL_QUAKEWORLD);
+ NetConn_ConnectionEstablished(mysocket, peeraddress, &protocol_quakeworld);
return true;
}
if (length > 2 && !memcmp(string, "n\\", 2))
return true;
}
// quakeworld ingame packet
- if (fromserver && cls.protocol == PROTOCOL_QUAKEWORLD && length >= 8 && (ret = NetConn_ReceivedMessage(cls.netcon, data, length, cls.protocol, net_messagetimeout.value)) == 2)
+ if (fromserver && cls.protocol == &protocol_quakeworld && length >= 8 && (ret = NetConn_ReceivedMessage(cls.netcon, data, length, cls.protocol, net_messagetimeout.value)) == 2)
{
ret = 0;
CL_ParseServerMessage();
#ifdef CONFIG_MENU
M_Update_Return_Reason("Accepted");
#endif
- NetConn_ConnectionEstablished(mysocket, &clientportaddress, PROTOCOL_QUAKE);
+ NetConn_ConnectionEstablished(mysocket, &clientportaddress, &protocol_netquake);
}
break;
case CCREP_REJECT:
// 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_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3) && !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) && !ENCRYPTION_REQUIRED)
{
int c;
int protocolnumber;
if(LHNETADDRESS_GetAddressType(&favorites[j]) == af)
{
if(LHNETADDRESS_ToString(&favorites[j], request, sizeof(request), true))
- NetConn_ClientParsePacket_ServerList_PrepareQuery( PROTOCOL_DARKPLACES7, request, true );
+ NetConn_ClientParsePacket_ServerList_PrepareQuery( protocol_dpp7.num, request, true );
}
}
}
if(LHNETADDRESS_ToString(&favorites[j], request, sizeof(request), true))
{
NetConn_WriteString(cl_sockets[i], "\377\377\377\377status\n", &favorites[j]);
- NetConn_ClientParsePacket_ServerList_PrepareQuery( PROTOCOL_QUAKEWORLD, request, true );
+ NetConn_ClientParsePacket_ServerList_PrepareQuery( protocol_quakeworld.num, request, true );
}
}
}
static void PrintStats(netconn_t *conn)
{
- if ((cls.state == ca_connected && cls.protocol == PROTOCOL_QUAKEWORLD) || (sv.active && sv.protocol == PROTOCOL_QUAKEWORLD))
+ if ((cls.state == ca_connected && cls.protocol == &protocol_quakeworld) || (sv.active && sv.protocol == &protocol_quakeworld))
Con_Printf("address=%21s canSend=%u sendSeq=%6u recvSeq=%6u\n", conn->address, !conn->sendMessageLength, conn->outgoing_unreliable_sequence, conn->qw.incoming_sequence);
else
Con_Printf("address=%21s canSend=%u sendSeq=%6u recvSeq=%6u\n", conn->address, !conn->sendMessageLength, conn->nq.sendSequence, conn->nq.receiveSequence);
#define NET_H
#include "lhnet.h"
+#include "protocol.h"
#define NET_HEADERSIZE (2 * sizeof(unsigned int))
extern cvar_t net_burstreserve;
qbool NetConn_CanSend(netconn_t *conn);
-int NetConn_Transmit(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qbool quakesignon_suppressreliables);
+int NetConn_Transmit(netconn_t *conn, sizebuf_t *data, protocol_t *protocol, int rate, int burstsize, qbool quakesignon_suppressreliables);
qbool NetConn_HaveClientPorts(void);
qbool NetConn_HaveServerPorts(void);
void NetConn_CloseClientPorts(void);
// LadyHavoc: I own protocol ranges 96, 97, 3500-3599
-struct protocolversioninfo_s
+protocol_t protocol_netquake =
{
- int number;
- protocolversion_t version;
- const char *name;
-}
-protocolversioninfo[] =
-{
- { 3504, PROTOCOL_DARKPLACES7 , "DP7"},
- { 3503, PROTOCOL_DARKPLACES6 , "DP6"},
- { 3502, PROTOCOL_DARKPLACES5 , "DP5"},
- { 3501, PROTOCOL_DARKPLACES4 , "DP4"},
- { 3500, PROTOCOL_DARKPLACES3 , "DP3"},
- { 97, PROTOCOL_DARKPLACES2 , "DP2"},
- { 96, PROTOCOL_DARKPLACES1 , "DP1"},
- { 15, PROTOCOL_QUAKEDP , "QUAKEDP"},
- { 15, PROTOCOL_QUAKE , "QUAKE"},
- { 28, PROTOCOL_QUAKEWORLD , "QW"},
- { 250, PROTOCOL_NEHAHRAMOVIE, "NEHAHRAMOVIE"},
- {10000, PROTOCOL_NEHAHRABJP , "NEHAHRABJP"},
- {10001, PROTOCOL_NEHAHRABJP2 , "NEHAHRABJP2"},
- {10002, PROTOCOL_NEHAHRABJP3 , "NEHAHRABJP3"},
- { 0, PROTOCOL_UNKNOWN , NULL}
-};
-
-protocolversion_t Protocol_EnumForName(const char *s)
+ .name = "QUAKE",
+ .num = 15,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 34,
+ .svcmsg = netmsg_nq_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_quakedp =
{
- int i;
- for (i = 0;protocolversioninfo[i].name;i++)
- if (!strcasecmp(s, protocolversioninfo[i].name))
- return protocolversioninfo[i].version;
- return PROTOCOL_UNKNOWN;
-}
+ .name = "QUAKEDP",
+ .num = 15,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
-const char *Protocol_NameForEnum(protocolversion_t p)
+protocol_t protocol_quakeworld =
{
- int i;
- for (i = 0;protocolversioninfo[i].name;i++)
- if (protocolversioninfo[i].version == p)
- return protocolversioninfo[i].name;
- return "UNKNOWN";
-}
+ .name = "QW",
+ .num = 28,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 53,
+ .svcmsg = netmsg_qw_svc,
+ .max_clcmsg = 59,
+ .clcmsg = NULL
+};
-protocolversion_t Protocol_EnumForNumber(int n)
+protocol_t protocol_dpp1 =
{
- int i;
- for (i = 0;protocolversioninfo[i].name;i++)
- if (protocolversioninfo[i].number == n)
- return protocolversioninfo[i].version;
- return PROTOCOL_UNKNOWN;
-}
+ .name = "DP1",
+ .num = 96,
+ .WriteCoord = MSG_WriteCoord32f,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector32f,
+ .ReadCoord = MSG_ReadCoord32f,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector32f,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
-int Protocol_NumberForEnum(protocolversion_t p)
+protocol_t protocol_dpp2 =
{
- int i;
- for (i = 0;protocolversioninfo[i].name;i++)
- if (protocolversioninfo[i].version == p)
- return protocolversioninfo[i].number;
- return 0;
-}
+ .name = "DP2",
+ .num = 97,
+ .WriteCoord = MSG_WriteCoord16i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector16i,
+ .ReadCoord = MSG_ReadCoord16i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector16i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
-void Protocol_Names(char *buffer, size_t buffersize)
+protocol_t protocol_dpp3 =
{
- int i;
- if (buffersize < 1)
- return;
- buffer[0] = 0;
- for (i = 0;protocolversioninfo[i].name;i++)
- {
- if (i > 1)
- strlcat(buffer, " ", buffersize);
- strlcat(buffer, protocolversioninfo[i].name, buffersize);
- }
-}
+ .name = "DP3",
+ .num = 3500,
+ .WriteCoord = MSG_WriteCoord16i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector16i,
+ .ReadCoord = MSG_ReadCoord16i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector16i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_dpp4 =
+{
+ .name = "DP4",
+ .num = 3501,
+ .WriteCoord = MSG_WriteCoord16i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector16i,
+ .ReadCoord = MSG_ReadCoord16i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector16i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_dpp5 =
+{
+ .name = "DP5",
+ .num = 3502,
+ .WriteCoord = MSG_WriteCoord32f,
+ .WriteAngle = MSG_WriteAngle16i,
+ .WriteVector = MSG_WriteVector32f,
+ .ReadCoord = MSG_ReadCoord32f,
+ .ReadAngle = MSG_ReadAngle16i,
+ .ReadVector = MSG_ReadVector32f,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_dpp6 =
+{
+ .name = "DP6",
+ .num = 3503,
+ .WriteCoord = MSG_WriteCoord32f,
+ .WriteAngle = MSG_WriteAngle16i,
+ .WriteVector = MSG_WriteVector32f,
+ .ReadCoord = MSG_ReadCoord32f,
+ .ReadAngle = MSG_ReadAngle16i,
+ .ReadVector = MSG_ReadVector32f,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_dpp7 =
+{
+ .name = "DP7",
+ .num = 3504,
+ .WriteCoord = MSG_WriteCoord32f,
+ .WriteAngle = MSG_WriteAngle16i,
+ .WriteVector = MSG_WriteVector32f,
+ .ReadCoord = MSG_ReadCoord32f,
+ .ReadAngle = MSG_ReadAngle16i,
+ .ReadVector = MSG_ReadVector32f,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+
+};
+
+protocol_t protocol_nehahramovie =
+{
+ .name = "NEHAHRAMOVIE",
+ .num = 250,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_nehahrabjp =
+{
+ .name = "NEHAHRABJP",
+ .num = 10000,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_nehahrabjp2 =
+{
+ .name = "NEHAHRABJP2",
+ .num = 10001,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t protocol_nehahrabjp3 =
+{
+ .name = "NEHAHRABJP3",
+ .num = 10002,
+ .WriteCoord = MSG_WriteCoord13i,
+ .WriteAngle = MSG_WriteAngle8i,
+ .WriteVector = MSG_WriteVector13i,
+ .ReadCoord = MSG_ReadCoord13i,
+ .ReadAngle = MSG_ReadAngle8i,
+ .ReadVector = MSG_ReadVector13i,
+ .max_svcmsg = 62,
+ .svcmsg = netmsg_dpext_svc,
+ .max_clcmsg = 59,
+ .clcmsg = netmsg_base_clc
+};
+
+protocol_t *protocols[] =
+{
+ &protocol_netquake,
+ &protocol_quakedp,
+ &protocol_quakeworld,
+ &protocol_dpp1,
+ &protocol_dpp2,
+ &protocol_dpp3,
+ &protocol_dpp4,
+ &protocol_dpp5,
+ &protocol_dpp6,
+ &protocol_dpp7,
+ &protocol_nehahramovie,
+ &protocol_nehahrabjp,
+ &protocol_nehahrabjp2,
+ &protocol_nehahrabjp3,
+ NULL
+};
void Protocol_UpdateClientStats(const int *stats)
{
-1,
};
+protocol_t *Protocol_ForName(const char *name)
+{
+ int i;
+ for(i = 0; &protocols[i]; i++)
+ {
+ if(!strncmp(name, protocols[i]->name, strlen(protocols[i]->name)))
+ break;
+ }
+ return protocols[i];
+}
+
+protocol_t *Protocol_ForNumber(int num)
+{
+ int i;
+ for(i = 0; &protocols[i]; i++)
+ {
+ if(protocols[i]->num == num)
+ break;
+ }
+ return protocols[i];
+}
+
+void Protocol_Names(char *buffer, size_t buffersize)
+{
+ int i;
+ if (buffersize < 1)
+ return;
+ buffer[0] = 0;
+ for (i = 0; protocols[i]; i++)
+ {
+ if (i > 1)
+ strlcat(buffer, " ", buffersize);
+ strlcat(buffer, protocols[i]->name, buffersize);
+ }
+}
+
void Protocol_WriteStatsReliable(void)
{
int i, j;
{
host_client->statsdeltabits[i >> 3] -= (1 << (i & 7));
// send the stat as a byte if possible
- if (sv.protocol == PROTOCOL_QUAKEWORLD)
+ if (sv.protocol == &protocol_quakeworld)
{
if (host_client->stats[i] >= 0 && host_client->stats[i] < 256)
{
#ifndef PROTOCOL_H
#define PROTOCOL_H
-// protocolversion_t is defined in common.h
-
-protocolversion_t Protocol_EnumForName(const char *s);
-const char *Protocol_NameForEnum(protocolversion_t p);
-protocolversion_t Protocol_EnumForNumber(int n);
-int Protocol_NumberForEnum(protocolversion_t p);
+enum
+{
+ PROTOCOL_UNKNOWN,
+ PROTOCOL_QUAKE = 15, ///< quake (aka netquake/normalquake/nq) protocol
+ PROTOCOL_QUAKEDP = 15, ///< darkplaces extended quake protocol (used by TomazQuake and others), backwards compatible as long as no extended features are used
+ PROTOCOL_QUAKEWORLD = 28, ///< quakeworld protocol
+ PROTOCOL_DARKPLACES1 = 96, ///< uses EntityFrame entity snapshot encoder/decoder which is a QuakeWorld-like entity snapshot delta compression method
+ PROTOCOL_DARKPLACES2 = 97, ///< various changes
+ PROTOCOL_NEHAHRAMOVIE = 250, ///< Nehahra movie protocol, a big nasty hack dating back to early days of the Quake Standards Group (but only ever used by neh_gl.exe), this is potentially backwards compatible with quake protocol as long as no extended features are used (but in actuality the neh_gl.exe which wrote this protocol ALWAYS wrote the extended information)
+ PROTOCOL_DARKPLACES3 = 3500, ///< uses EntityFrame4 entity snapshot encoder/decoder which is broken, this attempted to do partial snapshot updates on a QuakeWorld-like protocol, but it is broken and impossible to fix
+ PROTOCOL_DARKPLACES4 = 3501, ///< various changes
+ PROTOCOL_DARKPLACES5 = 3502, ///< uses EntityFrame5 entity snapshot encoder/decoder which is based on a Tribes networking article at http://www.garagegames.com/articles/networking1/
+ PROTOCOL_DARKPLACES6 = 3503, ///< various changes
+ PROTOCOL_DARKPLACES7 = 3504, ///< added QuakeWorld-style movement protocol to allow more consistent prediction
+ PROTOCOL_NEHAHRABJP = 10000, ///< same as QUAKEDP but with 16bit modelindex
+ PROTOCOL_NEHAHRABJP2 = 10001, ///< same as NEHAHRABJP but with 16bit soundindex
+ PROTOCOL_NEHAHRABJP3 = 10002 ///< same as NEHAHRABJP2 but with some changes
+};
+
+typedef struct protocol_netmsg_s protocol_netmsg_t;
+typedef struct protocol_s protocol_t;
+
+struct protocol_s
+{
+ const char *name;
+ const int num;
+
+ void (*WriteCoord)(sizebuf_t *, float);
+ void (*WriteAngle)(sizebuf_t *, float);
+ void (*WriteVector)(sizebuf_t *, const vec3_t);
+ float (*ReadCoord)(sizebuf_t *);
+ float (*ReadAngle)(sizebuf_t *);
+ void (*ReadVector)(sizebuf_t *, vec3_t);
+
+ // TODO: Other info?
+ const int max_svcmsg;
+ struct protocol_netmsg_s *svcmsg;
+ const int max_clcmsg;
+ struct protocol_netmsg_s *clcmsg;
+};
+
+struct protocol_netmsg_s
+{
+ const char *name;
+ void (*func)(struct protocol_s *);
+};
+
+typedef struct protocol_s protocol_t;
+typedef struct protocol_netmsg_s protocol_netmsg_t;
+
+extern protocol_t protocol_netquake;
+extern protocol_t protocol_quakedp;
+extern protocol_t protocol_quakeworld;
+extern protocol_t protocol_dpp1;
+extern protocol_t protocol_dpp2;
+extern protocol_t protocol_dpp3;
+extern protocol_t protocol_dpp4;
+extern protocol_t protocol_dpp5;
+extern protocol_t protocol_dpp6;
+extern protocol_t protocol_dpp7;
+extern protocol_t protocol_nehahramovie;
+extern protocol_t protocol_nehahrabjp;
+extern protocol_t protocol_nehahrabjp2;
+extern protocol_t protocol_nehahrabjp3;
+
+extern protocol_netmsg_t netmsg_nq_svc[];
+extern protocol_netmsg_t netmsg_qw_svc[];
+extern protocol_netmsg_t netmsg_dpext_svc[];
+extern protocol_netmsg_t netmsg_base_clc[];
+
+#define PF_PREDICTION (1<<0)
+#define PF_MOVE_CROUCH (1<<1)
+
+protocol_t *Protocol_ForName(const char *name);
+protocol_t *Protocol_ForNumber(int num);
void Protocol_Names(char *buffer, size_t buffersize);
#define ENTITYSIZEPROFILING_START(msg, num, flags) \
//
#define clc_bad 0
#define clc_nop 1
-#define clc_disconnect 2
-#define clc_move 3 // [usercmd_t]
+#define clc_disconnect 2 // (NETQUAKE)
+#define clc_move 3 // [usercmd_t]
#define clc_stringcmd 4 // [string] message
+#define clc_delta 5 // (QUAKEWORLD) [byte] sequence number, requests delta compression of message
+#define clc_tmove 6 // (QUAKEWORLD) teleport request, spectator only
+#define clc_upload 7 // (QUAKEWORLD) teleport request, spectator only
// LadyHavoc: my clc_ range, 50-59
#define clc_ackframe 50 // [int] framenumber
void EntityFrameQuake_ISeeDeadEntities(void);
/*
-PROTOCOL_DARKPLACES3
+&protocol_dpp3
server updates entities according to some (unmentioned) scheme.
a frame consists of all visible entities, some of which are up to date,
*/
/*
-PROTOCOL_DARKPLACES4
+&protocol_dpp4
a frame consists of some visible entities in a range (this is stored as start and end, note that end may be less than start if it wrapped).
these entities are stored in a range (firstentity/endentity) of structs in the entitydata[] buffer.
#define qw_svc_setinfo 51 // setinfo on a client
#define qw_svc_serverinfo 52 // serverinfo
#define qw_svc_updatepl 53 // [byte] [byte]
-// QUAKEWORLD
-// client to server
-#define qw_clc_bad 0
-#define qw_clc_nop 1
-#define qw_clc_move 3 // [[usercmd_t]
-#define qw_clc_stringcmd 4 // [string] message
-#define qw_clc_delta 5 // [byte] sequence number, requests delta compression of message
-#define qw_clc_tmove 6 // teleport request, spectator only
-#define qw_clc_upload 7 // teleport request, spectator only
+
// QUAKEWORLD
// playerinfo flags from server
// playerinfo always sends: playernum, flags, origin[] and framenumber
if((s->colors & 15) == (cl.scores[cl.playerentity - 1].colors & 15))
myself = true;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
if (s->qw_spectator)
{
if (cl.last_ping_request < host.realtime - 2 && cls.netcon)
{
cl.last_ping_request = host.realtime;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
- MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
+ MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
MSG_WriteString(&cls.netcon->message, "pings");
}
- else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6/* || cls.protocol == PROTOCOL_DARKPLACES7*/)
+ else if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5 || cls.protocol == &protocol_dpp6/* || cls.protocol == &protocol_dpp7*/)
{
// these servers usually lack the pings command and so a less efficient "ping" command must be sent, which on modern DP servers will also reply with a pingplreport command after the ping listing
static int ping_anyway_counter = 0;
ymin = 8;
ymax = 40 + 8 + (Sbar_IsTeammatch() ? (teamlines * 8 + 5): 0) + scoreboardlines * 8 - 1;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
xmin = (int) (vid_conwidth.integer - (26 + 15) * 8 * FONT_SBAR->maxwidth) / 2; // 26 characters until name, then we assume 15 character names (they can be longer but usually aren't)
else
xmin = (int) (vid_conwidth.integer - (16 + 25) * 8 * FONT_SBAR->maxwidth) / 2; // 16 characters until name, then we assume 25 character names (they can be longer but usually aren't)
// draw the text
y = 40;
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
{
DrawQ_String(xmin, y, va(vabuf, sizeof(vabuf), "ping pl%% time frags team name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
}
qbool loadgame;
/// one of the PROTOCOL_ values
- protocolversion_t protocol;
+ protocol_t *protocol;
double time;
// If it's a static sound
if (isstatic)
{
- if (sfx->loopstart >= sfx->total_length && (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEWORLD))
+ if (sfx->loopstart >= sfx->total_length && (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakeworld))
Con_DPrintf("Quake compatibility warning: Static sound \"%s\" is not looped\n", sfx->name);
target_chan->distfade = attenuation / (64.0f * snd_soundradius.value);
}
if (!host_client->netconnection)
return;
- if (sv.protocol != PROTOCOL_QUAKEWORLD)
+ if (sv.protocol != &protocol_quakeworld)
{
MSG_WriteByte(&host_client->netconnection->message, svc_stufftext);
MSG_WriteUnterminatedString(&host_client->netconnection->message, "pingplreport");
movementloss = (movementloss * 100 + NETGRAPH_PACKETS - 1) / NETGRAPH_PACKETS;
ping = (int)floor(svs.clients[i].ping*1000+0.5);
ping = bound(0, ping, 9999);
- if (sv.protocol == PROTOCOL_QUAKEWORLD)
+ if (sv.protocol == &protocol_quakeworld)
{
// send qw_svc_updateping and qw_svc_updatepl messages
MSG_WriteByte(&host_client->netconnection->message, qw_svc_updateping);
MSG_WriteUnterminatedString(&host_client->netconnection->message, temp);
}
}
- if (sv.protocol != PROTOCOL_QUAKEWORLD)
+ if (sv.protocol != &protocol_quakeworld)
MSG_WriteString(&host_client->netconnection->message, "\n");
}
players++;
print ("host: %s\n", Cvar_VariableString (&cvars_all, "hostname", CF_SERVER));
print ("version: %s build %s (gamename %s)\n", gamename, buildstring, gamenetworkfiltername);
- print ("protocol: %i (%s)\n", Protocol_NumberForEnum(sv.protocol), Protocol_NameForEnum(sv.protocol));
+ print ("protocol: %i (%s)\n", sv.protocol->num, sv.protocol->name);
print ("map: %s\n", sv.name);
print ("timing: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
print ("players: %i active (%i max)\n\n", players, svs.maxclients);
if (in == 0) // default layout
{
- if (sv.protocol == PROTOCOL_QUAKE && svs.maxclients <= 99)
+ if (sv.protocol == &protocol_netquake && svs.maxclients <= 99)
{
// LadyHavoc: this is very touchy because we must maintain ProQuake compatible status output
print ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", i+1, client->name, frags, hours, minutes, seconds);
void EntityState_WriteFields(const entity_state_t *ent, sizebuf_t *msg, unsigned int bits)
{
- if (sv.protocol == PROTOCOL_DARKPLACES2)
+ if (sv.protocol == &protocol_dpp2)
{
if (bits & E_ORIGIN1)
MSG_WriteCoord16i(msg, ent->origin[0]);
MSG_WriteCoord32f(msg, ent->origin[2]);
}
}
- if ((sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4) && (ent->flags & RENDER_LOWPRECISION))
+ if ((sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4) && (ent->flags & RENDER_LOWPRECISION))
{
if (bits & E_ANGLE1)
MSG_WriteAngle8i(msg, ent->angles[0]);
MSG_WriteByte(msg, ent->glowsize);
if (bits & E_GLOWCOLOR)
MSG_WriteByte(msg, ent->glowcolor);
- if (sv.protocol == PROTOCOL_DARKPLACES2)
+ if (sv.protocol == &protocol_dpp2)
if (bits & E_FLAGS)
MSG_WriteByte(msg, ent->flags);
if (bits & E_TAGATTACHMENT)
packetlog = NULL;
// write stat updates
- if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3 && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5)
+ 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)
{
for (i = 0;i < MAX_CL_STATS && msg->cursize + 6 + 11 <= maxsize;i++)
{
d->latestframenum = framenum;
MSG_WriteByte(msg, svc_entities);
MSG_WriteLong(msg, framenum);
- if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5 && sv.protocol != PROTOCOL_DARKPLACES6)
+ 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)
MSG_WriteLong(msg, movesequence);
for (priority = ENTITYFRAME5_PRIORITYLEVELS - 1;priority >= 0 && packetlog->numstates < ENTITYFRAME5_MAXSTATES;priority--)
{
if (baseline.modelindex != s->modelindex)
{
bits |= U_MODEL;
- if ((s->modelindex & 0xFF00) && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3)
+ if ((s->modelindex & 0xFF00) && sv.protocol != &protocol_nehahrabjp && sv.protocol != &protocol_nehahrabjp2 && sv.protocol != &protocol_nehahrabjp3)
bits |= U_MODEL2;
}
if (baseline.alpha != s->alpha)
bits |= U_COLORMOD;
// if extensions are disabled, clear the relevant update flags
- if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_NEHAHRAMOVIE)
+ if (sv.protocol == &protocol_netquake || sv.protocol == &protocol_nehahramovie)
bits &= 0x7FFF;
- if (sv.protocol == PROTOCOL_NEHAHRAMOVIE)
+ if (sv.protocol == &protocol_nehahramovie)
if (s->alpha != 255 || s->effects & EF_FULLBRIGHT)
bits |= U_EXTEND1;
MSG_WriteByte (&buf, bits);
if (bits & U_MOREBITS) MSG_WriteByte(&buf, bits>>8);
- if (sv.protocol != PROTOCOL_NEHAHRAMOVIE)
+ if (sv.protocol != &protocol_nehahramovie)
{
if (bits & U_EXTEND1) MSG_WriteByte(&buf, bits>>16);
if (bits & U_EXTEND2) MSG_WriteByte(&buf, bits>>24);
if (bits & U_MODEL)
{
- if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3)
MSG_WriteShort(&buf, s->modelindex);
else
MSG_WriteByte(&buf, s->modelindex);
if (bits & U_COLORMAP) MSG_WriteByte(&buf, s->colormap);
if (bits & U_SKIN) MSG_WriteByte(&buf, s->skin);
if (bits & U_EFFECTS) MSG_WriteByte(&buf, s->effects);
- if (bits & U_ORIGIN1) MSG_WriteCoord(&buf, s->origin[0], sv.protocol);
- if (bits & U_ANGLE1) MSG_WriteAngle(&buf, s->angles[0], sv.protocol);
- if (bits & U_ORIGIN2) MSG_WriteCoord(&buf, s->origin[1], sv.protocol);
- if (bits & U_ANGLE2) MSG_WriteAngle(&buf, s->angles[1], sv.protocol);
- if (bits & U_ORIGIN3) MSG_WriteCoord(&buf, s->origin[2], sv.protocol);
- if (bits & U_ANGLE3) MSG_WriteAngle(&buf, s->angles[2], sv.protocol);
+ if (bits & U_ORIGIN1) sv.protocol->WriteCoord(&buf, s->origin[0]);
+ if (bits & U_ANGLE1) sv.protocol->WriteAngle(&buf, s->angles[0]);
+ if (bits & U_ORIGIN2) sv.protocol->WriteCoord(&buf, s->origin[1]);
+ 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_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8);
// the nasty protocol
- if ((bits & U_EXTEND1) && sv.protocol == PROTOCOL_NEHAHRAMOVIE)
+ if ((bits & U_EXTEND1) && sv.protocol == &protocol_nehahramovie)
{
if (s->effects & EF_FULLBRIGHT)
{
if (sv.datagram.cursize > MAX_PACKETFRAGMENT-18)
return;
MSG_WriteByte (&sv.datagram, svc_particle);
- MSG_WriteCoord (&sv.datagram, org[0], sv.protocol);
- MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
- MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, org);
for (i=0 ; i<3 ; i++)
MSG_WriteChar (&sv.datagram, (int)bound(-128, dir[i]*16, 127));
MSG_WriteByte (&sv.datagram, count);
if (sv.datagram.cursize > MAX_PACKETFRAGMENT-19)
return;
MSG_WriteByte (&sv.datagram, svc_effect2);
- MSG_WriteCoord (&sv.datagram, org[0], sv.protocol);
- MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
- MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, org);
MSG_WriteShort (&sv.datagram, modelindex);
MSG_WriteShort (&sv.datagram, startframe);
MSG_WriteByte (&sv.datagram, framecount);
if (sv.datagram.cursize > MAX_PACKETFRAGMENT-17)
return;
MSG_WriteByte (&sv.datagram, svc_effect);
- MSG_WriteCoord (&sv.datagram, org[0], sv.protocol);
- MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
- MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, org);
MSG_WriteByte (&sv.datagram, modelindex);
MSG_WriteByte (&sv.datagram, startframe);
MSG_WriteByte (&sv.datagram, framecount);
}
else
MSG_WriteShort (dest, (ent<<3) | channel);
- if ((field_mask & SND_LARGESOUND) || sv.protocol == PROTOCOL_NEHAHRABJP2)
+ if ((field_mask & SND_LARGESOUND) || sv.protocol == &protocol_nehahrabjp2)
MSG_WriteShort (dest, sound_num);
else
MSG_WriteByte (dest, sound_num);
for (i = 0;i < 3;i++)
- MSG_WriteCoord (dest, PRVM_serveredictvector(entity, origin)[i]+0.5*(PRVM_serveredictvector(entity, mins)[i]+PRVM_serveredictvector(entity, maxs)[i]), sv.protocol);
+ sv.protocol->WriteCoord (dest, PRVM_serveredictvector(entity, origin)[i]+0.5*(PRVM_serveredictvector(entity, mins)[i]+PRVM_serveredictvector(entity, maxs)[i]));
// TODO do we have to do anything here when dest is &sv.reliable_datagram?
if(!reliable)
*/
void SV_StartPointSound (vec3_t origin, const char *sample, int nvolume, float attenuation, float speed)
{
- int sound_num, field_mask, i, speed4000;
+ int sound_num, field_mask, speed4000;
if (nvolume < 0 || nvolume > 255)
{
MSG_WriteShort (&sv.datagram, sound_num);
else
MSG_WriteByte (&sv.datagram, sound_num);
- for (i = 0;i < 3;i++)
- MSG_WriteCoord (&sv.datagram, origin[i], sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, origin);
SV_FlushBroadcastMessages();
}
memset(client->stats, 0, sizeof(client->stats));
memset(client->statsdeltabits, 0, sizeof(client->statsdeltabits));
- if (sv.protocol != PROTOCOL_QUAKE && 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)
{
- if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3)
+ if (sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3)
client->entitydatabase = EntityFrame_AllocDatabase(sv_mempool);
- else if (sv.protocol == PROTOCOL_DARKPLACES4)
+ else if (sv.protocol == &protocol_dpp4)
client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_mempool);
else
client->entitydatabase5 = EntityFrame5_AllocDatabase(sv_mempool);
sb.data = (unsigned char *) buf;
sb.maxsize = sizeof(buf);
k = 0;
- while(MakeDownloadPacket(sv.csqc_progname, svs.csqc_progdata, sv.csqc_progsize, sv.csqc_progcrc, k++, &sb, sv.protocol))
+ while(MakeDownloadPacket(sv.csqc_progname, svs.csqc_progdata, sv.csqc_progsize, sv.csqc_progcrc, k++, &sb, sv.protocol->num))
SV_WriteDemoMessage(client, &sb, false);
}
}
MSG_WriteByte (&client->netconnection->message, svc_serverinfo);
- MSG_WriteLong (&client->netconnection->message, Protocol_NumberForEnum(sv.protocol));
+ MSG_WriteLong (&client->netconnection->message, sv.protocol->num);
MSG_WriteByte (&client->netconnection->message, svs.maxclients);
if (!coop.integer && deathmatch.integer)
// 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_QUAKE || 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))
{
// entity has survived every check so far, check if visible
ed = PRVM_EDICT_NUM(s->number);
MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, dmg_save));
MSG_WriteByte (msg, (int)PRVM_serveredictfloat(ent, dmg_take));
for (i=0 ; i<3 ; i++)
- MSG_WriteCoord (msg, PRVM_serveredictvector(other, origin)[i] + 0.5*(PRVM_serveredictvector(other, mins)[i] + PRVM_serveredictvector(other, maxs)[i]), sv.protocol);
+ sv.protocol->WriteCoord (msg, PRVM_serveredictvector(other, origin)[i] + 0.5*(PRVM_serveredictvector(other, mins)[i] + PRVM_serveredictvector(other, maxs)[i]));
PRVM_serveredictfloat(ent, dmg_take) = 0;
PRVM_serveredictfloat(ent, dmg_save) = 0;
{
MSG_WriteByte (msg, svc_setangle);
for (i=0 ; i < 3 ; i++)
- MSG_WriteAngle (msg, host_client->fixangle_angles[i], sv.protocol);
+ sv.protocol->WriteAngle (msg, host_client->fixangle_angles[i]);
host_client->fixangle_angles_set = false;
}
{
if (PRVM_serveredictvector(ent, punchangle)[i])
bits |= (SU_PUNCH1<<i);
- if (sv.protocol != PROTOCOL_QUAKE && 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)
if (punchvector[i])
bits |= (SU_PUNCHVEC1<<i);
if (PRVM_serveredictvector(ent, velocity)[i])
statsf[STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION] = sv_airaccel_sideways_friction.value;
}
- if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ 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 (stats[STAT_VIEWHEIGHT] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT;
bits |= SU_ITEMS;
if (stats[STAT_WEAPONFRAME]) bits |= SU_WEAPONFRAME;
if (stats[STAT_ARMOR]) bits |= SU_ARMOR;
bits |= SU_WEAPON;
- // FIXME: which protocols support this? does PROTOCOL_DARKPLACES3 support viewzoom?
- if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ // FIXME: which protocols support this? does &protocol_dpp3 support viewzoom?
+ if (sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4 || sv.protocol == &protocol_dpp5)
if (viewzoom != 255)
bits |= SU_VIEWZOOM;
}
{
if (bits & (SU_PUNCH1<<i))
{
- if (sv.protocol == PROTOCOL_QUAKE || 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)
MSG_WriteChar(msg, (int)PRVM_serveredictvector(ent, punchangle)[i]);
else
MSG_WriteAngle16i(msg, PRVM_serveredictvector(ent, punchangle)[i]);
}
if (bits & (SU_PUNCHVEC1<<i))
{
- if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
+ if (sv.protocol == &protocol_dpp1 || sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4)
MSG_WriteCoord16i(msg, punchvector[i]);
else
MSG_WriteCoord32f(msg, punchvector[i]);
}
if (bits & (SU_VELOCITY1<<i))
{
- if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
+ 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)
MSG_WriteChar(msg, (int)(PRVM_serveredictvector(ent, velocity)[i] * (1.0f / 16.0f)));
else
MSG_WriteCoord32f(msg, PRVM_serveredictvector(ent, velocity)[i]);
if (bits & SU_ITEMS)
MSG_WriteLong (msg, stats[STAT_ITEMS]);
- if (sv.protocol == PROTOCOL_DARKPLACES5)
+ if (sv.protocol == &protocol_dpp5)
{
if (bits & SU_WEAPONFRAME)
MSG_WriteShort (msg, stats[STAT_WEAPONFRAME]);
if (bits & SU_VIEWZOOM)
MSG_WriteShort (msg, bound(0, stats[STAT_VIEWZOOM], 65535));
}
- else if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
+ else 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)
{
if (bits & SU_WEAPONFRAME)
MSG_WriteByte (msg, stats[STAT_WEAPONFRAME]);
MSG_WriteByte (msg, stats[STAT_ARMOR]);
if (bits & SU_WEAPON)
{
- if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3)
MSG_WriteShort (msg, stats[STAT_WEAPON]);
else
MSG_WriteByte (msg, stats[STAT_WEAPON]);
MSG_WriteByte (msg, stats[STAT_ACTIVEWEAPON]);
if (bits & SU_VIEWZOOM)
{
- if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
+ if (sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3 || sv.protocol == &protocol_dpp4)
MSG_WriteByte (msg, bound(0, stats[STAT_VIEWZOOM], 255));
else
MSG_WriteShort (msg, bound(0, stats[STAT_VIEWZOOM], 65535));
if (!NetConn_CanSend(client->netconnection))
return;
- // PROTOCOL_DARKPLACES5 and later support packet size limiting of updates
+ // &protocol_dpp5 and later support packet size limiting of updates
maxrate = max(NET_MINRATE, sv_maxrate.integer);
if (sv_maxrate.integer != maxrate)
Cvar_SetValueQuick(&sv_maxrate, maxrate);
// (how long to wait before sending another, based on this packet's size)
clientrate = bound(NET_MINRATE, client->rate, maxrate);
- switch (sv.protocol)
+ switch (sv.protocol->num)
{
case PROTOCOL_QUAKE:
- case PROTOCOL_QUAKEDP:
case PROTOCOL_NEHAHRAMOVIE:
case PROTOCOL_NEHAHRABJP:
case PROTOCOL_NEHAHRABJP2:
{
int i, prepared = false;
- if (sv.protocol == PROTOCOL_QUAKEWORLD)
+ if (sv.protocol == &protocol_quakeworld)
Sys_Error("SV_SendClientMessages: no quakeworld support\n");
SV_FlushBroadcastMessages();
*/
int SV_ModelIndex(const char *s, int precachemode)
{
- int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3) ? 256 : MAX_MODELS);
+ int i, limit = ((sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) ? 256 : MAX_MODELS);
char filename[MAX_QPATH];
if (!s || !*s)
return 0;
{
if (precachemode)
{
- if (sv.state != ss_loading && (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5))
+ 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))
{
Con_Printf("SV_ModelIndex(\"%s\"): precache_model can only be done in spawn functions\n", filename);
return 0;
*/
int SV_SoundIndex(const char *s, int precachemode)
{
- int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3) ? 256 : MAX_SOUNDS);
+ int i, limit = ((sv.protocol == &protocol_netquake || sv.protocol == &protocol_quakedp || sv.protocol == &protocol_nehahramovie || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3) ? 256 : MAX_SOUNDS);
char filename[MAX_QPATH];
if (!s || !*s)
return 0;
{
if (precachemode)
{
- if (sv.state != ss_loading && (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5))
+ 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))
{
Con_Printf("SV_SoundIndex(\"%s\"): precache_sound can only be done in spawn functions\n", filename);
return 0;
if (svent->priv.server->baseline.modelindex & 0xFF00 || svent->priv.server->baseline.frame & 0xFF00)
{
large = true;
- if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3)
large = false;
}
MSG_WriteShort (&sv.signon, svent->priv.server->baseline.modelindex);
MSG_WriteShort (&sv.signon, svent->priv.server->baseline.frame);
}
- else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ else if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3)
{
MSG_WriteShort (&sv.signon, svent->priv.server->baseline.modelindex);
MSG_WriteByte (&sv.signon, svent->priv.server->baseline.frame);
MSG_WriteByte (&sv.signon, svent->priv.server->baseline.skin);
for (i=0 ; i<3 ; i++)
{
- MSG_WriteCoord(&sv.signon, svent->priv.server->baseline.origin[i], sv.protocol);
- MSG_WriteAngle(&sv.signon, svent->priv.server->baseline.angles[i], sv.protocol);
+ sv.protocol->WriteCoord(&sv.signon, svent->priv.server->baseline.origin[i]);
+ sv.protocol->WriteAngle(&sv.signon, svent->priv.server->baseline.angles[i]);
}
}
}
Cvar_SetQuick(&sv_worldnamenoextension, sv.worldnamenoextension);
Cvar_SetQuick(&sv_worldbasename, sv.worldbasename);
- sv.protocol = Protocol_EnumForName(sv_protocolname.string);
- if (sv.protocol == PROTOCOL_UNKNOWN)
+ sv.protocol = Protocol_ForName(sv_protocolname.string);
+ if (!sv.protocol)
{
char buffer[1024];
Protocol_Names(buffer, sizeof(buffer));
Con_Printf(CON_ERROR "Unknown sv_protocolname \"%s\", valid values are:\n%s\n", sv_protocolname.string, buffer);
- sv.protocol = PROTOCOL_QUAKE;
+ sv.protocol = &protocol_netquake;
}
// load progs to get entity field count
Mod_PurgeUnused();
// create a baseline for more efficient communications
- if (sv.protocol == PROTOCOL_QUAKE || 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_CreateBaseline ();
sv.state = ss_active; // LadyHavoc: workaround for svc_precache bug
prog->builtins = vm_sv_builtins;
prog->numbuiltins = vm_sv_numbuiltins;
prog->max_edicts = 512;
- if (sv.protocol == PROTOCOL_QUAKE)
+ if (sv.protocol == &protocol_netquake)
prog->limit_edicts = 640; // before quake mission pack 1 this was 512
- else if (sv.protocol == PROTOCOL_QUAKEDP)
+ else if (sv.protocol == &protocol_quakedp)
prog->limit_edicts = 2048; // guessing
- else if (sv.protocol == PROTOCOL_NEHAHRAMOVIE)
+ else if (sv.protocol == &protocol_nehahramovie)
prog->limit_edicts = 2048; // guessing!
- else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ else if (sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3)
prog->limit_edicts = 4096; // guessing!
else
prog->limit_edicts = MAX_EDICTS;
--- /dev/null
+#include "quakedef.h"
+#include "sv_protocol_base.h"
+
+protocol_netmsg_t netmsg_base_clc[] =
+{
+ {"clc_bad", NULL},
+ {"clc_nop", Netmsg_clc_nop},
+ {"clc_disconnect", Netmsg_clc_disconnect},
+ {"clc_move", Netmsg_clc_move},
+ {"clc_stringcmd", Netmsg_clc_stringcmd},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {NULL, NULL},
+ {"clc_ackframe", Netmsg_clc_ackframe},
+ {"clc_ackdownloaddata", Netmsg_clc_ackdownloaddata},
+ {"clc_unusedlh2", NULL},
+ {"clc_unusedlh3", NULL},
+ {"clc_unusedlh4", NULL},
+ {"clc_unusedlh5", NULL},
+ {"clc_unusedlh6", NULL},
+ {"clc_unusedlh7", NULL},
+ {"clc_unusedlh8", NULL},
+ {"clc_unusedlh9", NULL}
+};
\ No newline at end of file
--- /dev/null
+#include "quakedef.h"
+#include "server.h"
+#include "protocol.h"
+#include "sv_user.h"
+
+static void Netmsg_clc_nop(protocol_t *protocol)
+{
+}
+
+static void Netmsg_clc_stringcmd(protocol_t *protocol)
+{
+ prvm_prog_t *prog = SVVM_prog;
+ char *s, *p, *q;
+
+ // allow reliable messages now as the client is done with initial loading
+ if (host_client->sendsignon == 2)
+ host_client->sendsignon = 0;
+ s = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
+ q = NULL;
+ for(p = s; *p; ++p) switch(*p)
+ {
+ case 10:
+ case 13:
+ if(!q)
+ q = p;
+ break;
+ default:
+ if(q)
+ goto clc_stringcmd_invalid; // newline seen, THEN something else -> possible exploit
+ break;
+ }
+ if(q)
+ *q = 0;
+ if (strncasecmp(s, "spawn", 5) == 0
+ || strncasecmp(s, "begin", 5) == 0
+ || strncasecmp(s, "prespawn", 8) == 0)
+ Cmd_ExecuteString (&cmd_serverfromclient, s, src_client, true);
+ else if (PRVM_serverfunction(SV_ParseClientCommand))
+ {
+ int restorevm_tempstringsbuf_cursize;
+ restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+ PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s);
+ PRVM_serverglobalfloat(time) = sv.time;
+ PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
+ prog->ExecuteProgram(prog, PRVM_serverfunction(SV_ParseClientCommand), "QC function SV_ParseClientCommand is missing");
+ prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+ }
+ else
+ Cmd_ExecuteString (&cmd_serverfromclient, s, src_client, true);
+ return;
+
+clc_stringcmd_invalid:
+ Con_Printf("Received invalid stringcmd from %s\n", host_client->name);
+ if(developer.integer > 0)
+ Com_HexDumpToConsole((unsigned char *) s, (int)strlen(s));
+ return;
+}
+
+static void Netmsg_clc_disconnect(protocol_t *protocol)
+{
+ SV_DropClient (false); // client wants to disconnect
+}
+
+static void Netmsg_clc_move(protocol_t *protocol)
+{
+ SV_ReadClientMove();
+}
+
+static void Netmsg_clc_ackdownloaddata(protocol_t *protocol)
+{
+ int start = MSG_ReadLong(&sv_message);
+ int num = MSG_ReadShort(&sv_message);
+ if (host_client->download_file && host_client->download_started)
+ {
+ if (host_client->download_expectedposition == start)
+ {
+ int size = (int)FS_FileSize(host_client->download_file);
+ // a data block was successfully received by the client,
+ // update the expected position on the next data block
+ host_client->download_expectedposition = start + num;
+ // if this was the last data block of the file, it's done
+ if (host_client->download_expectedposition >= FS_FileSize(host_client->download_file))
+ {
+ // tell the client that the download finished
+ // we need to calculate the crc now
+ //
+ // note: at this point the OS probably has the file
+ // entirely in memory, so this is a faster operation
+ // now than it was when the download started.
+ //
+ // it is also preferable to do this at the end of the
+ // download rather than the start because it reduces
+ // potential for Denial Of Service attacks against the
+ // server.
+ int crc;
+ unsigned char *temp;
+ FS_Seek(host_client->download_file, 0, SEEK_SET);
+ temp = (unsigned char *) Mem_Alloc(tempmempool, size);
+ FS_Read(host_client->download_file, temp, size);
+ crc = CRC_Block(temp, size);
+ Mem_Free(temp);
+ // calculated crc, send the file info to the client
+ // (so that it can verify the data)
+ SV_ClientCommands("\ncl_downloadfinished %i %i %s\n", size, crc, host_client->download_name);
+ Con_DPrintf("Download of %s by %s has finished\n", host_client->download_name, host_client->name);
+ FS_Close(host_client->download_file);
+ host_client->download_file = NULL;
+ host_client->download_name[0] = 0;
+ host_client->download_expectedposition = 0;
+ host_client->download_started = false;
+ }
+ }
+ else
+ {
+ // a data block was lost, reset to the expected position
+ // and resume sending from there
+ FS_Seek(host_client->download_file, host_client->download_expectedposition, SEEK_SET);
+ }
+ }
+}
+
+static void Netmsg_clc_ackframe(protocol_t *protocol)
+{
+ int num;
+ if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+ num = MSG_ReadLong(&sv_message);
+ if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+ if (developer_networkentities.integer >= 10)
+ Con_Printf("recv clc_ackframe %i\n", num);
+ // if the client hasn't progressed through signons yet,
+ // ignore any clc_ackframes we get (they're probably from the
+ // previous level)
+ if (host_client->begun && host_client->latestframenum < num)
+ {
+ int i;
+ for (i = host_client->latestframenum + 1;i < num;i++)
+ if (!SV_FrameLost(i))
+ break;
+ SV_FrameAck(num);
+ host_client->latestframenum = num;
+ }
+}
#include "quakedef.h"
#include "sv_demo.h"
+#include "sv_user.h"
#define DEBUGMOVES 0
static usercmd_t usercmd;
if (sv.loadgame)
{
MSG_WriteByte (&host_client->netconnection->message, svc_setangle);
- MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, v_angle)[0], sv.protocol);
- MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, v_angle)[1], sv.protocol);
- MSG_WriteAngle (&host_client->netconnection->message, 0, sv.protocol);
+ sv.protocol->WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, v_angle)[0]);
+ sv.protocol->WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, v_angle)[1]);
+ sv.protocol->WriteAngle (&host_client->netconnection->message, 0);
}
else
{
MSG_WriteByte (&host_client->netconnection->message, svc_setangle);
- MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, angles)[0], sv.protocol);
- MSG_WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, angles)[1], sv.protocol);
- MSG_WriteAngle (&host_client->netconnection->message, 0, sv.protocol);
+ sv.protocol->WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, angles)[0]);
+ sv.protocol->WriteAngle (&host_client->netconnection->message, PRVM_serveredictvector(host_client->edict, angles)[1]);
+ sv.protocol->WriteAngle (&host_client->netconnection->message, 0);
}
SV_WriteClientdataToMessage (host_client, host_client->edict, &host_client->netconnection->message, stats);
*/
int sv_numreadmoves = 0;
usercmd_t sv_readmoves[CL_MAX_USERCMDS];
-static void SV_ReadClientMove (void)
+void SV_ReadClientMove (void)
{
prvm_prog_t *prog = SVVM_prog;
int i;
if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
// read ping time
- if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3 && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5 && sv.protocol != PROTOCOL_DARKPLACES6)
+ 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)
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__);
// read current angles
for (i = 0;i < 3;i++)
{
- if (sv.protocol == PROTOCOL_QUAKE || 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)
move->viewangles[i] = MSG_ReadAngle8i(&sv_message);
- else if (sv.protocol == PROTOCOL_DARKPLACES1)
+ else if (sv.protocol == &protocol_dpp1)
move->viewangles[i] = MSG_ReadAngle16i(&sv_message);
- else if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3)
+ else if (sv.protocol == &protocol_dpp2 || sv.protocol == &protocol_dpp3)
move->viewangles[i] = MSG_ReadAngle32f(&sv_message);
else
move->viewangles[i] = MSG_ReadAngle16i(&sv_message);
// 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_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3 || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ 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)
move->buttons = MSG_ReadByte(&sv_message);
else
move->buttons = MSG_ReadLong(&sv_message);
if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
// PRYDON_CLIENTCURSOR
- if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3 && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5)
+ 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)
{
// 30 bytes
move->cursor_screen[0] = MSG_ReadShort(&sv_message) * (1.0f / 32767.0f);
PRVM_serveredictfloat(host_client->edict, ping_movementloss) = movementloss / (float) NETGRAPH_PACKETS;
}
-static qbool SV_FrameLost(int framenum)
+qbool SV_FrameLost(int framenum)
{
if (host_client->entitydatabase5)
{
return false;
}
-static void SV_FrameAck(int framenum)
+void SV_FrameAck(int framenum)
{
if (host_client->entitydatabase)
EntityFrame_AckFrame(host_client->entitydatabase, framenum);
*/
void SV_ReadClientMessage(void)
{
- prvm_prog_t *prog = SVVM_prog;
- int netcmd, num, start;
- char *s, *p, *q;
+ int netcmd;
+ protocol_t *protocol = sv.protocol;
if(sv_autodemo_perclient.integer >= 2)
SV_WriteDemoMessage(host_client, &(host_client->netconnection->message), true);
//MSG_BeginReading ();
sv_numreadmoves = 0;
- for(;;)
+ while(host_client)
{
if (!host_client->active)
{
SV_ExecuteClientMoves();
break;
}
-
- switch (netcmd)
+ if(!netcmd || netcmd >= protocol->max_clcmsg || !protocol->clcmsg[netcmd].func)
{
- default:
Con_Printf("SV_ReadClientMessage: unknown command char %i (at offset 0x%x)\n", netcmd, sv_message.readcount);
if (developer_networking.integer)
Com_HexDumpToConsole(sv_message.data, sv_message.cursize);
SV_DropClient (false);
return;
-
- case clc_nop:
- break;
-
- case clc_stringcmd:
- // allow reliable messages now as the client is done with initial loading
- if (host_client->sendsignon == 2)
- host_client->sendsignon = 0;
- s = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
- q = NULL;
- for(p = s; *p; ++p) switch(*p)
- {
- case 10:
- case 13:
- if(!q)
- q = p;
- break;
- default:
- if(q)
- goto clc_stringcmd_invalid; // newline seen, THEN something else -> possible exploit
- break;
- }
- if(q)
- *q = 0;
- if (strncasecmp(s, "spawn", 5) == 0
- || strncasecmp(s, "begin", 5) == 0
- || strncasecmp(s, "prespawn", 8) == 0)
- Cmd_ExecuteString (&cmd_serverfromclient, s, src_client, true);
- else if (PRVM_serverfunction(SV_ParseClientCommand))
- {
- int restorevm_tempstringsbuf_cursize;
- restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
- PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, s);
- PRVM_serverglobalfloat(time) = sv.time;
- PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
- prog->ExecuteProgram(prog, PRVM_serverfunction(SV_ParseClientCommand), "QC function SV_ParseClientCommand is missing");
- prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
- }
- else
- Cmd_ExecuteString (&cmd_serverfromclient, s, src_client, true);
- break;
-
-clc_stringcmd_invalid:
- Con_Printf("Received invalid stringcmd from %s\n", host_client->name);
- if(developer.integer > 0)
- Com_HexDumpToConsole((unsigned char *) s, (int)strlen(s));
- break;
-
- case clc_disconnect:
- SV_DropClient (false); // client wants to disconnect
- return;
-
- case clc_move:
- SV_ReadClientMove();
- break;
-
- case clc_ackdownloaddata:
- start = MSG_ReadLong(&sv_message);
- num = MSG_ReadShort(&sv_message);
- if (host_client->download_file && host_client->download_started)
- {
- if (host_client->download_expectedposition == start)
- {
- int size = (int)FS_FileSize(host_client->download_file);
- // a data block was successfully received by the client,
- // update the expected position on the next data block
- host_client->download_expectedposition = start + num;
- // if this was the last data block of the file, it's done
- if (host_client->download_expectedposition >= FS_FileSize(host_client->download_file))
- {
- // tell the client that the download finished
- // we need to calculate the crc now
- //
- // note: at this point the OS probably has the file
- // entirely in memory, so this is a faster operation
- // now than it was when the download started.
- //
- // it is also preferable to do this at the end of the
- // download rather than the start because it reduces
- // potential for Denial Of Service attacks against the
- // server.
- int crc;
- unsigned char *temp;
- FS_Seek(host_client->download_file, 0, SEEK_SET);
- temp = (unsigned char *) Mem_Alloc(tempmempool, size);
- FS_Read(host_client->download_file, temp, size);
- crc = CRC_Block(temp, size);
- Mem_Free(temp);
- // calculated crc, send the file info to the client
- // (so that it can verify the data)
- SV_ClientCommands("\ncl_downloadfinished %i %i %s\n", size, crc, host_client->download_name);
- Con_DPrintf("Download of %s by %s has finished\n", host_client->download_name, host_client->name);
- FS_Close(host_client->download_file);
- host_client->download_file = NULL;
- host_client->download_name[0] = 0;
- host_client->download_expectedposition = 0;
- host_client->download_started = false;
- }
- }
- else
- {
- // a data block was lost, reset to the expected position
- // and resume sending from there
- FS_Seek(host_client->download_file, host_client->download_expectedposition, SEEK_SET);
- }
- }
- break;
-
- case clc_ackframe:
- if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
- num = MSG_ReadLong(&sv_message);
- if (sv_message.badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
- if (developer_networkentities.integer >= 10)
- Con_Printf("recv clc_ackframe %i\n", num);
- // if the client hasn't progressed through signons yet,
- // ignore any clc_ackframes we get (they're probably from the
- // previous level)
- if (host_client->begun && host_client->latestframenum < num)
- {
- int i;
- for (i = host_client->latestframenum + 1;i < num;i++)
- if (!SV_FrameLost(i))
- break;
- SV_FrameAck(num);
- host_client->latestframenum = num;
- }
- break;
}
+ else
+ protocol->clcmsg[netcmd].func(protocol);
}
}
--- /dev/null
+#include "qtypes.h"
+
+void SV_ReadClientMove (void);
+qbool SV_FrameLost(int framenum);
+void SV_FrameAck(int framenum);
\ No newline at end of file
else
MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
- MSG_WriteVector(&sv.signon, pos, sv.protocol);
+ sv.protocol->WriteVector(&sv.signon, pos);
- if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ if (large || sv.protocol == &protocol_nehahrabjp || sv.protocol == &protocol_nehahrabjp2 || sv.protocol == &protocol_nehahrabjp3)
MSG_WriteShort (&sv.signon, soundnum);
else
MSG_WriteByte (&sv.signon, soundnum);
static void VM_SV_WriteAngle(prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
- MSG_WriteAngle (WriteDest(prog), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
+ sv.protocol->WriteAngle (WriteDest(prog), PRVM_G_FLOAT(OFS_PARM1));
}
static void VM_SV_WriteCoord(prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
- MSG_WriteCoord (WriteDest(prog), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
+ sv.protocol->WriteCoord (WriteDest(prog), PRVM_G_FLOAT(OFS_PARM1));
}
static void VM_SV_WriteString(prvm_prog_t *prog)
MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex));
MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
}
- else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+ else 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, skin));
for (i=0 ; i<3 ; i++)
{
- MSG_WriteCoord(&sv.signon, PRVM_serveredictvector(ent, origin)[i], sv.protocol);
- MSG_WriteAngle(&sv.signon, PRVM_serveredictvector(ent, angles)[i], sv.protocol);
+ sv.protocol->WriteCoord(&sv.signon, PRVM_serveredictvector(ent, origin)[i]);
+ sv.protocol->WriteAngle(&sv.signon, PRVM_serveredictvector(ent, angles)[i]);
}
// throw the entity away now
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_BLOOD);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// velocity
MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
// min
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// speed
- MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2));
// count
MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
SV_FlushBroadcastMessages();
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// color
MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
// min
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// velocity
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
// count
MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
// color
// gravity true/false
MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
// randomvel
- MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6));
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
// min
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// velocity
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
// count
MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
// color
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
// min
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// max
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// velocity
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
// count
MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
// color
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPARK);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// velocity
MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// radius
MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
// lifetime
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPIKE);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_TELEPORT);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
// origin
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// color
MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
// owner entity
MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
SV_FlushBroadcastMessages();
}
// owner entity
MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
SV_FlushBroadcastMessages();
}
// owner entity
MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
SV_FlushBroadcastMessages();
}
// owner entity
MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
// start
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// end
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2]);
SV_FlushBroadcastMessages();
}
VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
SV_FlushBroadcastMessages();
}
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
// org
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2]);
// vel
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
- MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1]);
+ sv.protocol->WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2]);
// count
MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
SV_FlushBroadcastMessages();
MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
VectorCopy(PRVM_G_VECTOR(OFS_PARM2), start);
VectorCopy(PRVM_G_VECTOR(OFS_PARM3), end);
- MSG_WriteVector(&sv.datagram, start, sv.protocol);
- MSG_WriteVector(&sv.datagram, end, sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, start);
+ sv.protocol->WriteVector(&sv.datagram, end);
SV_FlushBroadcastMessages();
}
// 1+2+12=15 bytes
MSG_WriteByte(&sv.datagram, svc_pointparticles1);
MSG_WriteShort(&sv.datagram, effectnum);
- MSG_WriteVector(&sv.datagram, org, sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, org);
}
else
{
// 1+2+12+12+2=29 bytes
MSG_WriteByte(&sv.datagram, svc_pointparticles);
MSG_WriteShort(&sv.datagram, effectnum);
- MSG_WriteVector(&sv.datagram, org, sv.protocol);
- MSG_WriteVector(&sv.datagram, vel, sv.protocol);
+ sv.protocol->WriteVector(&sv.datagram, org);
+ sv.protocol->WriteVector(&sv.datagram, vel);
MSG_WriteShort(&sv.datagram, count);
}
armor = MSG_ReadByte(&cl_message);
blood = MSG_ReadByte(&cl_message);
- MSG_ReadVector(&cl_message, from, cls.protocol);
+ cls.protocol->ReadVector(&cl_message, from);
// Send the Dmg Globals to CSQC
CL_VM_UpdateDmgGlobals(blood, armor, from);
if (clintermission)
{
// entity is a fixed camera, just copy the matrix
- if (cls.protocol == PROTOCOL_QUAKEWORLD)
+ if (cls.protocol == &protocol_quakeworld)
Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, cl.qw_intermission_origin[0], cl.qw_intermission_origin[1], cl.qw_intermission_origin[2], cl.qw_intermission_angles[0], cl.qw_intermission_angles[1], cl.qw_intermission_angles[2], 1);
else
{