1
0
forked from BRT/arc
arc/main.cpp
2025-05-24 15:19:27 +07:00

274 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <QApplication>
#include <QThread>
#include "dao/AccountDAO.h"
#include "views/MainWindow.h"
#include "database/DatabaseManager.h"
#include "database/dao/CommonDataDAO.h"
#include "db/AccountInfoScreener.h"
#include "services/DeviceScreener.h"
#include "automation_script/Script.h"
#include <iostream>
#include <QStyleFactory>
#include <thread>
#include <chrono>
#include <QFile>
#include "EventHandler.h"
#include "VideoWindow.h"
#include "net/NetworkService.h"
#include "rshb/GetLastDaysHistoryScript.h"
#include "rshb/HomeScreenScript.h"
#include "rshb/PayByPhoneScript.h"
void setupWorkerAndThread(QCoreApplication &app) {
auto *thread = new QThread;
auto *deviceScreenerWorker = new DeviceScreener;
// Перемещаем worker в новый поток thread.
// Это значит, что все слоты worker, вызываемые через connect(), теперь будут исполняться в этом фоне-потоке.
deviceScreenerWorker->moveToThread(thread);
// Когда поток запустится, автоматически вызовется worker->start() внутри фонового потока.
QObject::connect(thread, &QThread::started, deviceScreenerWorker, &DeviceScreener::start);
// 🔁 Эти 3 строки делают автоматическую зачистку:
// Когда worker закончит работу (emit finished()), мы:
// - останавливаем поток (thread->quit())
// - удаляем worker (deleteLater)
// - удаляем thread (deleteLater)
// Это защищает от утечек памяти и оставшихся потоков после завершения.
QObject::connect(deviceScreenerWorker, &DeviceScreener::finished, thread, &QThread::quit);
QObject::connect(deviceScreenerWorker, &DeviceScreener::finished, deviceScreenerWorker, &QObject::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
// Когда пользователь закрывает приложение (Ctrl+C, exit() и т.п.), мы вызываем worker->stop() — ты сам пишешь, что в этом методе.
//Обычно он просто ставит флаг m_running = false, чтобы остановить бесконечный цикл в start()
QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
deviceScreenerWorker->stop();
});
thread->start();
}
void setupWorkerAndThreadHistory(QCoreApplication &app) {
const QString appName = "rshb";
const QString lastNumber = "7183";
const QString deviceId = "6edc4a47";
AccountInfo account = AccountDAO::findAppAccount(deviceId, appName, lastNumber);
auto *thread = new QThread;
auto *deviceScreenerWorker = new GetLastDaysHistoryScript(account);
deviceScreenerWorker->moveToThread(thread);
QObject::connect(thread, &QThread::started, deviceScreenerWorker, &GetLastDaysHistoryScript::start);
QObject::connect(deviceScreenerWorker, &GetLastDaysHistoryScript::finished, thread, &QThread::quit);
QObject::connect(deviceScreenerWorker, &GetLastDaysHistoryScript::finished, deviceScreenerWorker,
&QObject::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
deviceScreenerWorker->stop();
});
thread->start();
}
void setupScriptAutoPaymentAndThread(QCoreApplication &app) {
const QString appName = "rshb";
const QString lastNumber = "7183";
const QString phoneNumber = "79641815146";
const QString deviceId = "6edc4a47";
const QString bankName = "Альфа-Банк";
// const QString bankName = "Сбербанк";
const double amount = 320;
const AccountInfo account = AccountDAO::findAppAccount(deviceId, appName, lastNumber);
if (account.id != -1) {
// Функция для подключения потоков к завершению приложения
auto connectStopOnQuit = [&](QObject *worker, QThread *thread) {
QObject::connect(&app, &QCoreApplication::aboutToQuit, [=]() {
if (thread->isRunning()) {
qDebug() << "Завершаем поток:" << thread;
thread->quit();
thread->wait(); // Ожидаем завершения потока
}
worker->deleteLater();
thread->deleteLater();
});
};
// Первый поток
auto *thread = new QThread;
auto *scriptWorker = new PayByPhoneScript(account, phoneNumber, bankName, amount);
scriptWorker->moveToThread(thread);
// Запуск первого потока
QObject::connect(thread, &QThread::started, scriptWorker, &PayByPhoneScript::start);
QObject::connect(scriptWorker, &PayByPhoneScript::finished, thread, &QThread::quit);
QObject::connect(scriptWorker, &PayByPhoneScript::finished, scriptWorker, &QObject::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
// Обработка результата первого потока
QObject::connect(scriptWorker, &PayByPhoneScript::finishedWithResult, &app,
[account, connectStopOnQuit](const QString &result) {
qDebug() << "Получен результат: [" << result << "]";
// Создаем второй поток после завершения первого
auto *thread2 = new QThread;
auto *scriptWorker2 = new GetLastDaysHistoryScript(account);
scriptWorker2->moveToThread(thread2);
// Запуск второго потока
QObject::connect(thread2, &QThread::started, scriptWorker2,
&GetLastDaysHistoryScript::start);
QObject::connect(scriptWorker2, &GetLastDaysHistoryScript::finished, thread2,
&QThread::quit);
QObject::connect(scriptWorker2, &GetLastDaysHistoryScript::finished, scriptWorker2,
&QObject::deleteLater);
QObject::connect(thread2, &QThread::finished, thread2, &QThread::deleteLater);
// Остановка второго потока при завершении приложения
connectStopOnQuit(scriptWorker2, thread2);
thread2->start();
});
// Остановка первого потока при завершении приложения
connectStopOnQuit(scriptWorker, thread);
// Запуск первого потока
thread->start();
}
}
static QFile logFile;
static QMutex logMutex;
void messageHandler(
const QtMsgType type,
const QMessageLogContext &context,
const QString &msg
) {
Q_UNUSED(context) // можно раскомментировать, если нужны file/line/function
// Формируем строку с типом и временем
const QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
QString level;
switch (type) {
case QtDebugMsg: level = "DEBUG";
break;
case QtInfoMsg: level = "INFO";
break;
case QtWarningMsg: level = "WARNING";
break;
case QtCriticalMsg: level = "CRITICAL";
break;
case QtFatalMsg: level = "FATAL";
break;
}
const QString line = QString("%1 [%2] [%3:%4] %5\n")
.arg(timestamp, level, context.function, QString::number(context.line), msg);
// Записываем в файл (потокобезопасно)
{
QMutexLocker locker(&logMutex);
if (logFile.isOpen()) {
QTextStream(&logFile) << line;
logFile.flush();
}
}
// По желанию — дублировать в консоль
const QByteArray localMsg = line.toLocal8Bit();
fprintf(stderr, "%s", localMsg.constData());
if (type == QtFatalMsg) {
abort();
}
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// Выбрать стиль Fusion
app.setStyle(QStyleFactory::create("Fusion"));
// logFile.setFileName("application.log");
// if (!logFile.open(QIODevice::Append | QIODevice::Text)) {
// qWarning() << "Не удалось открыть лог-файл для записи";
// }
// // Устанавливаем свой обработчик
// qInstallMessageHandler(messageHandler);
//
// auto *thread = new QThread;
// auto *worker = new EventHandler;
// worker->moveToThread(thread);
// QObject::connect(thread, &QThread::started, worker, &EventHandler::start);
// QObject::connect(worker, &EventHandler::finished, thread, &QThread::quit);
// QObject::connect(worker, &EventHandler::finished, worker, &QObject::deleteLater);
// QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
// thread->start();
//
// auto *paymentThread = new QThread;
// auto *networkService = new NetworkService;
//
// // FIXME доставить десктоп ид из настроеек
// networkService->setDeviceData("DT88bokcwQ", "");
// networkService->moveToThread(paymentThread);
// QObject::connect(paymentThread, &QThread::started, networkService, &NetworkService::start);
// QObject::connect(networkService, &NetworkService::finished, paymentThread, &QThread::quit);
// QObject::connect(networkService, &NetworkService::finished, networkService, &QObject::deleteLater);
// QObject::connect(paymentThread, &QThread::finished, paymentThread, &QThread::deleteLater);
// paymentThread->start();
//
// setupWorkerAndThread(app);
// MainWindow window;
// window.show();
// adb forward --list
// # порт 27183 — видео
// adb -s 6edc4a47 forward tcp:27183 localabstract:scrcpy_12345678
// # порт 27184 — управление
// adb -s 6edc4a47 forward tcp:27184 localabstract:scrcpy_12345679
// adb -s 6edc4a47 shell CLASSPATH=/data/local/tmp/scrcpy-server-v3.2.jar \
app_process / com.genymobile.scrcpy.Server 3.2 \
tunnel_forward=true control=false cleanup=false \
video_codec=h264 max_size=1920 \
raw_stream=true audio=false log_level=debug scid=12345678
// adb -s 6edc4a47 shell CLASSPATH=/data/local/tmp/scrcpy-server-v3.2.jar \
app_process / com.genymobile.scrcpy.Server 3.2 \
tunnel_forward=true control=true cleanup=false \
video=false audio=false log_level=debug scid=12345679
// qputenv("QTSCRCPY_ADB_PATH",QByteArray("/Users/trnsmkot/Library/Android/sdk/platform-tools/adb"));
VideoWindow w;
w.show();
// adb -s R9ZRYKBV8ES push scrcpy-server-v3.2.jar /data/local/tmp/scrcpy-server-v3.2.jar
// adb -s R9ZRYKBV8ES forward tcp:27185 localabstract:scrcpy_12345678
// adb -s R9ZRYKBV8ES forward tcp:27186 localabstract:scrcpy_12345679
// adb -s R9ZRYKBV8ES shell CLASSPATH=/data/local/tmp/scrcpy-server-v3.2.jar \
app_process / com.genymobile.scrcpy.Server 3.2 \
tunnel_forward=true control=false cleanup=false \
video_codec=h264 max_size=1920 \
raw_stream=true audio=false log_level=debug scid=12345678
// adb -s R9ZRYKBV8ES shell CLASSPATH=/data/local/tmp/scrcpy-server-v3.2.jar \
app_process / com.genymobile.scrcpy.Server 3.2 \
tunnel_forward=true control=true cleanup=false \
video=false audio=false log_level=debug scid=12345679
return QApplication::exec();
}