From 2d636fc67707e1156ab15e877b96e78bdc7853a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordan=20Bri=C3=A8re?= Date: Mon, 7 Dec 2020 14:13:13 -0500 Subject: [PATCH 1/3] Added instance_property support to entity managers. --- .../entities/csgo/CBasePlayer.ini | 6 +++--- .../source-python/entities/csgo/CCSPlayer.ini | 14 ++++++------- .../entities/orangebox/cstrike/CCSPlayer.ini | 10 ++++----- .../source-python/entities/classes.py | 21 ++++++++++++++++++- .../source-python/entities/datamaps.py | 9 +++++++- 5 files changed, 43 insertions(+), 17 deletions(-) diff --git a/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini b/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini index 48eea053a..d763db74b 100755 --- a/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini +++ b/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini @@ -58,7 +58,7 @@ srv_check = False offset_windows = 372 -[instance_attribute] +[instance_property] # from memory import alloc @@ -74,8 +74,8 @@ srv_check = False # break # print('Offset of Player.assists is:', offset) [[assists]] - offset_windows = 4024 - offset_linux = 4048 + base = m_iFrags + offset = 4 type = INT diff --git a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini index 90dae8df8..490373522 100755 --- a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini @@ -57,21 +57,21 @@ srv_check = False on_rescue_zone_touch = OnRescueZoneTouch -[instance_attribute] +[instance_property] [[mvps]] - offset_windows = 12272 - offset_linux = 12296 + base = m_bIsHoldingLookAtWeapon + offset = 11 type = INT [[score]] - offset_windows = 12312 - offset_linux = 12336 + base = m_bIsHoldingLookAtWeapon + offset = 51 type = INT [[clan_tag]] - offset_windows = 10240 - offset_linux = 10264 + base = m_flGroundAccelLinearFracLastTime + offset = 140 type = STRING_ARRAY diff --git a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini index 233f4df1c..8d941300f 100644 --- a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini @@ -50,16 +50,16 @@ on_rescue_zone_touch = OnRescueZoneTouch -[instance_attribute] +[instance_property] [[mvps]] - offset_windows = 6384 - offset_linux = 6404 + base = cslocaldata.m_bPlayerDominatingMe.065 + offset = 4 type = INT [[clan_tag]] - offset_windows = 5628 - offset_linux = 5648 + base = m_flFlashDuration + offset = -28 type = STRING_ARRAY diff --git a/addons/source-python/packages/source-python/entities/classes.py b/addons/source-python/packages/source-python/entities/classes.py index 3ce665fc7..f8744249c 100644 --- a/addons/source-python/packages/source-python/entities/classes.py +++ b/addons/source-python/packages/source-python/entities/classes.py @@ -37,6 +37,7 @@ from memory import DataType from memory import get_object_pointer from memory import make_object +from memory.helpers import Key from memory.helpers import Type from memory.manager import CustomType from memory.manager import TypeManager @@ -332,6 +333,23 @@ def _get_server_class(self, class_name, datamap): instance, name, offset, property_contents, _supported_descriptor_types[desc.type]) + # Loop through all instance properties + for name, data in manager_contents.get( + 'instance_property', {}).items(): + + # Register the property + setattr(instance, name, getattr( + self, data.get('method', 'instance_attribute') + )( + Key.as_attribute_type(self, data['type']), + instance.properties[data['base']].offset + Key.as_int( + self, data.get( + 'offset_' + PLATFORM, data.get('offset', 0)) + ), + data.get('doc', None) + ) + ) + # Get a list of all properties for the current server class properties = list(instance.properties) @@ -485,7 +503,8 @@ def _add_property( value = self.instance_attribute(prop_type, offset) # Add the property to the properties dictionary - instance.properties[name] = EntityProperty(value, prop_type, networked) + instance.properties[name] = EntityProperty( + value, prop_type, networked, offset) # Is the property not a named property? if name not in contents: diff --git a/addons/source-python/packages/source-python/entities/datamaps.py b/addons/source-python/packages/source-python/entities/datamaps.py index f1a88b2ca..ec08df4c1 100644 --- a/addons/source-python/packages/source-python/entities/datamaps.py +++ b/addons/source-python/packages/source-python/entities/datamaps.py @@ -103,11 +103,12 @@ class TypeDescriptionFlags(IntFlag): class EntityProperty(object): """Class used to store property information for verification.""" - def __init__(self, instance, prop_type, networked): + def __init__(self, instance, prop_type, networked, offset): """Store the base attributes on instantiation.""" self._instance = instance self._prop_type = prop_type self._networked = networked + self._offset = offset @property def instance(self): @@ -123,3 +124,9 @@ def prop_type(self): def networked(self): """Return whether the property is networked.""" return self._networked + + @property + def offset(self): + """Returns the offset of the property.""" + return self._offset + From 3832b92c2da6b42586154f29ea87e622eef8fe2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordan=20Bri=C3=A8re?= Date: Mon, 7 Dec 2020 14:44:57 -0500 Subject: [PATCH 2/3] Added platform specific support for base properties. --- .../packages/source-python/entities/classes.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/source-python/packages/source-python/entities/classes.py b/addons/source-python/packages/source-python/entities/classes.py index f8744249c..e68012e76 100644 --- a/addons/source-python/packages/source-python/entities/classes.py +++ b/addons/source-python/packages/source-python/entities/classes.py @@ -342,10 +342,13 @@ def _get_server_class(self, class_name, datamap): self, data.get('method', 'instance_attribute') )( Key.as_attribute_type(self, data['type']), - instance.properties[data['base']].offset + Key.as_int( + instance.properties[ + data.get('base_' + PLATFORM, data.get('base')) + ].offset + Key.as_int( self, data.get( - 'offset_' + PLATFORM, data.get('offset', 0)) - ), + 'offset_' + PLATFORM, data.get('offset', 0) + ) + ), data.get('doc', None) ) ) From 668891b82203bfb3ecb30e70d80fcf8dc7935911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordan=20Bri=C3=A8re?= Date: Sun, 13 Dec 2020 21:49:53 -0500 Subject: [PATCH 3/3] Renamed instance_property to based_attribute. Polished the code. Added old offsets back to the data files. --- .../entities/csgo/CBasePlayer.ini | 10 +++- .../source-python/entities/csgo/CCSPlayer.ini | 21 ++++++++- .../entities/orangebox/cstrike/CCSPlayer.ini | 16 ++++++- .../source-python/entities/classes.py | 46 ++++++++++++------- 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini b/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini index d763db74b..b07f976a6 100755 --- a/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini +++ b/addons/source-python/data/source-python/entities/csgo/CBasePlayer.ini @@ -58,8 +58,16 @@ srv_check = False offset_windows = 372 -[instance_property] +# TODO: Remove when outdated. +[instance_attribute] + [[assists]] + offset_windows = 4024 + offset_linux = 4048 + type = INT + + +[based_attribute] # from memory import alloc # from players.entity import Player diff --git a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini index 490373522..f9454fa3d 100755 --- a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini @@ -57,7 +57,26 @@ srv_check = False on_rescue_zone_touch = OnRescueZoneTouch -[instance_property] +# TODO: Remove when outdated. +[instance_attribute] + + [[mvps]] + offset_windows = 12272 + offset_linux = 12296 + type = INT + + [[score]] + offset_windows = 12312 + offset_linux = 12336 + type = INT + + [[clan_tag]] + offset_windows = 10240 + offset_linux = 10264 + type = STRING_ARRAY + + +[based_attribute] [[mvps]] base = m_bIsHoldingLookAtWeapon diff --git a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini index 8d941300f..83d0e60cf 100644 --- a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini @@ -50,7 +50,21 @@ on_rescue_zone_touch = OnRescueZoneTouch -[instance_property] +# TODO: Remove when outdated. +[instance_attribute] + + [[mvps]] + offset_windows = 6384 + offset_linux = 6404 + type = INT + + [[clan_tag]] + offset_windows = 5628 + offset_linux = 5648 + type = STRING_ARRAY + + +[based_attribute] [[mvps]] base = cslocaldata.m_bPlayerDominatingMe.065 diff --git a/addons/source-python/packages/source-python/entities/classes.py b/addons/source-python/packages/source-python/entities/classes.py index e68012e76..9ee55c82e 100644 --- a/addons/source-python/packages/source-python/entities/classes.py +++ b/addons/source-python/packages/source-python/entities/classes.py @@ -333,26 +333,38 @@ def _get_server_class(self, class_name, datamap): instance, name, offset, property_contents, _supported_descriptor_types[desc.type]) - # Loop through all instance properties - for name, data in manager_contents.get( - 'instance_property', {}).items(): - - # Register the property - setattr(instance, name, getattr( - self, data.get('method', 'instance_attribute') - )( - Key.as_attribute_type(self, data['type']), - instance.properties[ - data.get('base_' + PLATFORM, data.get('base')) - ].offset + Key.as_int( - self, data.get( - 'offset_' + PLATFORM, data.get('offset', 0) - ) - ), - data.get('doc', None) + # Loop through all based attributes + for name, data in manager_contents.get('based_attribute', {}).items(): + + # Resolve the method to register this attribute + method = getattr(self, data.get('method', 'instance_attribute')) + + # Resolve the offset of this attribute + offset = Key.as_int( + self, + data.get('offset_' + PLATFORM, data.get('offset', 0)) + ) + + # Resolve the base offset of this attribute + base = data.get('base_' + PLATFORM, data.get('base')) + try: + offset += instance.properties[base].offset + except KeyError: + raise NameError( + f'"{base}" is not a valid property ' + + f'for attribute "{class_name}.{name}".' ) + + # Generate the attribute + attribute = method( + Key.as_attribute_type(self, data['type']), + offset, + data.get('doc') ) + # Assign the attribute to the instance + setattr(instance, name, attribute) + # Get a list of all properties for the current server class properties = list(instance.properties)