TF2 Conditions

Please post any questions about developing your plugin here. Please use the search function before posting!
ghetto_life
Junior Member
Posts: 15
Joined: Fri Aug 26, 2022 11:06 pm

TF2 Conditions

Postby ghetto_life » Wed Aug 31, 2022 7:26 pm

Hi!
There are TF2_AddCondition and TF2_RemoveCondition functions in sourcemod.
How to make similar on SP? (Or call them via sourcemod)
cssbestrpg
Senior Member
Posts: 287
Joined: Sun May 17, 2020 7:56 am
Location: Finland
Contact:

Re: TF2 Conditions

Postby cssbestrpg » Sat Sep 03, 2022 12:00 pm

I don't think it can call via sourcemod, since Source.Python and sourcemod are different plugin.
Unfortunaly i don't have any clue about those 2 functions how to call them
ghetto_life
Junior Member
Posts: 15
Joined: Fri Aug 26, 2022 11:06 pm

Re: TF2 Conditions

Postby ghetto_life » Sun Sep 04, 2022 1:10 pm

I tried create funcs with memory package. But this is more complicated than the other functions.
https://github.com/alliedmodders/source ... s.cpp#L220

Syntax: Select all

from memory import find_binary, Convention, DataType
from memory.helpers import Type

if PLATFORM == 'windows':
CONDITION_SIG = (
b'\x55\x8B\xEC\x83\xEC\x08\x56\x8B\xF1\x8B\x8E\x2A\x2A\x2A\x2A\x85\xC9\x0F\x84\x2A\x2A\x2A\x2A\x8B\x01\x8B',
b'\x55\x8B\xEC\x83\xEC\x08\x53\x8B\x5D\x08\x56\x53',
)
else:
CONDITION_SIG = (
'_ZN15CTFPlayerShared7AddCondE7ETFCondfP11CBaseEntity',
'_ZN15CTFPlayerShared10RemoveCondE7ETFCondb',
)
server = find_binary('tf/bin/server')
CONDITION_FUNCS = (
server[CONDITION_SIG[0]].make_function(
Convention.THISCALL, (Type.POINTER, Type.INT, Type.FLOAT, Type.POINTER), DataType.VOID
),
server[CONDITION_SIG[1]].make_function(
Convention.THISCALL, (Type.POINTER, Type.INT, Type.BOOL), DataType.VOID
),
)
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: TF2 Conditions

Postby Ayuto » Fri Sep 09, 2022 12:21 pm

cssbestrpg wrote:I don't think it can call via sourcemod, since Source.Python and sourcemod are different plugin.
Unfortunaly i don't have any clue about those 2 functions how to call them

I don't think it's impossible to call SM natives from Source.Python. A few years ago I made a proof of concept that makes it possible vice-versa (call a Source.Python function from Sourcemod):
viewtopic.php?f=10&t=1710

@ghetto_life:
Try this (untested):

Syntax: Select all

from memory import find_binary, Convention, DataType
from core import PLATFORM
from entities.props import ServerClass
from entities.helpers import pointer_from_index

def find_datatable_offset(table, name):
found, offset = _find_datatable_offset(table, name)
if not found:
raise ValueError(f'Data table {name} not found.')

return offset

def _find_datatable_offset(table, name, offset=0):
for prop in table:
next_table = prop.data_table
if next_table is None:
continue

if next_table.name == name:
return (True, prop.offset + offset)

found, actual_offset = _find_datatable_offset(next_table, name, prop.offset + offset)
if found:
return (True, actual_offset)

return (False, 0)


OFFSET_DT_TFPlayerShared = find_datatable_offset(
ServerClass.find_server_class('CTFPlayer').table,
'DT_TFPlayerShared')

if PLATFORM == 'windows':
AddCondition_Sig = b'\x55\x8B\xEC\x83\xEC\x08\x56\x8B\xF1\x8B\x8E\x2A\x2A\x2A\x2A\x85\xC9\x0F\x84\x2A\x2A\x2A\x2A\x8B\x01\x8B'
RemoveCondition_Sig = b'\x55\x8B\xEC\x83\xEC\x08\x53\x8B\x5D\x08\x56\x53'
else:
AddCondition_Sig = '_ZN15CTFPlayerShared7AddCondE7ETFCondfP11CBaseEntity'
RemoveCondition_Sig = '_ZN15CTFPlayerShared10RemoveCondE7ETFCondb'

server = find_binary('tf/bin/server')

# CTFPlayerShared::AddCond(ETFCond, float, CBaseEntity *)
AddCondition = server[AddCondition_Sig].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.INT, DataType.FLOAT, DataType.POINTER),
DataType.VOID)

# CTFPlayerShared::RemoveCond(ETFCond, bool)
RemoveCondition = server[RemoveCondition_Sig].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.INT, DataType.BOOL),
DataType.VOID)

def add_condition(player_index, condition, duration, inflictor_index=None):
AddCondition(
pointer_from_index(player_index) + OFFSET_DT_TFPlayerShared,
condition,
duration,
None if inflictor_index is None else pointer_from_index(inflictor_index))

def remove_condition(player_index, condition):
RemoveCondition(
pointer_from_index(player_index) + OFFSET_DT_TFPlayerShared,
condition,
True)
ghetto_life
Junior Member
Posts: 15
Joined: Fri Aug 26, 2022 11:06 pm

Re: TF2 Conditions

Postby ghetto_life » Fri Sep 09, 2022 1:23 pm

Cool! It works.
I just corrected the deletion method a little bit, it missed True.

Syntax: Select all

def remove_condition(player_index, condition):
RemoveCondition(pointer_from_index(player_index) + OFFSET_DT_TFPlayerShared, condition, True)


Thank you!
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: TF2 Conditions

Postby Ayuto » Fri Sep 09, 2022 1:37 pm

Good catch! I also updated the code above.

I'm glad it's working!

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 37 guests