mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
- Tree line connectors (Unicode box-drawing ├─ └─ │) at arbitrary depth - Fix editor overwriting tree chars at depth 2+ (applyMarginText Pass 2) - Scanner: unknown value scan, comparison rescan modes (Changed/Unchanged/Increased/Decreased) - New Tailwind theme (tw.json), WCAG contrast fixes for warm/mid themes - Tooltip system (rcxtooltip.h) - Comprehensive README rewrite with full feature inventory - New tests for compose tree lines, scanner, tooltips Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
118 lines
4.0 KiB
C++
118 lines
4.0 KiB
C++
#pragma once
|
|
#include "providers/provider.h"
|
|
#include <QObject>
|
|
#include <QByteArray>
|
|
#include <QString>
|
|
#include <QVector>
|
|
#include <QFutureWatcher>
|
|
#include <atomic>
|
|
#include <memory>
|
|
|
|
namespace rcx {
|
|
|
|
// ── Value scan types ──
|
|
|
|
enum class ValueType {
|
|
Int8, Int16, Int32, Int64,
|
|
UInt8, UInt16, UInt32, UInt64,
|
|
Float, Double,
|
|
Vec2, Vec3, Vec4,
|
|
UTF8, UTF16,
|
|
HexBytes
|
|
};
|
|
|
|
// ── Scan condition (Cheat Engine-style) ──
|
|
|
|
enum class ScanCondition {
|
|
ExactValue, // first scan + rescan: match specific bytes
|
|
UnknownValue, // first scan only: capture all aligned addresses
|
|
Changed, // rescan: current != previous
|
|
Unchanged, // rescan: current == previous
|
|
Increased, // rescan: current > previous (numeric)
|
|
Decreased // rescan: current < previous (numeric)
|
|
};
|
|
|
|
// ── Scan request / result ──
|
|
|
|
struct ScanRequest {
|
|
QByteArray pattern; // literal bytes to match (empty for UnknownValue)
|
|
QByteArray mask; // 0xFF = must match, 0x00 = wildcard
|
|
|
|
bool filterExecutable = false; // only scan +x regions
|
|
bool filterWritable = false; // only scan +w regions
|
|
|
|
int alignment = 1; // 1 = every byte, 4 = dword, 8 = qword
|
|
int maxResults = 50000;
|
|
|
|
ScanCondition condition = ScanCondition::ExactValue;
|
|
int valueSize = 4; // bytes per value (for unknown scans)
|
|
|
|
uint64_t startAddress = 0; // 0 = no limit (scan all regions)
|
|
uint64_t endAddress = 0; // 0 = no limit (scan all regions)
|
|
};
|
|
|
|
struct ScanResult {
|
|
uint64_t address;
|
|
QString regionModule;
|
|
QByteArray scanValue; // cached bytes at scan/update time
|
|
QByteArray previousValue; // value before last update
|
|
};
|
|
|
|
// ── Pattern parsing ──
|
|
|
|
// Parse IDA-style signature string ("48 8B ?? 05") into pattern + mask.
|
|
// Returns true on success. On failure, sets errorMsg.
|
|
bool parseSignature(const QString& input, QByteArray& pattern, QByteArray& mask,
|
|
QString* errorMsg = nullptr);
|
|
|
|
// Serialize a typed value into raw bytes for exact-match scanning.
|
|
// Returns true on success. On failure, sets errorMsg.
|
|
bool serializeValue(ValueType type, const QString& input,
|
|
QByteArray& pattern, QByteArray& mask,
|
|
QString* errorMsg = nullptr);
|
|
|
|
// Natural alignment for a value type (used as default alignment for value scans).
|
|
int naturalAlignment(ValueType type);
|
|
|
|
// Byte-size for a value type (used for unknown scans and rescan read size).
|
|
int valueSizeForType(ValueType type);
|
|
|
|
// ── Scan engine ──
|
|
|
|
class ScanEngine : public QObject {
|
|
Q_OBJECT
|
|
public:
|
|
explicit ScanEngine(QObject* parent = nullptr);
|
|
|
|
void start(std::shared_ptr<Provider> provider, const ScanRequest& req);
|
|
void startRescan(std::shared_ptr<Provider> provider,
|
|
QVector<ScanResult> results, int readSize,
|
|
ScanCondition condition = ScanCondition::ExactValue,
|
|
ValueType valueType = ValueType::Int32,
|
|
const QByteArray& filterPattern = {},
|
|
const QByteArray& filterMask = {});
|
|
void abort();
|
|
bool isRunning() const;
|
|
|
|
signals:
|
|
void progress(int percent);
|
|
void finished(QVector<ScanResult> results);
|
|
void rescanFinished(QVector<ScanResult> results);
|
|
void error(QString message);
|
|
|
|
private:
|
|
QVector<ScanResult> runScan(std::shared_ptr<Provider> prov, const ScanRequest& req);
|
|
QVector<ScanResult> runRescan(std::shared_ptr<Provider> prov,
|
|
QVector<ScanResult> results, int readSize,
|
|
ScanCondition condition, ValueType valueType,
|
|
const QByteArray& filterPattern,
|
|
const QByteArray& filterMask);
|
|
|
|
std::atomic<bool> m_abort{false};
|
|
QFutureWatcher<QVector<ScanResult>>* m_watcher = nullptr;
|
|
};
|
|
|
|
} // namespace rcx
|
|
|
|
Q_DECLARE_METATYPE(QVector<rcx::ScanResult>)
|