mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2026-01-02 16:29:04 +08:00
remove naive and extra core support
This commit is contained in:
parent
bf8de2e9e9
commit
3688295d66
22
3rdparty/VT100Parser.hpp
vendored
22
3rdparty/VT100Parser.hpp
vendored
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
inline QString cleanVT100String(const QString &in) {
|
|
||||||
QString out;
|
|
||||||
bool in_033 = false;
|
|
||||||
for (auto &&chr: in) {
|
|
||||||
if (chr == '\033') {
|
|
||||||
in_033 = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (in_033) {
|
|
||||||
if (chr == 'm') {
|
|
||||||
in_033 = false;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
out += chr;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
11
3rdparty/fix_old_qt.h
vendored
11
3rdparty/fix_old_qt.h
vendored
@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
|
||||||
|
|
||||||
inline QString qEnvironmentVariable(const char *varName) {
|
|
||||||
return qgetenv(varName);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -100,7 +100,6 @@ set(PROJECT_SOURCES
|
|||||||
|
|
||||||
src/configs/proxy/AbstractBean.cpp
|
src/configs/proxy/AbstractBean.cpp
|
||||||
src/configs/proxy/Bean2CoreObj_box.cpp
|
src/configs/proxy/Bean2CoreObj_box.cpp
|
||||||
src/configs/proxy/Bean2External.cpp
|
|
||||||
src/configs/proxy/Bean2Link.cpp
|
src/configs/proxy/Bean2Link.cpp
|
||||||
src/configs/proxy/Link2Bean.cpp
|
src/configs/proxy/Link2Bean.cpp
|
||||||
include/configs/proxy/ChainBean.hpp # translate
|
include/configs/proxy/ChainBean.hpp # translate
|
||||||
@ -108,7 +107,8 @@ set(PROJECT_SOURCES
|
|||||||
include/configs/sub/GroupUpdater.hpp
|
include/configs/sub/GroupUpdater.hpp
|
||||||
src/configs/sub/GroupUpdater.cpp
|
src/configs/sub/GroupUpdater.cpp
|
||||||
|
|
||||||
src/sys/ExternalProcess.cpp
|
include/sys/Process.hpp
|
||||||
|
src/sys/Process.cpp
|
||||||
src/sys/AutoRun.cpp
|
src/sys/AutoRun.cpp
|
||||||
|
|
||||||
include/ui/setting/ThemeManager.hpp
|
include/ui/setting/ThemeManager.hpp
|
||||||
@ -143,10 +143,6 @@ set(PROJECT_SOURCES
|
|||||||
src/ui/profile/edit_trojan_vless.cpp
|
src/ui/profile/edit_trojan_vless.cpp
|
||||||
include/ui/profile/edit_trojan_vless.ui
|
include/ui/profile/edit_trojan_vless.ui
|
||||||
|
|
||||||
include/ui/profile/edit_naive.h
|
|
||||||
src/ui/profile/edit_naive.cpp
|
|
||||||
include/ui/profile/edit_naive.ui
|
|
||||||
|
|
||||||
include/ui/profile/edit_quic.h
|
include/ui/profile/edit_quic.h
|
||||||
src/ui/profile/edit_quic.cpp
|
src/ui/profile/edit_quic.cpp
|
||||||
include/ui/profile/edit_quic.ui
|
include/ui/profile/edit_quic.ui
|
||||||
@ -209,7 +205,7 @@ set(PROJECT_SOURCES
|
|||||||
src/sys/macos/MacOS.cpp
|
src/sys/macos/MacOS.cpp
|
||||||
|
|
||||||
src/sys/AutoRun.cpp
|
src/sys/AutoRun.cpp
|
||||||
src/sys/ExternalProcess.cpp
|
src/sys/Process.cpp
|
||||||
include/ui/mainwindow_interface.h
|
include/ui/mainwindow_interface.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#ifndef NKR_NO_GRPC
|
#ifndef NKR_NO_GRPC
|
||||||
|
|
||||||
#include "go/grpc_server/gen/libcore.pb.h"
|
#include "core/grpc_server/gen/libcore.pb.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace QtGrpc {
|
namespace QtGrpc {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "include/dataStore/ProxyEntity.hpp"
|
#include "include/dataStore/ProxyEntity.hpp"
|
||||||
#include "include/sys/ExternalProcess.hpp"
|
#include "include/sys/Process.hpp"
|
||||||
|
|
||||||
namespace NekoGui {
|
namespace NekoGui {
|
||||||
class BuildConfigResult {
|
class BuildConfigResult {
|
||||||
@ -12,8 +12,6 @@ namespace NekoGui {
|
|||||||
QList<std::shared_ptr<NekoGui_traffic::TrafficData>> outboundStats; // all, but not including "bypass" "block"
|
QList<std::shared_ptr<NekoGui_traffic::TrafficData>> outboundStats; // all, but not including "bypass" "block"
|
||||||
std::shared_ptr<NekoGui_traffic::TrafficData> outboundStat; // main
|
std::shared_ptr<NekoGui_traffic::TrafficData> outboundStat; // main
|
||||||
QStringList ignoreConnTag;
|
QStringList ignoreConnTag;
|
||||||
|
|
||||||
std::list<std::shared_ptr<NekoGui_fmt::ExternalBuildResult>> extRs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BuildTestConfigResult {
|
class BuildTestConfigResult {
|
||||||
|
|||||||
@ -12,18 +12,6 @@ namespace NekoGui_fmt {
|
|||||||
QString error;
|
QString error;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExternalBuildResult {
|
|
||||||
public:
|
|
||||||
QString program;
|
|
||||||
QStringList env;
|
|
||||||
QStringList arguments;
|
|
||||||
//
|
|
||||||
QString tag;
|
|
||||||
//
|
|
||||||
QString error;
|
|
||||||
QString config_export;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AbstractBean : public JsonStore {
|
class AbstractBean : public JsonStore {
|
||||||
public:
|
public:
|
||||||
int version;
|
int version;
|
||||||
@ -62,12 +50,8 @@ namespace NekoGui_fmt {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
virtual int NeedExternal(bool isFirstProfile) { return 0; };
|
|
||||||
|
|
||||||
virtual CoreObjOutboundBuildResult BuildCoreObjSingBox() { return {}; };
|
virtual CoreObjOutboundBuildResult BuildCoreObjSingBox() { return {}; };
|
||||||
|
|
||||||
virtual ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) { return {}; };
|
|
||||||
|
|
||||||
virtual QString ToShareLink() { return {}; };
|
virtual QString ToShareLink() { return {}; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@ namespace NekoGui_fmt {
|
|||||||
return core;
|
return core;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString DisplayCoreType() override { return NeedExternal(true) == 0 ? software_core_name : core; };
|
QString DisplayCoreType() override { return software_core_name; };
|
||||||
|
|
||||||
QString DisplayAddress() override {
|
QString DisplayAddress() override {
|
||||||
if (core == "internal") {
|
if (core == "internal") {
|
||||||
@ -43,10 +43,6 @@ namespace NekoGui_fmt {
|
|||||||
return AbstractBean::DisplayAddress();
|
return AbstractBean::DisplayAddress();
|
||||||
};
|
};
|
||||||
|
|
||||||
int NeedExternal(bool isFirstProfile) override;
|
|
||||||
|
|
||||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
};
|
};
|
||||||
} // namespace NekoGui_fmt
|
} // namespace NekoGui_fmt
|
||||||
@ -1,41 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "AbstractBean.hpp"
|
|
||||||
|
|
||||||
namespace NekoGui_fmt {
|
|
||||||
class NaiveBean : public AbstractBean {
|
|
||||||
public:
|
|
||||||
QString username = "";
|
|
||||||
QString password = "";
|
|
||||||
QString protocol = "https";
|
|
||||||
QString extra_headers = "";
|
|
||||||
QString sni = "";
|
|
||||||
QString certificate = "";
|
|
||||||
int insecure_concurrency = 0;
|
|
||||||
|
|
||||||
bool disable_log = false;
|
|
||||||
|
|
||||||
NaiveBean() : AbstractBean(0) {
|
|
||||||
_add(new configItem("username", &username, itemType::string));
|
|
||||||
_add(new configItem("password", &password, itemType::string));
|
|
||||||
_add(new configItem("protocol", &protocol, itemType::string));
|
|
||||||
_add(new configItem("extra_headers", &extra_headers, itemType::string));
|
|
||||||
_add(new configItem("sni", &sni, itemType::string));
|
|
||||||
_add(new configItem("certificate", &certificate, itemType::string));
|
|
||||||
_add(new configItem("insecure_concurrency", &insecure_concurrency, itemType::integer));
|
|
||||||
_add(new configItem("disable_log", &disable_log, itemType::boolean));
|
|
||||||
};
|
|
||||||
|
|
||||||
QString DisplayCoreType() override { return "Naive"; };
|
|
||||||
|
|
||||||
QString DisplayType() override { return "Naive"; };
|
|
||||||
|
|
||||||
int NeedExternal(bool isFirstProfile) override;
|
|
||||||
|
|
||||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
|
||||||
|
|
||||||
bool TryParseLink(const QString &link);
|
|
||||||
|
|
||||||
QString ToShareLink() override;
|
|
||||||
};
|
|
||||||
} // namespace NekoGui_fmt
|
|
||||||
@ -97,9 +97,7 @@ namespace NekoGui_fmt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString DisplayCoreType() override {
|
QString DisplayCoreType() override {
|
||||||
if (NeedExternal(true) == 0) {
|
if (proxy_type == proxy_TUIC) {
|
||||||
return software_core_name;
|
|
||||||
} else if (proxy_type == proxy_TUIC) {
|
|
||||||
return "tuic";
|
return "tuic";
|
||||||
} else if (proxy_type == proxy_Hysteria) {
|
} else if (proxy_type == proxy_Hysteria) {
|
||||||
return "hysteria";
|
return "hysteria";
|
||||||
@ -118,10 +116,6 @@ namespace NekoGui_fmt {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int NeedExternal(bool isFirstProfile) override;
|
|
||||||
|
|
||||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
|
||||||
|
|
||||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||||
|
|
||||||
bool TryParseLink(const QString &link);
|
bool TryParseLink(const QString &link);
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#include "ChainBean.hpp"
|
#include "ChainBean.hpp"
|
||||||
#include "VMessBean.hpp"
|
#include "VMessBean.hpp"
|
||||||
#include "TrojanVLESSBean.hpp"
|
#include "TrojanVLESSBean.hpp"
|
||||||
#include "NaiveBean.hpp"
|
|
||||||
#include "QUICBean.hpp"
|
#include "QUICBean.hpp"
|
||||||
#include "WireguardBean.h"
|
#include "WireguardBean.h"
|
||||||
#include "SSHBean.h"
|
#include "SSHBean.h"
|
||||||
|
|||||||
@ -19,8 +19,6 @@ inline std::function<void()> MF_release_runguard;
|
|||||||
class QWidget;
|
class QWidget;
|
||||||
inline QWidget *mainwindow;
|
inline QWidget *mainwindow;
|
||||||
inline std::function<void(QString)> MW_show_log;
|
inline std::function<void(QString)> MW_show_log;
|
||||||
inline std::function<void(QString, QString)> MW_show_log_ext;
|
|
||||||
inline std::function<void(QString)> MW_show_log_ext_vt100;
|
|
||||||
inline std::function<void(QString, QString)> MW_dialog_message;
|
inline std::function<void(QString, QString)> MW_dialog_message;
|
||||||
|
|
||||||
// Dispatchers
|
// Dispatchers
|
||||||
|
|||||||
@ -4,36 +4,25 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
namespace NekoGui_sys {
|
namespace NekoGui_sys {
|
||||||
class ExternalProcess : public QProcess {
|
class CoreProcess : public QProcess
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
QString tag;
|
QString tag;
|
||||||
QString program;
|
QString program;
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
QStringList env;
|
QStringList env;
|
||||||
|
|
||||||
bool managed = true; // MW_dialog_message
|
CoreProcess();
|
||||||
|
~CoreProcess();
|
||||||
ExternalProcess();
|
|
||||||
~ExternalProcess();
|
|
||||||
|
|
||||||
// start & kill is one time
|
// start & kill is one time
|
||||||
|
|
||||||
virtual void Start();
|
void Start();
|
||||||
|
|
||||||
void Kill();
|
void Kill();
|
||||||
|
|
||||||
protected:
|
|
||||||
bool started = false;
|
|
||||||
bool killed = false;
|
|
||||||
bool crashed = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CoreProcess : public ExternalProcess {
|
|
||||||
public:
|
|
||||||
CoreProcess(const QString &core_path, const QStringList &args);
|
CoreProcess(const QString &core_path, const QStringList &args);
|
||||||
|
|
||||||
void Start() override;
|
|
||||||
|
|
||||||
void Restart();
|
void Restart();
|
||||||
|
|
||||||
int start_profile_when_core_is_up = -1;
|
int start_profile_when_core_is_up = -1;
|
||||||
@ -42,10 +31,12 @@ namespace NekoGui_sys {
|
|||||||
bool show_stderr = false;
|
bool show_stderr = false;
|
||||||
bool failed_to_start = false;
|
bool failed_to_start = false;
|
||||||
bool restarting = false;
|
bool restarting = false;
|
||||||
};
|
|
||||||
|
|
||||||
// 手动管理
|
protected:
|
||||||
inline std::list<std::shared_ptr<ExternalProcess>> running_ext;
|
bool started = false;
|
||||||
|
bool killed = false;
|
||||||
|
bool crashed = false;
|
||||||
|
};
|
||||||
|
|
||||||
inline QAtomicInt logCounter;
|
inline QAtomicInt logCounter;
|
||||||
} // namespace NekoGui_sys
|
} // namespace NekoGui_sys
|
||||||
@ -1,41 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "profile_editor.h"
|
|
||||||
#include "ui_edit_naive.h"
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
namespace Ui {
|
|
||||||
class EditNaive;
|
|
||||||
}
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class EditNaive : public QWidget, public ProfileEditor {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit EditNaive(QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
~EditNaive() override;
|
|
||||||
|
|
||||||
void onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) override;
|
|
||||||
|
|
||||||
bool onEnd() override;
|
|
||||||
|
|
||||||
QList<QPair<QPushButton *, QString>> get_editor_cached() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::EditNaive *ui;
|
|
||||||
std::shared_ptr<NekoGui::ProxyEntity> ent;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
QString certificate;
|
|
||||||
QString extra_headers;
|
|
||||||
} CACHE;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
void on_certificate_clicked();
|
|
||||||
|
|
||||||
void on_extra_headers_clicked();
|
|
||||||
};
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>EditNaive</class>
|
|
||||||
<widget class="QWidget" name="EditNaive">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>525</width>
|
|
||||||
<height>304</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">EditNaive</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Username</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="MyLineEdit" name="username"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Password</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="MyLineEdit" name="password"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Protocol</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QComboBox" name="protocol">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">https</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">quic</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Extra headers</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QPushButton" name="extra_headers">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">PushButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>SNI</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="MyLineEdit" name="sni"/>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>Certificate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QPushButton" name="certificate">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">PushButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Insecure concurrency</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="MyLineEdit" name="insecure_concurrency"/>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>Disable logs</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QCheckBox" name="disable_log">
|
|
||||||
<property name="text">
|
|
||||||
<string>Turn on this option if your connection is lost after a while</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>MyLineEdit</class>
|
|
||||||
<extends>QLineEdit</extends>
|
|
||||||
<header>include/ui/utils/MyLineEdit.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@ -25,7 +25,6 @@ private:
|
|||||||
Ui::DialogBasicSettings *ui;
|
Ui::DialogBasicSettings *ui;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
QJsonObject extraCore;
|
|
||||||
QString custom_inbound;
|
QString custom_inbound;
|
||||||
bool needRestart = false;
|
bool needRestart = false;
|
||||||
} CACHE;
|
} CACHE;
|
||||||
|
|||||||
@ -756,61 +756,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tab_6">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Extra Core</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QScrollArea" name="extra_core_box_scrollArea">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::Shape::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="widgetResizable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="extra_core_box_scrollAreaWidgetContents">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>700</width>
|
|
||||||
<height>402</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="horizontalWidget_4" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="extra_core_add">
|
|
||||||
<property name="text">
|
|
||||||
<string>Add</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="extra_core_del">
|
|
||||||
<property name="text">
|
|
||||||
<string>Delete</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="tab_5">
|
<widget class="QWidget" name="tab_5">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Security</string>
|
<string>Security</string>
|
||||||
|
|||||||
@ -11,17 +11,6 @@
|
|||||||
#define BOX_UNDERLYING_DNS_EXPORT dataStore->core_box_underlying_dns.isEmpty() ? (status->forExport ? "local" : "underlying://0.0.0.0") : dataStore->core_box_underlying_dns
|
#define BOX_UNDERLYING_DNS_EXPORT dataStore->core_box_underlying_dns.isEmpty() ? (status->forExport ? "local" : "underlying://0.0.0.0") : dataStore->core_box_underlying_dns
|
||||||
|
|
||||||
namespace NekoGui {
|
namespace NekoGui {
|
||||||
|
|
||||||
QStringList getAutoBypassExternalProcessPaths(const std::shared_ptr<BuildConfigResult> &result) {
|
|
||||||
QStringList paths;
|
|
||||||
for (const auto &extR: result->extRs) {
|
|
||||||
auto path = extR->program;
|
|
||||||
if (path.trimmed().isEmpty()) continue;
|
|
||||||
paths << path.replace("\\", "/");
|
|
||||||
}
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString genTunName() {
|
QString genTunName() {
|
||||||
auto tun_name = "nekoray-tun";
|
auto tun_name = "nekoray-tun";
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
@ -281,83 +270,12 @@ namespace NekoGui {
|
|||||||
status->result->outboundStat = ent->traffic_data;
|
status->result->outboundStat = ent->traffic_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// chain rules: this
|
|
||||||
auto ext_mapping_port = 0;
|
|
||||||
auto ext_socks_port = 0;
|
|
||||||
auto thisExternalStat = ent->bean->NeedExternal(isFirstProfile);
|
|
||||||
if (thisExternalStat < 0) {
|
|
||||||
status->result->error = "This configuration cannot be set automatically, please try another.";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine port
|
|
||||||
if (thisExternalStat > 0) {
|
|
||||||
if (ent->type == "custom") {
|
|
||||||
auto bean = ent->CustomBean();
|
|
||||||
if (IsValidPort(bean->mapping_port)) {
|
|
||||||
ext_mapping_port = bean->mapping_port;
|
|
||||||
} else {
|
|
||||||
ext_mapping_port = MkPort();
|
|
||||||
}
|
|
||||||
if (IsValidPort(bean->socks_port)) {
|
|
||||||
ext_socks_port = bean->socks_port;
|
|
||||||
} else {
|
|
||||||
ext_socks_port = MkPort();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ext_mapping_port = MkPort();
|
|
||||||
ext_socks_port = MkPort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (thisExternalStat == 2) dataStore->need_keep_vpn_off = true;
|
|
||||||
if (thisExternalStat == 1) {
|
|
||||||
// mapping
|
|
||||||
status->inbounds += QJsonObject{
|
|
||||||
{"type", "direct"},
|
|
||||||
{"tag", tagOut + "-mapping"},
|
|
||||||
{"listen", "127.0.0.1"},
|
|
||||||
{"listen_port", ext_mapping_port},
|
|
||||||
{"override_address", ent->bean->serverAddress},
|
|
||||||
{"override_port", ent->bean->serverPort},
|
|
||||||
};
|
|
||||||
// no chain rule and not outbound, so need to set to direct
|
|
||||||
if (isFirstProfile) {
|
|
||||||
status->routingRules += QJsonObject{
|
|
||||||
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
|
||||||
{"outbound", "direct"},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outbound
|
// Outbound
|
||||||
|
|
||||||
QJsonObject outbound;
|
QJsonObject outbound;
|
||||||
|
|
||||||
if (thisExternalStat > 0) {
|
BuildOutbound(ent, status, outbound, tagOut);
|
||||||
auto extR = ent->bean->BuildExternal(ext_mapping_port, ext_socks_port, thisExternalStat);
|
|
||||||
if (extR.program.isEmpty()) {
|
|
||||||
status->result->error = QObject::tr("Core not found: %1").arg(ent->bean->DisplayCoreType());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (!extR.error.isEmpty()) { // rejected
|
|
||||||
status->result->error = extR.error;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
extR.tag = ent->bean->DisplayType();
|
|
||||||
status->result->extRs.emplace_back(std::make_shared<NekoGui_fmt::ExternalBuildResult>(extR));
|
|
||||||
|
|
||||||
// SOCKS OUTBOUND
|
|
||||||
outbound["type"] = "socks";
|
|
||||||
outbound["server"] = "127.0.0.1";
|
|
||||||
outbound["server_port"] = ext_socks_port;
|
|
||||||
// outbound misc
|
|
||||||
outbound["tag"] = tagOut;
|
|
||||||
ent->traffic_data->id = ent->id;
|
|
||||||
ent->traffic_data->tag = tagOut.toStdString();
|
|
||||||
status->result->outboundStats += ent->traffic_data;
|
|
||||||
} else {
|
|
||||||
BuildOutbound(ent, status, outbound, tagOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply custom outbound settings
|
// apply custom outbound settings
|
||||||
MergeJson(QString2QJsonObject(ent->bean->custom_outbound), outbound);
|
MergeJson(QString2QJsonObject(ent->bean->custom_outbound), outbound);
|
||||||
@ -377,7 +295,6 @@ namespace NekoGui {
|
|||||||
|
|
||||||
status->outbounds += outbound;
|
status->outbounds += outbound;
|
||||||
pastTag = tagOut;
|
pastTag = tagOut;
|
||||||
pastExternalStat = thisExternalStat;
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,6 @@ namespace NekoGui_fmt {
|
|||||||
bool noResolve = false;
|
bool noResolve = false;
|
||||||
if (dynamic_cast<ChainBean *>(this) != nullptr) noResolve = true;
|
if (dynamic_cast<ChainBean *>(this) != nullptr) noResolve = true;
|
||||||
if (dynamic_cast<CustomBean *>(this) != nullptr) noResolve = true;
|
if (dynamic_cast<CustomBean *>(this) != nullptr) noResolve = true;
|
||||||
if (dynamic_cast<NaiveBean *>(this) != nullptr) noResolve = true;
|
|
||||||
if (IsIpAddress(serverAddress)) noResolve = true;
|
if (IsIpAddress(serverAddress)) noResolve = true;
|
||||||
if (noResolve) {
|
if (noResolve) {
|
||||||
onFinished();
|
onFinished();
|
||||||
|
|||||||
@ -1,336 +0,0 @@
|
|||||||
#include "include/dataStore/ProxyEntity.hpp"
|
|
||||||
#include "include/configs/proxy/includes.h"
|
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
#define WriteTempFile(fn, data) \
|
|
||||||
QDir dir; \
|
|
||||||
if (!dir.exists("temp")) dir.mkdir("temp"); \
|
|
||||||
QFile f(QString("temp/") + fn); \
|
|
||||||
bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate); \
|
|
||||||
if (ok) { \
|
|
||||||
f.write(data); \
|
|
||||||
} else { \
|
|
||||||
result.error = f.errorString(); \
|
|
||||||
} \
|
|
||||||
f.close(); \
|
|
||||||
auto TempFile = QFileInfo(f).absoluteFilePath();
|
|
||||||
|
|
||||||
namespace NekoGui_fmt {
|
|
||||||
// -1: Cannot use this config
|
|
||||||
// 0: Internal
|
|
||||||
// 1: Mapping External
|
|
||||||
// 2: Direct External
|
|
||||||
|
|
||||||
int NaiveBean::NeedExternal(bool isFirstProfile) {
|
|
||||||
if (isFirstProfile) {
|
|
||||||
if (NekoGui::dataStore->spmode_vpn) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QUICBean::NeedExternal(bool isFirstProfile) {
|
|
||||||
auto hysteriaCore = [=] {
|
|
||||||
if (isFirstProfile) {
|
|
||||||
if (NekoGui::dataStore->spmode_vpn && hyProtocol != hysteria_protocol_facktcp) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
if (hyProtocol == hysteria_protocol_facktcp) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto hysteria2Core = [=] {
|
|
||||||
if (isFirstProfile) {
|
|
||||||
if (NekoGui::dataStore->spmode_vpn) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto tuicCore = [=] {
|
|
||||||
if (isFirstProfile) {
|
|
||||||
if (NekoGui::dataStore->spmode_vpn) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (IS_NEKO_BOX) {
|
|
||||||
if (!forceExternal && (proxy_type == proxy_TUIC || hyProtocol == hysteria_protocol_udp)) {
|
|
||||||
// sing-box support
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
// hysteria core support
|
|
||||||
return hysteriaCore();
|
|
||||||
}
|
|
||||||
} else if (proxy_type == proxy_TUIC) {
|
|
||||||
return tuicCore();
|
|
||||||
} else if (proxy_type == proxy_Hysteria2) {
|
|
||||||
return hysteria2Core();
|
|
||||||
} else {
|
|
||||||
return hysteriaCore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int CustomBean::NeedExternal(bool isFirstProfile) {
|
|
||||||
if (core == "internal" || core == "internal-full") return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalBuildResult NaiveBean::BuildExternal(int mapping_port, int socks_port, int external_stat) {
|
|
||||||
ExternalBuildResult result{NekoGui::dataStore->extraCore->Get("naive")};
|
|
||||||
|
|
||||||
auto is_direct = external_stat == 2;
|
|
||||||
auto domain_address = sni.isEmpty() ? serverAddress : sni;
|
|
||||||
auto connect_address = is_direct ? serverAddress : "127.0.0.1";
|
|
||||||
auto connect_port = is_direct ? serverPort : mapping_port;
|
|
||||||
domain_address = WrapIPV6Host(domain_address);
|
|
||||||
connect_address = WrapIPV6Host(connect_address);
|
|
||||||
|
|
||||||
auto proxy_url = QUrl();
|
|
||||||
proxy_url.setScheme(protocol);
|
|
||||||
proxy_url.setUserName(username);
|
|
||||||
proxy_url.setPassword(password);
|
|
||||||
proxy_url.setPort(connect_port);
|
|
||||||
proxy_url.setHost(domain_address);
|
|
||||||
|
|
||||||
if (!disable_log) result.arguments += "--log";
|
|
||||||
result.arguments += "--listen=socks://127.0.0.1:" + Int2String(socks_port);
|
|
||||||
result.arguments += "--proxy=" + proxy_url.toString(QUrl::FullyEncoded);
|
|
||||||
if (domain_address != connect_address)
|
|
||||||
result.arguments += "--host-resolver-rules=MAP " + domain_address + " " + connect_address;
|
|
||||||
if (insecure_concurrency > 0) result.arguments += "--insecure-concurrency=" + Int2String(insecure_concurrency);
|
|
||||||
if (!extra_headers.trimmed().isEmpty()) result.arguments += "--extra-headers=" + extra_headers;
|
|
||||||
if (!certificate.trimmed().isEmpty()) {
|
|
||||||
WriteTempFile("naive_" + GetRandomString(10) + ".crt", certificate.toUtf8());
|
|
||||||
result.env += "SSL_CERT_FILE=" + TempFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto config_export = QStringList{result.program};
|
|
||||||
config_export += result.arguments;
|
|
||||||
result.config_export = QStringList2Command(config_export);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalBuildResult QUICBean::BuildExternal(int mapping_port, int socks_port, int external_stat) {
|
|
||||||
if (proxy_type == proxy_TUIC) {
|
|
||||||
ExternalBuildResult result{NekoGui::dataStore->extraCore->Get("tuic")};
|
|
||||||
|
|
||||||
QJsonObject relay;
|
|
||||||
|
|
||||||
relay["uuid"] = uuid;
|
|
||||||
relay["password"] = password;
|
|
||||||
relay["udp_relay_mode"] = udpRelayMode;
|
|
||||||
relay["congestion_control"] = congestionControl;
|
|
||||||
relay["zero_rtt_handshake"] = zeroRttHandshake;
|
|
||||||
relay["disable_sni"] = disableSni;
|
|
||||||
if (!heartbeat.trimmed().isEmpty()) relay["heartbeat"] = heartbeat;
|
|
||||||
if (!alpn.trimmed().isEmpty()) relay["alpn"] = QListStr2QJsonArray(alpn.split(","));
|
|
||||||
|
|
||||||
if (!caText.trimmed().isEmpty()) {
|
|
||||||
WriteTempFile("tuic_" + GetRandomString(10) + ".crt", caText.toUtf8());
|
|
||||||
QJsonArray certificate;
|
|
||||||
certificate.append(TempFile);
|
|
||||||
relay["certificates"] = certificate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The most confused part of TUIC......
|
|
||||||
if (serverAddress == sni) {
|
|
||||||
relay["server"] = serverAddress + ":" + Int2String(serverPort);
|
|
||||||
} else {
|
|
||||||
relay["server"] = sni + ":" + Int2String(serverPort);
|
|
||||||
relay["ip"] = serverAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject local{
|
|
||||||
{"server", "127.0.0.1:" + Int2String(socks_port)},
|
|
||||||
};
|
|
||||||
|
|
||||||
QJsonObject config{
|
|
||||||
{"relay", relay},
|
|
||||||
{"local", local},
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
result.config_export = QJsonObject2QString(config, false);
|
|
||||||
WriteTempFile("tuic_" + GetRandomString(10) + ".json", result.config_export.toUtf8());
|
|
||||||
result.arguments = QStringList{"-c", TempFile};
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} else if (proxy_type == proxy_Hysteria2) {
|
|
||||||
ExternalBuildResult result{NekoGui::dataStore->extraCore->Get("hysteria2")};
|
|
||||||
|
|
||||||
QJsonObject config;
|
|
||||||
|
|
||||||
auto server = WrapIPV6Host(serverAddress) + ":" + Int2String(serverPort);;
|
|
||||||
|
|
||||||
QJsonObject transport;
|
|
||||||
transport["type"] = "udp";
|
|
||||||
config["transport"] = transport;
|
|
||||||
|
|
||||||
config["server"] = server;
|
|
||||||
config["socks5"] = QJsonObject{
|
|
||||||
{"listen", "127.0.0.1:" + Int2String(socks_port)},
|
|
||||||
{"disableUDP", false},
|
|
||||||
};
|
|
||||||
config["auth"] = password;
|
|
||||||
|
|
||||||
QJsonObject bandwidth;
|
|
||||||
if (uploadMbps > 0) bandwidth["up"] = Int2String(uploadMbps) + " mbps";
|
|
||||||
if (downloadMbps > 0) bandwidth["down"] = Int2String(downloadMbps) + " mbps";
|
|
||||||
config["bandwidth"] = bandwidth;
|
|
||||||
|
|
||||||
QJsonObject quic;
|
|
||||||
if (streamReceiveWindow > 0) quic["initStreamReceiveWindow"] = streamReceiveWindow;
|
|
||||||
if (connectionReceiveWindow > 0) quic["initConnReceiveWindow"] = connectionReceiveWindow;
|
|
||||||
if (disableMtuDiscovery) quic["disablePathMTUDiscovery"] = true;
|
|
||||||
config["quic"] = quic;
|
|
||||||
|
|
||||||
config["fastOpen"] = true;
|
|
||||||
config["lazy"] = true;
|
|
||||||
|
|
||||||
if (!obfsPassword.isEmpty()) {
|
|
||||||
QJsonObject obfs;
|
|
||||||
obfs["type"] = "salamander";
|
|
||||||
obfs["salamander"] = QJsonObject{
|
|
||||||
{"password", obfsPassword},
|
|
||||||
};
|
|
||||||
|
|
||||||
config["obfs"] = obfs;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject tls;
|
|
||||||
auto sniGen = sni;
|
|
||||||
if (sni.isEmpty() && !IsIpAddress(serverAddress)) sniGen = serverAddress;
|
|
||||||
tls["sni"] = sniGen;
|
|
||||||
if (allowInsecure) tls["insecure"] = true;
|
|
||||||
if (!caText.trimmed().isEmpty()) {
|
|
||||||
WriteTempFile("hysteria2_" + GetRandomString(10) + ".crt", caText.toUtf8());
|
|
||||||
QJsonArray certificate;
|
|
||||||
certificate.append(TempFile);
|
|
||||||
tls["certificates"] = certificate;
|
|
||||||
}
|
|
||||||
config["tls"] = tls;
|
|
||||||
|
|
||||||
result.config_export = QJsonObject2QString(config, false);
|
|
||||||
WriteTempFile("hysteria2_" + GetRandomString(10) + ".json", result.config_export.toUtf8());
|
|
||||||
result.arguments = QStringList{"-c", TempFile};
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} else { // Hysteria
|
|
||||||
ExternalBuildResult result{NekoGui::dataStore->extraCore->Get("hysteria")};
|
|
||||||
|
|
||||||
QJsonObject config;
|
|
||||||
|
|
||||||
// determine server format
|
|
||||||
auto is_direct = external_stat == 2;
|
|
||||||
auto sniGen = sni;
|
|
||||||
if (sni.isEmpty() && !IsIpAddress(serverAddress)) sniGen = serverAddress;
|
|
||||||
|
|
||||||
auto server = WrapIPV6Host(serverAddress) + ":" + Int2String(serverPort);
|
|
||||||
config["server"] = is_direct ? server : "127.0.0.1:" + Int2String(mapping_port);
|
|
||||||
|
|
||||||
// listen
|
|
||||||
config["socks5"] = QJsonObject{
|
|
||||||
{"listen", "127.0.0.1:" + Int2String(socks_port)},
|
|
||||||
};
|
|
||||||
|
|
||||||
// misc
|
|
||||||
|
|
||||||
config["retry"] = 5;
|
|
||||||
config["fast_open"] = true;
|
|
||||||
config["lazy_start"] = true;
|
|
||||||
config["obfs"] = obfsPassword;
|
|
||||||
config["up_mbps"] = uploadMbps;
|
|
||||||
config["down_mbps"] = downloadMbps;
|
|
||||||
|
|
||||||
if (authPayloadType == hysteria_auth_base64) config["auth"] = authPayload;
|
|
||||||
if (authPayloadType == hysteria_auth_string) config["auth_str"] = authPayload;
|
|
||||||
|
|
||||||
if (hyProtocol == hysteria_protocol_facktcp) config["protocol"] = "faketcp";
|
|
||||||
if (hyProtocol == hysteria_protocol_wechat_video) config["protocol"] = "wechat-video";
|
|
||||||
|
|
||||||
if (!sniGen.isEmpty()) config["server_name"] = sniGen;
|
|
||||||
if (!alpn.isEmpty()) config["alpn"] = alpn;
|
|
||||||
|
|
||||||
if (!caText.trimmed().isEmpty()) {
|
|
||||||
WriteTempFile("hysteria_" + GetRandomString(10) + ".crt", caText.toUtf8());
|
|
||||||
config["ca"] = TempFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowInsecure) config["insecure"] = true;
|
|
||||||
if (streamReceiveWindow > 0) config["recv_window_conn"] = streamReceiveWindow;
|
|
||||||
if (connectionReceiveWindow > 0) config["recv_window"] = connectionReceiveWindow;
|
|
||||||
if (disableMtuDiscovery) config["disable_mtu_discovery"] = true;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
result.config_export = QJsonObject2QString(config, false);
|
|
||||||
WriteTempFile("hysteria_" + GetRandomString(10) + ".json", result.config_export.toUtf8());
|
|
||||||
result.arguments = QStringList{"--no-check", "-c", TempFile};
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalBuildResult CustomBean::BuildExternal(int mapping_port, int socks_port, int external_stat) {
|
|
||||||
ExternalBuildResult result{NekoGui::dataStore->extraCore->Get(core)};
|
|
||||||
|
|
||||||
result.arguments = command; // TODO split?
|
|
||||||
|
|
||||||
for (int i = 0; i < result.arguments.length(); i++) {
|
|
||||||
auto arg = result.arguments[i];
|
|
||||||
arg = arg.replace("%mapping_port%", Int2String(mapping_port));
|
|
||||||
arg = arg.replace("%socks_port%", Int2String(socks_port));
|
|
||||||
arg = arg.replace("%server_addr%", serverAddress);
|
|
||||||
arg = arg.replace("%server_port%", Int2String(serverPort));
|
|
||||||
result.arguments[i] = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config_simple.trimmed().isEmpty()) {
|
|
||||||
auto config = config_simple;
|
|
||||||
config = config.replace("%mapping_port%", Int2String(mapping_port));
|
|
||||||
config = config.replace("%socks_port%", Int2String(socks_port));
|
|
||||||
config = config.replace("%server_addr%", serverAddress);
|
|
||||||
config = config.replace("%server_port%", Int2String(serverPort));
|
|
||||||
|
|
||||||
// suffix
|
|
||||||
QString suffix;
|
|
||||||
if (!config_suffix.isEmpty()) {
|
|
||||||
suffix = "." + config_suffix;
|
|
||||||
} else if (!QString2QJsonObject(config).isEmpty()) {
|
|
||||||
// trojan-go: unsupported config format: xxx.tmp. use .yaml or .json instead.
|
|
||||||
suffix = ".json";
|
|
||||||
}
|
|
||||||
|
|
||||||
// write config
|
|
||||||
WriteTempFile("custom_" + GetRandomString(10) + suffix, config.toUtf8());
|
|
||||||
for (int i = 0; i < result.arguments.count(); i++) {
|
|
||||||
result.arguments[i] = result.arguments[i].replace("%config%", TempFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.config_export = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NekoGui_fmt
|
|
||||||
@ -177,17 +177,6 @@ namespace NekoGui_fmt {
|
|||||||
return url.toString(QUrl::FullyEncoded);
|
return url.toString(QUrl::FullyEncoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NaiveBean::ToShareLink() {
|
|
||||||
QUrl url;
|
|
||||||
url.setScheme("naive+" + protocol);
|
|
||||||
url.setUserName(username);
|
|
||||||
url.setPassword(password);
|
|
||||||
url.setHost(serverAddress);
|
|
||||||
url.setPort(serverPort);
|
|
||||||
if (!name.isEmpty()) url.setFragment(name);
|
|
||||||
return url.toString(QUrl::FullyEncoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QUICBean::ToShareLink() {
|
QString QUICBean::ToShareLink() {
|
||||||
QUrl url;
|
QUrl url;
|
||||||
if (proxy_type == proxy_Hysteria) {
|
if (proxy_type == proxy_Hysteria) {
|
||||||
|
|||||||
@ -258,22 +258,6 @@ namespace NekoGui_fmt {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NaiveBean::TryParseLink(const QString &link) {
|
|
||||||
auto url = QUrl(link);
|
|
||||||
if (!url.isValid()) return false;
|
|
||||||
|
|
||||||
protocol = url.scheme().replace("naive+", "");
|
|
||||||
if (protocol != "https" && protocol != "quic") return false;
|
|
||||||
|
|
||||||
name = url.fragment(QUrl::FullyDecoded);
|
|
||||||
serverAddress = url.host();
|
|
||||||
serverPort = url.port();
|
|
||||||
username = url.userName();
|
|
||||||
password = url.password();
|
|
||||||
|
|
||||||
return !(username.isEmpty() || password.isEmpty() || serverAddress.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QUICBean::TryParseLink(const QString &link) {
|
bool QUICBean::TryParseLink(const QString &link) {
|
||||||
auto url = QUrl(link);
|
auto url = QUrl(link);
|
||||||
auto query = QUrlQuery(url.query());
|
auto query = QUrlQuery(url.query());
|
||||||
|
|||||||
@ -172,14 +172,6 @@ namespace NekoGui_sub {
|
|||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Naive
|
|
||||||
if (str.startsWith("naive+")) {
|
|
||||||
needFix = false;
|
|
||||||
ent = NekoGui::ProfileManager::NewProxyEntity("naive");
|
|
||||||
auto ok = ent->NaiveBean()->TryParseLink(str);
|
|
||||||
if (!ok) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hysteria1
|
// Hysteria1
|
||||||
if (str.startsWith("hysteria://")) {
|
if (str.startsWith("hysteria://")) {
|
||||||
needFix = false;
|
needFix = false;
|
||||||
|
|||||||
@ -215,8 +215,6 @@ namespace NekoGui {
|
|||||||
bean = new NekoGui_fmt::TrojanVLESSBean(NekoGui_fmt::TrojanVLESSBean::proxy_Trojan);
|
bean = new NekoGui_fmt::TrojanVLESSBean(NekoGui_fmt::TrojanVLESSBean::proxy_Trojan);
|
||||||
} else if (type == "vless") {
|
} else if (type == "vless") {
|
||||||
bean = new NekoGui_fmt::TrojanVLESSBean(NekoGui_fmt::TrojanVLESSBean::proxy_VLESS);
|
bean = new NekoGui_fmt::TrojanVLESSBean(NekoGui_fmt::TrojanVLESSBean::proxy_VLESS);
|
||||||
} else if (type == "naive") {
|
|
||||||
bean = new NekoGui_fmt::NaiveBean();
|
|
||||||
} else if (type == "hysteria") {
|
} else if (type == "hysteria") {
|
||||||
bean = new NekoGui_fmt::QUICBean(NekoGui_fmt::QUICBean::proxy_Hysteria);
|
bean = new NekoGui_fmt::QUICBean(NekoGui_fmt::QUICBean::proxy_Hysteria);
|
||||||
} else if (type == "hysteria2") {
|
} else if (type == "hysteria2") {
|
||||||
|
|||||||
@ -23,11 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
QStringList SplitLines(const QString &_string) {
|
QStringList SplitLines(const QString &_string) {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
|
||||||
return _string.split(QRegularExpression("[\r\n]"), Qt::SplitBehaviorFlags::SkipEmptyParts);
|
return _string.split(QRegularExpression("[\r\n]"), Qt::SplitBehaviorFlags::SkipEmptyParts);
|
||||||
#else
|
|
||||||
return _string.split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList SplitLinesSkipSharp(const QString &_string, int maxLine) {
|
QStringList SplitLinesSkipSharp(const QString &_string, int maxLine) {
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
#include "3rdparty/fix_old_qt.h"
|
|
||||||
#include "include/global/NekoGui.hpp"
|
#include "include/global/NekoGui.hpp"
|
||||||
|
|
||||||
// macOS headers (possibly OBJ-c)
|
// macOS headers (possibly OBJ-c)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "include/sys/ExternalProcess.hpp"
|
#include "include/sys/Process.hpp"
|
||||||
#include "include/global/NekoGui.hpp"
|
#include "include/global/NekoGui.hpp"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@ -8,61 +8,20 @@
|
|||||||
|
|
||||||
namespace NekoGui_sys {
|
namespace NekoGui_sys {
|
||||||
|
|
||||||
ExternalProcess::ExternalProcess() : QProcess() {
|
CoreProcess::CoreProcess() : QProcess() {
|
||||||
// qDebug() << "[Debug] ExternalProcess()" << this << running_ext;
|
|
||||||
this->env = QProcessEnvironment::systemEnvironment().toStringList();
|
this->env = QProcessEnvironment::systemEnvironment().toStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalProcess::~ExternalProcess() {
|
CoreProcess::~CoreProcess() {
|
||||||
// qDebug() << "[Debug] ~ExternalProcess()" << this << running_ext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalProcess::Start() {
|
void CoreProcess::Kill() {
|
||||||
if (started) return;
|
|
||||||
started = true;
|
|
||||||
|
|
||||||
if (managed) {
|
|
||||||
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
|
|
||||||
auto log = readAllStandardOutput();
|
|
||||||
if (logCounter.fetchAndAddRelaxed(log.count("\n")) > NekoGui::dataStore->max_log_line) return;
|
|
||||||
MW_show_log_ext_vt100(log);
|
|
||||||
});
|
|
||||||
connect(this, &QProcess::readyReadStandardError, this, [&]() {
|
|
||||||
MW_show_log_ext_vt100(readAllStandardError().trimmed());
|
|
||||||
});
|
|
||||||
connect(this, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
|
||||||
if (!killed) {
|
|
||||||
crashed = true;
|
|
||||||
MW_show_log_ext(tag, "errorOccurred:" + errorString());
|
|
||||||
MW_dialog_message("ExternalProcess", "Crashed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(this, &QProcess::stateChanged, this, [&](QProcess::ProcessState state) {
|
|
||||||
if (state == QProcess::NotRunning) {
|
|
||||||
if (killed) { // 用户命令退出
|
|
||||||
MW_show_log_ext(tag, "External core stopped");
|
|
||||||
} else if (!crashed) { // 异常退出
|
|
||||||
crashed = true;
|
|
||||||
MW_show_log_ext(tag, "[Error] Program exited accidentally: " + errorString());
|
|
||||||
Kill();
|
|
||||||
MW_dialog_message("ExternalProcess", "Crashed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
MW_show_log_ext(tag, "External core starting: " + env.join(" ") + " " + program + " " + arguments.join(" "));
|
|
||||||
}
|
|
||||||
|
|
||||||
QProcess::setEnvironment(env);
|
|
||||||
QProcess::start(program, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExternalProcess::Kill() {
|
|
||||||
if (killed) return;
|
if (killed) return;
|
||||||
killed = true;
|
killed = true;
|
||||||
|
|
||||||
if (!crashed) {
|
if (!crashed) {
|
||||||
QProcess::kill();
|
kill();
|
||||||
QProcess::waitForFinished(500);
|
waitForFinished(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,10 +29,9 @@ namespace NekoGui_sys {
|
|||||||
|
|
||||||
QElapsedTimer coreRestartTimer;
|
QElapsedTimer coreRestartTimer;
|
||||||
|
|
||||||
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) : ExternalProcess() {
|
CoreProcess::CoreProcess(const QString &core_path, const QStringList &args) : QProcess() {
|
||||||
ExternalProcess::managed = false;
|
program = core_path;
|
||||||
ExternalProcess::program = core_path;
|
arguments = args;
|
||||||
ExternalProcess::arguments = args;
|
|
||||||
|
|
||||||
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
|
connect(this, &QProcess::readyReadStandardOutput, this, [&]() {
|
||||||
auto log = readAllStandardOutput();
|
auto log = readAllStandardOutput();
|
||||||
@ -87,7 +45,7 @@ namespace NekoGui_sys {
|
|||||||
}
|
}
|
||||||
} else if (log.contains("failed to serve")) {
|
} else if (log.contains("failed to serve")) {
|
||||||
// The core failed to start
|
// The core failed to start
|
||||||
QProcess::kill();
|
kill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (logCounter.fetchAndAddRelaxed(log.count("\n")) > NekoGui::dataStore->max_log_line) return;
|
if (logCounter.fetchAndAddRelaxed(log.count("\n")) > NekoGui::dataStore->max_log_line) return;
|
||||||
@ -141,15 +99,19 @@ namespace NekoGui_sys {
|
|||||||
|
|
||||||
void CoreProcess::Start() {
|
void CoreProcess::Start() {
|
||||||
show_stderr = false;
|
show_stderr = false;
|
||||||
ExternalProcess::Start();
|
if (started) return;
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
setEnvironment(env);
|
||||||
|
start(program, arguments);
|
||||||
write((NekoGui::dataStore->core_token + "\n").toUtf8());
|
write((NekoGui::dataStore->core_token + "\n").toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreProcess::Restart() {
|
void CoreProcess::Restart() {
|
||||||
restarting = true;
|
restarting = true;
|
||||||
QProcess::kill();
|
kill();
|
||||||
QProcess::waitForFinished(500);
|
waitForFinished(500);
|
||||||
ExternalProcess::started = false;
|
started = false;
|
||||||
Start();
|
Start();
|
||||||
restarting = false;
|
restarting = false;
|
||||||
}
|
}
|
||||||
@ -3,7 +3,7 @@
|
|||||||
#include "include/dataStore/ProfileFilter.hpp"
|
#include "include/dataStore/ProfileFilter.hpp"
|
||||||
#include "include/configs/configBuilder.hpp"
|
#include "include/configs/configBuilder.hpp"
|
||||||
#include "include/configs/sub/GroupUpdater.hpp"
|
#include "include/configs/sub/GroupUpdater.hpp"
|
||||||
#include "include/sys/ExternalProcess.hpp"
|
#include "include/sys/Process.hpp"
|
||||||
#include "include/sys/AutoRun.hpp"
|
#include "include/sys/AutoRun.hpp"
|
||||||
|
|
||||||
#include "include/ui/setting/ThemeManager.hpp"
|
#include "include/ui/setting/ThemeManager.hpp"
|
||||||
@ -16,7 +16,6 @@
|
|||||||
#include "include/ui/setting/dialog_hotkey.h"
|
#include "include/ui/setting/dialog_hotkey.h"
|
||||||
|
|
||||||
#include "3rdparty/qrcodegen.hpp"
|
#include "3rdparty/qrcodegen.hpp"
|
||||||
#include "3rdparty/VT100Parser.hpp"
|
|
||||||
#include "3rdparty/qv2ray/v2/ui/LogHighlighter.hpp"
|
#include "3rdparty/qv2ray/v2/ui/LogHighlighter.hpp"
|
||||||
#include "3rdparty/ZxingQtReader.hpp"
|
#include "3rdparty/ZxingQtReader.hpp"
|
||||||
#include "include/ui/group/dialog_edit_group.h"
|
#include "include/ui/group/dialog_edit_group.h"
|
||||||
@ -154,12 +153,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
MW_show_log = [=](const QString &log) {
|
MW_show_log = [=](const QString &log) {
|
||||||
runOnUiThread([=] { show_log_impl(log); });
|
runOnUiThread([=] { show_log_impl(log); });
|
||||||
};
|
};
|
||||||
MW_show_log_ext = [=](const QString &tag, const QString &log) {
|
|
||||||
runOnUiThread([=] { show_log_impl("[" + tag + "] " + log); });
|
|
||||||
};
|
|
||||||
MW_show_log_ext_vt100 = [=](const QString &log) {
|
|
||||||
runOnUiThread([=] { show_log_impl(cleanVT100String(log)); });
|
|
||||||
};
|
|
||||||
|
|
||||||
// table UI
|
// table UI
|
||||||
ui->proxyListTable->callback_save_order = [=] {
|
ui->proxyListTable->callback_save_order = [=] {
|
||||||
|
|||||||
@ -12,24 +12,6 @@
|
|||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
// ext core
|
|
||||||
|
|
||||||
std::list<std::shared_ptr<NekoGui_sys::ExternalProcess>> CreateExtCFromExtR(const std::list<std::shared_ptr<NekoGui_fmt::ExternalBuildResult>> &extRs, bool start) {
|
|
||||||
// plz run and start in same thread
|
|
||||||
std::list<std::shared_ptr<NekoGui_sys::ExternalProcess>> l;
|
|
||||||
for (const auto &extR: extRs) {
|
|
||||||
std::shared_ptr<NekoGui_sys::ExternalProcess> extC(new NekoGui_sys::ExternalProcess());
|
|
||||||
extC->tag = extR->tag;
|
|
||||||
extC->program = extR->program;
|
|
||||||
extC->arguments = extR->arguments;
|
|
||||||
extC->env = extR->env;
|
|
||||||
l.emplace_back(extC);
|
|
||||||
//
|
|
||||||
if (start) extC->Start();
|
|
||||||
}
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
// grpc
|
// grpc
|
||||||
|
|
||||||
using namespace NekoGui_rpc;
|
using namespace NekoGui_rpc;
|
||||||
@ -52,9 +34,6 @@ void MainWindow::RunSpeedTest(const QString& config, bool useDefault, const QStr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<std::shared_ptr<NekoGui_sys::ExternalProcess>> extCs;
|
|
||||||
QSemaphore extSem;
|
|
||||||
|
|
||||||
libcore::TestReq req;
|
libcore::TestReq req;
|
||||||
for (const auto &item: outboundTags) {
|
for (const auto &item: outboundTags) {
|
||||||
req.add_outbound_tags(item.toStdString());
|
req.add_outbound_tags(item.toStdString());
|
||||||
@ -67,18 +46,6 @@ void MainWindow::RunSpeedTest(const QString& config, bool useDefault, const QStr
|
|||||||
bool rpcOK;
|
bool rpcOK;
|
||||||
auto result = defaultClient->Test(&rpcOK, req);
|
auto result = defaultClient->Test(&rpcOK, req);
|
||||||
//
|
//
|
||||||
if (!extCs.empty()) {
|
|
||||||
runOnUiThread(
|
|
||||||
[&] {
|
|
||||||
for (const auto &extC: extCs) {
|
|
||||||
extC->Kill();
|
|
||||||
}
|
|
||||||
extSem.release();
|
|
||||||
},
|
|
||||||
DS_cores);
|
|
||||||
extSem.acquire();
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (!rpcOK) return;
|
if (!rpcOK) return;
|
||||||
|
|
||||||
for (const auto &res: result.results()) {
|
for (const auto &res: result.results()) {
|
||||||
@ -313,13 +280,6 @@ void MainWindow::neko_start(int _id) {
|
|||||||
NekoGui::dataStore->ignoreConnTag = result->ignoreConnTag;
|
NekoGui::dataStore->ignoreConnTag = result->ignoreConnTag;
|
||||||
NekoGui_traffic::trafficLooper->loop_enabled = true;
|
NekoGui_traffic::trafficLooper->loop_enabled = true;
|
||||||
|
|
||||||
runOnUiThread(
|
|
||||||
[=] {
|
|
||||||
auto extCs = CreateExtCFromExtR(result->extRs, true);
|
|
||||||
NekoGui_sys::running_ext.splice(NekoGui_sys::running_ext.end(), extCs);
|
|
||||||
},
|
|
||||||
DS_cores);
|
|
||||||
|
|
||||||
NekoGui::dataStore->UpdateStartedId(ent->id);
|
NekoGui::dataStore->UpdateStartedId(ent->id);
|
||||||
running = ent;
|
running = ent;
|
||||||
|
|
||||||
@ -417,16 +377,6 @@ void MainWindow::neko_stop(bool crash, bool sem, bool manual) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread(
|
|
||||||
[=] {
|
|
||||||
while (!NekoGui_sys::running_ext.empty()) {
|
|
||||||
auto extC = NekoGui_sys::running_ext.front();
|
|
||||||
extC->Kill();
|
|
||||||
NekoGui_sys::running_ext.pop_front();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DS_cores);
|
|
||||||
|
|
||||||
auto neko_stop_stage2 = [=] {
|
auto neko_stop_stage2 = [=] {
|
||||||
if (!crash) {
|
if (!crash) {
|
||||||
bool rpcOK;
|
bool rpcOK;
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
#include "include/ui/profile/edit_chain.h"
|
#include "include/ui/profile/edit_chain.h"
|
||||||
#include "include/ui/profile/edit_vmess.h"
|
#include "include/ui/profile/edit_vmess.h"
|
||||||
#include "include/ui/profile/edit_trojan_vless.h"
|
#include "include/ui/profile/edit_trojan_vless.h"
|
||||||
#include "include/ui/profile/edit_naive.h"
|
|
||||||
#include "include/ui/profile/edit_quic.h"
|
#include "include/ui/profile/edit_quic.h"
|
||||||
#include "include/ui/profile/edit_wireguard.h"
|
#include "include/ui/profile/edit_wireguard.h"
|
||||||
#include "include/ui/profile/edit_ssh.h"
|
#include "include/ui/profile/edit_ssh.h"
|
||||||
@ -156,7 +155,6 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
LOAD_TYPE("trojan")
|
LOAD_TYPE("trojan")
|
||||||
LOAD_TYPE("vmess")
|
LOAD_TYPE("vmess")
|
||||||
LOAD_TYPE("vless")
|
LOAD_TYPE("vless")
|
||||||
LOAD_TYPE("naive")
|
|
||||||
LOAD_TYPE("hysteria")
|
LOAD_TYPE("hysteria")
|
||||||
LOAD_TYPE("hysteria2")
|
LOAD_TYPE("hysteria2")
|
||||||
LOAD_TYPE("tuic")
|
LOAD_TYPE("tuic")
|
||||||
@ -164,7 +162,6 @@ DialogEditProfile::DialogEditProfile(const QString &_type, int profileOrGroupId,
|
|||||||
LOAD_TYPE("ssh")
|
LOAD_TYPE("ssh")
|
||||||
ui->type->addItem(tr("Custom (%1 outbound)").arg(software_core_name), "internal");
|
ui->type->addItem(tr("Custom (%1 outbound)").arg(software_core_name), "internal");
|
||||||
ui->type->addItem(tr("Custom (%1 config)").arg(software_core_name), "internal-full");
|
ui->type->addItem(tr("Custom (%1 config)").arg(software_core_name), "internal-full");
|
||||||
ui->type->addItem(tr("Custom (Extra Core)"), "custom");
|
|
||||||
LOAD_TYPE("chain")
|
LOAD_TYPE("chain")
|
||||||
|
|
||||||
// type changed
|
// type changed
|
||||||
@ -213,10 +210,6 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
auto _innerWidget = new EditTrojanVLESS(this);
|
auto _innerWidget = new EditTrojanVLESS(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
innerEditor = _innerWidget;
|
innerEditor = _innerWidget;
|
||||||
} else if (type == "naive") {
|
|
||||||
auto _innerWidget = new EditNaive(this);
|
|
||||||
innerWidget = _innerWidget;
|
|
||||||
innerEditor = _innerWidget;
|
|
||||||
} else if (type == "hysteria" || type == "hysteria2" || type == "tuic") {
|
} else if (type == "hysteria" || type == "hysteria2" || type == "tuic") {
|
||||||
auto _innerWidget = new EditQUIC(this);
|
auto _innerWidget = new EditQUIC(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
@ -229,7 +222,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
|
|||||||
auto _innerWidget = new EditSSH(this);
|
auto _innerWidget = new EditSSH(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
innerEditor = _innerWidget;
|
innerEditor = _innerWidget;
|
||||||
} else if (type == "custom" || type == "internal" || type == "internal-full") {
|
} else if (type == "internal" || type == "internal-full") {
|
||||||
auto _innerWidget = new EditCustom(this);
|
auto _innerWidget = new EditCustom(this);
|
||||||
innerWidget = _innerWidget;
|
innerWidget = _innerWidget;
|
||||||
innerEditor = _innerWidget;
|
innerEditor = _innerWidget;
|
||||||
|
|||||||
@ -114,16 +114,6 @@ void EditCustom::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
|||||||
MessageBoxInfo(software_name, result->error);
|
MessageBoxInfo(software_name, result->error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto &extR: result->extRs) {
|
|
||||||
auto command = QStringList{extR->program};
|
|
||||||
command += extR->arguments;
|
|
||||||
auto btn = QMessageBox::information(this, tr("Preview config"),
|
|
||||||
QString("Command: %1\n\n%2").arg(QStringList2Command(command), extR->config_export),
|
|
||||||
"OK", "Copy", "", 0, 0);
|
|
||||||
if (btn == 1) {
|
|
||||||
QApplication::clipboard()->setText(extR->config_export);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
#include "include/ui/profile/edit_naive.h"
|
|
||||||
|
|
||||||
#include "include/configs/proxy/NaiveBean.hpp"
|
|
||||||
|
|
||||||
#include <QInputDialog>
|
|
||||||
|
|
||||||
EditNaive::EditNaive(QWidget *parent) : QWidget(parent), ui(new Ui::EditNaive) {
|
|
||||||
ui->setupUi(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditNaive::~EditNaive() {
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditNaive::onStart(std::shared_ptr<NekoGui::ProxyEntity> _ent) {
|
|
||||||
this->ent = _ent;
|
|
||||||
auto bean = this->ent->NaiveBean();
|
|
||||||
|
|
||||||
P_LOAD_STRING(username);
|
|
||||||
P_LOAD_STRING(password);
|
|
||||||
P_LOAD_COMBO_STRING(protocol);
|
|
||||||
P_C_LOAD_STRING(extra_headers);
|
|
||||||
P_LOAD_STRING(sni);
|
|
||||||
P_C_LOAD_STRING(certificate);
|
|
||||||
P_LOAD_INT(insecure_concurrency);
|
|
||||||
P_LOAD_BOOL(disable_log);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EditNaive::onEnd() {
|
|
||||||
auto bean = this->ent->NaiveBean();
|
|
||||||
|
|
||||||
P_SAVE_STRING(username);
|
|
||||||
P_SAVE_STRING(password);
|
|
||||||
P_SAVE_COMBO_STRING(protocol);
|
|
||||||
P_C_SAVE_STRING(extra_headers);
|
|
||||||
P_SAVE_STRING(sni);
|
|
||||||
P_C_SAVE_STRING(certificate);
|
|
||||||
P_SAVE_INT(insecure_concurrency);
|
|
||||||
P_SAVE_BOOL(disable_log);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QPair<QPushButton *, QString>> EditNaive::get_editor_cached() {
|
|
||||||
return {
|
|
||||||
{ui->certificate, CACHE.certificate},
|
|
||||||
{ui->extra_headers, CACHE.extra_headers},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditNaive::on_certificate_clicked() {
|
|
||||||
bool ok;
|
|
||||||
auto txt = QInputDialog::getMultiLineText(this, tr("Certificate"), "", CACHE.certificate, &ok);
|
|
||||||
if (ok) {
|
|
||||||
CACHE.certificate = txt;
|
|
||||||
editor_cache_updated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditNaive::on_extra_headers_clicked() {
|
|
||||||
bool ok;
|
|
||||||
auto txt = QInputDialog::getMultiLineText(this, tr("Extra headers"), "", CACHE.extra_headers, &ok);
|
|
||||||
if (ok) {
|
|
||||||
CACHE.extra_headers = txt;
|
|
||||||
editor_cache_updated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -15,44 +15,6 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <qfontdatabase.h>
|
#include <qfontdatabase.h>
|
||||||
|
|
||||||
class ExtraCoreWidget : public QWidget {
|
|
||||||
public:
|
|
||||||
QString coreName;
|
|
||||||
|
|
||||||
QLabel *label_name;
|
|
||||||
MyLineEdit *lineEdit_path;
|
|
||||||
QPushButton *pushButton_pick;
|
|
||||||
|
|
||||||
explicit ExtraCoreWidget(QJsonObject *extraCore, const QString &coreName_,
|
|
||||||
QWidget *parent = nullptr)
|
|
||||||
: QWidget(parent) {
|
|
||||||
coreName = coreName_;
|
|
||||||
label_name = new QLabel;
|
|
||||||
label_name->setText(coreName);
|
|
||||||
lineEdit_path = new MyLineEdit;
|
|
||||||
lineEdit_path->setText(extraCore->value(coreName).toString());
|
|
||||||
pushButton_pick = new QPushButton;
|
|
||||||
pushButton_pick->setText(QObject::tr("Select"));
|
|
||||||
auto layout = new QHBoxLayout;
|
|
||||||
layout->addWidget(label_name);
|
|
||||||
layout->addWidget(lineEdit_path);
|
|
||||||
layout->addWidget(pushButton_pick);
|
|
||||||
setLayout(layout);
|
|
||||||
setContentsMargins(0, 0, 0, 0);
|
|
||||||
//
|
|
||||||
connect(pushButton_pick, &QPushButton::clicked, this, [=] {
|
|
||||||
auto fn = QFileDialog::getOpenFileName(this, QObject::tr("Select"), QDir::currentPath(),
|
|
||||||
"", nullptr, QFileDialog::Option::ReadOnly);
|
|
||||||
if (!fn.isEmpty()) {
|
|
||||||
lineEdit_path->setText(fn);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(lineEdit_path, &QLineEdit::textChanged, this, [=](const QString &newTxt) {
|
|
||||||
extraCore->insert(coreName, newTxt);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||||
: QDialog(parent), ui(new Ui::DialogBasicSettings) {
|
: QDialog(parent), ui(new Ui::DialogBasicSettings) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -169,46 +131,6 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
|||||||
MW_show_log("Removed all rule-set files");
|
MW_show_log("Removed all rule-set files");
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
|
||||||
CACHE.extraCore = QString2QJsonObject(NekoGui::dataStore->extraCore->core_map);
|
|
||||||
if (!CACHE.extraCore.contains("naive")) CACHE.extraCore.insert("naive", "");
|
|
||||||
if (!CACHE.extraCore.contains("hysteria")) CACHE.extraCore.insert("hysteria", "");
|
|
||||||
if (!CACHE.extraCore.contains("hysteria2")) CACHE.extraCore.insert("hysteria2", "");
|
|
||||||
if (!CACHE.extraCore.contains("tuic")) CACHE.extraCore.insert("tuic", "");
|
|
||||||
//
|
|
||||||
auto extra_core_layout = ui->extra_core_box_scrollAreaWidgetContents->layout();
|
|
||||||
for (const auto &s: CACHE.extraCore.keys()) {
|
|
||||||
extra_core_layout->addWidget(new ExtraCoreWidget(&CACHE.extraCore, s));
|
|
||||||
}
|
|
||||||
//
|
|
||||||
connect(ui->extra_core_add, &QPushButton::clicked, this, [=] {
|
|
||||||
bool ok;
|
|
||||||
auto s = QInputDialog::getText(nullptr, tr("Add"),
|
|
||||||
tr("Please input the core name."),
|
|
||||||
QLineEdit::Normal, "", &ok)
|
|
||||||
.trimmed();
|
|
||||||
if (s.isEmpty() || !ok) return;
|
|
||||||
if (CACHE.extraCore.contains(s)) return;
|
|
||||||
extra_core_layout->addWidget(new ExtraCoreWidget(&CACHE.extraCore, s));
|
|
||||||
CACHE.extraCore.insert(s, "");
|
|
||||||
});
|
|
||||||
connect(ui->extra_core_del, &QPushButton::clicked, this, [=] {
|
|
||||||
bool ok;
|
|
||||||
auto s = QInputDialog::getItem(nullptr, tr("Delete"),
|
|
||||||
tr("Please select the core name."),
|
|
||||||
CACHE.extraCore.keys(), 0, false, &ok);
|
|
||||||
if (s.isEmpty() || !ok) return;
|
|
||||||
for (int i = 0; i < extra_core_layout->count(); i++) {
|
|
||||||
auto item = extra_core_layout->itemAt(i);
|
|
||||||
auto ecw = dynamic_cast<ExtraCoreWidget *>(item->widget());
|
|
||||||
if (ecw != nullptr && ecw->coreName == s) {
|
|
||||||
ecw->deleteLater();
|
|
||||||
CACHE.extraCore.remove(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mux
|
// Mux
|
||||||
D_LOAD_INT(mux_concurrency)
|
D_LOAD_INT(mux_concurrency)
|
||||||
D_LOAD_COMBO_STRING(mux_protocol)
|
D_LOAD_COMBO_STRING(mux_protocol)
|
||||||
@ -290,7 +212,6 @@ void DialogBasicSettings::accept() {
|
|||||||
D_SAVE_INT_ENABLE(sub_auto_update, sub_auto_update_enable)
|
D_SAVE_INT_ENABLE(sub_auto_update, sub_auto_update_enable)
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
NekoGui::dataStore->extraCore->core_map = QJsonObject2QString(CACHE.extraCore, true);
|
|
||||||
NekoGui::dataStore->disable_traffic_stats = ui->disable_stats->isChecked();
|
NekoGui::dataStore->disable_traffic_stats = ui->disable_stats->isChecked();
|
||||||
|
|
||||||
// Assets
|
// Assets
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user