72 lines
2.0 KiB
C++
72 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include "playerslot.h"
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
struct AppliedOverride
|
|
{
|
|
uint8_t* address {};
|
|
std::vector<uint8_t> original;
|
|
};
|
|
|
|
enum class OverrideRuleKind
|
|
{
|
|
Bytes,
|
|
VectorFirstFromField,
|
|
};
|
|
|
|
struct FieldAddressStep
|
|
{
|
|
int32_t offset {};
|
|
bool dereference {};
|
|
};
|
|
|
|
struct CompiledOverrideRule
|
|
{
|
|
int id {};
|
|
int recipientSlot {-1};
|
|
int entityIndex {-1};
|
|
std::string className;
|
|
std::string fieldPath;
|
|
std::string sourceFieldPath;
|
|
int32_t offset {};
|
|
int32_t size {};
|
|
int32_t sourceSize {};
|
|
std::vector<FieldAddressStep> addressSteps;
|
|
std::vector<FieldAddressStep> sourceAddressSteps;
|
|
std::vector<uint8_t> value;
|
|
OverrideRuleKind kind {OverrideRuleKind::Bytes};
|
|
bool enabled {true};
|
|
};
|
|
|
|
class OverrideManager
|
|
{
|
|
public:
|
|
void Clear();
|
|
void Compact();
|
|
int AddRuleBytes(int recipientSlot, int entityIndex, const char* className, const char* fieldPath, const void* value, int valueSize, std::string& error);
|
|
int AddRuleVectorFirstFromField(int recipientSlot, int entityIndex, const char* className, const char* vectorFieldPath, const char* sourceFieldPath, std::string& error);
|
|
bool RemoveRule(int id);
|
|
bool MarkEntityFieldDirty(int entityIndex, const char* className, const char* fieldPath, std::string& error);
|
|
bool HasPackedOverrides() const { return !m_rulesByEntity.empty(); }
|
|
|
|
std::vector<AppliedOverride> ApplyForPackedEntity(CPlayerSlot recipient, int entityIndex, void* entityData);
|
|
void Restore(const std::vector<AppliedOverride>& applied);
|
|
|
|
private:
|
|
bool ResolveFieldPath(const char* className, const char* fieldPath, int32_t& offset, int32_t& size, std::vector<FieldAddressStep>& addressSteps, std::string& error) const;
|
|
void RebuildIndex();
|
|
bool MarkEntityFieldDirtyByOffset(int entityIndex, int32_t offset);
|
|
bool MarkEntityFullDirty(int entityIndex);
|
|
|
|
std::vector<CompiledOverrideRule> m_rules;
|
|
std::unordered_map<int, std::vector<size_t>> m_rulesByEntity;
|
|
int m_nextId {1};
|
|
};
|
|
|
|
extern OverrideManager g_overrides;
|