Example #1
0
static void *secure_unpack_sv_vote_status()
{
    static NETMSG_SV_VOTE_STATUS msg;
    msg.yes = msg_unpack_int();
    msg.no = msg_unpack_int();
    msg.pass = msg_unpack_int();
    msg.total = msg_unpack_int();
    if(msg.yes < 0 || msg.yes > MAX_CLIENTS) {
        msg_failed_on = "yes";
        return 0;
    }
    if(msg.no < 0 || msg.no > MAX_CLIENTS) {
        msg_failed_on = "no";
        return 0;
    }
    if(msg.pass < 0 || msg.pass > MAX_CLIENTS) {
        msg_failed_on = "pass";
        return 0;
    }
    if(msg.total < 0 || msg.total > MAX_CLIENTS) {
        msg_failed_on = "total";
        return 0;
    }
    return &msg;
}
Example #2
0
static void *secure_unpack_sv_emoticon()
{
	static NETMSG_SV_EMOTICON msg;
	msg.cid = msg_unpack_int();
	msg.emoticon = msg_unpack_int();
	if(msg.cid < 0 || msg.cid > MAX_CLIENTS-1) { msg_failed_on = "cid"; return 0; }
	if(msg.emoticon < 0 || msg.emoticon > NUM_EMOTICONS-1) { msg_failed_on = "emoticon"; return 0; }
	return &msg;
}
Example #3
0
static void *secure_unpack_sv_chat()
{
	static NETMSG_SV_CHAT msg;
	msg.team = msg_unpack_int();
	msg.cid = msg_unpack_int();
	msg.message = msg_unpack_string();
	if(msg.team < -1 || msg.team > 1) { msg_failed_on = "team"; return 0; }
	if(msg.cid < -1 || msg.cid > MAX_CLIENTS-1) { msg_failed_on = "cid"; return 0; }
	return &msg;
}
Example #4
0
static void *secure_unpack_cl_changeinfo()
{
	static NETMSG_CL_CHANGEINFO msg;
	msg.name = msg_unpack_string();
	msg.skin = msg_unpack_string();
	msg.use_custom_color = msg_unpack_int();
	msg.color_body = msg_unpack_int();
	msg.color_feet = msg_unpack_int();
	if(msg.use_custom_color < 0 || msg.use_custom_color > 1) { msg_failed_on = "use_custom_color"; return 0; }
	return &msg;
}
Example #5
0
static void *secure_unpack_sv_killmsg()
{
	static NETMSG_SV_KILLMSG msg;
	msg.killer = msg_unpack_int();
	msg.victim = msg_unpack_int();
	msg.weapon = msg_unpack_int();
	msg.mode_special = msg_unpack_int();
	if(msg.killer < 0 || msg.killer > MAX_CLIENTS-1) { msg_failed_on = "killer"; return 0; }
	if(msg.victim < 0 || msg.victim > MAX_CLIENTS-1) { msg_failed_on = "victim"; return 0; }
	if(msg.weapon < -3 || msg.weapon > NUM_WEAPONS-1) { msg_failed_on = "weapon"; return 0; }
	return &msg;
}
Example #6
0
static void *secure_unpack_cl_emoticon()
{
	static NETMSG_CL_EMOTICON msg;
	msg.emoticon = msg_unpack_int();
	if(msg.emoticon < 0 || msg.emoticon > NUM_EMOTICONS-1) { msg_failed_on = "emoticon"; return 0; }
	return &msg;
}
Example #7
0
static void *secure_unpack_sv_weaponpickup()
{
	static NETMSG_SV_WEAPONPICKUP msg;
	msg.weapon = msg_unpack_int();
	if(msg.weapon < 0 || msg.weapon > NUM_WEAPONS-1) { msg_failed_on = "weapon"; return 0; }
	return &msg;
}
Example #8
0
static void *secure_unpack_sv_soundglobal()
{
	static NETMSG_SV_SOUNDGLOBAL msg;
	msg.soundid = msg_unpack_int();
	if(msg.soundid < 0 || msg.soundid > NUM_SOUNDS-1) { msg_failed_on = "soundid"; return 0; }
	return &msg;
}
Example #9
0
static void *secure_unpack_cl_say()
{
	static NETMSG_CL_SAY msg;
	msg.team = msg_unpack_int();
	msg.message = msg_unpack_string();
	if(msg.team < 0 || msg.team > 1) { msg_failed_on = "team"; return 0; }
	return &msg;
}
Example #10
0
int msg_unpack_start(const void *data, int data_size, int *system)
{
	int msg;
	unpacker_reset(&msg_unpacker, (const unsigned char *)data, data_size);
	msg = msg_unpack_int();
	*system = msg&1;
	return msg>>1;
}
Example #11
0
static void *secure_unpack_cl_vote()
{
    static NETMSG_CL_VOTE msg;
    msg.vote = msg_unpack_int();
    if(msg.vote < -1 || msg.vote > 1) {
        msg_failed_on = "vote";
        return 0;
    }
    return &msg;
}
Example #12
0
static void *secure_unpack_cl_setteam()
{
    static NETMSG_CL_SETTEAM msg;
    msg.team = msg_unpack_int();
    if(msg.team < -1 || msg.team > 1) {
        msg_failed_on = "team";
        return 0;
    }
    return &msg;
}
Example #13
0
static void *secure_unpack_sv_vote_set()
{
    static NETMSG_SV_VOTE_SET msg;
    msg.timeout = msg_unpack_int();
    msg.description = msg_unpack_string();
    msg.command = msg_unpack_string();
    if(msg.timeout < 0 || msg.timeout > 60) {
        msg_failed_on = "timeout";
        return 0;
    }
    return &msg;
}
Example #14
0
static void server_process_client_packet(NETCHUNK *packet)
{
	int cid = packet->client_id;
	NETADDR addr;
	
	int sys;
	int msg = msg_unpack_start(packet->data, packet->data_size, &sys);
	
	if(clients[cid].state == SRVCLIENT_STATE_AUTH)
	{
		if(sys && msg == NETMSG_INFO)
		{
			char version[64];
			const char *password;
			str_copy(version, msg_unpack_string(), 64);
			if(strcmp(version, mods_net_version()) != 0)
			{
				/* OH F**K! wrong version, drop him */
				char reason[256];
				str_format(reason, sizeof(reason), "wrong version. server is running '%s' and client '%s'.", mods_net_version(), version);
				netserver_drop(net, cid, reason);
				return;
			}
			
			str_copy(clients[cid].name, msg_unpack_string(), MAX_NAME_LENGTH);
			str_copy(clients[cid].clan, msg_unpack_string(), MAX_CLANNAME_LENGTH);
			password = msg_unpack_string();
			
			if(config.password[0] != 0 && strcmp(config.password, password) != 0)
			{
				/* wrong password */
				netserver_drop(net, cid, "wrong password");
				return;
			}
			
			clients[cid].state = SRVCLIENT_STATE_CONNECTING;
			server_send_map(cid);
		}
	}
	else
	{
		if(sys)
		{
			/* system message */
			if(msg == NETMSG_REQUEST_MAP_DATA)
			{
				int chunk = msg_unpack_int();
				int chunk_size = 1024-128;
				int offset = chunk * chunk_size;
				int last = 0;
				
				/* drop faulty map data requests */
				if(chunk < 0 || offset > current_map_size)
					return;
				
				if(offset+chunk_size >= current_map_size)
				{
					chunk_size = current_map_size-offset;
					if(chunk_size < 0)
						chunk_size = 0;
					last = 1;
				}
				
				msg_pack_start_system(NETMSG_MAP_DATA, MSGFLAG_VITAL|MSGFLAG_FLUSH);
				msg_pack_int(last);
				msg_pack_int(current_map_size);
				msg_pack_int(chunk_size);
				msg_pack_raw(&current_map_data[offset], chunk_size);
				msg_pack_end();
				server_send_msg(cid);
				
				if(config.debug)
					dbg_msg("server", "sending chunk %d with size %d", chunk, chunk_size);
			}
			else if(msg == NETMSG_READY)
			{
				if(clients[cid].state == SRVCLIENT_STATE_CONNECTING)
				{
					netserver_client_addr(net, cid, &addr);
					
					dbg_msg("server", "player is ready. cid=%x ip=%d.%d.%d.%d",
						cid,
						addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3]
						);
					clients[cid].state = SRVCLIENT_STATE_READY;
					mods_connected(cid);
				}
			}
			else if(msg == NETMSG_ENTERGAME)
			{
				if(clients[cid].state == SRVCLIENT_STATE_READY)
				{
					netserver_client_addr(net, cid, &addr);
					
					dbg_msg("server", "player has entered the game. cid=%x ip=%d.%d.%d.%d",
						cid,
						addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3]
						);
					clients[cid].state = SRVCLIENT_STATE_INGAME;
					mods_client_enter(cid);
				}
			}
			else if(msg == NETMSG_INPUT)
			{
				int tick, size, i;
				CLIENT_INPUT *input;
				int64 tagtime;
				
				clients[cid].last_acked_snapshot = msg_unpack_int();
				tick = msg_unpack_int();
				size = msg_unpack_int();
				
				/* check for errors */
				if(msg_unpack_error() || size/4 > MAX_INPUT_SIZE)
					return;

				if(clients[cid].last_acked_snapshot > 0)
					clients[cid].snap_rate = SRVCLIENT_SNAPRATE_FULL;
					
				if(snapstorage_get(&clients[cid].snapshots, clients[cid].last_acked_snapshot, &tagtime, 0, 0) >= 0)
					clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq());

				/* add message to report the input timing */
				/* skip packets that are old */
				if(tick > clients[cid].last_input_tick)
				{
					int time_left = ((server_tick_start_time(tick)-time_get())*1000) / time_freq();
					msg_pack_start_system(NETMSG_INPUTTIMING, 0);
					msg_pack_int(tick);
					msg_pack_int(time_left);
					msg_pack_end();
					server_send_msg(cid);
				}

				clients[cid].last_input_tick = tick;

				input = &clients[cid].inputs[clients[cid].current_input];
				
				if(tick <= server_tick())
					tick = server_tick()+1;

				input->game_tick = tick;
				
				for(i = 0; i < size/4; i++)
					input->data[i] = msg_unpack_int();
				
				mem_copy(clients[cid].latestinput.data, input->data, MAX_INPUT_SIZE*sizeof(int));
				
				clients[cid].current_input++;
				clients[cid].current_input %= 200;
			
				/* call the mod with the fresh input data */
				if(clients[cid].state == SRVCLIENT_STATE_INGAME)
					mods_client_direct_input(cid, clients[cid].latestinput.data);
			}
			else if(msg == NETMSG_RCON_CMD)
			{
				const char *cmd = msg_unpack_string();
				
				if(msg_unpack_error() == 0 && clients[cid].authed)
				{
					dbg_msg("server", "cid=%d rcon='%s'", cid, cmd);
					console_execute_line(cmd);
				}
			}
			else if(msg == NETMSG_RCON_AUTH)
			{
				const char *pw;
				msg_unpack_string(); /* login name, not used */
				pw = msg_unpack_string();
				
				if(msg_unpack_error() == 0)
				{
					if(config.sv_rcon_password[0] == 0)
					{
						server_send_rcon_line(cid, "No rcon password set on server. Set sv_rcon_password to enable the remote console.");
					}
					else if(strcmp(pw, config.sv_rcon_password) == 0)
					{
						msg_pack_start_system(NETMSG_RCON_AUTH_STATUS, MSGFLAG_VITAL);
						msg_pack_int(1);
						msg_pack_end();
						server_send_msg(cid);
						
						clients[cid].authed = 1;
						server_send_rcon_line(cid, "Authentication successful. Remote console access granted.");
						dbg_msg("server", "cid=%d authed", cid);
					}
					else
					{
						server_send_rcon_line(cid, "Wrong password.");
					}
				}
			}
			else if(msg == NETMSG_PING)
			{
				msg_pack_start_system(NETMSG_PING_REPLY, 0);
				msg_pack_end();
				server_send_msg(cid);
			}
			else
			{
				char hex[] = "0123456789ABCDEF";
				char buf[512];
				int b;

				for(b = 0; b < packet->data_size && b < 32; b++)
				{
					buf[b*3] = hex[((const unsigned char *)packet->data)[b]>>4];
					buf[b*3+1] = hex[((const unsigned char *)packet->data)[b]&0xf];
					buf[b*3+2] = ' ';
					buf[b*3+3] = 0;
				}

				dbg_msg("server", "strange message cid=%d msg=%d data_size=%d", cid, msg, packet->data_size);
				dbg_msg("server", "%s", buf);
				
			}
		}
		else
		{
			/* game message */
			if(clients[cid].state >= SRVCLIENT_STATE_READY)
				mods_message(msg, cid);
		}
	}
Example #15
0
void GAMECLIENT::on_message(int msgtype)
{
	
	// special messages
	if(msgtype == NETMSGTYPE_SV_EXTRAPROJECTILE)
	{
		/*
		int num = msg_unpack_int();
		
		for(int k = 0; k < num; k++)
		{
			NETOBJ_PROJECTILE proj;
			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
				((int *)&proj)[i] = msg_unpack_int();
				
			if(msg_unpack_error())
				return;
				
			if(extraproj_num != MAX_EXTRA_PROJECTILES)
			{
				extraproj_projectiles[extraproj_num] = proj;
				extraproj_num++;
			}
		}
		
		return;*/
	}
	else if(msgtype == NETMSGTYPE_SV_TUNEPARAMS)
	{
		// unpack the new tuning
		TUNING_PARAMS new_tuning;
		int *params = (int *)&new_tuning;
		for(unsigned i = 0; i < sizeof(TUNING_PARAMS)/sizeof(int); i++)
			params[i] = msg_unpack_int();

		// check for unpacking errors
		if(msg_unpack_error())
			return;
		
		servermode = SERVERMODE_PURE;
			
		// apply new tuning
		tuning = new_tuning;
		return;
	}
	
	void *rawmsg = netmsg_secure_unpack(msgtype);
	if(!rawmsg)
	{
		dbg_msg("client", "dropped weird message '%s' (%d), failed on '%s'", netmsg_get_name(msgtype), msgtype, netmsg_failed_on());
		return;
	}

	// TODO: this should be done smarter
	for(int i = 0; i < all.num; i++)
		all.components[i]->on_message(msgtype, rawmsg);
	
	if(msgtype == NETMSGTYPE_SV_READYTOENTER)
	{
		client_entergame();
	}
	else if (msgtype == NETMSGTYPE_SV_EMOTICON)
	{
		NETMSG_SV_EMOTICON *msg = (NETMSG_SV_EMOTICON *)rawmsg;

		// apply
		clients[msg->cid].emoticon = msg->emoticon;
		clients[msg->cid].emoticon_start = client_tick();
	}
	else if(msgtype == NETMSGTYPE_SV_SOUNDGLOBAL)
	{
		if(suppress_events)
			return;
			
		NETMSG_SV_SOUNDGLOBAL *msg = (NETMSG_SV_SOUNDGLOBAL *)rawmsg;
		gameclient.sounds->play(SOUNDS::CHN_GLOBAL, msg->soundid, 1.0f, vec2(0,0));
	}		
}