diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ac1f40..b8715f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/loginwindow/loginwindow.cpp b/loginwindow/loginwindow.cpp new file mode 100644 index 0000000..3f7c2a6 --- /dev/null +++ b/loginwindow/loginwindow.cpp @@ -0,0 +1,42 @@ +#include "loginwindow.h" + +#include + +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); +} diff --git a/loginwindow/loginwindow.h b/loginwindow/loginwindow.h new file mode 100644 index 0000000..1e96ab6 --- /dev/null +++ b/loginwindow/loginwindow.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#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; +}; diff --git a/loginwindow/loginwindow.ui b/loginwindow/loginwindow.ui new file mode 100644 index 0000000..e6c78fe --- /dev/null +++ b/loginwindow/loginwindow.ui @@ -0,0 +1,93 @@ + + + LoginWindow + + + + 0 + 0 + 385 + 155 + + + + 登录 + + + + + + 登录 + + + + + + QLineEdit::Password + + + + + + + 账号 + + + + + + + 密码 + + + + + + + + + + 记住登录信息(可在设置中删除) + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + usernameLineEdit + passwordLineEdit + saveLoginDetailCheckBox + + + + + buttonBox + rejected() + LoginWindow + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/main.cpp b/main.cpp index ef97946..54c5b71 100644 --- a/main.cpp +++ b/main.cpp @@ -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(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 18c4e75..a374b2e 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -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(); } diff --git a/mainwindow.h b/mainwindow.h index 56aee0c..b1172ff 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -8,6 +8,7 @@ #include #include +#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 diff --git a/mainwindow.ui b/mainwindow.ui index 049730a..c21aa77 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 731 - 266 + 717 + 298 @@ -36,22 +36,6 @@ - - - - - 0 - 0 - - - - 启用 TUN 模式需要以管理员权限运行程序 - - - TUN 模式 - - - @@ -136,11 +120,10 @@ Line 2 - 提示:左上角“功能”→“设置”里可以填写账号信息。 -可以使用 TUN 模式解决部分软件无法代理的问题。 -建议关闭 Clash 等代理后开启系统代理。 + 提示: +左上角“功能”->“设置”里有更多可调整项目。 +建议关闭 Clash 等代理软件后开启系统代理。 -一般而言,设置系统代理↘后即可使用。 使用中遇到任何问题欢迎加入 HITSZ OSA 进行反馈。 @@ -152,7 +135,7 @@ Line 2 0 0 - 731 + 717 22 @@ -221,7 +204,6 @@ Line 2 pushButton1 pushButton2 - tunCheckBox copyLogPushButton logPlainTextEdit diff --git a/portforwardingwindow/portforwardingwindow.cpp b/portforwardingwindow/portforwardingwindow.cpp index dc99152..ae2fdb5 100644 --- a/portforwardingwindow/portforwardingwindow.cpp +++ b/portforwardingwindow/portforwardingwindow.cpp @@ -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() diff --git a/portforwardingwindow/portforwardingwindow.h b/portforwardingwindow/portforwardingwindow.h index 16de19d..15cb9ec 100644 --- a/portforwardingwindow/portforwardingwindow.h +++ b/portforwardingwindow/portforwardingwindow.h @@ -1,7 +1,7 @@ #ifndef PORTFORWARDINGWINDOW_H #define PORTFORWARDINGWINDOW_H -#include +#include #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; diff --git a/portforwardingwindow/portforwardingwindow.ui b/portforwardingwindow/portforwardingwindow.ui index 44eef90..095f4f8 100644 --- a/portforwardingwindow/portforwardingwindow.ui +++ b/portforwardingwindow/portforwardingwindow.ui @@ -1,7 +1,7 @@ PortForwardingWindow - + 0 @@ -17,13 +17,6 @@ - - - - 确定 - - - @@ -38,19 +31,6 @@ li.checked::marker { content: "\2612"; } - - - - Qt::Horizontal - - - - 213 - 20 - - - - @@ -64,8 +44,48 @@ li.checked::marker { content: "\2612"; } + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + - + + + buttonBox + rejected() + PortForwardingWindow + reject() + + + 244 + 295 + + + 244 + 158 + + + + + buttonBox + accepted() + PortForwardingWindow + accept() + + + 244 + 295 + + + 244 + 158 + + + + diff --git a/settingwindow/settingwindow.cpp b/settingwindow/settingwindow.cpp index 2f30870..9e6df3d 100644 --- a/settingwindow/settingwindow.cpp +++ b/settingwindow/settingwindow.cpp @@ -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()); } diff --git a/settingwindow/settingwindow.h b/settingwindow/settingwindow.h index eed3b8d..fc9329b 100644 --- a/settingwindow/settingwindow.h +++ b/settingwindow/settingwindow.h @@ -1,7 +1,7 @@ #ifndef SETTINGWINDOW_H #define SETTINGWINDOW_H -#include +#include #include #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; diff --git a/settingwindow/settingwindow.ui b/settingwindow/settingwindow.ui index d279b0f..f82e8ab 100644 --- a/settingwindow/settingwindow.ui +++ b/settingwindow/settingwindow.ui @@ -1,13 +1,13 @@ SettingWindow - + 0 0 486 - 348 + 396 @@ -17,35 +17,11 @@ - - - - Qt::Horizontal - - - - 213 - 20 - - - - - - - - 确定 - - - - - - - 取消 - - - - + + + + 0 @@ -54,7 +30,113 @@ 通用 - + + + + 启动时 + + + + + + 启动后自动连接 + + + + + + + 开机自启动 + + + + + + + + 150 + 0 + + + + 12 + + + + + + + + + + + + + + + + + + 150 + 0 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 221 + 72 + + + + + + + + 启动后检查更新 + + + + + + + + 150 + 0 + + + + + + + + + + + + + + + + + + Qt::Vertical @@ -68,123 +150,52 @@ - - - 网络账号 - - - - - - - 启动后检查更新 - - - - - - - 网络密码 - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 170 - 20 - - - - - - - - 开机启动 - - - - - - - Qt::Horizontal - - - - 170 - 20 - - - - - - - - 启动后自动连接 - - - - - - - Qt::Horizontal + + + 保存的信息 + + + + + + + + 账号 + + + + + + + QLineEdit::Password + + + + + + + 密码 + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 100 + 20 + + + + + @@ -194,38 +205,140 @@ 高级 - - + + 9 - 服务器端口 + 自动重连时间(秒) - - - - 调试模式 + + + + + false + + + + 不填则采用系统 DNS ,使用 DNS 劫持必须填写 - - - - 断线自动重连 + + + + + false + - 自动重连 - - - false + DNS 服务器 + + + + Qt::Horizontal + + + + + + + + + 连接服务器后自动设置代理 + + + 自动设置系统代理 + + + + + + + 自动选择线路 + + + false + + + false + + + + + + + 代理全部流量 + + + + + + + 连接服务器后自动设置代理 + + + 定时保活 + + + + + + + 连接服务器后自动设置代理 + + + 允许外部访问 + + + + + + + 核心调试模式 + + + + + + + TUN 模式下有效 + + + DNS 劫持(TUN) + + + + + + + TUN 模式下有效 + + + 设置路由(TUN) + + + + + + + TUN 模式下有效 + + + TUN 模式 + + + + + @@ -233,38 +346,17 @@ - - - - - 9 - - + + - 65535 + 86400 - 11080 + 1 - - - - 自动选择线路 - - - true - - - false - - - false - - - - + 65535 @@ -274,39 +366,19 @@ - - - - TUN 模式下有效 - - - 自动设置路由 - - - - - - - 连接服务器后自动设置代理 - - - 自动设置系统代理 - - - - - + + - 9 + false - SOCKS5 代理端口 + 10.248.98.30 - + @@ -321,42 +393,6 @@ - - - - 设置端口转发 - - - - - - - - 9 - - - - vpn.hitsz.edu.cn - - - - - - - 86400 - - - 1 - - - - - - - 代理全部流量 - - - @@ -369,39 +405,118 @@ - - + + 9 - 自动重连时间 (s) + SOCKS5 代理端口 + + + + + + + + 9 + + + + vpn.hitsz.edu.cn - + false - DNS 服务器 + 备用 DNS - - + + + + 设置端口转发 + + + + + + + + 9 + + + + 65535 + + + 11080 + + + + + + + : + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 断线自动重连 + + + 启用 + + + false + + + + + + + + 9 + + + + Shadowsocks 服务器 + + + + + false - - 10.248.98.30 + + 不填则不启用,格式:ss://chiper:password@server:port @@ -409,30 +524,75 @@ + + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults + + + + tabWidget usernameLineEdit passwordLineEdit autoStartComboBox connectAfterStartComboBox - applyPushButton - cancelPushButton - tabWidget + checkUpdateAfterStartComboBox serverAddressLineEdit serverPortSpinBox + dnsLineEdit + secondaryDnsLineEdit socks5PortSpinBox httpPortSpinBox + shadowsocksUrlLineEdit reconnectTimeSpinBox - multiLineCheckBox - proxyAllCheckBox autoReconnectCheckBox + multiLineCheckBox + keepAliveCheckBox + outsideAccessCheckBox autoSetProxyCheckBox - portForwardingPushButton + proxyAllCheckBox debugCheckBox + tunCheckBox routeCheckBox - dnsLineEdit + dnsHijackCheckBox + portForwardingPushButton - + + + buttonBox + rejected() + SettingWindow + reject() + + + 239 + 374 + + + 242 + 197 + + + + + buttonBox + accepted() + SettingWindow + accept() + + + 239 + 374 + + + 242 + 197 + + + + diff --git a/utils/utils.cpp b/utils/utils.cpp index 404cb25..86ef8e7 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -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() + "
针对哈工大深圳的修改版 ZJU-Connect-for-Windows" + diff --git a/zjuconnectcontroller/zjuconnectcontroller.cpp b/zjuconnectcontroller/zjuconnectcontroller.cpp index 185aa35..e94d6a3 100644 --- a/zjuconnectcontroller/zjuconnectcontroller.cpp +++ b/zjuconnectcontroller/zjuconnectcontroller.cpp @@ -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(); diff --git a/zjuconnectcontroller/zjuconnectcontroller.h b/zjuconnectcontroller/zjuconnectcontroller.h index cd397b3..f752622 100644 --- a/zjuconnectcontroller/zjuconnectcontroller.h +++ b/zjuconnectcontroller/zjuconnectcontroller.h @@ -3,6 +3,18 @@ #include +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); diff --git a/zjuconnectmode.cpp b/zjuconnectmode.cpp index 19d2e8c..79fddd8 100644 --- a/zjuconnectmode.cpp +++ b/zjuconnectmode.cpp @@ -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; }