Getting IMoveHelper instance?

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Getting IMoveHelper instance?

Postby quartata » Wed Apr 18, 2018 2:12 am

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.
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Wed Apr 18, 2018 4:40 pm

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
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Getting IMoveHelper instance?

Postby Ayuto » Thu Apr 19, 2018 5:35 pm

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?
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Fri Apr 20, 2018 11:39 pm

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?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Getting IMoveHelper instance?

Postby Ayuto » Sat Apr 21, 2018 10:12 am

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()
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Sun Apr 22, 2018 12:46 am

Oh cool! I thought they had starting stripping out the symbols, but maybe that was CS:GO... anyways thanks!
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Mon Apr 23, 2018 2:17 am

Seem to have had no joy with this test plugin:

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.
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Mon Apr 23, 2018 2:30 am

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?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Getting IMoveHelper instance?

Postby Ayuto » Mon Apr 23, 2018 6:47 pm

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.
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Mon Apr 23, 2018 8:34 pm

Oh, right, because it'll be like it's held. I'll try it with alternating every tick instead
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Mon Apr 23, 2018 9:07 pm

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.
User avatar
quartata
Member
Posts: 77
Joined: Wed Jun 22, 2016 11:49 pm

Re: Getting IMoveHelper instance?

Postby quartata » Tue Apr 24, 2018 12:20 am

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 40 guests