mirror of
https://github.com/Qv2ray/Qv2ray.git
synced 2025-05-20 02:40:20 +08:00
parent
5bb39a133b
commit
ee667d1a07
@ -1 +1 @@
|
||||
1620
|
||||
1636
|
||||
|
@ -57,83 +57,48 @@ namespace Qv2ray
|
||||
case 4: {
|
||||
// From 2 to 3, we changed the "proxyCN" to "bypassCN" as it's easier to understand....
|
||||
auto v2_oldProxyCN = root["proxyCN"].toBool();
|
||||
root.remove("proxyCN");
|
||||
root.insert("bypassCN", !v2_oldProxyCN);
|
||||
UPDATELOG("Upgrading proxyCN to bypassCN and changed the value to " + to_string(!v2_oldProxyCN))
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
//
|
||||
auto v3_oldrunAsRoot = root["runAsRoot"].toBool();
|
||||
// From 3 to 4, we changed 'runAsRoot' to 'tProxySupport'
|
||||
root.remove("runAsRoot");
|
||||
root.insert("tProxySupport", v3_oldrunAsRoot);
|
||||
UPDATELOG("Upgrading runAsRoot to tProxySupport, the value is not changed: " + to_string(v3_oldrunAsRoot))
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
root["enableStats"] = true;
|
||||
UPDATELOG("Default statistics enabled.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: {
|
||||
//
|
||||
//
|
||||
QString path;
|
||||
path = QV2RAY_DEFAULT_VCORE_PATH;
|
||||
root["v2CorePath"] = path;
|
||||
UPDATELOG("Added v2CorePath to the config file.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 8: {
|
||||
//
|
||||
auto lang = root["language"].toString();
|
||||
QJsonObject uiSettings;
|
||||
uiSettings["language"] = lang;
|
||||
root["uiConfig"] = uiSettings;
|
||||
UPDATELOG("Reconstructing config file.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 9: {
|
||||
root["uiConfig"] = root["UISettings"];
|
||||
root.remove("UISettings");
|
||||
UPDATELOG("Renamed UISettings to uiConfig.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 10: {
|
||||
//
|
||||
root["inboundConfig"] = root["inBoundSettings"];
|
||||
root.remove("inBoundSettings");
|
||||
UPDATELOG("Renamed inBoundSettings to inboundConfig.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 11: {
|
||||
//
|
||||
//connectionConfig
|
||||
QJsonObject o;
|
||||
o["dnsList"] = root["dnsList"];
|
||||
o["withLocalDNS"] = root["withLocalDNS"];
|
||||
o["enableProxy"] = root["enableProxy"];
|
||||
o["bypassCN"] = root["bypassCN"];
|
||||
o["enableStats"] = root["enableStats"];
|
||||
o["statsPort"] = root["statsPort"];
|
||||
o["bypassCN"] = !v2_oldProxyCN;
|
||||
o["enableStats"] = true;
|
||||
o["statsPort"] = 13459;
|
||||
UPDATELOG("Default statistics enabled.")
|
||||
root["connectionConfig"] = o;
|
||||
UPDATELOG("Renamed some connection configs to connectionConfig.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 12: {
|
||||
//
|
||||
auto inbound = root["inboundConfig"].toObject();
|
||||
auto pacConfig = inbound["pacConfig"].toObject();
|
||||
pacConfig["enablePAC"] = pacConfig["usePAC"].toBool();
|
||||
inbound["pacConfig"] = pacConfig;
|
||||
root["inboundConfig"] = inbound;
|
||||
UPDATELOG("Renamed usePAC to enablePAC.")
|
||||
break;
|
||||
}
|
||||
|
||||
case 13: {
|
||||
//
|
||||
ConfigIdentifier i;
|
||||
i.connectionName = root["autoStartConfig"].toString().toStdString();
|
||||
root["autoStartConfig"] = GetRootObject(i);
|
||||
|
@ -5,33 +5,34 @@ namespace Qv2ray
|
||||
{
|
||||
namespace Components
|
||||
{
|
||||
TCPingModel::TCPingModel(int defaultCount, QObject *parent) : QObject(parent)
|
||||
QvTCPingModel::QvTCPingModel(int defaultCount, QObject *parent) : QObject(parent)
|
||||
{
|
||||
count = defaultCount;
|
||||
}
|
||||
void TCPingModel::StartPing(const QString &connectionName, const QString &hostName, int port)
|
||||
void QvTCPingModel::StartPing(const QString &connectionName, const QString &hostName, int port)
|
||||
{
|
||||
QvTCPingData data;
|
||||
data.hostName = hostName;
|
||||
data.port = port;
|
||||
data.connectionName = connectionName;
|
||||
auto watcher = new QFutureWatcher<QvTCPingData>(this);
|
||||
watcher->setFuture(QtConcurrent::run(&TCPingModel::startTestLatency, data, count));
|
||||
DEBUG(MODULE_NETWORK, "Start Ping: " + hostName.toStdString() + ":" + to_string(port))
|
||||
watcher->setFuture(QtConcurrent::run(&QvTCPingModel::startTestLatency, data, count));
|
||||
pingWorkingThreads.enqueue(watcher);
|
||||
connect(watcher, &QFutureWatcher<void>::finished, this, [this, watcher]() {
|
||||
this->pingWorkingThreads.removeOne(watcher);
|
||||
auto result = watcher->result();
|
||||
LOG(MODULE_NETWORK, "Ping finished: " + result.hostName.toStdString() + ":" + to_string(result.port) + " --> " + to_string(result.avg) + "ms")
|
||||
DEBUG(MODULE_NETWORK, "Ping finished: " + result.hostName.toStdString() + ":" + to_string(result.port) + " --> " + to_string(result.avg) + "ms")
|
||||
|
||||
if (!result.errorMessage.isEmpty()) {
|
||||
LOG(MODULE_NETWORK, "--> " + result.errorMessage.toStdString())
|
||||
LOG(MODULE_NETWORK, "Ping --> " + result.errorMessage.toStdString())
|
||||
}
|
||||
|
||||
emit this->PingFinished(result);
|
||||
});
|
||||
}
|
||||
|
||||
QvTCPingData TCPingModel::startTestLatency(QvTCPingData data, const int count)
|
||||
QvTCPingData QvTCPingModel::startTestLatency(QvTCPingData data, const int count)
|
||||
{
|
||||
double successCount = 0, errorCount = 0;
|
||||
addrinfo *resolved;
|
||||
@ -75,7 +76,7 @@ namespace Qv2ray
|
||||
}
|
||||
|
||||
currentCount++;
|
||||
sleep(1);
|
||||
QThread::msleep(500);
|
||||
}
|
||||
|
||||
data.avg = data.avg / successCount;
|
||||
@ -83,7 +84,7 @@ namespace Qv2ray
|
||||
return data;
|
||||
}
|
||||
|
||||
int TCPingModel::resolveHost(const string &host, int port, addrinfo **res)
|
||||
int QvTCPingModel::resolveHost(const string &host, int port, addrinfo **res)
|
||||
{
|
||||
addrinfo hints;
|
||||
#ifdef _WIN32
|
||||
@ -99,7 +100,7 @@ namespace Qv2ray
|
||||
return getaddrinfo(host.c_str(), to_string(port).c_str(), &hints, res);
|
||||
}
|
||||
|
||||
int TCPingModel::testLatency(struct addrinfo *addr, struct timeval *rtt)
|
||||
int QvTCPingModel::testLatency(struct addrinfo *addr, struct timeval *rtt)
|
||||
{
|
||||
int fd;
|
||||
struct timeval start;
|
||||
|
@ -26,14 +26,13 @@ namespace Qv2ray
|
||||
double min = 999999999999999.0, max = 0.0, avg = 0.0;
|
||||
};
|
||||
//
|
||||
//
|
||||
|
||||
class TCPingModel : public QObject
|
||||
class QvTCPingModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TCPingModel(int defaultCount = 5, QObject *parent = nullptr);
|
||||
explicit QvTCPingModel(int defaultCount = 5, QObject *parent = nullptr);
|
||||
void StartPing(const QString &connectionName, const QString &hostName, int port);
|
||||
signals:
|
||||
void PingFinished(QvTCPingData data);
|
||||
|
@ -56,7 +56,7 @@
|
||||
MainWindow *MainWindow::mwInstance = nullptr;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent):
|
||||
QMainWindow(parent), vinstance(), uploadList(), downloadList(), HTTPRequestHelper(),
|
||||
QMainWindow(parent), vinstance(), uploadList(), downloadList(),
|
||||
hTray(new QSystemTrayIcon(this)), vCoreLogHighlighter(), qvAppLogHighlighter()
|
||||
{
|
||||
MainWindow::mwInstance = this;
|
||||
@ -86,6 +86,10 @@ MainWindow::MainWindow(QWidget *parent):
|
||||
logTimerId = startTimer(500);
|
||||
//
|
||||
pacServer = new PACServer();
|
||||
tcpingModel = new QvTCPingModel(5, this);
|
||||
requestHelper = new QvHttpRequestHelper();
|
||||
connect(tcpingModel, &QvTCPingModel::PingFinished, this, &MainWindow::onPingFinished);
|
||||
//
|
||||
this->setWindowIcon(QIcon(":/icons/qv2ray.png"));
|
||||
hTray->setIcon(QIcon(currentConfig.uiConfig.useDarkTrayIcon ? ":/icons/ui_dark/tray.png" : ":/icons/ui_light/tray.png"));
|
||||
importConfigButton->setIcon(QICON_R("import.png"));
|
||||
@ -154,8 +158,6 @@ MainWindow::MainWindow(QWidget *parent):
|
||||
listMenu->addAction(action_RCM_ShareQR);
|
||||
//
|
||||
ReloadConnections();
|
||||
connect(&HTTPRequestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate);
|
||||
HTTPRequestHelper.get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest");
|
||||
//
|
||||
// For charts
|
||||
uploadSerie = new QSplineSeries(this);
|
||||
@ -221,6 +223,8 @@ MainWindow::MainWindow(QWidget *parent):
|
||||
this->show();
|
||||
}
|
||||
|
||||
connect(requestHelper, &QvHttpRequestHelper::httpRequestFinished, this, &MainWindow::VersionUpdate);
|
||||
requestHelper->get("https://api.github.com/repos/lhy0403/Qv2ray/releases/latest");
|
||||
StartProcessingPlugins();
|
||||
}
|
||||
|
||||
@ -229,6 +233,7 @@ void MainWindow::SetEditWidgetEnable(bool enabled)
|
||||
removeConfigButton->setEnabled(enabled);
|
||||
editConfigButton->setEnabled(enabled);
|
||||
duplicateBtn->setEnabled(enabled);
|
||||
pingTestBtn->setEnabled(enabled);
|
||||
editJsonBtn->setEnabled(enabled);
|
||||
shareBtn->setEnabled(enabled);
|
||||
}
|
||||
@ -320,6 +325,7 @@ void MainWindow::ReloadConnections()
|
||||
_o.subscriptionName = "";
|
||||
_o.connectionName = _regularConnections.keys()[i];
|
||||
_o.config = _regularConnections.values()[i];
|
||||
_o.latency = 0;
|
||||
connections[_o.connectionName] = _o;
|
||||
connectionListWidget->addTopLevelItem(new QTreeWidgetItem(QStringList() << _o.connectionName));
|
||||
}
|
||||
@ -337,6 +343,7 @@ void MainWindow::ReloadConnections()
|
||||
_o.subscriptionName = subName;
|
||||
_o.connectionName = _subsConnections.values()[i].keys()[j];
|
||||
_o.config = _subsConnections.values()[i].values()[j];
|
||||
_o.latency = 0;
|
||||
auto connName = _o.connectionName + " (" + tr("Subscription:") + " " + _o.subscriptionName + ")";
|
||||
connections[connName] = _o;
|
||||
subTopLevel->addChild(new QTreeWidgetItem(QStringList() << connName));
|
||||
@ -418,10 +425,13 @@ void MainWindow::on_startButton_clicked()
|
||||
bool startFlag = this->vinstance->StartConnection(CurrentFullConfig, currentConfig.connectionConfig.enableStats, currentConfig.connectionConfig.statsPort);
|
||||
|
||||
if (startFlag) {
|
||||
on_pingTestBtn_clicked();
|
||||
|
||||
if (currentConfig.connectionConfig.enableStats) {
|
||||
speedTimerId = startTimer(1000);
|
||||
}
|
||||
|
||||
pingTimerId = startTimer(60000);
|
||||
this->hTray->showMessage("Qv2ray", tr("Connected To Server: ") + CurrentConnectionName, this->windowIcon());
|
||||
hTray->setToolTip(TRAY_TOOLTIP_PREFIX NEWLINE + tr("Connected To Server: ") + CurrentConnectionName);
|
||||
statusLabel->setText(tr("Connected") + ": " + CurrentConnectionName);
|
||||
@ -525,6 +535,7 @@ void MainWindow::on_stopButton_clicked()
|
||||
// Is running or starting
|
||||
this->vinstance->StopConnection();
|
||||
killTimer(speedTimerId);
|
||||
killTimer(pingTimerId);
|
||||
hTray->setToolTip(TRAY_TOOLTIP_PREFIX);
|
||||
QFile(QV2RAY_GENERATED_FILE_PATH).remove();
|
||||
statusLabel->setText(tr("Disconnected"));
|
||||
@ -631,6 +642,12 @@ void MainWindow::ShowAndSetConnection(QString guiConnectionName, bool SetConnect
|
||||
auto isComplexConfig = CheckIsComplexConfig(root);
|
||||
routeCountLabel->setText(isComplexConfig ? tr("Complex") : tr("Simple"));
|
||||
|
||||
if (conf.latency == 0.0) {
|
||||
latencyLabel->setText(tr("No data yet"));
|
||||
} else {
|
||||
latencyLabel->setText(QString::number(conf.latency) + " " + tr("ms"));
|
||||
}
|
||||
|
||||
if (conf.configType == CON_SUBSCRIPTION) {
|
||||
routeCountLabel->setText(routeCountLabel->text().append(" (" + tr("From subscription") + ":" + conf.subscriptionName + ")"));
|
||||
}
|
||||
@ -962,6 +979,13 @@ void MainWindow::on_editJsonBtn_clicked()
|
||||
void MainWindow::on_pingTestBtn_clicked()
|
||||
{
|
||||
// Ping
|
||||
if (!IsSelectionConnectable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We get data from UI?
|
||||
auto alias = connectionListWidget->currentItem()->text(0);
|
||||
tcpingModel->StartPing(alias, _hostLabel->text(), stoi(_portLabel->text().isEmpty() ? "0" : _portLabel->text().toStdString()));
|
||||
}
|
||||
void MainWindow::on_shareBtn_clicked()
|
||||
{
|
||||
@ -1038,6 +1062,8 @@ void MainWindow::timerEvent(QTimerEvent *event)
|
||||
if (!lastLog.isEmpty()) {
|
||||
qvAppLogBrowser->append(lastLog);
|
||||
}
|
||||
} else if (event->timerId() == pingTimerId) {
|
||||
on_pingTestBtn_clicked();
|
||||
}
|
||||
}
|
||||
void MainWindow::on_duplicateBtn_clicked()
|
||||
@ -1065,11 +1091,6 @@ void MainWindow::on_duplicateBtn_clicked()
|
||||
this->OnConfigListChanged(false);
|
||||
}
|
||||
|
||||
void MainWindow::on_masterLogBrowser_textChanged()
|
||||
{
|
||||
//setMasterLogHBar();
|
||||
}
|
||||
|
||||
void MainWindow::on_subsButton_clicked()
|
||||
{
|
||||
SubscribeEditor w;
|
||||
@ -1088,3 +1109,16 @@ void MainWindow::on_connectionListWidget_itemSelectionChanged()
|
||||
_portLabel->setText(tr("N/A"));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPingFinished(QvTCPingData data)
|
||||
{
|
||||
if (!connections.contains(data.connectionName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
connections[data.connectionName].latency = data.avg;
|
||||
|
||||
if (data.connectionName == CurrentConnectionName) {
|
||||
ShowAndSetConnection(CurrentConnectionName, false, false);
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,15 @@
|
||||
#include <QtCharts>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
#include "ui_w_MainWindow.h"
|
||||
|
||||
#include "QvUtils.hpp"
|
||||
#include "QvCoreInteractions.hpp"
|
||||
#include "QvCoreConfigOperations.hpp"
|
||||
#include "QvHTTPRequestHelper.hpp"
|
||||
#include "QvPACHandler.hpp"
|
||||
#include "QvLogHighlighter.hpp"
|
||||
|
||||
#include "ui_w_MainWindow.h"
|
||||
#include "QvTCPing.hpp"
|
||||
|
||||
enum TREENODEOBJECT_TYPE {
|
||||
CON_REGULAR = 1,
|
||||
@ -24,6 +25,7 @@ struct ConnectionObject {
|
||||
TREENODEOBJECT_TYPE configType;
|
||||
QString subscriptionName;
|
||||
QString connectionName;
|
||||
double latency;
|
||||
CONFIGROOT config;
|
||||
};
|
||||
|
||||
@ -38,6 +40,7 @@ class MainWindow : public QMainWindow, Ui::MainWindow
|
||||
void DisConnect() const;
|
||||
void ReConnect() const;
|
||||
public slots:
|
||||
void onPingFinished(QvTCPingData data);
|
||||
void UpdateVCoreLog(const QString &log);
|
||||
void OnConfigListChanged(bool need_restart);
|
||||
private slots:
|
||||
@ -80,8 +83,6 @@ class MainWindow : public QMainWindow, Ui::MainWindow
|
||||
|
||||
void on_duplicateBtn_clicked();
|
||||
|
||||
void on_masterLogBrowser_textChanged();
|
||||
|
||||
void on_subsButton_clicked();
|
||||
|
||||
public:
|
||||
@ -101,7 +102,6 @@ class MainWindow : public QMainWindow, Ui::MainWindow
|
||||
void on_action_RCM_EditJson_triggered();
|
||||
void on_action_RCM_ConvToComplex_triggered();
|
||||
void on_action_RCM_RenameConnection_triggered();
|
||||
|
||||
void on_connectionListWidget_itemSelectionChanged();
|
||||
|
||||
private:
|
||||
@ -127,16 +127,19 @@ class MainWindow : public QMainWindow, Ui::MainWindow
|
||||
//
|
||||
int logTimerId;
|
||||
int speedTimerId;
|
||||
int pingTimerId;
|
||||
//
|
||||
void ShowAndSetConnection(QString currentText, bool SetConnection, bool Apply);
|
||||
void ReloadConnections();
|
||||
//
|
||||
QvHttpRequestHelper HTTPRequestHelper;
|
||||
//
|
||||
QvHttpRequestHelper *requestHelper;
|
||||
QSystemTrayIcon *hTray;
|
||||
PACServer *pacServer;
|
||||
QvTCPingModel *tcpingModel;
|
||||
SyntaxHighlighter *vCoreLogHighlighter;
|
||||
SyntaxHighlighter *qvAppLogHighlighter;
|
||||
|
||||
//
|
||||
Qv2rayConfig currentConfig;
|
||||
|
||||
QList<QTextBrowser *> logTextBrowsers;
|
||||
|
@ -334,6 +334,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Latency</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="latencyLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -377,7 +391,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="pingTestBtn">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ping Test</string>
|
||||
|
Loading…
Reference in New Issue
Block a user