コード例 #1
0
ファイル: cl_cmd.c プロジェクト: jayschwa/quake2world
/*
 * @brief Pumps the command cycle, sending the most recently gathered movement
 * to the server.
 */
void Cl_SendCmd(void) {
	mem_buf_t buf;
	byte data[128];

	if (cls.state <= CL_CONNECTING)
		return;

	if (cls.state == CL_CONNECTED) {
		// send any reliable messages and / or don't timeout
		if (cls.net_chan.message.size || cls.real_time - cls.net_chan.last_sent > 1000)
			Netchan_Transmit(&cls.net_chan, NULL, 0);
		return;
	}

	// send a user info update if needed
	if (cvar_user_info_modified) {
		Net_WriteByte(&cls.net_chan.message, CL_CMD_USER_INFO);
		Net_WriteString(&cls.net_chan.message, Cvar_UserInfo());

		cvar_user_info_modified = false;
	}

	// finalize the current command
	Cl_FinalizeCmd();

	// and write it out
	Mem_InitBuffer(&buf, data, sizeof(data));

	Net_WriteByte(&buf, CL_CMD_MOVE);

	// let the server know what the last frame we got was, so the next
	// message can be delta compressed
	if (!cl.frame.valid || (cls.demo_file && Fs_Tell(cls.demo_file) == 0))
		Net_WriteLong(&buf, -1); // no compression
	else
		Net_WriteLong(&buf, cl.frame.frame_num);

	// send this and the previous two cmds in the message, so
	// if the last packet was dropped, it can be recovered
	static user_cmd_t null_cmd;

	cl_cmd_t *cmd = &cl.cmds[(cls.net_chan.outgoing_sequence - 2) & CMD_MASK];
	Net_WriteDeltaUserCmd(&buf, &null_cmd, &cmd->cmd);

	user_cmd_t *old_cmd = &cmd->cmd;
	cmd = &cl.cmds[(cls.net_chan.outgoing_sequence - 1) & CMD_MASK];
	Net_WriteDeltaUserCmd(&buf, old_cmd, &cmd->cmd);

	old_cmd = &cmd->cmd;
	cmd = &cl.cmds[(cls.net_chan.outgoing_sequence) & CMD_MASK];
	Net_WriteDeltaUserCmd(&buf, old_cmd, &cmd->cmd);

	// deliver the message
	Netchan_Transmit(&cls.net_chan, buf.data, buf.size);

	cl.packet_counter++;

	// initialize the next command
	Cl_InitCmd();
}
コード例 #2
0
ファイル: info.cpp プロジェクト: BenJamesbabala/ViZDoom
static void SummonActor (int command, int command2, FCommandLine argv)
{
	if (CheckCheatmode ())
		return;

	if (argv.argc() > 1)
	{
		const PClass *type = PClass::FindClass (argv[1]);
		if (type == NULL)
		{
			Printf ("Unknown class '%s'\n", argv[1]);
			return;
		}
		Net_WriteByte (argv.argc() > 2 ? command2 : command);
		Net_WriteString (type->TypeName.GetChars());

		if (argv.argc () > 2) {
			Net_WriteWord (atoi (argv[2])); // angle
			if (argv.argc () > 3) Net_WriteWord (atoi (argv[3])); // TID
			else Net_WriteWord (0);
			if (argv.argc () > 4) Net_WriteByte (atoi (argv[4])); // special
			else Net_WriteByte (0);
			for(int i = 5; i < 10; i++) { // args[5]
				if(i < argv.argc()) Net_WriteLong (atoi (argv[i]));
				else Net_WriteLong (0);
			}
		}
	}
}
コード例 #3
0
ファイル: info.cpp プロジェクト: Accusedbold/zdoom
static void SummonActor (int command, int command2, FCommandLine argv)
{
	if (CheckCheatmode ())
		return;

	if (argv.argc() > 1)
	{
		PClassActor *type = PClass::FindActor(argv[1]);
		if (type == NULL)
		{
			Printf ("Unknown actor '%s'\n", argv[1]);
			return;
		}
		Net_WriteByte (argv.argc() > 2 ? command2 : command);
		Net_WriteString (type->TypeName.GetChars());

		if (argv.argc () > 2)
		{
			Net_WriteWord (atoi (argv[2])); // angle
			Net_WriteWord ((argv.argc() > 3) ? atoi(argv[3]) : 0); // TID
			Net_WriteByte ((argv.argc() > 4) ? atoi(argv[4]) : 0); // special
			for (int i = 5; i < 10; i++)
			{ // args[5]
				Net_WriteLong((i < argv.argc()) ? atoi(argv[i]) : 0);
			}
		}
	}
}
コード例 #4
0
/**
 * @brief Send data to the specified TCP stream.
 */
_Bool Net_SendStream(int32_t sock, const void *data, size_t len) {
	mem_buf_t buf;
	byte buffer[MAX_MSG_SIZE];

	Mem_InitBuffer(&buf, buffer, sizeof(buffer));

	// write the packet length
	Net_WriteLong(&buf, (int32_t) len);

	// and copy the payload
	Net_WriteData(&buf, data, len);

	ssize_t sent = 0;
	while ((size_t) sent < buf.size) {
		const ssize_t s = send(sock, (void *)(buf.data + sent), buf.size - sent, 0);
		if (s == -1) {
			if (Net_GetError() != EWOULDBLOCK) {
				Com_Warn("%s\n", Net_GetErrorString());
				return false;
			}
		}
		sent += s;
	}

	return sent == (ssize_t) buf.size;
}
コード例 #5
0
void D_SendServerInfoChange (const FBaseCVar *cvar, UCVarValue value, ECVarType type)
{
    size_t namelen;

    namelen = strlen (cvar->GetName ());

    Net_WriteByte (DEM_SINFCHANGED);
    Net_WriteByte ((BYTE)(namelen | (type << 6)));
    Net_WriteBytes ((BYTE *)cvar->GetName (), (int)namelen);
    switch (type)
    {
    case CVAR_Bool:
        Net_WriteByte (value.Bool);
        break;
    case CVAR_Int:
        Net_WriteLong (value.Int);
        break;
    case CVAR_Float:
        Net_WriteFloat (value.Float);
        break;
    case CVAR_String:
        Net_WriteString (value.String);
        break;
    default:
        break; // Silence GCC
    }
}
コード例 #6
0
ファイル: cl_cmd.c プロジェクト: jdolan/quetoo
/**
 * @brief Writes the most recent movement command(s) using delta-compression if available.
 */
static void Cl_WriteMovementCommand(mem_buf_t *buf) {
	static cl_cmd_t null_cmd;

	Net_WriteByte(buf, CL_CMD_MOVE);

	if (!cl.frame.valid || (cls.demo_file && Fs_Tell(cls.demo_file) == 0)) {
		Net_WriteLong(buf, -1);
	} else {
		Net_WriteLong(buf, cl.frame.frame_num);
	}

	cl_cmd_t *from = &null_cmd, *to = &cl.cmds[(cls.net_chan.outgoing_sequence - 2) & CMD_MASK];
	Net_WriteDeltaMoveCmd(buf, &from->cmd, &to->cmd);

	from = to; to = &cl.cmds[(cls.net_chan.outgoing_sequence - 1) & CMD_MASK];
	Net_WriteDeltaMoveCmd(buf, &from->cmd, &to->cmd);

	from = to;  to = &cl.cmds[(cls.net_chan.outgoing_sequence) & CMD_MASK];
	Net_WriteDeltaMoveCmd(buf, &from->cmd, &to->cmd);
}
コード例 #7
0
ファイル: net_chan.c プロジェクト: jayschwa/quake2world
/*
 * @brief Sends an out-of-band datagram
 */
void Netchan_OutOfBand(int32_t sock, const net_addr_t *addr, const void *data, size_t len) {
	mem_buf_t send;
	byte send_buffer[MAX_MSG_SIZE];

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

	Net_WriteLong(&send, -1); // -1 sequence means out of band
	Mem_WriteBuffer(&send, data, len);

	// send the datagram
	Net_SendDatagram(sock, addr, send.data, send.size);
}
コード例 #8
0
/**
 * @brief
 */
void Sv_WriteClientFrame(sv_client_t *client, mem_buf_t *msg) {
	sv_frame_t *frame, *delta_frame;
	int32_t delta_frame_num;

	// this is the frame we are creating
	frame = &client->frames[sv.frame_num & PACKET_MASK];

	if (client->last_frame < 0) {
		// client is asking for a retransmit
		delta_frame = NULL;
		delta_frame_num = -1;
	} else if (sv.frame_num - client->last_frame >= (PACKET_BACKUP - 3)) {
		// client hasn't gotten a good message through in a long time
		delta_frame = NULL;
		delta_frame_num = -1;
	} else {
		// we have a valid message to delta from
		delta_frame = &client->frames[client->last_frame & PACKET_MASK];
		delta_frame_num = client->last_frame;
	}

	Net_WriteByte(msg, SV_CMD_FRAME);
	Net_WriteLong(msg, sv.frame_num);
	Net_WriteLong(msg, delta_frame_num); // what we are delta'ing from
	Net_WriteByte(msg, client->suppress_count); // rate dropped packets
	client->suppress_count = 0;

	// send over the area bits
	Net_WriteByte(msg, frame->area_bytes);
	Net_WriteData(msg, frame->area_bits, frame->area_bytes);

	// delta encode the player state
	Sv_WritePlayerState(delta_frame, frame, msg);

	// delta encode the entities
	Sv_WriteEntities(delta_frame, frame, msg);
}
コード例 #9
0
ファイル: net_chan.c プロジェクト: jayschwa/quake2world
/*
 * @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);
	}
}