• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++ MSG_WriteData函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中MSG_WriteData函数的典型用法代码示例。如果您正苦于以下问题:C++ MSG_WriteData函数的具体用法?C++ MSG_WriteData怎么用?C++ MSG_WriteData使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了MSG_WriteData函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: Netchan_Transmit

/*
===============
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, int 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 );
    }
}
开发者ID:Wbuanguna,项目名称:tremfusion,代码行数:53,代码来源:net_chan.c


示例2: SV_WriteBinaryMessage

/*
=======================================================================================================================================
SV_WriteBinaryMessage
=======================================================================================================================================
*/
static void SV_WriteBinaryMessage(msg_t *msg, client_t *cl) {

	if (!cl->binaryMessageLength) {
		return;
	}

	MSG_Uncompressed(msg);

	if ((msg->cursize + cl->binaryMessageLength) >= msg->maxsize) {
		cl->binaryMessageOverflowed = qtrue;
		return;
	}

	MSG_WriteData(msg, cl->binaryMessage, cl->binaryMessageLength);

	cl->binaryMessageLength = 0;
	cl->binaryMessageOverflowed = qfalse;
}
开发者ID:ioid3-games,项目名称:ioid3-wet,代码行数:23,代码来源:sv_net_chan.c


示例3: HL2Rcon_SourceRconSendDataToEachClient

void HL2Rcon_SourceRconSendDataToEachClient( const byte* data, int msglen, int type){

	rconUser_t* user;
	int i;
	msg_t msg;
	int32_t *updatelen;
	byte sourcemsgbuf[MAX_MSGLEN];
	qboolean msgbuild = qfalse;

	for(i = 0, user = sourceRcon.activeRconUsers; i < MAX_RCONUSERS; i++, user++ ){

		if(!user->streamgamelog && type == SERVERDATA_GAMELOG)
			continue;

		if(!user->streamlog && type == SERVERDATA_CONLOG)
			continue;

		if(!user->streamevents && type == SERVERDATA_EVENT)
			continue;

		
		if(!msgbuild){
			MSG_Init(&msg, sourcemsgbuf, sizeof(sourcemsgbuf));
			MSG_WriteLong(&msg, 0); //writing 0 for now
			MSG_WriteLong(&msg, 0);
			MSG_WriteLong(&msg, type);

			if(type == SERVERDATA_EVENT)
				MSG_WriteData(&msg, data, msglen);
			else
				MSG_WriteBigString(&msg, (char*)data);

			MSG_WriteByte(&msg, 0);

			//Adjust the length
			updatelen = (int32_t*)msg.data;
			*updatelen = msg.cursize - 4;
			msgbuild = qtrue;
		}
		NET_SendData(user->remote.sock, &msg);
	}
}
开发者ID:Call-of-Duty-Scripts,项目名称:CoD4X18-Server,代码行数:42,代码来源:hl2rcon.c


示例4: SV_WriteVoipToClient

/*
==================
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);
	}
}
开发者ID:burzumishi,项目名称:dragonballworld,代码行数:48,代码来源:sv_client.c


示例5: CL_SendUserinfo

static void CL_SendUserinfo( void ) {
    char userinfo[MAX_INFO_STRING];
    cvar_t *var;
    int i;

    if( !cls.userinfo_modified ) {
        return;
    }

    if( cls.userinfo_modified == MAX_PACKET_USERINFOS ) {
        size_t len = Cvar_BitInfo( userinfo, CVAR_USERINFO );
        Com_DDPrintf( "%s: %u: full update\n", __func__, com_framenum );
        MSG_WriteByte( clc_userinfo );
        MSG_WriteData( userinfo, len + 1 );
        MSG_FlushTo( &cls.netchan->message );
    } else if( cls.serverProtocol == PROTOCOL_VERSION_Q2PRO ) {
        Com_DDPrintf( "%s: %u: %d updates\n", __func__, com_framenum,
            cls.userinfo_modified );
        for( i = 0; i < cls.userinfo_modified; i++ ) { 
            var = cls.userinfo_updates[i];
            MSG_WriteByte( clc_userinfo_delta );
            MSG_WriteString( var->name );
            if( var->flags & CVAR_USERINFO ) {
                MSG_WriteString( var->string );
            } else {
                // no longer in userinfo
                MSG_WriteString( NULL );
            }
        }
        MSG_FlushTo( &cls.netchan->message );
    } else {
        Com_WPrintf( "%s: update count is %d, should never happen.\n",
            __func__, cls.userinfo_modified );
    }

    cls.userinfo_modified = 0;
}
开发者ID:Bad-ptr,项目名称:q2pro,代码行数:37,代码来源:cl_input.c


示例6: SV_WriteVoipToClient

/*
==================
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 );
	}
}
开发者ID:OnlyTheGhosts,项目名称:OWEngine,代码行数:44,代码来源:sv_snapshot.cpp


示例7: SV_WriteDownloadToClient


//.........这里部分代码省略.........
		curindex = (cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW);

		if (!cl->downloadBlocks[curindex])
			cl->downloadBlocks[curindex] = (unsigned char *)Z_Malloc( MAX_DOWNLOAD_BLKSIZE, TAG_DOWNLOAD, qtrue );

		cl->downloadBlockSize[curindex] = FS_Read( cl->downloadBlocks[curindex], MAX_DOWNLOAD_BLKSIZE, cl->download );

		if (cl->downloadBlockSize[curindex] < 0) {
			// EOF right now
			cl->downloadCount = cl->downloadSize;
			break;
		}

		cl->downloadCount += cl->downloadBlockSize[curindex];

		// Load in next block
		cl->downloadCurrentBlock++;
	}

	// Check to see if we have eof condition and add the EOF block
	if (cl->downloadCount == cl->downloadSize &&
		!cl->downloadEOF &&
		cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW) {

		cl->downloadBlockSize[cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW] = 0;
		cl->downloadCurrentBlock++;

		cl->downloadEOF = qtrue;  // We have added the EOF block
	}

	// Loop up to window size times based on how many blocks we can fit in the
	// client snapMsec and rate

	// based on the rate, how many bytes can we fit in the snapMsec time of the client
	// normal rate / snapshotMsec calculation
	rate = cl->rate;
	if ( sv_maxRate->integer ) {
		if ( sv_maxRate->integer < 1000 ) {
			Cvar_Set( "sv_MaxRate", "1000" );
		}
		if ( sv_maxRate->integer < rate ) {
			rate = sv_maxRate->integer;
		}
	}

	if (!rate) {
		blockspersnap = 1;
	} else {
		blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) /
			MAX_DOWNLOAD_BLKSIZE;
	}

	if (blockspersnap < 0)
		blockspersnap = 1;

	while (blockspersnap--) {

		// Write out the next section of the file, if we have already reached our window,
		// automatically start retransmitting

		if (cl->downloadClientBlock == cl->downloadCurrentBlock)
			return; // Nothing to transmit

		if (cl->downloadXmitBlock == cl->downloadCurrentBlock) {
			// We have transmitted the complete window, should we start resending?

			//FIXME:  This uses a hardcoded one second timeout for lost blocks
			//the timeout should be based on client rate somehow
			if (svs.time - cl->downloadSendTime > 1000)
				cl->downloadXmitBlock = cl->downloadClientBlock;
			else
				return;
		}

		// Send current block
		curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW);

		MSG_WriteByte( msg, svc_download );
		MSG_WriteShort( msg, cl->downloadXmitBlock );

		// block zero is special, contains file size
		if ( cl->downloadXmitBlock == 0 )
			MSG_WriteLong( msg, cl->downloadSize );
 
		MSG_WriteShort( msg, cl->downloadBlockSize[curindex] );

		// Write the block
		if ( cl->downloadBlockSize[curindex] ) {
			MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] );
		}

		Com_DPrintf( "clientDownload: %d : writing block %d\n", cl - svs.clients, cl->downloadXmitBlock );

		// Move on to the next block
		// It will get sent with next snap shot.  The rate will keep us in line.
		cl->downloadXmitBlock++;

		cl->downloadSendTime = svs.time;
	}
}
开发者ID:Chedo,项目名称:OpenJK,代码行数:101,代码来源:sv_client.cpp


示例8: 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);
//.........这里部分代码省略.........
开发者ID:Chedo,项目名称:OpenJK,代码行数:101,代码来源:sv_client.cpp


示例9: CL_WritePacket

/*
===================
CL_WritePacket

Create and send the command packet to the server
Including both the reliable commands and the usercmds

A client packet will contain something like:

4 sequence number
2 qport
4 serverid
4 acknowledged sequence number
4 clc.serverCommandSequence
<optional reliable commands>
1 clc_move or clc_moveNoDelta
1 command count
<count * usercmds>

===================
*/
void CL_WritePacket()
{
	msg_t     buf;
	byte      data[ MAX_MSGLEN ];
	int       i, j;
	usercmd_t *cmd, *oldcmd;
	usercmd_t nullcmd;
	int       packetNum;
	int       oldPacketNum;
	int       count;

	// don't send anything if playing back a demo
	if ( clc.demoplaying || cls.state == CA_CINEMATIC )
	{
		return;
	}

	memset( &nullcmd, 0, sizeof( nullcmd ) );
	oldcmd = &nullcmd;

	MSG_Init( &buf, data, sizeof( data ) );

	MSG_Bitstream( &buf );
	// write the current serverId so the server
	// can tell if this is from the current gameState
	MSG_WriteLong( &buf, cl.serverId );

	// write the last message we received, which can
	// be used for delta compression, and is also used
	// to tell if we dropped a gamestate
	MSG_WriteLong( &buf, clc.serverMessageSequence );

	// write the last reliable message we received
	MSG_WriteLong( &buf, clc.serverCommandSequence );

	// write any unacknowledged clientCommands
	// NOTE TTimo: if you verbose this, you will see that there are quite a few duplicates
	// typically several unacknowledged cp or userinfo commands stacked up
	for ( i = clc.reliableAcknowledge + 1; i <= clc.reliableSequence; i++ )
	{
		MSG_WriteByte( &buf, clc_clientCommand );
		MSG_WriteLong( &buf, i );
		MSG_WriteString( &buf, clc.reliableCommands[ i & ( MAX_RELIABLE_COMMANDS - 1 ) ] );
	}

	// we want to send all the usercmds that were generated in the last
	// few packet, so even if a couple packets are dropped in a row,
	// all the cmds will make it to the server
	if ( cl_packetdup->integer < 0 )
	{
		Cvar_Set( "cl_packetdup", "0" );
	}
	else if ( cl_packetdup->integer > 5 )
	{
		Cvar_Set( "cl_packetdup", "5" );
	}

	oldPacketNum = ( clc.netchan.outgoingSequence - 1 - cl_packetdup->integer ) & PACKET_MASK;
	count = cl.cmdNumber - cl.outPackets[ oldPacketNum ].p_cmdNumber;

	if ( count > MAX_PACKET_USERCMDS )
	{
		count = MAX_PACKET_USERCMDS;
		Com_Printf( "MAX_PACKET_USERCMDS" );
	}

#ifdef USE_VOIP

	if ( clc.voipOutgoingDataSize > 0 )
	{
		if ( ( clc.voipFlags & VOIP_SPATIAL ) || Com_IsVoipTarget( clc.voipTargets, sizeof( clc.voipTargets ), -1 ) )
		{
			MSG_WriteByte( &buf, clc_voip );
			MSG_WriteByte( &buf, clc.voipOutgoingGeneration );
			MSG_WriteLong( &buf, clc.voipOutgoingSequence );
			MSG_WriteByte( &buf, clc.voipOutgoingDataFrames );
			MSG_WriteData( &buf, clc.voipTargets, sizeof( clc.voipTargets ) );
			MSG_WriteByte( &buf, clc.voipFlags );
			MSG_WriteShort( &buf, clc.voipOutgoingDataSize );
//.........这里部分代码省略.........
开发者ID:norfenstein,项目名称:unvqx,代码行数:101,代码来源:cl_input.cpp


示例10: SV_WriteSnapshotToClient


//.........这里部分代码省略.........

	if ( oldframe == NULL ) {
		if ( client->demo.demowaiting ) {
			// this is a non-delta frame, so we can delta against it in the demo
			client->demo.minDeltaFrame = client->netchan.outgoingSequence;
		}
		client->demo.demowaiting = qfalse;
	}

	MSG_WriteByte (msg, svc_snapshot);

	// NOTE, MRE: now sent at the start of every message from server to client
	// let the client know which reliable clientCommands we have received
	//MSG_WriteLong( msg, client->lastClientCommand );

	// send over the current server time so the client can drift
	// its view of time to try to match
	if( client->oldServerTime &&
		!( client->demo.demorecording && client->demo.isBot ) ) {
		// The server has not yet got an acknowledgement of the
		// new gamestate from this client, so continue to send it
		// a time as if the server has not restarted. Note from
		// the client's perspective this time is strictly speaking
		// incorrect, but since it'll be busy loading a map at
		// the time it doesn't really matter.
		MSG_WriteLong (msg, sv.time + client->oldServerTime);
	} else {
		MSG_WriteLong (msg, sv.time);
	}

	// what we are delta'ing from
	MSG_WriteByte (msg, lastframe);

	snapFlags = svs.snapFlagServerBit;
	if ( client->rateDelayed ) {
		snapFlags |= SNAPFLAG_RATE_DELAYED;
	}
	if ( client->state != CS_ACTIVE ) {
		snapFlags |= SNAPFLAG_NOT_ACTIVE;
	}

	MSG_WriteByte (msg, snapFlags);

	// send over the areabits
	MSG_WriteByte (msg, frame->areabytes);
	MSG_WriteData (msg, frame->areabits, frame->areabytes);

	// delta encode the playerstate
	if ( oldframe ) {
#ifdef _ONEBIT_COMBO
		MSG_WriteDeltaPlayerstate( msg, &oldframe->ps, &frame->ps, frame->pDeltaOneBit, frame->pDeltaNumBit );
#else
		MSG_WriteDeltaPlayerstate( msg, &oldframe->ps, &frame->ps );
#endif
		if (frame->ps.m_iVehicleNum)
		{ //then write the vehicle's playerstate too
			if (!oldframe->ps.m_iVehicleNum)
			{ //if last frame didn't have vehicle, then the old vps isn't gonna delta
				//properly (because our vps on the client could be anything)
#ifdef _ONEBIT_COMBO
				MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, NULL, NULL, qtrue );
#else
				MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, qtrue );
#endif
			}
			else
			{
#ifdef _ONEBIT_COMBO
				MSG_WriteDeltaPlayerstate( msg, &oldframe->vps, &frame->vps, frame->pDeltaOneBitVeh, frame->pDeltaNumBitVeh, qtrue );
#else
				MSG_WriteDeltaPlayerstate( msg, &oldframe->vps, &frame->vps, qtrue );
#endif
			}
		}
	} else {
#ifdef _ONEBIT_COMBO
		MSG_WriteDeltaPlayerstate( msg, NULL, &frame->ps, NULL, NULL );
#else
		MSG_WriteDeltaPlayerstate( msg, NULL, &frame->ps );
#endif
		if (frame->ps.m_iVehicleNum)
		{ //then write the vehicle's playerstate too
#ifdef _ONEBIT_COMBO
			MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, NULL, NULL, qtrue );
#else
			MSG_WriteDeltaPlayerstate( msg, NULL, &frame->vps, qtrue );
#endif
		}
	}

	// delta encode the entities
	SV_EmitPacketEntities (oldframe, frame, msg);

	// padding for rate debugging
	if ( sv_padPackets->integer ) {
		for ( i = 0 ; i < sv_padPackets->integer ; i++ ) {
			MSG_WriteByte (msg, svc_nop);
		}
	}
}
开发者ID:LeadGuitar,项目名称:OpenJK,代码行数:101,代码来源:sv_snapshot.cpp


示例11: SV_WriteSnapshotToClient

/*
==================
SV_WriteSnapshotToClient
==================
*/
static void SV_WriteSnapshotToClient(client_t *client, msg_t *msg)
{
	clientSnapshot_t *frame, *oldframe;
	int              lastframe;
	int              snapFlags;

	// this is the snapshot we are creating
	frame = &client->frames[client->netchan.outgoingSequence & PACKET_MASK];

	// try to use a previous frame as the source for delta compressing the snapshot
	if (client->deltaMessage <= 0 || client->state != CS_ACTIVE)
	{
		// client is asking for a retransmit
		oldframe  = NULL;
		lastframe = 0;
	}
	else if (client->netchan.outgoingSequence - client->deltaMessage >= (PACKET_BACKUP - 3))
	{
		// client hasn't gotten a good message through in a long time
		Com_DPrintf("%s: Delta request from out of date packet.\n", client->name);
		oldframe  = NULL;
		lastframe = 0;
	}
	else
	{
		// we have a valid snapshot to delta from
		oldframe  = &client->frames[client->deltaMessage & PACKET_MASK];
		lastframe = client->netchan.outgoingSequence - client->deltaMessage;

		// the snapshot's entities may still have rolled off the buffer, though
		if (oldframe->first_entity <= svs.nextSnapshotEntities - svs.numSnapshotEntities)
		{
			Com_DPrintf("%s: Delta request from out of date entities.\n", client->name);
			oldframe  = NULL;
			lastframe = 0;
		}
	}

	MSG_WriteByte(msg, svc_snapshot);

	// NOTE, MRE: now sent at the start of every message from server to client
	// let the client know which reliable clientCommands we have received
	//MSG_WriteLong( msg, client->lastClientCommand );

	// send over the current server time so the client can drift
	// its view of time to try to match
	MSG_WriteLong(msg, svs.time);

	// what we are delta'ing from
	MSG_WriteByte(msg, lastframe);

	snapFlags = svs.snapFlagServerBit;
	if (client->rateDelayed)
	{
		snapFlags |= SNAPFLAG_RATE_DELAYED;
	}
	if (client->state != CS_ACTIVE)
	{
		snapFlags |= SNAPFLAG_NOT_ACTIVE;
	}

	MSG_WriteByte(msg, snapFlags);

	// send over the areabits
	MSG_WriteByte(msg, frame->areabytes);
	MSG_WriteData(msg, frame->areabits, frame->areabytes);

	//{
	//int sz = msg->cursize;
	//int usz = msg->uncompsize;

	// delta encode the playerstate
	if (oldframe)
	{
		MSG_WriteDeltaPlayerstate(msg, &oldframe->ps, &frame->ps);
	}
	else
	{
		MSG_WriteDeltaPlayerstate(msg, NULL, &frame->ps);
	}

	//Com_Printf( "Playerstate delta size: %f\n", ((msg->cursize - sz) * sv_fps->integer) / 8.f );
	//}

	// delta encode the entities
	SV_EmitPacketEntities(oldframe, frame, msg);

	// padding for rate debugging
	if (sv_padPackets->integer)
	{
		int i;

		for (i = 0 ; i < sv_padPackets->integer ; i++)
		{
			MSG_WriteByte(msg, svc_nop);
//.........这里部分代码省略.........
开发者ID:scenna,项目名称:etlegacy,代码行数:101,代码来源:sv_snapshot.c


示例12: demoCutWriteDemoHeader

void demoCutWriteDemoHeader(fileHandle_t f, clientConnection_t *clcCut, clientActive_t *clCut) {
	byte			bufData[MAX_MSGLEN];
	msg_t			buf;
	int				i;
	int				len;
	entityState_t	*ent;
	entityState_t	nullstate;
	char			*s;
	// 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, clcCut->reliableSequence);
	MSG_WriteByte(&buf, svc_gamestate);
	MSG_WriteLong(&buf, clcCut->serverCommandSequence);
	// configstrings
	for (i = 0; i < MAX_CONFIGSTRINGS; i++) {
		if (!clCut->gameState.stringOffsets[i]) {
			continue;
		}
		s = clCut->gameState.stringData + clCut->gameState.stringOffsets[i];
		MSG_WriteByte(&buf, svc_configstring);
		MSG_WriteShort(&buf, i);
		MSG_WriteBigString(&buf, s);
	}
	// baselines
	Com_Memset(&nullstate, 0, sizeof(nullstate));
	for (i = 0; i < MAX_GENTITIES ; i++) {
		ent = &clCut->entityBaselines[i];
		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, clcCut->clientNum);
	// write the checksum feed
	MSG_WriteLong(&buf, clcCut->checksumFeed);
	// RMG stuff
	if ( clcCut->rmgHeightMapSize ) {
		// Height map
		MSG_WriteShort(&buf, (unsigned short)clcCut->rmgHeightMapSize);
		MSG_WriteBits(&buf, 0, 1 );
		MSG_WriteData(&buf, clcCut->rmgHeightMap, clcCut->rmgHeightMapSize);
		// Flatten map
		MSG_WriteShort(&buf, (unsigned short)clcCut->rmgHeightMapSize);
		MSG_WriteBits(&buf, 0, 1 );
		MSG_WriteData(&buf, clcCut->rmgFlattenMap, clcCut->rmgHeightMapSize);
		// Seed
		MSG_WriteLong (&buf, clcCut->rmgSeed);
		// Automap symbols
		MSG_WriteShort (&buf, (unsigned short)clcCut->rmgAutomapSymbolCount);
		for (i = 0; i < clcCut->rmgAutomapSymbolCount; i ++) {
			MSG_WriteByte(&buf, (unsigned char)clcCut->rmgAutomapSymbols[i].mType);
			MSG_WriteByte(&buf, (unsigned char)clcCut->rmgAutomapSymbols[i].mSide);
			MSG_WriteLong(&buf, (long)clcCut->rmgAutomapSymbols[i].mOrigin[0]);
			MSG_WriteLong(&buf, (long)clcCut->rmgAutomapSymbols[i].mOrigin[1]);
		}
	} else {
		MSG_WriteShort (&buf, 0);
	}
	// finished writing the client packet
	MSG_WriteByte(&buf, svc_EOF);
	// write it to the demo file
	len = LittleLong(clcCut->serverMessageSequence - 1);
	FS_Write(&len, 4, f);
	len = LittleLong(buf.cursize);
	FS_Write(&len, 4, f);
	FS_Write(buf.data, buf.cursize, f);
}
开发者ID:deathsythe47,项目名称:jaMME,代码行数:73,代码来源:cl_demos_cut.cpp


示例13: SV_WriteSnapshotToClient

/*
==================
SV_WriteSnapshotToClient
==================
*/
static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg ) {
	clientSnapshot_t	*frame, *oldframe;
	int					lastframe;
	int					snapFlags;

	// this is the snapshot we are creating
	frame = &client->frames[ client->netchan.outgoingSequence & PACKET_MASK ];

	// try to use a previous frame as the source for delta compressing the snapshot
	if ( client->deltaMessage <= 0 || client->state != CS_ACTIVE ) {
		// client is asking for a retransmit
		oldframe = NULL;
		lastframe = 0;
	} else if ( client->netchan.outgoingSequence - client->deltaMessage 
		>= (PACKET_BACKUP - 3) ) {
		// client hasn't gotten a good message through in a long time
		Com_DPrintf ("%s: Delta request from out of date packet.\n", client->name);
		oldframe = NULL;
		lastframe = 0;
	} else {
		// we have a valid snapshot to delta from
		oldframe = &client->frames[ client->deltaMessage & PACKET_MASK ];
		lastframe = client->netchan.outgoingSequence - client->deltaMessage;

		// the snapshot's entities may still have rolled off the buffer, though
		if ( oldframe->first_entity <= svs.nextSnapshotEntities - svs.numSnapshotEntities ) {
			Com_DPrintf ("%s: Delta request from out of date entities.\n", client->name);
			oldframe = NULL;
			lastframe = 0;
		}
	}

	MSG_WriteByte (msg, svc_snapshot);

	// let the client know which reliable clientCommands we have received
	MSG_WriteLong( msg, client->lastClientCommand );

	// send over the current server time so the client can drift
	// its view of time to try to match
	MSG_WriteLong (msg, sv.time);

	// we must write a message number, because recorded demos won't have
	// the same network message sequences
	MSG_WriteLong (msg, client->netchan.outgoingSequence );
	MSG_WriteByte (msg, lastframe);				// what we are delta'ing from
	MSG_WriteLong (msg, client->cmdNum);		// we have executed up to here

	snapFlags = client->rateDelayed | ( client->droppedCommands << 1 );
	client->droppedCommands = 0;

	MSG_WriteByte (msg, snapFlags);

	// send over the areabits
	MSG_WriteByte (msg, frame->areabytes);
	MSG_WriteData (msg, frame->areabits, frame->areabytes);

	// delta encode the playerstate
	if ( oldframe ) {
		MSG_WriteDeltaPlayerstate( msg, &oldframe->ps, &frame->ps );
	} else {
		MSG_WriteDeltaPlayerstate( msg, NULL, &frame->ps );
	}

	// delta encode the entities
	SV_EmitPacketEntities (oldframe, frame, msg);
}
开发者ID:CairnTrenor,项目名称:OpenJK,代码行数:71,代码来源:sv_snapshot.cpp


示例14: demoCutWriteDeltaSnapshot

void demoCutWriteDeltaSnapshot(int firstServerCommand, fileHandle_t f, qboolean forceNonDelta, clientConnection_t *clcCut, clientActive_t *clCut) {
	msg_t			msgImpl, *msg = &msgImpl;
	byte			msgData[MAX_MSGLEN];
	clSnapshot_t	*frame, *oldframe;
	int				lastframe = 0;
	int				snapFlags;
	MSG_Init(msg, msgData, sizeof(msgData));
	MSG_Bitstream(msg);
	MSG_WriteLong(msg, clcCut->reliableSequence);
	// copy over any commands
	for (int serverCommand = firstServerCommand; serverCommand <= clcCut->serverCommandSequence; serverCommand++) {
		char *command = clcCut->serverCommands[serverCommand & (MAX_RELIABLE_COMMANDS - 1)];
		MSG_WriteByte(msg, svc_serverCommand);
		MSG_WriteLong(msg, serverCommand/* + serverCommandOffset*/);
		MSG_WriteString(msg, command);
	}
	// this is the snapshot we are creating
	frame = &clCut->snap;
	if (clCut->snap.messageNum > 0 && !forceNonDelta) {
		lastframe = 1;
		oldframe = &clCut->snapshots[(clCut->snap.messageNum - 1) & PACKET_MASK]; // 1 frame previous
		if (!oldframe->valid) {
			// not yet set
			lastframe = 0;
			oldframe = NULL;
		}
	} else {
		lastframe = 0;
		oldframe = NULL;
	}
	MSG_WriteByte(msg, svc_snapshot);
	// send over the current server time so the client can drift
	// its view of time to try to match
	MSG_WriteLong(msg, frame->serverTime);
	// what we are delta'ing from
	MSG_WriteByte(msg, lastframe);
	snapFlags = frame->snapFlags;
	MSG_WriteByte(msg, snapFlags);
	// send over the areabits
	MSG_WriteByte(msg, sizeof(frame->areamask));
	MSG_WriteData(msg, frame->areamask, sizeof(frame->areamask));
	// delta encode the playerstate
	if (oldframe) {
#ifdef _ONEBIT_COMBO
		MSG_WriteDeltaPlayerstate(msg, &oldframe->ps, &frame->ps, frame->pDeltaOneBit, frame->pDeltaNumBit);
#else
		MSG_WriteDeltaPlayerstate(msg, &oldframe->ps, &frame->ps);
#endif
		if (frame->ps.m_iVehicleNum) {
		//then write the vehicle's playerstate too
			if (!oldframe->ps.m_iVehicleNum) {
			//if last frame didn't have vehicle, then the old vps isn't gonna delta
			//properly (because our vps on the client could be anything)
#ifdef _ONEBIT_COMBO
				MSG_WriteDeltaPlayerstate(msg, NULL, &frame->vps, NULL, NULL, qtrue);
#else
				MSG_WriteDeltaPlayerstate(msg, NULL, &frame->vps, qtrue);
#endif
			} else {
#ifdef _ONEBIT_COMBO
				MSG_WriteDeltaPlayerstate(msg, &oldframe->vps, &frame->vps, frame->pDeltaOneBitVeh, frame->pDeltaNumBitVeh, qtrue);
#else
				MSG_WriteDeltaPlayerstate(msg, &oldframe->vps, &frame->vps, qtrue);
#endif
			}
		}
	} else {
#ifdef _ONEBIT_COMBO
		MSG_WriteDeltaPlayerstate(msg, NULL, &frame->ps, NULL, NULL);
#else
		MSG_WriteDeltaPlayerstate(msg, NULL, &frame->ps);
#endif
		if (frame->ps.m_iVehicleNum) {
		//then write the vehicle's playerstate too
#ifdef _ONEBIT_COMBO
			MSG_WriteDeltaPlayerstate(msg, NULL, &frame->vps, NULL, NULL, qtrue);
#else
			MSG_WriteDeltaPlayerstate(msg, NULL, &frame->vps, qtrue);
#endif
		}
	}
	// delta encode the entities
	demoCutEmitPacketEntities(oldframe, frame, msg, clCut);
	MSG_WriteByte(msg, svc_EOF);
	demoCutWriteDemoMessage(msg, f, clcCut);
}
开发者ID:deathsythe47,项目名称:jaMME,代码行数:86,代码来源:cl_demos_cut.cpp


示例15: 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 );
	}
}
开发者ID:YPowTecH,项目名称:OpenJK,代码行数:95,代码来源:sv_client.cpp


示例16: SV_WriteDownloadToClient


//.........这里部分代码省略.........
		curindex = (cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW);

		if (!cl->downloadBlocks[curindex])
			cl->downloadBlocks[curindex] = Z_Malloc( MAX_DOWNLOAD_BLKSIZE );

		cl->downloadBlockSize[curindex] = FS_Read( cl->downloadBlocks[curindex], MAX_DOWNLOAD_BLKSIZE, cl->download );

		if (cl->downloadBlockSize[curindex] < 0) {
			// EOF right now
			cl->downloadCount = cl->downloadSize;
			break;
		}

		cl->downloadCount += cl->downloadBlockSize[curindex];

		// Load in next block
		cl->downloadCurrentBlock++;
	}

	// Check to see if we have eof condition and add the EOF block
	if (cl->downloadCount == cl->downloadSize &&
		!cl->downloadEOF &&
		cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW) {

		cl->downloadBlockSize[cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW] = 0;
		cl->downloadCurrentBlock++;

		cl->downloadEOF = qtrue;  // We have added the EOF block
	}

	// Loop up to window size times based on how many blocks we can fit in the
	// client snapMsec and rate

	// based on the rate, how many bytes can we fit in the snapMsec time of the client
	// normal rate / snapshotMsec calculation
	rate = cl->rate;
	if ( sv_maxRate->integer ) {
		if ( sv_maxRate->integer < 1000 ) {
			Cvar_Set( "sv_MaxRate", "1000" );
		}
		if ( sv_maxRate->integer < rate ) {
			rate = sv_maxRate->integer;
		}
	}

	if (!rate) {
		blockspersnap = 1;
	} else {
		blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) /
			MAX_DOWNLOAD_BLKSIZE;
	}

	if (blockspersnap < 0)
		blockspersnap = 1;

	while (blockspersnap--) {

		// Write out the next section of the file, if we have already reached our window,
		// automatically start retransmitting

		if (cl->downloadClientBlock == cl->downloadCurrentBlock)
			return; // Nothing to transmit

		if (cl->downloadXmitBlock == cl->downloadCurrentBlock) {
			// We have transmitted the complete window, should we start resending?

			//FIXME:  This uses a hardcoded one second timeout for lost blocks
			//the timeout should be based on client rate somehow
			if (svs.time - cl->downloadSendTime > 1000)
				cl->downloadXmitBlock = cl->downloadClientBlock;
			else
				return;
		}

		// Send current block
		curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW);

		MSG_WriteByte( msg, svc_download );
		MSG_WriteShort( msg, cl->downloadXmitBlock );

		// block zero is special, contains file size
		if ( cl->downloadXmitBlock == 0 )
			MSG_WriteLong( msg, cl->downloadSize );
 
		MSG_WriteShort( msg, cl->downloadBlockSize[curindex] );

		// Write the block
		if ( cl->downloadBlockSize[curindex] ) {
			MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] );
		}

		Com_DPrintf( "clientDownload: %d : writing block %d\n", cl - svs.clients, cl->downloadXmitBlock );

		// Move on to the next block
		// It will get sent with next snap shot.  The rate will keep us in line.
		cl->downloadXmitBlock++;

		cl->downloadSendTime = svs.time;
	}
}
开发者ID:Fighter19,项目名称:Quake3PSP-mirror,代码行数:101,代码来源:sv_client.c


示例17: SV_WriteDownloadToClient


//.........这里部分代码省略.........
	     !cl->downloadEOF && cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW )
	{
		cl->downloadBlockSize[ cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW ] = 0;
		cl->downloadCurrentBlock++;

		cl->downloadEOF = true; // We have added the EOF block
	}

	// Loop up to window size times based on how many blocks we can fit in the
	// client snapMsec and rate

	// based on the rate, how many bytes can we fit in the snapMsec time of the client
	rate = cl->rate;

	// show_bug.cgi?id=509
	// for autodownload, we use a separate max rate value
	// we do this everytime because the client might change its rate during the download
	if ( sv_dl_maxRate->integer < rate )
	{
		rate = sv_dl_maxRate->integer;

		if ( bTellRate )
		{
			Log::Notice( "'%s' downloading at sv_dl_maxrate (%d)\n", cl->name, sv_dl_maxRate->integer );
		}
	}
	else if ( bTellRate )
	{
		Log::Notice( "'%s' downloading at rate %d\n", cl->name, rate );
	}

	if ( !rate )
	{
		blockspersnap = 1;
	}
	else
	{
		blockspersnap = ( ( rate * cl->snapshotMsec ) / 1000 + MAX_DOWNLOAD_BLKSIZE ) / MAX_DOWNLOAD_BLKSIZE;
	}

	if ( blockspersnap < 0 )
	{
		blockspersnap = 1;
	}

	while ( blockspersnap-- )
	{
		// Write out the next section of the file, if we have already reached our window,
		// automatically start retransmitting

		if ( cl->downloadClientBlock == cl->downloadCurrentBlock )
		{
			return; // Nothing to transmit
		}

		if ( cl->downloadXmitBlock == cl->downloadCurrentBlock )
		{
			// We have transmitted the complete window, should we start resending?

			//FIXME:  This uses a hardcoded one second timeout for lost blocks
			//the timeout should be based on client rate somehow
			if ( svs.time - cl->downloadSendTime > 1000 )
			{
				cl->downloadXmitBlock = cl->downloadClientBlock;
			}
			else
			{
				return;
			}
		}

		// Send current block
		curindex = ( cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW );

		MSG_WriteByte( msg, svc_download );
		MSG_WriteShort( msg, cl->downloadXmitBlock );

		// block zero is special, contains file size
		if ( cl->downloadXmitBlock == 0 )
		{
			MSG_WriteLong( msg, cl->downloadSize );
		}

		MSG_WriteShort( msg, cl->downloadBlockSize[ curindex ] );

		 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ MSG_WriteDeltaEntity函数代码示例发布时间:2022-05-30
下一篇:
C++ MSG_WriteBits函数代码示例发布时间:2022-05-30
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap