Still doing NextBot stuff.
This time I'm attempting to port over a Source:Python plugin called
PLRBots (a plugin that patches TFBots to support Payload Race) to an extension.
Right now I'm running into an issue attempting to call the original function from a hooked
CTFGameRules::GetPayloadToPush.
The author of the S:Py plugin had the same issue here.
Here's a disassembly view of the start of the function:
The demangled symbol suggests a sole integer argument, but the linked forum question (as well as the disassembly, I think) indicates that two arguments are provided (in addition to the implicit
this).
Here's a link to the S:Py equivalent of gamedata, the highlighted section suggesting it takes a pointer and an integer argument (a train watcher handle and a team respectively) on the Linux version.
I decided to hook it as a two-argument function. I seem to be able to correctly get the team argument (not sure if the handle is correct; I can work that out later), but passing the values into
DETOUR_MEMBER_CALL causes the server to eventually crash.
Here's an abbreviated portion of the code:
Code:
CDetour *dt_CTFGameRules_GetPayloadToPush;
DETOUR_DECL_MEMBER2(CTFGameRules_GetPayloadToPush, void, CBaseHandle*, handle, int, team) {
// prints "called CTFGameRules::GetPayloadToPush(3)", team index is correct
rootconsole->ConsolePrint("%s(%d)", "called CTFGameRules::GetPayloadToPush", team);
// crashes here sooner or later
DETOUR_MEMBER_CALL(CTFGameRules_GetPayloadToPush)(handle, team);
}
bool CTFBotExtension::SDK_OnLoad(char *error, size_t maxlen, bool late) {
if (!gameconfs->LoadGameConfigFile("tfbotext", &g_pGameConf, error, maxlen)) {
return false;
}
CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf);
dt_CTFGameRules_GetPayloadToPush = DETOUR_CREATE_MEMBER(CTFGameRules_GetPayloadToPush, "CTFGameRules::GetPayloadToPush(int)");
if (dt_CTFGameRules_GetPayloadToPush == nullptr) {
snprintf(error, maxlen, "%s", "Failed to load CTFGameRules::GetPayloadToPush detour");
return false;
}
dt_CTFGameRules_GetPayloadToPush->EnableDetour();
return true;
}
I've also tried detouring as a struct with similar results:
Code:
struct payloadargs_t {
CBaseHandle* handle;
int team;
};
DETOUR_DECL_MEMBER1(CTFGameRules_GetPayloadToPush, void, payloadargs_t, args) {
// prints "called CTFGameRules::GetPayloadToPush(3)", team index is correct
rootconsole->ConsolePrint("%s(%d)", "called CTFGameRules::GetPayloadToPush", args.team);
// crashes here sooner or later
DETOUR_MEMBER_CALL(CTFGameRules_GetPayloadToPush)(args);
}
Any ideas on how to call the function correctly, as well as suggestions on how the arguments should be set up?