Page 1 of 1

Block round end

Posted: Mon Oct 15, 2018 3:59 am
by Retro
How would I be able to emulate this into python

Code: Select all

public Action CS_OnTerminateRound(float& delay, CSRoundEndReason& reason)
{
    return Plugin_Handled;
}


I'm guessing using PreHook but I'm not sure on what entity or if there is an easier way

Re: Block round end

Posted: Mon Oct 15, 2018 6:26 pm
by Ayuto
So, you would like to stop rounds from terminating? IIRC, there is a convar to do that in some games. For which game do you need that? If the convar does not exist you will need to hook CCSGameRules::TerminateRound.

Re: Block round end

Posted: Mon Oct 15, 2018 6:42 pm
by satoon101
mp_ignore_round_win_conditions

If you want to stop the rounds from ending, set that to 1.

Re: Block round end

Posted: Tue Oct 16, 2018 12:19 am
by Retro
satoon101 wrote:mp_ignore_round_win_conditions

If you want to stop the rounds from ending, set that to 1.


Most of the time that is fine but if you want to keep rounds from ending for like when your the only person in the server than a 2nd person joins the round will still end with that convar. So you would need something to make it so rounds can't terminate.

Re: Block round end

Posted: Tue Oct 16, 2018 4:01 am
by VinciT
I took what Ayuto made earlier, changed the signatures, and I think I got the right arguments? (I took a peek at how the SM guys did it)

Syntax: Select all

# ../terminate_round/terminate_round.py

# Source.Python
import core
import memory
from memory import Convention, DataType
from memory.hooks import PreHook


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

if core.PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x2A\x53\x8B\xD9\xF3\x0F\x2A\x2A\x2A\x2A\x56\x57\x89\x2A\x2A\x2A\x83\xBB'
else:
identifier = b'\x55\x89\xE5\x57\x56\x53\x81\xEC\xBC\x00\x00\x00\x8B\x7D\x08\x8B\x9F'

terminate_round = server[identifier].make_function(
Convention.THISCALL,
[DataType.POINTER, DataType.INT, DataType.INT, DataType.INT],
DataType.VOID
)

@PreHook(terminate_round)
def pre_terminate_round(stack_data):
return 0

Returning 0 seems to be blocking the round from ending (tested on Windows). However, without the return statement the round ends instantly.
There is no delay between rounds. Looking at the SM code, they seem to be using assembly to mess with the delay.

Honestly, I've no idea what I'm doing, so hopefully someone else can figure this out.

Re: Block round end

Posted: Tue Oct 16, 2018 7:23 pm
by Ayuto
The assembly part is only required for CS:GO on Windows due to LTCG. This option does some speed improvements by storing the delay in the xmm1 register instead of pushing it onto the stack. It's also possible to grab this value with SP, but is this actually required?

Re: Block round end

Posted: Wed Oct 17, 2018 12:18 am
by VinciT
The delay before the round actually ends can be important depending on the gamemode (picking up weapons or something similar). How can we preserve the original delay when we're not trying to block the round from ending but we're still using the hook?

Re: Block round end

Posted: Wed Oct 17, 2018 10:33 pm
by Retro
VinciT wrote:I took what Ayuto made earlier, changed the signatures, and I think I got the right arguments? (I took a peek at how the SM guys did it)

Syntax: Select all

# ../terminate_round/terminate_round.py

# Source.Python
import core
import memory
from memory import Convention, DataType
from memory.hooks import PreHook


server = memory.find_binary('server')

if core.PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x2A\x53\x8B\xD9\xF3\x0F\x2A\x2A\x2A\x2A\x56\x57\x89\x2A\x2A\x2A\x83\xBB'
else:
identifier = b'\x55\x89\xE5\x57\x56\x53\x81\xEC\xBC\x00\x00\x00\x8B\x7D\x08\x8B\x9F'

terminate_round = server[identifier].make_function(
Convention.THISCALL,
[DataType.POINTER, DataType.INT, DataType.INT, DataType.INT],
DataType.VOID
)

@PreHook(terminate_round)
def pre_terminate_round(stack_data):
return 0

Returning 0 seems to be blocking the round from ending (tested on Windows). However, without the return statement the round ends instantly.
There is no delay between rounds. Looking at the SM code, they seem to be using assembly to mess with the delay.

Honestly, I've no idea what I'm doing, so hopefully someone else can figure this out.


Whenever I try this I get this error

Code: Select all

[SP] Caught an Exception:

Traceback (most recent call last):

File "../addons/source-python/packages/source-python/plugins/command.py", line 162, in load_plugin

plugin = self.manager.load(plugin_name)

File "../addons/source-python/packages/source-python/plugins/manager.py", line 194, in load

plugin._load()

File "../addons/source-python/packages/source-python/plugins/instance.py", line 74, in _load

self.module = import_module(self.import_name)

File "../addons/source-python/plugins/roleplay/roleplay.py", line 91, in <module>
server = memory.find_binary('server')

OSError: Unable to find ../bin/server_srv.so


[SP] Plugin 'roleplay' was unable to be loaded.

[SP] Unloading plugin 'roleplay'...

[SP] Unable to unload plugin 'roleplay' as it is not currently loaded.

[SP] Loading plugin 'roleplay'...



[SP] Caught an Exception:

Traceback (most recent call last):

File "../addons/source-python/packages/source-python/plugins/command.py", line 162, in load_plugin

plugin = self.manager.load(plugin_name)

File "../addons/source-python/packages/source-python/plugins/manager.py", line 194, in load

plugin._load()

File "../addons/source-python/packages/source-python/plugins/instance.py", line 74, in _load

self.module = import_module(self.import_name)

File "../addons/source-python/plugins/roleplay/roleplay.py", line 91, in <module>

server = memory.find_binary('server')



OSError: Unable to find ../bin/server_srv.so





[SP] Plugin 'roleplay' was unable to be loaded.



[SP] Caught an Exception:

Traceback (most recent call last):

File "../addons/source-python/packages/source-python/commands/typed.py", line 554, in on_command

result = cls.on_clean_command(command_info, command_node, args)

File "../addons/source-python/packages/source-python/commands/typed.py", line 569, in on_clean_command

return command_node.callback(command_info, *cleaned_args)

File "../addons/source-python/plugins/pycmds/pycmds.py", line 288, in command_test

eval(info.command.arg_string, globals(), locals())

File "<string>", line 1, in <module>



NameError: name 'core' is not defined





[SP] Unloading plugin 'roleplay'...

[SP] Unable to unload plugin 'roleplay' as it is not currently loaded.

[SP] Loading plugin 'roleplay'...



[SP] Caught an Exception:

Traceback (most recent call last):

File "../addons/source-python/packages/source-python/plugins/command.py", line 162, in load_plugin

plugin = self.manager.load(plugin_name)

File "../addons/source-python/packages/source-python/plugins/manager.py", line 194, in load

plugin._load()

File "../addons/source-python/packages/source-python/plugins/instance.py", line 74, in _load

self.module = import_module(self.import_name)

File "../addons/source-python/plugins/roleplay/roleplay.py", line 91, in <module>

server = memory.find_binary('server')



OSError: Unable to find ../bin/server_srv.so





[SP] Plugin 'roleplay' was unable to be loaded.



[SP] Caught an Exception:

Traceback (most recent call last):

File "../addons/source-python/packages/source-python/commands/typed.py", line 554, in on_command

result = cls.on_clean_command(command_info, command_node, args)

File "../addons/source-python/packages/source-python/commands/typed.py", line 569, in on_clean_command

return command_node.callback(command_info, *cleaned_args)

File "../addons/source-python/plugins/pycmds/pycmds.py", line 288, in command_test

eval(info.command.arg_string, globals(), locals())

File "<string>", line 1, in <module>



NameError: name 'core' is not defined





[SP] Unloading plugin 'roleplay'...

[SP] Unable to unload plugin 'roleplay' as it is not currently loaded.

[SP] Loading plugin 'roleplay'...



[SP] Caught an Exception:

Traceback (most recent call last):

File "../addons/source-python/packages/source-python/plugins/command.py", line 162, in load_plugin

plugin = self.manager.load(plugin_name)

File "../addons/source-python/packages/source-python/plugins/manager.py", line 194, in load

plugin._load()

File "../addons/source-python/packages/source-python/plugins/instance.py", line 74, in _load

self.module = import_module(self.import_name)

File "../addons/source-python/plugins/roleplay/roleplay.py", line 91, in <module>

server = memory.find_binary('server')



OSError: Unable to find ../bin/server_srv.so





[SP] Plugin 'roleplay' was unable to be loaded.


Pretty sure it just means i don't have that .so file but shouldn't it download when you dl a server?

Re: Block round end

Posted: Wed Oct 17, 2018 11:04 pm
by VinciT
I think that happened because srv_check=False was missing from memory.find_binary().
I've updated the code above, give it another try.

Re: Block round end

Posted: Thu Oct 18, 2018 8:49 pm
by Retro
Nvm it works ty