Beispiel #1
0
	fl::configuration get_freelan_configuration(const fscp::logger& logger, const service_configuration& configuration)
	{
		namespace po = boost::program_options;

		po::options_description configuration_options("Configuration");
		configuration_options.add(get_server_options());
		configuration_options.add(get_client_options());
		configuration_options.add(get_fscp_options());
		configuration_options.add(get_security_options());
		configuration_options.add(get_tap_adapter_options());
		configuration_options.add(get_switch_options());
		configuration_options.add(get_router_options());

		fl::configuration fl_configuration;
		po::variables_map vm;
		const fs::path configuration_file = configuration.configuration_file;
		const fs::path root_directory = configuration_file.parent_path();
		fs::basic_ifstream<char> ifs(configuration_file);

		if (!ifs)
		{
			throw po::reading_file(configuration_file.string().c_str());
		}

		po::store(po::parse_config_file(ifs, configuration_options, true), vm);
		make_paths_absolute(vm, root_directory);
		po::notify(vm);

		setup_configuration(logger, fl_configuration, vm);

		return fl_configuration;
	}
Beispiel #2
0
bool parse_options(fscp::logger& logger, int argc, char** argv, cli_configuration& configuration)
{
	namespace po = boost::program_options;

	po::options_description visible_options;
	po::options_description all_options;

	po::options_description generic_options("Generic options");
	generic_options.add_options()
	("help,h", "Produce help message.")
	("version,v", "Get the program version.")
	("debug,d", "Enables debug output.")
	("threads,t", po::value<unsigned int>(&configuration.thread_count)->default_value(0), "The number of threads to use.")
	("configuration_file,c", po::value<std::string>(), "The configuration file to use.")
	;

	visible_options.add(generic_options);
	all_options.add(generic_options);

	po::options_description configuration_options("Configuration");
	configuration_options.add(get_server_options());
	configuration_options.add(get_client_options());
	configuration_options.add(get_fscp_options());
	configuration_options.add(get_security_options());
	configuration_options.add(get_tap_adapter_options());
	configuration_options.add(get_switch_options());
	configuration_options.add(get_router_options());

	visible_options.add(configuration_options);
	all_options.add(configuration_options);

#ifdef WINDOWS
	po::options_description service_options("Service");
	service_options.add_options()
	("install", "Install the service.")
	("uninstall", "Uninstall the service.")
	("reinstall", "Reinstall the service.")
	;

	visible_options.add(service_options);
	all_options.add(service_options);
#else
	po::options_description daemon_options("Daemon");
	daemon_options.add_options()
	("foreground,f", "Do not run as a daemon.")
	("pid_file,p", po::value<std::string>(), "A pid file to use.")
	;

	visible_options.add(daemon_options);
	all_options.add(daemon_options);

	po::options_description misc_options("Miscellaneous");
	misc_options.add_options()
	("nocolor", "Disable color output.")
	;

	visible_options.add(misc_options);
	all_options.add(misc_options);
#endif

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, all_options), vm);
	make_paths_absolute(vm, fs::current_path());

	if (vm.count("help"))
	{
		std::cout << visible_options << std::endl;

		return false;
	}

	if (vm.count("version"))
	{
		std::cout << FREELAN_NAME << " " << FREELAN_VERSION_STRING << " " << FREELAN_DATE << std::endl;

		return false;
	}

#ifdef WINDOWS
	if (vm.count("install"))
	{
		if (vm.count("uninstall"))
		{
			throw std::runtime_error("Cannot specify both --install and --uninstall options. Use --reinstall instead.");
		}
		else
		{
			if (windows::install_service())
			{
				logger(fscp::log_level::important) << "Service installed.";
			}
			else
			{
				logger(fscp::log_level::error) << "The service was already installed.";
			}

			return false;
		}
	}
	else if (vm.count("uninstall"))
	{
		if (windows::uninstall_service())
		{
			logger(fscp::log_level::important) << "Service uninstalled.";
		}
		else
		{
			logger(fscp::log_level::error) << "The service has already been deleted.";
		}

		return false;
	}
	else if (vm.count("reinstall"))
	{
		if (windows::uninstall_service())
		{
			logger(fscp::log_level::important) << "Service uninstalled.";
		}
		else
		{
			logger(fscp::log_level::error) << "The service has already been deleted.";
		}

		if (windows::install_service())
		{
			logger(fscp::log_level::important) << "Service installed.";
		}
		else
		{
			logger(fscp::log_level::error) << "The service was already installed.";
		}

		return false;
	}
#else
	configuration.foreground = (vm.count("foreground") > 0);

	if (vm.count("nocolor") > 0)
	{
		// This is a global variable. Not really nice but does its job in this case.
		DISABLE_COLOR = true;
	}

	if (vm.count("pid_file"))
	{
		configuration.pid_file = fs::absolute(vm["pid_file"].as<std::string>());
	}
	else
	{
		char* val = getenv("FREELAN_PID_FILE");

		if (val)
		{
			configuration.pid_file = fs::absolute(std::string(val));
		}
	}
#endif

	fs::path configuration_file;

	if (vm.count("configuration_file"))
	{
		configuration_file = fs::absolute(vm["configuration_file"].as<std::string>());
	}
	else
	{
#ifdef _MSC_VER
#ifdef UNICODE
		std::wstring value(4096, L'\0');

		const DWORD value_size = GetEnvironmentVariable(L"FREELAN_CONFIGURATION_FILE", &value[0], static_cast<DWORD>(value.size()));
#else
		std::string value(4096, '\0');

		const DWORD value_size = GetEnvironmentVariable("FREELAN_CONFIGURATION_FILE", &value[0], static_cast<DWORD>(value.size()));
#endif

		if (value_size > 0)
		{
			value.resize(value_size);

			configuration_file = fs::absolute(value);
		}
#else
		const char* val = getenv("FREELAN_CONFIGURATION_FILE");

		if (val)
		{
			configuration_file = fs::absolute(std::string(val));
		}
#endif
	}

	if (!configuration_file.empty())
	{
		logger(fscp::log_level::information) << "Reading configuration file at: " << configuration_file;

		fs::basic_ifstream<char> ifs(configuration_file);

		if (!ifs)
		{
			throw po::reading_file(configuration_file.string().c_str());
		}

		po::store(po::parse_config_file(ifs, configuration_options, true), vm);
	}
	else
	{
		bool configuration_read = false;

		const std::vector<fs::path> configuration_files = get_configuration_files();

		BOOST_FOREACH(const fs::path& conf, configuration_files)
		{
			fs::basic_ifstream<char> ifs(conf);

			if (ifs)
			{
				logger(fscp::log_level::information) << "Reading configuration file at: " << conf << std::endl;

				po::store(po::parse_config_file(ifs, configuration_options, true), vm);

				configuration_file = fs::absolute(conf);

				configuration_read = true;

				break;
			}
		}

		if (!configuration_read)
		{
			logger(fscp::log_level::warning) << "Warning ! No configuration file specified and none found in the environment.";
			logger(fscp::log_level::warning) << "Looked up locations were:";

			for (auto&& conf : configuration_files)
			{
				logger(fscp::log_level::warning) << "- "  << conf;
			}
		}
	}
Beispiel #3
0
bool parse_options(int argc, char** argv, cli_configuration& configuration)
{
	namespace po = boost::program_options;

	po::options_description visible_options;
	po::options_description all_options;

	po::options_description generic_options("Generic options");
	generic_options.add_options()
	("help,h", "Produce help message.")
	("debug,d", "Enables debug output.")
	("configuration_file,c", po::value<std::string>(), "The configuration file to use")
	;

	visible_options.add(generic_options);
	all_options.add(generic_options);

	po::options_description configuration_options("Configuration");
	configuration_options.add(get_server_options());
	configuration_options.add(get_fscp_options());
	configuration_options.add(get_security_options());
	configuration_options.add(get_tap_adapter_options());
	configuration_options.add(get_switch_options());

	visible_options.add(configuration_options);
	all_options.add(configuration_options);

#ifdef WINDOWS
	po::options_description service_options("Service");
	service_options.add_options()
	("install", "Install the service.")
	("uninstall", "Uninstall the service.")
	("reinstall", "Reinstall the service.")
	;

	visible_options.add(service_options);
	all_options.add(service_options);
#else
	po::options_description daemon_options("Daemon");
	daemon_options.add_options()
	("foreground,f", "Do not run as a daemon.")
	("pid_file,p", po::value<std::string>(), "A pid file to use.")
	;

	visible_options.add(daemon_options);
	all_options.add(daemon_options);
#endif

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, all_options), vm);

	if (vm.count("help"))
	{
		std::cout << visible_options << std::endl;

		return false;
	}

#ifdef WINDOWS
	if (vm.count("install"))
	{
		if (vm.count("uninstall"))
		{
			throw std::runtime_error("Cannot specify both --install and --uninstall options. Use --reinstall instead.");
		}
		else
		{
			if (win32::install_service())
			{
				std::cout << "Service installed." << std::endl;
			}
			else
			{
				std::cerr << "The service was already installed." << std::endl;
			}

			return false;
		}
	}
	else if (vm.count("uninstall"))
	{
		if (win32::uninstall_service())
		{
			std::cout << "Service uninstalled." << std::endl;
		}
		else
		{
			std::cerr << "The service has already been deleted." << std::endl;
		}

		return false;
	}
	else if (vm.count("reinstall"))
	{
		if (win32::uninstall_service())
		{
			std::cout << "Service uninstalled." << std::endl;
		}
		else
		{
			std::cerr << "The service has already been deleted." << std::endl;
		}

		if (win32::install_service())
		{
			std::cout << "Service installed." << std::endl;
		}
		else
		{
			std::cerr << "The service was already installed." << std::endl;
		}

		return false;
	}
#else
	configuration.foreground = (vm.count("foreground") > 0);

	if (vm.count("pid_file"))
	{
		configuration.pid_file = fs::absolute(vm["pid_file"].as<std::string>());
	}
	else
	{
		char* val = getenv("FREELAN_PID_FILE");

		if (val)
		{
			configuration.pid_file = fs::absolute(std::string(val));
		}
	}
#endif

	fs::path configuration_file;

	if (vm.count("configuration_file"))
	{
		configuration_file = fs::absolute(vm["configuration_file"].as<std::string>());
	}
	else
	{
		char* val = getenv("FREELAN_CONFIGURATION_FILE");

		if (val)
		{
			configuration_file = fs::absolute(std::string(val));
		}
	}

	if (!configuration_file.empty())
	{
		std::cout << "Reading configuration file at: " << configuration_file << std::endl;

		fs::basic_ifstream<char> ifs(configuration_file);

		if (!ifs)
		{
			throw po::reading_file(configuration_file.string().c_str());
		}

		po::store(po::parse_config_file(ifs, configuration_options, true), vm);
	}
	else
	{
		bool configuration_read = false;

		const std::vector<fs::path> configuration_files = get_configuration_files();

		BOOST_FOREACH(const fs::path& conf, configuration_files)
		{
			fs::basic_ifstream<char> ifs(conf);

			if (ifs)
			{
				std::cout << "Reading configuration file at: " << conf << std::endl;

				po::store(po::parse_config_file(ifs, configuration_options, true), vm);

				configuration_file = fs::absolute(conf);

				break;
			}
		}

		if (!configuration_read)
		{
			std::cerr << "Warning ! No configuration file specified and none found in the environment." << std::endl;
			std::cerr << "Looked up locations were:" << std::endl;

			BOOST_FOREACH(const fs::path& conf, configuration_files)
			{
				std::cerr << "- " << conf << std::endl;
			}
// 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();
}