refactor sq api init
Makes initializing the SquirrelManagers more readable by having definitions for CLIENT, UI & SERVER vm in one place. Currently it looks like this
ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module))
{
// ...
g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst = module.Offset(0x12120).As<sq_defconstType>();
g_pSquirrel<ScriptContext::UI>->__sq_defconst = g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst;
// repeat for every function ...
}
ON_DLL_LOAD_RELIESON("server.dll", ClientSquirrel, ConCommand, (CModule module))
{
g_pSquirrel<ScriptContext::SERVER>->__sq_defconst = module.Offset(0x12120).As<sq_defconstType>();
// repeat for every function ...
}
The redundancy is annoying and makes it hard to see at a glance what the offsets for the functions are.
This PR implements this function that initializes the functions either on the CLIENT & UI or on the SERVER dynamically:
// Initialize a function on the CLIENT and UI or SERVER, depending on context
template <ScriptContext context, typename T>
void SetSharedMember(SquirrelManager<context>* manager, T* member, const CModule module, const int clOffset, const int svOffset)
{
switch (context)
{
case ScriptContext::CLIENT:
{
*member = module.Offset(clOffset).As<T>(); // Set the member for the CLIENT vm
*(T*)((char*)g_pSquirrel<ScriptContext::UI> + (int64_t)member - (int64_t)manager) = *member; // Set the member for the UI vm
break;
}
case ScriptContext::SERVER:
*member = module.Offset(svOffset).As<T>();
}
}
Initializing a function for all vms now looks like this:
template <ScriptContext context> void InitSharedSquirrelFunctions(SquirrelManager<context>* manager, CModule module)
{
SetSharedMember<context, sq_defconstType>(manager, &manager->__sq_defconst, module, 0x12120, 0x1F550);
}
The issue with this is that the memory layout of classes is ub afaik
*bump*
@uniboi just a heads-up that this PR has some merge conflicts atm
merge conflicts still
Converting to draft until merge conflicts are addressed. cc @uniboi