mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 02:40:20 +08:00
parent
ce218f1ada
commit
22ecbe25a3
@ -1 +1 @@
|
|||||||
887
|
917
|
||||||
|
@ -34,7 +34,7 @@ namespace Qv2ray
|
|||||||
bool RenameConnection(QString originalName, QString newName);
|
bool RenameConnection(QString originalName, QString newName);
|
||||||
// VMess URI Protocol
|
// VMess URI Protocol
|
||||||
QJsonObject ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage);
|
QJsonObject ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage);
|
||||||
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds);
|
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds);
|
||||||
QString ConvertConfigToVMessString(const StreamSettingsObject &transfer, const VMessServerObject &serverConfig, const QString &alias);
|
QString ConvertConfigToVMessString(const StreamSettingsObject &transfer, const VMessServerObject &serverConfig, const QString &alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "QvCoreConfigOperations.hpp"
|
#include "QvCoreConfigOperations.hpp"
|
||||||
|
|
||||||
namespace Qv2ray
|
namespace Qv2ray
|
||||||
{
|
{
|
||||||
@ -224,7 +224,7 @@ namespace Qv2ray
|
|||||||
RROOT
|
RROOT
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds)
|
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds)
|
||||||
{
|
{
|
||||||
QFile source(sourceFilePath);
|
QFile source(sourceFilePath);
|
||||||
|
|
||||||
@ -233,9 +233,9 @@ namespace Qv2ray
|
|||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto root = JsonFromString(StringFromFile(new QFile(sourceFilePath)));
|
auto root = JsonFromString(StringFromFile(&source));
|
||||||
|
|
||||||
if (overrideInbounds) {
|
if (!keepInbounds) {
|
||||||
JSON_ROOT_TRY_REMOVE("inbounds")
|
JSON_ROOT_TRY_REMOVE("inbounds")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,15 @@ ImportConfigWindow::ImportConfigWindow(QWidget *parent)
|
|||||||
nameTxt->setText(QDateTime::currentDateTime().toString("MM-dd_hh-mm") + "_" + tr("Imported") + "_");
|
nameTxt->setText(QDateTime::currentDateTime().toString("MM-dd_hh-mm") + "_" + tr("Imported") + "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMap<QString, QJsonObject> ImportConfigWindow::OpenImport(bool outboundsOnly)
|
||||||
|
{
|
||||||
|
// if Outbound Only, set keepImported to false and disable the checkbox
|
||||||
|
// keepImportedInboundCheckBox->setChecked(!outboundsOnly);
|
||||||
|
keepImportedInboundCheckBox->setEnabled(!outboundsOnly);
|
||||||
|
this->exec();
|
||||||
|
return this->result() == QDialog::Accepted ? connections : QMap<QString, QJsonObject>();
|
||||||
|
}
|
||||||
|
|
||||||
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
|
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
stackedWidget->setCurrentIndex(index);
|
stackedWidget->setCurrentIndex(index);
|
||||||
@ -37,17 +46,7 @@ void ImportConfigWindow::on_selectFileBtn_clicked()
|
|||||||
|
|
||||||
void ImportConfigWindow::on_qrFromScreenBtn_clicked()
|
void ImportConfigWindow::on_qrFromScreenBtn_clicked()
|
||||||
{
|
{
|
||||||
// QRubberBand
|
|
||||||
QThread::msleep(static_cast<ulong>(doubleSpinBox->value() * 1000));
|
QThread::msleep(static_cast<ulong>(doubleSpinBox->value() * 1000));
|
||||||
//bool hasVmessDetected = false;
|
|
||||||
//for (auto screen : qApp->screens()) {
|
|
||||||
// if (!screen) {
|
|
||||||
// LOG(MODULE_UI, "Cannot even find a screen. RARE")
|
|
||||||
// QvMessageBox(this, tr("Screenshot failed"), tr("Cannot find a valid screen, it's rare."));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//auto pix = screen->grabWindow(0);
|
|
||||||
//
|
|
||||||
ScreenShotWindow w;
|
ScreenShotWindow w;
|
||||||
auto pix = w.DoScreenShot();
|
auto pix = w.DoScreenShot();
|
||||||
|
|
||||||
@ -57,32 +56,25 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
|
|||||||
if (str.trimmed().isEmpty()) {
|
if (str.trimmed().isEmpty()) {
|
||||||
LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + to_string(pix.width()) + ", v=" + to_string(pix.height()))
|
LOG(MODULE_UI, "Cannot decode QR Code from an image, size: h=" + to_string(pix.width()) + ", v=" + to_string(pix.height()))
|
||||||
QvMessageBox(this, tr("Capture QRCode"), tr("Cannot find a valid QRCode from this region."));
|
QvMessageBox(this, tr("Capture QRCode"), tr("Cannot find a valid QRCode from this region."));
|
||||||
// continue;
|
|
||||||
} else {
|
} else {
|
||||||
vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE);
|
vmessConnectionStringTxt->appendPlainText(str.trimmed() + NEWLINE);
|
||||||
//hasVmessDetected = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
|
||||||
//if (!hasVmessDetected) {
|
|
||||||
//QvMessageBox(this, tr("QRCode scanning failed"), tr("Cannot find any QRCode from any screens."));
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportConfigWindow::on_beginImportBtn_clicked()
|
void ImportConfigWindow::on_beginImportBtn_clicked()
|
||||||
{
|
{
|
||||||
QString aliasPrefix = nameTxt->text();
|
QString aliasPrefix = nameTxt->text();
|
||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
auto conf = GetGlobalConfig();
|
//auto conf = GetGlobalConfig();
|
||||||
|
|
||||||
switch (importSourceCombo->currentIndex()) {
|
switch (importSourceCombo->currentIndex()) {
|
||||||
case 0: {
|
case 0: {
|
||||||
// From File...
|
// From File...
|
||||||
bool overrideInBound = !keepImportedInboundCheckBox->isChecked();
|
bool keepInBound = keepImportedInboundCheckBox->isChecked();
|
||||||
QString path = fileLineTxt->text();
|
QString path = fileLineTxt->text();
|
||||||
aliasPrefix = aliasPrefix.isEmpty() ? aliasPrefix : QFileInfo(path).fileName();
|
aliasPrefix = aliasPrefix.isEmpty() ? aliasPrefix : QFileInfo(path).fileName();
|
||||||
config = ConvertConfigFromFile(path, overrideInBound);
|
config = ConvertConfigFromFile(path, keepInBound);
|
||||||
|
|
||||||
if (config.isEmpty()) {
|
if (config.isEmpty()) {
|
||||||
QvMessageBox(this, tr("Import config file"), tr("Import from file failed, for more information, please check the log file."));
|
QvMessageBox(this, tr("Import config file"), tr("Import from file failed, for more information, please check the log file."));
|
||||||
@ -91,14 +83,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
|||||||
QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file."));
|
QvMessageBox(this, tr("Import config file"), tr("Failed to check the validity of the config file."));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// We save first, "alias" may change to prevent override existing file.
|
connections[aliasPrefix] = config;
|
||||||
bool alwaysFalse = SaveConnectionConfig(config, &aliasPrefix, false);
|
|
||||||
|
|
||||||
if (alwaysFalse) {
|
|
||||||
QvMessageBox(this, tr("Assertion Failed"), tr("Assertion failed: ::SaveConnectionConfig should returns false."));
|
|
||||||
}
|
|
||||||
|
|
||||||
conf.configs.push_back(aliasPrefix.toStdString());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,13 +110,7 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
|||||||
vmessErrors[vmess] = QString::number(vmessErrors.count() + 1) + ": " + errMessage;
|
vmessErrors[vmess] = QString::number(vmessErrors.count() + 1) + ": " + errMessage;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
bool alwaysFalse = SaveConnectionConfig(config, &aliasPrefix, false);
|
connections[aliasPrefix] = config;
|
||||||
|
|
||||||
if (alwaysFalse) {
|
|
||||||
QvMessageBox(this, tr("Assertion Failed"), "Assertion failed: ::SaveConnectionConfig should returns false.");
|
|
||||||
}
|
|
||||||
|
|
||||||
conf.configs.push_back(aliasPrefix.toStdString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,24 +120,19 @@ void ImportConfigWindow::on_beginImportBtn_clicked()
|
|||||||
vmessConnectionStringTxt->appendPlainText(vmessErrors.key(item));
|
vmessConnectionStringTxt->appendPlainText(vmessErrors.key(item));
|
||||||
errorsList->addItem(item);
|
errorsList->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't quit;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2: {
|
case 2: {
|
||||||
|
QvMessageBox(this, tr("TODO"), tr("TODO"));
|
||||||
// Subscription link.
|
// Subscription link.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetGlobalConfig(conf);
|
accept();
|
||||||
// Never restart current connection after import.
|
|
||||||
emit s_reload_config(false);
|
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
void ImportConfigWindow::on_selectImageBtn_clicked()
|
void ImportConfigWindow::on_selectImageBtn_clicked()
|
||||||
{
|
{
|
||||||
@ -197,7 +171,7 @@ void ImportConfigWindow::on_errorsList_currentItemChanged(QListWidgetItem *curre
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Select vmess string that is invalid.
|
||||||
QTextCursor c = vmessConnectionStringTxt->textCursor();
|
QTextCursor c = vmessConnectionStringTxt->textCursor();
|
||||||
c.setPosition(startPos);
|
c.setPosition(startPos);
|
||||||
c.setPosition(endPos, QTextCursor::KeepAnchor);
|
c.setPosition(endPos, QTextCursor::KeepAnchor);
|
||||||
@ -218,8 +192,7 @@ void ImportConfigWindow::on_editFileBtn_clicked()
|
|||||||
if (!jsonCheckingError.isEmpty()) {
|
if (!jsonCheckingError.isEmpty()) {
|
||||||
LOG(MODULE_FILE, "Currupted JSON file detected")
|
LOG(MODULE_FILE, "Currupted JSON file detected")
|
||||||
|
|
||||||
if (QvMessageBoxAsk(this, tr("Edit file as JSON"), tr("The file you selected has json syntax error. Continue editing may make you lose data. Would you like to continue?") +
|
if (QvMessageBoxAsk(this, tr("Edit file as JSON"), tr("The file you selected has json syntax error. Continue editing may make you lose data. Would you like to continue?") + NEWLINE + jsonCheckingError) != QMessageBox::Yes) {
|
||||||
NEWLINE + jsonCheckingError) != QMessageBox::Yes) {
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LOG(MODULE_FILE, "Continue editing curruped json file, data loss is expected.")
|
LOG(MODULE_FILE, "Continue editing curruped json file, data loss is expected.")
|
||||||
@ -257,13 +230,15 @@ void ImportConfigWindow::on_connectionEditBtn_clicked()
|
|||||||
root.insert("outbounds", outboundsList);
|
root.insert("outbounds", outboundsList);
|
||||||
//
|
//
|
||||||
// WARN This one will change the connection name, because of some duplicates.
|
// WARN This one will change the connection name, because of some duplicates.
|
||||||
SaveConnectionConfig(root, &alias, false);
|
connections[alias] = root;
|
||||||
|
//SaveConnectionConfig(root, &alias, false);
|
||||||
//
|
//
|
||||||
auto conf = GetGlobalConfig();
|
// WARN Add connection here
|
||||||
auto connectionList = conf.configs;
|
//auto conf = GetGlobalConfig();
|
||||||
connectionList.push_back(alias.toStdString());
|
//auto connectionList = conf.configs;
|
||||||
conf.configs = connectionList;
|
//connectionList.push_back(alias.toStdString());
|
||||||
SetGlobalConfig(conf);
|
//conf.configs = connectionList;
|
||||||
|
//SetGlobalConfig(conf);
|
||||||
close();
|
close();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define IMPORTCONF_H
|
#define IMPORTCONF_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QString>
|
||||||
|
#include <QJsonObject>
|
||||||
#include "ui_w_ImportConfig.h"
|
#include "ui_w_ImportConfig.h"
|
||||||
|
|
||||||
class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
|
class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
|
||||||
@ -11,8 +13,7 @@ class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
|
|||||||
public:
|
public:
|
||||||
explicit ImportConfigWindow(QWidget *parent = nullptr);
|
explicit ImportConfigWindow(QWidget *parent = nullptr);
|
||||||
~ImportConfigWindow() { }
|
~ImportConfigWindow() { }
|
||||||
signals:
|
QMap<QString, QJsonObject> OpenImport(bool outboundsOnly = false);
|
||||||
void s_reload_config(bool need_restart);
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_importSourceCombo_currentIndexChanged(int index);
|
void on_importSourceCombo_currentIndexChanged(int index);
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
|
|||||||
void on_cancelImportBtn_clicked();
|
void on_cancelImportBtn_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QMap<QString, QJsonObject> connections;
|
||||||
QMap<QString, QString> vmessErrors;
|
QMap<QString, QString> vmessErrors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,9 +24,13 @@ InboundEditor::InboundEditor(QJsonObject root, QWidget *parent) :
|
|||||||
} else if (inboundType == "mtproto") {
|
} else if (inboundType == "mtproto") {
|
||||||
mtSettings = root["settings"].toObject();
|
mtSettings = root["settings"].toObject();
|
||||||
} else {
|
} else {
|
||||||
LOG(MODULE_UI, "Unsupported inbound type: " + inboundType.toStdString() + ", decisions should be made if to open JSONEDITOR")
|
if (!root["protocol"].toString().isEmpty()) {
|
||||||
QvMessageBox(this, tr("Inbound type not supported"), tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" +
|
LOG(MODULE_UI, "Unsupported inbound type: " + inboundType.toStdString())
|
||||||
tr("Inbound: ") + inboundType);
|
QvMessageBox(this, tr("Inbound type not supported"), tr("The inbound type is not supported by Qv2ray (yet). Please use JsonEditor to change the settings") + "\r\n" +
|
||||||
|
tr("Inbound: ") + inboundType);
|
||||||
|
} else {
|
||||||
|
LOG(MODULE_UI, "Creating new inbound config")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadUIData();
|
LoadUIData();
|
||||||
@ -61,7 +65,10 @@ QJsonObject InboundEditor::GenerateNewRoot()
|
|||||||
void InboundEditor::LoadUIData()
|
void InboundEditor::LoadUIData()
|
||||||
{
|
{
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
strategyCombo->setCurrentText(allocate["strategy"].toString());
|
auto x = allocate["strategy"].toString();
|
||||||
|
allocate["strategy"] = x.isEmpty() ? "always" : x;
|
||||||
|
strategyCombo->setCurrentText(x);
|
||||||
|
//
|
||||||
refreshNumberBox->setValue(allocate["refresh"].toInt());
|
refreshNumberBox->setValue(allocate["refresh"].toInt());
|
||||||
concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
|
concurrencyNumberBox->setValue(allocate["concurrency"].toInt());
|
||||||
enableSniffingCB->setChecked(sniffing["enabled"].toBool());
|
enableSniffingCB->setChecked(sniffing["enabled"].toBool());
|
||||||
|
@ -65,6 +65,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
//
|
//
|
||||||
QAction *action_RCM_RenameConnection = new QAction(tr("Rename"), this);
|
QAction *action_RCM_RenameConnection = new QAction(tr("Rename"), this);
|
||||||
QAction *action_RCM_StartThis = new QAction(tr("Connect to this"), this);
|
QAction *action_RCM_StartThis = new QAction(tr("Connect to this"), this);
|
||||||
|
QAction *action_RCM_ConvToComplex = new QAction(tr("Edit as Complex Config"), this);
|
||||||
QAction *action_RCM_EditJson = new QAction(QICON_R("json.png"), tr("Edit as Json"), this);
|
QAction *action_RCM_EditJson = new QAction(QICON_R("json.png"), tr("Edit as Json"), this);
|
||||||
QAction *action_RCM_ShareQR = new QAction(QICON_R("share.png"), tr("Share as QRCode/VMess URL"), this);
|
QAction *action_RCM_ShareQR = new QAction(QICON_R("share.png"), tr("Share as QRCode/VMess URL"), this);
|
||||||
//
|
//
|
||||||
@ -88,6 +89,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
connect(action_RCM_RenameConnection, &QAction::triggered, this, &MainWindow::on_action_RenameConnection_triggered);
|
connect(action_RCM_RenameConnection, &QAction::triggered, this, &MainWindow::on_action_RenameConnection_triggered);
|
||||||
connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered);
|
connect(action_RCM_StartThis, &QAction::triggered, this, &MainWindow::on_action_StartThis_triggered);
|
||||||
connect(action_RCM_EditJson, &QAction::triggered, this, &MainWindow::on_action_RCM_EditJson_triggered);
|
connect(action_RCM_EditJson, &QAction::triggered, this, &MainWindow::on_action_RCM_EditJson_triggered);
|
||||||
|
connect(action_RCM_ConvToComplex, &QAction::triggered, this, &MainWindow::on_action_RCM_ConvToComplex_triggered);
|
||||||
//
|
//
|
||||||
// Share optionss
|
// Share optionss
|
||||||
connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered);
|
connect(action_RCM_ShareQR, &QAction::triggered, this, &MainWindow::on_action_RCM_ShareQR_triggered);
|
||||||
@ -102,6 +104,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
listMenu = new QMenu(this);
|
listMenu = new QMenu(this);
|
||||||
listMenu->addAction(action_RCM_RenameConnection);
|
listMenu->addAction(action_RCM_RenameConnection);
|
||||||
listMenu->addAction(action_RCM_StartThis);
|
listMenu->addAction(action_RCM_StartThis);
|
||||||
|
listMenu->addAction(action_RCM_ConvToComplex);
|
||||||
listMenu->addAction(action_RCM_EditJson);
|
listMenu->addAction(action_RCM_EditJson);
|
||||||
listMenu->addAction(action_RCM_ShareQR);
|
listMenu->addAction(action_RCM_ShareQR);
|
||||||
//
|
//
|
||||||
@ -308,8 +311,6 @@ void MainWindow::on_startButton_clicked()
|
|||||||
bool httpEnabled = conf.inboundConfig.useHTTP;
|
bool httpEnabled = conf.inboundConfig.useHTTP;
|
||||||
bool socksEnabled = conf.inboundConfig.useSocks;
|
bool socksEnabled = conf.inboundConfig.useSocks;
|
||||||
|
|
||||||
// TODO: Set PAC proxy string
|
|
||||||
|
|
||||||
if (usePAC) {
|
if (usePAC) {
|
||||||
bool canStartPAC = true;
|
bool canStartPAC = true;
|
||||||
QString pacProxyString; // Something like this --> SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT; http://proxy:8080
|
QString pacProxyString; // Something like this --> SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT; http://proxy:8080
|
||||||
@ -498,35 +499,44 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect
|
|||||||
// Check empty again...
|
// Check empty again...
|
||||||
if (guiConnectionName.isEmpty()) return;
|
if (guiConnectionName.isEmpty()) return;
|
||||||
|
|
||||||
// --------- BRGIN Show Connection
|
|
||||||
auto root = connections[guiConnectionName];
|
|
||||||
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
|
|
||||||
//
|
//
|
||||||
auto outboundType = outBoundRoot["protocol"].toString();
|
|
||||||
_OutBoundTypeLabel->setText(outboundType);
|
|
||||||
removeConfigButton->setEnabled(true);
|
removeConfigButton->setEnabled(true);
|
||||||
editConfigButton->setEnabled(true);
|
editConfigButton->setEnabled(true);
|
||||||
editJsonBtn->setEnabled(true);
|
editJsonBtn->setEnabled(true);
|
||||||
duplicateBtn->setEnabled(true);
|
duplicateBtn->setEnabled(true);
|
||||||
|
//
|
||||||
|
// --------- BRGIN Show Connection
|
||||||
|
auto root = connections[guiConnectionName];
|
||||||
|
//
|
||||||
|
auto isComplexConfig = root["routing"].toObject()["rules"].toArray().count() > 0;
|
||||||
|
routeCountLabel->setText(isComplexConfig > 0 ? tr("Complex") : tr("Simple"));
|
||||||
|
|
||||||
if (outboundType == "vmess") {
|
if (isComplexConfig) {
|
||||||
auto Server = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
|
_OutBoundTypeLabel->setText(tr("N/A"));
|
||||||
_hostLabel->setText(QSTRING(Server.address));
|
_hostLabel->setText(tr("N/A"));
|
||||||
_portLabel->setText(QSTRING(to_string(Server.port)));
|
_portLabel->setText(tr("N/A"));
|
||||||
} else if (outboundType == "shadowsocks") {
|
} else {
|
||||||
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
|
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
|
||||||
auto Server = StructFromJsonString<ShadowSocksServerObject>(x);
|
auto outboundType = outBoundRoot["protocol"].toString();
|
||||||
_hostLabel->setText(QSTRING(Server.address));
|
_OutBoundTypeLabel->setText(outboundType);
|
||||||
_portLabel->setText(QSTRING(to_string(Server.port)));
|
|
||||||
} else if (outboundType == "socks") {
|
if (outboundType == "vmess") {
|
||||||
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
|
auto Server = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
|
||||||
auto Server = StructFromJsonString<SocksServerObject>(x);
|
_hostLabel->setText(QSTRING(Server.address));
|
||||||
_hostLabel->setText(QSTRING(Server.address));
|
_portLabel->setText(QSTRING(to_string(Server.port)));
|
||||||
_portLabel->setText(QSTRING(to_string(Server.port)));
|
} else if (outboundType == "shadowsocks") {
|
||||||
|
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
|
||||||
|
auto Server = StructFromJsonString<ShadowSocksServerObject>(x);
|
||||||
|
_hostLabel->setText(QSTRING(Server.address));
|
||||||
|
_portLabel->setText(QSTRING(to_string(Server.port)));
|
||||||
|
} else if (outboundType == "socks") {
|
||||||
|
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
|
||||||
|
auto Server = StructFromJsonString<SocksServerObject>(x);
|
||||||
|
_hostLabel->setText(QSTRING(Server.address));
|
||||||
|
_portLabel->setText(QSTRING(to_string(Server.port)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
routeCountLabel->setText(QString::number(root["routing"].toObject()["rules"].toArray().count()));
|
|
||||||
|
|
||||||
// --------- END Show Connection
|
// --------- END Show Connection
|
||||||
//
|
//
|
||||||
// Set Connection
|
// Set Connection
|
||||||
@ -660,8 +670,22 @@ void MainWindow::on_removeConfigButton_clicked()
|
|||||||
}
|
}
|
||||||
void MainWindow::on_importConfigButton_clicked()
|
void MainWindow::on_importConfigButton_clicked()
|
||||||
{
|
{
|
||||||
|
// BETA
|
||||||
ImportConfigWindow *w = new ImportConfigWindow(this);
|
ImportConfigWindow *w = new ImportConfigWindow(this);
|
||||||
w->exec();
|
auto configs = w->OpenImport();
|
||||||
|
auto gConf = GetGlobalConfig();
|
||||||
|
|
||||||
|
for (auto conf : configs) {
|
||||||
|
auto name = configs.key(conf, "");
|
||||||
|
|
||||||
|
if (name.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SaveConnectionConfig(conf, &name, false);
|
||||||
|
gConf.configs.push_back(name.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
SetGlobalConfig(gConf);
|
||||||
OnConfigListChanged(false);
|
OnConfigListChanged(false);
|
||||||
}
|
}
|
||||||
void MainWindow::on_editConfigButton_clicked()
|
void MainWindow::on_editConfigButton_clicked()
|
||||||
@ -677,7 +701,7 @@ void MainWindow::on_editConfigButton_clicked()
|
|||||||
QJsonObject root;
|
QJsonObject root;
|
||||||
bool isChanged = false;
|
bool isChanged = false;
|
||||||
|
|
||||||
if (outBoundRoot["outbounds"].toArray().count() > 1) {
|
if (CheckIsComplexConfig(outBoundRoot)) {
|
||||||
LOG(MODULE_UI, "INFO: Opening route editor.")
|
LOG(MODULE_UI, "INFO: Opening route editor.")
|
||||||
RouteEditor *routeWindow = new RouteEditor(outBoundRoot, this);
|
RouteEditor *routeWindow = new RouteEditor(outBoundRoot, this);
|
||||||
root = routeWindow->OpenEditor();
|
root = routeWindow->OpenEditor();
|
||||||
@ -705,6 +729,34 @@ void MainWindow::on_reconnectButton_clicked()
|
|||||||
on_stopButton_clicked();
|
on_stopButton_clicked();
|
||||||
on_startButton_clicked();
|
on_startButton_clicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_action_RCM_ConvToComplex_triggered()
|
||||||
|
{
|
||||||
|
// Check if we have a connection selected...
|
||||||
|
if (connectionListWidget->currentIndex().row() < 0) {
|
||||||
|
QvMessageBox(this, tr("No Config Selected"), tr("Please Select a Config"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto alias = connectionListWidget->currentItem()->text();
|
||||||
|
auto outBoundRoot = connections[alias];
|
||||||
|
QJsonObject root;
|
||||||
|
bool isChanged = false;
|
||||||
|
//
|
||||||
|
LOG(MODULE_UI, "INFO: Opening route editor.")
|
||||||
|
RouteEditor *routeWindow = new RouteEditor(outBoundRoot, this);
|
||||||
|
root = routeWindow->OpenEditor();
|
||||||
|
isChanged = routeWindow->result() == QDialog::Accepted;
|
||||||
|
|
||||||
|
if (isChanged) {
|
||||||
|
connections[alias] = root;
|
||||||
|
// true indicates the alias will NOT change
|
||||||
|
SaveConnectionConfig(root, &alias, true);
|
||||||
|
OnConfigListChanged(alias == CurrentConnectionName);
|
||||||
|
ShowAndSetConnection(CurrentConnectionName, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_action_RCM_EditJson_triggered()
|
void MainWindow::on_action_RCM_EditJson_triggered()
|
||||||
{
|
{
|
||||||
// Check if we have a connection selected...
|
// Check if we have a connection selected...
|
||||||
@ -745,10 +797,9 @@ void MainWindow::on_shareBtn_clicked()
|
|||||||
auto alias = connectionListWidget->currentItem()->text();
|
auto alias = connectionListWidget->currentItem()->text();
|
||||||
auto root = connections[alias];
|
auto root = connections[alias];
|
||||||
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
|
auto outBoundRoot = root["outbounds"].toArray().first().toObject();
|
||||||
//
|
|
||||||
auto outboundType = outBoundRoot["protocol"].toString();
|
auto outboundType = outBoundRoot["protocol"].toString();
|
||||||
|
|
||||||
if (outboundType == "vmess") {
|
if (CheckIsComplexConfig(root) && outboundType == "vmess") {
|
||||||
auto vmessServer = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
|
auto vmessServer = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
|
||||||
auto transport = StructFromJsonString<StreamSettingsObject>(JsonToString(outBoundRoot["streamSettings"].toObject()));
|
auto transport = StructFromJsonString<StreamSettingsObject>(JsonToString(outBoundRoot["streamSettings"].toObject()));
|
||||||
auto vmess = ConvertConfigToVMessString(transport, vmessServer, alias);
|
auto vmess = ConvertConfigToVMessString(transport, vmessServer, alias);
|
||||||
|
@ -90,6 +90,7 @@ class MainWindow : public QMainWindow, Ui::MainWindow
|
|||||||
//
|
//
|
||||||
void on_action_StartThis_triggered();
|
void on_action_StartThis_triggered();
|
||||||
void on_action_RCM_EditJson_triggered();
|
void on_action_RCM_EditJson_triggered();
|
||||||
|
void on_action_RCM_ConvToComplex_triggered();
|
||||||
void on_action_RenameConnection_triggered();
|
void on_action_RenameConnection_triggered();
|
||||||
//
|
//
|
||||||
QvHttpRequestHelper HTTPRequestHelper;
|
QvHttpRequestHelper HTTPRequestHelper;
|
||||||
|
@ -331,26 +331,12 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>Mux</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLabel" name="muxLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_7">
|
<widget class="QLabel" name="label_7">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Actions</string>
|
<string>Operations</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -387,6 +373,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pingTestBtn">
|
<widget class="QPushButton" name="pingTestBtn">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Ping Test</string>
|
<string>Ping Test</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "w_OutboundEditor.hpp"
|
#include "w_OutboundEditor.hpp"
|
||||||
#include "w_MainWindow.hpp"
|
#include "w_MainWindow.hpp"
|
||||||
#include "w_JsonEditor.hpp"
|
#include "w_JsonEditor.hpp"
|
||||||
|
#include "w_RoutesEditor.hpp"
|
||||||
|
|
||||||
OutboundEditor::OutboundEditor(QWidget *parent)
|
OutboundEditor::OutboundEditor(QWidget *parent)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4" columnstretch="8,3">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QFormLayout" name="formLayout_5">
|
<layout class="QFormLayout" name="formLayout_5">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
@ -327,7 +327,7 @@
|
|||||||
<item row="3" column="5">
|
<item row="3" column="5">
|
||||||
<widget class="QPushButton" name="tcpRespDefBtn">
|
<widget class="QPushButton" name="tcpRespDefBtn">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Default Value</string>
|
<string>Default</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -428,7 +428,7 @@
|
|||||||
<item row="3" column="2">
|
<item row="3" column="2">
|
||||||
<widget class="QPushButton" name="tcpRequestDefBtn">
|
<widget class="QPushButton" name="tcpRequestDefBtn">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Default Value</string>
|
<string>Default</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -1045,15 +1045,19 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<property name="orientation">
|
<item>
|
||||||
<enum>Qt::Horizontal</enum>
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
</property>
|
<property name="orientation">
|
||||||
<property name="standardButtons">
|
<enum>Qt::Horizontal</enum>
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
</property>
|
||||||
</property>
|
<property name="standardButtons">
|
||||||
</widget>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "w_RoutesEditor.hpp"
|
#include "w_RoutesEditor.hpp"
|
||||||
#include "QvCoreConfigOperations.hpp"
|
#include "QvCoreConfigOperations.hpp"
|
||||||
#include "w_OutboundEditor.hpp"
|
#include "w_OutboundEditor.hpp"
|
||||||
#include "w_JsonEditor.hpp"
|
#include "w_JsonEditor.hpp"
|
||||||
#include "w_InboundEditor.hpp"
|
#include "w_InboundEditor.hpp"
|
||||||
|
#include "w_ImportConfig.hpp"
|
||||||
|
|
||||||
static bool isLoading = false;
|
static bool isLoading = false;
|
||||||
#define CurrentRule this->rules[this->currentRuleIndex]
|
#define CurrentRule this->rules[this->currentRuleIndex]
|
||||||
#define STATUS(msg) statusLabel->setText(tr(msg));
|
|
||||||
#define LOADINGCHECK if(isLoading) return;
|
#define LOADINGCHECK if(isLoading) return;
|
||||||
|
|
||||||
RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
|
RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
|
||||||
@ -318,9 +318,9 @@ void RouteEditor::ShowRuleDetail(RuleObject rule)
|
|||||||
|
|
||||||
inboundsList->item(_index)->setCheckState(Qt::Checked);
|
inboundsList->item(_index)->setCheckState(Qt::Checked);
|
||||||
inboundsList->setCurrentRow(_index);
|
inboundsList->setCurrentRow(_index);
|
||||||
STATUS("OK")
|
statusLabel->setText(tr("OK"));
|
||||||
} else {
|
} else {
|
||||||
STATUS("Cannot find inbound by a tag, possible currupted files?")
|
statusLabel->setText(tr("Cannot find inbound by a tag, possible currupted files?"));
|
||||||
LOG(MODULE_UI, "An inbound could not be determined by tag.")
|
LOG(MODULE_UI, "An inbound could not be determined by tag.")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -335,7 +335,7 @@ void RouteEditor::on_editOutboundBtn_clicked()
|
|||||||
int row = outboundsList->currentRow();
|
int row = outboundsList->currentRow();
|
||||||
|
|
||||||
if (row < 0) {
|
if (row < 0) {
|
||||||
STATUS("No row selected.")
|
statusLabel->setText(tr("No row selected."));
|
||||||
LOG(MODULE_UI, "No outbound row selected.")
|
LOG(MODULE_UI, "No outbound row selected.")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -348,19 +348,19 @@ void RouteEditor::on_editOutboundBtn_clicked()
|
|||||||
tr("This outbound entry is not supported by the GUI editor.") + "\r\n" +
|
tr("This outbound entry is not supported by the GUI editor.") + "\r\n" +
|
||||||
tr("We will launch Json Editor instead."));
|
tr("We will launch Json Editor instead."));
|
||||||
JsonEditor *w = new JsonEditor(currentOutbound, this);
|
JsonEditor *w = new JsonEditor(currentOutbound, this);
|
||||||
STATUS("Opening JSON editor")
|
statusLabel->setText(tr("Opening JSON editor"));
|
||||||
result = w->OpenEditor();
|
result = w->OpenEditor();
|
||||||
delete w;
|
delete w;
|
||||||
} else {
|
} else {
|
||||||
OutboundEditor *w = new OutboundEditor(currentOutbound, this);
|
OutboundEditor *w = new OutboundEditor(currentOutbound, this);
|
||||||
STATUS("Opening default outbound editor.")
|
statusLabel->setText(tr("Opening default outbound editor."));
|
||||||
result = w->OpenEditor();
|
result = w->OpenEditor();
|
||||||
delete w;
|
delete w;
|
||||||
}
|
}
|
||||||
|
|
||||||
outbounds[row] = result;
|
outbounds[row] = result;
|
||||||
on_outboundsList_currentRowChanged(row);
|
on_outboundsList_currentRowChanged(row);
|
||||||
STATUS("OK")
|
statusLabel->setText(tr("OK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_insertDirectBtn_clicked()
|
void RouteEditor::on_insertDirectBtn_clicked()
|
||||||
@ -370,7 +370,7 @@ void RouteEditor::on_insertDirectBtn_clicked()
|
|||||||
auto out = GenerateOutboundEntry("freedom", freedom, QJsonObject(), QJsonObject(), "0.0.0.0", tag);
|
auto out = GenerateOutboundEntry("freedom", freedom, QJsonObject(), QJsonObject(), "0.0.0.0", tag);
|
||||||
this->outbounds.append(out);
|
this->outbounds.append(out);
|
||||||
outboundsList->addItem(tag);
|
outboundsList->addItem(tag);
|
||||||
STATUS("Added DIRECT outbound")
|
statusLabel->setText(tr("Added DIRECT outbound"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_editInboundBtn_clicked()
|
void RouteEditor::on_editInboundBtn_clicked()
|
||||||
@ -386,20 +386,20 @@ void RouteEditor::on_editInboundBtn_clicked()
|
|||||||
if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") {
|
if (protocol != "http" && protocol != "mtproto" && protocol != "socks" && protocol != "dokodemo-door") {
|
||||||
QvMessageBox(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" +
|
QvMessageBox(this, tr("Cannot Edit"), tr("Currently, this type of outbound is not supported by the editor.") + "\r\n" +
|
||||||
tr("We will launch Json Editor instead."));
|
tr("We will launch Json Editor instead."));
|
||||||
STATUS("Opening JSON editor")
|
statusLabel->setText(tr("Opening JSON editor"));
|
||||||
JsonEditor *w = new JsonEditor(currentInbound, this);
|
JsonEditor *w = new JsonEditor(currentInbound, this);
|
||||||
result = w->OpenEditor();
|
result = w->OpenEditor();
|
||||||
delete w;
|
delete w;
|
||||||
} else {
|
} else {
|
||||||
InboundEditor *w = new InboundEditor(currentInbound, this);
|
InboundEditor *w = new InboundEditor(currentInbound, this);
|
||||||
STATUS("Opening default inbound editor")
|
statusLabel->setText(tr("Opening default inbound editor"));
|
||||||
result = w->OpenEditor();
|
result = w->OpenEditor();
|
||||||
delete w;
|
delete w;
|
||||||
}
|
}
|
||||||
|
|
||||||
inbounds[row] = result;
|
inbounds[row] = result;
|
||||||
on_inboundsList_currentRowChanged(row);
|
on_inboundsList_currentRowChanged(row);
|
||||||
STATUS("OK")
|
statusLabel->setText(tr("OK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
|
void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
|
||||||
@ -414,7 +414,7 @@ void RouteEditor::on_routeProtocolHTTPCB_stateChanged(int arg1)
|
|||||||
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
|
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
|
||||||
|
|
||||||
CurrentRule.protocol = protocols.toStdList();
|
CurrentRule.protocol = protocols.toStdList();
|
||||||
STATUS("Protocol list changed.")
|
statusLabel->setText(tr("Protocol list changed."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
|
void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
|
||||||
@ -429,7 +429,7 @@ void RouteEditor::on_routeProtocolTLSCB_stateChanged(int arg1)
|
|||||||
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
|
if (routeProtocolBTCB->isChecked()) protocols << "bittorrent";
|
||||||
|
|
||||||
CurrentRule.protocol = protocols.toStdList();
|
CurrentRule.protocol = protocols.toStdList();
|
||||||
STATUS("Protocol list changed.")
|
statusLabel->setText(tr("Protocol list changed."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
|
void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
|
||||||
@ -444,7 +444,7 @@ void RouteEditor::on_routeProtocolBTCB_stateChanged(int arg1)
|
|||||||
if (routeProtocolTLSCB->isChecked()) protocols << "tls";
|
if (routeProtocolTLSCB->isChecked()) protocols << "tls";
|
||||||
|
|
||||||
CurrentRule.protocol = protocols.toStdList();
|
CurrentRule.protocol = protocols.toStdList();
|
||||||
STATUS("Protocol list changed.")
|
statusLabel->setText(tr("Protocol list changed."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_balabcerAddBtn_clicked()
|
void RouteEditor::on_balabcerAddBtn_clicked()
|
||||||
@ -460,9 +460,9 @@ void RouteEditor::on_balabcerAddBtn_clicked()
|
|||||||
if (!balancerTx.isEmpty()) {
|
if (!balancerTx.isEmpty()) {
|
||||||
balancerList->addItem(balancerTx);
|
balancerList->addItem(balancerTx);
|
||||||
balancerSelectionCombo->setEditText("");
|
balancerSelectionCombo->setEditText("");
|
||||||
STATUS("OK")
|
statusLabel->setText(tr("OK"));
|
||||||
} else {
|
} else {
|
||||||
STATUS("Balacer is empty, not processing.")
|
statusLabel->setText(tr("Balacer is empty, not processing."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +476,7 @@ void RouteEditor::on_balancerDelBtn_clicked()
|
|||||||
|
|
||||||
Balancers[QSTRING(CurrentRule.balancerTag)].removeAt(balancerList->currentRow());
|
Balancers[QSTRING(CurrentRule.balancerTag)].removeAt(balancerList->currentRow());
|
||||||
balancerList->takeItem(balancerList->currentRow());
|
balancerList->takeItem(balancerList->currentRow());
|
||||||
STATUS("Removed a balancer entry.")
|
statusLabel->setText(tr("Removed a balancer entry."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_hostList_textChanged()
|
void RouteEditor::on_hostList_textChanged()
|
||||||
@ -569,7 +569,7 @@ void RouteEditor::on_routesTable_cellChanged(int row, int column)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rules[row].QV2RAY_RULE_ENABLED = routesTable->item(row, column)->checkState() == Qt::Checked;
|
rules[row].QV2RAY_RULE_ENABLED = routesTable->item(row, column)->checkState() == Qt::Checked;
|
||||||
STATUS((rules[row].QV2RAY_RULE_ENABLED ? "Enabled a route" : "Disabled a route"))
|
statusLabel->setText(tr((rules[row].QV2RAY_RULE_ENABLED ? "Enabled a route" : "Disabled a route")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_netBothRB_clicked()
|
void RouteEditor::on_netBothRB_clicked()
|
||||||
@ -647,7 +647,7 @@ void RouteEditor::on_inboundsList_itemChanged(QListWidgetItem *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CurrentRule.inboundTag = new_inbounds.toStdList();
|
CurrentRule.inboundTag = new_inbounds.toStdList();
|
||||||
STATUS("OK")
|
statusLabel->setText(tr("OK"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouteEditor::on_delRouteBtn_clicked()
|
void RouteEditor::on_delRouteBtn_clicked()
|
||||||
@ -730,3 +730,35 @@ void RouteEditor::on_delInboundBtn_clicked()
|
|||||||
inbounds.removeAt(index);
|
inbounds.removeAt(index);
|
||||||
inboundsList->takeItem(index);
|
inboundsList->takeItem(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouteEditor::on_addInboundBtn_clicked()
|
||||||
|
{
|
||||||
|
LOADINGCHECK
|
||||||
|
InboundEditor w(QJsonObject(), this);
|
||||||
|
auto _result = w.OpenEditor();
|
||||||
|
inbounds.append(_result);
|
||||||
|
inboundsList->addItem(tr("New Inbound"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouteEditor::on_addOutboundBtn_clicked()
|
||||||
|
{
|
||||||
|
LOADINGCHECK
|
||||||
|
ImportConfigWindow *w = new ImportConfigWindow(this);
|
||||||
|
// True here for not keep the inbounds.
|
||||||
|
auto configs = w->OpenImport(true);
|
||||||
|
|
||||||
|
for (auto conf : configs) {
|
||||||
|
auto name = configs.key(conf, "");
|
||||||
|
|
||||||
|
if (name.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// conf is rootObject, needs to unwrap it.
|
||||||
|
auto confList = conf["outbounds"].toArray();
|
||||||
|
|
||||||
|
for (int i = 0; i < confList.count(); i++) {
|
||||||
|
outbounds.append(confList[i]);
|
||||||
|
outboundsList->addItem(name + "_" + QString::number(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifndef W_QVOUTBOUNDEDITOR_H
|
#ifndef W_QVOUTBOUNDEDITOR_H
|
||||||
#define W_QVOUTBOUNDEDITOR_H
|
#define W_QVOUTBOUNDEDITOR_H
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -80,12 +80,16 @@ class RouteEditor : public QDialog, private Ui::RouteEditor
|
|||||||
|
|
||||||
void on_delInboundBtn_clicked();
|
void on_delInboundBtn_clicked();
|
||||||
|
|
||||||
|
void on_addInboundBtn_clicked();
|
||||||
|
|
||||||
|
void on_addOutboundBtn_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ShowRuleDetail(RuleObject rule);
|
void ShowRuleDetail(RuleObject rule);
|
||||||
int currentRuleIndex;
|
int currentRuleIndex;
|
||||||
QString DomainStrategy;
|
|
||||||
QMap<QString, QStringList> Balancers;
|
QMap<QString, QStringList> Balancers;
|
||||||
QList<RuleObject> rules;
|
QList<RuleObject> rules;
|
||||||
|
QString DomainStrategy;
|
||||||
//
|
//
|
||||||
QJsonArray inbounds;
|
QJsonArray inbounds;
|
||||||
QJsonArray outbounds;
|
QJsonArray outbounds;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user