Fix script leaks + increase memory

This commit is contained in:
fed 2022-11-11 22:04:24 +01:00
parent 02b3dd1493
commit 69f251bfda
3 changed files with 102 additions and 22 deletions

View File

@ -46,13 +46,52 @@ namespace gsc
std::unordered_map<std::string, unsigned int> main_handles;
std::unordered_map<std::string, unsigned int> init_handles;
std::unordered_map<std::string, game::ScriptFile*> loaded_scripts;
std::unordered_map<scripting::script_function, unsigned int> functions;
std::optional<std::string> gsc_error;
char* allocate_buffer(std::uint32_t size)
utils::memory::allocator scriptfile_allocator;
std::unordered_map<std::string, game::ScriptFile*> loaded_scripts;
struct
{
return static_cast<char*>(game::PMem_AllocFromSource_NoDebug(size, 4, 1, 5));
char* buf = nullptr;
char* pos = nullptr;
unsigned int size = 0x1000000;
} script_memory;
char* allocate_buffer(size_t size)
{
if (script_memory.buf == nullptr)
{
script_memory.buf = game::PMem_AllocFromSource_NoDebug(script_memory.size, 4, 1, game::PMEM_SOURCE_SCRIPT);
script_memory.pos = script_memory.buf;
}
if (script_memory.pos + size > script_memory.buf + script_memory.size)
{
game::Com_Error(game::ERR_FATAL, "Out of custom script memory");
}
const auto pos = script_memory.pos;
script_memory.pos += size;
return pos;
}
void free_script_memory()
{
game::PMem_PopFromSource_NoDebug(script_memory.buf, script_memory.size, 4, 1, game::PMEM_SOURCE_SCRIPT);
script_memory.buf = nullptr;
script_memory.pos = nullptr;
}
void clear()
{
main_handles.clear();
init_handles.clear();
loaded_scripts.clear();
scriptfile_allocator.clear();
free_script_memory();
}
bool read_scriptfile(const std::string& name, std::string* data)
@ -123,7 +162,7 @@ namespace gsc
return nullptr;
}
const auto script_file_ptr = reinterpret_cast<game::ScriptFile*>(allocate_buffer(sizeof(game::ScriptFile)));
const auto script_file_ptr = scriptfile_allocator.allocate<game::ScriptFile>();
script_file_ptr->name = file_name;
const auto stack = assembler->output_stack();
@ -132,15 +171,12 @@ namespace gsc
const auto script = assembler->output_script();
script_file_ptr->bytecodeLen = static_cast<int>(script.size());
const auto script_size = script.size();
const auto buffer_size = script_size + stack.size() + 2;
script_file_ptr->buffer = game::Hunk_AllocateTempMemoryHigh(stack.size() + 1);
std::memcpy(script_file_ptr->buffer, stack.data(), stack.size());
const auto buffer = allocate_buffer(static_cast<std::uint32_t>(buffer_size));
std::memcpy(buffer, script.data(), script_size);
std::memcpy(&buffer[script_size], stack.data(), stack.size());
script_file_ptr->bytecode = allocate_buffer(script.size() + 1);
std::memcpy(script_file_ptr->bytecode, script.data(), script.size());
script_file_ptr->bytecode = &buffer[0];
script_file_ptr->buffer = &buffer[script.size()];
script_file_ptr->compressedLen = 0;
loaded_scripts[real_name] = script_file_ptr;
@ -197,19 +233,10 @@ namespace gsc
}
}
void clear()
{
main_handles.clear();
init_handles.clear();
loaded_scripts.clear();
}
void load_gametype_script_stub(void* a1, void* a2)
{
utils::hook::invoke<void>(0x1404E1400, a1, a2);
clear();
fastfiles::enum_assets(game::ASSET_TYPE_RAWFILE, [](game::XAssetHeader header)
{
std::string name = header.rawfile->name;
@ -562,6 +589,27 @@ namespace gsc
return decompiler->output();
}
void pmem_init_stub()
{
utils::hook::invoke<void>(0x14061EC80);
const auto type_0 = &game::g_scriptmem[0];
const auto type_1 = &game::g_scriptmem[1];
const auto size_0 = 0x200000; // default size
const auto size_1 = 0x200000 + script_memory.size;
const auto block = reinterpret_cast<char*>(VirtualAlloc(NULL, size_0 + size_1, MEM_RESERVE, PAGE_READWRITE));
type_0->buf = block;
type_0->size = size_0;
type_1->buf = block + size_0;
type_1->size = size_1;
utils::hook::set<uint32_t>(0x14061EC72, size_0 + size_1);
}
}
game::ScriptFile* find_script(game::XAssetType /*type*/, const char* name, int /*allow_create_default*/)
@ -645,6 +693,9 @@ namespace gsc
utils::hook::nop(0x1405CA683, 8);
utils::hook::call(0x1405CA683, vm_call_builtin_stub);
// Increase script memory
utils::hook::call(0x1405A4798, pmem_init_stub);
add_function("print", [](const game::scr_entref_t ref)
{
const auto num = game::Scr_GetNumParam();

View File

@ -866,7 +866,7 @@ namespace game
int compressedLen;
int len;
int bytecodeLen;
const char* buffer;
char* buffer;
char* bytecode;
};
@ -1386,6 +1386,28 @@ namespace game
int vertAlign;
};
enum PMem_Source
{
PMEM_SOURCE_EXTERNAL = 0x0,
PMEM_SOURCE_DATABASE = 0x1,
PMEM_SOURCE_DEFAULT_LOW = 0x2,
PMEM_SOURCE_DEFAULT_HIGH = 0x3,
PMEM_SOURCE_MOVIE = 0x4,
PMEM_SOURCE_SCRIPT = 0x5,
};
struct physical_memory
{
char __pad0[0x10];
char* buf;
char __pad1[0x8];
int unk1;
size_t size;
char __pad2[0x500];
};
static_assert(sizeof(physical_memory) == 0x530);
namespace hks
{
struct lua_State;

View File

@ -94,6 +94,8 @@ namespace game
WEAK symbol<void(int localClientNum, const unsigned int weapon)> G_SelectWeapon{0x14051C0D0};
WEAK symbol<bool(int localClientNum, ScreenPlacement* screenPlacement, const float* worldDir, float* outScreenPos)> WorldPosToScreenPos{0x14036F310};
WEAK symbol<char*(const size_t size)> Hunk_AllocateTempMemoryHigh{0x140614790};
WEAK symbol<char*(char* string)> I_CleanStr{0x140620660};
WEAK symbol<char*(GfxImage* image, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipCount,
@ -133,7 +135,10 @@ namespace game
WEAK symbol<unsigned int(int handle, unsigned int paramcount)> Scr_ExecThread{0x1405C6F40};
WEAK symbol<unsigned int(void* func, int type, unsigned int name)> Scr_RegisterFunction{0x1405BC7B0};
WEAK symbol<void*(unsigned int size, unsigned int alignment, unsigned int type, int source)> PMem_AllocFromSource_NoDebug{0x14061E680};
WEAK symbol<char*(unsigned int size, unsigned int alignment,
unsigned int type, int source)> PMem_AllocFromSource_NoDebug{0x14061E680};
WEAK symbol<int(char* buf, unsigned int size, unsigned int alignment,
unsigned int type, int source)> PMem_PopFromSource_NoDebug{0x14061EDF0};
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x1405C8DB0};
@ -237,6 +242,8 @@ namespace game
WEAK symbol<jmp_buf> g_script_error{0x14BA9CD40};
WEAK symbol<scr_classStruct_t> g_classMap{0x140BF95C0};
WEAK symbol<physical_memory> g_scriptmem{0x14CC9FEC0};
WEAK symbol<scrVarGlob_t> scr_VarGlob{0x14B617C00};
WEAK symbol<scrVmPub_t> scr_VmPub{0x14BA9EE40};
WEAK symbol<function_stack_t> scr_function_stack{0x14BAA93C0};