mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 13:42:51 +08:00
fix: Fix linux system proxy bug
This commit is contained in:
parent
2f16d498de
commit
6d7ce2868c
440
3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.cpp
vendored
Normal file
440
3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.cpp
vendored
Normal file
@ -0,0 +1,440 @@
|
||||
#include "QvProxyConfigurator.hpp"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
//
|
||||
#include <wininet.h>
|
||||
#include <ras.h>
|
||||
#include <raserror.h>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QProcess>
|
||||
|
||||
#include "3rdparty/fix_old_qt.h"
|
||||
#include "3rdparty/qv2ray/wrapper.hpp"
|
||||
#include "fmt/Preset.hpp"
|
||||
#include "main/NekoGui.hpp"
|
||||
|
||||
#define QV_MODULE_NAME "SystemProxy"
|
||||
|
||||
#define QSTRN(num) QString::number(num)
|
||||
|
||||
namespace Qv2ray::components::proxy {
|
||||
|
||||
using ProcessArgument = QPair<QString, QStringList>;
|
||||
#ifdef Q_OS_MACOS
|
||||
QStringList macOSgetNetworkServices() {
|
||||
QProcess p;
|
||||
p.setProgram("/usr/sbin/networksetup");
|
||||
p.setArguments(QStringList{"-listallnetworkservices"});
|
||||
p.start();
|
||||
p.waitForStarted();
|
||||
p.waitForFinished();
|
||||
LOG(p.errorString());
|
||||
auto str = p.readAllStandardOutput();
|
||||
auto lines = SplitLines(str);
|
||||
QStringList result;
|
||||
|
||||
// Start from 1 since first line is unneeded.
|
||||
for (auto i = 1; i < lines.count(); i++) {
|
||||
// * means disabled.
|
||||
if (!lines[i].contains("*")) {
|
||||
result << lines[i];
|
||||
}
|
||||
}
|
||||
|
||||
LOG("Found " + QSTRN(result.size()) + " network services: " + result.join(";"));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
#define NO_CONST(expr) const_cast<wchar_t *>(expr)
|
||||
// static auto DEFAULT_CONNECTION_NAME =
|
||||
// NO_CONST(L"DefaultConnectionSettings");
|
||||
///
|
||||
/// INTERNAL FUNCTION
|
||||
bool __QueryProxyOptions() {
|
||||
INTERNET_PER_CONN_OPTION_LIST List;
|
||||
INTERNET_PER_CONN_OPTION Option[5];
|
||||
//
|
||||
unsigned long nSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
|
||||
Option[0].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
|
||||
Option[1].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
|
||||
Option[2].dwOption = INTERNET_PER_CONN_FLAGS;
|
||||
Option[3].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
|
||||
Option[4].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
|
||||
//
|
||||
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST);
|
||||
List.pszConnection = nullptr; // NO_CONST(DEFAULT_CONNECTION_NAME);
|
||||
List.dwOptionCount = 5;
|
||||
List.dwOptionError = 0;
|
||||
List.pOptions = Option;
|
||||
|
||||
if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
|
||||
LOG("InternetQueryOption failed, GLE=" + QSTRN(GetLastError()));
|
||||
}
|
||||
|
||||
LOG("System default proxy info:");
|
||||
|
||||
if (Option[0].Value.pszValue != nullptr) {
|
||||
LOG(QString::fromWCharArray(Option[0].Value.pszValue));
|
||||
}
|
||||
|
||||
if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_PROXY_URL) == PROXY_TYPE_AUTO_PROXY_URL) {
|
||||
LOG("PROXY_TYPE_AUTO_PROXY_URL");
|
||||
}
|
||||
|
||||
if ((Option[2].Value.dwValue & PROXY_TYPE_AUTO_DETECT) == PROXY_TYPE_AUTO_DETECT) {
|
||||
LOG("PROXY_TYPE_AUTO_DETECT");
|
||||
}
|
||||
|
||||
if ((Option[2].Value.dwValue & PROXY_TYPE_DIRECT) == PROXY_TYPE_DIRECT) {
|
||||
LOG("PROXY_TYPE_DIRECT");
|
||||
}
|
||||
|
||||
if ((Option[2].Value.dwValue & PROXY_TYPE_PROXY) == PROXY_TYPE_PROXY) {
|
||||
LOG("PROXY_TYPE_PROXY");
|
||||
}
|
||||
|
||||
if (!InternetQueryOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &List, &nSize)) {
|
||||
LOG("InternetQueryOption failed,GLE=" + QSTRN(GetLastError()));
|
||||
}
|
||||
|
||||
if (Option[4].Value.pszValue != nullptr) {
|
||||
LOG(QString::fromStdWString(Option[4].Value.pszValue));
|
||||
}
|
||||
|
||||
INTERNET_VERSION_INFO Version;
|
||||
nSize = sizeof(INTERNET_VERSION_INFO);
|
||||
InternetQueryOption(nullptr, INTERNET_OPTION_VERSION, &Version, &nSize);
|
||||
|
||||
if (Option[0].Value.pszValue != nullptr) {
|
||||
GlobalFree(Option[0].Value.pszValue);
|
||||
}
|
||||
|
||||
if (Option[3].Value.pszValue != nullptr) {
|
||||
GlobalFree(Option[3].Value.pszValue);
|
||||
}
|
||||
|
||||
if (Option[4].Value.pszValue != nullptr) {
|
||||
GlobalFree(Option[4].Value.pszValue);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool __SetProxyOptions(LPWSTR proxy_full_addr, bool isPAC) {
|
||||
INTERNET_PER_CONN_OPTION_LIST list;
|
||||
DWORD dwBufSize = sizeof(list);
|
||||
// Fill the list structure.
|
||||
list.dwSize = sizeof(list);
|
||||
// NULL == LAN, otherwise connectoid name.
|
||||
list.pszConnection = nullptr;
|
||||
|
||||
if (nullptr == proxy_full_addr) {
|
||||
LOG("Clearing system proxy");
|
||||
//
|
||||
list.dwOptionCount = 1;
|
||||
list.pOptions = new INTERNET_PER_CONN_OPTION[1];
|
||||
|
||||
// Ensure that the memory was allocated.
|
||||
if (nullptr == list.pOptions) {
|
||||
// Return if the memory wasn't allocated.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flags.
|
||||
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
|
||||
list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT;
|
||||
} else if (isPAC) {
|
||||
LOG("Setting system proxy for PAC");
|
||||
//
|
||||
list.dwOptionCount = 2;
|
||||
list.pOptions = new INTERNET_PER_CONN_OPTION[2];
|
||||
|
||||
if (nullptr == list.pOptions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flags.
|
||||
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
|
||||
list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_AUTO_PROXY_URL;
|
||||
// Set proxy name.
|
||||
list.pOptions[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
|
||||
list.pOptions[1].Value.pszValue = proxy_full_addr;
|
||||
} else {
|
||||
LOG("Setting system proxy for Global Proxy");
|
||||
//
|
||||
list.dwOptionCount = 2;
|
||||
list.pOptions = new INTERNET_PER_CONN_OPTION[2];
|
||||
|
||||
if (nullptr == list.pOptions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set flags.
|
||||
list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
|
||||
list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_PROXY;
|
||||
// Set proxy name.
|
||||
list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
|
||||
list.pOptions[1].Value.pszValue = proxy_full_addr;
|
||||
// Set proxy override.
|
||||
// list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
|
||||
// auto localhost = L"localhost";
|
||||
// list.pOptions[2].Value.pszValue = NO_CONST(localhost);
|
||||
}
|
||||
|
||||
// Set proxy for LAN.
|
||||
if (!InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize)) {
|
||||
LOG("InternetSetOption failed for LAN, GLE=" + QSTRN(GetLastError()));
|
||||
}
|
||||
|
||||
RASENTRYNAME entry;
|
||||
entry.dwSize = sizeof(entry);
|
||||
std::vector<RASENTRYNAME> entries;
|
||||
DWORD size = sizeof(entry), count;
|
||||
LPRASENTRYNAME entryAddr = &entry;
|
||||
auto ret = RasEnumEntries(nullptr, nullptr, entryAddr, &size, &count);
|
||||
if (ERROR_BUFFER_TOO_SMALL == ret) {
|
||||
entries.resize(count);
|
||||
entries[0].dwSize = sizeof(RASENTRYNAME);
|
||||
entryAddr = entries.data();
|
||||
ret = RasEnumEntries(nullptr, nullptr, entryAddr, &size, &count);
|
||||
}
|
||||
if (ERROR_SUCCESS != ret) {
|
||||
LOG("Failed to list entry names");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set proxy for each connectoid.
|
||||
for (DWORD i = 0; i < count; ++i) {
|
||||
list.pszConnection = entryAddr[i].szEntryName;
|
||||
if (!InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize)) {
|
||||
LOG("InternetSetOption failed for connectoid " + QString::fromWCharArray(list.pszConnection) + ", GLE=" + QSTRN(GetLastError()));
|
||||
}
|
||||
}
|
||||
|
||||
delete[] list.pOptions;
|
||||
InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
|
||||
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetSystemProxy(int httpPort, int socksPort) {
|
||||
const QString &address = "127.0.0.1";
|
||||
bool hasHTTP = (httpPort > 0 && httpPort < 65536);
|
||||
bool hasSOCKS = (socksPort > 0 && socksPort < 65536);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (!hasHTTP) {
|
||||
LOG("Nothing?");
|
||||
return;
|
||||
} else {
|
||||
LOG("Qv2ray will set system proxy to use HTTP");
|
||||
}
|
||||
#else
|
||||
if (!hasHTTP && !hasSOCKS) {
|
||||
LOG("Nothing?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasHTTP) {
|
||||
LOG("Qv2ray will set system proxy to use HTTP");
|
||||
}
|
||||
|
||||
if (hasSOCKS) {
|
||||
LOG("Qv2ray will set system proxy to use SOCKS");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString str = NekoGui::dataStore->system_proxy_format;
|
||||
if (str.isEmpty()) str = Preset::Windows::system_proxy_format[0];
|
||||
str = str.replace("{ip}", address)
|
||||
.replace("{http_port}", Int2String(httpPort))
|
||||
.replace("{socks_port}", Int2String(socksPort));
|
||||
//
|
||||
LOG("Windows proxy string: " + str);
|
||||
auto proxyStrW = new WCHAR[str.length() + 1];
|
||||
wcscpy(proxyStrW, str.toStdWString().c_str());
|
||||
//
|
||||
__QueryProxyOptions();
|
||||
|
||||
if (!__SetProxyOptions(proxyStrW, false)) {
|
||||
LOG("Failed to set proxy.");
|
||||
}
|
||||
|
||||
__QueryProxyOptions();
|
||||
#elif defined(Q_OS_LINUX)
|
||||
QList<ProcessArgument> actions;
|
||||
actions << ProcessArgument{"gsettings", {"set", "org.gnome.system.proxy", "mode", "manual"}};
|
||||
//
|
||||
bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE" ||
|
||||
qEnvironmentVariable("XDG_SESSION_DESKTOP") == "plasma";
|
||||
const auto configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
||||
|
||||
//
|
||||
// Configure HTTP Proxies for HTTP, FTP and HTTPS
|
||||
if (hasHTTP) {
|
||||
// iterate over protocols...
|
||||
for (const auto &protocol: QStringList{"http", "ftp", "https"}) {
|
||||
// for GNOME:
|
||||
{
|
||||
actions << ProcessArgument{"gsettings",
|
||||
{"set", "org.gnome.system.proxy." + protocol, "host", address}};
|
||||
actions << ProcessArgument{"gsettings",
|
||||
{"set", "org.gnome.system.proxy." + protocol, "port", QSTRN(httpPort)}};
|
||||
}
|
||||
|
||||
// for KDE:
|
||||
if (isKDE) {
|
||||
actions << ProcessArgument{"kwriteconfig5",
|
||||
{"--file", configPath + "/kioslaverc", //
|
||||
"--group", "Proxy Settings", //
|
||||
"--key", protocol + "Proxy", //
|
||||
"http://" + address + " " + QSTRN(httpPort)}};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Configure SOCKS5 Proxies
|
||||
if (hasSOCKS) {
|
||||
// for GNOME:
|
||||
{
|
||||
actions << ProcessArgument{"gsettings", {"set", "org.gnome.system.proxy.socks", "host", address}};
|
||||
actions << ProcessArgument{"gsettings",
|
||||
{"set", "org.gnome.system.proxy.socks", "port", QSTRN(socksPort)}};
|
||||
|
||||
// for KDE:
|
||||
if (isKDE) {
|
||||
actions << ProcessArgument{"kwriteconfig5",
|
||||
{"--file", configPath + "/kioslaverc", //
|
||||
"--group", "Proxy Settings", //
|
||||
"--key", "socksProxy", //
|
||||
"socks://" + address + " " + QSTRN(socksPort)}};
|
||||
}
|
||||
}
|
||||
}
|
||||
// Setting Proxy Mode to Manual
|
||||
{
|
||||
// for GNOME:
|
||||
{
|
||||
actions << ProcessArgument{"gsettings", {"set", "org.gnome.system.proxy", "mode", "manual"}};
|
||||
}
|
||||
|
||||
// for KDE:
|
||||
if (isKDE) {
|
||||
actions << ProcessArgument{"kwriteconfig5",
|
||||
{"--file", configPath + "/kioslaverc", //
|
||||
"--group", "Proxy Settings", //
|
||||
"--key", "ProxyType", "1"}};
|
||||
}
|
||||
}
|
||||
|
||||
// Notify kioslaves to reload system proxy configuration.
|
||||
if (isKDE) {
|
||||
actions << ProcessArgument{"dbus-send",
|
||||
{"--type=signal", "/KIO/Scheduler", //
|
||||
"org.kde.KIO.Scheduler.reparseSlaveConfiguration", //
|
||||
"string:''"}};
|
||||
}
|
||||
// Execute them all!
|
||||
//
|
||||
// note: do not use std::all_of / any_of / none_of,
|
||||
// because those are short-circuit and cannot guarantee atomicity.
|
||||
QList<bool> results;
|
||||
for (const auto &action: actions) {
|
||||
// execute and get the code
|
||||
const auto returnCode = QProcess::execute(action.first, action.second);
|
||||
// print out the commands and result codes
|
||||
DEBUG(QString("[%1] Program: %2, Args: %3").arg(returnCode).arg(action.first).arg(action.second.join(";")));
|
||||
// give the code back
|
||||
results << (returnCode == QProcess::NormalExit);
|
||||
}
|
||||
|
||||
if (results.count(true) != actions.size()) {
|
||||
LOG("Something wrong when setting proxies.");
|
||||
}
|
||||
#else
|
||||
|
||||
for (const auto &service: macOSgetNetworkServices()) {
|
||||
LOG("Setting proxy for interface: " + service);
|
||||
if (hasHTTP) {
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setwebproxystate", service, "on"});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setsecurewebproxystate", service, "on"});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setwebproxy", service, address, QSTRN(httpPort)});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setsecurewebproxy", service, address, QSTRN(httpPort)});
|
||||
}
|
||||
|
||||
if (hasSOCKS) {
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setsocksfirewallproxystate", service, "on"});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setsocksfirewallproxy", service, address, QSTRN(socksPort)});
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClearSystemProxy() {
|
||||
LOG("Clearing System Proxy");
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (!__SetProxyOptions(nullptr, false)) {
|
||||
LOG("Failed to clear proxy.");
|
||||
}
|
||||
#elif defined(Q_OS_LINUX)
|
||||
QList<ProcessArgument> actions;
|
||||
const bool isKDE = qEnvironmentVariable("XDG_SESSION_DESKTOP") == "KDE" ||
|
||||
qEnvironmentVariable("XDG_SESSION_DESKTOP") == "plasma";
|
||||
const auto configRoot = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
|
||||
|
||||
// Setting System Proxy Mode to: None
|
||||
{
|
||||
// for GNOME:
|
||||
{
|
||||
actions << ProcessArgument{"gsettings", {"set", "org.gnome.system.proxy", "mode", "none"}};
|
||||
}
|
||||
|
||||
// for KDE:
|
||||
if (isKDE) {
|
||||
actions << ProcessArgument{"kwriteconfig5",
|
||||
{"--file", configRoot + "/kioslaverc", //
|
||||
"--group", "Proxy Settings", //
|
||||
"--key", "ProxyType", "0"}};
|
||||
}
|
||||
}
|
||||
|
||||
// Notify kioslaves to reload system proxy configuration.
|
||||
if (isKDE) {
|
||||
actions << ProcessArgument{"dbus-send",
|
||||
{"--type=signal", "/KIO/Scheduler", //
|
||||
"org.kde.KIO.Scheduler.reparseSlaveConfiguration", //
|
||||
"string:''"}};
|
||||
}
|
||||
|
||||
// Execute the Actions
|
||||
for (const auto &action: actions) {
|
||||
// execute and get the code
|
||||
const auto returnCode = QProcess::execute(action.first, action.second);
|
||||
// print out the commands and result codes
|
||||
DEBUG(QString("[%1] Program: %2, Args: %3").arg(returnCode).arg(action.first).arg(action.second.join(";")));
|
||||
}
|
||||
|
||||
#else
|
||||
for (const auto &service: macOSgetNetworkServices()) {
|
||||
LOG("Clearing proxy for interface: " + service);
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setautoproxystate", service, "off"});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setwebproxystate", service, "off"});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setsecurewebproxystate", service, "off"});
|
||||
QProcess::execute("/usr/sbin/networksetup", {"-setsocksfirewallproxystate", service, "off"});
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
} // namespace Qv2ray::components::proxy
|
||||
12
3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp
vendored
Normal file
12
3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <QHostAddress>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
//
|
||||
namespace Qv2ray::components::proxy {
|
||||
void ClearSystemProxy();
|
||||
void SetSystemProxy(int http_port, int socks_port);
|
||||
} // namespace Qv2ray::components::proxy
|
||||
|
||||
using namespace Qv2ray::components;
|
||||
using namespace Qv2ray::components::proxy;
|
||||
@ -88,6 +88,7 @@ set(PROJECT_SOURCES
|
||||
3rdparty/qv2ray/v2/ui/widgets/editors/w_JsonEditor.cpp
|
||||
3rdparty/qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp
|
||||
3rdparty/qv2ray/v2/ui/widgets/editors/w_JsonEditor.ui
|
||||
3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.cpp
|
||||
|
||||
rpc/gRPC.cpp
|
||||
|
||||
|
||||
@ -417,7 +417,7 @@ namespace NekoGui {
|
||||
admin = Windows_IsInAdmin();
|
||||
#else
|
||||
#ifdef Q_OS_LINUX
|
||||
admin |= Linux_GetCapString(FindNekorayRealPath()).contains("cap_sys_admin");
|
||||
admin |= Linux_GetCapString(FindNekoBoxCoreRealPath()).contains("cap_sys_admin");
|
||||
#endif
|
||||
admin |= geteuid() == 0;
|
||||
#endif
|
||||
|
||||
@ -714,7 +714,7 @@ bool MainWindow::get_elevated_permissions() {
|
||||
}
|
||||
auto n = QMessageBox::warning(GetMessageBoxParent(), software_name, tr("Please run Nekoray as admin"), QMessageBox::Yes | QMessageBox::No);
|
||||
if (n == QMessageBox::Yes) {
|
||||
auto ret = Linux_Pkexec_SetCapString(NekoGui::FindNekorayRealPath(), "cap_sys_admin=ep");
|
||||
auto ret = Linux_Pkexec_SetCapString(NekoGui::FindNekoBoxCoreRealPath(), "cap_sys_admin=ep");
|
||||
if (ret == 0) {
|
||||
this->exit_reason = 3;
|
||||
on_menu_exit_triggered();
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
#include "db/traffic/TrafficLooper.hpp"
|
||||
#include "rpc/gRPC.h"
|
||||
#include "ui/widget/MessageBoxTimer.h"
|
||||
#include "3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QInputDialog>
|
||||
#include <QPushButton>
|
||||
#include <QDesktopServices>
|
||||
@ -343,6 +343,7 @@ void MainWindow::neko_start(int _id) {
|
||||
|
||||
void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||
if (enable != NekoGui::dataStore->spmode_system_proxy) {
|
||||
#ifndef Q_OS_LINUX
|
||||
bool ok;
|
||||
auto error = defaultClient->SetSystemProxy(&ok, enable);
|
||||
if (!ok) {
|
||||
@ -351,6 +352,14 @@ void MainWindow::neko_set_spmode_system_proxy(bool enable, bool save) {
|
||||
refresh_status();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (enable) {
|
||||
auto socks_port = NekoGui::dataStore->inbound_socks_port;
|
||||
SetSystemProxy(socks_port, socks_port);
|
||||
} else {
|
||||
ClearSystemProxy();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (save) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user