mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 20:44:38 +03:00
refactor vpn settings
fix: nekoray_core freedom udp loopback feat: copy custom config
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -80,3 +80,4 @@ CMakeLists.txt.user*
|
|||||||
|
|
||||||
# Deploy
|
# Deploy
|
||||||
/deployment
|
/deployment
|
||||||
|
/neko*.sh
|
||||||
|
|||||||
@@ -181,6 +181,10 @@ set(PROJECT_SOURCES
|
|||||||
ui/dialog_manage_routes.h
|
ui/dialog_manage_routes.h
|
||||||
ui/dialog_manage_routes.ui
|
ui/dialog_manage_routes.ui
|
||||||
|
|
||||||
|
ui/dialog_vpn_settings.cpp
|
||||||
|
ui/dialog_vpn_settings.h
|
||||||
|
ui/dialog_vpn_settings.ui
|
||||||
|
|
||||||
ui/dialog_hotkey.cpp
|
ui/dialog_hotkey.cpp
|
||||||
ui/dialog_hotkey.h
|
ui/dialog_hotkey.h
|
||||||
ui/dialog_hotkey.ui
|
ui/dialog_hotkey.ui
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#include "db/ConfigBuilder.hpp"
|
#include "db/ConfigBuilder.hpp"
|
||||||
#include "db/Database.hpp"
|
#include "db/Database.hpp"
|
||||||
#include "fmt/includes.h"
|
#include "fmt/includes.h"
|
||||||
|
#include "fmt/Preset.hpp"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
namespace NekoRay {
|
namespace NekoRay {
|
||||||
|
|
||||||
@@ -694,7 +696,7 @@ namespace NekoRay {
|
|||||||
{"outbound", "dns-out"}};
|
{"outbound", "dns-out"}};
|
||||||
|
|
||||||
// geopath
|
// geopath
|
||||||
auto geopath = NekoRay::dataStore->v2ray_asset_dir;
|
auto geopath = dataStore->v2ray_asset_dir;
|
||||||
if (geopath.isEmpty()) geopath = QApplication::applicationDirPath();
|
if (geopath.isEmpty()) geopath = QApplication::applicationDirPath();
|
||||||
auto geoip = geopath + "/geoip.db";
|
auto geoip = geopath + "/geoip.db";
|
||||||
auto geosite = geopath + "/geosite.db";
|
auto geosite = geopath + "/geosite.db";
|
||||||
@@ -714,4 +716,58 @@ namespace NekoRay {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString WriteVPNSingBoxConfig() {
|
||||||
|
//
|
||||||
|
QString process_name_rule = dataStore->vpn_bypass_process.trimmed();
|
||||||
|
if (!process_name_rule.isEmpty()) {
|
||||||
|
auto arr = SplitLines(process_name_rule);
|
||||||
|
QJsonObject rule{{"outbound", "direct"},
|
||||||
|
{"process_name", QList2QJsonArray(arr)}};
|
||||||
|
process_name_rule = "," + QJsonObject2QString(rule, false);
|
||||||
|
}
|
||||||
|
QString cidr_rule = dataStore->vpn_bypass_cidr.trimmed();
|
||||||
|
if (!cidr_rule.isEmpty()) {
|
||||||
|
auto arr = SplitLines(cidr_rule);
|
||||||
|
QJsonObject rule{{"outbound", "direct"},
|
||||||
|
{"ip_cidr", QList2QJsonArray(arr)}};
|
||||||
|
cidr_rule = "," + QJsonObject2QString(rule, false);
|
||||||
|
}
|
||||||
|
// gen config
|
||||||
|
auto configFn = ":/nekoray/vpn/sing-box-vpn.json";
|
||||||
|
if (QFile::exists("vpn/sing-box-vpn.json")) configFn = "vpn/sing-box-vpn.json";
|
||||||
|
auto config = ReadFileText(configFn)
|
||||||
|
.replace("%IPV6_ADDRESS%", dataStore->vpn_ipv6 ? R"("inet6_address": "fdfe:dcba:9876::1/126",)" : "")
|
||||||
|
.replace("%MTU%", Int2String(dataStore->vpn_mtu))
|
||||||
|
.replace("%STACK%", Preset::SingBox::VpnImplementation.value(dataStore->vpn_implementation))
|
||||||
|
.replace("%PROCESS_NAME_RULE%", process_name_rule)
|
||||||
|
.replace("%CIDR_RULE%", cidr_rule)
|
||||||
|
.replace("%PORT%", Int2String(dataStore->inbound_socks_port));
|
||||||
|
// write config
|
||||||
|
QFile file;
|
||||||
|
file.setFileName(QFileInfo(configFn).fileName());
|
||||||
|
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
||||||
|
file.write(config.toUtf8());
|
||||||
|
file.close();
|
||||||
|
return QFileInfo(file).absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WriteVPNLinuxScript(const QString &protectPath, const QString &configPath) {
|
||||||
|
// gen script
|
||||||
|
auto scriptFn = ":/nekoray/vpn/vpn-run-root.sh";
|
||||||
|
if (QFile::exists("vpn/vpn-run-root.sh")) scriptFn = "vpn/vpn-run-root.sh";
|
||||||
|
auto script = ReadFileText(scriptFn)
|
||||||
|
.replace("$PORT", Int2String(dataStore->inbound_socks_port))
|
||||||
|
.replace("./nekobox_core", QApplication::applicationDirPath() + "/nekobox_core")
|
||||||
|
.replace("$PROTECT_LISTEN_PATH", protectPath)
|
||||||
|
.replace("$CONFIG_PATH", configPath)
|
||||||
|
.replace("$TABLE_FWMARK", "514");
|
||||||
|
// write script
|
||||||
|
QFile file2;
|
||||||
|
file2.setFileName(QFileInfo(scriptFn).fileName());
|
||||||
|
file2.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
||||||
|
file2.write(script.toUtf8());
|
||||||
|
file2.close();
|
||||||
|
return QFileInfo(file2).absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -51,4 +51,8 @@ namespace NekoRay {
|
|||||||
|
|
||||||
QString BuildChainInternal(int chainId, const QList<QSharedPointer<ProxyEntity>> &ents,
|
QString BuildChainInternal(int chainId, const QList<QSharedPointer<ProxyEntity>> &ents,
|
||||||
const QSharedPointer<BuildConfigStatus> &status);
|
const QSharedPointer<BuildConfigStatus> &status);
|
||||||
|
|
||||||
|
QString WriteVPNSingBoxConfig();
|
||||||
|
|
||||||
|
QString WriteVPNLinuxScript(const QString &protectPath, const QString &configPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,14 @@
|
|||||||
{
|
{
|
||||||
"type": "block",
|
"type": "block",
|
||||||
"tag": "block"
|
"tag": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "direct",
|
||||||
|
"tag": "direct"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"route": {
|
"route": {
|
||||||
|
"auto_detect_interface": true,
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
{
|
||||||
"network": "udp",
|
"network": "udp",
|
||||||
@@ -36,7 +41,23 @@
|
|||||||
5353
|
5353
|
||||||
],
|
],
|
||||||
"outbound": "block"
|
"outbound": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ip_cidr": [
|
||||||
|
"224.0.0.0/4",
|
||||||
|
"ff00::/8"
|
||||||
|
],
|
||||||
|
"outbound": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source_ip_cidr": [
|
||||||
|
"224.0.0.0/4",
|
||||||
|
"ff00::/8"
|
||||||
|
],
|
||||||
|
"outbound": "block"
|
||||||
}
|
}
|
||||||
|
%PROCESS_NAME_RULE%
|
||||||
|
%CIDR_RULE%
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@ namespace NekoRay::fmt {
|
|||||||
QStringList env;
|
QStringList env;
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
QString error;
|
QString error;
|
||||||
|
QString config_export;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbstractBean : public JsonStore {
|
class AbstractBean : public JsonStore {
|
||||||
@@ -38,6 +39,8 @@ namespace NekoRay::fmt {
|
|||||||
|
|
||||||
[[nodiscard]] virtual QString DisplayName();
|
[[nodiscard]] virtual QString DisplayName();
|
||||||
|
|
||||||
|
virtual QString DisplayCoreType() { return software_core_name; };
|
||||||
|
|
||||||
virtual QString DisplayType() { return {}; };
|
virtual QString DisplayType() { return {}; };
|
||||||
|
|
||||||
virtual QString DisplayTypeAndName();
|
virtual QString DisplayTypeAndName();
|
||||||
|
|||||||
@@ -26,14 +26,17 @@ namespace NekoRay::fmt {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto _serverAddress = sni.isEmpty() ? serverAddress : sni;
|
auto is_export = mapping_port == 114514;
|
||||||
|
auto domain_address = sni.isEmpty() ? serverAddress : sni;
|
||||||
|
auto connect_address = is_export ? serverAddress : "127.0.0.1";
|
||||||
|
auto connect_port = is_export ? serverPort : mapping_port;
|
||||||
|
|
||||||
result.arguments += "--log";
|
result.arguments += "--log";
|
||||||
result.arguments += "--listen=socks://127.0.0.1:" + Int2String(socks_port);
|
result.arguments += "--listen=socks://127.0.0.1:" + Int2String(socks_port);
|
||||||
result.arguments += "--proxy=" + protocol + "://" +
|
result.arguments += "--proxy=" + protocol + "://" + username + ":" + password + "@" +
|
||||||
username + ":" + password + "@" +
|
domain_address + ":" + Int2String(connect_port);
|
||||||
_serverAddress + ":" + Int2String(mapping_port);
|
if (domain_address != connect_address)
|
||||||
result.arguments += "--host-resolver-rules=MAP " + _serverAddress + " 127.0.0.1";
|
result.arguments += "--host-resolver-rules=MAP " + domain_address + " " + connect_address;
|
||||||
if (insecure_concurrency > 0) result.arguments += "--insecure-concurrency=" + Int2String(insecure_concurrency);
|
if (insecure_concurrency > 0) result.arguments += "--insecure-concurrency=" + Int2String(insecure_concurrency);
|
||||||
if (!extra_headers.isEmpty()) result.arguments += "--extra-headers=" + extra_headers;
|
if (!extra_headers.isEmpty()) result.arguments += "--extra-headers=" + extra_headers;
|
||||||
if (!certificate.isEmpty()) {
|
if (!certificate.isEmpty()) {
|
||||||
@@ -41,6 +44,10 @@ namespace NekoRay::fmt {
|
|||||||
result.env += "SSL_CERT_FILE=" + TempFile;
|
result.env += "SSL_CERT_FILE=" + TempFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto config_export = QStringList{result.program};
|
||||||
|
config_export += result.arguments;
|
||||||
|
result.config_export = QStringList2Command(config_export);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +81,8 @@ namespace NekoRay::fmt {
|
|||||||
for (int i = 0; i < result.arguments.count(); i++) {
|
for (int i = 0; i < result.arguments.count(); i++) {
|
||||||
result.arguments[i] = result.arguments[i].replace("%config%", TempFile);
|
result.arguments[i] = result.arguments[i].replace("%config%", TempFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.config_export = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ namespace NekoRay::fmt {
|
|||||||
|
|
||||||
QString DisplayType() override { return core; };
|
QString DisplayType() override { return core; };
|
||||||
|
|
||||||
|
QString DisplayCoreType() override { return NeedExternal() ? core : software_core_name; };
|
||||||
|
|
||||||
bool NeedExternal() override {
|
bool NeedExternal() override {
|
||||||
if (IS_NEKO_BOX && core == "hysteria") return false;
|
if (IS_NEKO_BOX && core == "hysteria") return false;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ namespace NekoRay::fmt {
|
|||||||
_add(new configItem("insecure_concurrency", &insecure_concurrency, itemType::integer));
|
_add(new configItem("insecure_concurrency", &insecure_concurrency, itemType::integer));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QString DisplayCoreType() override { return "Naive"; };
|
||||||
|
|
||||||
QString DisplayType() override { return "Naive"; };
|
QString DisplayType() override { return "Naive"; };
|
||||||
|
|
||||||
bool NeedExternal() override { return true; };
|
bool NeedExternal() override { return true; };
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func updateRoutes() {
|
|||||||
|
|
||||||
func getBindInterfaceIndex(address string) uint32 {
|
func getBindInterfaceIndex(address string) uint32 {
|
||||||
host, _, _ := net.SplitHostPort(address)
|
host, _, _ := net.SplitHostPort(address)
|
||||||
if !net.ParseIP(host).IsGlobalUnicast() {
|
if net.ParseIP(host).IsLoopback() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ inline QMenu *CreateMenu(QWidget *parent, const QList<QString> &texts, const std
|
|||||||
#define P_SAVE_STRING_QTEXTEDIT(a) bean->a = ui->a->toPlainText();
|
#define P_SAVE_STRING_QTEXTEDIT(a) bean->a = ui->a->toPlainText();
|
||||||
#define D_LOAD_STRING(a) ui->a->setText(NekoRay::dataStore->a);
|
#define D_LOAD_STRING(a) ui->a->setText(NekoRay::dataStore->a);
|
||||||
#define D_SAVE_STRING(a) NekoRay::dataStore->a = ui->a->text();
|
#define D_SAVE_STRING(a) NekoRay::dataStore->a = ui->a->text();
|
||||||
|
#define D_SAVE_STRING_QTEXTEDIT(a) NekoRay::dataStore->a = ui->a->toPlainText();
|
||||||
#define P_C_LOAD_STRING(a) CACHE.a = bean->a;
|
#define P_C_LOAD_STRING(a) CACHE.a = bean->a;
|
||||||
#define P_C_SAVE_STRING(a) bean->a = CACHE.a;
|
#define P_C_SAVE_STRING(a) bean->a = CACHE.a;
|
||||||
#define D_C_LOAD_STRING(a) CACHE.a = NekoRay::dataStore->a;
|
#define D_C_LOAD_STRING(a) CACHE.a = NekoRay::dataStore->a;
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ namespace NekoRay {
|
|||||||
_add(new configItem("vpn_mtu", &vpn_mtu, itemType::integer));
|
_add(new configItem("vpn_mtu", &vpn_mtu, itemType::integer));
|
||||||
_add(new configItem("vpn_ipv6", &vpn_ipv6, itemType::boolean));
|
_add(new configItem("vpn_ipv6", &vpn_ipv6, itemType::boolean));
|
||||||
_add(new configItem("vpn_hide_console", &vpn_hide_consloe, itemType::boolean));
|
_add(new configItem("vpn_hide_console", &vpn_hide_consloe, itemType::boolean));
|
||||||
|
_add(new configItem("vpn_bypass_process", &vpn_bypass_process, itemType::string));
|
||||||
|
_add(new configItem("vpn_bypass_cidr", &vpn_bypass_cidr, itemType::string));
|
||||||
_add(new configItem("check_include_pre", &check_include_pre, itemType::boolean));
|
_add(new configItem("check_include_pre", &check_include_pre, itemType::boolean));
|
||||||
_add(new configItem("neko_core", &neko_core, itemType::integer));
|
_add(new configItem("neko_core", &neko_core, itemType::integer));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ namespace NekoRay {
|
|||||||
int vpn_mtu = 9000;
|
int vpn_mtu = 9000;
|
||||||
bool vpn_ipv6 = false;
|
bool vpn_ipv6 = false;
|
||||||
bool vpn_hide_consloe = false;
|
bool vpn_hide_consloe = false;
|
||||||
|
QString vpn_bypass_process = "";
|
||||||
|
QString vpn_bypass_cidr = "";
|
||||||
|
|
||||||
// Hotkey
|
// Hotkey
|
||||||
QString hotkey_mainwindow = "";
|
QString hotkey_mainwindow = "";
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ inline QString SubStrAfter(QString str, const QString &sub) {
|
|||||||
return str.right(str.length() - str.indexOf(sub) - sub.length());
|
return str.right(str.length() - str.indexOf(sub) - sub.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QString QStringList2Command(const QStringList &list) {
|
||||||
|
QStringList new_list;
|
||||||
|
for (auto str: list) {
|
||||||
|
auto q = "\"" + str.replace("\"", "\\\"") + "\"";
|
||||||
|
new_list << q;
|
||||||
|
}
|
||||||
|
return new_list.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
inline QString
|
inline QString
|
||||||
DecodeB64IfValid(const QString &input, QByteArray::Base64Option options = QByteArray::Base64Option::Base64Encoding) {
|
DecodeB64IfValid(const QString &input, QByteArray::Base64Option options = QByteArray::Base64Option::Base64Encoding) {
|
||||||
auto result = QByteArray::fromBase64Encoding(input.toUtf8(),
|
auto result = QByteArray::fromBase64Encoding(input.toUtf8(),
|
||||||
|
|||||||
@@ -486,17 +486,32 @@
|
|||||||
<source>Custom (global)</source>
|
<source>Custom (global)</source>
|
||||||
<translation>自定义 (全局)</translation>
|
<translation>自定义 (全局)</translation>
|
||||||
</message>
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>DialogVPNSettings</name>
|
||||||
|
<message>
|
||||||
|
<source>VPN Settings</source>
|
||||||
|
<translation>VPN 设置</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>VPN Implementation</source>
|
<source>VPN Implementation</source>
|
||||||
<translation>VPN 实现</translation>
|
<translation>VPN 实现</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Hide Console</source>
|
||||||
|
<translation>隐藏控制台</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>VPN Enable IPv6</source>
|
<source>VPN Enable IPv6</source>
|
||||||
<translation>启用 VPN IPv6</translation>
|
<translation>启用 VPN IPv6</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Hide Console</source>
|
<source>Bypass CIDR</source>
|
||||||
<translation>隐藏控制台</translation>
|
<translation>绕过 CIDR</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Bypass Process Name</source>
|
||||||
|
<translation>绕过进程名</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -819,10 +834,6 @@
|
|||||||
<source>Stop</source>
|
<source>Stop</source>
|
||||||
<translation>停止</translation>
|
<translation>停止</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Routing VPN Settings</source>
|
|
||||||
<translation>路由 VPN 设置</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Add profile from clipboard</source>
|
<source>Add profile from clipboard</source>
|
||||||
<translation>从剪切板添加</translation>
|
<translation>从剪切板添加</translation>
|
||||||
@@ -1029,10 +1040,6 @@ End: %2</source>
|
|||||||
<source>QR Code and link</source>
|
<source>QR Code and link</source>
|
||||||
<translation>显示 QR Code 和分享链接</translation>
|
<translation>显示 QR Code 和分享链接</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Export V2ray config</source>
|
|
||||||
<translation type="vanished">导出 V2ray 配置</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Active Routing</source>
|
<source>Active Routing</source>
|
||||||
<translation>当前路由规则</translation>
|
<translation>当前路由规则</translation>
|
||||||
@@ -1141,6 +1148,14 @@ End: %2</source>
|
|||||||
<source>Export %1 config</source>
|
<source>Export %1 config</source>
|
||||||
<translation>导出 %1 配置</translation>
|
<translation>导出 %1 配置</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Routing Settings</source>
|
||||||
|
<translation>路由设置</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>VPN Settings</source>
|
||||||
|
<translation>VPN 设置</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ProxyItem</name>
|
<name>ProxyItem</name>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp"
|
#include "qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp"
|
||||||
#include "qv2ray/v3/components/GeositeReader/GeositeReader.hpp"
|
#include "qv2ray/v3/components/GeositeReader/GeositeReader.hpp"
|
||||||
#include "fmt/Preset.hpp"
|
|
||||||
#include "main/GuiUtils.hpp"
|
#include "main/GuiUtils.hpp"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@@ -31,11 +30,9 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) :
|
|||||||
title_base = windowTitle();
|
title_base = windowTitle();
|
||||||
|
|
||||||
if (IS_NEKO_BOX) {
|
if (IS_NEKO_BOX) {
|
||||||
ui->fake_dns->setVisible(false);
|
|
||||||
ui->enhance_resolve_server_domain->setVisible(false);
|
ui->enhance_resolve_server_domain->setVisible(false);
|
||||||
ui->domain_v2ray->setVisible(false);
|
ui->domain_v2ray->setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
ui->fake_dns->setVisible(true);
|
|
||||||
ui->enhance_resolve_server_domain->setVisible(true);
|
ui->enhance_resolve_server_domain->setVisible(true);
|
||||||
ui->domain_v2ray->setVisible(true);
|
ui->domain_v2ray->setVisible(true);
|
||||||
}
|
}
|
||||||
@@ -44,20 +41,11 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) :
|
|||||||
ui->outbound_domain_strategy->setCurrentText(NekoRay::dataStore->outbound_domain_strategy);
|
ui->outbound_domain_strategy->setCurrentText(NekoRay::dataStore->outbound_domain_strategy);
|
||||||
ui->domainMatcherCombo->setCurrentIndex(NekoRay::dataStore->domain_matcher);
|
ui->domainMatcherCombo->setCurrentIndex(NekoRay::dataStore->domain_matcher);
|
||||||
ui->domainStrategyCombo->setCurrentText(NekoRay::dataStore->domain_strategy);
|
ui->domainStrategyCombo->setCurrentText(NekoRay::dataStore->domain_strategy);
|
||||||
ui->fake_dns->setChecked(NekoRay::dataStore->fake_dns);
|
|
||||||
ui->dns_routing->setChecked(NekoRay::dataStore->dns_routing);
|
ui->dns_routing->setChecked(NekoRay::dataStore->dns_routing);
|
||||||
ui->dns_remote->setText(NekoRay::dataStore->remote_dns);
|
ui->dns_remote->setText(NekoRay::dataStore->remote_dns);
|
||||||
ui->dns_direct->setText(NekoRay::dataStore->direct_dns);
|
ui->dns_direct->setText(NekoRay::dataStore->direct_dns);
|
||||||
ui->enhance_resolve_server_domain->setChecked(NekoRay::dataStore->enhance_resolve_server_domain);
|
ui->enhance_resolve_server_domain->setChecked(NekoRay::dataStore->enhance_resolve_server_domain);
|
||||||
D_C_LOAD_STRING(custom_route_global)
|
D_C_LOAD_STRING(custom_route_global)
|
||||||
//
|
|
||||||
ui->vpn_implementation->setCurrentIndex(NekoRay::dataStore->vpn_implementation);
|
|
||||||
ui->vpn_mtu->setCurrentText(Int2String(NekoRay::dataStore->vpn_mtu));
|
|
||||||
ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6);
|
|
||||||
ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_consloe);
|
|
||||||
#ifndef Q_OS_WIN
|
|
||||||
ui->hide_console->setVisible(false);
|
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
connect(ui->custom_route_edit, &QPushButton::clicked, this, [=] {
|
connect(ui->custom_route_edit, &QPushButton::clicked, this, [=] {
|
||||||
C_EDIT_JSON_ALLOW_EMPTY(custom_route)
|
C_EDIT_JSON_ALLOW_EMPTY(custom_route)
|
||||||
@@ -113,25 +101,6 @@ void DialogManageRoutes::accept() {
|
|||||||
NekoRay::dataStore->direct_dns = ui->dns_direct->text();
|
NekoRay::dataStore->direct_dns = ui->dns_direct->text();
|
||||||
NekoRay::dataStore->enhance_resolve_server_domain = ui->enhance_resolve_server_domain->isChecked();
|
NekoRay::dataStore->enhance_resolve_server_domain = ui->enhance_resolve_server_domain->isChecked();
|
||||||
D_C_SAVE_STRING(custom_route_global)
|
D_C_SAVE_STRING(custom_route_global)
|
||||||
//
|
|
||||||
bool vpnChanged = false;
|
|
||||||
auto fakedns = ui->fake_dns->isChecked();
|
|
||||||
auto mtu = ui->vpn_mtu->currentText().toInt();
|
|
||||||
if (mtu > 10000 || mtu < 1000) mtu = 9000;
|
|
||||||
auto ipv6 = ui->vpn_ipv6->isChecked();
|
|
||||||
//
|
|
||||||
auto impl = ui->vpn_implementation->currentIndex();
|
|
||||||
vpnChanged |= NekoRay::dataStore->vpn_implementation != impl;
|
|
||||||
NekoRay::dataStore->vpn_implementation = impl;
|
|
||||||
//
|
|
||||||
vpnChanged |= NekoRay::dataStore->fake_dns != fakedns;
|
|
||||||
vpnChanged |= NekoRay::dataStore->vpn_mtu != mtu;
|
|
||||||
vpnChanged |= NekoRay::dataStore->vpn_ipv6 != ipv6;
|
|
||||||
NekoRay::dataStore->fake_dns = fakedns;
|
|
||||||
NekoRay::dataStore->vpn_mtu = mtu;
|
|
||||||
NekoRay::dataStore->vpn_ipv6 = ipv6;
|
|
||||||
NekoRay::dataStore->vpn_hide_consloe = ui->hide_console->isChecked();
|
|
||||||
//
|
|
||||||
bool routeChanged = false;
|
bool routeChanged = false;
|
||||||
if (NekoRay::dataStore->active_routing != active_routing) routeChanged = true;
|
if (NekoRay::dataStore->active_routing != active_routing) routeChanged = true;
|
||||||
SAVE_TO_ROUTING(NekoRay::dataStore->routing)
|
SAVE_TO_ROUTING(NekoRay::dataStore->routing)
|
||||||
@@ -141,7 +110,6 @@ void DialogManageRoutes::accept() {
|
|||||||
//
|
//
|
||||||
QString info = "UpdateDataStore";
|
QString info = "UpdateDataStore";
|
||||||
if (routeChanged) info += "RouteChanged";
|
if (routeChanged) info += "RouteChanged";
|
||||||
if (vpnChanged) info += "VPNChanged";
|
|
||||||
dialog_message(Dialog_DialogManageRoutes, info);
|
dialog_message(Dialog_DialogManageRoutes, info);
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ private:
|
|||||||
QString custom_route_global;
|
QString custom_route_global;
|
||||||
} CACHE;
|
} CACHE;
|
||||||
|
|
||||||
|
|
||||||
QMenu *builtInSchemesMenu;
|
QMenu *builtInSchemesMenu;
|
||||||
Qv2ray::ui::widgets::AutoCompleteTextEdit *directDomainTxt;
|
Qv2ray::ui::widgets::AutoCompleteTextEdit *directDomainTxt;
|
||||||
Qv2ray::ui::widgets::AutoCompleteTextEdit *proxyDomainTxt;
|
Qv2ray::ui::widgets::AutoCompleteTextEdit *proxyDomainTxt;
|
||||||
@@ -41,6 +40,7 @@ private:
|
|||||||
//
|
//
|
||||||
QString title_base;
|
QString title_base;
|
||||||
QString active_routing;
|
QString active_routing;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void accept() override;
|
void accept() override;
|
||||||
|
|||||||
@@ -111,106 +111,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>VPN Implementation</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="vpn_implementation">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">gVisor</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">System</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_10">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">MTU</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="vpn_mtu">
|
|
||||||
<property name="editable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">9000</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">1500</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="hide_console">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Hide Console</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="vpn_ipv6">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>VPN Enable IPv6</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="fake_dns">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">FakeDNS</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
@@ -470,9 +370,6 @@
|
|||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>sniffing_mode</tabstop>
|
<tabstop>sniffing_mode</tabstop>
|
||||||
<tabstop>outbound_domain_strategy</tabstop>
|
<tabstop>outbound_domain_strategy</tabstop>
|
||||||
<tabstop>vpn_implementation</tabstop>
|
|
||||||
<tabstop>vpn_mtu</tabstop>
|
|
||||||
<tabstop>fake_dns</tabstop>
|
|
||||||
<tabstop>dns_remote</tabstop>
|
<tabstop>dns_remote</tabstop>
|
||||||
<tabstop>dns_direct</tabstop>
|
<tabstop>dns_direct</tabstop>
|
||||||
<tabstop>enhance_resolve_server_domain</tabstop>
|
<tabstop>enhance_resolve_server_domain</tabstop>
|
||||||
|
|||||||
45
ui/dialog_vpn_settings.cpp
Normal file
45
ui/dialog_vpn_settings.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include "dialog_vpn_settings.h"
|
||||||
|
#include "ui_dialog_vpn_settings.h"
|
||||||
|
|
||||||
|
#include "main/GuiUtils.hpp"
|
||||||
|
#include "main/NekoRay.hpp"
|
||||||
|
|
||||||
|
DialogVPNSettings::DialogVPNSettings(QWidget *parent) :
|
||||||
|
QDialog(parent), ui(new Ui::DialogVPNSettings) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->fake_dns->setVisible(!IS_NEKO_BOX);
|
||||||
|
ui->fake_dns->setChecked(NekoRay::dataStore->fake_dns);
|
||||||
|
//
|
||||||
|
ui->vpn_implementation->setCurrentIndex(NekoRay::dataStore->vpn_implementation);
|
||||||
|
ui->vpn_mtu->setCurrentText(Int2String(NekoRay::dataStore->vpn_mtu));
|
||||||
|
ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6);
|
||||||
|
ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_consloe);
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
ui->hide_console->setVisible(false);
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
D_LOAD_STRING(vpn_bypass_cidr)
|
||||||
|
D_LOAD_STRING(vpn_bypass_process)
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogVPNSettings::~DialogVPNSettings() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogVPNSettings::accept() {
|
||||||
|
//
|
||||||
|
auto mtu = ui->vpn_mtu->currentText().toInt();
|
||||||
|
if (mtu > 10000 || mtu < 1000) mtu = 9000;
|
||||||
|
NekoRay::dataStore->vpn_implementation = ui->vpn_implementation->currentIndex();
|
||||||
|
NekoRay::dataStore->fake_dns = ui->fake_dns->isChecked();
|
||||||
|
NekoRay::dataStore->vpn_mtu = mtu;
|
||||||
|
NekoRay::dataStore->vpn_ipv6 = ui->vpn_ipv6->isChecked();
|
||||||
|
NekoRay::dataStore->vpn_hide_consloe = ui->hide_console->isChecked();
|
||||||
|
//
|
||||||
|
D_SAVE_STRING_QTEXTEDIT(vpn_bypass_cidr)
|
||||||
|
D_SAVE_STRING_QTEXTEDIT(vpn_bypass_process)
|
||||||
|
//
|
||||||
|
dialog_message("", "UpdateDataStore,VPNChanged");
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
29
ui/dialog_vpn_settings.h
Normal file
29
ui/dialog_vpn_settings.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef NEKORAY_DIALOG_VPN_SETTINGS_H
|
||||||
|
#define NEKORAY_DIALOG_VPN_SETTINGS_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui { class DialogVPNSettings; }
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class DialogVPNSettings : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DialogVPNSettings(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
~DialogVPNSettings() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::DialogVPNSettings *ui;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void accept() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //NEKORAY_DIALOG_VPN_SETTINGS_H
|
||||||
194
ui/dialog_vpn_settings.ui
Normal file
194
ui/dialog_vpn_settings.ui
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DialogVPNSettings</class>
|
||||||
|
<widget class="QDialog" name="DialogVPNSettings">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>600</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>VPN Settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>VPN Implementation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="vpn_implementation">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">gVisor</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">System</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">MTU</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="vpn_mtu">
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">9000</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">1500</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="horizontalGroupBox_2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="hide_console">
|
||||||
|
<property name="text">
|
||||||
|
<string>Hide Console</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="vpn_ipv6">
|
||||||
|
<property name="text">
|
||||||
|
<string>VPN Enable IPv6</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="fake_dns">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">FakeDNS</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="verticalGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Bypass CIDR</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="vpn_bypass_cidr"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="verticalGroupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Bypass Process Name</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="vpn_bypass_process"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>vpn_implementation</tabstop>
|
||||||
|
<tabstop>vpn_mtu</tabstop>
|
||||||
|
<tabstop>hide_console</tabstop>
|
||||||
|
<tabstop>vpn_ipv6</tabstop>
|
||||||
|
<tabstop>fake_dns</tabstop>
|
||||||
|
<tabstop>vpn_bypass_cidr</tabstop>
|
||||||
|
<tabstop>vpn_bypass_process</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>DialogVPNSettings</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>575</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>DialogVPNSettings</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>575</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "./ui_mainwindow.h"
|
#include "./ui_mainwindow.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include "fmt/Preset.hpp"
|
|
||||||
#include "db/ProfileFilter.hpp"
|
#include "db/ProfileFilter.hpp"
|
||||||
#include "db/ConfigBuilder.hpp"
|
#include "db/ConfigBuilder.hpp"
|
||||||
#include "sub/GroupUpdater.hpp"
|
#include "sub/GroupUpdater.hpp"
|
||||||
@@ -14,6 +13,7 @@
|
|||||||
#include "ui/dialog_basic_settings.h"
|
#include "ui/dialog_basic_settings.h"
|
||||||
#include "ui/dialog_manage_groups.h"
|
#include "ui/dialog_manage_groups.h"
|
||||||
#include "ui/dialog_manage_routes.h"
|
#include "ui/dialog_manage_routes.h"
|
||||||
|
#include "ui/dialog_vpn_settings.h"
|
||||||
#include "ui/dialog_hotkey.h"
|
#include "ui/dialog_hotkey.h"
|
||||||
|
|
||||||
#include "3rdparty/qrcodegen.hpp"
|
#include "3rdparty/qrcodegen.hpp"
|
||||||
@@ -97,7 +97,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
if (IS_NEKO_BOX) {
|
if (IS_NEKO_BOX) {
|
||||||
software_name = "NekoBox";
|
software_name = "NekoBox";
|
||||||
software_core_name = "sing-box";
|
software_core_name = "sing-box";
|
||||||
ui->menu_export_config->setText(ui->menu_export_config->text().arg(software_core_name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// top bar
|
// top bar
|
||||||
@@ -342,6 +341,16 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
connect(ui->menu_tcp_ping, &QAction::triggered, this, [=]() { speedtest_current_group(0); });
|
connect(ui->menu_tcp_ping, &QAction::triggered, this, [=]() { speedtest_current_group(0); });
|
||||||
connect(ui->menu_url_test, &QAction::triggered, this, [=]() { speedtest_current_group(1); });
|
connect(ui->menu_url_test, &QAction::triggered, this, [=]() { speedtest_current_group(1); });
|
||||||
connect(ui->menu_full_test, &QAction::triggered, this, [=]() { speedtest_current_group(2); });
|
connect(ui->menu_full_test, &QAction::triggered, this, [=]() { speedtest_current_group(2); });
|
||||||
|
//
|
||||||
|
connect(ui->menu_share_item, &QMenu::aboutToShow, this, [=] {
|
||||||
|
auto name = software_core_name;
|
||||||
|
auto selected = get_now_selected();
|
||||||
|
if (!selected.isEmpty()) {
|
||||||
|
auto ent = selected.first();
|
||||||
|
name = ent->bean->DisplayCoreType();
|
||||||
|
}
|
||||||
|
ui->menu_export_config->setText(tr("Export %1 config").arg(name));
|
||||||
|
});
|
||||||
refresh_status();
|
refresh_status();
|
||||||
|
|
||||||
// Prepare core
|
// Prepare core
|
||||||
@@ -499,6 +508,10 @@ void MainWindow::on_menu_routing_settings_triggered() {
|
|||||||
USE_DIALOG(DialogManageRoutes)
|
USE_DIALOG(DialogManageRoutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_menu_vpn_settings_triggered() {
|
||||||
|
USE_DIALOG(DialogVPNSettings)
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_menu_hotkey_settings_triggered() {
|
void MainWindow::on_menu_hotkey_settings_triggered() {
|
||||||
USE_DIALOG(DialogHotkey)
|
USE_DIALOG(DialogHotkey)
|
||||||
}
|
}
|
||||||
@@ -987,8 +1000,16 @@ void MainWindow::on_menu_export_config_triggered() {
|
|||||||
auto ents = get_now_selected();
|
auto ents = get_now_selected();
|
||||||
if (ents.count() != 1) return;
|
if (ents.count() != 1) return;
|
||||||
auto ent = ents.first();
|
auto ent = ents.first();
|
||||||
auto result = NekoRay::BuildConfig(ent, false);
|
QString config_core;
|
||||||
auto config_core = QJsonObject2QString(result->coreConfig, true);
|
|
||||||
|
if (ent->bean->NeedExternal()) {
|
||||||
|
auto result = ent->bean->BuildExternal(114514, MkPort());
|
||||||
|
config_core = result.config_export.replace("127.0.0.1:114514", ent->bean->DisplayAddress());
|
||||||
|
} else {
|
||||||
|
auto result = NekoRay::BuildConfig(ent, false);
|
||||||
|
config_core = QJsonObject2QString(result->coreConfig, true);
|
||||||
|
}
|
||||||
|
|
||||||
QApplication::clipboard()->setText(config_core);
|
QApplication::clipboard()->setText(config_core);
|
||||||
MessageBoxWarning(tr("Config copied"), config_core);
|
MessageBoxWarning(tr("Config copied"), config_core);
|
||||||
}
|
}
|
||||||
@@ -1406,39 +1427,10 @@ bool MainWindow::StartVPNProcess() {
|
|||||||
if (vpn_pid != 0) {
|
if (vpn_pid != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// gen config
|
//
|
||||||
auto configFn = ":/nekoray/vpn/sing-box-vpn.json";
|
|
||||||
if (QFile::exists("vpn/sing-box-vpn.json")) configFn = "vpn/sing-box-vpn.json";
|
|
||||||
auto config = ReadFileText(configFn)
|
|
||||||
.replace("%IPV6_ADDRESS%",
|
|
||||||
NekoRay::dataStore->vpn_ipv6 ? R"("inet6_address": "fdfe:dcba:9876::1/126",)" : "")
|
|
||||||
.replace("%MTU%", Int2String(NekoRay::dataStore->vpn_mtu))
|
|
||||||
.replace("%STACK%", Preset::SingBox::VpnImplementation.value(NekoRay::dataStore->vpn_implementation))
|
|
||||||
.replace("%PORT%", Int2String(NekoRay::dataStore->inbound_socks_port));
|
|
||||||
// write config
|
|
||||||
QFile file;
|
|
||||||
file.setFileName(QFileInfo(configFn).fileName());
|
|
||||||
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
|
||||||
file.write(config.toUtf8());
|
|
||||||
file.close();
|
|
||||||
auto configPath = QFileInfo(file).absoluteFilePath();
|
|
||||||
// gen script
|
|
||||||
auto protectPath = QDir::currentPath() + "/protect";
|
auto protectPath = QDir::currentPath() + "/protect";
|
||||||
auto scriptFn = ":/nekoray/vpn/vpn-run-root.sh";
|
auto configPath = NekoRay::WriteVPNSingBoxConfig();
|
||||||
if (QFile::exists("vpn/vpn-run-root.sh")) scriptFn = "vpn/vpn-run-root.sh";
|
auto scriptPath = NekoRay::WriteVPNLinuxScript(protectPath, configPath);
|
||||||
auto script = ReadFileText(scriptFn)
|
|
||||||
.replace("$PORT", Int2String(NekoRay::dataStore->inbound_socks_port))
|
|
||||||
.replace("./nekobox_core", QApplication::applicationDirPath() + "/nekobox_core")
|
|
||||||
.replace("$PROTECT_LISTEN_PATH", protectPath)
|
|
||||||
.replace("$CONFIG_PATH", configPath)
|
|
||||||
.replace("$TABLE_FWMARK", "514");
|
|
||||||
// write script
|
|
||||||
QFile file2;
|
|
||||||
file2.setFileName(QFileInfo(scriptFn).fileName());
|
|
||||||
file2.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
|
||||||
file2.write(script.toUtf8());
|
|
||||||
file2.close();
|
|
||||||
auto scriptPath = QFileInfo(file2).absoluteFilePath();
|
|
||||||
//
|
//
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
runOnNewThread([=] {
|
runOnNewThread([=] {
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ private slots:
|
|||||||
|
|
||||||
void on_menu_routing_settings_triggered();
|
void on_menu_routing_settings_triggered();
|
||||||
|
|
||||||
|
void on_menu_vpn_settings_triggered();
|
||||||
|
|
||||||
void on_menu_hotkey_settings_triggered();
|
void on_menu_hotkey_settings_triggered();
|
||||||
|
|
||||||
void on_menu_add_from_input_triggered();
|
void on_menu_add_from_input_triggered();
|
||||||
|
|||||||
@@ -498,6 +498,7 @@
|
|||||||
<addaction name="menu_manage_groups"/>
|
<addaction name="menu_manage_groups"/>
|
||||||
<addaction name="menu_basic_settings"/>
|
<addaction name="menu_basic_settings"/>
|
||||||
<addaction name="menu_routing_settings"/>
|
<addaction name="menu_routing_settings"/>
|
||||||
|
<addaction name="menu_vpn_settings"/>
|
||||||
<addaction name="menu_hotkey_settings"/>
|
<addaction name="menu_hotkey_settings"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menu_server">
|
<widget class="QMenu" name="menu_server">
|
||||||
@@ -590,7 +591,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="menu_routing_settings">
|
<action name="menu_routing_settings">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Routing VPN Settings</string>
|
<string>Routing Settings</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="menu_add_from_clipboard">
|
<action name="menu_add_from_clipboard">
|
||||||
@@ -822,6 +823,11 @@
|
|||||||
<string>Resolve domain</string>
|
<string>Resolve domain</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="menu_vpn_settings">
|
||||||
|
<property name="text">
|
||||||
|
<string>VPN Settings</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|||||||
Reference in New Issue
Block a user