Calling virtual function CBaseTrigger::IsTouching?

Please post any questions about developing your plugin here. Please use the search function before posting!
inf
Junior Member
Posts: 20
Joined: Mon Aug 07, 2017 2:46 am

Calling virtual function CBaseTrigger::IsTouching?

Postby inf » Wed Aug 23, 2017 9:54 pm

I wish to call this function: https://github.com/ValveSoftware/source-sdk-2013/blob/master/sp/src/game/server/triggers.cpp#L539. I know it is possible to call virtual functions with the memory module, but I am unsure where to find the offsets for this particular function, as well as how to use the memory module to call this function in my python code. Hooking the trigger's OnStartTouch output is not enough in my case, I need to be able to test if the trigger is touching an entity at a specific tick. If anyone could do up a quick example or point me in the right direction I would really appreciate it!
Thanks
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby iPlayer » Wed Aug 23, 2017 10:49 pm

I'd avoid extra offsets. What you're trying to do can be implemented this way (untested):

Syntax: Select all

from entities.dictionary import EntityDictionary
from entities.entity import Entity
from entities.helpers import index_from_pointer
from entities.hooks import EntityCondition, EntityPostHook
from memory import make_object


TRIGGER_CLASSNAME = 'trigger_multiple'

_touching_entities = EntityDictionary(lambda index: list())


@EntityPostHook(EntityCondition.equals_entity_classname(TRIGGER_CLASSNAME), 'start_touch')
def post_start_touch(stack_data, ret_val):
trigger = make_object(Entity, stack_data[0])
if trigger.classname != TRIGGER_CLASSNAME:
return

_touching_entities[trigger.index].append(make_object(Entity, stack_data[1]))


@EntityPostHook(EntityCondition.equals_entity_classname(TRIGGER_CLASSNAME), 'end_touch')
def post_end_touch(stack_data, ret_val):
trigger = make_object(Entity, stack_data[0])
if trigger.classname != TRIGGER_CLASSNAME:
return

entity = make_object(Entity, stack_data[1])

# If hot plugged, the entity might have been touching the trigger without us knowing
if entity in _touching_entities[trigger.index]:
_touching_entities[trigger.index].remove(entity)


def is_touching(trigger, entity):
return entity in _touching_entities[trigger.index]


This is assuming that when the entity is removed, it will call end_touch of the trigger it is in - I don't know if it's true in fact.
Also I hope that start_touch and end_touch don't mess up its stack arguments while executing, otherwise you'll have to replace post-hooks with pre-hooks.

EDIT: It may occur that the engine will call StartTouch multiple times for a single entity (without calling EndTouch) - nobody guarantees the opposite. So you might need to check if the entity is in your list before appending to it.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby L'In20Cible » Thu Aug 24, 2017 1:10 am

Might be better to hook the On[Start/End]Touch outputs as hooking the raw methods ignores the PassesTriggerFilters call you might face issue as an entity might touch the trigger without activating it.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby iPlayer » Thu Aug 24, 2017 1:13 am

Yeah, that'll be better. The reason I went with function hooks is because I misread the code for StartTouch as if it was only firing the outputs for the first entity.

When in fact it does that for OnStartTouchAll output, but OnStartTouch output is always fired.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby Ayuto » Thu Aug 24, 2017 5:09 am

If you still want to call a virtual function, this might help you.
http://wiki.sourcepython.com/developing ... l-function

Edit: What game/os btw. (sp info)?
inf
Junior Member
Posts: 20
Joined: Mon Aug 07, 2017 2:46 am

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby inf » Thu Aug 24, 2017 5:31 pm

Ayuto wrote:If you still want to call a virtual function, this might help you.
http://wiki.sourcepython.com/developing ... l-function

Edit: What game/os btw. (sp info)?


CSGO, hoping to support windows and linux. I think iPlayer's solution will work fine as long as I use pre hooks. The reason I couldn't figure out how to create the virtual function after viewing that wiki article is because I have no idea how to get the offsets for that function I want to call, but if I can avoid having to keep the offsets updated that's even better.

Thanks for the help!
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby Predz » Fri Aug 25, 2017 8:34 am

I would normally use Asherkin's vtable dumper, however it is not functioning at the moment. Unsure why it isn't working tbh. I think Ayuto/L'Inc/Satoon have a way of dumping the vtables using python as well, but I don't have that code to hand.
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Calling virtual function CBaseTrigger::IsTouching?

Postby Ayuto » Fri Aug 25, 2017 8:56 am

It's not working for CS:GO, because they removed all symbols from the binaries last year. I have written some scripts to "migrate" an old IDA database (where all the symbols still existed) to a new database. It's not able to find all functions and it also provides wrong results, but it's an enormous help. I have shared that code some months ago, but it seems like the download link expired. I might publish that to Github this weekend.

Edit:

Here you are: https://github.com/Ayuto/mig_ida_dbs

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 22 guests