Fix script leaks + increase memory
This commit is contained in:
parent
02b3dd1493
commit
69f251bfda
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user