[pre2.0] Bumped version to pre2.0, Added more UI functions. #19

Signed-off-by: Leroy.H.Y <lhy20010403@hotmail.com>

Former-commit-id: 695e8a5c55
This commit is contained in:
Leroy.H.Y 2019-08-26 19:49:07 +08:00
parent 11c66b45cf
commit eb53687b63
17 changed files with 603 additions and 423 deletions

View File

@ -14,7 +14,7 @@ CONFIG += c++11 openssl-linked lrelease
win32: QMAKE_TARGET_DESCRIPTION = "Qv2ray, a cross-platform v2ray GUI client."
win32: QMAKE_TARGET_PRODUCT = "Qv2ray"
VERSION = 1.3
VERSION = 2.0
DEFINES += "QV_MAJOR_VERSION=\"\\\"$${VERSION}\\\"\""
SOURCES += \

View File

@ -5,7 +5,7 @@
#include "QvTinyLog.h"
#include "QvCoreConfigObjects.h"
#define QV2RAY_VERSION_STRING "v" QV_MAJOR_VERSION ".4.2"
#define QV2RAY_VERSION_STRING "v" QV_MAJOR_VERSION ".0.0"
#define QV2RAY_CONFIG_VERSION 2
#define QV2RAY_CONFIG_DIR_PATH (Qv2ray::Utils::GetConfigDirPath() + "/")
@ -62,7 +62,8 @@ namespace Qv2ray
bool http_useAuth;
AccountObject httpAccount;
Qv2rayBasicInboundsConfig(): listenip(), socks_port(), socks_useAuth(), socksAccount(), http_port(), http_useAuth(), httpAccount() {}
Qv2rayBasicInboundsConfig(string listen, int socksPort, int httpPort): Qv2rayBasicInboundsConfig() {
Qv2rayBasicInboundsConfig(string listen, int socksPort, int httpPort): Qv2rayBasicInboundsConfig()
{
socks_port = socksPort;
http_port = httpPort;
listenip = listen;
@ -96,7 +97,8 @@ namespace Qv2ray
map<string, string> subscribes;
MuxObject mux;
Qv2rayConfig(): config_version(QV2RAY_CONFIG_VERSION), runAsRoot(false), logLevel(), proxyDefault(), proxyCN(), withLocalDNS(), inBoundSettings(), configs(), subscribes(), mux() { }
Qv2rayConfig(string lang, string exePath, string assetsPath, int log, Qv2rayBasicInboundsConfig _inBoundSettings): Qv2rayConfig() {
Qv2rayConfig(string lang, string exePath, string assetsPath, int log, Qv2rayBasicInboundsConfig _inBoundSettings): Qv2rayConfig()
{
// These settings below are defaults.
ignoredVersion = "";
autoStartConfig = "";

View File

@ -66,7 +66,42 @@ namespace Qv2ray
};
//
//
namespace TransferSettingObjects
struct RuleObject {
string type;
list<string> domain;
list<string> ip;
string port;
string network;
list<string> source;
list<string> user;
list<string> inboundTag;
string protocol;
string attrs;
string outboundTag;
string balancerTag;
RuleObject() : type("field"), domain(), ip(), port(), network(), source(), user(), inboundTag(), protocol(), attrs(), outboundTag(), balancerTag() {}
XTOSTRUCT(O(type, domain, ip, port, network, source, user, inboundTag, protocol, attrs, outboundTag, balancerTag))
};
//
//
struct BalancerObject {
string tag ;
list<string> selector;
BalancerObject() : tag(), selector() {}
XTOSTRUCT(O(tag, selector))
};
//
//
struct RoutingObject {
string domainStrategy;
list<RuleObject> rules;
list<BalancerObject> balancers;
RoutingObject() : domainStrategy(), rules(), balancers() {}
XTOSTRUCT(O(domainStrategy, rules, balancers))
};
//
//
namespace TSObjects
{
struct HTTPRequestObject {
string version;
@ -200,14 +235,14 @@ namespace Qv2ray
struct StreamSettingsObject {
string network;
string security;
TransferSettingObjects::SockoptObject sockopt;
TransferSettingObjects::TLSObject tlsSettings;
TransferSettingObjects::TCPObject tcpSettings;
TransferSettingObjects::KCPObject kcpSettings;
TransferSettingObjects::WebSocketObject wsSettings;
TransferSettingObjects::HttpObject httpSettings;
TransferSettingObjects::DomainSocketObject dsSettings;
TransferSettingObjects::QuicObject quicSettings;
TSObjects::SockoptObject sockopt;
TSObjects::TLSObject tlsSettings;
TSObjects::TCPObject tcpSettings;
TSObjects::KCPObject kcpSettings;
TSObjects::WebSocketObject wsSettings;
TSObjects::HttpObject httpSettings;
TSObjects::DomainSocketObject dsSettings;
TSObjects::QuicObject quicSettings;
StreamSettingsObject(): network("tcp"), security(), sockopt(), tlsSettings(), tcpSettings(), kcpSettings(), wsSettings(), httpSettings(), dsSettings(), quicSettings() {}
XTOSTRUCT(O(network, security, sockopt, tcpSettings, tlsSettings, kcpSettings, wsSettings, httpSettings, dsSettings, quicSettings))
};

View File

@ -36,7 +36,7 @@ namespace Qv2ray
template<typename T>
QJsonObject GetRootObject(T t)
{
auto json = StructToJSONString(t);
auto json = StructToJsonString(t);
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(json.toStdString()));
return doc.object();
}

View File

@ -7,7 +7,7 @@ namespace Qv2ray
bool SaveConnectionConfig(QJsonObject obj, const QString *alias)
{
QFile config(QV2RAY_CONFIG_DIR_PATH + *alias + QV2RAY_CONNECTION_FILE_EXTENSION);
return StringToFile(JSONToString(obj), &config);
return StringToFile(JsonToString(obj), &config);
}
// This generates global config containing only one outbound....
@ -15,7 +15,7 @@ namespace Qv2ray
{
DROOT
QStringRef vmessJsonB64(&str, 8, str.length() - 8);
auto vmessConf = StructFromJSONString<VMessProtocolConfigObject>(Base64Decode(vmessJsonB64.toString()));
auto vmessConf = StructFromJsonString<VMessProtocolConfigObject>(Base64Decode(vmessJsonB64.toString()));
//
// User
VMessServerObject::UserObject user;
@ -31,7 +31,7 @@ namespace Qv2ray
// VMess root config
QJsonObject vConf;
QJsonArray vnextArray;
vnextArray.append(JSONFromString(StructToJSONString(serv)));
vnextArray.append(JsonFromString(StructToJsonString(serv)));
vConf["vnext"] = vnextArray;
//
// Stream Settings
@ -72,7 +72,7 @@ namespace Qv2ray
QJsonObject ConvertConfigFromFile(QString sourceFilePath, bool overrideInbounds)
{
auto root = JSONFromString(StringFromFile(new QFile(sourceFilePath)));
auto root = JsonFromString(StringFromFile(new QFile(sourceFilePath)));
if (overrideInbounds) {
JSON_ROOT_TRY_REMOVE("inbounds")
@ -92,7 +92,7 @@ namespace Qv2ray
foreach (auto conn, connectionNames) {
QString jsonString = StringFromFile(new QFile(QV2RAY_CONFIG_DIR_PATH + QString::fromStdString(conn) + QV2RAY_CONNECTION_FILE_EXTENSION));
QJsonObject connectionObject = JSONFromString(jsonString);
QJsonObject connectionObject = JsonFromString(jsonString);
list.insert(QString::fromStdString(conn), connectionObject);
}
@ -106,7 +106,7 @@ namespace Qv2ray
int StartPreparation(QJsonObject fullConfig)
{
QString json = JSONToString(fullConfig);
QString json = JsonToString(fullConfig);
StringToFile(json, new QFile(QV2RAY_GENERATED_FILE_PATH));
return 0;
}

View File

@ -15,7 +15,7 @@ namespace Qv2ray
try {
QStringRef vmessJsonB64(&vmess, 8, vmess.length() - 8);
auto vmessString = Base64Decode(vmessJsonB64.toString());
auto vmessConf = StructFromJSONString<VMessProtocolConfigObject>(vmessString);
auto vmessConf = StructFromJsonString<VMessProtocolConfigObject>(vmessString);
return 0;
} catch (exception *e) {
LOG(MODULE_CONNECTION, QObject::tr("#VMessDecodeError").toStdString() << e->what())

View File

@ -30,10 +30,40 @@ namespace Qv2ray
void SaveGlobalConfig()
{
QFile config(QV2RAY_CONFIG_FILE_PATH);
QString str = StructToJSONString(GetGlobalConfig());
QString str = StructToJsonString(GetGlobalConfig());
StringToFile(str, &config);
}
QString Stringify(list<string> list, QString saperator)
{
QString out;
foreach (string item, list) {
out.append(QSTRING(item));
out.append(saperator);
}
if (out.length() >= 1)
out = out.remove(out.length() - 1, 1);
return out;
}
QString Stringify(QList<QString> list, QString saperator)
{
QString out;
foreach (QString item, list) {
out.append(saperator);
out.append(item);
}
if (out.length() >= 1)
out = out.remove(out.length() - 1, 1);
return out;
}
bool StringToFile(QString text, QFile *targetFile)
{
bool override = targetFile->exists();
@ -48,17 +78,17 @@ namespace Qv2ray
QJsonObject JSONFromFile(QFile *sourceFile)
{
QString json = StringFromFile(sourceFile);
return JSONFromString(json);
return JsonFromString(json);
}
QString JSONToString(QJsonObject json)
QString JsonToString(QJsonObject json)
{
QJsonDocument doc;
doc.setObject(json);
return doc.toJson();
}
QJsonObject JSONFromString(QString string)
QJsonObject JsonFromString(QString string)
{
QJsonDocument doc = QJsonDocument::fromJson(string.toUtf8());
return doc.object();
@ -93,7 +123,7 @@ namespace Qv2ray
file.open(QFile::ReadOnly);
QTextStream stream(&file);
auto str = stream.readAll();
auto config = StructFromJSONString<Qv2rayConfig>(str);
auto config = StructFromJsonString<Qv2rayConfig>(str);
SetGlobalConfig(config);
file.close();
}

View File

@ -33,19 +33,22 @@ namespace Qv2ray
bool StringToFile(QString text, QFile *target);
QString StringFromFile(QFile *sourceFile);
//
QJsonObject JSONFromString(QString string);
QString JSONToString(QJsonObject json);
QJsonObject JsonFromString(QString string);
QString JsonToString(QJsonObject json);
//
QString Stringify(list<string> list, QString saperator = ";");
QString Stringify(QList<QString> list, QString saperator = ";");
//
//
template <typename TYPE>
QString StructToJSONString(const TYPE t)
QString StructToJsonString(const TYPE t)
{
return QString::fromStdString(X::tojson(t, "", 4, ' '));
}
//
//
template <typename TYPE>
TYPE StructFromJSONString(const QString &str)
TYPE StructFromJsonString(const QString &str)
{
TYPE v;
X::loadjson(str.toStdString(), v, false);

View File

@ -56,7 +56,9 @@ bool initQv()
return false;
}
}
QFile configFile(QV2RAY_CONFIG_FILE_PATH);
if (!configFile.exists()) {
// This is first run!
//
@ -71,13 +73,15 @@ bool initQv()
LOG(MODULE_INIT, "Created initial config file.")
} else {
// Some config file upgrades.
auto conf = JSONFromString(StringFromFile(&configFile));
auto conf = JsonFromString(StringFromFile(&configFile));
auto confVersion = conf["config_version"].toVariant().toString();
auto newVersion = QSTRING(to_string(QV2RAY_CONFIG_VERSION));
if(QString::compare(confVersion, newVersion) != 0) {
if (QString::compare(confVersion, newVersion) != 0) {
conf = UpgradeConfig(stoi(conf["config_version"].toString().toStdString()), QV2RAY_CONFIG_VERSION, conf);
}
auto confObject = StructFromJSONString<Qv2rayConfig>(JSONToString(conf));
auto confObject = StructFromJsonString<Qv2rayConfig>(JsonToString(conf));
SetGlobalConfig(confObject);
SaveGlobalConfig();
LOG(MODULE_INIT, "Loaded config file.")
@ -135,17 +139,18 @@ int main(int argc, char *argv[])
"DEBUG_VERSION"
#endif
);
#ifdef __WIN32
#ifndef __APPLE__
auto osslReqVersion = QSslSocket::sslLibraryBuildVersionString().toStdString();
auto osslCurVersion = QSslSocket::sslLibraryVersionString().toStdString();
if (osslCurVersion != osslReqVersion){
LOG(MODULE_NETWORK, "Current OpenSSL version: " + osslCurVersion)
if (osslCurVersion != osslReqVersion) {
LOG(MODULE_NETWORK, "Required OpenSSL version: " + osslReqVersion)
LOG(MODULE_NETWORK, "Current OpenSSL version: " + osslCurVersion)
QvMessageBox(nullptr, QObject::tr("DependencyMissing"), QObject::tr("osslDependMissing,PleaseReDownload"));
LOG(MODULE_NETWORK, "OpenSSL library MISSING, Quitting.")
return -2;
}
#endif
if (!guard.isSingleInstance()) {
@ -153,6 +158,7 @@ int main(int argc, char *argv[])
QvMessageBox(nullptr, "Qv2ray", QObject::tr("#AnotherInstanceRunning"));
return -1;
}
// Show MainWindow
MainWindow w;
return _qApp.exec();

View File

@ -6,8 +6,6 @@
#include "w_ConnectionEditWindow.h"
#include "w_MainWindow.h"
#define GEN_JSON ConnectionEditWindow::on_genJsonBtn_clicked();
ConnectionEditWindow::ConnectionEditWindow(QWidget *parent)
: QDialog(parent),
_alias(),
@ -27,7 +25,6 @@ ConnectionEditWindow::ConnectionEditWindow(QWidget *parent)
stream = StreamSettingsObject();
OutboundType = "vmess";
ReLoad_GUI_JSON_ModelContent();
GEN_JSON
}
ConnectionEditWindow::ConnectionEditWindow(QJsonObject editRootObject, QString alias, QWidget *parent)
@ -39,20 +36,20 @@ ConnectionEditWindow::ConnectionEditWindow(QJsonObject editRootObject, QString a
OutboundType = outBoundRoot["protocol"].toString();
if (OutboundType == "vmess") {
vmess = StructFromJSONString<VMessServerObject>(JSONToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
stream = StructFromJSONString<StreamSettingsObject>(JSONToString(outBoundRoot["streamSettings"].toObject()));
vmess = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
stream = StructFromJsonString<StreamSettingsObject>(JsonToString(outBoundRoot["streamSettings"].toObject()));
shadowsocks.port = vmess.port;
shadowsocks.address = vmess.address;
socks.address = vmess.address;
socks.port = vmess.port;
} else if (OutboundType == "shadowsocks") {
shadowsocks = StructFromJSONString<ShadowSocksServer>(JSONToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject()));
shadowsocks = StructFromJsonString<ShadowSocksServer>(JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject()));
vmess.address = shadowsocks.address;
vmess.port = shadowsocks.port;
socks.address = shadowsocks.address;
socks.port = shadowsocks.port;
} else if (OutboundType == "socks") {
socks = StructFromJSONString<SocksServerObject>(JSONToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject()));
socks = StructFromJsonString<SocksServerObject>(JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject()));
vmess.address = socks.address;
vmess.port = socks.port;
shadowsocks.address = socks.address;
@ -60,7 +57,6 @@ ConnectionEditWindow::ConnectionEditWindow(QJsonObject editRootObject, QString a
}
ReLoad_GUI_JSON_ModelContent();
GEN_JSON
}
@ -82,8 +78,8 @@ void ConnectionEditWindow::ReLoad_GUI_JSON_ModelContent()
ui->tlsCB->setChecked(stream.security == "tls");
// TCP
ui->tcpHeaderTypeCB->setCurrentText(QSTRING(stream.tcpSettings.header.type));
ui->tcpRequestTxt->setPlainText(StructToJSONString(stream.tcpSettings.header.request));
ui->tcpRespTxt->setPlainText(StructToJSONString(stream.tcpSettings.header.response));
ui->tcpRequestTxt->setPlainText(StructToJsonString(stream.tcpSettings.header.request));
ui->tcpRespTxt->setPlainText(StructToJsonString(stream.tcpSettings.header.response));
// HTTP
QString allHosts;
@ -174,7 +170,6 @@ void ConnectionEditWindow::on_ipLineEdit_textEdited(const QString &arg1)
vmess.address = arg1.toStdString();
shadowsocks.address = arg1.toStdString();
socks.address = arg1.toStdString();
GEN_JSON
//
// No thanks.
//if (ui->httpHostTxt->toPlainText() == "") {
@ -194,7 +189,6 @@ void ConnectionEditWindow::on_portLineEdit_textEdited(const QString &arg1)
vmess.port = stoi(arg1.toStdString());
shadowsocks.port = stoi(arg1.toStdString());
socks.port = stoi(arg1.toStdString());
GEN_JSON
}
}
@ -203,7 +197,6 @@ void ConnectionEditWindow::on_idLineEdit_textEdited(const QString &arg1)
if (vmess.users.size() == 0) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().id = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_alterLineEdit_textEdited(const QString &arg1)
@ -211,7 +204,6 @@ void ConnectionEditWindow::on_alterLineEdit_textEdited(const QString &arg1)
if (vmess.users.size() == 0) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().alterId = stoi(arg1.toStdString());
GEN_JSON
}
void ConnectionEditWindow::on_securityCombo_currentIndexChanged(const QString &arg1)
@ -219,19 +211,16 @@ void ConnectionEditWindow::on_securityCombo_currentIndexChanged(const QString &a
if (vmess.users.size() == 0) vmess.users.push_back(VMessServerObject::UserObject());
vmess.users.front().security = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_tranportCombo_currentIndexChanged(const QString &arg1)
{
stream.network = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_httpPathTxt_textEdited(const QString &arg1)
{
stream.httpSettings.path = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_httpHostTxt_textChanged()
@ -245,7 +234,6 @@ void ConnectionEditWindow::on_httpHostTxt_textChanged()
stream.httpSettings.host.push_back(host.trimmed().toStdString());
}
GEN_JSON
BLACK(httpHostTxt)
} catch (...) {
RED(httpHostTxt)
@ -266,7 +254,6 @@ void ConnectionEditWindow::on_wsHeadersTxt_textChanged()
stream.wsSettings.headers.insert(make_pair(content[0].toStdString(), content[1].toStdString()));
}
GEN_JSON
BLACK(wsHeadersTxt)
} catch (...) {
RED(wsHeadersTxt)
@ -285,22 +272,19 @@ void ConnectionEditWindow::on_tcpRequestDefBtn_clicked()
"AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 "
"Safari/601.1.46\"],\"Accept-Encoding\":[\"gzip, deflate\"],"
"\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}");
GEN_JSON
}
void ConnectionEditWindow::on_tcpRespDefBtn_clicked()
{
ui->tcpRespTxt->clear();
ui->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\"}}");
GEN_JSON
}
void ConnectionEditWindow::on_tcpRequestTxt_textChanged()
{
try {
auto tcpReqObject = StructFromJSONString<TransferSettingObjects::HTTPRequestObject>(ui->tcpRequestTxt->toPlainText());
auto tcpReqObject = StructFromJsonString<TSObjects::HTTPRequestObject>(ui->tcpRequestTxt->toPlainText());
stream.tcpSettings.header.request = tcpReqObject;
GEN_JSON
BLACK(tcpRequestTxt)
} catch (...) {
RED(tcpRequestTxt)
@ -310,9 +294,8 @@ void ConnectionEditWindow::on_tcpRequestTxt_textChanged()
void ConnectionEditWindow::on_tcpRespTxt_textChanged()
{
try {
auto tcpRspObject = StructFromJSONString<TransferSettingObjects::HTTPResponseObject>(ui->tcpRespTxt->toPlainText());
auto tcpRspObject = StructFromJsonString<TSObjects::HTTPResponseObject>(ui->tcpRespTxt->toPlainText());
stream.tcpSettings.header.response = tcpRspObject;
GEN_JSON
BLACK(tcpRespTxt)
} catch (...) {
RED(tcpRespTxt)
@ -322,15 +305,14 @@ void ConnectionEditWindow::on_tcpRespTxt_textChanged()
void ConnectionEditWindow::on_genJsonBtn_clicked()
{
auto json = GenerateConnectionJson();
ui->finalJson->setText(JSONToString(json));
}
QJsonObject ConnectionEditWindow::GenerateConnectionJson()
{
// VMess is only a ServerObject, and we need an array { "vnext": [] }
QJsonObject settings;
auto mux = JSONFromString(StructToJSONString(GetGlobalConfig().mux));
auto streaming = JSONFromString(StructToJSONString(stream));
auto mux = JsonFromString(StructToJsonString(GetGlobalConfig().mux));
auto streaming = JsonFromString(StructToJsonString(stream));
if (OutboundType == "vmess") {
QJsonArray vnext;
@ -355,45 +337,37 @@ QJsonObject ConnectionEditWindow::GenerateConnectionJson()
void ConnectionEditWindow::on_tlsCB_stateChanged(int arg1)
{
stream.security = arg1 == Qt::Checked ? "tls" : "none";
GEN_JSON
}
void ConnectionEditWindow::on_soMarkSpinBox_valueChanged(int arg1)
{
stream.sockopt.mark = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_tcpFastOpenCB_stateChanged(int arg1)
{
stream.sockopt.tcpFastOpen = arg1 == Qt::Checked;
GEN_JSON
}
void ConnectionEditWindow::on_tProxyCB_currentIndexChanged(const QString &arg1)
{
stream.sockopt.tproxy = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_quicSecurityCB_currentTextChanged(const QString &arg1)
{
stream.quicSettings.security = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_quicKeyTxt_textEdited(const QString &arg1)
{
stream.quicSettings.key = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_quicHeaderTypeCB_currentIndexChanged(const QString &arg1)
{
stream.quicSettings.header.type = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_tcpRequestPrettifyBtn_clicked()
{
try {
auto tcpReqObject = StructFromJSONString<TransferSettingObjects::HTTPRequestObject>(ui->tcpRequestTxt->toPlainText());
auto tcpReqObjectStr = StructToJSONString(tcpReqObject);
auto tcpReqObject = StructFromJsonString<TSObjects::HTTPRequestObject>(ui->tcpRequestTxt->toPlainText());
auto tcpReqObjectStr = StructToJsonString(tcpReqObject);
ui->tcpRequestTxt->setPlainText(tcpReqObjectStr);
GEN_JSON
} catch (...) {
QvMessageBox(this, tr("#JsonPrettify"), tr("#JsonContainsError"));
}
@ -401,10 +375,9 @@ void ConnectionEditWindow::on_tcpRequestPrettifyBtn_clicked()
void ConnectionEditWindow::on_tcpRespPrettifyBtn_clicked()
{
try {
auto tcpRspObject = StructFromJSONString<TransferSettingObjects::HTTPResponseObject>(ui->tcpRespTxt->toPlainText());
auto tcpRspObjectStr = StructToJSONString(tcpRspObject);
auto tcpRspObject = StructFromJsonString<TSObjects::HTTPResponseObject>(ui->tcpRespTxt->toPlainText());
auto tcpRspObjectStr = StructToJsonString(tcpRspObject);
ui->tcpRespTxt->setPlainText(tcpRspObjectStr);
GEN_JSON
} catch (...) {
QvMessageBox(this, tr("#JsonPrettify"), tr("#JsonContainsError"));
}
@ -412,62 +385,50 @@ void ConnectionEditWindow::on_tcpRespPrettifyBtn_clicked()
void ConnectionEditWindow::on_tcpHeaderTypeCB_currentIndexChanged(const QString &arg1)
{
stream.tcpSettings.header.type = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_wsPathTxt_textEdited(const QString &arg1)
{
stream.wsSettings.path = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_kcpMTU_valueChanged(int arg1)
{
stream.kcpSettings.mtu = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_kcpTTI_valueChanged(int arg1)
{
stream.kcpSettings.tti = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_kcpUploadCapacSB_valueChanged(int arg1)
{
stream.kcpSettings.uplinkCapacity = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_kcpCongestionCB_stateChanged(int arg1)
{
stream.kcpSettings.congestion = arg1 == Qt::Checked;
GEN_JSON
}
void ConnectionEditWindow::on_kcpDownCapacitySB_valueChanged(int arg1)
{
stream.kcpSettings.downlinkCapacity = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_kcpReadBufferSB_valueChanged(int arg1)
{
stream.kcpSettings.readBufferSize = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_kcpWriteBufferSB_valueChanged(int arg1)
{
stream.kcpSettings.writeBufferSize = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_kcpHeaderType_currentTextChanged(const QString &arg1)
{
stream.kcpSettings.header.type = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_tranportCombo_currentIndexChanged(int index)
{
ui->v2rayStackView->setCurrentIndex(index);
GEN_JSON
}
void ConnectionEditWindow::on_dsPathTxt_textEdited(const QString &arg1)
{
stream.dsSettings.path = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_finalJson_textChanged()
{
@ -487,47 +448,39 @@ void ConnectionEditWindow::on_outBoundTypeCombo_currentIndexChanged(int index)
{
ui->outboundTypeStackView->setCurrentIndex(index);
OutboundType = ui->outBoundTypeCombo->currentText().toLower();
GEN_JSON
}
void ConnectionEditWindow::on_ss_emailTxt_textEdited(const QString &arg1)
{
shadowsocks.email = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_ss_passwordTxt_textEdited(const QString &arg1)
{
shadowsocks.password = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_ss_encryptionMethod_currentIndexChanged(const QString &arg1)
{
shadowsocks.method = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_ss_levelSpin_valueChanged(int arg1)
{
shadowsocks.level = arg1;
GEN_JSON
}
void ConnectionEditWindow::on_ss_otaCheckBox_stateChanged(int arg1)
{
shadowsocks.ota = arg1 == Qt::Checked;
GEN_JSON
}
void ConnectionEditWindow::on_socks_UserNameTxt_textEdited(const QString &arg1)
{
socks.users.front().user = arg1.toStdString();
GEN_JSON
}
void ConnectionEditWindow::on_socks_PasswordTxt_textEdited(const QString &arg1)
{
socks.users.front().pass = arg1.toStdString();
GEN_JSON
}

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>911</width>
<height>614</height>
<width>920</width>
<height>570</height>
</rect>
</property>
<property name="sizePolicy">
@ -18,8 +18,8 @@
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
<width>920</width>
<height>570</height>
</size>
</property>
<property name="windowTitle">
@ -28,8 +28,8 @@
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="ipLabel">
@ -89,7 +89,7 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item>
<widget class="QGroupBox" name="outboundSettingWrapper">
<property name="title">
<string>#OutBoundSettings</string>
@ -107,23 +107,9 @@
<number>0</number>
</property>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="4,6">
<item>
<layout class="QFormLayout" name="formLayout_9">
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>#UseTLS</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="tlsCB">
<property name="text">
<string>#Enabled</string>
</property>
</widget>
</item>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="idLabel">
<property name="text">
@ -164,6 +150,12 @@
</item>
<item row="2" column="1">
<widget class="QComboBox" name="securityCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string notr="true">auto</string>
@ -186,6 +178,20 @@
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>#UseTLS</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="tlsCB">
<property name="text">
<string>#Enabled</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="transportLabel">
<property name="text">
@ -230,7 +236,7 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="transportGroupbox">
<property name="title">
<string>#TransportSettings</string>
</property>
@ -247,32 +253,7 @@
<number>0</number>
</property>
<widget class="QWidget" name="tcpStackPage">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,5">
<item row="0" column="1">
<widget class="QComboBox" name="tcpHeaderTypeCB">
<item>
<property name="text">
<string notr="true">none</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">http</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>#Type</string>
</property>
</widget>
</item>
</layout>
</item>
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,1,0">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
@ -303,6 +284,12 @@
</item>
<item row="2" column="0" colspan="2">
<widget class="QPlainTextEdit" name="tcpRequestTxt">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
@ -316,6 +303,12 @@
</item>
<item row="2" column="2" colspan="2">
<widget class="QPlainTextEdit" name="tcpRespTxt">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
@ -338,6 +331,31 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>#Type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="tcpHeaderTypeCB">
<item>
<property name="text">
<string notr="true">none</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">http</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="httpStackPage">
@ -404,219 +422,211 @@
</layout>
</widget>
<widget class="QWidget" name="mKCPStackPage">
<layout class="QGridLayout" name="gridLayout_10">
<layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>#MTU</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="kcpMTU">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>576</number>
</property>
<property name="maximum">
<number>1460</number>
</property>
<property name="value">
<number>1350</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>#TTI (ms)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="kcpTTI">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>#UplinkCapacity (MB/s)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="kcpUploadCapacSB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>4096</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>#Congestion</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="kcpCongestionCB">
<property name="text">
<string>#Enabled</string>
</property>
</widget>
</item>
</layout>
<widget class="QLabel" name="label_8">
<property name="text">
<string>#MTU</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QFormLayout" name="formLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>#DownlinkCapacity (MB/s)</string>
</property>
</widget>
<widget class="QSpinBox" name="kcpMTU">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>576</number>
</property>
<property name="maximum">
<number>1460</number>
</property>
<property name="value">
<number>1350</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>#TTI (ms)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="kcpTTI">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>#UplinkCapacity (MB/s)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="kcpUploadCapacSB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>4096</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>#Congestion</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="kcpCongestionCB">
<property name="text">
<string>#Enabled</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>#DownlinkCapacity (MB/s)</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="kcpDownCapacitySB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>4096</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>#ReadBufferSize (MB)</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="kcpReadBufferSB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>1024</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="labelx">
<property name="text">
<string>#WriteBufferSize (MB)</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="kcpWriteBufferSB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>1024</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>#Type</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="kcpHeaderType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string notr="true">none</string>
</property>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="kcpDownCapacitySB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>4096</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
<item>
<property name="text">
<string notr="true">srtp</string>
</property>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>#ReadBufferSize (MB)</string>
</property>
</widget>
<item>
<property name="text">
<string notr="true">utp</string>
</property>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="kcpReadBufferSB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>1024</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
<item>
<property name="text">
<string notr="true">wechat-video</string>
</property>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelx">
<property name="text">
<string>#WriteBufferSize (MB)</string>
</property>
</widget>
<item>
<property name="text">
<string notr="true">dtls</string>
</property>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="kcpWriteBufferSB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>1024</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
<item>
<property name="text">
<string notr="true">wireguard</string>
</property>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>#Type</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="kcpHeaderType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string notr="true">none</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">srtp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">utp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">wechat-video</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dtls</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">wireguard</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
@ -929,32 +939,7 @@
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>#JsonPreview</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextBrowser" name="finalJson">
<property name="lineWrapMode">
<enum>QTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -979,8 +964,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>586</x>
<y>523</y>
<x>592</x>
<y>655</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -995,8 +980,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>654</x>
<y>523</y>
<x>660</x>
<y>655</y>
</hint>
<hint type="destinationlabel">
<x>286</x>

View File

@ -19,6 +19,7 @@
#include "w_ImportConfig.h"
#include "w_ConnectionEditWindow.h"
#include "w_MainWindow.h"
#include "w_RouteEditor.h"
#define TRAY_TOOLTIP_PREFIX "Qv2ray " QV2RAY_VERSION_STRING "\r\n"
@ -104,7 +105,7 @@ void MainWindow::VersionUpdate(QByteArray &data)
{
auto conf = GetGlobalConfig();
QString jsonString(data);
QJsonObject root = JSONFromString(jsonString);
QJsonObject root = JsonFromString(jsonString);
//
QVersionNumber newversion = QVersionNumber::fromString(root["tag_name"].toString("").remove(0, 1));
QVersionNumber current = QVersionNumber::fromString(QSTRING(QV2RAY_VERSION_STRING).remove(0, 1));
@ -304,6 +305,7 @@ void MainWindow::QTextScrollToBottom()
void MainWindow::ShowAndSetConnection(int index, bool SetConnection, bool ApplyConnection)
{
if (index < 0) return;
auto guiConnectionName = ui->connectionListWidget->item(index)->text();
// --------- BRGIN Show Connection
auto outBoundRoot = (connections[guiConnectionName])["outbounds"].toArray().first().toObject();
@ -312,10 +314,10 @@ void MainWindow::ShowAndSetConnection(int index, bool SetConnection, bool ApplyC
ui->_OutBoundTypeLabel->setText(outboundType);
if (outboundType == "vmess") {
auto Server = StructFromJSONString<VMessServerObject>(JSONToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
ui->_hostLabel->setText(QSTRING(Server.address));
ui->_portLabel->setText(QSTRING(to_string(Server.port)));
auto user = QList<VMessServerObject::UserObject>::fromStdList(Server.users).first();
auto x = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
ui->_hostLabel->setText(QSTRING(x.address));
ui->_portLabel->setText(QSTRING(to_string(x.port)));
auto user = QList<VMessServerObject::UserObject>::fromStdList(x.users).first();
auto _configString = tr("#UUID") + ": " + QSTRING(user.id)
+ "\r\n"
+ tr("#AlterID") + ": " + QSTRING(to_string(user.alterId))
@ -323,8 +325,8 @@ void MainWindow::ShowAndSetConnection(int index, bool SetConnection, bool ApplyC
+ tr("#Transport") + ": " + outBoundRoot["streamSettings"].toObject()["network"].toString();
ui->detailInfoTxt->setPlainText(_configString);
} else if (outboundType == "shadowsocks") {
auto x = JSONToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJSONString<ShadowSocksServer>(x);
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJsonString<ShadowSocksServer>(x);
ui->_hostLabel->setText(QSTRING(Server.address));
ui->_portLabel->setText(QSTRING(to_string(Server.port)));
auto _configString = tr("#Email") + ": " + QSTRING(Server.email)
@ -332,8 +334,8 @@ void MainWindow::ShowAndSetConnection(int index, bool SetConnection, bool ApplyC
+ tr("#Encryption") + ": " + QSTRING(Server.method);
ui->detailInfoTxt->setPlainText(_configString);
} else if (outboundType == "socks") {
auto x = JSONToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJSONString<SocksServerObject>(x);
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJsonString<SocksServerObject>(x);
ui->_hostLabel->setText(QSTRING(Server.address));
ui->_portLabel->setText(QSTRING(to_string(Server.port)));
auto _configString = tr("#Username") + ": " + QSTRING(Server.users.front().user);
@ -471,14 +473,14 @@ void MainWindow::on_importConfigButton_clicked()
{
ImportConfigWindow *w = new ImportConfigWindow(this);
connect(w, &ImportConfigWindow::s_reload_config, this, &MainWindow::save_reload_globalconfig);
w->show();
w->exec();
}
void MainWindow::on_addConfigButton_clicked()
{
ConnectionEditWindow *w = new ConnectionEditWindow(this);
connect(w, &ConnectionEditWindow::s_reload_config, this, &MainWindow::save_reload_globalconfig);
w->show();
w->exec();
}
void MainWindow::on_editConfigButton_clicked()
@ -491,7 +493,21 @@ void MainWindow::on_editConfigButton_clicked()
return;
}
ConnectionEditWindow *w = new ConnectionEditWindow(connections.values()[index], connections.keys()[index], this);
ConnectionEditWindow *w = new ConnectionEditWindow(connections[ui->connectionListWidget->currentItem()->text()], ui->connectionListWidget->currentItem()->text(), this);
connect(w, &ConnectionEditWindow::s_reload_config, this, &MainWindow::save_reload_globalconfig);
w->show();
w->exec();
}
void MainWindow::on_editConfigAdvButton_clicked()
{
// Check if we have a connection selected...
auto index = ui->connectionListWidget->currentIndex().row();
if (index < 0) {
QvMessageBox(this, tr("#NoConfigSelected"), tr("#PleaseSelectAConfig"));
return;
}
RouteEditor *w = new RouteEditor(connections[ui->connectionListWidget->currentItem()->text()], ui->connectionListWidget->currentItem()->text(), this);
w->exec();
}

View File

@ -57,6 +57,8 @@ class MainWindow : public QMainWindow
void on_editConfigButton_clicked();
void on_editConfigAdvButton_clicked();
private:
void on_action_StartThis_triggered();
void on_action_RenameConnection_triggered();

View File

@ -298,6 +298,13 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="editConfigAdvButton">
<property name="text">
<string>#</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">

View File

@ -1,14 +1,110 @@
#include "w_RouteEditor.h"
#include "ui_w_OutboundEditor.h"
#include "ui_w_RouteEditor.h"
RouteEditor::RouteEditor(QWidget *parent) :
RouteEditor::RouteEditor(QJsonObject connection, const QString alias, QWidget *parent) :
QDialog(parent),
root(connection),
rootAlias(alias),
ui(new Ui::RouteEditor)
{
inbounds = root["inbounds"].toArray();
outbounds = root["outbounds"].toArray();
routes = StructFromJsonString<RoutingObject>(JsonToString(root["routing"].toObject()));
ui->setupUi(this);
ui->outboundsList->clear();
foreach (auto out, outbounds) {
bool hasTag = out.toObject().contains("tag");
if (hasTag) {
ui->outboundsList->addItem(out.toObject()["tag"].toString());
} else {
ui->outboundsList->addItem(out.toObject()["protocol"].toString());
}
}
foreach (auto in, inbounds) {
bool hasTag = in.toObject().contains("tag");
auto inItem = new QListWidgetItem();
inItem->setCheckState(Qt::Unchecked);
if (hasTag) {
inItem->setText(in.toObject()["tag"].toString());
} else {
inItem->setText(in.toObject()["protocol"].toString());
}
ui->inboundsList->addItem(inItem);
}
foreach (auto route, routes.rules) {
ui->routesTable->insertRow(ui->routesTable->rowCount());
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 0,
new QTableWidgetItem(route.inboundTag.size() > 0 ? Stringify(route.inboundTag) : "Any"));
//
auto tmplist = QList<string>::fromStdList(route.ip);
tmplist.append(QList<string>::fromStdList(route.domain));
//
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 1,
new QTableWidgetItem(Stringify(tmplist.toStdList())));
ui->routesTable->setItem(ui->routesTable->rowCount() - 1, 2,
new QTableWidgetItem(QSTRING(route.outboundTag)));
}
}
RouteEditor::~RouteEditor()
{
delete ui;
}
void RouteEditor::on_buttonBox_accepted()
{
}
void RouteEditor::on_outboundsList_currentRowChanged(int currentRow)
{
LOG(MODULE_UI, "Outbound selected: " + to_string(currentRow))
auto outBoundRoot = outbounds[currentRow].toObject();
ui->outboundTagLabel->setText(outBoundRoot.contains("tag") ? outBoundRoot["tag"].toString() : tr("#NoTag"));
auto outboundType = outBoundRoot["protocol"].toString();
ui->outboundTypeLabel->setText(outboundType);
if (outboundType == "vmess") {
auto x = StructFromJsonString<VMessServerObject>(JsonToString(outBoundRoot["settings"].toObject()["vnext"].toArray().first().toObject()));
ui->outboundAddressLabel->setText(QSTRING(x.address));
ui->outboundPortLabel->setText(QSTRING(to_string(x.port)));
} else if (outboundType == "shadowsocks") {
auto x = JsonToString(outBoundRoot["settings"].toObject()["servers"].toArray().first().toObject());
auto Server = StructFromJsonString<ShadowSocksServer>(x);
ui->outboundAddressLabel->setText(QSTRING(Server.address));
ui->outboundPortLabel->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);
ui->outboundAddressLabel->setText(QSTRING(Server.address));
ui->outboundPortLabel->setText(QSTRING(to_string(Server.port)));
}
}
void RouteEditor::on_inboundsList_currentRowChanged(int currentRow)
{
LOG(MODULE_UI, "Inbound selected: " + to_string(currentRow))
auto inBoundRoot = inbounds[currentRow].toObject();
ui->inboundTagLabel->setText(inBoundRoot.contains("tag") ? inBoundRoot["tag"].toString() : tr("#NoTag"));
ui->inboundTypeLabel->setText(inBoundRoot["protocol"].toString());
ui->inboundAddressLabel->setText(inBoundRoot["listen"].toString());
ui->inboundPortLabel->setText(inBoundRoot["port"].toVariant().toString());
}
void RouteEditor::on_routesTable_cellClicked(int row, int column)
{
Q_UNUSED(column)
auto outboundTag = ui->routesTable->item(row, 2)->text();
ui->outboundsList->setCurrentItem(ui->outboundsList->findItems(outboundTag, Qt::MatchExactly).first());
//
auto inboundTagList = ui->routesTable->item(row, 0)->text();
bool isAnyInbounds = inboundTagList == "any";
if (isAnyInbounds) {
}
}

View File

@ -1,7 +1,11 @@
#ifndef W_QVOUTBOUNDEDITOR_H
#define W_QVOUTBOUNDEDITOR_H
#include <list>
#include <QDialog>
#include <QJsonArray>
#include <QJsonObject>
#include "QvUtils.h"
namespace Ui
{
@ -13,10 +17,24 @@ class RouteEditor : public QDialog
Q_OBJECT
public:
explicit RouteEditor(QWidget *parent = nullptr);
explicit RouteEditor(QJsonObject connection, const QString alias, QWidget *parent = nullptr);
~RouteEditor();
private slots:
void on_buttonBox_accepted();
void on_outboundsList_currentRowChanged(int currentRow);
void on_inboundsList_currentRowChanged(int currentRow);
void on_routesTable_cellClicked(int row, int column);
private:
QJsonArray inbounds;
QJsonArray outbounds;
RoutingObject routes;
QJsonObject root;
QString rootAlias;
Ui::RouteEditor *ui;
};

View File

@ -24,10 +24,13 @@
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget">
<widget class="QTableWidget" name="routesTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<column>
<property name="text">
<string>#Type</string>
<string>#InBounds</string>
</property>
</column>
<column>
@ -136,11 +139,7 @@
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget">
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
<widget class="QListWidget" name="inboundsList"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
@ -191,7 +190,7 @@
<item row="0" column="1">
<widget class="QLabel" name="inboundTagLabel">
<property name="text">
<string>TextLabel</string>
<string/>
</property>
</widget>
</item>
@ -205,7 +204,35 @@
<item row="1" column="1">
<widget class="QLabel" name="inboundTypeLabel">
<property name="text">
<string>TextLabel</string>
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>#Address</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>#Port</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="inboundAddressLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="inboundPortLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
@ -215,7 +242,7 @@
</layout>
</item>
<item row="0" column="2">
<layout class="QVBoxLayout" name="outboundLayout" stretch="0,1,0,1">
<layout class="QVBoxLayout" name="outboundLayout" stretch="0,0,0,0">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
@ -269,14 +296,14 @@
<string>#OutboundDetail</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>#Tag</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QLabel" name="outboundTagLabel">
<property name="text">
<string/>
@ -320,45 +347,45 @@
</item>
</layout>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>#Type</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>#Address</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>#Port</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QLabel" name="outboundTypeLabel">
<property name="text">
<string>xx</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="outboundAddressLabel">
<property name="text">
<string>xx</string>
<string/>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="outboundAddressLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="outboundPortLabel">
<property name="text">
<string>xx</string>
<string/>
</property>
</widget>
</item>