Merge branch 'master' of github.com:c-my/NEU-Monitor

This commit is contained in:
w-mj
2018-07-31 20:37:52 +08:00
8 changed files with 177 additions and 140 deletions
+30 -9
View File
@@ -1,30 +1,51 @@
# NEU-Monitor
## 使用教程
* 注:软件只有托盘中的图标以及单击显示的菜单,并没有主窗口
1. 在设置中填好校园网账号,密码以及流量(剩余流量过少时发出提醒)
1. 在设置中填好校园网账号,密码以及流量(剩余流量过少时发出提醒,0为无限制)
2. 开始使用
3. 双击托盘图标可以登录
3. 双击或鼠标中键点击托盘图标可以登录或注销
![](optionsWindow.png)
![](menu.png)
## 自动登陆
1. 在已经登陆的状态下检测到校园网状态变为断开,此时会进行重新登陆,重新登陆等同于在ipgw网页点击`断开连接`后再进行`连接网络`
### 自动登陆
1. 在已经登陆的状态下检测到校园网状态变为断开,此时会进行重新登陆,重新登陆等同于在网关页面点击`断开连接`后再进行`连接网络`
2. 首次启动应用时进行登陆
3. 手动断开网络的情况下不会自动重新登陆
3. 手动点击断开网络后不会自动重新登陆
## 勿扰模式
### 断开连接
* 当前在线:仅注销当前连接
* 当前断开:断开全部连接
### 作为移动端登陆
开启此功能后将作为移动端登陆,由于校园网限制只能一个移动端和一个桌面端登陆,可用这一功能实现两台PC同时在线。
### 勿扰模式
该模式下不会发出系统通知
## 网络状态检测
### 账户信息
信息只有在进行登陆时才会更新
单击`IP地址`可将IP复制到剪切板
### 网络状态检测
*为了检测网络状态,此工具会持续向查询信息接口发送请求*
网络状态分为
* 未连接到校园网
* 连接到校园网并已经登陆
* 连接到校园网但未登陆
*为了检测网络状态,此工具会持续发送请求,~~可能由于请求频率过高,有很大概率会出现网关登陆被限制的情况(提示请5分钟之后再尝试)~~
**请不要短时间内频繁的进行登陆,否则会出现登陆受限的情况**
*请不要短时间内频繁的进行登陆,否则会出现登陆受限的情况
## 注意事项
1. 一旦网管登陆等接口出现变动,该软件会部分或全部失效
2. 请不要短时间内频繁的进行登陆,否则会出现登陆受限的情况
+22 -20
View File
@@ -7,12 +7,13 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
settingsMenu(new QMenu()),
//初始化settings
settings(QSettings::IniFormat, QSettings::UserScope, "Cai.MY", "NEU-Monitor"),
//初始化optionswindow
opWindow(settings.value("id", "").toByteArray(), QByteArray::fromBase64(settings.value("password", "").toByteArray()), settings.value("total traffic", 60).toInt()),
logFileName("NEU_Monitor.log"),
logFile(logFileName, this),
user(settings.value("id", "").toByteArray()),
passwd(QByteArray::fromBase64(settings.value("password", "").toByteArray()))
passwd(QByteArray::fromBase64(settings.value("password", "").toByteArray())),
totalTraffic(settings.value("total traffic", 0).toInt()),
isMobile(settings.value("isMobile", false).toBool()),
opWindow(user, passwd, totalTraffic, isMobile),
logFileName("NEU_Monitor.log"),
logFile(logFileName, this)
{
openLogFile();
@@ -21,10 +22,10 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
netctrl = new NetController(user, passwd, this); //passwd为解密后密码
connect(netctrl, &NetController::sendLog, this, &MainTray::writeLog);
totalTraffic = settings.value("total traffic", 60).toInt();
netctrl->setUsername(user);
netctrl->setPassword(passwd);
netctrl->setTotalTraffic(totalTraffic);
netctrl->setMobile(isMobile);
writeLog(tr("Load username[") + user + tr("] traffic[") + QString::number(totalTraffic) + tr("]."));
@@ -46,7 +47,6 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
optionsAction = new QAction(tr("选项"), this);
bootAction = new QAction(tr("开机启动"), this);
muteAction = new QAction(tr("勿扰模式"), this);
mobileAction = new QAction(tr("作为移动端"), this);
aboutAction = new QAction(tr("关于"), this);
quitAction = new QAction(tr("退出"), this);
@@ -62,7 +62,7 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
QClipboard *clipBoard = QApplication::clipboard();
clipBoard->setText(ipList.at(1));
}
if(!muteAction->isChecked())
if (!muteAction->isChecked())
{
showMessage(tr("复制成功"), tr("IP地址已复制到剪切板"));
}
@@ -71,21 +71,21 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
autoLogin->setCheckable(true);
bootAction->setCheckable(true);
muteAction->setCheckable(true);
mobileAction->setCheckable(true);
muteAction->setToolTip(tr("勿扰模式下不会发出通知"));
connect(loginAction, &QAction::triggered, this, [this]() {
writeLog(tr("Login triggered."));
isForceLogin = true;
netctrl->sendLogoutRequest(true, mobileAction->isChecked());
// netctrl->sendLogoutRequest(true);
logoutAction->trigger();
hasWarned = false;
netctrl->sendLoginRequest(mobileAction->isChecked());
netctrl->sendLoginRequest();
isForceLogout = false;
});
connect(logoutAction, &QAction::triggered, this, [this]() {
writeLog(tr("Logout triggered."));
netctrl->sendLogoutRequest(false, mobileAction->isChecked());
netctrl->sendLogoutRequest(currentState != NetController::Online); //若不在线则断开全部链接
isForceLogout = true;
});
connect(autoLogin, &QAction::toggled, this, [this](bool set) {
@@ -112,11 +112,9 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
autoLogin->setChecked(settings.value("isAutoLogin", true).toBool());
bootAction->setChecked(settings.value("isOnBoot", false).toBool());
muteAction->setChecked(settings.value("isMute", false).toBool());
mobileAction->setChecked(settings.value("isMobile", false).toBool());
settingsMenu->setTitle(tr("设置"));
settingsMenu->addAction(optionsAction);
settingsMenu->addAction(mobileAction);
settingsMenu->addAction(muteAction);
settingsMenu->addAction(bootAction);
@@ -187,6 +185,7 @@ void MainTray::showToolTip(NetController::State state)
default:
break;
}
tooltipString += tr("(") + (netctrl->getMobile() ? tr("Mobile") : tr("PC")) + tr(")");
tooltipString += tr("\n自动登陆:");
tooltipString += autoLogin->isChecked() ? tr("开启") : tr("关闭");
if (state == NetController::Online)
@@ -278,7 +277,7 @@ void MainTray::setAutoStart(bool set)
QFile file(path + "/ipgw.desktop");
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
{
if(!muteAction->isChecked())
if (!muteAction->isChecked())
{
showMessage(tr("设置失败"), tr("读写/home/.config/autostart/失败"), this->icon(), msgDur);
return;
@@ -308,7 +307,7 @@ void MainTray::openLogFile()
{
if (!logFile.open(QIODevice::Append | QIODevice::Text))
{
if(!muteAction->isChecked())
if (!muteAction->isChecked())
{
showMessage(tr("警告"), tr("日志文件打开失败"));
}
@@ -319,21 +318,24 @@ void MainTray::openLogFile()
logFile.close();
}
void MainTray::updateUserInfo(QByteArray id, QByteArray pass, int traffic) //pass为未加密的密码
void MainTray::updateUserInfo(QByteArray id, QByteArray pass, int traffic, bool isMobile) //pass为未加密的密码
{
writeLog(tr("Set username[") + id + tr("]; Traffic: [") + QString::number(traffic) + tr("]."));
logoutAction->trigger(); //注销当前via old info
netctrl->setUsername(id);
netctrl->setPassword(pass);
netctrl->setTotalTraffic(traffic);
netctrl->setMobile(isMobile);
user = id;
passwd = pass;
totalTraffic = traffic;
opWindow.hide();
netctrl->sendLoginRequest();
loginAction->trigger();
hasWarned = false;
settings.setValue("id", id);
settings.setValue("password", pass.toBase64());
settings.setValue("total traffic", traffic);
settings.setValue("isMobile", isMobile);
}
void MainTray::handleState(NetController::State state)
@@ -414,7 +416,7 @@ void MainTray::handleInfo(QString byte, QString sec, QString balance, QString ip
{ //流量已超
trafficstate = Over;
if (!muteAction->isChecked())
QTimer::singleShot(5000, this, [this]{
QTimer::singleShot(5000, this, [this] {
showMessage(tr("流量警告"), tr("本月流量已超"), QSystemTrayIcon::Warning);
});
}
@@ -422,7 +424,7 @@ void MainTray::handleInfo(QString byte, QString sec, QString balance, QString ip
{ //流量将超
trafficstate = Nearly;
if (!muteAction->isChecked())
QTimer::singleShot(5000, this, [this, leftoverString]{
QTimer::singleShot(5000, this, [this, leftoverString] {
showMessage(tr("流量预警"), tr("剩余流量:") + leftoverString + tr("G"));
});
}
+49 -44
View File
@@ -18,57 +18,62 @@
class MainTray : public QSystemTrayIcon
{
Q_OBJECT
public:
MainTray(QObject *parent = Q_NULLPTR);
~MainTray();
enum TrafficState
{
Normal,
Over,
Nearly
};
Q_OBJECT
public:
MainTray(QObject *parent = Q_NULLPTR);
~MainTray();
enum TrafficState
{
Normal,
Over,
Nearly
};
private:
QMenu *menu, *infoMenu, *settingsMenu;
QAction *loginAction, *logoutAction, *autoLogin, *optionsAction, *aboutAction, *quitAction;
QAction *mbAction, *timeAction, *balanceAction, *ipAction, *bootAction, *muteAction, *mobileAction;
NetController *netctrl;
QSettings settings;
OptionsWindow opWindow;
QTimer *autoLoginTimer; //自动重连定时器
QString logFileName;
QFile logFile;
QString olIconPath = tr(":/icons/favicon.ico");
QString offIconPath = tr(":/icons/offline.ico");
private:
QMenu *menu, *infoMenu, *settingsMenu;
QAction *loginAction, *logoutAction, *autoLogin, *optionsAction, *aboutAction, *quitAction;
QAction *mbAction, *timeAction, *balanceAction, *ipAction, *bootAction, *muteAction, *mobileAction;
NetController *netctrl;
QSettings settings;
bool isForceLogout = false;
bool isForceLogin = false;
bool hasWarned = false;
QByteArray user, passwd;
int totalTraffic;
bool isMobile = false;
NetController::State currentState = NetController::Unknown; //当前状态
TrafficState trafficstate = Normal;
OptionsWindow opWindow;
QTimer *autoLoginTimer; //自动重连定时器
void showToolTip(NetController::State state);
void handleActivated(QSystemTrayIcon::ActivationReason reason); //处理左键单击、双击
void showOptions(); //显示选项窗口
void showAbout(); //显示关于窗口
void setAutoStart(bool set);
QString logFileName;
QFile logFile;
QByteArray user, passwd;
int totalTraffic;
int msgDur = 500; //通知持续时间
int checkInterval = 1000; //查询状态定时器周期
QString olIconPath = tr(":/icons/favicon.ico");
QString offIconPath = tr(":/icons/offline.ico");
signals:
void exit();
bool isForceLogout = false;
bool isForceLogin = false;
bool hasWarned = false;
private slots:
void updateUserInfo(QByteArray id, QByteArray pass, int traffic);
void handleState(NetController::State state);
void handleInfo(QString mb, QString sec, QString balance, QString ip);
void openLogFile();
void writeLog(QString content, bool timeStamp = true);
NetController::State currentState = NetController::Unknown; //当前状态
TrafficState trafficstate = Normal;
void showToolTip(NetController::State state);
void handleActivated(QSystemTrayIcon::ActivationReason reason); //处理左键单击、双击
void showOptions(); //显示选项窗口
void showAbout(); //显示关于窗口
void setAutoStart(bool set);
int msgDur = 500; //通知持续时间
int checkInterval = 1000; //查询状态定时器周期
signals:
void exit();
private slots:
void updateUserInfo(QByteArray id, QByteArray pass, int traffic, bool isMobile);
void handleState(NetController::State state);
void handleInfo(QString mb, QString sec, QString balance, QString ip);
void openLogFile();
void writeLog(QString content, bool timeStamp = true);
};
#endif // MAINTRAY_H
+12 -14
View File
@@ -17,12 +17,11 @@ NetController::NetController(QByteArray id, QByteArray passwd, QObject *parent)
desktopRequest.setRawHeader("Accept-Encoding", "gzip, deflate");
desktopRequest.setRawHeader("Accept-Language", "zh-CN,zh;q=0.9");
mobileRequest.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
mobileRequest.setRawHeader("Accept-Encoding", "gzip, deflate");
mobileRequest.setRawHeader("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7");
mobileRequest.setRawHeader("Cache-Control", "max-age=0");
// mobileRequest.setHeader(QNetworkRequest::ContentLengthHeader, "85"); //XXX:这行一定不能有
// mobileRequest.setHeader(QNetworkRequest::ContentLengthHeader, "85"); //XXX:这行一定不能有
mobileRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
mobileRequest.setRawHeader("Host", "ipgw.neu.edu.cn");
mobileRequest.setRawHeader("Origin", "http://ipgw.neu.edu.cn");
@@ -31,7 +30,6 @@ NetController::NetController(QByteArray id, QByteArray passwd, QObject *parent)
mobileRequest.setRawHeader("Upgrade-Insecure-Requests", "1");
mobileRequest.setRawHeader("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36");
connect(&manager, &QNetworkAccessManager::finished, this, &NetController::handleResponse);
}
@@ -46,7 +44,7 @@ void NetController::sendCheckRequest()
manager.post(desktopRequest, checkParam);
}
void NetController::sendLoginRequest(bool isMobile)
void NetController::sendLoginRequest()
{
sendLog(tr("Send login request. [") + username + tr("]"));
@@ -62,7 +60,7 @@ void NetController::sendLoginRequest(bool isMobile)
loginParam.append("username=");
loginParam.append(username);
if(!isMobile)
if (!isMobile)
{
desktopRequest.setUrl(QUrl(desktopLoginUrl));
manager.post(desktopRequest, loginParam);
@@ -74,29 +72,29 @@ void NetController::sendLoginRequest(bool isMobile)
}
}
void NetController::sendLogoutRequest(bool isAll, bool isMobile)
void NetController::sendLogoutRequest(bool isAll)
{
sendLog(tr("Send logout request. [") + username + tr("]"));
QByteArray logoutParam;
logoutParam.append("action=logout&");
logoutParam.append("ajax=1&");
if(isAll)
if (isAll)
{
logoutParam.append("password=");//有password是全部断开
logoutParam.append("password="); //有password是全部断开
logoutParam.append(password);
logoutParam.append("&");
}
logoutParam.append("username=");
logoutParam.append(username);
if(!isMobile)
if (!isMobile)
{
desktopRequest.setUrl(QUrl(desktopLoginUrl));
manager.post(desktopRequest, logoutParam);
}
else
{
mobileRequest.setUrl(QUrl(mobileLoginUrl));//TODO:测试这样logout是否会影响pc端
mobileRequest.setUrl(QUrl(mobileLoginUrl));
manager.post(mobileRequest, logoutParam);
}
}
@@ -145,8 +143,8 @@ void NetController::handleResponse(QNetworkReply *reply)
emit sendState(Online);
}
}
// else if (url == mobileLoginUrl)
// {
// qDebug()<<reply->readAll().toStdString();
// }
// else if (url == mobileLoginUrl)
// {
// qDebug()<<reply->readAll().toStdString();
// }
}
+38 -35
View File
@@ -9,47 +9,50 @@
class NetController : public QObject
{
Q_OBJECT
public:
explicit NetController(QByteArray username, QByteArray password, QObject *parent = nullptr);
void checkState();
void sendCheckRequest();
void sendLoginRequest(bool isMobile=false);
void sendLogoutRequest(bool isAll=false, bool isMobile=false);
Q_OBJECT
public:
explicit NetController(QByteArray username, QByteArray password, QObject *parent = nullptr);
void checkState();
void sendCheckRequest();
void sendLoginRequest();
void sendLogoutRequest(bool isAll = false);
void setUsername(QByteArray newName) { username = newName; }
void setPassword(QByteArray newPass) { password = newPass; }
void setTotalTraffic(int newTraffic) { traffic = newTraffic; }
inline void setUsername(QByteArray newName) { username = newName; }
inline void setPassword(QByteArray newPass) { password = newPass; }
inline void setTotalTraffic(int newTraffic) { traffic = newTraffic; }
inline void setMobile(bool isMobile) { this->isMobile = isMobile; }
inline bool getMobile() { return this->isMobile; }
enum State
{
Unknown,
Offline,
Online,
Disconnected,
Owed,
WrongPass
};
enum State
{
Unknown,
Offline,
Online,
Disconnected,
Owed,
WrongPass
};
private:
QString checkUrl = "http://ipgw.neu.edu.cn/include/auth_action.php";
QString desktopLoginUrl = "http://ipgw.neu.edu.cn/srun_portal_pc.php?ac_id=1&";
QString mobileLoginUrl = "http://ipgw.neu.edu.cn/srun_portal_phone.php?ac_id=1&";
QString offlineString = "not_online";
QByteArray checkParam, username, password;
int traffic;
int onlineCount = 0, offlineCount = 0, disconnectCount = 0;
private:
QString checkUrl = "http://ipgw.neu.edu.cn/include/auth_action.php";
QString desktopLoginUrl = "http://ipgw.neu.edu.cn/srun_portal_pc.php?ac_id=1&";
QString mobileLoginUrl = "http://ipgw.neu.edu.cn/srun_portal_phone.php?ac_id=1&";
QString offlineString = "not_online";
QByteArray checkParam, username, password;
int traffic;
bool isMobile;
int onlineCount = 0, offlineCount = 0, disconnectCount = 0;
QNetworkAccessManager manager;
QNetworkRequest desktopRequest, mobileRequest;
QNetworkAccessManager manager;
QNetworkRequest desktopRequest, mobileRequest;
signals:
void sendState(State newState);
void sendInfo(QString mb, QString sec, QString balance, QString ip);
void sendLog(QString content, bool timeStamp = true);
signals:
void sendState(State newState);
void sendInfo(QString mb, QString sec, QString balance, QString ip);
void sendLog(QString content, bool timeStamp = true);
public slots:
void handleResponse(QNetworkReply *reply);
public slots:
void handleResponse(QNetworkReply *reply);
};
#endif // NETCONTROLLER_H
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

+8 -2
View File
@@ -1,6 +1,6 @@
#include "optionswindow.h"
OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidget *parent) : QMainWindow(parent)
OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, bool isMobile, QWidget *parent) : QMainWindow(parent)
{
setWindowTitle(tr("选项"));
@@ -20,6 +20,10 @@ OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidge
passwordEdit->setText(pass);
passwordEdit->setToolTip(tr("密码仅用于登陆"));
mobileCheck = new QCheckBox(tr("作为移动端登陆"), this);
mobileCheck->setChecked(isMobile);
mobileCheck->setToolTip(tr("实现PC多终端在线"));
trafficSpin = new QSpinBox(this);
trafficSpin->setValue(traffic);
trafficSpin->setToolTip(tr("0为无限制"));
@@ -30,6 +34,7 @@ OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidge
layout->addRow(tr("用户名"), idEdit);
layout->addRow(tr("密码"), passwordEdit);
layout->addRow(trafficLabel, trafficSpin);
layout->addRow(mobileCheck);
layout->setSpacing(20);
saveButton = new QPushButton("确定", this);
@@ -52,7 +57,8 @@ OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidge
connect(saveButton, &QPushButton::clicked, this, [this]() {
emit saveSettings(idEdit->text().toUtf8(),
passwordEdit->text().toUtf8(),
trafficSpin->value());
trafficSpin->value(),
mobileCheck->isChecked());
});
connect(cancleButton, &QPushButton::clicked, this, &OptionsWindow::hide);
}
+18 -16
View File
@@ -10,29 +10,31 @@
#include <QFormLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QCheckBox>
#include <QSettings>
class OptionsWindow : public QMainWindow
{
Q_OBJECT
public:
explicit OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidget *parent = nullptr);
Q_OBJECT
public:
explicit OptionsWindow(QByteArray id, QByteArray pass, int traffic, bool isMobile, QWidget *parent = nullptr);
private:
QTabWidget *tabWidget;
QWidget *page1;
QLineEdit *idEdit, *passwordEdit;
QSpinBox *trafficSpin;
QPushButton *saveButton, *cancleButton;
QFormLayout *layout;
QVBoxLayout *vlayout;
QHBoxLayout *hlayout;
private:
QTabWidget *tabWidget;
QWidget *page1;
QLineEdit *idEdit, *passwordEdit;
QSpinBox *trafficSpin;
QPushButton *saveButton, *cancleButton;
QFormLayout *layout;
QVBoxLayout *vlayout;
QHBoxLayout *hlayout;
QCheckBox *mobileCheck;
QLabel *trafficLabel;
QLabel *trafficLabel;
signals:
void saveSettings(QByteArray id, QByteArray pass, int traffic);
public slots:
signals:
void saveSettings(QByteArray id, QByteArray pass, int traffic, bool isMobile);
public slots:
};
#endif // OPTIONSWINDOW_H