本文整理汇总了C++中MSG_WriteDeltaEntity函数的典型用法代码示例。如果您正苦于以下问题:C++ MSG_WriteDeltaEntity函数的具体用法?C++ MSG_WriteDeltaEntity怎么用?C++ MSG_WriteDeltaEntity使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了MSG_WriteDeltaEntity函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SV_EmitPacketEntities
/*
=============
SV_EmitPacketEntities
Writes a delta update of an entityState_t list to the message.
=============
*/
static void SV_EmitPacketEntities( clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg ) {
entityState_t *oldent, *newent;
int oldindex, newindex;
int oldnum, newnum;
int from_num_entities;
// generate the delta update
if ( !from ) {
from_num_entities = 0;
} else {
from_num_entities = from->num_entities;
}
newent = NULL;
oldent = NULL;
newindex = 0;
oldindex = 0;
while ( newindex < to->num_entities || oldindex < from_num_entities ) {
if ( newindex >= to->num_entities ) {
newnum = 9999;
} else {
newent = &svs.snapshotEntities[(to->first_entity+newindex) % svs.numSnapshotEntities];
newnum = newent->number;
}
if ( oldindex >= from_num_entities ) {
oldnum = 9999;
} else {
oldent = &svs.snapshotEntities[(from->first_entity+oldindex) % svs.numSnapshotEntities];
oldnum = oldent->number;
}
if ( newnum == oldnum ) {
// delta update from old position
// because the force parm is qfalse, this will not result
// in any bytes being emited if the entity has not changed at all
MSG_WriteDeltaEntity (msg, oldent, newent, qfalse );
oldindex++;
newindex++;
continue;
}
if ( newnum < oldnum ) {
// this is a new entity, send it from the baseline
MSG_WriteDeltaEntity (msg, &sv.svEntities[newnum].baseline, newent, qtrue );
newindex++;
continue;
}
if ( newnum > oldnum ) {
// the old entity isn't present in the new message
MSG_WriteDeltaEntity (msg, oldent, NULL, qtrue );
oldindex++;
continue;
}
}
MSG_WriteBits( msg, (MAX_GENTITIES-1), GENTITYNUM_BITS ); // end of packetentities
}
示例2: SV_EmitPacketEntities
/*
=============
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 )
{
entity_state_t *oldent, *newent;
int oldindex, newindex;
int oldnum, newnum;
int from_num_entities;
MSG_WriteByte( msg, svc_packetentities );
if( !from ) from_num_entities = 0;
else from_num_entities = from->num_entities;
newent = NULL;
oldent = NULL;
newindex = 0;
oldindex = 0;
while( newindex < to->num_entities || oldindex < from_num_entities )
{
if( newindex >= to->num_entities ) newnum = MAX_ENTNUMBER;
else
{
newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
newnum = newent->number;
}
if( oldindex >= from_num_entities ) oldnum = MAX_ENTNUMBER;
else
{
oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
oldnum = oldent->number;
}
if( newnum == oldnum )
{
// 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 ));
oldindex++;
newindex++;
continue;
}
if( newnum < oldnum )
{
// this is a new entity, send it from the baseline
MSG_WriteDeltaEntity( &svs.baselines[newnum], newent, msg, true, true );
newindex++;
continue;
}
if( newnum > oldnum )
{
// remove from message
MSG_WriteDeltaEntity( oldent, NULL, msg, false, false );
oldindex++;
continue;
}
}
MSG_WriteBits( msg, 0, "svc_packetentities", NET_WORD ); // end of packetentities
}
示例3: SV_Baselines_f
void
SV_Baselines_f(void)
{
int start;
entity_state_t nullstate;
entity_state_t *base;
Com_DPrintf("Baselines() from %s\n", sv_client->name);
if (sv_client->state != cs_connected)
{
Com_Printf("baselines not valid -- already spawned\n");
return;
}
/* handle the case of a level changing while a client was connecting */
if ((int)strtol(Cmd_Argv(1), (char **)NULL, 10) != svs.spawncount)
{
Com_Printf("SV_Baselines_f from different level\n");
SV_New_f();
return;
}
start = (int)strtol(Cmd_Argv(2), (char **)NULL, 10);
memset(&nullstate, 0, sizeof(nullstate));
/* write a packet full of data */
while (sv_client->netchan.message.cursize < MAX_MSGLEN / 2 &&
start < MAX_EDICTS)
{
base = &sv.baselines[start];
if (base->modelindex || base->sound || base->effects)
{
MSG_WriteByte(&sv_client->netchan.message, svc_spawnbaseline);
MSG_WriteDeltaEntity(&nullstate, base,
&sv_client->netchan.message,
true, true);
}
start++;
}
/* send next command */
if (start == MAX_EDICTS)
{
MSG_WriteByte(&sv_client->netchan.message, svc_stufftext);
MSG_WriteString(&sv_client->netchan.message,
va("precache %i\n", svs.spawncount));
}
else
{
MSG_WriteByte(&sv_client->netchan.message, svc_stufftext);
MSG_WriteString(&sv_client->netchan.message,
va("cmd baselines %i %i\n", svs.spawncount, start));
}
}
示例4: demoFramePack
static void demoFramePack( msg_t *msg, const demoFrame_t *newFrame, const demoFrame_t *oldFrame ) {
int i;
/* Full or delta frame marker */
MSG_WriteBits( msg, oldFrame ? 0 : 1, 1 );
MSG_WriteLong( msg, newFrame->serverTime );
/* Add the config strings */
for (i = 0;i<MAX_CONFIGSTRINGS;i++) {
const char *oldString = !oldFrame ? "" : &oldFrame->string.data[oldFrame->string.offsets[i]];
const char *newString = newFrame->string.data + newFrame->string.offsets[i];
if (strcmp( oldString, newString)) {
MSG_WriteShort( msg, i );
MSG_WriteBigString( msg, newString );
}
}
MSG_WriteShort( msg, MAX_CONFIGSTRINGS );
/* Add the playerstates */
for (i=0; i<MAX_CLIENTS; i++) {
const playerState_t *oldPlayer, *newPlayer;
if (!newFrame->clientData[i])
continue;
oldPlayer = (!oldFrame || !oldFrame->clientData[i]) ? &demoNullPlayerState : &oldFrame->clients[i];
newPlayer = &newFrame->clients[i];
MSG_WriteByte( msg, i );
MSG_WriteDeltaPlayerstate( msg, oldPlayer, newPlayer );
}
MSG_WriteByte( msg, MAX_CLIENTS );
/* Add the entities */
for (i=0; i<MAX_GENTITIES-1; i++) {
const entityState_t *oldEntity, *newEntity;
newEntity = &newFrame->entities[i];
if (oldFrame) {
oldEntity = &oldFrame->entities[i];
if (oldEntity->number == (MAX_GENTITIES -1))
oldEntity = 0;
} else {
oldEntity = 0;
}
if (newEntity->number != i || newEntity->number >= (MAX_GENTITIES -1)) {
newEntity = 0;
} else {
if (!oldEntity) {
oldEntity = &demoNullEntityState;
}
}
MSG_WriteDeltaEntity( msg, oldEntity, newEntity, qfalse );
}
MSG_WriteBits( msg, (MAX_GENTITIES-1), GENTITYNUM_BITS );
/* Add the area mask */
MSG_WriteByte( msg, newFrame->areaUsed );
MSG_WriteData( msg, newFrame->areamask, newFrame->areaUsed );
/* Add the command string data */
MSG_WriteLong( msg, newFrame->commandUsed );
MSG_WriteData( msg, newFrame->commandData, newFrame->commandUsed );
}
示例5: SV_SendClientGameState
/*
================
SV_SendClientGameState
Sends the first message from the server to a connected client.
This will be sent on the initial connection and upon each new map load.
It will be resent if the client acknowledges a later message but has
the wrong gamestate.
================
*/
void SV_SendClientGameState( client_t *client ) {
int start;
entityState_t *base, nullstate;
msg_t msg;
byte msgBuffer[MAX_MSGLEN];
Com_DPrintf ("SV_SendGameState() for %s\n", client->name);
client->state = CS_PRIMED;
// when we receive the first packet from the client, we will
// notice that it is from a different serverid and that the
// gamestate message was not just sent, forcing a retransmit
client->gamestateMessageNum = client->netchan.outgoingSequence;
// clear the reliable message list for this client
client->reliableSequence = 0;
client->reliableAcknowledge = 0;
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
// send the gamestate
MSG_WriteByte( &msg, svc_gamestate );
MSG_WriteLong( &msg, client->reliableSequence );
// write the configstrings
for ( start = 0 ; start < MAX_CONFIGSTRINGS ; start++ ) {
if (sv.configstrings[start][0]) {
MSG_WriteByte( &msg, svc_configstring );
MSG_WriteShort( &msg, start );
MSG_WriteString( &msg, sv.configstrings[start] );
}
}
// write the baselines
memset( &nullstate, 0, sizeof( nullstate ) );
for ( start = 0 ; start < MAX_GENTITIES; start++ ) {
base = &sv.svEntities[start].baseline;
if ( !base->number ) {
continue;
}
MSG_WriteByte( &msg, svc_baseline );
MSG_WriteDeltaEntity( &msg, &nullstate, base, qtrue );
}
MSG_WriteByte( &msg, 0 );
// check for overflow
if ( msg.overflowed ) {
Com_Printf ("WARNING: GameState overflowed for %s\n", client->name);
}
// deliver this to the client
SV_SendMessageToClient( &msg, client );
}
示例6: SV_Baselines_f
/*
* SV_Baselines_f
*/
static void SV_Baselines_f( client_t *client )
{
int start;
entity_state_t nullstate;
entity_state_t *base;
Com_DPrintf( "Baselines() from %s\n", client->name );
if( client->state != CS_CONNECTED )
{
Com_Printf( "baselines not valid -- already spawned\n" );
return;
}
// handle the case of a level changing while a client was connecting
if( atoi( Cmd_Argv( 1 ) ) != svs.spawncount )
{
Com_Printf( "SV_Baselines_f from different level\n" );
SV_New_f( client );
return;
}
start = atoi( Cmd_Argv( 2 ) );
if( start < 0 )
start = 0;
memset( &nullstate, 0, sizeof( nullstate ) );
// write a packet full of data
SV_InitClientMessage( client, &tmpMessage, NULL, 0 );
while( tmpMessage.cursize < FRAGMENT_SIZE * 3 && start < MAX_EDICTS )
{
base = &sv.baselines[start];
if( base->modelindex || base->sound || base->effects )
{
MSG_WriteByte( &tmpMessage, svc_spawnbaseline );
MSG_WriteDeltaEntity( &nullstate, base, &tmpMessage, qtrue, qtrue );
}
start++;
}
// send next command
if( start == MAX_EDICTS )
SV_SendServerCommand( client, "precache %i", svs.spawncount );
else
SV_SendServerCommand( client, "cmd baselines %i %i", svs.spawncount, start );
SV_AddReliableCommandsToMessage( client, &tmpMessage );
SV_SendMessageToClient( client, &tmpMessage );
}
示例7: SV_CreateClientGameStateMessage
void SV_CreateClientGameStateMessage( client_t *client, msg_t *msg ) {
int start;
entityState_t *base, nullstate;
// NOTE, MRE: all server->client messages now acknowledge
// let the client know which reliable clientCommands we have received
MSG_WriteLong( msg, client->lastClientCommand );
// send any server commands waiting to be sent first.
// we have to do this cause we send the client->reliableSequence
// with a gamestate and it sets the clc.serverCommandSequence at
// the client side
SV_UpdateServerCommandsToClient( client, msg );
// send the gamestate
MSG_WriteByte( msg, svc_gamestate );
MSG_WriteLong( msg, client->reliableSequence );
// write the configstrings
for ( start = 0 ; start < MAX_CONFIGSTRINGS ; start++ ) {
if (sv.configstrings[start][0]) {
MSG_WriteByte( msg, svc_configstring );
MSG_WriteShort( msg, start );
MSG_WriteBigString( msg, sv.configstrings[start] );
}
}
// write the baselines
Com_Memset( &nullstate, 0, sizeof( nullstate ) );
for ( start = 0 ; start < MAX_GENTITIES; start++ ) {
base = &sv.svEntities[start].baseline;
if ( !base->number ) {
continue;
}
MSG_WriteByte( msg, svc_baseline );
MSG_WriteDeltaEntity( msg, &nullstate, base, qtrue );
}
MSG_WriteByte( msg, svc_EOF );
MSG_WriteLong( msg, client - svs.clients);
// write the checksum feed
MSG_WriteLong( msg, sv.checksumFeed);
// For old RMG system.
MSG_WriteShort ( msg, 0 );
}
示例8: SV_WriteBaselineToClient
/*
==================
SV_WriteBaselineToClient
==================
*/
void SV_WriteBaselineToClient( client_t *client, msg_t *msg ) {
sharedEntityState_t *base;
int start;
if ( !client->needBaseline ) {
return;
}
client->needBaseline = qfalse;
// write the baselines
for ( start = 0 ; start < MAX_GENTITIES; start++ ) {
base = (sharedEntityState_t *)DA_ElementPointer( sv.svEntitiesBaseline, start );
if ( !base->number ) {
continue;
}
MSG_WriteByte( msg, svc_baseline );
MSG_WriteDeltaEntity( msg, NULL, base, qtrue );
}
}
示例9: SV_CreateClientGameStateMessage
void SV_CreateClientGameStateMessage( client_t *client, msg_t *msg, qboolean updateServerCommands ) {
int start;
entityState_t *base, nullstate;
// NOTE, MRE: all server->client messages now acknowledge
// let the client know which reliable clientCommands we have received
MSG_WriteLong( msg, client->lastClientCommand );
if ( updateServerCommands ) {
// send any server commands waiting to be sent first.
// we have to do this cause we send the client->reliableSequence
// with a gamestate and it sets the clc.serverCommandSequence at
// the client side
SV_UpdateServerCommandsToClient( client, msg );
}
// send the gamestate
MSG_WriteByte( msg, svc_gamestate );
MSG_WriteLong( msg, client->reliableSequence );
// write the configstrings
for ( start = 0 ; start < MAX_CONFIGSTRINGS ; start++ ) {
if (sv.configstrings[start][0]) {
MSG_WriteByte( msg, svc_configstring );
MSG_WriteShort( msg, start );
MSG_WriteBigString( msg, sv.configstrings[start] );
}
}
// write the baselines
Com_Memset( &nullstate, 0, sizeof( nullstate ) );
for ( start = 0 ; start < MAX_GENTITIES; start++ ) {
base = &sv.svEntities[start].baseline;
if ( !base->number ) {
continue;
}
MSG_WriteByte( msg, svc_baseline );
MSG_WriteDeltaEntity( msg, &nullstate, base, qtrue );
}
MSG_WriteByte( msg, svc_EOF );
MSG_WriteLong( msg, client - svs.clients);
// write the checksum feed
MSG_WriteLong( msg, sv.checksumFeed);
//rwwRMG - send info for the terrain
if ( TheRandomMissionManager )
{
z_stream zdata;
// Send the height map
memset(&zdata, 0, sizeof(z_stream));
deflateInit ( &zdata, Z_BEST_COMPRESSION );
unsigned char heightmap[15000];
zdata.next_out = (unsigned char*)heightmap;
zdata.avail_out = 15000;
zdata.next_in = TheRandomMissionManager->GetLandScape()->GetHeightMap();
zdata.avail_in = TheRandomMissionManager->GetLandScape()->GetRealArea();
deflate(&zdata, Z_SYNC_FLUSH);
MSG_WriteShort ( msg, (unsigned short)zdata.total_out );
MSG_WriteBits ( msg, 1, 1 );
MSG_WriteData ( msg, heightmap, zdata.total_out);
deflateEnd(&zdata);
// Send the flatten map
memset(&zdata, 0, sizeof(z_stream));
deflateInit ( &zdata, Z_BEST_COMPRESSION );
zdata.next_out = (unsigned char*)heightmap;
zdata.avail_out = 15000;
zdata.next_in = TheRandomMissionManager->GetLandScape()->GetFlattenMap();
zdata.avail_in = TheRandomMissionManager->GetLandScape()->GetRealArea();
deflate(&zdata, Z_SYNC_FLUSH);
MSG_WriteShort ( msg, (unsigned short)zdata.total_out );
MSG_WriteBits ( msg, 1, 1 );
MSG_WriteData ( msg, heightmap, zdata.total_out);
deflateEnd(&zdata);
// Seed is needed for misc ents and noise
MSG_WriteLong ( msg, TheRandomMissionManager->GetLandScape()->get_rand_seed ( ) );
SV_WriteRMGAutomapSymbols ( msg );
}
else
{
MSG_WriteShort ( msg, 0 );
}
}
示例10: SVD_StartDemoFile
/*
Start a server-side demo.
This does it all, create the file and adjust the demo-related
stuff in client_t.
This is mostly ripped from sv_client.c/SV_SendClientGameState
and cl_main.c/CL_Record_f.
*/
static void SVD_StartDemoFile(client_t *client, const char *path)
{
int i, len;
entityState_t *base, nullstate;
msg_t msg;
byte buffer[MAX_MSGLEN];
fileHandle_t file;
Com_DPrintf("SVD_StartDemoFile\n");
assert(!client->demo_recording);
// create the demo file and write the necessary header
file = FS_FOpenFileWrite(path);
assert(file != 0);
MSG_Init(&msg, buffer, sizeof(buffer));
MSG_Bitstream(&msg); // XXX server code doesn't do this, client code does
MSG_WriteLong(&msg, client->lastClientCommand); // TODO: or is it client->reliableSequence?
MSG_WriteByte(&msg, svc_gamestate);
MSG_WriteLong(&msg, client->reliableSequence);
for (i = 0; i < MAX_CONFIGSTRINGS; i++) {
if (sv.configstrings[i][0]) {
MSG_WriteByte(&msg, svc_configstring);
MSG_WriteShort(&msg, i);
MSG_WriteBigString(&msg, sv.configstrings[i]);
}
}
Com_Memset(&nullstate, 0, sizeof(nullstate));
for (i = 0 ; i < MAX_GENTITIES; i++) {
base = &sv.svEntities[i].baseline;
if (!base->number) {
continue;
}
MSG_WriteByte(&msg, svc_baseline);
MSG_WriteDeltaEntity(&msg, &nullstate, base, qtrue);
}
MSG_WriteByte(&msg, svc_EOF);
MSG_WriteLong(&msg, client - svs.clients);
MSG_WriteLong(&msg, sv.checksumFeed);
MSG_WriteByte(&msg, svc_EOF); // XXX server code doesn't do this, SV_Netchan_Transmit adds it!
len = LittleLong(client->netchan.outgoingSequence-1);
FS_Write(&len, 4, file);
len = LittleLong (msg.cursize);
FS_Write(&len, 4, file);
FS_Write(msg.data, msg.cursize, file);
FS_Flush(file);
// adjust client_t to reflect demo started
client->demo_recording = qtrue;
client->demo_file = file;
client->demo_waiting = qtrue;
client->demo_backoff = 1;
client->demo_deltas = 0;
}
示例11: SV_SendClientGameState
/*
================
SV_SendClientGameState
Sends the first message from the server to a connected client.
This will be sent on the initial connection and upon each new map load.
It will be resent if the client acknowledges a later message but has
the wrong gamestate.
================
*/
void SV_SendClientGameState( client_t *client )
{
int start;
entityState_t *base, nullstate;
msg_t msg;
byte msgBuffer[ MAX_MSGLEN ];
Log::Debug( "SV_SendClientGameState() for %s", client->name );
Log::Debug( "Going from CS_CONNECTED to CS_PRIMED for %s", client->name );
client->state = clientState_t::CS_PRIMED;
// when we receive the first packet from the client, we will
// notice that it is from a different serverid and that the
// gamestate message was not just sent, forcing a retransmit
client->gamestateMessageNum = client->netchan.outgoingSequence;
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
// NOTE, MRE: all server->client messages now acknowledge
// let the client know which reliable clientCommands we have received
MSG_WriteLong( &msg, client->lastClientCommand );
// send any server commands waiting to be sent first.
// we have to do this cause we send the client->reliableSequence
// with a gamestate and it sets the clc.serverCommandSequence at
// the client side
SV_UpdateServerCommandsToClient( client, &msg );
// send the gamestate
MSG_WriteByte( &msg, svc_gamestate );
MSG_WriteLong( &msg, client->reliableSequence );
// write the configstrings
for ( start = 0; start < MAX_CONFIGSTRINGS; start++ )
{
if ( sv.configstrings[ start ][ 0 ] )
{
MSG_WriteByte( &msg, svc_configstring );
MSG_WriteShort( &msg, start );
MSG_WriteBigString( &msg, sv.configstrings[ start ] );
}
}
// write the baselines
memset( &nullstate, 0, sizeof( nullstate ) );
for ( start = 0; start < MAX_GENTITIES; start++ )
{
base = &sv.svEntities[ start ].baseline;
if ( !base->number )
{
continue;
}
MSG_WriteByte( &msg, svc_baseline );
MSG_WriteDeltaEntity( &msg, &nullstate, base, true );
}
MSG_WriteByte( &msg, svc_EOF );
MSG_WriteLong( &msg, client - svs.clients );
// write the checksum feed
MSG_WriteLong( &msg, sv.checksumFeed );
// NERVE - SMF - debug info
Log::Debug( "Sending %i bytes in gamestate to client: %li", msg.cursize, ( long )( client - svs.clients ) );
// deliver this to the client
SV_SendMessageToClient( &msg, client );
}
示例12: SV_SendClientGameState
/*
================
SV_SendClientGameState
Sends the first message from the server to a connected client.
This will be sent on the initial connection and upon each new map load.
It will be resent if the client acknowledges a later message but has
the wrong gamestate.
================
*/
void SV_SendClientGameState( client_t *client ) {
int start;
entityState_t *base, nullstate;
msg_t msg;
byte msgBuffer[MAX_MSGLEN];
// MW - my attempt to fix illegible server message errors caused by
// packet fragmentation of initial snapshot.
while(client->state&&client->netchan.unsentFragments)
{
// send additional message fragments if the last message
// was too large to send at once
Com_Printf ("[ISM]SV_SendClientGameState() [2] for %s, writing out old fragments\n", client->name);
SV_Netchan_TransmitNextFragment(&client->netchan);
}
Com_DPrintf ("SV_SendClientGameState() for %s\n", client->name);
Com_DPrintf( "Going from CS_CONNECTED to CS_PRIMED for %s\n", client->name );
client->state = CS_PRIMED;
client->pureAuthentic = 0;
// when we receive the first packet from the client, we will
// notice that it is from a different serverid and that the
// gamestate message was not just sent, forcing a retransmit
client->gamestateMessageNum = client->netchan.outgoingSequence;
MSG_Init( &msg, msgBuffer, sizeof( msgBuffer ) );
// NOTE, MRE: all server->client messages now acknowledge
// let the client know which reliable clientCommands we have received
MSG_WriteLong( &msg, client->lastClientCommand );
// send any server commands waiting to be sent first.
// we have to do this cause we send the client->reliableSequence
// with a gamestate and it sets the clc.serverCommandSequence at
// the client side
SV_UpdateServerCommandsToClient( client, &msg );
// send the gamestate
MSG_WriteByte( &msg, svc_gamestate );
MSG_WriteLong( &msg, client->reliableSequence );
// write the configstrings
for ( start = 0 ; start < MAX_CONFIGSTRINGS ; start++ ) {
if (sv.configstrings[start][0]) {
MSG_WriteByte( &msg, svc_configstring );
MSG_WriteShort( &msg, start );
MSG_WriteBigString( &msg, sv.configstrings[start] );
}
}
// write the baselines
Com_Memset( &nullstate, 0, sizeof( nullstate ) );
for ( start = 0 ; start < MAX_GENTITIES; start++ ) {
base = &sv.svEntities[start].baseline;
if ( !base->number ) {
continue;
}
MSG_WriteByte( &msg, svc_baseline );
MSG_WriteDeltaEntity( &msg, &nullstate, base, qtrue );
}
MSG_WriteByte( &msg, svc_EOF );
MSG_WriteLong( &msg, client - svs.clients);
// write the checksum feed
MSG_WriteLong( &msg, sv.checksumFeed);
//rwwRMG - send info for the terrain
if ( TheRandomMissionManager )
{
z_stream zdata;
// Send the height map
memset(&zdata, 0, sizeof(z_stream));
deflateInit ( &zdata, Z_MAX_COMPRESSION );
unsigned char heightmap[15000];
zdata.next_out = (unsigned char*)heightmap;
zdata.avail_out = 15000;
zdata.next_in = TheRandomMissionManager->GetLandScape()->GetHeightMap();
zdata.avail_in = TheRandomMissionManager->GetLandScape()->GetRealArea();
deflate(&zdata, Z_SYNC_FLUSH);
MSG_WriteShort ( &msg, (unsigned short)zdata.total_out );
MSG_WriteBits ( &msg, 1, 1 );
MSG_WriteData ( &msg, heightmap, zdata.total_out);
//.........这里部分代码省略.........
示例13: SV_Baselines_f
/*
==================
SV_Baselines_f
==================
*/
void SV_Baselines_f (void)
{
int startPos, start;
int maxLen; // Knightmare added
entity_state_t nullstate;
entity_state_t *base;
Com_DPrintf ("Baselines() from %s\n", sv_client->name);
if (sv_client->state != cs_connected)
{
Com_Printf ("baselines not valid -- already spawned\n");
return;
}
// handle the case of a level changing while a client was connecting
if ( atoi(Cmd_Argv(1)) != svs.spawncount )
{
Com_Printf ("SV_Baselines_f from different level\n");
SV_New_f ();
return;
}
// Knightmare- use sv_baselines_maxlen for proper bounding in multiplayer
maxLen = SV_SetMaxBaselinesSize();
// start = atoi(Cmd_Argv(2));
startPos = atoi(Cmd_Argv(2));
if (startPos < 0) // r1ch's fix for negative index
{
Com_Printf ("Illegal baselines request (negative index) from %s[%s], dropping client\n", sv_client->name, NET_AdrToString(sv_client->netchan.remote_address));
SV_DropClient (sv_client);
return;
}
start = startPos;
memset (&nullstate, 0, sizeof(nullstate));
// write a packet full of data
// Knightmare- use maxLen for proper bounding
// while ( sv_client->netchan.message.cursize < MAX_MSGLEN/2 && start < MAX_EDICTS)
while ( sv_client->netchan.message.cursize < maxLen && start < MAX_EDICTS)
{
base = &sv.baselines[start];
if (base->modelindex || base->sound || base->effects)
{
MSG_WriteByte (&sv_client->netchan.message, svc_spawnbaseline);
MSG_WriteDeltaEntity (&nullstate, base, &sv_client->netchan.message, true, true);
}
start++;
}
// send next command
if (start == MAX_EDICTS)
{
MSG_WriteByte (&sv_client->netchan.message, svc_stufftext);
MSG_WriteString (&sv_client->netchan.message, va("precache %i\n", svs.spawncount) );
}
else
{
MSG_WriteByte (&sv_client->netchan.message, svc_stufftext);
MSG_WriteString (&sv_client->netchan.message, va("cmd baselines %i %i\n",svs.spawncount, start) );
}
}
示例14: CL_Record
//.........这里部分代码省略.........
guid = "LONGGONE";
}
Q_strncpyz(prefix, guid, 9);
// scan for a free demo name
for ( number = 0 ; number <= 9999 ; number++ ) {
if(number < 0 || number > 9999)
number = 9999;
n = number;
a = n / 1000;
n -= a*1000;
b = n / 100;
n -= b*100;
c = n / 10;
n -= c*10;
d = n;
Com_sprintf (name, sizeof(name), "demos/%s_%s_%i%i%i%i.dm_%d", prefix, sv_mapname->string, a, b, c, d, PROTOCOL_VERSION );
Com_sprintf (name_zip, sizeof(name_zip), "demos/%s_%s_%i%i%i%i.dm_%d.zip", prefix, sv_mapname->string, a, b, c, d, PROTOCOL_VERSION );
Q_strlwr(name);
Q_strlwr(name_zip);
if (!FS_FileExists(name) && !FS_FileExists(name_zip)) {
break; // file doesn't exist
}
}
}
// open the demo file
if (!sv_autorecord->integer) {
Com_Printf ("recording client %i to %s.\n", clientnum, name);
} else {
Com_Printf ("Record: %i: %s\n", clientnum, name);
}
cl->demofile = FS_FOpenFileWrite( name );
if ( !cl->demofile ) {
Com_Printf ("ERROR: couldn't open.\n");
return;
}
// don't start saving messages until a non-delta compressed message is received
cl->demowaiting = qtrue;
cl->savedemo = qfalse; // demo will not be saved if sv_autorecord 1 and cl's score is too low
Q_strncpyz( cl->demoName, name, sizeof( cl->demoName ) );
// write out the gamestate message
MSG_Init (&buf, bufData, sizeof(bufData));
MSG_Bitstream(&buf);
// NOTE, MRE: all server->client messages now acknowledge
MSG_WriteLong( &buf, cl->lastClientCommand );// 0007 - 000A
MSG_WriteByte (&buf, svc_gamestate);// 000B
MSG_WriteLong (&buf, cl->reliableSequence );// 000C - 000F
// write the configstrings
for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
if (sv.configstrings[i][0]) {
MSG_WriteByte( &buf, svc_configstring );
MSG_WriteShort( &buf, i );
MSG_WriteBigString( &buf, sv.configstrings[i] );
}
}
// write the baselines
Com_Memset( &nullstate, 0, sizeof( nullstate ) );
for ( i = 0 ; i < MAX_GENTITIES; i++ ) {
ent = &sv.svEntities[i].baseline;
if ( !ent->number ) {
continue;
}
MSG_WriteByte( &buf, svc_baseline );
MSG_WriteDeltaEntity( &buf, &nullstate, ent, qtrue );
}
MSG_WriteByte( &buf, svc_EOF );
// finished writing the gamestate stuff
// write the client num
MSG_WriteLong(&buf, clientnum);
// write the checksum feed
MSG_WriteLong(&buf, sv.checksumFeed);
// finished writing the client packet
MSG_WriteByte( &buf, svc_EOF );
// write it to the demo file
len = LittleLong( cl->netchan.outgoingSequence-1 );
FS_Write (&len, 4, cl->demofile);// 0000 - 0003
len = LittleLong (buf.cursize);
FS_Write (&len, 4, cl->demofile);// 0004 - 0007
FS_Write (buf.data, buf.cursize, cl->demofile);// 0007 - ...
// the rest of the demo file will be copied from net messages
cl->demorecording = qtrue;
}
示例15: SVD_StartDemoFile
/*
Start a server-side demo.
This does it all, create the file and adjust the demo-related
stuff in client_t.
This is mostly ripped from sv_client.c/SV_SendClientGameState
and cl_main.c/CL_Record_f.
*/
static void SVD_StartDemoFile(client_t *client, const char *path)
{
int i, len;
entityState_t *base, nullstate;
msg_t msg;
byte buffer[MAX_MSGLEN];
fileHandle_t file;
#ifdef USE_DEMO_FORMAT_42
char *s;
int v, size;
#endif
Com_DPrintf("SVD_StartDemoFile\n");
assert(!client->demo_recording);
// create the demo file and write the necessary header
file = FS_FOpenFileWrite(path);
assert(file != 0);
/* File_write_header_demo // ADD this fx */
/* HOLBLIN entete demo */
#ifdef USE_DEMO_FORMAT_42
//@Barbatos: get the mod version from the server
s = Cvar_VariableString("g_modversion");
size = strlen( s );
len = LittleLong( size );
FS_Write( &len, 4, file );
FS_Write( s , size , file );
v = LittleLong( PROTOCOL_VERSION );
FS_Write ( &v, 4 , file );
len = 0;
len = LittleLong( len );
FS_Write ( &len, 4 , file );
FS_Write ( &len, 4 , file );
#endif
/* END HOLBLIN entete demo */
MSG_Init(&msg, buffer, sizeof(buffer));
MSG_Bitstream(&msg); // XXX server code doesn't do this, client code does
MSG_WriteLong(&msg, client->lastClientCommand); // TODO: or is it client->reliableSequence?
MSG_WriteByte(&msg, svc_gamestate);
MSG_WriteLong(&msg, client->reliableSequence);
for (i = 0; i < MAX_CONFIGSTRINGS; i++) {
if (sv.configstrings[i][0]) {
MSG_WriteByte(&msg, svc_configstring);
MSG_WriteShort(&msg, i);
MSG_WriteBigString(&msg, sv.configstrings[i]);
}
}
Com_Memset(&nullstate, 0, sizeof(nullstate));
for (i = 0 ; i < MAX_GENTITIES; i++) {
base = &sv.svEntities[i].baseline;
if (!base->number) {
continue;
}
MSG_WriteByte(&msg, svc_baseline);
MSG_WriteDeltaEntity(&msg, &nullstate, base, qtrue);
}
MSG_WriteByte(&msg, svc_EOF);
MSG_WriteLong(&msg, client - svs.clients);
MSG_WriteLong(&msg, sv.checksumFeed);
MSG_WriteByte(&msg, svc_EOF); // XXX server code doesn't do this, SV_Netchan_Transmit adds it!
len = LittleLong(client->netchan.outgoingSequence-1);
FS_Write(&len, 4, file);
len = LittleLong (msg.cursize);
FS_Write(&len, 4, file);
FS_Write(msg.data, msg.cursize, file);
#ifdef USE_DEMO_FORMAT_42
// add size of packet in the end for backward play /* holblin */
FS_Write(&len, 4, file);
#endif
FS_Flush(file);
// adjust client_t to reflect demo started
client->demo_recording = qtrue;
client->demo_file = file;
client->demo_waiting = qtrue;
//.........这里部分代码省略.........