diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index 40fb3d2b..64ec57a3 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -478,6 +478,34 @@ namespace fastfiles { return format_bsp_name(dest, size, mapname); } + + const char* get_zone_name(const unsigned int index) + { + if (game::environment::is_sp()) + { + return game::sp::g_zones[index].name; + } + else + { + return game::mp::g_zones[index].name; + } + } + + utils::hook::detour db_unload_x_zones_hook; + void db_unload_x_zones_stub(const unsigned short* unload_zones, + const unsigned int unload_count, const bool create_default) + { + for (auto i = 0u; i < unload_count; i++) + { + const auto zone_name = get_zone_name(unload_zones[i]); + if (zone_name[0] != '\0') + { + imagefiles::close_handle(zone_name); + } + } + + db_unload_x_zones_hook.invoke(unload_zones, unload_count, create_default); + } } bool exists(const std::string& zone, bool ignore_usermap) @@ -570,6 +598,9 @@ namespace fastfiles SELECT_VALUE(0x1F5700_b, 0x39A620_b), &db_try_load_x_file_internal); db_find_xasset_header_hook.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub); + db_unload_x_zones_hook.create(SELECT_VALUE(0x1F6040_b, + 0x39B3C0_b), db_unload_x_zones_stub); + g_dump_scripts = dvars::register_bool("g_dumpScripts", false, game::DVAR_FLAG_NONE, "Dump GSC scripts"); // Allow loading of unsigned fastfiles & imagefiles diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index c989da7d..3f9596e8 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1086,6 +1086,13 @@ namespace game int freeFlags; }; + struct XZoneInfoInternal + { + char name[64]; + int flags; + int isBaseMap; + }; + enum XAssetType { ASSET_TYPE_PHYSPRESET, @@ -1897,6 +1904,15 @@ namespace game }; // size = 1011960 static_assert(sizeof(client_t) == 1011960); + + struct XZone + { + char __pad0[32]; + char name[64]; + char __pad1[408]; + }; + + static_assert(sizeof(XZone) == 504); } namespace sp @@ -1918,6 +1934,15 @@ namespace game struct playerState_s { }; + + struct XZone + { + char __pad0[32]; + char name[64]; + char __pad1[128]; + }; + + static_assert(sizeof(XZone) == 224); } union playerState_s diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 928e4aab..e62eac9f 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -314,6 +314,8 @@ namespace game WEAK symbol DB_XAssetPool{0xEC9FB0, 0x10B4460}; WEAK symbol g_assetNames{0x991BA0, 0x10B30D0}; + WEAK symbol g_zoneInfo{0x0, 0x5F5A370}; + WEAK symbol g_zoneIndex{0x0, 0x3D1008C}; WEAK symbol< DB_FileSysInterface*> db_fs{0x25C1168, 0x1566C08}; @@ -346,11 +348,15 @@ namespace game WEAK symbol client_state{0x0, 0x2EC84F0}; WEAK symbol connect_state{0x0, 0x2EC8510}; + + WEAK symbol g_zones{0x0, 0x5F292B0}; } namespace sp { WEAK symbol g_entities{0x56E74D0, 0x0}; + + WEAK symbol g_zones{0x45FE990, 0x0}; } namespace hks