Member
|
01-30-2018
, 17:12
Re: [DHooks] IGameMovement Help (unexposed interfaces)
|
#5
|
Thanks a lot for the help boys
It worked after I changed the library from engine to server.
Quote:
If you see just "@g_pGameMovement" in gamedata, you only know it's a symbol in a binary. It's a pretty easy guess that it's a global variable that's a pointer to something based on the name. A "member pointer variable" sounds like maybe you mean "a member of a class that's a pointer" or "a pointer to a member of a class" which are both wrong.
|
Yeah, a global ptr var is what I meant there, my bad. Confused the prefix, thought it was m_
Anyway, I got ProcessMovement to work. However, the callbacks for AirMove & AirAccelerate don't seem to get called using the offsets I've set above. I've tried increasing and decreasing the offsets to see if any work. The server crashed when I did that. I've tried changing the hooks from pre to post - still no luck. Does any of you know what the problem could be? Here's the script as it is right now:
PHP Code:
/* Headers */
#include <sourcemod>
#include <sdktools>
#include <dhooks>
/* Compiler options */
#pragma newdecls required // Use the new syntax
#pragma semicolon 1 // Let me know if I miss a semicolon
/* Preprocessor directives */
#define PLUGIN_VERSION "1.0.0"
/* Global variables */
// CCSGameMovement::ProcessMovement(CBasePlayer *,CMoveData *)
Handle g_hProcessMovement;
// CGameMovement::AirAccelerate(Vector &,float,float)
Handle g_hAirAccelerate;
// CCSGameMovement::AirMove(void)
Handle g_hAirMove;
// CCSGameMovement::OnJump(float)
Handle g_hOnJump;
public void OnPluginStart()
{
Handle gameconf = LoadGameConfigFile("gamemove.games");
if ( gameconf == null )
SetFailState("Why you no has gamedata?");
StartPrepSDKCall(SDKCall_Static);
if ( !PrepSDKCall_SetFromConf(gameconf, SDKConf_Signature, "CreateInterface") )
{
SetFailState("Failed to get CreateInterface");
delete gameconf;
}
PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
char iface[32];
if ( !GameConfGetKeyValue(gameconf, "IGameMovement", iface, sizeof(iface)) )
{
SetFailState("Failed to get interface name");
delete gameconf;
}
Handle call = EndPrepSDKCall();
Address addr = SDKCall(call, iface, 0);
delete call;
if ( !addr )
{
SetFailState("Failed to get IGameMovement ptr");
}
int offset = GameConfGetOffset(gameconf, "ProcessMovement");
if (offset == -1)
SetFailState("Couldn't find offset for ProcessMovement");
g_hProcessMovement = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, Hook_ProcessMovement);
DHookAddParam(g_hProcessMovement, HookParamType_CBaseEntity);
DHookAddParam(g_hProcessMovement, HookParamType_ObjectPtr);
DHookRaw(g_hProcessMovement, false, addr);
offset = GameConfGetOffset(gameconf, "AirAccelerate");
if (offset == -1)
SetFailState("Couldn't find offset for AirAccelerate");
g_hAirAccelerate = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, Hook_AirAccelerate);
DHookAddParam(g_hAirAccelerate, HookParamType_Object, 4 * 3, DHookPass_ByRef); // Vector& wishdir
DHookAddParam(g_hAirAccelerate, HookParamType_Float); // float wishspeed
DHookAddParam(g_hAirAccelerate, HookParamType_Float); // float accel
DHookRaw(g_hAirAccelerate, false, addr);
offset = GameConfGetOffset(gameconf, "AirMove");
if (offset == -1)
SetFailState("Couldn't find offset for AirMove");
g_hAirMove = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, Hook_AirMove);
DHookRaw(g_hAirMove, false, addr);
offset = GameConfGetOffset(gameconf, "OnJump");
if (offset == -1)
SetFailState("Couldn't find offset for OnJump");
g_hOnJump = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, Hook_OnJump);
DHookAddParam(g_hOnJump, HookParamType_Float); // float fImpulse
//DHookRaw(g_hOnJump, false, addr);
delete gameconf;
}
public MRESReturn Hook_OnJump(Handle hParams)
{
PrintToChatAll("OnJump");
return MRES_Ignored;
}
public MRESReturn Hook_AirMove(Handle hParams)
{
PrintToChatAll("AirMove");
return MRES_Ignored;
}
public MRESReturn Hook_AirAccelerate(Handle hParams)
{
PrintToChatAll("AirAccelerate");
return MRES_Ignored;
}
public MRESReturn Hook_ProcessMovement(Handle hParams)
{
int client = DHookGetParam(hParams, 1);
// m_bFirstRunOfFunctions & m_bGameCodeMovedPlayer bit field
//int m_bFirstRunOfFunctions = DHookGetParamObjectPtrVar(hParams, 2, 0, ObjectValueType_Int); // or Bool
//int m_nPlayerHandle = DHookGetParamObjectPtrVar(hParams, 2, 4, ObjectValueType_Ehandle);
//int m_nImpulseCommand = DHookGetParamObjectPtrVar(hParams, 2, 8, ObjectValueType_Int);
//float m_vecViewAngles[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 12, ObjectValueType_Vector, m_vecViewAngles);
//float m_vecAbsViewAngles[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 24, ObjectValueType_Vector, m_vecAbsViewAngles);
//int m_nButtons = DHookGetParamObjectPtrVar(hParams, 2, 36, ObjectValueType_Int);
//int m_nOldButtons = DHookGetParamObjectPtrVar(hParams, 2, 40, ObjectValueType_Int);
//float m_flForwardMove = DHookGetParamObjectPtrVar(hParams, 2, 44, ObjectValueType_Float);
//float m_flSideMove = DHookGetParamObjectPtrVar(hParams, 2, 48, ObjectValueType_Float);
//float m_flUpMove = DHookGetParamObjectPtrVar(hParams, 2, 52, ObjectValueType_Float);
//float m_flMaxSpeed = DHookGetParamObjectPtrVar(hParams, 2, 56, ObjectValueType_Float);
//float m_flClientMaxSpeed = DHookGetParamObjectPtrVar(hParams, 2, 60, ObjectValueType_Float);
//float m_vecVelocity[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 64, ObjectValueType_Vector, m_vecVelocity);
//float m_vecAngles[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 76, ObjectValueType_Vector, m_vecAngles);
//float m_vecOldAngles[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 88, ObjectValueType_Vector, m_vecAngles);
//float m_outStepHeight = DHookGetParamObjectPtrVar(hParams, 2, 100, ObjectValueType_Float);
//float m_outWishVel[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 104, ObjectValueType_Vector, m_outWishVel);
//float m_outJumpVel[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 116, ObjectValueType_Vector, m_outJumpVel);
//float m_vecConstraintCenter[3];
//DHookGetParamObjectPtrVarVector(hParams, 2, 128, ObjectValueType_Vector, m_vecConstraintCenter);
//float m_flConstraintRadius = DHookGetParamObjectPtrVar(hParams, 2, 140, ObjectValueType_Float);
//float m_flConstraintWidth = DHookGetParamObjectPtrVar(hParams, 2, 144, ObjectValueType_Float);
//float m_flConstraintSpeedFactor = DHookGetParamObjectPtrVar(hParams, 2, 148, ObjectValueType_Float);
float m_vecAbsOrigin[3];
DHookGetParamObjectPtrVarVector(hParams, 2, 152, ObjectValueType_Vector, m_vecAbsOrigin);
PrintHintText(client, "ProcessMovement\n \n"
//... "m_bFirstRunOfFunctions: %d\n"
//... "m_nPlayerHandle: %d\n"
//... "m_nImpulseCommand: %d\n"
//... "m_vecViewAngles: %.1f %.1f %.1f\n"
//... "m_vecAbsViewAngles: %.1f %.1f %.1f\n"
//... "m_nButtons: %d\n"
//... "m_nOldButtons: %d\n"
//... "m_flForwardMove: %.2f\n"
//... "m_flSideMove: %.2f\n"
//... "m_flUpMove: %.2f\n"
//... "m_flMaxSpeed: %.2f\n"
//... "m_flClientMaxSpeed: %.2f\n"
//... "m_vecVelocity: %.1f %.1f %.1f\n"
//... "m_vecAngles: %.1f %.1f %.1f\n"
//... "m_vecOldAngles: %.1f %.1f %.1f\n"
//... "m_outStepHeight: %.2f\n"
//... "m_outWishVel: %.1f %.1f %.1f\n"
//... "m_outJumpVel: %.1f %.1f %.1f\n"
//... "m_vecConstraintCenter: %.1f %.1f %.1f\n"
//... "m_flConstraintRadius: %.2f\n"
//... "m_flConstraintWidth: %.2f\n"
//... "m_flConstraintSpeedFactor: %.2f\n"
... "m_vecAbsOrigin: %.1f %.1f %.1f\n",
//m_bFirstRunOfFunctions,
//m_nPlayerHandle,
//m_nImpulseCommand,
//m_vecViewAngles[0], m_vecViewAngles[1], m_vecViewAngles[2],
//m_vecAbsViewAngles[0], m_vecAbsViewAngles[1], m_vecAbsViewAngles[2],
//m_nButtons,
//m_nOldButtons,
//m_flForwardMove,
//m_flSideMove,
//m_flUpMove,
//m_flMaxSpeed,
//m_flClientMaxSpeed,
//m_vecVelocity[0], m_vecVelocity[1], m_vecVelocity[2]
//m_vecAngles[0], m_vecAngles[1], m_vecAngles[2],
//m_vecOldAngles[0], m_vecOldAngles[1], m_vecOldAngles[2],
//m_outStepHeight,
//m_outWishVel[0], m_outWishVel[1], m_outWishVel[2],
//m_outJumpVel[0], m_outJumpVel[1], m_outJumpVel[2],
//m_vecConstraintCenter[0], m_vecConstraintCenter[1], m_vecConstraintCenter[2],
//m_flConstraintRadius,
//m_flConstraintWidth,
//m_flConstraintSpeedFactor,
m_vecAbsOrigin[0], m_vecAbsOrigin[1], m_vecAbsOrigin[2]
);
return MRES_Ignored;
}
Also, OnJump seems to crash the server for whatever reason too. That's why I've commented it out. Any ideas why this one doesn't work as well?
Quote:
If you're looking up a function, you can use a signature made up of the instructions for that function. A global variable is just going to be sitting off in space somewhere, probably with other globals around it. There's nothing to directly search for. You instead will have to find somewhere it's used in a function, then write some code/gamedata to pull out the address from the code that uses it.
|
I had a look at hmmmmm's example code and I think I understand the concept better now. I have a question. Suppose you have the following function and you're trying to access g_pGameMovement:
Code:
void foo(int param)
{
doSomething(param);
int temp;
g_pGameMovement = nullptr; // how many bytes should you offset away from foo?
}
How do you know how many bytes to offset away from foo in order to reach g_pGameMovement? I assume you'd have to know how cpp works internally and how it lays out data in memory. Are there any rules one needs to follow? Perhaps find the correct "read" value by trial and error? hmmmmm, how did you find out you had to offset 9 bytes away from CPhysicsPushedEntities::SpeculativelyCheckPus h for ex.?
Quote:
I'm surprised you're going this far inside a source mod plugin, most people at this point would switch to a c++ plugin project.
|
Quote:
But if you're doing a big project you should probably be doing this in an extension instead. I don't think sourcemod plugins are built for this type of thing, and it can get really messy.
|
I'm not working on anything huge in particular. I'm curious about how certain things work under the hood. I also don't feel very confident I could write extensions. I might look up the tutorials and try something out in the future, though.
Once again, thanks a lot for the replies!
|
|