05 Aug 2010
This commit is contained in:
parent
edcae071bd
commit
621d270b4b
|
@ -1215,7 +1215,6 @@ addEntity:
|
|||
state->rendermode = pEntity->pev->rendermode; // rendering mode
|
||||
state->renderamt = pEntity->pev->renderamt; // alpha value
|
||||
state->animtime = (int)(1000.0 * pEntity->pev->animtime) * 0.001; // sequence time
|
||||
state->localtime = (int)(1000.0 * pEntity->pev->ltime) * 0.001; // movement time
|
||||
state->scale = pEntity->pev->scale; // shared client and render flags
|
||||
state->movetype = (movetype_t)pEntity->pev->movetype;
|
||||
state->frame = pEntity->pev->frame; // any model current frame
|
||||
|
@ -1223,24 +1222,27 @@ addEntity:
|
|||
state->mins = pEntity->pev->mins;
|
||||
state->maxs = pEntity->pev->maxs;
|
||||
state->flags = pEntity->pev->flags;
|
||||
state->rendercolor = pEntity->pev->rendercolor;
|
||||
state->oldorigin = pEntity->pev->oldorigin;
|
||||
state->colormap = pEntity->pev->colormap; // attachments
|
||||
|
||||
state->rendercolor.r = (byte)pEntity->pev->rendercolor.x;
|
||||
state->rendercolor.g = (byte)pEntity->pev->rendercolor.y;
|
||||
state->rendercolor.b = (byte)pEntity->pev->rendercolor.z;
|
||||
|
||||
if( pEntity->pev->groundentity )
|
||||
state->groundent = ENTINDEX( pEntity->pev->groundentity );
|
||||
else state->groundent = -1;
|
||||
state->onground = ENTINDEX( pEntity->pev->groundentity );
|
||||
else state->onground = 0;
|
||||
|
||||
// translate attached entity
|
||||
if( pEntity->pev->aiment )
|
||||
state->aiment = ENTINDEX( pEntity->pev->aiment );
|
||||
else state->aiment = -1;
|
||||
else state->aiment = 0;
|
||||
|
||||
// studio model sequence
|
||||
if( pEntity->pev->sequence != -1 )
|
||||
state->sequence = pEntity->pev->sequence;
|
||||
|
||||
for( int i = 0; i < 16; i++ )
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
// copy blendings and bone ctrlrs
|
||||
state->blending[i] = pEntity->pev->blending[i];
|
||||
|
@ -1256,18 +1258,12 @@ addEntity:
|
|||
pEntity->pev->teleport_time = 0.0f;
|
||||
}
|
||||
|
||||
if( pEntity->pev->viewmodel )
|
||||
state->viewmodel = MODEL_INDEX( STRING( pEntity->pev->viewmodel ));
|
||||
else state->viewmodel = 0;
|
||||
|
||||
if( pEntity->pev->aiment )
|
||||
state->aiment = ENTINDEX( pEntity->pev->aiment );
|
||||
else state->aiment = -1;
|
||||
else state->aiment = 0;
|
||||
|
||||
state->viewoffset = pEntity->pev->view_ofs;
|
||||
state->viewangles = pEntity->pev->v_angle;
|
||||
state->idealpitch = pEntity->pev->idealpitch;
|
||||
state->punch_angles = pEntity->pev->punchangle;
|
||||
state->velocity = pEntity->pev->velocity;
|
||||
state->basevelocity = pEntity->pev->clbasevelocity;
|
||||
state->iStepLeft = pEntity->pev->iStepLeft;
|
||||
|
@ -1279,13 +1275,7 @@ addEntity:
|
|||
if( pEntity->pev->weaponmodel != iStringNull )
|
||||
state->weaponmodel = MODEL_INDEX( STRING( pEntity->pev->weaponmodel ));
|
||||
else state->weaponmodel = 0;
|
||||
state->weapons = pEntity->pev->weapons;
|
||||
state->maxspeed = pEntity->pev->maxspeed;
|
||||
|
||||
// clamp fov
|
||||
if( pEntity->pev->fov < 0.0 ) pEntity->pev->fov = 0.0;
|
||||
if( pEntity->pev->fov > 160 ) pEntity->pev->fov = 160;
|
||||
state->fov = pEntity->pev->fov;
|
||||
}
|
||||
else if( state->ed_type == ED_AMBIENT )
|
||||
{
|
||||
|
@ -1306,7 +1296,7 @@ addEntity:
|
|||
// translate StartBeamEntity
|
||||
if( pEntity->pev->owner )
|
||||
state->owner = ENTINDEX( pEntity->pev->owner );
|
||||
else state->owner = -1;
|
||||
else state->owner = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1332,9 +1322,9 @@ void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodeli
|
|||
// render information
|
||||
baseline->rendermode = (byte)entity->v.rendermode;
|
||||
baseline->renderamt = (byte)entity->v.renderamt;
|
||||
baseline->rendercolor.x = (byte)entity->v.rendercolor.x;
|
||||
baseline->rendercolor.y = (byte)entity->v.rendercolor.y;
|
||||
baseline->rendercolor.z = (byte)entity->v.rendercolor.z;
|
||||
baseline->rendercolor.r = (byte)entity->v.rendercolor.x;
|
||||
baseline->rendercolor.g = (byte)entity->v.rendercolor.y;
|
||||
baseline->rendercolor.b = (byte)entity->v.rendercolor.z;
|
||||
baseline->renderfx = (byte)entity->v.renderfx;
|
||||
|
||||
baseline->mins = entity->v.mins;
|
||||
|
|
|
@ -188,13 +188,6 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
m_fLerp = 1.0f;
|
||||
else m_fLerp = GetLerpFrac();
|
||||
|
||||
if( state->flags & FL_PROJECTILE && state->ed_flags & ( ESF_NO_PREDICTION|ESF_NODELTA ))
|
||||
{
|
||||
// cut rocket trail, dont pass it from teleport
|
||||
// FIXME: don't work
|
||||
g_pViewRenderBeams->KillDeadBeams( ent );
|
||||
}
|
||||
|
||||
// copy state to progs
|
||||
ent->v.modelindex = state->modelindex;
|
||||
ent->v.weaponmodel = state->weaponmodel;
|
||||
|
@ -212,23 +205,25 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
ent->v.colormap = state->colormap;
|
||||
ent->v.rendermode = state->rendermode;
|
||||
ent->v.renderfx = state->renderfx;
|
||||
ent->v.fov = state->fov;
|
||||
// ent->v.fov = state->fov;
|
||||
ent->v.scale = state->scale;
|
||||
ent->v.weapons = state->weapons;
|
||||
ent->v.gravity = state->gravity;
|
||||
ent->v.health = state->health;
|
||||
ent->v.solid = state->solid;
|
||||
ent->v.movetype = state->movetype;
|
||||
ent->v.flags = state->flags;
|
||||
ent->v.idealpitch = state->idealpitch;
|
||||
ent->v.animtime = state->animtime;
|
||||
ent->v.ltime = state->localtime;
|
||||
|
||||
if( state->groundent != -1 )
|
||||
ent->v.groundentity = GetEntityByIndex( state->groundent );
|
||||
if( ent != GetLocalPlayer())
|
||||
{
|
||||
ent->v.health = state->health;
|
||||
}
|
||||
|
||||
if( state->onground )
|
||||
ent->v.groundentity = GetEntityByIndex( state->onground );
|
||||
else ent->v.groundentity = NULL;
|
||||
|
||||
if( state->aiment != -1 )
|
||||
if( state->aiment )
|
||||
ent->v.aiment = GetEntityByIndex( state->aiment );
|
||||
else ent->v.aiment = NULL;
|
||||
|
||||
|
@ -255,15 +250,17 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
else
|
||||
{
|
||||
ent->v.angles = LerpAngle( prev->angles, state->angles, m_fLerp );
|
||||
ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp );
|
||||
ent->v.basevelocity = LerpPoint( prev->basevelocity, state->basevelocity, m_fLerp );
|
||||
}
|
||||
|
||||
// interpolate scale, renderamount etc
|
||||
ent->v.scale = LerpPoint( prev->scale, state->scale, m_fLerp );
|
||||
ent->v.rendercolor = LerpPoint( prev->rendercolor, state->rendercolor, m_fLerp );
|
||||
ent->v.renderamt = LerpPoint( prev->renderamt, state->renderamt, m_fLerp );
|
||||
|
||||
ent->v.rendercolor.x = state->rendercolor.r;
|
||||
ent->v.rendercolor.y = state->rendercolor.g;
|
||||
ent->v.rendercolor.z = state->rendercolor.b;
|
||||
|
||||
if( ent->v.animtime )
|
||||
{
|
||||
// use normal studio lerping
|
||||
|
@ -278,32 +275,21 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
switch( state->ed_type )
|
||||
{
|
||||
case ED_CLIENT:
|
||||
ent->v.punchangle = LerpAngle( prev->punch_angles, state->punch_angles, m_fLerp );
|
||||
ent->v.v_angle = LerpAngle( prev->viewangles, state->viewangles, m_fLerp );
|
||||
ent->v.view_ofs = LerpPoint( prev->viewoffset, state->viewoffset, m_fLerp );
|
||||
|
||||
if( prev->fov != 90.0f && state->fov == 90.0f )
|
||||
ent->v.fov = state->fov; // fov is reset, so don't lerping
|
||||
else ent->v.fov = LerpPoint( prev->fov, state->fov, m_fLerp );
|
||||
if( ent != GetLocalPlayer( ))
|
||||
{
|
||||
ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp );
|
||||
|
||||
if( prev->fov != 90.0f && state->fov == 90.0f )
|
||||
ent->v.fov = state->fov; // fov is reset, so don't lerping
|
||||
else ent->v.fov = LerpPoint( prev->fov, state->fov, m_fLerp );
|
||||
}
|
||||
|
||||
ent->v.maxspeed = state->maxspeed;
|
||||
|
||||
ent->v.iStepLeft = state->iStepLeft;
|
||||
ent->v.flFallVelocity = state->flFallVelocity;
|
||||
|
||||
if( ent == GetLocalPlayer())
|
||||
{
|
||||
edict_t *viewent = GetViewModel();
|
||||
|
||||
// if viewmodel has changed update sequence here
|
||||
if( viewent->v.modelindex != state->viewmodel )
|
||||
{
|
||||
// ALERT( at_console, "Viewmodel changed\n" );
|
||||
SendWeaponAnim( viewent->v.sequence, viewent->v.body, viewent->v.framerate );
|
||||
}
|
||||
// setup player viewmodel (only for local player!)
|
||||
viewent->v.modelindex = state->viewmodel;
|
||||
gHUD.m_flFOV = ent->v.fov; // keep client fov an actual
|
||||
}
|
||||
break;
|
||||
case ED_PORTAL:
|
||||
case ED_MOVER:
|
||||
|
@ -326,7 +312,7 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
case ED_BEAM:
|
||||
ent->v.oldorigin = state->oldorigin; // beam endpoint
|
||||
ent->v.frags = state->gaitsequence;
|
||||
if( state->owner != -1 )
|
||||
if( state->owner )
|
||||
ent->v.owner = GetEntityByIndex( state->owner );
|
||||
else ent->v.owner = NULL;
|
||||
|
||||
|
@ -341,11 +327,11 @@ void HUD_UpdateEntityVars( edict_t *ent, const entity_state_t *state, const enti
|
|||
int i;
|
||||
|
||||
// copy blendings
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
for( i = 0; i < 4; i++ )
|
||||
ent->v.blending[i] = state->blending[i];
|
||||
|
||||
// copy controllers
|
||||
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
|
||||
for( i = 0; i < 4; i++ )
|
||||
ent->v.controller[i] = state->controller[i];
|
||||
|
||||
// g-cont. moved here because we may needs apply null scale to skyportal
|
||||
|
@ -372,20 +358,66 @@ playerstate update in entity_state_t. In order for these overrides to eventuall
|
|||
structure, we need to copy them into the state structure at this point.
|
||||
=========================
|
||||
*/
|
||||
void HUD_UpdateClientVars( entity_state_t *state, const clientdata_t *client )
|
||||
void HUD_UpdateClientVars( edict_t *ent, const clientdata_t *state, const clientdata_t *prev )
|
||||
{
|
||||
// Copy origin
|
||||
state->origin = client->origin;
|
||||
float m_fLerp;
|
||||
|
||||
m_fLerp = GetLerpFrac();
|
||||
|
||||
// copy origin
|
||||
ent->v.origin = LerpPoint( prev->origin, state->origin, m_fLerp );
|
||||
ent->v.velocity = state->velocity;
|
||||
ent->v.flags = state->flags;
|
||||
ent->v.health = state->health;
|
||||
ent->v.flags = state->flags;
|
||||
|
||||
ent->v.punchangle = LerpAngle( prev->punchangle, state->punchangle, m_fLerp );
|
||||
ent->v.view_ofs = LerpPoint( prev->view_ofs, state->view_ofs, m_fLerp );
|
||||
|
||||
if( prev->fov != 90.0f && state->fov == 90.0f )
|
||||
ent->v.fov = state->fov; // fov is reset, so don't lerping
|
||||
else ent->v.fov = LerpPoint( prev->fov, state->fov, m_fLerp );
|
||||
|
||||
// Water state
|
||||
ent->v.watertype = state->watertype;
|
||||
ent->v.waterlevel = state->waterlevel;
|
||||
|
||||
// suit and weapon bits
|
||||
ent->v.weapons = state->weapons;
|
||||
|
||||
ent->v.bInDuck = state->bInDuck;
|
||||
ent->v.flTimeStepSound = state->flTimeStepSound;
|
||||
ent->v.flDuckTime = state->flDuckTime;
|
||||
ent->v.flSwimTime = state->flSwimTime;
|
||||
ent->v.teleport_time = state->waterjumptime;
|
||||
|
||||
// Viewmodel code
|
||||
edict_t *viewent = GetViewModel();
|
||||
|
||||
// if viewmodel has changed update sequence here
|
||||
if( viewent->v.modelindex != state->viewmodel )
|
||||
{
|
||||
// ALERT( at_console, "Viewmodel changed\n" );
|
||||
SendWeaponAnim( viewent->v.sequence, viewent->v.body, viewent->v.framerate );
|
||||
}
|
||||
|
||||
// setup player viewmodel (only for local player!)
|
||||
viewent->v.modelindex = state->viewmodel;
|
||||
gHUD.m_flFOV = ent->v.fov; // keep client fov an actual
|
||||
|
||||
ent->v.maxspeed = state->maxspeed;
|
||||
ent->v.weaponanim = state->weaponanim; // g-cont. hmm. we can grab weaponanim from here ?
|
||||
ent->v.pushmsec = state->pushmsec;
|
||||
|
||||
// Spectator
|
||||
state->iuser1 = client->iuser1;
|
||||
state->iuser2 = client->iuser2;
|
||||
ent->v.iuser1 = state->iuser1;
|
||||
ent->v.iuser2 = state->iuser2;
|
||||
|
||||
// Duck prevention
|
||||
state->iuser3 = client->iuser3;
|
||||
ent->v.iuser3 = state->iuser3;
|
||||
|
||||
// Fire prevention
|
||||
state->iuser4 = client->iuser4;
|
||||
ent->v.iuser4 = state->iuser4;
|
||||
}
|
||||
|
||||
int HUD_AddVisibleEntity( edict_t *pEnt, int ed_type )
|
||||
|
|
|
@ -124,7 +124,6 @@ inline void CL_PlaySound( int iSound, float flVolume, Vector &pos, float pitch =
|
|||
#define ConsolePrint (*g_engfuncs.pfnConsolePrint)
|
||||
#define GetViewAngles (*g_engfuncs.pfnGetViewAngles)
|
||||
#define SetViewAngles (*g_engfuncs.pfnSetViewAngles)
|
||||
#define GetEntityByIndex (*g_engfuncs.pfnGetEntityByIndex)
|
||||
#define GetLocalPlayer (*g_engfuncs.pfnGetLocalPlayer)
|
||||
#define GetClientMaxspeed (*g_engfuncs.pfnGetClientMaxspeed)
|
||||
#define IsSpectateOnly (*g_engfuncs.pfnIsSpectateOnly)
|
||||
|
|
|
@ -518,9 +518,6 @@ void IN_CreateMove( usercmd_t *cmd, int msec, int active )
|
|||
// set button and flag bits
|
||||
cmd->buttons = CL_ButtonBits( 1 );
|
||||
|
||||
// random seed for predictable random values
|
||||
cmd->random_seed = RANDOM_LONG( 0, 0x7fffffff ); // full range
|
||||
|
||||
last_msec = msec;
|
||||
|
||||
GetViewAngles( cl_viewangles );
|
||||
|
|
|
@ -23,7 +23,7 @@ void DBG_AssertFunction( BOOL fExpr, const char* szExpr, const char* szFile, int
|
|||
if( szMessage != NULL )
|
||||
sprintf( szOut, "ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage );
|
||||
else sprintf( szOut, "ASSERT FAILED:\n %s \n(%s@%d)", szExpr, szFile, szLine );
|
||||
HOST_ERROR( szOut );
|
||||
ALERT( at_error, szOut );
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@ void DBG_AssertFunction( BOOL fExpr, const char* szExpr, const char* szFile, int
|
|||
#define ASSERTSZ( f, sz )
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define GetEntityByIndex(e) DBG_GetEntityByIndex( e, __FILE__, __LINE__ )
|
||||
#else
|
||||
#define GetEntityByIndex (*g_engfuncs.pfnGetEntityByIndex)
|
||||
#endif
|
||||
|
||||
extern DLL_GLOBAL const Vector g_vecZero;
|
||||
extern cl_globalvars_t *gpGlobals;
|
||||
extern movevars_t *gpMovevars;
|
||||
|
@ -35,7 +41,7 @@ extern int HUD_VidInit( void );
|
|||
extern void HUD_Init( void );
|
||||
extern int HUD_Redraw( float flTime, int state );
|
||||
extern void HUD_UpdateEntityVars( edict_t *out, const entity_state_t *s, const entity_state_t *p );
|
||||
extern void HUD_UpdateClientVars( entity_state_t *state, const clientdata_t *client );
|
||||
extern void HUD_UpdateClientVars( edict_t *out, const clientdata_t *s, const clientdata_t *p );
|
||||
extern void HUD_UpdateOnRemove( edict_t *pEdict );
|
||||
extern void HUD_Reset( void );
|
||||
extern void HUD_StartFrame( void );
|
||||
|
@ -173,6 +179,14 @@ inline int ConsoleStringLen( const char *string )
|
|||
return _width;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
inline edict_t *DBG_GetEntityByIndex( int entnum, const char *file, const int line )
|
||||
{
|
||||
DBG_AssertFunction(( entnum >= 0 && entnum < gpGlobals->numEntities ), "Invalid entnum", file, line, NULL );
|
||||
return (*g_engfuncs.pfnGetEntityByIndex)( entnum );
|
||||
}
|
||||
#endif
|
||||
|
||||
extern Vector BitsToDir( int bits );
|
||||
|
||||
// message reading
|
||||
|
|
|
@ -139,7 +139,7 @@ void V_Init( void )
|
|||
//==========================
|
||||
void V_StartPitchDrift( void )
|
||||
{
|
||||
if( pd.laststop == GetClientTime())
|
||||
if( pd.laststop == GetClientTime( ))
|
||||
return;
|
||||
|
||||
if( pd.nodrift || !pd.pitchvel )
|
||||
|
|
|
@ -46,4 +46,6 @@ typedef float vec_t;
|
|||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||
|
||||
typedef struct { byte r; byte g; byte b; } color24;
|
||||
|
||||
#endif//BASETYPES_H
|
|
@ -228,7 +228,7 @@ typedef struct
|
|||
void (*pfnInit)( void );
|
||||
int (*pfnRedraw)( float flTime, int state );
|
||||
void (*pfnUpdateEntityVars)( edict_t *out, const struct entity_state_s *in1, const struct entity_state_s *in2 );
|
||||
void (*pfnUpdateClientVars)( struct entity_state_s *state, const struct clientdata_s *client );
|
||||
void (*pfnUpdateClientVars)( edict_t *ent, const struct clientdata_s *in1, const struct clientdata_s *in2 );
|
||||
void (*pfnOnFreeEntPrivateData)( edict_t *pEnt ); // this is called on entity removed
|
||||
void (*pfnReset)( void );
|
||||
void (*pfnStartFrame)( void );
|
||||
|
|
|
@ -41,58 +41,63 @@ typedef struct entity_state_s
|
|||
string_t classname; // edict classname
|
||||
int ed_flags; // engine clearing this at end of server frame
|
||||
|
||||
// physics information
|
||||
// Fields which can be transitted and reconstructed over the network stream
|
||||
vec3_t origin;
|
||||
vec3_t angles; // entity angles, not viewangles
|
||||
solid_t solid; // entity solid
|
||||
movetype_t movetype; // entity movetype
|
||||
float friction; // friction, for prediction.
|
||||
int gravity; // gravity multiplier
|
||||
int aiment; // attached entity
|
||||
int owner; // projectiles owner
|
||||
int groundent; // onground edict num, valid only if FL_ONGROUND is set, else -1
|
||||
vec3_t mins; // entity bbox mins
|
||||
vec3_t maxs; // entity bbox maxs
|
||||
vec3_t velocity; // for predicting & tracing
|
||||
vec3_t basevelocity; // for predicting & tracing
|
||||
vec3_t oldorigin; // portal pvs, lerping state, etc
|
||||
int contents; // for predicting & tracing on client
|
||||
int modelindex;
|
||||
int sequence;
|
||||
float frame;
|
||||
int colormap;
|
||||
short skin;
|
||||
short solid;
|
||||
int effects;
|
||||
float scale;
|
||||
byte eflags;
|
||||
|
||||
// model state
|
||||
int modelindex; // general modelindex
|
||||
int colormap; // change base color for some textures or sprite frames
|
||||
float scale; // model or sprite scale, affects to physics too
|
||||
float frame; // % playback position in animation sequences (0..255)
|
||||
int skin; // skin for studiomodels
|
||||
int body; // sub-model selection for studiomodels
|
||||
float localtime; // pev->ltime for monsters for right lerping on platforms, trains etc
|
||||
float animtime; // auto-animating time
|
||||
float framerate; // custom framerate, specified by QC
|
||||
int sequence; // animation sequence (0 - 255)
|
||||
int blending[16]; // studio animation blending
|
||||
int controller[16]; // studio bone controllers
|
||||
int flags; // v.flags
|
||||
int effects; // effect flags like q1 and hl1
|
||||
int renderfx; // render effects same as hl1
|
||||
float renderamt; // alpha value or like somewhat
|
||||
vec3_t rendercolor; // hl1 legacy stuff, working, but not needed
|
||||
int rendermode; // hl1 legacy stuff, working, but not needed
|
||||
// Render information
|
||||
int rendermode;
|
||||
int renderamt;
|
||||
color24 rendercolor;
|
||||
int renderfx;
|
||||
|
||||
int movetype;
|
||||
float animtime;
|
||||
float framerate;
|
||||
int body;
|
||||
byte controller[4];
|
||||
byte blending[4];
|
||||
vec3_t velocity;
|
||||
|
||||
// Send bbox down to client for use during prediction.
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
|
||||
int aiment;
|
||||
int owner; // If owned by a player, the index of that player ( for projectiles )
|
||||
float friction; // Friction, for prediction.
|
||||
float gravity; // Gravity multiplier
|
||||
|
||||
// client specific
|
||||
vec3_t punch_angles; // add to view direction to get render angles
|
||||
vec3_t viewangles; // already calculated view angles on server-side
|
||||
vec3_t viewoffset; // viewoffset over ground
|
||||
int gaitsequence; // client\nps\bot gaitsequence
|
||||
int viewmodel; // contains viewmodel index
|
||||
int weaponmodel; // contains weaponmodel index
|
||||
float idealpitch; // client idealpitch
|
||||
float maxspeed; // min( pev->maxspeed, sv_maxspeed->value )
|
||||
float health; // client health (other parms can be send by custom messages)
|
||||
int weapons; // weapon flags
|
||||
float fov; // horizontal field of view
|
||||
int iStepLeft; // synched footsteps
|
||||
float flFallVelocity; // how fast we are falling
|
||||
int weaponanim; // to see weapon animation of other players
|
||||
int team;
|
||||
int playerclass;
|
||||
int health;
|
||||
int spectator;
|
||||
int weaponmodel;
|
||||
int gaitsequence;
|
||||
vec3_t basevelocity; // If standing on conveyor, e.g.
|
||||
int usehull; // Use the crouched hull, or the regular player hull.
|
||||
int oldbuttons; // Latched buttons last time state updated.
|
||||
int onground; // -1 = in air, else pmove entity number
|
||||
int iStepLeft;
|
||||
float flFallVelocity; // How fast we are falling
|
||||
float fov;
|
||||
int weaponanim;
|
||||
|
||||
// parametric movement overrides
|
||||
vec3_t startpos;
|
||||
vec3_t endpos;
|
||||
float impacttime;
|
||||
float starttime;
|
||||
|
||||
// for mods
|
||||
int iuser1;
|
||||
|
@ -108,6 +113,12 @@ typedef struct entity_state_s
|
|||
vec3_t vuser3;
|
||||
vec3_t vuser4;
|
||||
|
||||
// FIXME: old xash variables needs to be removed
|
||||
int flags;
|
||||
float maxspeed;
|
||||
float idealpitch;
|
||||
vec3_t oldorigin; // FIXME: needs to be removed
|
||||
vec3_t viewangles; // already calculated view angles on server-side
|
||||
} entity_state_t;
|
||||
|
||||
typedef struct clientdata_s
|
||||
|
|
|
@ -8,17 +8,22 @@
|
|||
// usercmd_t communication (a part of network protocol)
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
short lerp_msec; // interpolation time on client
|
||||
int msec; // duration in ms of command
|
||||
vec3_t viewangles; // command view angles
|
||||
|
||||
// intended velocities
|
||||
float forwardmove; // forward velocity
|
||||
float sidemove; // sideways velocity
|
||||
float upmove; // upward velocity
|
||||
int lightlevel; // light level at spot where we are standing.
|
||||
int buttons; // attack and move buttons
|
||||
int impulse; // impulse command issued
|
||||
int weaponselect; // current weapon id
|
||||
int random_seed; // shared random seed
|
||||
int target_edict; // mouse captured edict
|
||||
byte lightlevel; // light level at spot where we are standing.
|
||||
word buttons; // attack and move buttons
|
||||
byte impulse; // impulse command issued
|
||||
byte weaponselect; // current weapon id
|
||||
|
||||
// experimental player impact stuff.
|
||||
int impact_index;
|
||||
vec3_t impact_position;
|
||||
} usercmd_t;
|
||||
|
||||
#endif//USERCMD_H
|
|
@ -6,6 +6,8 @@
|
|||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "byteorder.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -14,7 +16,7 @@ CL_WriteDemoMessage
|
|||
Dumps the current net message, prefixed by the length
|
||||
====================
|
||||
*/
|
||||
void CL_WriteDemoMessage( sizebuf_t *msg, int head_size )
|
||||
void CL_WriteDemoMessage( bitbuf_t *msg, int head_size )
|
||||
{
|
||||
int len, swlen;
|
||||
|
||||
|
@ -23,12 +25,12 @@ void CL_WriteDemoMessage( sizebuf_t *msg, int head_size )
|
|||
return;
|
||||
|
||||
// the first eight bytes are just packet sequencing stuff
|
||||
len = msg->cursize - head_size;
|
||||
len = BF_GetNumBytesWritten( msg ) - head_size;
|
||||
swlen = LittleLong( len );
|
||||
|
||||
if( !swlen ) return; // ignore null messages
|
||||
FS_Write( cls.demofile, &swlen, 4 );
|
||||
FS_Write( cls.demofile, msg->data + head_size, len );
|
||||
FS_Write( cls.demofile, BF_GetData( msg ) + head_size, len );
|
||||
}
|
||||
|
||||
void CL_WriteDemoHeader( const char *name )
|
||||
|
@ -36,7 +38,7 @@ void CL_WriteDemoHeader( const char *name )
|
|||
char buf_data[MAX_MSGLEN];
|
||||
entity_state_t *state, nullstate;
|
||||
movevars_t nullmovevars;
|
||||
sizebuf_t buf;
|
||||
bitbuf_t buf;
|
||||
int i, len;
|
||||
|
||||
MsgDev( D_INFO, "recording to %s.\n", name );
|
||||
|
@ -53,34 +55,34 @@ void CL_WriteDemoHeader( const char *name )
|
|||
cls.demowaiting = true;
|
||||
|
||||
// write out messages to hold the startup information
|
||||
MSG_Init( &buf, buf_data, sizeof( buf_data ));
|
||||
BF_Init( &buf, "DemoWrite", buf_data, sizeof( buf_data ));
|
||||
|
||||
// send the serverdata
|
||||
MSG_WriteByte( &buf, svc_serverdata );
|
||||
MSG_WriteLong( &buf, PROTOCOL_VERSION );
|
||||
MSG_WriteLong( &buf, cl.servercount );
|
||||
MSG_WriteByte( &buf, cl.playernum );
|
||||
MSG_WriteByte( &buf, clgame.globals->maxClients );
|
||||
MSG_WriteWord( &buf, clgame.globals->maxEntities );
|
||||
MSG_WriteString( &buf, cl.configstrings[CS_NAME] );
|
||||
MSG_WriteString( &buf, clgame.maptitle );
|
||||
BF_WriteByte( &buf, svc_serverdata );
|
||||
BF_WriteLong( &buf, PROTOCOL_VERSION );
|
||||
BF_WriteLong( &buf, cl.servercount );
|
||||
BF_WriteByte( &buf, cl.playernum );
|
||||
BF_WriteByte( &buf, clgame.globals->maxClients );
|
||||
BF_WriteWord( &buf, clgame.globals->maxEntities );
|
||||
BF_WriteString( &buf, cl.configstrings[CS_NAME] );
|
||||
BF_WriteString( &buf, clgame.maptitle );
|
||||
|
||||
// configstrings
|
||||
for( i = 0; i < MAX_CONFIGSTRINGS; i++ )
|
||||
{
|
||||
if( cl.configstrings[i][0] )
|
||||
{
|
||||
MSG_WriteByte( &buf, svc_configstring );
|
||||
MSG_WriteShort( &buf, i );
|
||||
MSG_WriteString( &buf, cl.configstrings[i] );
|
||||
BF_WriteByte( &buf, svc_configstring );
|
||||
BF_WriteShort( &buf, i );
|
||||
BF_WriteString( &buf, cl.configstrings[i] );
|
||||
|
||||
if( buf.cursize > ( buf.maxsize / 2 ))
|
||||
if( BF_GetNumBytesWritten( &buf ) > ( BF_GetMaxBytes( &buf ) / 2 ))
|
||||
{
|
||||
// write it out
|
||||
len = LittleLong( buf.cursize );
|
||||
len = LittleLong( BF_GetNumBytesWritten( &buf ));
|
||||
FS_Write( cls.demofile, &len, 4 );
|
||||
FS_Write( cls.demofile, buf.data, buf.cursize );
|
||||
buf.cursize = 0;
|
||||
FS_Write( cls.demofile, BF_GetData( &buf ), len );
|
||||
BF_Clear( &buf );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,18 +93,18 @@ void CL_WriteDemoHeader( const char *name )
|
|||
{
|
||||
if( clgame.msg[i].name[0] )
|
||||
{
|
||||
MSG_WriteByte( &buf, svc_usermessage );
|
||||
MSG_WriteString( &buf, clgame.msg[i].name );
|
||||
MSG_WriteByte( &buf, clgame.msg[i].number );
|
||||
MSG_WriteByte( &buf, (byte)clgame.msg[i].size );
|
||||
BF_WriteByte( &buf, svc_usermessage );
|
||||
BF_WriteString( &buf, clgame.msg[i].name );
|
||||
BF_WriteByte( &buf, clgame.msg[i].number );
|
||||
BF_WriteByte( &buf, (byte)clgame.msg[i].size );
|
||||
|
||||
if( buf.cursize > ( buf.maxsize / 2 ))
|
||||
if( BF_GetNumBytesWritten( &buf ) > ( BF_GetMaxBytes( &buf ) / 2 ))
|
||||
{
|
||||
// write it out
|
||||
len = LittleLong( buf.cursize );
|
||||
len = LittleLong( BF_GetNumBytesWritten( &buf ));
|
||||
FS_Write( cls.demofile, &len, 4 );
|
||||
FS_Write( cls.demofile, buf.data, buf.cursize );
|
||||
buf.cursize = 0;
|
||||
FS_Write( cls.demofile, BF_GetData( &buf ), len );
|
||||
BF_Clear( &buf );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,48 +120,48 @@ void CL_WriteDemoHeader( const char *name )
|
|||
if( !state->modelindex && !state->effects )
|
||||
continue;
|
||||
|
||||
MSG_WriteByte( &buf, svc_spawnbaseline );
|
||||
BF_WriteByte( &buf, svc_spawnbaseline );
|
||||
MSG_WriteDeltaEntity( &nullstate, state, &buf, true, true );
|
||||
|
||||
if( buf.cursize > ( buf.maxsize / 2 ))
|
||||
if( BF_GetNumBytesWritten( &buf ) > ( BF_GetMaxBytes( &buf ) / 2 ))
|
||||
{
|
||||
// write it out
|
||||
len = LittleLong( buf.cursize );
|
||||
len = LittleLong( BF_GetNumBytesWritten( &buf ));
|
||||
FS_Write( cls.demofile, &len, 4 );
|
||||
FS_Write( cls.demofile, buf.data, buf.cursize );
|
||||
buf.cursize = 0;
|
||||
FS_Write( cls.demofile, BF_GetData( &buf ), len );
|
||||
BF_Clear( &buf );
|
||||
}
|
||||
}
|
||||
|
||||
MSG_WriteByte( &buf, svc_stufftext );
|
||||
MSG_WriteString( &buf, "precache\n" );
|
||||
BF_WriteByte( &buf, svc_stufftext );
|
||||
BF_WriteString( &buf, "precache\n" );
|
||||
|
||||
MSG_WriteByte( &buf, svc_setview );
|
||||
MSG_WriteWord( &buf, cl.refdef.viewentity );
|
||||
BF_WriteByte( &buf, svc_setview );
|
||||
BF_WriteWord( &buf, cl.refdef.viewentity );
|
||||
|
||||
// write all clients userinfo
|
||||
for( i = 0; i < clgame.globals->maxClients; i++ )
|
||||
{
|
||||
player_info_t *pi;
|
||||
|
||||
MSG_WriteByte( &buf, svc_updateuserinfo );
|
||||
MSG_WriteByte( &buf, i );
|
||||
BF_WriteByte( &buf, svc_updateuserinfo );
|
||||
BF_WriteByte( &buf, i );
|
||||
pi = &cl.players[i];
|
||||
|
||||
if( pi->name[0] )
|
||||
{
|
||||
MSG_WriteByte( &buf, true );
|
||||
MSG_WriteString( &buf, pi->userinfo );
|
||||
BF_WriteByte( &buf, true );
|
||||
BF_WriteString( &buf, pi->userinfo );
|
||||
}
|
||||
else MSG_WriteByte( &buf, false );
|
||||
else BF_WriteByte( &buf, false );
|
||||
}
|
||||
|
||||
MSG_WriteDeltaMovevars( &buf, &nullmovevars, &clgame.movevars );
|
||||
BF_WriteDeltaMovevars( &buf, &nullmovevars, &clgame.movevars );
|
||||
|
||||
// write it to the demo file
|
||||
len = LittleLong( buf.cursize );
|
||||
len = LittleLong( BF_GetNumBytesWritten( &buf ));
|
||||
FS_Write( cls.demofile, &len, 4 );
|
||||
FS_Write( cls.demofile, buf.data, buf.cursize );
|
||||
FS_Write( cls.demofile, BF_GetData( &buf ), len );
|
||||
|
||||
// force client.dll update
|
||||
Cmd_ExecuteString( "cmd fullupdate\n" );
|
||||
|
@ -194,7 +196,6 @@ CLIENT SIDE DEMO PLAYBACK
|
|||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_NextDemo
|
||||
|
@ -253,9 +254,9 @@ reads demo data and write it to client
|
|||
*/
|
||||
void CL_ReadDemoMessage( void )
|
||||
{
|
||||
sizebuf_t buf;
|
||||
char bufData[MAX_MSGLEN];
|
||||
int r;
|
||||
bitbuf_t buf;
|
||||
char buf_data[MAX_MSGLEN];
|
||||
int r, curSize;
|
||||
|
||||
if( !cls.demofile )
|
||||
{
|
||||
|
@ -270,32 +271,32 @@ void CL_ReadDemoMessage( void )
|
|||
if( cl.time <= cl.frame.servertime )
|
||||
return;
|
||||
|
||||
// init the message
|
||||
MSG_Init( &buf, bufData, sizeof( bufData ));
|
||||
|
||||
// get the length
|
||||
r = FS_Read( cls.demofile, &buf.cursize, 4 );
|
||||
r = FS_Read( cls.demofile, &curSize, 4 );
|
||||
if( r != 4 )
|
||||
{
|
||||
CL_DemoCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
buf.cursize = LittleLong( buf.cursize );
|
||||
if( buf.cursize == -1 )
|
||||
curSize = LittleLong( curSize );
|
||||
if( curSize == -1 )
|
||||
{
|
||||
CL_DemoCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
if( buf.cursize > buf.maxsize )
|
||||
if( curSize > sizeof( buf_data ))
|
||||
{
|
||||
Host_Error( "CL_ReadDemoMessage: demoMsglen > MAX_MSGLEN\n" );
|
||||
return;
|
||||
}
|
||||
r = FS_Read( cls.demofile, buf.data, buf.cursize );
|
||||
|
||||
if( r != buf.cursize )
|
||||
// init the message (set maxsize to cursize so overflow check will be working properly)
|
||||
BF_Init( &buf, "DemoRead", buf_data, curSize );
|
||||
r = FS_Read( cls.demofile, buf.pData, curSize );
|
||||
|
||||
if( r != curSize )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_ReadDemoMessage: demo file was truncated( %d )\n", cls.state );
|
||||
CL_DemoCompleted();
|
||||
|
@ -303,7 +304,8 @@ void CL_ReadDemoMessage( void )
|
|||
}
|
||||
|
||||
cls.connect_time = cls.realtime;
|
||||
buf.readcount = 0;
|
||||
BF_Clear( &buf ); // reset curpos
|
||||
|
||||
CL_ParseServerMessage( &buf );
|
||||
}
|
||||
|
||||
|
@ -355,9 +357,9 @@ bool CL_GetComment( const char *demoname, char *comment )
|
|||
{
|
||||
file_t *demfile;
|
||||
char buf_data[MAX_MSGLEN];
|
||||
int r, maxClients, curSize;
|
||||
string maptitle;
|
||||
int r, maxClients;
|
||||
sizebuf_t buf;
|
||||
bitbuf_t buf;
|
||||
|
||||
if( !comment ) return false;
|
||||
|
||||
|
@ -368,12 +370,9 @@ bool CL_GetComment( const char *demoname, char *comment )
|
|||
return false;
|
||||
}
|
||||
|
||||
// write out messages to hold the startup information
|
||||
MSG_Init( &buf, buf_data, sizeof( buf_data ));
|
||||
|
||||
// read the first demo packet. extract info from it
|
||||
// get the length
|
||||
r = FS_Read( demfile, &buf.cursize, 4 );
|
||||
r = FS_Read( demfile, &curSize, 4 );
|
||||
if( r != 4 )
|
||||
{
|
||||
FS_Close( demfile );
|
||||
|
@ -381,45 +380,47 @@ bool CL_GetComment( const char *demoname, char *comment )
|
|||
return false;
|
||||
}
|
||||
|
||||
buf.cursize = LittleLong( buf.cursize );
|
||||
if( buf.cursize == -1 )
|
||||
curSize = LittleLong( curSize );
|
||||
|
||||
if( curSize == -1 )
|
||||
{
|
||||
FS_Close( demfile );
|
||||
com.strncpy( comment, "<corrupted>", MAX_STRING );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( buf.cursize > buf.maxsize )
|
||||
if( curSize > sizeof( buf_data ))
|
||||
{
|
||||
FS_Close( demfile );
|
||||
com.strncpy( comment, "<not compatible>", MAX_STRING );
|
||||
return false;
|
||||
}
|
||||
|
||||
r = FS_Read( demfile, buf.data, buf.cursize );
|
||||
// init the message (set maxsize to cursize so overflow check will be working properly)
|
||||
BF_Init( &buf, "DemoRead", buf_data, curSize );
|
||||
r = FS_Read( demfile, buf.pData, curSize );
|
||||
|
||||
if( r != buf.cursize )
|
||||
if( r != curSize )
|
||||
{
|
||||
FS_Close( demfile );
|
||||
com.strncpy( comment, "<truncated file>", MAX_STRING );
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_BeginReading( &buf );
|
||||
// skip server data ident
|
||||
BF_ReadByte( &buf );
|
||||
|
||||
// send the serverdata
|
||||
MSG_ReadByte( &buf ); // skip server data
|
||||
if( PROTOCOL_VERSION != MSG_ReadLong( &buf ))
|
||||
if( PROTOCOL_VERSION != BF_ReadLong( &buf ))
|
||||
{
|
||||
FS_Close( demfile );
|
||||
com.strncpy( comment, "<invalid protocol>", MAX_STRING );
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_ReadLong( &buf ); // server count
|
||||
MSG_ReadByte( &buf );// playernum
|
||||
maxClients = MSG_ReadByte( &buf );
|
||||
if( MSG_ReadWord( &buf ) > GI->max_edicts )
|
||||
BF_ReadLong( &buf ); // server count
|
||||
BF_ReadByte( &buf );// playernum
|
||||
maxClients = BF_ReadByte( &buf );
|
||||
if( BF_ReadWord( &buf ) > GI->max_edicts )
|
||||
{
|
||||
FS_Close( demfile );
|
||||
com.strncpy( comment, "<too many edicts>", MAX_STRING );
|
||||
|
@ -427,8 +428,8 @@ bool CL_GetComment( const char *demoname, char *comment )
|
|||
}
|
||||
|
||||
// split comment to sections
|
||||
com.strncpy( comment, MSG_ReadString( &buf ), CS_SIZE ); // mapname
|
||||
com.strncpy( maptitle, MSG_ReadString( &buf ), MAX_STRING ); // maptitle
|
||||
com.strncpy( comment, BF_ReadString( &buf ), CS_SIZE ); // mapname
|
||||
com.strncpy( maptitle, BF_ReadString( &buf ), MAX_STRING ); // maptitle
|
||||
if( !com.strlen( maptitle )) com.strncpy( maptitle, "<no title>", MAX_STRING );
|
||||
com.strncpy( comment + CS_SIZE, maptitle, CS_SIZE );
|
||||
com.strncpy( comment + CS_SIZE * 2, va( "%i", maxClients ), CS_TIME );
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
/*
|
||||
=========================================================================
|
||||
|
@ -40,7 +42,7 @@ Parses deltas from the given base and adds the resulting entity
|
|||
to the current frame
|
||||
==================
|
||||
*/
|
||||
void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, bool unchanged )
|
||||
void CL_DeltaEntity( bitbuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, bool unchanged )
|
||||
{
|
||||
edict_t *ent;
|
||||
entity_state_t *state;
|
||||
|
@ -52,7 +54,7 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
|
|||
if( newent ) old = &clgame.baselines[newnum];
|
||||
|
||||
if( unchanged ) *state = *old;
|
||||
else MSG_ReadDeltaEntity( msg, old, state, newnum );
|
||||
else MSG_ReadDeltaEntity( msg, old, state, newnum, cl.frame.servertime );
|
||||
|
||||
if( state->number == MAX_EDICTS )
|
||||
{
|
||||
|
@ -92,7 +94,7 @@ An svc_packetentities has just been parsed, deal with the
|
|||
rest of the data stream.
|
||||
==================
|
||||
*/
|
||||
void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newframe )
|
||||
void CL_ParsePacketEntities( bitbuf_t *msg, frame_t *oldframe, frame_t *newframe )
|
||||
{
|
||||
int newnum;
|
||||
entity_state_t *oldstate;
|
||||
|
@ -121,11 +123,11 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram
|
|||
while( 1 )
|
||||
{
|
||||
// read the entity index number
|
||||
newnum = MSG_ReadShort( msg );
|
||||
newnum = BF_ReadShort( msg );
|
||||
if( !newnum ) break; // end of packet entities
|
||||
|
||||
if( msg->error )
|
||||
Host_Error("CL_ParsePacketEntities: end of message[%d > %d]\n", msg->readcount, msg->cursize );
|
||||
if( BF_CheckOverflow( msg ))
|
||||
Host_Error( "CL_ParsePacketEntities: read overflow\n" );
|
||||
|
||||
while( newnum >= clgame.globals->numEntities )
|
||||
clgame.globals->numEntities++;
|
||||
|
@ -193,30 +195,47 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CL_ParseClientData
|
||||
===================
|
||||
*/
|
||||
void CL_ParseClientData( frame_t *from, frame_t *to, bitbuf_t *msg )
|
||||
{
|
||||
clientdata_t *cd, *ocd;
|
||||
clientdata_t dummy;
|
||||
|
||||
cd = &to->cd;
|
||||
|
||||
// clear to old value before delta parsing
|
||||
if( !from )
|
||||
{
|
||||
ocd = &dummy;
|
||||
Mem_Set( &dummy, 0, sizeof( dummy ));
|
||||
}
|
||||
else ocd = &from->cd;
|
||||
|
||||
MSG_ReadClientData( msg, ocd, cd, to->servertime );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ParseFrame
|
||||
================
|
||||
*/
|
||||
void CL_ParseFrame( sizebuf_t *msg )
|
||||
void CL_ParseFrame( bitbuf_t *msg )
|
||||
{
|
||||
int cmd, client_idx;
|
||||
int cmd;
|
||||
edict_t *clent;
|
||||
|
||||
Mem_Set( &cl.frame, 0, sizeof( cl.frame ));
|
||||
|
||||
cl.frame.serverframe = MSG_ReadLong( msg );
|
||||
cl.frame.servertime = MSG_ReadLong( msg );
|
||||
cl.frame.deltaframe = MSG_ReadLong( msg );
|
||||
cl.serverframetime = MSG_ReadByte( msg );
|
||||
cl.surpressCount = MSG_ReadByte( msg );
|
||||
client_idx = MSG_ReadByte( msg );
|
||||
cl.frame.serverframe = BF_ReadLong( msg );
|
||||
cl.frame.servertime = BF_ReadLong( msg );
|
||||
cl.frame.deltaframe = BF_ReadLong( msg );
|
||||
cl.serverframetime = BF_ReadByte( msg );
|
||||
cl.surpressCount = BF_ReadByte( msg );
|
||||
|
||||
// read clientindex
|
||||
clent = EDICT_NUM( client_idx ); // get client
|
||||
if(( client_idx - 1 ) != cl.playernum )
|
||||
Host_Error( "CL_ParseFrame: invalid playernum (%d should be %d)\n", client_idx - 1, cl.playernum );
|
||||
|
||||
// If the frame is delta compressed from data that we
|
||||
// no longer have available, we must suck up the rest of
|
||||
// the frame, but not use it, then ask for a non-compressed
|
||||
|
@ -254,9 +273,16 @@ void CL_ParseFrame( sizebuf_t *msg )
|
|||
else if( cl.time < cl.frame.servertime - cl.serverframetime )
|
||||
cl.time = cl.frame.servertime - cl.serverframetime;
|
||||
|
||||
// read clientdata
|
||||
cmd = BF_ReadByte( msg );
|
||||
if( cmd != svc_clientdata ) Host_Error( "CL_ParseFrame: not cliendata[%d]\n", cmd );
|
||||
CL_ParseClientData( cl.oldframe, &cl.frame, msg );
|
||||
|
||||
clent = CL_GetLocalPlayer(); // get client
|
||||
|
||||
// read packet entities
|
||||
cmd = MSG_ReadByte( msg );
|
||||
if( cmd != svc_packetentities ) Host_Error("CL_ParseFrame: not packetentities[%d]\n", cmd );
|
||||
cmd = BF_ReadByte( msg );
|
||||
if( cmd != svc_packetentities ) Host_Error( "CL_ParseFrame: not packetentities[%d]\n", cmd );
|
||||
CL_ParsePacketEntities( msg, cl.oldframe, &cl.frame );
|
||||
|
||||
// save the frame off in the backup array for later delta comparisons
|
||||
|
@ -300,12 +326,31 @@ CL_AddPacketEntities
|
|||
*/
|
||||
void CL_AddPacketEntities( frame_t *frame )
|
||||
{
|
||||
edict_t *ent;
|
||||
int e, ed_type;
|
||||
edict_t *ent, *clent;
|
||||
clientdata_t *cd, *ocd, dummy;
|
||||
int e, ed_type;
|
||||
|
||||
// now recalc actual entcount
|
||||
for( ; EDICT_NUM( clgame.globals->numEntities - 1 )->free; clgame.globals->numEntities-- );
|
||||
|
||||
clent = CL_GetLocalPlayer();
|
||||
if( !clent ) return;
|
||||
|
||||
cd = &cl.frame.cd;
|
||||
|
||||
if( cl.oldframe )
|
||||
{
|
||||
ocd = &cl.oldframe->cd;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mem_Set( &dummy, 0, sizeof( dummy ));
|
||||
ocd = &dummy;
|
||||
}
|
||||
|
||||
// update client vars
|
||||
clgame.dllFuncs.pfnUpdateClientVars( clent, cd, ocd );
|
||||
|
||||
for( e = 1; e < clgame.globals->numEntities; e++ )
|
||||
{
|
||||
ent = CL_GetEdictByIndex( e );
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "byteorder.h"
|
||||
#include "matrix_lib.h"
|
||||
#include "const.h"
|
||||
#include "protocol.h"
|
||||
#include "triangle_api.h"
|
||||
#include "effects_api.h"
|
||||
#include "pm_defs.h"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "byteorder.h"
|
||||
#include "protocol.h"
|
||||
|
||||
cvar_t *rcon_client_password;
|
||||
cvar_t *rcon_address;
|
||||
|
@ -116,10 +117,11 @@ void CL_ForwardToServer_f( void )
|
|||
// don't forward the first argument
|
||||
if( Cmd_Argc() > 1 )
|
||||
{
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, Cmd_Args());
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, Cmd_Args( ));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Cmd_ForwardToServer
|
||||
|
@ -147,13 +149,13 @@ void Cmd_ForwardToServer( void )
|
|||
return;
|
||||
}
|
||||
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, cmd );
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, cmd );
|
||||
|
||||
if( Cmd_Argc() > 1 )
|
||||
{
|
||||
MSG_Print( &cls.netchan.message, " " );
|
||||
MSG_Print( &cls.netchan.message, Cmd_Args( ));
|
||||
BF_WriteString( &cls.netchan.message, " " );
|
||||
BF_WriteString( &cls.netchan.message, Cmd_Args( ));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,12 +363,34 @@ void CL_ClearState( void )
|
|||
|
||||
// wipe the entire cl structure
|
||||
Mem_Set( &cl, 0, sizeof( cl ));
|
||||
MSG_Clear( &cls.netchan.message );
|
||||
BF_Clear( &cls.netchan.message );
|
||||
|
||||
Cvar_SetValue( "scr_download", 0.0f );
|
||||
Cvar_SetValue( "scr_loading", 0.0f );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_SendDisconnectMessage
|
||||
|
||||
Sends a disconnect message to the server
|
||||
=====================
|
||||
*/
|
||||
void CL_SendDisconnectMessage( void )
|
||||
{
|
||||
bitbuf_t buf;
|
||||
byte data[32];
|
||||
|
||||
BF_Init( &buf, "LastMessage", data, sizeof( data ));
|
||||
BF_WriteByte( &buf, clc_stringcmd );
|
||||
BF_WriteString( &buf, "disconnect" );
|
||||
|
||||
// make sure message will be delivered
|
||||
Netchan_Transmit( &cls.netchan, BF_GetNumBytesWritten( &buf ), BF_GetData( &buf ));
|
||||
Netchan_Transmit( &cls.netchan, BF_GetNumBytesWritten( &buf ), BF_GetData( &buf ));
|
||||
Netchan_Transmit( &cls.netchan, BF_GetNumBytesWritten( &buf ), BF_GetData( &buf ));
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Disconnect
|
||||
|
@ -378,8 +402,6 @@ This is also called on Host_Error, so it shouldn't cause any errors
|
|||
*/
|
||||
void CL_Disconnect( void )
|
||||
{
|
||||
byte final[32];
|
||||
|
||||
if( cls.state == ca_disconnected )
|
||||
return;
|
||||
|
||||
|
@ -387,11 +409,7 @@ void CL_Disconnect( void )
|
|||
CL_Stop_f();
|
||||
|
||||
// send a disconnect message to the server
|
||||
final[0] = clc_stringcmd;
|
||||
com.strcpy((char *)final+1, "disconnect" );
|
||||
Netchan_Transmit( &cls.netchan, com.strlen( final ), final );
|
||||
Netchan_Transmit( &cls.netchan, com.strlen( final ), final );
|
||||
Netchan_Transmit( &cls.netchan, com.strlen( final ), final );
|
||||
CL_SendDisconnectMessage();
|
||||
|
||||
CL_ClearState ();
|
||||
|
||||
|
@ -416,8 +434,6 @@ void CL_Disconnect_f( void )
|
|||
|
||||
void CL_Crashed_f( void )
|
||||
{
|
||||
byte final[32];
|
||||
|
||||
// already freed
|
||||
if( host.state == HOST_CRASHED ) return;
|
||||
if( host.type != HOST_NORMAL ) return;
|
||||
|
@ -428,11 +444,7 @@ void CL_Crashed_f( void )
|
|||
CL_Stop_f(); // stop any demos
|
||||
|
||||
// send a disconnect message to the server
|
||||
final[0] = clc_stringcmd;
|
||||
com.strcpy((char *)final+1, "disconnect" );
|
||||
Netchan_Transmit( &cls.netchan, com.strlen( final ), final );
|
||||
Netchan_Transmit( &cls.netchan, com.strlen( final ), final );
|
||||
Netchan_Transmit( &cls.netchan, com.strlen( final ), final );
|
||||
CL_SendDisconnectMessage();
|
||||
|
||||
// stop any downloads
|
||||
if( cls.download ) FS_Close( cls.download );
|
||||
|
@ -537,8 +549,8 @@ void CL_Reconnect_f( void )
|
|||
{
|
||||
cls.demonum = -1; // not in the demo loop now
|
||||
cls.state = ca_connected;
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, "new" );
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, "new" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -564,11 +576,11 @@ CL_ParseStatusMessage
|
|||
Handle a reply from a info
|
||||
=================
|
||||
*/
|
||||
void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
|
||||
void CL_ParseStatusMessage( netadr_t from, bitbuf_t *msg )
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = MSG_ReadString( msg );
|
||||
s = BF_ReadString( msg );
|
||||
UI_AddServerToList( from, s );
|
||||
}
|
||||
|
||||
|
@ -692,14 +704,14 @@ CL_ConnectionlessPacket
|
|||
Responses to broadcasts, etc
|
||||
=================
|
||||
*/
|
||||
void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
void CL_ConnectionlessPacket( netadr_t from, bitbuf_t *msg )
|
||||
{
|
||||
char *s, *c;
|
||||
|
||||
MSG_BeginReading( msg );
|
||||
MSG_ReadLong( msg ); // skip the -1
|
||||
BF_Clear( msg );
|
||||
BF_ReadLong( msg ); // skip the -1
|
||||
|
||||
s = MSG_ReadStringLine( msg );
|
||||
s = BF_ReadStringLine( msg );
|
||||
|
||||
Cmd_TokenizeString( s );
|
||||
c = Cmd_Argv( 0 );
|
||||
|
@ -714,11 +726,15 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
MsgDev( D_INFO, "dup connect received. ignored\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, from, Cvar_VariableValue( "net_qport" ));
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, "new" );
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, "new" );
|
||||
cls.state = ca_connected;
|
||||
UI_SetActiveMenu( false );
|
||||
|
||||
// FIXME!!! properly send tables to client
|
||||
Delta_Init ();
|
||||
}
|
||||
else if( !com.strcmp( c, "info" ))
|
||||
{
|
||||
|
@ -728,7 +744,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
else if( !com.strcmp( c, "cmd" ))
|
||||
{
|
||||
// remote command from gui front end
|
||||
if(!NET_IsLocalAddress( from ))
|
||||
if( !NET_IsLocalAddress( from ))
|
||||
{
|
||||
Msg( "Command packet from remote host. Ignored.\n" );
|
||||
return;
|
||||
|
@ -736,14 +752,14 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
|
||||
ShowWindow( host.hWnd, SW_RESTORE );
|
||||
SetForegroundWindow ( host.hWnd );
|
||||
s = MSG_ReadString( msg );
|
||||
s = BF_ReadString( msg );
|
||||
Cbuf_AddText( s );
|
||||
Cbuf_AddText( "\n" );
|
||||
}
|
||||
else if( !com.strcmp( c, "print" ))
|
||||
{
|
||||
// print command from somewhere
|
||||
s = MSG_ReadString( msg );
|
||||
s = BF_ReadString( msg );
|
||||
Msg( s );
|
||||
}
|
||||
else if( !com.strcmp( c, "ping" ))
|
||||
|
@ -779,12 +795,17 @@ CL_ReadNetMessage
|
|||
*/
|
||||
void CL_ReadNetMessage( void )
|
||||
{
|
||||
while( NET_GetPacket( NS_CLIENT, &net_from, net_message.data, &net_message.cursize ))
|
||||
int curSize;
|
||||
|
||||
while( NET_GetPacket( NS_CLIENT, &net_from, net_message_buffer, &curSize ))
|
||||
{
|
||||
if( host.type == HOST_DEDICATED || cls.demoplayback )
|
||||
return;
|
||||
|
||||
if( net_message.cursize >= 4 && *(int *)net_message.data == -1 )
|
||||
BF_Init( &net_message, "ServerData", net_message_buffer, curSize );
|
||||
|
||||
// check for connectionless packet (0xffffffff) first
|
||||
if( BF_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
|
||||
{
|
||||
CL_ConnectionlessPacket( net_from, &net_message );
|
||||
return;
|
||||
|
@ -793,7 +814,7 @@ void CL_ReadNetMessage( void )
|
|||
// can't be a valid sequenced packet
|
||||
if( cls.state < ca_connected ) return;
|
||||
|
||||
if( net_message.cursize < 8 )
|
||||
if( BF_GetMaxBytes( &net_message ) < 8 )
|
||||
{
|
||||
MsgDev( D_WARN, "%s: runt packet\n", NET_AdrToString( net_from ));
|
||||
return;
|
||||
|
@ -809,7 +830,7 @@ void CL_ReadNetMessage( void )
|
|||
if( Netchan_Process( &cls.netchan, &net_message ))
|
||||
{
|
||||
// the header is different lengths for reliable and unreliable messages
|
||||
int headerBytes = net_message.readcount;
|
||||
int headerBytes = BF_GetNumBytesRead( &net_message );
|
||||
|
||||
CL_ParseServerMessage( &net_message );
|
||||
|
||||
|
@ -881,8 +902,8 @@ int precache_spawncount;
|
|||
|
||||
void CL_RequestNextDownload( void )
|
||||
{
|
||||
string fn;
|
||||
uint map_checksum; // for detecting cheater maps
|
||||
string fn;
|
||||
uint map_checksum; // for detecting cheater maps
|
||||
|
||||
if( cls.state != ca_connected )
|
||||
return;
|
||||
|
@ -989,8 +1010,8 @@ void CL_RequestNextDownload( void )
|
|||
CL_PrepVideo();
|
||||
|
||||
if( cls.demoplayback ) return; // not really connected
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va( "begin %i\n", precache_spawncount ));
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, va( "begin %i\n", precache_spawncount ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1031,6 +1052,7 @@ void CL_DumpCfgStrings_f( void )
|
|||
Msg( "%s [%i]\n", cl.configstrings[i], i );
|
||||
numStrings++;
|
||||
}
|
||||
|
||||
Msg( "%i total strings used\n", numStrings );
|
||||
}
|
||||
|
||||
|
@ -1060,8 +1082,6 @@ void CL_InitLocal( void )
|
|||
{
|
||||
cls.state = ca_disconnected;
|
||||
|
||||
MSG_Init( &net_message, net_message_buffer, sizeof( net_message_buffer ));
|
||||
|
||||
// register our variables
|
||||
cl_predict = Cvar_Get( "cl_predict", "1", CVAR_ARCHIVE, "disables client movement prediction" );
|
||||
cl_crosshair = Cvar_Get( "crosshair", "1", CVAR_ARCHIVE|CVAR_USERINFO, "show weapon chrosshair" );
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "matrix_lib.h"
|
||||
#include "const.h"
|
||||
#include "pm_defs.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
#define CONNECTION_PROBLEM_TIME 15.0 * 1000 // 15 seconds
|
||||
|
||||
|
@ -74,6 +76,9 @@ usercmd_t CL_CreateCmd( void )
|
|||
|
||||
clgame.dllFuncs.pfnCreateMove( &cmd, host.inputmsec, ( cls.state == ca_active && !cl.refdef.paused ));
|
||||
|
||||
// random seed for predictable random values
|
||||
cl.random_seed = Com_RandomLong( 0, 0x7fffffff ); // full range
|
||||
|
||||
// never let client.dll calc frametime for player
|
||||
// because is potential backdoor for cheating
|
||||
cmd.msec = ms;
|
||||
|
@ -98,12 +103,12 @@ During normal gameplay, a client packet will contain something like:
|
|||
*/
|
||||
void CL_WritePacket( void )
|
||||
{
|
||||
sizebuf_t buf;
|
||||
bool noDelta = false;
|
||||
byte data[MAX_MSGLEN];
|
||||
usercmd_t *cmd, *oldcmd;
|
||||
usercmd_t nullcmd;
|
||||
int key;
|
||||
bitbuf_t buf;
|
||||
bool noDelta = false;
|
||||
byte data[MAX_MSGLEN];
|
||||
usercmd_t *cmd, *oldcmd;
|
||||
usercmd_t nullcmd;
|
||||
int key, size;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if( cls.demoplayback || cls.state == ca_cinematic )
|
||||
|
@ -115,7 +120,7 @@ void CL_WritePacket( void )
|
|||
if( cls.state == ca_connected )
|
||||
{
|
||||
// just update reliable
|
||||
if( cls.netchan.message.cursize || cls.realtime - cls.netchan.last_sent > 1000 )
|
||||
if( BF_GetNumBytesWritten( &cls.netchan.message ) || cls.realtime - cls.netchan.last_sent > 1000 )
|
||||
Netchan_Transmit( &cls.netchan, 0, NULL );
|
||||
return;
|
||||
}
|
||||
|
@ -136,23 +141,27 @@ void CL_WritePacket( void )
|
|||
if( userinfo->modified )
|
||||
{
|
||||
userinfo->modified = false;
|
||||
MSG_WriteByte( &cls.netchan.message, clc_userinfo );
|
||||
MSG_WriteString( &cls.netchan.message, Cvar_Userinfo( ));
|
||||
BF_WriteByte( &cls.netchan.message, clc_userinfo );
|
||||
BF_WriteString( &cls.netchan.message, Cvar_Userinfo( ));
|
||||
}
|
||||
|
||||
MSG_Init( &buf, data, sizeof( data ));
|
||||
BF_Init( &buf, "ClientData", data, sizeof( data ));
|
||||
|
||||
// write new random_seed
|
||||
BF_WriteByte( &buf, clc_random_seed );
|
||||
BF_WriteUBitLong( &buf, cl.random_seed, 32 ); // full range
|
||||
|
||||
// begin a client move command
|
||||
MSG_WriteByte( &buf, clc_move );
|
||||
BF_WriteByte( &buf, clc_move );
|
||||
|
||||
// save the position for a checksum byte
|
||||
key = buf.cursize;
|
||||
MSG_WriteByte( &buf, 0 );
|
||||
key = BF_GetNumBytesWritten( &buf );
|
||||
BF_WriteByte( &buf, 0 );
|
||||
|
||||
// let the server know what the last frame we
|
||||
// got was, so the next message can be delta compressed
|
||||
if( noDelta ) MSG_WriteLong( &buf, -1 ); // no compression
|
||||
else MSG_WriteLong( &buf, cl.frame.serverframe );
|
||||
if( noDelta ) BF_WriteLong( &buf, -1 ); // no compression
|
||||
else BF_WriteLong( &buf, cl.frame.serverframe );
|
||||
|
||||
// send this and the previous cmds in the message, so
|
||||
// if the last packet was dropped, it can be recovered
|
||||
|
@ -169,10 +178,11 @@ void CL_WritePacket( void )
|
|||
MSG_WriteDeltaUsercmd( &buf, oldcmd, cmd );
|
||||
|
||||
// calculate a checksum over the move commands
|
||||
buf.data[key] = CRC_Sequence( buf.data + key + 1, buf.cursize - key - 1, cls.netchan.outgoing_sequence );
|
||||
size = BF_GetNumBytesWritten( &buf ) - key - 1;
|
||||
buf.pData[key] = CRC_Sequence( buf.pData + key + 1, size, cls.netchan.outgoing_sequence );
|
||||
|
||||
// deliver the message
|
||||
Netchan_Transmit( &cls.netchan, buf.cursize, buf.data );
|
||||
Netchan_Transmit( &cls.netchan, BF_GetNumBytesWritten( &buf ), BF_GetData( &buf ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -503,7 +513,7 @@ void CL_PostRunCmd( edict_t *clent, usercmd_t *ucmd )
|
|||
{
|
||||
if( !clent ) return;
|
||||
clgame.pmove->runfuncs = false; // all next calls ignore footstep sounds
|
||||
clgame.dllFuncs.pfnCmdEnd( clent, ucmd, ucmd->random_seed );
|
||||
clgame.dllFuncs.pfnCmdEnd( clent, ucmd, cl.random_seed );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -560,6 +570,7 @@ void CL_PredictMovement( void )
|
|||
int frame;
|
||||
int ack, current;
|
||||
edict_t *player, *viewent;
|
||||
clientdata_t *cd;
|
||||
usercmd_t *cmd;
|
||||
|
||||
if( cls.state != ca_active ) return;
|
||||
|
@ -567,6 +578,7 @@ void CL_PredictMovement( void )
|
|||
|
||||
player = CL_GetLocalPlayer ();
|
||||
viewent = CL_GetEdictByIndex( cl.refdef.viewentity );
|
||||
cd = &cl.frame.cd;
|
||||
|
||||
if( cls.demoplayback && CL_IsValidEdict( viewent ))
|
||||
{
|
||||
|
@ -604,10 +616,10 @@ void CL_PredictMovement( void )
|
|||
|
||||
// setup initial pmove state
|
||||
VectorCopy( player->v.movedir, clgame.pmove->movedir );
|
||||
VectorCopy( player->pvClientData->current.origin, clgame.pmove->origin );
|
||||
VectorCopy( player->pvClientData->current.velocity, clgame.pmove->velocity );
|
||||
VectorCopy( cd->origin, clgame.pmove->origin );
|
||||
VectorCopy( cd->velocity, clgame.pmove->velocity );
|
||||
VectorCopy( player->pvClientData->current.basevelocity, clgame.pmove->basevelocity );
|
||||
VectorCopy( player->pvClientData->current.viewoffset, player->v.view_ofs );
|
||||
VectorCopy( cd->view_ofs, player->v.view_ofs );
|
||||
clgame.pmove->flWaterJumpTime = player->v.teleport_time;
|
||||
clgame.pmove->onground = player->v.groundentity;
|
||||
clgame.pmove->usehull = (player->pvClientData->current.flags & FL_DUCKING) ? 1 : 0; // reset hull
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "protocol.h"
|
||||
#include "net_sound.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
#define MSG_COUNT 32 // last 32 messages parsed
|
||||
#define MSG_MASK (MSG_COUNT - 1)
|
||||
|
@ -111,7 +113,7 @@ CL_WriteErrorMessage
|
|||
write net_message into buffer.dat for debugging
|
||||
=====================
|
||||
*/
|
||||
void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
||||
void CL_WriteErrorMessage( int current_count, bitbuf_t *msg )
|
||||
{
|
||||
file_t *fp;
|
||||
const char *buffer_file = "buffer.dat";
|
||||
|
@ -121,7 +123,7 @@ void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
|||
|
||||
FS_Write( fp, &starting_count, sizeof( int ));
|
||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||
FS_Write( fp, msg->data, msg->cursize );
|
||||
FS_Write( fp, BF_GetData( msg ), BF_GetMaxBytes( msg ));
|
||||
FS_Close( fp );
|
||||
|
||||
MsgDev( D_INFO, "Wrote erroneous message to %s\n", buffer_file );
|
||||
|
@ -138,7 +140,7 @@ void CL_WriteMessageHistory( void )
|
|||
{
|
||||
int i, thecmd;
|
||||
oldcmd_t *old, *failcommand;
|
||||
sizebuf_t *msg = &net_message;
|
||||
bitbuf_t *msg = &net_message;
|
||||
|
||||
if( !cls.initialized || cls.state == ca_disconnected )
|
||||
return;
|
||||
|
@ -164,11 +166,11 @@ void CL_WriteMessageHistory( void )
|
|||
|
||||
failcommand = &cls_message_debug.oldcmd[thecmd];
|
||||
|
||||
MsgDev( D_INFO, "BAD: %3i:%s\n", msg->readcount - 1, CL_MsgInfo( failcommand->command ));
|
||||
MsgDev( D_INFO, "BAD: %3i:%s\n", BF_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
|
||||
|
||||
if( host.developer >= 3 )
|
||||
{
|
||||
CL_WriteErrorMessage( msg->readcount - 1, msg );
|
||||
CL_WriteErrorMessage( BF_GetNumBytesRead( msg ) - 1, msg );
|
||||
}
|
||||
cls_message_debug.parsing = false;
|
||||
}
|
||||
|
@ -210,14 +212,14 @@ bool CL_CheckOrDownloadFile( const char *filename )
|
|||
cls.download = f;
|
||||
// give the server an offset to start the download
|
||||
MsgDev( D_INFO, "Resume download %s at %i\n", cls.downloadname, len );
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("download %s %i", cls.downloadname, len ));
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, va("download %s %i", cls.downloadname, len ));
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_INFO, "Start download %s\n", cls.downloadname );
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("download %s", cls.downloadname ));
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, va("download %s", cls.downloadname ));
|
||||
}
|
||||
|
||||
cls.downloadnumber++;
|
||||
|
@ -231,15 +233,16 @@ CL_ParseDownload
|
|||
A download message has been received from the server
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseDownload( sizebuf_t *msg )
|
||||
void CL_ParseDownload( bitbuf_t *msg )
|
||||
{
|
||||
int size, percent;
|
||||
string name;
|
||||
int r;
|
||||
int size, percent;
|
||||
char buffer[MAX_MSGLEN];
|
||||
string name;
|
||||
int r;
|
||||
|
||||
// read the data
|
||||
size = MSG_ReadShort( msg );
|
||||
percent = MSG_ReadByte( msg );
|
||||
size = BF_ReadShort( msg );
|
||||
percent = BF_ReadByte( msg );
|
||||
|
||||
if( size == -1 )
|
||||
{
|
||||
|
@ -262,22 +265,24 @@ void CL_ParseDownload( sizebuf_t *msg )
|
|||
|
||||
if( !cls.download )
|
||||
{
|
||||
msg->readcount += size;
|
||||
Msg( "Failed to open %s\n", cls.downloadtempname );
|
||||
msg->iCurBit += size << 3; // FIXME!!!
|
||||
MsgDev( D_ERROR, "failed to open %s\n", cls.downloadtempname );
|
||||
CL_RequestNextDownload();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FS_Write( cls.download, msg->data + msg->readcount, size );
|
||||
msg->readcount += size;
|
||||
ASSERT( size <= sizeof( buffer ));
|
||||
|
||||
BF_ReadBytes( msg, buffer, size );
|
||||
FS_Write( cls.download, buffer, size );
|
||||
|
||||
if( percent != 100 )
|
||||
{
|
||||
// request next block
|
||||
Cvar_SetValue("scr_download", percent );
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, "nextdl" );
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, "nextdl" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -327,7 +332,7 @@ CL_ParseSoundPacket
|
|||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseSoundPacket( sizebuf_t *msg, bool is_ambient )
|
||||
void CL_ParseSoundPacket( bitbuf_t *msg, bool is_ambient )
|
||||
{
|
||||
vec3_t pos_;
|
||||
float *pos = NULL;
|
||||
|
@ -336,30 +341,30 @@ void CL_ParseSoundPacket( sizebuf_t *msg, bool is_ambient )
|
|||
int flags, pitch, entnum;
|
||||
sound_t handle;
|
||||
|
||||
flags = MSG_ReadWord( msg );
|
||||
sound = MSG_ReadWord( msg );
|
||||
chan = MSG_ReadByte( msg );
|
||||
flags = BF_ReadWord( msg );
|
||||
sound = BF_ReadWord( msg );
|
||||
chan = BF_ReadByte( msg );
|
||||
|
||||
if( flags & SND_VOLUME )
|
||||
volume = MSG_ReadByte( msg ) / 255.0f;
|
||||
volume = BF_ReadByte( msg ) / 255.0f;
|
||||
else volume = VOL_NORM;
|
||||
|
||||
if( flags & SND_ATTENUATION )
|
||||
attn = MSG_ReadByte( msg ) / 64.0f;
|
||||
attn = BF_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
|
||||
if( flags & SND_PITCH )
|
||||
pitch = MSG_ReadByte( msg );
|
||||
pitch = BF_ReadByte( msg );
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
// entity reletive
|
||||
entnum = MSG_ReadWord( msg );
|
||||
entnum = BF_ReadWord( msg );
|
||||
|
||||
// positioned in space
|
||||
if( flags & SND_FIXED_ORIGIN )
|
||||
{
|
||||
pos = pos_;
|
||||
MSG_ReadPos( msg, pos );
|
||||
BF_ReadBitVec3Coord( msg, pos );
|
||||
}
|
||||
|
||||
if( flags & SND_SENTENCE )
|
||||
|
@ -387,9 +392,9 @@ CL_ParseMovevars
|
|||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseMovevars( sizebuf_t *msg )
|
||||
void CL_ParseMovevars( bitbuf_t *msg )
|
||||
{
|
||||
MSG_ReadDeltaMovevars( msg, &clgame.oldmovevars, &clgame.movevars );
|
||||
BF_ReadDeltaMovevars( msg, &clgame.oldmovevars, &clgame.movevars );
|
||||
Mem_Copy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t ));
|
||||
}
|
||||
|
||||
|
@ -399,18 +404,18 @@ CL_ParseParticles
|
|||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseParticles( sizebuf_t *msg )
|
||||
void CL_ParseParticles( bitbuf_t *msg )
|
||||
{
|
||||
vec3_t org, dir;
|
||||
int i, count, color;
|
||||
|
||||
MSG_ReadPos( msg, org );
|
||||
BF_ReadBitVec3Coord( msg, org );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
dir[i] = MSG_ReadChar( msg ) * (1.0f / 16);
|
||||
dir[i] = BF_ReadChar( msg ) * (1.0f / 16);
|
||||
|
||||
count = MSG_ReadByte( msg );
|
||||
color = MSG_ReadByte( msg );
|
||||
count = BF_ReadByte( msg );
|
||||
color = BF_ReadByte( msg );
|
||||
if( count == 255 ) count = 1024;
|
||||
|
||||
clgame.dllFuncs.pfnParticleEffect( org, dir, color, count );
|
||||
|
@ -422,56 +427,56 @@ CL_ParseStaticDecal
|
|||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseStaticDecal( sizebuf_t *msg )
|
||||
void CL_ParseStaticDecal( bitbuf_t *msg )
|
||||
{
|
||||
vec3_t origin;
|
||||
int decalIndex, entityIndex, modelIndex;
|
||||
int flags;
|
||||
|
||||
MSG_ReadPos( msg, origin );
|
||||
decalIndex = MSG_ReadWord( msg );
|
||||
entityIndex = MSG_ReadShort( msg );
|
||||
BF_ReadBitVec3Coord( msg, origin );
|
||||
decalIndex = BF_ReadWord( msg );
|
||||
entityIndex = BF_ReadShort( msg );
|
||||
|
||||
if( entityIndex > 0 )
|
||||
modelIndex = MSG_ReadWord( msg );
|
||||
modelIndex = BF_ReadWord( msg );
|
||||
else modelIndex = 0;
|
||||
flags = MSG_ReadByte( msg );
|
||||
flags = BF_ReadByte( msg );
|
||||
|
||||
CL_DecalShoot( cl.decal_shaders[decalIndex], entityIndex, modelIndex, origin, flags );
|
||||
}
|
||||
|
||||
void CL_ParseSoundFade( sizebuf_t *msg )
|
||||
void CL_ParseSoundFade( bitbuf_t *msg )
|
||||
{
|
||||
float fadePercent, fadeOutSeconds;
|
||||
float holdTime, fadeInSeconds;
|
||||
|
||||
fadePercent = MSG_ReadFloat( msg );
|
||||
fadeOutSeconds = MSG_ReadFloat( msg );
|
||||
holdTime = MSG_ReadFloat( msg );
|
||||
fadeInSeconds = MSG_ReadFloat( msg );
|
||||
fadePercent = BF_ReadFloat( msg );
|
||||
fadeOutSeconds = BF_ReadFloat( msg );
|
||||
holdTime = BF_ReadFloat( msg );
|
||||
fadeInSeconds = BF_ReadFloat( msg );
|
||||
|
||||
S_FadeClientVolume( fadePercent, fadeOutSeconds, holdTime, fadeInSeconds );
|
||||
}
|
||||
|
||||
void CL_ParseReliableEvent( sizebuf_t *msg, int flags )
|
||||
void CL_ParseReliableEvent( bitbuf_t *msg, int flags )
|
||||
{
|
||||
int event_index;
|
||||
event_args_t nullargs, args;
|
||||
float delay;
|
||||
|
||||
Mem_Set( &nullargs, 0, sizeof( nullargs ));
|
||||
event_index = MSG_ReadWord( msg ); // read event index
|
||||
delay = MSG_ReadWord( msg ) / 100.0f; // read event delay
|
||||
event_index = BF_ReadWord( msg ); // read event index
|
||||
delay = BF_ReadWord( msg ) / 100.0f; // read event delay
|
||||
MSG_ReadDeltaEvent( msg, &nullargs, &args ); // FIXME: zero-compressing
|
||||
|
||||
CL_QueueEvent( flags, event_index, delay, &args );
|
||||
}
|
||||
|
||||
void CL_ParseEvent( sizebuf_t *msg )
|
||||
void CL_ParseEvent( bitbuf_t *msg )
|
||||
{
|
||||
int i, num_events;
|
||||
|
||||
num_events = MSG_ReadByte( msg );
|
||||
num_events = BF_ReadByte( msg );
|
||||
|
||||
// parse events queue
|
||||
for( i = 0 ; i < num_events; i++ )
|
||||
|
@ -490,7 +495,7 @@ void CL_ParseEvent( sizebuf_t *msg )
|
|||
CL_ParseServerData
|
||||
==================
|
||||
*/
|
||||
void CL_ParseServerData( sizebuf_t *msg )
|
||||
void CL_ParseServerData( bitbuf_t *msg )
|
||||
{
|
||||
string str;
|
||||
int i;
|
||||
|
@ -503,18 +508,18 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
cls.state = ca_connected;
|
||||
|
||||
// parse protocol version number
|
||||
i = MSG_ReadLong( msg );
|
||||
i = BF_ReadLong( msg );
|
||||
cls.serverProtocol = i;
|
||||
|
||||
if( i != PROTOCOL_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
|
||||
|
||||
cl.servercount = MSG_ReadLong( msg );
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
clgame.globals->maxClients = MSG_ReadByte( msg );
|
||||
clgame.globals->maxEntities = MSG_ReadWord( msg );
|
||||
com.strncpy( str, MSG_ReadString( msg ), MAX_STRING );
|
||||
com.strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
|
||||
cl.servercount = BF_ReadLong( msg );
|
||||
cl.playernum = BF_ReadByte( msg );
|
||||
clgame.globals->maxClients = BF_ReadByte( msg );
|
||||
clgame.globals->maxEntities = BF_ReadWord( msg );
|
||||
com.strncpy( str, BF_ReadString( msg ), MAX_STRING );
|
||||
com.strncpy( clgame.maptitle, BF_ReadString( msg ), MAX_STRING );
|
||||
|
||||
gameui.globals->maxClients = clgame.globals->maxClients;
|
||||
com.strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
|
||||
|
@ -552,15 +557,15 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
CL_ParseBaseline
|
||||
==================
|
||||
*/
|
||||
void CL_ParseBaseline( sizebuf_t *msg )
|
||||
void CL_ParseBaseline( bitbuf_t *msg )
|
||||
{
|
||||
int newnum;
|
||||
int newnum, timebase;
|
||||
entity_state_t nullstate;
|
||||
entity_state_t *baseline;
|
||||
edict_t *ent;
|
||||
|
||||
Mem_Set( &nullstate, 0, sizeof( nullstate ));
|
||||
newnum = MSG_ReadWord( msg );
|
||||
newnum = BF_ReadWord( msg );
|
||||
|
||||
if( newnum < 0 ) Host_Error( "CL_SpawnEdict: invalid number %i\n", newnum );
|
||||
if( newnum > clgame.globals->maxEntities ) Host_Error( "CL_AllocEdict: no free edicts\n" );
|
||||
|
@ -572,8 +577,12 @@ void CL_ParseBaseline( sizebuf_t *msg )
|
|||
ent = EDICT_NUM( newnum );
|
||||
if( ent->free ) CL_InitEdict( ent ); // initialize edict
|
||||
|
||||
if( cls.state == ca_active )
|
||||
timebase = cl.frame.servertime;
|
||||
else timebase = 1000; // sv.state == ss_loading
|
||||
|
||||
baseline = &clgame.baselines[newnum];
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, baseline, newnum );
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, baseline, newnum, cl.time );
|
||||
CL_LinkEdict( ent, false ); // first entering, link always
|
||||
}
|
||||
|
||||
|
@ -582,14 +591,14 @@ void CL_ParseBaseline( sizebuf_t *msg )
|
|||
CL_ParseConfigString
|
||||
================
|
||||
*/
|
||||
void CL_ParseConfigString( sizebuf_t *msg )
|
||||
void CL_ParseConfigString( bitbuf_t *msg )
|
||||
{
|
||||
int i;
|
||||
|
||||
i = MSG_ReadShort( msg );
|
||||
i = BF_ReadShort( msg );
|
||||
if( i < 0 || i >= MAX_CONFIGSTRINGS )
|
||||
Host_Error( "configstring > MAX_CONFIGSTRINGS\n" );
|
||||
com.strcpy( cl.configstrings[i], MSG_ReadString( msg ));
|
||||
com.strcpy( cl.configstrings[i], BF_ReadString( msg ));
|
||||
|
||||
// do something apropriate
|
||||
if( i == CS_SKYNAME && cl.video_prepped )
|
||||
|
@ -660,13 +669,10 @@ CL_ParseSetAngle
|
|||
set the view angle to this absolute value
|
||||
================
|
||||
*/
|
||||
void CL_ParseSetAngle( sizebuf_t *msg )
|
||||
void CL_ParseSetAngle( bitbuf_t *msg )
|
||||
{
|
||||
cl.refdef.cl_viewangles[0] = MSG_ReadAngle32( msg );
|
||||
cl.refdef.cl_viewangles[1] = MSG_ReadAngle32( msg );
|
||||
|
||||
if( cl.refdef.cl_viewangles[0] > 180 ) cl.refdef.cl_viewangles[0] -= 360;
|
||||
if( cl.refdef.cl_viewangles[1] > 180 ) cl.refdef.cl_viewangles[1] -= 360;
|
||||
cl.refdef.cl_viewangles[0] = BF_ReadBitAngle( msg, 16 );
|
||||
cl.refdef.cl_viewangles[1] = BF_ReadBitAngle( msg, 16 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -676,15 +682,11 @@ CL_ParseAddAngle
|
|||
add the view angle yaw
|
||||
================
|
||||
*/
|
||||
void CL_ParseAddAngle( sizebuf_t *msg )
|
||||
void CL_ParseAddAngle( bitbuf_t *msg )
|
||||
{
|
||||
float add_angle;
|
||||
|
||||
add_angle = MSG_ReadAngle32( msg );
|
||||
|
||||
if( add_angle > 180.0f )
|
||||
add_angle -= 360.0f;
|
||||
|
||||
add_angle = BF_ReadBitAngle( msg, 16 );
|
||||
cl.refdef.cl_viewangles[1] += add_angle;
|
||||
}
|
||||
/*
|
||||
|
@ -694,10 +696,10 @@ CL_ParseCrosshairAngle
|
|||
offset crosshair angles
|
||||
================
|
||||
*/
|
||||
void CL_ParseCrosshairAngle( sizebuf_t *msg )
|
||||
void CL_ParseCrosshairAngle( bitbuf_t *msg )
|
||||
{
|
||||
cl.refdef.crosshairangle[0] = MSG_ReadAngle8( msg );
|
||||
cl.refdef.crosshairangle[1] = MSG_ReadAngle8( msg );
|
||||
cl.refdef.crosshairangle[0] = BF_ReadBitAngle( msg, 8 );
|
||||
cl.refdef.crosshairangle[1] = BF_ReadBitAngle( msg, 8 );
|
||||
cl.refdef.crosshairangle[2] = 0.0f; // not used for screen space
|
||||
}
|
||||
|
||||
|
@ -708,14 +710,14 @@ CL_RegisterUserMessage
|
|||
register new user message or update existing
|
||||
================
|
||||
*/
|
||||
void CL_RegisterUserMessage( sizebuf_t *msg )
|
||||
void CL_RegisterUserMessage( bitbuf_t *msg )
|
||||
{
|
||||
char *pszName;
|
||||
int svc_num, size;
|
||||
|
||||
pszName = MSG_ReadString( msg );
|
||||
svc_num = MSG_ReadByte( msg );
|
||||
size = MSG_ReadByte( msg );
|
||||
pszName = BF_ReadString( msg );
|
||||
svc_num = BF_ReadByte( msg );
|
||||
size = BF_ReadByte( msg );
|
||||
|
||||
// important stuff
|
||||
if( size == 0xFF ) size = -1;
|
||||
|
@ -730,23 +732,23 @@ CL_UpdateUserinfo
|
|||
collect userinfo from all players
|
||||
================
|
||||
*/
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg )
|
||||
void CL_UpdateUserinfo( bitbuf_t *msg )
|
||||
{
|
||||
int slot;
|
||||
bool active;
|
||||
player_info_t *player;
|
||||
|
||||
slot = MSG_ReadByte( msg );
|
||||
slot = BF_ReadByte( msg );
|
||||
|
||||
if( slot >= MAX_CLIENTS )
|
||||
Host_Error( "CL_ParseServerMessage: svc_updateuserinfo > MAX_CLIENTS\n" );
|
||||
|
||||
player = &cl.players[slot];
|
||||
active = MSG_ReadByte( msg ) ? true : false;
|
||||
active = BF_ReadByte( msg ) ? true : false;
|
||||
|
||||
if( active )
|
||||
{
|
||||
com.strncpy( player->userinfo, MSG_ReadString( msg ), sizeof( player->userinfo ));
|
||||
com.strncpy( player->userinfo, BF_ReadString( msg ), sizeof( player->userinfo ));
|
||||
com.strncpy( player->name, Info_ValueForKey( player->userinfo, "name" ), sizeof( player->name ));
|
||||
com.strncpy( player->model, Info_ValueForKey( player->userinfo, "model" ), sizeof( player->model ));
|
||||
}
|
||||
|
@ -760,13 +762,13 @@ CL_ServerInfo
|
|||
change serverinfo
|
||||
==============
|
||||
*/
|
||||
void CL_ServerInfo( sizebuf_t *msg )
|
||||
void CL_ServerInfo( bitbuf_t *msg )
|
||||
{
|
||||
char key[MAX_MSGLEN];
|
||||
char value[MAX_MSGLEN];
|
||||
|
||||
com.strncpy( key, MSG_ReadString( msg ), sizeof( key ));
|
||||
com.strncpy( value, MSG_ReadString( msg ), sizeof( value ));
|
||||
com.strncpy( key, BF_ReadString( msg ), sizeof( key ));
|
||||
com.strncpy( value, BF_ReadString( msg ), sizeof( value ));
|
||||
Info_SetValueForKey( cl.serverinfo, key, value );
|
||||
}
|
||||
|
||||
|
@ -777,9 +779,9 @@ CL_ParseUserMessage
|
|||
handles all user messages
|
||||
==============
|
||||
*/
|
||||
void CL_ParseUserMessage( sizebuf_t *net_buffer, int svc_num )
|
||||
void CL_ParseUserMessage( bitbuf_t *msg, int svc_num )
|
||||
{
|
||||
int iSize;
|
||||
int i, iSize;
|
||||
byte *pbuf;
|
||||
|
||||
// NOTE: any user message parse on engine, not in client.dll
|
||||
|
@ -792,17 +794,31 @@ void CL_ParseUserMessage( sizebuf_t *net_buffer, int svc_num )
|
|||
|
||||
// unregister message can't be parsed
|
||||
if( clgame.msg[svc_num].number != svc_num )
|
||||
Host_Error( "CL_ParseUserMessage: illegible server message %d\n", svc_num );
|
||||
{
|
||||
for( i = 0; i < MAX_USER_MESSAGES; i++ )
|
||||
{
|
||||
// across-transition problems... this is temporary solution
|
||||
if( clgame.msg[i].number == svc_num )
|
||||
{
|
||||
MsgDev( D_WARN, "CL_RemapUserMsg: from %i to %i\n", svc_num, i );
|
||||
svc_num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i == MAX_USER_MESSAGES )
|
||||
Host_Error( "CL_ParseUserMessage: illegible server message %d\n", svc_num );
|
||||
}
|
||||
|
||||
iSize = clgame.msg[svc_num].size;
|
||||
pbuf = NULL;
|
||||
|
||||
// message with variable sizes receive an actual size as first byte
|
||||
if( iSize == -1 ) iSize = MSG_ReadByte( net_buffer );
|
||||
if( iSize == -1 ) iSize = BF_ReadByte( msg );
|
||||
if( iSize > 0 ) pbuf = Mem_Alloc( clgame.private, iSize );
|
||||
|
||||
// parse user message into buffer
|
||||
MSG_ReadData( net_buffer, pbuf, iSize );
|
||||
BF_ReadBytes( msg, pbuf, iSize );
|
||||
|
||||
if( clgame.msg[svc_num].func ) clgame.msg[svc_num].func( clgame.msg[svc_num].name, iSize, pbuf );
|
||||
else MsgDev( D_WARN, "CL_ParseUserMessage: %s not hooked\n", clgame.msg[svc_num].name );
|
||||
|
@ -821,29 +837,32 @@ ACTION MESSAGES
|
|||
CL_ParseServerMessage
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseServerMessage( sizebuf_t *msg )
|
||||
void CL_ParseServerMessage( bitbuf_t *msg )
|
||||
{
|
||||
char *s;
|
||||
int i, cmd;
|
||||
int bufStart;
|
||||
|
||||
cls_message_debug.parsing = true; // begin parsing
|
||||
starting_count = msg->readcount; // updates each frame
|
||||
cls_message_debug.parsing = true; // begin parsing
|
||||
starting_count = BF_GetNumBytesRead( msg ); // updates each frame
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( msg->error )
|
||||
if( BF_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: bad server message\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark start position
|
||||
bufStart = msg->readcount;
|
||||
bufStart = BF_GetNumBytesRead( msg );
|
||||
|
||||
cmd = MSG_ReadByte( msg );
|
||||
if( cmd == -1 ) break;
|
||||
// end of message
|
||||
if( BF_GetNumBitsLeft( msg ) < 8 )
|
||||
break;
|
||||
|
||||
cmd = BF_ReadByte( msg );
|
||||
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
@ -875,7 +894,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
|
||||
break;
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
s = BF_ReadString( msg );
|
||||
Cbuf_AddText( s );
|
||||
break;
|
||||
case svc_serverdata:
|
||||
|
@ -904,25 +923,25 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_setview:
|
||||
cl.refdef.viewentity = MSG_ReadWord( msg );
|
||||
cl.refdef.viewentity = BF_ReadWord( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
case svc_physinfo:
|
||||
com.strncpy( cl.physinfo, MSG_ReadString( msg ), sizeof( cl.physinfo ));
|
||||
com.strncpy( cl.physinfo, BF_ReadString( msg ), sizeof( cl.physinfo ));
|
||||
break;
|
||||
case svc_print:
|
||||
i = MSG_ReadByte( msg );
|
||||
i = BF_ReadByte( msg );
|
||||
if( i == PRINT_CHAT ) // chat
|
||||
S_StartLocalSound( "misc/talk.wav" ); // FIXME: INTRESOURCE
|
||||
MsgDev( D_INFO, "^6%s\n", MSG_ReadString( msg ));
|
||||
MsgDev( D_INFO, "^6%s\n", BF_ReadString( msg ));
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.35f );
|
||||
CL_CenterPrint( BF_ReadString( msg ), 0.35f );
|
||||
break;
|
||||
case svc_setpause:
|
||||
cl.refdef.paused = (MSG_ReadByte( msg ) != 0 );
|
||||
cl.refdef.paused = (BF_ReadByte( msg ) != 0 );
|
||||
break;
|
||||
case svc_movevars:
|
||||
CL_ParseMovevars( msg );
|
||||
|
|
|
@ -31,12 +31,13 @@ typedef struct player_info_s
|
|||
//=============================================================================
|
||||
typedef struct frame_s
|
||||
{
|
||||
bool valid; // cleared if delta parsing was invalid
|
||||
int servertime;
|
||||
int serverframe;
|
||||
int deltaframe;
|
||||
int num_entities;
|
||||
int parse_entities; // non-masked index into cl_parse_entities array
|
||||
bool valid; // cleared if delta parsing was invalid
|
||||
int servertime;
|
||||
int serverframe;
|
||||
int deltaframe;
|
||||
int num_entities;
|
||||
int parse_entities; // non-masked index into cl_parse_entities array
|
||||
clientdata_t cd; // current client data
|
||||
} frame_t;
|
||||
|
||||
#define CMD_BACKUP 64 // allow a lot of command backups for very fast systems
|
||||
|
@ -82,6 +83,7 @@ typedef struct
|
|||
event_state_t events;
|
||||
|
||||
// predicting stuff
|
||||
uint random_seed; // for predictable random values
|
||||
vec3_t predicted_origins[CMD_BACKUP]; // for debug comparing against server
|
||||
vec3_t predicted_origin; // generated by CL_PredictMovement
|
||||
vec3_t predicted_viewofs;
|
||||
|
@ -363,7 +365,7 @@ extern cvar_t *userinfo;
|
|||
//=============================================================================
|
||||
|
||||
bool CL_CheckOrDownloadFile( const char *filename );
|
||||
void CL_ParseConfigString( sizebuf_t *msg );
|
||||
void CL_ParseConfigString( bitbuf_t *msg );
|
||||
void CL_SetLightstyle( int i );
|
||||
void CL_RunLightStyles( void );
|
||||
|
||||
|
@ -411,7 +413,7 @@ void CL_SendCmd( void );
|
|||
// cl_demo.c
|
||||
//
|
||||
void CL_DrawDemoRecording( void );
|
||||
void CL_WriteDemoMessage( sizebuf_t *msg, int head_size );
|
||||
void CL_WriteDemoMessage( bitbuf_t *msg, int head_size );
|
||||
void CL_ReadDemoMessage( void );
|
||||
void CL_StopPlayback( void );
|
||||
void CL_StopRecord( void );
|
||||
|
@ -427,7 +429,7 @@ void CL_Stop_f( void );
|
|||
//
|
||||
void CL_UnloadProgs( void );
|
||||
bool CL_LoadProgs( const char *name );
|
||||
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
|
||||
void CL_ParseUserMessage( bitbuf_t *msg, int svc_num );
|
||||
void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
|
||||
void CL_DrawHUD( int state );
|
||||
void CL_InitEdicts( void );
|
||||
|
@ -459,7 +461,7 @@ _inline edict_t *CL_EDICT_NUM( int n, const char *file, const int line )
|
|||
//
|
||||
// cl_parse.c
|
||||
//
|
||||
void CL_ParseServerMessage( sizebuf_t *msg );
|
||||
void CL_ParseServerMessage( bitbuf_t *msg );
|
||||
void CL_RunBackgroundTrack( void );
|
||||
void CL_Download_f( void );
|
||||
|
||||
|
@ -502,7 +504,7 @@ void CL_UpdateBaseVelocity( edict_t *ent );
|
|||
//
|
||||
// cl_frame.c
|
||||
//
|
||||
void CL_ParseFrame( sizebuf_t *msg );
|
||||
void CL_ParseFrame( bitbuf_t *msg );
|
||||
void CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity );
|
||||
|
||||
//
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "keydefs.h"
|
||||
#include "protocol.h" // get the protocol version
|
||||
#include "byteorder.h"
|
||||
|
||||
cvar_t *con_notifytime;
|
||||
cvar_t *scr_conspeed;
|
||||
cvar_t *con_fontsize;
|
||||
|
||||
#define CON_TIMES 5 // need for 4 lines
|
||||
#define CON_TIMES 5 // need for 4 lines
|
||||
#define COLOR_DEFAULT '7'
|
||||
#define CON_HISTORY 32
|
||||
|
||||
|
@ -379,15 +380,23 @@ static int Con_DrawCharacter( int x, int y, int number, rgba_t color )
|
|||
|
||||
void Con_DrawStringLen( const char *pText, int *length, int *height )
|
||||
{
|
||||
int curLength = 0;
|
||||
|
||||
if( height ) *height = con.charHeight;
|
||||
if( !length ) return;
|
||||
|
||||
*length = 0;
|
||||
|
||||
while( *pText && *pText != '\n' )
|
||||
while( *pText )
|
||||
{
|
||||
byte c = *pText;
|
||||
|
||||
if( *pText == '\n' )
|
||||
{
|
||||
pText++;
|
||||
curLength = 0;
|
||||
}
|
||||
|
||||
// skip color strings they are not drawing
|
||||
if( IsColorString( pText ))
|
||||
{
|
||||
|
@ -395,8 +404,11 @@ void Con_DrawStringLen( const char *pText, int *length, int *height )
|
|||
continue;
|
||||
}
|
||||
|
||||
*length += con.charWidths[c];
|
||||
curLength += con.charWidths[c];
|
||||
pText++;
|
||||
|
||||
if( curLength > *length )
|
||||
*length = curLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,6 +433,13 @@ int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, bo
|
|||
|
||||
while ( *s )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
{
|
||||
s++;
|
||||
drawLen = 0; // begin new row
|
||||
y += con.charHeight;
|
||||
}
|
||||
|
||||
if( IsColorString( s ))
|
||||
{
|
||||
if( !forceColor )
|
||||
|
|
|
@ -33,7 +33,7 @@ void BF_InitMasks( void )
|
|||
ExtraMasks[maskBit] = BIT( maskBit ) - 1;
|
||||
}
|
||||
|
||||
void BF_Init( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits )
|
||||
void BF_InitExt( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits )
|
||||
{
|
||||
bf->pDebugName = pDebugName;
|
||||
|
||||
|
@ -42,8 +42,8 @@ void BF_Init( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int
|
|||
|
||||
void BF_StartWriting( bitbuf_t *bf, void *pData, int nBytes, int iStartBit, int nBits )
|
||||
{
|
||||
// Make sure it's dword aligned and padded.
|
||||
ASSERT(( nBytes % 4 ) == 0 );
|
||||
// make sure it's dword aligned and padded.
|
||||
// ASSERT(( nBytes % 4 ) == 0 );
|
||||
ASSERT(((dword)pData & 3 ) == 0 );
|
||||
|
||||
bf->pData = (byte *)pData;
|
||||
|
@ -63,6 +63,13 @@ void BF_StartWriting( bitbuf_t *bf, void *pData, int nBytes, int iStartBit, int
|
|||
bf->bOverflow = false;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
MSG_Clear
|
||||
|
||||
for clearing overflowed buffer
|
||||
=======================
|
||||
*/
|
||||
void BF_Clear( bitbuf_t *bf )
|
||||
{
|
||||
bf->iCurBit = 0;
|
||||
|
@ -74,16 +81,28 @@ static bool BF_Overflow( bitbuf_t *bf, int nBits )
|
|||
if( bf->iCurBit + nBits > bf->nDataBits )
|
||||
{
|
||||
bf->bOverflow = true;
|
||||
MsgDev( D_ERROR, "Msg %s: overflow!\n", bf->pDebugName );
|
||||
Host_Error( "Msg %s: overflow! %i + %i > %i\n", bf->pDebugName, bf->iCurBit, nBits, bf->nDataBits );
|
||||
}
|
||||
return bf->bOverflow;
|
||||
}
|
||||
|
||||
bool BF_CheckOverflow( bitbuf_t *bf )
|
||||
{
|
||||
ASSERT( bf );
|
||||
|
||||
return BF_Overflow( bf, 0 );
|
||||
}
|
||||
|
||||
void BF_SeekToBit( bitbuf_t *bf, int bitPos )
|
||||
{
|
||||
bf->iCurBit = bitPos;
|
||||
}
|
||||
|
||||
void BF_SeekToByte( bitbuf_t *bf, int bytePos )
|
||||
{
|
||||
bf->iCurBit = bytePos << 3;
|
||||
}
|
||||
|
||||
void BF_WriteOneBit( bitbuf_t *bf, int nValue )
|
||||
{
|
||||
if( !BF_Overflow( bf, 1 ))
|
||||
|
@ -112,7 +131,7 @@ void BF_WriteUBitLongExt( bitbuf_t *bf, uint curData, int numbits, bool bCheckRa
|
|||
{
|
||||
bf->bOverflow = true;
|
||||
bf->iCurBit = bf->nDataBits;
|
||||
MsgDev( D_ERROR, "Msg %s: overflow!\n", bf->pDebugName );
|
||||
MsgDev( D_ERROR, "WriteError: %s: overflow!\n", bf->pDebugName );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -240,6 +259,10 @@ void BF_WriteBitAngle( bitbuf_t *bf, float fAngle, int numbits )
|
|||
uint mask, shift;
|
||||
int d;
|
||||
|
||||
// clamp the angle before receiving
|
||||
if( fAngle > 360 ) fAngle -= 360;
|
||||
else if( fAngle < 0 ) fAngle += 360;
|
||||
|
||||
shift = ( 1 << numbits );
|
||||
mask = shift - 1;
|
||||
|
||||
|
@ -390,11 +413,11 @@ bool BF_WriteString( bitbuf_t *bf, const char *pStr )
|
|||
do
|
||||
{
|
||||
BF_WriteChar( bf, *pStr );
|
||||
++pStr;
|
||||
} while(*( pStr - 1 ) != 0 );
|
||||
pStr++;
|
||||
} while( *( pStr - 1 ));
|
||||
}
|
||||
else BF_WriteChar( bf, 0 );
|
||||
|
||||
|
||||
return !bf->bOverflow;
|
||||
}
|
||||
|
||||
|
@ -414,11 +437,19 @@ uint BF_ReadUBitLong( bitbuf_t *bf, int numbits )
|
|||
int idword1;
|
||||
uint dword1, ret;
|
||||
|
||||
if( numbits == 8 )
|
||||
{
|
||||
int leftBits = BF_GetNumBitsLeft( bf );
|
||||
|
||||
if( leftBits >= 0 && leftBits < 8 )
|
||||
return 0; // end of message
|
||||
}
|
||||
|
||||
if(( bf->iCurBit + numbits ) > bf->nDataBits )
|
||||
{
|
||||
bf->bOverflow = true;
|
||||
MsgDev( D_ERROR, "ReadError: %s: overflow! cur %i num %i, total %i\n", bf->pDebugName, bf->iCurBit, numbits, bf->nDataBits );
|
||||
bf->iCurBit = bf->nDataBits;
|
||||
MsgDev( D_ERROR, "Msg %s: overflow!\n", bf->pDebugName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -447,7 +478,6 @@ uint BF_ReadUBitLong( bitbuf_t *bf, int numbits )
|
|||
// shift the second dword's part into the high bits.
|
||||
ret |= (dword2 << ( numbits - nExtraBits ));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -526,6 +556,10 @@ float BF_ReadBitAngle( bitbuf_t *bf, int numbits )
|
|||
i = BF_ReadUBitLong( bf, numbits );
|
||||
fReturn = (float)i * ( 360.0 / shift );
|
||||
|
||||
// clamp the finale angle
|
||||
if( fReturn < -180 ) fReturn += 360;
|
||||
else if( fReturn > 180 ) fReturn -= 360;
|
||||
|
||||
return fReturn;
|
||||
}
|
||||
|
||||
|
@ -688,36 +722,27 @@ bool BF_ReadBytes( bitbuf_t *bf, void *pOut, int nBytes )
|
|||
return BF_ReadBits( bf, pOut, nBytes << 3 );
|
||||
}
|
||||
|
||||
const char *BF_ReadString( bitbuf_t *bf, bool bLine )
|
||||
char *BF_ReadStringExt( bitbuf_t *bf, bool bLine )
|
||||
{
|
||||
static char string[2048];
|
||||
int maxLen = sizeof( string ) - 1;
|
||||
char *pStr = string;
|
||||
bool bTooSmall = false;
|
||||
int iChar = 0;
|
||||
|
||||
while( 1 )
|
||||
static char string[MAX_SYSPATH];
|
||||
int l = 0, c;
|
||||
|
||||
do
|
||||
{
|
||||
char val = BF_ReadChar( bf );
|
||||
// use BF_ReadByte so -1 is out of bounds
|
||||
c = BF_ReadByte( bf );
|
||||
|
||||
if( val == 0 ) break;
|
||||
else if( bLine && val == '\n' )
|
||||
if( c == 0 ) break;
|
||||
else if( bLine && c == '\n' )
|
||||
break;
|
||||
|
||||
// translate all fmt spec to avoid crash bugs
|
||||
if( val == '%' ) val = '.';
|
||||
if( c == '%' ) c = '.';
|
||||
|
||||
if( iChar < ( maxLen - 1 ))
|
||||
{
|
||||
pStr[iChar] = val;
|
||||
iChar++;
|
||||
}
|
||||
else bTooSmall = true;
|
||||
}
|
||||
|
||||
// make sure it's null-terminated.
|
||||
ASSERT( iChar < maxLen );
|
||||
pStr[iChar] = 0;
|
||||
string[l] = c;
|
||||
l++;
|
||||
} while( l < sizeof( string ) - 1 );
|
||||
string[l] = 0; // terminator
|
||||
|
||||
return string;
|
||||
}
|
|
@ -14,7 +14,7 @@ _inline int BitByte( int bits )
|
|||
return PAD_NUMBER( bits, 8 ) >> 3;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
typedef struct bitbuf_s
|
||||
{
|
||||
bool bOverflow; // overflow reading or writing
|
||||
const char *pDebugName; // buffer name (pointer to const name)
|
||||
|
@ -30,18 +30,22 @@ typedef struct
|
|||
#define BF_StartReading BF_StartWriting
|
||||
#define BF_GetNumBytesRead BF_GetNumBytesWritten
|
||||
#define BF_ReadBitAngles BF_ReadBitVec3Coord
|
||||
#define BF_ReadStringLine( bf ) BF_ReadString( bf, true );
|
||||
#define BF_ReadString( bf ) BF_ReadStringExt( bf, false )
|
||||
#define BF_ReadStringLine( bf ) BF_ReadStringExt( bf, true )
|
||||
#define BF_Init( bf, name, data, bytes ) BF_InitExt( bf, name, data, bytes, -1 )
|
||||
|
||||
// common functions
|
||||
void BF_Init( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits );
|
||||
void BF_InitExt( bitbuf_t *bf, const char *pDebugName, void *pData, int nBytes, int nMaxBits );
|
||||
void BF_InitMasks( void ); // called once at startup engine
|
||||
void BF_SeekToBit( bitbuf_t *bf, int bitPos );
|
||||
void BF_SeekToByte( bitbuf_t *bf, int bytePos );
|
||||
bool BF_CheckOverflow( bitbuf_t *bf );
|
||||
|
||||
// init writing
|
||||
void BF_StartWriting( bitbuf_t *bf, void *pData, int nBytes, int iStartBit, int nBits );
|
||||
void BF_Clear( bitbuf_t *bf );
|
||||
|
||||
// Bit-write functions
|
||||
void BF_SeekToBit( bitbuf_t *bf, int bitPos );
|
||||
void BF_WriteOneBit( bitbuf_t *bf, int nValue );
|
||||
void BF_WriteUBitLongExt( bitbuf_t *bf, uint curData, int numbits, bool bCheckRange );
|
||||
void BF_WriteSBitLong( bitbuf_t *bf, int data, int numbits );
|
||||
|
@ -65,10 +69,14 @@ void BF_WriteFloat( bitbuf_t *bf, float val );
|
|||
bool BF_WriteBytes( bitbuf_t *bf, const void *pBuf, int nBytes ); // same as MSG_WriteData
|
||||
bool BF_WriteString( bitbuf_t *bf, const char *pStr ); // returns false if it overflows the buffer.
|
||||
|
||||
// delta-write functions
|
||||
bool BF_WriteDeltaMovevars( bitbuf_t *sb, movevars_t *from, movevars_t *cmd );
|
||||
|
||||
// helper functions
|
||||
_inline int BF_GetNumBytesWritten( bitbuf_t *bf ) { return BitByte( bf->iCurBit ); }
|
||||
_inline int BF_GetNumBitsWritten( bitbuf_t *bf ) { return bf->iCurBit; }
|
||||
_inline int BF_GetMaxNumBits( bitbuf_t *bf ) { return bf->nDataBits; }
|
||||
_inline int BF_GetMaxBits( bitbuf_t *bf ) { return bf->nDataBits; }
|
||||
_inline int BF_GetMaxBytes( bitbuf_t *bf ) { return bf->nDataBytes; }
|
||||
_inline int BF_GetNumBitsLeft( bitbuf_t *bf ) { return bf->nDataBits - bf->iCurBit; }
|
||||
_inline int BF_GetNumBytesLeft( bitbuf_t *bf ) { return BF_GetNumBitsLeft( bf ) >> 3; }
|
||||
_inline byte *BF_GetData( bitbuf_t *bf ) { return bf->pData; }
|
||||
|
@ -79,6 +87,7 @@ float BF_ReadBitFloat( bitbuf_t *bf );
|
|||
bool BF_ReadBits( bitbuf_t *bf, void *pOutData, int nBits );
|
||||
float BF_ReadBitAngle( bitbuf_t *bf, int numbits );
|
||||
int BF_ReadSBitLong( bitbuf_t *bf, int numbits );
|
||||
uint BF_ReadUBitLong( bitbuf_t *bf, int numbits );
|
||||
uint BF_ReadBitLong( bitbuf_t *bf, int numbits, bool bSigned );
|
||||
float BF_ReadBitCoord( bitbuf_t *bf );
|
||||
void BF_ReadBitVec3Coord( bitbuf_t *bf, vec3_t fa );
|
||||
|
@ -93,7 +102,9 @@ int BF_ReadWord( bitbuf_t *bf );
|
|||
long BF_ReadLong( bitbuf_t *bf );
|
||||
float BF_ReadFloat( bitbuf_t *bf );
|
||||
bool BF_ReadBytes( bitbuf_t *bf, void *pOut, int nBytes );
|
||||
const char *BF_ReadString( bitbuf_t *bf, bool bLine );
|
||||
char *BF_ReadStringExt( bitbuf_t *bf, bool bLine );
|
||||
|
||||
// delta-read functions
|
||||
void BF_ReadDeltaMovevars( bitbuf_t *sb, movevars_t *from, movevars_t *cmd );
|
||||
|
||||
#endif//NET_BUFFER_H
|
|
@ -6,6 +6,8 @@
|
|||
#include "common.h"
|
||||
#include "mathlib.h"
|
||||
#include "byteorder.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
/*
|
||||
packet header ( size in bits )
|
||||
|
@ -28,7 +30,7 @@ the retransmit has been acknowledged and the reliable still failed to get there.
|
|||
if the sequence number is -1, the packet should be handled without a netcon
|
||||
|
||||
The reliable message can be added to at any time by doing
|
||||
MSG_Write* (&netchan->message, <data>).
|
||||
BF_Write* (&netchan->message, <data>).
|
||||
|
||||
If the message buffer is overflowed, either by a single message, or by
|
||||
multiple frames worth piling up while the last reliable transmit goes
|
||||
|
@ -64,7 +66,7 @@ cvar_t *net_speeds;
|
|||
cvar_t *net_qport;
|
||||
|
||||
netadr_t net_from;
|
||||
sizebuf_t net_message;
|
||||
bitbuf_t net_message;
|
||||
byte net_message_buffer[MAX_MSGLEN];
|
||||
|
||||
/*
|
||||
|
@ -83,6 +85,9 @@ void Netchan_Init( void )
|
|||
net_showdrop = Cvar_Get ("net_showdrop", "0", 0, "show packets that are dropped" );
|
||||
net_speeds = Cvar_Get ("net_speeds", "0", CVAR_ARCHIVE, "show network packets" );
|
||||
net_qport = Cvar_Get ("net_qport", va( "%i", port ), CVAR_INIT, "current quake netport" );
|
||||
|
||||
Huff_Init (); // initialize huffman compression
|
||||
BF_InitMasks (); // initialize bit-masks
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -102,9 +107,9 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport )
|
|||
chan->last_received = Sys_Milliseconds ();
|
||||
chan->incoming_sequence = 0;
|
||||
chan->outgoing_sequence = 1;
|
||||
chan->compress = true;
|
||||
chan->compress = false;
|
||||
|
||||
MSG_Init( &chan->message, chan->message_buf, sizeof( chan->message_buf ));
|
||||
BF_Init( &chan->message, "NetData", chan->message_buf, sizeof( chan->message_buf ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -116,17 +121,17 @@ Sends an out-of-band datagram
|
|||
*/
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data )
|
||||
{
|
||||
sizebuf_t send;
|
||||
bitbuf_t send;
|
||||
byte send_buf[MAX_MSGLEN];
|
||||
|
||||
// write the packet header
|
||||
MSG_Init( &send, send_buf, sizeof( send_buf ));
|
||||
BF_Init( &send, "SequencePacket", send_buf, sizeof( send_buf ));
|
||||
|
||||
MSG_WriteLong( &send, -1 ); // -1 sequence means out of band
|
||||
MSG_WriteData( &send, data, length );
|
||||
BF_WriteLong( &send, -1 ); // -1 sequence means out of band
|
||||
BF_WriteBytes( &send, data, length );
|
||||
|
||||
// send the datagram
|
||||
NET_SendPacket( net_socket, send.cursize, send.data, adr );
|
||||
NET_SendPacket( net_socket, BF_GetNumBytesWritten( &send ), BF_GetData( &send ), adr );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -139,7 +144,7 @@ Sends a text message in an out-of-band datagram
|
|||
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char string[MAX_MSGLEN];
|
||||
char string[MAX_SYSPATH];
|
||||
|
||||
va_start( argptr, format );
|
||||
com.vsprintf( string, format, argptr );
|
||||
|
@ -159,14 +164,14 @@ bool Netchan_NeedReliable( netchan_t *chan )
|
|||
send_reliable = true;
|
||||
|
||||
// if the reliable transmit buffer is empty, copy the current message out
|
||||
if( !chan->reliable_length && chan->message.cursize )
|
||||
if( !chan->reliable_length && BF_GetNumBitsWritten( &chan->message ))
|
||||
send_reliable = true;
|
||||
|
||||
if( !chan->reliable_length && chan->message.cursize )
|
||||
if( !chan->reliable_length && BF_GetNumBitsWritten( &chan->message ))
|
||||
{
|
||||
Mem_Copy( chan->reliable_buf, chan->message_buf, chan->message.cursize );
|
||||
chan->reliable_length = chan->message.cursize;
|
||||
chan->message.cursize = 0;
|
||||
Mem_Copy( chan->reliable_buf, chan->message_buf, BF_GetNumBytesWritten( &chan->message ));
|
||||
chan->reliable_length = BF_GetNumBitsWritten( &chan->message );
|
||||
BF_Clear( &chan->message );
|
||||
chan->reliable_sequence ^= 1;
|
||||
}
|
||||
|
||||
|
@ -183,9 +188,14 @@ transmition / retransmition of the reliable messages.
|
|||
A 0 length will still generate a packet and deal with the reliable messages.
|
||||
================
|
||||
*/
|
||||
void Netchan_Transmit( netchan_t *chan, int length, byte *data )
|
||||
void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data )
|
||||
{
|
||||
sizebuf_t send;
|
||||
Netchan_TransmitBits( chan, lengthInBytes << 3, data );
|
||||
}
|
||||
|
||||
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data )
|
||||
{
|
||||
bitbuf_t send;
|
||||
static bool overflow = false;
|
||||
byte send_buf[MAX_MSGLEN];
|
||||
bool send_reliable;
|
||||
|
@ -193,7 +203,7 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
|
|||
uint w1, w2;
|
||||
|
||||
// check for message overflow
|
||||
if( chan->message.overflowed )
|
||||
if( BF_CheckOverflow( &chan->message ))
|
||||
{
|
||||
chan->fatal_error = true;
|
||||
MsgDev( D_ERROR, "%s:outgoing message overflow\n", NET_AdrToString( chan->remote_address ));
|
||||
|
@ -203,7 +213,7 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
|
|||
send_reliable = Netchan_NeedReliable( chan );
|
||||
|
||||
// write the packet header
|
||||
MSG_Init( &send, send_buf, sizeof(send_buf));
|
||||
BF_Init( &send, "NetSend", send_buf, sizeof( send_buf ));
|
||||
|
||||
w1 = (chan->outgoing_sequence & ~(1<<31)) | (send_reliable<<31);
|
||||
w2 = (chan->incoming_sequence & ~(1<<31)) | (chan->incoming_reliable_sequence<<31);
|
||||
|
@ -211,23 +221,23 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
|
|||
chan->outgoing_sequence++;
|
||||
chan->last_sent = Sys_Milliseconds ();
|
||||
|
||||
MSG_WriteLong( &send, w1 );
|
||||
MSG_WriteLong( &send, w2 );
|
||||
BF_WriteLong( &send, w1 );
|
||||
BF_WriteLong( &send, w2 );
|
||||
|
||||
// send the qport if we are a client
|
||||
if( chan->sock == NS_CLIENT ) MSG_WriteWord( &send, Cvar_VariableValue( "net_qport" ));
|
||||
if( chan->sock == NS_CLIENT ) BF_WriteWord( &send, Cvar_VariableValue( "net_qport" ));
|
||||
|
||||
// copy the reliable message to the packet first
|
||||
if( send_reliable )
|
||||
{
|
||||
MSG_WriteData( &send, chan->reliable_buf, chan->reliable_length );
|
||||
BF_WriteBits( &send, chan->reliable_buf, chan->reliable_length );
|
||||
chan->last_reliable_sequence = chan->outgoing_sequence;
|
||||
}
|
||||
|
||||
// add the unreliable part if space is available
|
||||
if( send.maxsize - send.cursize >= length )
|
||||
if( BF_GetNumBitsLeft( &send ) >= lengthInBits )
|
||||
{
|
||||
MSG_WriteData( &send, data, length );
|
||||
BF_WriteBits( &send, data, lengthInBits );
|
||||
overflow = false;
|
||||
}
|
||||
else
|
||||
|
@ -237,15 +247,15 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
|
|||
overflow = true;
|
||||
}
|
||||
|
||||
size1 = send.cursize;
|
||||
size1 = BF_GetNumBytesWritten( &send );
|
||||
if( chan->compress ) Huff_CompressPacket( &send, (chan->sock == NS_CLIENT) ? 10 : 8 );
|
||||
size2 = send.cursize;
|
||||
size2 = BF_GetNumBytesWritten( &send );
|
||||
|
||||
chan->total_sended += size2;
|
||||
chan->total_sended_uncompressed += size1;
|
||||
|
||||
// send the datagram
|
||||
NET_SendPacket( chan->sock, send.cursize, send.data, chan->remote_address );
|
||||
NET_SendPacket( chan->sock, BF_GetNumBytesWritten( &send ), BF_GetData( &send ), chan->remote_address );
|
||||
|
||||
if( net_showpackets->integer == 1 )
|
||||
{
|
||||
|
@ -269,7 +279,7 @@ called when the current net message is from remote_address
|
|||
modifies net message so that it points to the packet payload
|
||||
=================
|
||||
*/
|
||||
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
||||
bool Netchan_Process( netchan_t *chan, bitbuf_t *msg )
|
||||
{
|
||||
uint sequence, sequence_ack;
|
||||
uint reliable_ack, recv_reliable;
|
||||
|
@ -277,13 +287,13 @@ bool Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
|||
int qport;
|
||||
|
||||
// get sequence numbers
|
||||
MSG_BeginReading( msg );
|
||||
sequence = MSG_ReadLong( msg );
|
||||
sequence_ack = MSG_ReadLong( msg );
|
||||
BF_Clear( msg );
|
||||
sequence = BF_ReadLong( msg );
|
||||
sequence_ack = BF_ReadLong( msg );
|
||||
|
||||
// read the qport if we are a server
|
||||
if( chan->sock == NS_SERVER )
|
||||
qport = MSG_ReadShort( msg );
|
||||
qport = BF_ReadShort( msg );
|
||||
|
||||
recv_reliable = sequence>>31;
|
||||
reliable_ack = sequence_ack>>31;
|
||||
|
@ -318,9 +328,10 @@ bool Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
|||
chan->incoming_acknowledged = sequence_ack;
|
||||
chan->incoming_reliable_acknowledged = reliable_ack;
|
||||
if( recv_reliable ) chan->incoming_reliable_sequence ^= 1;
|
||||
size1 = msg->cursize;
|
||||
|
||||
size1 = BF_GetMaxBytes( msg );
|
||||
if( chan->compress ) Huff_DecompressPacket( msg, ( chan->sock == NS_SERVER) ? 10 : 8 );
|
||||
size2 = msg->cursize;
|
||||
size2 = BF_GetMaxBytes( msg );
|
||||
|
||||
chan->total_received += size1;
|
||||
chan->total_received_uncompressed += size2;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,94 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2010 ©
|
||||
// net_encode.h - delta encode routines
|
||||
//=======================================================================
|
||||
#ifndef NET_ENCODE_H
|
||||
#define NET_ENCODE_H
|
||||
|
||||
#define DT_BYTE BIT( 0 ) // A byte
|
||||
#define DT_SHORT BIT( 1 ) // 2 byte field
|
||||
#define DT_FLOAT BIT( 2 ) // A floating point field
|
||||
#define DT_INTEGER BIT( 3 ) // 4 byte integer
|
||||
#define DT_ANGLE BIT( 4 ) // A floating point angle ( will get masked correctly )
|
||||
#define DT_TIMEWINDOW BIT( 5 ) // A floating point timestamp, relative to sv.time
|
||||
// and re-encoded on the client relative to the client's clock
|
||||
#define DT_STRING BIT( 6 ) // A null terminated string, sent as 8 byte chars
|
||||
#define DT_SIGNED BIT( 7 ) // sign modificator
|
||||
|
||||
#define offsetof( s, m ) (size_t)&(((s *)0)->m)
|
||||
#define NUM_FIELDS( x ) ((sizeof( x ) / sizeof( x[0] )) - 1)
|
||||
|
||||
// helper macroses
|
||||
#define ENTS_DEF( x ) #x, offsetof( entity_state_t, x ), sizeof( ((entity_state_t *)0)->x )
|
||||
#define UCMD_DEF( x ) #x, offsetof( usercmd_t, x ), sizeof( ((usercmd_t *)0)->x )
|
||||
#define EVNT_DEF( x ) #x, offsetof( event_args_t, x ), sizeof( ((event_args_t *)0)->x )
|
||||
#define PHYS_DEF( x ) #x, offsetof( movevars_t, x ), sizeof( ((movevars_t *)0)->x )
|
||||
#define CLDT_DEF( x ) #x, offsetof( clientdata_t, x ), sizeof( ((clientdata_t *)0)->x )
|
||||
#define WPDT_DEF( x ) #x, offsetof( weapon_data_t, x ), sizeof( ((weapon_data_t *)0)->x )
|
||||
|
||||
enum
|
||||
{
|
||||
CUSTOM_NONE = 0,
|
||||
CUSTOM_SEREVR_ENCODE, // keyword "gamedll"
|
||||
CUSTOM_CLIENT_ENCODE, // keyword "client"
|
||||
};
|
||||
|
||||
// struct info (filled by engine)
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
const int offset;
|
||||
const int size;
|
||||
} delta_field_t;
|
||||
|
||||
typedef struct delta_s
|
||||
{
|
||||
const char *name;
|
||||
int offset; // in bytes
|
||||
int flags; // DT_INTEGER, DT_FLOAT etc
|
||||
float multiplier;
|
||||
float post_multiplier; // for DEFINE_DELTA_POST
|
||||
int bits; // how many bits we send\receive
|
||||
} delta_t;
|
||||
|
||||
typedef void (*pfnDeltaEncode)( delta_t *pFields, const byte *from, const byte *to );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *pName;
|
||||
const delta_field_t *pInfo;
|
||||
const int maxFields; // maximum number of fields in struct
|
||||
int numFields; // may be merged during initialization
|
||||
delta_t *pFields;
|
||||
|
||||
// added these for custom entity encode
|
||||
int customEncode;
|
||||
char funcName[32];
|
||||
pfnDeltaEncode userCallback;
|
||||
bool bInitialized;
|
||||
} delta_info_t;
|
||||
|
||||
//
|
||||
// net_encode.c
|
||||
//
|
||||
void Delta_Init( void );
|
||||
void Delta_Shutdown( void );
|
||||
void Delta_InitFields( void );
|
||||
void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc );
|
||||
int MSG_DeltaFindField( delta_t *pFields, const char *fieldname );
|
||||
void MSG_DeltaSetField( delta_t *pFields, const char *fieldname );
|
||||
void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname );
|
||||
void MSG_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber );
|
||||
void MSG_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber );
|
||||
|
||||
// encode routines
|
||||
void MSG_WriteDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to );
|
||||
void MSG_ReadDeltaUsercmd( bitbuf_t *msg, usercmd_t *from, usercmd_t *to );
|
||||
void MSG_WriteDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to );
|
||||
void MSG_ReadDeltaEvent( bitbuf_t *msg, event_args_t *from, event_args_t *to );
|
||||
void MSG_WriteClientData( bitbuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
|
||||
void MSG_ReadClientData( bitbuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
|
||||
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, bitbuf_t *msg, bool force, int timebase );
|
||||
void MSG_ReadDeltaEntity( bitbuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int timebase );
|
||||
|
||||
#endif//NET_ENCODE_H
|
|
@ -499,7 +499,7 @@ Compress message using dynamic Huffman tree,
|
|||
beginning from specified offset
|
||||
============
|
||||
*/
|
||||
void Huff_CompressPacket( sizebuf_t *msg, int offset )
|
||||
void Huff_CompressPacket( bitbuf_t *msg, int offset )
|
||||
{
|
||||
tree_t tree;
|
||||
byte buffer[MAX_MSGLEN];
|
||||
|
@ -507,8 +507,8 @@ void Huff_CompressPacket( sizebuf_t *msg, int offset )
|
|||
int outLen;
|
||||
int i, inLen;
|
||||
|
||||
data = msg->data + offset;
|
||||
inLen = msg->cursize - offset;
|
||||
data = BF_GetData( msg ) + offset;
|
||||
inLen = BF_GetNumBytesWritten( msg ) - offset;
|
||||
if( inLen <= 0 || inLen >= MAX_MSGLEN )
|
||||
return;
|
||||
|
||||
|
@ -525,7 +525,7 @@ void Huff_CompressPacket( sizebuf_t *msg, int offset )
|
|||
}
|
||||
|
||||
outLen = (huffBitPos >> 3) + 1;
|
||||
msg->cursize = offset + outLen;
|
||||
msg->iCurBit = ( offset + outLen ) << 3;
|
||||
Mem_Copy( data, buffer, outLen );
|
||||
|
||||
}
|
||||
|
@ -538,7 +538,7 @@ Decompress message using dynamic Huffman tree,
|
|||
beginning from specified offset
|
||||
============
|
||||
*/
|
||||
void Huff_DecompressPacket( sizebuf_t *msg, int offset )
|
||||
void Huff_DecompressPacket( bitbuf_t *msg, int offset )
|
||||
{
|
||||
tree_t tree;
|
||||
byte buffer[MAX_MSGLEN];
|
||||
|
@ -547,8 +547,8 @@ void Huff_DecompressPacket( sizebuf_t *msg, int offset )
|
|||
int inLen;
|
||||
int ch, i, j;
|
||||
|
||||
data = msg->data + offset;
|
||||
inLen = msg->cursize - offset;
|
||||
data = BF_GetData( msg ) + offset;
|
||||
inLen = BF_GetMaxBytes( msg ) - offset;
|
||||
if( inLen <= 0 ) return;
|
||||
|
||||
Huff_PrepareTree( tree );
|
||||
|
@ -556,8 +556,8 @@ void Huff_DecompressPacket( sizebuf_t *msg, int offset )
|
|||
outLen = (data[0] << 8) + data[1];
|
||||
huffBitPos = 16;
|
||||
|
||||
if( outLen > msg->maxsize - offset )
|
||||
outLen = msg->maxsize - offset;
|
||||
if( outLen > BF_GetMaxBytes( msg ) - offset )
|
||||
outLen = BF_GetMaxBytes( msg ) - offset;
|
||||
|
||||
for( i = 0; i < outLen; i++ )
|
||||
{
|
||||
|
@ -582,7 +582,8 @@ void Huff_DecompressPacket( sizebuf_t *msg, int offset )
|
|||
Huff_AddReference( tree, ch );
|
||||
}
|
||||
|
||||
msg->cursize = offset + outLen;
|
||||
msg->nDataBytes = offset + outLen;
|
||||
msg->nDataBits = ( msg->nDataBytes ) << 3;
|
||||
Mem_Copy( data, buffer, outLen );
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
#include "protocol.h"
|
||||
#include "byteorder.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
|
@ -13,100 +14,6 @@
|
|||
#define ANGLE2SHORT(x) ((int)((x)*65536 / 360) & 65535)
|
||||
#define SHORT2ANGLE(x) ((x)*(360.0f / 65536))
|
||||
|
||||
static net_field_t ent_fields[] =
|
||||
{
|
||||
{ ES_FIELD(ed_type), NET_BYTE, false }, // stateflags_t #0 (4 bytes)
|
||||
{ ES_FIELD(ed_flags), NET_BYTE, false }, // stateflags_t #0 (4 bytes)
|
||||
{ ES_FIELD(classname), NET_WORD, false },
|
||||
{ ES_FIELD(angles[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(angles[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(angles[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(velocity[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(velocity[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(velocity[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(basevelocity[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(basevelocity[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(basevelocity[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(modelindex), NET_WORD, false }, // 4096 models
|
||||
{ ES_FIELD(colormap), NET_WORD, false }, // encoded as two shorts for top and bottom color
|
||||
{ ES_FIELD(scale), NET_FLOAT, false }, // 0-255 values
|
||||
{ ES_FIELD(frame), NET_FLOAT, false }, // interpolate value
|
||||
{ ES_FIELD(animtime), NET_FLOAT, false }, // auto-animating time
|
||||
{ ES_FIELD(framerate), NET_FLOAT, false }, // custom framerate
|
||||
{ ES_FIELD(sequence), NET_WORD, false }, // 1024 sequences
|
||||
{ ES_FIELD(gaitsequence), NET_WORD, false }, // 1024 gaitsequences
|
||||
{ ES_FIELD(skin), NET_SHORT, false }, // beacuse negative skins are contents
|
||||
{ ES_FIELD(body), NET_BYTE, false }, // 255 bodies
|
||||
{ ES_FIELD(weaponmodel), NET_WORD, false }, // p_model index, not name
|
||||
{ ES_FIELD(contents), NET_LONG, false }, // full range contents
|
||||
{ ES_FIELD(blending[0]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[1]), NET_BYTE, false }, // stateflags_t #1 (4 bytes)
|
||||
{ ES_FIELD(blending[2]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[3]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[4]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[5]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[6]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[7]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[8]), NET_BYTE, false },
|
||||
{ ES_FIELD(blending[9]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[0]), NET_BYTE, false }, // bone controllers #
|
||||
{ ES_FIELD(controller[1]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[2]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[3]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[4]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[5]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[6]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[7]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[8]), NET_BYTE, false },
|
||||
{ ES_FIELD(controller[9]), NET_BYTE, false },
|
||||
{ ES_FIELD(solid), NET_BYTE, false },
|
||||
{ ES_FIELD(flags), NET_LONG, false }, // misc edict flags
|
||||
{ ES_FIELD(movetype), NET_BYTE, false },
|
||||
{ ES_FIELD(gravity), NET_SHORT, false }, // gravity multiplier
|
||||
{ ES_FIELD(friction), NET_FLOAT, false }, // friction for prediction
|
||||
{ ES_FIELD(aiment), NET_SHORT, false }, // entity index
|
||||
{ ES_FIELD(owner), NET_SHORT, false }, // entity owner index
|
||||
{ ES_FIELD(groundent), NET_SHORT, false }, // ground entity index, if FL_ONGROUND is set
|
||||
{ ES_FIELD(effects), NET_LONG, false }, // effect flags
|
||||
{ ES_FIELD(mins[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(mins[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(mins[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(maxs[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(maxs[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(maxs[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(renderfx), NET_LONG, false }, // renderfx flags
|
||||
{ ES_FIELD(renderamt), NET_FLOAT, false }, // alpha amount
|
||||
{ ES_FIELD(rendercolor[0]), NET_FLOAT, false }, // stateflags_t #2 (4 bytes)
|
||||
{ ES_FIELD(rendercolor[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(rendercolor[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(oldorigin[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(oldorigin[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(oldorigin[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(origin[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(origin[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(origin[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(rendermode), NET_BYTE, false }, // render mode (legacy stuff)
|
||||
{ ES_FIELD(punch_angles[0]), NET_SCALE, false },
|
||||
{ ES_FIELD(punch_angles[1]), NET_SCALE, false },
|
||||
{ ES_FIELD(punch_angles[2]), NET_SCALE, false },
|
||||
{ ES_FIELD(viewangles[0]), NET_FLOAT, false }, // for fixed views
|
||||
{ ES_FIELD(viewangles[1]), NET_FLOAT, false },
|
||||
{ ES_FIELD(viewangles[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(viewoffset[0]), NET_SCALE, false },
|
||||
{ ES_FIELD(viewoffset[1]), NET_SCALE, false },
|
||||
{ ES_FIELD(viewoffset[2]), NET_FLOAT, false },
|
||||
{ ES_FIELD(idealpitch), NET_SCALE, false },
|
||||
{ ES_FIELD(viewmodel), NET_WORD, false },
|
||||
{ ES_FIELD(maxspeed), NET_FLOAT, false }, // client maxspeed
|
||||
{ ES_FIELD(fov), NET_FLOAT, false }, // client horizontal field of view
|
||||
{ ES_FIELD(weapons), NET_LONG, false }, // client weapon 0-64
|
||||
{ ES_FIELD(health), NET_FLOAT, false }, // client health
|
||||
{ ES_FIELD(iStepLeft), NET_LONG, false }, // client footsteps
|
||||
{ ES_FIELD(flFallVelocity), NET_FLOAT, false }, // client fallvelocity
|
||||
// revision 6. reserve for 5 fields without enlarge null_msg_size
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
// probably movevars_t never reached 32 field integer limit (in theory of course)
|
||||
static net_field_t move_fields[] =
|
||||
{
|
||||
|
@ -129,48 +36,6 @@ static net_field_t move_fields[] =
|
|||
{ NULL },
|
||||
};
|
||||
|
||||
// probably event_info_t never reached 32 field integer limit (in theory of course)
|
||||
static net_field_t ev_fields[] =
|
||||
{
|
||||
{ EV_FIELD(flags), NET_WORD, true },
|
||||
{ EV_FIELD(entindex), NET_WORD, true },
|
||||
{ EV_FIELD(origin[0]), NET_FLOAT, false },
|
||||
{ EV_FIELD(origin[1]), NET_FLOAT, false },
|
||||
{ EV_FIELD(origin[2]), NET_FLOAT, false },
|
||||
{ EV_FIELD(angles[0]), NET_ANGLE, false },
|
||||
{ EV_FIELD(angles[1]), NET_ANGLE, false },
|
||||
{ EV_FIELD(angles[2]), NET_ANGLE, false },
|
||||
{ EV_FIELD(velocity[0]), NET_FLOAT, false },
|
||||
{ EV_FIELD(velocity[1]), NET_FLOAT, false },
|
||||
{ EV_FIELD(velocity[2]), NET_FLOAT, false },
|
||||
{ EV_FIELD(ducking), NET_BYTE, false },
|
||||
{ EV_FIELD(fparam1), NET_FLOAT, false },
|
||||
{ EV_FIELD(fparam2), NET_FLOAT, false },
|
||||
{ EV_FIELD(iparam1), NET_LONG, false },
|
||||
{ EV_FIELD(iparam2), NET_LONG, false },
|
||||
{ EV_FIELD(bparam1), NET_BYTE, false }, // 0 - 255 brightness
|
||||
{ EV_FIELD(bparam2), NET_BYTE, false },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
// probably usercmd_t never reached 32 field integer limit (in theory of course)
|
||||
static net_field_t cmd_fields[] =
|
||||
{
|
||||
{ CM_FIELD(msec), NET_BYTE, true },
|
||||
{ CM_FIELD(viewangles[0]), NET_ANGLE, false },
|
||||
{ CM_FIELD(viewangles[1]), NET_ANGLE, false },
|
||||
{ CM_FIELD(viewangles[2]), NET_ANGLE, false },
|
||||
{ CM_FIELD(forwardmove), NET_FLOAT, false },
|
||||
{ CM_FIELD(sidemove), NET_FLOAT, false },
|
||||
{ CM_FIELD(upmove), NET_FLOAT, false },
|
||||
{ CM_FIELD(buttons), NET_SHORT, false },
|
||||
{ CM_FIELD(impulse), NET_BYTE, false },
|
||||
{ CM_FIELD(lightlevel), NET_BYTE, false }, // 0 - 255 brightness
|
||||
{ CM_FIELD(random_seed), NET_LONG, false },
|
||||
{ CM_FIELD(target_edict), NET_SHORT, false },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
|
@ -249,13 +114,7 @@ void _MSG_WriteData( sizebuf_t *buf, const void *data, size_t length, const char
|
|||
Mem_Copy( MSG_GetSpace( buf, length ), data, length );
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
MSG_Clear
|
||||
|
||||
for clearing overflowed buffer
|
||||
=======================
|
||||
*/
|
||||
void MSG_Clear( sizebuf_t *buf )
|
||||
{
|
||||
buf->cursize = 0;
|
||||
|
@ -274,6 +133,7 @@ MSG_WriteBits
|
|||
write # of bytes
|
||||
=======================
|
||||
*/
|
||||
|
||||
void _MSG_WriteBits( sizebuf_t *msg, long value, const char *name, int net_type, const char *filename, const int fileline )
|
||||
{
|
||||
ftol_t dat;
|
||||
|
@ -287,7 +147,7 @@ void _MSG_WriteBits( sizebuf_t *msg, long value, const char *name, int net_type,
|
|||
return;
|
||||
}
|
||||
dat.l = value;
|
||||
|
||||
/*
|
||||
switch( net_type )
|
||||
{
|
||||
case NET_SCALE:
|
||||
|
@ -344,7 +204,7 @@ void _MSG_WriteBits( sizebuf_t *msg, long value, const char *name, int net_type,
|
|||
Host_Error( "MSG_WriteBits: bad net.type %i (called at %s:%i)\n", net_type, filename, fileline );
|
||||
break;
|
||||
}
|
||||
|
||||
*/
|
||||
if((NWDesc[net_type].min_range + NWDesc[net_type].max_range) != 0 )
|
||||
{
|
||||
// check range
|
||||
|
@ -369,7 +229,7 @@ long _MSG_ReadBits( sizebuf_t *msg, const char *name, int net_type, const char *
|
|||
{
|
||||
ftol_t dat;
|
||||
long value = 0;
|
||||
|
||||
/*
|
||||
switch( net_type )
|
||||
{
|
||||
case NET_SCALE:
|
||||
|
@ -423,7 +283,7 @@ long _MSG_ReadBits( sizebuf_t *msg, const char *name, int net_type, const char *
|
|||
Host_Error( "MSG_ReadBits: bad net.type %i, (called at %s:%i)\n", net_type, filename, fileline );
|
||||
break;
|
||||
}
|
||||
|
||||
*/
|
||||
value = dat.l;
|
||||
|
||||
// end of message or error reading
|
||||
|
@ -447,39 +307,6 @@ long _MSG_ReadBits( sizebuf_t *msg, const char *name, int net_type, const char *
|
|||
Handles byte ordering and avoids alignment errors
|
||||
==============================================================================
|
||||
*/
|
||||
/*
|
||||
=======================
|
||||
writing functions
|
||||
=======================
|
||||
*/
|
||||
void _MSG_WriteAngle8( sizebuf_t *sb, float f, const char *filename, int fileline )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.f = f;
|
||||
_MSG_WriteBits( sb, dat.l, NWDesc[NET_ANGLE8].name, NET_ANGLE8, filename, fileline );
|
||||
}
|
||||
|
||||
void _MSG_WriteAngle16( sizebuf_t *sb, float f, const char *filename, int fileline )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.f = f;
|
||||
_MSG_WriteBits( sb, dat.l, NWDesc[NET_ANGLE].name, NET_ANGLE, filename, fileline );
|
||||
}
|
||||
|
||||
void _MSG_WriteCoord16( sizebuf_t *sb, float f, const char *filename, int fileline )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.f = f;
|
||||
_MSG_WriteBits( sb, dat.l, NWDesc[NET_COORD].name, NET_COORD, filename, fileline );
|
||||
}
|
||||
|
||||
void _MSG_WriteFloat( sizebuf_t *sb, float f, const char *filename, int fileline )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.f = f;
|
||||
_MSG_WriteBits( sb, dat.l, NWDesc[NET_FLOAT].name, NET_FLOAT, filename, fileline );
|
||||
}
|
||||
|
||||
void _MSG_WriteString( sizebuf_t *sb, const char *src, const char *filename, int fileline )
|
||||
{
|
||||
if( !src )
|
||||
|
@ -555,46 +382,6 @@ void _MSG_WriteStringLine( sizebuf_t *sb, const char *src, const char *filename,
|
|||
}
|
||||
}
|
||||
|
||||
void _MSG_WritePos( sizebuf_t *sb, const vec3_t pos, const char *filename, int fileline )
|
||||
{
|
||||
_MSG_WriteFloat( sb, pos[0], filename, fileline );
|
||||
_MSG_WriteFloat( sb, pos[1], filename, fileline );
|
||||
_MSG_WriteFloat( sb, pos[2], filename, fileline );
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
reading functions
|
||||
=======================
|
||||
*/
|
||||
float MSG_ReadFloat( sizebuf_t *msg )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.l = MSG_ReadBits( msg, NWDesc[NET_FLOAT].name, NET_FLOAT );
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
float MSG_ReadAngle8( sizebuf_t *msg )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.l = MSG_ReadBits( msg, NWDesc[NET_ANGLE8].name, NET_ANGLE8 );
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
float MSG_ReadAngle16( sizebuf_t *msg )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.l = MSG_ReadBits( msg, NWDesc[NET_ANGLE].name, NET_ANGLE );
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
float MSG_ReadCoord16( sizebuf_t *msg )
|
||||
{
|
||||
union { float f; int l; } dat;
|
||||
dat.l = MSG_ReadBits( msg, NWDesc[NET_COORD].name, NET_COORD );
|
||||
return dat.f;
|
||||
}
|
||||
|
||||
char *MSG_ReadString( sizebuf_t *msg )
|
||||
{
|
||||
static char string[MAX_SYSPATH];
|
||||
|
@ -641,95 +428,6 @@ char *MSG_ReadStringLine( sizebuf_t *msg )
|
|||
return string;
|
||||
}
|
||||
|
||||
void MSG_ReadData( sizebuf_t *msg, void *data, size_t length )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < length; i++ )
|
||||
((byte *)data)[i] = MSG_ReadByte( msg );
|
||||
}
|
||||
|
||||
void MSG_ReadPos( sizebuf_t *msg_read, vec3_t pos )
|
||||
{
|
||||
pos[0] = MSG_ReadFloat( msg_read );
|
||||
pos[1] = MSG_ReadFloat( msg_read );
|
||||
pos[2] = MSG_ReadFloat( msg_read );
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
usercmd_t communication
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
=====================
|
||||
MSG_WriteDeltaUsercmd
|
||||
=====================
|
||||
*/
|
||||
void _MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to, const char *filename, const int fileline )
|
||||
{
|
||||
int num_fields;
|
||||
net_field_t *field;
|
||||
int *fromF, *toF;
|
||||
int i, flags = 0;
|
||||
|
||||
num_fields = (sizeof( cmd_fields ) / sizeof( cmd_fields[0] )) - 1;
|
||||
if( num_fields > MASK_FLAGS ) return; // this should never happen
|
||||
|
||||
// compare fields
|
||||
for( i = 0, field = cmd_fields; i < num_fields; i++, field++ )
|
||||
{
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
if(*fromF != *toF || field->force) flags |= 1<<i;
|
||||
}
|
||||
if( flags == 0 )
|
||||
{
|
||||
// nothing at all changed
|
||||
MSG_WriteLong( msg, -99 ); // no delta info
|
||||
return;
|
||||
}
|
||||
|
||||
MSG_WriteLong( msg, flags ); // send flags who indicates changes
|
||||
for( i = 0, field = cmd_fields; i < num_fields; i++, field++ )
|
||||
{
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
if( flags & 1<<i ) MSG_WriteBits( msg, *toF, field->name, field->bits );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
MSG_ReadDeltaUsercmd
|
||||
=====================
|
||||
*/
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
|
||||
{
|
||||
net_field_t *field;
|
||||
int i, flags;
|
||||
int *fromF, *toF;
|
||||
|
||||
*to = *from;
|
||||
|
||||
if(*(int *)&msg->data[msg->readcount] == -99 )
|
||||
{
|
||||
MSG_ReadLong( msg );
|
||||
return;
|
||||
}
|
||||
for( i = 0, field = cmd_fields; field->name; i++, field++ )
|
||||
{
|
||||
// get flags of next packet if LONG out of range
|
||||
if(( i & MASK_FLAGS ) == 0) flags = MSG_ReadLong( msg );
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
|
||||
if( flags & ( 1<<( i & MASK_FLAGS )))
|
||||
*toF = MSG_ReadBits( msg, field->name, field->bits );
|
||||
else *toF = *fromF; // no change
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
|
@ -737,7 +435,7 @@ movevars_t communication
|
|||
|
||||
=============================================================================
|
||||
*/
|
||||
bool _MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to, const char *filename, const int fileline )
|
||||
bool BF_WriteDeltaMovevars( bitbuf_t *msg, movevars_t *from, movevars_t *to )
|
||||
{
|
||||
int num_fields;
|
||||
net_field_t *field;
|
||||
|
@ -758,17 +456,17 @@ bool _MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to,
|
|||
// nothing at all changed
|
||||
if( flags == 0 ) return false;
|
||||
|
||||
MSG_WriteByte( msg, svc_movevars );
|
||||
MSG_WriteLong( msg, flags ); // send flags who indicates changes
|
||||
BF_WriteByte( msg, svc_movevars );
|
||||
BF_WriteLong( msg, flags ); // send flags who indicates changes
|
||||
for( i = 0, field = move_fields; i < num_fields; i++, field++ )
|
||||
{
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
if( flags & 1<<i ) MSG_WriteBits( msg, *toF, field->name, field->bits );
|
||||
if( flags & 1<<i ) BF_WriteBits( msg, toF, field->bits );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
|
||||
void BF_ReadDeltaMovevars( bitbuf_t *msg, movevars_t *from, movevars_t *to )
|
||||
{
|
||||
net_field_t *field;
|
||||
int i, flags;
|
||||
|
@ -779,209 +477,12 @@ void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
|
|||
for( i = 0, field = move_fields; field->name; i++, field++ )
|
||||
{
|
||||
// get flags of next packet if LONG out of range
|
||||
if(( i & MASK_FLAGS ) == 0) flags = MSG_ReadLong( msg );
|
||||
if(( i & MASK_FLAGS ) == 0) flags = BF_ReadLong( msg );
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
|
||||
if( flags & ( 1<<( i & MASK_FLAGS )))
|
||||
*toF = MSG_ReadBits( msg, field->name, field->bits );
|
||||
else *toF = *fromF; // no change
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
entity_state_t communication
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
==================
|
||||
MSG_WriteDeltaEntity
|
||||
|
||||
Writes part of a packetentities message, including the entity number.
|
||||
Can delta from either a baseline or a previous packet_entity
|
||||
If to is NULL, a remove entity update will be sent
|
||||
If force is not set, then nothing at all will be generated if the entity is
|
||||
identical, under the assumption that the in-order delta code will catch it.
|
||||
==================
|
||||
*/
|
||||
void _MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, bool force, bool newentity, const char *filename, int fileline )
|
||||
{
|
||||
net_field_t *field, *field2;
|
||||
int i, j, flags = 0;
|
||||
int *fromF, *toF;
|
||||
int num_fields;
|
||||
size_t null_msg_size;
|
||||
size_t start_size;
|
||||
|
||||
if( to == NULL )
|
||||
{
|
||||
if( from == NULL ) return;
|
||||
|
||||
// a NULL to is a delta remove message
|
||||
MSG_WriteBits( msg, from->number, NWDesc[NET_WORD].name, NET_WORD );
|
||||
MSG_WriteBits( msg, 0x1869F, NWDesc[NET_LONG].name, NET_LONG );
|
||||
return;
|
||||
}
|
||||
|
||||
num_fields = sizeof(ent_fields) / sizeof(net_field_t);
|
||||
null_msg_size = (int)ceil( num_fields / 32.0f ) * sizeof( int ) + sizeof( short );
|
||||
start_size = msg->cursize;
|
||||
|
||||
if( to->number < 0 || to->number >= GI->max_edicts )
|
||||
Host_Error( "MSG_WriteDeltaEntity: Bad entity number: %i (called at %s:%i)\n", to->number, filename, fileline );
|
||||
|
||||
MSG_WriteBits( msg, to->number, "serialnumber", NET_WORD );
|
||||
for( i = 0, field = field2 = ent_fields; field->name; i++, field++ )
|
||||
{
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
|
||||
if( *fromF != *toF || ( newentity && field->force ))
|
||||
flags |= (1<<( i & MASK_FLAGS ));
|
||||
|
||||
if((( i & MASK_FLAGS ) + 1 == MAX_FLAGS ) || !ent_fields[i+1].name ) // dump packet
|
||||
{
|
||||
MSG_WriteLong( msg, flags ); // send flags who indicates changes
|
||||
for( j = 0; field2->name; j++, field2++ )
|
||||
{
|
||||
if( j == MAX_FLAGS ) break; // return to main cycle
|
||||
toF = (int *)((byte *)to + field2->offset );
|
||||
if( flags & (1<<( j & MASK_FLAGS )))
|
||||
MSG_WriteBits( msg, *toF, field2->name, field2->bits );
|
||||
}
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: null_msg_size is number of (ent_fields / 32) + (1),
|
||||
// who indicates flags count multiplied by sizeof(long)
|
||||
// plus sizeof(short) (head number). if message equal null_message_size
|
||||
// we will be ignore it
|
||||
if( !force && (( msg->cursize - start_size ) == null_msg_size ))
|
||||
msg->cursize = start_size; // kill message
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
MSG_ReadDeltaEntity
|
||||
|
||||
The entity number has already been read from the message, which
|
||||
is how the from state is identified.
|
||||
|
||||
If the delta removes the entity, entity_state_t->number will be set to MAX_EDICTS - 1
|
||||
|
||||
Can go from either a baseline or a previous packet_entity
|
||||
==================
|
||||
*/
|
||||
void MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number )
|
||||
{
|
||||
net_field_t *field;
|
||||
int i, flags;
|
||||
int *fromF, *toF;
|
||||
|
||||
if( number < 0 || number >= GI->max_edicts )
|
||||
Host_Error( "MSG_ReadDeltaEntity: bad delta entity number: %i\n", number );
|
||||
|
||||
*to = *from;
|
||||
to->number = number;
|
||||
|
||||
if(*(int *)&msg->data[msg->readcount] == 0x1869F )
|
||||
{
|
||||
// check for a remove
|
||||
MSG_ReadLong( msg );
|
||||
Mem_Set( to, 0, sizeof( *to ));
|
||||
to->number = MAX_EDICTS; // entity was removed
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0, field = ent_fields; field->name; i++, field++ )
|
||||
{
|
||||
// get flags of next packet if LONG out of range
|
||||
if(( i & MASK_FLAGS ) == 0 ) flags = MSG_ReadLong( msg );
|
||||
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
|
||||
if( flags & ( 1<<( i & MASK_FLAGS )))
|
||||
*toF = MSG_ReadBits( msg, field->name, field->bits );
|
||||
else *toF = *fromF; // no change
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
event_state_t communication
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
/*
|
||||
=====================
|
||||
MSG_WriteDeltaEvent
|
||||
=====================
|
||||
*/
|
||||
void _MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to, const char *filename, const int fileline )
|
||||
{
|
||||
int num_fields;
|
||||
net_field_t *field;
|
||||
int *fromF, *toF;
|
||||
int i, flags = 0;
|
||||
|
||||
num_fields = (sizeof( ev_fields ) / sizeof( ev_fields[0] )) - 1;
|
||||
if( num_fields > MASK_FLAGS ) return; // this should never happen
|
||||
|
||||
// compare fields
|
||||
for( i = 0, field = ev_fields; i < num_fields; i++, field++ )
|
||||
{
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
if(*fromF != *toF || field->force) flags |= 1<<i;
|
||||
}
|
||||
if( flags == 0 )
|
||||
{
|
||||
// nothing at all changed
|
||||
MSG_WriteLong( msg, -99 ); // no delta info
|
||||
return;
|
||||
}
|
||||
|
||||
MSG_WriteLong( msg, flags ); // send flags who indicates changes
|
||||
for( i = 0, field = ev_fields; i < num_fields; i++, field++ )
|
||||
{
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
if( flags & 1<<i ) MSG_WriteBits( msg, *toF, field->name, field->bits );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
MSG_ReadDeltaEvent
|
||||
=====================
|
||||
*/
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
|
||||
{
|
||||
net_field_t *field;
|
||||
int i, flags;
|
||||
int *fromF, *toF;
|
||||
|
||||
*to = *from;
|
||||
|
||||
if(*(int *)&msg->data[msg->readcount] == -99 )
|
||||
{
|
||||
MSG_ReadLong( msg );
|
||||
return;
|
||||
}
|
||||
for( i = 0, field = ev_fields; field->name; i++, field++ )
|
||||
{
|
||||
// get flags of next packet if LONG out of range
|
||||
if(( i & MASK_FLAGS ) == 0) flags = MSG_ReadLong( msg );
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
|
||||
if( flags & ( 1<<( i & MASK_FLAGS )))
|
||||
*toF = MSG_ReadBits( msg, field->name, field->bits );
|
||||
BF_ReadBits( msg, toF, field->bits );
|
||||
else *toF = *fromF; // no change
|
||||
}
|
||||
}
|
|
@ -8,17 +8,17 @@
|
|||
enum net_types_e
|
||||
{
|
||||
NET_BAD = 0,
|
||||
NET_CHAR,
|
||||
NET_BYTE,
|
||||
NET_SHORT,
|
||||
NET_WORD,
|
||||
NET_LONG,
|
||||
NET_FLOAT,
|
||||
NET_ANGLE8, // angle 2 char
|
||||
NET_ANGLE, // angle 2 short
|
||||
NET_SCALE,
|
||||
NET_COORD,
|
||||
NET_COLOR,
|
||||
NET_CHAR = 8,
|
||||
NET_BYTE = 8,
|
||||
NET_SHORT = 16,
|
||||
NET_WORD = 16,
|
||||
NET_LONG = 32,
|
||||
NET_FLOAT = 32,
|
||||
NET_ANGLE8 = 8, // angle 2 char
|
||||
NET_ANGLE = 16, // angle 2 short
|
||||
NET_SCALE = 8,
|
||||
NET_COORD = 32,
|
||||
NET_COLOR = 8,
|
||||
NET_TYPES,
|
||||
};
|
||||
|
||||
|
@ -56,69 +56,6 @@ typedef struct net_field_s
|
|||
bool force; // will be send for newentity
|
||||
} net_field_t;
|
||||
|
||||
typedef struct delta_s
|
||||
{
|
||||
char *name;
|
||||
int offset; // in bytes
|
||||
int deltaType; // DT_INTEGER, DT_FLOAT etc
|
||||
float multiplier;
|
||||
int bits; // how many bits we send\receive
|
||||
} delta_t;
|
||||
|
||||
typedef void (*pfnDeltaEncode)( delta_t *pFields, const byte *from, const byte *to );
|
||||
|
||||
// server to client
|
||||
enum svc_ops_e
|
||||
{
|
||||
// user messages
|
||||
svc_bad = 0, // don't send!
|
||||
|
||||
// engine messages
|
||||
svc_nop = 201, // end of user messages
|
||||
svc_disconnect, // kick client from server
|
||||
svc_reconnect, // reconnecting server request
|
||||
svc_stufftext, // [string] stuffed into client's console buffer, should be \n terminated
|
||||
svc_serverdata, // [long] protocol ...
|
||||
svc_configstring, // [short] [string]
|
||||
svc_spawnbaseline, // valid only at spawn
|
||||
svc_download, // [short] size [size bytes]
|
||||
svc_changing, // changelevel by server request
|
||||
svc_physinfo, // [physinfo string]
|
||||
svc_usermessage, // [string][byte] REG_USER_MSG stuff
|
||||
svc_packetentities, // [...]
|
||||
svc_frame, // begin a new server frame
|
||||
svc_sound, // <see code>
|
||||
svc_ambientsound, // <see code>
|
||||
svc_setangle, // [float float] set the view angle to this absolute value
|
||||
svc_addangle, // [float] add angles when client turn on mover
|
||||
svc_setview, // [short] entity number
|
||||
svc_print, // [byte] id [string] null terminated string
|
||||
svc_centerprint, // [string] to put in center of the screen
|
||||
svc_crosshairangle, // [short][short][short]
|
||||
svc_setpause, // [byte] 0 = unpaused, 1 = paused
|
||||
svc_movevars, // [movevars_t]
|
||||
svc_particle, // [float*3][char*3][byte][byte]
|
||||
svc_soundfade, // [float*4] sound fade parms
|
||||
svc_bspdecal, // [float*3][short][short][short]
|
||||
svc_event, // playback event queue
|
||||
svc_event_reliable, // playback event directly from message, not queue
|
||||
svc_updateuserinfo, // [byte] playernum, [string] userinfo
|
||||
svc_serverinfo, // [string] key [string] value
|
||||
};
|
||||
|
||||
// client to server
|
||||
enum clc_ops_e
|
||||
{
|
||||
clc_bad = 0,
|
||||
|
||||
// engine messages
|
||||
clc_nop = 201,
|
||||
clc_move, // [[usercmd_t]
|
||||
clc_delta, // [byte] sequence number, requests delta compression of message
|
||||
clc_userinfo, // [[userinfo string]
|
||||
clc_stringcmd, // [string] message
|
||||
};
|
||||
|
||||
static const net_desc_t NWDesc[] =
|
||||
{
|
||||
{ NET_BAD, "none", 0, 0 }, // full range
|
||||
|
@ -147,6 +84,7 @@ static const net_desc_t NWDesc[] =
|
|||
#include "event_api.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "entity_state.h"
|
||||
#include "net_buffer.h"
|
||||
|
||||
#define ES_FIELD( x ) #x,(int)&((entity_state_t*)0)->x
|
||||
#define EV_FIELD( x ) #x,(int)&((event_args_t*)0)->x
|
||||
|
@ -194,17 +132,8 @@ long _MSG_ReadBits( sizebuf_t *msg, const char *name, int bits, const char *file
|
|||
void _MSG_Begin( int dest, const char *filename, int fileline );
|
||||
void _MSG_WriteString( sizebuf_t *sb, const char *s, const char *filename, int fileline );
|
||||
void _MSG_WriteStringLine( sizebuf_t *sb, const char *src, const char *filename, int fileline );
|
||||
void _MSG_WriteFloat( sizebuf_t *sb, float f, const char *filename, int fileline );
|
||||
void _MSG_WriteDouble( sizebuf_t *sb, double f, const char *filename, int fileline );
|
||||
void _MSG_WriteAngle8( sizebuf_t *sb, float f, const char *filename, int fileline );
|
||||
void _MSG_WriteAngle16( sizebuf_t *sb, float f, const char *filename, int fileline );
|
||||
void _MSG_WriteCoord16( sizebuf_t *sb, float f, const char *filename, int fileline );
|
||||
void _MSG_WritePos( sizebuf_t *sb, const vec3_t pos, const char *filename, int fileline );
|
||||
void _MSG_WriteData( sizebuf_t *sb, const void *data, size_t length, const char *filename, int fileline );
|
||||
void _MSG_WriteDeltaUsercmd( sizebuf_t *sb, usercmd_t *from, usercmd_t *cmd, const char *filename, const int fileline );
|
||||
bool _MSG_WriteDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd, const char *filename, const int fileline );
|
||||
void _MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to, const char *filename, const int fileline );
|
||||
void _MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, bool force, bool newentity, const char *file, int line );
|
||||
bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct, const char *filename, int fileline );
|
||||
|
||||
#define MSG_Begin( x ) _MSG_Begin( x, __FILE__, __LINE__)
|
||||
|
@ -217,17 +146,8 @@ bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct,
|
|||
#define MSG_WriteDouble(x,y) _MSG_WriteDouble(x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteString(x,y) _MSG_WriteString (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteStringLine(x,y) _MSG_WriteStringLine (x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteCoord16(x, y) _MSG_WriteCoord16(x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteCoord32(x, y) _MSG_WriteFloat(x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteAngle8(x, y) _MSG_WriteAngle8(x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteAngle16(x, y) _MSG_WriteAngle16(x, y, __FILE__, __LINE__)
|
||||
#define MSG_WriteAngle32(x, y) _MSG_WriteFloat(x, y, __FILE__, __LINE__)
|
||||
#define MSG_WritePos(x, y) _MSG_WritePos( x, y, __FILE__, __LINE__ )
|
||||
#define MSG_WriteData(x,y,z) _MSG_WriteData( x, y, z, __FILE__, __LINE__)
|
||||
#define MSG_WriteDeltaEvent(x, y, z) _MSG_WriteDeltaEvent(x, y, z, __FILE__, __LINE__)
|
||||
#define MSG_WriteDeltaUsercmd(x, y, z) _MSG_WriteDeltaUsercmd(x, y, z, __FILE__, __LINE__)
|
||||
#define MSG_WriteDeltaMovevars(x, y, z) _MSG_WriteDeltaMovevars(x, y, z, __FILE__, __LINE__)
|
||||
#define MSG_WriteDeltaEntity(from, to, msg, force, new ) _MSG_WriteDeltaEntity (from, to, msg, force, new, __FILE__, __LINE__)
|
||||
#define MSG_WriteBits( buf, value, name, bits ) _MSG_WriteBits( buf, value, name, bits, __FILE__, __LINE__ )
|
||||
#define MSG_ReadBits( buf, name, bits ) _MSG_ReadBits( buf, name, bits, __FILE__, __LINE__ )
|
||||
#define MSG_Send(x, y, z) _MSG_Send(x, y, z, false, __FILE__, __LINE__)
|
||||
|
@ -239,26 +159,15 @@ void MSG_BeginReading (sizebuf_t *sb);
|
|||
#define MSG_ReadShort( x) _MSG_ReadBits( x, NWDesc[NET_SHORT].name, NET_SHORT, __FILE__, __LINE__ )
|
||||
#define MSG_ReadWord( x ) _MSG_ReadBits( x, NWDesc[NET_WORD].name, NET_WORD, __FILE__, __LINE__ )
|
||||
#define MSG_ReadLong( x ) _MSG_ReadBits( x, NWDesc[NET_LONG].name, NET_LONG, __FILE__, __LINE__ )
|
||||
#define MSG_ReadCoord32( x ) MSG_ReadFloat( x )
|
||||
#define MSG_ReadAngle32( x ) MSG_ReadFloat( x )
|
||||
float MSG_ReadFloat( sizebuf_t *msg );
|
||||
char *MSG_ReadString( sizebuf_t *sb );
|
||||
float MSG_ReadAngle8( sizebuf_t *msg );
|
||||
float MSG_ReadAngle16( sizebuf_t *msg );
|
||||
float MSG_ReadCoord16( sizebuf_t *msg );
|
||||
double MSG_ReadDouble( sizebuf_t *msg );
|
||||
char *MSG_ReadStringLine( sizebuf_t *sb );
|
||||
void MSG_ReadPos( sizebuf_t *sb, vec3_t pos );
|
||||
void MSG_ReadData( sizebuf_t *sb, void *buffer, size_t size );
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *sb, usercmd_t *from, usercmd_t *cmd );
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd );
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to );
|
||||
void MSG_ReadDeltaEntity( sizebuf_t *sb, entity_state_t *from, entity_state_t *to, int number );
|
||||
|
||||
// huffman compression
|
||||
void Huff_Init( void );
|
||||
void Huff_CompressPacket( sizebuf_t *msg, int offset );
|
||||
void Huff_DecompressPacket( sizebuf_t *msg, int offset );
|
||||
void Huff_CompressPacket( bitbuf_t *msg, int offset );
|
||||
void Huff_DecompressPacket( bitbuf_t *msg, int offset );
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
@ -297,7 +206,7 @@ typedef struct netchan_s
|
|||
int last_reliable_sequence; // sequence number of last send
|
||||
|
||||
// reliable staging and holding areas
|
||||
sizebuf_t message; // writing buffer to send to server
|
||||
bitbuf_t message; // writing buffer to send to server
|
||||
byte message_buf[MAX_MSGLEN-16]; // leave space for header
|
||||
|
||||
// message is copied to this buffer when it is first transfered
|
||||
|
@ -313,11 +222,10 @@ typedef struct netchan_s
|
|||
} netchan_t;
|
||||
|
||||
extern netadr_t net_from;
|
||||
extern sizebuf_t net_message;
|
||||
extern bitbuf_t net_message;
|
||||
extern byte net_message_buffer[MAX_MSGLEN];
|
||||
extern cvar_t *net_speeds;
|
||||
|
||||
#define PROTOCOL_VERSION 38
|
||||
#define PORT_MASTER 27900
|
||||
#define PORT_CLIENT 27901
|
||||
#define PORT_SERVER 27910
|
||||
|
@ -329,19 +237,10 @@ extern cvar_t *net_speeds;
|
|||
void Netchan_Init( void );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
|
||||
bool Netchan_NeedReliable( netchan_t *chan );
|
||||
void Netchan_Transmit( netchan_t *chan, int length, byte *data );
|
||||
void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data );
|
||||
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data );
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data );
|
||||
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... );
|
||||
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg );
|
||||
|
||||
//
|
||||
// net_encode.c
|
||||
//
|
||||
void MSG_DeltaAddEncoder( char *name, pfnDeltaEncode encodeFunc );
|
||||
int MSG_DeltaFindField( delta_t *pFields, const char *fieldname );
|
||||
void MSG_DeltaSetField( delta_t *pFields, const char *fieldname );
|
||||
void MSG_DeltaUnsetField( delta_t *pFields, const char *fieldname );
|
||||
void MSG_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber );
|
||||
void MSG_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber );
|
||||
bool Netchan_Process( netchan_t *chan, bitbuf_t *msg );
|
||||
|
||||
#endif//NET_MSG_H
|
|
@ -0,0 +1,56 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// protocol.h - communications protocols
|
||||
//=======================================================================
|
||||
#ifndef PROTOCOL_H
|
||||
#define PROTOCOL_H
|
||||
|
||||
#define PROTOCOL_VERSION 38
|
||||
|
||||
// server to client
|
||||
#define svc_bad 0 // immediately crash client when received
|
||||
// space 1 - 200 it's reserved for user messages
|
||||
#define svc_nop 201 // end of user messages
|
||||
#define svc_disconnect 202 // kick client from server
|
||||
#define svc_reconnect 203 // reconnecting server request
|
||||
#define svc_stufftext 204 // [string] stuffed into client's console buffer, should be \n terminated
|
||||
#define svc_serverdata 205 // [long] protocol ...
|
||||
#define svc_configstring 206 // [short] [string]
|
||||
#define svc_spawnbaseline 207 // valid only at spawn
|
||||
#define svc_download 208 // [short] size [size bytes]
|
||||
#define svc_changing 209 // changelevel by server request
|
||||
#define svc_physinfo 210 // [physinfo string]
|
||||
#define svc_usermessage 211 // [string][byte] REG_USER_MSG stuff
|
||||
#define svc_packetentities 212 // [...]
|
||||
#define svc_frame 213 // begin a new server frame
|
||||
#define svc_sound 214 // <see code>
|
||||
#define svc_ambientsound 215 // <see code>
|
||||
#define svc_setangle 216 // [float float] set the view angle to this absolute value
|
||||
#define svc_addangle 217 // [float] add angles when client turn on mover
|
||||
#define svc_setview 218 // [short] entity number
|
||||
#define svc_print 219 // [byte] id [string] null terminated string
|
||||
#define svc_centerprint 220 // [string] to put in center of the screen
|
||||
#define svc_crosshairangle 221 // [short][short][short]
|
||||
#define svc_setpause 222 // [byte] 0 = unpaused, 1 = paused
|
||||
#define svc_movevars 223 // [movevars_t]
|
||||
#define svc_particle 224 // [float*3][char*3][byte][byte]
|
||||
#define svc_soundfade 225 // [float*4] sound fade parms
|
||||
#define svc_bspdecal 226 // [float*3][short][short][short]
|
||||
#define svc_event 227 // playback event queue
|
||||
#define svc_event_reliable 228 // playback event directly from message, not queue
|
||||
#define svc_updateuserinfo 229 // [byte] playernum, [string] userinfo
|
||||
#define svc_serverinfo 230 // [string] key [string] value
|
||||
#define svc_clientdata 231 // [...]
|
||||
|
||||
// client to server
|
||||
#define clc_bad 0 // immediately drop client when received
|
||||
#define clc_nop 1
|
||||
#define clc_move 2 // [[usercmd_t]
|
||||
#define clc_delta 3 // [byte] sequence number, requests delta compression of message
|
||||
#define clc_userinfo 4 // [[userinfo string]
|
||||
#define clc_stringcmd 5 // [string] message
|
||||
#define clc_random_seed 6 // [long] random seed
|
||||
|
||||
#define msg_end 255 // shared marker for end the message
|
||||
|
||||
#endif//PROTOCOL_H
|
|
@ -294,10 +294,18 @@ SOURCE=.\common\net_buffer.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\net_encode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\net_msg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\protocol.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\server\server.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -765,8 +765,6 @@ Host_Init
|
|||
*/
|
||||
void Host_Init( const int argc, const char **argv )
|
||||
{
|
||||
char *s;
|
||||
|
||||
host.state = HOST_INIT; // initialzation started
|
||||
host.type = g_Instance();
|
||||
|
||||
|
@ -797,9 +795,6 @@ void Host_Init( const int argc, const char **argv )
|
|||
host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" );
|
||||
host_serverstate = Cvar_Get( "host_serverstate", "0", 0, "displays current server state" );
|
||||
|
||||
s = va( "Xash3D %i/%g (hw build ^3%i^7)", PROTOCOL_VERSION, SI->version, com_buildnum( ));
|
||||
Cvar_Get( "version", s, CVAR_INIT, "engine current version" );
|
||||
|
||||
// content control
|
||||
Cvar_Get( "violence_hgibs", "1", CVAR_INIT|CVAR_ARCHIVE, "content control disables human gibs" );
|
||||
Cvar_Get( "violence_agibs", "1", CVAR_INIT|CVAR_ARCHIVE, "content control disables alien gibs" );
|
||||
|
|
|
@ -74,10 +74,10 @@ typedef struct server_s
|
|||
|
||||
// the multicast buffer is used to send a message to a set of clients
|
||||
// it is only used to marshall data until SV_Message is called
|
||||
sizebuf_t multicast;
|
||||
bitbuf_t multicast;
|
||||
byte multicast_buf[MAX_MSGLEN];
|
||||
|
||||
sizebuf_t signon;
|
||||
bitbuf_t signon;
|
||||
byte signon_buf[MAX_MSGLEN];
|
||||
|
||||
bool write_bad_message; // just for debug
|
||||
|
@ -86,13 +86,11 @@ typedef struct server_s
|
|||
|
||||
typedef struct
|
||||
{
|
||||
entity_state_t ps; // player state
|
||||
int num_entities;
|
||||
int first_entity; // into the circular sv_packet_entities[]
|
||||
int senttime; // time the message was transmitted
|
||||
int latency;
|
||||
|
||||
int index; // client edict index
|
||||
clientdata_t cd; // clientdata
|
||||
} client_frame_t;
|
||||
|
||||
typedef struct sv_client_s
|
||||
|
@ -106,6 +104,7 @@ typedef struct sv_client_s
|
|||
bool sendmovevars;
|
||||
bool sendinfo;
|
||||
|
||||
int random_seed; // fpr predictable random values
|
||||
int lastframe; // for delta compression
|
||||
usercmd_t lastcmd; // for filling in big drops
|
||||
|
||||
|
@ -130,12 +129,12 @@ typedef struct sv_client_s
|
|||
|
||||
// The reliable buf contain reliable user messages that must be followed
|
||||
// after pvs frame
|
||||
sizebuf_t reliable;
|
||||
bitbuf_t reliable;
|
||||
byte reliable_buf[MAX_MSGLEN];
|
||||
|
||||
// the datagram is written to by sound calls, prints, temp ents, etc.
|
||||
// it can be harmlessly overflowed.
|
||||
sizebuf_t datagram;
|
||||
bitbuf_t datagram;
|
||||
byte datagram_buf[MAX_MSGLEN];
|
||||
|
||||
client_frame_t *frames; // updates can be delta'd from here
|
||||
|
@ -207,7 +206,7 @@ typedef struct
|
|||
// user messages stuff
|
||||
const char *msg_name; // just for debug
|
||||
sv_user_message_t msg[MAX_USER_MESSAGES]; // user messages array
|
||||
int msg_size_index; // write message size at this pos in sizebuf
|
||||
int msg_size_index; // write message size at this pos in bitbuf
|
||||
int msg_realsize; // left in bytes
|
||||
int msg_index; // for debug messages
|
||||
int msg_dest; // msg destination ( MSG_ONE, MSG_ALL etc )
|
||||
|
@ -364,12 +363,12 @@ void SV_GetChallenge( netadr_t from );
|
|||
void SV_DirectConnect( netadr_t from );
|
||||
void SV_TogglePause( const char *msg );
|
||||
void SV_PutClientInServer( edict_t *ent );
|
||||
void SV_FullClientUpdate( sv_client_t *cl, sizebuf_t *msg );
|
||||
void SV_UpdatePhysinfo( sv_client_t *cl, sizebuf_t *msg );
|
||||
void SV_FullClientUpdate( sv_client_t *cl, bitbuf_t *msg );
|
||||
void SV_UpdatePhysinfo( sv_client_t *cl, bitbuf_t *msg );
|
||||
bool SV_ClientConnect( edict_t *ent, char *userinfo );
|
||||
void SV_ClientThink( sv_client_t *cl, usercmd_t *cmd );
|
||||
void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg );
|
||||
void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg );
|
||||
void SV_ExecuteClientMessage( sv_client_t *cl, bitbuf_t *msg );
|
||||
void SV_ConnectionlessPacket( netadr_t from, bitbuf_t *msg );
|
||||
edict_t *SV_FakeConnect( const char *netname );
|
||||
void SV_PreRunCmd( sv_client_t *cl, usercmd_t *ucmd );
|
||||
void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd );
|
||||
|
@ -387,7 +386,7 @@ void SV_Newgame_f( void );
|
|||
//
|
||||
// sv_frame.c
|
||||
//
|
||||
void SV_WriteFrameToClient( sv_client_t *client, sizebuf_t *msg );
|
||||
void SV_WriteFrameToClient( sv_client_t *client, bitbuf_t *msg );
|
||||
void SV_BuildClientFrame( sv_client_t *client );
|
||||
void SV_InactivateClients( void );
|
||||
void SV_SendMessagesToAll( void );
|
||||
|
@ -407,7 +406,7 @@ void SV_SetModel( edict_t *ent, const char *name );
|
|||
void SV_CopyTraceToGlobal( trace_t *trace );
|
||||
void SV_SetMinMaxSize( edict_t *e, const float *min, const float *max );
|
||||
void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags );
|
||||
void SV_PlaybackEvent( sizebuf_t *msg, event_info_t *info );
|
||||
void SV_PlaybackEvent( bitbuf_t *msg, event_info_t *info );
|
||||
void SV_BaselineForEntity( edict_t *pEdict );
|
||||
void SV_WriteEntityPatch( const char *filename );
|
||||
script_t *SV_GetEntityScript( const char *filename );
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "common.h"
|
||||
#include "const.h"
|
||||
#include "server.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
#define MAX_FORWARD 6
|
||||
|
||||
|
@ -203,8 +205,8 @@ gotnewcl:
|
|||
Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect" );
|
||||
|
||||
Netchan_Setup( NS_SERVER, &newcl->netchan, from, qport );
|
||||
MSG_Init( &newcl->reliable, newcl->reliable_buf, sizeof( newcl->reliable_buf )); // reliable buf
|
||||
MSG_Init( &newcl->datagram, newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf
|
||||
BF_Init( &newcl->reliable, "Reliable", newcl->reliable_buf, sizeof( newcl->reliable_buf )); // reliable buf
|
||||
BF_Init( &newcl->datagram, "Datagram", newcl->datagram_buf, sizeof( newcl->datagram_buf )); // datagram buf
|
||||
|
||||
newcl->state = cs_connected;
|
||||
newcl->lastmessage = svs.realtime;
|
||||
|
@ -333,7 +335,7 @@ void SV_DropClient( sv_client_t *drop )
|
|||
|
||||
// add the disconnect
|
||||
if(!( drop->edict && (drop->edict->v.flags & FL_FAKECLIENT )))
|
||||
MSG_WriteByte( &drop->netchan.message, svc_disconnect );
|
||||
BF_WriteByte( &drop->netchan.message, svc_disconnect );
|
||||
|
||||
// let the game known about client state
|
||||
if( drop->edict->v.flags & FL_SPECTATOR )
|
||||
|
@ -403,9 +405,9 @@ void SV_FlushRedirect( netadr_t adr, int dest, char *buf )
|
|||
break;
|
||||
case RD_CLIENT:
|
||||
if( !sv_client ) return; // client not set
|
||||
MSG_WriteByte( &sv_client->netchan.message, svc_print );
|
||||
MSG_WriteByte( &sv_client->netchan.message, PRINT_HIGH );
|
||||
MSG_WriteString( &sv_client->netchan.message, buf );
|
||||
BF_WriteByte( &sv_client->netchan.message, svc_print );
|
||||
BF_WriteByte( &sv_client->netchan.message, PRINT_HIGH );
|
||||
BF_WriteString( &sv_client->netchan.message, buf );
|
||||
break;
|
||||
case RD_NONE:
|
||||
MsgDev( D_ERROR, "SV_FlushRedirect: %s: invalid destination\n", NET_AdrToString( adr ));
|
||||
|
@ -554,14 +556,14 @@ Shift down the remaining args
|
|||
Redirect all printfs
|
||||
===============
|
||||
*/
|
||||
void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
||||
void SV_RemoteCommand( netadr_t from, bitbuf_t *msg )
|
||||
{
|
||||
char remaining[1024];
|
||||
static char outputbuf[MAX_MSGLEN - 16];
|
||||
int i;
|
||||
|
||||
if(!Rcon_Validate()) MsgDev(D_INFO, "Bad rcon from %s:\n%s\n", NET_AdrToString( from ), msg->data + 4 );
|
||||
else MsgDev( D_INFO, "Rcon from %s:\n%s\n", NET_AdrToString( from ), msg->data + 4 );
|
||||
if(!Rcon_Validate()) MsgDev(D_INFO, "Bad rcon from %s:\n%s\n", NET_AdrToString( from ), BF_GetData( msg ) + 4 );
|
||||
else MsgDev( D_INFO, "Rcon from %s:\n%s\n", NET_AdrToString( from ), BF_GetData( msg ) + 4 );
|
||||
SV_BeginRedirect( from, RD_PACKET, outputbuf, MAX_MSGLEN - 16, SV_FlushRedirect );
|
||||
|
||||
if( !Rcon_Validate( ))
|
||||
|
@ -585,33 +587,33 @@ void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
|||
===================
|
||||
SV_FullClientUpdate
|
||||
|
||||
Writes all update values to a sizebuf
|
||||
Writes all update values to a bitbuf
|
||||
===================
|
||||
*/
|
||||
void SV_FullClientUpdate( sv_client_t *cl, sizebuf_t *msg )
|
||||
void SV_FullClientUpdate( sv_client_t *cl, bitbuf_t *msg )
|
||||
{
|
||||
int i;
|
||||
char info[MAX_INFO_STRING];
|
||||
|
||||
i = cl - svs.clients;
|
||||
|
||||
MSG_WriteByte( msg, svc_updateuserinfo );
|
||||
MSG_WriteByte( msg, i );
|
||||
BF_WriteByte( msg, svc_updateuserinfo );
|
||||
BF_WriteByte( msg, i );
|
||||
|
||||
if( cl->name[0] )
|
||||
{
|
||||
MSG_WriteByte( msg, true );
|
||||
BF_WriteByte( msg, true );
|
||||
|
||||
com.strncpy( info, cl->userinfo, sizeof( info ));
|
||||
|
||||
// remove server passwords, etc.
|
||||
Info_RemovePrefixedKeys( info, '_' );
|
||||
MSG_WriteString( msg, info );
|
||||
BF_WriteString( msg, info );
|
||||
}
|
||||
else MSG_WriteByte( msg, false );
|
||||
else BF_WriteByte( msg, false );
|
||||
|
||||
MSG_DirectSend( MSG_ALL, vec3_origin, NULL );
|
||||
MSG_Clear( msg );
|
||||
BF_Clear( msg );
|
||||
}
|
||||
|
||||
void SV_RefreshUserinfo( void )
|
||||
|
@ -632,14 +634,14 @@ this is send all movevars values when client connected
|
|||
otherwise see code SV_UpdateMovevars()
|
||||
===================
|
||||
*/
|
||||
void SV_UpdatePhysinfo( sv_client_t *cl, sizebuf_t *msg )
|
||||
void SV_UpdatePhysinfo( sv_client_t *cl, bitbuf_t *msg )
|
||||
{
|
||||
movevars_t nullmovevars;
|
||||
|
||||
Mem_Set( &nullmovevars, 0, sizeof( nullmovevars ));
|
||||
MSG_WriteDeltaMovevars( msg, &nullmovevars, &svgame.movevars );
|
||||
BF_WriteDeltaMovevars( msg, &nullmovevars, &svgame.movevars );
|
||||
MSG_DirectSend( MSG_ONE, NULL, cl->edict );
|
||||
MSG_Clear( msg );
|
||||
BF_Clear( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -687,9 +689,9 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
// NOTE: we needs to setup angles on restore here
|
||||
if( ent->v.fixangle == 1 )
|
||||
{
|
||||
MSG_WriteByte( &sv.multicast, svc_setangle );
|
||||
MSG_WriteAngle32( &sv.multicast, ent->v.angles[0] );
|
||||
MSG_WriteAngle32( &sv.multicast, ent->v.angles[1] );
|
||||
BF_WriteByte( &sv.multicast, svc_setangle );
|
||||
BF_WriteBitAngle( &sv.multicast, ent->v.angles[0], 16 );
|
||||
BF_WriteBitAngle( &sv.multicast, ent->v.angles[1], 16 );
|
||||
MSG_DirectSend( MSG_ONE, vec3_origin, client->edict );
|
||||
ent->v.fixangle = 0;
|
||||
}
|
||||
|
@ -701,10 +703,10 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
if( !( ent->v.flags & FL_FAKECLIENT ))
|
||||
{
|
||||
// copy signon buffer
|
||||
MSG_WriteData( &client->netchan.message, sv.signon.data, sv.signon.cursize );
|
||||
BF_WriteBits( &client->netchan.message, BF_GetData( &sv.signon ), BF_GetNumBitsWritten( &sv.signon ));
|
||||
|
||||
MSG_WriteByte( &client->netchan.message, svc_setview );
|
||||
MSG_WriteWord( &client->netchan.message, NUM_FOR_EDICT( client->edict ));
|
||||
BF_WriteByte( &client->netchan.message, svc_setview );
|
||||
BF_WriteWord( &client->netchan.message, NUM_FOR_EDICT( client->edict ));
|
||||
MSG_Send( MSG_ONE, NULL, client->edict );
|
||||
}
|
||||
|
||||
|
@ -728,8 +730,8 @@ void SV_TogglePause( const char *msg )
|
|||
if( msg ) SV_BroadcastPrintf( PRINT_HIGH, "%s", msg );
|
||||
|
||||
// send notification to all clients
|
||||
MSG_Begin( svc_setpause );
|
||||
MSG_WriteByte( &sv.multicast, sv.paused );
|
||||
BF_WriteByte( &sv.multicast, svc_setpause );
|
||||
BF_WriteByte( &sv.multicast, sv.paused );
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
}
|
||||
|
||||
|
@ -762,14 +764,14 @@ void SV_New_f( sv_client_t *cl )
|
|||
playernum = cl - svs.clients;
|
||||
|
||||
// send the serverdata
|
||||
MSG_WriteByte( &cl->netchan.message, svc_serverdata );
|
||||
MSG_WriteLong( &cl->netchan.message, PROTOCOL_VERSION );
|
||||
MSG_WriteLong( &cl->netchan.message, svs.spawncount );
|
||||
MSG_WriteByte( &cl->netchan.message, playernum );
|
||||
MSG_WriteByte( &cl->netchan.message, svgame.globals->maxClients );
|
||||
MSG_WriteWord( &cl->netchan.message, svgame.globals->maxEntities );
|
||||
MSG_WriteString( &cl->netchan.message, sv.configstrings[CS_NAME] );
|
||||
MSG_WriteString( &cl->netchan.message, STRING( EDICT_NUM( 0 )->v.message )); // Map Message
|
||||
BF_WriteByte( &cl->netchan.message, svc_serverdata );
|
||||
BF_WriteLong( &cl->netchan.message, PROTOCOL_VERSION );
|
||||
BF_WriteLong( &cl->netchan.message, svs.spawncount );
|
||||
BF_WriteByte( &cl->netchan.message, playernum );
|
||||
BF_WriteByte( &cl->netchan.message, svgame.globals->maxClients );
|
||||
BF_WriteWord( &cl->netchan.message, svgame.globals->maxEntities );
|
||||
BF_WriteString( &cl->netchan.message, sv.configstrings[CS_NAME] );
|
||||
BF_WriteString( &cl->netchan.message, STRING( EDICT_NUM( 0 )->v.message )); // Map Message
|
||||
|
||||
// refresh userinfo on spawn
|
||||
SV_RefreshUserinfo();
|
||||
|
@ -784,8 +786,8 @@ void SV_New_f( sv_client_t *cl )
|
|||
Mem_Set( &cl->lastcmd, 0, sizeof( cl->lastcmd ));
|
||||
|
||||
// begin fetching configstrings
|
||||
MSG_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, va( "cmd configstrings %i %i\n", svs.spawncount, 0 ));
|
||||
BF_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
BF_WriteString( &cl->netchan.message, va( "cmd configstrings %i %i\n", svs.spawncount, 0 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -816,13 +818,13 @@ void SV_Configstrings_f( sv_client_t *cl )
|
|||
start = com.atoi( Cmd_Argv( 2 ));
|
||||
|
||||
// write a packet full of data
|
||||
while( cl->netchan.message.cursize < (MAX_MSGLEN / 2) && start < MAX_CONFIGSTRINGS )
|
||||
while( BF_GetNumBytesWritten( &cl->netchan.message ) < ( MAX_MSGLEN / 2 ) && start < MAX_CONFIGSTRINGS )
|
||||
{
|
||||
if( sv.configstrings[start][0] )
|
||||
{
|
||||
MSG_WriteByte( &cl->netchan.message, svc_configstring );
|
||||
MSG_WriteShort( &cl->netchan.message, start );
|
||||
MSG_WriteString( &cl->netchan.message, sv.configstrings[start] );
|
||||
BF_WriteByte( &cl->netchan.message, svc_configstring );
|
||||
BF_WriteShort( &cl->netchan.message, start );
|
||||
BF_WriteString( &cl->netchan.message, sv.configstrings[start] );
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
@ -831,8 +833,8 @@ void SV_Configstrings_f( sv_client_t *cl )
|
|||
else com.snprintf( cmd, MAX_STRING, "cmd configstrings %i %i\n", svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, cmd );
|
||||
BF_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
BF_WriteString( &cl->netchan.message, cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -863,15 +865,15 @@ void SV_UserMessages_f( sv_client_t *cl )
|
|||
start = com.atoi( Cmd_Argv( 2 ));
|
||||
|
||||
// write a packet full of data
|
||||
while( cl->netchan.message.cursize < MAX_MSGLEN / 2 && start < MAX_USER_MESSAGES )
|
||||
while( BF_GetNumBytesWritten( &cl->netchan.message ) < ( MAX_MSGLEN / 2 ) && start < MAX_USER_MESSAGES )
|
||||
{
|
||||
message = &svgame.msg[start];
|
||||
if( message->name[0] )
|
||||
{
|
||||
MSG_WriteByte( &cl->netchan.message, svc_usermessage );
|
||||
MSG_WriteString( &cl->netchan.message, message->name );
|
||||
MSG_WriteByte( &cl->netchan.message, message->number );
|
||||
MSG_WriteByte( &cl->netchan.message, (byte)message->size );
|
||||
BF_WriteByte( &cl->netchan.message, svc_usermessage );
|
||||
BF_WriteString( &cl->netchan.message, message->name );
|
||||
BF_WriteByte( &cl->netchan.message, message->number );
|
||||
BF_WriteByte( &cl->netchan.message, (byte)message->size );
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
@ -880,8 +882,8 @@ void SV_UserMessages_f( sv_client_t *cl )
|
|||
else com.snprintf( cmd, MAX_STRING, "cmd usermsgs %i %i\n", svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, cmd );
|
||||
BF_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
BF_WriteString( &cl->netchan.message, cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -914,13 +916,13 @@ void SV_Baselines_f( sv_client_t *cl )
|
|||
Mem_Set( &nullstate, 0, sizeof( nullstate ));
|
||||
|
||||
// write a packet full of data
|
||||
while( cl->netchan.message.cursize < MAX_MSGLEN / 2 && start < svgame.globals->numEntities )
|
||||
while( BF_GetNumBytesWritten( &cl->netchan.message ) < ( MAX_MSGLEN / 2 ) && start < svgame.globals->numEntities )
|
||||
{
|
||||
base = &svs.baselines[start];
|
||||
if( base->modelindex || base->effects )
|
||||
{
|
||||
MSG_WriteByte( &cl->netchan.message, svc_spawnbaseline );
|
||||
MSG_WriteDeltaEntity( &nullstate, base, &cl->netchan.message, true, true );
|
||||
BF_WriteByte( &cl->netchan.message, svc_spawnbaseline );
|
||||
MSG_WriteDeltaEntity( &nullstate, base, &cl->netchan.message, true, sv.time );
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
@ -929,8 +931,8 @@ void SV_Baselines_f( sv_client_t *cl )
|
|||
else com.snprintf( cmd, MAX_STRING, "cmd baselines %i %i\n", svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, cmd );
|
||||
BF_WriteByte( &cl->netchan.message, svc_stufftext );
|
||||
BF_WriteString( &cl->netchan.message, cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -954,8 +956,8 @@ void SV_Begin_f( sv_client_t *cl )
|
|||
// if we are paused, tell the client
|
||||
if( sv.paused )
|
||||
{
|
||||
MSG_Begin( svc_setpause );
|
||||
MSG_WriteByte( &sv.multicast, sv.paused );
|
||||
BF_WriteByte( &sv.multicast, svc_setpause );
|
||||
BF_WriteByte( &sv.multicast, sv.paused );
|
||||
MSG_Send( MSG_ONE, vec3_origin, cl->edict );
|
||||
SV_ClientPrintf( cl, PRINT_HIGH, "Server is paused.\n" );
|
||||
}
|
||||
|
@ -976,15 +978,15 @@ void SV_NextDownload_f( sv_client_t *cl )
|
|||
r = cl->downloadsize - cl->downloadcount;
|
||||
if( r > 1024 ) r = 1024;
|
||||
|
||||
MSG_WriteByte( &cl->netchan.message, svc_download );
|
||||
MSG_WriteShort( &cl->netchan.message, r );
|
||||
BF_WriteByte( &cl->netchan.message, svc_download );
|
||||
BF_WriteShort( &cl->netchan.message, r );
|
||||
|
||||
cl->downloadcount += r;
|
||||
size = cl->downloadsize;
|
||||
if( !size ) size = 1;
|
||||
percent = cl->downloadcount * 100 / size;
|
||||
MSG_WriteByte( &cl->netchan.message, percent );
|
||||
MSG_WriteData( &cl->netchan.message, cl->download + cl->downloadcount - r, r );
|
||||
BF_WriteByte( &cl->netchan.message, percent );
|
||||
BF_WriteBytes( &cl->netchan.message, cl->download + cl->downloadcount - r, r );
|
||||
if( cl->downloadcount == cl->downloadsize ) cl->download = NULL;
|
||||
}
|
||||
|
||||
|
@ -1008,9 +1010,9 @@ void SV_BeginDownload_f( sv_client_t *cl )
|
|||
{
|
||||
MsgDev( D_ERROR, "SV_BeginDownload_f: couldn't download %s to %s\n", name, cl->name );
|
||||
if( cl->download ) Mem_Free( cl->download );
|
||||
MSG_WriteByte( &cl->netchan.message, svc_download );
|
||||
MSG_WriteShort( &cl->netchan.message, -1 );
|
||||
MSG_WriteByte( &cl->netchan.message, 0 );
|
||||
BF_WriteByte( &cl->netchan.message, svc_download );
|
||||
BF_WriteShort( &cl->netchan.message, -1 );
|
||||
BF_WriteByte( &cl->netchan.message, 0 );
|
||||
cl->download = NULL;
|
||||
return;
|
||||
}
|
||||
|
@ -1186,19 +1188,6 @@ void SV_ExecuteClientCommand( sv_client_t *cl, char *s )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
MSG_Begin
|
||||
|
||||
Misc helper function
|
||||
=================
|
||||
*/
|
||||
|
||||
void _MSG_Begin( int dest, const char *filename, int fileline )
|
||||
{
|
||||
_MSG_WriteBits( &sv.multicast, dest, "MSG_Begin", NET_BYTE, filename, fileline );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_Send
|
||||
|
@ -1227,11 +1216,11 @@ bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct,
|
|||
if( sv.state == ss_loading )
|
||||
{
|
||||
// copy signon buffer
|
||||
MSG_WriteData( &sv.signon, sv.multicast.data, sv.multicast.cursize );
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_WriteBits( &sv.signon, BF_GetData( &sv.multicast ), BF_GetNumBitsWritten( &sv.multicast ));
|
||||
BF_Clear( &sv.multicast );
|
||||
return true;
|
||||
}
|
||||
// intentional fallthrough (in-game MSG_INIT it's a MSG_ALL reliable)
|
||||
// intentional fallthrough (in-game BF_INIT it's a BF_ALL reliable)
|
||||
case MSG_ALL:
|
||||
reliable = true;
|
||||
// intentional fallthrough
|
||||
|
@ -1295,21 +1284,21 @@ bool _MSG_Send( int dest, const vec3_t origin, const edict_t *ent, bool direct,
|
|||
|
||||
if( reliable )
|
||||
{
|
||||
if( direct ) MSG_WriteData( &cl->netchan.message, sv.multicast.data, sv.multicast.cursize );
|
||||
else MSG_WriteData( &cl->reliable, sv.multicast.data, sv.multicast.cursize );
|
||||
if( direct ) BF_WriteBits( &cl->netchan.message, BF_GetData( &sv.multicast ), BF_GetNumBitsWritten( &sv.multicast ));
|
||||
else BF_WriteBits( &cl->reliable, BF_GetData( &sv.multicast ), BF_GetNumBitsWritten( &sv.multicast ));
|
||||
}
|
||||
else MSG_WriteData( &cl->datagram, sv.multicast.data, sv.multicast.cursize );
|
||||
else BF_WriteBits( &cl->datagram, BF_GetData( &sv.multicast ), BF_GetNumBitsWritten( &sv.multicast ));
|
||||
numsends++;
|
||||
}
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_Clear( &sv.multicast );
|
||||
|
||||
// 25% chanse for simulate random network bugs
|
||||
if( sv.write_bad_message && Com_RandomLong( 0, 32 ) <= 8 )
|
||||
{
|
||||
// just for network debugging (send only for local client)
|
||||
MSG_WriteByte( &sv.multicast, svc_bad );
|
||||
MSG_WriteLong( &sv.multicast, rand( )); // send some random data
|
||||
MSG_WriteString( &sv.multicast, host.finalmsg ); // send final message
|
||||
BF_WriteByte( &sv.multicast, svc_bad );
|
||||
BF_WriteLong( &sv.multicast, rand( )); // send some random data
|
||||
BF_WriteString( &sv.multicast, host.finalmsg ); // send final message
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
sv.write_bad_message = false;
|
||||
}
|
||||
|
@ -1326,15 +1315,15 @@ Clients that are in the game can still send
|
|||
connectionless packets.
|
||||
=================
|
||||
*/
|
||||
void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
void SV_ConnectionlessPacket( netadr_t from, bitbuf_t *msg )
|
||||
{
|
||||
char *s;
|
||||
char *c;
|
||||
|
||||
MSG_BeginReading( msg );
|
||||
MSG_ReadLong( msg );// skip the -1 marker
|
||||
BF_Clear( msg );
|
||||
BF_ReadLong( msg );// skip the -1 marker
|
||||
|
||||
s = MSG_ReadStringLine( msg );
|
||||
s = BF_ReadStringLine( msg );
|
||||
Cmd_TokenizeString( s );
|
||||
|
||||
c = Cmd_Argv( 0 );
|
||||
|
@ -1357,13 +1346,13 @@ SV_SetIdealPitch
|
|||
*/
|
||||
void SV_SetIdealPitch( sv_client_t *cl )
|
||||
{
|
||||
float angleval, sinval, cosval;
|
||||
trace_t tr;
|
||||
vec3_t top, bottom;
|
||||
float z[MAX_FORWARD];
|
||||
int i, j;
|
||||
int step, dir, steps;
|
||||
edict_t *ent = cl->edict;
|
||||
float angleval, sinval, cosval;
|
||||
trace_t tr;
|
||||
vec3_t top, bottom;
|
||||
float z[MAX_FORWARD];
|
||||
int i, j;
|
||||
int step, dir, steps;
|
||||
edict_t *ent = cl->edict;
|
||||
|
||||
if( !( ent->v.flags & FL_ONGROUND ))
|
||||
return;
|
||||
|
@ -1428,15 +1417,15 @@ On very fast clients, there may be multiple usercmd packed into
|
|||
each of the backup packets.
|
||||
==================
|
||||
*/
|
||||
static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
|
||||
static void SV_ReadClientMove( sv_client_t *cl, bitbuf_t *msg )
|
||||
{
|
||||
int checksum1, checksum2;
|
||||
int key, lastframe, net_drop;
|
||||
int key, lastframe, net_drop, size;
|
||||
usercmd_t oldest, oldcmd, newcmd, nulcmd;
|
||||
|
||||
key = msg->readcount;
|
||||
checksum1 = MSG_ReadByte( msg );
|
||||
lastframe = MSG_ReadLong( msg );
|
||||
key = BF_GetNumBytesRead( msg );
|
||||
checksum1 = BF_ReadByte( msg );
|
||||
lastframe = BF_ReadLong( msg );
|
||||
|
||||
if( lastframe != cl->lastframe )
|
||||
{
|
||||
|
@ -1462,7 +1451,8 @@ static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
|
|||
}
|
||||
|
||||
// if the checksum fails, ignore the rest of the packet
|
||||
checksum2 = CRC_Sequence( msg->data + key + 1, msg->readcount - key - 1, cl->netchan.incoming_sequence );
|
||||
size = BF_GetNumBytesRead( msg ) - key - 1;
|
||||
checksum2 = CRC_Sequence( BF_GetData( msg ) + key + 1, size, cl->netchan.incoming_sequence );
|
||||
if( checksum2 != checksum1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_UserMove: failed command checksum for %s (%d != %d)\n", cl->name, checksum2, checksum1 );
|
||||
|
@ -1503,7 +1493,7 @@ SV_ExecuteClientMessage
|
|||
Parse a client packet
|
||||
===================
|
||||
*/
|
||||
void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
||||
void SV_ExecuteClientMessage( sv_client_t *cl, bitbuf_t *msg )
|
||||
{
|
||||
int c, stringCmdCount = 0;
|
||||
bool move_issued = false;
|
||||
|
@ -1521,22 +1511,25 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
|||
// read optional clientCommand strings
|
||||
while( cl->state != cs_zombie )
|
||||
{
|
||||
c = MSG_ReadByte( msg );
|
||||
if( c == -1 ) break;
|
||||
|
||||
if( msg->error )
|
||||
if( BF_CheckOverflow( msg ))
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_ReadClientMessage: clc_bad\n" );
|
||||
SV_DropClient( cl );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// end of message
|
||||
if( BF_GetNumBitsLeft( msg ) < 8 )
|
||||
break;
|
||||
|
||||
c = BF_ReadByte( msg );
|
||||
|
||||
switch( c )
|
||||
{
|
||||
case clc_nop:
|
||||
break;
|
||||
case clc_userinfo:
|
||||
SV_UserinfoChanged( cl, MSG_ReadString( msg ));
|
||||
SV_UserinfoChanged( cl, BF_ReadString( msg ));
|
||||
break;
|
||||
case clc_move:
|
||||
if( move_issued ) return; // someone is trying to cheat...
|
||||
|
@ -1544,11 +1537,14 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
|||
SV_ReadClientMove( cl, msg );
|
||||
break;
|
||||
case clc_stringcmd:
|
||||
s = MSG_ReadString( msg );
|
||||
s = BF_ReadString( msg );
|
||||
// malicious users may try using too many string commands
|
||||
if( ++stringCmdCount < 8 ) SV_ExecuteClientCommand( cl, s );
|
||||
if( cl->state == cs_zombie ) return; // disconnect command
|
||||
break;
|
||||
case clc_random_seed:
|
||||
cl->random_seed = BF_ReadUBitLong( msg, 32 );
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "SV_ReadClientMessage: clc_bad\n" );
|
||||
SV_DropClient( cl );
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
#include "protocol.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
sv_client_t *sv_client; // current client
|
||||
|
@ -31,9 +32,9 @@ void SV_ClientPrintf( sv_client_t *cl, int level, char *fmt, ... )
|
|||
com.vsprintf( string, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
MSG_WriteByte( &cl->netchan.message, svc_print );
|
||||
MSG_WriteByte( &cl->netchan.message, level );
|
||||
MSG_WriteString( &cl->netchan.message, string );
|
||||
BF_WriteByte( &cl->netchan.message, svc_print );
|
||||
BF_WriteByte( &cl->netchan.message, level );
|
||||
BF_WriteString( &cl->netchan.message, string );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -62,9 +63,9 @@ void SV_BroadcastPrintf( int level, char *fmt, ... )
|
|||
if( cl->state != cs_spawned ) continue;
|
||||
if( cl->edict && (cl->edict->v.flags & FL_FAKECLIENT ))
|
||||
continue;
|
||||
MSG_WriteByte( &cl->netchan.message, svc_print );
|
||||
MSG_WriteByte( &cl->netchan.message, level );
|
||||
MSG_WriteString( &cl->netchan.message, string );
|
||||
BF_WriteByte( &cl->netchan.message, svc_print );
|
||||
BF_WriteByte( &cl->netchan.message, level );
|
||||
BF_WriteString( &cl->netchan.message, string );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,8 +86,8 @@ void SV_BroadcastCommand( char *fmt, ... )
|
|||
com.vsprintf( string, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
MSG_Begin( svc_stufftext );
|
||||
MSG_WriteString( &sv.multicast, string );
|
||||
BF_WriteByte( &sv.multicast, svc_stufftext );
|
||||
BF_WriteString( &sv.multicast, string );
|
||||
MSG_Send( MSG_ALL, NULL, NULL );
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "common.h"
|
||||
#include "server.h"
|
||||
#include "const.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
|
||||
#define MAX_VISIBLE_PACKET 1024
|
||||
typedef struct
|
||||
|
@ -51,14 +53,14 @@ SV_EmitPacketEntities
|
|||
Writes a delta update of an entity_state_t list to the message->
|
||||
=============
|
||||
*/
|
||||
void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, sizebuf_t *msg )
|
||||
void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, bitbuf_t *msg )
|
||||
{
|
||||
entity_state_t *oldent, *newent;
|
||||
int oldindex, newindex;
|
||||
int oldnum, newnum;
|
||||
int from_num_entities;
|
||||
|
||||
MSG_WriteByte( msg, svc_packetentities );
|
||||
BF_WriteByte( msg, svc_packetentities );
|
||||
|
||||
if( !from ) from_num_entities = 0;
|
||||
else from_num_entities = from->num_entities;
|
||||
|
@ -95,7 +97,7 @@ void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, sizebuf_t
|
|||
// delta update from old position
|
||||
// because the force parm is false, this will not result
|
||||
// in any bytes being emited if the entity has not changed at all
|
||||
MSG_WriteDeltaEntity( oldent, newent, msg, false, ( newent->number <= sv_maxclients->integer ));
|
||||
MSG_WriteDeltaEntity( oldent, newent, msg, false, sv.time );
|
||||
oldindex++;
|
||||
newindex++;
|
||||
continue;
|
||||
|
@ -104,7 +106,7 @@ void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, sizebuf_t
|
|||
if( newnum < oldnum )
|
||||
{
|
||||
// this is a new entity, send it from the baseline
|
||||
MSG_WriteDeltaEntity( &svs.baselines[newnum], newent, msg, true, true );
|
||||
MSG_WriteDeltaEntity( &svs.baselines[newnum], newent, msg, true, sv.time );
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
|
@ -112,12 +114,12 @@ void SV_EmitPacketEntities( client_frame_t *from, client_frame_t *to, sizebuf_t
|
|||
if( newnum > oldnum )
|
||||
{
|
||||
// remove from message
|
||||
MSG_WriteDeltaEntity( oldent, NULL, msg, false, false );
|
||||
MSG_WriteDeltaEntity( oldent, NULL, msg, false, sv.time );
|
||||
oldindex++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
MSG_WriteBits( msg, 0, "svc_packetentities", NET_WORD ); // end of packetentities
|
||||
BF_WriteWord( msg, 0 ); // end of packetentities
|
||||
}
|
||||
|
||||
static void SV_AddEntitiesToPacket( edict_t *pViewEnt, edict_t *pClient, client_frame_t *frame, sv_ents_t *ents, bool portal )
|
||||
|
@ -207,7 +209,7 @@ static void SV_AddEntitiesToPacket( edict_t *pViewEnt, edict_t *pClient, client_
|
|||
}
|
||||
}
|
||||
|
||||
static void SV_EmitEvents( sv_client_t *cl, client_frame_t *frame, sizebuf_t *msg )
|
||||
static void SV_EmitEvents( sv_client_t *cl, client_frame_t *frame, bitbuf_t *msg )
|
||||
{
|
||||
int i, ev;
|
||||
event_state_t *es;
|
||||
|
@ -232,8 +234,8 @@ static void SV_EmitEvents( sv_client_t *cl, client_frame_t *frame, sizebuf_t *ms
|
|||
if( ev_count >= MAX_EVENT_QUEUE )
|
||||
ev_count = MAX_EVENT_QUEUE - 1;
|
||||
|
||||
MSG_WriteByte( msg, svc_event ); // create message
|
||||
MSG_WriteByte( msg, ev_count ); // Up to MAX_EVENT_QUEUE events
|
||||
BF_WriteByte( msg, svc_event ); // create message
|
||||
BF_WriteByte( msg, ev_count ); // Up to MAX_EVENT_QUEUE events
|
||||
|
||||
for( i = c = 0 ; i < MAX_EVENT_QUEUE; i++ )
|
||||
{
|
||||
|
@ -251,12 +253,36 @@ static void SV_EmitEvents( sv_client_t *cl, client_frame_t *frame, sizebuf_t *ms
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_WriteClientData
|
||||
|
||||
=============
|
||||
*/
|
||||
void SV_WriteClientData( client_frame_t *from, client_frame_t *to, bitbuf_t *msg )
|
||||
{
|
||||
clientdata_t *cd, *ocd;
|
||||
clientdata_t dummy;
|
||||
|
||||
cd = &to->cd;
|
||||
|
||||
if( !from )
|
||||
{
|
||||
Mem_Set( &dummy, 0, sizeof( dummy ));
|
||||
ocd = &dummy;
|
||||
}
|
||||
else ocd = &from->cd;
|
||||
|
||||
BF_WriteByte( msg, svc_clientdata );
|
||||
MSG_WriteClientData( msg, ocd, cd, sv.time );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_WriteFrameToClient
|
||||
==================
|
||||
*/
|
||||
void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg )
|
||||
void SV_WriteFrameToClient( sv_client_t *cl, bitbuf_t *msg )
|
||||
{
|
||||
client_frame_t *frame, *oldframe;
|
||||
int lastframe;
|
||||
|
@ -294,22 +320,24 @@ void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg )
|
|||
if( cl->physinfo_modified )
|
||||
{
|
||||
cl->physinfo_modified = false;
|
||||
MSG_WriteByte( msg, svc_physinfo );
|
||||
MSG_WriteString( msg, cl->physinfo );
|
||||
BF_WriteByte( msg, svc_physinfo );
|
||||
BF_WriteString( msg, cl->physinfo );
|
||||
}
|
||||
|
||||
// delta encode the events
|
||||
SV_EmitEvents( cl, frame, msg );
|
||||
|
||||
MSG_WriteByte( msg, svc_frame );
|
||||
MSG_WriteLong( msg, sv.framenum );
|
||||
MSG_WriteLong( msg, sv.time ); // send a servertime each frame
|
||||
MSG_WriteLong( msg, lastframe ); // what we are delta'ing from
|
||||
MSG_WriteByte( msg, sv.frametime );
|
||||
MSG_WriteByte( msg, cl->surpressCount ); // rate dropped packets
|
||||
MSG_WriteByte( msg, frame->index ); // send a client index
|
||||
BF_WriteByte( msg, svc_frame );
|
||||
BF_WriteLong( msg, sv.framenum );
|
||||
BF_WriteLong( msg, sv.time ); // send a servertime each frame
|
||||
BF_WriteLong( msg, lastframe ); // what we are delta'ing from
|
||||
BF_WriteByte( msg, sv.frametime );
|
||||
BF_WriteByte( msg, cl->surpressCount ); // rate dropped packets
|
||||
cl->surpressCount = 0;
|
||||
|
||||
// delta encode the clientdata
|
||||
SV_WriteClientData( oldframe, frame, msg );
|
||||
|
||||
// delta encode the entities
|
||||
SV_EmitPacketEntities( oldframe, frame, msg );
|
||||
}
|
||||
|
@ -352,15 +380,15 @@ void SV_BuildClientFrame( sv_client_t *cl )
|
|||
switch( clent->v.fixangle )
|
||||
{
|
||||
case 1:
|
||||
MSG_WriteByte( &sv.multicast, svc_setangle );
|
||||
MSG_WriteAngle32( &sv.multicast, clent->v.angles[0] );
|
||||
MSG_WriteAngle32( &sv.multicast, clent->v.angles[1] );
|
||||
BF_WriteByte( &sv.multicast, svc_setangle );
|
||||
BF_WriteBitAngle( &sv.multicast, clent->v.angles[0], 16 );
|
||||
BF_WriteBitAngle( &sv.multicast, clent->v.angles[1], 16 );
|
||||
MSG_DirectSend( MSG_ONE, vec3_origin, clent );
|
||||
clent->pvServerData->s.ed_flags |= ESF_NO_PREDICTION;
|
||||
break;
|
||||
case 2:
|
||||
MSG_WriteByte( &sv.multicast, svc_addangle );
|
||||
MSG_WriteAngle32( &sv.multicast, cl->addangle );
|
||||
BF_WriteByte( &sv.multicast, svc_addangle );
|
||||
BF_WriteBitAngle( &sv.multicast, cl->addangle, 16 );
|
||||
MSG_DirectSend( MSG_ONE, vec3_origin, clent );
|
||||
cl->addangle = 0;
|
||||
break;
|
||||
|
@ -376,8 +404,8 @@ void SV_BuildClientFrame( sv_client_t *cl )
|
|||
frame_ents.num_entities = c_fullsend = 0;
|
||||
if( !clent->pvServerData->client ) return; // not in game yet
|
||||
|
||||
// grab the current player index
|
||||
frame->index = NUM_FOR_EDICT( clent );
|
||||
// update clientdata_t
|
||||
svgame.dllFuncs.pfnUpdateClientData( clent, false, &frame->cd );
|
||||
|
||||
// add all the entities directly visible to the eye, which
|
||||
// may include portal entities that merge other viewpoints
|
||||
|
@ -423,12 +451,12 @@ SV_SendClientDatagram
|
|||
*/
|
||||
bool SV_SendClientDatagram( sv_client_t *cl )
|
||||
{
|
||||
byte msg_buf[MAX_MSGLEN];
|
||||
sizebuf_t msg;
|
||||
byte msg_buf[MAX_MSGLEN];
|
||||
bitbuf_t msg;
|
||||
|
||||
SV_BuildClientFrame( cl );
|
||||
|
||||
MSG_Init( &msg, msg_buf, sizeof( msg_buf ));
|
||||
BF_Init( &msg, "Datagram", msg_buf, sizeof( msg_buf ));
|
||||
|
||||
// send over all the relevant entity_state_t
|
||||
// and the player state
|
||||
|
@ -438,37 +466,37 @@ bool SV_SendClientDatagram( sv_client_t *cl )
|
|||
// for this client out to the message
|
||||
// it is necessary for this to be after the WriteEntities
|
||||
// so that entity references will be current
|
||||
if( cl->reliable.overflowed ) MsgDev( D_ERROR, "reliable datagram overflowed for %s\n", cl->name );
|
||||
else MSG_WriteData( &msg, cl->reliable.data, cl->reliable.cursize );
|
||||
MSG_Clear( &cl->reliable );
|
||||
if( BF_CheckOverflow( &cl->reliable )) MsgDev( D_ERROR, "reliable datagram overflowed for %s\n", cl->name );
|
||||
else BF_WriteBits( &msg, BF_GetData( &cl->reliable ), BF_GetNumBitsWritten( &cl->reliable ));
|
||||
BF_Clear( &cl->reliable );
|
||||
|
||||
if( msg.overflowed )
|
||||
if( BF_CheckOverflow( &msg ))
|
||||
{
|
||||
// must have room left for the packet header
|
||||
MsgDev( D_WARN, "msg overflowed for %s\n", cl->name );
|
||||
MSG_Clear( &msg );
|
||||
BF_Clear( &msg );
|
||||
}
|
||||
|
||||
// copy the accumulated multicast datagram
|
||||
// for this client out to the message
|
||||
// it is necessary for this to be after the WriteEntities
|
||||
// so that entity references will be current
|
||||
if( cl->datagram.overflowed ) MsgDev( D_WARN, "datagram overflowed for %s\n", cl->name );
|
||||
else MSG_WriteData( &msg, cl->datagram.data, cl->datagram.cursize );
|
||||
MSG_Clear( &cl->datagram );
|
||||
if( BF_CheckOverflow( &cl->datagram )) MsgDev( D_WARN, "datagram overflowed for %s\n", cl->name );
|
||||
else BF_WriteBits( &msg, BF_GetData( &cl->datagram ), BF_GetNumBitsWritten( &cl->datagram ));
|
||||
BF_Clear( &cl->datagram );
|
||||
|
||||
if( msg.overflowed )
|
||||
if( BF_CheckOverflow( &msg ))
|
||||
{
|
||||
// must have room left for the packet header
|
||||
MsgDev( D_WARN, "msg overflowed for %s\n", cl->name );
|
||||
MSG_Clear( &msg );
|
||||
BF_Clear( &msg );
|
||||
}
|
||||
|
||||
// send the datagram
|
||||
Netchan_Transmit( &cl->netchan, msg.cursize, msg.data );
|
||||
Netchan_TransmitBits( &cl->netchan, BF_GetNumBitsWritten( &msg ), BF_GetData( &msg ));
|
||||
|
||||
// record the size for rate estimation
|
||||
cl->message_size[sv.framenum % RATE_MESSAGES] = msg.cursize;
|
||||
cl->message_size[sv.framenum % RATE_MESSAGES] = BF_GetNumBytesWritten( &msg );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -540,11 +568,11 @@ void SV_SendClientMessages( void )
|
|||
}
|
||||
|
||||
// if the reliable message overflowed, drop the client
|
||||
if( cl->netchan.message.overflowed )
|
||||
if( BF_CheckOverflow( &cl->netchan.message ))
|
||||
{
|
||||
MSG_Clear( &cl->netchan.message );
|
||||
MSG_Clear( &cl->reliable );
|
||||
MSG_Clear( &cl->datagram );
|
||||
BF_Clear( &cl->netchan.message );
|
||||
BF_Clear( &cl->reliable );
|
||||
BF_Clear( &cl->datagram );
|
||||
SV_BroadcastPrintf( PRINT_HIGH, "%s overflowed\n", cl->name );
|
||||
SV_DropClient( cl );
|
||||
cl->send_message = true;
|
||||
|
@ -561,7 +589,7 @@ void SV_SendClientMessages( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( cl->netchan.message.cursize || svs.realtime - cl->netchan.last_sent > 1000 )
|
||||
if( BF_GetNumBytesWritten( &cl->netchan.message ) || svs.realtime - cl->netchan.last_sent > 1000 )
|
||||
Netchan_Transmit( &cl->netchan, 0, NULL );
|
||||
}
|
||||
// yes, message really sended
|
||||
|
@ -619,6 +647,6 @@ void SV_InactivateClients( void )
|
|||
svs.clients[i].state = cs_connected;
|
||||
|
||||
// clear netchan message (but keep other buffers)
|
||||
MSG_Clear( &cl->netchan.message );
|
||||
BF_Clear( &cl->netchan.message );
|
||||
}
|
||||
}
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
#include "protocol.h"
|
||||
#include "net_sound.h"
|
||||
#include "net_encode.h"
|
||||
#include "byteorder.h"
|
||||
#include "matrix_lib.h"
|
||||
#include "pm_defs.h"
|
||||
|
@ -153,10 +155,10 @@ void SV_ConfigString( int index, const char *val )
|
|||
if( sv.state != ss_loading )
|
||||
{
|
||||
// send the update to everyone
|
||||
MSG_Clear( &sv.multicast );
|
||||
MSG_Begin( svc_configstring );
|
||||
MSG_WriteShort( &sv.multicast, index );
|
||||
MSG_WriteString( &sv.multicast, val );
|
||||
BF_Clear( &sv.multicast );
|
||||
BF_WriteByte( &sv.multicast, svc_configstring );
|
||||
BF_WriteShort( &sv.multicast, index );
|
||||
BF_WriteString( &sv.multicast, val );
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
}
|
||||
}
|
||||
|
@ -166,13 +168,13 @@ void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int m
|
|||
ASSERT( origin );
|
||||
|
||||
// static decals are posters, it's always reliable
|
||||
MSG_WriteByte( &sv.multicast, svc_bspdecal );
|
||||
MSG_WritePos( &sv.multicast, origin );
|
||||
MSG_WriteWord( &sv.multicast, decalIndex );
|
||||
MSG_WriteShort( &sv.multicast, entityIndex );
|
||||
BF_WriteByte( &sv.multicast, svc_bspdecal );
|
||||
BF_WriteBitVec3Coord( &sv.multicast, origin );
|
||||
BF_WriteWord( &sv.multicast, decalIndex );
|
||||
BF_WriteShort( &sv.multicast, entityIndex );
|
||||
if( entityIndex > 0 )
|
||||
MSG_WriteWord( &sv.multicast, modelIndex );
|
||||
MSG_WriteByte( &sv.multicast, flags );
|
||||
BF_WriteWord( &sv.multicast, modelIndex );
|
||||
BF_WriteByte( &sv.multicast, flags );
|
||||
MSG_Send( MSG_INIT, NULL, NULL );
|
||||
}
|
||||
|
||||
|
@ -505,7 +507,7 @@ void SV_FreeEdicts( void )
|
|||
}
|
||||
}
|
||||
|
||||
void SV_PlaybackEvent( sizebuf_t *msg, event_info_t *info )
|
||||
void SV_PlaybackEvent( bitbuf_t *msg, event_info_t *info )
|
||||
{
|
||||
event_args_t nullargs;
|
||||
|
||||
|
@ -514,8 +516,8 @@ void SV_PlaybackEvent( sizebuf_t *msg, event_info_t *info )
|
|||
|
||||
Mem_Set( &nullargs, 0, sizeof( nullargs ));
|
||||
|
||||
MSG_WriteWord( msg, info->index ); // send event index
|
||||
MSG_WriteWord( msg, (int)( info->fire_time * 100.0f )); // send event delay
|
||||
BF_WriteWord( msg, info->index ); // send event index
|
||||
BF_WriteWord( msg, (int)( info->fire_time * 100.0f )); // send event delay
|
||||
MSG_WriteDeltaEvent( msg, &nullargs, &info->args ); // FIXME: zero-compressing
|
||||
}
|
||||
|
||||
|
@ -616,8 +618,8 @@ void SV_BaselineForEntity( edict_t *pEdict )
|
|||
entity_state_t nullstate;
|
||||
|
||||
Mem_Set( &nullstate, 0, sizeof( nullstate ));
|
||||
MSG_WriteByte( &sv.multicast, svc_spawnbaseline );
|
||||
MSG_WriteDeltaEntity( &nullstate, &sv_ent->s, &sv.multicast, true, true );
|
||||
BF_WriteByte( &sv.multicast, svc_spawnbaseline );
|
||||
MSG_WriteDeltaEntity( &nullstate, &sv_ent->s, &sv.multicast, true, sv.time );
|
||||
MSG_DirectSend( MSG_ALL, vec3_origin, NULL );
|
||||
}
|
||||
}
|
||||
|
@ -757,6 +759,7 @@ int pfnModelIndex( const char *m )
|
|||
{
|
||||
int index;
|
||||
|
||||
if( !m || !m[0] ) return 0;
|
||||
index = SV_FindIndex( m, CS_MODELS, MAX_MODELS, false );
|
||||
if( !index ) MsgDev( D_WARN, "SV_ModelIndex: %s not precached\n", m );
|
||||
|
||||
|
@ -1436,17 +1439,17 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
|
|||
entityIndex = ent->v.aiment->serialnumber;
|
||||
else entityIndex = ent->serialnumber;
|
||||
|
||||
MSG_Begin( svc_sound );
|
||||
MSG_WriteWord( &sv.multicast, flags );
|
||||
MSG_WriteWord( &sv.multicast, sound_idx );
|
||||
MSG_WriteByte( &sv.multicast, chan );
|
||||
BF_WriteByte( &sv.multicast, svc_sound );
|
||||
BF_WriteWord( &sv.multicast, flags );
|
||||
BF_WriteWord( &sv.multicast, sound_idx );
|
||||
BF_WriteByte( &sv.multicast, chan );
|
||||
|
||||
if( flags & SND_VOLUME ) MSG_WriteByte( &sv.multicast, vol * 255 );
|
||||
if( flags & SND_ATTENUATION ) MSG_WriteByte( &sv.multicast, attn * 64 );
|
||||
if( flags & SND_PITCH ) MSG_WriteByte( &sv.multicast, pitch );
|
||||
if( flags & SND_VOLUME ) BF_WriteByte( &sv.multicast, vol * 255 );
|
||||
if( flags & SND_ATTENUATION ) BF_WriteByte( &sv.multicast, attn * 64 );
|
||||
if( flags & SND_PITCH ) BF_WriteByte( &sv.multicast, pitch );
|
||||
|
||||
MSG_WriteWord( &sv.multicast, entityIndex );
|
||||
if( flags & SND_FIXED_ORIGIN ) MSG_WritePos( &sv.multicast, origin );
|
||||
BF_WriteWord( &sv.multicast, entityIndex );
|
||||
if( flags & SND_FIXED_ORIGIN ) BF_WriteBitVec3Coord( &sv.multicast, origin );
|
||||
|
||||
MSG_Send( msg_dest, origin, NULL );
|
||||
}
|
||||
|
@ -1519,18 +1522,18 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
|
|||
sound_idx = SV_SoundIndex( sample );
|
||||
}
|
||||
|
||||
MSG_Begin( svc_ambientsound );
|
||||
MSG_WriteWord( &sv.multicast, flags );
|
||||
MSG_WriteWord( &sv.multicast, sound_idx );
|
||||
MSG_WriteByte( &sv.multicast, CHAN_AUTO );
|
||||
BF_WriteByte( &sv.multicast, svc_ambientsound );
|
||||
BF_WriteWord( &sv.multicast, flags );
|
||||
BF_WriteWord( &sv.multicast, sound_idx );
|
||||
BF_WriteByte( &sv.multicast, CHAN_AUTO );
|
||||
|
||||
if( flags & SND_VOLUME ) MSG_WriteByte( &sv.multicast, vol * 255 );
|
||||
if( flags & SND_ATTENUATION ) MSG_WriteByte( &sv.multicast, attn * 64 );
|
||||
if( flags & SND_PITCH ) MSG_WriteByte( &sv.multicast, pitch );
|
||||
if( flags & SND_VOLUME ) BF_WriteByte( &sv.multicast, vol * 255 );
|
||||
if( flags & SND_ATTENUATION ) BF_WriteByte( &sv.multicast, attn * 64 );
|
||||
if( flags & SND_PITCH ) BF_WriteByte( &sv.multicast, pitch );
|
||||
|
||||
// plays from fixed position
|
||||
MSG_WriteWord( &sv.multicast, number );
|
||||
MSG_WritePos( &sv.multicast, pos );
|
||||
BF_WriteWord( &sv.multicast, number );
|
||||
BF_WriteBitVec3Coord( &sv.multicast, pos );
|
||||
|
||||
MSG_Send( msg_dest, origin, NULL );
|
||||
}
|
||||
|
@ -1826,8 +1829,8 @@ void pfnClientCommand( edict_t* pEdict, char* szFmt, ... )
|
|||
|
||||
if( SV_IsValidCmd( buffer ))
|
||||
{
|
||||
MSG_WriteByte( &sv.multicast, svc_stufftext );
|
||||
MSG_WriteString( &sv.multicast, buffer );
|
||||
BF_WriteByte( &sv.multicast, svc_stufftext );
|
||||
BF_WriteString( &sv.multicast, buffer );
|
||||
MSG_Send( MSG_ONE, NULL, client->edict );
|
||||
}
|
||||
else MsgDev( D_ERROR, "Tried to stuff bad command %s\n", buffer );
|
||||
|
@ -1851,16 +1854,16 @@ void pfnParticleEffect( const float *org, const float *dir, float color, float c
|
|||
return;
|
||||
}
|
||||
|
||||
MSG_WriteByte( &sv.multicast, svc_particle );
|
||||
MSG_WritePos( &sv.multicast, org );
|
||||
BF_WriteByte( &sv.multicast, svc_particle );
|
||||
BF_WriteBitVec3Coord( &sv.multicast, org );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
v = bound( -128, dir[i] * 16, 127 );
|
||||
MSG_WriteChar( &sv.multicast, v );
|
||||
BF_WriteChar( &sv.multicast, v );
|
||||
}
|
||||
MSG_WriteByte( &sv.multicast, count );
|
||||
MSG_WriteByte( &sv.multicast, color );
|
||||
BF_WriteByte( &sv.multicast, count );
|
||||
BF_WriteByte( &sv.multicast, color );
|
||||
MSG_Send( MSG_ALL, org, NULL );
|
||||
}
|
||||
|
||||
|
@ -1923,7 +1926,7 @@ void pfnMessageBegin( int msg_dest, int msg_num, const float *pOrigin, edict_t *
|
|||
svgame.msg_name = svgame.msg[svgame.msg_index].name;
|
||||
else svgame.msg_name = NULL;
|
||||
|
||||
MSG_Begin( svgame.msg_index );
|
||||
BF_WriteByte( &sv.multicast, svgame.msg_index );
|
||||
|
||||
// save message destination
|
||||
if( pOrigin ) VectorCopy( pOrigin, svgame.msg_org );
|
||||
|
@ -1932,8 +1935,8 @@ void pfnMessageBegin( int msg_dest, int msg_num, const float *pOrigin, edict_t *
|
|||
if( svgame.msg[svgame.msg_index].size == -1 )
|
||||
{
|
||||
// variable sized messages sent size as first byte
|
||||
svgame.msg_size_index = sv.multicast.cursize;
|
||||
MSG_WriteByte( &sv.multicast, 0 ); // reserve space for now
|
||||
svgame.msg_size_index = BF_GetNumBytesWritten( &sv.multicast );
|
||||
BF_WriteByte( &sv.multicast, 0 ); // reserve space for now
|
||||
}
|
||||
else svgame.msg_size_index = -1;
|
||||
|
||||
|
@ -1966,7 +1969,7 @@ void pfnMessageEnd( void )
|
|||
if( expsize != realsize )
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_Message: %s expected %i bytes, it written %i. Ignored.\n", name, expsize, realsize );
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_Clear( &sv.multicast );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1976,22 +1979,22 @@ void pfnMessageEnd( void )
|
|||
if( svgame.msg_realsize > 255 )
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_Message: %s too long (more than 255 bytes)\n", name );
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_Clear( &sv.multicast );
|
||||
return;
|
||||
}
|
||||
else if( svgame.msg_realsize <= 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_Message: %s writes NULL message\n", name );
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_Clear( &sv.multicast );
|
||||
return;
|
||||
}
|
||||
sv.multicast.data[svgame.msg_size_index] = svgame.msg_realsize;
|
||||
sv.multicast.pData[svgame.msg_size_index] = svgame.msg_realsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this should never happen
|
||||
MsgDev( D_ERROR, "SV_Message: %s have encountered error\n", name );
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_Clear( &sv.multicast );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2009,7 +2012,7 @@ pfnWriteByte
|
|||
void pfnWriteByte( int iValue )
|
||||
{
|
||||
if( iValue == -1 ) iValue = 0xFF; // convert char to byte
|
||||
_MSG_WriteBits( &sv.multicast, (int)iValue, svgame.msg_name, NET_BYTE, __FILE__, __LINE__ );
|
||||
BF_WriteByte( &sv.multicast, iValue );
|
||||
svgame.msg_realsize++;
|
||||
}
|
||||
|
||||
|
@ -2021,7 +2024,7 @@ pfnWriteChar
|
|||
*/
|
||||
void pfnWriteChar( int iValue )
|
||||
{
|
||||
_MSG_WriteBits( &sv.multicast, (int)iValue, svgame.msg_name, NET_CHAR, __FILE__, __LINE__ );
|
||||
BF_WriteChar( &sv.multicast, iValue );
|
||||
svgame.msg_realsize++;
|
||||
}
|
||||
|
||||
|
@ -2033,7 +2036,7 @@ pfnWriteShort
|
|||
*/
|
||||
void pfnWriteShort( int iValue )
|
||||
{
|
||||
_MSG_WriteBits( &sv.multicast, (int)iValue, svgame.msg_name, NET_SHORT, __FILE__, __LINE__ );
|
||||
BF_WriteShort( &sv.multicast, iValue );
|
||||
svgame.msg_realsize += 2;
|
||||
}
|
||||
|
||||
|
@ -2045,7 +2048,7 @@ pfnWriteLong
|
|||
*/
|
||||
void pfnWriteLong( int iValue )
|
||||
{
|
||||
_MSG_WriteBits( &sv.multicast, (int)iValue, svgame.msg_name, NET_LONG, __FILE__, __LINE__ );
|
||||
BF_WriteLong( &sv.multicast, iValue );
|
||||
svgame.msg_realsize += 4;
|
||||
}
|
||||
|
||||
|
@ -2057,7 +2060,7 @@ pfnWriteAngle
|
|||
*/
|
||||
void pfnWriteAngle( float flValue )
|
||||
{
|
||||
MSG_WriteAngle16( &sv.multicast, flValue );
|
||||
BF_WriteBitAngle( &sv.multicast, flValue, 16 );
|
||||
svgame.msg_realsize += 2;
|
||||
}
|
||||
|
||||
|
@ -2069,10 +2072,7 @@ pfnWriteCoord
|
|||
*/
|
||||
void pfnWriteCoord( float flValue )
|
||||
{
|
||||
ftol_t dat;
|
||||
|
||||
dat.f = flValue;
|
||||
_MSG_WriteBits( &sv.multicast, dat.l, svgame.msg_name, NET_FLOAT, __FILE__, __LINE__ );
|
||||
BF_WriteFloat( &sv.multicast, flValue );
|
||||
svgame.msg_realsize += 4;
|
||||
}
|
||||
|
||||
|
@ -2084,11 +2084,12 @@ pfnWriteString
|
|||
*/
|
||||
void pfnWriteString( const char *sz )
|
||||
{
|
||||
int cur_size = sv.multicast.cursize;
|
||||
int cur_size = BF_GetNumBytesWritten( &sv.multicast );
|
||||
int total_size;
|
||||
|
||||
MSG_WriteStringLine( &sv.multicast, sz ); // allow \n, \r, \t
|
||||
total_size = sv.multicast.cursize - cur_size;
|
||||
// FIXME: replace with BF_WriteStringLine
|
||||
BF_WriteString( &sv.multicast, sz ); // allow \n, \r, \t
|
||||
total_size = BF_GetNumBytesWritten( &sv.multicast ) - cur_size;
|
||||
|
||||
// NOTE: some messages with constant string length can be marked as known sized
|
||||
svgame.msg_realsize += total_size;
|
||||
|
@ -2103,8 +2104,8 @@ pfnWriteEntity
|
|||
void pfnWriteEntity( int iValue )
|
||||
{
|
||||
if( iValue < 0 || iValue >= svgame.globals->numEntities )
|
||||
Host_Error( "MSG_WriteEntity: invalid entnumber %i\n", iValue );
|
||||
MSG_WriteShort( &sv.multicast, iValue );
|
||||
Host_Error( "BF_WriteEntity: invalid entnumber %i\n", iValue );
|
||||
BF_WriteShort( &sv.multicast, iValue );
|
||||
svgame.msg_realsize += 2;
|
||||
}
|
||||
|
||||
|
@ -2338,10 +2339,10 @@ int pfnRegUserMsg( const char *pszName, int iSize )
|
|||
|
||||
if( sv.state == ss_active )
|
||||
{
|
||||
MSG_WriteByte( &sv.multicast, svc_usermessage );
|
||||
MSG_WriteString( &sv.multicast, pszName );
|
||||
MSG_WriteByte( &sv.multicast, i );
|
||||
MSG_WriteByte( &sv.multicast, (byte)iSize );
|
||||
BF_WriteByte( &sv.multicast, svc_usermessage );
|
||||
BF_WriteString( &sv.multicast, pszName );
|
||||
BF_WriteByte( &sv.multicast, i );
|
||||
BF_WriteByte( &sv.multicast, (byte)iSize );
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
}
|
||||
return i;
|
||||
|
@ -2437,8 +2438,8 @@ void pfnClientPrintf( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg )
|
|||
break;
|
||||
case print_center:
|
||||
if( fake ) return;
|
||||
MSG_Begin( svc_centerprint );
|
||||
MSG_WriteString( &sv.multicast, szMsg );
|
||||
BF_WriteByte( &sv.multicast, svc_centerprint );
|
||||
BF_WriteString( &sv.multicast, szMsg );
|
||||
MSG_Send( MSG_ONE, NULL, client->edict );
|
||||
break;
|
||||
}
|
||||
|
@ -2539,9 +2540,9 @@ void pfnCrosshairAngle( const edict_t *pClient, float pitch, float yaw )
|
|||
// fakeclients ignore it silently
|
||||
if( pClient->v.flags & FL_FAKECLIENT ) return;
|
||||
|
||||
MSG_Begin( svc_crosshairangle );
|
||||
MSG_WriteAngle8( &sv.multicast, pitch );
|
||||
MSG_WriteAngle8( &sv.multicast, yaw );
|
||||
BF_WriteByte( &sv.multicast, svc_crosshairangle );
|
||||
BF_WriteBitAngle( &sv.multicast, pitch, 8 );
|
||||
BF_WriteBitAngle( &sv.multicast, yaw, 8 );
|
||||
MSG_Send( MSG_ONE, vec3_origin, pClient );
|
||||
}
|
||||
|
||||
|
@ -2580,8 +2581,8 @@ void pfnSetView( const edict_t *pClient, const edict_t *pViewent )
|
|||
// fakeclients ignore to send client message
|
||||
if( pClient->v.flags & FL_FAKECLIENT ) return;
|
||||
|
||||
MSG_WriteByte( &client->netchan.message, svc_setview );
|
||||
MSG_WriteWord( &client->netchan.message, NUM_FOR_EDICT( pViewent ));
|
||||
BF_WriteByte( &client->netchan.message, svc_setview );
|
||||
BF_WriteWord( &client->netchan.message, NUM_FOR_EDICT( pViewent ));
|
||||
MSG_Send( MSG_ONE, NULL, client->edict );
|
||||
}
|
||||
|
||||
|
@ -2710,11 +2711,11 @@ void pfnFadeClientVolume( const edict_t *pEdict, float fadePercent, float fadeOu
|
|||
return;
|
||||
}
|
||||
|
||||
MSG_WriteByte( &sv.multicast, svc_soundfade );
|
||||
MSG_WriteFloat( &sv.multicast, fadePercent );
|
||||
MSG_WriteFloat( &sv.multicast, fadeOutSeconds );
|
||||
MSG_WriteFloat( &sv.multicast, holdTime );
|
||||
MSG_WriteFloat( &sv.multicast, fadeInSeconds );
|
||||
BF_WriteByte( &sv.multicast, svc_soundfade );
|
||||
BF_WriteFloat( &sv.multicast, fadePercent );
|
||||
BF_WriteFloat( &sv.multicast, fadeOutSeconds );
|
||||
BF_WriteFloat( &sv.multicast, holdTime );
|
||||
BF_WriteFloat( &sv.multicast, fadeInSeconds );
|
||||
MSG_Send( MSG_ONE, NULL, cl->edict );
|
||||
}
|
||||
|
||||
|
@ -2778,9 +2779,10 @@ void pfnRunPlayerMove( edict_t *pClient, const float *v_angle, float fmove, floa
|
|||
cmd.upmove = upmove;
|
||||
cmd.buttons = buttons;
|
||||
cmd.impulse = impulse;
|
||||
cmd.random_seed = Com_RandomLong( 0, 0x7fffffff ); // full range
|
||||
cmd.msec = msec;
|
||||
|
||||
cl->random_seed = Com_RandomLong( 0, 0x7fffffff ); // full range
|
||||
|
||||
SV_PreRunCmd( cl, &cmd );
|
||||
SV_RunCmd( cl, &cmd );
|
||||
SV_PostRunCmd( cl );
|
||||
|
@ -3088,7 +3090,7 @@ static void pfnPlaybackEvent( int flags, const edict_t *pInvoker, word eventinde
|
|||
info.flags = 0; // server ignore flags
|
||||
|
||||
// skipping queue, write in reliable datagram
|
||||
MSG_WriteByte( &cl->reliable, svc_event_reliable );
|
||||
BF_WriteByte( &cl->reliable, svc_event_reliable );
|
||||
SV_PlaybackEvent( &cl->reliable, &info );
|
||||
continue;
|
||||
}
|
||||
|
@ -3740,6 +3742,8 @@ void SV_UnloadProgs( void )
|
|||
{
|
||||
SV_DeactivateServer ();
|
||||
|
||||
Delta_Shutdown ();
|
||||
|
||||
svgame.dllFuncs.pfnGameShutdown ();
|
||||
|
||||
if( sys_sharedstrings->integer )
|
||||
|
@ -3831,6 +3835,8 @@ bool SV_LoadProgs( const char *name )
|
|||
// initialize pm_shared
|
||||
SV_InitClientMove();
|
||||
|
||||
Delta_Init ();
|
||||
|
||||
// fire once
|
||||
MsgDev( D_INFO, "Dll loaded for mod %s\n", svgame.dllFuncs.pfnGetGameDescription() );
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
#include "protocol.h"
|
||||
|
||||
int SV_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
|
||||
|
||||
|
@ -40,10 +41,10 @@ int SV_FindIndex( const char *name, int start, int end, bool create )
|
|||
if( sv.state != ss_loading )
|
||||
{
|
||||
// send the update to everyone
|
||||
MSG_Clear( &sv.multicast );
|
||||
MSG_Begin( svc_configstring );
|
||||
MSG_WriteShort( &sv.multicast, start + i );
|
||||
MSG_WriteString( &sv.multicast, name );
|
||||
BF_Clear( &sv.multicast );
|
||||
BF_WriteByte( &sv.multicast, svc_configstring );
|
||||
BF_WriteShort( &sv.multicast, start + i );
|
||||
BF_WriteString( &sv.multicast, name );
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
}
|
||||
return i;
|
||||
|
@ -315,8 +316,8 @@ bool SV_SpawnServer( const char *mapname, const char *startspot )
|
|||
sv.time = 1000; // server spawn time it's always 1.0 second
|
||||
|
||||
// initialize buffers
|
||||
MSG_Init( &sv.multicast, sv.multicast_buf, sizeof( sv.multicast_buf ));
|
||||
MSG_Init( &sv.signon, sv.signon_buf, sizeof( sv.signon_buf ));
|
||||
BF_Init( &sv.multicast, "Multicast", sv.multicast_buf, sizeof( sv.multicast_buf ));
|
||||
BF_Init( &sv.signon, "Signon", sv.signon_buf, sizeof( sv.signon_buf ));
|
||||
|
||||
// leave slots at start for clients only
|
||||
for( i = 0; i < sv_maxclients->integer; i++ )
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "server.h"
|
||||
#include "protocol.h"
|
||||
|
||||
#define HEARTBEAT_SECONDS (300 * 1000) // 300 seconds
|
||||
|
||||
|
@ -230,9 +231,9 @@ void SV_UpdateMovevars( void )
|
|||
svgame.movevars.rollangle = sv_rollangle->value;
|
||||
svgame.movevars.rollspeed = sv_rollspeed->value;
|
||||
|
||||
MSG_Clear( &sv.multicast );
|
||||
BF_Clear( &sv.multicast );
|
||||
|
||||
if( MSG_WriteDeltaMovevars( &sv.multicast, &svgame.oldmovevars, &svgame.movevars ))
|
||||
if( BF_WriteDeltaMovevars( &sv.multicast, &svgame.oldmovevars, &svgame.movevars ))
|
||||
{
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
Mem_Copy( &svgame.oldmovevars, &svgame.movevars, sizeof( movevars_t )); // oldstate changed
|
||||
|
@ -246,9 +247,9 @@ void pfnUpdateServerInfo( const char *szKey, const char *szValue, const char *un
|
|||
|
||||
if( !cv || !cv->modified ) return; // this cvar not changed
|
||||
|
||||
MSG_WriteByte( &sv.multicast, svc_serverinfo );
|
||||
MSG_WriteString( &sv.multicast, szKey );
|
||||
MSG_WriteString( &sv.multicast, szValue );
|
||||
BF_WriteByte( &sv.multicast, svc_serverinfo );
|
||||
BF_WriteString( &sv.multicast, szKey );
|
||||
BF_WriteString( &sv.multicast, szValue );
|
||||
MSG_Send( MSG_ALL, vec3_origin, NULL );
|
||||
cv->modified = false; // reset state
|
||||
}
|
||||
|
@ -295,14 +296,15 @@ SV_ReadPackets
|
|||
*/
|
||||
void SV_ReadPackets( void )
|
||||
{
|
||||
int i;
|
||||
sv_client_t *cl;
|
||||
int qport;
|
||||
int i, qport, curSize;
|
||||
|
||||
while( NET_GetPacket( NS_SERVER, &net_from, net_message.data, &net_message.cursize ))
|
||||
while( NET_GetPacket( NS_SERVER, &net_from, net_message_buffer, &curSize ))
|
||||
{
|
||||
BF_Init( &net_message, "ClientPacket", net_message_buffer, curSize );
|
||||
|
||||
// check for connectionless packet (0xffffffff) first
|
||||
if( net_message.cursize >= 4 && *(int *)net_message.data == -1 )
|
||||
if( BF_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
|
||||
{
|
||||
SV_ConnectionlessPacket( net_from, &net_message );
|
||||
continue;
|
||||
|
@ -310,10 +312,10 @@ void SV_ReadPackets( void )
|
|||
|
||||
// read the qport out of the message so we can fix up
|
||||
// stupid address translating routers
|
||||
MSG_BeginReading( &net_message );
|
||||
MSG_ReadLong( &net_message ); // sequence number
|
||||
MSG_ReadLong( &net_message ); // sequence number
|
||||
qport = (int)MSG_ReadShort( &net_message ) & 0xffff;
|
||||
BF_Clear( &net_message );
|
||||
BF_ReadLong( &net_message ); // sequence number
|
||||
BF_ReadLong( &net_message ); // sequence number
|
||||
qport = (int)BF_ReadShort( &net_message ) & 0xffff;
|
||||
|
||||
// check for packets from connected clients
|
||||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
|
@ -680,7 +682,7 @@ void SV_Init( void )
|
|||
sv_reconnect_limit = Cvar_Get ("sv_reconnect_limit", "3", CVAR_ARCHIVE, "max reconnect attempts" );
|
||||
|
||||
SV_ClearSaveDir (); // delete all temporary *.hl files
|
||||
MSG_Init( &net_message, net_message_buffer, sizeof( net_message_buffer ));
|
||||
BF_Init( &net_message, "NetMessage", net_message_buffer, sizeof( net_message_buffer ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -697,34 +699,34 @@ void SV_FinalMessage( char *message, bool reconnect )
|
|||
{
|
||||
sv_client_t *cl;
|
||||
byte msg_buf[MAX_MSGLEN];
|
||||
sizebuf_t msg;
|
||||
bitbuf_t msg;
|
||||
int i;
|
||||
|
||||
MSG_Init( &msg, msg_buf, sizeof( msg_buf ));
|
||||
MSG_WriteByte( &msg, svc_print );
|
||||
MSG_WriteByte( &msg, PRINT_HIGH );
|
||||
MSG_WriteString( &msg, message );
|
||||
BF_Init( &msg, "FinalMessage", msg_buf, sizeof( msg_buf ));
|
||||
BF_WriteByte( &msg, svc_print );
|
||||
BF_WriteByte( &msg, PRINT_HIGH );
|
||||
BF_WriteString( &msg, message );
|
||||
|
||||
if( reconnect )
|
||||
{
|
||||
if( sv.loadgame || sv_maxclients->integer > 1 )
|
||||
MSG_WriteByte( &msg, svc_changing );
|
||||
else MSG_WriteByte( &msg, svc_reconnect );
|
||||
BF_WriteByte( &msg, svc_changing );
|
||||
else BF_WriteByte( &msg, svc_reconnect );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteByte( &msg, svc_disconnect );
|
||||
BF_WriteByte( &msg, svc_disconnect );
|
||||
}
|
||||
|
||||
// send it twice
|
||||
// stagger the packets to crutch operating system limited buffers
|
||||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
if( cl->state >= cs_connected && !(cl->edict && cl->edict->v.flags & FL_FAKECLIENT ))
|
||||
Netchan_Transmit( &cl->netchan, msg.cursize, msg.data );
|
||||
Netchan_Transmit( &cl->netchan, BF_GetNumBytesWritten( &msg ), BF_GetData( &msg ));
|
||||
|
||||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
if( cl->state >= cs_connected && !(cl->edict && cl->edict->v.flags & FL_FAKECLIENT ))
|
||||
Netchan_Transmit( &cl->netchan, msg.cursize, msg.data );
|
||||
Netchan_Transmit( &cl->netchan, BF_GetNumBytesWritten( &msg ), BF_GetData( &msg ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "common.h"
|
||||
#include "mathlib.h"
|
||||
#include "matrix_lib.h"
|
||||
#include "protocol.h"
|
||||
#include "server.h"
|
||||
#include "const.h"
|
||||
#include "pm_defs.h"
|
||||
|
@ -337,9 +338,9 @@ static void PM_ClientPrintf( int index, char *fmt, ... )
|
|||
com.vsprintf( string, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
MSG_WriteByte( &cl->netchan.message, svc_print );
|
||||
MSG_WriteByte( &cl->netchan.message, PRINT_HIGH );
|
||||
MSG_WriteString( &cl->netchan.message, string );
|
||||
BF_WriteByte( &cl->netchan.message, svc_print );
|
||||
BF_WriteByte( &cl->netchan.message, PRINT_HIGH );
|
||||
BF_WriteString( &cl->netchan.message, string );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -589,7 +590,7 @@ void SV_InitClientMove( void )
|
|||
void SV_PreRunCmd( sv_client_t *cl, usercmd_t *ucmd )
|
||||
{
|
||||
svgame.pmove->runfuncs = true;
|
||||
svgame.dllFuncs.pfnCmdStart( cl->edict, ucmd, ucmd->random_seed );
|
||||
svgame.dllFuncs.pfnCmdStart( cl->edict, ucmd, cl->random_seed );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1747,9 +1747,9 @@ void SV_SaveGame( const char *pName )
|
|||
{
|
||||
const char *pMsg = "GAMESAVED"; // defined in titles.txt
|
||||
|
||||
MSG_Begin( svgame.gmsgHudText );
|
||||
MSG_WriteByte( &sv.multicast, com.strlen( pMsg ) + 1 );
|
||||
MSG_WriteString( &sv.multicast, pMsg );
|
||||
BF_WriteByte( &sv.multicast, svgame.gmsgHudText );
|
||||
BF_WriteByte( &sv.multicast, com.strlen( pMsg ) + 1 );
|
||||
BF_WriteString( &sv.multicast, pMsg );
|
||||
MSG_Send( MSG_ONE, NULL, EDICT_NUM( 1 ));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,6 +132,9 @@ static void UI_Controls_ParseKeysList( void )
|
|||
|
||||
if( !afile )
|
||||
{
|
||||
for( ; i < MAX_KEYS; i++ ) uiControls.keysDescriptionPtr[i] = NULL;
|
||||
uiControls.keysList.itemNames = (const char **)uiControls.keysDescriptionPtr;
|
||||
|
||||
ALERT( at_error, "UI_Parse_KeysList: kb_act.lst not found\n" );
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
// color packs
|
||||
typedef struct { uint b:5; uint g:6; uint r:5; } color16;
|
||||
typedef struct { byte r:8; byte g:8; byte b:8; } color24;
|
||||
typedef struct { byte r; byte g; byte b; byte a; } color32;
|
||||
|
||||
// cubemap hints
|
||||
|
|
|
@ -163,39 +163,41 @@ size_t com_strncat(char *dst, const char *src, size_t size)
|
|||
return(dlen + (s - src)); // count does not include NULL
|
||||
}
|
||||
|
||||
size_t com_strcat(char *dst, const char *src )
|
||||
size_t com_strcat( char *dst, const char *src )
|
||||
{
|
||||
return com_strncat( dst, src, 99999 );
|
||||
}
|
||||
|
||||
size_t com_strncpy(char *dst, const char *src, size_t size)
|
||||
size_t com_strncpy( char *dst, const char *src, size_t size )
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = size;
|
||||
|
||||
if(!dst || !src || !size) return 0;
|
||||
if( !dst || !src || !size )
|
||||
return 0;
|
||||
|
||||
// copy as many bytes as will fit
|
||||
if (n != 0 && --n != 0)
|
||||
if( n != 0 && --n != 0 )
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((*d++ = *s++) == 0)
|
||||
if(( *d++ = *s++ ) == 0 )
|
||||
break;
|
||||
} while (--n != 0);
|
||||
} while( --n != 0 );
|
||||
}
|
||||
|
||||
// not enough room in dst, add NULL and traverse rest of src
|
||||
if (n == 0)
|
||||
if( n == 0 )
|
||||
{
|
||||
if (size != 0) *d = '\0'; // NULL-terminate dst
|
||||
while (*s++);
|
||||
if( size != 0 )
|
||||
*d = '\0'; // NULL-terminate dst
|
||||
while( *s++ );
|
||||
}
|
||||
return(s - src - 1); // count does not include NULL
|
||||
return( s - src - 1 ); // count does not include NULL
|
||||
}
|
||||
|
||||
size_t com_strcpy(char *dst, const char *src )
|
||||
size_t com_strcpy( char *dst, const char *src )
|
||||
{
|
||||
return com_strncpy( dst, src, 99999 );
|
||||
}
|
||||
|
|
|
@ -1329,7 +1329,6 @@ addEntity:
|
|||
state->rendermode = pEntity->pev->rendermode; // rendering mode
|
||||
state->renderamt = pEntity->pev->renderamt; // alpha value
|
||||
state->animtime = (int)(1000.0 * pEntity->pev->animtime) * 0.001; // sequence time
|
||||
state->localtime = (int)(1000.0 * pEntity->pev->ltime) * 0.001; // movement time
|
||||
state->scale = pEntity->pev->scale; // shared client and render flags
|
||||
state->movetype = (movetype_t)pEntity->pev->movetype;
|
||||
state->frame = pEntity->pev->frame; // any model current frame
|
||||
|
@ -1337,18 +1336,21 @@ addEntity:
|
|||
state->mins = pEntity->pev->mins;
|
||||
state->maxs = pEntity->pev->maxs;
|
||||
state->flags = pEntity->pev->flags;
|
||||
state->rendercolor = pEntity->pev->rendercolor;
|
||||
state->oldorigin = pEntity->pev->oldorigin;
|
||||
state->colormap = pEntity->pev->colormap; // attachments
|
||||
|
||||
state->rendercolor.r = (byte)pEntity->pev->rendercolor.x;
|
||||
state->rendercolor.g = (byte)pEntity->pev->rendercolor.y;
|
||||
state->rendercolor.b = (byte)pEntity->pev->rendercolor.z;
|
||||
|
||||
if( pEntity->pev->groundentity )
|
||||
state->groundent = ENTINDEX( pEntity->pev->groundentity );
|
||||
else state->groundent = -1;
|
||||
state->onground = ENTINDEX( pEntity->pev->groundentity );
|
||||
else state->onground = 0;
|
||||
|
||||
// translate attached entity
|
||||
if( pEntity->pev->aiment )
|
||||
state->aiment = ENTINDEX( pEntity->pev->aiment );
|
||||
else state->aiment = -1;
|
||||
else state->aiment = 0;
|
||||
|
||||
// studio model sequence
|
||||
if( pEntity->pev->sequence != -1 )
|
||||
|
@ -1370,18 +1372,12 @@ addEntity:
|
|||
pEntity->pev->teleport_time = 0.0f;
|
||||
}
|
||||
|
||||
if( pEntity->pev->viewmodel )
|
||||
state->viewmodel = MODEL_INDEX( STRING( pEntity->pev->viewmodel ));
|
||||
else state->viewmodel = 0;
|
||||
|
||||
if( pEntity->pev->aiment )
|
||||
state->aiment = ENTINDEX( pEntity->pev->aiment );
|
||||
else state->aiment = -1;
|
||||
else state->aiment = 0;
|
||||
|
||||
state->viewoffset = pEntity->pev->view_ofs;
|
||||
state->viewangles = pEntity->pev->v_angle;
|
||||
state->idealpitch = pEntity->pev->idealpitch;
|
||||
state->punch_angles = pEntity->pev->punchangle;
|
||||
state->velocity = pEntity->pev->velocity;
|
||||
state->basevelocity = pEntity->pev->clbasevelocity;
|
||||
state->iStepLeft = pEntity->pev->iStepLeft;
|
||||
|
@ -1393,7 +1389,6 @@ addEntity:
|
|||
if( pEntity->pev->weaponmodel != iStringNull )
|
||||
state->weaponmodel = MODEL_INDEX( STRING( pEntity->pev->weaponmodel ));
|
||||
else state->weaponmodel = 0;
|
||||
state->weapons = pEntity->pev->weapons;
|
||||
state->maxspeed = pEntity->pev->maxspeed;
|
||||
|
||||
// clamp fov
|
||||
|
@ -1420,7 +1415,7 @@ addEntity:
|
|||
// translate StartBeamEntity
|
||||
if( pEntity->pev->owner )
|
||||
state->owner = ENTINDEX( pEntity->pev->owner );
|
||||
else state->owner = -1;
|
||||
else state->owner = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1446,9 +1441,9 @@ void CreateBaseline( entity_state_t *baseline, edict_t *entity, int playermodeli
|
|||
// render information
|
||||
baseline->rendermode = (byte)entity->v.rendermode;
|
||||
baseline->renderamt = (byte)entity->v.renderamt;
|
||||
baseline->rendercolor.x = (byte)entity->v.rendercolor.x;
|
||||
baseline->rendercolor.y = (byte)entity->v.rendercolor.y;
|
||||
baseline->rendercolor.z = (byte)entity->v.rendercolor.z;
|
||||
baseline->rendercolor.r = (byte)entity->v.rendercolor.x;
|
||||
baseline->rendercolor.g = (byte)entity->v.rendercolor.y;
|
||||
baseline->rendercolor.b = (byte)entity->v.rendercolor.z;
|
||||
baseline->renderfx = (byte)entity->v.renderfx;
|
||||
|
||||
baseline->mins = entity->v.mins;
|
||||
|
|
Reference in New Issue