conqp / rcon

Python RCON client library
GNU General Public License v3.0
83 stars 15 forks source link

Bug: single quotes in examples prevents rcon from interfacing with certain games #19

Closed Juksefantomet closed 1 year ago

Juksefantomet commented 1 year ago

Hello, examples with single quotes is preventing games like e.g from properly responding when executing rcon commands.

Game affected by this bug:

Avorion server

simply changing to double quotes in the examples provides reponse from the server instantly.

behavior with single quotes is muted. it hangs on command execution.

conqp commented 1 year ago

Please provide more details. Strings in Python with single and double quotes are freely interchangeable.

Juksefantomet commented 1 year ago
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye

Python 3.9.2

It was not due to single quotes vs double quotes, but i thought the solution was the change at the reported time.

The behavior is erratic response during script execution, I can successfully execute the script 1-3 times, but on a quick repeat execution the rcon connection hangs.

Below is the script used and the first successful run, followed by the subsequent run with hang, after 2 minutes i eventually hit ctrl+c and that is the output provided on interrupt.

Both behaviors confirmed with single/double quotes script, at random after quick repeat execution.

script:

from rcon.source import Client

with Client('192.168.0.30', 27001, passwd='REDACTED') as client:
    response = client.run('/save')

print(response)

runtime log:

juksefantomet@avorionserver:~/pycon$ python3 test_commands.py
Saving all server data.

juksefantomet@avorionserver:~/pycon$ python3 test_commands.py
^CTraceback (most recent call last):
  File "/home/juksefantomet/pycon/test_commands.py", line 3, in <module>
    with Client('192.168.0.30', 27001, passwd='REDACTED') as client:
  File "/home/juksefantomet/.local/lib/python3.9/site-packages/rcon/client.py", line 31, in __enter__
    self.connect(login=True)
  File "/home/juksefantomet/.local/lib/python3.9/site-packages/rcon/client.py", line 55, in connect
    self.login(self.passwd)
  File "/home/juksefantomet/.local/lib/python3.9/site-packages/rcon/source/client.py", line 34, in login
    response = self.read()
  File "/home/juksefantomet/.local/lib/python3.9/site-packages/rcon/source/client.py", line 24, in read
    return Packet.read(file)
  File "/home/juksefantomet/.local/lib/python3.9/site-packages/rcon/source/proto.py", line 114, in read
    size = LittleEndianSignedInt32.read(file)
  File "/home/juksefantomet/.local/lib/python3.9/site-packages/rcon/source/proto.py", line 50, in read
    return cls.from_bytes(file.read(4), 'little', signed=True)
  File "/usr/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
KeyboardInterrupt

juksefantomet@avorionserver:~/pycon$
conqp commented 1 year ago

The above stacktrace only indicates that you interrupted the program via a keyboard interrupt (Ctrl+C) as you stated. I suspect that the issue lies on the server which gets congested or that you hit the edge case of a response of size 4096 which is the current frag_threshold.

To confirm this, please try running the client with a different frag_threshold.

Juksefantomet commented 1 year ago

How do i adjust my frag_threshold for client side? I am unfamiliar with that.

The expected response is simply "Galaxy saved" :smile: so the response is not of a large size, unless it somewhat attempts to fetch parts of the save log during the save process, this is highly unlikely as the RCON acts as if one executes commands in console/chat which only produces the "Galaxy saved" response.

I will investigate the matter further, but it's not something i can easily get more debug output on at this point as it simply hangs and yields no additional data during negotiation with my server.

conqp commented 1 year ago

Unfortunately I do not own a copy of "Avorion" and thus cannot reproduce the issue myself. frag_threshold is a kwarg of rcon.source.Client.__init__(). Hence, you could try something like:

from rcon.source import Client

with Client('192.168.0.30', 27001, passwd='REDACTED', frag_threshold=1024) as client:
    response = client.run('/save')

print(response)

If this does not affect the behavior, I am inclined to conclude that there's some race-condition on the server side. Do other RCON clients also produce this issue with your server?

conqp commented 1 year ago

Closing this until further feedback is given. Feel free to re-open if can provide further details, especially regarding the documented behvior of other RCON client implementations.