[change] USE STRONG TYPE NOW TO PREVENT MISUSE OF QJsonObject

Former-commit-id: 84d8167822
This commit is contained in:
Leroy.H.Y 2019-11-27 23:16:30 +08:00
parent 834dca8bf8
commit c6f70c1a60
18 changed files with 143 additions and 131 deletions

View File

@ -1 +1 @@
936
960

View File

@ -71,27 +71,11 @@
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define SAFE_TYPEDEF(Base, name) \
class name : public Base { \
public: \
template <class... Args> \
explicit name (Args... args) : Base(args...) {} \
const Base& raw() const { return *this; } \
};
namespace Qv2ray
{
// To prevent anonying QJsonObject misuse
SAFE_TYPEDEF(QJsonObject, INBOUND)
SAFE_TYPEDEF(QJsonObject, OUTBOUND)
SAFE_TYPEDEF(QJsonObject, ROOT)
SAFE_TYPEDEF(QJsonArray, OUTBOUNDS)
SAFE_TYPEDEF(QJsonArray, INBOUNDS)
SAFE_TYPEDEF(QJsonArray, ROUTING)
SAFE_TYPEDEF(QJsonObject, ROUTERULE)
//
// Extra header for QvConfigUpgrade.cpp
QJsonObject UpgradeConfig(int fromVersion, int toVersion, QJsonObject root);
CONFIGROOT UpgradeConfig(int fromVersion, int toVersion, CONFIGROOT root);
struct QvBarLine {
string Family;

View File

@ -10,7 +10,7 @@
namespace Qv2ray
{
// Private member
QJsonObject UpgradeConfig_Inc(int fromVersion, QJsonObject root)
CONFIGROOT UpgradeConfig_Inc(int fromVersion, CONFIGROOT root)
{
switch (fromVersion) {
case 1: {
@ -128,7 +128,7 @@ namespace Qv2ray
}
// Exported function
QJsonObject UpgradeConfig(int fromVersion, int toVersion, QJsonObject root)
CONFIGROOT UpgradeConfig(int fromVersion, int toVersion, CONFIGROOT root)
{
LOG(MODULE_CONFIG, "Migrating config from version " + to_string(fromVersion) + " to " + to_string(toVersion))

View File

@ -2,13 +2,39 @@
#define V2CONFIG_H
#include <list>
#include <string>
#include <QJsonObject>
#include <QJsonArray>
#include <x2struct/x2struct.hpp>
using namespace x2struct;
using namespace std;
/* ----------------------------------------- * ---------------------
* --------------------- * ----------------------------------------- */
#define SAFE_TYPEDEF(Base, name) \
class name : public Base { \
public: \
template <class... Args> \
explicit name (Args... args) : Base(args...) {} \
const Base& raw() const { return *this; } \
};
namespace Qv2ray
{
// To prevent anonying QJsonObject misuse
SAFE_TYPEDEF(QJsonObject, INBOUNDSETTING)
SAFE_TYPEDEF(QJsonObject, OUTBOUNDSETTING)
SAFE_TYPEDEF(QJsonObject, INBOUND)
SAFE_TYPEDEF(QJsonObject, OUTBOUND)
SAFE_TYPEDEF(QJsonObject, CONFIGROOT)
//
SAFE_TYPEDEF(QJsonArray, INOUTLIST)
SAFE_TYPEDEF(INOUTLIST, OUTBOUNDS)
SAFE_TYPEDEF(INOUTLIST, INBOUNDS)
SAFE_TYPEDEF(QJsonObject, ROUTING)
SAFE_TYPEDEF(QJsonObject, ROUTERULE)
SAFE_TYPEDEF(QJsonArray, ROUTERULELIST)
}
/* ----------------------------------------- */
namespace Qv2ray
{
@ -320,6 +346,7 @@ namespace Qv2ray
}
}
using namespace Qv2ray;
using namespace Qv2ray::V2ConfigModels;
using namespace Qv2ray::V2ConfigModels::Protocols;

View File

@ -5,20 +5,20 @@ namespace Qv2ray
namespace ConfigOperations
{
QMap<QString, QJsonObject> GetConnections(list<string> connectionNames)
QMap<QString, CONFIGROOT> GetConnections(list<string> connectionNames)
{
QMap<QString, QJsonObject> list;
QMap<QString, CONFIGROOT> list;
for (auto conn : connectionNames) {
QString jsonString = StringFromFile(new QFile(QV2RAY_CONFIG_DIR + QSTRING(conn) + QV2RAY_CONFIG_FILE_EXTENSION));
QJsonObject connectionObject = JsonFromString(jsonString);
CONFIGROOT connectionObject = CONFIGROOT(JsonFromString(jsonString));
list.insert(QString::fromStdString(conn), connectionObject);
}
return list;
}
bool CheckIsComplexConfig(QJsonObject root)
bool CheckIsComplexConfig(CONFIGROOT root)
{
bool cRouting = root.contains("routing");
bool cRule = cRouting && root["routing"].toObject().contains("rules");
@ -26,14 +26,15 @@ namespace Qv2ray
return cRules;
}
int StartPreparation(QJsonObject fullConfig)
int StartPreparation(CONFIGROOT fullConfig)
{
// Writes the final configuration to the disk.
QString json = JsonToString(fullConfig);
StringToFile(&json, new QFile(QV2RAY_GENERATED_FILE_PATH));
return 0;
}
int FindIndexByTag(QJsonArray list, QString *tag)
int FindIndexByTag(INOUTLIST list, QString *tag)
{
for (int i = 0; i < list.count(); i++) {
auto value = list[i].toObject();

View File

@ -16,10 +16,10 @@ namespace Qv2ray
// -------------------------- BEGIN GENERAL FUNCTIONS ----------------------------------------------
namespace ConfigOperations
{
QMap<QString, QJsonObject> GetConnections(list<string> connections);
bool CheckIsComplexConfig(QJsonObject root);
int StartPreparation(QJsonObject fullConfig);
int FindIndexByTag(QJsonArray list, QString *tag);
QMap<QString, CONFIGROOT> GetConnections(list<string> connections);
bool CheckIsComplexConfig(CONFIGROOT root);
int StartPreparation(CONFIGROOT fullConfig);
int FindIndexByTag(INOUTLIST list, QString *tag);
//
// -------------------------- BEGIN CONFIG CONVERSIONS --------------------------
@ -29,12 +29,12 @@ namespace Qv2ray
QString DecodeSubscriptionString(QByteArray arr);
//
// Save Connection Config
bool SaveConnectionConfig(QJsonObject obj, QString *alias, bool canOverrideExisting);
bool SaveConnectionConfig(CONFIGROOT obj, QString *alias, bool canOverrideExisting);
bool RemoveConnection(const QString &alias);
bool RenameConnection(QString originalName, QString newName);
// VMess URI Protocol
QJsonObject ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage);
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds);
CONFIGROOT ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage);
CONFIGROOT ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds);
QString ConvertConfigToVMessString(const StreamSettingsObject &transfer, const VMessServerObject &serverConfig, const QString &alias);
}
@ -42,26 +42,26 @@ namespace Qv2ray
// -------------------------- BEGIN CONFIG GENERATIONS ---------------------------------------------
namespace Generation
{
QJsonObject GenerateRoutes(bool enableProxy, bool cnProxy);
QJsonObject GenerateSingleRouteRule(QStringList list, bool isDomain, QString outboundTag, QString type = "field");
ROUTING GenerateRoutes(bool enableProxy, bool cnProxy);
ROUTERULE GenerateSingleRouteRule(QStringList list, bool isDomain, QString outboundTag, QString type = "field");
QJsonObject GenerateDNS(bool withLocalhost, QStringList dnsServers);
QJsonObject GenerateAPIEntry(QString tag, bool withHandler = true, bool withLogger = true, bool withStats = true);
//
// Outbound Protocols
QJsonObject GenerateFreedomOUT(QString domainStrategy, QString redirect, int userLevel);
QJsonObject GenerateBlackHoleOUT(bool useHTTP);
QJsonObject GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level);
QJsonObject GenerateShadowSocksOUT(QList<QJsonObject> servers);
OUTBOUNDSETTING GenerateFreedomOUT(QString domainStrategy, QString redirect, int userLevel);
OUTBOUNDSETTING GenerateBlackHoleOUT(bool useHTTP);
OUTBOUNDSETTING GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level);
OUTBOUNDSETTING GenerateShadowSocksOUT(QList<QJsonObject> servers);
//
// Inbounds Protocols
QJsonObject GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel);
QJsonObject GenerateHTTPIN(QList<AccountObject> accounts, int timeout = 300, bool allowTransparent = true, int userLevel = 0);
QJsonObject GenerateSocksIN(QString auth, QList<AccountObject> _accounts, bool udp = false, QString ip = "127.0.0.1", int userLevel = 0);
INBOUNDSETTING GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel);
INBOUNDSETTING GenerateHTTPIN(QList<AccountObject> accounts, int timeout = 300, bool allowTransparent = true, int userLevel = 0);
INBOUNDSETTING GenerateSocksIN(QString auth, QList<AccountObject> _accounts, bool udp = false, QString ip = "127.0.0.1", int userLevel = 0);
//
// Generate FINAL Configs
QJsonObject GenerateRuntimeConfig(QJsonObject root);
QJsonObject GenerateOutboundEntry(QString protocol, QJsonObject settings, QJsonObject streamSettings, QJsonObject mux = QJsonObject(), QString sendThrough = "0.0.0.0", QString tag = "");
QJsonObject GenerateInboundEntry(QString listen, int port, QString protocol, QJsonObject settings, QString tag, QJsonObject sniffing = QJsonObject(), QJsonObject allocate = QJsonObject());
CONFIGROOT GenerateRuntimeConfig(CONFIGROOT root);
OUTBOUND GenerateOutboundEntry(QString protocol, OUTBOUNDSETTING settings, QJsonObject streamSettings, QJsonObject mux = QJsonObject(), QString sendThrough = "0.0.0.0", QString tag = "");
INBOUND GenerateInboundEntry(QString listen, int port, QString protocol, INBOUNDSETTING settings, QString tag, QJsonObject sniffing = QJsonObject(), QJsonObject allocate = QJsonObject());
}
}
}

View File

@ -55,7 +55,7 @@ namespace Qv2ray
//
/// Save Connection to a place, with checking if there's existing file.
/// If so, append "_N" to the name.
bool SaveConnectionConfig(QJsonObject obj, QString *alias, bool canOverrideExisting)
bool SaveConnectionConfig(CONFIGROOT obj, QString *alias, bool canOverrideExisting)
{
auto str = JsonToString(obj);
QFile *config = new QFile(QV2RAY_CONFIG_DIR + *alias + QV2RAY_CONFIG_FILE_EXTENSION);
@ -84,14 +84,14 @@ namespace Qv2ray
}
// This generates global config containing only one outbound....
QJsonObject ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage)
CONFIGROOT ConvertConfigFromVMessString(QString vmess, QString *alias, QString *errMessage)
{
// Reset errMessage
*errMessage = "";
if (!vmess.toLower().startsWith("vmess://")) {
*errMessage = QObject::tr("VMess string should start with 'vmess://'");
return QJsonObject();
return CONFIGROOT();
}
try {
@ -100,7 +100,7 @@ namespace Qv2ray
if (b64Str.isEmpty()) {
*errMessage = QObject::tr("VMess string should be a valid base64 string");
return QJsonObject();
return CONFIGROOT();
}
auto vmessString = Base64Decode(b64Str);
@ -108,14 +108,14 @@ namespace Qv2ray
if (!jsonErr.isEmpty()) {
*errMessage = jsonErr;
return QJsonObject();
return CONFIGROOT();
}
auto vmessConf = JsonFromString(vmessString);
if (vmessConf.isEmpty()) {
*errMessage = QObject::tr("JSON should not be empty");
return QJsonObject();
return CONFIGROOT();
}
// C is a quick hack...
@ -140,11 +140,11 @@ namespace Qv2ray
} catch (exception *e) {
LOG(MODULE_CONNECTION_VMESS, "Failed to decode vmess string: " << e->what())
*errMessage = QSTRING(e->what());
return QJsonObject();
return CONFIGROOT();
}
// --------------------------------------------------------------------------------------
DROOT
CONFIGROOT root;
QStringRef vmessJsonB64(&vmess, 8, vmess.length() - 8);
auto vmessConf = JsonFromString(Base64Decode(vmessJsonB64.toString()));
//
@ -179,7 +179,7 @@ namespace Qv2ray
serv.users.push_back(user);
//
// VMess root config
QJsonObject vConf;
OUTBOUNDSETTING vConf;
QJsonArray vnextArray;
vnextArray.append(JsonFromString(StructToJsonString(serv)));
vConf["vnext"] = vnextArray;
@ -224,16 +224,16 @@ namespace Qv2ray
RROOT
}
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds)
CONFIGROOT ConvertConfigFromFile(QString sourceFilePath, bool keepInbounds)
{
QFile source(sourceFilePath);
if (!source.exists()) {
LOG(MODULE_FILE, "Trying to import from an non-existing file.")
return QJsonObject();
return CONFIGROOT();
}
auto root = JsonFromString(StringFromFile(&source));
auto root = CONFIGROOT(JsonFromString(StringFromFile(&source)));
if (!keepInbounds) {
JSON_ROOT_TRY_REMOVE("inbounds")
@ -246,14 +246,14 @@ namespace Qv2ray
return root;
}
QMap<QString, QJsonObject> GetConnections(list<string> connectionNames)
QMap<QString, CONFIGROOT> GetConnections(list<string> connectionNames)
{
QMap<QString, QJsonObject> list;
QMap<QString, CONFIGROOT> list;
for (auto conn : connectionNames) {
QString jsonString = StringFromFile(new QFile(QV2RAY_CONFIG_DIR + QSTRING(conn) + QV2RAY_CONFIG_FILE_EXTENSION));
QJsonObject connectionObject = JsonFromString(jsonString);
list.insert(QString::fromStdString(conn), connectionObject);
list.insert(QString::fromStdString(conn), CONFIGROOT(connectionObject));
}
return list;
@ -265,7 +265,7 @@ namespace Qv2ray
return QFile::rename(QV2RAY_CONFIG_DIR + originalName + QV2RAY_CONFIG_FILE_EXTENSION, QV2RAY_CONFIG_DIR + newName + QV2RAY_CONFIG_FILE_EXTENSION);
}
int StartPreparation(QJsonObject fullConfig)
int StartPreparation(CONFIGROOT fullConfig)
{
// Writes the final configuration to the disk.
QString json = JsonToString(fullConfig);

View File

@ -9,13 +9,13 @@ namespace Qv2ray
// Important config generation algorithms.
static const QStringList vLogLevels = {"none", "debug", "info", "warning", "error"};
// -------------------------- BEGIN CONFIG GENERATIONS ----------------------------------------------------------------------------
QJsonObject GenerateRoutes(bool enableProxy, bool proxyCN)
ROUTING GenerateRoutes(bool enableProxy, bool proxyCN)
{
DROOT
ROUTING root;
root.insert("domainStrategy", "IPIfNonMatch");
//
// For Rules list
QJsonArray rulesList;
ROUTERULELIST rulesList;
if (!enableProxy) {
// This is added to disable all proxies, as a alternative influence of #64
@ -35,32 +35,32 @@ namespace Qv2ray
RROOT
}
QJsonObject GenerateSingleRouteRule(QStringList list, bool isDomain, QString outboundTag, QString type)
ROUTERULE GenerateSingleRouteRule(QStringList list, bool isDomain, QString outboundTag, QString type)
{
DROOT
ROUTERULE root;
root.insert(isDomain ? "domain" : "ip", QJsonArray::fromStringList(list));
JADD(outboundTag, type)
RROOT
}
QJsonObject GenerateFreedomOUT(QString domainStrategy, QString redirect, int userLevel)
OUTBOUNDSETTING GenerateFreedomOUT(QString domainStrategy, QString redirect, int userLevel)
{
DROOT
OUTBOUNDSETTING root;
JADD(domainStrategy, redirect, userLevel)
RROOT
}
QJsonObject GenerateBlackHoleOUT(bool useHTTP)
OUTBOUNDSETTING GenerateBlackHoleOUT(bool useHTTP)
{
DROOT
OUTBOUNDSETTING root;
QJsonObject resp;
resp.insert("type", useHTTP ? "http" : "none");
root.insert("response", resp);
RROOT
}
QJsonObject GenerateShadowSocksOUT(QList<QJsonObject> servers)
OUTBOUNDSETTING GenerateShadowSocksOUT(QList<QJsonObject> servers)
{
DROOT
OUTBOUNDSETTING root;
QJsonArray x;
foreach (auto server, servers) {
@ -71,16 +71,16 @@ namespace Qv2ray
RROOT
}
QJsonObject GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level)
OUTBOUNDSETTING GenerateShadowSocksServerOUT(QString email, QString address, int port, QString method, QString password, bool ota, int level)
{
DROOT
OUTBOUNDSETTING root;
JADD(email, address, port, method, password, level, ota)
RROOT
}
QJsonObject GenerateDNS(bool withLocalhost, QStringList dnsServers)
{
DROOT
QJsonObject root;
QJsonArray servers(QJsonArray::fromStringList(dnsServers));
if (withLocalhost) {
@ -95,16 +95,16 @@ namespace Qv2ray
RROOT
}
QJsonObject GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel)
INBOUNDSETTING GenerateDokodemoIN(QString address, int port, QString network, int timeout, bool followRedirect, int userLevel)
{
DROOT
INBOUNDSETTING root;
JADD(address, port, network, timeout, followRedirect, userLevel)
RROOT
}
QJsonObject GenerateHTTPIN(QList<AccountObject> _accounts, int timeout, bool allowTransparent, int userLevel)
INBOUNDSETTING GenerateHTTPIN(QList<AccountObject> _accounts, int timeout, bool allowTransparent, int userLevel)
{
DROOT
INBOUNDSETTING root;
QJsonArray accounts;
foreach (auto account, _accounts) {
@ -115,9 +115,9 @@ namespace Qv2ray
RROOT
}
QJsonObject GenerateSocksIN(QString auth, QList<AccountObject> _accounts, bool udp, QString ip, int userLevel)
INBOUNDSETTING GenerateSocksIN(QString auth, QList<AccountObject> _accounts, bool udp, QString ip, int userLevel)
{
DROOT
INBOUNDSETTING root;
QJsonArray accounts;
foreach (auto acc, _accounts) {
@ -133,16 +133,16 @@ namespace Qv2ray
RROOT
}
QJsonObject GenerateOutboundEntry(QString protocol, QJsonObject settings, QJsonObject streamSettings, QJsonObject mux, QString sendThrough, QString tag)
OUTBOUND GenerateOutboundEntry(QString protocol, OUTBOUNDSETTING settings, QJsonObject streamSettings, QJsonObject mux, QString sendThrough, QString tag)
{
DROOT
OUTBOUND root;
JADD(sendThrough, protocol, settings, tag, streamSettings, mux)
RROOT
}
QJsonObject GenerateInboundEntry(QString listen, int port, QString protocol, QJsonObject settings, QString tag, QJsonObject sniffing, QJsonObject allocate)
INBOUND GenerateInboundEntry(QString listen, int port, QString protocol, INBOUNDSETTING settings, QString tag, QJsonObject sniffing, QJsonObject allocate)
{
DROOT
INBOUND root;
LOG(MODULE_CONNECTION, "allocation is not used here.")
Q_UNUSED(allocate)
JADD(listen, port, protocol, settings, tag, sniffing)
@ -151,7 +151,7 @@ namespace Qv2ray
QJsonObject GenerateAPIEntry(QString tag, bool withHandler, bool withLogger, bool withStats)
{
DROOT
QJsonObject root;
QJsonArray services;
if (withHandler)
@ -170,7 +170,7 @@ namespace Qv2ray
// -------------------------- END CONFIG GENERATIONS ------------------------------------------------------------------------------
// BEGIN RUNTIME CONFIG GENERATION
QJsonObject GenerateRuntimeConfig(QJsonObject root)
CONFIGROOT GenerateRuntimeConfig(CONFIGROOT root)
{
auto gConf = GetGlobalConfig();
QJsonObject logObject;
@ -191,11 +191,11 @@ namespace Qv2ray
root.insert("dns", dnsObject);
//
//
QJsonArray inboundsList;
INBOUNDS inboundsList;
// HTTP InBound
if (gConf.inboundConfig.http_port != 0) {
QJsonObject httpInBoundObject;
INBOUND httpInBoundObject;
httpInBoundObject.insert("listen", QString::fromStdString(gConf.inboundConfig.listenip));
httpInBoundObject.insert("port", gConf.inboundConfig.http_port);
httpInBoundObject.insert("protocol", "http");
@ -211,7 +211,7 @@ namespace Qv2ray
// SOCKS InBound
if (gConf.inboundConfig.socks_port != 0) {
QJsonObject socksInBoundObject;
INBOUND socksInBoundObject;
socksInBoundObject.insert("listen", QString::fromStdString(gConf.inboundConfig.listenip));
socksInBoundObject.insert("port", gConf.inboundConfig.socks_port);
socksInBoundObject.insert("protocol", "socks");
@ -240,8 +240,8 @@ namespace Qv2ray
//
// HOWEVER, we need to verify the QV2RAY_RULE_ENABLED entry.
// And what's more, process (by removing unused items) from a rule object.
QJsonObject routing = root["routing"].toObject();
QJsonArray rules;
ROUTING routing = ROUTING(root["routing"].toObject());
ROUTERULELIST rules;
LOG(MODULE_CONNECTION, "Processing an existing routing table.")
for (auto _a : routing["rules"].toArray()) {
@ -281,7 +281,7 @@ namespace Qv2ray
auto routeObject = GenerateRoutes(gConf.connectionConfig.enableProxy, gConf.connectionConfig.bypassCN);
root.insert("routing", routeObject);
QJsonArray outbounds = root["outbounds"].toArray();
OUTBOUNDS outbounds = OUTBOUNDS(root["outbounds"].toArray());
outbounds.append(GenerateOutboundEntry("freedom", GenerateFreedomOUT("AsIs", ":0", 0), QJsonObject(), QJsonObject(), "0.0.0.0", OUTBOUND_TAG_DIRECT));
root["outbounds"] = outbounds;
}
@ -320,8 +320,8 @@ namespace Qv2ray
//
// Inbounds
//
QJsonArray inbounds = root["inbounds"].toArray();
QJsonObject fakeDocodemoDoor;
INBOUNDS inbounds = INBOUNDS(root["inbounds"].toArray());
INBOUNDSETTING fakeDocodemoDoor;
fakeDocodemoDoor["address"] = "127.0.0.1";
QJsonObject apiInboundsRoot = GenerateInboundEntry("127.0.0.1", gConf.connectionConfig.statsPort, "dokodemo-door", fakeDocodemoDoor, QV2RAY_API_TAG_INBOUND);
inbounds.push_front(apiInboundsRoot);

View File

@ -197,7 +197,7 @@ int main(int argc, char *argv[])
return -1;
}
auto conf = JsonFromString(StringFromFile(new QFile(QV2RAY_CONFIG_FILE)));
auto conf = CONFIGROOT(JsonFromString(StringFromFile(new QFile(QV2RAY_CONFIG_FILE))));
//
auto confVersion = conf["config_version"].toVariant().toString();
auto newVersion = QSTRING(to_string(QV2RAY_CONFIG_VERSION));

View File

@ -24,13 +24,13 @@ ImportConfigWindow::ImportConfigWindow(QWidget *parent)
nameTxt->setText(QDateTime::currentDateTime().toString("MM-dd_hh-mm") + "_" + tr("Imported") + "_");
}
QMap<QString, QJsonObject> ImportConfigWindow::OpenImport(bool outboundsOnly)
QMap<QString, CONFIGROOT> 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>();
return this->result() == QDialog::Accepted ? connections : QMap<QString, CONFIGROOT>();
}
void ImportConfigWindow::on_importSourceCombo_currentIndexChanged(int index)
@ -65,7 +65,7 @@ void ImportConfigWindow::on_qrFromScreenBtn_clicked()
void ImportConfigWindow::on_beginImportBtn_clicked()
{
QString aliasPrefix = nameTxt->text();
QJsonObject config;
CONFIGROOT config;
//auto conf = GetGlobalConfig();
switch (importSourceCombo->currentIndex()) {
@ -224,9 +224,9 @@ void ImportConfigWindow::on_connectionEditBtn_clicked()
delete w;
if (isChanged) {
QJsonArray outboundsList;
OUTBOUNDS outboundsList;
outboundsList.push_back(outboundEntry);
QJsonObject root;
CONFIGROOT root;
root.insert("outbounds", outboundsList);
//
// WARN This one will change the connection name, because of some duplicates.

View File

@ -4,6 +4,7 @@
#include <QDialog>
#include <QString>
#include <QJsonObject>
#include "QvCoreConfigObjects.hpp"
#include "ui_w_ImportConfig.h"
class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
@ -13,7 +14,7 @@ class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
public:
explicit ImportConfigWindow(QWidget *parent = nullptr);
~ImportConfigWindow() { }
QMap<QString, QJsonObject> OpenImport(bool outboundsOnly = false);
QMap<QString, CONFIGROOT> OpenImport(bool outboundsOnly = false);
private slots:
void on_importSourceCombo_currentIndexChanged(int index);
@ -31,7 +32,7 @@ class ImportConfigWindow : public QDialog, private Ui::ImportConfigWindow
void on_cancelImportBtn_clicked();
private:
QMap<QString, QJsonObject> connections;
QMap<QString, CONFIGROOT> connections;
QMap<QString, QString> vmessErrors;
};

View File

@ -698,7 +698,7 @@ void MainWindow::on_editConfigButton_clicked()
auto alias = connectionListWidget->currentItem()->text();
auto outBoundRoot = connections[alias];
QJsonObject root;
CONFIGROOT root;
bool isChanged = false;
if (CheckIsComplexConfig(outBoundRoot)) {
@ -708,7 +708,7 @@ void MainWindow::on_editConfigButton_clicked()
isChanged = routeWindow->result() == QDialog::Accepted;
} else {
LOG(MODULE_UI, "INFO: Opening single connection edit window.")
OutboundEditor *w = new OutboundEditor(outBoundRoot["outbounds"].toArray().first().toObject(), this);
OutboundEditor *w = new OutboundEditor(OUTBOUND(outBoundRoot["outbounds"].toArray().first().toObject()), this);
auto outboundEntry = w->OpenEditor();
isChanged = w->result() == QDialog::Accepted;
QJsonArray outboundsList;
@ -740,7 +740,7 @@ void MainWindow::on_action_RCM_ConvToComplex_triggered()
auto alias = connectionListWidget->currentItem()->text();
auto outBoundRoot = connections[alias];
QJsonObject root;
CONFIGROOT root;
bool isChanged = false;
//
LOG(MODULE_UI, "INFO: Opening route editor.")
@ -767,7 +767,7 @@ void MainWindow::on_action_RCM_EditJson_triggered()
auto alias = connectionListWidget->currentItem()->text();
JsonEditor *w = new JsonEditor(connections[alias], this);
auto root = w->OpenEditor();
auto root = CONFIGROOT(w->OpenEditor());
bool isChanged = w->result() == QDialog::Accepted;
delete w;

View File

@ -68,7 +68,7 @@ class MainWindow : public QMainWindow, Ui::MainWindow
void on_duplicateBtn_clicked();
public:
QJsonObject CurrentFullConfig;
CONFIGROOT CurrentFullConfig;
QString CurrentConnectionName = "";
ConnectionInstance *vinstance;
QString totalDataUp;
@ -98,7 +98,7 @@ class MainWindow : public QMainWindow, Ui::MainWindow
//
QMenu *trayMenu = new QMenu(this);
QMenu *listMenu;
QMap<QString, QJsonObject> connections;
QMap<QString, CONFIGROOT> connections;
//
QString originalName;
bool isRenamingInProgress;

View File

@ -29,7 +29,7 @@ OutboundEditor::OutboundEditor(QWidget *parent)
Result = GenerateConnectionJson();
}
OutboundEditor::OutboundEditor(QJsonObject outboundEntry, QWidget *parent)
OutboundEditor::OutboundEditor(OUTBOUND outboundEntry, QWidget *parent)
: OutboundEditor(parent)
{
Original = outboundEntry;
@ -68,7 +68,7 @@ OutboundEditor::~OutboundEditor()
{
}
QJsonObject OutboundEditor::OpenEditor()
OUTBOUND OutboundEditor::OpenEditor()
{
int resultCode = this->exec();
return resultCode == QDialog::Accepted ? Result : Original;
@ -263,9 +263,9 @@ void OutboundEditor::on_tcpRespDefBtn_clicked()
tcpRespTxt->insertPlainText("{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
}
QJsonObject OutboundEditor::GenerateConnectionJson()
OUTBOUND OutboundEditor::GenerateConnectionJson()
{
QJsonObject settings;
OUTBOUNDSETTING settings;
auto streaming = JsonFromString(StructToJsonString(stream));
if (OutboundType == "vmess") {

View File

@ -11,9 +11,9 @@ class OutboundEditor : public QDialog, private Ui::OutboundEditor
Q_OBJECT
public:
explicit OutboundEditor(QWidget *parent = nullptr);
explicit OutboundEditor(QJsonObject outboundEntry, QWidget *parent = nullptr);
explicit OutboundEditor(OUTBOUND outboundEntry, QWidget *parent = nullptr);
~OutboundEditor();
QJsonObject OpenEditor();
OUTBOUND OpenEditor();
QString GetFriendlyName();
signals:
void s_reload_config(bool need_restart);
@ -109,9 +109,9 @@ class OutboundEditor : public QDialog, private Ui::OutboundEditor
private:
QString Tag;
void ReLoad_GUI_JSON_ModelContent();
QJsonObject GenerateConnectionJson();
QJsonObject Original;
QJsonObject Result;
OUTBOUND GenerateConnectionJson();
OUTBOUND Original;
OUTBOUND Result;
QJsonObject Mux;
//
// Connection Configs

View File

@ -27,8 +27,8 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
balabcerAddBtn->setIcon(QICON_R("add.png"));
balancerDelBtn->setIcon(QICON_R("delete.png"));
//
inbounds = root["inbounds"].toArray();
outbounds = root["outbounds"].toArray();
inbounds = INBOUNDS(root["inbounds"].toArray());
outbounds = OUTBOUNDS(root["outbounds"].toArray());
DomainStrategy = root["routing"].toObject()["domainStrategy"].toString();
// Applying Balancers.
@ -109,7 +109,7 @@ RouteEditor::RouteEditor(QJsonObject connection, QWidget *parent) :
}
}
QJsonObject RouteEditor::OpenEditor()
CONFIGROOT RouteEditor::OpenEditor()
{
auto result = this->exec();
@ -340,7 +340,7 @@ void RouteEditor::on_editOutboundBtn_clicked()
return;
}
auto currentOutbound = outbounds[row].toObject();
auto currentOutbound = OUTBOUND(outbounds[row].toObject());
auto protocol = currentOutbound["protocol"].toString();
if (protocol != "vmess" && protocol != "shadowsocks" && protocol != "socks") {

View File

@ -16,7 +16,7 @@ class RouteEditor : public QDialog, private Ui::RouteEditor
public:
explicit RouteEditor(QJsonObject connection, QWidget *parent = nullptr);
~RouteEditor();
QJsonObject OpenEditor();
CONFIGROOT OpenEditor();
private slots:
void on_buttonBox_accepted();
@ -91,10 +91,10 @@ class RouteEditor : public QDialog, private Ui::RouteEditor
QList<RuleObject> rules;
QString DomainStrategy;
//
QJsonArray inbounds;
QJsonArray outbounds;
QJsonObject root;
QJsonObject original;
INBOUNDS inbounds;
OUTBOUNDS outbounds;
CONFIGROOT root;
CONFIGROOT original;
};
#endif // W_QVOUTBOUNDEDITOR_H

View File

@ -46,7 +46,6 @@
// Add key value pair into JSON named 'root'
#define JADD(...) FOR_EACH(JADDEx, __VA_ARGS__)
#define DROOT QJsonObject root;
#define RROOT return root;
#endif