Page 1 of 1

[Q] Custom structures

Posted: Thu May 14, 2020 1:36 am
by Sam
How can I create my own structure for the `memory` module, similar to the `ctypes.Structure`?

I need `player_info_s` for: `VEngineClient->GetPlayerInfo(int, player_info_s*);`

Re: [Q] Custom structures

Posted: Thu May 14, 2020 4:11 am
by Sam
This method does not cause errors and works better than `memory.alloc` :\

Syntax: Select all

import memory
import ctypes

class PlayerInfov2(ctypes.Structure):
_fields_ = [
('name', ctypes.c_char * 32),
('userID', ctypes.c_int),
('guid', ctypes.c_char * 33),
('friendsID', ctypes.c_uint32),
('friendsName', ctypes.c_char * 32),
('fakeplayer', ctypes.c_bool),
('ishltv', ctypes.c_bool),
('customFiles', ctypes.c_uint * 4),
('filesDownloaded', ctypes.c_ushort),
]

pi = PlayerInfov2()
ppi = ctypes.pointer(pi)
pinf = Pointer(ctypes.addressof(pi))
result = engine.GetPlayerInfo(engine.GetLocalPlayer(), pinf)
console_message(f'Result -> {result}\n')
console_message(f'Name -> {pi.userID}\n')

Re: [Q] Custom structures

Posted: Thu May 14, 2020 4:30 am
by Sam

Syntax: Select all

class PlayerInfoType(Pointer):
name = property(
lambda self: self.get_string_array(0x00),
)
userID = property(
lambda self: self.get_int(0x20),
)
guid = property(
lambda self: self.get_string_array(0x24),
)
friendsID = property(
lambda self: self.get_int(0x48),
)
friendsName = property(
lambda self: self.get_string_array(0x4C),
)
fakeplayer = property(
lambda self: self.get_bool(0x6C),
)
ishltv = property(
lambda self: self.get_bool(0x6D),
)
customFiles = property(
lambda self: [
self.get_uint(0x70),
self.get_uint(0x74),
self.get_uint(0x78),
self.get_uint(0x7C),
],
)
filesDownloaded = property(
lambda self: self.get_uchar(0x80),
)

class PlayerInfoStructure(ctypes.Structure):
_fields_ = [
('name', ctypes.c_char * 32),
('userID', ctypes.c_int),
('guid', ctypes.c_char * (32 + 1)),
('friendsID', ctypes.c_uint32),
('friendsName', ctypes.c_char * 32),
('fakeplayer', ctypes.c_bool),
('ishltv', ctypes.c_bool),
('customFiles', ctypes.c_uint * 4),
('filesDownloaded', ctypes.c_ushort),
]
def ConvertToPlayerInfo(self):
return PlayerInfoType(ctypes.addressof(self))


pinf = PlayerInfoStructure()
ptr_pinf = Pointer(ctypes.addressof(pi))
result = engine.GetPlayerInfo(engine.GetLocalPlayer(), ptr_pinf)
console_message(f'Result -> {result}\n')
console_message(f'Name -> {pinf.ConvertToPlayerInfo().name}\n')

Result -> True
Name -> Ren


*Closed. But open to add a record*

Re: [Q] Custom structures

Posted: Thu May 14, 2020 9:26 am
by Ayuto
Try searching for CustomType here on the forums. There are a few examples. CustomType provides a few more features like automatically registering it as a return type, so you can easily use it with virtual functions and normal functions. Moreover, make_object and get_object_pointer will work on instances of CustomType.

For example this one:
viewtopic.php?p=7679#p7679

Re: [Q] Custom structures

Posted: Thu May 14, 2020 1:01 pm
by InvisibleSoldiers
Offtop:
I noticed that you do many low level things, so why don't you go in VSP or Metamod?

Re: [Q] Custom structures

Posted: Thu May 14, 2020 8:07 pm
by Sam
Ayuto wrote:Try searching for CustomType here on the forums. There are a few examples. CustomType provides a few more features like automatically registering it as a return type, so you can easily use it with virtual functions and normal functions. Moreover, make_object and get_object_pointer will work on instances of CustomType.

For example this one:
viewtopic.php?p=7679#p7679

Thx for manager.instance_attribute. Now my code has become a little prettier -w-

Syntax: Select all

class PlayerInfoType(Pointer):
name = manager.instance_attribute(Type.STRING_ARRAY, 0)
userID = manager.instance_attribute(Type.INT, 0x20)
guid = manager.instance_attribute(Type.STRING_ARRAY, 0x24)
friendsID = manager.instance_attribute(Type.INT, 0x48)
friendsName = manager.instance_attribute(Type.STRING_ARRAY, 0x4C)
fakeplayer = manager.instance_attribute(Type.BOOL, 0x6C)
ishltv = manager.instance_attribute(Type.BOOL, 0x6D)
customFiles = manager.static_instance_array(Type.UINT, 0x70, 4)
filesDownloaded = manager.instance_attribute(Type.UCHAR, 0x6D)

class PlayerInfoStructure(ctypes.Structure):
_fields_ = [
('name', ctypes.c_char * 32),
('userID', ctypes.c_int),
('guid', ctypes.c_char * (32 + 1)),
('friendsID', ctypes.c_uint32),
('friendsName', ctypes.c_char * 32),
('fakeplayer', ctypes.c_bool),
('ishltv', ctypes.c_bool),
('customFiles', ctypes.c_uint * 4),
('filesDownloaded', ctypes.c_ubyte),
]
def ConvertToPlayerInfo(self):
return PlayerInfoType(ctypes.addressof(self))

I previously tried CustomType with memory.alloc but it causes a crash of the game and is very unstable (with the fourth call memory.alloc, the game crashes). The most stable method (error-resistant) turned out to be ctypes and SP.

InvisibleSoldiers wrote:Offtop:
I noticed that you do many low level things, so why don't you go in VSP or Metamod?

I don't think that my place there.

Re: [Q] Custom structures

Posted: Thu May 14, 2020 8:36 pm
by Ayuto
Your PlayerInfoType class should be a subclass of CustomType and use the manager as the metaclass. If you also provide the size, you can then instantiate your PlayerInfoType class and internally memory is allocated automatically.

I never had any stability issues with CustomType. Today I would have implemented a lot differently, but well...

Try disabling the automatic deallocation of the memory (second argument of memory.alloc). I could imagine that this is causing your crashes.