custom GSC loading

This commit is contained in:
m 2023-05-02 16:33:39 -05:00
parent f7ad60d767
commit 1a17d186db
3 changed files with 40 additions and 21 deletions

View File

@ -12,6 +12,8 @@ namespace script
{ {
namespace namespace
{ {
constexpr size_t GSC_MAGIC = 0x1C000A0D43534780;
utils::hook::detour db_findxassetheader_hook; utils::hook::detour db_findxassetheader_hook;
utils::hook::detour gscr_get_bgb_remaining_hook; utils::hook::detour gscr_get_bgb_remaining_hook;
@ -23,11 +25,6 @@ namespace script
return (itr == loaded_scripts.end()) ? nullptr : itr->second; return (itr == loaded_scripts.end()) ? nullptr : itr->second;
} }
void print_loading_script(const std::string& name)
{
printf("Loading GSC script '%s'\n", name.data());
}
void load_script(std::string& name, const std::string& data) void load_script(std::string& name, const std::string& data)
{ {
auto& allocator = *utils::memory::get_allocator(); auto& allocator = *utils::memory::get_allocator();
@ -49,11 +46,14 @@ namespace script
} }
auto* rawfile = allocator.allocate<game::RawFile>(); auto* rawfile = allocator.allocate<game::RawFile>();
rawfile->name = name.c_str(); rawfile->name = name.data();
rawfile->buffer = file_string; rawfile->buffer = file_string;
rawfile->len = static_cast<int>(data.length()); rawfile->len = static_cast<int>(data.length());
loaded_scripts[name] = rawfile; loaded_scripts[name] = rawfile;
const auto base_name = name.substr(0, name.size() - 4); // .gsc suffix will be readded by Scr_LoadScript
game::Scr_LoadScript(game::SCRIPTINSTANCE_SERVER, base_name.data());
} }
void load_scripts_folder(const std::string& script_dir) void load_scripts_folder(const std::string& script_dir)
@ -64,16 +64,19 @@ namespace script
} }
const auto scripts = utils::io::list_files(script_dir); const auto scripts = utils::io::list_files(script_dir);
for (const auto& script : scripts) for (const auto& script : scripts)
{ {
std::string data; std::string data;
auto script_file = script.generic_string(); auto script_file = script.generic_string();
if (!std::filesystem::is_directory(script) && utils::io::read_file(script_file, &data)) if (!std::filesystem::is_directory(script) && utils::io::read_file(script_file, &data))
{ {
print_loading_script(script_file); if (data.size() >= sizeof(GSC_MAGIC) && !std::memcmp(data.data(), &GSC_MAGIC, sizeof(GSC_MAGIC)))
{
auto base_name = script_file.substr(0, script_file.size() - 4);
printf("Loading GSC script '%s'\n", base_name.data());
load_script(script_file, data); load_script(script_file, data);
} }
}
else if (std::filesystem::is_directory(script)) else if (std::filesystem::is_directory(script))
{ {
load_scripts_folder(script_file); load_scripts_folder(script_file);
@ -86,7 +89,8 @@ namespace script
loaded_scripts = {}; loaded_scripts = {};
const utils::nt::library host{}; const utils::nt::library host{};
load_scripts_folder((game::get_appdata_path() / "data/scripts").string()); load_scripts_folder((game::get_appdata_path() / "data/scripts").string());
load_scripts_folder((host.get_folder() / "boiii/scripts").string()); auto path = (host.get_folder() / "boiii/scripts").string();
load_scripts_folder(path);
} }
game::RawFile* db_findxassetheader_stub(const game::XAssetType type, const char* name, game::RawFile* db_findxassetheader_stub(const game::XAssetType type, const char* name,
@ -104,9 +108,10 @@ namespace script
auto* script = get_loaded_script(name); auto* script = get_loaded_script(name);
if (script) if (script)
{ {
// Copy over the checksum of the original script /*
// TODO: don't check checksums for custom GSC, but only for stock scripts we override
utils::hook::copy(const_cast<char*>(script->buffer + 0x8), asset_header->buffer + 0x8, 4); utils::hook::copy(const_cast<char*>(script->buffer + 0x8), asset_header->buffer + 0x8, 4);
*/
return script; return script;
} }
@ -117,23 +122,30 @@ namespace script
{ {
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 255); game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 255);
} }
utils::hook::detour load_gametype_script_hook;
void load_gametype_script_stub()
{
if (!game::Com_IsInGame() || game::Com_IsRunningUILevel())
{
load_gametype_script_hook.invoke<void>();
return;
}
load_gametype_script_hook.invoke<void>();
load_scripts();
}
} }
struct component final : generic_component struct component final : generic_component
{ {
void post_unpack() override void post_unpack() override
{ {
if (game::is_server())
{
load_scripts();
}
else
{
scheduler::once(load_scripts, scheduler::pipeline::renderer);
}
db_findxassetheader_hook.create(game::select(0x141420ED0, 0x1401D5FB0), db_findxassetheader_stub); db_findxassetheader_hook.create(game::select(0x141420ED0, 0x1401D5FB0), db_findxassetheader_stub);
gscr_get_bgb_remaining_hook.create(game::select(0x141A8CAB0, 0x1402D2310), gscr_get_bgb_remaining_stub); gscr_get_bgb_remaining_hook.create(game::select(0x141A8CAB0, 0x1402D2310), gscr_get_bgb_remaining_stub);
load_gametype_script_hook.create(0x141AAD850_g, load_gametype_script_stub);
} }
}; };
}; };

View File

@ -1814,7 +1814,9 @@ namespace game
PlayerSoundsTable* playerSounds; PlayerSoundsTable* playerSounds;
PlayerFXTable* playerFX; PlayerFXTable* playerFX;
SharedWeaponSounds* sharedWeaponSounds; SharedWeaponSounds* sharedWeaponSounds;
*/
RawFile* rawfile; RawFile* rawfile;
/*
StringTable* stringTable; StringTable* stringTable;
StructuredTable* structuredTable; StructuredTable* structuredTable;
LeaderboardDef* leaderboardDef; LeaderboardDef* leaderboardDef;

View File

@ -35,6 +35,7 @@ namespace game
0x1420F4E00, 0x1404FE5C0 0x1420F4E00, 0x1404FE5C0
}; };
WEAK symbol<bool()> Com_IsRunningUILevel{0x142148350}; WEAK symbol<bool()> Com_IsRunningUILevel{0x142148350};
WEAK symbol<bool()> Com_IsInGame{0x1421482C0};
WEAK symbol<void(int localClientNum, eModes fromMode, eModes toMode, uint32_t flags)> Com_SwitchMode{ WEAK symbol<void(int localClientNum, eModes fromMode, eModes toMode, uint32_t flags)> Com_SwitchMode{
0x14214A4D0 0x14214A4D0
}; };
@ -80,6 +81,9 @@ namespace game
WEAK symbol<qboolean(void* ent)> StuckInClient{0x1415A8360, 0x14023BFE0}; WEAK symbol<qboolean(void* ent)> StuckInClient{0x1415A8360, 0x14023BFE0};
// GScr
WEAK symbol<void()> GScr_LoadGametypeScript{0x14092F680, 0x0};
// Live // Live
WEAK symbol<bool(uint64_t, int*, bool)> Live_GetConnectivityInformation{0x141E0C380}; WEAK symbol<bool(uint64_t, int*, bool)> Live_GetConnectivityInformation{0x141E0C380};
@ -175,6 +179,7 @@ namespace game
0x0, 0x1402F5FF0 0x0, 0x1402F5FF0
}; };
WEAK symbol<unsigned int(scriptInstance_t inst)> Scr_GetNumParam{0x0, 0x140171320}; WEAK symbol<unsigned int(scriptInstance_t inst)> Scr_GetNumParam{0x0, 0x140171320};
WEAK symbol<unsigned int(scriptInstance_t inst, const char* filename)> Scr_LoadScript{0x1412C83F0};
WEAK symbol<void(const char* name, const char* key, unsigned int playbackFlags, float volume, void* callbackInfo, WEAK symbol<void(const char* name, const char* key, unsigned int playbackFlags, float volume, void* callbackInfo,
int id)> Cinematic_StartPlayback{0x1412BE3A0}; int id)> Cinematic_StartPlayback{0x1412BE3A0};