alroyso 3 жил өмнө
parent
commit
e017ebfdb8

+ 21 - 3
SProxy/CApp.cpp

@@ -4,7 +4,7 @@
 
 CApp* SSingleton<CApp>::ms_Singleton = NULL;
 
-CApp::CApp() : m_is_out(0),m_userinfo(nullptr), m_server_list(nullptr), m_proxy_mode(PROXY_MODE::sys_mode), m_route_mode(ROUT_MODE::cn_mode)
+CApp::CApp() : m_is_out(0), m_versioninfo(nullptr),m_userinfo(nullptr), m_server_list(nullptr), m_proxy_mode(PROXY_MODE::sys_mode), m_route_mode(ROUT_MODE::cn_mode)
 {
 	m_hInst = nullptr;
 }
@@ -25,7 +25,10 @@ void CApp::Init()
 		m_server_list = new CServerList();
 	}
  
-
+	if (!m_versioninfo)
+	{
+		m_versioninfo = new CVersion();
+	}
 }
 
 void CApp::UnInit() {
@@ -39,7 +42,12 @@ void CApp::UnInit() {
 		delete m_server_list;
 		m_server_list = nullptr;
 	}
-	 
+	
+	if (m_versioninfo)
+	{
+		delete m_versioninfo;
+		m_versioninfo = nullptr;
+	}
 }
 
  
@@ -53,6 +61,11 @@ CServerList* CApp::GetServerList()
 	return m_server_list;
 }
 
+CVersion* CApp::GetVerinfo()
+{
+	return m_versioninfo;
+}
+
 void CApp::SetOut(int out)
 {
 	m_is_out = out;
@@ -152,4 +165,9 @@ bool CApp::GetClashRuning()
 	return m_clashRuning;
 }
 
+std::string CApp::GetSelect_node() const { return select_node; }
+
+void CApp::SetSelect_node(std::string val) {
+	select_node = val; 
+}
  

+ 8 - 0
SProxy/CApp.h

@@ -2,6 +2,8 @@
 #include "CBaseMode.h"
 #include "CUserInfo.h"
 #include "CServerList.h"
+#include "CVersion.h"
+
 enum struct PROXY_MODE {
 
 	sys_mode = 0,
@@ -42,6 +44,7 @@ public:
  
 	CUserInfo* GetUserinfo();
 	CServerList* GetServerList();
+	CVersion* GetVerinfo();
 
 	void SetOut(int out);
 
@@ -74,13 +77,17 @@ public:
 
 	bool GetClashRuning();
 
+ 
 
 	std::string GetToken() const { return m_token; }
 	void SetToken(std::string val) { m_token = val; }
+	std::string GetSelect_node() const;
+	void SetSelect_node(std::string val);
 private:
 	int m_is_out;
 	CServerList* m_server_list;
 	CUserInfo* m_userinfo;
+	CVersion* m_versioninfo;
 	PROXY_MODE m_proxy_mode;
 	ROUT_MODE  m_route_mode;
 	HINSTANCE  m_hInst;
@@ -91,5 +98,6 @@ private:
 	bool m_clashRuning = true;
 	std::string m_token;
 	/**/
+	std::string select_node;
 };
 

+ 289 - 0
SProxy/CConnectMage.cpp

@@ -0,0 +1,289 @@
+#include "stdafx.h"
+#include "CConnectMage.h"
+
+CConnectMage::CConnectMage() : m_clash_Api(nullptr), m_clash_config(nullptr), m_connect_status(ConnectState::Stop), m_Asyntask(4)
+{
+	SNotifyCenter::getSingleton().addEvent(EVENTID(EventConnect));
+	m_isclash_config = false;
+}
+
+CConnectMage::~CConnectMage()
+{
+	if (m_clash_Api)
+	{
+		delete m_clash_Api;
+		m_clash_Api = nullptr;
+	}
+}
+
+void CConnectMage::Stop()
+{
+	m_connect_status = ConnectState::Stop;
+	m_Asyntask.AddTask(&CConnectMage::ThreadFun_ChangeClash_Stop, this, (LPARAM)nullptr);
+}
+
+void CConnectMage::ReqConfig()
+{
+	m_Asyntask.AddTask(&CConnectMage::ThreadFun_ChangeClash_Config, this, (LPARAM)nullptr);
+}
+
+void CConnectMage::ChangeClashNode()
+{
+	m_Asyntask.AddTask(&CConnectMage::ThreadFun_ChangeClash_Node, this, (LPARAM)nullptr);
+}
+
+void CConnectMage::ChangeClashInit()
+{
+}
+
+void CConnectMage::Init()
+{
+	if (!m_clash_Api)
+	{
+		m_clash_Api = new ClashApi();
+		m_clash_Api->SetProt(m_clash_config->GetClasApiPort());
+
+	}
+}
+
+void CConnectMage::SetNodeName(std::string name)
+{
+	m_name = name;
+}
+
+void CConnectMage::SetClashConfig(CLashConfig* m)
+{
+	m_clash_config = m;
+}
+
+ConnectState CConnectMage::GetConnectStatus()
+{
+	return m_connect_status;
+}
+
+void CConnectMage::ThreadFun_ChangeClash_Config(LPARAM lParam)
+{
+	if (!CApp::getSingletonPtr()->GetClashRuning())
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"内核没有启动,重启电脑或者软件";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+ 
+	if (m_clash_config == nullptr || m_clash_Api == nullptr)
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"错误,重启电脑";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+	//创建配置
+	if (!m_clash_config->MakeClash())
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"没有生成配置,检查系统是否有管理员";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+
+	/*std::filesystem::path config;
+
+	if (m_connect_status == ConnectState::Stop && CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode)
+	{
+		config = CApp::getSingletonPtr()->GetConfigPath() / DSPROXY_CONFIG_INIT_ClASH_NAME;
+	}*/
+	 
+
+	//切换请求
+	if (m_clash_Api->RequestConfigUpdate(m_clash_config->GetRunConfig()))
+	{
+		m_isclash_config = true;
+		if (m_name.empty())
+		{
+			CServerList* serverlist = CApp::getSingletonPtr()->GetServerList();
+			if (serverlist)
+			{
+				serverlist->MinimumSelectNode();
+
+				if (!serverlist->node_name.empty())
+				{
+					if (m_clash_Api->UpdateProxyGroup("Proxy", serverlist->node_name))
+					{
+						m_connect_status = ConnectState::SwitchNodeSuccEss;
+						m_error = L"连接成功";
+						m_clash_config->SetProxy();
+					}
+					else {
+						m_connect_status = ConnectState::Stop;
+						m_error = L"连接失败,可以重新尝试";
+					}
+				}
+			}
+
+		}
+		else {
+			if (m_clash_Api->UpdateProxyGroup("Proxy", m_name))
+			{
+				m_connect_status = ConnectState::SwitchNodeSuccEss;
+				m_error = L"连接成功";
+				m_clash_config->SetProxy();
+			}
+			else {
+				m_connect_status = ConnectState::Stop;
+				m_error = L"连接失败,可以重新尝试";
+			}
+		}
+	}
+	else {
+		m_connect_status = ConnectState::Stop;
+		m_error = L"连接失败,可以重新尝试";
+	}
+ 
+	
+	
+
+
+	EventConnect* pEvt = new EventConnect(nullptr);
+	pEvt->status = m_connect_status;
+	pEvt->msg = m_error;
+	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+	pEvt->Release();
+}
+
+void CConnectMage::ThreadFun_ChangeClash_Node(LPARAM lParam)
+{
+	if (m_clash_config == nullptr || m_clash_Api == nullptr)
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"错误,重启电脑";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+	
+	if (m_clash_Api->UpdateProxyGroup("Proxy", m_name))
+	{
+		m_connect_status = ConnectState::SwitchNodeSuccEss;
+		m_error = L"切换成功..点击断开";
+		m_clash_config->SetProxy();
+	}
+	else {
+		m_connect_status = ConnectState::Stop;
+		m_error = L"切换失败,可以重新尝试";
+	}
+
+	EventConnect* pEvt = new EventConnect(nullptr);
+	pEvt->status = m_connect_status;
+	pEvt->msg = m_error;
+	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+	pEvt->Release();
+}
+
+void CConnectMage::ThreadFun_ChangeClash_Stop(LPARAM lParam)
+{
+	if (!CApp::getSingletonPtr()->GetClashRuning())
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"内核没有启动,重启电脑或者软件";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+
+	if (m_clash_config == nullptr || m_clash_Api == nullptr)
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"错误,重启电脑";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+	//创建配置
+	if (!m_clash_config->MakeClash())
+	{
+		m_connect_status = ConnectState::Stop;
+		m_error = L"没有生成配置,检查系统是否有管理员";
+		EventConnect* pEvt = new EventConnect(nullptr);
+		pEvt->status = m_connect_status;
+		pEvt->msg = m_error;
+		SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+		pEvt->Release();
+		return;
+	}
+
+	/*std::filesystem::path config;
+
+	if (m_connect_status == ConnectState::Stop && CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode)
+	{
+		config = CApp::getSingletonPtr()->GetConfigPath() / DSPROXY_CONFIG_INIT_ClASH_NAME;
+	}*/
+
+
+	//切换请求
+	if (m_clash_Api->RequestConfigUpdate(CApp::getSingletonPtr()->GetConfigPath() / DSPROXY_CONFIG_INIT_ClASH_NAME))
+	{
+		m_isclash_config = true;
+		if (m_name.empty())
+		{
+			CServerList* serverlist = CApp::getSingletonPtr()->GetServerList();
+			if (serverlist)
+			{
+				serverlist->MinimumSelectNode();
+
+				if (!serverlist->node_name.empty())
+				{
+					if (m_clash_Api->UpdateProxyGroup("Proxy", serverlist->node_name))
+					{
+						m_connect_status = ConnectState::SwitchNodeSuccEss;
+						m_error = L"连接成功";
+						m_clash_config->SetProxy();
+					}
+					else {
+						m_connect_status = ConnectState::Stop;
+						m_error = L"连接失败,可以重新尝试";
+					}
+				}
+			}
+
+		}
+		else {
+			if (m_clash_Api->UpdateProxyGroup("Proxy", m_name))
+			{
+				m_connect_status = ConnectState::SwitchNodeSuccEss;
+				m_error = L"连接成功";
+				m_clash_config->SetProxy();
+			}
+			else {
+				m_connect_status = ConnectState::Stop;
+				m_error = L"连接失败,可以重新尝试";
+			}
+		}
+	}
+	else {
+		m_connect_status = ConnectState::Stop;
+		m_error = L"连接失败,可以重新尝试";
+	}
+
+}

+ 37 - 0
SProxy/CConnectMage.h

@@ -0,0 +1,37 @@
+#pragma once
+#include "CThread.h"
+#include "CLashConfig.h"
+#include "ClashApi.h"
+
+
+
+class CConnectMage  
+{
+public:
+	CConnectMage();
+	 ~CConnectMage();
+	 void Stop();
+	 void ReqConfig();
+	 void ChangeClashNode();
+	 void ChangeClashInit();
+	 void Init();
+	 void SetNodeName(std::string name);
+public:
+	void SetClashConfig(CLashConfig* m);
+	ConnectState GetConnectStatus();
+	 
+private:
+	
+	void ThreadFun_ChangeClash_Config(LPARAM lParam);
+	void ThreadFun_ChangeClash_Node(LPARAM lParam);
+	void ThreadFun_ChangeClash_Stop(LPARAM lParam);
+private:
+	ConnectState m_connect_status;
+	CLashConfig* m_clash_config;
+	ClashApi* m_clash_Api;
+	SStringW  m_error;
+	AsynTaskHandle<LPARAM>	m_Asyntask;
+	std::string   m_name;
+	bool  m_isclash_config;
+};
+

+ 140 - 76
SProxy/CLashConfig.cpp

@@ -3,12 +3,12 @@
 #include "CApp.h"
 #include "comm.h"
 #include "FileOperate.h"
+#include "SysProxy.h"
 
-
-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)
+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)
 {
 	SNotifyCenter::getSingleton().addEvent(EVENTID(EventClashPreOceeQut));
-	_hEvent = nullptr;
+	 
 
 }
 
@@ -19,11 +19,7 @@ CLashConfig::~CLashConfig(void)
 		delete m_process;
 		m_process = nullptr;
 	}
-	if (m_log)
-	{
-		delete m_log;
-		m_log = nullptr;
-	}
+ 
 }
 
 BOOL CLashConfig::MakeClash()
@@ -61,18 +57,18 @@ BOOL CLashConfig::MakeClash()
 
 	//CList_node::getSingletonPtr()->listnode;
 	YAML::Node proxies;
-	//for each (LISTNODE node in CList_node::getSingletonPtr()->listnode)
-	//{
-	//	if (node.type == "shadowsocks") {
-	//		proxies.push_back(buildShadowsocks(&node));
-	//	}
-	//	else if (node.type == "trojan") {
-	//		proxies.push_back(buildtrojan(&node));
-	//	}
-	//	else if (node.type == "v2ray") {
-	//		proxies.push_back(buildv2ray(&node));
-	//	}
-	//}
+	for each (auto node in CApp::getSingletonPtr()->GetServerList()->vectlistmode)
+	{
+		if (node.type == "shadowsocks") {
+			proxies.push_back(buildShadowsocks(&node));
+		}
+		else if (node.type == "trojan") {
+			proxies.push_back(buildtrojan(&node));
+		}
+		else if (node.type == "v2ray") {
+			proxies.push_back(buildv2ray(&node));
+		}
+	}
 
 
 	root["proxies"] = proxies;
@@ -130,16 +126,25 @@ BOOL CLashConfig::MakeClash()
 	}
 
 	root["rules"] = m_rules;
-	auto name_file = "config.yaml";
+	auto name_file = DSPROXY_CONFIG_ClASH_NAME;
 
 	if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode) {
-		name_file = "tun_config.yaml";
+		name_file = DSPROXY_CONFIG_TUN_ClASH_NAME;
+	}
+
+
+	try
+	{
+		m_run_config = CApp::getSingletonPtr()->GetConfigPath() / name_file;
+		std::ofstream ofstream(CApp::getSingletonPtr()->GetConfigPath() /  name_file);
+		ofstream << root;
+		ofstream.close();
+	}
+	catch (const std::exception& e) {
+		LOG_CAUGHT_EXCEPTION();
+		return FALSE;
 	}
 
-	//std::ofstream ofstream(path + "\\config\\" + name_file);
-	//// ÉèÖÃÅäÖÃÎļþnodeÊý
-	//ofstream << root << std::endl;
-	//ofstream.close();
 
 	return TRUE;
 }
@@ -150,23 +155,12 @@ BOOL CLashConfig::InitClash()
 	{
 		m_process = new CProcess();
 	}
-	std::string logfile = std::filesystem::current_path().string() + "\\log\\log.log";
-	if (m_log == nullptr)
-	{
-		m_log = new Logger(Logger::file_and_terminal, Logger::info, logfile);
-	}
+	
+	
 	m_http_port = CTool::getSingletonPtr()->FindAvailableTcpPort(9300,9500);
 	m_socks_port = CTool::getSingletonPtr()->FindAvailableTcpPort(9600,9800);
 	m_c_port = CTool::getSingletonPtr()->FindAvailableTcpPort(9900);
 
- ;
-
-	/*std::string dir = CLASHCONFIGDIR;
-
-	auto name_file = dir + "\\" + CLASHCONFIINIT;
-
-	*/
-	
 	auto name_file = DSPROXY_CONFIG_INIT_ClASH_NAME;
 
 	if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::tun_mode) {
@@ -182,14 +176,16 @@ BOOL CLashConfig::InitClash()
 
 	try
 	{
-		auto config_path = CApp::getSingletonPtr()->GetConfigPath().wstring() + L"\\" + name_file;
-		std::ofstream ofstream(config_path);
+		
+		std::ofstream ofstream(CApp::getSingletonPtr()->GetConfigPath() / name_file);
 		ofstream << root << std::endl;
 		ofstream.close();
 		return TRUE;
 	}
-	catch (const std::exception&)
+	catch (const std::exception& e)
 	{
+		Logger::getSingletonPtr()->INFO(e.what());
+		LOG_CAUGHT_EXCEPTION();
 		return FALSE;
 	}
 
@@ -199,20 +195,6 @@ BOOL CLashConfig::InitClash()
 
 BOOL CLashConfig::StartClash()
 {
-	/*wil::unique_handle hEvent(CreateEventW(nullptr, FALSE, FALSE, nullptr));
-	THROW_LAST_ERROR_IF_NULL(hEvent);*/
-	//std::wstring config = path + L"\\" + WCLASHCONFIGDIR;
-	////args.push_back("-d");
-	//////args.push_back(std::filesystem::current_path().string() + "\\route");
-	////args.push_back(path + "\\config");
-	////args.push_back("-f");
-	////args.push_back(path + "\\config\\configinit.yaml");
-	//std::wstring run_config = config + L"\\" + S_CA2W(CLASHCONFIINIT).GetBuffer(0);
-	//SStringW path_config;
-	//path_config.Format(L"%s\\%s -d %s -f %s", config.c_str(),CLASHEXE,config.c_str(), run_config.c_str());
-
-
-
 	auto assetsDir = std::filesystem::current_path() / CLASH_ASSETS_DIR_NAME;
 	auto confg_path = CApp::getSingletonPtr()->GetConfigPath() / DSPROXY_CONFIG_INIT_ClASH_NAME;
 	CProcessManager::getSingletonPtr()->SetArgs(assetsDir / DSPROXY_EXE_NAME, assetsDir, std::move(confg_path));
@@ -251,29 +233,112 @@ BOOL CLashConfig::StopClash()
     return 0;
 }
 
-YAML::Node CLashConfig::buildShadowsocks()
+int CLashConfig::GetHttpPort()
 {
-    return YAML::Node();
+	return m_http_port;
 }
 
-YAML::Node CLashConfig::buildtrojan()
+int CLashConfig::GetSocketPort()
 {
+	return m_socks_port;
+}
+
+int CLashConfig::GetClasApiPort()
+{
+	return m_c_port;
+}
+
+std::filesystem::path CLashConfig::GetRunConfig()
+{
+	return m_run_config;
+}
+
+YAML::Node CLashConfig::buildShadowsocks(CServerListMode* node)
+{
+	YAML::Node t_map;
+
+	if (!node)
+	{
+		return t_map;
+	}
+	
+	t_map["name"] = node->name;
+	t_map["type"] = std::string("ss");
+	t_map["server"] = node->host;
+	t_map["port"] = std::to_string(node->port);
+	t_map["cipher"] = node->method;
+	t_map["password"] = node->passwd;
+	t_map["udp"] = true;
+
+	return t_map;
+
     return YAML::Node();
 }
 
-YAML::Node CLashConfig::buildv2ray()
+YAML::Node CLashConfig::buildtrojan(CServerListMode* node)
 {
+	YAML::Node t_map;
+
+	if (!node)
+	{
+		return t_map;
+	}
+	
+	t_map["name"] = node->name;
+	t_map["type"] = std::string("trojan");
+	t_map["server"] = node->host;
+	t_map["port"] = std::to_string(node->port);
+	t_map["password"] = node->passwd;
+	if (!node->sni.empty()) {
+		t_map["sni"] = node->sni;
+	}
+	t_map["udp"] = true;
+
+	return t_map;
     return YAML::Node();
 }
 
-std::vector<YAML::Node> CLashConfig::buildv2rayHost()
+YAML::Node CLashConfig::buildv2ray(CServerListMode* node)
 {
+	YAML::Node t_map;
+	if (!node)
+	{
+		return t_map;
+	}
+
 	std::vector<YAML::Node> p;
-	/*if (node) {
+	t_map["name"] = node->name;
+	t_map["type"] = std::string("vmess");
+	t_map["server"] = node->host;
+	t_map["port"] = std::to_string(node->port);
+	t_map["uuid"] = node->uuid;
+	t_map["cipher"] = node->method;
+	t_map["alterId"] = node->v2_alter_id;
+	t_map["udp"] = node->udp;
+
+	if (node->v2_tls == "tls") {
+		t_map["tls"] = node->v2_tls;
+	}
+
+	if (node->v2_net == "tcp") {
+		t_map["network"] = node->v2_net;
+	}
+	else if (node->v2_net == "ws") {
+		t_map["network"] = node->v2_net;
+		t_map["ws-path"] = node->v2_path;
+		t_map["ws-headers"] = buildv2rayHost(node);
+	}
+	return t_map;
+}
+
+std::vector<YAML::Node> CLashConfig::buildv2rayHost(CServerListMode* node)
+{
+	std::vector<YAML::Node> p;
+	if (node) {
 		YAML::Node t_map;
 		t_map["host"] = node->v2_host;
 		p.push_back(t_map);
-	}*/
+	}
 	return p;
 }
 
@@ -321,11 +386,10 @@ std::vector<YAML::Node> CLashConfig::buildProxyGroups()
 	std::vector<YAML::Node> dns_arr;
 	std::vector<std::string> proxy;
 	YAML::Node proxies;
-	/*for each (LISTNODE node in CList_node::getSingletonPtr()->listnode)
+	for each (auto node in CApp::getSingletonPtr()->GetServerList()->vectlistmode)
 	{
 		proxy.push_back(node.name.c_str());
-
-	}*/
+	}
 	YAML::Node li;
 	li["name"] = "Proxy";
 	li["type"] = "select";
@@ -431,16 +495,7 @@ std::vector<YAML::Node> CLashConfig::buildruleproviders()
 
 void CLashConfig::ThreadFun_process_Config(LPARAM lParam)
 {
-	
-	CProcessManager* p = (CProcessManager*)lParam;
-	
-	if (p->Start())
-	{
-	
-	}
-
-	 
-	 WaitForSingleObject(_hEvent.get(),INFINITE);
+ 
 }
 
 void CLashConfig::ThreadFun_ProcessMonitor_Config(LPARAM lParam)
@@ -496,6 +551,15 @@ void CLashConfig::ThreadFun_ProcessMonitor_Config(LPARAM lParam)
 	 
 }
 
+void CLashConfig::SetProxy()
+{
+	if (CApp::getSingletonPtr()->GetSysMode() == PROXY_MODE::sys_mode)
+	{
+		auto proxy = "127.0.0.1:" + std::to_string(m_http_port);
+		SetSystemProxy(S_CA2W(proxy.c_str()), NULL, L"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*");
+	}
+}
+
 //winrt::fire_and_forget CLashConfig::_StartClash()
 //{
 //	if (CProcessManager::getSingletonPtr()->Start())

+ 15 - 6
SProxy/CLashConfig.h

@@ -23,12 +23,19 @@ public:
 	virtual BOOL StartClash() override;
 
 	virtual BOOL StopClash() override;
+	virtual int GetHttpPort() override;
+	virtual int GetSocketPort() override;
+	virtual int GetClasApiPort() override;
 
+public:
+ 
+	std::filesystem::path GetRunConfig();
+	void SetProxy();
 private:
-	YAML::Node buildShadowsocks();
-	YAML::Node buildtrojan();
-	YAML::Node buildv2ray();
-	std::vector<YAML::Node> buildv2rayHost();
+	YAML::Node buildShadowsocks(CServerListMode* node);
+	YAML::Node buildtrojan(CServerListMode* node);
+	YAML::Node buildv2ray(CServerListMode* node);
+	std::vector<YAML::Node> buildv2rayHost(CServerListMode* node);
 
 	YAML::Node builTunConfig();
 	YAML::Node buildDnsConfig();
@@ -38,6 +45,7 @@ private:
 private:
 	void ThreadFun_process_Config(LPARAM lParam);
 	void ThreadFun_ProcessMonitor_Config(LPARAM lParam);
+	
 	/*winrt::fire_and_forget _StartClash();
 	winrt::Windows::Foundation::IAsyncAction ProcessMonitor();*/
 private:
@@ -48,8 +56,9 @@ private:
 	CProcess* m_process;
 	AsynTaskHandle<LPARAM>	m_Asyntask;
 	AsynTaskHandle<LPARAM>	m_AsyntaskProcessMonitor;
-	Logger*     m_log;
 	std::vector<std::string> m_rules;
-	wil::unique_handle _hEvent;
+ 
+	std::filesystem::path m_run_config;
+	
 };
 

+ 85 - 7
SProxy/CManageNetWork.cpp

@@ -28,6 +28,7 @@ void CManageNetWork::init()
 	SNotifyCenter::getSingleton().addEvent(EVENTID(EventLogin));
 	SNotifyCenter::getSingleton().addEvent(EVENTID(EventDoWNload));
 	SNotifyCenter::getSingleton().addEvent(EVENTID(EventNodeList));
+	SNotifyCenter::getSingleton().addEvent(EVENTID(EventVerions));
 
 
 	if (!m_base_curl)
@@ -93,6 +94,17 @@ void CManageNetWork::GetNodeList()
 	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Node_Config, this, (LPARAM)m_base_curl);
 }
 
+void CManageNetWork::GetVersion()
+{
+	if (!m_base_curl)
+	{
+		return;
+	}
+
+	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Version_Config, this, (LPARAM)m_base_curl);
+
+}
+
 void CManageNetWork::ThreadFun_login(LPARAM lParam)
 {
 	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
@@ -143,26 +155,92 @@ void CManageNetWork::ThreadFun_Dowlon_Config(LPARAM lParam)
 	pEvt->Release();
 }
 
-void CManageNetWork::ThreadFun_Node_Config(LPARAM lParam)
+void CManageNetWork::ThreadFun_Version_Config(LPARAM lParam)
 {
 	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
 	int code = 200;
-	SStringW msg = L"";
+	SStringW msg = L"有新版本,点我升级";
 	std::string data;
-	HTTPRET httpstatus = m_base_curl->GetServerNode(data);
-	if (httpstatus == http_f) {
+	if (!m_base_curl->Version(data)) {
 		code = 0;
 		msg = m_base_curl->GetLastErrorW();
 	}
-
 	if (!data.empty())
 	{
-		if (!CApp::getSingletonPtr()->GetServerList()->Init(data))
+		if (!CApp::getSingletonPtr()->GetVerinfo()->Inti(data))
 		{
 			code = -1;
-			msg = CApp::getSingletonPtr()->GetServerList()->GetLastErrorW();
+			msg = CApp::getSingletonPtr()->GetVerinfo()->GetLastErrorW();
 		}
+		 
 	}
+	EventVerions* pEvt = new EventVerions(nullptr);
+	pEvt->status = code;
+	pEvt->msg = msg;
+	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
+	pEvt->Release();
+}
+
+void CManageNetWork::ThreadFun_Node_Config(LPARAM lParam)
+{
+	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
+	int code = 200;
+	SStringW msg = L"";
+	std::string data;
+	int count = 0;
+	do 
+	{
+		data = "";
+
+		HTTPRET httpstatus = m_base_curl->GetServerNode(data);
+		if (httpstatus == http_f) {
+			code = 0;
+			msg = m_base_curl->GetLastErrorW();
+		}
+
+		if (m_base_curl->GetHttpStatus() == 401)
+		{
+			if (count >= 3)
+			{
+				code = m_base_curl->GetHttpStatus();
+				msg = L"鉴权失败,需要重新登录";
+				break;
+			}
+			httpstatus = m_base_curl->PostLogin(this->m_username, this->m_password, data);
+			if (httpstatus == http_f) {
+				code = m_base_curl->GetHttpStatus();
+				msg = m_base_curl->GetLastErrorW();
+				count++;
+			}
+			else {
+				if (!CApp::getSingletonPtr()->GetUserinfo()->Init(data))
+				{
+					code = -1;
+					msg = CApp::getSingletonPtr()->GetServerList()->GetLastErrorW();
+				}
+				
+				continue;
+			}
+			
+		}
+		else {
+			if (!data.empty())
+			{
+				if (!CApp::getSingletonPtr()->GetServerList()->Init(data))
+				{
+					code = -1;
+					msg = CApp::getSingletonPtr()->GetServerList()->GetLastErrorW();
+				}
+
+				break;
+			}
+		}
+ 
+	
+
+
+	} while (m_base_curl);
+
 
 	EventNodeList* pEvt = new EventNodeList(nullptr);
 	pEvt->status = code;

+ 3 - 0
SProxy/CManageNetWork.h

@@ -25,9 +25,12 @@ public:
 
 	void GetNodeList();
 
+	void GetVersion();
+
 private:
 	void ThreadFun_login(LPARAM lParam);
 	void ThreadFun_Dowlon_Config(LPARAM lParam);
+	void ThreadFun_Version_Config(LPARAM lParam);
 	void ThreadFun_Node_Config(LPARAM lParam);
 	void LoadFileToData();
 

+ 44 - 4
SProxy/CNetWork.cpp

@@ -14,6 +14,39 @@ CNetWork::~CNetWork(void)
 {
 
 }
+
+int  CNetWork::GetHttpStatus() {
+	return m_http_status;
+}
+
+HTTPRET  CNetWork::Version(std::string& data) {
+	std::vector<cpr::Parameter> p;
+	p.push_back({ "tag","win" });
+	p.push_back({ "appverion",S_CW2A(VERSION).GetBuffer(0)});
+	std::string text = GetUrl("/api/client/v3/version", p, CApp::getSingletonPtr()->GetUserinfo()->access_token);
+	if (text.empty()) {
+
+		return http_f;
+	}
+	data = text.c_str();
+	return http_yes;
+}
+
+HTTPRET CNetWork::Refresh(std::string& data) {
+	std::vector<cpr::Parameter> p;
+	std::string text = GetUrl("/api/client/v3/refresh", p, CApp::getSingletonPtr()->GetUserinfo()->access_token);
+	if (text.empty()) {
+
+		return http_f;
+	}
+	data = text.c_str();
+	return http_yes;
+}
+
+
+HTTPRET CNetWork::Auth(std::string& data) {
+	return http_yes;
+}
 HTTPRET CNetWork::GetServerNode(std::string& data) {
 	std::vector<cpr::Parameter> p;
 	std::string text = GetUrl("/api/client/v3/nodes",p,CApp::getSingletonPtr()->GetUserinfo()->access_token);
@@ -61,6 +94,13 @@ SStringW CNetWork::GetLastErrorW()
 
 std::string CNetWork::GetUrl(std::string path, std::vector<cpr::Parameter> parame,std::string token)
 {
+	cpr::Parameters ps;
+	std::vector<cpr::Parameter>::iterator it_i;
+	for (it_i = parame.begin(); it_i != parame.end(); ++it_i)
+	{
+		ps.Add(*it_i);
+		//ps(cpr::Parameter({ it->first, it->second }));
+	}
 
 	cpr::Header hander;
 
@@ -78,10 +118,10 @@ std::string CNetWork::GetUrl(std::string path, std::vector<cpr::Parameter> param
 
 	if (parame.empty())
 	{
-		r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::Timeout{ 30 * 100});
+		r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::Timeout{ 60 * 100});
 	}
 	else {
-		r = cpr::Get(cpr::Url{ s.c_str() }, hander, cpr::Timeout{ 30 * 100 });
+		r = cpr::Get(cpr::Url{ s.c_str() }, ps, hander, cpr::Timeout{ 60 * 100 });
 	}
 	if (r.status_code == 200 || r.status_code == 201)
 	{
@@ -120,10 +160,10 @@ std::string CNetWork::PostUrl(std::string path, std::vector<cpr::Pair> parame, s
 
 	if (parame.empty())
 	{
-		r = cpr::Get(cpr::Url{ s.c_str() },hander , cpr::Timeout{ 30 * 100 });
+		r = cpr::Get(cpr::Url{ s.c_str() },hander , cpr::Timeout{ 60 * 100 });
 	}
 	else {
-		r = cpr::Post(cpr::Url{ s.c_str() }, cpr::Payload{ parame.begin(),parame.end() }, hander, cpr::Timeout{ 30 * 100 });
+		r = cpr::Post(cpr::Url{ s.c_str() }, cpr::Payload{ parame.begin(),parame.end() }, hander, cpr::Timeout{ 60 * 100 });
 	}
 
 	if (r.status_code == 200 || r.status_code == 201)

+ 7 - 2
SProxy/CNetWork.h

@@ -2,6 +2,8 @@
 
 #include "IBaseCurl.h"
 #include <cpr/cpr.h>
+#include "comm.h"
+
 class CNetWork : public IBaseCurl
 {
 public:
@@ -19,9 +21,12 @@ public:
 
 	bool Download(std::string path);
 
-	 
-
+	//
+	HTTPRET Auth(std::string& data);
+	HTTPRET Refresh(std::string& data);
 
+	int  GetHttpStatus();
+	HTTPRET Version(std::string& data);
 private:
 	std::string GetUrl(std::string path, std::vector<cpr::Parameter> parame, std::string token = "");
 	std::string PostUrl(std::string path, std::vector<cpr::Pair> parame,std::string token = "");

+ 25 - 1
SProxy/CServerList.cpp

@@ -16,8 +16,11 @@ CServerList::~CServerList()
 
 bool CServerList::Init(std::string data)
 {
+	
 	try
 	{
+		vectlistmode.clear();
+
 		nlohmann::json j = nlohmann::json::parse(data.begin(), data.end());
 
 		if (j["ret"].get<int>() == 1)
@@ -83,4 +86,25 @@ bool CServerList::Init(std::string data)
 		this->m_error_msg = L"½âÎöÊý¾Ý´íÎó";
 		return false;
 	}
-}
+}
+
+bool GreaterSort(CServerListMode a, CServerListMode b)
+{
+	return a.online_users < b.online_users;
+}
+
+void CServerList::MinimumSelectNode()
+{
+
+	if (vectlistmode.empty())
+	{
+		return;
+	}
+	auto t = vectlistmode;
+	std::sort(t.begin(), t.end(), GreaterSort);
+
+	if (!t.empty())
+	{
+		node_name = t[0].name;
+	}
+}

+ 2 - 0
SProxy/CServerList.h

@@ -10,9 +10,11 @@ public:
 
 	bool Init(std::string data);
 
+	void MinimumSelectNode();
 
 	std::vector<CServerListMode> vectlistmode;
 	
+	std::string node_name;
 
 };
 

+ 48 - 0
SProxy/CThread.cpp

@@ -0,0 +1,48 @@
+#include "stdafx.h"
+#include "CThread.h"
+
+CThread::CThread()
+{
+}
+
+CThread::~CThread()
+{
+	if (!this->isInterrupted())
+	{
+		this->interrupt();
+	}
+
+	if (this->th.joinable()) {
+		this->th.join();
+	}
+}
+
+void CThread::start()
+{
+	std::thread thr(std::bind(&CThread::run, this));
+	this->th = std::move(thr);
+}
+
+std::thread::id CThread::getId()
+{
+    return this->th.get_id();
+}
+
+void CThread::interrupt()
+{
+	this->isInterript;
+}
+
+bool CThread::isInterrupted()
+{
+    return false;
+}
+
+void CThread::join()
+{
+	this->th.join();
+}
+
+void CThread::run()
+{
+}

+ 19 - 0
SProxy/CThread.h

@@ -0,0 +1,19 @@
+#pragma once
+class CThread
+{
+public:
+	CThread();
+	virtual ~CThread();
+
+	void start();
+	std::thread::id getId();
+	void interrupt();
+	bool isInterrupted();
+	void join();
+	virtual void run();
+
+private:
+	std::atomic<bool> isInterript = false;
+	std::thread  th;
+};
+

+ 2 - 1
SProxy/CUserInfo.cpp

@@ -29,6 +29,7 @@ bool CUserInfo::Init(std::string data)
 			this->affurl = j["data"]["affurl"].get<std::string>();
 			this->swoftdownload = j["data"]["swoftdownload"].get<std::string>();
 			this->clash_config = j["data"]["clash_config"].get<std::string>();
+			this->user_login_url = j["data"]["user_login_url"].get<std::string>();
 			//
 			this->id = j["data"]["user"].at("id").get<int>();
 			this->username = j["data"]["user"].at("account").get<std::string>();
@@ -38,7 +39,7 @@ bool CUserInfo::Init(std::string data)
 			this->uuid = j["data"]["user"].at("uuid").get<std::string>();
 			this->level = j["data"]["user"].at("level").get<std::string>();
 			this->port = j["data"]["user"].at("port").get<int>();
-
+		
 			
 			return true;
 

+ 1 - 0
SProxy/CUserInfo.h

@@ -29,6 +29,7 @@ public:
 	std::string affurl; //芢熱華硊
 	std::string swoftdownload; //⻏璃狟婥華硊
 	std::string clash_config; //饜离華硊
+	std::string user_login_url; //蚚誧URL
 	int id;
 	int port;
 };

+ 49 - 0
SProxy/CVersion.cpp

@@ -0,0 +1,49 @@
+#include "stdafx.h"
+#include "CVersion.h"
+
+CVersion::CVersion()
+{
+}
+
+CVersion::~CVersion()
+{
+}
+
+bool CVersion::Inti(std::string data)
+{
+	if (data.empty())
+	{
+		return false;
+	}
+
+	try
+	{
+		nlohmann::json j = nlohmann::json::parse(data.begin(), data.end());
+
+		if (j["ret"].get<int>() == 1)
+		{
+			//
+			this->appversion = j["data"]["appversion"].get<std::string>();
+			this->appdownload = j["data"]["appdownload"].get<std::string>();
+			this->appmsg = j["data"]["appmsg"].get<std::string>();
+		 
+			return true;
+
+		}
+		else
+		{
+			SStringW msg;
+			msg.Format(L"当前版本号:%s", VERSION, S_CA2W(j["msg"].get<std::string>().c_str(), CP_UTF8));
+			this->m_error_msg = msg.GetBuffer(0);
+			return false;
+		}
+
+
+	}
+	catch (...)
+	{
+		this->m_error_msg = L"解析数据错误";
+		return false;
+	}
+	return false;
+}

+ 21 - 0
SProxy/CVersion.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "CBaseMode.h"
+
+
+class CVersion : public CBaseMode
+{
+public:
+	CVersion();
+	~CVersion();
+
+
+	bool Inti(std::string data);
+
+
+	std::string appversion;
+	std::string appdownload;
+	std::string appmsg;
+ 
+};
+

+ 51 - 30
SProxy/ClashApi.cpp

@@ -12,13 +12,14 @@ ClashApi::~ClashApi()
 void ClashApi::SetProt(int port)
 {
     std::string t;
-    t.append("http://172.0.0.1:");
+    t.append("http://127.0.0.1:");
     t.append(std::to_string(port));
     m_api_base_url = t;
 }
 
 std::string ClashApi::GetVersion()
 {
+	cpr::Session   m_cpr_session;
     auto url = m_api_base_url + "/version";
     m_cpr_session.SetUrl(cpr::Url{ url });
     auto res = m_cpr_session.Get();
@@ -30,6 +31,7 @@ std::string ClashApi::GetVersion()
 
 ClashConfig ClashApi::GetConfig()
 {
+	cpr::Session   m_cpr_session;
 	auto url = m_api_base_url + "/configs";
 	m_cpr_session.SetUrl(cpr::Url{ url });
 	auto res = m_cpr_session.Get();
@@ -37,33 +39,33 @@ ClashConfig ClashApi::GetConfig()
     return  nlohmann::json::parse(res.text).get<ClashConfig>();
 }
 
-std::optional<std::wstring> ClashApi::RequestConfigUpdate(std::filesystem::path configPath)
+bool ClashApi::RequestConfigUpdate(std::filesystem::path configPath)
 {
-	nlohmann::json j = {
-	    {"path",configPath.u8string()}
-	};
-    // cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });
-
-	auto url = m_api_base_url + "/configs";
-	m_cpr_session.SetUrl(cpr::Url{ url });
-    m_cpr_session.SetBody(cpr::Body{j.dump()});
-    auto res = m_cpr_session.Put();
-	if (res.status_code != 204)
+	
+	try
 	{
-		std::wstring errorDesp = L"Error occoured, Please try to fix it by restarting .";
-		try
-		{
-			errorDesp = Utf8ToUtf16(nlohmann::json::parse(res.text).at("message").get<std::string_view>());
-		}
-		CATCH_LOG();
-		return errorDesp;
+		cpr::Session   m_cpr_session;
+		nlohmann::json j = {
+			{"path",configPath.string()}
+		};
+		// cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });
+		auto url = m_api_base_url + "/configs";
+	/*	auto url = m_api_base_url + "/configs";
+		m_cpr_session.SetUrl(cpr::Url{ url });
+		m_cpr_session.SetBody(cpr::Body{ j.dump() });
+		auto res = m_cpr_session.Put();*/
+		auto ret = cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });
+		return ret.status_code == 204;
+	 
 	}
+	CATCH_LOG();
 
-    return std::nullopt;
+    return false;
 }
 
 bool ClashApi::UpdateProxyMode(ClashProxyMode mode)
 {
+	cpr::Session   m_cpr_session;
 	nlohmann::json j = {
 	{"mode",mode}
 	};
@@ -76,6 +78,7 @@ bool ClashApi::UpdateProxyMode(ClashProxyMode mode)
 
 bool ClashApi::UpdateLogLevel(ClashLogLevel level)
 {
+	cpr::Session   m_cpr_session;
 	nlohmann::json j = {
 	{"log-level",level}
 	};
@@ -88,8 +91,9 @@ bool ClashApi::UpdateLogLevel(ClashLogLevel level)
 
 bool ClashApi::UpdateAllowLan(bool allow)
 {
+	cpr::Session   m_cpr_session;
 	nlohmann::json j = {
-	 {"allow-lan",allow}
+		 {"allow-lan",allow}
 	};
 	auto url = m_api_base_url + "/configs";
 	m_cpr_session.SetUrl(cpr::Url{ url });
@@ -100,6 +104,7 @@ bool ClashApi::UpdateAllowLan(bool allow)
 
 u16milliseconds ClashApi::GetProxyDelay(std::string_view proxyName)
 {
+	cpr::Session   m_cpr_session;
 	std::string path = m_api_base_url + "/proxies/";
 	path.append(Utf16ToUtf8(Utf8ToUtf16(proxyName)));
 	path.append("/delay"); // "/proxies/\(proxyName.encoded)/delay"
@@ -114,6 +119,7 @@ u16milliseconds ClashApi::GetProxyDelay(std::string_view proxyName)
 
 ClashProxies ClashApi::GetProxies()
 {
+	cpr::Session   m_cpr_session;
 	auto url = m_api_base_url + "/proxies";
 	m_cpr_session.SetUrl(cpr::Url{ url });
 	auto res = m_cpr_session.Get();
@@ -124,14 +130,29 @@ ClashProxies ClashApi::GetProxies()
 
 bool ClashApi::UpdateProxyGroup(std::string_view group, std::string_view selectProxy)
 {
-	nlohmann::json j = {
-		{"allow-lan",selectProxy}
-	};
-	std::string path = "/proxies/";
-	path.append(Utf16ToUtf8(Utf8ToUtf16(group)));
-	m_cpr_session.SetUrl(cpr::Url{ path });
-	m_cpr_session.SetBody(cpr::Body{ j.dump() });
-	auto res = m_cpr_session.Put();
-	return res.status_code == 204; // HTTP 204 No Content
+	try
+	{
+		cpr::Session   m_cpr_session;
+		nlohmann::json j = {
+			{"name",selectProxy}
+		};
+
+		auto url = m_api_base_url + "/proxies/Proxy";
+		auto res = cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });
+
+
+		/*std::string path = "/proxies/";
+		path.append(group);
+		m_cpr_session.SetUrl(cpr::Url{ path });
+		m_cpr_session.SetBody(cpr::Body{ j.dump() });
+		auto res = m_cpr_session.Put()*/;
+		return res.status_code == 204; // HTTP 204 No Content
+	}
+	catch (...)
+	{
+		return false;
+	}
+
+	return false;
  
 }

+ 4 - 3
SProxy/ClashApi.h

@@ -19,16 +19,17 @@ public:
 
 	std::string GetVersion();
 	ClashConfig GetConfig();
-	std::optional<std::wstring> RequestConfigUpdate(std::filesystem::path configPath);
+	bool RequestConfigUpdate(std::filesystem::path configPath);
 	bool UpdateProxyMode(ClashProxyMode mode);
 	bool UpdateLogLevel(ClashLogLevel level);
 	bool UpdateAllowLan(bool allow);
 	//L"http://cp.cloudflare.com/generate_204"
 	u16milliseconds GetProxyDelay(std::string_view proxyName);
 	ClashProxies GetProxies();
-	bool UpdateProxyGroup(std::string_view group, std::string_view selectProxy);
+	//Proxy
+	bool UpdateProxyGroup(std::string_view group , std::string_view selectProxy);
 private:
-	cpr::Session   m_cpr_session;
+	
 	int			   m_port;
 	std::string	   m_api_base_url;
 };

+ 4 - 0
SProxy/IBaseClash.h

@@ -12,6 +12,10 @@ public:
 	virtual BOOL StartClash() = 0;
 
 	virtual BOOL StopClash() = 0;
+
+	virtual int GetHttpPort() = 0;
+	virtual int GetSocketPort() = 0;
+	virtual int GetClasApiPort() = 0;
  
 };
 

+ 6 - 0
SProxy/IBaseCurl.h

@@ -27,10 +27,16 @@ public:
 	//»ñÈ¡Ïß·
 	virtual HTTPRET GetServerNode(std::string& data) = 0;
 
+	//¼øȨ
+	virtual HTTPRET Auth(std::string& data) = 0;
 
+	virtual HTTPRET Refresh(std::string& data) = 0;
+
+	virtual HTTPRET Version(std::string& data) = 0;
 
 	virtual SStringA  GetLastErrorA() = 0;
 	virtual SStringW  GetLastErrorW() = 0;
+	virtual int  GetHttpStatus() = 0;
 
 };
 

+ 8 - 2
SProxy/Logger.cpp

@@ -1,6 +1,7 @@
 #include "stdafx.h"
 #include "Logger.h"
  
+Logger* SSingleton<Logger>::ms_Singleton = NULL;
 
 Logger::Logger() {
 	// 默认构造函数
@@ -9,9 +10,13 @@ Logger::Logger() {
 	cout << "[WELCOME] " << __FILE__ << " " << currTime() << " : " << "=== Start logging ===" << endl;
 }
 
-Logger::Logger(log_target target, log_level level, string path) {
+void Logger::Init(log_target target, log_level level, string path)
+{
 	this->target = target;
-	this->path = path;
+	if (path.empty())
+	{
+		this->path = std::filesystem::current_path().string() + "\\log\\log.log";
+	}
 	this->level = level;
 	string tmp = "";  // 双引号下的常量不能直接相加,所以用一个string类型做转换
 	string welcome_dialog = tmp + "[SProxy] " + __FILE__ + " " + currTime() + " : " + "=== Start logging ===\n";
@@ -24,6 +29,7 @@ Logger::Logger(log_target target, log_level level, string path) {
 		cout << welcome_dialog;
 	}
 }
+ 
 
 void Logger::output(string text, log_level act_level) {
 	string prefix;

+ 2 - 2
SProxy/Logger.h

@@ -16,7 +16,7 @@ using std::to_string;
 using std::ios;
 
 
-class Logger {
+class Logger : public SSingleton<Logger> {
 public:
 	enum log_level { debug, info, warning, error };// 日志等级
 	enum log_target { file, terminal, file_and_terminal };// 日志输出目标
@@ -40,7 +40,7 @@ private:
 	void output(string text, log_level act_level);            // 输出行为
 public:
 	Logger();  // 默认构造函数
-	Logger(log_target target, log_level level, string path);
+	void Init(log_target target, log_level level, string path = "");
 	void DEBUG(string text);
 	void INFO(string text);
 	void WARNING(string text);

BIN
SProxy/MainDlg.cpp


BIN
SProxy/MainDlg.h


BIN
SProxy/SProxy.cpp


+ 21 - 6
SProxy/SProxy.vcxproj

@@ -34,7 +34,7 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -73,9 +73,10 @@
     <LinkIncremental>true</LinkIncremental>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Configuration)\</IntDir>
-    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>..\__obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+    <OutDir>..\__bin\$(Platform)\$(Configuration)\</OutDir>
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(SOUIPATH)\soui-sys-resource;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <IntDir>..\__obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
@@ -94,6 +95,9 @@
   <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <VcpkgUseStatic>true</VcpkgUseStatic>
   </PropertyGroup>
+  <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <VcpkgUseStatic>true</VcpkgUseStatic>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>Use</PrecompiledHeader>
@@ -125,17 +129,19 @@
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
       <WarningLevel>Level3</WarningLevel>
-      <AdditionalIncludeDirectories>$(SOUIPATH)\config;$(SOUIPATH)\components;$(SOUIPATH)\SOUI\include;$(SOUIPATH)\utilities\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(SOUIPATH)\soui-sys-resource;$(SOUIPATH)\config;$(SOUIPATH)\components;$(SOUIPATH)\SOUI\include;$(SOUIPATH)\utilities\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN64;_WINDOWS;NDEBUG;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <WholeProgramOptimization>true</WholeProgramOptimization>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>$(SOUIPATH)\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>utilities.lib;soui.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>utilities.lib;soui.lib;crypt32.lib;wldap32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Windows</SubSystem>
+      <UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
     </Link>
     <ResourceCompile>
       <Culture>0x0804</Culture>
@@ -185,6 +191,7 @@
       <AdditionalLibraryDirectories>$(SOUIPATH)\bin64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>utilities.lib;soui.lib;souid.lib;crypt32.lib;wldap32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Windows</SubSystem>
+      <UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
     </Link>
     <ResourceCompile>
       <Culture>0x0804</Culture>
@@ -197,6 +204,7 @@
   <ItemGroup>
     <ClCompile Include="CApp.cpp" />
     <ClCompile Include="CBaseMode.cpp" />
+    <ClCompile Include="CConnectMage.cpp" />
     <ClCompile Include="ClashApi.cpp" />
     <ClCompile Include="CLashConfig.cpp" />
     <ClCompile Include="ClashModel.cpp" />
@@ -206,8 +214,10 @@
     <ClCompile Include="CProcessManager.cpp" />
     <ClCompile Include="CServerList.cpp" />
     <ClCompile Include="CServerListMode.cpp" />
+    <ClCompile Include="CThread.cpp" />
     <ClCompile Include="CTool.cpp" />
     <ClCompile Include="CUserInfo.cpp" />
+    <ClCompile Include="CVersion.cpp" />
     <ClCompile Include="FileOperate.cpp" />
     <ClCompile Include="IBaseClash.cpp" />
     <ClCompile Include="IBaseCurl.cpp" />
@@ -226,6 +236,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="SysProxy.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="SProxy.rc" />
@@ -233,6 +244,7 @@
   <ItemGroup>
     <ClInclude Include="CApp.h" />
     <ClInclude Include="CBaseMode.h" />
+    <ClInclude Include="CConnectMage.h" />
     <ClInclude Include="ClashApi.h" />
     <ClInclude Include="CLashConfig.h" />
     <ClInclude Include="ClashModel.h" />
@@ -244,8 +256,10 @@
     <ClInclude Include="CProcessManager.h" />
     <ClInclude Include="CServerList.h" />
     <ClInclude Include="CServerListMode.h" />
+    <ClInclude Include="CThread.h" />
     <ClInclude Include="CTool.h" />
     <ClInclude Include="CUserInfo.h" />
+    <ClInclude Include="CVersion.h" />
     <ClInclude Include="event.h" />
     <ClInclude Include="FileOperate.h" />
     <ClInclude Include="IBaseClash.h" />
@@ -262,6 +276,7 @@
     <ClInclude Include="SShellNotifyIcon.h" />
     <ClInclude Include="StabtypeControl.h" />
     <ClInclude Include="stdafx.h" />
+    <ClInclude Include="SysProxy.h" />
     <ClInclude Include="Util.hpp" />
   </ItemGroup>
   <ItemGroup>

+ 24 - 0
SProxy/SProxy.vcxproj.filters

@@ -116,6 +116,18 @@
     <ClCompile Include="CBaseMode.cpp">
       <Filter>Model</Filter>
     </ClCompile>
+    <ClCompile Include="CVersion.cpp">
+      <Filter>Model</Filter>
+    </ClCompile>
+    <ClCompile Include="CConnectMage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="CThread.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="SysProxy.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="SProxy.rc">
@@ -219,6 +231,18 @@
     <ClInclude Include="CNodeAdapter.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="CVersion.h">
+      <Filter>Model</Filter>
+    </ClInclude>
+    <ClInclude Include="CConnectMage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="CThread.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="SysProxy.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\soui_res.rc2">

+ 261 - 0
SProxy/SysProxy.cpp

@@ -0,0 +1,261 @@
+#include "stdafx.h"
+#include "SysProxy.h"
+ 
+#include <WinInet.h>
+#include <assert.h>
+
+#pragma comment( lib,"wininet.lib")
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/** @brief 设置系统代理 (IE代理)
+*
+* @param lpszProxyServer 代理服务器地址, 为NULL表示不设置
+* @param lpszPacUrl pac地址,为NULL表示不设置
+* @param lpszByPass 设置By pass( 跳过代理服务器的列表 ), 为NULL的时候不设置
+* @param lpszPac pac地址,只有在bIsPacMode=TRUE时才有效
+*
+* @note 如果指定了lpszByPass, bLocalAddrNotUseProxy将被忽略
+*/
+BOOL SetSystemProxy(
+	LPCTSTR lpszProxyServer,
+	LPCTSTR lpszPacUrl,
+	LPCTSTR lpszByPass /*= NULL */,
+	BOOL bLocalAddrNotUseProxy /* = TRUE */)
+{
+	// To include server for FTP, HTTPS, and so on, use the string
+	// (ftp=http://<ProxyServerName>:80; https=https://<ProxyServerName>:80)
+	INTERNET_PER_CONN_OPTION_LIST    List;
+	INTERNET_PER_CONN_OPTION         Option[5];  //  最多5个
+	unsigned long                    nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
+	int nPos = 0;
+
+	//PrintfW( LEVEL_INFO, _T("[SetSystemProxy]: Proxy Server: %s, PacUrl: %s") , lpszProxyServer?lpszProxyServer:_T("NULL"),lpszPacUrl?lpszPacUrl:_T("NULL"));
+
+	// proxy server
+	if (lpszProxyServer)
+	{
+		Option[nPos].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
+		Option[nPos].Value.pszValue = (LPTSTR)lpszProxyServer;
+		nPos++;
+	}
+	if (lpszPacUrl)
+	{
+		Option[nPos].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
+		Option[nPos].Value.pszValue = (LPTSTR)lpszPacUrl;
+		nPos++;
+	}
+
+	// 指定连接类型
+	// Sets or retrieves the connection type. The Value member will contain one or more of the following values:
+	Option[nPos].dwOption = INTERNET_PER_CONN_FLAGS;
+	Option[nPos].Value.dwValue = PROXY_TYPE_DIRECT;
+	if (lpszProxyServer)
+		Option[nPos].Value.dwValue |= PROXY_TYPE_PROXY;
+	if (lpszPacUrl)
+		Option[nPos].Value.dwValue |= PROXY_TYPE_AUTO_PROXY_URL;
+	nPos++;
+
+	// 指定不通过代理服务器的地址
+	// Sets or retrieves a string containing the URLs that do not use the proxy server.
+	Option[nPos].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
+	if (lpszByPass != NULL)
+	{
+		Option[nPos].Value.pszValue = (LPTSTR)lpszByPass;
+	}
+	else
+	{
+		if (bLocalAddrNotUseProxy)
+			// local;<local> 这个值是查注册表得知的. IE中设置了"对于本地地址不使用代理服务器"后就是这样的
+			Option[nPos].Value.pszValue = _T("local;<local>");
+		else
+			Option[nPos].Value.pszValue = _T("local");
+	}
+	nPos++;
+
+	List.dwSize = nSize;
+	List.pszConnection = NULL;
+	List.dwOptionCount = nPos;
+	List.dwOptionError = 0;
+	List.pOptions = Option;
+
+	if (!InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))
+	{
+		//PrintfW( LEVEL_ERROR, _T("[SetSystemProxy]: Set internet options failed, Code: %d") , GetLastError() );
+		return FALSE;
+	}
+	// To refresh the global proxy settings, you must call InternetSetOption with the INTERNET_OPTION_REFRESH option flag.
+	InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
+	InternetSetOption(NULL, INTERNET_OPTION_REFRESH, NULL, NULL);
+	//The connection settings for other instances of Internet Explorer.
+
+   // PrintfW( LEVEL_INFO, _T("[SetSystemProxy]: Set internet options done") );
+
+	return TRUE;
+}
+
+/** @brief 是否设置了系统代理
+*/
+BOOL IsSetSystemProxy()
+{
+	TCHAR szPacUrl[1024] = { 0 };
+	TCHAR szProxy[1024] = { 0 };
+	TCHAR szByPass[1024] = { 0 };
+	DWORD flags = 0;
+	BOOL bUseAutoDetect;
+	BOOL bUseAutoConfigUrl;
+	BOOL bUseProxyServer;
+
+	if (GetSystemProxyInfo(
+		bUseAutoDetect,
+		bUseAutoConfigUrl,
+		szPacUrl,
+		1024,
+		bUseProxyServer,
+		szProxy,
+		1024,
+		szByPass,
+		1024) && (szProxy[0] != 0 || szPacUrl[0] != 0))
+		return TRUE;
+
+	return FALSE;
+}
+
+/** @brief 获取IE的代理设置,( 系统代理)
+*
+* @param bUseAutoDetect[out] 自动检测设置属性
+* @param bUseAutoConfigUrl[out] Buffer使用自动配置脚本属性
+* @param lpAutoConfigUrl[out] 自动配置脚本URL地址
+* @param nAutoConfigUrlLe[out] 自动配置脚本URL Buffer长度
+* @param bUseProxyServer[out] 使用代理服务器地址
+* @param lpProxyServer[out] 代理服务器地址
+* @param nProxyServerLen[out] 代理服务器地址BUFFER 长度
+* @param lpByPass[out] By pass字符串
+* @param nByPassLen[out] By pass字符串BUFFER长度
+
+* @return
+* TRUE 成功, 返回值在以上参数中
+* FALSE 失败.
+*
+* https://msdn.microsoft.com/en-us/library/aa385145.aspx
+*/
+BOOL GetSystemProxyInfo(
+	BOOL &bUseAutoDetect, // 自动检测设置属性
+	BOOL &bUseAutoConfigUrl, // 使用自动配置脚本属性
+	LPTSTR lpAutoConfigUrl,	// 自动配置脚本URL地址
+	int nAutoConfigUrlLen,		// 自动配置脚本URL Buffer长度
+	BOOL &bUseProxyServer,		// 使用代理服务器地址
+	LPTSTR lpProxyServer,		// 代理服务器地址
+	int nProxyServerLen,		// 代理服务器地址BUFFER 长度
+	LPTSTR lpByPass,			// By pass字符串
+	int nByPassLen				// By pass字符串BUFFER长度
+)
+{
+	assert(lpAutoConfigUrl != NULL);
+	assert(nAutoConfigUrlLen > 0);
+
+	assert(lpProxyServer != NULL);
+	assert(nProxyServerLen > 0);
+
+	assert(lpByPass != NULL);
+	assert(nByPassLen > 0);
+
+	const int optionCount = 5;
+	INTERNET_PER_CONN_OPTION_LIST List;
+	INTERNET_PER_CONN_OPTION Option[optionCount];
+	unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
+
+	Option[0].dwOption = INTERNET_PER_CONN_FLAGS;
+	Option[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
+	Option[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
+	Option[3].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
+	Option[4].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
+	//Option[0].dwOption = 1;
+	//for (int i = 1; i < optionCount; i++) {
+	//	Option[i].dwOption = i;
+	//}
+	List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
+	List.pszConnection = NULL;
+	List.dwOptionCount = optionCount;
+	List.dwOptionError = 0;
+	List.pOptions = Option;
+
+	if (!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
+		return FALSE;
+	}
+
+	// proxy server
+	bUseProxyServer = FALSE;
+	if ((Option[0].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY
+		&& Option[1].Value.pszValue != NULL
+		)
+	{
+		bUseProxyServer = TRUE;
+		_tcsncpy_s(lpProxyServer, nProxyServerLen, Option[1].Value.pszValue, nProxyServerLen - 1);
+	}
+
+	// autoconfig url
+	bUseAutoConfigUrl = FALSE;
+	if ((Option[0].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL
+		&& Option[3].Value.pszValue != NULL
+		)
+	{
+		bUseAutoConfigUrl = TRUE;
+		_tcsncpy_s(lpAutoConfigUrl, nAutoConfigUrlLen, Option[3].Value.pszValue, nAutoConfigUrlLen - 1);
+	}
+
+	// auto detect
+	bUseAutoDetect = FALSE;
+	if ((Option[0].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT)
+	{
+		bUseAutoDetect = TRUE;
+	}
+
+	if (Option[2].Value.pszValue != NULL)
+	{
+		_tcsncpy_s(lpByPass, nByPassLen, Option[2].Value.pszValue, nByPassLen - 1);
+	}
+
+	return TRUE;
+}
+
+/** @brief 禁用系统代理
+*/
+BOOL DisableSystemProxy()
+{
+	INTERNET_PER_CONN_OPTION_LIST    List;
+	INTERNET_PER_CONN_OPTION         Option;
+	unsigned long                    nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
+
+	//PrintfW( LEVEL_INFO, _T("[DisableSystemProxy]: ...") );
+
+	// Set flags.
+	Option.dwOption = INTERNET_PER_CONN_FLAGS;
+	Option.Value.dwValue = PROXY_TYPE_DIRECT;
+
+	// Fill out list struct.
+	List.dwSize = nSize;
+	// NULL == LAN, otherwise connectoid name.
+	List.pszConnection = NULL;
+	// Set three options.
+	List.dwOptionCount = 1;
+	List.pOptions = &Option;
+
+	// Set the options on the connection.
+	if (!InternetSetOption(NULL,
+		INTERNET_OPTION_PER_CONNECTION_OPTION, &List, nSize))
+	{
+		//PrintfW( LEVEL_ERROR, _T("[DisableSystemProxy]: Set internet options failed, Code: %d") ,GetLastError() );
+		return FALSE;
+	}
+
+	InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
+	InternetSetOption(NULL, INTERNET_OPTION_REFRESH, NULL, 0);
+
+	//PrintfW( LEVEL_INFO, _T("[DisableSystemProxy]: Set internet options done."));
+
+	return TRUE;
+}

+ 54 - 0
SProxy/SysProxy.h

@@ -0,0 +1,54 @@
+#pragma once
+
+/** @brief 设置系统代理 (IE代理)
+*
+* @param lpszProxyServer 代理服务器地址, 为NULL表示不设置
+* @param lpszPacUrl pac地址,为NULL表示不设置
+* @param lpszByPass 设置By pass( 跳过代理服务器的列表 ), 为NULL的时候不设置
+* @param bLocalAddrNotUseProxy 对应于IE代理设置中的: 对于本地地址不使用代理服务器
+*
+* @note 如果指定了lpszByPass, bLocalAddrNotUseProxy将被忽略
+*/
+BOOL SetSystemProxy(
+	LPCTSTR lpszProxyServer,
+	LPCTSTR lpszPacUrl,
+	LPCTSTR lpszByPass = NULL,
+	BOOL bLocalAddrNotUseProxy = FALSE);
+
+/** @brief 禁用系统代理
+*/
+BOOL DisableSystemProxy();
+
+/** @brief 获取IE的代理设置,( 系统代理)
+*
+* @param bUseAutoDetect[out] 自动检测设置属性
+* @param bUseAutoConfigUrl[out] Buffer使用自动配置脚本属性
+* @param lpAutoConfigUrl[out] 自动配置脚本URL地址
+* @param nAutoConfigUrlLe[out] 自动配置脚本URL Buffer长度
+* @param bUseProxyServer[out] 使用代理服务器地址
+* @param lpProxyServer[out] 代理服务器地址
+* @param nProxyServerLen[out] 代理服务器地址BUFFER 长度
+* @param lpByPass[out] By pass字符串
+* @param nByPassLen[out] By pass字符串BUFFER长度
+
+* @return
+* TRUE 成功, 返回值在以上参数中
+* FALSE 失败.
+*
+* https://msdn.microsoft.com/en-us/library/aa385145.aspx
+*/
+BOOL GetSystemProxyInfo(
+	BOOL &bUseAutoDetect, // 自动检测设置属性
+	BOOL &bUseAutoConfigUrl, // 使用自动配置脚本属性
+	LPTSTR lpAutoConfigUrl,	// 自动配置脚本URL地址
+	int nAutoConfigUrlLen,		// 自动配置脚本URL Buffer长度
+	BOOL &bUseProxyServer,		// 使用代理服务器地址
+	LPTSTR lpProxyServer,		// 代理服务器地址
+	int nProxyServerLen,		// 代理服务器地址BUFFER 长度
+	LPTSTR lpByPass,			// By pass字符串
+	int nByPassLen				// By pass字符串BUFFER长度
+);
+
+/** @brief 是否设置了系统代理
+*/
+BOOL IsSetSystemProxy();

+ 5 - 2
SProxy/comm.h

@@ -10,7 +10,7 @@ constexpr auto CLASH_ASSETS_DIR_NAME = L"Assets";
 
 constexpr auto DSPROXY_CONFIG_INIT_ClASH_NAME = L"config_info.yaml";
 constexpr auto DSPROXY_CONFIG_ClASH_NAME = L"config.yaml";
-constexpr auto DSPROXY_CONFIG_TUN_ClASH_NAME = L"config.yaml";
+constexpr auto DSPROXY_CONFIG_TUN_ClASH_NAME = L"tun_config.yaml";
 
 
 constexpr auto DSPROXY_CONFIG_DIR_NAME = L"Config";
@@ -18,4 +18,7 @@ constexpr auto DSPROXY_EXE_NAME = L"syscode.exe";
 
 
 constexpr auto CONNECT_NODE_MSG = L"正在获取节点..不能操作"; 
-constexpr auto SUEECS_NODE_MSG = L"获取节点成功..";
+constexpr auto SUEECS_NODE_MSG = L"获取节点成功.."; 
+
+
+constexpr auto VERSION = L"1.1.2";

+ 45 - 0
SProxy/event.h

@@ -76,4 +76,49 @@ public:
 
 	int		 status;
 	SStringW msg;
+};
+
+
+#define EVT_VERIONS (SOUI::EVT_EXTERNAL_BEGIN + 1004)
+
+class EventVerions : public TplEventArgs<EventVerions>
+{
+	SOUI_CLASS_NAME(EventVerions, L"on_event_version")
+public:
+	EventVerions(SOUI::SWindow* pSender) : TplEventArgs<EventVerions>(pSender)
+	{
+
+	}
+	enum {
+		EventID = EVT_VERIONS
+	};
+
+	int		 status;
+	SStringW msg;
+};
+
+
+enum struct ConnectState
+{
+	Stop,
+	SwitchConfigSuccEss,
+	SwitchNodeSuccEss,
+};
+
+#define EVT_CONNECT (SOUI::EVT_EXTERNAL_BEGIN + 1005)
+
+class EventConnect : public TplEventArgs<EventConnect>
+{
+	SOUI_CLASS_NAME(EventConnect, L"on_event_connect")
+public:
+	EventConnect(SOUI::SWindow* pSender) : TplEventArgs<EventConnect>(pSender)
+	{
+
+	}
+	enum {
+		EventID = EVT_CONNECT
+	};
+
+	ConnectState status;
+	SStringW	 msg;
 };

BIN
SProxy/res/resource.h


BIN
SProxy/res/soui_res.rc2


BIN
SProxy/stdafx.h


+ 14 - 8
SProxy/uires/xml/page_home.xml

@@ -8,15 +8,21 @@
             <window pos="5,[2,-5,-5">
             <window size="-2,-2" layout="vbox" gravity="center" >
                 <window size="-2,-1" layout="vbox"   gravity="left"  extend="0,30,0,0">
-                    <text name="edit_username" extend="35,0,0,0" colorText="#ffffff">用户名</text>
+                    <text name="username" extend="35,0,0,0" colorText="#ffffff">用户名</text>
                     <img skin="skin_line" extend="35,10,0,0"/>
-                    <text name="edit_username" extend="35,10,0,0" colorText="#ffffff">到期时间</text>
+                    <text name="username_time" extend="35,10,0,0" colorText="#ffffff">到期时间</text>
                     <img skin="skin_line" extend="35,10,0,0"/>
-                    <text name="edit_username" extend="35,10,0,0" colorText="#ffffff">用户流量</text>
+                    <text name="username_liulaing" extend="35,10,0,0" colorText="#ffffff">用户流量</text>
                     <img skin="skin_line" extend="35,10,0,0"/>
                     <window size="-2,-1" layout="hbox"   gravity="center"  extend="0,10,0,0">
-                            <link name="edit_username" extend="35,0,0,0" colorText="#ffffff">使用教程</link>
-                            <link name="edit_username" extend="35,0,0,0" colorText="#ffffff">充值续费</link>
+                            <link name="username_jiaocheng" extend="35,0,0,0" colorText="#ffffff">使用教程</link>
+                            <link name="username_chongzhi" extend="35,0,0,0" colorText="#ffffff">充值续费</link>
+                            <link name="username_tuiguang" extend="35,0,0,0" colorText="#ffffff">推广地址</link>
+                    </window>
+                     <img skin="skin_line" extend="35,10,0,0"/>
+                      <window size="-2,-1" layout="vbox"   gravity="left"  extend="0,10,0,0">
+                            <text name="httpproxy" extend="35,0,0,0" colorText="#ffffff">http代理地址</text>
+                            <text name="socksproxy" extend="35,5,0,0" colorText="#ffffff">socksProxy</text>
                     </window>
                     <img skin="skin_line" extend="35,10,0,0"/>
                 </window>
@@ -30,7 +36,7 @@
 
                     <window name="selectnode" size="230,59" layout="hbox"  skin="skin_btnselection"  gravity="center" extend="0,10,0,0"> 
                             <img skin="skin_default" extend="10,0,0,0"/>
-                            <text name="node_name" colorText="#D8D8D8"  extend="5,0,0,0" font="adding:5,bold:1">切换服务器</text>
+                            <text name="node_name" colorText="#D8D8D8"  extend="5,0,0,0" font="adding:5,bold:1">智能选线</text>
                             <text name="node_delay" colorText="#D8D8D8" extend="15,0,0,0" ></text>
                     </window>
 
@@ -38,8 +44,8 @@
                 <tabtypecontrol name="sysmode" size="400,45" gravity="center" extend="47,25,44,0"/>
                 <tabtypecontrol name="routemode" size="400,45" gravity="center" extend="47,5,44,0"/>
 
-                <window size="220,10" layout="vbox" gravity="center" extend="0,15,0,0">     
-                    <link name="app_version" colorText="#707070"  extend="5,0,0,0" >版本号:1.0.0</link> 
+                <window size="220,-1" layout="vbox" gravity="center" extend="0,15,0,0">     
+                    <link name="app_version" colorText="#707070"  extend="5,0,0,0" >版本号:正在检测1.0.7</link> 
                 </window>
                 
             </window>

+ 1 - 1
SProxy/uires/xml/page_node.xml

@@ -14,7 +14,7 @@
          <window size="-2,-2" layout="vbox" gravity="center"  extend="0,0,0,0">
 
                <window name="nodeclass" size="-2,25" layout="hbox"  skin=""  gravity="center" extend="0,0,0,0"> 
-                     <text colorText="#ffffff88" font="adding:5,bold:1" >更新状态</text>
+                     <text name="refresh_status" colorText="#ffffff88" font="adding:5,bold:1" >更新状态</text>
                </window>
 
                  <!-- <window name="nodeclass" size="-2,51" layout="hbox"  skin=""  gravity="center" extend="0,0,0,0"> 

+ 55 - 0
__INCLUDE/CThread.hpp

@@ -0,0 +1,55 @@
+#ifndef THREAD_H_
+#define THREAD_H_
+ 
+#include <thread>
+#include <iostream>
+#include <utility>
+#include <system_error>
+ 
+class CThread
+{
+public:
+	CThread() : _bRun(false){}
+	CThread(CThread& src): _bRun(src._bRun), _thread(move(src._thread)){src._bRun = false;}
+ 
+	virtual ~CThread()
+	{
+		if(_thread.joinable())
+			_thread.detach();
+	}
+ 
+	template <typename F, typename... Args>
+	bool Start(F&& f, Args&&... args)
+	{
+		if(_bRun) return false;
+		try
+		{
+			_bRun = true;
+			_thread = std::thread(std::forward<F>(f), std::forward<Args>(args)...);
+		}
+		catch(std::system_error& ex)
+		{
+			std::cout << "start thread fails:" << ex.what() << std::endl;
+		}
+		catch(...)
+		{
+			std::cout << "start thread fails" << std::endl;
+		}
+		return _bRun;
+	}
+ 
+	bool IsRun() const {return _bRun;}
+	void Join()
+	{
+		bool bRun = _bRun;
+		_bRun = false;
+		if(bRun)
+			_thread.join();
+	}
+ 
+private:
+	bool 		_bRun;
+	std::thread	_thread;
+};
+ 
+#endif /* THREAD_H_ */