#include #include #include #include #include "client.h" #include "config.h" #include "version.h" #ifdef _WIN32 #include #include #include #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif #endif std::shared_ptr g_Config = nullptr; int parse_cmd(int argc, char** argv, CmdParam& param) { std::string intro( fmt::format("tsc cmd introduce, version: {}\nopensource: {}", VERSION_NUM, VERSION_URL)); CLI::App app(intro); app.add_option("-u, --use", param.use_config, "使用服务器地址组(值为使用--show中显示的序号)"); 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, "添加服务器时直接使用此服务器。"); app.add_flag("-l, --last", param.last_use, "直接使用之前最后一次使用的服务器。"); if (argc == 1) { std::cout << app.help() << std::endl; return 0; } // 这里的 CLI11_PARSE 在程序没有输入或者仅输入--help(-h)时,会直接返回,后面代码都不会执行。 // 当有自定义的参数被输入时,后面代码会执行。 try { CLI11_PARSE(app, argc, argv); } catch (const CLI::ParseError& e) { return app.exit(e); } param.parsed = true; return 0; } bool exec_cmd(CmdParam& param, bool& run) { run = false; // 如果是展示 if (param.showValue) { std::vector set; if (!g_Config->read_ini(set)) { return false; } for (const auto& item : set) { TLOGI("{} => {}:{} {}", item.group, item.ip, item.port, item.comment); } return true; } if (param.use_config != -1) { run = true; return true; } if (!param.appendValue.empty() && !param.removeValue.empty()) { TLOGW("append and remove can't simultaneous operate!"); return false; } if (!param.appendValue.empty()) { 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"; } 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()) { if (!g_Config->remove_ini(std::stol(param.removeValue))) { TLOGW("remove config num=[{}] failed, please check!", param.removeValue); return false; } TLOGI("remove config num=[{}] success!", param.removeValue); return true; } if (param.last_use) { return true; } TLOGW("not matched!", param.removeValue); return false; } int main(int argc, char* argv[]) { #ifdef _WIN32 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode; GetConsoleMode(hConsole, &mode); mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; SetConsoleMode(hConsole, mode); #endif std::shared_ptr deleter(new int(), [](int* p) { fc_recovery_color(); delete p; }); g_Config = std::make_shared(); if (!g_Config->baseInit()) { return -1; } bool run = false; CmdParam param; parse_cmd(argc, argv, param); if (!param.parsed) { return 0; } if (!exec_cmd(param, run)) { TLOGW("exec_cmd failed!"); return -1; } if (!run && !param.direct_use && !param.last_use) { return 0; } std::string ip; long port{}; if (param.last_use) { if (!g_Config->get_last_use(ip, port)) { return -1; } } else { std::vector set; if (!g_Config->read_ini(set)) { return -1; } TransmSet use; if (!g_Config->get_ini(set, param.use_config, use)) { TLOGW("Not found config by num:[{}]", param.use_config); return -1; } ip = use.ip; port = use.port; } g_Config->save_last_use(ip, port); TLOGI("Build At {} {} under {} on {}", __DATE__, __TIME__, VERSION_GIT_COMMIT, VERSION_GIT_BRANCH); TLOGI("use ip => [{}], port => [{}]", ip, port); CClient client; client.run(ip, std::to_string(port)); TLOGI("exit =========="); return 0; }