Beispiel #1
0
/*
=================
Netchan_TransmitNextFragment

Send one fragment of the current message
=================
*/
void Netchan_TransmitNextFragment( netchan_t *chan ) {
    msg_t		send;
    byte		send_buf[MAX_PACKETLEN];
    int			fragmentLength;

    // write the packet header
    MSG_InitOOB (&send, send_buf, sizeof(send_buf));				// <-- only do the oob here

    MSG_WriteLong( &send, chan->outgoingSequence | FRAGMENT_BIT );

    // send the qport if we are a client
    if ( chan->sock == NS_CLIENT ) {
        MSG_WriteShort( &send, qport->integer );
    }

    // copy the reliable message to the packet first
    fragmentLength = FRAGMENT_SIZE;
    if ( chan->unsentFragmentStart  + fragmentLength > chan->unsentLength ) {
        fragmentLength = chan->unsentLength - chan->unsentFragmentStart;
    }

    MSG_WriteShort( &send, chan->unsentFragmentStart );
    MSG_WriteShort( &send, fragmentLength );
    MSG_WriteData( &send, chan->unsentBuffer + chan->unsentFragmentStart, fragmentLength );

    // send the datagram
    NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress );

    if ( showpackets->integer ) {
        Com_Printf ("%s send %4i : s=%i fragment=%i,%i\n"
                    , netsrcString[ chan->sock ]
                    , send.cursize
                    , chan->outgoingSequence
                    , chan->unsentFragmentStart, fragmentLength);
    }

    chan->unsentFragmentStart += fragmentLength;

    // this exit condition is a little tricky, because a packet
    // that is exactly the fragment length still needs to send
    // a second packet of zero length so that the other side
    // can tell there aren't more to follow
    if ( chan->unsentFragmentStart == chan->unsentLength && fragmentLength != FRAGMENT_SIZE ) {
        chan->outgoingSequence++;
        chan->unsentFragments = qfalse;
    }
}
Beispiel #2
0
/*
=======================
SV_SendClientSnapshot

Also called by SV_FinalMessage

=======================
*/
void SV_SendClientSnapshot( client_t* client )
{
	byte        msg_buf[MAX_MSGLEN];
	msg_s       msg;
	
	// build the snapshot
	SV_BuildClientSnapshot( client );
	
	// bots need to have their snapshots build, but
	// the query them directly without needing to be sent
	//if ( client->gentity && client->gentity->r.svFlags & SVF_BOT ) {
	//  return;
	//}
	
	MSG_Init( &msg, msg_buf, sizeof( msg_buf ) );
	msg.allowoverflow = true;
	
	// compression byte is the first byte in all server->client messages
	msg.oob = true;
	MSG_WriteByte( &msg, 0 );
	msg.oob = false;
	
	// NOTE, MRE: all server->client messages now acknowledge
	// let the client know which reliable clientCommands we have received
	MSG_WriteLong( &msg, client->lastClientCommand );
	
	// (re)send any reliable server commands
	SV_UpdateServerCommandsToClient( client, &msg );
	
	// send over all the relevant entityState_s
	// and the playerState_s
	SV_WriteSnapshotToClient( client, &msg );
	
#ifdef USE_VOIP
	SV_WriteVoipToClient( client, &msg );
#endif
	
	// check for overflow
	if ( msg.overflowed )
	{
		Com_Printf( "WARNING: msg overflowed for %s\n", client->name );
		MSG_Clear( &msg );
	}
	
	SV_SendMessageToClient( &msg, client );
}
Beispiel #3
0
/*
================
SV_SendServerinfo

Sends the first message from the server to a connected client.
This will be sent on the initial connection and upon each server load.
================
*/
void SV_SendServerinfo (client_t *client)
{
	char			**s;
	char			message[2048];

	MSG_WriteByte (&client->message, svc_print);
	sprintf (message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, VERSION, pr_crc);
	MSG_WriteString (&client->message,message);

	MSG_WriteByte (&client->message, svc_serverinfo);
	MSG_WriteLong (&client->message, PROTOCOL_VERSION);
	MSG_WriteByte (&client->message, svs.maxclients);

	if (!coop.value && deathmatch.value)
		MSG_WriteByte (&client->message, GAME_DEATHMATCH);
	else
		MSG_WriteByte (&client->message, GAME_COOP);

	sprintf (message, pr_strings+sv.edicts->u.v.message);

	MSG_WriteString (&client->message,message);

	for (s = sv.model_precache+1 ; *s ; s++)
		MSG_WriteString (&client->message, *s);
	MSG_WriteByte (&client->message, 0);

	for (s = sv.sound_precache+1 ; *s ; s++)
		MSG_WriteString (&client->message, *s);
	MSG_WriteByte (&client->message, 0);

// send music
	MSG_WriteByte (&client->message, svc_cdtrack);
	MSG_WriteByte (&client->message, (int) sv.edicts->u.v.sounds);
	MSG_WriteByte (&client->message, (int) sv.edicts->u.v.sounds);

// set view	
	MSG_WriteByte (&client->message, svc_setview);
	MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));

	MSG_WriteByte (&client->message, svc_signonnum);
	MSG_WriteByte (&client->message, 1);

	client->sendsignon = true;
	client->spawned = false;		// need prespawn, spawn, etc
}
Beispiel #4
0
/*
===============
Netchan_Transmit

Sends a message to a connection, fragmenting if necessary
A 0 length will still generate a packet.
================
*/
void Netchan_Transmit( netchan_t *chan, size_t length, const byte *data ) {
	msg_t		send;
	byte		send_buf[MAX_PACKETLEN];

	if ( length > MAX_MSGLEN ) {
		Com_Error( ERR_DROP, "Netchan_Transmit: length = %i", length );
	}
	chan->unsentFragmentStart = 0;

	// fragment large reliable messages
	if ( length >= FRAGMENT_SIZE ) {
		chan->unsentFragments = qtrue;
		chan->unsentLength = length;
		Com_Memcpy( chan->unsentBuffer, data, length );

		// only send the first fragment now
		Netchan_TransmitNextFragment( chan );

		return;
	}

	// write the packet header
	MSG_InitOOB (&send, send_buf, sizeof(send_buf));

	MSG_WriteLong( &send, chan->outgoingSequence );
	chan->outgoingSequence++;

	// send the qport if we are a client
	if ( chan->sock == NS_CLIENT ) {
		MSG_WriteShort( &send, qport->integer );
	}

	MSG_WriteData( &send, data, length );

	// send the datagram
	NET_SendPacket( chan->sock, send.cursize, send.data, chan->remoteAddress );

	if ( showpackets->integer ) {
		Com_Printf( "%s send %4i : s=%i ack=%i\n"
			, netsrcString[ chan->sock ]
			, send.cursize
			, chan->outgoingSequence - 1
			, chan->incomingSequence );
	}
}
Beispiel #5
0
/*
==================
SV_UpdateServerCommandsToClient

(re)send all server commands the client hasn't acknowledged yet
==================
*/
void SV_UpdateServerCommandsToClient( client_t *client, msg_t *msg ) {
	int		i;
	int		reliableAcknowledge;

	if ( client->demo.isBot && client->demo.demorecording ) {
		reliableAcknowledge = client->demo.botReliableAcknowledge;
	} else {
		reliableAcknowledge = client->reliableAcknowledge;
	}

	// write any unacknowledged serverCommands
	for ( i = reliableAcknowledge + 1 ; i <= client->reliableSequence ; i++ ) {
		MSG_WriteByte( msg, svc_serverCommand );
		MSG_WriteLong( msg, i );
		MSG_WriteString( msg, client->reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
	}
	client->reliableSent = client->reliableSequence;
}
void CTerraBillingCtrl_Decoder::
Transmite_TerraGCPacket_Remain_Minute_NoticeMessage(
	playerCharacter_t* pToPlayerRecord,
	const int RemainMinute) const
{
	MSG_BeginWriting(&netMessage);
	
	MSG_Clear(&netMessage);
	{
		MSG_WriteByte(&netMessage, GSC_EXTEND);
		MSG_WriteByte(&netMessage, GSC_EXTEND_TERRA);
		MSG_WriteByte(&netMessage, tagTerraGCPacket::Remain_Minute_NoticeMessage);
		MSG_WriteLong(&netMessage, RemainMinute);		

		NET_SendMessage(&pToPlayerRecord->sock, &netMessage);
	}
	MSG_EndWriting(&netMessage);
}
Beispiel #7
0
void CHelperManager_Encoder::SendMessage_Mypoint_toTaker(
	playerCharacter_t* pPlayer, char* pTakerName,char* pHelperName, int MyPoint)
{
	MSG_BeginWriting(&netMessage);
	MSG_Clear( &netMessage );
	{
		MSG_WriteByte(&netMessage, EXTEND_SECOND);
		MSG_WriteShort( &netMessage, HELPER_SYSTEM );
		MSG_WriteShort(&netMessage, SC_SENDMYPOINT_toAllPlayer);
		MSG_WriteString(&netMessage,pTakerName);
		MSG_WriteString(&netMessage,pHelperName);
		MSG_WriteLong(&netMessage,MyPoint);
		NET_SendMessage(&pPlayer->sock, &netMessage);
	}
	
	MSG_EndWriting(&netMessage);
	
}
Beispiel #8
0
void CPostFunc::GTH_SendMessage_PostSystem_Send()
{

	
	char    name[NAMESTRING+1];
	char	title[CPostManager::POST_TITLESIZE+1];
	char	message[CPostManager::POST_STRSIZE+1];



	strncpy(name,g_ifMng->m_mailBoxWin->m_name,NAMESTRING);
	name[NAMESTRING]=NULL;
	CTools::Replace_singleQUOTATIONmark_by_doubleQUOTATIONmark(name);


	strncpy(title,g_ifMng->m_mailBoxWin->m_title,CPostManager::POST_TITLESIZE);
	title[CPostManager::POST_TITLESIZE]=NULL;
	CTools::Replace_singleQUOTATIONmark_by_doubleQUOTATIONmark(title);

	strncpy(message,g_ifMng->m_mailBoxWin->m_message,CPostManager::POST_STRSIZE);
	message[CPostManager::POST_STRSIZE]=NULL;
	CTools::Replace_singleQUOTATIONmark_by_doubleQUOTATIONmark(message);







	MSG_BeginWriting(&netMessage);
	MSG_Clear( &netMessage );
	{
		MSG_WriteByte(&netMessage, CC_EXTEND);
		MSG_WriteByte(&netMessage, CC_POSTSYSTEM);
		MSG_WriteByte(&netMessage, POSTSYSTEM_SEND);
		
		MSG_WriteString(&netMessage, name);
		MSG_WriteString(&netMessage, title);
		MSG_WriteString(&netMessage, message);
		MSG_WriteLong(&netMessage, g_ifMng->m_mailBoxWin->m_nak);
		NET_SendMessage(&gsSocket, &netMessage); 
	}
	MSG_EndWriting( &netMessage );	
}
Beispiel #9
0
/*
	Netchan_OutOfBand

	Sends an out-of-band datagram
*/
void
Netchan_OutOfBand (netadr_t adr, int length, byte * data)
{
	byte        send_buf[MAX_MSGLEN + PACKET_HEADER];
	sizebuf_t   send;

	// write the packet header
	send.data = send_buf;
	send.maxsize = sizeof (send_buf);
	send.cursize = 0;

	MSG_WriteLong (&send, -1);			// -1 sequence means out of band
	SZ_Write (&send, data, length);

	// send the datagram
	// zoid, no input in demo playback mode
	if (!net_blocksend)
		Netchan_SendPacket (send.cursize, send.data, adr);
}
Beispiel #10
0
inline void CGMCtrl::TransmitePacket_NProtect_msgs_notify_change(const BOOL in_bEnable) const
{
	MSG_BeginWriting(&netMessage);
	MSG_Clear( &netMessage );
	{
		MSG_WriteByte(&netMessage, EXTEND_SECOND);		
		MSG_WriteShort(&netMessage, GMsystem);
		MSG_WriteShort(&netMessage, tagExtendSecondPacket_GMsystem::GMsystem_NProtect);
		MSG_WriteShort(&netMessage, tagExtendSecondPacket_GMsystem::tagNProtect::msgs_notify_change);
		MSG_WriteLong(&netMessage,in_bEnable);

		for(int i=1; i < MAX_MEMBER_SERVER; i++){ 
			if ( !g_memberServer[i].active )	continue;
			NET_SendUnreliableMessage(&g_memberServer[i].sock, &netMessage);
		}
	}
	MSG_EndWriting(&netMessage);

}
Beispiel #11
0
void CGs_To_Cc::Send(playerCharacter_t* pPlayer,int SystemType,int mainType, int subType,int val, char *TargetPlayerName)
{
	MSG_BeginWriting( &netMessage );
	MSG_Clear( &netMessage );
	{
		MSG_WriteByte(&netMessage, EXTEND_SECOND);
		
		MSG_WriteShort(&netMessage, SystemType);
		MSG_WriteShort(&netMessage, mainType);		
		MSG_WriteShort(&netMessage, subType);	

		MSG_WriteLong(&netMessage, val);	

		MSG_WriteString(&netMessage, TargetPlayerName);	

		NET_SendMessage(&pPlayer->sock, &netMessage);
	}
	MSG_EndWriting(&netMessage);
}
Beispiel #12
0
void Netchan_OutOfBand(netsrc_t sock, netadr_t adr, int length, byte *data)
{
	sizebuf_t send;
	byte send_buf[NET_MAX_PAYLOAD];

	send.buffername = "Netchan_OutOfBand";
	send.data = send_buf;
	send.maxsize = sizeof(send_buf);
	send.cursize = 0;
	send.flags = SIZEBUF_ALLOW_OVERFLOW;

	MSG_WriteLong(&send, -1);
	SZ_Write(&send, data, length);

	if (!g_pcls.demoplayback)
	{
		NET_SendPacket(sock, send.cursize, send.data, adr);
	}
}
Beispiel #13
0
/*
================
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;
	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] );
		}
	}

	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 );
}
Beispiel #14
0
/*
* TV_Downstream_AddReliableCommandsToMessage
* 
* (re)send all server commands the client hasn't acknowledged yet
*/
void TV_Downstream_AddReliableCommandsToMessage( client_t *client, msg_t *msg )
{
	unsigned int i;

	// write any unacknowledged serverCommands
	for( i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++ )
	{
		if( !strlen( client->reliableCommands[i & ( MAX_RELIABLE_COMMANDS-1 )] ) )
			continue;

		MSG_WriteByte( msg, svc_servercmd );
		if( !client->reliable )
			MSG_WriteLong( msg, i );
		MSG_WriteString( msg, client->reliableCommands[i & ( MAX_RELIABLE_COMMANDS-1 )] );
	}

	client->reliableSent = client->reliableSequence;
	if( client->reliable )
		client->reliableAcknowledge = client->reliableSent;
}
Beispiel #15
0
// Sends resource to all other players, optionally skipping originating player.
void SV_Customization(client_t *pPlayer, resource_t *pResource, qboolean bSkipPlayer)
{
	int i;
	int nPlayerNumber;
	client_t *pHost;

	// Get originating player id
	for (i = 0, pHost = g_psvs.clients; i < g_psvs.maxclients; i++, pHost++)
	{
		if (pHost == pPlayer)
			break;
	}
	if (i == g_psvs.maxclients)
	{
		Sys_Error("Couldn't find player index for customization.");
	}

	nPlayerNumber = i;

	// Send resource to all other active players
	for (i = 0, pHost = g_psvs.clients; i < g_psvs.maxclients; i++, pHost++)
	{
		if (!pHost->active && !pHost->spawned || pHost->fakeclient)
			continue;

		if (pHost == pPlayer && bSkipPlayer)
			continue;

		MSG_WriteByte(&pHost->netchan.message, svc_customization);
		MSG_WriteByte(&pHost->netchan.message, nPlayerNumber);
		MSG_WriteByte(&pHost->netchan.message, pResource->type);
		MSG_WriteString(&pHost->netchan.message, pResource->szFileName);
		MSG_WriteShort(&pHost->netchan.message, pResource->nIndex);
		MSG_WriteLong(&pHost->netchan.message, pResource->nDownloadSize);
		MSG_WriteByte(&pHost->netchan.message, pResource->ucFlags);
		if (pResource->ucFlags & RES_CUSTOM)
		{
			SZ_Write(&pHost->netchan.message, pResource->rgucMD5_hash, 16);
		}
	}
}
Beispiel #16
0
/*
==================
SV_WriteVoipToClient

Check to see if there is any VoIP queued for a client, and send if there is.
==================
*/
void SV_WriteVoipToClient( client_t *cl, msg_t *msg )
{
	voipServerPacket_t *packet = &cl->voipPacket[0];
	int totalbytes = 0;
	int i;

	if (*cl->downloadName) {
		cl->queuedVoipPackets = 0;
		return;  // no VoIP allowed if download is going, to save bandwidth.
	}

	// Write as many VoIP packets as we reasonably can...
	for (i = 0; i < cl->queuedVoipPackets; i++, packet++) {
		totalbytes += packet->len;
		if (totalbytes > MAX_DOWNLOAD_BLKSIZE)
			break;

		// You have to start with a svc_EOF, so legacy clients drop the
		//  rest of this packet. Otherwise, those without VoIP support will
		//  see the svc_voip command, then panic and disconnect.
		// Generally we don't send VoIP packets to legacy clients, but this
		//  serves as both a safety measure and a means to keep demo files
		//  compatible.
		MSG_WriteByte( msg, svc_EOF );
		MSG_WriteByte( msg, svc_extension );
		MSG_WriteByte( msg, svc_voip );
		MSG_WriteShort( msg, packet->sender );
		MSG_WriteByte( msg, (byte) packet->generation );
		MSG_WriteLong( msg, packet->sequence );
		MSG_WriteByte( msg, packet->frames );
		MSG_WriteShort( msg, packet->len );
		MSG_WriteData( msg, packet->data, packet->len );
	}

	// !!! FIXME: I hate this queue system.
	cl->queuedVoipPackets -= i;
	if (cl->queuedVoipPackets > 0) {
		memmove( &cl->voipPacket[0], &cl->voipPacket[i],
		         sizeof (voipServerPacket_t) * i);
	}
}
Beispiel #17
0
void SV_UpdateServerCommandsToClientRecover( client_t *client, msg_t *msg )
{
	int i;
	int cmdlen;
	
	for(i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++)
	{
		
		cmdlen = strlen(client->reliableCommands[i & ( MAX_RELIABLE_COMMANDS - 1 )].command);
		
		if ( cmdlen + msg->cursize + 6 >= msg->maxsize )
			break;
		
		MSG_WriteByte(msg, svc_serverCommand);
		MSG_WriteLong(msg, i);
		MSG_WriteString(msg, client->reliableCommands[i & ( MAX_RELIABLE_COMMANDS - 1 )].command);
	
	}
	if ( i - 1 > client->reliableSent )
	client->reliableSent = i - 1;
}
Beispiel #18
0
/*
====================
CL_Stop_f

stop recording a demo
====================
*/
void CL_Stop_f (void)
{
	if (!cls.demorecording)
	{
		Con_Printf ("Not recording a demo.\n");
		return;
	}

// write a disconnect message to the demo file
	SZ_Clear (&net_message);
	MSG_WriteLong (&net_message, -1);	// -1 sequence means out of band
	MSG_WriteByte (&net_message, svc_disconnect);
	MSG_WriteString (&net_message, "EndOfDemo");
	CL_WriteDemoMessage (&net_message);

// finish up
	fclose (cls.demofile);
	cls.demofile = NULL;
	cls.demorecording = false;
	Con_Printf ("Completed demo\n");
}
Beispiel #19
0
Datei: net.c Projekt: deurk/qwfwd
/*
===============
Netchan_OutOfBand

Sends an out-of-band datagram
================
*/
void Netchan_OutOfBand(int s, struct sockaddr_in *adr, int length, byte *data)
{
	sizebuf_t send1;
	byte send_buf[MAX_MSGLEN + PACKET_HEADER];

	SZ_InitEx(&send1, send_buf, sizeof(send_buf), true);

	// write the packet header
	MSG_WriteLong(&send1, -1);	// -1 sequence means out of band
	// write data
	SZ_Write(&send1, data, length);

	if (send1.overflowed)
	{
		Sys_Printf("Netchan_OutOfBand: overflowed\n");
		return; // ah, should not happens
	}

	// send the datagram
	NET_SendPacket(s, send1.cursize, send1.data, adr);
}
Beispiel #20
0
//
// P_FireWeapon.
//
void P_FireWeapon (player_t *player)
{
	statenum_t	newstate;

	if (!P_CheckAmmo (player))
		return;

	// [tm512] Send the client the weapon they just fired so
	// that they can fix any weapon desyncs that they get - apr 14 2012
	if (serverside && !clientside)
	{
		MSG_WriteMarker (&player->client.reliablebuf, svc_fireweapon);
		MSG_WriteByte (&player->client.reliablebuf, player->readyweapon);
		MSG_WriteLong (&player->client.reliablebuf, player->tic);
	}

	P_SetMobjState (player->mo, S_PLAY_ATK1);
	newstate = weaponinfo[player->readyweapon].atkstate;
	P_SetPsprite (player, ps_weapon, newstate);
	P_NoiseAlert (player->mo, player->mo);
}
Beispiel #21
0
void CDanBattleManager::SendGSM_Refresh_PersonData(playerCharacter_t* pc, int type, int etc1, int etc2)
{
			
	
	
	
	

	MSG_BeginWriting(&netMessage);
	MSG_Clear( &netMessage );
	
	MSG_WriteByte(&netMessage, GSC_EXTEND);
	MSG_WriteByte(&netMessage, GSC_DAN_BATTLE);
	MSG_WriteByte(&netMessage, DANB_BATTLE_REFRESH_PERSONDATA);	
	MSG_WriteLong(&netMessage, type);

	switch(type)
	{
		
	case 0:
		MSG_WriteLong(&netMessage, pc->curChargeSE);		
		break;		

		
		
	case 1:
		MSG_WriteLong(&netMessage, pc->rankPoint);
		MSG_WriteLong(&netMessage, g_guild[pc->guildIdx].famePoint);

		
	case 2:
		MSG_WriteLong(&netMessage, etc1);		
		break;		

		
	case 3:
		MSG_WriteLong(&netMessage, etc1);
		break;

	
	}	
	NET_SendUnreliableMessage(&pc->sock, &netMessage);
	
	MSG_EndWriting(&netMessage);

}
Beispiel #22
0
void SV_SendClientMapChange( client_t *client ) 
{
	msg_t		msg;
	byte		msgBuffer[MAX_MSGLEN];

	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_mapchange );

	// deliver this to the client
	SV_SendMessageToClient( &msg, client );
}
Beispiel #23
0
/*
==================
SV_WriteVoipToClient

Check to see if there is any VoIP queued for a client, and send if there is.
==================
*/
static void SV_WriteVoipToClient( client_t* cl, msg_s* msg )
{
	int totalbytes = 0;
	int i;
	voipServerPacket_t* packet;
	
	if ( cl->queuedVoipPackets )
	{
		// Write as many VoIP packets as we reasonably can...
		for ( i = 0; i < cl->queuedVoipPackets; i++ )
		{
			packet = cl->voipPacket[( i + cl->queuedVoipIndex ) % ARRAY_LEN( cl->voipPacket )];
			
			if ( !*cl->downloadName )
			{
				totalbytes += packet->len;
				if ( totalbytes > ( msg->maxsize - msg->cursize ) / 2 )
					break;
					
				MSG_WriteByte( msg, svc_voip );
				MSG_WriteShort( msg, packet->sender );
				MSG_WriteByte( msg, ( byte ) packet->generation );
				MSG_WriteLong( msg, packet->sequence );
				MSG_WriteByte( msg, packet->frames );
				MSG_WriteShort( msg, packet->len );
				MSG_WriteBits( msg, packet->flags, VOIP_FLAGCNT );
				MSG_WriteData( msg, packet->data, packet->len );
			}
			
			free( packet );
		}
		
		cl->queuedVoipPackets -= i;
		cl->queuedVoipIndex += i;
		cl->queuedVoipIndex %= ARRAY_LEN( cl->voipPacket );
	}
}
Beispiel #24
0
/*
===================
SV_FullClientUpdate

Writes all update values to a sizebuf
===================
*/
void SV_FullClientUpdate (client_t *client, sizebuf_t *buf)
{
	int		i;
	char	info[MAX_INFO_STRING];

	i = client - svs.clients;

	if (client->state == cs_free && sv_fastconnect.value)
		return;

	MSG_WriteByte (buf, svc_updatefrags);
	MSG_WriteByte (buf, i);
	MSG_WriteShort (buf, client->old_frags);
	
	MSG_WriteByte (buf, svc_updateping);
	MSG_WriteByte (buf, i);
	MSG_WriteShort (buf, SV_CalcPing (client));
	
	MSG_WriteByte (buf, svc_updatepl);
	MSG_WriteByte (buf, i);
	MSG_WriteByte (buf, client->lossage);
	
	MSG_WriteByte (buf, svc_updateentertime);
	MSG_WriteByte (buf, i);
	MSG_WriteFloat (buf, svs.realtime - client->connection_started);

	strcpy (info, client->userinfo);
	Info_RemovePrefixedKeys (info, '_');	// server passwords, etc
	Info_RemoveKey (info, "pmodel");
	Info_RemoveKey (info, "emodel");

	MSG_WriteByte (buf, svc_updateuserinfo);
	MSG_WriteByte (buf, i);
	MSG_WriteLong (buf, client->userid);
	MSG_WriteString (buf, info);
}
Beispiel #25
0
static void FWD_check_timeout(void)
{
	byte msg_data[6];
	sizebuf_t msg;
	time_t cur_time;
	double d_cur_time;
	peer_t *p;

	SZ_InitEx(&msg, msg_data, sizeof(msg_data), true);

	cur_time = time(NULL);
	d_cur_time = Sys_DoubleTime();

	for (p = peers; p; p = p->next)
	{
		// this is helper for q3 to guess disconnect asap
		if (p->proto == pr_q3)
		{
			if (cur_time - p->last > 1 && d_cur_time - p->q3_disconnect_check > 0.05 && p->ps == ps_connected)
			{
				p->q3_disconnect_check = d_cur_time;
				SZ_Clear(&msg);
				MSG_WriteLong(&msg, 0);
				MSG_WriteShort(&msg, p->qport);
				NET_SendPacket(p->s, msg.cursize, msg.data, &p->to);
			}
		}

		if (cur_time - p->last < 15) // few seconds timeout
			continue;

		Sys_DPrintf("peer %s:%d timed out\n", inet_ntoa(p->from.sin_addr), (int)ntohs(p->from.sin_port));

		p->ps = ps_drop;
	}
}
Beispiel #26
0
void CWeatherSystem::
GTH_SendMessage_Request_WeatherSetting
( TIMESTATE weather, float limittime, bool IsUseItem , int invenpos )
{
	MSG_BeginWriting( &netMessage );
	
	MSG_Clear( &netMessage );
	{
		MSG_WriteByte(&netMessage,	EXTEND_SECOND);
		MSG_WriteShort(&netMessage, WEATHER_SYSTEM );
		MSG_WriteShort(&netMessage, CC_WEATHER_SYSTEM );		
		MSG_WriteByte(&netMessage,	CC_WEATHER_SYSTEM_REQUEST_USE_WEATHER_ITEM);		
		MSG_WriteByte(&netMessage,	weather);				
		MSG_WriteLong(&netMessage,	limittime);						
		MSG_WriteByte(&netMessage,	IsUseItem);								

		if ( IsUseItem )
		 MSG_WriteByte(&netMessage,  invenpos);

		NET_SendMessage(&gsSocket, &netMessage);
	}
	MSG_EndWriting(&netMessage);
	
}
Beispiel #27
0
//
// CL_RequestDownload
// please sir, can i have some more?
//
void CL_RequestDownload(std::string filename, std::string filehash)
{
	if (cl_serverdownload)
	{
		// [Russell] - Allow resumeable downloads
		if ((download.filename != filename) ||
			(download.md5 != filehash))
		{
			download.filename = filename;
			download.md5 = filehash;
			download.got_bytes = 0;
		}

		// denis todo clear previous downloads
		MSG_WriteMarker(&net_buffer, clc_wantwad);
		MSG_WriteString(&net_buffer, filename.c_str());
		MSG_WriteString(&net_buffer, filehash.c_str());
		MSG_WriteLong(&net_buffer, download.got_bytes);

		NET_SendPacket(net_buffer, serveraddr);

		Printf(PRINT_HIGH, "Requesting download...\n");

		// check for completion
		// [Russell] - We go over the boundary, because sometimes the download will
		// pause at 100% if the server disconnected you previously, you can
		// reconnect a couple of times and this will let the checksum system do its
		// work

		if ((download.buf != NULL) &&
			(download.got_bytes >= download.buf->maxsize()))
		{
			IntDownloadComplete();
		}
	}
}
Beispiel #28
0
/*
* SNAP_DemoMetaDataMessage
*/
static void SNAP_DemoMetaDataMessage( msg_t *msg, const char *meta_data, size_t meta_data_realsize )
{
	int demoinfo_len, demoinfo_len_pos, demoinfo_end;
	int meta_data_ofs, meta_data_ofs_pos;

	// demoinfo message
	MSG_WriteByte( msg, svc_demoinfo );

	demoinfo_len_pos = msg->cursize;
	MSG_WriteLong( msg, 0 );	// svc_demoinfo length
	demoinfo_len = msg->cursize;

	meta_data_ofs_pos = msg->cursize;
	MSG_WriteLong( msg, 0 );	// meta data start offset
	meta_data_ofs = msg->cursize;

	if( meta_data_realsize > SNAP_MAX_DEMO_META_DATA_SIZE )
		meta_data_realsize = SNAP_MAX_DEMO_META_DATA_SIZE;
	if( meta_data_realsize > 0 )
		meta_data_realsize--;

	meta_data_ofs = msg->cursize - meta_data_ofs;
	MSG_WriteLong( msg, meta_data_realsize );		// real size
	MSG_WriteLong( msg, SNAP_MAX_DEMO_META_DATA_SIZE ); // max size
	MSG_WriteData( msg, meta_data, meta_data_realsize );
	MSG_WriteData( msg, dummy_meta_data, SNAP_MAX_DEMO_META_DATA_SIZE - meta_data_realsize );

	demoinfo_end = msg->cursize;
	demoinfo_len = msg->cursize - demoinfo_len;

	msg->cursize = demoinfo_len_pos;
	MSG_WriteLong( msg, demoinfo_len );	// svc_demoinfo length
	msg->cursize = meta_data_ofs_pos;
	MSG_WriteLong( msg, meta_data_ofs );	// meta data start offset

	msg->cursize = demoinfo_end;
}
Beispiel #29
0
/*
* CL_WriteUcmdsToMessage
*/
void CL_WriteUcmdsToMessage( msg_t *msg )
{
	usercmd_t *cmd;
	usercmd_t *oldcmd;
	usercmd_t nullcmd;
	unsigned int resendCount;
	unsigned int i;
	unsigned int ucmdFirst;
	unsigned int ucmdHead;

	if( !msg || cls.state < CA_ACTIVE || cls.demo.playing )
		return;

	// find out what ucmds we have to send
	ucmdFirst = cls.ucmdAcknowledged + 1;
	ucmdHead = cl.cmdNum + 1;

	if( cl_ucmdMaxResend->integer > CMD_BACKUP * 0.5 )
		Cvar_SetValue( "cl_ucmdMaxResend", CMD_BACKUP * 0.5 );
	else if( cl_ucmdMaxResend->integer < 1 )
		Cvar_SetValue( "cl_ucmdMaxResend", 1 );

	// find what is our resend count (resend doesn't include the newly generated ucmds)
	// and move the start back to the resend start
	if( ucmdFirst <= cls.ucmdSent + 1 )
		resendCount = 0;
	else
		resendCount = ( cls.ucmdSent + 1 ) - ucmdFirst;
	if( resendCount > (unsigned int)cl_ucmdMaxResend->integer )
		resendCount = (unsigned int)cl_ucmdMaxResend->integer;

	if( ucmdFirst > ucmdHead )
		ucmdFirst = ucmdHead;

	// if this happens, the player is in a freezing lag. Send him the less possible data
	if( ( ucmdHead - ucmdFirst ) + resendCount > CMD_MASK * 0.5 )
		resendCount = 0;

	// move the start backwards to the resend point
	ucmdFirst = ( ucmdFirst > resendCount ) ? ucmdFirst - resendCount : ucmdFirst;

	if( ( ucmdHead - ucmdFirst ) > CMD_MASK ) // ran out of updates, seduce the send to try to recover activity
		ucmdFirst = ucmdHead - 3;

	// begin a client move command
	MSG_WriteByte( msg, clc_move );

	// (acknowledge server frame snap)
	// let the server know what the last frame we
	// got was, so the next message can be delta compressed
	if( cl.receivedSnapNum <= 0 )
		MSG_WriteLong( msg, -1 );
	else
		MSG_WriteLong( msg, cl.snapShots[cl.receivedSnapNum & UPDATE_MASK].serverFrame );

	// Write the actual ucmds

	// write the id number of first ucmd to be sent, and the count
	MSG_WriteLong( msg, ucmdHead );
	MSG_WriteByte( msg, (uint8_t)( ucmdHead - ucmdFirst ) );

	// write the ucmds
	for( i = ucmdFirst; i < ucmdHead; i++ )
	{
		if( i == ucmdFirst ) // first one isn't delta-compressed
		{
			cmd = &cl.cmds[i & CMD_MASK];
			memset( &nullcmd, 0, sizeof( nullcmd ) );
			MSG_WriteDeltaUsercmd( msg, &nullcmd, cmd );
		}
		else // delta compress to previous written
		{
			cmd = &cl.cmds[i & CMD_MASK];
			oldcmd = &cl.cmds[( i-1 ) & CMD_MASK];
			MSG_WriteDeltaUsercmd( msg, oldcmd, cmd );
		}
	}

	cls.ucmdSent = i;
}
Beispiel #30
0
/*
====================
CL_Record_f

record <demoname> <server>
====================
*/
void CL_Record_f (void)
{
	int		c;
	char	name[MAX_OSPATH];
	sizebuf_t	buf;
	char	buf_data[MAX_MSGLEN];
	int n, i, j;
	char *s;
	entity_t *ent;
	entity_state_t *es, blankes;
	player_info_t *player;
	extern	char gamedirfile[];
	int seq = 1;

	c = Cmd_Argc();
	if (c != 2)
	{
		Con_Printf ("record <demoname>\n");
		return;
	}

	if (cls.state != ca_active) {
		Con_Printf ("You must be connected to record.\n");
		return;
	}

	if (cls.demorecording)
		CL_Stop_f();
  
	sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));

//
// open the demo file
//
	COM_DefaultExtension (name, ".qwd");

	cls.demofile = fopen (name, "wb");
	if (!cls.demofile)
	{
		Con_Printf ("ERROR: couldn't open.\n");
		return;
	}

	Con_Printf ("recording to %s.\n", name);
	cls.demorecording = true;

/*-------------------------------------------------*/

// serverdata
	// send the info about the new client to all connected clients
	memset(&buf, 0, sizeof(buf));
	buf.data = buf_data;
	buf.maxsize = sizeof(buf_data);

// send the serverdata
	MSG_WriteByte (&buf, svc_serverdata);
	MSG_WriteLong (&buf, PROTOCOL_VERSION);
	MSG_WriteLong (&buf, cl.servercount);
	MSG_WriteString (&buf, gamedirfile);

	if (cl.spectator)
		MSG_WriteByte (&buf, cl.playernum | 128);
	else
		MSG_WriteByte (&buf, cl.playernum);

	// send full levelname
	MSG_WriteString (&buf, cl.levelname);

	// send the movevars
	MSG_WriteFloat(&buf, movevars.gravity);
	MSG_WriteFloat(&buf, movevars.stopspeed);
	MSG_WriteFloat(&buf, movevars.maxspeed);
	MSG_WriteFloat(&buf, movevars.spectatormaxspeed);
	MSG_WriteFloat(&buf, movevars.accelerate);
	MSG_WriteFloat(&buf, movevars.airaccelerate);
	MSG_WriteFloat(&buf, movevars.wateraccelerate);
	MSG_WriteFloat(&buf, movevars.friction);
	MSG_WriteFloat(&buf, movevars.waterfriction);
	MSG_WriteFloat(&buf, movevars.entgravity);

	// send music
	MSG_WriteByte (&buf, svc_cdtrack);
	MSG_WriteByte (&buf, 0); // none in demos

	// send server info string
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) );

	// flush packet
	CL_WriteRecordDemoMessage (&buf, seq++);
	SZ_Clear (&buf); 

// soundlist
	MSG_WriteByte (&buf, svc_soundlist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = cl.sound_name[n+1];
	while (*s) {
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2) {
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
			MSG_WriteByte (&buf, svc_soundlist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = cl.sound_name[n+1];
	}
	if (buf.cursize) {
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// modellist
	MSG_WriteByte (&buf, svc_modellist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = cl.model_name[n+1];
	while (*s) {
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2) {
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
			MSG_WriteByte (&buf, svc_modellist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = cl.model_name[n+1];
	}
	if (buf.cursize) {
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// spawnstatic

	for (i = 0; i < cl.num_statics; i++) {
		ent = cl_static_entities + i;

		MSG_WriteByte (&buf, svc_spawnstatic);

		for (j = 1; j < MAX_MODELS; j++)
			if (ent->model == cl.model_precache[j])
				break;
		if (j == MAX_MODELS)
			MSG_WriteByte (&buf, 0);
		else
			MSG_WriteByte (&buf, j);

		MSG_WriteByte (&buf, ent->frame);
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, ent->skinnum);
		for (j=0 ; j<3 ; j++)
		{
			MSG_WriteCoord (&buf, ent->origin[j]);
			MSG_WriteAngle (&buf, ent->angles[j]);
		}

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

// spawnstaticsound
	// static sounds are skipped in demos, life is hard

// baselines

	memset(&blankes, 0, sizeof(blankes));
	for (i = 0; i < MAX_EDICTS; i++) {
		es = cl_baselines + i;

		if (memcmp(es, &blankes, sizeof(blankes))) {
			MSG_WriteByte (&buf,svc_spawnbaseline);		
			MSG_WriteShort (&buf, i);

			MSG_WriteByte (&buf, es->modelindex);
			MSG_WriteByte (&buf, es->frame);
			MSG_WriteByte (&buf, es->colormap);
			MSG_WriteByte (&buf, es->skinnum);
			for (j=0 ; j<3 ; j++)
			{
				MSG_WriteCoord(&buf, es->origin[j]);
				MSG_WriteAngle(&buf, es->angles[j]);
			}

			if (buf.cursize > MAX_MSGLEN/2) {
				CL_WriteRecordDemoMessage (&buf, seq++);
				SZ_Clear (&buf); 
			}
		}
	}

	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("cmd spawn %i 0\n", cl.servercount) );

	if (buf.cursize) {
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// send current status of all other players

	for (i = 0; i < MAX_CLIENTS; i++) {
		player = cl.players + i;

		MSG_WriteByte (&buf, svc_updatefrags);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->frags);
		
		MSG_WriteByte (&buf, svc_updateping);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->ping);
		
		MSG_WriteByte (&buf, svc_updatepl);
		MSG_WriteByte (&buf, i);
		MSG_WriteByte (&buf, player->pl);
		
		MSG_WriteByte (&buf, svc_updateentertime);
		MSG_WriteByte (&buf, i);
		MSG_WriteFloat (&buf, player->entertime);

		MSG_WriteByte (&buf, svc_updateuserinfo);
		MSG_WriteByte (&buf, i);
		MSG_WriteLong (&buf, player->userid);
		MSG_WriteString (&buf, player->userinfo);

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}
	
// send all current light styles
	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
	{
		MSG_WriteByte (&buf, svc_lightstyle);
		MSG_WriteByte (&buf, (char)i);
		MSG_WriteString (&buf, cl_lightstyle[i].map);
	}

	for (i = 0; i < MAX_CL_STATS; i++) {
		MSG_WriteByte (&buf, svc_updatestatlong);
		MSG_WriteByte (&buf, i);
		MSG_WriteLong (&buf, cl.stats[i]);
		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

#if 0
	MSG_WriteByte (&buf, svc_updatestatlong);
	MSG_WriteByte (&buf, STAT_TOTALMONSTERS);
	MSG_WriteLong (&buf, cl.stats[STAT_TOTALMONSTERS]);

	MSG_WriteByte (&buf, svc_updatestatlong);
	MSG_WriteByte (&buf, STAT_SECRETS);
	MSG_WriteLong (&buf, cl.stats[STAT_SECRETS]);

	MSG_WriteByte (&buf, svc_updatestatlong);
	MSG_WriteByte (&buf, STAT_MONSTERS);
	MSG_WriteLong (&buf, cl.stats[STAT_MONSTERS]);
#endif

	// get the client to check and download skins
	// when that is completed, a begin command will be issued
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("skins\n") );

	CL_WriteRecordDemoMessage (&buf, seq++);

	CL_WriteSetDemoMessage();

	// done
}