Exemplo n.º 1
0
/*
===============
Netchan_Transmit

tries to send an unreliable message to a connection, and handles the
transmition / retransmition of the reliable messages.

A 0 length will still generate a packet and deal with the reliable messages.
================
*/
void Netchan_Transmit (netchan_t *chan, int length, byte *data)
{
	sizebuf_t	send;
	byte		send_buf[MAX_MSGLEN];
	qboolean	send_reliable;
	unsigned	w1, w2;

// check for message overflow
	if (chan->message.overflowed)
	{
		chan->fatal_error = true;
		Com_Printf ("%s:Outgoing message overflow\n"
			, NET_AdrToString (chan->remote_address));
		return;
	}

	send_reliable = Netchan_NeedReliable (chan);

	if (!chan->reliable_length && chan->message.cursize)
	{
		memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
		chan->reliable_length = chan->message.cursize;
		chan->message.cursize = 0;
		chan->reliable_sequence ^= 1;
	}


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

	w1 = ( chan->outgoing_sequence & ~(1<<31) ) | (send_reliable<<31);
	w2 = ( chan->incoming_sequence & ~(1<<31) ) | (chan->incoming_reliable_sequence<<31);

	chan->outgoing_sequence++;
	chan->last_sent = curtime;

	MSG_WriteLong (&send, w1);
	MSG_WriteLong (&send, w2);

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

// copy the reliable message to the packet first
	if (send_reliable)
	{
		SZ_Write (&send, chan->reliable_buf, chan->reliable_length);
		chan->last_reliable_sequence = chan->outgoing_sequence;
	}
	
// add the unreliable part if space is available
	if (send.maxsize - send.cursize >= length)
		SZ_Write (&send, data, length);
	else
		Com_Printf ("Netchan_Transmit: dumped unreliable\n");

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

	if (showpackets->value)
	{
		if (send_reliable)
			Com_Printf ("send %4i : s=%i reliable=%i ack=%i rack=%i\n"
				, send.cursize
				, chan->outgoing_sequence - 1
				, chan->reliable_sequence
				, chan->incoming_sequence
				, chan->incoming_reliable_sequence);
		else
			Com_Printf ("send %4i : s=%i ack=%i rack=%i\n"
				, send.cursize
				, chan->outgoing_sequence - 1
				, chan->incoming_sequence
				, chan->incoming_reliable_sequence);
	}
}
Exemplo n.º 2
0
/*
 * @brief Tries to send an unreliable message to a connection, and handles the
 * transmission / retransmission of the reliable messages.
 *
 * A 0 size will still generate a packet and deal with the reliable messages.
 */
void Netchan_Transmit(net_chan_t *chan, byte *data, size_t len) {
	mem_buf_t send;
	byte send_buffer[MAX_MSG_SIZE];

	// check for message overflow
	if (chan->message.overflowed) {
		chan->fatal_error = true;
		Com_Print("%s:Outgoing message overflow\n", Net_NetaddrToString(&chan->remote_address));
		return;
	}

	const _Bool send_reliable = Netchan_NeedReliable(chan);

	if (!chan->reliable_size && chan->message.size) {
		memcpy(chan->reliable_buffer, chan->message_buffer, chan->message.size);
		chan->reliable_size = chan->message.size;
		chan->message.size = 0;
		chan->reliable_sequence ^= 1;
	}

	// write the packet header
	Mem_InitBuffer(&send, send_buffer, sizeof(send_buffer));

	const uint32_t w1 = (chan->outgoing_sequence & ~(1 << 31)) | (send_reliable << 31);
	const uint32_t w2 = (chan->incoming_sequence & ~(1 << 31)) | (chan->incoming_reliable_sequence
			<< 31);

	chan->outgoing_sequence++;
	chan->last_sent = quake2world.time;

	Net_WriteLong(&send, w1);
	Net_WriteLong(&send, w2);

	// send the qport if we are a client
	if (chan->source == NS_UDP_CLIENT)
		Net_WriteByte(&send, chan->qport);

	// copy the reliable message to the packet first
	if (send_reliable) {
		Mem_WriteBuffer(&send, chan->reliable_buffer, chan->reliable_size);
		chan->last_reliable_sequence = chan->outgoing_sequence;
	}

	// add the unreliable part if space is available
	if (send.max_size - send.size >= len)
		Mem_WriteBuffer(&send, data, len);
	else
		Com_Warn("Netchan_Transmit: dumped unreliable\n");

	// send the datagram
	Net_SendDatagram(chan->source, &chan->remote_address, send.data, send.size);

	if (net_showpackets->value) {
		if (send_reliable)
			Com_Print("Send %u bytes: s=%i reliable=%i ack=%i rack=%i\n", (uint32_t) send.size,
					chan->outgoing_sequence - 1, chan->reliable_sequence, chan->incoming_sequence,
					chan->incoming_reliable_sequence);
		else
			Com_Print("Send %u bytes : s=%i ack=%i rack=%i\n", (uint32_t) send.size,
					chan->outgoing_sequence - 1, chan->incoming_sequence,
					chan->incoming_reliable_sequence);
	}
}