diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index a85bfb8b..f0757e0e 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -429,6 +429,50 @@ namespace fastfiles console::warn("No aipaths found for this map\n"); } } + + int format_bsp_name(char* filename, int size, const char* mapname) + { + std::string name = mapname; + auto fmt = "maps/%s.d3dbsp"; + if (name.starts_with("mp_")) + { + fmt = "maps/mp/%s.d3dbsp"; + } + + return game::Com_sprintf(filename, size, fmt, mapname); + } + + void get_bsp_filename_stub(char* filename, int size, const char* mapname) + { + auto base_mapname = mapname; + game::Com_IsAddonMap(mapname, &base_mapname); + format_bsp_name(filename, size, base_mapname); + } + + utils::hook::detour image_file_decrypt_value_hook; + bool image_file_decrypt_value_stub(char* value, int size, char* buffer) + { + auto is_all_zero = true; + for (auto i = 0; i < size; i++) + { + if (value[i] != 0) + { + is_all_zero = false; + } + } + + if (is_all_zero) + { + return true; + } + + return image_file_decrypt_value_hook.invoke(value, size, buffer); + } + + int com_sprintf_stub(char* dest, int size, const char* /*fmt*/, const char* mapname) + { + return format_bsp_name(dest, size, mapname); + } } bool exists(const std::string& zone, bool ignore_usermap) @@ -523,10 +567,13 @@ namespace fastfiles g_dump_scripts = dvars::register_bool("g_dumpScripts", false, game::DVAR_FLAG_NONE, "Dump GSC scripts"); - // Allow loading of unsigned fastfiles + // Allow loading of unsigned fastfiles & imagefiles if (!game::environment::is_sp()) { utils::hook::nop(0x368153_b, 2); // DB_InflateInit + + image_file_decrypt_value_hook.create(0x367520_b, image_file_decrypt_value_stub); + utils::hook::set(0x366F00_b, 0xC301B0); } if (game::environment::is_sp()) @@ -536,6 +583,12 @@ namespace fastfiles // Don't sys_error if aipaths are missing utils::hook::call(0x2F8EE9_b, db_find_aipaths_stub); } + else + { + // Allow loading sp maps on mp + utils::hook::jump(0x15AFC0_b, get_bsp_filename_stub); + utils::hook::call(0x112ED8_b, com_sprintf_stub); + } // Allow loading of mixed compressor types utils::hook::nop(SELECT_VALUE(0x1C4BE7_b, 0x3687A7_b), 2); diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 62bf8a98..af330029 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -48,6 +48,8 @@ namespace game WEAK symbol Com_Error{0x384820, 0x159860}; WEAK symbol Com_Quit_f{0x0, 0x1F9280}; WEAK symbol Com_Shutdown{0x3A6A50, 0x0}; + WEAK symbol Com_IsAddonMap{0x40AED0, 0x17C100}; + WEAK symbol Com_sprintf{0x429200, 0x5AF0F0}; WEAK symbol Quit{0x3A5A20, 0x17CF50};