08 Feb 2017

This commit is contained in:
g-cont 2017-02-08 00:00:00 +03:00 committed by Alibek Omarov
parent f340ba92fb
commit aae52e1ca3
15 changed files with 215 additions and 189 deletions

View File

@ -1003,7 +1003,7 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize )
if( !pszName || !*pszName )
Host_Error( "CL_LinkUserMessage: bad message name\n" );
if( svc_num < svc_lastmsg )
if( svc_num <= svc_lastmsg )
Host_Error( "CL_LinkUserMessage: tried to hook a system message \"%s\"\n", svc_strings[svc_num] );
// see if already hooked

View File

@ -31,8 +31,8 @@ const char *svc_strings[256] =
"svc_bad",
"svc_nop",
"svc_disconnect",
"svc_event",
"svc_changing",
"svc_version",
"svc_setview",
"svc_sound",
"svc_time",
@ -45,7 +45,7 @@ const char *svc_strings[256] =
"svc_deltatable",
"svc_clientdata",
"svc_stopsound",
"svc_updatepings",
"svc_pings",
"svc_particle",
"svc_restoresound",
"svc_spawnstatic",
@ -55,14 +55,14 @@ const char *svc_strings[256] =
"svc_setpause",
"svc_signonnum",
"svc_centerprint",
"svc_event",
"svc_modelindex",
"svc_soundindex",
"svc_ambientsound",
"svc_intermission",
"svc_modelindex",
"svc_cdtrack",
"svc_serverinfo",
"svc_eventindex",
"svc_cdtrack",
"svc_restore",
"svc_serverinfo",
"svc_weaponanim",
"svc_bspdecal",
"svc_roomtype",
@ -73,25 +73,20 @@ const char *svc_strings[256] =
"svc_chokecount",
"svc_resourcelist",
"svc_deltamovevars",
"svc_resourcerequest",
"svc_customization",
"svc_unused46",
"svc_crosshairangle",
"svc_soundfade",
"svc_unused49",
"svc_unused50",
"svc_filetxferfailed",
"svc_hltv",
"svc_director",
"svc_studiodecal",
"svc_unused53",
"svc_voicedata",
"svc_unused54",
"svc_unused55",
"svc_unused56",
"svc_resourcelocation",
"svc_querycvarvalue",
"svc_querycvarvalue2",
"svc_unused59",
"svc_unused60",
"svc_unused61",
"svc_unused62",
"svc_unused63",
};
typedef struct
@ -118,12 +113,12 @@ const char *CL_MsgInfo( int cmd )
Q_strcpy( sz, "???" );
if( cmd >= 0 && cmd < svc_lastmsg )
if( cmd >= 0 && cmd <= svc_lastmsg )
{
// get engine message name
Q_strncpy( sz, svc_strings[cmd], sizeof( sz ));
}
else if( cmd >= svc_lastmsg && cmd < ( svc_lastmsg + MAX_USER_MESSAGES ))
else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES ))
{
int i;
@ -244,7 +239,7 @@ CL_ParseSoundPacket
==================
*/
void CL_ParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
void CL_ParseSoundPacket( sizebuf_t *msg )
{
vec3_t pos;
int chan, sound;
@ -252,11 +247,9 @@ void CL_ParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
int flags, pitch, entnum;
sound_t handle = 0;
flags = MSG_ReadWord( msg );
if( flags & SND_LARGE_INDEX )
sound = MSG_ReadWord( msg );
else sound = MSG_ReadByte( msg );
chan = MSG_ReadByte( msg );
flags = MSG_ReadUBitLong( msg, MAX_SND_FLAGS_BITS );
sound = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
chan = MSG_ReadUBitLong( msg, MAX_SND_CHAN_BITS );
if( flags & SND_VOLUME )
volume = (float)MSG_ReadByte( msg ) / 255.0f;
@ -271,7 +264,7 @@ void CL_ParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
else pitch = PITCH_NORM;
// entity reletive
entnum = MSG_ReadWord( msg );
entnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
@ -280,15 +273,21 @@ void CL_ParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
{
char sentenceName[32];
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
if( flags & SND_SEQUENCE )
Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound );
else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
if( !cl.audio_prepped )
{
MsgDev( D_WARN, "CL_StartSoundPacket: ignore sound message: too early\n" );
return; // too early
}
if( is_ambient )
if( chan == CHAN_STATIC )
{
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
}
@ -314,11 +313,9 @@ void CL_ParseRestoreSoundPacket( sizebuf_t *msg )
int wordIndex;
sound_t handle = 0;
flags = MSG_ReadWord( msg );
if( flags & SND_LARGE_INDEX )
sound = MSG_ReadWord( msg );
else sound = MSG_ReadByte( msg );
chan = MSG_ReadByte( msg );
flags = MSG_ReadUBitLong( msg, MAX_SND_FLAGS_BITS );
sound = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
chan = MSG_ReadUBitLong( msg, MAX_SND_CHAN_BITS );
if( flags & SND_VOLUME )
volume = (float)MSG_ReadByte( msg ) / 255.0f;
@ -332,26 +329,36 @@ void CL_ParseRestoreSoundPacket( sizebuf_t *msg )
pitch = MSG_ReadByte( msg );
else pitch = PITCH_NORM;
// entity reletive
entnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
if( flags & SND_SENTENCE )
{
char sentenceName[32];
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
if( flags & SND_SEQUENCE )
Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound );
else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
// entity reletive
entnum = MSG_ReadWord( msg );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
wordIndex = MSG_ReadByte( msg );
// 16 bytes here
MSG_ReadBytes( msg, &samplePos, sizeof( samplePos ));
MSG_ReadBytes( msg, &forcedEnd, sizeof( forcedEnd ));
if( !cl.audio_prepped )
{
MsgDev( D_WARN, "CL_RestoreSoundPacket: ignore sound message: too early\n" );
return; // too early
}
S_RestoreSound( pos, entnum, chan, handle, volume, attn, pitch, flags, samplePos, forcedEnd, wordIndex );
}
@ -1081,7 +1088,7 @@ void CL_UpdateUserPings( sizebuf_t *msg )
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
if( slot >= MAX_CLIENTS )
Host_Error( "CL_ParseServerMessage: svc_updatepings > MAX_CLIENTS\n" );
Host_Error( "CL_ParseServerMessage: svc_pings > MAX_CLIENTS\n" );
player = &cl.players[slot];
player->ping = MSG_ReadUBitLong( msg, 12 );
@ -1407,7 +1414,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
byte pbuf[256]; // message can't be larger than 255 bytes
// NOTE: any user message is really parse at engine, not in client.dll
if( svc_num < svc_lastmsg || svc_num >= ( MAX_USER_MESSAGES + svc_lastmsg ))
if( svc_num <= svc_lastmsg || svc_num > ( MAX_USER_MESSAGES + svc_lastmsg ))
{
// out or range
Host_Error( "CL_ParseUserMessage: illegible server message %d\n", svc_num );
@ -1549,7 +1556,8 @@ void CL_ParseServerMessage( sizebuf_t *msg )
cl.refdef.viewentity = MSG_ReadWord( msg );
break;
case svc_sound:
CL_ParseSoundPacket( msg, false );
case svc_ambientsound:
CL_ParseSoundPacket( msg );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_time:
@ -1591,7 +1599,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_updatepings:
case svc_pings:
CL_UpdateUserPings( msg );
break;
case svc_usermessage:
@ -1607,10 +1615,6 @@ void CL_ParseServerMessage( sizebuf_t *msg )
case svc_spawnstatic:
CL_ParseStaticEntity( msg );
break;
case svc_ambientsound:
CL_ParseSoundPacket( msg, true );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_crosshairangle:
CL_ParseCrosshairAngle( msg );
break;

View File

@ -275,11 +275,6 @@ typedef struct host_redirect_s
void (*flush)( netadr_t adr, rdtype_t target, char *buffer );
} host_redirect_t;
// local flags (never sending acorss the net)
#define SND_LOCALSOUND (1<<9) // not paused, not looped, for internal use
#define SND_STOP_LOOPING (1<<10) // stop all looping sounds on the entity.
#define SND_FILTER_CLIENT (1<<11) // don't send sound from local player if prediction was enabled
typedef struct
{
char name[64];

View File

@ -18,6 +18,9 @@ GNU General Public License for more details.
#include "net_buffer.h"
#include "mathlib.h"
//#define DEBUG_NET_MESSAGES_SEND
//#define DEBUG_NET_MESSAGES_READ
// precalculated bit masks for WriteUBitLong.
// Using these tables instead of doing the calculations
// gives a 33% speedup in WriteUBitLong.
@ -284,25 +287,25 @@ void MSG_WriteBitFloat( sizebuf_t *sb, float val )
void MSG_WriteCmdExt( sizebuf_t *sb, int cmd, netsrc_t type, const char *name )
{
#ifdef DEBUG_NET_MESSAGES
#ifdef DEBUG_NET_MESSAGES_SEND
if( name != NULL )
{
// get custom name
Msg( "^1sv^7: %s\n", name );
Msg( "^1sv^7 write: %s\n", name );
}
else if( type == NS_SERVER )
{
if( cmd >= 0 && cmd < svc_lastmsg )
if( cmd >= 0 && cmd <= svc_lastmsg )
{
// get engine message name
Msg( "^1sv^7: %s\n", svc_strings[cmd] );
Msg( "^1sv^7 write: %s\n", svc_strings[cmd] );
}
}
else if( type == NS_CLIENT )
{
if( cmd >= 0 && cmd < clc_lastmsg )
if( cmd >= 0 && cmd <= clc_lastmsg )
{
Msg( "^1cl^7: %s\n", clc_strings[cmd] );
Msg( "^1cl^7 write: %s\n", clc_strings[cmd] );
}
}
#endif
@ -530,14 +533,14 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
{
int cmd = MSG_ReadUBitLong( sb, sizeof( byte ) << 3 );
#ifdef DEBUG_NET_MESSAGES
#ifdef DEBUG_NET_MESSAGES_READ
if( type == NS_SERVER )
{
Msg( "^1cl^7: %s\n", CL_MsgInfo( cmd ));
Msg( "^1cl^7 read: %s\n", CL_MsgInfo( cmd ));
}
else if( cmd >= 0 && cmd < clc_lastmsg )
else if( cmd >= 0 && cmd <= clc_lastmsg )
{
Msg( "^1sv^7: %s\n", clc_strings[cmd] );
Msg( "^1sv^7 read: %s\n", clc_strings[cmd] );
}
#endif
return cmd;

View File

@ -18,8 +18,6 @@ GNU General Public License for more details.
#include "features.h"
// #define DEBUG_NET_MESSAGES
/*
==============================================================================

View File

@ -548,8 +548,8 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
{
fragbuf_t *buf;
int chunksize;
int send, pos;
int remaining;
int bits, pos;
int bufferid = 1;
fragbufwaiting_t *wait, *p;
@ -562,23 +562,32 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
wait = (fragbufwaiting_t *)Mem_Alloc( net_mempool, sizeof( fragbufwaiting_t ));
remaining = MSG_GetNumBytesWritten( msg );
pos = 0;
remaining = MSG_GetNumBitsWritten( msg );
chunksize <<= 3; // convert bytes to bits
pos = 0; // current position in bits
while( remaining > 0 )
{
send = Q_min( remaining, chunksize );
remaining -= send;
byte buffer[MAX_MSGLEN];
sizebuf_t temp;
bits = Q_min( remaining, chunksize );
remaining -= bits;
buf = Netchan_AllocFragbuf();
buf->bufferid = bufferid++;
// Copy in data
MSG_Clear( &buf->frag_message );
MSG_WriteBits( &buf->frag_message, msg->pData + pos, send << 3 );
pos += send;
MSG_StartReading( &temp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ), MSG_GetNumBitsWritten( msg ), -1 );
MSG_SeekToBit( &temp, pos );
MSG_ReadBits( &temp, buffer, bits );
MSG_WriteBits( &buf->frag_message, buffer, bits );
Netchan_AddFragbufToTail( wait, buf );
pos += bits;
}
// now add waiting list item to end of buffer queue
@ -1236,7 +1245,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
// if the reliable buffer has gotten too big, queue it at the end of everything and clear out buffer
if( MSG_GetNumBytesWritten( &chan->message ) > MAX_RELIABLE_PAYLOAD )
{
Netchan_CreateFragments( chan, &chan->message );
Netchan_CreateFragments_( chan, &chan->message );
MSG_Clear( &chan->message );
}
}
@ -1621,12 +1630,12 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
MSG_Clear( &pbuf->frag_message );
MSG_StartReading( &temp, msg->pData, MSG_GetMaxBytes( msg ), MSG_GetNumBitsRead( msg ) + frag_offset[i], -1 );
MSG_ReadBits( msg, buffer, bits );
MSG_ReadBits( &temp, buffer, bits );
MSG_WriteBits( &pbuf->frag_message, buffer, bits );
}
else
{
MsgDev( D_ERROR, "Netchan_Process: Couldn't allocate or find buffer %i\n", inbufferid );
MsgDev( D_ERROR, "Netchan_Process: Couldn't find buffer %i\n", inbufferid );
}
// count # of incoming bufs we've queued? are we done?

View File

@ -1501,7 +1501,8 @@ void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to,
{
delta_t *pField;
delta_info_t *dt;
int i;
int i, startBit;
int numChanges = 0;
dt = Delta_FindStruct( "clientdata_t" );
Assert( dt && dt->bInitialized );
@ -1509,14 +1510,24 @@ void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to,
pField = dt->pFields;
Assert( pField != NULL );
startBit = msg->iCurBit;
MSG_WriteOneBit( msg, 1 ); // have clientdata
// activate fields and call custom encode func
Delta_CustomEncode( dt, from, to );
// process fields
for( i = 0; i < dt->numFields; i++, pField++ )
{
Delta_WriteField( msg, pField, from, to, timebase );
if( Delta_WriteField( msg, pField, from, to, timebase ))
numChanges++;
}
if( numChanges ) return; // we have updates
MSG_SeekToBit( msg, startBit );
MSG_WriteOneBit( msg, 0 ); // no changes
}
/*
@ -1540,6 +1551,9 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, f
*to = *from;
if( !MSG_ReadOneBit( msg ))
return; // we have no changes
// process fields
for( i = 0; i < dt->numFields; i++, pField++ )
{

View File

@ -22,8 +22,8 @@ GNU General Public License for more details.
#define svc_bad 0 // immediately crash client when received
#define svc_nop 1 // does nothing
#define svc_disconnect 2 // kick client from server
#define svc_changing 3 // changelevel by server request
#define svc_version 4 // [long] server version
#define svc_event 3 // playback event queue
#define svc_changing 4 // changelevel by server request
#define svc_setview 5 // [short] entity number
#define svc_sound 6 // <see code>
#define svc_time 7 // [float] server time
@ -36,7 +36,7 @@ GNU General Public License for more details.
#define svc_deltatable 14 // [table header][...]
#define svc_clientdata 15 // [...]
#define svc_stopsound 16 // <see code>
#define svc_updatepings 17 // [bit][idx][ping][packet_loss]
#define svc_pings 17 // [bit][idx][ping][packet_loss]
#define svc_particle 18 // [float*3][char*3][byte][byte]
#define svc_restoresound 19 // <see code>
#define svc_spawnstatic 20 // creates a static client entity
@ -46,14 +46,14 @@ GNU General Public License for more details.
#define svc_setpause 24 // [byte] 0 = unpaused, 1 = paused
#define svc_signonnum 25 // [byte] used for the signon sequence
#define svc_centerprint 26 // [string] to put in center of the screen
#define svc_event 27 // playback event queue
#define svc_modelindex 27 // [index][modelpath]
#define svc_soundindex 28 // [index][soundpath]
#define svc_ambientsound 29 // <see code>
#define svc_intermission 30 // empty message (event)
#define svc_modelindex 31 // [index][modelpath]
#define svc_eventindex 31 // [index][eventname]
#define svc_cdtrack 32 // [string] trackname
#define svc_serverinfo 33 // [string] key [string] value
#define svc_eventindex 34 // [index][eventname]
#define svc_restore 33 // [string] savename
#define svc_serverinfo 34 // [string] key [string] value
#define svc_weaponanim 35 // [byte]iAnim [byte]body
#define svc_bspdecal 36 // [float*3][short][short][short]
#define svc_roomtype 37 // [short] room type
@ -64,17 +64,21 @@ GNU General Public License for more details.
#define svc_chokecount 42 // [byte]
#define svc_resourcelist 43 // [short][...]
#define svc_deltamovevars 44 // [movevars_t]
#define svc_customization 45 // <see code>
#define svc_resourcerequest 45 // <see code>
#define svc_customization 46
#define svc_crosshairangle 47 // [byte][byte]
#define svc_soundfade 48 // [float*4] sound fade parms
#define svc_filetxferfailed 49 // [string]
#define svc_hltv 50
#define svc_director 51 // <variable sized>
#define svc_studiodecal 52 // [float*3][float*3][short][short][byte]
#define svc_voicedata 53 // [byte][short][...]
// reserved
// reserved
#define svc_resourcelocation 56 // [string]
#define svc_querycvarvalue 57 // [string]
#define svc_querycvarvalue2 58 // [string][long] (context)
#define svc_lastmsg 64 // start user messages at this point
#define svc_lastmsg 58 // start user messages at this point
// client to server
#define clc_bad 0 // immediately drop client when received
@ -88,7 +92,7 @@ GNU General Public License for more details.
#define clc_voicedata 8
#define clc_requestcvarvalue 9
#define clc_requestcvarvalue2 10
#define clc_lastmsg 11 // end client messages
#define clc_lastmsg 10 // end client messages
#define MAX_VISIBLE_PACKET 1024 // 1024 visible entities per frame (hl1 has 256)
@ -112,22 +116,29 @@ GNU General Public License for more details.
#define MAX_EDICTS (1<<MAX_ENTITY_BITS)// 12 bits = 4096 edicts
#define MAX_CUSTOM 1024 // max custom resources per level
#define MAX_USER_MESSAGES 191 // another 63 messages reserved for engine routines
#define MAX_USER_MESSAGES 197 // another 58 messages reserved for engine routines
#define MAX_DLIGHTS 32 // dynamic lights (rendered per one frame)
#define MAX_ELIGHTS 64 // entity only point lights
#define MAX_LIGHTSTYLES 256 // a byte limit, don't modify
#define MAX_RENDER_DECALS 4096 // max rendering decals per a level
// sound proto
#define MAX_SND_FLAGS_BITS 14
#define MAX_SND_CHAN_BITS 4
// sound flags
#define SND_VOLUME (1<<0) // a scaled byte
#define SND_ATTENUATION (1<<1) // a byte
#define SND_LARGE_INDEX (1<<2) // a send sound as short
#define SND_SEQUENCE (1<<2) // get sentence from a script
#define SND_PITCH (1<<3) // a byte
#define SND_SENTENCE (1<<4) // set if sound num is actually a sentence num
#define SND_STOP (1<<5) // stop the sound
#define SND_CHANGE_VOL (1<<6) // change sound vol
#define SND_CHANGE_PITCH (1<<7) // change sound pitch
#define SND_SPAWNING (1<<8) // we're spawning, used in some cases for ambients (not sent across network)
#define SND_LOCALSOUND (1<<9) // not paused, not looped, for internal use
#define SND_STOP_LOOPING (1<<10) // stop all looping sounds on the entity.
#define SND_FILTER_CLIENT (1<<11) // don't send sound from local player if prediction was enabled
// decal flags
#define FDECAL_PERMANENT 0x01 // This decal should not be removed in favor of any new decals

View File

@ -210,9 +210,9 @@ typedef struct sv_client_s
double cl_updaterate; // client requested updaterate
double timebase; // client timebase
customization_t customization; // player customization linked list
resource_t resource1;
resource_t resource2; // <mapname.res> from client (server downloading)
customization_t customdata; // player customization linked list
resource_t resourcesonhand;
resource_t resourcesneeded; // <mapname.res> from client (server downloading)
usercmd_t lastcmd; // for filling in big drops

View File

@ -1076,6 +1076,7 @@ void SV_PutClientInServer( sv_client_t *cl )
else ent->v.flags = 0;
ent->v.netname = MAKE_STRING( cl->name );
ent->v.colormap = NUM_FOR_EDICT( ent ); // ???
// fisrt entering
svgame.globals->time = sv.time;
@ -1135,7 +1136,9 @@ void SV_PutClientInServer( sv_client_t *cl )
sv_client_t *cur;
int i, viewEnt;
MSG_WriteBits( &cl->netchan.message, MSG_GetData( &sv.signon ), MSG_GetNumBitsWritten( &sv.signon ));
// time to send signon buffer
Netchan_CreateFragments( &cl->netchan, &sv.signon );
Netchan_FragSend( &cl->netchan );
if( cl->pViewEntity )
viewEnt = NUM_FOR_EDICT( cl->pViewEntity );
@ -1379,7 +1382,7 @@ void SV_WriteModels_f( sv_client_t *cl )
start = Q_atoi( Cmd_Argv( 2 ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && start < MAX_MODELS )
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && start < MAX_MODELS )
{
if( sv.model_precache[start][0] )
{
@ -1425,7 +1428,7 @@ void SV_WriteSounds_f( sv_client_t *cl )
start = Q_atoi( Cmd_Argv( 2 ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && start < MAX_SOUNDS )
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && start < MAX_SOUNDS )
{
if( sv.sound_precache[start][0] )
{
@ -1471,7 +1474,7 @@ void SV_WriteEvents_f( sv_client_t *cl )
start = Q_atoi( Cmd_Argv( 2 ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && start < MAX_EVENTS )
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && start < MAX_EVENTS )
{
if( sv.event_precache[start][0] )
{
@ -1517,7 +1520,7 @@ void SV_WriteLightstyles_f( sv_client_t *cl )
start = Q_atoi( Cmd_Argv( 2 ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && start < MAX_LIGHTSTYLES )
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && start < MAX_LIGHTSTYLES )
{
if( sv.lightstyles[start].pattern[0] )
{
@ -1565,7 +1568,7 @@ void SV_UserMessages_f( sv_client_t *cl )
start = Q_atoi( Cmd_Argv( 2 ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && start < MAX_USER_MESSAGES )
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && start < MAX_USER_MESSAGES )
{
message = &svgame.msg[start];
if( message->name[0] )
@ -1616,7 +1619,7 @@ void SV_DeltaInfo_f( sv_client_t *cl )
fieldIndex = Q_atoi( Cmd_Argv( 3 ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && tableIndex < Delta_NumTables( ))
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && tableIndex < Delta_NumTables( ))
{
dt = Delta_FindStructByIndex( tableIndex );
@ -1680,7 +1683,7 @@ void SV_Baselines_f( sv_client_t *cl )
memset( &nullstate, 0, sizeof( nullstate ));
// write a packet full of data
while( MSG_GetNumBytesWritten( &cl->netchan.message ) < ( NET_MAX_PAYLOAD / 2 ) && start < svgame.numEntities )
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_UDP_PACKET ) && start < svgame.numEntities )
{
base = &svs.baselines[start];
if(( !start || base->number ) && ( base->modelindex || base->effects != EF_NODRAW ))
@ -1722,7 +1725,7 @@ void SV_Begin_f( sv_client_t *cl )
SV_PutClientInServer( cl );
// if we are paused, tell the client
// if we are paused, tell the clients
if( sv.paused )
{
MSG_BeginServerCmd( &sv.reliable_datagram, svc_setpause );

View File

@ -150,13 +150,13 @@ void SV_CreateCustomizationList( sv_client_t *cl )
customization_t *pCust, *pNewCust;
int duplicated, lump_count;
cl->customization.pNext = NULL;
cl->customdata.pNext = NULL;
for( pRes = cl->resource1.pNext; pRes != &cl->resource1; pRes = pRes->pNext )
for( pRes = cl->resourcesonhand.pNext; pRes != &cl->resourcesonhand; pRes = pRes->pNext )
{
duplicated = false;
for( pCust = cl->customization.pNext; pCust != NULL; pCust = pCust->pNext )
for( pCust = cl->customdata.pNext; pCust != NULL; pCust = pCust->pNext )
{
if( !memcmp( pCust->resource.rgucMD5_hash, pRes->rgucMD5_hash, 16 ))
{
@ -174,7 +174,7 @@ void SV_CreateCustomizationList( sv_client_t *cl )
// create it.
lump_count = 0;
if( !SV_CreateCustomization( &cl->customization, pRes, -1, 3, &pNewCust, &lump_count ))
if( !SV_CreateCustomization( &cl->customdata, pRes, -1, 3, &pNewCust, &lump_count ))
{
MsgDev( D_WARN, "CreateCustomizationList: ignoring custom decal.\n" );
continue;

View File

@ -413,7 +413,7 @@ void SV_EmitPings( sizebuf_t *msg )
int packet_loss;
int i, ping;
MSG_BeginServerCmd( msg, svc_updatepings );
MSG_BeginServerCmd( msg, svc_pings );
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
{
@ -819,7 +819,7 @@ void SV_SendClientMessages( void )
// If we haven't gotten a message in sv_failuretime seconds, then stop sending messages to this client
// until we get another packet in from the client. This prevents crash/drop and reconnect where they are
// being hosed with "sequenced packet without connection" packets.
if(( host.realtime - cl->netchan.last_received ) > sv_failuretime->value )
if( sv_failuretime->value < ( host.realtime - cl->netchan.last_received ))
ClearBits( cl->flags, FCL_SEND_NET_MESSAGE );
}

View File

@ -403,7 +403,7 @@ void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int en
return;
// this can happens if serialized map contain 4096 static decals...
if( MSG_GetNumBytesLeft( msg ) >= 20 )
if( MSG_GetNumBytesLeft( msg ) < 20 )
return;
// static decals are posters, it's always reliable
@ -437,7 +437,7 @@ void SV_CreateStudioDecal( sizebuf_t *msg, const float *origin, const float *sta
ASSERT( start );
// this can happens if serialized map contain 4096 static decals...
if( MSG_GetNumBytesLeft( msg ) >= 30 )
if( MSG_GetNumBytesLeft( msg ) < 32 )
return;
// static decals are posters, it's always reliable
@ -474,7 +474,7 @@ void SV_CreateStaticEntity( sizebuf_t *msg, sv_static_entity_t *ent )
int index, i;
// this can happens if serialized map contain too many static entities...
if( MSG_GetNumBytesLeft( msg ) >= 64 )
if( MSG_GetNumBytesLeft( msg ) < 64 )
return;
index = SV_ModelIndex( ent->model );
@ -1767,7 +1767,7 @@ SV_BuildSoundMsg
=================
*/
int SV_BuildSoundMsg( edict_t *ent, int chan, const char *samp, int vol, float attn, int flags, int pitch, const vec3_t pos )
int SV_BuildSoundMsg( edict_t *ent, int chan, const char *sample, int vol, float attn, int flags, int pitch, const vec3_t pos )
{
int sound_idx;
int entityIndex;
@ -1780,13 +1780,13 @@ int SV_BuildSoundMsg( edict_t *ent, int chan, const char *samp, int vol, float a
if( attn < 0.0f || attn > 4.0f )
{
MsgDev( D_ERROR, "SV_StartSound: attenuation = %g\n", attn );
MsgDev( D_ERROR, "SV_StartSound: attenuation %g must be in range 0-4\n", attn );
return 0;
}
if( chan < 0 || chan > 7 )
{
MsgDev( D_ERROR, "SV_StartSound: channel = %i\n", chan );
MsgDev( D_ERROR, "SV_StartSound: channel must be in range 0-7\n" );
return 0;
}
@ -1796,36 +1796,30 @@ int SV_BuildSoundMsg( edict_t *ent, int chan, const char *samp, int vol, float a
return 0;
}
if( !samp || !*samp )
if( !sample || !*sample )
{
MsgDev( D_ERROR, "SV_StartSound: passed NULL sample\n" );
return 0;
}
if( samp[0] == '!' && Q_isdigit( samp + 1 ))
if( sample[0] == '!' && Q_isdigit( sample + 1 ))
{
flags |= SND_SENTENCE;
sound_idx = Q_atoi( samp + 1 );
if( sound_idx >= 1536 )
{
MsgDev( D_ERROR, "SV_StartSound: invalid sentence number %s.\n", samp );
return 0;
}
sound_idx = Q_atoi( sample + 1 );
}
else if( samp[0] == '#' && Q_isdigit( samp + 1 ))
else if( sample[0] == '#' && Q_isdigit( sample + 1 ))
{
flags |= SND_SENTENCE;
sound_idx = Q_atoi( samp + 1 ) + 1536;
flags |= SND_SENTENCE|SND_SEQUENCE;
sound_idx = Q_atoi( sample + 1 );
}
else
{
// precache_sound can be used twice: cache sounds when loading
// and return sound index when server is active
sound_idx = SV_SoundIndex( samp );
sound_idx = SV_SoundIndex( sample );
}
if( !ent->v.modelindex || !ent->v.model )
if( !ent || !ent->v.modelindex || !ent->v.model )
entityIndex = 0;
else if( SV_IsValidEdict( ent->v.aiment ))
entityIndex = NUM_FOR_EDICT( ent->v.aiment );
@ -1835,23 +1829,19 @@ int SV_BuildSoundMsg( edict_t *ent, int chan, const char *samp, int vol, float a
if( attn != ATTN_NONE ) flags |= SND_ATTENUATION;
if( pitch != PITCH_NORM ) flags |= SND_PITCH;
if( sound_idx > 255 ) flags |= SND_LARGE_INDEX;
// not sending (because this is out of range)
flags &= ~SND_SPAWNING;
MSG_BeginServerCmd( &sv.multicast, svc_sound );
MSG_WriteWord( &sv.multicast, flags );
if( flags & SND_LARGE_INDEX )
MSG_WriteWord( &sv.multicast, sound_idx );
else MSG_WriteByte( &sv.multicast, sound_idx );
MSG_WriteByte( &sv.multicast, chan );
MSG_WriteUBitLong( &sv.multicast, flags, MAX_SND_FLAGS_BITS );
MSG_WriteUBitLong( &sv.multicast, sound_idx, MAX_SOUND_BITS );
MSG_WriteUBitLong( &sv.multicast, chan, MAX_SND_CHAN_BITS );
if( flags & SND_VOLUME ) MSG_WriteByte( &sv.multicast, vol );
if( flags & SND_ATTENUATION ) MSG_WriteByte( &sv.multicast, attn * 64 );
if( flags & SND_PITCH ) MSG_WriteByte( &sv.multicast, pitch );
MSG_WriteWord( &sv.multicast, entityIndex );
MSG_WriteUBitLong( &sv.multicast, entityIndex, MAX_ENTITY_BITS );
MSG_WriteVec3Coord( &sv.multicast, pos );
return 1;
@ -1915,8 +1905,8 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
}
else if( sample[0] == '#' && Q_isdigit( sample + 1 ))
{
flags |= SND_SENTENCE;
sound_idx = Q_atoi( sample + 1 ) + 1536;
flags |= SND_SENTENCE|SND_SEQUENCE;
sound_idx = Q_atoi( sample + 1 );
}
else
{
@ -1929,24 +1919,20 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
entityIndex = NUM_FOR_EDICT( ent->v.aiment );
else entityIndex = NUM_FOR_EDICT( ent );
if( sound_idx > 255 ) flags |= SND_LARGE_INDEX;
// not sending (because this is out of range)
flags &= ~SND_FILTER_CLIENT;
flags &= ~SND_SPAWNING;
MSG_BeginServerCmd( &sv.multicast, svc_sound );
MSG_WriteWord( &sv.multicast, flags );
if( flags & SND_LARGE_INDEX )
MSG_WriteWord( &sv.multicast, sound_idx );
else MSG_WriteByte( &sv.multicast, sound_idx );
MSG_WriteByte( &sv.multicast, chan );
MSG_WriteUBitLong( &sv.multicast, flags, MAX_SND_FLAGS_BITS );
MSG_WriteUBitLong( &sv.multicast, sound_idx, MAX_SOUND_BITS );
MSG_WriteUBitLong( &sv.multicast, chan, MAX_SND_CHAN_BITS );
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 );
MSG_WriteWord( &sv.multicast, entityIndex );
MSG_WriteUBitLong( &sv.multicast, entityIndex, MAX_ENTITY_BITS );
MSG_WriteVec3Coord( &sv.multicast, origin );
SV_Multicast( msg_dest, origin, NULL, false, filter );
@ -1960,7 +1946,7 @@ pfnEmitAmbientSound
*/
void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vol, float attn, int flags, int pitch )
{
int number = 0, sound_idx;
int entityIndex = 0, sound_idx;
int msg_dest = MSG_PAS_R;
if( !sample ) return;
@ -1987,7 +1973,7 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
else msg_dest = MSG_ALL;
if( SV_IsValidEdict( ent ))
number = NUM_FOR_EDICT( ent );
entityIndex = NUM_FOR_EDICT( ent );
// always sending stop sound command
if( flags & SND_STOP ) msg_dest = MSG_ALL;
@ -1999,8 +1985,8 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
}
else if( sample[0] == '#' && Q_isdigit( sample + 1 ))
{
flags |= SND_SENTENCE;
sound_idx = Q_atoi( sample + 1 ) + 1536;
flags |= SND_SENTENCE|SND_SEQUENCE;
sound_idx = Q_atoi( sample + 1 );
}
else
{
@ -2009,24 +1995,20 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
sound_idx = SV_SoundIndex( sample );
}
if( sound_idx > 255 ) flags |= SND_LARGE_INDEX;
// not sending (because this is out of range)
flags &= ~SND_SPAWNING;
MSG_BeginServerCmd( &sv.multicast, svc_ambientsound );
MSG_WriteWord( &sv.multicast, flags );
if( flags & SND_LARGE_INDEX )
MSG_WriteWord( &sv.multicast, sound_idx );
else MSG_WriteByte( &sv.multicast, sound_idx );
MSG_WriteByte( &sv.multicast, CHAN_STATIC );
MSG_WriteUBitLong( &sv.multicast, flags, MAX_SND_FLAGS_BITS );
MSG_WriteUBitLong( &sv.multicast, sound_idx, MAX_SOUND_BITS );
MSG_WriteUBitLong( &sv.multicast, CHAN_STATIC, MAX_SND_CHAN_BITS );
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 );
// plays from fixed position
MSG_WriteWord( &sv.multicast, number );
MSG_WriteUBitLong( &sv.multicast, entityIndex, MAX_ENTITY_BITS );
MSG_WriteVec3Coord( &sv.multicast, pos );
SV_Multicast( msg_dest, pos, NULL, false, false );
@ -2343,20 +2325,20 @@ void pfnParticleEffect( const float *org, const float *dir, float color, float c
return;
}
if( MSG_GetNumBytesLeft( &sv.datagram ) >= 16 )
{
MSG_BeginServerCmd( &sv.multicast, svc_particle );
MSG_WriteVec3Coord( &sv.multicast, org );
v = bound( -128, dir[0] * 16.0f, 127 );
MSG_WriteChar( &sv.multicast, v );
v = bound( -128, dir[1] * 16.0f, 127 );
MSG_WriteChar( &sv.multicast, v );
v = bound( -128, dir[2] * 16.0f, 127 );
MSG_WriteChar( &sv.multicast, v );
MSG_WriteByte( &sv.multicast, count );
MSG_WriteByte( &sv.multicast, color );
MSG_WriteByte( &sv.multicast, 0 );
}
if( MSG_GetNumBytesLeft( &sv.datagram ) < 16 )
return;
MSG_BeginServerCmd( &sv.multicast, svc_particle );
MSG_WriteVec3Coord( &sv.multicast, org );
v = bound( -128, dir[0] * 16.0f, 127 );
MSG_WriteChar( &sv.multicast, v );
v = bound( -128, dir[1] * 16.0f, 127 );
MSG_WriteChar( &sv.multicast, v );
v = bound( -128, dir[2] * 16.0f, 127 );
MSG_WriteChar( &sv.multicast, v );
MSG_WriteByte( &sv.multicast, count );
MSG_WriteByte( &sv.multicast, color );
MSG_WriteByte( &sv.multicast, 0 );
}
/*
@ -2429,7 +2411,7 @@ void pfnMessageBegin( int msg_dest, int msg_num, const float *pOrigin, edict_t *
// check range
msg_num = bound( svc_bad, msg_num, 255 );
if( msg_num < svc_lastmsg )
if( msg_num <= svc_lastmsg )
{
svgame.msg_index = -msg_num; // this is a system message
svgame.msg_name = svc_strings[msg_num];
@ -2441,7 +2423,7 @@ void pfnMessageBegin( int msg_dest, int msg_num, const float *pOrigin, edict_t *
else
{
// check for existing
for( i = 0; i < MAX_USER_MESSAGES && svgame.msg[i].name[0]; i++ )
for( i = 1; i < MAX_USER_MESSAGES && svgame.msg[i].name[0]; i++ )
{
if( svgame.msg[i].number == msg_num )
break; // found
@ -3060,7 +3042,7 @@ int pfnRegUserMsg( const char *pszName, int iSize )
iSize = bound( -1, iSize, 255 );
// message 0 is reserved for svc_bad
for( i = 0; i < MAX_USER_MESSAGES && svgame.msg[i].name[0]; i++ )
for( i = 1; i < MAX_USER_MESSAGES && svgame.msg[i].name[0]; i++ )
{
// see if already registered
if( !Q_strcmp( svgame.msg[i].name, pszName ))

View File

@ -310,7 +310,7 @@ void SV_ReadPackets( void )
if( Netchan_Process( &cl->netchan, &net_message ))
{
if(( sv_maxclients->integer == 1 && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE )) || cl->state != cs_spawned )
if( sv_maxclients->integer == 1 || cl->state != cs_spawned )
SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); // reply at end of frame
// this is a valid, sequenced packet, so process it
@ -329,7 +329,18 @@ void SV_ReadPackets( void )
if( Netchan_CopyNormalFragments( &cl->netchan, &net_message, &curSize ))
{
MSG_Init( &net_message, "ClientPacket", net_message_buffer, curSize );
SV_ExecuteClientMessage( cl, &net_message );
if( sv_maxclients->integer == 1 || cl->state != cs_spawned )
SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); // reply at end of frame
// this is a valid, sequenced packet, so process it
if( cl->state != cs_zombie )
{
cl->lastmessage = host.realtime; // don't timeout
SV_ExecuteClientMessage( cl, &net_message );
svgame.globals->frametime = sv.frametime;
svgame.globals->time = sv.time;
}
}
if( Netchan_CopyFileFragments( &cl->netchan, &net_message ))

View File

@ -505,7 +505,7 @@ void RestoreSound( soundlist_t *entry )
edict_t *ent;
// this can happens if serialized map contain 4096 static decals...
if( MSG_GetNumBytesLeft( &sv.signon ) >= 20 )
if( MSG_GetNumBytesLeft( &sv.signon ) < 36 )
return;
if( entry->name[0] == '!' && Q_isdigit( entry->name + 1 ))
@ -515,8 +515,8 @@ void RestoreSound( soundlist_t *entry )
}
else if( entry->name[0] == '#' && Q_isdigit( entry->name + 1 ))
{
flags |= SND_SENTENCE;
soundIndex = Q_atoi( entry->name + 1 ) + 1536;
flags |= SND_SENTENCE|SND_SEQUENCE;
soundIndex = Q_atoi( entry->name + 1 );
}
else
{
@ -550,20 +550,16 @@ void RestoreSound( soundlist_t *entry )
if( entry->pitch != PITCH_NORM ) flags |= SND_PITCH;
if( !entry->looping ) flags |= SND_STOP_LOOPING; // just in case
if( soundIndex > 255 ) flags |= SND_LARGE_INDEX;
MSG_BeginServerCmd( &sv.signon, svc_restoresound );
MSG_WriteWord( &sv.signon, flags );
if( flags & SND_LARGE_INDEX )
MSG_WriteWord( &sv.signon, soundIndex );
else MSG_WriteByte( &sv.signon, soundIndex );
MSG_WriteByte( &sv.signon, entry->channel );
MSG_WriteUBitLong( &sv.signon, flags, MAX_SND_FLAGS_BITS );
MSG_WriteUBitLong( &sv.signon, soundIndex, MAX_SOUND_BITS );
MSG_WriteUBitLong( &sv.signon, entry->channel, MAX_SND_CHAN_BITS );
if( flags & SND_VOLUME ) MSG_WriteByte( &sv.signon, entry->volume * 255 );
if( flags & SND_ATTENUATION ) MSG_WriteByte( &sv.signon, entry->attenuation * 64 );
if( flags & SND_PITCH ) MSG_WriteByte( &sv.signon, entry->pitch );
MSG_WriteWord( &sv.signon, entry->entnum );
MSG_WriteUBitLong( &sv.signon, entry->entnum, MAX_ENTITY_BITS );
MSG_WriteVec3Coord( &sv.signon, entry->origin );
MSG_WriteByte( &sv.signon, entry->wordIndex );