Skip to content

Commit

Permalink
Merge branch 'master' into csharp-api
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Nov 11, 2024
2 parents a9e23f1 + 3e8c47d commit b14dba5
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 13 deletions.
68 changes: 66 additions & 2 deletions shared/sdk/REContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ namespace sdk {
static void* (*s_context_unhandled_exception_fn)(::REThreadContext*) = nullptr;
static void* (*s_context_local_frame_gc_fn)(::REThreadContext*) = nullptr;
static void* (*s_context_end_global_frame_fn)(::REThreadContext*) = nullptr;
static void* (*s_context_full_cleanup_fn)(::REThreadContext*) = nullptr;

void sdk::VMContext::update_pointers() {
{
Expand All @@ -489,7 +490,7 @@ namespace sdk {
s_fully_updated_vm_context_pointers = true;
}};

spdlog::info("Locating funcs");
spdlog::info("[VMContext] Locating funcs");

// Version 1
//auto ref = utility::scan(g_framework->getModule().as<HMODULE>(), "48 83 78 18 00 74 ? 48 89 D9 E8 ? ? ? ? 48 89 D9 E8 ? ? ? ?");
Expand All @@ -498,7 +499,65 @@ namespace sdk {
auto ref = utility::scan(utility::get_executable(), "48 83 78 18 00 74 ? 48 ? ? E8 ? ? ? ? 48 ? ? E8 ? ? ? ? 48 ? ? E8 ? ? ? ?");

if (!ref) {
spdlog::error("We're going to crash");
spdlog::info("[VMContext] Could not locate functions we need, trying fallback for full cleanup...");

auto full_cleanup_ref = utility::scan(utility::get_executable(), "48 8B 41 50 48 83 78 18 00");

if (full_cleanup_ref) {
auto fn = utility::find_function_start_with_call(*full_cleanup_ref);

if (!fn) {
spdlog::error("[VMContext] Could not locate full cleanup function.");
return;
}

s_context_full_cleanup_fn = (decltype(s_context_full_cleanup_fn))*fn;
spdlog::info("Context::FullCleanup {:x}", (uintptr_t)s_context_full_cleanup_fn);

// We need LocalFrameGC at least now, the other functions are not important if we have the full cleanup function.
// Because we actually do call LocalFrameGC by itself when needed.
// Doing this because I'm seeing tail calls which can confuse the disassembler
auto basic_blocks = utility::collect_basic_blocks(*fn);

if (basic_blocks.empty()) {
spdlog::error("[VMContext] Could not locate LocalFrameGC function (basic blocks).");
return;
}

for (const auto& bb : basic_blocks) {
if (s_context_local_frame_gc_fn != nullptr) {
break;
}

for (const auto& ix : bb.instructions) {
if (s_context_local_frame_gc_fn != nullptr) {
break;
}

// Hit a call
if (*(uint8_t*)ix.addr == 0xE8) {
const auto dst = utility::calculate_absolute(ix.addr + 1);

// This is always near the very start of the function entry, seen back in RE8 up to MHWilds.
// However it's such a common set of instructions which is why we narrow it to this function.
if (utility::scan_disasm(dst, 20, "48 8B 41 50")) {
s_context_local_frame_gc_fn = (decltype(s_context_local_frame_gc_fn))dst;
spdlog::info("[VMContext] Context::LocalFrameGC {:x}", (uintptr_t)s_context_local_frame_gc_fn);
break;
}
}
}
}

if (s_context_local_frame_gc_fn == nullptr) {
spdlog::error("[VMContext] Could not locate LocalFrameGC function.");
return;
}

return;
}

spdlog::error("[VMContext] We're going to crash, could not locate functions we need.");
return;
}

Expand Down Expand Up @@ -535,6 +594,11 @@ namespace sdk {

spdlog::error("{}", reference_count);
if (count_delta >= 1) {
if (s_context_full_cleanup_fn != nullptr) {
s_context_full_cleanup_fn(this);
return;
}

--reference_count;

// Perform object cleanup that was missed because an exception occurred.
Expand Down
24 changes: 15 additions & 9 deletions shared/sdk/RETypeDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,33 @@ reframework::InvokeRet invoke_object_func(::REManagedObject* obj, std::string_vi
}

sdk::RETypeDefinition* RETypeDB::find_type(std::string_view name) const {
static bool map_populated = false;

{
std::shared_lock _{ g_tdb_type_mtx };

if (auto it = g_tdb_type_map.find(name.data()); it != g_tdb_type_map.end()) {
return it->second;
}

if (map_populated) {
return nullptr;
}
}

for (uint32_t i = 0; i < this->numTypes; ++i) {
auto t = get_type(i);
{
std::unique_lock _{ g_tdb_type_mtx };

map_populated = true;

if (t->get_full_name() == name) {
std::unique_lock _{ g_tdb_type_mtx };
for (uint32_t i = 0; i < this->numTypes; ++i) {
auto t = get_type(i);

g_tdb_type_map[name.data()] = t;
return g_tdb_type_map[name.data()];
g_tdb_type_map[t->get_full_name()] = t;
}
}

std::unique_lock _{ g_tdb_type_mtx };
return g_tdb_type_map[name.data()];
return this->find_type(name);
}

sdk::RETypeDefinition* RETypeDB::find_type_by_fqn(uint32_t fqn) const {
Expand Down Expand Up @@ -1152,4 +1158,4 @@ std::vector<const char*> REMethodDefinition::get_param_names() const {
return out;
#endif
}
} // namespace sdk
} // namespace sdk
8 changes: 6 additions & 2 deletions src/mods/FreeCam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

using namespace utility;

#if defined(RE2) || defined(RE3) || defined(RE8) || defined(RE4)
#define MOVEMENT_DISABLE_FEATURE
#endif

void FreeCam::on_config_load(const Config& cfg) {
for (IModValue& option : m_options) {
option.config_load(cfg);
Expand Down Expand Up @@ -49,15 +53,15 @@ void FreeCam::on_draw_ui() {
ImGui::SameLine();
m_lock_camera->draw("Lock Position");

#ifndef SF6
#ifdef MOVEMENT_DISABLE_FEATURE
m_disable_movement->draw("Disable Character Movement");
#endif

m_toggle_key->draw("Toggle Key");
m_move_up_key->draw("Move camera up Key");
m_move_down_key->draw("Move camera down Key");
m_lock_camera_key->draw("Lock Position Toggle Key");
#ifndef SF6
#ifdef MOVEMENT_DISABLE_FEATURE
m_disable_movement_key->draw("Disable Movement Toggle Key");
#endif
m_speed_modifier_fast_key->draw("Speed modifier Fast key");
Expand Down

0 comments on commit b14dba5

Please sign in to comment.