2018-09-24 11:37:21 +02:00
|
|
|
import struct
|
2019-12-14 20:08:34 +01:00
|
|
|
import logging
|
|
|
|
|
2020-03-29 18:45:38 +02:00
|
|
|
from .. import glob
|
|
|
|
from ..helpers import dataHelper
|
2018-09-24 11:37:21 +02:00
|
|
|
|
2019-12-14 20:08:34 +01:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
logger.propagate = False # Disable console logging
|
|
|
|
|
2018-09-24 11:37:21 +02:00
|
|
|
def handle(client, data):
|
2019-12-14 20:08:34 +01:00
|
|
|
ping_ip = ".".join((str(x) for x in struct.unpack(b"<4B", data[4:8])))
|
|
|
|
ping_port = struct.unpack(b"<H", data[9:11])[0]
|
2018-09-24 11:37:21 +02:00
|
|
|
|
2019-12-14 20:08:34 +01:00
|
|
|
logger.debug("[%s] -> Pinging to %s:%d" % (client.addr, ping_ip, ping_port))
|
2018-09-24 11:37:21 +02:00
|
|
|
|
|
|
|
if len(data) == 11: # We should add our data ontop
|
|
|
|
if data[-1:] in RESPONSE:
|
|
|
|
data += RESPONSE[data[-1:]]()
|
|
|
|
|
2019-12-14 20:08:34 +01:00
|
|
|
logger.debug("[%s] <- %s" % (client.addr, data))
|
|
|
|
|
2018-09-24 11:37:21 +02:00
|
|
|
return data
|
|
|
|
|
|
|
|
def query_i():
|
|
|
|
len_hostname = len(glob.config["server"]["hostname"])
|
|
|
|
len_mode = len(glob.config["server"]["mode"])
|
|
|
|
len_language = len(glob.config["server"]["language"])
|
|
|
|
|
|
|
|
packet = struct.pack(b"<?HHI%dsI%dsI%ds" % (len_hostname, len_mode, len_language),
|
|
|
|
False,
|
2018-09-26 10:05:54 +02:00
|
|
|
len(get_online_players()),
|
2018-09-24 11:37:21 +02:00
|
|
|
glob.config["server"]["max_players"],
|
|
|
|
len_hostname,
|
|
|
|
glob.config["server"]["hostname"].encode(),
|
|
|
|
len_mode,
|
|
|
|
glob.config["server"]["mode"].encode(),
|
|
|
|
len_language,
|
|
|
|
glob.config["server"]["language"].encode())
|
|
|
|
|
|
|
|
return packet
|
|
|
|
|
2018-09-24 13:40:46 +02:00
|
|
|
def query_r():
|
|
|
|
packet_data = []
|
|
|
|
|
|
|
|
rules = get_rules()
|
|
|
|
packet_data.append(len(rules)) # len_rules
|
|
|
|
|
|
|
|
for name, value in rules.items():
|
2018-09-26 08:41:50 +02:00
|
|
|
packet_data.append([
|
|
|
|
len(name), name,
|
|
|
|
len(value), value
|
|
|
|
])
|
2018-09-24 13:40:46 +02:00
|
|
|
|
2018-09-26 08:41:50 +02:00
|
|
|
flat_packet_data = dataHelper.flatten(packet_data)
|
2018-09-24 13:40:46 +02:00
|
|
|
|
2018-09-26 15:25:01 +02:00
|
|
|
packet = struct.pack(b"<H" + b"B%dsB%ds" * flat_packet_data[0] # using len_rules
|
|
|
|
% tuple(len(y) for x in rules.items() for y in x), # tuple of only rules entries
|
2018-09-24 13:40:46 +02:00
|
|
|
*flat_packet_data)
|
|
|
|
|
|
|
|
return packet
|
|
|
|
|
2018-09-26 09:42:18 +02:00
|
|
|
def query_c():
|
|
|
|
packet_data = []
|
2019-12-14 20:08:34 +01:00
|
|
|
|
2018-09-26 09:42:18 +02:00
|
|
|
players_scores = get_players_scores()
|
|
|
|
packet_data.append(len(players_scores))
|
|
|
|
|
|
|
|
for name, value in players_scores.items():
|
|
|
|
packet_data.append([
|
|
|
|
len(name), name,
|
|
|
|
value
|
|
|
|
])
|
2019-12-14 20:08:34 +01:00
|
|
|
|
2018-09-26 09:42:18 +02:00
|
|
|
flat_packet_data = dataHelper.flatten(packet_data)
|
|
|
|
|
2018-09-26 15:25:01 +02:00
|
|
|
packet = struct.pack(b"<H" + b"B%dsI" * flat_packet_data[0]
|
|
|
|
% tuple(len(x) for x in players_scores.keys()),
|
2018-09-26 09:42:18 +02:00
|
|
|
*flat_packet_data)
|
2019-12-14 20:08:34 +01:00
|
|
|
|
2018-09-26 09:43:05 +02:00
|
|
|
return packet
|
2018-09-26 09:42:18 +02:00
|
|
|
|
2018-09-26 10:05:54 +02:00
|
|
|
def query_d():
|
|
|
|
packet_data = []
|
|
|
|
|
|
|
|
players = get_online_players()
|
|
|
|
packet_data.append(len(players))
|
|
|
|
|
|
|
|
for player in players:
|
|
|
|
packet_data.append([
|
|
|
|
player["id"],
|
|
|
|
len(player["nick"]), player["nick"],
|
|
|
|
player["score"],
|
|
|
|
player["ping"]
|
|
|
|
])
|
|
|
|
|
|
|
|
flat_packet_data = dataHelper.flatten(packet_data)
|
|
|
|
|
|
|
|
packet = struct.pack(b"<H" + b"cc%dsII" * flat_packet_data[0]
|
|
|
|
% [len(player["nick"]) for player in players],
|
|
|
|
*flat_packet_data)
|
|
|
|
|
|
|
|
return packet
|
|
|
|
|
|
|
|
def get_online_players(): #TODO: Get data from server's client objects
|
|
|
|
return [
|
2018-09-26 15:25:01 +02:00
|
|
|
{"nick": b"Sunpy", "score": 64, "ping": 8, "id": 1} # replace id with function to get player's id
|
2018-09-26 10:05:54 +02:00
|
|
|
]
|
2018-09-24 11:37:21 +02:00
|
|
|
|
2018-09-24 13:40:46 +02:00
|
|
|
def get_rules(): #TODO
|
2018-10-02 00:38:25 +02:00
|
|
|
return {b"Rule name sample": b"Rule value", b"weburl": b"https://git.osufx.com/Sunpy/sampy"}
|
2018-09-24 13:40:46 +02:00
|
|
|
|
2018-09-26 10:05:54 +02:00
|
|
|
def get_players_scores(): #TODO
|
2018-09-26 15:25:01 +02:00
|
|
|
return {b"Sunpy": 64, b"username": 123}
|
2018-09-26 09:42:18 +02:00
|
|
|
|
2018-10-02 00:38:25 +02:00
|
|
|
RESPONSE = { #TODO?: p (https://wiki.sa-mp.com/wiki/Query_Mechanism) (We dont really need to do the last handler as it happens somewhat automatically)
|
2018-09-24 13:40:46 +02:00
|
|
|
b"i": query_i,
|
2018-09-26 09:42:18 +02:00
|
|
|
b"r": query_r,
|
2018-09-26 10:05:54 +02:00
|
|
|
b"c": query_c,
|
|
|
|
b"d": query_d
|
2019-12-14 20:08:34 +01:00
|
|
|
}
|