feat: Introduce more settings.

feat: Better ZJUConnect core error process.
feat: Added login dialog.
refactor: Make all child widgets be dialogs.
chore: Make setting system proxy default.
chore: Bump version to 1.2.0 .
This commit is contained in:
Chenx Dust
2024-08-20 18:37:51 +08:00
parent e80ec83ab2
commit 189bd62bf6
18 changed files with 964 additions and 564 deletions

View File

@@ -25,6 +25,7 @@ add_executable(${PROJECT_NAME} WIN32
zjuconnectcontroller/zjuconnectcontroller.cpp
portforwardingwindow/portforwardingwindow.cpp
settingwindow/settingwindow.cpp
loginwindow/loginwindow.cpp
utils/utils.cpp
resource.qrc
${CMAKE_CURRENT_SOURCE_DIR}/resource/icon.rc

View File

@@ -0,0 +1,42 @@
#include "loginwindow.h"
#include <QMessageBox>
LoginWindow::LoginWindow(QWidget *parent)
: QDialog(parent),
ui(new Ui::LoginWindow)
{
ui->setupUi(this);
setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose);
connect(ui->buttonBox, &QDialogButtonBox::accepted,
[&]()
{
if (ui->usernameLineEdit->text().isEmpty())
{
QMessageBox::warning(this, "警告", "账号不应为空!");
return;
}
else if (ui->passwordLineEdit->text().isEmpty())
{
QMessageBox::warning(this, "警告", "密码不应为空!");
return;
}
emit login(ui->usernameLineEdit->text(), ui->passwordLineEdit->text(), ui->saveLoginDetailCheckBox->isChecked());
emit accept();
}
);
}
LoginWindow::~LoginWindow()
{
delete ui;
}
void LoginWindow::setDetail(const QString& username, const QString& password)
{
ui->usernameLineEdit->setText(username);
ui->passwordLineEdit->setText(password);
}

22
loginwindow/loginwindow.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <QDialog>
#include "ui_loginwindow.h"
class LoginWindow : public QDialog
{
Q_OBJECT
public:
LoginWindow(QWidget *parent = nullptr);
~LoginWindow() override;
void setDetail(const QString& username, const QString& password);
signals:
void login(const QString& username, const QString& password, bool saveDetail);
private:
Ui::LoginWindow *ui;
};

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LoginWindow</class>
<widget class="QDialog" name="LoginWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>385</width>
<height>155</height>
</rect>
</property>
<property name="windowTitle">
<string>登录</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>登录</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="1">
<widget class="QLineEdit" name="passwordLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label1">
<property name="text">
<string>账号</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label2">
<property name="text">
<string>密码</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="usernameLineEdit"/>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="saveLoginDetailCheckBox">
<property name="text">
<string>记住登录信息(可在设置中删除)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>usernameLineEdit</tabstop>
<tabstop>passwordLineEdit</tabstop>
<tabstop>saveLoginDetailCheckBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LoginWindow</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -9,7 +9,7 @@ int main(int argc, char *argv[])
SingleApplication app(argc, argv);
QApplication::setApplicationName("HITsz Connect for Windows");
QApplication::setApplicationDisplayName("HITsz Connect for Windows");
QApplication::setApplicationVersion("1.1.6");
QApplication::setApplicationVersion("1.2.0");
// 愚人节彩蛋
QDate currentDate = QDate::currentDate();

View File

@@ -35,15 +35,9 @@ MainWindow::MainWindow(QWidget *parent) :
upgradeSettings();
isFirstTimeSetMode = true;
isL2tpLinked = false;
isL2tpReconnecting = false;
isWebLogged = false;
isZjuConnectLinked = false;
isZjuConnectLoginError = false;
isZjuConnectAccessDenied = false;
isZjuConnectListenFailed = false;
isZjuConnectSetupError = false;
isSystemProxySet = false;
zjuConnectError = ZJU_ERROR::NONE;
ui->setupUi(this);
@@ -325,8 +319,6 @@ void MainWindow::cleanUpWhenQuit()
if (settings->value("Common/ConfigVersion", "1").toInt() <= 2)
{
settings->setValue("Common/ConfigVersion", 2);
settings->setValue("Common/LastMode", mode);
settings->setValue("ZJUConnect/TunMode", ui->tunCheckBox->isChecked());
settings->sync();
}

View File

@@ -8,6 +8,7 @@
#include <QNetworkReply>
#include <QSettings>
#include "loginwindow/loginwindow.h"
#include "portforwardingwindow/portforwardingwindow.h"
#include "zjuconnectcontroller/zjuconnectcontroller.h"
#include "settingwindow/settingwindow.h"
@@ -75,22 +76,13 @@ private:
QObject *diagnosisContext;
SettingWindow *settingWindow;
QString mode;
LoginWindow *login_window;
bool isFirstTimeSetMode;
bool isL2tpLinked;
bool isL2tpReconnecting;
bool isWebLogged;
bool isZjuConnectLinked;
bool isZjuConnectLoginError;
bool isZjuConnectAccessDenied;
bool isZjuConnectListenFailed;
bool isZjuConnectSetupError;
bool isSystemProxySet;
ZJU_ERROR zjuConnectError;
};
#endif //MAINWINDOW_H

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>731</width>
<height>266</height>
<width>717</width>
<height>298</height>
</rect>
</property>
<widget class="QWidget" name="centralWidget">
@@ -36,22 +36,6 @@
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="tunCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>启用 TUN 模式需要以管理员权限运行程序</string>
</property>
<property name="text">
<string>TUN 模式</string>
</property>
</widget>
</item>
<item row="8" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -136,11 +120,10 @@ Line 2
<item row="2" column="1" colspan="3">
<widget class="QLabel" name="accountLabel">
<property name="text">
<string>提示:左上角“功能”→“设置”里可以填写账号信息。
可以使用 TUN 模式解决部分软件无法代理的问题
建议关闭 Clash 等代理后开启系统代理。
<string>提示:
左上角“功能”-&gt;“设置”里有更多可调整项目
建议关闭 Clash 等代理软件后开启系统代理。
一般而言,设置系统代理↘后即可使用。
使用中遇到任何问题欢迎加入 HITSZ OSA 进行反馈。</string>
</property>
</widget>
@@ -152,7 +135,7 @@ Line 2
<rect>
<x>0</x>
<y>0</y>
<width>731</width>
<width>717</width>
<height>22</height>
</rect>
</property>
@@ -221,7 +204,6 @@ Line 2
<tabstops>
<tabstop>pushButton1</tabstop>
<tabstop>pushButton2</tabstop>
<tabstop>tunCheckBox</tabstop>
<tabstop>copyLogPushButton</tabstop>
<tabstop>logPlainTextEdit</tabstop>
</tabstops>

View File

@@ -1,8 +1,8 @@
#include "portforwardingwindow.h"
#include "ui_portforwardingwindow.h"
PortForwardingWindow::PortForwardingWindow(QWidget *parent) :
QWidget(parent),
PortForwardingWindow::PortForwardingWindow(QDialog *parent) :
QDialog(parent),
ui(new Ui::PortForwardingWindow)
{
ui->setupUi(this);
@@ -11,11 +11,10 @@ PortForwardingWindow::PortForwardingWindow(QWidget *parent) :
512, 512, Qt::KeepAspectRatio, Qt::SmoothTransformation
)));
setWindowFlag(Qt::Window);
setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose);
connect(ui->applyPushButton, &QPushButton::clicked,
connect(ui->buttonBox, &QDialogButtonBox::accepted,
[&]()
{
QStringList tcpPortForwardingList;
@@ -45,9 +44,8 @@ PortForwardingWindow::PortForwardingWindow(QWidget *parent) :
}
emit applied(tcpPortForwardingList.join(","), udpPortForwardingList.join(","));
close();
});
}
PortForwardingWindow::~PortForwardingWindow()

View File

@@ -1,7 +1,7 @@
#ifndef PORTFORWARDINGWINDOW_H
#define PORTFORWARDINGWINDOW_H
#include <QWidget>
#include <QDialog>
#include "ui_portforwardingwindow.h"
namespace Ui
@@ -9,12 +9,12 @@ namespace Ui
class PortForwardingWindow;
}
class PortForwardingWindow : public QWidget
class PortForwardingWindow : public QDialog
{
Q_OBJECT
public:
explicit PortForwardingWindow(QWidget *parent = nullptr);
explicit PortForwardingWindow(QDialog *parent = nullptr);
~PortForwardingWindow() override;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PortForwardingWindow</class>
<widget class="QWidget" name="PortForwardingWindow">
<widget class="QDialog" name="PortForwardingWindow">
<property name="geometry">
<rect>
<x>0</x>
@@ -17,13 +17,6 @@
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QPushButton" name="applyPushButton">
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QTextEdit" name="textEdit">
<property name="html">
@@ -38,19 +31,6 @@ li.checked::marker { content: &quot;\2612&quot;; }
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>213</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="text">
@@ -64,8 +44,48 @@ li.checked::marker { content: &quot;\2612&quot;; }
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PortForwardingWindow</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>244</x>
<y>295</y>
</hint>
<hint type="destinationlabel">
<x>244</x>
<y>158</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PortForwardingWindow</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>244</x>
<y>295</y>
</hint>
<hint type="destinationlabel">
<x>244</x>
<y>158</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -7,19 +7,117 @@
#include "ui_settingwindow.h"
SettingWindow::SettingWindow(QWidget *parent, QSettings *inputSettings) :
QWidget(parent),
QDialog(parent),
ui(new Ui::SettingWindow)
{
ui->setupUi(this);
this->settings = inputSettings;
setWindowFlag(Qt::Window);
setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose);
ui->passwordLineEdit->setEchoMode(QLineEdit::Password);
loadSettings();
connect(ui->portForwardingPushButton, &QPushButton::clicked,
[&]()
{
portForwardingWindow = new PortForwardingWindow(this);
portForwardingWindow->setPortForwarding(tcpPortForwarding, udpPortForwarding);
connect(portForwardingWindow, &PortForwardingWindow::applied, this,
[&](const QString &tcpForwarding, const QString &udpForwarding)
{
tcpPortForwarding = tcpForwarding;
udpPortForwarding = udpForwarding;
});
portForwardingWindow->show();
});
auto applySettings = [&]()
{
settings->setValue("Common/Username", ui->usernameLineEdit->text());
settings->setValue("Common/Password", QString(ui->passwordLineEdit->text().toUtf8().toBase64()));
settings->setValue("Common/AutoStart", ui->autoStartComboBox->currentText() == "");
settings->setValue("Common/ConnectAfterStart", ui->connectAfterStartComboBox->currentText() == "");
settings->setValue("Common/checkUpdateAfterStart", ui->checkUpdateAfterStartComboBox->currentText() == "");
settings->setValue("ZJUConnect/ServerAddress", ui->serverAddressLineEdit->text());
settings->setValue("ZJUConnect/ServerPort", ui->serverPortSpinBox->value());
settings->setValue("ZJUConnect/DNS", ui->dnsLineEdit->text());
settings->setValue("ZJUConnect/Socks5Port", ui->socks5PortSpinBox->value());
settings->setValue("ZJUConnect/HttpPort", ui->httpPortSpinBox->value());
settings->setValue("ZJUConnect/MultiLine", ui->multiLineCheckBox->isChecked());
settings->setValue("ZJUConnect/ProxyAll", ui->proxyAllCheckBox->isChecked());
settings->setValue("ZJUConnect/Debug", ui->debugCheckBox->isChecked());
settings->setValue("ZJUConnect/TcpPortForwarding", tcpPortForwarding);
settings->setValue("ZJUConnect/UdpPortForwarding", udpPortForwarding);
settings->setValue("ZJUConnect/AutoReconnect", ui->autoReconnectCheckBox->isChecked());
settings->setValue("ZJUConnect/ReconnectTime", ui->reconnectTimeSpinBox->value());
settings->setValue("ZJUConnect/AutoSetProxy", ui->autoSetProxyCheckBox->isChecked());
settings->setValue("ZJUConnect/Route", ui->routeCheckBox->isChecked());
settings->setValue("ZJUConnect/SecondaryDNS", ui->secondaryDnsLineEdit->text());
settings->setValue("ZJUConnect/ShadowsocksUrl", ui->shadowsocksUrlLineEdit->text());
settings->setValue("ZJUConnect/KeepAlive", ui->keepAliveCheckBox->isChecked());
settings->setValue("ZJUConnect/TunMode", ui->tunCheckBox->isChecked());
settings->setValue("ZJUConnect/DNSHijack", ui->dnsHijackCheckBox->isChecked());
settings->setValue("ZJUConnect/OutsideAccess", ui->outsideAccessCheckBox->isChecked());
settings->sync();
if (settings->value("Common/AutoStart").toBool())
{
QSettings autoStartSettings(
R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)",
QSettings::NativeFormat
);
autoStartSettings.setValue(
QApplication::applicationName(),
QCoreApplication::applicationFilePath().replace('/', '\\')
);
}
else
{
QSettings autoStartSettings(
R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)",
QSettings::NativeFormat
);
autoStartSettings.remove(QApplication::applicationName());
}
};
connect(ui->buttonBox, &QDialogButtonBox::accepted, applySettings);
connect(ui->buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, applySettings);
connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
[&]()
{
int status = QMessageBox::warning(this, "警告", "将会重置所有设置,是否继续?", QMessageBox::Ok, QMessageBox::Cancel);
if (status == QMessageBox::Ok)
{
settings->clear();
settings->sync();
loadSettings();
}
});
connect(ui->tunCheckBox, &QCheckBox::toggled,
[&](bool checked)
{
ui->routeCheckBox->setEnabled(checked);
ui->dnsHijackCheckBox->setEnabled(checked);
});
}
SettingWindow::~SettingWindow()
{
delete ui;
}
void SettingWindow::loadSettings()
{
ui->usernameLineEdit->setText(settings->value("Common/Username", "").toString());
ui->passwordLineEdit->setText(
QByteArray::fromBase64(settings->value("Common/Password", "").toString().toUtf8())
@@ -64,79 +162,15 @@ SettingWindow::SettingWindow(QWidget *parent, QSettings *inputSettings) :
udpPortForwarding = settings->value("ZJUConnect/UdpPortForwarding", "").toString();
ui->autoReconnectCheckBox->setChecked(settings->value("ZJUConnect/AutoReconnect", false).toBool());
ui->reconnectTimeSpinBox->setValue(settings->value("ZJUConnect/ReconnectTime", 1).toInt());
ui->autoSetProxyCheckBox->setChecked(settings->value("ZJUConnect/AutoSetProxy", false).toBool());
ui->autoSetProxyCheckBox->setChecked(settings->value("ZJUConnect/AutoSetProxy", true).toBool());
ui->routeCheckBox->setChecked(settings->value("ZJUConnect/Route", false).toBool());
ui->secondaryDnsLineEdit->setText(settings->value("ZJUConnect/SecondaryDNS", "").toString());
ui->shadowsocksUrlLineEdit->setText(settings->value("ZJUConnect/ShadowsocksUrl", "").toString());
ui->keepAliveCheckBox->setChecked(settings->value("ZJUConnect/KeepAlive", true).toBool());
ui->tunCheckBox->setChecked(settings->value("ZJUConnect/TunMode", false).toBool());
ui->dnsHijackCheckBox->setChecked(settings->value("ZJUConnect/DNSHijack", false).toBool());
ui->outsideAccessCheckBox->setChecked(settings->value("ZJUConnect/OutsideAccess", false).toBool());
connect(ui->portForwardingPushButton, &QPushButton::clicked,
[&]()
{
portForwardingWindow = new PortForwardingWindow(this);
portForwardingWindow->setPortForwarding(tcpPortForwarding, udpPortForwarding);
connect(portForwardingWindow, &PortForwardingWindow::applied, this,
[&](const QString &tcpForwarding, const QString &udpForwarding)
{
tcpPortForwarding = tcpForwarding;
udpPortForwarding = udpForwarding;
});
portForwardingWindow->show();
});
connect(ui->applyPushButton, &QPushButton::clicked,
[&]()
{
settings->setValue("Common/Username", ui->usernameLineEdit->text());
settings->setValue("Common/Password", QString(ui->passwordLineEdit->text().toUtf8().toBase64()));
settings->setValue("Common/AutoStart", ui->autoStartComboBox->currentText() == "");
settings->setValue("Common/ConnectAfterStart", ui->connectAfterStartComboBox->currentText() == "");
settings->setValue("Common/checkUpdateAfterStart", ui->checkUpdateAfterStartComboBox->currentText() == "");
settings->setValue("ZJUConnect/ServerAddress", ui->serverAddressLineEdit->text());
settings->setValue("ZJUConnect/ServerPort", ui->serverPortSpinBox->value());
settings->setValue("ZJUConnect/DNS", ui->dnsLineEdit->text());
settings->setValue("ZJUConnect/Socks5Port", ui->socks5PortSpinBox->value());
settings->setValue("ZJUConnect/HttpPort", ui->httpPortSpinBox->value());
settings->setValue("ZJUConnect/MultiLine", ui->multiLineCheckBox->isChecked());
settings->setValue("ZJUConnect/ProxyAll", ui->proxyAllCheckBox->isChecked());
settings->setValue("ZJUConnect/Debug", ui->debugCheckBox->isChecked());
settings->setValue("ZJUConnect/TcpPortForwarding", tcpPortForwarding);
settings->setValue("ZJUConnect/UdpPortForwarding", udpPortForwarding);
settings->setValue("ZJUConnect/AutoReconnect", ui->autoReconnectCheckBox->isChecked());
settings->setValue("ZJUConnect/ReconnectTime", ui->reconnectTimeSpinBox->value());
settings->setValue("ZJUConnect/AutoSetProxy", ui->autoSetProxyCheckBox->isChecked());
settings->setValue("ZJUConnect/Route", ui->routeCheckBox->isChecked());
settings->sync();
if (settings->value("Common/AutoStart").toBool())
{
QSettings autoStartSettings(
R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)",
QSettings::NativeFormat
);
autoStartSettings.setValue(
QApplication::applicationName(),
QCoreApplication::applicationFilePath().replace('/', '\\')
);
}
else
{
QSettings autoStartSettings(
R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)",
QSettings::NativeFormat
);
autoStartSettings.remove(QApplication::applicationName());
}
close();
});
connect(ui->cancelPushButton, &QPushButton::clicked, [&]() { close(); });
}
SettingWindow::~SettingWindow()
{
delete ui;
ui->routeCheckBox->setEnabled(ui->tunCheckBox->isChecked());
ui->dnsHijackCheckBox->setEnabled(ui->tunCheckBox->isChecked());
}

View File

@@ -1,7 +1,7 @@
#ifndef SETTINGWINDOW_H
#define SETTINGWINDOW_H
#include <QWidget>
#include <QDialog>
#include <QSettings>
#include "ui_settingwindow.h"
#include "../portforwardingwindow/portforwardingwindow.h"
@@ -11,7 +11,7 @@ namespace Ui
class SettingWindow;
}
class SettingWindow : public QWidget
class SettingWindow : public QDialog
{
Q_OBJECT
@@ -21,6 +21,8 @@ public:
~SettingWindow() override;
private:
void loadSettings();
Ui::SettingWindow *ui;
QSettings *settings;

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingWindow</class>
<widget class="QWidget" name="SettingWindow">
<widget class="QDialog" name="SettingWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>486</width>
<height>348</height>
<height>396</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,35 +17,11 @@
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>213</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="applyPushButton">
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="cancelPushButton">
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<item row="0" column="0" colspan="2">
<widget class="QTabWidget" name="tabWidget">
<property name="locale">
<locale language="Chinese" country="China"/>
</property>
<property name="currentIndex">
<number>0</number>
</property>
@@ -54,7 +30,113 @@
<string>通用</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="7" column="0" colspan="4">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>启动时</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="1" column="0">
<widget class="QLabel" name="commonTabLable5">
<property name="text">
<string>启动后自动连接</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="commonTabLable4">
<property name="text">
<string>开机自启动</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="autoStartComboBox">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maxVisibleItems">
<number>12</number>
</property>
<item>
<property name="text">
<string>否</string>
</property>
</item>
<item>
<property name="text">
<string>是</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="connectAfterStartComboBox">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<item>
<property name="text">
<string>否</string>
</property>
</item>
<item>
<property name="text">
<string>是</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1" rowspan="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>221</width>
<height>72</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="commonTabLable6">
<property name="text">
<string>启动后检查更新</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="checkUpdateAfterStartComboBox">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<item>
<property name="text">
<string>否</string>
</property>
</item>
<item>
<property name="text">
<string>是</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="6" column="0" colspan="2">
<spacer name="commonTabVerticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -68,123 +150,52 @@
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="commonTabLable2">
<property name="text">
<string>网络账号</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="commonTabLable6">
<property name="text">
<string>启动后检查更新</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="commonTabLable3">
<property name="text">
<string>网络密码</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QComboBox" name="connectAfterStartComboBox">
<item>
<property name="text">
<string>否</string>
</property>
</item>
<item>
<property name="text">
<string>是</string>
</property>
</item>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="passwordLineEdit">
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="usernameLineEdit"/>
</item>
<item row="4" column="3">
<widget class="QComboBox" name="autoStartComboBox">
<property name="maxVisibleItems">
<number>12</number>
</property>
<item>
<property name="text">
<string>否</string>
</property>
</item>
<item>
<property name="text">
<string>是</string>
</property>
</item>
</widget>
</item>
<item row="6" column="3">
<widget class="QComboBox" name="checkUpdateAfterStartComboBox">
<item>
<property name="text">
<string>否</string>
</property>
</item>
<item>
<property name="text">
<string>是</string>
</property>
</item>
</widget>
</item>
<item row="4" column="2" rowspan="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>170</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="commonTabLable4">
<property name="text">
<string>开机启动</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>170</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0">
<widget class="QLabel" name="commonTabLable5">
<property name="text">
<string>启动后自动连接</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="4">
<widget class="Line" name="commonTabLine1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>保存的信息</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="2">
<widget class="QLineEdit" name="usernameLineEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="commonTabLable2">
<property name="text">
<string>账号</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="passwordLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="commonTabLable3">
<property name="text">
<string>密码</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>100</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
@@ -194,38 +205,140 @@
<string>高级</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="zjuConnectTabLabel2">
<item row="6" column="0">
<widget class="QLabel" name="zjuConnectTabLabel7">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>服务器端口</string>
<string>自动重连时间(秒)</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QCheckBox" name="debugCheckBox">
<property name="text">
<string>调试模式</string>
<item row="2" column="1" colspan="3">
<widget class="QLineEdit" name="secondaryDnsLineEdit">
<property name="font">
<font>
<bold>false</bold>
</font>
</property>
<property name="placeholderText">
<string>不填则采用系统 DNS ,使用 DNS 劫持必须填写</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QCheckBox" name="autoReconnectCheckBox">
<property name="toolTip">
<string>断线自动重连</string>
<item row="1" column="0">
<widget class="QLabel" name="zjuConnectTabLabel8">
<property name="font">
<font>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>自动重连</string>
</property>
<property name="checked">
<bool>false</bool>
<string>DNS 服务器</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="9" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0">
<widget class="QCheckBox" name="autoSetProxyCheckBox">
<property name="toolTip">
<string>连接服务器后自动设置代理</string>
</property>
<property name="text">
<string>自动设置系统代理</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="multiLineCheckBox">
<property name="text">
<string>自动选择线路</string>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="proxyAllCheckBox">
<property name="text">
<string>代理全部流量</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="keepAliveCheckBox">
<property name="toolTip">
<string>连接服务器后自动设置代理</string>
</property>
<property name="text">
<string>定时保活</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="outsideAccessCheckBox">
<property name="toolTip">
<string>连接服务器后自动设置代理</string>
</property>
<property name="text">
<string>允许外部访问</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="debugCheckBox">
<property name="text">
<string>核心调试模式</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="dnsHijackCheckBox">
<property name="toolTip">
<string>TUN 模式下有效</string>
</property>
<property name="text">
<string>DNS 劫持TUN</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="routeCheckBox">
<property name="toolTip">
<string>TUN 模式下有效</string>
</property>
<property name="text">
<string>设置路由TUN</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="tunCheckBox">
<property name="toolTip">
<string>TUN 模式下有效</string>
</property>
<property name="text">
<string>TUN 模式</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="zjuConnectTabLabel6">
<property name="text">
@@ -233,38 +346,17 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QSpinBox" name="socks5PortSpinBox">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<item row="6" column="1" colspan="2">
<widget class="QSpinBox" name="reconnectTimeSpinBox">
<property name="maximum">
<number>65535</number>
<number>86400</number>
</property>
<property name="value">
<number>11080</number>
<number>1</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="multiLineCheckBox">
<property name="text">
<string>自动选择线路</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<item row="4" column="1" colspan="3">
<widget class="QSpinBox" name="httpPortSpinBox">
<property name="maximum">
<number>65535</number>
@@ -274,39 +366,19 @@
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="routeCheckBox">
<property name="toolTip">
<string>TUN 模式下有效</string>
</property>
<property name="text">
<string>自动设置路由</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="autoSetProxyCheckBox">
<property name="toolTip">
<string>连接服务器后自动设置代理</string>
</property>
<property name="text">
<string>自动设置系统代理</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="zjuConnectTabLabel5">
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="dnsLineEdit">
<property name="font">
<font>
<pointsize>9</pointsize>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>SOCKS5 代理端口</string>
<string>10.248.98.30</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<item row="0" column="3">
<widget class="QSpinBox" name="serverPortSpinBox">
<property name="font">
<font>
@@ -321,42 +393,6 @@
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<widget class="QPushButton" name="portForwardingPushButton">
<property name="text">
<string>设置端口转发</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="serverAddressLineEdit">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>vpn.hitsz.edu.cn</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QSpinBox" name="reconnectTimeSpinBox">
<property name="maximum">
<number>86400</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="proxyAllCheckBox">
<property name="text">
<string>代理全部流量</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="zjuConnectTabLabel1">
<property name="font">
@@ -369,39 +405,118 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="zjuConnectTabLabel7">
<item row="3" column="0">
<widget class="QLabel" name="zjuConnectTabLabel5">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>自动重连时间 (s)</string>
<string>SOCKS5 代理端口</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="serverAddressLineEdit">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>vpn.hitsz.edu.cn</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="zjuConnectTabLabel8">
<widget class="QLabel" name="zjuConnectTabLabel9">
<property name="font">
<font>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>DNS 服务器</string>
<string>备用 DNS</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="dnsLineEdit">
<item row="12" column="0" colspan="4">
<widget class="QPushButton" name="portForwardingPushButton">
<property name="text">
<string>设置端口转发</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QSpinBox" name="socks5PortSpinBox">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>11080</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label">
<property name="text">
<string>:</string>
</property>
</widget>
</item>
<item row="13" column="0" colspan="4">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="3">
<widget class="QCheckBox" name="autoReconnectCheckBox">
<property name="toolTip">
<string>断线自动重连</string>
</property>
<property name="text">
<string>启用</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="zjuConnectTabLabel7_2">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>Shadowsocks 服务器</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QLineEdit" name="shadowsocksUrlLineEdit">
<property name="font">
<font>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>10.248.98.30</string>
<property name="placeholderText">
<string>不填则不启用格式ss://chiper:password@server:port</string>
</property>
</widget>
</item>
@@ -409,30 +524,75 @@
</widget>
</widget>
</item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>usernameLineEdit</tabstop>
<tabstop>passwordLineEdit</tabstop>
<tabstop>autoStartComboBox</tabstop>
<tabstop>connectAfterStartComboBox</tabstop>
<tabstop>applyPushButton</tabstop>
<tabstop>cancelPushButton</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>checkUpdateAfterStartComboBox</tabstop>
<tabstop>serverAddressLineEdit</tabstop>
<tabstop>serverPortSpinBox</tabstop>
<tabstop>dnsLineEdit</tabstop>
<tabstop>secondaryDnsLineEdit</tabstop>
<tabstop>socks5PortSpinBox</tabstop>
<tabstop>httpPortSpinBox</tabstop>
<tabstop>shadowsocksUrlLineEdit</tabstop>
<tabstop>reconnectTimeSpinBox</tabstop>
<tabstop>multiLineCheckBox</tabstop>
<tabstop>proxyAllCheckBox</tabstop>
<tabstop>autoReconnectCheckBox</tabstop>
<tabstop>multiLineCheckBox</tabstop>
<tabstop>keepAliveCheckBox</tabstop>
<tabstop>outsideAccessCheckBox</tabstop>
<tabstop>autoSetProxyCheckBox</tabstop>
<tabstop>portForwardingPushButton</tabstop>
<tabstop>proxyAllCheckBox</tabstop>
<tabstop>debugCheckBox</tabstop>
<tabstop>tunCheckBox</tabstop>
<tabstop>routeCheckBox</tabstop>
<tabstop>dnsLineEdit</tabstop>
<tabstop>dnsHijackCheckBox</tabstop>
<tabstop>portForwardingPushButton</tabstop>
</tabstops>
<resources/>
<connections/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SettingWindow</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>239</x>
<y>374</y>
</hint>
<hint type="destinationlabel">
<x>242</x>
<y>197</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SettingWindow</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>239</x>
<y>374</y>
</hint>
<hint type="destinationlabel">
<x>242</x>
<y>197</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -67,7 +67,7 @@ void Utils::setWidgetFixedWhenHidden(QWidget *widget)
void Utils::showAboutMessageBox(QWidget *parent)
{
QMessageBox messageBox(parent);
messageBox.setWindowTitle("关于本软件");
messageBox.setWindowTitle("关于");
messageBox.setTextFormat(Qt::RichText);
QString aboutText = QApplication::applicationDisplayName() + " v" + QApplication::applicationVersion() +
"<br>针对哈工大深圳的修改版 ZJU-Connect-for-Windows" +

View File

@@ -11,21 +11,33 @@ ZjuConnectController::ZjuConnectController()
emit outputRead(output);
if (output.contains("Login failed") || output.contains("too many login failures"))
if (output.contains("Access is denied."))
{
emit loginFailed();
}
else if (output.contains("Access is denied."))
{
emit accessDenied();
emit error(ZJU_ERROR::ACCESS_DENIED);
}
else if (output.contains("listen failed"))
{
emit listenFailed();
emit error(ZJU_ERROR::LISTEN_FAILED);
}
else if (output.contains("client setup error"))
{
emit setupError();
emit error(ZJU_ERROR::CLIENT_FAILED);
}
else if (output.contains("Invalid username or password!"))
{
emit error(ZJU_ERROR::INVALID_DETAIL);
}
else if (output.contains("You are trying brute-force login on this IP address."))
{
emit error(ZJU_ERROR::BRUTE_FORCE);
}
else if (output.contains("Login failed") || output.contains("too many login failures"))
{
emit error(ZJU_ERROR::OTHER_LOGIN_FAILED);
}
else if (output.contains("panic"))
{
emit error(ZJU_ERROR::OTHER);
}
});
@@ -35,21 +47,33 @@ ZjuConnectController::ZjuConnectController()
emit outputRead(output);
if (output.contains("Login failed") || output.contains("too many login failures"))
if (output.contains("Access is denied."))
{
emit loginFailed();
}
else if (output.contains("Access is denied."))
{
emit accessDenied();
emit error(ZJU_ERROR::ACCESS_DENIED);
}
else if (output.contains("listen failed"))
{
emit listenFailed();
emit error(ZJU_ERROR::LISTEN_FAILED);
}
else if (output.contains("client setup error"))
{
emit setupError();
emit error(ZJU_ERROR::CLIENT_FAILED);
}
else if (output.contains("Invalid username or password!"))
{
emit error(ZJU_ERROR::INVALID_DETAIL);
}
else if (output.contains("You are trying brute-force login on this IP address."))
{
emit error(ZJU_ERROR::BRUTE_FORCE);
}
else if (output.contains("Login failed") || output.contains("too many login failures"))
{
emit error(ZJU_ERROR::OTHER_LOGIN_FAILED);
}
else if (output.contains("panic"))
{
emit error(ZJU_ERROR::OTHER);
}
});
@@ -60,21 +84,25 @@ ZjuConnectController::ZjuConnectController()
}
void ZjuConnectController::start(
const QString &program,
const QString &username,
const QString &password,
const QString &server,
const QString& program,
const QString& username,
const QString& password,
const QString& server,
int port,
const QString& dns,
const QString& secondaryDns,
bool disableMultiLine,
bool disableKeepAlive,
bool proxyAll,
const QString &socksBind,
const QString &httpBind,
const QString& socksBind,
const QString& httpBind,
const QString& shadowsocksUrl,
bool tunMode,
bool addRoute,
bool dnsHijack,
bool debugDump,
const QString &tcpPortForwarding,
const QString &udpPortForwarding
const QString& tcpPortForwarding,
const QString& udpPortForwarding
)
{
QStringList args;
@@ -97,11 +125,22 @@ void ZjuConnectController::start(
args.append(dns);
}
if (!secondaryDns.isEmpty())
{
args.append("-secondary-dns-server");
args.append(secondaryDns);
}
if (disableMultiLine)
{
args.append("-disable-multi-line");
}
if (disableKeepAlive)
{
args.append("-disable-keep-alive");
}
if (proxyAll)
{
args.append("-proxy-all");
@@ -110,7 +149,11 @@ void ZjuConnectController::start(
if (tunMode)
{
args.append("-tun-mode");
args.append("-dns-hijack");
if (dnsHijack)
{
args.append("-dns-hijack");
}
if (addRoute)
{
@@ -135,6 +178,12 @@ void ZjuConnectController::start(
args.append(httpBind);
}
if (!shadowsocksUrl.isEmpty())
{
args.append("-shadowsocks-url");
args.append(shadowsocksUrl);
}
if (!tcpPortForwarding.isEmpty())
{
args.append("-tcp-port-forwarding");
@@ -147,7 +196,8 @@ void ZjuConnectController::start(
args.append(udpPortForwarding);
}
emit outputRead("参数:" + args.join(' '));
QString timeString = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
emit outputRead(timeString + " VPN 启动!参数:" + args.join(' '));
zjuConnectProcess->start(program, QStringList({ "-username", username, "-password", password }) + args);
zjuConnectProcess->waitForStarted();

View File

@@ -3,6 +3,18 @@
#include <QtCore>
enum class ZJU_ERROR
{
NONE,
INVALID_DETAIL,
BRUTE_FORCE,
OTHER_LOGIN_FAILED,
ACCESS_DENIED,
LISTEN_FAILED,
CLIENT_FAILED,
OTHER,
};
class ZjuConnectController : public QObject
{
Q_OBJECT
@@ -13,21 +25,25 @@ public:
~ZjuConnectController() override;
void start(
const QString &program,
const QString &username,
const QString &password,
const QString &server = "",
const QString& program,
const QString& username,
const QString& password,
const QString& server = "",
int port = 0,
const QString& dns = "",
const QString& secondaryDns = "",
bool disableMultiLine = false,
bool disableKeepAlive = false,
bool proxyAll = false,
const QString &socksBind = "",
const QString &httpBind = "",
const QString& socksBind = "",
const QString& httpBind = "",
const QString& shadowsocksUrl = "",
bool tunMode = false,
bool addRoute = false,
bool dnsHijack = false,
bool debugDump = false,
const QString &tcpPortForwarding = "",
const QString &udpPortForwarding = ""
const QString& tcpPortForwarding = "",
const QString& udpPortForwarding = ""
);
void stop();
@@ -35,13 +51,7 @@ public:
signals:
void loginFailed();
void accessDenied();
void listenFailed();
void setupError();
void error(ZJU_ERROR err);
void outputRead(const QString &output);

View File

@@ -2,24 +2,13 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "loginwindow/loginwindow.h"
#include "utils/utils.h"
void MainWindow::setModeToZjuConnect()
{
mode = "RVPN";
clearLog();
ui->tunCheckBox->show();
if (settings->contains("ZJUConnect/TunMode"))
{
if (settings->value("ZJUConnect/TunMode").toBool())
{
ui->tunCheckBox->setChecked(true);
}
}
zjuConnectController = new ZjuConnectController();
disconnect(ui->pushButton1, &QPushButton::clicked, nullptr, nullptr);
@@ -29,36 +18,26 @@ void MainWindow::setModeToZjuConnect()
ui->pushButton2->hide();
// 连接服务器
connect(zjuConnectController, &ZjuConnectController::outputRead, this, [&](const QString &output)
{
ui->logPlainTextEdit->appendPlainText(output.trimmed());
});
connect(zjuConnectController, &ZjuConnectController::outputRead, this,
[&](const QString &output)
{
ui->logPlainTextEdit->appendPlainText(output.trimmed());
});
connect(zjuConnectController, &ZjuConnectController::loginFailed, this, [&]()
{
isZjuConnectLoginError = true;
});
connect(zjuConnectController, &ZjuConnectController::accessDenied, this, [&]()
{
isZjuConnectAccessDenied = true;
});
connect(zjuConnectController, &ZjuConnectController::listenFailed, this, [&]()
{
isZjuConnectListenFailed = true;
});
connect(zjuConnectController, &ZjuConnectController::setupError, this, [&]()
{
isZjuConnectSetupError = true;
});
connect(zjuConnectController, &ZjuConnectController::error, this,
[&](ZJU_ERROR err)
{
if (zjuConnectError == ZJU_ERROR::NONE)
{
zjuConnectError = err;
}
});
connect(zjuConnectController, &ZjuConnectController::finished, this, [&]()
{
if (
!isZjuConnectLoginError &&
!isZjuConnectAccessDenied &&
zjuConnectError != ZJU_ERROR::NONE &&
zjuConnectError != ZJU_ERROR::OTHER &&
settings->value("ZJUConnect/AutoReconnect", false).toBool() &&
isZjuConnectLinked
)
@@ -87,26 +66,34 @@ void MainWindow::setModeToZjuConnect()
}
ui->pushButton2->hide();
if (isZjuConnectLoginError)
switch (zjuConnectError)
{
isZjuConnectLoginError = false;
QMessageBox::critical(this, "错误", "登录失败!\n请检查设置中的网络账号和密码是否设置正确");
}
else if (isZjuConnectAccessDenied)
{
isZjuConnectAccessDenied = false;
QMessageBox::critical(this, "错误", "权限不足!\n请关闭程序,点击右键以管理员身份运行");
}
else if (isZjuConnectListenFailed)
{
isZjuConnectListenFailed = false;
QMessageBox::critical(this, "错误", "监听失败!\n请关闭占用端口的程序(如残留的 zju-connect.exe或者监听其它端口");
}
else if (isZjuConnectSetupError)
{
isZjuConnectSetupError = false;
QMessageBox::critical(this, "错误", "连接失败!\n请检查网络和服务器设置是否正确");
case ZJU_ERROR::INVALID_DETAIL:
QMessageBox::critical(this, "错误", "登录失败!\n请检查设置中的网络账号和密码是否设置正确");
break;
case ZJU_ERROR::BRUTE_FORCE:
QMessageBox::critical(this, "错误", "登录失败!\n登录尝试过于频繁IP 被风控,请稍后重试或换用 EasyConnect。");
break;
case ZJU_ERROR::OTHER_LOGIN_FAILED:
QMessageBox::critical(this, "错误", "登录失败!\n未知原因,可将日志反馈给开发者以便调查。");
break;
case ZJU_ERROR::ACCESS_DENIED:
QMessageBox::critical(this, "错误", "权限不足!\n请关闭程序,点击右键以管理员身份运行。");
break;
case ZJU_ERROR::LISTEN_FAILED:
QMessageBox::critical(this, "错误", "监听失败!\n请关闭占用端口的程序(如残留的 zju-connect.exe或者监听其它端口。");
break;
case ZJU_ERROR::CLIENT_FAILED:
QMessageBox::critical(this, "错误", "连接失败!\n可能是响应超时,请检查本地网络配置是否正常,服务器设置是否正确");
break;
case ZJU_ERROR::OTHER:
QMessageBox::critical(this, "错误", "其它错误!\n未知原因,可将日志反馈给开发者以便调查。");
break;
case ZJU_ERROR::NONE:
default:
break;
}
zjuConnectError = ZJU_ERROR::NONE;
});
connect(ui->pushButton1, &QPushButton::clicked,
@@ -114,51 +101,72 @@ void MainWindow::setModeToZjuConnect()
{
if (!isZjuConnectLinked)
{
addLog("VPN 启动!");
if (settings->value("ZJUConnect/ServerAddress", "vpn.hitsz.edu.cn").toString().isEmpty())
if (settings->contains("ZJUConnect/ServerAddress") &&
settings->value("ZJUConnect/ServerAddress").toString().isEmpty())
{
QMessageBox::critical(this, "错误", "服务器地址不能为空");
return;
}
if (settings->value("Common/Username", "").toString().isEmpty())
QString username_ = settings->value("Common/Username", "").toString();
QString password_ = QByteArray::fromBase64(settings->value("Common/Password", "").toString().toUtf8());
auto startZjuConnect = [this](const QString& username, const QString& password)
{
zjuConnectController->start(
"zju-connect.exe",
username,
password,
settings->value("ZJUConnect/ServerAddress", "vpn.hitsz.edu.cn").toString(),
settings->value("ZJUConnect/ServerPort", 443).toInt(),
settings->value("ZJUConnect/DNS").toString(),
settings->value("ZJUConnect/SecondaryDNS", "").toString(),
!settings->value("ZJUConnect/MultiLine", true).toBool(),
!settings->value("ZJUConnect/KeepAlive", true).toBool(),
settings->value("ZJUConnect/ProxyAll", false).toBool(),
"127.0.0.1:" + QString::number(settings->value("ZJUConnect/Socks5Port", 11080).toInt()),
"127.0.0.1:" + QString::number(settings->value("ZJUConnect/HttpPort", 11081).toInt()),
settings->value("ZJUConnect/ShadowsocksUrl", "").toString(),
settings->value("ZJUConnect/TunMode", false).toBool(),
settings->value("ZJUConnect/Route", false).toBool(),
settings->value("ZJUConnect/DNSHijack", false).toBool(),
settings->value("ZJUConnect/Debug", false).toBool(),
settings->value("ZJUConnect/TcpPortForwarding", "").toString(),
settings->value("ZJUConnect/UdpPortForwarding", "").toString()
);
isZjuConnectLinked = true;
ui->pushButton1->setText("断开服务器");
ui->pushButton2->show();
if (settings->value("ZJUConnect/AutoSetProxy", true).toBool())
{
ui->pushButton2->click();
}
};
if (username_.isEmpty() || password_.isEmpty())
{
QMessageBox::critical(this, "错误", "用户名不能为空");
return;
login_window = new LoginWindow(this);
login_window->setDetail(username_, password_);
connect(login_window, &LoginWindow::login, this,
[&, startZjuConnect](const QString& username, const QString& password, bool saveDetail)
{
if (saveDetail)
{
settings->setValue("Common/Username", username);
settings->setValue("Common/Password", QString(password.toUtf8().toBase64()));
settings->sync();
}
startZjuConnect(username, password);
}
);
login_window->show();
}
if (QByteArray::fromBase64(settings->value("Common/Password", "").toString().toUtf8()).isEmpty())
else
{
QMessageBox::critical(this, "错误", "密码不能为空");
return;
}
zjuConnectController->start(
"zju-connect.exe",
settings->value("Common/Username").toString(),
QByteArray::fromBase64(settings->value("Common/Password").toString().toUtf8()),
settings->value("ZJUConnect/ServerAddress").toString(),
settings->value("ZJUConnect/ServerPort", 443).toInt(),
settings->value("ZJUConnect/DNS").toString(),
!settings->value("ZJUConnect/MultiLine", true).toBool(),
settings->value("ZJUConnect/ProxyAll", false).toBool(),
"127.0.0.1:" + QString::number(settings->value("ZJUConnect/Socks5Port", 11080).toInt()),
"127.0.0.1:" + QString::number(settings->value("ZJUConnect/HttpPort", 11081).toInt()),
ui->tunCheckBox->isChecked(),
settings->value("ZJUConnect/Route", false).toBool(),
settings->value("ZJUConnect/Debug", false).toBool(),
settings->value("ZJUConnect/TcpPortForwarding", "").toString(),
settings->value("ZJUConnect/UdpPortForwarding", "").toString()
);
isZjuConnectLinked = true;
ui->pushButton1->setText("断开服务器");
ui->pushButton2->show();
if (settings->value("ZJUConnect/AutoSetProxy", false).toBool())
{
ui->pushButton2->click();
startZjuConnect(username_, password_);
}
}
else
@@ -189,17 +197,11 @@ void MainWindow::setModeToZjuConnect()
);
if (proxySettings.value("ProxyEnable", 0).toInt() == 1)
{
QMessageBox messageBox(this);
messageBox.setWindowTitle("警告");
messageBox.setText(
"当前已存在系统代理配置\n是否覆盖当前系统代理配置?"
);
int rtn = QMessageBox::warning(this, "警告",
"当前已存在系统代理配置(可能是 Clash 或其它代理软件)\n是否覆盖当前系统代理配置?",
QMessageBox::Yes | QMessageBox::No);
messageBox.addButton(QMessageBox::Yes)->setText("");
messageBox.addButton(QMessageBox::No)->setText("");
messageBox.setDefaultButton(QMessageBox::Yes);
if (messageBox.exec() == QMessageBox::No)
if (rtn == QMessageBox::No)
{
return;
}