@@ -66,21 +66,22 @@ REGlobals::REGlobals() {
6666 }
6767
6868 // Create a list of getter functions instead
69- if (m_objects.empty ()) {
69+ if (m_objects.empty () || TDB_VER >= 78 ) {
7070 spdlog::info (" Usual pattern for REGlobals not working, falling back to scanning for SingletonBehavior types" );
7171
7272 auto & types = reframework::get_types ();
7373 auto & type_list = types->get_types ();
7474
7575 size_t i = 0 ;
7676
77- for (auto t : type_list) {
77+ for (auto t : type_list) try {
7878 auto name = std::string{t->name };
7979
8080 if (name.find (game_namespace (" SingletonBehavior`1" )) != std::string::npos ||
8181 name.find (game_namespace (" SingletonBehaviorRoot`1" )) != std::string::npos ||
8282 name.find (game_namespace (" SnowSingletonBehaviorRoot`1" )) != std::string::npos ||
83- name.find (game_namespace (" RopewaySingletonBehaviorRoot`1" )) != std::string::npos)
83+ name.find (game_namespace (" RopewaySingletonBehaviorRoot`1" )) != std::string::npos ||
84+ name.find (game_namespace (" ace.GAElement`1" )) != std::string::npos)
8485 {
8586 const auto type_definition = utility::re_type::get_type_definition (t);
8687
@@ -89,6 +90,8 @@ REGlobals::REGlobals() {
8990 continue ;
9091 }
9192
93+ spdlog::info (" Found singleton type: {}" , name);
94+
9295 // using asdf = decltype(m_getters)::value_type::second_type::_Func_class;
9396 using Getter = REManagedObject* (*)();
9497 auto getter = (Getter)sdk::find_native_method (type_definition, " get_Instance" );
@@ -106,6 +109,61 @@ REGlobals::REGlobals() {
106109
107110 m_getters[type_name] = getter;
108111 }
112+ } catch (...) {
113+ continue ;
114+ }
115+ }
116+
117+ // lets just go through the tdb types
118+ if (m_objects.empty () || TDB_VER >= 78 ) {
119+ auto tdb = sdk::RETypeDB::get ();
120+
121+ for (size_t i = 0 ; i < tdb->get_num_types (); ++i) try {
122+ auto type_definition = tdb->get_type (i);
123+
124+ if (type_definition == nullptr || type_definition->get_name () == nullptr ) {
125+ continue ;
126+ }
127+
128+ auto high_name = std::string_view{ type_definition->get_name () };
129+
130+ for (auto super = type_definition; super != nullptr ; super = super->get_parent_type ()) {
131+ auto name = std::string_view{ super->get_name () };
132+
133+ if (name.find (" SingletonBehavior`1" ) != std::string::npos ||
134+ name.find (" SingletonBehaviorRoot`1" ) != std::string::npos ||
135+ name.find (" SnowSingletonBehaviorRoot`1" ) != std::string::npos ||
136+ name.find (" RopewaySingletonBehaviorRoot`1" ) != std::string::npos ||
137+ name.find (" GAElement`1" ) != std::string::npos ||
138+ name.find (" AppSingleton`1" ) != std::string::npos)
139+ {
140+ if (high_name == name) {
141+ continue ; // dont care.
142+ }
143+
144+ auto full_name = super->get_full_name ();
145+
146+ spdlog::info (" Found singleton type: {}" , high_name.data ());
147+
148+ using Getter = REManagedObject* (*)();
149+ auto getter = (Getter)sdk::find_native_method (type_definition, " get_Instance" );
150+
151+ if (getter == nullptr ) {
152+ spdlog::warn (" Failed to find get_Instance method for {}" , high_name.data ());
153+ continue ;
154+ }
155+
156+ // Get the contained type by grabbing the string between the "`1<"" and the ">""
157+ auto type_name = std::string{full_name}.substr (full_name.find (" `1<" ) + 3 , full_name.find (" >" ) - full_name.find (" `1<" ) - 3 );
158+
159+ spdlog::info (" {}" , type_name);
160+
161+ m_getters[type_name] = getter;
162+ break ;
163+ }
164+ }
165+ } catch (...) {
166+ continue ;
109167 }
110168 }
111169
@@ -124,13 +182,13 @@ std::unordered_set<REManagedObject*> REGlobals::get_objects() {
124182 out.insert (*obj_ptr);
125183 }
126184 }
127- } else {
128- for (auto getter : m_getters) {
129- auto result = getter.second ();
185+ }
130186
131- if (result != nullptr ) {
132- out.insert (result);
133- }
187+ for (auto getter : m_getters) {
188+ auto result = getter.second ();
189+
190+ if (result != nullptr ) {
191+ out.insert (result);
134192 }
135193 }
136194
0 commit comments