Skip to content

Commit

Permalink
add refs to bo4 dll and generic config
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed Jul 27, 2024
1 parent 73c4a26 commit cefe580
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 65 deletions.
2 changes: 1 addition & 1 deletion src/acts/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ int MainActs(int argc, const char* _argv[], HINSTANCE hInstance, int nShowCmd) {
bool cli{ hInstance == nullptr };
auto& profiler = actscli::GetProfiler();

core::config::SyncConfig();
core::config::SyncConfig(true);

// by default we don't display heavy logs in cli

Expand Down
4 changes: 3 additions & 1 deletion src/acts/tools/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ namespace {

int cfgtest(Process& proc, int argc, const char* argv[]) {
using namespace core::config;
SyncConfig();
SyncConfig(true);

LOG_INFO("file: {}", GetMainConfig().configFile.string());

LOG_INFO("{}", GetInteger("test", 64));
LOG_INFO("{}", GetBool("test2.bool.val", true));
Expand Down
24 changes: 15 additions & 9 deletions src/bo4-ext-dll/data/bo4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ namespace bo4 {
byte requires_implements_count;
};

typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];

enum scriptInstance_t : int32_t {
SCRIPTINSTANCE_SERVER = 0x0,
Expand Down Expand Up @@ -489,18 +493,20 @@ namespace bo4 {
};

struct HksGlobal {};
struct HksCallstack
{
void* m_records; // hks::CallStack::ActivationRecord*
void* m_lastrecord; // hks::CallStack::ActivationRecord*
void* m_current; // hks::CallStack::ActivationRecord*
const void* m_current_lua_pc; // const hksInstruction*
const void* m_hook_return_addr; // const hksInstruction*
int32_t m_hook_level;
};
struct HksCallStackActivationRecord {};
struct hksInstruction {};
struct HksUpvalue {};
typedef void* HksErrorhandler;
struct lua_State;

struct HksCallstack {
HksCallStackActivationRecord* m_records;
HksCallStackActivationRecord* m_lastrecord;
HksCallStackActivationRecord* m_current;
const hksInstruction* m_current_lua_pc;
const hksInstruction* m_hook_return_addr;
int32_t m_hook_level;
};
struct HksObject {
uint32_t t;
union {
Expand Down
52 changes: 52 additions & 0 deletions src/bo4-ext-dll/data/refs.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once
#include <hook/refs.hpp>
#include "bo4.hpp"

namespace bo4 {
using namespace hook::refs;

// gsc
S_ANY Ref<void(scriptInstance_t inst, int value)> ScrVm_AddBool{ 0x276E760_a };
S_ANY Ref<void(scriptInstance_t inst, float value)> ScrVm_AddFloat{ 0x276E9B0_a };
S_ANY Ref<void(scriptInstance_t inst, XHash* value)> ScrVm_AddHash{ 0x276EAB0_a };
S_ANY Ref<void(scriptInstance_t inst, int64_t value)> ScrVm_AddInt{ 0x276EB80_a };
S_ANY Ref<void(scriptInstance_t inst, const char* value) > ScrVm_AddString{ 0x276EE30_a };
S_ANY Ref<void(scriptInstance_t inst)> ScrVm_AddUndefined{ 0x276F3C0_a };
S_ANY Ref<void(scriptInstance_t inst, int32_t value)> ScrVm_AddConstString{ 0x276E5F0_a };
S_ANY Ref<bool(scriptInstance_t inst, unsigned int index)> ScrVm_GetBool{ 0x2772AB0_a };
S_ANY Ref<float(scriptInstance_t inst, unsigned int index)> ScrVm_GetFloat{ 0x27733F0_a };
S_ANY Ref<XHash* (XHash* hash, scriptInstance_t inst, unsigned int index)> ScrVm_GetHash{ 0x27738E0_a };
S_ANY Ref<int64_t(scriptInstance_t inst, unsigned int index)> ScrVm_GetInt{ 0x2773B50_a };
S_ANY Ref<const char* (scriptInstance_t inst, unsigned int index)> ScrVm_GetString{ 0x2774840_a };
S_ANY Ref<void(scriptInstance_t inst, unsigned int index, vec3_t* vector)> ScrVm_GetVector{ 0x2774E40_a };
S_ANY Ref<ScrVarIndex_t(scriptInstance_t inst, unsigned int index)> ScrVm_GetConstString{ 0x2772E10_a };
S_ANY Ref<uint32_t(scriptInstance_t inst)> ScrVm_GetNumParam{ 0x2774440_a };
S_ANY Ref<ScrVarType_t(scriptInstance_t inst, unsigned int index)> ScrVm_GetPointerType{ 0x27746E0_a };
S_ANY Ref<ScrVarType_t(scriptInstance_t inst, unsigned int index)> ScrVm_GetType{ 0x2774A20_a };
S_ANY Ref<uint32_t(scriptInstance_t inst)> ScrVm_AddStruct{ 0x276EF00_a };
S_ANY Ref<void(scriptInstance_t inst, uint32_t structId, uint32_t name)> ScrVm_SetStructField{ 0x2778450_a };
S_ANY Ref<void(scriptInstance_t inst)> ScrVm_AddToArray{ 0x276F1C0_a };
S_ANY Ref<void(scriptInstance_t inst, XHash* name)> ScrVm_AddToArrayStringIndexed{ 0x276F230_a };
S_ANY Ref<void(scriptInstance_t inst, vec3_t* vec)> ScrVm_AddVector{ 0x276F490_a };
S_ANY Ref<void(scriptInstance_t inst)> ScrVar_PushArray{ 0x2775CF0_a };
S_ANY Ref<const char* (ScrVarIndex_t index)> ScrStr_ConvertToString{ 0x2759030_a };
S_ANY Ref<ScrVarIndex_t(scriptInstance_t inst, ScrVarIndex_t parentId, ScrVarNameIndex_t index)> ScrVar_NewVariableByIndex{ 0x2760440_a };
S_ANY Ref<void(scriptInstance_t inst, ScrVarIndex_t id, ScrVarValue_t* value)> ScrVar_SetValue{ 0x27616B0_a };

// gsc funcs
S_ANY Ref<BuiltinFunction(uint32_t canonId, int* type, int* min_args, int* max_args)> CScr_GetFunction{ 0x1F13140_a };
S_ANY Ref<BuiltinFunction(uint32_t canonId, int* type, int* min_args, int* max_args)> Scr_GetFunction{ 0x33AF840_a };
S_ANY Ref<void* (uint32_t canonId, int* type, int* min_args, int* max_args)> CScr_GetMethod{ 0x1F13650_a };
S_ANY Ref<void* (uint32_t canonId, int* type, int* min_args, int* max_args)> Scr_GetMethod{ 0x33AFC20_a };
S_ANY Ref<void(scriptInstance_t inst, byte* codepos, const char** scriptname, int32_t* sloc, int32_t* crc, int32_t* vm)> Scr_GetGscExportInfo{ 0x2748550_a };
S_ANY Ref<void(uint64_t code, scriptInstance_t inst, char* unused, bool terminal)> ScrVm_Error{ 0x2770330_a };

// gsc structs
S_ANY Ref<BO4_scrVarPub> scrVarPub{ 0x8307880_a };
S_ANY Ref<scrVarGlob_t> scrVarGlob{ 0x8307830_a };
S_ANY Ref<scrVmPub_t> scrVmPub{ 0x8307AA0_a };
S_ANY Ref<VM_OP_FUNC> gVmOpJumpTable{ 0x4EED340_a };
S_ANY Ref<uint32_t> gObjFileInfoCount{ 0x82F76B0_a };
S_ANY Ref<objFileInfo_t[SCRIPTINSTANCE_MAX][650]> gObjFileInfo{ 0x82EFCD0_a };

}
2 changes: 1 addition & 1 deletion src/bo4-ext-dll/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace bo4 {

void InitDll() {
try {
core::config::SyncConfig();
core::config::SyncConfig(true);
static std::string logFile{ "acts-bo4.log" };
logFile = core::config::GetString("logger.output", logFile.c_str());

Expand Down
1 change: 1 addition & 0 deletions src/bo4-ext-dll/systems/modding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <hook/library.hpp>
#include <pool.hpp>
#include <data/bo4.hpp>
#include <data/refs.hpp>

namespace {
hook::library::Detour GetAssetHeaderDetour;
Expand Down
85 changes: 45 additions & 40 deletions src/shared/core/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

namespace core::config {
namespace {
rapidjson::Document main{};

rapidjson::GenericValue<decltype(main)::EncodingType, decltype(main)::AllocatorType>& GetVal(const char* path, size_t off = 0, rapidjson::GenericValue<decltype(main)::EncodingType, decltype(main)::AllocatorType>& loc = main) {
rapidjson::GenericValue<decltype(Config::main)::EncodingType, decltype(Config::main)::AllocatorType>& GetVal(const char* path, size_t off, rapidjson::GenericValue<decltype(Config::main)::EncodingType, decltype(Config::main)::AllocatorType>& loc) {
static rapidjson::Value nullAnswer{ rapidjson::kNullType };
if (!path || !*path) {
return nullAnswer; // not a valid path
Expand Down Expand Up @@ -41,7 +39,7 @@ namespace core::config {
return GetVal(path + off, idx + 1, val);
}

void SetVal(const char* path, rapidjson::Value& value, size_t off = 0, rapidjson::GenericValue<decltype(main)::EncodingType, decltype(main)::AllocatorType>& loc = main) {
void SetVal(Config& cfg, const char* path, rapidjson::Value& value, size_t off, rapidjson::GenericValue<decltype(Config::main)::EncodingType, decltype(Config::main)::AllocatorType>& loc) {
if (!path || !*path) {
LOG_WARNING("Using setval with invalid path");
return; // not a valid path
Expand All @@ -56,102 +54,103 @@ namespace core::config {
std::string node{ path + off, sv.length() };

rapidjson::Value key{ rapidjson::kStringType };
key.SetString(node.c_str(), main.GetAllocator());
key.SetString(node.c_str(), cfg.main.GetAllocator());

if (loc.HasMember(key)) {
loc.EraseMember(key);
}

loc.AddMember(key, value, main.GetAllocator());
loc.AddMember(key, value, cfg.main.GetAllocator());
return;
}

std::string node{ path + off, idx };

rapidjson::Value key{ rapidjson::kStringType };
key.SetString(node.c_str(), main.GetAllocator());
key.SetString(node.c_str(), cfg.main.GetAllocator());

if (!loc.HasMember(key)) {
rapidjson::Value v{ rapidjson::kObjectType };
SetVal(path + off, value, idx + 1, v);
loc.AddMember(key, v, main.GetAllocator());
SetVal(cfg, path + off, value, idx + 1, v);
loc.AddMember(key, v, cfg.main.GetAllocator());
}
else {
SetVal(path + off, value, idx + 1, loc[key]);
SetVal(cfg, path + off, value, idx + 1, loc[key]);
}

}
}
Config::Config(const std::filesystem::path& path) : configFile(path.is_absolute() ? path : (utils::GetProgDir() / path)) {}

int64_t GetInteger(const char* path, int64_t defaultValue) {
rapidjson::Value& val = GetVal(path);
int64_t Config::GetInteger(const char* path, int64_t defaultValue) {
rapidjson::Value& val = GetVal(path, 0, main);

if (val.IsNull() || !val.IsNumber()) {
SetInteger(path, defaultValue);
this->SetInteger(path, defaultValue);
return defaultValue;
}
return val.GetInt64();
}

double GetDouble(const char* path, double defaultValue) {
rapidjson::Value& val = GetVal(path);
double Config::GetDouble(const char* path, double defaultValue) {
rapidjson::Value& val = GetVal(path, 0, main);

if (val.IsNull() || !val.IsNumber()) {
SetDouble(path, defaultValue);
this->SetDouble(path, defaultValue);
return defaultValue;
}
return val.GetDouble();
}

std::string GetString(const char* path, const char* defaultValue) {
rapidjson::Value& val = GetVal(path);
std::string Config::GetString(const char* path, const char* defaultValue) {
rapidjson::Value& val = GetVal(path, 0, main);

if (val.IsNull() || !val.IsString()) {
SetString(path, defaultValue);
this->SetString(path, defaultValue);
return defaultValue;
}
return val.GetString();
}

bool GetBool(const char* path, bool defaultValue) {
rapidjson::Value& val = GetVal(path);
bool Config::GetBool(const char* path, bool defaultValue) {
rapidjson::Value& val = GetVal(path, 0, main);

if (val.IsNull() || !val.IsBool()) {
SetBool(path, defaultValue);
this->SetBool(path, defaultValue);
return defaultValue;
}
return val.GetBool();
}

void SetInteger(const char* path, int64_t defaultValue) {
void Config::SetInteger(const char* path, int64_t defaultValue) {
rapidjson::Value v{ defaultValue };
SetVal(path, v);
SetVal(*this, path, v, 0, main);
}

void SetDouble(const char* path, double defaultValue) {
void Config::SetDouble(const char* path, double defaultValue) {
rapidjson::Value v{ defaultValue };
SetVal(path, v);
SetVal(*this, path, v, 0, main);
}

void SetString(const char* path, const std::string& defaultValue) {
void Config::SetString(const char* path, const std::string& defaultValue) {
rapidjson::Value v{ rapidjson::kStringType };
v.SetString(defaultValue.c_str(), main.GetAllocator());
SetVal(path, v);
SetVal(*this, path, v, 0, main);
}

void SetBool(const char* path, bool defaultValue) {
void Config::SetBool(const char* path, bool defaultValue) {
rapidjson::Value v{ defaultValue };
SetVal(path, v);
SetVal(*this, path, v, 0, main);
}
int64_t GetEnum(const char* path, ConfigEnumData* data, size_t dataCount, int64_t defaultEnumValue) {
int64_t Config::GetEnum(const char* path, ConfigEnumData* data, size_t dataCount, int64_t defaultEnumValue) {
const char* defaultValueStr{ "" };
for (size_t i = 0; i < dataCount; i++) {
if (data[i].enumValue == defaultEnumValue) {
defaultValueStr = data[i].name;
break;
}
}
std::string val{ GetString(path, defaultValueStr) };
std::string val{ this->GetString(path, defaultValueStr) };

if (val.empty()) {
return defaultEnumValue;
Expand All @@ -168,33 +167,39 @@ namespace core::config {
return defaultEnumValue;
}

void SetEnum(const char* path, int64_t enumValue, ConfigEnumData* data, size_t dataCount) {
void Config::SetEnum(const char* path, int64_t enumValue, ConfigEnumData* data, size_t dataCount) {
for (size_t i = 0; i < dataCount; i++) {
if (data[i].enumValue == enumValue) {
SetString(path, data[i].name);
this->SetString(path, data[i].name);
return;
}
}
LOG_WARNING("No enum value for path '{}': {}", path, enumValue);
}

void SyncConfig() {
void Config::SyncConfig(bool save) {
std::string json{};

if (utils::ReadFile(utils::GetProgDir() / CONFIG_FILE, json)) {
if (utils::ReadFile(utils::GetProgDir() / configFile, json)) {
main.Parse(json.data());
}
// not reading isn't an error

SaveConfig();
if (save) {
this->SaveConfig();
}
}

void SaveConfig() {
void Config::SaveConfig() const {
rapidjson::StringBuffer buff;
rapidjson::PrettyWriter<decltype(buff)> writer{ buff };
main.Accept(writer);

std::string json{ buff.GetString() };
utils::WriteFile(utils::GetProgDir() / CONFIG_FILE, json);
utils::WriteFile(utils::GetProgDir() / configFile, json);
}

Config& GetMainConfig() {
static Config mainCfg{ MAIN_CONFIG_FILE };
return mainCfg;
}
}
Loading

0 comments on commit cefe580

Please sign in to comment.