diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000..522c8be --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,63 @@ +{ + "configurations": [ + { + "name": "x64 Local Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "" + }, + { + "name": "x64 Local Release", + "generator": "Ninja", + "configurationType": "Release", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}" + }, + { + "name": "x64 Linux Debug", + "generator": "Ninja", + "configurationType": "Debug", + "cmakeExecutable": "cmake", + "remoteCopySourcesExclusionList": [ ".vs", "out" ], + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x64" ], + "remoteMachineName": "${defaultRemoteMachineName}", + "remoteCMakeListsRoot": "$HOME/vs/${projectDirName}/${workspaceHash}/src", + "remoteBuildRoot": "$HOME/vs/${projectDirName}/${workspaceHash}/out/build/${name}", + "remoteInstallRoot": "$HOME/vs/${projectDirName}/${workspaceHash}/out/install/${name}", + "remoteCopySources": true, + "rsyncCommandArgs": "-t --delete", + "remoteCopyBuildOutput": false, + "remoteCopySourcesMethod": "rsync", + "variables": [] + }, + { + "name": "x64 Linux Release", + "generator": "Ninja", + "configurationType": "Release", + "cmakeExecutable": "cmake", + "remoteCopySourcesExclusionList": [ ".vs", "out" ], + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x64" ], + "remoteMachineName": "${defaultRemoteMachineName}", + "remoteCMakeListsRoot": "$HOME/vs/${projectDirName}/${workspaceHash}/src", + "remoteBuildRoot": "$HOME/vs/${projectDirName}/${workspaceHash}/out/build/${name}", + "remoteInstallRoot": "$HOME/vs/${projectDirName}/${workspaceHash}/out/install/${name}", + "remoteCopySources": true, + "rsyncCommandArgs": "-t --delete", + "remoteCopyBuildOutput": false, + "remoteCopySourcesMethod": "rsync", + "variables": [] + } + ] +} \ No newline at end of file diff --git a/client/config.cpp b/client/config.cpp index cb70ba8..d05ea1b 100644 --- a/client/config.cpp +++ b/client/config.cpp @@ -48,11 +48,28 @@ bool CServerConfig::read_ini(std::vector& set) ts.grp_id = i; ts.ip = ini_handle_.GetValue(key.c_str(), "IP"); ts.port = ini_handle_.GetLongValue(key.c_str(), "PORT"); + if (!ini_handle_.KeyExists(key.c_str(), "COMMENT")) { + ts.comment = "default"; + } else { + ts.comment = ini_handle_.GetValue(key.c_str(), "COMMENT"); + } set.push_back(ts); } return true; } +long CServerConfig::have_ini(const std::vector& set, const std::string& ip, long port) +{ + long id = -1; + for (const auto& item : set) { + if (item.ip == ip && item.port == port) { + id = item.grp_id; + break; + } + } + return id; +} + bool CServerConfig::write_ini(const std::vector& set) { assert(init_ == true); @@ -60,21 +77,35 @@ bool CServerConfig::write_ini(const std::vector& set) std::string key = "GROUP" + std::to_string(start); ini_handle_.SetValue(key.c_str(), "IP", set[start].ip.c_str()); ini_handle_.SetLongValue(key.c_str(), "PORT", set[start].port); + ini_handle_.SetValue(key.c_str(), "COMMENT", set[start].comment.c_str()); } ini_handle_.SaveFile(config_path_.c_str()); return true; } -bool CServerConfig::append_ini(const std::string& ip, long port) +long CServerConfig::append_ini(const std::string& ip, long port, const std::string& comment) { assert(init_ == true); - int group = ini_handle_.GetLongValue("BASE", "GROUPS"); - std::string node_name = "GROUP" + std::to_string(group); + long id = -1; + std::vector set; + if (!read_ini(set)) { + return false; + } + id = have_ini(set, ip, port); + if (id >= 0) { + std::string node_name = "GROUP" + std::to_string(id); + ini_handle_.SetValue(node_name.c_str(), "COMMENT", comment.c_str()); + ini_handle_.SaveFile(config_path_.c_str()); + return true; + } + id = ini_handle_.GetLongValue("BASE", "GROUPS"); + std::string node_name = "GROUP" + std::to_string(id); ini_handle_.SetValue(node_name.c_str(), "IP", ip.c_str()); ini_handle_.SetLongValue(node_name.c_str(), "PORT", port); - ini_handle_.SetLongValue("BASE", "GROUPS", group + 1); + ini_handle_.SetValue(node_name.c_str(), "COMMENT", comment.c_str()); + ini_handle_.SetLongValue("BASE", "GROUPS", id + 1); ini_handle_.SaveFile(config_path_.c_str()); - return true; + return id; } bool CServerConfig::remove_ini(long num) diff --git a/client/config.h b/client/config.h index f91aae1..b95a08b 100644 --- a/client/config.h +++ b/client/config.h @@ -8,6 +8,7 @@ using namespace ofen; struct TransmSet { std::string group; std::string ip{}; + std::string comment{}; long port{}; long grp_id{}; }; @@ -18,6 +19,7 @@ struct CmdParam { bool showValue{false}; long use_config{-1}; bool parsed{false}; + bool direct_use{false}; }; class CServerConfig @@ -29,8 +31,9 @@ public: public: bool baseInit(); bool read_ini(std::vector& set); + long have_ini(const std::vector& set, const std::string& ip, long port); bool write_ini(const std::vector& set); - bool append_ini(const std::string& ip, long port); + long append_ini(const std::string& ip, long port, const std::string& comment); bool remove_ini(long num); static bool get_ini(const std::vector& set, long num, TransmSet& use); diff --git a/client/main.cpp b/client/main.cpp index c6e0171..acb9d4f 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -24,9 +24,10 @@ int parse_cmd(int argc, char** argv, CmdParam& param) CLI::App app(intro); app.add_option("-n, --number", param.use_config, "使用服务器地址组(值为使用--show中显示的序号)"); - app.add_option("-a, --append", param.appendValue, "添加服务器地址组(地址格式:127.0.0.1:9898)"); + app.add_option("-a, --append", param.appendValue, "添加服务器地址组(地址格式:127.0.0.1:9898:注释)"); app.add_flag("-s, --show", param.showValue, "查看服务器地址组"); app.add_option("-r, --remove", param.removeValue, "移除服务器地址组(值为使用--show中显示的序号)"); + app.add_flag("-d, --direct", param.direct_use, "添加服务器时直接使用此服务器。"); if (argc == 1) { std::cout << app.help() << std::endl; @@ -43,7 +44,7 @@ int parse_cmd(int argc, char** argv, CmdParam& param) return 0; } -bool exec_cmd(const CmdParam& param, bool& run) +bool exec_cmd(CmdParam& param, bool& run) { run = false; // 如果是展示 @@ -53,7 +54,7 @@ bool exec_cmd(const CmdParam& param, bool& run) return false; } for (const auto& item : set) { - TLOGI("{} => {}:{}", item.group, item.ip, item.port); + TLOGI("{} => {}:{} {}", item.group, item.ip, item.port, item.comment); } return true; } @@ -66,19 +67,21 @@ bool exec_cmd(const CmdParam& param, bool& run) return false; } if (!param.appendValue.empty()) { - std::regex rg(R"(([^:]+):(\d+))"); - std::smatch match; - if (!std::regex_search(param.appendValue, match, rg)) { - TLOGW("append invalid format!"); - return false; + std::regex pattern(R"((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)(?::(.*))?)"); + std::smatch matches; + std::string ip, port, comment; + if (std::regex_match(param.appendValue, matches, pattern)) { + ip = matches[1].str(); + port = matches[2].str(); + comment = matches.size() > 3 ? matches[3].str() : "default"; } - std::string ip = match[1].str(); - std::string port = match[2].str(); - if (!g_Config->append_ini(ip, std::stol(port))) { + auto id = g_Config->append_ini(ip, std::stol(port), comment); + if (id < 0) { TLOGW("add {}:{} failed.", ip, port); return false; } TLOGI("add {}:{} success.", ip, port); + param.use_config = id; return true; } if (!param.removeValue.empty()) { @@ -123,7 +126,7 @@ int main(int argc, char* argv[]) TLOGW("exec_cmd failed!"); return -1; } - if (!run) { + if (!run && !param.direct_use) { return 0; } diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt deleted file mode 100644 index 5bdc7cc..0000000 --- a/gui/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -project(tsc-gui LANGUAGES CXX) - -# 查找 FLTK 模块 -find_package(FLTK REQUIRED NO_MODULE) -# 包含 FLTK 头文件 -include_directories(${FLTK_INCLUDE_DIRS}) -# 输出 FLTK 头文件路径 -message(STATUS "FLTK include: ${FLTK_INCLUDE_DIRS}") - -add_executable(tsc-gui main.cxx) -target_link_libraries(tsc-gui PRIVATE fltk::fltk) \ No newline at end of file diff --git a/gui/main.cxx b/gui/main.cxx deleted file mode 100644 index 82dd7f2..0000000 --- a/gui/main.cxx +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include - -int main(int argc, char** argv) -{ - // 创建主窗口 - Fl_Window* window = new Fl_Window(800, 600, u8"FLTK 上下布局示例"); - window->color(FL_WHITE); - - // 创建一个垂直排列的 Fl_Pack 容器 - Fl_Pack* vpack = new Fl_Pack(0, 0, 800, 600); - vpack->type(Fl_Pack::VERTICAL); // 设置为垂直布局 - vpack->spacing(10); // 设置子部件之间的间距 - - // 上部分内容 - Fl_Box* top_box = new Fl_Box(0, 0, 800, 300, u8"上部分"); - top_box->box(FL_UP_BOX); - top_box->color(FL_BLUE); - top_box->labelsize(24); - top_box->labelcolor(FL_WHITE); - - // 下部分内容 - Fl_Box* bottom_box = new Fl_Box(0, 0, 800, 300, u8"下部分"); - bottom_box->box(FL_UP_BOX); - bottom_box->color(FL_GREEN); - bottom_box->labelsize(24); - bottom_box->labelcolor(FL_WHITE); - - // 结束 Fl_Pack 容器 - vpack->end(); - - // 设置窗口的布局容器 - window->end(); - window->resizable(vpack); // 使布局随窗口缩放 - window->show(argc, argv); - - // 运行事件循环 - return Fl::run(); -} \ No newline at end of file