[CS:S] JumpStats
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
[CS:S] JumpStats
Improved version of SSJ with various bug fixes and new features.
Reogranized menu
Reorganized menu for comfortable tweeking chat preferences.
Better configuration
Server owners can easily configure almost all options in one single file.
Fixes
Fixed printing jump stats to spectators when a spectator saw wrong numbers if him mode preference was different that him target.
Fixed ignoring first tick after prespeed.
Fixed counting strafes when you was in air but didn't press JUMP before it being on ground.
Fixed all code leading to float division by zero.
Links
SSJ: Advanced: https://forums.alliedmods.net/showthread.php?t=287039
Reogranized menu
Reorganized menu for comfortable tweeking chat preferences.
Better configuration
Server owners can easily configure almost all options in one single file.
Fixes
Fixed printing jump stats to spectators when a spectator saw wrong numbers if him mode preference was different that him target.
Fixed ignoring first tick after prespeed.
Fixed counting strafes when you was in air but didn't press JUMP before it being on ground.
Fixed all code leading to float division by zero.
Links
SSJ: Advanced: https://forums.alliedmods.net/showthread.php?t=287039
Last edited by InvisibleSoldiers on Sat Nov 05, 2022 10:51 am, edited 3 times in total.
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
Question to L'In20Cible or Ayuto. Why the windows signatures CGameMovement::AirAccelerate ('55 8B EC 51 56 8B F1 8B 46 04') and CGameMovement::Friction ('55 8B EC F3 0F 10 1D ? ? ? ? 83 EC 08 56 8B F1 8B 4E 04') lead to server crash. I pass these raw strings to the binary 'server' and create function from it through 'make_function'..
Last edited by InvisibleSoldiers on Thu Sep 15, 2022 5:11 pm, edited 1 time in total.
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
InvisibleSoldiers wrote:Question to L'In20Cible or Ayuto. Why the windows signatures CGameMovement::AirAccelerate ('55 8B EC 51 56 8B F1 8B 46 04') and CGameMovement::Friction ('55 8B EC F3 0F 10 1D ? ? ? ? 83 EC 08 56 8B F1 8B 4E 04') lead to server crash. I pass these raw strings to the binary 'server' and create function from it through 'make_function'.
I've looked at your code just now, and there is a lot of things wrong.
First of all, signatures must be hex representation, so the following:
Syntax: Select all
'55 8B EC 51 56 8B F1 8B 46 04'
Should be:
Syntax: Select all
b'\x55\x8B\xEC\x51\x56\x8B\xF1\x8B\x46\x04'
Wildcarded bytes are represented by 2A, not ?. So the following:
Syntax: Select all
'55 8B EC F3 0F 10 1D ? ? ? ? 83 EC 08 56 8B F1 8B 4E 04'
Should be:
Syntax: Select all
b'\x55\x8B\xEC\xF3\x0F\x10\x1D\x2A\x2A\x2A\x2A\x83\xEC\x08\x56\x8B\xF1\x8B\x4E\x04'
I can also notice that there are a lot of undefined names on Windows. E.g. friction_signature and getairspeedcap_signature are only defined on Linux, etc. I haven't tested nor looked in the binaries if your signatures are valid/unique, though. But for the reasons mentioned above your code should not even loads and raise so it crashing is surprising to me.
To be honest, there is absolutely no reason not to use TypeManager.create_type_from_dict or even better from a file and let it to its work instead.

-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:InvisibleSoldiers wrote:To be honest, there is absolutely no reason not to use TypeManager.create_type_from_dict or even better from a file and let it to its work instead.
Can you explain how to properly create the type using this, it is a bit hard to read for me, i tried:
Syntax: Select all
manager = TypeManager()
gamemovement = {
'_binary': 'server',
'function': {
'AIRACCELERATE': {
'identifier': aa_signature,
'args': (DataType.POINTER, DataType.POINTER, DataType.FLOAT, DataType.FLOAT),
'return_type': DataType.VOID,
'convention': Convention.THISCALL
},
'FRICTION': {
'identifier': friction_signature,
'args': (DataType.POINTER, ),
'return_type': DataType.VOID,
'convention': Convention.THISCALL
}
},
'player_pointer': manager.pointer_attribute('CBasePlayer', player_offset)
}
if PLATFORM == 'linux':
gamemovement['function']['GETAIRSPEEDCAP'] = {
'identifier': getairspeedcap_signature,
'args': (DataType.POINTER, ),
'return_type': DataType.FLOAT,
'convention': Convention.THISCALL
}
elif PLATFORM == 'windows':
gamemovement['virtual_function']['GETAIRSPEEDCAP'] = {
'offset': getairspeedcap_offset,
'args': (DataType.POINTER, ),
'return_type': DataType.FLOAT,
'convention': Convention.THISCALL
}
GameMovement = manager.create_type_from_dict('GameMovement', gamemovement)
ValueError: _binary was not specified
Edit: OK, i understood, '_binary' should have been renamed to 'binary'
But some problems with 'player_pointer':
Syntax: Select all
[SP] Caught an Exception:
Traceback (most recent call last):
File "../addons/source-python/plugins/jumpstats/jumpstats.py", line 51, in post_friction
player = PLAYERS[index_from_pointer(game_movement.player_pointer)]
AttributeError: 'GameMovement' object has no attribute 'player_pointer'
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:Syntax: Select all
'_binary': 'server',
Should be:Syntax: Select all
'binary': 'server',
Edit
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
InvisibleSoldiers wrote:But some problems with 'player_pointer':Syntax: Select all
[SP] Caught an Exception:
Traceback (most recent call last):
File "../addons/source-python/plugins/jumpstats/jumpstats.py", line 51, in post_friction
player = PLAYERS[index_from_pointer(game_movement.player_pointer)]
AttributeError: 'GameMovement' object has no attribute 'player_pointer'
You should bind it to the class yourself:
Syntax: Select all
gamemovement.player_pointer = manager.pointer_attribute('CBasePlayer', player_offset)
Or, set the following structure in your dictionary:
Syntax: Select all
[pointer_attribute]
[[player_pointer]]
type = POINTER
offset = 4
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:InvisibleSoldiers wrote:Syntax: Select all
[pointer_attribute]
[[player_pointer]]
type = POINTER
offset = 4
Syntax: Select all
'pointer_attribute': {
'player_pointer': {
'type': DataType.POINTER,
'offset': 0x4
}
}
Syntax: Select all
File "../addons/source-python/packages/source-python/memory/helpers.py", line 63, in is_native
return hasattr(Type, type_name.upper())
AttributeError: 'DataType' object has no attribute 'upper'
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
InvisibleSoldiers wrote:AttributeError: 'DataType' object has no attribute 'upper'[/syntax]
Syntax: Select all
'POINTER'
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:InvisibleSoldiers wrote:AttributeError: 'DataType' object has no attribute 'upper'[/syntax]Syntax: Select all
'POINTER'
Syntax: Select all
ValueError: Conversion from "Pointer" (<_memory.Pointer object at 0xeced29e0>) to "Index" failed.
Early i did it through Player() object to get index: PLAYERS[Player().index]
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
Full traceback?
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:Full traceback?
Syntax: Select all
[SP] Caught an Exception:
Traceback (most recent call last):
File "../addons/source-python/plugins/jumpstats/jumpstats.py", line 51, in post_friction
player = PLAYERS[index_from_pointer(game_movement.player_pointer)]
ValueError: Conversion from "Pointer" (<_memory.Pointer object at 0xe82fe0b0>) to "Index" failed.
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
Btw you don't know what's wrong?
Syntax: Select all
print(get_interface('server_srv.so', 'GameMovement001'))
Syntax: Select all
File "../addons/source-python/plugins/jumpstats/config/__init__.py", line 186, in <module>
print(get_interface('server_srv.so', 'GameMovement001'))
ValueError: Unable to load library 'server_srv.so'
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
The this pointer register is being reused during the call, making your game_movement invalid because stack_data[0] is a local pointer that has been freed when exiting the original function call. Mostly why you are crashing, actually. Either store the this pointer from the pre hook and use it in the post, or handle the call yourself if your code absolutely need to be executed post call:
Syntax: Select all
from memory import *
from memory.hooks import *
friction = find_binary('server')[b'\x55\x8B\xEC\xF3\x0F\x10\x1D\x2A\x2A\x2A\x2A\x83\xEC\x08\x56\x8B\xF1\x8B\x4E\x04'].make_function(
Convention.THISCALL, (DataType.POINTER, ),
DataType.VOID
)
@PreHook(friction)
def pre_friction(stack):
ret = friction.call_trampoline(*stack)
# ... your code ...
return ret
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
InvisibleSoldiers wrote:Btw you don't know what's wrong?Syntax: Select all
print(get_interface('server_srv.so', 'GameMovement001'))Syntax: Select all
File "../addons/source-python/plugins/jumpstats/config/__init__.py", line 186, in <module>
print(get_interface('server_srv.so', 'GameMovement001'))
ValueError: Unable to load library 'server_srv.so'
I guess you need 'bin/ser..'.
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:The this pointer register is being reused during the call, making your game_movement invalid because stack_data[0] is a local pointer that has been freed when exiting the original function call. Mostly why you are crashing, actually. Either store the this pointer from the pre hook and use it in the post, or handle the call yourself if your code absolutely need to be executed post call:Syntax: Select all
from memory import *
from memory.hooks import *
friction = find_binary('server')[b'\x55\x8B\xEC\xF3\x0F\x10\x1D\x2A\x2A\x2A\x2A\x83\xEC\x08\x56\x8B\xF1\x8B\x4E\x04'].make_function(
Convention.THISCALL, (DataType.POINTER, ),
DataType.VOID
)
@PreHook(friction)
def pre_friction(stack):
ret = friction.call_trampoline(*stack)
# ... your code ...
return ret
Why does it work then?
Syntax: Select all
manager.register_converter('CBasePlayer', lambda pointer: make_object(Player, pointer))
player = manager.pointer_attribute('CBasePlayer', player_offset) inside GameMovement
@PostHook(GameMovement.FRICTION)
def post_friction(stack_data, ret):
game_movement = make_object(GameMovement, stack_data[0])
player = PLAYERS[game_movement.player.index]
print(player.index)
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:InvisibleSoldiers wrote:Btw you don't know what's wrong?Syntax: Select all
print(get_interface('server_srv.so', 'GameMovement001'))Syntax: Select all
File "../addons/source-python/plugins/jumpstats/config/__init__.py", line 186, in <module>
print(get_interface('server_srv.so', 'GameMovement001'))
ValueError: Unable to load library 'server_srv.so'
I guess you need 'bin/ser..'.
Syntax: Select all
ValueError: Unable to load library 'bin/server_srv.so'.
- L'In20Cible
- Project Leader
- Posts: 1536
- Joined: Sat Jul 14, 2012 9:29 pm
- Location: Québec
Re: [CS:S] JumpStats
InvisibleSoldiers wrote:Why does it work then?Syntax: Select all
manager.register_converter('CBasePlayer', lambda pointer: make_object(Player, pointer))
player = manager.pointer_attribute('CBasePlayer', player_offset) inside GameMovement
@PostHook(GameMovement.FRICTION)
def post_friction(stack_data, ret):
game_movement = make_object(GameMovement, stack_data[0])
player = PLAYERS[game_movement.player.index]
print(player.index)
Because CBasePlayer is just wrapping the pointer, and not validating it whatsoever. The fact it "work" is random and this is actually called; undefined behaviour. Actually it can't work, since your CBasePlayer instance is wrapping a NULL pointer. Run this code:
Syntax: Select all
from memory import *
from memory.hooks import *
func = find_binary('server')[b'\x55\x8B\xEC\xF3\x0F\x10\x1D\x2A\x2A\x2A\x2A\x83\xEC\x08\x56\x8B\xF1\x8B\x4E\x04'].make_function(
Convention.THISCALL, (DataType.POINTER, ),
DataType.VOID
)
@PreHook(func)
def pre_friction(stack):
print('Pre:', stack[0].address, stack[0].get_pointer(4).address)
@PostHook(func)
def post_friction(stack, ret):
print('Post:', stack[0].address, stack[0].get_pointer(4).address)
Result:
Syntax: Select all
Pre: 1681373248 487443176
Post: 487443176 0
Basically, your this pointer in the post-hook has been reused by CGameMovement::pl. So when you wrap stack_data[0] as a CGameMovement, you are basically wrapping a CCSPlayer pointer, then you are retrieving a random address that you wrap as a CBasePlayer, etc.
InvisibleSoldiers wrote:L'In20Cible wrote:InvisibleSoldiers wrote:Btw you don't know what's wrong?Syntax: Select all
print(get_interface('server_srv.so', 'GameMovement001'))Syntax: Select all
File "../addons/source-python/plugins/jumpstats/config/__init__.py", line 186, in <module>
print(get_interface('server_srv.so', 'GameMovement001'))
ValueError: Unable to load library 'server_srv.so'
I guess you need 'bin/ser..'.Syntax: Select all
ValueError: Unable to load library 'bin/server_srv.so'.
Try without _srv suffix.
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
Syntax: Select all
@PreHook(GameMovement.AIRACCELERATE)
def pre_airaccelerate(stack_data):
game_movement = make_object(GameMovement, stack_data[0])
index = index_from_pointer(game_movement.player_pointer)
player = PLAYERS[index]
[SP] Caught an Exception:
Traceback (most recent call last):
File "../addons/source-python/plugins/jumpstats/jumpstats.py", line 38, in pre_airaccelerate
index = index_from_pointer(game_movement.player_pointer)
ValueError: Conversion from "Pointer" (<_memory.Pointer object at 0xe81ddd10>) to "Index" failed.
Syntax: Select all
'pointer_attribute': {
'player_pointer': {
'type': 'POINTER',
'offset': 4
}
}
-
- Senior Member
- Posts: 114
- Joined: Fri Mar 15, 2019 6:08 am
Re: [CS:S] JumpStats
L'In20Cible wrote:Try without _srv suffix.
Still the error.
Who is online
Users browsing this forum: No registered users and 56 guests