Hooking FireBullets

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

Hooking FireBullets

Postby VinciT » Wed May 04, 2016 4:38 pm

Since HL2DM doesn't have the 'weapon_fire' event, hooking FireBullets seemed like the way to go.
Here's the offset:

Code: Select all

#CHL2MP_Player::FireBullets(FireBulletsInfo_t const&)
[[fire_bullets]]
   offset_linux = 113
   offset_windows = 112
   arguments = POINTER
   return_type = INT
And here's the code:

Syntax: Select all

from memory import make_object
from players.entity import Player
from entities.hooks import EntityPreHook, EntityCondition

@EntityPreHook(EntityCondition.is_player, 'fire_bullets')
def fire_bullets_hook(args):
player = make_object(Player, args[0])

# FireBulletsInfo??
info = make_object(????, args[1])
The hook works, I've tested it by adding print(), but I have no idea how to handle the FireBulletsInfo that's passed to the FireBullets hook.

Also, how can I add virtual offsets outside of core data files?
At the moment I'm adding the offsets into the core SP data files (source-python/data/source-python/entities/orangebox/hl2mp in this case), so every time there's an update, I have to add them again.
Predz
Senior Member
Posts: 158
Joined: Wed Aug 08, 2012 9:05 pm
Location: Bristol, United Kingdom

Re: Hooking FireBullets

Postby Predz » Thu May 05, 2016 7:30 am

Hey, I think there is a way to achieve this using the memory module to retrieve data from the pointer supplied. I am unsure on how to do this specifically using the memory module but hopefully I can help by proving the data inside the pointer.

If I remember correctly I saw someone using offsets to pull data out of Bot and Player pointers.

https://developer.valvesoftware.com/wik ... letsInfo_t

https://github.com/ValveSoftware/source ... 7.cpp#L130
User avatar
Ayuto
Project Leader
Posts: 2195
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Hooking FireBullets

Postby Ayuto » Fri May 06, 2016 7:01 pm

You might want to hook TE_HL2MPFireBullets. Then you don't even have to access the FireBulletsInfo_t struct.

However, this is a more advanced example about how to reconstruct classes with Source.Python.

Syntax: Select all

from path import Path

import memory

from memory.manager import CustomType
from memory.manager import TypeManager
from memory.manager import Type

from entities.hooks import EntityPreHook
from entities.hooks import EntityCondition

from players.entity import Player

manager = TypeManager()

CBaseEntity = manager.create_type_from_file(
'CBaseEntity', Path(__file__).parent / 'CBaseEntity.ini')

# You could also reconstruct the class just like the CBaseEntity class with
# create_type_from_file.
class FireBulletsInfo_t(CustomType, metaclass=manager):
# Reconstructed class based on the SDK. I haven't checked if the offsets
# are correct
"""
int m_iShots;
Vector m_vecSrc;
Vector m_vecDirShooting;
Vector m_vecSpread;
float m_flDistance;
int m_iAmmoType;
int m_iTracerFreq;
int m_iDamage;
int m_iPlayerDamage; // Damage to be used instead of m_iDamage if we hit a player
int m_nFlags; // See FireBulletsFlags_t
float m_flDamageForceScale;
CBaseEntity *m_pAttacker;
CBaseEntity *m_pAdditionalIgnoreEnt;
bool m_bPrimaryAttack;
"""
shots = manager.instance_attribute(Type.INT, 0)
src = manager.instance_attribute('Vector', 4)
dir_shooting = manager.instance_attribute('Vector', 16)
vec_spread = manager.instance_attribute('Vector', 28)
distance = manager.instance_attribute(Type.FLOAT, 40)
ammo_type = manager.instance_attribute(Type.INT, 44)
tracer_freq = manager.instance_attribute(Type.INT, 48)
damage = manager.instance_attribute(Type.INT, 52)
player_damage = manager.instance_attribute(Type.INT, 56)
flags = manager.instance_attribute(Type.INT, 60)
damage_force_scale = manager.instance_attribute(Type.FLOAT, 64)
attacker = manager.pointer_attribute('CBaseEntity', 68)
additional_ignore_ent = manager.pointer_attribute('CBaseEntity', 72)
primary_attack = manager.instance_attribute(Type.BOOL, 76)

@EntityPreHook(
EntityCondition.is_player,
lambda entity: memory.make_object(CBaseEntity, entity.pointer).fire_bullets)
def pre_fire_bullets(args):
player = memory.make_object(Player, args[0])
info = memory.make_object(FireBulletsInfo_t, args[1])
print('damage = {}'.format(info.damage))

Code: Select all

# ../addons/source-python/plugins/<your plugin>/CBaseEntity.ini

[virtual_function]
    # CBaseEntity::FireBullets(FireBulletsInfo_t  const&)
    [[fire_bullets]]
       offset_linux = 113
       offset_windows = 112
       arguments = POINTER
       # FireBullets does not have a return type!
User avatar
VinciT
Senior Member
Posts: 331
Joined: Thu Dec 18, 2014 2:41 am

Re: Hooking FireBullets

Postby VinciT » Thu May 12, 2016 6:24 pm

Thank you so much Ayuto. Do you happen to know the offset for TE_HL2MPFireBullets?
User avatar
Ayuto
Project Leader
Posts: 2195
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Hooking FireBullets

Postby Ayuto » Thu May 12, 2016 7:52 pm

It's not a virtual function, so you will need the symbol if you are on Linux or the signature if you are on Windows.

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 54 guests