Page 1 of 1

[Cs:s] Hook remaining time of the map

Posted: Mon Apr 11, 2022 2:12 pm
by cssbestrpg
Hi guys, i have issue to hook properly remaining time for my linux server.

I have tried to hook:
[CCSGameRules::GetMapRemainingTime]
shortname = "GetMapRemainingTime"
sig = " 55 8B EC 51 8B 15 2A 2A 2A 2A 56 8B F1 8B 0D 2A 2A 2A 2A 81"
symbol = "_ZN12CCSGameRules19GetMapRemainingTimeEv"
param = "p)f"
convention = "thiscall"

Here is the code:

Syntax: Select all

import memory
from memory import Convention, DataType
from memory.hooks import PreHook
from messages import SayText2

server = memory.find_binary('server', srv_check=False)

identifier = '_ZN12CCSGameRules19GetMapRemainingTimeEv'

GetMapRemainingTime = server[identifier].make_function(
Convention.THISCALL,
[DataType.POINTER],
DataType.FLOAT
)

def load():
@PreHook(GetMapRemainingTime)
def pre_terminate_round(stack_data):
SayText2(f'Timeleft: {stack_data}').send()
print(f'Timeleft: {stack_data}')


Whenever the round end i just get these errors:

Code: Select all

Timeleft: (<_memory.Pointer object at 0xe09c5a70>, 186542880)


Edit:

Syntax: Select all

import memory
from memory import Convention, DataType
from memory.hooks import PreHook
from messages import SayText2

server = memory.find_binary('server', srv_check=False)

identifier = '_ZN12CCSGameRules19GetMapRemainingTimeEv'

GetMapRemainingTime = server[identifier].make_function(
Convention.THISCALL,
[],
DataType.VOID
)

@PreHook(GetMapRemainingTime)
def pre_terminate_round(stack_data):
SayText2(f'Timeleft: {stack_data}').send()


Now it shows in chat: Timeleft: ()
How i can get it show remaining time of map?

Re: [Cs:s] Hook remaining time of the map

Posted: Thu Apr 14, 2022 7:15 am
by Ayuto
You first version was quite correct. The message you see, is simply the output of your print statement. It's not an error. What exactly would you like to archieve?

Maybe this helps a little bit more:

Syntax: Select all

import memory
from memory import Convention, DataType
from memory.hooks import PostHook

server = memory.find_binary('server', srv_check=False)

identifier = '_ZN12CCSGameRules19GetMapRemainingTimeEv'

GetMapRemainingTime = server[identifier].make_function(
Convention.THISCALL,
[DataType.POINTER],
DataType.FLOAT
)

@PostHook(GetMapRemainingTime)
def pre_get_remaining_time(stack_data, return_value):
# The first entry in stack_data is the gamerules pointer (instance of
# CSSGameRules). There are no other arguments.
gamerules_ptr = stack_data[0]

# CSSGameRules::GetMapRemainingTime() returns a floating value, which is
# the remaining time. If you would like to know the return value and make
# a decision based on that, you need to create a post hook. In that case
# GetMapRemainingTime was already called and returns to this hook.
print(f'Remaining time: {return_value}')

# You can still override the return value if you want. This will probably
# cause an infinite running map.
return 4711.0

Re: [Cs:s] Hook remaining time of the map

Posted: Thu Apr 14, 2022 11:39 am
by cssbestrpg
I would want it show remaining time of the map, when type in chat timeleft

Re: [Cs:s] Hook remaining time of the map

Posted: Thu Apr 14, 2022 1:51 pm
by Ayuto
Ah, in that case you don't want to hook the function, but you want to call it instead. Usually, you only hook functions if you want to modify their behaviour.

Try this:

Syntax: Select all

import memory
from memory import Convention, DataType

from engines.gamerules import find_gamerules
from commands.typed import TypedSayCommand

server = memory.find_binary('server', srv_check=False)

identifier = '_ZN12CCSGameRules19GetMapRemainingTimeEv'

GetMapRemainingTime = server[identifier].make_function(
Convention.THISCALL,
[DataType.POINTER],
DataType.FLOAT)

@TypedSayCommand('timeleft')
def on_timeleft(info):
timeleft = GetMapRemainingTime(find_gamerules())
info.reply('Timeleft: {timeleft}')

Re: [Cs:s] Hook remaining time of the map

Posted: Thu Apr 14, 2022 2:38 pm
by cssbestrpg
Ayuto wrote:Ah, in that case you don't want to hook the function, but you want to call it instead. Usually, you only hook functions if you want to modify their behaviour.

Try this:

Syntax: Select all

import memory
from memory import Convention, DataType

from engines.gamerules import find_gamerules
from commands.typed import TypedSayCommand

server = memory.find_binary('server', srv_check=False)

identifier = '_ZN12CCSGameRules19GetMapRemainingTimeEv'

GetMapRemainingTime = server[identifier].make_function(
Convention.THISCALL,
[DataType.POINTER],
DataType.FLOAT)

@TypedSayCommand('timeleft')
def on_timeleft(info):
timeleft = GetMapRemainingTime(find_gamerules())
info.reply('Timeleft: {timeleft}')


I got it work after fixing small typos of code, but thanks for the help. I am new to gamerules thing

Re: [Cs:s] Hook remaining time of the map

Posted: Fri Apr 15, 2022 9:35 am
by L'In20Cible
You don't necessarily need a signature for that:

Syntax: Select all

from cvars import ConVar
from engines.gamerules import find_game_rules
from engines.server import global_vars

mp_timelimit = ConVar('mp_timelimit')

def get_map_remaining_time():
"""Returns the remaining time for the current map."""
timelimit = mp_timelimit.get_int()
if timelimit < 1:
return -1 # No time limit
start = find_game_rules().get_property_float('cs_gamerules_data.m_flGameStartTime')
timeleft = (start + timelimit * 60) - global_vars.current_time
if timeleft < 0.0:
return 0 # Last round
return timeleft


Though, if you don't have to manipulate the format yourself, it could be as simple as:

Syntax: Select all

from commands.typed import TypedSayCommand
from players.entity import Player

@TypedSayCommand('timeleft')
def on_timeleft(info):
Player(info.index).client_command('timeleft', True)

Re: [Cs:s] Hook remaining time of the map

Posted: Mon Apr 18, 2022 6:06 pm
by cssbestrpg
L'In20Cible wrote:You don't necessarily need a signature for that:

Syntax: Select all

from cvars import ConVar
from engines.gamerules import find_game_rules
from engines.server import global_vars

mp_timelimit = ConVar('mp_timelimit')

def get_map_remaining_time():
"""Returns the remaining time for the current map."""
timelimit = mp_timelimit.get_int()
if timelimit < 1:
return -1 # No time limit
start = find_game_rules().get_property_float('cs_gamerules_data.m_flGameStartTime')
timeleft = (start + timelimit * 60) - global_vars.current_time
if timeleft < 0.0:
return 0 # Last round
return timeleft


Though, if you don't have to manipulate the format yourself, it could be as simple as:

Syntax: Select all

from commands.typed import TypedSayCommand
from players.entity import Player

@TypedSayCommand('timeleft')
def on_timeleft(info):
Player(info.index).client_command('timeleft', True)


Okay, i thought it requires a signature for it, i just never done game_rules stuff.
Btw does the signature and non signature version have performance difference?

Re: [Cs:s] Hook remaining time of the map

Posted: Mon Apr 18, 2022 8:18 pm
by Ayuto
I can't say without testing, but performance shouldn't matter in this case as you are probably not invoking it a thousand times per frame. So, you better choose the non-signature solution. That way you don't have to maintain a signature which might break with a game update. Moreover, you are more cross game/OS compatible.