Hey all,
So I was going through an old plugin of mine and I noticed in parts that I was using a pre-hook to hook into CBasePlayer::PlayerRunCommand and inject my own usercmds there. I kinda find that a little ugly, so I wanted to try and call PlayerRunCommand directly instead. However when looking at the signature for it, I noticed it also needs an IMoveHelper*... I don't really know what it does, but it seems to be a singleton object -- the SDK calls IMoveHelper::GetSingleton to get a handle to one. However, it's obviously not a virtual function, so I wouldn't know how to call it easily from SP. How can I do this?
Thanks.
Getting IMoveHelper instance?
Re: Getting IMoveHelper instance?
This is the header I found, for reference: https://github.com/ValveSoftware/source ... vehelper.h
This is what one of the SDK sample plugins does: https://github.com/ValveSoftware/source ... p.cpp#L203 Looks like IMoveHelper has separate server and client implementations which obfuscates things
This is what one of the SDK sample plugins does: https://github.com/ValveSoftware/source ... p.cpp#L203 Looks like IMoveHelper has separate server and client implementations which obfuscates things
Re: Getting IMoveHelper instance?
There are multiple ways to retrieve the IMoveHelper instance. A quick and dirty hack would be to hook PlayerRunCommand, store the IMoveHelper instance and then unhook it.
The nice and clean solution is to call MoveHelper() or directly rip out the singleton instance. MoveHelper() is defined in the server binary.
For which game/OS do you need this?
The nice and clean solution is to call MoveHelper() or directly rip out the singleton instance. MoveHelper() is defined in the server binary.
For which game/OS do you need this?
Re: Getting IMoveHelper instance?
This is for TF2. I'm developing on Linux currently (do I need to resort to signature scanning?)
I thought of hooking PlayerRunCommand, the only trouble is I can't guarantee that there will be any non-fake clients to run it in the first place... are there any other virtual methods that get the IMoveHelper instance?
I thought of hooking PlayerRunCommand, the only trouble is I can't guarantee that there will be any non-fake clients to run it in the first place... are there any other virtual methods that get the IMoveHelper instance?
Re: Getting IMoveHelper instance?
Since the binaries in TF2 contains symbols on Linux, you don't need signature scanning. You can simply do this:
Syntax: Select all
import memory
from memory import DataType
from memory import Convention
server = memory.find_binary('server')
MoveHelperServer = server['_Z16MoveHelperServerv'].make_function(
Convention.CDECL,
[],
DataType.POINTER)
ptr = MoveHelperServer()
Re: Getting IMoveHelper instance?
Oh cool! I thought they had starting stripping out the symbols, but maybe that was CS:GO... anyways thanks!
Re: Getting IMoveHelper instance?
Seem to have had no joy with this test plugin:
My fake client spawns correctly, but doesn't jump like I expected (no errors or anything, I presume everything goes right up until the actual run_command). Am I missing a step? (423 should be the offset for CBasePlayer::PlayerRunCommand, 14 for CMoveHelperServer::SetHost)
(Perhaps OnTick occurs too late in the game frame to do this? I dunno. I might try hooking PlayerRunCommand to see when it gets normally executed vs when I execute it)
Syntax: Select all
import engines.server
import entities.helpers
import memory
import listeners
import players
import players.entity
def load():
bot_ptr = entities.helpers.pointer_from_edict(engines.server.engine_server.create_fake_client("asdf"))
run_command = bot_ptr.make_virtual_function(423, memory.Convention.THISCALL,
(memory.DataType.POINTER, memory.DataType.POINTER, memory.DataType.POINTER),
memory.DataType.VOID)
bot = memory.make_object(players.entity.Player, bot_ptr)
bot.set_team(2)
bot.set_property_uchar("m_Shared.m_iDesiredPlayerClass", 1)
bot.spawn()
server = memory.find_binary("server")
move_helper = server["_Z16MoveHelperServerv"].make_function(memory.Convention.CDECL,
(),
memory.DataType.POINTER)()
set_host = move_helper.make_virtual_function(14, memory.Convention.THISCALL,
(memory.DataType.POINTER, memory.DataType.POINTER),
memory.DataType.VOID)
usercmd = players.UserCmd()
usercmd.buttons = 2
usercmd_ptr = memory.get_object_pointer(usercmd)
@listeners.OnTick
def tick():
set_host(move_helper, bot_ptr)
run_command(bot_ptr, usercmd_ptr, move_helper)
My fake client spawns correctly, but doesn't jump like I expected (no errors or anything, I presume everything goes right up until the actual run_command). Am I missing a step? (423 should be the offset for CBasePlayer::PlayerRunCommand, 14 for CMoveHelperServer::SetHost)
(Perhaps OnTick occurs too late in the game frame to do this? I dunno. I might try hooking PlayerRunCommand to see when it gets normally executed vs when I execute it)
Last edited by quartata on Mon Apr 23, 2018 2:30 am, edited 1 time in total.
Re: Getting IMoveHelper instance?
The plot thickens: I just noticed that the scout was actually facing a different direction than it should have... So I'm guessing it applied the view angle correctly, and just not the buttons... maybe I'm setting them wrong?
Re: Getting IMoveHelper instance?
Ahh, we might have an XY problem here. If you want to create your own bots, then you might want to take a look at this:
https://github.com/Ayuto/ReplayBot
The problem why the bot isn't jumping is probably, because you constantly send the jump key/action, which doesn't make a player jump all the time. The player will only jump once and only if he is able to jump at that specific point.
https://github.com/Ayuto/ReplayBot
The problem why the bot isn't jumping is probably, because you constantly send the jump key/action, which doesn't make a player jump all the time. The player will only jump once and only if he is able to jump at that specific point.
Re: Getting IMoveHelper instance?
Oh, right, because it'll be like it's held. I'll try it with alternating every tick instead
Re: Getting IMoveHelper instance?
Oh, huh... I hadn't seen BotController before, is that new? I'd definitely rather use that, if only so it'll work on Windows too. I'll give it a try.
Re: Getting IMoveHelper instance?
Got it working. You were right, I did need to press the button every other tick, so it wouldn't be held. Thank you.
Return to “Plugin Development Support”
Who is online
Users browsing this forum: No registered users and 105 guests