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
Calling virtual function CBaseTrigger::IsTouching?
Re: Calling virtual function CBaseTrigger::IsTouching?
I'd avoid extra offsets. What you're trying to do can be implemented this way (untested):
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.
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.

My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam
Hail, Companion. [...] Hands to yourself, sneak thief.

- L'In20Cible
- Project Leader
- Posts: 1535
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: Calling virtual function CBaseTrigger::IsTouching?
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.
Re: Calling virtual function CBaseTrigger::IsTouching?
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.
When in fact it does that for OnStartTouchAll output, but OnStartTouch output is always fired.

My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam
Hail, Companion. [...] Hands to yourself, sneak thief.

Re: Calling virtual function CBaseTrigger::IsTouching?
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)?
http://wiki.sourcepython.com/developing ... l-function
Edit: What game/os btw. (sp info)?
Re: Calling virtual function CBaseTrigger::IsTouching?
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!
Re: Calling virtual function CBaseTrigger::IsTouching?
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.
Re: Calling virtual function CBaseTrigger::IsTouching?
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
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 103 guests