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; }
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; } } }
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(); }