diff --git a/main.cmake b/main.cmake index 345662e..88e81a3 100644 --- a/main.cmake +++ b/main.cmake @@ -30,6 +30,29 @@ target_include_directories(mlat_source PUBLIC "${md}") target_link_libraries(mlat_source PUBLIC ${Core}) append_glob_source(ecap_server_srcs "${md}/Local_Server") add_executable(ecap_server "${md}/Local_Server_main.cpp" ${ecap_server_srcs}) +if (WIN32) + set(ecap_default_dsp_library_path "@/dll_source.dll") + set(ecap_default_webapp_path "@/../third_party/eacp_webapp/wwwroot") + set(ecap_default_tile_directory "C:/tiles") + set(ecap_default_file_source 1) + set(ecap_default_file_source_path "D:/ae/proj/projects/ECAP_Server/data/BIN_Blank_Text/ADS-B_195_0205.txt") + set(ecap_default_sqlite_path "@/../data/sqlite/ecap.sqlite") +else () + set(ecap_default_dsp_library_path "@/lib9002/lib9002.so") + set(ecap_default_webapp_path "@/wwwroot") + set(ecap_default_tile_directory "/home/heco/tiles") + set(ecap_default_file_source 0) + set(ecap_default_file_source_path "") + set(ecap_default_sqlite_path "@/../ecap.sqlite") +endif () +target_compile_definitions(ecap_server PRIVATE + ECAP_DEFAULT_DSP_LIBRARY_PATH="${ecap_default_dsp_library_path}" + ECAP_DEFAULT_WEBAPP_PATH="${ecap_default_webapp_path}" + ECAP_DEFAULT_TILE_DIRECTORY="${ecap_default_tile_directory}" + ECAP_DEFAULT_FILE_SOURCE=${ecap_default_file_source} + ECAP_DEFAULT_FILE_SOURCE_PATH="${ecap_default_file_source_path}" + ECAP_DEFAULT_SQLITE_PATH="${ecap_default_sqlite_path}" +) target_include_directories(ecap_server PUBLIC "${md}") target_include_directories(ecap_server PRIVATE "${CMAKE_CURRENT_LIST_DIR}/third_party/Adminive/backend/library/include" diff --git a/module/Local_Server/server/Config.cpp b/module/Local_Server/server/Config.cpp index f80c9a1..54391c0 100644 --- a/module/Local_Server/server/Config.cpp +++ b/module/Local_Server/server/Config.cpp @@ -7,259 +7,11 @@ #include #include #include +#include "Config_Default/Config_Default.h" #include "Global.h" #include "Psc_Cpp_Core/Base/Check.h" std::string default_config_directory; namespace { -Map_Tile_Source_Config make_local_tile_source(std::string key, std::string name, Map_Tile_Type tile_type, - std::vector files, - std::optional encoding = std::nullopt) { - Map_Tile_Source_Config source; - source.key = std::move(key); - source.name = std::move(name); - source.tile_type = tile_type; - source.resource.file_format = Map_Tile_File_Format::mbtiles; - source.resource.files = std::move(files); - source.resource.y_axis = Map_Tile_Y_Axis::tms; - source.resource.extension = ".png"; - source.resource.tile_size = 256; - source.resource.maximum_level = 11; - source.resource.encoding = encoding; - return source; -} -Map_Tile_Source_Config make_online_tile_source(std::string key, std::string name, std::string url, - std::uint32_t maximum_level) { - Map_Tile_Source_Config source; - source.key = std::move(key); - source.name = std::move(name); - source.url = std::move(url); - source.resource.file_format = Map_Tile_File_Format::online; - source.resource.extension = ".png"; - source.resource.tile_size = 256; - source.resource.maximum_level = maximum_level; - return source; -} -void configure_source_display(Data_Source_Map_Display_Data& display, std::string color, - std::uint32_t aircraft_pixel_size, std::uint32_t base_station_pixel_size, - double aircraft_scale, bool show_call_sign, bool show_fly_status) { - display.color = std::move(color); - display.aircraft_pixel_size = aircraft_pixel_size; - display.base_station_pixel_size = base_station_pixel_size; - display.aircraft_scale = aircraft_scale; - display.base_station_scale = 0.44; - display.show_call_sign = show_call_sign; - display.show_fly_status = show_fly_status; -} -std::shared_ptr make_default_dll_source() { - auto source = std::make_shared(); - source->key = "lzy_dll"; - source->set_enabled(true); - source->settings.write([](auto& value) { - value.base_station_has_valid_position = true; - configure_source_display(value.map_display.map2d, "#454641", 34, 30, 2.0, false, false); - configure_source_display(value.map_display.map3d, "#454641", 50, 100, 1.0, false, false); - value.lat = 37.433547; - value.lon = 121.40873; - value.alt = 2300.0; - value.ignore_msg_time = true; - }); - source->specific.write([](auto& value) { - value.library_path = "@/dll_source.dll"; - value.function_name = "adsb_read"; - value.data_type = File_Data_Type::BIN_Blank_Text; - value.buffer_size = 200000; - }); - return source; -} -std::shared_ptr make_default_file_source() { - auto source = std::make_shared(); - source->key = "aaaa"; - source->set_enabled(false); - source->settings.write([](auto& value) { - configure_source_display(value.map_display.map2d, "#d1a54c", 50, 100, 2.0, true, true); - configure_source_display(value.map_display.map3d, "#d1a54c", 50, 100, 2.0, true, true); - value.lat = 37.0; - value.lon = 121.0; - value.alt = 1000.0; - value.ignore_msg_time = true; - }); - source->specific.write([](auto& value) { - value.file_path = R"(D:\ae\proj\projects\ECAP_Server\data\BIN_Blank_Text\ADS-B_195_0205.txt)"; - value.data_type = File_Data_Type::BIN_Blank_Text; - value.play_mode = Play_Mode::loop; - }); - return source; -} -void configure_feed(Data_Feed& feed, std::string type, std::string key, bool enabled, Output_Data_Format format, - bool use_status, Mode_S_Output_Type mode_s_output_type, bool use_mode_ac, bool sbs_only_pos) { - feed.type = std::move(type); - feed.key = std::move(key); - feed.set_enabled(enabled); - feed.source_key = "lzy_dll"; - feed.output_format.write([&](auto& value) { - value.type = format; - value.use_status = use_status; - value.mode_s_output_type = mode_s_output_type; - value.use_mode_ac = use_mode_ac; - value.sbs_only_pos = sbs_only_pos; - }); -} -std::shared_ptr make_default_tcp_server_feed(std::string key, bool enabled, - Output_Data_Format format, bool use_status, - Mode_S_Output_Type mode_s_output_type, - bool use_mode_ac, bool sbs_only_pos, - std::uint16_t port, std::size_t user_buffer_size, - std::size_t system_buffer_size) { - auto feed = std::make_shared(); - configure_feed(*feed, "Data_Feed_TCP_Server", std::move(key), enabled, format, use_status, mode_s_output_type, - use_mode_ac, sbs_only_pos); - feed->specific.write([&](auto& value) { - value.port = port; - value.connect_user_buffer_size = user_buffer_size; - value.connect_system_buffer_size = system_buffer_size; - }); - return feed; -} -Psc::JSON make_external_resource(std::string name, std::string download_url, std::string description, - std::uint64_t update_interval_seconds, std::time_t last_updated_at) { - External_Resources_Data resource; - resource.name = std::move(name); - resource.download_url = std::move(download_url); - resource.description = std::move(description); - resource.update_interval_seconds = update_interval_seconds; - resource.last_updated_at = last_updated_at; - return resource.to_base_json(); -} -void configure_windows_defaults(Config& config) { - config.version = "windows_v1.0.5"; - config.dsp_config.library_path = "@/dll_source.dll"; - config.dsp_config.center_freq = 16000000; - config.dsp_config.band_width = 6000; - config.dsp_config.sample_rate = 60000; - config.dsp_config.fft_point_number = 2048; - config.dsp_config.fft_period_ms = 50; - config.dsp_config.fft_win_type = UHD_FFTWin::blkmc; - config.dsp_config.frame_rate = 60; - config.dsp_config.debug = false; - config.drogon_config = Psc::JSON::object({{"app", Psc::JSON::object({{"threads_num", 0}, - {"client_max_body_size", "1000M"}, - {"client_max_memory_body_size", "1000M"}})}}); - config.http_monitor_config.access_log = false; - config.http_monitor_config.slow_request_threshold_ms = 3000; - config.http_monitor_config.slow_scope_threshold_ms = 1000; - config.mlat.settings.write([](auto& value) { value.merge = false; }); - config.web_server_config.webapp = "@/../third_party/eacp_webapp/wwwroot"; - config.web_server_config.listen_port = 9081; - config.map_resources_config.write([](auto& value) { - value.current_imagery_key = "mixed_imagery"; - value.tile_sources = { - make_local_tile_source("mixed_imagery", "本地混合图", Map_Tile_Type::imagery, - {"C:/tiles/混合图-世界-0-8.mbtiles", "C:/tiles/混合图-中国-9-10.mbtiles", - "C:/tiles/混合图-中国-11.mbtiles"}), - make_local_tile_source("height_terrain", "本地高程", Map_Tile_Type::terrain, - {"C:/tiles/高程-世界-0-8.mbtiles", "C:/tiles/高程-中国-9-10.mbtiles", - "C:/tiles/高程-中国-11.mbtiles"}, Map_Tile_Encoding::terrarium), - make_online_tile_source("osm_online", "OpenStreetMap在线", "https://tile.openstreetmap.org/{z}/{x}/{y}.png", 19), - make_online_tile_source("osm_hot_online", "OpenStreetMap HOT在线", "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", 19), - make_online_tile_source("cyclosm_online", "CyclOSM在线", "https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", 20), - make_online_tile_source("carto_light_online", "Carto Light在线", "https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", 20), - make_online_tile_source("carto_dark_online", "Carto Dark在线", "https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", 20), - make_online_tile_source("carto_voyager_online", "Carto Voyager在线", "https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", 20), - make_online_tile_source("carto_dark_nolabels_online", "Carto Dark无标注在线", "https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png", 20), - make_online_tile_source("opentopomap_online", "OpenTopoMap在线", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png", 17)}; - }); - config.map_view_config.write([](auto& value) { - value.scene_mode = Map_Scene_Mode::map_3d; - value.map2d.current_imagery_key = "mixed_imagery"; - value.map2d.current_terrain_key = "terrain"; - value.map2d.tile_display_maximum_level = 8; - value.map3d.current_imagery_key = "mixed_imagery"; - value.map3d.current_terrain_key = "terrain"; - value.map3d.tile_display_maximum_level = 19; - value.camera.longitude = 122.014707; - value.camera.latitude = 35.714108; - value.camera.height = 241660.03182; - value.camera.heading = 347.582854; - value.camera.pitch = -54.917211; - value.camera.roll = 359.999884; - }); - config.mode_acs.settings.write([](auto& value) { - value.timeout_seconds = 160; - value.max_speed_m_s = 1000; - value.wait_process_msg = true; - value.time_space_filter = true; - value.speed_filter = true; - value.max_track_point_size = 20000; - value.mode_s_max_num = 700000; - value.mode_other_max_num = 10000; - value.report_data_feed_msg_mum = 10000; - value.default_min_aircraft_list_num = 10; - }); - config.mode_acs.data_source_config.map.push_back(make_default_dll_source()); - config.mode_acs.data_source_config.map.push_back(make_default_file_source()); - config.mode_acs.data_feed_config.map.push_back(make_default_tcp_server_feed( - "Port_10003", true, Output_Data_Format::BIN, true, Mode_S_Output_Type::ALL_Mode_S, true, true, 10003, - 409600, 409600)); - auto udp_server = std::make_shared(); - configure_feed(*udp_server, "Data_Feed_UDP_Server", "22333", false, Output_Data_Format::BIN, false, - Mode_S_Output_Type::ALL_Mode_S, false, false); - udp_server->specific.write([](auto& value) { value.port = 50001; }); - config.mode_acs.data_feed_config.map.push_back(udp_server); - auto udp_client = std::make_shared(); - configure_feed(*udp_client, "Data_Feed_UDP_Client", "Port_10004", false, Output_Data_Format::AVR, false, - Mode_S_Output_Type::DF_11_17_18, false, true); - udp_client->specific.write([](auto& value) { - value.port = 30004; - value.url = "192.168.1.75"; - }); - config.mode_acs.data_feed_config.map.push_back(udp_client); - auto tcp_client = std::make_shared(); - configure_feed(*tcp_client, "Data_Feed_TCP_Client", "Port_10005", false, Output_Data_Format::BIN, true, - Mode_S_Output_Type::NO_POS_Mode_S, true, true); - tcp_client->specific.write([](auto& value) { - value.url = "192.168.1.167"; - value.port = 10005; - }); - config.mode_acs.data_feed_config.map.push_back(tcp_client); - config.mode_acs.data_feed_config.map.push_back(make_default_tcp_server_feed( - "Port_30003", false, Output_Data_Format::SBS, false, Mode_S_Output_Type::ALL_Mode_S, true, true, 30003, 0, 0)); - config.log_config.open_mode = Log_Config::Open_Mode::Delete; - config.log_config.piece_num = 10; - config.log_config.size_MB = 10; - config.console_config.record_playback = false; - config.console_config.mode_s_console = false; - config.external_resources_manager.ecap_sqlite_path = "@/../data/sqlite/ecap.sqlite"; - auto external_database = Psc::JSON::object(); - external_database.append({"ecap_sqlite_path", config.external_resources_manager.ecap_sqlite_path}); - auto external_resources = Psc::JSON::array(); - external_resources.append(make_external_resource("tar1090_db_aircraft", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", "wiedehopf/tar1090-db 发布的轻量 ICAO24 飞机静态库,提供注册号、机型、年份和运营方备注。", 604800, 1780388281)); - external_resources.append(make_external_resource("wiedehopf_tar1090_db_aircraft", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", "wiedehopf/tar1090-db 项目发布的飞机静态数据库镜像,供 tar1090 本地识别飞机。", 604800, 1780381804)); - external_resources.append(make_external_resource("mictronics_aircraft_database", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", "Mictronics 社区飞机数据库的 tar1090 汇总镜像,可按 ICAO24 查询注册号、机型和运营方。", 604800, 1780381804)); - external_resources.append(make_external_resource("opensky_aircraft_database", "https://opensky-network.org/datasets/metadata/aircraftDatabase.csv", "OpenSky Network 飞机元数据 CSV,包含制造商、型号、注册号和运营方等字段。", 604800, 1780381804)); - external_resources.append(make_external_resource("faa_aircraft_registry", "https://registry.faa.gov/database/ReleasableAircraft.zip", "FAA 官方可公开下载的美国飞机注册库,MASTER.txt 包含 Mode-S Hex 注册信息。", 86400, 1780381804)); - external_resources.append(make_external_resource("icao_doc_8643_aircraft_type_designators", "", "ICAO Doc 8643 机型代码表,用于将 A320、B738 等 designator 映射为制造商、型号和类别。", 2419200, 1780381804)); - external_resources.append(make_external_resource("vrs_routes", "https://vrs-standing-data.adsb.lol/routes.csv", "VRS 航线表,以 callsign 查询机场代码序列,用于推断起飞机场、经停机场和目的机场。", 3600, 1780381804)); - external_resources.append(make_external_resource("vrs_airports", "https://vrs-standing-data.adsb.lol/airports.csv", "VRS 机场字典,提供机场代码、名称、国家、经纬度和高度。", 3600, 1780381804)); - external_resources.append(make_external_resource("adsblol_vrs_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv", "ADSB.lol 发布的 VRS standing-data 航线镜像,以 callsign 查询机场代码序列。", 3600, 1780381804)); - external_resources.append(make_external_resource("vradarserver_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv", "Virtual Radar Server standing-data 的航线适配表;当前在线更新使用 ADSB.lol 公共镜像。", 3600, 1780381804)); - external_resources.append(make_external_resource("opensky_flightdata_api_cache", "", "OpenSky FlightData API 查询缓存,按 ICAO24 和时间范围保存历史航班起降机场结果。", 0, 1780381804)); - external_database.append({"list", external_resources}); - config.external_resources_manager.from_json(&external_database); - config.cesium_graphics_config.settings.write([](auto& value) { - value.resolution_scale = 1.0; - value.fxaa = true; - value.shadows = true; - value.enable_lighting = true; - value.solar_lighting = true; - value.terrain_enabled_in_3d = true; - value.terrain_exaggeration = 5.0; - value.surface_navigation_reference_visible = true; - value.view_axes_visible = true; - value.view_axes_panel_x = 3.0; - value.view_axes_panel_y = 337.0; - value.view_axes_panel_size = 184.0; - }); -} std::filesystem::path config_directory() { if (!default_config_directory.empty()) { return default_config_directory; @@ -270,10 +22,8 @@ std::filesystem::path config_section_path(Config_Section section) { return config_directory() / (std::string(config_section_name(section)) + ".json"); } std::array(Config_Section::count)> config_section_mutexes; -void write_config_section_unlocked(Config_Section section, const Psc::JSON& value) { - const auto directory = config_directory(); - std::filesystem::create_directories(directory); - const auto path = config_section_path(section); +void write_config_file_unlocked(const std::filesystem::path& path, const Psc::JSON& value) { + std::filesystem::create_directories(path.parent_path()); auto temporary = path; temporary += ".tmp"; std::ofstream output(temporary, std::ios::binary | std::ios::trunc); @@ -290,6 +40,9 @@ void write_config_section_unlocked(Config_Section section, const Psc::JSON& valu std::filesystem::remove(path, error); std::filesystem::rename(temporary, path); } +void write_config_section_unlocked(Config_Section section, const Psc::JSON& value) { + write_config_file_unlocked(config_section_path(section), value); +} void write_config_section(Config_Section section, const Psc::JSON& value) { std::lock_guard lock(config_section_mutexes[static_cast(section)]); write_config_section_unlocked(section, value); @@ -306,9 +59,8 @@ Psc::JSON read_existing_config_section_unlocked(Config_Section section) { } void merge_json_object(Psc::JSON& target, const Psc::JSON& value) { for (const auto& child : value.children) { - auto iterator = std::find_if(target.children.begin(), target.children.end(), [&](const Psc::JSON& current) { - return current.key == child.key; - }); + auto iterator = std::find_if(target.children.begin(), target.children.end(), + [&](const Psc::JSON& current) { return current.key == child.key; }); if (iterator == target.children.end()) { target.append(child); continue; @@ -319,11 +71,6 @@ void merge_json_object(Psc::JSON& target, const Psc::JSON& value) { *iterator = child; } } -Psc::JSON default_config() { - Config config; - configure_windows_defaults(config); - return config.toJson(); -} [[noreturn]] void config_load_failed(Config_Section section, std::string_view reason) { std::cerr << "配置文件加载失败: 【" << config_section_path(section).string() << "】 配置: 【" << config_section_name(section) << "】 原因: " << reason << std::endl; @@ -348,30 +95,36 @@ void assign_config_section(Config_Section section, Function&& function) { } Psc::JSON config_section_value(Global& global, Config_Section section) { switch (section) { - case Config_Section::version: return Psc::JSON(global.version); - case Config_Section::dsp: return global.dsp_config.to_base_json(); - case Config_Section::drogon: return global.drogon_config; - case Config_Section::http_monitor: return global.http_monitor_config.to_base_json(); - case Config_Section::mlat: return global.mlat.to_base_json(); - case Config_Section::web_server: return global.web_server_config.to_base_json(); + case Config_Section::version: + return Psc::JSON(global.version); + case Config_Section::dsp: + return global.dsp_config.to_base_json(); + case Config_Section::drogon: + return global.drogon_config; + case Config_Section::http_monitor: + return global.http_monitor_config.to_base_json(); + case Config_Section::mlat: + return global.mlat.to_base_json(); + case Config_Section::web_server: + return global.web_server_config.to_base_json(); case Config_Section::map_resources: - return global.map_resources_config.read([](const auto& value) { - return value.to_base_json(); - }); + return global.map_resources_config.read([](const auto& value) { return value.to_base_json(); }); case Config_Section::map_view: - return global.map_view_config.read([](const auto& value) { - return value.to_base_json(); - }); + return global.map_view_config.read([](const auto& value) { return value.to_base_json(); }); case Config_Section::map_models: - return global.map_model_config.read([](const auto& value) { - return value.to_base_json(); - }); - case Config_Section::mode_acs: return global.mode_acs.to_base_json(); - case Config_Section::log: return global.log_config.to_base_json(); - case Config_Section::console: return global.console_config.to_base_json(); - case Config_Section::external_database: return global.external_resources_manager.to_base_json(); - case Config_Section::cesium_graphics: return global.cesium_graphics_config.to_base_json(); - case Config_Section::count: break; + return global.map_model_config.read([](const auto& value) { return value.to_base_json(); }); + case Config_Section::mode_acs: + return global.mode_acs.to_base_json(); + case Config_Section::log: + return global.log_config.to_base_json(); + case Config_Section::console: + return global.console_config.to_base_json(); + case Config_Section::external_database: + return global.external_resources_manager.to_base_json(); + case Config_Section::cesium_graphics: + return global.cesium_graphics_config.to_base_json(); + case Config_Section::count: + break; } std::terminate(); } @@ -417,9 +170,8 @@ void migrate_legacy_source_feed_relations(const Psc::JSON* mode_acs, Data_Source }); if (default_relation != list->children.end()) { const auto source_list = sources.map.list(); - const auto first_source = std::find_if(source_list.begin(), source_list.end(), [](const auto& source) { - return source->enabled(); - }); + const auto first_source = + std::find_if(source_list.begin(), source_list.end(), [](const auto& source) { return source->enabled(); }); if (first_source != source_list.end()) { for (const auto& feed : feed_list) { if (!assignments.contains(feed->key)) @@ -433,13 +185,14 @@ void migrate_legacy_source_feed_relations(const Psc::JSON* mode_acs, Data_Source feed->source_key = assignment->second; } } -} +} // namespace void Data_Topology_View_Config::from_json(const Psc::JSON* that_json) { if (that_json == nullptr || that_json->valueType != Psc::Object) throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "data_topology_view"); - Get_J(initialized) Get_J(layout_revision) Get_J(zoom) Get_J(pan_x) Get_J(pan_y) - if (!std::isfinite(zoom) || zoom <= 0.0 || !std::isfinite(pan_x) || !std::isfinite(pan_y)) - throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "data_topology_view"); + Get_J(initialized) Get_J(layout_revision) Get_J(zoom) Get_J(pan_x) Get_J( + pan_y) if (!std::isfinite(zoom) || zoom <= 0.0 || !std::isfinite(pan_x) || + !std::isfinite(pan_y)) throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), + "data_topology_view"); const auto* positions = that_json->get("node_positions"); if (positions == nullptr || positions->valueType != Psc::Object) throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "node_positions"); @@ -458,14 +211,19 @@ Psc::JSON Data_Topology_View_Config::to_json() const { auto positions = Psc::JSON::object(); for (const auto& [id, position] : node_positions) positions.append({id, Psc::JSON::object({{"x", position.x}, {"y", position.y}})}); - return Psc::JSON::object({{"initialized", initialized}, {"layout_revision", layout_revision}, {"zoom", zoom}, {"pan_x", pan_x}, {"pan_y", pan_y}, + return Psc::JSON::object({{"initialized", initialized}, + {"layout_revision", layout_revision}, + {"zoom", zoom}, + {"pan_x", pan_x}, + {"pan_y", pan_y}, {"node_positions", positions}}); } Psc::JSON Mode_ACS_Config::to_base_json() const { auto result = settings.read([](const auto& value) { return value.to_base_json(); }); result.append(Psc::JSON("data_feed", data_feed_config.to_json())); result.append(Psc::JSON("data_source", data_source_config.to_json())); - result.append(Psc::JSON("data_topology_view", data_topology_view.read([](const auto& value) { return value.to_json(); }))); + result.append( + Psc::JSON("data_topology_view", data_topology_view.read([](const auto& value) { return value.to_json(); }))); return result; } void Mode_ACS_Config::from_json(const Psc::JSON* that_json) { @@ -482,21 +240,19 @@ void Config::create_missing_config_files() { std::filesystem::create_directories(config_directory()); std::error_code ignored_error; std::filesystem::remove(config_directory() / "device.json", ignored_error); - const auto defaults = default_config(); for (std::size_t index = 0; index < static_cast(Config_Section::count); ++index) { const auto section = static_cast(index); if (std::filesystem::exists(config_section_path(section))) continue; - const auto* value = defaults.get(config_section_name(section)); - if (value == nullptr) - config_load_failed(section, "内置 Windows 默认配置缺少该分片"); + const auto file = make_default_config_file(section, config_directory()); try { - write_config_section(section, *value); + std::lock_guard lock(config_section_mutexes[static_cast(file.section)]); + write_config_file_unlocked(file.path, file.value); } catch (const std::exception& error) { config_load_failed(section, error.what()); } - std::cout << "生成默认配置文件: 【" << config_section_path(section).string() << "】" << std::endl; + std::cout << "生成默认配置文件: 【" << file.path.string() << "】" << std::endl; } } Psc::JSON Config::load() { @@ -506,7 +262,8 @@ Psc::JSON Config::load() { const auto section = static_cast(index); result.append({std::string(config_section_name(section)), read_config_section(section)}); } - std::cout << get_current_date_string() << " 启动加载配置目录: 【" << config_directory().string() << "】" << std::endl; + std::cout << get_current_date_string() << " 启动加载配置目录: 【" << config_directory().string() << "】" + << std::endl; return result; } void Config::from_log_json(const Psc::JSON* that_json) { @@ -515,16 +272,16 @@ void Config::from_log_json(const Psc::JSON* that_json) { void Config::from_base_json(Psc::JSON* that_json) { assign_config_section(Config_Section::version, [&] { Get_J(version) }); assign_config_section(Config_Section::mlat, [&] { mlat.from_json(that_json->get("mlat")); }); - assign_config_section(Config_Section::web_server, [&] { web_server_config.from_base_json(that_json->get("web_server")); }); + assign_config_section(Config_Section::web_server, + [&] { web_server_config.from_base_json(that_json->get("web_server")); }); assign_config_section(Config_Section::map_resources, [&] { map_resources_config.write([&](auto& value) { value.from_base_json(that_json->get("map_resources")); }); }); assign_config_section(Config_Section::map_view, [&] { map_view_config.write([&](auto& value) { value.from_base_json(that_json->get("map_view")); }); }); - assign_config_section(Config_Section::cesium_graphics, [&] { - cesium_graphics_config.from_base_json(that_json->get("cesium_graphics")); - }); + assign_config_section(Config_Section::cesium_graphics, + [&] { cesium_graphics_config.from_base_json(that_json->get("cesium_graphics")); }); assign_config_section(Config_Section::map_models, [&] { map_model_config.write([&](auto& value) { value.from_base_json(that_json->get("map_models")); }); }); @@ -532,10 +289,10 @@ void Config::from_base_json(Psc::JSON* that_json) { assign_config_section(Config_Section::console, [&] { console_config.from_base_json(that_json->get("console")); }); assign_config_section(Config_Section::dsp, [&] { dsp_config.from_json(that_json->get("dsp")); }); assign_config_section(Config_Section::drogon, [&] { drogon_config = *that_json->get("drogon"); }); - assign_config_section(Config_Section::http_monitor, [&] { http_monitor_config.from_base_json(that_json->get("http_monitor")); }); - assign_config_section(Config_Section::external_database, [&] { - external_resources_manager.from_json(that_json->get("external_database")); - }); + assign_config_section(Config_Section::http_monitor, + [&] { http_monitor_config.from_base_json(that_json->get("http_monitor")); }); + assign_config_section(Config_Section::external_database, + [&] { external_resources_manager.from_json(that_json->get("external_database")); }); } Psc::JSON Web_Server_Config::to_base_json() const { return Psc::JSON::object({{"webapp", webapp}, {"listen_port", listen_port}}); @@ -599,7 +356,8 @@ static std::map make_default_aircraft_models } return ret; } -static std::map read_model_object_field(const Psc::JSON* json, std::string_view key) { +static std::map read_model_object_field(const Psc::JSON* json, + std::string_view key) { auto field = json->get(key); if (field == nullptr || field->valueType != Psc::Object) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); @@ -818,7 +576,8 @@ void Map_View_Config::from_base_json(const Psc::JSON* that_json) { map2d.from_base_json(that_json->get("map2d")); map3d.from_base_json(that_json->get("map3d")); camera.from_base_json(that_json->get("camera")); - base_station_fly_to_height_offset_meters = std::max(100.0, read_double_field(that_json, "base_station_fly_to_height_offset_meters")); + base_station_fly_to_height_offset_meters = + std::max(100.0, read_double_field(that_json, "base_station_fly_to_height_offset_meters")); } Psc::JSON Map_View_Config::to_base_json() const { auto ret = Psc::JSON::object(); @@ -848,9 +607,7 @@ void Cesium_Graphics_Config::from_base_json(const Psc::JSON* that_json) { }); } Psc::JSON Cesium_Graphics_Config::to_base_json() const { - return settings.read([](const auto& value) { - return value.to_base_json(); - }); + return settings.read([](const auto& value) { return value.to_base_json(); }); } Map_Model_Item_Config::Map_Model_Item_Config(std::string url) : url(std::move(url)) { } diff --git a/module/Local_Server/server/Config_Default/Config_Default.cpp b/module/Local_Server/server/Config_Default/Config_Default.cpp new file mode 100644 index 0000000..a972ffe --- /dev/null +++ b/module/Local_Server/server/Config_Default/Config_Default.cpp @@ -0,0 +1,36 @@ +#include "Config_Default.h" +Default_Config_File make_default_config_file(Config_Section section, const std::filesystem::path& directory) { + switch (section) { + case Config_Section::version: + return make_default_version_config(directory); + case Config_Section::dsp: + return make_default_dsp_config(directory); + case Config_Section::drogon: + return make_default_drogon_config(directory); + case Config_Section::http_monitor: + return make_default_http_monitor_config(directory); + case Config_Section::mlat: + return make_default_mlat_config(directory); + case Config_Section::web_server: + return make_default_web_server_config(directory); + case Config_Section::map_resources: + return make_default_map_resources_config(directory); + case Config_Section::map_view: + return make_default_map_view_config(directory); + case Config_Section::map_models: + return make_default_map_models_config(directory); + case Config_Section::mode_acs: + return make_default_mode_acs_config(directory); + case Config_Section::log: + return make_default_log_config(directory); + case Config_Section::console: + return make_default_console_config(directory); + case Config_Section::external_database: + return make_default_external_database_config(directory); + case Config_Section::cesium_graphics: + return make_default_cesium_graphics_config(directory); + case Config_Section::count: + std::terminate(); + } + std::terminate(); +} diff --git a/module/Local_Server/server/Config_Default/Config_Default.h b/module/Local_Server/server/Config_Default/Config_Default.h new file mode 100644 index 0000000..34a7649 --- /dev/null +++ b/module/Local_Server/server/Config_Default/Config_Default.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include "../Config.h" +struct Default_Config_File { + Config_Section section; + std::filesystem::path path; + Psc::JSON value; +}; +Default_Config_File make_default_config_file(Config_Section section, const std::filesystem::path& directory); +Default_Config_File make_default_version_config(const std::filesystem::path& directory); +Default_Config_File make_default_dsp_config(const std::filesystem::path& directory); +Default_Config_File make_default_drogon_config(const std::filesystem::path& directory); +Default_Config_File make_default_http_monitor_config(const std::filesystem::path& directory); +Default_Config_File make_default_mlat_config(const std::filesystem::path& directory); +Default_Config_File make_default_web_server_config(const std::filesystem::path& directory); +Default_Config_File make_default_map_resources_config(const std::filesystem::path& directory); +Default_Config_File make_default_map_view_config(const std::filesystem::path& directory); +Default_Config_File make_default_map_models_config(const std::filesystem::path& directory); +Default_Config_File make_default_mode_acs_config(const std::filesystem::path& directory); +Default_Config_File make_default_log_config(const std::filesystem::path& directory); +Default_Config_File make_default_console_config(const std::filesystem::path& directory); +Default_Config_File make_default_external_database_config(const std::filesystem::path& directory); +Default_Config_File make_default_cesium_graphics_config(const std::filesystem::path& directory); diff --git a/module/Local_Server/server/Config_Default/cesium_graphics.cpp b/module/Local_Server/server/Config_Default/cesium_graphics.cpp new file mode 100644 index 0000000..8b8ada6 --- /dev/null +++ b/module/Local_Server/server/Config_Default/cesium_graphics.cpp @@ -0,0 +1,19 @@ +#include "Config_Default.h" +Default_Config_File make_default_cesium_graphics_config(const std::filesystem::path& directory) { + Cesium_Graphics_Config config; + config.settings.write([](auto& value) { + value.resolution_scale = 1.0; + value.fxaa = true; + value.shadows = true; + value.enable_lighting = true; + value.solar_lighting = true; + value.terrain_enabled_in_3d = true; + value.terrain_exaggeration = 5.0; + value.surface_navigation_reference_visible = true; + value.view_axes_visible = true; + value.view_axes_panel_x = 3.0; + value.view_axes_panel_y = 337.0; + value.view_axes_panel_size = 184.0; + }); + return {Config_Section::cesium_graphics, directory / "cesium_graphics.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/console.cpp b/module/Local_Server/server/Config_Default/console.cpp new file mode 100644 index 0000000..05fcbe2 --- /dev/null +++ b/module/Local_Server/server/Config_Default/console.cpp @@ -0,0 +1,7 @@ +#include "Config_Default.h" +Default_Config_File make_default_console_config(const std::filesystem::path& directory) { + Console_Config config{}; + config.record_playback = false; + config.mode_s_console = false; + return {Config_Section::console, directory / "console.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/drogon.cpp b/module/Local_Server/server/Config_Default/drogon.cpp new file mode 100644 index 0000000..b0c6616 --- /dev/null +++ b/module/Local_Server/server/Config_Default/drogon.cpp @@ -0,0 +1,6 @@ +#include "Config_Default.h" +Default_Config_File make_default_drogon_config(const std::filesystem::path& directory) { + auto app = Psc::JSON::object( + {{"threads_num", 0}, {"client_max_body_size", "1000M"}, {"client_max_memory_body_size", "1000M"}}); + return {Config_Section::drogon, directory / "drogon.json", Psc::JSON::object({{"app", app}})}; +} diff --git a/module/Local_Server/server/Config_Default/dsp.cpp b/module/Local_Server/server/Config_Default/dsp.cpp new file mode 100644 index 0000000..0e34d4c --- /dev/null +++ b/module/Local_Server/server/Config_Default/dsp.cpp @@ -0,0 +1,14 @@ +#include "Config_Default.h" +Default_Config_File make_default_dsp_config(const std::filesystem::path& directory) { + DSP_Config config; + config.library_path = ECAP_DEFAULT_DSP_LIBRARY_PATH; + config.center_freq = 16000000; + config.band_width = 6000; + config.sample_rate = 60000; + config.fft_point_number = 2048; + config.fft_period_ms = 50; + config.fft_win_type = UHD_FFTWin::blkmc; + config.frame_rate = 60; + config.debug = false; + return {Config_Section::dsp, directory / "dsp.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/external_database.cpp b/module/Local_Server/server/Config_Default/external_database.cpp new file mode 100644 index 0000000..0a7e984 --- /dev/null +++ b/module/Local_Server/server/Config_Default/external_database.cpp @@ -0,0 +1,57 @@ +#include "Config_Default.h" +namespace { +Psc::JSON make_resource(std::string name, std::string download_url, std::string description, + std::uint64_t update_interval_seconds, std::time_t last_updated_at) { + External_Resources_Data resource; + resource.name = std::move(name); + resource.download_url = std::move(download_url); + resource.description = std::move(description); + resource.update_interval_seconds = update_interval_seconds; + resource.last_updated_at = last_updated_at; + return resource.to_base_json(); +} +} // namespace +Default_Config_File make_default_external_database_config(const std::filesystem::path& directory) { + External_Resources_Manager config; + config.ecap_sqlite_path = ECAP_DEFAULT_SQLITE_PATH; + auto value = Psc::JSON::object(); + value.append({"ecap_sqlite_path", config.ecap_sqlite_path}); + auto resources = Psc::JSON::array(); + resources.append(make_resource( + "tar1090_db_aircraft", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", + "wiedehopf/tar1090-db 发布的轻量 ICAO24 飞机静态库,提供注册号、机型、年份和运营方备注。", 604800, 1780388281)); + resources.append( + make_resource("wiedehopf_tar1090_db_aircraft", + "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", + "wiedehopf/tar1090-db 项目发布的飞机静态数据库镜像,供 tar1090 本地识别飞机。", 604800, 1780381804)); + resources.append(make_resource( + "mictronics_aircraft_database", + "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", + "Mictronics 社区飞机数据库的 tar1090 汇总镜像,可按 ICAO24 查询注册号、机型和运营方。", 604800, 1780381804)); + resources.append( + make_resource("opensky_aircraft_database", "https://opensky-network.org/datasets/metadata/aircraftDatabase.csv", + "OpenSky Network 飞机元数据 CSV,包含制造商、型号、注册号和运营方等字段。", 604800, 1780381804)); + resources.append(make_resource("faa_aircraft_registry", "https://registry.faa.gov/database/ReleasableAircraft.zip", + "FAA 官方可公开下载的美国飞机注册库,MASTER.txt 包含 Mode-S Hex 注册信息。", 86400, + 1780381804)); + resources.append(make_resource( + "icao_doc_8643_aircraft_type_designators", "", + "ICAO Doc 8643 机型代码表,用于将 A320、B738 等 designator 映射为制造商、型号和类别。", 2419200, 1780381804)); + resources.append(make_resource("vrs_routes", "https://vrs-standing-data.adsb.lol/routes.csv", + "VRS 航线表,以 callsign 查询机场代码序列,用于推断起飞机场、经停机场和目的机场。", + 3600, 1780381804)); + resources.append(make_resource("vrs_airports", "https://vrs-standing-data.adsb.lol/airports.csv", + "VRS 机场字典,提供机场代码、名称、国家、经纬度和高度。", 3600, 1780381804)); + resources.append(make_resource("adsblol_vrs_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv", + "ADSB.lol 发布的 VRS standing-data 航线镜像,以 callsign 查询机场代码序列。", 3600, + 1780381804)); + resources.append(make_resource( + "vradarserver_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv", + "Virtual Radar Server standing-data 的航线适配表;当前在线更新使用 ADSB.lol 公共镜像。", 3600, 1780381804)); + resources.append(make_resource("opensky_flightdata_api_cache", "", + "OpenSky FlightData API 查询缓存,按 ICAO24 和时间范围保存历史航班起降机场结果。", 0, + 1780381804)); + value.append({"list", resources}); + config.from_json(&value); + return {Config_Section::external_database, directory / "external_database.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/http_monitor.cpp b/module/Local_Server/server/Config_Default/http_monitor.cpp new file mode 100644 index 0000000..e61afca --- /dev/null +++ b/module/Local_Server/server/Config_Default/http_monitor.cpp @@ -0,0 +1,8 @@ +#include "Config_Default.h" +Default_Config_File make_default_http_monitor_config(const std::filesystem::path& directory) { + Http_Monitor_Config config; + config.access_log = false; + config.slow_request_threshold_ms = 3000; + config.slow_scope_threshold_ms = 1000; + return {Config_Section::http_monitor, directory / "http_monitor.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/log.cpp b/module/Local_Server/server/Config_Default/log.cpp new file mode 100644 index 0000000..1cb9169 --- /dev/null +++ b/module/Local_Server/server/Config_Default/log.cpp @@ -0,0 +1,8 @@ +#include "Config_Default.h" +Default_Config_File make_default_log_config(const std::filesystem::path& directory) { + Log_Config config; + config.open_mode = Log_Config::Open_Mode::Delete; + config.piece_num = 10; + config.size_MB = 10; + return {Config_Section::log, directory / "log.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/map_models.cpp b/module/Local_Server/server/Config_Default/map_models.cpp new file mode 100644 index 0000000..2749251 --- /dev/null +++ b/module/Local_Server/server/Config_Default/map_models.cpp @@ -0,0 +1,5 @@ +#include "Config_Default.h" +Default_Config_File make_default_map_models_config(const std::filesystem::path& directory) { + Map_Model_Config config; + return {Config_Section::map_models, directory / "map_models.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/map_resources.cpp b/module/Local_Server/server/Config_Default/map_resources.cpp new file mode 100644 index 0000000..36ddd7e --- /dev/null +++ b/module/Local_Server/server/Config_Default/map_resources.cpp @@ -0,0 +1,60 @@ +#include "Config_Default.h" +namespace { +Map_Tile_Source_Config make_local_tile_source(std::string key, std::string name, Map_Tile_Type tile_type, + std::vector files, + std::optional encoding = std::nullopt) { + Map_Tile_Source_Config source; + source.key = std::move(key); + source.name = std::move(name); + source.tile_type = tile_type; + source.resource.file_format = Map_Tile_File_Format::mbtiles; + source.resource.files = std::move(files); + source.resource.y_axis = Map_Tile_Y_Axis::tms; + source.resource.extension = ".png"; + source.resource.tile_size = 256; + source.resource.maximum_level = 11; + source.resource.encoding = encoding; + return source; +} +Map_Tile_Source_Config make_online_tile_source(std::string key, std::string name, std::string url, + std::uint32_t maximum_level) { + Map_Tile_Source_Config source; + source.key = std::move(key); + source.name = std::move(name); + source.url = std::move(url); + source.resource.file_format = Map_Tile_File_Format::online; + source.resource.extension = ".png"; + source.resource.tile_size = 256; + source.resource.maximum_level = maximum_level; + return source; +} +} // namespace +Default_Config_File make_default_map_resources_config(const std::filesystem::path& directory) { + Map_Resources_Config config; + config.current_imagery_key = "mixed_imagery"; + const auto tile_directory = std::string(ECAP_DEFAULT_TILE_DIRECTORY); + config.tile_sources = { + make_local_tile_source("mixed_imagery", "本地混合图", Map_Tile_Type::imagery, + {tile_directory + "/混合图-世界-0-8.mbtiles", tile_directory + "/混合图-中国-9-10.mbtiles", + tile_directory + "/混合图-中国-11.mbtiles"}), + make_local_tile_source("height_terrain", "本地高程", Map_Tile_Type::terrain, + {tile_directory + "/高程-世界-0-8.mbtiles", tile_directory + "/高程-中国-9-10.mbtiles", + tile_directory + "/高程-中国-11.mbtiles"}, + Map_Tile_Encoding::terrarium), + make_online_tile_source("osm_online", "OpenStreetMap在线", "https://tile.openstreetmap.org/{z}/{x}/{y}.png", 19), + make_online_tile_source("osm_hot_online", "OpenStreetMap HOT在线", + "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", 19), + make_online_tile_source("cyclosm_online", "CyclOSM在线", + "https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", 20), + make_online_tile_source("carto_light_online", "Carto Light在线", + "https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", 20), + make_online_tile_source("carto_dark_online", "Carto Dark在线", + "https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", 20), + make_online_tile_source("carto_voyager_online", "Carto Voyager在线", + "https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", 20), + make_online_tile_source("carto_dark_nolabels_online", "Carto Dark无标注在线", + "https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png", 20), + make_online_tile_source("opentopomap_online", "OpenTopoMap在线", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png", + 17)}; + return {Config_Section::map_resources, directory / "map_resources.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/map_view.cpp b/module/Local_Server/server/Config_Default/map_view.cpp new file mode 100644 index 0000000..5fb58c8 --- /dev/null +++ b/module/Local_Server/server/Config_Default/map_view.cpp @@ -0,0 +1,18 @@ +#include "Config_Default.h" +Default_Config_File make_default_map_view_config(const std::filesystem::path& directory) { + Map_View_Config config; + config.scene_mode = Map_Scene_Mode::map_3d; + config.map2d.current_imagery_key = "mixed_imagery"; + config.map2d.current_terrain_key = "terrain"; + config.map2d.tile_display_maximum_level = 8; + config.map3d.current_imagery_key = "mixed_imagery"; + config.map3d.current_terrain_key = "terrain"; + config.map3d.tile_display_maximum_level = 19; + config.camera.longitude = 122.014707; + config.camera.latitude = 35.714108; + config.camera.height = 241660.03182; + config.camera.heading = 347.582854; + config.camera.pitch = -54.917211; + config.camera.roll = 359.999884; + return {Config_Section::map_view, directory / "map_view.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/mlat.cpp b/module/Local_Server/server/Config_Default/mlat.cpp new file mode 100644 index 0000000..4130b66 --- /dev/null +++ b/module/Local_Server/server/Config_Default/mlat.cpp @@ -0,0 +1,6 @@ +#include "Config_Default.h" +Default_Config_File make_default_mlat_config(const std::filesystem::path& directory) { + MLAT_Config config; + config.settings.write([](auto& value) { value.merge = false; }); + return {Config_Section::mlat, directory / "mlat.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/mode_acs.cpp b/module/Local_Server/server/Config_Default/mode_acs.cpp new file mode 100644 index 0000000..b5120bb --- /dev/null +++ b/module/Local_Server/server/Config_Default/mode_acs.cpp @@ -0,0 +1,131 @@ +#include "Config_Default.h" +namespace { +void configure_source_display(Data_Source_Map_Display_Data& display, std::string color, + std::uint32_t aircraft_pixel_size, std::uint32_t base_station_pixel_size, + double aircraft_scale, bool show_call_sign, bool show_fly_status) { + display.color = std::move(color); + display.aircraft_pixel_size = aircraft_pixel_size; + display.base_station_pixel_size = base_station_pixel_size; + display.aircraft_scale = aircraft_scale; + display.base_station_scale = 0.44; + display.show_call_sign = show_call_sign; + display.show_fly_status = show_fly_status; +} +std::shared_ptr make_dll_source() { + auto source = std::make_shared(); + source->key = "lzy_dll"; + source->set_enabled(true); + source->settings.write([](auto& value) { + value.base_station_has_valid_position = true; + configure_source_display(value.map_display.map2d, "#454641", 34, 30, 2.0, false, false); + configure_source_display(value.map_display.map3d, "#454641", 50, 100, 1.0, false, false); + value.lat = 37.433547; + value.lon = 121.40873; + value.alt = 2300.0; + value.ignore_msg_time = true; + }); + source->specific.write([](auto& value) { + value.library_path = ECAP_DEFAULT_DSP_LIBRARY_PATH; + value.function_name = "adsb_read"; + value.data_type = File_Data_Type::BIN_Blank_Text; + value.buffer_size = 200000; + }); + return source; +} +#if ECAP_DEFAULT_FILE_SOURCE +std::shared_ptr make_file_source() { + auto source = std::make_shared(); + source->key = "aaaa"; + source->set_enabled(false); + source->settings.write([](auto& value) { + configure_source_display(value.map_display.map2d, "#d1a54c", 50, 100, 2.0, true, true); + configure_source_display(value.map_display.map3d, "#d1a54c", 50, 100, 2.0, true, true); + value.lat = 37.0; + value.lon = 121.0; + value.alt = 1000.0; + value.ignore_msg_time = true; + }); + source->specific.write([](auto& value) { + value.file_path = ECAP_DEFAULT_FILE_SOURCE_PATH; + value.data_type = File_Data_Type::BIN_Blank_Text; + value.play_mode = Play_Mode::loop; + }); + return source; +} +#endif +void configure_feed(Data_Feed& feed, std::string type, std::string key, bool enabled, Output_Data_Format format, + bool use_status, Mode_S_Output_Type mode_s_output_type, bool use_mode_ac, bool sbs_only_pos) { + feed.type = std::move(type); + feed.key = std::move(key); + feed.set_enabled(enabled); + feed.source_key = "lzy_dll"; + feed.output_format.write([&](auto& value) { + value.type = format; + value.use_status = use_status; + value.mode_s_output_type = mode_s_output_type; + value.use_mode_ac = use_mode_ac; + value.sbs_only_pos = sbs_only_pos; + }); +} +std::shared_ptr make_tcp_server_feed(std::string key, bool enabled, Output_Data_Format format, + bool use_status, Mode_S_Output_Type mode_s_output_type, + bool use_mode_ac, bool sbs_only_pos, std::uint16_t port, + std::size_t user_buffer_size, + std::size_t system_buffer_size) { + auto feed = std::make_shared(); + configure_feed(*feed, "Data_Feed_TCP_Server", std::move(key), enabled, format, use_status, mode_s_output_type, + use_mode_ac, sbs_only_pos); + feed->specific.write([&](auto& value) { + value.port = port; + value.connect_user_buffer_size = user_buffer_size; + value.connect_system_buffer_size = system_buffer_size; + }); + return feed; +} +} // namespace +Default_Config_File make_default_mode_acs_config(const std::filesystem::path& directory) { + Mode_ACS_Config config; + config.settings.write([](auto& value) { + value.timeout_seconds = 160; + value.max_speed_m_s = 1000; + value.wait_process_msg = true; + value.time_space_filter = true; + value.speed_filter = true; + value.max_track_point_size = 20000; + value.mode_s_max_num = 700000; + value.mode_other_max_num = 10000; + value.report_data_feed_msg_mum = 10000; + value.default_min_aircraft_list_num = 10; + }); + config.data_source_config.map.push_back(make_dll_source()); +#if ECAP_DEFAULT_FILE_SOURCE + config.data_source_config.map.push_back(make_file_source()); +#endif + config.data_feed_config.map.push_back(make_tcp_server_feed("Port_10003", true, Output_Data_Format::BIN, true, + Mode_S_Output_Type::ALL_Mode_S, true, true, 10003, + 409600, 409600)); + auto udp_server = std::make_shared(); + configure_feed(*udp_server, "Data_Feed_UDP_Server", "22333", false, Output_Data_Format::BIN, false, + Mode_S_Output_Type::ALL_Mode_S, false, false); + udp_server->specific.write([](auto& value) { value.port = 50001; }); + config.data_feed_config.map.push_back(udp_server); + auto udp_client = std::make_shared(); + configure_feed(*udp_client, "Data_Feed_UDP_Client", "Port_10004", false, Output_Data_Format::AVR, false, + Mode_S_Output_Type::DF_11_17_18, false, true); + udp_client->specific.write([](auto& value) { + value.port = 30004; + value.url = "192.168.1.75"; + }); + config.data_feed_config.map.push_back(udp_client); + auto tcp_client = std::make_shared(); + configure_feed(*tcp_client, "Data_Feed_TCP_Client", "Port_10005", false, Output_Data_Format::BIN, true, + Mode_S_Output_Type::NO_POS_Mode_S, true, true); + tcp_client->specific.write([](auto& value) { + value.url = "192.168.1.167"; + value.port = 10005; + }); + config.data_feed_config.map.push_back(tcp_client); + config.data_feed_config.map.push_back(make_tcp_server_feed( + "Port_30003", false, Output_Data_Format::SBS, false, Mode_S_Output_Type::ALL_Mode_S, true, true, 30003, 0, 0)); + return {Config_Section::mode_acs, directory / "mode_acs.json", config.to_base_json()}; +} diff --git a/module/Local_Server/server/Config_Default/version.cpp b/module/Local_Server/server/Config_Default/version.cpp new file mode 100644 index 0000000..79ccd3d --- /dev/null +++ b/module/Local_Server/server/Config_Default/version.cpp @@ -0,0 +1,4 @@ +#include "Config_Default.h" +Default_Config_File make_default_version_config(const std::filesystem::path& directory) { + return {Config_Section::version, directory / "version.json", Psc::JSON("v1.0.5")}; +} diff --git a/module/Local_Server/server/Config_Default/web_server.cpp b/module/Local_Server/server/Config_Default/web_server.cpp new file mode 100644 index 0000000..d04c6c5 --- /dev/null +++ b/module/Local_Server/server/Config_Default/web_server.cpp @@ -0,0 +1,7 @@ +#include "Config_Default.h" +Default_Config_File make_default_web_server_config(const std::filesystem::path& directory) { + Web_Server_Config config; + config.webapp = ECAP_DEFAULT_WEBAPP_PATH; + config.listen_port = 9081; + return {Config_Section::web_server, directory / "web_server.json", config.to_base_json()}; +}