Skip to content

Commit c837921

Browse files
committed
Add Client.players() to get player list
1 parent 0969160 commit c837921

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ async def main(*args: str) -> str | None:
1313
client = Client(ip, int(port))
1414
print(await client.ping())
1515
print(await client.info())
16+
print(await client.players())
1617
return None
1718

1819

samp_query/__init__.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import trio
88

99

10-
def unpack_string(data: bytes) -> tuple[str, bytes]:
11-
str_len, data = *struct.unpack_from('<I', data), data[4:]
10+
def unpack_string(data: bytes, len_type: str = 'I') -> tuple[str, bytes]:
11+
format = f'<{len_type}'
12+
size = struct.calcsize(format)
13+
str_len, data = *struct.unpack_from(format, data), data[size:]
1214
string, data = data[:str_len], data[str_len:]
1315
encoding: str = chardet.detect(string)['encoding']
1416
return string.decode(encoding), data
@@ -43,6 +45,42 @@ def from_data(cls, data: bytes) -> ServerInfo:
4345
)
4446

4547

48+
@dataclass
49+
class PlayerInfo:
50+
name: str
51+
score: int
52+
53+
@classmethod
54+
def from_data(cls, data: bytes) -> tuple[PlayerInfo, bytes]:
55+
name, data = unpack_string(data, 'B')
56+
score = struct.unpack_from('<i', data)[0]
57+
data = data[4:] # int, see above
58+
59+
return cls(
60+
name=name,
61+
score=score,
62+
), data
63+
64+
65+
@dataclass
66+
class PlayerList:
67+
players: list[PlayerInfo]
68+
69+
@classmethod
70+
def from_data(cls, data: bytes) -> PlayerList:
71+
player_count = struct.unpack_from('<H', data)[0]
72+
data = data[2:] # short, see above
73+
players = []
74+
75+
for _ in range(player_count):
76+
player, data = PlayerInfo.from_data(data)
77+
players.append(player)
78+
79+
assert not data # We consumed all the buffer
80+
81+
return cls(players=players)
82+
83+
4684
@dataclass
4785
class Client:
4886
ip: str
@@ -98,3 +136,9 @@ async def info(self) -> ServerInfo:
98136
assert self._prefix
99137
data = await self.receive(header=self._prefix + b'i')
100138
return ServerInfo.from_data(data)
139+
140+
async def players(self) -> PlayerList:
141+
await self.send(b'c')
142+
assert self._prefix
143+
data = await self.receive(header=self._prefix + b'c')
144+
return PlayerList.from_data(data)

0 commit comments

Comments
 (0)