[add] Added Ping for UI

Former-commit-id: 4db9e7108c
This commit is contained in:
Leroy.H.Y 2019-12-08 22:25:19 +08:00
parent 5bb39a133b
commit ee667d1a07
7 changed files with 92 additions and 76 deletions

View File

@ -1 +1 @@
1620
1636

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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>