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 6737da37d..d2344a47c 100755 --- a/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/csgo/CCSPlayer.ini @@ -73,6 +73,7 @@ srv_check = False base = m_flGroundAccelLinearFracLastTime offset = 140 type = STRING_ARRAY + length = 16 [property] 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 old mode 100644 new mode 100755 index 83d0e60cf..f7904215b --- a/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini +++ b/addons/source-python/data/source-python/entities/orangebox/cstrike/CCSPlayer.ini @@ -62,6 +62,7 @@ offset_windows = 5628 offset_linux = 5648 type = STRING_ARRAY + length = 16 [based_attribute] @@ -75,6 +76,7 @@ base = m_flFlashDuration offset = -28 type = STRING_ARRAY + length = 16 [property] diff --git a/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini old mode 100644 new mode 100755 index f64a9af2f..06096d718 --- a/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/WeaponInfo.ini @@ -27,3 +27,4 @@ [[class_name]] type = STRING_ARRAY offset = 6 + length = 80 diff --git a/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini old mode 100644 new mode 100755 index a7d40e6f2..2c7cafe87 --- a/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/csgo/WeaponInfo.ini @@ -8,22 +8,27 @@ [[print_name]] type = STRING_ARRAY offset = 86 + length = 80 [[view_model_name]] type = STRING_ARRAY offset = 166 + length = 80 [[world_model_name]] type = STRING_ARRAY offset = 246 + length = 80 [[primary_ammo_type]] type = STRING_ARRAY offset = 326 + length = 32 [[animation_prefix]] type = STRING_ARRAY offset = 438 + length = 16 [[bucket]] type = INT @@ -72,14 +77,17 @@ [[secondary_ammo_type]] type = STRING_ARRAY offset = 496 + length = 32 [[ai_addon_base]] type = STRING_ARRAY offset = 528 + length = 80 [[ai_addon]] type = STRING_ARRAY offset = 608 + length = 80 [[primary_ammo_index]] type = INT @@ -180,6 +188,7 @@ [[heat_effect_name]] type = STRING_ARRAY offset = 2096 + length = 80 [[smoke_color]] type = Vector @@ -188,18 +197,22 @@ [[muzzle_flash_effect_1stperson]] type = STRING_ARRAY offset = 2188 + length = 80 [[muzzle_flash_effect_3rdperson]] type = STRING_ARRAY offset = 2268 + length = 80 [[eject_brass_effect]] type = STRING_ARRAY offset = 2348 + length = 80 [[tracer_effect]] type = STRING_ARRAY offset = 2428 + length = 80 [[tracer_frequency]] type = INT @@ -368,10 +381,12 @@ [[zoom_in_sound_name]] type = STRING_ARRAY offset = 3705 + length = 80 [[zoom_out_sound_name]] type = STRING_ARRAY offset = 3785 + length = 80 [[bot_audible_range]] type = FLOAT @@ -384,26 +399,32 @@ [[wrong_team_message]] type = STRING_ARRAY offset = 3873 + length = 32 [[player_animation_extension]] type = STRING_ARRAY offset = 3905 + length = 16 [[shield_view_model_name]] type = STRING_ARRAY offset = 3921 + length = 64 [[addon_model_name]] type = STRING_ARRAY offset = 3985 + length = 80 [[addon_location_name]] type = STRING_ARRAY offset = 4065 + length = 80 [[silencer_model_name]] type = STRING_ARRAY offset = 4145 + length = 80 [[addon_scale]] type = FLOAT diff --git a/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini old mode 100644 new mode 100755 index 62fa98efa..fd882d800 --- a/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/orangebox/WeaponInfo.ini @@ -8,14 +8,17 @@ [[print_name]] type = STRING_ARRAY offset = 86 + length = 80 [[world_model]] type = STRING_ARRAY offset = 166 + length = 80 [[animation_prefix]] type = STRING_ARRAY offset = 326 + length = 16 [[slot_index]] type = INT @@ -64,70 +67,87 @@ [[primary_ammo_name]] type = STRING_ARRAY offset = 384 + length = 32 [[secondary_ammo_name]] type = STRING_ARRAY offset = 416 + length = 32 [[empty_sound]] type = STRING_ARRAY offset = 448 + length = 80 [[single_sound]] type = STRING_ARRAY offset = 528 + length = 80 [[single_npc_sound]] type = STRING_ARRAY offset = 608 + length = 80 [[double_sound]] type = STRING_ARRAY offset = 688 + length = 80 [[double_npc_sound]] type = STRING_ARRAY offset = 768 + length = 80 [[burst_sound]] type = STRING_ARRAY offset = 848 + length = 80 [[reload_sound]] type = STRING_ARRAY offset = 928 + length = 80 [[reload_npc_sound]] type = STRING_ARRAY offset = 1008 + length = 80 [[melee_miss_sound]] type = STRING_ARRAY offset = 1088 + length = 80 [[melee_hit_sound]] type = STRING_ARRAY offset = 1168 + length = 80 [[melee_hit_world_sound]] type = STRING_ARRAY offset = 1248 + length = 80 [[special_sound_1]] type = STRING_ARRAY offset = 1328 + length = 80 [[special_sound_2]] type = STRING_ARRAY offset = 1408 + length = 80 [[special_sound_3]] type = STRING_ARRAY offset = 1488 + length = 80 [[taunt_sound]] type = STRING_ARRAY offset = 1568 + length = 80 [[primary_ammo_type]] type = INT @@ -196,3 +216,4 @@ [[ai_addon]] type = STRING_ARRAY offset = 1704 + length = 80 diff --git a/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini b/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini old mode 100644 new mode 100755 index 85f94022f..e3acb5d8a --- a/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini +++ b/addons/source-python/data/source-python/weapons/scripts/orangebox/cstrike/WeaponInfo.ini @@ -50,26 +50,32 @@ size = 2320 [[wrong_team_message]] type = STRING_ARRAY offset = 1817 + length = 32 [[player_animation_extension]] type = STRING_ARRAY offset = 1849 + length = 16 [[shield_view_model]] type = STRING_ARRAY offset = 1865 + length = 64 [[addon_model]] type = STRING_ARRAY offset = 1929 + length = 80 [[dropped_model]] type = STRING_ARRAY offset = 2009 + length = 80 [[silencer_model]] type = STRING_ARRAY offset = 2089 + length = 80 [[muzzle_flash_style_index]] type = INT diff --git a/addons/source-python/packages/source-python/entities/classes.py b/addons/source-python/packages/source-python/entities/classes.py index a8628a1d8..ef0a0b20b 100755 --- a/addons/source-python/packages/source-python/entities/classes.py +++ b/addons/source-python/packages/source-python/entities/classes.py @@ -359,7 +359,8 @@ def _get_server_class(self, class_name, datamap): attribute = method( Key.as_attribute_type(self, data['type']), offset, - data.get('doc') + data.get('doc'), + Key.as_int(self, data.get('length', 0)), ) # Assign the attribute to the instance diff --git a/addons/source-python/packages/source-python/memory/helpers.py b/addons/source-python/packages/source-python/memory/helpers.py index 4c0ba2177..d2367d377 100755 --- a/addons/source-python/packages/source-python/memory/helpers.py +++ b/addons/source-python/packages/source-python/memory/helpers.py @@ -79,7 +79,7 @@ class Key(object): # Attribute/array keys TYPE_NAME = 'type' - # Array keys + # Attribute(string length)/Array keys LENGTH = 'length' # Pointer keys diff --git a/addons/source-python/packages/source-python/memory/manager.py b/addons/source-python/packages/source-python/memory/manager.py index b09649420..a6d259e6c 100755 --- a/addons/source-python/packages/source-python/memory/manager.py +++ b/addons/source-python/packages/source-python/memory/manager.py @@ -368,7 +368,8 @@ def create_type_from_dict(self, type_name, raw_data, bases=(CustomType,)): ( (Key.TYPE_NAME, Key.as_attribute_type, NO_DEFAULT), (Key.OFFSET, Key.as_int, NO_DEFAULT), - (Key.DOC, Key.as_str, None) + (Key.DOC, Key.as_str, None), + (Key.LENGTH, Key.as_int, 0) ) ) @@ -434,7 +435,7 @@ def create_type_from_dict(self, type_name, raw_data, bases=(CustomType,)): # Now create and register the type return self(type_name, bases, cls_dict) - def instance_attribute(self, type_name, offset, doc=None): + def instance_attribute(self, type_name, offset, doc=None, length=0): """Create a wrapper for an instance attribute. Examples: @@ -467,11 +468,31 @@ def fset(ptr, value): # Handle native type else: - getattr(ptr, 'set_' + type_name)(value, offset) + # Handle string pointer type + if type_name == Type.STRING_POINTER: + string_pointer = ptr.set_string_pointer(value, offset) + if string_pointer: + string_pointer.auto_dealloc = True + + # Make sure the value will not deallocate as long as + # it is part of this object + ptr._pointer_values[offset] = string_pointer + + # Handle string array type + elif type_name == Type.STRING_ARRAY: + if length and len(value.encode()) >= length: + raise ValueError( + 'The string length exceeds ' + 'the limit "{0}".'.format(length-1)) + + ptr.set_string_array(value, offset) + + else: + getattr(ptr, 'set_' + type_name)(value, offset) return property(fget, fset, None, doc) - def pointer_attribute(self, type_name, offset, doc=None): + def pointer_attribute(self, type_name, offset, doc=None, length=0): """Create a wrapper for a pointer attribute. Examples: @@ -512,7 +533,12 @@ def fset(ptr, value): # Is there no space allocated? if not instance_ptr: # Allocate space for the value - instance_ptr = alloc(TYPE_SIZES[type_name.upper()]) + if type_name == Type.STRING_ARRAY: + size = length if length else len(value.encode()) + 1 + else: + size = TYPE_SIZES[type_name.upper()] + + instance_ptr = alloc(size) # Add the pointer to the set, so there will be a reference # until the instance gets deleted @@ -521,8 +547,29 @@ def fset(ptr, value): # Set the pointer ptr.set_pointer(instance_ptr, offset) - # Set the value - getattr(instance_ptr, 'set_' + type_name)(value) + # Handle string pointer type + if type_name == Type.STRING_POINTER: + string_pointer = instance_ptr.set_string_pointer( + value, offset) + if string_pointer: + string_pointer.auto_dealloc = True + + # Make sure the value will not deallocate as long as + # it is part of this object + ptr._pointer_values[offset] = string_pointer + + # Handle string array type + elif type_name == Type.STRING_ARRAY: + if length and len(value.encode()) >= length: + raise ValueError( + 'The string length exceeds ' + 'the limit "{0}".'.format(length-1)) + + instance_ptr.set_string_array(value, offset) + + else: + # Set the value + getattr(instance_ptr, 'set_' + type_name)(value) return property(fget, fset, None, doc) diff --git a/src/core/modules/memory/memory_pointer.cpp b/src/core/modules/memory/memory_pointer.cpp index d8ddc6a8a..3efa50be1 100755 --- a/src/core/modules/memory/memory_pointer.cpp +++ b/src/core/modules/memory/memory_pointer.cpp @@ -92,6 +92,47 @@ CPointer::CPointer(unsigned long ulAddr /* = 0 */, bool bAutoDealloc /* false */ m_bAutoDealloc = bAutoDealloc; } +const char * CPointer::GetStringPointer(int iOffset /* = 0 */) +{ + Validate(); + const char * result; + TRY_SEGV() + result = *(const char **) (m_ulAddr + iOffset); + EXCEPT_SEGV() + return result; +} + +void SetStringPointerHelper(unsigned long addr, const char * ptr) +{ + TRY_SEGV() + *(const char **) (addr) = ptr; + EXCEPT_SEGV() +} + +CPointer * CPointer::SetStringPointer(char * szText, int iOffset /* = 0 */) +{ + Validate(); + + char * value; + + if (szText) + { + // Get length of string. + unsigned long length = strlen(szText) + 1; + + value = (char *) UTIL_Alloc(length); + memcpy(value, szText, length); + } + else + { + value = szText; + } + + SetStringPointerHelper(m_ulAddr + iOffset, value); + + return new CPointer((unsigned long) value, false); +} + const char * CPointer::GetStringArray(int iOffset /* = 0 */) { Validate(); diff --git a/src/core/modules/memory/memory_pointer.h b/src/core/modules/memory/memory_pointer.h old mode 100644 new mode 100755 index 99d9b26a5..fd337add6 --- a/src/core/modules/memory/memory_pointer.h +++ b/src/core/modules/memory/memory_pointer.h @@ -136,6 +136,9 @@ class CPointer EXCEPT_SEGV() } + const char * GetStringPointer(int iOffset = 0); + CPointer* SetStringPointer(char * szText, int iOffset = 0); + const char * GetStringArray(int iOffset = 0); void SetStringArray(char* szText, int iOffset = 0); diff --git a/src/core/modules/memory/memory_wrap.cpp b/src/core/modules/memory/memory_wrap.cpp index 76d868222..be1cd74b5 100755 --- a/src/core/modules/memory/memory_wrap.cpp +++ b/src/core/modules/memory/memory_wrap.cpp @@ -201,7 +201,6 @@ void export_pointer(scope _memory) EXPOSE_GET_SET_TYPE(ulong_long, unsigned long long) EXPOSE_GET_SET_TYPE(float, float) EXPOSE_GET_SET_TYPE(double, double) - EXPOSE_GET_SET_TYPE(string_pointer, const char*) .def("get_pointer", &CPointer::GetPtr, @@ -210,6 +209,12 @@ void export_pointer(scope _memory) manage_new_object_policy() ) + .def("get_string_pointer", + &CPointer::GetStringPointer, + "Returns the value at the memory location.", + (arg("offset")=0) + ) + .def("get_string_array", &CPointer::GetStringArray, "Returns the value at the memory location.", @@ -222,10 +227,17 @@ void export_pointer(scope _memory) ("value", arg("offset")=0) ) + .def("set_string_pointer", + &CPointer::SetStringPointer, + "Sets the value at the given memory location. Returns the string object. This string object must be deallocated by the user.", + ("value", arg( "offset")=0), + manage_new_object_policy() + ) + .def("set_string_array", &CPointer::SetStringArray, "Sets the value at the given memory location.", - ("value",arg( "offset")=0) + ("value", arg( "offset")=0) ) // Other methods @@ -1048,6 +1060,7 @@ void export_global_variables(scope _memory) ADD_NATIVE_TYPE_SIZE("DOUBLE", double) ADD_NATIVE_TYPE_SIZE("POINTER", void*) ADD_NATIVE_TYPE_SIZE("STRING", char*) + ADD_NATIVE_TYPE_SIZE("STRING_POINTER", char*) _memory.attr("NULL") = object(CPointer());