Skip to content

Commit 96a9bea

Browse files
authored
Merge branch 'praydog:master' into master
2 parents 14270c5 + ad6bffe commit 96a9bea

5 files changed

Lines changed: 110 additions & 14 deletions

File tree

.github/workflows/dev-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
persist-credentials: false
1818

1919
- name: Configure CMake
20-
run: cmake -S ${{github.workspace}} -B ${{github.workspace}}/build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DDEVELOPER_MODE=ON
20+
run: cmake -S ${{github.workspace}} -B ${{github.workspace}}/build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DDEVELOPER_MODE=ON "-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
2121

2222
- name: Build
2323
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --target ${{matrix.target}}

shared/sdk/REContext.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,69 @@ namespace sdk {
821821
return create_instance_method->call<sdk::SystemArray*>(sdk::get_thread_context(), runtime_type, length);
822822
}
823823

824+
sdk::Delegate* VM::create_delegate(sdk::RETypeDefinition* t, uint32_t num_methods) {
825+
if (t == nullptr) {
826+
return nullptr;
827+
}
828+
829+
static const auto delegate_type = sdk::find_type_definition("System.Delegate");
830+
static const auto combine_method = delegate_type->get_method("Combine(System.Delegate, System.Delegate)");
831+
832+
if (combine_method == nullptr) {
833+
return nullptr;
834+
}
835+
836+
::REObjectInfo fake_object_info {
837+
.classInfo = (::REClassInfo*)t,
838+
};
839+
840+
sdk::Delegate fake_delegate_non_empty {
841+
.num_methods = 1,
842+
};
843+
844+
fake_delegate_non_empty.info = &fake_object_info;
845+
846+
sdk::Delegate fake_delegate_empty = fake_delegate_non_empty;
847+
fake_delegate_empty.num_methods = 0;
848+
849+
sdk::Delegate* new_delegate = &fake_delegate_empty;
850+
851+
auto ctx = sdk::get_thread_context();
852+
853+
for (uint32_t i = 0; i < num_methods; ++i) {
854+
const auto previous_delegate = new_delegate;
855+
new_delegate = combine_method->call<sdk::Delegate*>(ctx, new_delegate, &fake_delegate_non_empty);
856+
857+
if (new_delegate == nullptr) {
858+
spdlog::error("[VM::create_delegate] Unable to create delegate.");
859+
return nullptr;
860+
}
861+
}
862+
863+
if (new_delegate == nullptr || new_delegate == &fake_delegate_empty) {
864+
spdlog::error("[VM::create_delegate] Unable to create delegate.");
865+
return nullptr;
866+
}
867+
868+
return new_delegate;
869+
}
870+
871+
sdk::Delegate* VM::create_delegate(::REManagedObject* runtime_type, uint32_t num_methods) {
872+
if (runtime_type == nullptr) {
873+
return nullptr;
874+
}
875+
876+
static auto runtime_type_t = sdk::find_type_definition("System.RuntimeType");
877+
static auto get_TypeHandle = runtime_type_t->get_method("get_TypeHandle");
878+
879+
if (get_TypeHandle == nullptr) {
880+
return nullptr;
881+
}
882+
883+
auto type_handle = (sdk::RETypeDefinition*)get_TypeHandle->invoke(runtime_type).ptr;
884+
return create_delegate(type_handle, num_methods);
885+
}
886+
824887
::REManagedObject* VM::create_sbyte(int8_t value) {
825888
static auto sbyte_type = ::sdk::find_type_definition("System.SByte");
826889
static auto value_field = [&]() {

shared/sdk/REContext.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ struct REStaticTbl {
3535
uint32_t size;
3636
};
3737

38+
struct DelegateInvocation {
39+
using InvocationFn = void (*)(void*, void*, void*);
40+
41+
REManagedObject* object;
42+
InvocationFn* func;
43+
sdk::REMethodDefinition* method;
44+
};
45+
46+
struct Delegate : public REManagedObject {
47+
uint32_t num_methods{0};
48+
DelegateInvocation methods[1];
49+
};
50+
3851
// AKA via.clr.VM
3952
#if TDB_VER <= 49
4053
class VM : public regenny::via::clr::VM {
@@ -55,6 +68,8 @@ class VM {
5568
static sdk::InvokeMethod* get_invoke_table();
5669
static SystemString* create_managed_string(std::wstring_view str); // System.String
5770
static sdk::SystemArray* create_managed_array(::REManagedObject* runtime_type, uint32_t length); // System.Array
71+
static sdk::Delegate* create_delegate(sdk::RETypeDefinition* t, uint32_t num_methods); // System.Delegate
72+
static sdk::Delegate* create_delegate(::REManagedObject* runtime_type, uint32_t num_methods); // System.Delegate
5873

5974
static ::REManagedObject* create_sbyte(int8_t value); // System.SByte
6075
static ::REManagedObject* create_byte(uint8_t value); // System.Byte

src/mods/bindings/Sdk.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,36 @@ sol::object create_managed_array(sol::this_state s, sol::object t_obj, uint32_t
583583
return sol::make_object(s, (::sdk::SystemArray*)out);
584584
}
585585

586+
sol::object create_delegate(sol::this_state s, sol::object t_obj, uint32_t num_methods) {
587+
::REManagedObject* t{nullptr};
588+
589+
if (t_obj.is<::REManagedObject*>()) {
590+
t = t_obj.as<::REManagedObject*>();
591+
} else if (t_obj.is<::sdk::RETypeDefinition*>()) {
592+
t = t_obj.as<::sdk::RETypeDefinition*>()->get_runtime_type();
593+
} else if (t_obj.is<const char*>()) {
594+
const auto tdef = ::sdk::find_type_definition(t_obj.as<const char*>());
595+
596+
if (tdef != nullptr) {
597+
t = tdef->get_runtime_type();
598+
}
599+
} else {
600+
throw sol::error("Invalid type passed to create_delegate. Must be a runtime type, a type definition, or a type name.");
601+
}
602+
603+
if (t == nullptr) {
604+
throw sol::error("Type passed to create_delegate resolved to null.");
605+
}
606+
607+
auto out = ::sdk::VM::create_delegate(t, num_methods);
608+
609+
if (out == nullptr) {
610+
return sol::make_object(s, sol::nil);
611+
}
612+
613+
return sol::make_object(s, (::REManagedObject*)out);
614+
}
615+
586616
sol::object create_sbyte(sol::this_state s, int8_t value) {
587617
auto new_obj = ::sdk::VM::create_sbyte(value);
588618

@@ -1435,6 +1465,7 @@ void bindings::open_sdk(ScriptState* s) {
14351465
sdk["get_managed_singleton"] = api::sdk::get_managed_singleton;
14361466
sdk["create_managed_string"] = api::sdk::create_managed_string;
14371467
sdk["create_managed_array"] = api::sdk::create_managed_array;
1468+
sdk["create_delegate"] = api::sdk::create_delegate;
14381469
sdk["create_sbyte"] = api::sdk::create_sbyte;
14391470
sdk["create_byte"] = api::sdk::create_byte;
14401471
sdk["create_int16"] = api::sdk::create_int16;

src/mods/tools/GameObjectsDisplay.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,6 @@
1515
#include "../BackBufferRenderer.hpp"
1616
#include "GameObjectsDisplay.hpp"
1717

18-
namespace detail {
19-
struct Invocation {
20-
void* object_ptr;
21-
void* method_ptr;
22-
void* unk;
23-
};
24-
25-
struct Predicate : public REManagedObject {
26-
uint32_t num_invocations{0};
27-
std::array<Invocation, 10> invocations;
28-
};
29-
}
30-
3118
std::optional<std::string> GameObjectsDisplay::on_initialize_d3d_thread() {
3219
return initialize_d3d_resources();
3320
}

0 commit comments

Comments
 (0)