#include #include #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 #include #include #include 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 runADBCommand(const std::string& command) { // Формируем команду для запуска в shell std::string fullCommand = "adb shell " + command; std::cout << "Executing: " << fullCommand << std::endl; // Запуск команды int result = std::system(fullCommand.c_str()); // Проверка на успешность выполнения if (result != 0) { std::cerr << "Error executing command: " << fullCommand << std::endl; } } void wait(const int milliseconds) { std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); } int main(int argc, char *argv[]) { // Шаг 1: запускаем приложение РСХБ runADBCommand("monkey -p ru.rshb.dbo -c android.intent.category.LAUNCHER 1"); wait(4500); // Ждем пока загружается приложение, перед экраном ввода пин-кода // Шаг 2: Ввод ПИН runADBCommand("input tap 275 900"); // Клик по цифре 1 runADBCommand("input tap 560 900"); // Клик по цифре 2 runADBCommand("input tap 275 900"); // Клик по цифре 1 runADBCommand("input tap 275 900"); // Клик по цифре 1 wait(5500); // Шаг 3: Закрытие рекламы runADBCommand("input tap 300 2090"); // Закрыть баннер пуш-уведомлений (Баннер высвечивается при каждом 2-м запуске) // runADBCommand("input tap 993 163"); // Закрыть сторис (только при первом входе после логина) // runADBCommand("input tap 920 151"); // Закрыть окно перед главным экраном (только при первом входе после логина) // runADBCommand("input tap 990 170"); // Закрыть другое окно (только при первом входе после логина) wait(1500); // Шаг 4: Пролистывание до кнопки "Все продукты" runADBCommand("input swipe 1000 2000 1000 1300"); wait(3000); // Шаг 5: Нажимаем на кнопку "Все продукты" runADBCommand("input tap 570 1240"); wait(3000); // Шаг 6: Выбор карты // runADBCommand("input tap 530 535"); // Для карты дебетовая, цифровая, **6387 runADBCommand("input tap 530 675"); // Для карты дебетовая, **0823 // runADBCommand("input tap 530 800"); // Для карты дебетовая, **7498 wait(1500); // Шаг 7: Нажимаем на кнопку "Оплатить" runADBCommand("input tap 430 920"); wait(1200); // Шаг 8: Нажимаем на блок "По номеру телефона" runADBCommand("input tap 260 1500"); wait(2000); // Шаг 8.1: Закрытие окна разрешения доступа к контактам // runADBCommand("input tap 540 2140"); // wait(500); // Вводим номер телефона для перевода runADBCommand("input tap 250 250"); runADBCommand("input text '9272960333'"); wait(1200); // Шаг 9: Нажимаем на область "Другой банк через СБП" runADBCommand("input tap 500 600"); wait(2000); // Шаг 10: Выбор банка // runADBCommand("input tap 280 280"); // Нажимаем для фокуса у поля ввода текста // runADBCommand("input text 'Т-Банк'"); // Передаем текст 'Т-банк' (Проблема - выдает NullPointerException из-за кириллицы) runADBCommand("input tap 420 620"); // Т-Банк (Пока выбираю хардкодовым нажатием по списку) wait(2000); // Шаг 11: Ввод суммы runADBCommand("input tap 300 1040"); runADBCommand("input text '10'"); wait(2000); // Шаг 11.1: Подтверждаем перевод runADBCommand("input tap 500 2170"); wait(2000); // Завершаем перевод runADBCommand("input tap 500 2170"); std::cout << "All commands executed successfully." << std::endl; return 0; QApplication app(argc, argv); // QList cards = AccountInfoScreener::parseCardData(QByteArray()); // for (const Card &card: cards) { // AccountInfo info; // info.deviceId = "6edc4a47"; // info.appName = "bank"; // info.cardName = card.name; // info.amount = card.amount; // info.description = card.description; // info.status = "active"; // info.updateTime = QDateTime::currentDateTime(); // qDebug() << "Account info: " << AccountDAO::upsertAccount(info); // } // setupWorkerAndThread(app); // // const QDateTime current = QDateTime::currentDateTimeUtc(); // qDebug() << "Обновление lastScan:" << CommonDataDAO::updateLastScan(current); // // const QDateTime savedTime = CommonDataDAO::getLastScan(); // qDebug() << "Сохранившееся время:" << savedTime.toString(); // // MainWindow window; window.show(); return app.exec(); }