Răsfoiți Sursa

完善 游戏 iphost

zhuizhu 1 an în urmă
părinte
comite
123476016c
14 a modificat fișierele cu 455 adăugiri și 177 ștergeri
  1. 2 0
      api/api.pri
  2. 44 0
      api/hostsapi.cpp
  3. 22 0
      api/hostsapi.h
  4. 20 0
      api/processapi.cpp
  5. 12 0
      api/processapi.h
  6. 12 2
      api/tapi.cpp
  7. 30 0
      appevent.cpp
  8. 2 0
      appevent.h
  9. 3 0
      basemain.pro
  10. 149 18
      hostthread.cpp
  11. 10 2
      hostthread.h
  12. 4 2
      main.cpp
  13. 2 0
      messagequeue.cpp
  14. 143 153
      processthread.cpp

+ 2 - 0
api/api.pri

@@ -1,5 +1,6 @@
 HEADERS += \
     $$PWD/configapi.h \
+    $$PWD/hostsapi.h \
     $$PWD/machine.h \
     $$PWD/processapi.h \
     $$PWD/student.h \
@@ -8,6 +9,7 @@ HEADERS += \
 
 SOURCES += \
     $$PWD/configapi.cpp \
+    $$PWD/hostsapi.cpp \
     $$PWD/machine.cpp \
     $$PWD/processapi.cpp \
     $$PWD/student.cpp \

+ 44 - 0
api/hostsapi.cpp

@@ -0,0 +1,44 @@
+#include "hostsapi.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonValue>
+#include <QNetworkAccessManager>
+#include <QUrlQuery>
+#include <basemainTr.h>
+
+#include <optional>
+
+#include "appevent.h"
+#include "qjsonarray.h"
+namespace TC {
+void critical(const QString &text, const QString &title = Tr::tr("Error"));
+std::optional<QJsonValue> sendRequest(QNetworkAccessManager::Operation op,
+                                      const QString &url,
+                                      const QByteArray &postData = QByteArray());
+
+static const QLatin1String scCode("code");
+static const QLatin1String scMessage("message");
+static const QLatin1String scData("data");
+static const QLatin1String scList("list");
+HostsApi::HostsApi(QObject *parent)
+    : QObject{parent}
+    , url("/api/v1/sys/web_game/no_list")
+{}
+
+QJsonArray HostsApi::get()
+{
+    const auto responseData = sendRequest(QNetworkAccessManager::GetOperation, url);
+    if (!responseData.has_value()) {
+        return QJsonArray();
+    }
+    const QJsonObject &object = responseData.value().toObject();
+    if (object[scData].isObject()) {
+        const QJsonObject &data = object[scData].toObject();
+        if (data.contains(scList)) {
+            return data[scList].toArray(QJsonArray());
+        }
+    }
+    return QJsonArray();
+}
+} // namespace TC

+ 22 - 0
api/hostsapi.h

@@ -0,0 +1,22 @@
+#ifndef HOSTSAPI_H
+#define HOSTSAPI_H
+
+#include <QObject>
+#include <optional>
+
+namespace TC {
+
+class HostsApi : public QObject
+{
+    Q_OBJECT
+public:
+    explicit HostsApi(QObject *parent = nullptr);
+
+    QJsonArray get();
+
+    QString url;
+    QByteArray sendData;
+};
+
+} // namespace TC
+#endif // HOSTSAPI_H

+ 20 - 0
api/processapi.cpp

@@ -18,6 +18,7 @@ void critical(const QString &text, const QString &title = Tr::tr("Error"));
 std::optional<QJsonValue> sendRequest(QNetworkAccessManager::Operation op,
                                       const QString &url,
                                       const QByteArray &postData = QByteArray());
+std::optional<QJsonValue> uploaderRequest(const QString &url, const QStringList &fileList);
 
 static const QLatin1String scCode("code");
 static const QLatin1String scMessage("message");
@@ -91,4 +92,23 @@ QJsonArray ProcessNameApi::get()
     return QJsonArray();
 }
 
+ProcessImageApi::ProcessImageApi()
+    : url("/api/v1/student_game_pic/single_up")
+{}
+
+bool ProcessImageApi::post(const QStringList &fileList)
+{
+    std::optional<QJsonValue> responseData = uploaderRequest(url, fileList);
+    if (!responseData.has_value()) {
+        return false;
+    }
+    QJsonValue data;
+    const QJsonObject object = responseData.value().toObject();
+
+    if (object.contains(scCode)) {
+        return object.value(scCode).toInt() == 200;
+    }
+    return false;
+}
+
 } // namespace TC

+ 12 - 0
api/processapi.h

@@ -31,6 +31,18 @@ public:
     QByteArray sendData;
 };
 
+class ProcessImageApi : public QObject
+{
+    Q_OBJECT
+public:
+    ProcessImageApi();
+
+    bool post(const QStringList &fileList);
+
+    QString url;
+    QByteArray sendData;
+};
+
 // is_prompt
 } // namespace TC
 #endif // PROCESSAPI_H

+ 12 - 2
api/tapi.cpp

@@ -279,7 +279,7 @@ std::optional<QJsonValue> uploaderRequest(const QString &url, const QStringList
 {
     QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
     // Create a file part
-
+    QVector<QFile *> files;
     for (const QString &filePath : fileList) {
         QFile *file = new QFile(filePath);
         if (!file->open(QIODevice::ReadOnly)) {
@@ -295,6 +295,8 @@ std::optional<QJsonValue> uploaderRequest(const QString &url, const QStringList
 
         file->setParent(multiPart); // Ensure file is deleted with multiPart
         multiPart->append(filePart);
+
+        files.append(file);
     }
 
     QNetworkAccessManager *manager = NetworkAccessManager::instance();
@@ -305,8 +307,14 @@ std::optional<QJsonValue> uploaderRequest(const QString &url, const QStringList
 
     if (!reply) {
         qDebug() << "sendRequest Operation error";
+        delete multiPart;
+        qDeleteAll(files);
+        return std::nullopt;
     }
-
+    QObject::connect(reply, &QNetworkReply::finished, [multiPart, files]() {
+        multiPart->deleteLater();
+        qDeleteAll(files);
+    });
     //等待请求结束
     QEventLoop loop;
     QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
@@ -314,8 +322,10 @@ std::optional<QJsonValue> uploaderRequest(const QString &url, const QStringList
 
     QJsonValue data;
     if (!InterceptorsResponse(reply, data)) {
+        reply->deleteLater();
         return std::nullopt;
     }
+    reply->deleteLater();
     return data;
 }
 } // namespace TC

+ 30 - 0
appevent.cpp

@@ -91,6 +91,36 @@ QString AppEvent::formatElapsedTime(qint64 ms)
     return time.toString("hh:mm:ss");
 }
 
+void AppEvent::captureDesktop(QIODevice *device, const char *format, int quality)
+{
+    QList<QScreen *> screens = QGuiApplication::screens();
+    if (screens.isEmpty()) {
+        qWarning("No screens found.");
+        return;
+    }
+
+    // 计算整个桌面的大小
+    QRect fullDesktopRect;
+    for (QScreen *screen : screens) {
+        fullDesktopRect = fullDesktopRect.united(screen->geometry());
+    }
+
+    // 创建一个空白的 QPixmap,大小为整个桌面的大小
+    QPixmap fullDesktop(fullDesktopRect.size());
+    fullDesktop.fill(Qt::transparent);
+
+    // 使用 QPainter 将每个屏幕的内容绘制到 fullDesktop 上
+    QPainter painter(&fullDesktop);
+    for (QScreen *screen : screens) {
+        // 计算当前屏幕在 fullDesktop 中的位置
+        QPoint screenPos = screen->geometry().topLeft() - fullDesktopRect.topLeft();
+        painter.drawPixmap(screenPos, screen->grabWindow(0));
+    }
+    painter.end();
+
+    fullDesktop.save(device, format, quality);
+}
+
 void AppEvent::captureDesktop(const QString &path)
 {
     QList<QScreen *> screens = QGuiApplication::screens();

+ 2 - 0
appevent.h

@@ -1,6 +1,7 @@
 #ifndef APPEVENT_H
 #define APPEVENT_H
 
+#include <QIODevice>
 #include <QObject>
 #include <QVariant>
 
@@ -18,6 +19,7 @@ public:
 
     static QString formatElapsedTime(qint64 ms);
 
+    static void captureDesktop(QIODevice *device, const char *format = nullptr, int quality = -1);
     static void captureDesktop(const QString &path);
 
     static void saveTimeFile(qint64 elapsed, const QString &path);

+ 3 - 0
basemain.pro

@@ -54,3 +54,6 @@ msvc {
     QMAKE_CFLAGS += /utf-8
     QMAKE_CXXFLAGS += /utf-8
 }
+msvc {
+    QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
+}

+ 149 - 18
hostthread.cpp

@@ -1,11 +1,67 @@
 #include "hostthread.h"
 #include "qdebug.h"
+#include "qjsonarray.h"
+#include "qjsonobject.h"
 
 #include <QFile>
+#include <QProcess>
+#include <QRegularExpression>
 #include <QString>
 #include <QTextStream>
 
-static bool modifyHostsFile(const QString &hostname, const QString &ipAddress)
+#include <api/hostsapi.h>
+/*
+# Copyright (c) 1993-2009 Microsoft Corp.
+#
+# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
+#
+# This file contains the mappings of IP addresses to host names. Each
+# entry should be kept on an individual line. The IP address should
+# be placed in the first column followed by the corresponding host name.
+# The IP address and the host name should be separated by at least one
+# space.
+#
+# Additionally, comments (such as these) may be inserted on individual
+# lines or following the machine name denoted by a '#' symbol.
+#
+# For example:
+#
+#      102.54.94.97     rhino.acme.com          # source server
+#       38.25.63.10     x.acme.com              # x client host
+
+# localhost name resolution is handled within DNS itself.
+#	127.0.0.1       localhost
+#	::1             localhost
+
+127.0.0.1       activate.navicat.com
+
+127.0.0.1 example.com 
+*/
+
+static void ipconfigFlushdns()
+{
+    // 创建 QProcess 对象
+    QProcess process;
+
+    // 设置要执行的命令和参数
+    process.start("ipconfig", QStringList() << "/flushdns");
+
+    // 等待命令执行完成
+    process.waitForFinished();
+
+    // 获取命令输出(如果有的话)
+    auto output = process.readAllStandardOutput();
+    auto errorOutput = process.readAllStandardError();
+
+    // 输出结果
+    if (!output.isEmpty()) {
+        qDebug() << "Command output:" << QString::fromLocal8Bit(output);
+    }
+    if (!errorOutput.isEmpty()) {
+        qDebug() << "Command error:" << errorOutput;
+    }
+}
+static bool modifyHostsFile(const QString &hostname, const QString &ipAddress, bool action)
 {
     QString hostsFilePath;
 
@@ -21,32 +77,107 @@ static bool modifyHostsFile(const QString &hostname, const QString &ipAddress)
         qWarning() << "无法打开文件" << hostsFilePath;
         return false;
     }
-
     // 读取文件内容
     QTextStream stream(&file);
-    QString fileContent = stream.readAll();
-    qDebug() << fileContent;
-    // 检查是否已经包含该映射
-    if (fileContent.contains(hostname)) {
-        qDebug() << "该域名映射已经存在";
-        file.close();
-        return true;
+    QStringList fileLines;
+    QRegularExpression regex(
+        R"RX(^(#?\s*)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-zA-Z0-9.-]+)(\s+#.*)?$)RX");
+
+    bool isExist = false;
+    while (!stream.atEnd()) {
+        QString line = stream.readLine(); // 读取一行
+        fileLines.append(line);           // 保存当前行
+        QRegularExpressionMatch expressionMatch = regex.match(line);
+        if (expressionMatch.hasMatch()) {
+            const QString url = expressionMatch.captured(3);
+            if (url.compare(hostname) == 0) {
+                if (action) { // 添加
+                    qDebug() << "---------------add" << url;
+                    qDebug() << "已存在,进行添加操作: " << url;
+                    fileLines.removeOne(line);
+                } else {
+                    qDebug() << "---------------remove" << url;
+                    qDebug() << "删除操作: " << url;
+                    fileLines.removeOne(line);
+                }
+            }
+        }
+    }
+    // 如果是添加操作并且记录不存在,添加新条目
+    if (!isExist && action) {
+        QString newLine = QString("%1 %2").arg(ipAddress).arg(hostname);
+        fileLines.append(newLine); // 将新的条目添加到文件末尾
+        qDebug() << "添加新的条目: " << newLine;
     }
 
-    // 添加新的映射
-    file.seek(file.size());                         // 将文件指针移动到文件末尾
-    stream << "\n" << ipAddress << " " << hostname; // 添加映射
+    // 重写文件内容
+    file.resize(0); // 清空文件内容
+    QTextStream out(&file);
+    for (const QString &line : fileLines) {
+        out << line << "\n";
+    }
 
     file.close();
-    qDebug() << "已成功修改 hosts 文件";
+    ipconfigFlushdns();
     return true;
 }
 
-HostThread::HostThread()
+// HostThread::HostThread()
+// {
+//     if (modifyHostsFile("example.com", "127.0.0.1")) {
+//         qDebug() << "Hosts 文件已成功更新。";
+//     } else {
+//         qDebug() << "修改失败。";
+//     }
+// }
+
+HostThread::HostThread(QObject *parent) {}
+
+void HostThread::upDataHost()
 {
-    if (modifyHostsFile("example.com", "127.0.0.1")) {
-        qDebug() << "Hosts 文件已成功更新。";
-    } else {
-        qDebug() << "修改失败。";
+    TC::HostsApi hostsApi;
+    const auto serverArray = hostsApi.get();
+
+    QSet<QString> addressSet;       // 添加
+    QSet<QString> removeAddressSet; // 取消
+    for (const QJsonValue &item : serverArray) {
+        if (!item.isObject()) {
+            return;
+        }
+        const QJsonObject object = item.toObject();
+        const QString name = object["address"].toString();
+        if (object.contains("value")) {
+            if (object["value"].toString() == "-1" || object["value"].toInt() == -1) {
+                addressSet.insert(name);
+                modifyHostsFile(name, "127.0.0.1", true);
+            } else {
+                removeAddressSet.insert(name);
+                modifyHostsFile(name, "127.0.0.1", false);
+            }
+        }
+    }
+
+    // if (modifyHostsFile("example.com", "127.0.0.1", true)) {
+    //     qDebug() << "Hosts 文件已成功更新。";
+    // } else {
+    //     qDebug() << "修改失败。";
+    // }
+}
+
+void HostThread::run()
+{
+    QElapsedTimer timer; // 创建高精度计时器
+    timer.start();       // 启动计时器
+
+    upDataHost();
+
+    while (true) {
+        // 校验网络
+        if (timer.elapsed() >= 30 * 1000) {
+            timer.restart();
+
+            upDataHost();
+        }
+        msleep(1000); // 休息1秒
     }
 }

+ 10 - 2
hostthread.h

@@ -1,10 +1,18 @@
 #ifndef HOSTTHREAD_H
 #define HOSTTHREAD_H
 
-class HostThread
+#include <QThread>
+
+class HostThread : public QThread
 {
+    Q_OBJECT
 public:
-    HostThread();
+    explicit HostThread(QObject *parent = nullptr);
+
+    void upDataHost();
+
+protected:
+    void run() override;
 };
 
 #endif // HOSTTHREAD_H

+ 4 - 2
main.cpp

@@ -9,6 +9,7 @@
 #include <QSettings>
 #include <QTranslator>
 
+#include "hostthread.h"
 #include "messagequeue.h"
 #include "processthread.h"
 #include "qdatetime.h"
@@ -77,7 +78,7 @@ int main(int argc, char *argv[])
     dir.mkdir("log"); // 创建日志目录
     addToStartup();   // 开机启动
 
-    redirectOutputToLogFile(); // 日志
+    // redirectOutputToLogFile(); // 日志
     a.setApplicationVersion("1.1.2");
     a.setQuitOnLastWindowClosed(false);
 
@@ -103,7 +104,7 @@ int main(int argc, char *argv[])
             break;
         }
     }
-
+    HostThread host;
     UpdaterThread thread;
     ProcessThread Process;
 
@@ -113,5 +114,6 @@ int main(int argc, char *argv[])
     QObject::connect(&Process, &ProcessThread::finished, &Process, &QObject::deleteLater);
     thread.start();
     Process.start();
+    host.start();
     return a.exec();
 }

+ 2 - 0
messagequeue.cpp

@@ -41,7 +41,9 @@ void MessageQueue::processQueue()
             if (title.isEmpty()) {
                 title = tr("Tips");
             }
+            // messageBox->setWindowFlags(messageBox->windowFlags() | Qt::WindowStaysOnTopHint);
             messageBox->setWindowModality(Qt::NonModal);
+            messageBox->setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint);
             messageBox->setText(currentMessage);
             messageBox->setWindowTitle(title);
             connect(messageBox, &QMessageBox::finished, this, &MessageQueue::onMessageBoxClosed);

+ 143 - 153
processthread.cpp

@@ -1,4 +1,6 @@
 #include "processthread.h"
+#include <QProcess>
+#include <QTemporaryFile>
 #include "api/configapi.h"
 #include "appevent.h"
 #include "processmodel.h"
@@ -64,6 +66,7 @@ void ProcessThread::sendExitTime(qint64 updataTime)
 
     // 获取过滤名单
     QSet<QString> filter;
+    QSet<QString> gameFilter;
     for (const QJsonValue &item : serverArray) {
         if (!item.isObject()) {
             return;
@@ -75,6 +78,12 @@ void ProcessThread::sendExitTime(qint64 updataTime)
                 filter.insert(name);
             }
         }
+        if (object.contains("pid_type")) {
+            const QString type = object["pid_type"].toString();
+            if (type == "游戏" || type == "game") {
+                gameFilter.insert(name);
+            }
+        }
     }
 
     ProcessModel processModel{storage};
@@ -124,9 +133,12 @@ void ProcessThread::sendExitTime(qint64 updataTime)
             QJsonArray jsonArray = qry.toJson();
         }
     }
+
+    // 获取配置
     QVariant messageBoxPointX = QVariant();
     QVariant messageBoxPointY = QVariant();
     QVariant messageText = QVariant("");
+    QVariant gameMessageText = QVariant("");
     QVariant messageTitle = QVariant(Tr::tr("Tips"));
     {
         TC::ConfigApi configApi("messageBoxPointX");
@@ -156,7 +168,15 @@ void ProcessThread::sendExitTime(qint64 updataTime)
             messageTitle = value.value();
         }
     }
+    {
+        TC::ConfigApi configApi("gameMessageText");
+        std::optional<QVariant> value = configApi.get();
+        if (value.has_value()) {
+            gameMessageText = value.value();
+        }
+    }
 
+    // 获取服务器 对应的时间信息
     for (const QJsonValue &item : serverArray) {
         if (!item.isObject()) {
             return;
@@ -165,102 +185,134 @@ void ProcessThread::sendExitTime(qint64 updataTime)
 
         const QString name = object["name"].toString();
         const QString zhName = object["chinese_name"].toString();
-        if (object.contains("is_prompt")) {
+        const QString type = object["pid_type"].toString();
+        // 2 提示 1 不提示 0 未知
+        if (object.contains("is_prompt")) { // 提示
             if (object["is_prompt"].toInt() == 2) {
-                const QString name = object["name"].toString();
-                const QString zhName = object["chinese_name"].toString();
-                const int time = object["prompt_time"].toInt();
-                if (time > 0) {
-                    const QString whereTime = QString("(updataTime - lastAlertTime) > %1").arg(time);
-                    const QString whereProcessName = QString("processName = '%1'").arg(name);
-                    const QString whereUpdataTime = QString("updataTime = '%1'").arg(updataTime);
-                    CWF::SqlQueryManager qry(storage);
-                    qry.select("*", processModel.getTableName())
-                        .where(QString("%1 AND %2 AND %3")
-                                   .arg(whereTime)
-                                   .arg(whereProcessName)
-                                   .arg(whereUpdataTime));
-                    qry.prepare();
-                    QJsonObject jsonObject = qry.exec();
-                    QJsonArray jsonArray = qry.toJson();
-                    qDebug() << jsonArray;
-                    for (const auto &value : jsonArray) {
-                        const QJsonObject object = value.toObject();
-                        const QString processName = object["processName"].toString();
-                        const qint64 runTime = object["exitTime"].toVariant().toLongLong()
-                                               - object["creationTime"].toVariant().toLongLong();
-
-                        const QString text = QString(
-                            tr("Program %1 has been used for %2 minutes%3")
-                                .arg(zhName)
-                                .arg(convertSecondsToMinutesTimeFormat(runTime))
-                                .arg(messageText.toString()));
-                        emit messageBox(text, messageBoxPointX, messageBoxPointY, messageTitle);
-
-                        // 更新 lastAlertTime
-                        ProcessModel processModel{storage};
-                        processModel.buildFromJson(object);
-                        // 更新 消息时间
-                        processModel.setLastAlertTime(updataTime);
-                        processModel.save();
+                if (type == "游戏" || type == "game") {
+                } else {
+                    // const QString name = object["name"].toString();
+                    // const QString zhName = object["chinese_name"].toString();
+                    const int time = object["prompt_time"].toInt();
+                    if (time > 0) {
+                        const QString whereTime = QString("(updataTime - lastAlertTime) > %1")
+                                                      .arg(time);
+                        const QString whereProcessName = QString("processName = '%1'").arg(name);
+                        const QString whereUpdataTime = QString("updataTime = '%1'").arg(updataTime);
+                        CWF::SqlQueryManager qry(storage);
+                        qry.select("*", processModel.getTableName())
+                            .where(QString("%1 AND %2 AND %3")
+                                       .arg(whereTime)
+                                       .arg(whereProcessName)
+                                       .arg(whereUpdataTime));
+                        qry.prepare();
+                        QJsonObject jsonObject = qry.exec();
+                        QJsonArray jsonArray = qry.toJson();
+                        qDebug() << jsonArray;
+                        for (const auto &value : jsonArray) {
+                            const QJsonObject object = value.toObject();
+                            const QString processName = object["processName"].toString();
+                            const qint64 runTime = object["exitTime"].toVariant().toLongLong()
+                                                   - object["creationTime"].toVariant().toLongLong();
+
+                            const QString text = QString(
+                                tr("Program %1 has been used for %2 minutes%3")
+                                    .arg(zhName)
+                                    .arg(convertSecondsToMinutesTimeFormat(runTime))
+                                    .arg(messageText.toString()));
+                            emit messageBox(text, messageBoxPointX, messageBoxPointY, messageTitle);
+
+                            // 更新 lastAlertTime
+                            ProcessModel processModel{storage};
+                            processModel.buildFromJson(object);
+                            // 更新 消息时间
+                            processModel.setLastAlertTime(updataTime);
+                            processModel.save();
+                        }
                     }
                 }
             }
         }
-    }
 
-    // for (const QJsonValue &item : array) {
-    //     if (item.isObject()) {
-    //         const QJsonObject object = item.toObject();
-
-    //         const QString name = object["name"].toString();
-    //         const QString zhName = object["chinese_name"].toString();
-    //         if (object.contains("is_prompt")) {
-    //             if (object["is_prompt"].toInt() == 2) {
-    //                 messageProcessName[name] = zhName;
-    //             };
-    //         }
-    //     }
-    // }
-    // qDebug() << messageProcessName;
-    // // SELECT * FROM ProcessTime  WHERE (updataTime - lastAlertTime) > 1565;
-    // if (time > 0) {
-    //     const QString whereTime = QString("(updataTime - lastAlertTime) > %1").arg(time);
-    //     const QString whereProcessName = QString("processName = '%1'").arg("WeChat.exe");
-    //     CWF::SqlQueryManager qry(storage);
-    //     qry.select("*", processModel.getTableName()).where(whereTime);
-    //     qry.prepare();
-    //     QJsonObject jsonObject = qry.exec();
-    //     QJsonArray jsonArray = qry.toJson();
-
-    //     const QStringList keys = messageProcessName.keys();
-
-    //     for (const auto &value : jsonArray) {
-    //         // SLDWORKS.exe
-
-    //         const QJsonObject object = value.toObject();
-    //         const QString processName = object["processName"].toString();
-    //         const qint64 runTime = object["exitTime"].toVariant().toLongLong()
-    //                                - object["creationTime"].toVariant().toLongLong();
-
-    //         for (const QString &key : keys) {
-    //             if (processName.compare(key, Qt::CaseSensitivity::CaseInsensitive) == 0) {
-    //                 const QString text = QString(tr("Program %1 has been used for %2 minutes%3")
-    //                                                  .arg(messageProcessName[key])
-    //                                                  .arg(convertSecondsToMinutesTimeFormat(runTime))
-    //                                                  .arg(messageText.toString()));
-    //                 emit messageBox(text, messageBoxPointX, messageBoxPointY, messageTitle);
-    //             }
-    //         }
-
-    //         // 更新 lastAlertTime
-    //         ProcessModel processModel{storage};
-    //         processModel.buildFromJson(object);
-    //         // 更新 消息时间
-    //         processModel.setLastAlertTime(updataTime);
-    //         processModel.save();
-    //     }
-    // }
+        if (object.contains("pid_type")) {
+            if (type == "游戏" || type == "game") {
+                const QString whereTime = QString("(updataTime - lastAlertTime) > %1").arg(1);
+                const QString whereProcessName = QString("processName = '%1'").arg(name);
+                const QString whereUpdataTime = QString("updataTime = '%1'").arg(updataTime);
+                CWF::SqlQueryManager qry(storage);
+                qry.select("*", processModel.getTableName())
+                    .where(QString("%1 AND %2 AND %3")
+                               .arg(whereTime)
+                               .arg(whereProcessName)
+                               .arg(whereUpdataTime));
+                qry.prepare();
+                QJsonObject jsonObject = qry.exec();
+                QJsonArray jsonArray = qry.toJson();
+
+                for (const auto &value : jsonArray) {
+                    const QJsonObject object = value.toObject();
+                    const QString processName = object["processName"].toString();
+                    const qint64 runTime = object["exitTime"].toVariant().toLongLong()
+                                           - object["creationTime"].toVariant().toLongLong();
+
+                    const QString text = QString(tr("Program %1 has been used for %2 minutes%3")
+                                                     .arg(zhName)
+                                                     .arg(convertSecondsToMinutesTimeFormat(runTime))
+                                                     .arg(messageText.toString()));
+
+                    qDebug() << "玩游戏?" << text;
+
+                    QTemporaryFile tempFile("tempfile_XXXXXX.png");
+                    tempFile.setAutoRemove(true);
+                    tempFile.open();
+                    AppEvent::captureDesktop(&tempFile, "PNG");
+
+                    // qDebug() << "发送截图" << tempFile.fileName();
+                    TC::ProcessImageApi processImageApi;
+                    qDebug() << "发送截图" << processImageApi.post({tempFile.fileName()});
+                    tempFile.close();
+                    qDebug() << "发送截图" << tempFile.remove() << tempFile.errorString();
+                    // if (object.contains("is_prompt")) { // 提示
+                    //     if (object["is_prompt"].toInt() == 2) {
+                    //     }
+                    // }
+                    const QString message = gameMessageText.toString().isEmpty()
+                                                ? text
+                                                : gameMessageText.toString();
+
+                    emit messageBox(message, messageBoxPointX, messageBoxPointY, messageTitle);
+
+                    QProcess p;
+                    p.startDetached("taskkill", {"/im", name, "/f"});
+                    p.waitForFinished(3000);
+                    p.close();
+                    // 更新 lastAlertTime
+                    ProcessModel processModel{storage};
+                    processModel.buildFromJson(object);
+                    // 更新 消息时间
+                    processModel.setLastAlertTime(updataTime);
+                    processModel.save();
+                }
+
+                // 获取游戏 截图 并关闭进程
+                // QTemporaryFile tempFile("tempfile_XXXXXX.png");
+                // tempFile.setAutoRemove(true);
+                // tempFile.open();
+                // AppEvent::captureDesktop(&tempFile, "PNG");
+
+                // qDebug() << "发送截图" << tempFile.fileName();
+                // TC::ProcessImageApi processImageApi;
+                // qDebug() << "发送截图" << processImageApi.post({tempFile.fileName()});
+
+                // tempFile.close();
+                // qDebug() << "发送截图" << tempFile.remove() << tempFile.errorString();
+                // if (object.contains("is_prompt")) { // 提示
+                //     if (object["is_prompt"].toInt() == 2) {
+                //     }
+                // }
+            }
+        }
+    }
 }
 
 bool ProcessThread::upDataProcessSql()
@@ -309,71 +361,9 @@ bool ProcessThread::upDataProcessSql()
                 processModel.save();
             }
         }
-        // qDebug().noquote().nospace() << jsonObject << qry.toJson();
-
-        // jsonObject.insert("begin_time", object["creationTime"]);
-        // jsonObject.insert("end_time", object["exitTime"]);
-        // jsonObject.insert("last_check_time", object["updataTime"]);
-        // jsonObject.insert("status", 1);
-        // jsonObject.insert("notes", "");
-        // FILETIME ft = timeProcess->creationTime;
-        // FILETIME currentTime;
-        // GetSystemTimeAsFileTime(&currentTime);
-
-        // ULARGE_INTEGER creation, current;
-        // creation.LowPart = ft.dwLowDateTime;
-        // creation.HighPart = ft.dwHighDateTime;
-        // current.LowPart = currentTime.dwLowDateTime;
-        // current.HighPart = currentTime.dwHighDateTime;
-
-        // ULONGLONG elapsedSeconds = (current.QuadPart - creation.QuadPart) / 10000000;
-
-        // // 计算天、小时、分钟和秒
-        // ULONGLONG days = elapsedSeconds / 86400;           // 1天 = 86400秒
-        // ULONGLONG hours = (elapsedSeconds % 86400) / 3600; // 1小时 = 3600秒
-        // ULONGLONG minutes = (elapsedSeconds % 3600) / 60;  // 1分钟 = 60秒
-        // ULONGLONG seconds = elapsedSeconds % 60;           // 剩余秒数
-
-        // // 打印进程的运行时间
-        // qDebug() << QString::fromStdString(timeProcess->processName) //
-        //          << days << hours << minutes << seconds << timestamp;
-
-        /*
-INSERT OR REPLACE INTO ProcessTime (pid, processName, creationTime, exitTime)
-VALUES
-  (123, 'process1', strftime('%s', 'now'), strftime('%s', 'now')),
-  (124, 'process2', strftime('%s', 'now'), strftime('%s', 'now')),
-  (125, 'process3', strftime('%s', 'now'), strftime('%s', 'now'));
-*/
-        // sqlValues.append(QString("(%1,'%2',%3,%4,%5)")
-        //                      .arg(timeProcess->pid)                 // pid
-        //                      .arg(timeProcess->processName.c_str()) // 进程名
-        //                      .arg(timestamp)                        // 开始时间戳
-        //                      .arg(exitTimestamp)                    // 结束时间戳
-        //                      .arg(updataTimestamp));                // 数据更新时间
     }
-
-    //     const QString query = QString(
-    //                               R"(INSERT OR REPLACE INTO ProcessTime
-    // (pid, processName, creationTime, exitTime, updataTime)
-    // VALUES
-    // %1)")
-    //                               .arg(sqlValues.join(","));
-
-    //     // 使用上述插入或者替换
-    //     // 首先查找
-    //     QString where;
-    //     CWF::SqlQueryManager qry(storage);
-    //     QJsonObject jsonObject = qry.exec(query);
-
     // 发送更新后的数据
     sendExitTime(updataTimestamp);
-
-    // if (jsonObject.contains("success")) {
-    //     if (jsonObject["success"].toBool()) {
-    //         return true;
-    //     }
-    // }
     return false;
 }
 
@@ -401,7 +391,7 @@ void ProcessThread::run()
 
     while (true) {
         // 校验网络
-        if (timer.elapsed() >= 30 * 1000) { // 检查是否经过1分钟
+        if (timer.elapsed() >= 10 * 1000) { // 检查是否经过1分钟
             timer.restart();                // 重新启动计时器
 
             upDataProcessSql();