@@ -131,7 +131,7 @@ class recomp::mods::DynamicLibrary {
131131
132132 template <typename T>
133133 bool get_dll_symbol (T& out, const char * name) const {
134- out = (T)GetProcAddress (native_handle, name);
134+ out = (T)( void *) GetProcAddress (native_handle, name);
135135 if (out == nullptr ) {
136136 return false ;
137137 }
@@ -638,6 +638,7 @@ void recomp::mods::ModContext::close_mods() {
638638 opened_mods_by_filename.clear ();
639639 opened_mods.clear ();
640640 opened_mods_order.clear ();
641+ mod_order_lookup.clear ();
641642 mod_ids.clear ();
642643 enabled_mods.clear ();
643644 auto_enabled_mods.clear ();
@@ -877,6 +878,8 @@ void recomp::mods::ModContext::load_mods_config() {
877878 return sort_order[i] < sort_order[j];
878879 });
879880
881+ rebuild_mod_order_lookup ();
882+
880883 // Enable mods that are specified in the configuration or mods that are considered new.
881884 for (size_t i = 0 ; i < opened_mods.size (); i++) {
882885 const ModHandle& mod = opened_mods[i];
@@ -889,6 +892,18 @@ void recomp::mods::ModContext::load_mods_config() {
889892 }
890893}
891894
895+ void recomp::mods::ModContext::rebuild_mod_order_lookup () {
896+ // Initialize the mod order lookup to all -1 so that mods that aren't enabled have an order index of -1.
897+ mod_order_lookup.resize (opened_mods.size ());
898+ std::fill (mod_order_lookup.begin (), mod_order_lookup.end (), static_cast <size_t >(-1 ));
899+
900+ // Build the lookup of mod index to mod order by inverting the opened mods order list.
901+ for (size_t mod_order_index = 0 ; mod_order_index < opened_mods_order.size (); mod_order_index++) {
902+ size_t mod_index = opened_mods_order[mod_order_index];
903+ mod_order_lookup[mod_index] = mod_order_index;
904+ }
905+ }
906+
892907recomp::mods::ModContext::ModContext () {
893908 // Register the code content type.
894909 ModContentType code_content_type {
@@ -1128,14 +1143,18 @@ size_t recomp::mods::ModContext::get_mod_order_index(const std::string& mod_id)
11281143 return static_cast <size_t >(-1 );
11291144 }
11301145
1131- // TODO keep a mapping of mod index to mod order index to prevent needing a lookup here.
1132- auto find_order_it = std::find (opened_mods_order.begin (), opened_mods_order.end (), find_it->second );
1133- if (find_order_it == opened_mods_order.end ()) {
1146+ return get_mod_order_index (find_it->second );
1147+ }
1148+
1149+ size_t recomp::mods::ModContext::get_mod_order_index (size_t mod_index) const {
1150+ size_t order_index = mod_order_lookup[mod_index];
1151+ // Check if the mod has a proper order index and assert if it doesn't, as that means the mod isn't actually loaded.
1152+ if (order_index == static_cast <size_t >(-1 )) {
11341153 assert (false );
11351154 return static_cast <size_t >(-1 );
11361155 }
11371156
1138- return find_order_it - opened_mods_order. begin () ;
1157+ return order_index ;
11391158}
11401159
11411160std::optional<recomp::mods::ModDetails> recomp::mods::ModContext::get_details_for_mod (const std::string& mod_id) const {
@@ -1347,6 +1366,8 @@ void recomp::mods::ModContext::set_mod_index(const std::string &mod_game_id, con
13471366 opened_mods_order.push_back (mod_index);
13481367 }
13491368
1369+ rebuild_mod_order_lookup ();
1370+
13501371 for (ModContentTypeId type_id : opened_mods[mod_index].content_types ) {
13511372 content_reordered_callback* callback = content_types[type_id.value ].on_reordered ;
13521373 if (callback) {
@@ -1655,12 +1676,13 @@ std::vector<recomp::mods::ModLoadErrorDetails> recomp::mods::ModContext::load_mo
16551676
16561677 // Regenerate any remaining hook slots that weren't handled during mod recompilation.
16571678
1658- // List of unprocessed hooks and their hook index.
1679+ // List of unprocessed hooks and their hook index. Also set up which hooks are return hooks.
16591680 std::vector<std::pair<recomp::mods::HookDefinition, size_t >> unprocessed_hooks;
16601681 for (const auto & [def, index] : hook_slots) {
16611682 if (!processed_hook_slots[index]) {
16621683 unprocessed_hooks.emplace_back (std::make_pair (def, index));
16631684 }
1685+ recomp::mods::set_hook_type (index, def.at_return );
16641686 }
16651687
16661688 if (!unprocessed_hooks.empty ()) {
@@ -1685,6 +1707,9 @@ std::vector<recomp::mods::ModLoadErrorDetails> recomp::mods::ModContext::load_mo
16851707 }
16861708 }
16871709
1710+ finish_event_setup (*this );
1711+ finish_hook_setup (*this );
1712+
16881713 active_game = mod_game_index;
16891714 return ret;
16901715}
@@ -2389,7 +2414,7 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependenci
23892414 return CodeModLoadError::InvalidCallbackEvent;
23902415 }
23912416
2392- recomp::mods::register_event_callback (event_index, func);
2417+ recomp::mods::register_event_callback (event_index, mod_index, func);
23932418 }
23942419
23952420 // Register hooks.
@@ -2411,7 +2436,7 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependenci
24112436
24122437 // Register the function handle for this hook slot.
24132438 GenericFunction func = mod.code_handle ->get_function_handle (cur_hook.func_index );
2414- recomp::mods::register_hook (find_it->second , func);
2439+ recomp::mods::register_hook (find_it->second , mod_index, func);
24152440 }
24162441
24172442 // Populate the relocated section addresses for the mod.
0 commit comments