Closed ate47 closed 11 months ago
gsc functions only work host side
csc functions work via p2p - tested
thanks for your contribution in advance. your codding well met our required standards but I didnt quite understand what new features your component adds to game. can you add some simple explanation if possible? *I have been outa reversing and developing for a while and have lost my touch(tbh i didnt have much experience about vm game script system when i worked on project either)
To quickly discribe it, the GSC VM is actually 2 VMs, one for the client (CSC) and one for the server (GSC), the server one is handling how the gameplay is, the client one the FXs.
It's simple single-threaded script VMs in a C style able to call c++ functions from the game.
The scripts are first loaded and linked by the game when a map is started. During this linking process the game will replace the function references (or imports) with pointers to the functions so the game don't have to search for them at runtime.
It is done inside
int GscObjResolve(scriptInstance_t, GSC_OBJ*); // 0x2746A30
with calls to: (Scr is server and CScr is client)
typedef void (*BuiltinFunction)(scriptInstance_t inst); // inst = 0 : GSC / inst = 1 : CSC
BuiltinFunction CScr_GetFunction(uint canonId, int *type, int *min_args, int *max_args); // 0x1F13140
BuiltinFunction CScr_GetMethod(uint canonId, int *type, int *min_args, int *max_args); // 0x1F13650
BuiltinFunction Scr_GetFunction(uint canonId, int *type, int *min_args, int *max_args); // 0x33AF840
BuiltinFunction Scr_GetMethod(uint canonId, int *type, int *min_args, int *max_args); // 0x33AFC20
These functions are the ones with a detour, in this PR what I did is to put a base to inject our own functions/methods, it's just checking if the returned function is null, if it's the case I added a code to check inside a custom list of functions (custom_functions_gsc for GSC and custom_functions_csc for CSC) and to return our own function if it is asked.
void* func = scr_get_function.invoke<void*>(name, type, min_args, max_args);
if (func)
{
return func;
}
// ...
auto f = std::find_if(std::begin(custom_functions_gsc), std::end(custom_functions_gsc), [name](const game::BO4_BuiltinFunctionDef& func) { return func.canonId == name; });
if (f != std::end(custom_functions_gsc))
{
*type = f->type && !enable_dev_func;
*min_args = f->min_args;
*max_args = f->max_args;
return f->actionFunc;
}
return nullptr;
Like that we can implement custom functions and use them in a custom script.
Inside the game, you have normal functions, but also dev functions, these functions are usually nulled, (you have list here, type=1 = dev funcs) but some are still implemented, the only problem is, the game doesn't accept to link a function if *type is set to 1 by GetFunction or GetMethod and crash with a linking error. (1670707254)
What I've added in the detours and in the config is the gsc.dev_funcs
boolean, if it is set to true, the client will set the type to normal every time and allow the call to dev functions. With a similar code if we want to implement custom dev functions.
Bod on Discord was asking for a small hud to do a zombies counter, so in my laziness I implemented some GSC custom functions to config basic text HUDs in the renderer scheduler. Even if the best would obviously be some LUI menu.
To conclude it's mostly useless things, except for when someone will add a code to load custom scripts or is using a script injector.
Hello,
This pull request is adding a component and a config related to the GSC VMs.
It adds the config
{ "gsc" : { "dev_funcs" : false } }
to enable dev functions. Most of them are nulled and useless (search for type = 1 in funcs.csv), but some are still interesting likeAssert(val, msg)
- Basic assertAssertMsg(msg)
- Display an assert error messageErrorMsg(msg)
- Display an error messageMakeLocalizedString(key)
- Translate the key and return a stringExample of
AssertMsg("hello world")
:I've also add code to display the GSC errors in the logs. Except rare cases with Treyarch's code or bad script modders, it won't write anything in the logs for most of the users.
Then I've created few GSC/CSC functions to have a basic HUD, all with the prefix
Shield
:A hud element is a text on the screen in game, example with a basic zombies counter
the aligns and anchors are based with these values:
The anchor is from which side of the screen the (x,y) are relative to and the align is written at this location.
Knowing no easily available CSC injector is available, the custom functions are available in both GSC and CSC, but the GSC functions are only working for the host side.