596 lines
25 KiB
C++
596 lines
25 KiB
C++
#include "Config.h"
|
|
#include "Core/Base/Check.h"
|
|
#include "Core/Net_Adapter/Net_Adapter.h"
|
|
#include "Global.h"
|
|
#include <algorithm>
|
|
#include <filesystem>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#undef interface
|
|
|
|
std::string default_config_path;
|
|
|
|
std::string get_config_path() {
|
|
// #ifdef WIN32
|
|
// get_exe_dir()
|
|
// return "D:/ae/proj/projects/ECAP_Server/config/config.json";
|
|
// #endif
|
|
static bool first = true;
|
|
if (!default_config_path.empty())
|
|
return default_config_path;
|
|
std::string ret;
|
|
std::ostringstream oss;
|
|
std::string file_name = "config.json";
|
|
ret = get_exe_dir() + "/" + file_name;
|
|
if (first) {
|
|
std::cout << oss.str() << std::endl;
|
|
first = false;
|
|
}
|
|
return ret;
|
|
}
|
|
static std::vector<std::string> read_string_array(const Psc::JSON* json, std::string_view key) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr || field->valueType != Psc::Array) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
std::vector<std::string> ret;
|
|
ret.reserve(field->children.size());
|
|
for (const auto& child : field->children) {
|
|
if (child.valueType != Psc::String) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
ret.emplace_back(child.val);
|
|
}
|
|
return ret;
|
|
}
|
|
static Psc::JSON write_string_array(std::string_view key, const std::vector<std::string>& list) {
|
|
auto array = Psc::JSON::array();
|
|
for (const auto& path : list) {
|
|
array.append(Psc::JSON(path));
|
|
}
|
|
return Psc::JSON(key, array);
|
|
}
|
|
static const std::pair<std::string_view, std::string_view> kDefaultAircraftModelUrls[] = {
|
|
{"no_category_information", "/ui/model/aircraft-no-category-information.glb"},
|
|
{"surface_emergency_vehicle", "/ui/model/aircraft-surface-emergency-vehicle.glb"},
|
|
{"surface_service_vehicle", "/ui/model/aircraft-surface-service-vehicle.glb"},
|
|
{"ground_obstruction_4", "/ui/model/aircraft-ground-obstruction-4.glb"},
|
|
{"ground_obstruction_5", "/ui/model/aircraft-ground-obstruction-5.glb"},
|
|
{"ground_obstruction_6", "/ui/model/aircraft-ground-obstruction-6.glb"},
|
|
{"ground_obstruction_7", "/ui/model/aircraft-ground-obstruction-7.glb"},
|
|
{"glider", "/ui/model/aircraft-glider.glb"},
|
|
{"lighter_than_air", "/ui/model/aircraft-lighter-than-air.glb"},
|
|
{"parachutist", "/ui/model/aircraft-parachutist.glb"},
|
|
{"ultralight_hangglider_paraglider", "/ui/model/aircraft-ultralight-hangglider-paraglider.glb"},
|
|
{"reserved_3_5", "/ui/model/aircraft-reserved-3-5.glb"},
|
|
{"unmanned_aerial_vehicle", "/ui/model/aircraft-unmanned-aerial-vehicle.glb"},
|
|
{"space_transatmospheric_vehicle", "/ui/model/aircraft-space-transatmospheric-vehicle.glb"},
|
|
{"light_aircraft", "/ui/model/aircraft-light-aircraft.glb"},
|
|
{"medium_1_aircraft", "/ui/model/aircraft-medium-1-aircraft.glb"},
|
|
{"medium_2_aircraft", "/ui/model/aircraft-medium-2-aircraft.glb"},
|
|
{"high_vortex_aircraft", "/ui/model/aircraft-high-vortex-aircraft.glb"},
|
|
{"heavy_aircraft", "/ui/model/aircraft-heavy-aircraft.glb"},
|
|
{"high_performance_aircraft", "/ui/model/aircraft-high-performance-aircraft.glb"},
|
|
{"rotorcraft", "/ui/model/aircraft-rotorcraft.glb"}
|
|
};
|
|
static std::map<std::string, Map_Model_Item_Config> make_default_aircraft_models() {
|
|
std::map<std::string, Map_Model_Item_Config> ret;
|
|
for (const auto& item : kDefaultAircraftModelUrls) {
|
|
ret.emplace(std::string(item.first), Map_Model_Item_Config{std::string(item.second), 50.0, -90.0, 0.0, 0.0});
|
|
}
|
|
return ret;
|
|
}
|
|
static std::map<std::string, Map_Model_Item_Config> read_optional_model_object_field(const Psc::JSON* json, std::string_view key, std::map<std::string, Map_Model_Item_Config> fallback) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr) {
|
|
return fallback;
|
|
}
|
|
if (field->valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
for (const auto& child : field->children) {
|
|
if (child.valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
fallback[child.key].from_base_json(&child);
|
|
}
|
|
return fallback;
|
|
}
|
|
static Psc::JSON write_model_object(std::string_view key, const std::map<std::string, Map_Model_Item_Config>& values) {
|
|
auto object = Psc::JSON::object();
|
|
for (const auto& item : values) {
|
|
object.append({item.first, item.second.to_base_json()});
|
|
}
|
|
return Psc::JSON(key, object);
|
|
}
|
|
static std::string read_string_field(const Psc::JSON* json, std::string_view key) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr || field->valueType != Psc::String) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->val;
|
|
}
|
|
static std::uint32_t read_uint32_field(const Psc::JSON* json, std::string_view key) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr || field->valueType != Psc::Number) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->number_val<std::uint32_t>();
|
|
}
|
|
static std::string read_optional_string_field(const Psc::JSON* json, std::string_view key) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr) {
|
|
return {};
|
|
}
|
|
if (field->valueType != Psc::String) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->val;
|
|
}
|
|
static std::string read_optional_string_field(const Psc::JSON* json, std::string_view key, std::string_view fallback) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr) {
|
|
return std::string(fallback);
|
|
}
|
|
if (field->valueType != Psc::String) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->val;
|
|
}
|
|
static bool read_optional_bool_field(const Psc::JSON* json, std::string_view key, bool fallback) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr) {
|
|
return fallback;
|
|
}
|
|
if (field->valueType != Psc::Bool) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->bool_val();
|
|
}
|
|
static std::uint32_t read_optional_uint32_field(const Psc::JSON* json, std::string_view key, std::uint32_t fallback) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr) {
|
|
return fallback;
|
|
}
|
|
if (field->valueType != Psc::Number) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->number_val<std::uint32_t>();
|
|
}
|
|
static double read_optional_double_field(const Psc::JSON* json, std::string_view key, double fallback) {
|
|
auto field = json->get(key);
|
|
if (field == nullptr) {
|
|
return fallback;
|
|
}
|
|
if (field->valueType != Psc::Number) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
|
}
|
|
return field->number_val<double>();
|
|
}
|
|
void Map_Tile_Config::from_base_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), "map tile config");
|
|
}
|
|
directories = read_string_array(that_json, "directories");
|
|
path_layout = read_string_field(that_json, "path_layout");
|
|
y_axis = read_string_field(that_json, "y_axis");
|
|
projection = read_string_field(that_json, "projection");
|
|
extension = read_string_field(that_json, "extension");
|
|
tile_size = read_uint32_field(that_json, "tile_size");
|
|
minimum_level = read_uint32_field(that_json, "minimum_level");
|
|
maximum_level = read_uint32_field(that_json, "maximum_level");
|
|
encoding = read_optional_string_field(that_json, "encoding");
|
|
}
|
|
Psc::JSON Map_Tile_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append(write_string_array("directories", directories));
|
|
ret.append({"path_layout", path_layout});
|
|
ret.append({"y_axis", y_axis});
|
|
ret.append({"projection", projection});
|
|
ret.append({"extension", extension});
|
|
ret.append({"tile_size", tile_size});
|
|
ret.append({"minimum_level", minimum_level});
|
|
ret.append({"maximum_level", maximum_level});
|
|
if (!encoding.empty()) {
|
|
ret.append({"encoding", encoding});
|
|
}
|
|
return ret;
|
|
}
|
|
Psc::JSON Map_Tile_Config::to_public_json(std::string_view url) const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"url", std::string(url)});
|
|
ret.append({"minimum_level", minimum_level});
|
|
ret.append({"maximum_level", maximum_level});
|
|
ret.append({"tile_size", tile_size});
|
|
ret.append({"projection", projection});
|
|
ret.append({"y_axis", y_axis});
|
|
if (!encoding.empty()) {
|
|
ret.append({"encoding", encoding});
|
|
}
|
|
return ret;
|
|
}
|
|
void Map_Resources_Config::from_base_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), "map_resources");
|
|
}
|
|
current_imagery_key = read_optional_string_field(that_json, "current_imagery_key");
|
|
if (current_imagery_key.empty()) {
|
|
current_imagery_key = "imagery";
|
|
}
|
|
imagery.from_base_json(that_json->get("imagery"));
|
|
google_imagery.from_base_json(that_json->get("google_imagery"));
|
|
terrain.from_base_json(that_json->get("terrain"));
|
|
if (!is_imagery_key(current_imagery_key)) {
|
|
current_imagery_key = "imagery";
|
|
}
|
|
}
|
|
Psc::JSON Map_Resources_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"current_imagery_key", current_imagery_key});
|
|
ret.append({"imagery", imagery.to_base_json()});
|
|
ret.append({"google_imagery", google_imagery.to_base_json()});
|
|
ret.append({"terrain", terrain.to_base_json()});
|
|
return ret;
|
|
}
|
|
static Psc::JSON make_public_imagery_source(std::string_view key, std::string_view name, const Psc::JSON& resource) {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"key", std::string(key)});
|
|
ret.append({"name", std::string(name)});
|
|
ret.append({"resource", resource});
|
|
return ret;
|
|
}
|
|
static Psc::JSON make_osm_public_resource() {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"url", "https://tile.openstreetmap.org/{z}/{x}/{y}.png"});
|
|
ret.append({"minimum_level", 0});
|
|
ret.append({"maximum_level", 19});
|
|
ret.append({"tile_size", 256});
|
|
ret.append({"projection", "web_mercator"});
|
|
ret.append({"y_axis", "xyz"});
|
|
ret.append({"credit", "OpenStreetMap contributors"});
|
|
return ret;
|
|
}
|
|
Psc::JSON Map_Resources_Config::to_public_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
auto imagery_json = imagery.to_public_json("/map/imagery/{z}/{x}/{y}");
|
|
auto google_imagery_json = google_imagery.to_public_json("/tiles/{z}/{x}/{y}");
|
|
auto osm_json = make_osm_public_resource();
|
|
auto sources = Psc::JSON::array();
|
|
sources.append(make_public_imagery_source("imagery", "本地卫星影像", imagery_json));
|
|
sources.append(make_public_imagery_source("google_imagery", "本地Google瓦片", google_imagery_json));
|
|
sources.append(make_public_imagery_source("osm_online", "OpenStreetMap在线", osm_json));
|
|
ret.append({"current_imagery_key", current_imagery_key});
|
|
ret.append({"imagery_sources", sources});
|
|
ret.append({"imagery", imagery_json});
|
|
ret.append({"google_imagery", google_imagery_json});
|
|
ret.append({"terrain", terrain.to_public_json("/map/terrain/{z}/{x}/{y}")});
|
|
return ret;
|
|
}
|
|
bool Map_Resources_Config::is_imagery_key(std::string_view key) const {
|
|
return key == "imagery" || key == "google_imagery" || key == "osm_online";
|
|
}
|
|
void Map_Camera_Config::from_base_json(const Psc::JSON* that_json) {
|
|
if (that_json == nullptr) {
|
|
return;
|
|
}
|
|
if (that_json->valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map camera");
|
|
}
|
|
longitude = read_optional_double_field(that_json, "longitude", longitude);
|
|
latitude = read_optional_double_field(that_json, "latitude", latitude);
|
|
height = read_optional_double_field(that_json, "height", height);
|
|
heading = read_optional_double_field(that_json, "heading", heading);
|
|
pitch = read_optional_double_field(that_json, "pitch", pitch);
|
|
roll = read_optional_double_field(that_json, "roll", roll);
|
|
}
|
|
Psc::JSON Map_Camera_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"longitude", longitude});
|
|
ret.append({"latitude", latitude});
|
|
ret.append({"height", height});
|
|
ret.append({"heading", heading});
|
|
ret.append({"pitch", pitch});
|
|
ret.append({"roll", roll});
|
|
return ret;
|
|
}
|
|
bool Map_View_Config::is_scene_mode(std::string_view mode) {
|
|
return mode == "2d" || mode == "2.5d" || mode == "3d";
|
|
}
|
|
bool Map_Tile_View_Config::is_tile_zoom_mode(std::string_view mode) {
|
|
return mode == "native" || mode == "upscale" || mode == "both";
|
|
}
|
|
void Map_Tile_View_Config::from_base_json(const Psc::JSON* that_json) {
|
|
if (that_json == nullptr) {
|
|
return;
|
|
}
|
|
if (that_json->valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map_tile_view");
|
|
}
|
|
current_imagery_key = read_optional_string_field(that_json, "current_imagery_key", current_imagery_key);
|
|
auto next_tile_zoom_mode = read_optional_string_field(that_json, "tile_zoom_mode", tile_zoom_mode);
|
|
if (!is_tile_zoom_mode(next_tile_zoom_mode)) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "tile_zoom_mode");
|
|
}
|
|
tile_zoom_mode = next_tile_zoom_mode;
|
|
tile_display_maximum_level = std::clamp(read_optional_uint32_field(that_json, "tile_display_maximum_level", tile_display_maximum_level), 0u, 24u);
|
|
}
|
|
Psc::JSON Map_Tile_View_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"current_imagery_key", current_imagery_key});
|
|
ret.append({"tile_zoom_mode", tile_zoom_mode});
|
|
ret.append({"tile_display_maximum_level", tile_display_maximum_level});
|
|
return ret;
|
|
}
|
|
void Map_View_Config::from_base_json(const Psc::JSON* that_json) {
|
|
if (that_json == nullptr) {
|
|
return;
|
|
}
|
|
if (that_json->valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map_view");
|
|
}
|
|
auto next_scene_mode = read_optional_string_field(that_json, "scene_mode", scene_mode);
|
|
if (!is_scene_mode(next_scene_mode)) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "scene_mode");
|
|
}
|
|
scene_mode = next_scene_mode;
|
|
map2d.from_base_json(that_json->get("map2d"));
|
|
map3d.from_base_json(that_json->get("map3d"));
|
|
camera.from_base_json(that_json->get("camera"));
|
|
}
|
|
Psc::JSON Map_View_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"scene_mode", scene_mode});
|
|
ret.append({"map2d", map2d.to_base_json()});
|
|
ret.append({"map3d", map3d.to_base_json()});
|
|
ret.append({"camera", camera.to_base_json()});
|
|
return ret;
|
|
}
|
|
void Cesium_Graphics_Config::from_base_json(const Psc::JSON* that_json) {
|
|
if (that_json == nullptr) {
|
|
return;
|
|
}
|
|
if (that_json->valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "cesium_graphics");
|
|
}
|
|
debug_show_frames_per_second = read_optional_bool_field(that_json, "debug_show_frames_per_second", debug_show_frames_per_second);
|
|
target_frame_rate = std::clamp(read_optional_uint32_field(that_json, "target_frame_rate", target_frame_rate), 1u, 120u);
|
|
use_browser_recommended_resolution = read_optional_bool_field(that_json, "use_browser_recommended_resolution", use_browser_recommended_resolution);
|
|
resolution_scale = std::clamp(read_optional_double_field(that_json, "resolution_scale", resolution_scale), 0.2, 1.5);
|
|
msaa_samples = std::clamp(read_optional_uint32_field(that_json, "msaa_samples", msaa_samples), 1u, 8u);
|
|
fxaa = read_optional_bool_field(that_json, "fxaa", fxaa);
|
|
shadows = read_optional_bool_field(that_json, "shadows", shadows);
|
|
enable_lighting = read_optional_bool_field(that_json, "enable_lighting", enable_lighting);
|
|
solar_lighting = read_optional_bool_field(that_json, "solar_lighting", solar_lighting);
|
|
solar_light_intensity = read_optional_double_field(that_json, "solar_light_intensity", solar_light_intensity);
|
|
maximum_screen_space_error = std::clamp(read_optional_uint32_field(that_json, "maximum_screen_space_error", maximum_screen_space_error), 1u, 16u);
|
|
terrain_enabled_in_3d = read_optional_bool_field(that_json, "terrain_enabled_in_3d", terrain_enabled_in_3d);
|
|
terrain_exaggeration = read_optional_double_field(that_json, "terrain_exaggeration", terrain_exaggeration);
|
|
terrain_limit_maximum_level = read_optional_bool_field(that_json, "terrain_limit_maximum_level", terrain_limit_maximum_level);
|
|
terrain_maximum_level = std::clamp(read_optional_uint32_field(that_json, "terrain_maximum_level", terrain_maximum_level), 0u, 24u);
|
|
terrain_cache_tiles = std::clamp(read_optional_uint32_field(that_json, "terrain_cache_tiles", terrain_cache_tiles), 16u, 2048u);
|
|
}
|
|
Psc::JSON Cesium_Graphics_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"debug_show_frames_per_second", debug_show_frames_per_second});
|
|
ret.append({"target_frame_rate", target_frame_rate});
|
|
ret.append({"use_browser_recommended_resolution", use_browser_recommended_resolution});
|
|
ret.append({"resolution_scale", resolution_scale});
|
|
ret.append({"msaa_samples", msaa_samples});
|
|
ret.append({"fxaa", fxaa});
|
|
ret.append({"shadows", shadows});
|
|
ret.append({"enable_lighting", enable_lighting});
|
|
ret.append({"solar_lighting", solar_lighting});
|
|
ret.append({"solar_light_intensity", solar_light_intensity});
|
|
ret.append({"maximum_screen_space_error", maximum_screen_space_error});
|
|
ret.append({"terrain_enabled_in_3d", terrain_enabled_in_3d});
|
|
ret.append({"terrain_exaggeration", terrain_exaggeration});
|
|
ret.append({"terrain_limit_maximum_level", terrain_limit_maximum_level});
|
|
ret.append({"terrain_maximum_level", terrain_maximum_level});
|
|
ret.append({"terrain_cache_tiles", terrain_cache_tiles});
|
|
return ret;
|
|
}
|
|
Map_Model_Item_Config::Map_Model_Item_Config(std::string url)
|
|
: url(std::move(url)) {}
|
|
Map_Model_Item_Config::Map_Model_Item_Config(std::string url, double built_in_size, double heading, double pitch, double roll)
|
|
: url(std::move(url)), built_in_size(built_in_size), heading_offset_degrees(heading), pitch_offset_degrees(pitch), roll_offset_degrees(roll) {}
|
|
void Map_Model_Item_Config::from_base_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), "map_model_item");
|
|
}
|
|
url = read_optional_string_field(that_json, "url", url);
|
|
built_in_size = read_optional_double_field(that_json, "built_in_size", built_in_size);
|
|
heading_offset_degrees = read_optional_double_field(that_json, "heading_offset_degrees", heading_offset_degrees);
|
|
pitch_offset_degrees = read_optional_double_field(that_json, "pitch_offset_degrees", pitch_offset_degrees);
|
|
roll_offset_degrees = read_optional_double_field(that_json, "roll_offset_degrees", roll_offset_degrees);
|
|
}
|
|
Psc::JSON Map_Model_Item_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"url", url});
|
|
ret.append({"built_in_size", built_in_size});
|
|
ret.append({"heading_offset_degrees", heading_offset_degrees});
|
|
ret.append({"pitch_offset_degrees", pitch_offset_degrees});
|
|
ret.append({"roll_offset_degrees", roll_offset_degrees});
|
|
return ret;
|
|
}
|
|
Map_Model_Config::Map_Model_Config()
|
|
: aircraft_models(make_default_aircraft_models()) {}
|
|
void Map_Model_Config::from_base_json(const Psc::JSON* that_json) {
|
|
if (that_json == nullptr) {
|
|
return;
|
|
}
|
|
if (that_json->valueType != Psc::Object) {
|
|
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map_models");
|
|
}
|
|
aircraft_model.from_base_json(that_json->get("aircraft_model"));
|
|
aircraft_models = read_optional_model_object_field(that_json, "aircraft_models", make_default_aircraft_models());
|
|
base_station_model.from_base_json(that_json->get("base_station_model"));
|
|
}
|
|
Psc::JSON Map_Model_Config::to_base_json() const {
|
|
auto ret = Psc::JSON::object();
|
|
ret.append({"aircraft_model", aircraft_model.to_base_json()});
|
|
ret.append(write_model_object("aircraft_models", aircraft_models));
|
|
ret.append({"base_station_model", base_station_model.to_base_json()});
|
|
return ret;
|
|
}
|
|
|
|
void Mode_ACS_Config::server(Global *g) {
|
|
auto &svr = g->svr;
|
|
auto &api = g->api;
|
|
data_source_config.server(g);
|
|
data_feed_config.server(g);
|
|
source_feed_relation_config.server(g);
|
|
|
|
svr.Post(api + "get_mode_s_basic_config", [this](HTTP_Param) {
|
|
CHECK_JSON_PARAM
|
|
res->setBody(warp(to_base_json()).to_json_string());
|
|
});
|
|
svr.Post(api + "set_mode_s_basic_config", [this](HTTP_Param) {
|
|
CHECK_JSON_PARAM
|
|
auto &j = o_params.value();
|
|
init_base_json(&j);
|
|
if (auto min_points = j.try_get_number<std::size_t>("aircraft_change_list_min_position_points")) {
|
|
aircraft_change_list_min_position_points = min_points.value();
|
|
}
|
|
if (auto range_filter = j.try_get_bool("aircraft_change_list_adsb_range_filter")) {
|
|
aircraft_change_list_adsb_range_filter = range_filter.value();
|
|
}
|
|
if (auto range_factor = j.try_get_number<double>("aircraft_change_list_adsb_range_factor")) {
|
|
aircraft_change_list_adsb_range_factor = range_factor.value();
|
|
}
|
|
if (auto target_altitude = j.try_get_number<double>("adsb_theoretical_target_altitude_meters")) {
|
|
adsb_theoretical_target_altitude_meters = target_altitude.value();
|
|
}
|
|
Global::save();
|
|
res->setBody(warp(to_base_json()).to_json_string());
|
|
});
|
|
}
|
|
|
|
void Device_Config::server(Global *g) {
|
|
auto &svr = g->svr;
|
|
auto &api = g->api;
|
|
svr.Post(api + "get_device_config", [this](HTTP_Param) {
|
|
res->setBody(warp(to_base_json()).to_json_string());
|
|
});
|
|
|
|
svr.Post(api + "get_net_adapter_list", [this](HTTP_Param) {
|
|
JSON ret = JSON::object();
|
|
auto arr = JSON::array();
|
|
for (auto &it: Psc::get_net_adapter_info_map()) {
|
|
arr.append(it.second.to_Json());
|
|
}
|
|
ret.append({"list", arr});
|
|
res->setBody(warp(ret).to_json_string());
|
|
});
|
|
|
|
svr.Post(api + "set_device_config", [this](HTTP_Param) {
|
|
CHECK_JSON_PARAM
|
|
JSON old_device_config;
|
|
{
|
|
old_device_config = to_base_json();
|
|
}
|
|
HTTP_REQUIRE_PTR(net, params.get("net"))
|
|
Net_Config device, wifi;
|
|
bool has_device = false;
|
|
bool has_wifi = false;
|
|
for (const auto &it: net->children) {
|
|
HTTP_REQUIRE_VALUE(net_key, it.try_get_string("key"))
|
|
if (net_key == "device") {
|
|
device.from_base_json(&it);
|
|
has_device = true;
|
|
}
|
|
if (net_key == "wifi") {
|
|
wifi.from_base_json(&it);
|
|
has_wifi = true;
|
|
}
|
|
}
|
|
HTTP_REQUIRE_TRUE(has_device && has_wifi, "net")
|
|
|
|
bool it1 =
|
|
check_ip_netmask_gateway(device.ip, device.netmask, device.gateway);
|
|
bool it2 = check_ip_netmask_gateway(wifi.ip, wifi.netmask, wifi.gateway);
|
|
bool p1 = check_port(device.port);
|
|
bool p2 = check_port(wifi.port);
|
|
if (!it1 || !it2 || !p1 || !p2) {
|
|
server_logger->error("", {},
|
|
LOG_POS + " ip port! " + device.ip + ":" +
|
|
std::to_string(device.port));
|
|
res->setBody(warp(old_device_config).to_json_string());
|
|
return;
|
|
}
|
|
|
|
#if WIN32
|
|
bool use = false;
|
|
#else
|
|
bool use = true;
|
|
#endif
|
|
{
|
|
auto &w = *this;
|
|
*w.list.get("device").value() = device;
|
|
*w.list.get("wifi").value() = wifi;
|
|
}
|
|
Global::save();
|
|
if (use) {
|
|
std::string interface;
|
|
{
|
|
std::string path = get_exe_dir() + "/interface";
|
|
std::ifstream ifs(path);
|
|
if (!ifs.is_open()) {
|
|
server_logger->error("", {}, LOG_POS + " 无法打开文件! " + path);
|
|
res->setBody(warp(old_device_config).to_json_string());
|
|
return;
|
|
}
|
|
std::stringstream buffer;
|
|
buffer << ifs.rdbuf();
|
|
interface = buffer.str();
|
|
}
|
|
static auto set = [](std::string &interface, std::string_view token,
|
|
std::string_view value) {
|
|
std::string var_name = "${" + std::string(token) + "}";
|
|
auto size = var_name.size();
|
|
size_t pos = interface.find(var_name);
|
|
while (pos != std::string::npos) {
|
|
interface.replace(pos, size, value);
|
|
pos = interface.find(var_name);
|
|
}
|
|
};
|
|
set(interface, "ip", device.ip);
|
|
set(interface, "gateway", device.gateway);
|
|
set(interface, "netmask", device.netmask);
|
|
set(interface, "wifi_ip", wifi.ip);
|
|
set(interface, "wifi_gateway", wifi.gateway);
|
|
set(interface, "wifi_netmask", wifi.netmask);
|
|
std::cout << interface << std::endl;
|
|
std::string path = "/etc/network/interfaces";
|
|
std::ofstream outfile(path);
|
|
if (!outfile.is_open()) {
|
|
server_logger->error("", {}, LOG_POS + " 无法打开文件!" + path);
|
|
res->setBody(warp(old_device_config).to_json_string());
|
|
return;
|
|
}
|
|
outfile << interface;
|
|
outfile.close();
|
|
std::string bash_path = get_exe_dir() + "/restart_net_service.sh";
|
|
if (!std::filesystem::exists(bash_path)) {
|
|
server_logger->error("", {}, LOG_POS + " !" + bash_path);
|
|
res->setBody(warp(old_device_config).to_json_string());
|
|
return;
|
|
}
|
|
int result = system(bash_path.c_str());
|
|
if (result != 0) {
|
|
server_logger->error("", {}, LOG_POS + " 脚本执行失败!" + bash_path);
|
|
res->setBody(warp(old_device_config).to_json_string());
|
|
return;
|
|
}
|
|
}
|
|
res->setBody(warp(params).to_json_string());
|
|
});
|
|
}
|
|
|
|
void Config::save() {
|
|
std::ofstream config_file;
|
|
config_file.open(get_config_path());
|
|
std::string json = Global::instance()->toJson().to_json_string();
|
|
config_file.write(json.c_str(), static_cast<long long>(json.size()));
|
|
config_file.close();
|
|
}
|