CLashConfig.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. #include "stdafx.h"
  2. #include "CLashConfig.h"
  3. #include "CApp.h"
  4. #include "comm.h"
  5. #include "FileOperate.h"
  6. CLashConfig::CLashConfig() : m_socks_port(9200), m_http_port(9300), m_c_port(9090), m_process(nullptr), m_Asyntask(1), m_AsyntaskProcessMonitor(1), m_is_qut(false), m_log(nullptr)
  7. {
  8. SNotifyCenter::getSingleton().addEvent(EVENTID(EventClashPreOceeQut));
  9. _hEvent = nullptr;
  10. }
  11. CLashConfig::~CLashConfig(void)
  12. {
  13. if (m_process)
  14. {
  15. delete m_process;
  16. m_process = nullptr;
  17. }
  18. if (m_log)
  19. {
  20. delete m_log;
  21. m_log = nullptr;
  22. }
  23. }
  24. BOOL CLashConfig::MakeClash()
  25. {
  26. buildRules();
  27. YAML::Node root;
  28. root["port"] = m_http_port;
  29. root["socks-port"] = m_socks_port;
  30. root["allow-lan"] = true;
  31. root["external-controller"] = "127.0.0.1:" + std::to_string(m_c_port);
  32. if (CApp::getSingletonPtr()->GetRouteMode() == ROUT_MODE::cn_mode)
  33. {
  34. root["mode"] = "rule";
  35. }
  36. else {
  37. root["mode"] = "rule";
  38. }
  39. #ifdef _DEBUG
  40. root["log-level"] = "debug";
  41. #else
  42. root["log-level"] = "info";
  43. #endif
  44. root["dns"] = buildDnsConfig();
  45. if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode)
  46. {
  47. root["tun"] = builTunConfig();
  48. }
  49. //proxys.reserve(0);
  50. //CList_node::getSingletonPtr()->listnode;
  51. YAML::Node proxies;
  52. //for each (LISTNODE node in CList_node::getSingletonPtr()->listnode)
  53. //{
  54. // if (node.type == "shadowsocks") {
  55. // proxies.push_back(buildShadowsocks(&node));
  56. // }
  57. // else if (node.type == "trojan") {
  58. // proxies.push_back(buildtrojan(&node));
  59. // }
  60. // else if (node.type == "v2ray") {
  61. // proxies.push_back(buildv2ray(&node));
  62. // }
  63. //}
  64. root["proxies"] = proxies;
  65. root["proxy-groups"] = buildProxyGroups();
  66. YAML::Node reject;
  67. YAML::Node google;
  68. YAML::Node gfw;
  69. YAML::Node proxy;
  70. YAML::Node cncidr;
  71. reject["type"] = "http";
  72. reject["behavior"] = "domain";
  73. reject["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/reject.txt";
  74. reject["path"] = "./ruleset/reject.yaml";
  75. reject["interval"] = 86400;
  76. google["type"] = "http";
  77. google["behavior"] = "domain";
  78. google["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/google.txt";
  79. google["path"] = "./ruleset/google.yaml";
  80. google["interval"] = 86400;
  81. gfw["type"] = "http";
  82. gfw["behavior"] = "domain";
  83. gfw["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/gfw.txt";
  84. gfw["path"] = "./ruleset/gfw.yaml";
  85. gfw["interval"] = 86400;
  86. proxy["type"] = "http";
  87. proxy["behavior"] = "domain";
  88. proxy["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt";
  89. proxy["path"] = "./ruleset/proxy.yaml";
  90. proxy["interval"] = 86400;
  91. cncidr["type"] = "http";
  92. cncidr["behavior"] = "domain";
  93. cncidr["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/cncidr.txt";
  94. cncidr["path"] = "./ruleset/cncidr.yaml";
  95. cncidr["interval"] = 86400;
  96. if (CApp::getSingletonPtr()->GetRouteMode() == ROUT_MODE::cn_mode)
  97. {
  98. root["rule-providers"]["reject"] = reject;
  99. root["rule-providers"]["cncidr"] = cncidr;
  100. root["rule-providers"]["proxy"] = proxy;
  101. root["rule-providers"]["gfw"] = gfw;
  102. root["rule-providers"]["google"] = google;
  103. }
  104. root["rules"] = m_rules;
  105. auto name_file = "config.yaml";
  106. if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode) {
  107. name_file = "tun_config.yaml";
  108. }
  109. //std::ofstream ofstream(path + "\\config\\" + name_file);
  110. //// ÉèÖÃÅäÖÃÎļþnodeÊý
  111. //ofstream << root << std::endl;
  112. //ofstream.close();
  113. return TRUE;
  114. }
  115. BOOL CLashConfig::InitClash()
  116. {
  117. if (!m_process)
  118. {
  119. m_process = new CProcess();
  120. }
  121. std::string logfile = std::filesystem::current_path().string() + "\\log\\log.log";
  122. if (m_log == nullptr)
  123. {
  124. m_log = new Logger(Logger::file_and_terminal, Logger::info, logfile);
  125. }
  126. m_http_port = CTool::getSingletonPtr()->FindAvailableTcpPort(9300,9500);
  127. m_socks_port = CTool::getSingletonPtr()->FindAvailableTcpPort(9600,9800);
  128. m_c_port = CTool::getSingletonPtr()->FindAvailableTcpPort(9900);
  129. ;
  130. /*std::string dir = CLASHCONFIGDIR;
  131. auto name_file = dir + "\\" + CLASHCONFIINIT;
  132. */
  133. auto name_file = DSPROXY_CONFIG_INIT_ClASH_NAME;
  134. if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode) {
  135. /*name_file = dir + "\\" + CLASHCONFIINIT;*/
  136. name_file = DSPROXY_CONFIG_TUN_ClASH_NAME;
  137. }
  138. YAML::Node root;
  139. root["port"] = m_http_port;
  140. root["socks-port"] = m_socks_port;
  141. root["allow-lan"] = true;
  142. root["external-controller"] = "127.0.0.1:" + std::to_string(m_c_port);
  143. try
  144. {
  145. auto config_path = CApp::getSingletonPtr()->GetConfigPath().wstring() + L"\\" + name_file;
  146. std::ofstream ofstream(config_path);
  147. ofstream << root << std::endl;
  148. ofstream.close();
  149. return TRUE;
  150. }
  151. catch (const std::exception&)
  152. {
  153. return FALSE;
  154. }
  155. return TRUE;
  156. }
  157. BOOL CLashConfig::StartClash()
  158. {
  159. /*wil::unique_handle hEvent(CreateEventW(nullptr, FALSE, FALSE, nullptr));
  160. THROW_LAST_ERROR_IF_NULL(hEvent);*/
  161. //std::wstring config = path + L"\\" + WCLASHCONFIGDIR;
  162. ////args.push_back("-d");
  163. //////args.push_back(std::filesystem::current_path().string() + "\\route");
  164. ////args.push_back(path + "\\config");
  165. ////args.push_back("-f");
  166. ////args.push_back(path + "\\config\\configinit.yaml");
  167. //std::wstring run_config = config + L"\\" + S_CA2W(CLASHCONFIINIT).GetBuffer(0);
  168. //SStringW path_config;
  169. //path_config.Format(L"%s\\%s -d %s -f %s", config.c_str(),CLASHEXE,config.c_str(), run_config.c_str());
  170. auto assetsDir = std::filesystem::current_path() / CLASH_ASSETS_DIR_NAME;
  171. auto confg_path = CApp::getSingletonPtr()->GetConfigPath() / DSPROXY_CONFIG_INIT_ClASH_NAME;
  172. CProcessManager::getSingletonPtr()->SetArgs(assetsDir / DSPROXY_EXE_NAME, assetsDir, std::move(confg_path));
  173. /*ProcessManager::SetConfigFile(confg_path / DSPROXY_CONFIG_INIT_ClASH_NAME);*/
  174. /* m_Asyntask.AddTask(&CLashConfig::ThreadFun_process_Config, this, (LPARAM)CProcessManager::getSingletonPtr());*/
  175. if (CProcessManager::getSingletonPtr()->Start())
  176. {
  177. CApp::getSingletonPtr()->SetCLashRuning(true);
  178. m_AsyntaskProcessMonitor.AddTask(&CLashConfig::ThreadFun_ProcessMonitor_Config, this, (LPARAM)CProcessManager::getSingletonPtr());
  179. }
  180. /*if (m_process)
  181. {
  182. m_process->Create(CProcess::ASYNC);
  183. if (m_process->Execute(path_config.GetBuffer(0)))
  184. {
  185. }
  186. }*/
  187. return 0;
  188. }
  189. BOOL CLashConfig::StopClash()
  190. {
  191. m_is_qut = true;
  192. /*SetEvent(_hEvent.get());*/
  193. //char ch[MAX_PATH];
  194. //memset(ch, 0, MAX_PATH);
  195. //sprintf_s(ch, "ok\n");
  196. //m_process->WriteSome(ch, sizeof(ch));
  197. return 0;
  198. }
  199. YAML::Node CLashConfig::buildShadowsocks()
  200. {
  201. return YAML::Node();
  202. }
  203. YAML::Node CLashConfig::buildtrojan()
  204. {
  205. return YAML::Node();
  206. }
  207. YAML::Node CLashConfig::buildv2ray()
  208. {
  209. return YAML::Node();
  210. }
  211. std::vector<YAML::Node> CLashConfig::buildv2rayHost()
  212. {
  213. std::vector<YAML::Node> p;
  214. /*if (node) {
  215. YAML::Node t_map;
  216. t_map["host"] = node->v2_host;
  217. p.push_back(t_map);
  218. }*/
  219. return p;
  220. }
  221. YAML::Node CLashConfig::builTunConfig()
  222. {
  223. std::vector<std::string> dns;
  224. dns.push_back("198.18.0.2:53");
  225. YAML::Node node;
  226. node["enable"] = true;
  227. node["stack"] = "gvisor";
  228. node["dns-hijack"] = dns;
  229. node["auto-route"] = true;
  230. node["auto-detect-interface"] = true;
  231. return node;
  232. }
  233. YAML::Node CLashConfig::buildDnsConfig()
  234. {
  235. YAML::Node dns;
  236. std::vector<std::string> dns_arr;
  237. dns_arr.push_back("114.114.114.114");
  238. dns_arr.push_back("8.8.8.8");
  239. dns_arr.push_back("tls://dns.rubyfish.cn:853");
  240. dns_arr.push_back("https://1.1.1.1/dns-query");
  241. dns["enable"] = true;
  242. if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode)
  243. {
  244. dns["enhanced-mode"] = "redir-host";
  245. }
  246. else
  247. {
  248. //dns["enable"] = false;
  249. }
  250. dns["nameserver"] = dns_arr;
  251. //dns["use-hosts"] = true;
  252. return dns;
  253. }
  254. std::vector<YAML::Node> CLashConfig::buildProxyGroups()
  255. {
  256. std::vector<YAML::Node> dns_arr;
  257. std::vector<std::string> proxy;
  258. YAML::Node proxies;
  259. /*for each (LISTNODE node in CList_node::getSingletonPtr()->listnode)
  260. {
  261. proxy.push_back(node.name.c_str());
  262. }*/
  263. YAML::Node li;
  264. li["name"] = "Proxy";
  265. li["type"] = "select";
  266. li["proxies"] = proxy;
  267. dns_arr.push_back(li);
  268. return dns_arr;
  269. }
  270. std::vector<YAML::Node> CLashConfig::buildRules()
  271. {
  272. std::vector<YAML::Node> p;
  273. m_rules.clear();
  274. if (CApp::getSingletonPtr()->GetRouteMode() == ROUT_MODE::cn_mode)
  275. {
  276. m_rules.push_back("RULE-SET,proxy,Proxy");
  277. m_rules.push_back("RULE-SET,google,Proxy");
  278. m_rules.push_back("RULE-SET,gfw,Proxy");
  279. m_rules.push_back("RULE-SET,cncidr,DIRECT");
  280. m_rules.push_back("GEOIP,CN,DIRECT");
  281. m_rules.push_back("IP-CIDR,127.0.0.0/8,DIRECT");
  282. m_rules.push_back("IP-CIDR,172.16.0.0/12,DIRECT");
  283. m_rules.push_back("IP-CIDR,192.168.0.0/16,DIRECT");
  284. m_rules.push_back("IP-CIDR,10.0.0.0/8,DIRECT");
  285. m_rules.push_back("IP-CIDR,100.64.0.0/10,DIRECT");
  286. }
  287. else
  288. {
  289. // m_rules.push_back("RULE-SET,proxy,Proxy");
  290. // m_rules.push_back("RULE-SET,google,Proxy");
  291. // m_rules.push_back("RULE-SET,gfw,Proxy");
  292. // m_rules.push_back("RULE-SET,cncidr,Proxy");
  293. m_rules.push_back("GEOIP,CN,Proxy");
  294. m_rules.push_back("IP-CIDR,127.0.0.0/8,DIRECT");
  295. m_rules.push_back("IP-CIDR,172.16.0.0/12,DIRECT");
  296. m_rules.push_back("IP-CIDR,192.168.0.0/16,DIRECT");
  297. m_rules.push_back("IP-CIDR,10.0.0.0/8,DIRECT");
  298. m_rules.push_back("IP-CIDR,100.64.0.0/10,DIRECT");
  299. }
  300. m_rules.push_back("MATCH,Proxy");
  301. return p;
  302. }
  303. std::vector<YAML::Node> CLashConfig::buildruleproviders()
  304. {
  305. std::vector<YAML::Node> pp;
  306. YAML::Node node;
  307. YAML::Node reject;
  308. YAML::Node google;
  309. YAML::Node gfw;
  310. YAML::Node proxy;
  311. YAML::Node cncidr;
  312. reject["type"] = "http";
  313. reject["behavior"] = "domain";
  314. reject["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/reject.txt";
  315. reject["path"] = "./ruleset/reject.yaml";
  316. reject["interval"] = 86400;
  317. node["reject"] = reject;
  318. pp.push_back(node);
  319. google["type"] = "http";
  320. google["behavior"] = "domain";
  321. google["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/google.txt";
  322. google["path"] = "./ruleset/google.yaml";
  323. google["interval"] = 86400;
  324. node["google"] = google;
  325. pp.push_back(node);
  326. gfw["type"] = "http";
  327. gfw["behavior"] = "domain";
  328. gfw["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/gfw.txt";
  329. gfw["path"] = "./ruleset/gfw.yaml";
  330. gfw["interval"] = 86400;
  331. node["gfw"] = gfw;
  332. pp.push_back(node);
  333. proxy["type"] = "http";
  334. proxy["behavior"] = "domain";
  335. proxy["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt";
  336. proxy["path"] = "./ruleset/proxy.yaml";
  337. proxy["interval"] = 86400;
  338. node["proxy"] = proxy;
  339. pp.push_back(node);
  340. cncidr["type"] = "http";
  341. cncidr["behavior"] = "domain";
  342. cncidr["url"] = "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/cncidr.txt";
  343. cncidr["path"] = "./ruleset/cncidr.yaml";
  344. cncidr["interval"] = 86400;
  345. node["cncidr"] = proxy;
  346. pp.push_back(node);
  347. return pp;
  348. }
  349. void CLashConfig::ThreadFun_process_Config(LPARAM lParam)
  350. {
  351. CProcessManager* p = (CProcessManager*)lParam;
  352. if (p->Start())
  353. {
  354. }
  355. WaitForSingleObject(_hEvent.get(),INFINITE);
  356. }
  357. void CLashConfig::ThreadFun_ProcessMonitor_Config(LPARAM lParam)
  358. {
  359. CProcessManager* p = (CProcessManager*)lParam;
  360. if (p)
  361. {
  362. HANDLE hClashProcess = p->GetClashProcessInfo().hProcess;
  363. HANDLE hSubProcess = p->GetSubProcessInfo().hProcess;
  364. WaitForSingleObject(hClashProcess, INFINITE);
  365. CApp::getSingletonPtr()->SetCLashRuning(false);
  366. if (p->IsRunning() != State::Running)
  367. {
  368. return;
  369. }
  370. DWORD exitCode = 0;
  371. THROW_IF_WIN32_BOOL_FALSE(GetExitCodeProcess(hClashProcess, &exitCode));
  372. LOG_HR_MSG(E_FAIL, "syscode.exe exited with code: %ul", exitCode);
  373. FILETIME creationTime = {}, exitTime = {}, kernelTime = {}, userTime = {};
  374. THROW_IF_WIN32_BOOL_FALSE(GetProcessTimes(hClashProcess, &creationTime, &exitTime, &kernelTime, &userTime));
  375. auto creation = winrt::clock::from_FILETIME(creationTime);
  376. auto exit = winrt::clock::from_FILETIME(exitTime);
  377. if (exit - creation < 5s)
  378. {
  379. /*g_balloonClickAction = BalloonClickAction::ShowConsoleWindow;
  380. ShowBalloon(_(L"Clash process was alive less than 5 seconds\nTap to view console log"), _(L"Error"), NIIF_ERROR);
  381. co_await winrt::resume_on_signal(hSubProcess);*/
  382. WaitForSingleObject(hSubProcess, INFINITE);
  383. }
  384. if (p->IsRunning() != State::Running)
  385. {
  386. return;
  387. }
  388. p->Stop();
  389. EventClashPreOceeQut* pEvt = new EventClashPreOceeQut(nullptr);
  390. pEvt->status = 200;
  391. pEvt->msg = L"";
  392. SNotifyCenter::getSingleton().FireEventAsync(pEvt);
  393. pEvt->Release();
  394. }
  395. }
  396. //winrt::fire_and_forget CLashConfig::_StartClash()
  397. //{
  398. // if (CProcessManager::getSingletonPtr()->Start())
  399. // {
  400. // CApp::getSingletonPtr()->SetCLashRuning(true);
  401. //
  402. //
  403. //
  404. // /*HANDLE hClashProcess = CProcessManager::getSingletonPtr()->GetClashProcessInfo().hProcess;
  405. //
  406. // for (size_t i = 0; i < 5; ++i) {
  407. //
  408. // }*/
  409. // }
  410. //
  411. //
  412. //
  413. //}
  414. //
  415. //winrt::Windows::Foundation::IAsyncAction CLashConfig::ProcessMonitor()
  416. //{
  417. // HANDLE hSubProcess = CProcessManager::getSingletonPtr()->GetClashProcessInfo().hProcess,
  418. // hClashProcess = CProcessManager::getSingletonPtr()->GetClashProcessInfo().hProcess;
  419. //
  420. // winrt::resume_on_signal(hClashProcess);
  421. //
  422. // /*std::future<void> f = std::async(std::launch::async, []() {
  423. // })*/
  424. //
  425. //
  426. //
  427. //
  428. //}