Mod loading stuff

This commit is contained in:
Federico Cecchetto 2022-08-17 03:05:45 +02:00
parent e8930c1415
commit 1fb1842647
4 changed files with 94 additions and 4 deletions

View File

@ -73,6 +73,56 @@ namespace fastfiles
localized_strings::override(str, str);
}
}
utils::hook::detour db_read_stream_file_hook;
void db_read_stream_file_stub(int a1, int a2)
{
// always use lz4 compressor type when reading stream files
*game::g_compressor = 4;
return db_read_stream_file_hook.invoke<void>(a1, a2);
}
bool exists(const std::string& zone)
{
const auto is_localized = game::DB_IsLocalized(zone.data());
const auto db_fs = game::DB_FSInitialize();
auto handle = db_fs->vftbl->OpenFile(db_fs,
(is_localized ? game::SF_ZONE_LOC : game::SF_ZONE), utils::string::va("%s.ff", zone.data()));
const auto _0 = gsl::finally([&]
{
if (handle != nullptr)
{
db_fs->vftbl->Close(db_fs, handle);
}
});
return handle != nullptr;
}
void skip_extra_zones_stub(utils::hook::assembler& a)
{
const auto skip = a.newLabel();
const auto original = a.newLabel();
a.pushad64();
a.test(r15d, game::DB_ZONE_CUSTOM); // allocFlags
a.jnz(skip);
a.bind(original);
a.popad64();
a.mov(r8d, 9);
a.mov(rdx, 0x140933528);
a.jmp(0x140415E09);
a.bind(skip);
a.popad64();
a.mov(r14d, game::DB_ZONE_CUSTOM);
a.not_(r14d);
a.and_(r15d, r14d);
a.jmp(0x140415E29);
}
}
void enum_assets(const game::XAssetType type, const std::function<void(game::XAssetHeader)>& callback, const bool includeOverride)
@ -103,6 +153,16 @@ namespace fastfiles
add_missing_localized_strings();
// Allow loading of mixed compressor types
utils::hook::nop(0x1403E66A7, 2);
// Fix compressor type on streamed file load
db_read_stream_file_hook.create(0x14041D710, db_read_stream_file_stub);
// Don't load extra zones with loadzone
utils::hook::nop(0x140415DFC, 13);
utils::hook::jump(0x140415DFC, utils::hook::assemble(skip_extra_zones_stub), true);
command::add("loadzone", [](const command::params& params)
{
if (params.size() < 2)
@ -111,9 +171,17 @@ namespace fastfiles
return;
}
const auto name = params.get(1);
if (!fastfiles::exists(name))
{
console::warn("loadzone: zone \"%s\" could not be found!\n", name);
return;
}
game::XZoneInfo info{};
info.name = params.get(1);
info.allocFlags = 1;
info.name = name;
info.allocFlags = game::DB_ZONE_GAME | game::DB_ZONE_CUSTOM;
info.freeFlags = 0;
game::DB_LoadXAssets(&info, 1u, game::DBSyncMode::DB_LOAD_SYNC);
});

View File

@ -276,6 +276,12 @@ namespace mapents
scripting::token_map[name] = id;
}
void add_field(const std::string& name, game::scriptType_e type, unsigned int id)
{
custom_fields[id] = type;
scripting::token_map[name] = id;
}
utils::hook::detour scr_find_field_hook;
unsigned int scr_find_field_stub(unsigned int name, game::scriptType_e* type)
{
@ -382,7 +388,7 @@ namespace mapents
utils::hook::call(0x14058BD6B, should_load_addon_mapents);
utils::hook::call(0x1406B3384, cm_trigger_model_bounds_stub);
add_field("script_specialops", game::SCRIPT_INTEGER);
add_field("script_specialops", game::SCRIPT_INTEGER, 0x20000);
}
};
}

View File

@ -995,6 +995,20 @@ namespace game
DB_LOAD_SYNC_SKIP_ALWAYS_LOADED = 0x5,
};
enum DBAllocFlags : std::int32_t
{
DB_ZONE_NONE = 0x0,
DB_ZONE_COMMON = 0x1,
DB_ZONE_UI = 0x2,
DB_ZONE_GAME = 0x4,
DB_ZONE_LOAD = 0x8,
DB_ZONE_DEV = 0x10,
DB_ZONE_BASEMAP = 0x20,
DB_ZONE_TRANSIENT_POOL = 0x40,
DB_ZONE_TRANSIENT_MASK = 0x40,
DB_ZONE_CUSTOM = 0x1000 // added for custom zone loading
};
struct XZoneInfo
{
const char* name;

View File

@ -44,6 +44,7 @@ namespace game
WEAK symbol<int(const RawFile* rawfile)> DB_GetRawFileLen{0x140413D80};
WEAK symbol<int(const RawFile* rawfile, char* buf, int size)> DB_GetRawBuffer{0x140413C40};
WEAK symbol<XAssetEntry*(XAssetType type, XAssetHeader* header)> DB_LinkXAssetEntry1{0x140414900};
WEAK symbol<bool(const char* zoneName)> DB_IsLocalized{0x1404141E0};
WEAK symbol<dvar_t*(const char* name)> Dvar_FindVar{0x140618F90};
WEAK symbol<dvar_t*(int hash)> Dvar_FindMalleableVar{0x140618F00};
@ -192,6 +193,7 @@ namespace game
WEAK symbol<const char*> g_assetNames{0x140BEF280};
WEAK symbol<int> g_compressor{0x142065E80};
WEAK symbol<int> g_poolSize{0x140BF2E40};
WEAK symbol<gentity_s> g_entities{0x1452DDDA0};