Fix gsc crash

This commit is contained in:
fed 2022-11-13 20:03:34 +01:00
parent 15fdab136f
commit 87d20bb856
6 changed files with 65 additions and 54 deletions

View File

@ -12,63 +12,63 @@
#define MAX_ARENAS 64 #define MAX_ARENAS 64
namespace namespace arena
{ {
std::recursive_mutex arena_mutex; namespace
bool parse_arena(const std::string& path)
{ {
std::lock_guard<std::recursive_mutex> _0(arena_mutex); std::recursive_mutex arena_mutex;
std::string buffer{}; bool parse_arena(const std::string& path)
if (filesystem::read_file(path, &buffer) && !buffer.empty())
{ {
*game::ui_num_arenas += game::GameInfo_ParseArenas(buffer.data(), MAX_ARENAS - *game::ui_num_arenas, std::lock_guard<std::recursive_mutex> _0(arena_mutex);
std::string buffer{};
if (filesystem::read_file(path, &buffer) && !buffer.empty())
{
*game::ui_num_arenas += game::GameInfo_ParseArenas(buffer.data(), MAX_ARENAS - *game::ui_num_arenas,
&game::ui_arena_infos[*game::ui_num_arenas]);
return true;
}
if (!game::DB_XAssetExists(game::ASSET_TYPE_RAWFILE, path.data()) ||
game::DB_IsXAssetDefault(game::ASSET_TYPE_RAWFILE, path.data()))
{
return false;
}
const auto rawfile = game::DB_FindXAssetHeader(game::ASSET_TYPE_RAWFILE, path.data(), 0).rawfile;
const auto len = game::DB_GetRawFileLen(rawfile);
const auto rawfile_buffer = utils::memory::get_allocator()->allocate_array<char>(len);
const auto _1 = gsl::finally([&]
{
utils::memory::get_allocator()->free(rawfile_buffer);
});
game::DB_GetRawBuffer(rawfile, rawfile_buffer, len);
*game::ui_num_arenas += game::GameInfo_ParseArenas(rawfile_buffer, MAX_ARENAS - *game::ui_num_arenas,
&game::ui_arena_infos[*game::ui_num_arenas]); &game::ui_arena_infos[*game::ui_num_arenas]);
return true; return true;
} }
if (!game::DB_XAssetExists(game::ASSET_TYPE_RAWFILE, path.data()) || void load_arenas_stub()
game::DB_IsXAssetDefault(game::ASSET_TYPE_RAWFILE, path.data()))
{ {
return false; *game::ui_num_arenas = 0;
} *game::ui_arena_buf_pos = 0;
const auto rawfile = game::DB_FindXAssetHeader(game::ASSET_TYPE_RAWFILE, path.data(), 0).rawfile; parse_arena("mp/basemaps.arena");
const auto len = game::DB_GetRawFileLen(rawfile);
const auto rawfile_buffer = utils::memory::get_allocator()->allocate_array<char>(len); // read usermap arena from disk
const auto _1 = gsl::finally([&] const auto mapname = game::Dvar_FindVar("ui_mapname");
{ if (mapname && mapname->current.string)
utils::memory::get_allocator()->free(rawfile_buffer); {
}); const auto usermap_path = "usermaps/"s + mapname->current.string;
const auto arena_path = usermap_path + "/" + mapname->current.string + ".arena";
game::DB_GetRawBuffer(rawfile, rawfile_buffer, len); parse_arena(arena_path);
*game::ui_num_arenas += game::GameInfo_ParseArenas(rawfile_buffer, MAX_ARENAS - *game::ui_num_arenas, }
&game::ui_arena_infos[*game::ui_num_arenas]);
return true;
}
void load_arenas_stub()
{
*game::ui_num_arenas = 0;
*game::ui_arena_buf_pos = 0;
parse_arena("mp/basemaps.arena");
// read usermap arena from disk
const auto mapname = game::Dvar_FindVar("ui_mapname");
if (mapname && mapname->current.string)
{
const auto usermap_path = "usermaps/"s + mapname->current.string;
const auto arena_path = usermap_path + "/" + mapname->current.string + ".arena";
parse_arena(arena_path);
} }
} }
}
namespace arena
{
class component final : public component_interface class component final : public component_interface
{ {
public: public:

View File

@ -151,10 +151,13 @@ namespace bots
}); });
// Clear bot names and reset ID on game shutdown to allow new names to be added without restarting // Clear bot names and reset ID on game shutdown to allow new names to be added without restarting
scripting::on_shutdown([](int) scripting::on_shutdown([](bool /*free_scripts*/, bool post_shutdown)
{ {
bot_names.clear(); if (!post_shutdown)
bot_id = 0; {
bot_names.clear();
bot_id = 0;
}
}); });
} }
}; };

View File

@ -417,9 +417,9 @@ namespace gsc
// Increase script memory // Increase script memory
utils::hook::call(SELECT_VALUE(0x38639C_b, 0x15C4D6_b), pmem_init_stub); utils::hook::call(SELECT_VALUE(0x38639C_b, 0x15C4D6_b), pmem_init_stub);
scripting::on_shutdown([](int free_scripts) scripting::on_shutdown([](bool free_scripts, bool post_shutdown)
{ {
if (free_scripts) if (free_scripts && post_shutdown)
{ {
xsk::gsc::h1::resolver::cleanup(); xsk::gsc::h1::resolver::cleanup();
clear(); clear();

View File

@ -403,9 +403,12 @@ namespace logfile
return scripting::script_value{}; return scripting::script_value{};
}); });
scripting::on_shutdown([](int) scripting::on_shutdown([](bool /*free_scripts*/, bool post_shutdown)
{ {
say_callbacks.clear(); if (!post_shutdown)
{
say_callbacks.clear();
}
}); });
} }
}; };

View File

@ -51,7 +51,7 @@ namespace scripting
game::dvar_t* g_dump_scripts; game::dvar_t* g_dump_scripts;
std::vector<std::function<void(bool)>> shutdown_callbacks; std::vector<std::function<void(bool, bool)>> shutdown_callbacks;
std::unordered_map<unsigned int, std::string> canonical_string_table; std::unordered_map<unsigned int, std::string> canonical_string_table;
@ -125,7 +125,7 @@ namespace scripting
for (const auto& callback : shutdown_callbacks) for (const auto& callback : shutdown_callbacks)
{ {
callback(free_scripts); callback(free_scripts, false);
} }
scripting::notify(*game::levelEntityId, "shutdownGame_called", {1}); scripting::notify(*game::levelEntityId, "shutdownGame_called", {1});
@ -135,6 +135,11 @@ namespace scripting
game::G_LogPrintf("------------------------------------------------------------\n"); game::G_LogPrintf("------------------------------------------------------------\n");
g_shutdown_game_hook.invoke<void>(free_scripts); g_shutdown_game_hook.invoke<void>(free_scripts);
for (const auto& callback : shutdown_callbacks)
{
callback(free_scripts, true);
}
} }
void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t name, unsigned int canonical_string, unsigned int offset) void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t name, unsigned int canonical_string, unsigned int offset)
@ -243,7 +248,7 @@ namespace scripting
return scripting::find_token(id); return scripting::find_token(id);
} }
void on_shutdown(const std::function<void(bool)>& callback) void on_shutdown(const std::function<void(bool, bool)>& callback)
{ {
shutdown_callbacks.push_back(callback); shutdown_callbacks.push_back(callback);
} }

View File

@ -14,7 +14,7 @@ namespace scripting
extern std::string current_file; extern std::string current_file;
void on_shutdown(const std::function<void(bool)>& callback); void on_shutdown(const std::function<void(bool, bool)>& callback);
std::optional<std::string> get_canonical_string(const unsigned int id); std::optional<std::string> get_canonical_string(const unsigned int id);
std::string get_token(unsigned int id); std::string get_token(unsigned int id);
} }