Page 1 of 1

Getting the name of a game event in PostHook of firing an event?

Posted: Sat Jul 25, 2015 1:18 pm
by Mahi
I'm trying to fire my own game event listeners after all the other listeners have been called. I'm using PostHook for this purpose, here's my code:

Syntax: Select all

FIRE_EVENT_FUNC = get_object_pointer(game_event_manager).make_virtual_function(
7 if PLATFORM == 'windows' else 8,
Convention.THISCALL,
(DataType.POINTER, DataType.POINTER, DataType.BOOL),
DataType.BOOL
)

@PostHook(FIRE_EVENT_FUNC)
def post_fire_event(args, return_value):
game_event = make_object(GameEvent, args[1])
name = game_event.get_name()
if name == 'player_death':
post_player_death(game_event)
elif name == 'player_disconnect':
post_player_disconnect(game_event)
I'm getting this error:

Code: Select all

[SP] Caught an Exception:
Traceback (most recent call last):
  File '..\addons\source-python\packages\custom\easyplayer.py', line 64, in post
_fire_event
    game_event = make_object(GameEvent, args[1])

RuntimeError: Access violation - no RTTI data!
Apparently this is because FireEvent function deletes the IGameEvent pointer (thanks Ayuto), and thus I can't get the event's name.

Any fix for this, or a work around to post-fire my own game event listeners?

Posted: Sat Jul 25, 2015 4:36 pm
by L'In20Cible

Syntax: Select all

# ../testing/testing.py

# ============================================================================
# >> IMPORTS
# ============================================================================
# Source.Python Imports
# Core
from core import PLATFORM
# Events
from events import GameEvent
from events.manager import game_event_manager
# Memory
from memory import Convention
from memory import DataType
from memory import get_object_pointer
from memory import make_object
from memory.hooks import PostHook
from memory.hooks import PreHook


# ============================================================================
# >> GLOBAL VARIABLES
# ============================================================================
# Get the IGameEventManager::FireEvent function...
FIRE_EVENT_FUNC = get_object_pointer(game_event_manager).make_virtual_function(
7 if PLATFORM == 'windows' else 8,
Convention.THISCALL,
(DataType.POINTER, DataType.POINTER, DataType.BOOL),
DataType.BOOL
)

# Get a dictionary to store fired event names...
game_event_names = dict()


# ============================================================================
# >> HOOK CALLBACKS
# ============================================================================
@PreHook(FIRE_EVENT_FUNC)
def pre_fire_event(args):
"""Called every times the game fires an event."""
# Get the GameEvent instance...
game_event = make_object(GameEvent, args[1])

# Store the name of the fired event...
game_event_names[args[1].address] = game_event.get_name()


@PostHook(FIRE_EVENT_FUNC)
def post_fire_event(args, return_value):
"""Called every times the game fires an event."""
# Get the GameEvent instance...
game_event_name = game_event_names[args[1].address]

# Print the name...
print(game_event_name)

# Delete the stored pointer...
del game_event_names[args[1].address]