// update the standalone with the mission settings I have picked (mission filename, etc)
void multi_options_update_mission(netgame_info *ng, int campaign_mode)
{
	ubyte data[MAX_PACKET_SIZE],code;
	int packet_size = 0;

	// should be a host on a standalone
	Assert((Net_player->flags & NETINFO_FLAG_GAME_HOST) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER));

	// build the header
	BUILD_HEADER(OPTIONS_UPDATE);
	code = MULTI_OPTION_MISSION;
	ADD_DATA(code);

	// type (coop or team vs. team)
	ADD_INT(ng->type_flags);

	// respawns
	ADD_UINT(ng->respawn);

	// add the mission/campaign filename
	code = (ubyte)campaign_mode;
	ADD_DATA(code);
	if(campaign_mode){
		ADD_STRING(ng->campaign_name);
	} else {
		ADD_STRING(ng->mission_name);
	}

	// send to the server	
	multi_io_send_reliable(Net_player, data, packet_size);
}
// send a squadmsg packet to a player
void multi_msg_send_squadmsg_packet(net_player *target,net_player *source,int command,ushort net_sig,int subsys_type)
{
	ubyte data[100];		
	char s_val;
	int packet_size;

	Assert(source != NULL);
	Assert(target != NULL);
	if((source == NULL) || (target == NULL)){
		return;
	}

	// build the header
	BUILD_HEADER(SQUADMSG_PLAYER);

	// add the command and targeting data	
	ADD_INT(command);

	// add the id of the guy sending the order
	ADD_SHORT(source->player_id);

	// net signature
	ADD_USHORT(net_sig);
	
	// targeted subsytem (or -1 if none)
	s_val = (char)subsys_type;
	ADD_DATA(s_val);	

	// send to the player	
	multi_io_send_reliable(target, data, packet_size);
}
// update the standalone with the settings I have picked at the "start game" screen
void multi_options_update_start_game(netgame_info *ng)
{
	ubyte data[MAX_PACKET_SIZE],code;
	int packet_size = 0;

	// should be a host on a standalone
	Assert((Net_player->flags & NETINFO_FLAG_GAME_HOST) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER));

	// build the header
	BUILD_HEADER(OPTIONS_UPDATE);
	code = MULTI_OPTION_START_GAME;
	ADD_DATA(code);

	// add the start game options
	ADD_STRING(ng->name);
	ADD_INT(ng->mode);
	ADD_INT(ng->security);

	// add mode-specific data
	switch(ng->mode){
	case NG_MODE_PASSWORD:
		ADD_STRING(ng->passwd);
		break;
	case NG_MODE_RANK_ABOVE:
	case NG_MODE_RANK_BELOW:
		ADD_INT(ng->rank_base);
		break;
	}

	// send to the standalone server	
	multi_io_send_reliable(Net_player, data, packet_size);
}
// send a player kick packet
void send_player_kick_packet(int player_index, int ban, int reason)
{		
	ubyte data[MAX_PACKET_SIZE];
	int packet_size = 0;

	BUILD_HEADER(KICK_PLAYER);

	// add the address of the player to be kicked
	ADD_SHORT(Net_players[player_index].player_id);
	
	// indicate if he should be banned
	ADD_INT(ban);
	ADD_INT(reason);

	// send the request to the server	
	multi_io_send_reliable(Net_player, data, packet_size);
}
Beispiel #5
0
// send a request to the server saying I want to respawn (as an observer or not)
void multi_respawn_send_request(int as_observer)
{
	ubyte data[10],val;
	int packet_size = 0;

	// build the header and add the opcode
	BUILD_HEADER(RESPAWN_NOTICE);
	val = RESPAWN_REQUEST;
	ADD_DATA(val);

	// add a byte indicating whether or not we want to respawn as an observer
	val = (ubyte)as_observer;
	ADD_DATA(val);

	// send the request to the server	
	multi_io_send_reliable(Net_player, data, packet_size);
}
// update everyone with my local settings
void multi_options_update_local()
{
	ubyte data[MAX_PACKET_SIZE],code;
	int packet_size = 0;
	
	// if i'm the server, don't do anything
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		return;
	}

	// build the header and add the opcode
	BUILD_HEADER(OPTIONS_UPDATE);
	code = MULTI_OPTION_LOCAL;
	ADD_DATA(code);

	// add the netgame options
	add_local_options(data, &packet_size, &Net_player->p_info.options);

	// send the packet		
	multi_io_send_reliable(Net_player, data, packet_size);
}
// update everyone on the current netgame options
void multi_options_update_netgame()
{
	ubyte data[MAX_PACKET_SIZE],code;
	int packet_size = 0;
	
	Assert(Net_player->flags & NETINFO_FLAG_GAME_HOST);

	// build the header and add the opcode
	BUILD_HEADER(OPTIONS_UPDATE);
	code = MULTI_OPTION_SERVER;
	ADD_DATA(code);

	// add the netgame options
	add_server_options(data, &packet_size, &Netgame.options);

	// send the packet
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		multi_io_send_to_all_reliable(data, packet_size);
	} else {
		multi_io_send_reliable(Net_player, data, packet_size);
	}
}
// process an incoming multi options packet
void multi_options_process_packet(unsigned char *data, header *hinfo)
{
	ubyte code;	
	multi_local_options bogus;
	int idx,player_index;
	char str[255];
	int offset = HEADER_LENGTH;

	// find out who is sending this data	
	player_index = find_player_id(hinfo->id);

	if (player_index < 0) {
		nprintf(("Network", "Received packet from unknown player!\n"));
		return;
	}

	// get the packet code
	GET_DATA(code);
	switch(code){
	// get the start game options
	case MULTI_OPTION_START_GAME:
		Assert(Game_mode & GM_STANDALONE_SERVER);

		// get the netgame name
		GET_STRING(Netgame.name);		

		// get the netgame mode
		GET_INT(Netgame.mode);

		// get the security #
		GET_INT(Netgame.security);

		// get mode specific data
		switch(Netgame.mode){
		case NG_MODE_PASSWORD:
			GET_STRING(Netgame.passwd);
			break;
		case NG_MODE_RANK_ABOVE:
		case NG_MODE_RANK_BELOW:
			GET_INT(Netgame.rank_base);
			break;
		}

		// update standalone stuff
		std_connect_set_gamename(Netgame.name);
		std_multi_update_netgame_info_controls();
		break;

	// get mission choice options
	case MULTI_OPTION_MISSION:
		netgame_info ng;
		char title[NAME_LENGTH+1];
		int campaign_type,max_players;
		
		memset(&ng,0,sizeof(netgame_info));

		Assert(Game_mode & GM_STANDALONE_SERVER);

		// coop or team vs. team mode
		GET_INT(ng.type_flags);
		if((ng.type_flags & NG_TYPE_TEAM) && !(Netgame.type_flags & NG_TYPE_TEAM)){
			multi_team_reset();
		}
		// if squad war was switched on
		if((ng.type_flags & NG_TYPE_SW) && !(Netgame.type_flags & NG_TYPE_SW)){
			mprintf(("STANDALONE TURNED ON SQUAD WAR!!\n"));
		}
		Netgame.type_flags = ng.type_flags;

		// new respawn count
		GET_UINT(Netgame.respawn);

		// name string
		memset(str,0,255);

		GET_DATA(code);
		// campaign mode
		if(code){
			GET_STRING(ng.campaign_name);

			// set the netgame max players here if the filename has changed
			if(strcmp(Netgame.campaign_name,ng.campaign_name) != 0){				
				memset(title,0,NAME_LENGTH+1);			
				if(!mission_campaign_get_info(ng.campaign_name,title,&campaign_type,&max_players)){
					Netgame.max_players = 0;
				} else {
					Netgame.max_players = max_players;
				}

				strcpy_s(Netgame.campaign_name,ng.campaign_name);
			}

			Netgame.campaign_mode = 1;

			// put brackets around the campaign name
			if(Game_mode & GM_STANDALONE_SERVER){
				strcpy_s(str,"(");
				strcat_s(str,Netgame.campaign_name);
				strcat_s(str,")");
				std_multi_set_standalone_mission_name(str);
			}
		}
		// non-campaign mode
		else {
			GET_STRING(ng.mission_name);

			if(strcmp(Netgame.mission_name,ng.mission_name) != 0){
				if(strlen(ng.mission_name)){
					Netgame.max_players = mission_parse_get_multi_mission_info( ng.mission_name );
				} else {
					// setting this to -1 will prevent us from being seen on the network
					Netgame.max_players = -1;				
				}
				strcpy_s(Netgame.mission_name,ng.mission_name);
				strcpy_s(Game_current_mission_filename,Netgame.mission_name);				
			}			

			Netgame.campaign_mode = 0;
            
			// set the mission name
			if(Game_mode & GM_STANDALONE_SERVER){
				std_multi_set_standalone_mission_name(Netgame.mission_name);			
			}
		}

		// update FS2NetD as well
		if (MULTI_IS_TRACKER_GAME) {
			fs2netd_gameserver_update(true);
		}

		send_netgame_update_packet();	   
		break;

	// get the netgame options
	case MULTI_OPTION_SERVER:		
		get_server_options(data, &offset, &Netgame.options);

		// if we're a standalone set for no sound, do so here
		if((Game_mode & GM_STANDALONE_SERVER) && !Multi_options_g.std_voice){
			Netgame.options.flags |= MSO_FLAG_NO_VOICE;
		} else {
			// maybe update the quality of sound
			multi_voice_maybe_update_vars(Netgame.options.voice_qos,Netgame.options.voice_record_time);
		}

		// set the skill level
		Game_skill_level = Netgame.options.skill_level;		

		if((Game_mode & GM_STANDALONE_SERVER) && !(Game_mode & GM_CAMPAIGN_MODE)){
			Netgame.respawn = Netgame.options.respawn;
		}

		// if we have the "temp closed" flag toggle
		if(Netgame.options.flags & MLO_FLAG_TEMP_CLOSED){
			Netgame.flags ^= NG_FLAG_TEMP_CLOSED;
		}
		Netgame.options.flags &= ~(MLO_FLAG_TEMP_CLOSED);

		// if i'm the standalone server, I should rebroadcast to all other players
		if(Game_mode & GM_STANDALONE_SERVER){
			for(idx=0;idx<MAX_PLAYERS;idx++){
				if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx]) && (&Net_players[idx] != &Net_players[player_index]) ){
					multi_io_send_reliable(&Net_players[idx], data, offset);
				}
			}

			send_netgame_update_packet();
		}
		break;
	
	// local netplayer options
	case MULTI_OPTION_LOCAL:
		if(player_index == -1){
			get_local_options(data, &offset, &bogus);
		} else {
			get_local_options(data, &offset, &Net_players[player_index].p_info.options);

			//If the client has sent an object update higher than that which the server allows, reset it
			if (Net_player->flags & NETINFO_FLAG_AM_MASTER) {
				if (Net_players[player_index].p_info.options.obj_update_level > Cmdline_objupd) {
					Net_players[player_index].p_info.options.obj_update_level = Cmdline_objupd;
				}
			}
		}		
		break;
	}
	PACKET_SET_SIZE();
}