Preparement for rcon support
This commit is contained in:
parent
c1ad95d233
commit
f55275a627
|
@ -14,6 +14,7 @@
|
||||||
"port": 7777,
|
"port": 7777,
|
||||||
"hostname": "Python > C",
|
"hostname": "Python > C",
|
||||||
"password": "",
|
"password": "",
|
||||||
|
"rcon_password": "changeme",
|
||||||
"max_players": 50,
|
"max_players": 50,
|
||||||
"mode": "debug",
|
"mode": "debug",
|
||||||
"language": "python"
|
"language": "python"
|
||||||
|
|
|
@ -16,24 +16,14 @@ class QueryClient(BaseClient):
|
||||||
b"i": self.query_i,
|
b"i": self.query_i,
|
||||||
b"r": self.query_r,
|
b"r": self.query_r,
|
||||||
b"c": self.query_c,
|
b"c": self.query_c,
|
||||||
b"d": self.query_d
|
b"d": self.query_d,
|
||||||
|
b"p": self.query_p,
|
||||||
|
b"x": self.query_x
|
||||||
}
|
}
|
||||||
|
|
||||||
async def on_packet(self, packet: bytes):
|
async def on_packet(self, packet: bytes):
|
||||||
logger.debug("on_packet(%s)" % packet)
|
logger.debug("on_packet(%s)" % packet)
|
||||||
|
|
||||||
"""
|
|
||||||
if len(packet) != 11: # Just a ping with some random numbers at the end (14 bytes in total)
|
|
||||||
await self.send(packet)
|
|
||||||
return
|
|
||||||
"""
|
|
||||||
# ip ~~and port~~ the client connected to; (would be server ip ~~and port~~ if not though proxy)
|
|
||||||
# This could be used to check if client connected remotely in some way though a proxy
|
|
||||||
# SA:MP default server drops the connection if port does not match (when its client (not query protocol))
|
|
||||||
#server_ip = ".".join((str(x) for x in struct.unpack(b"<4B", packet[4:8])))
|
|
||||||
#server_port, = struct.unpack(b"<H", packet[8:10]) # This is not port, the wiki is wrong: https://wiki.sa-mp.com/wiki/Query
|
|
||||||
#logger.debug("[%s:%d] via %s:%d" % (self.ip, self.port, server_ip, server_port))
|
|
||||||
|
|
||||||
if len(packet) <= 10: # Invalid
|
if len(packet) <= 10: # Invalid
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -109,4 +99,20 @@ class QueryClient(BaseClient):
|
||||||
return packet + struct.pack(b"<H" + (b"cc%dsII" * data[0]) % tuple(len(p["nick"]) for p in players), *data)
|
return packet + struct.pack(b"<H" + (b"cc%dsII" * data[0]) % tuple(len(p["nick"]) for p in players), *data)
|
||||||
|
|
||||||
async def query_p(self, packet: bytes) -> bytes:
|
async def query_p(self, packet: bytes) -> bytes:
|
||||||
return packet
|
return packet
|
||||||
|
|
||||||
|
async def query_x(self, packet: bytes) -> bytes:
|
||||||
|
len_pswd, = struct.unpack_from(b"<H", packet, 11)
|
||||||
|
pswd, len_cmd = struct.unpack_from(b"<%dsH" % len_pswd, packet, 13)
|
||||||
|
cmd = struct.unpack_from(b"<%ds" % len_cmd, packet, 15 + len_pswd)
|
||||||
|
|
||||||
|
if len(self.server.config.rcon_password) == 0:
|
||||||
|
msg = b"Remote Console is not enabled on this server."
|
||||||
|
elif self.server.config.rcon_password.encode() != pswd:
|
||||||
|
msg = b"Invalid RCON password."
|
||||||
|
logger.warning("BAD RCON ATTEMPT BY: %s:%d" % (self.ip, self.port))
|
||||||
|
else:
|
||||||
|
# TODO: Add rcon client to command stdouts
|
||||||
|
return b"" # No response as all is ok
|
||||||
|
|
||||||
|
return packet[:11] + struct.pack(b"<H%ds" % len(msg), len(msg), msg)
|
|
@ -22,6 +22,7 @@ class Server:
|
||||||
|
|
||||||
async def on_command(self, cmd: str):
|
async def on_command(self, cmd: str):
|
||||||
logger.debug("on_command(%s)" % cmd)
|
logger.debug("on_command(%s)" % cmd)
|
||||||
|
# TODO: When commands return a reponse we also want to forward this to potential rcon clients
|
||||||
|
|
||||||
async def get_online_players(self): # TODO: Get data from server's client objects
|
async def get_online_players(self): # TODO: Get data from server's client objects
|
||||||
return [
|
return [
|
||||||
|
@ -48,4 +49,4 @@ class Server:
|
||||||
self.clients[addr] = Client(self, ip, port)
|
self.clients[addr] = Client(self, ip, port)
|
||||||
await self.clients[addr].on_packet(data)
|
await self.clients[addr].on_packet(data)
|
||||||
|
|
||||||
await asyncio.sleep(0)
|
await asyncio.sleep(0)
|
||||||
|
|
|
@ -4,6 +4,7 @@ class ServerConfig:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
host: str, port: int,
|
host: str, port: int,
|
||||||
hostname: str, password: str,
|
hostname: str, password: str,
|
||||||
|
rcon_password: str,
|
||||||
max_players: int,
|
max_players: int,
|
||||||
mode: str, language: str):
|
mode: str, language: str):
|
||||||
self.host = host
|
self.host = host
|
||||||
|
@ -12,6 +13,8 @@ class ServerConfig:
|
||||||
self.hostname = hostname
|
self.hostname = hostname
|
||||||
self.password = password
|
self.password = password
|
||||||
|
|
||||||
|
self.rcon_password = rcon_password
|
||||||
|
|
||||||
self.max_players = max_players
|
self.max_players = max_players
|
||||||
|
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
|
Loading…
Reference in New Issue
Block a user