[HL2DM/ANY] Hooking VphysicsCollision

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

[HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Thu Oct 01, 2020 6:30 am

I'm working with a bunch of prop_physics entities and I'm trying to check when they hit the world. I settled for the CPhysicsProp::VPhysicsCollision() function, but I've no idea how to recreate the gamevcollisionevent_t struct. All 4 attributes are arrays/lists of 2 - how can I recreate those?

Syntax: Select all

# ../vphysics_collision/vphysics_collision.py

# Source.Python
from core import PLATFORM
from entities.entity import Entity
from memory import Convention, DataType
from memory.hooks import PreHook
from memory.manager import CustomType, TypeManager, Type


manager = TypeManager()


VPHYSICS_COLLISION_OFFSET = 161 if PLATFORM == 'windows' else 162


vphysics_collision = Entity.find('prop_physics').pointer.make_virtual_function(
VPHYSICS_COLLISION_OFFSET,
Convention.THISCALL,
(DataType.POINTER, DataType.INT, DataType.POINTER),
DataType.VOID
)


class GameVCollisionEvent(CustomType, metaclass=manager):
# No idea what Type to use.
pass


# void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
@PreHook(vphysics_collision)
def vphysics_collision_pre(stack_data):
print(stack_data)
ImageImageImageImageImage
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby L'In20Cible » Thu Oct 01, 2020 3:50 pm

User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Thu Oct 01, 2020 8:07 pm

Thank you! I managed to get the first three attributes working, but the last one (array of entity pointers) is giving me some trouble.
This is what I have so far:

Syntax: Select all

# ../vphysics_collision/vphysics_collision.py

# Source.Python
from core import PLATFORM
from entities.entity import Entity
from memory import Convention, DataType
from memory.hooks import PreHook
from memory.manager import CustomType, TypeManager, Type


manager = TypeManager()


VPHYSICS_COLLISION_OFFSET = 161 if PLATFORM == 'windows' else 162


vphysics_collision = Entity.find('prop_physics').pointer.make_virtual_function(
VPHYSICS_COLLISION_OFFSET,
Convention.THISCALL,
(DataType.POINTER, DataType.INT, DataType.POINTER),
DataType.VOID
)


class GameVCollisionEvent(CustomType, metaclass=manager):
"""Reconstructed 'gamevcollisionevent_t' struct from the engine."""
pre_velocity = manager.static_instance_array('Vector', 0, 2)
post_velocity = manager.static_instance_array('Vector', 24, 2)
pre_angular_velocity = manager.static_instance_array('Vector', 48, 2)
entity_pointers = manager.static_instance_array(Type.POINTER, 72, 2)


# void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
@PreHook(vphysics_collision)
def vphysics_collision_pre(stack_data):
index = stack_data[1]
event = GameVCollisionEvent._obj(stack_data[2])
entity = Entity._obj(event.entity_pointers[index])

print(entity.classname)

Code: Select all

[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\plugins\vphysics_collision\vphysics_collision.py", line 40, in vphysics_collision_pre
    entity = Entity._obj(event.entity_pointers[index])
  File "..\addons\source-python\packages\source-python\entities\_base.py", line 293, in _obj
    return cls(index_from_pointer(ptr))

ValueError: Conversion from "Pointer" (<_memory.Pointer object at 0x190C1A70>) to "Index" failed.
ImageImageImageImageImage
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby L'In20Cible » Fri Oct 02, 2020 3:18 am

Tried BaseEntity? It's possible that entity is simply not networked.
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Fri Oct 02, 2020 3:30 am

With BaseEntity I'm either getting:

Code: Select all

[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\plugins\vphysics_collision\vphysics_collision.py", line 41, in vphysics_collision_pre
    print(base_entity.classname)

AttributeError: 'NoneType' object has no attribute 'classname'
Or:

Code: Select all

[SP] Caught an Exception:
Traceback (most recent call last):
  File "..\addons\source-python\plugins\vphysics_collision\vphysics_collision.py", line 39, in vphysics_collision_pre
    base_entity = BaseEntity._obj(event.entity_pointers[index])

RuntimeError: Access violation - no RTTI data!
ImageImageImageImageImage
Jezza
Junior Member
Posts: 16
Joined: Tue Aug 28, 2012 5:52 pm

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby Jezza » Fri Oct 02, 2020 5:36 am

That's because your offsets are incorrect.

Syntax: Select all

class GameVCollisionEvent(CustomType, metaclass=manager):
manager.register_converter("BaseEntity", BaseEntity._obj)
pre_velocity = manager.static_instance_array("Vector", 32, 2, "Vector preVelocity[2]")
post_velocity = manager.static_instance_array("Vector", 56, 2, "Vector postVelocity[2]")
pre_angular_velocity = manager.static_instance_array("Vector", 80, 2, "AngularImpulse preAngularVelocity[2]")
p_entities = manager.static_pointer_array("BaseEntity", 104, 2, "CBaseEntity *pEntities[2]")
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Fri Oct 02, 2020 6:11 am

It works! Much appreciated Jezza. I'm assuming the offsets start at 32 because of the inherited vcollisionevent_t struct , am I correct?
ImageImageImageImageImage
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby Ayuto » Fri Oct 02, 2020 6:24 am

Exactly! Btw. I don't think you need to register a converter. IIRC, you have to use the C++ class name (CBaseEntity in that case).
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Fri Oct 02, 2020 6:42 am

Cool, I got one more question if you don't mind. :tongue:
Am I terrible at counting or should the starting offset be at 30?

Syntax: Select all

struct vcollisionevent_t
{
IPhysicsObject *pObjects[2]; // 0
int surfaceProps[2]; // 8
bool isCollision; // 16
bool isShadowCollision; // 17
float deltaCollisionTime; // 18

float collisionSpeed; // 22
IPhysicsCollisionData *pInternalData; // 26
};

Ayuto wrote:IIRC, you have to use the C++ class name (CBaseEntity in that case).
Had no idea about converters at all, but I'll probably stick to pointers or register an Entity converter and get that sweet performance from caching.


Edit: Never mind, it appears I'm terrible at counting. Where am I missing those 2 bytes? :confused:
ImageImageImageImageImage
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby L'In20Cible » Fri Oct 02, 2020 7:38 am

It's caused by the 32 bit alignment. Offsets are:

Syntax: Select all

struct vcollisionevent_t
{
IPhysicsObject *pObjects[2]; // 0
int surfaceProps[2]; // 8
bool isCollision; // 16
bool isShadowCollision; // 17
float deltaCollisionTime; // 20

float collisionSpeed; // 24
IPhysicsCollisionData *pInternalData; // 28
};
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Sat Oct 03, 2020 4:30 am

I see, thanks for the info. Guess I'll have to do some reading on memory/data alignment.
ImageImageImageImageImage
Jezza
Junior Member
Posts: 16
Joined: Tue Aug 28, 2012 5:52 pm

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby Jezza » Sat Oct 03, 2020 4:40 am

Ayuto wrote:Exactly! Btw. I don't think you need to register a converter. IIRC, you have to use the C++ class name (CBaseEntity in that case).

I forgot about that, and yes, it's cleaner that way.

VinciT wrote:Cool, I got one more question if you don't mind. :tongue:
Am I terrible at counting or should the starting offset be at 30?

In general, size of bool is 1. But as L'In20Cible wrote, compiler will add padding to improve performance.
In this case, at bool we count 16, 17 and add 2 bytes for padding, and we get an offset value of 32.
Jezza
Junior Member
Posts: 16
Joined: Tue Aug 28, 2012 5:52 pm

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby Jezza » Sat Oct 03, 2020 4:57 am

And using godbolt.org is an easy way to check.

Example: https://godbolt.org/z/4zn6rY
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: [HL2DM/ANY] Hooking VphysicsCollision

Postby VinciT » Sun Oct 04, 2020 11:09 am

Jezza wrote:In general, size of bool is 1. But as L'In20Cible wrote, compiler will add padding to improve performance.
In this case, at bool we count 16, 17 and add 2 bytes for padding, and we get an offset value of 32.
Thank you for the detailed explanation!

Jezza wrote:And using godbolt.org is an easy way to check.

Example: https://godbolt.org/z/4zn6rY
This is going to come in handy. :grin:
Thanks again for all the help guys!
ImageImageImageImageImage

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 34 guests