Hook AirAccelerate

Please post any questions about developing your plugin here. Please use the search function before posting!
InvisibleSoldiers
Senior Member
Posts: 114
Joined: Fri Mar 15, 2019 6:08 am

Hook AirAccelerate

Postby InvisibleSoldiers » Sun Dec 01, 2019 12:08 pm

I'm trying to get function parameters inside CGameMovement::AirAccelerate through @PreHook, the function itself hooks properly but getting parameters unclear.

CGameMovement::AirAccelerate( Vector& wishdir, float wishspeed, float accel ): https://github.com/ValveSoftware/source ... .cpp#L1707

Syntax: Select all

from memory import find_binary
from memory import Convention
from memory import DataType
from memory.hooks import PreHook


SERVER = find_binary('server')
AIRACCELERATE = SERVER['_ZN13CGameMovement13AirAccelerateER6Vectorff'].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
DataType.VOID
)

# ACCELERATE = SERVER['_ZN13CGameMovement10AccelerateER6Vectorff'].make_function(
# Convention.THISCALL,
# (DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
# DataType.VOID
#)

@PreHook(AIRACCELERATE)
def pre_hook_airaccelerate(stack_data):
print(stack_data[0])
print(stack_data[1])
print(stack_data[2])

stack_data[0] = _memory.Pointer (CGameMovement::AirAccelerate)
stack_data[1] = NaN
stack_data[2] = wishspeed (CGameMovement::AirAccelerate)

Why did 'wishspeed' and 'accel' switch index places and why is 'accel' NaN
Last edited by InvisibleSoldiers on Sun Dec 01, 2019 1:52 pm, edited 3 times in total.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Hook AirAccelerate

Postby L'In20Cible » Sun Dec 01, 2019 1:20 pm

Syntax: Select all

AIRACCELERATE = SERVER['_ZN13CGameMovement13AirAccelerateER6Vectorff'].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
DataType.VOID
)

Should be:

Syntax: Select all

AIRACCELERATE = SERVER['_ZN13CGameMovement13AirAccelerateER6Vectorff'].make_function(
Convention.THISCALL,
# this wishdir wishspeed accel
(DataType.POINTER, DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
DataType.VOID
)
InvisibleSoldiers
Senior Member
Posts: 114
Joined: Fri Mar 15, 2019 6:08 am

Re: Hook AirAccelerate

Postby InvisibleSoldiers » Sun Dec 01, 2019 1:25 pm

Edit
InvisibleSoldiers
Senior Member
Posts: 114
Joined: Fri Mar 15, 2019 6:08 am

Re: Hook AirAccelerate

Postby InvisibleSoldiers » Sun Dec 01, 2019 1:51 pm

L'In20Cible wrote:

Syntax: Select all

AIRACCELERATE = SERVER['_ZN13CGameMovement13AirAccelerateER6Vectorff'].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
DataType.VOID
)

Should be:

Syntax: Select all

AIRACCELERATE = SERVER['_ZN13CGameMovement13AirAccelerateER6Vectorff'].make_function(
Convention.THISCALL,
# this wishdir wishspeed accel
(DataType.POINTER, DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
DataType.VOID
)

I did it early but the error is still remaining because i guess Source.Python has a bag with AutoUnload hooks, need full server restart to load next version of the plugin, because 'sp plugin reload ' on existing plugin with the hook leads to some error and full server restart (maybe changelevel) is requred.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Hook AirAccelerate

Postby L'In20Cible » Sun Dec 01, 2019 2:12 pm

InvisibleSoldiers wrote:I did it early but the error is still remaining because i guess Source.Python has a bag with AutoUnload hooks, need full server restart to load next version of the plugin, because 'sp plugin reload ' on existing plugin with the hook leads to some error and full server restart (maybe changelevel) is requred.

Not sure what you mean by a bag with AutoUnload but, the fact you have to reboot your server is normal. When an address is hooked for the first time, a hook is installed that points to our internal handler and it is never uninstalled. When you unload your plugin, your callback is removed but the hook remains in place so if you want to change the prototype of that hook, you must indeed reboot your server.

EDIT: In fact, if you really wanted to you could call:

Syntax: Select all

AIRACCELERATE._delete_hook()


Before your @PreHook decorator and it would apply your changes. However, that method is private for a reason and you should not use it for a public plugin as it could cause conflict with other addons. Take for example the following scenario:

  • Source.Python installs a hook on SomeFunction().
  • SourceMod installs a hook on that same function.
  • Source.Python uninstalls its hook.
  • SourceMod attempts to call the original function, which would either crash or never forward to the real function as they are calling Source.Python's handler resulting into undefined behaviour.

Basically, once a hook have been installed it has to remain to preserve the calling chain, otherwise it would break the relation between everyone hooking the same addresses, etc. Now well, perhaps Source.Python could update the hook, but I believe this would be a waste of effort. I mean, a prototype should never change at run-time, so if you made a mistake then you must reboot.

Return to “Plugin Development Support”

Who is online

Users browsing this forum: Bing [Bot] and 36 guests