Skip to content

Commit

Permalink
Merge branch 'praydog:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyhodge authored Jan 16, 2024
2 parents b5d9c03 + 1ed9f31 commit 4355b69
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 19 deletions.
22 changes: 11 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2140,7 +2140,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -2337,7 +2337,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -3971,7 +3971,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -4168,7 +4168,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -4365,7 +4365,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -6719,7 +6719,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -6916,7 +6916,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -7833,7 +7833,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -8748,7 +8748,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -9665,7 +9665,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down Expand Up @@ -10582,7 +10582,7 @@ if(REF_BUILD_FRAMEWORK AND CMAKE_SIZEOF_VOID_P EQUAL 8) # build-framework
OUTPUT_NAME
dinput8
LINK_FLAGS
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
"/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Expand Down
2 changes: 1 addition & 1 deletion cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ link-libraries = [

[template.game.properties]
OUTPUT_NAME = "dinput8"
LINK_FLAGS = "/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll"
LINK_FLAGS = "/DELAYLOAD:openvr_api.dll /DELAYLOAD:openxr_loader.dll /DELAYLOAD:d3d11.dll /DELAYLOAD:d3d12.dll /DELAYLOAD:D3DCOMPILER_47.dll"
RUNTIME_OUTPUT_DIRECTORY_RELEASE = "${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO = "${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
LIBRARY_OUTPUT_DIRECTORY_RELEASE = "${CMAKE_BINARY_DIR}/lib/${CMKR_TARGET}"
Expand Down
18 changes: 18 additions & 0 deletions shared/sdk/REContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,26 @@ namespace sdk {
std::vector<std::string> invoke_patterns {
"40 53 48 83 ec 20 48 8b 41 30 4c 8b d2 48 8b 51 40 48 8b d9 4c 8b 00 48 8b 41 10", // RE2 - MHRise v1
"40 53 48 83 ec 20 48 8b 41 10 48 8b da 8b 48 08", // MHRise Sunbreak/newer games?
"40 53 48 83 EC ? 48 8B 41 30 4C 8B D2 4C 8B 49 10 48 8B D9 48 8B 51 40 49 8B CA 4C 8B 00 41 FF" // seen in game pass RE2
};

// ok so if these patterns above are failing, we can find the invoke table by looking for these set of instructions:
// 8D 56 FF lea edx, [rsi-1]
// 48 8B CF mov rcx, rdi
// E8 67 FD 6C 01 call sub_[removed]

// Then, scroll up from here, and you'll see something that looks like this:
/*
E8 D4 D6 6C 01 call sub_[removed]
41 B8 53 15 00 00 mov r8d, 1553h ; dead giveaway is a number like this that is the size of the invoke table
48 8D 15 37 C7 6B 06 lea rdx, g_invokeTbl ; this is what we want
48 8B 08 mov rcx, [rax]
48 8B 05 2D 47 86 06 mov rax, cs:off_[removed]
48 89 08 mov [rax], rcx
48 8B CF mov rcx, rdi
*/


std::optional<uintptr_t> method_inside_invoke_tbl{std::nullopt};

for (const auto& pat : invoke_patterns) {
Expand Down
3 changes: 2 additions & 1 deletion shared/sdk/REGlobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ REGlobals::REGlobals() {

if (name.find(game_namespace("SingletonBehavior`1")) != std::string::npos ||
name.find(game_namespace("SingletonBehaviorRoot`1")) != std::string::npos ||
name.find(game_namespace("SnowSingletonBehaviorRoot`1")) != std::string::npos)
name.find(game_namespace("SnowSingletonBehaviorRoot`1")) != std::string::npos ||
name.find(game_namespace("RopewaySingletonBehaviorRoot`1")) != std::string::npos)
{
const auto type_definition = utility::re_type::get_type_definition(t);

Expand Down
1 change: 1 addition & 0 deletions src/Mod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ class Mod {
// Called when REFramework::initialize finishes in the first render frame
// Returns an error string if it fails
virtual std::optional<std::string> on_initialize() { return std::nullopt; };
virtual std::optional<std::string> on_initialize_d3d_thread() { return std::nullopt; };
virtual void on_lua_state_created(sol::state& lua) {};
virtual void on_lua_state_destroyed(sol::state& lua) {};

Expand Down
29 changes: 29 additions & 0 deletions src/Mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ std::optional<std::string> Mods::on_initialize() const {
return std::nullopt;
}


std::optional<std::string> Mods::on_initialize_d3d_thread() const {
std::scoped_lock _{g_framework->get_hook_monitor_mutex()};

utility::Config cfg{ (REFramework::get_persistent_dir() / "re2_fw_config.txt").string() };

// once here to at least setup the values
for (auto& mod : m_mods) {
spdlog::info("{:s}::on_config_load()", mod->get_name().data());
mod->on_config_load(cfg);
}

for (auto& mod : m_mods) {
spdlog::info("{:s}::on_initialize_d3d_thread()", mod->get_name().data());

if (auto e = mod->on_initialize_d3d_thread(); e != std::nullopt) {
spdlog::info("{:s}::on_initialize_d3d_thread() has failed: {:s}", mod->get_name().data(), *e);
return e;
}
}

for (auto& mod : m_mods) {
spdlog::info("{:s}::on_config_load()", mod->get_name().data());
mod->on_config_load(cfg);
}

return std::nullopt;
}

void Mods::on_pre_imgui_frame() const {
for (auto& mod : m_mods) {
mod->on_pre_imgui_frame();
Expand Down
1 change: 1 addition & 0 deletions src/Mods.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Mods {
virtual ~Mods() {}

std::optional<std::string> on_initialize() const;
std::optional<std::string> on_initialize_d3d_thread() const;

void on_pre_imgui_frame() const;
void on_frame() const;
Expand Down
47 changes: 45 additions & 2 deletions src/REFramework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ REFramework::REFramework(HMODULE reframework_module)
const auto pre_allocated_buffer = (uintptr_t)AllocateBuffer((LPVOID)halfway_module); // minhook function
spdlog::info("Preallocated buffer: {:x}", pre_allocated_buffer);

IntegrityCheckBypass::fix_virtual_protect();

IMGUI_CHECKVERSION();
ImGui::CreateContext();

Expand Down Expand Up @@ -503,7 +505,7 @@ void REFramework::on_frame_d3d11() {
return;
}

const bool is_init_ok = m_error.empty() && m_game_data_initialized;
bool is_init_ok = m_error.empty() && m_game_data_initialized;

if (is_init_ok) {
// Write default config once if it doesn't exist.
Expand All @@ -514,6 +516,8 @@ void REFramework::on_frame_d3d11() {
}
}

is_init_ok = first_frame_initialize();

if (!m_has_frame) {
if (!is_init_ok) {
update_fonts();
Expand Down Expand Up @@ -606,7 +610,7 @@ void REFramework::on_frame_d3d12() {
return;
}

const bool is_init_ok = m_error.empty() && m_game_data_initialized;
bool is_init_ok = m_error.empty() && m_game_data_initialized;

if (is_init_ok) {
// Write default config once if it doesn't exist.
Expand All @@ -629,6 +633,8 @@ void REFramework::on_frame_d3d12() {
ImGui_ImplDX12_NewFrame();
};

is_init_ok = first_frame_initialize();

if (!m_has_frame) {
if (!is_init_ok) {
update_fonts();
Expand Down Expand Up @@ -1632,6 +1638,43 @@ bool REFramework::initialize_windows_message_hook() {
return false;
}

// Ran on the first valid frame after pre-initialization of mods has taken place and hasn't failed
// This one allows mods to run any initialization code in the context of the D3D thread (like VR code)
// It also is the one that actually loads any config files
bool REFramework::first_frame_initialize() {
const bool is_init_ok = m_error.empty() && m_game_data_initialized;

if (!is_init_ok || !m_first_frame_d3d_initialize) {
return is_init_ok;
}

std::scoped_lock _{get_hook_monitor_mutex()};

spdlog::info("Running first frame D3D initialization of mods...");

m_first_frame_d3d_initialize = false;
auto e = m_mods->on_initialize_d3d_thread();

if (e) {
if (e->empty()) {
m_error = "An unknown error has occurred.";
} else {
m_error = *e;
}

spdlog::error("Initialization of mods failed. Reason: {}", m_error);
m_game_data_initialized = false;
m_mods_fully_initialized = false;
return false;
} else {
// Do an initial config save to set the default values for the frontend
save_config();
m_mods_fully_initialized = true;
}

return true;
}

void REFramework::call_on_frame() {
const bool is_init_ok = m_error.empty() && m_game_data_initialized;

Expand Down
4 changes: 4 additions & 0 deletions src/REFramework.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,14 @@ class REFramework {
bool initialize_game_data();
bool initialize_windows_message_hook();

bool first_frame_initialize();

void call_on_frame();

HMODULE m_reframework_module{};

bool m_first_frame{true};
bool m_first_frame_d3d_initialize{true};
bool m_is_d3d12{false};
bool m_is_d3d11{false};
bool m_valid{false};
Expand All @@ -160,6 +163,7 @@ class REFramework {
bool m_started_game_data_thread{false};
std::atomic<bool> m_terminating{false}; // Destructor is called
std::atomic<bool> m_game_data_initialized{false};
std::atomic<bool> m_mods_fully_initialized{false};

// UI
bool m_has_frame{false};
Expand Down
4 changes: 3 additions & 1 deletion src/mods/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ std::optional<std::string> Hooks::hook_update_transform() {
m_update_transform_hook = std::make_unique<FunctionHook>(update_transform, &update_transform_hook);

if (!m_update_transform_hook->create()) {
return "Failed to hook UpdateTransform";
//return "Failed to hook UpdateTransform";
spdlog::error("Failed to hook UpdateTransform");
return std::nullopt; // who cares
}

return std::nullopt;
Expand Down
Loading

0 comments on commit 4355b69

Please sign in to comment.