Open Holiverh opened 9 years ago
These changes will more or less be incorporated into a rewrite of the RCON module.
My server is running on Linux, the player name in response may contains non-ascii char.
So I changed default encoding from ascii
to utf-8
in rcon.py
, and it works well.
And I just checked other libraries, all of that used utf-8
encoding.
Any update on this one? I tried changing rcon.py
from ascii
to utf-8
and am presented with this error:
Unexpected message <RCONMessage 0 AUTH_RESPONSE 0B>
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 994-996: ordinal not in range(128)
Quite unhelpful. I'm not sure why ascii
is even still being used.
I've tried pretty much everything mentioned in the docs. I can't run valve.rcon.RCON.execute()
without this error - I don't even get a chance to encode/decode with my desired format.
I've hit this issue yesterday. I have my own web interface for the server I'm running, which is dependent on this package. It was stable as hell until someone joined a server with a weird chars in his name. That's when simpe status
request was crashing my app:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "./application.py", line 45, in decorator
return f(*args, **kwargs)
File "./application.py", line 73, in index
data = rcon('status')
File "/usr/local/lib/python2.7/dist-packages/valve/rcon.py", line 346, in __call__
raise RCONMessageError("Couldn't decode response: {}".format(exc))
valve.rcon.RCONMessageError: Couldn't decode response: 'utf8' codec can't decode byte 0xd0 in position 359: invalid continuation byte
After looking into detalis a bit further it does not matter what encoding you are using - you might hit this issue in any case. IMO, quick (right?) solution would be to simply drop those chars that can't be encoded:
text.encode(encoding=self.ENCODING, errors='ignore')
I'll create a PR, and then it's up to you to decide what would be the correct way to do this.
Here you go. Feel free to update a commit message if needed.
For others who may find this in the future, this is what I found a solution in:
First, read https://python-valve.readthedocs.io/en/latest/rcon.html#unicode-and-string-encoding
with valve.rcon.RCON(server_address, password) as rcon:
rcon_resp = rcon('status')
rcon_text = rcon_resp.body.decode('utf-8', 'ignore')
This works for me on a Ubuntu 18 LTS server running this under Python 3.6 against SRCDS running on the same instance.
13 highlighted a case where the body of an RCON message (a response to a
status
command to be specific) may not be valid ASCII.This is contrary to the Valve wiki page for RCON which seems to imply that RCON message bodies should be null terminated ASCII encoded strings. Evidently this isn't always the case. As I was unable to recreate the issue for my self I can't really dig into it much further to know what encoding
srcds
is actually using. Perhaps its some kind of "extended ASCII", e.g. ISO 8859-1? Maybe it's UTF-8. Who knows, but I don't think we should simply guess.https://github.com/Holiverh/python-valve/commit/2d56e64da0f37e0fc63e7f325c2a99bc064f2877 was added as a workaround for #13 but this is not ideal as it simply ignores anything it can't decode.
Looking at the two other Python RCON implementations (SourceLib and pysrcds) neither of them seem to even attempt to decode the message body, leaving it as a bytestring. Whilst no confident assertions can be made about the encoding of RCON messages there is merit to this behavior IMO.
Ultimately:
UnicodeDecodeError
should never be propagated fromMessage.decode
.Message
should expose the message body as a bytestring along side the Unicode body so that if there is any data loss from ignoring decode errors the user at least has a chance of salvaging the real message body by handling the decoding themselves or by just using the bytestring bodies exclusively.:8ball: