Browse Source

push latest changes

pull/43/head
Alex Nørgaard 2 years ago
parent
commit
561ceaf845
No known key found for this signature in database GPG Key ID: 94D54F6A3604E97
  1. 9
      .github/workflows/coverage_and_lint.yml
  2. 3
      MANIFEST.in
  3. 24
      a2s/__init__.py
  4. 39
      a2s/a2s_async.py
  5. 24
      a2s/a2s_fragment.py
  6. 34
      a2s/a2s_sync.py
  7. 37
      a2s/byteio.py
  8. 24
      a2s/datacls.py
  9. 24
      a2s/defaults.py
  10. 25
      a2s/exceptions.py
  11. 59
      a2s/info.py
  12. 33
      a2s/players.py
  13. 36
      a2s/rules.py
  14. 2
      setup.py

9
.github/workflows/coverage_and_lint.yml

@ -32,8 +32,6 @@ jobs:
python-version: "${{ matrix.python-version }}"
- name: "Install Python deps @ ${{ matrix.python-version }}"
env:
PY_VER: "${{ matrix.python-version }}"
run: |
pip install -U .
@ -42,10 +40,11 @@ jobs:
node-version: "17"
- run: npm install --location=global pyright@latest
- name: "Type Sanity @ ${{ matrix.python-version }}"
run: pyright --pythonversion ${{ matrix.python-version }}
- name: "Type Coverage @ ${{ matrix.python-version }}"
run: |
pyright
pyright --ignoreexternal --lib --verifytypes a2s
run: pyright --ignoreexternal --lib --verifytypes a2s --pythonversion ${{ matrix.python-version }}
- name: Lint
if: ${{ github.event_name != 'pull_request' }}

3
MANIFEST.in

@ -0,0 +1,3 @@
include README.md
include LICENSE
include a2s/py.typed

24
a2s/__init__.py

@ -1,27 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from a2s.exceptions import BrokenMessageError as BrokenMessageError, BufferExhaustedError as BufferExhaustedError
from a2s.info import GoldSrcInfo as GoldSrcInfo, SourceInfo as SourceInfo, ainfo as ainfo, info as info
from a2s.players import Player as Player, aplayers as aplayers, players as players

39
a2s/a2s_async.py

@ -1,26 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from __future__ import annotations
import asyncio
@ -68,13 +45,13 @@ async def request_async(
@overload
async def request_async(
address: Tuple[str, int], timeout: float, encoding: str, a2s_proto: Type[RulesProtocol]
) -> Dict[str, str]:
) -> Dict[Union[str, bytes], Union[str, bytes]]:
...
async def request_async(
address: Tuple[str, int], timeout: float, encoding: str, a2s_proto: Type[T]
) -> Union[SourceInfo, GoldSrcInfo, List[Player], Dict[str, str]]:
) -> Union[SourceInfo, GoldSrcInfo, List[Player], Dict[Union[str, bytes], Union[str, bytes]]]:
conn = await A2SStreamAsync.create(address, timeout)
response = await request_async_impl(conn, encoding, a2s_proto)
conn.close()
@ -113,7 +90,7 @@ async def request_async_impl(
challenge: int = ...,
retries: int = ...,
ping: Optional[float] = ...,
) -> Dict[str, str]:
) -> Dict[Union[str, bytes], Union[str, bytes]]:
...
@ -124,7 +101,7 @@ async def request_async_impl(
challenge: int = 0,
retries: int = 0,
ping: Optional[float] = None,
) -> Union[SourceInfo, GoldSrcInfo, Dict[str, str], List[Player]]:
) -> Union[SourceInfo, GoldSrcInfo, Dict[Union[str, bytes], Union[str, bytes]], List[Player]]:
send_time = time.monotonic()
resp_data = await conn.request(a2s_proto.serialize_request(challenge))
recv_time = time.monotonic()
@ -163,7 +140,7 @@ class A2SProtocol(asyncio.DatagramProtocol):
self.fragment_buf: List[A2SFragment] = []
def connection_made(self, transport: asyncio.DatagramTransport) -> None:
self.transport = transport
self.transport: asyncio.DatagramTransport = transport
def datagram_received(self, data: bytes, addr: Tuple[str, int]) -> None:
header = data[:4]
@ -207,9 +184,9 @@ class A2SStreamAsync:
)
def __init__(self, transport: asyncio.DatagramTransport, protocol: A2SProtocol, timeout: float) -> None:
self.transport = transport
self.protocol = protocol
self.timeout = timeout
self.transport: asyncio.DatagramTransport = transport
self.protocol: A2SProtocol = protocol
self.timeout: float = timeout
def __del__(self) -> None:
self.close()

24
a2s/a2s_fragment.py

@ -1,27 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
import bz2
import io

34
a2s/a2s_sync.py

@ -1,27 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from __future__ import annotations
import io
@ -62,13 +38,15 @@ def request_sync(address: Tuple[str, int], timeout: float, encoding: str, a2s_pr
@overload
def request_sync(address: Tuple[str, int], timeout: float, encoding: str, a2s_proto: Type[RulesProtocol]) -> Dict[str, str]:
def request_sync(
address: Tuple[str, int], timeout: float, encoding: str, a2s_proto: Type[RulesProtocol]
) -> Dict[Union[str, bytes], Union[str, bytes]]:
...
def request_sync(
address: Tuple[str, int], timeout: float, encoding: str, a2s_proto: Type[T]
) -> Union[List[Player], GoldSrcInfo, SourceInfo, Dict[str, str]]:
) -> Union[List[Player], GoldSrcInfo, SourceInfo, Dict[Union[str, bytes], Union[str, bytes]]]:
conn = A2SStream(address, timeout)
response = request_sync_impl(conn, encoding, a2s_proto)
conn.close()
@ -107,13 +85,13 @@ def request_sync_impl(
challenge: int = ...,
retries: int = ...,
ping: Optional[float] = ...,
) -> Dict[str, str]:
) -> Dict[Union[str, bytes], Union[str, bytes]]:
...
def request_sync_impl(
conn: A2SStream, encoding: str, a2s_proto: Type[T], challenge: int = 0, retries: int = 0, ping: Optional[float] = None
) -> Union[SourceInfo, GoldSrcInfo, Dict[str, str], List[Player]]:
) -> Union[SourceInfo, GoldSrcInfo, List[Player], Dict[Union[str, bytes], Union[str, bytes]]]:
send_time = time.monotonic()
resp_data = conn.request(a2s_proto.serialize_request(challenge))
recv_time = time.monotonic()

37
a2s/byteio.py

@ -1,27 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from __future__ import annotations
import io
@ -30,8 +6,6 @@ from typing import TYPE_CHECKING, Any, Optional, Tuple, Union
from a2s.exceptions import BufferExhaustedError
from .defaults import DEFAULT_ENCODING
if TYPE_CHECKING:
from typing_extensions import Literal
@ -108,14 +82,14 @@ class ByteReader:
def read_bool(self) -> bool:
return bool(self.unpack_one("b"))
def read_char(self) -> str:
def read_char(self) -> Union[str, bytes]:
char = self.unpack_one("c")
if self.encoding is not None:
return char.decode(self.encoding, errors="replace")
else:
return char.decode(DEFAULT_ENCODING, errors="replace")
return char
def read_cstring(self, charsize: int = 1) -> str:
def read_cstring(self, charsize: int = 1) -> Union[str, bytes]:
string = b""
while True:
c = self.read(charsize)
@ -127,7 +101,7 @@ class ByteReader:
if self.encoding is not None:
return string.decode(self.encoding, errors="replace")
else:
return string.decode(DEFAULT_ENCODING, errors="replace")
return string
class ByteWriter:
@ -182,8 +156,9 @@ class ByteWriter:
def write_bool(self, val: bool) -> None:
self.pack("b", val)
def write_char(self, val: str) -> None:
def write_char(self, val: Union[str, bytes]) -> None:
if self.encoding is not None:
assert isinstance(val, str)
self.pack("c", val.encode(self.encoding))
else:
self.pack("c", val)

24
a2s/datacls.py

@ -1,28 +1,4 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-----
Cheap dataclasses module backport
Check out the official documentation to see what this is trying to

24
a2s/defaults.py

@ -1,27 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
DEFAULT_TIMEOUT = 3.0
DEFAULT_ENCODING = "utf-8"
DEFAULT_RETRIES = 5

25
a2s/exceptions.py

@ -1,28 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
class BrokenMessageError(Exception):
pass

59
a2s/info.py

@ -1,26 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from __future__ import annotations
from typing import Optional, Tuple, Union
@ -42,16 +19,16 @@ class SourceInfo(metaclass=DataclsMeta):
protocol: int
"""Protocol version used by the server"""
server_name: str
server_name: Union[str, bytes]
"""Display name of the server"""
map_name: str
map_name: Union[str, bytes]
"""The currently loaded map"""
folder: str
folder: Union[str, bytes]
"""Name of the game directory"""
game: str
game: Union[str, bytes]
"""Name of the game"""
app_id: int
@ -66,13 +43,13 @@ class SourceInfo(metaclass=DataclsMeta):
bot_count: int
"""Number of bots on the server"""
server_type: str
server_type: Union[str, bytes]
"""Type of the server:
'd': Dedicated server
'l': Non-dedicated server
'p': SourceTV relay (proxy)"""
platform: str
platform: Union[str, bytes]
"""Operating system of the server
'l', 'w', 'm' for Linux, Windows, macOS"""
@ -82,7 +59,7 @@ class SourceInfo(metaclass=DataclsMeta):
vac_enabled: bool
"""Server has VAC enabled"""
version: str
version: Union[str, bytes]
"""Version of the server software"""
# Optional:
@ -99,10 +76,10 @@ class SourceInfo(metaclass=DataclsMeta):
stv_port: int
"""Port of the SourceTV server"""
stv_name: str
stv_name: Union[str, bytes]
"""Name of the SourceTV server"""
keywords: str
keywords: Union[str, bytes]
"""Tags that describe the gamemode being played"""
game_id: int
@ -134,19 +111,19 @@ class SourceInfo(metaclass=DataclsMeta):
class GoldSrcInfo(metaclass=DataclsMeta):
address: str
address: Union[str, bytes]
"""IP Address and port of the server"""
server_name: str
server_name: Union[str, bytes]
"""Display name of the server"""
map_name: str
map_name: Union[str, bytes]
"""The currently loaded map"""
folder: str
folder: Union[str, bytes]
"""Name of the game directory"""
game: str
game: Union[str, bytes]
"""Name of the game"""
player_count: int
@ -158,13 +135,13 @@ class GoldSrcInfo(metaclass=DataclsMeta):
protocol: int
"""Protocol version used by the server"""
server_type: str
server_type: Union[str, bytes]
"""Type of the server:
'd': Dedicated server
'l': Non-dedicated server
'p': SourceTV relay (proxy)"""
platform: str
platform: Union[str, bytes]
"""Operating system of the server
'l', 'w' for Linux and Windows"""
@ -181,10 +158,10 @@ class GoldSrcInfo(metaclass=DataclsMeta):
"""Number of bots on the server"""
# Optional:
mod_website: str
mod_website: Union[str, bytes]
"""URL to the mod website"""
mod_download: str
mod_download: Union[str, bytes]
"""URL to download the mod"""
mod_version: int

33
a2s/players.py

@ -1,27 +1,3 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from typing import List, Optional, Tuple
from a2s.a2s_async import request_async
@ -34,18 +10,17 @@ A2S_PLAYER_RESPONSE = 0x44
class Player(metaclass=DataclsMeta):
"""Apparently an entry index, but seems to be always 0"""
index: int
"""Apparently an entry index, but seems to be always 0"""
"""Name of the player"""
name: str
"""Name of the player"""
"""Score of the player"""
score: int
"""Score of the player"""
"""Time the player has been connected to the server"""
duration: float
"""Time the player has been connected to the server"""
def players(address: Tuple[str, int], timeout: float = DEFAULT_TIMEOUT, encoding: str = DEFAULT_ENCODING) -> List[Player]:

36
a2s/rules.py

@ -1,28 +1,4 @@
"""
MIT License
Copyright (c) 2020 Gabriel Huber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from typing import Dict, Optional, Tuple
from typing import Dict, Optional, Tuple, Union
from a2s.a2s_async import request_async
from a2s.a2s_sync import request_sync
@ -32,13 +8,15 @@ from a2s.defaults import DEFAULT_ENCODING, DEFAULT_TIMEOUT
A2S_RULES_RESPONSE = 0x45
def rules(address: Tuple[str, int], timeout: float = DEFAULT_TIMEOUT, encoding: str = DEFAULT_ENCODING) -> Dict[str, str]:
def rules(
address: Tuple[str, int], timeout: float = DEFAULT_TIMEOUT, encoding: str = DEFAULT_ENCODING
) -> Dict[Union[str, bytes], Union[str, bytes]]:
return request_sync(address, timeout, encoding, RulesProtocol)
async def arules(
address: Tuple[str, int], timeout: float = DEFAULT_TIMEOUT, encoding: str = DEFAULT_ENCODING
) -> Dict[str, str]:
) -> Dict[Union[str, bytes], Union[str, bytes]]:
return await request_async(address, timeout, encoding, RulesProtocol)
@ -52,7 +30,9 @@ class RulesProtocol:
return b"\x56" + challenge.to_bytes(4, "little")
@staticmethod
def deserialize_response(reader: ByteReader, response_type: int, ping: Optional[float]) -> Dict[str, str]:
def deserialize_response(
reader: ByteReader, response_type: int, ping: Optional[float]
) -> Dict[Union[str, bytes], Union[str, bytes]]:
rule_count = reader.read_int16()
# Have to use tuples to preserve evaluation order
resp = dict((reader.read_cstring(), reader.read_cstring()) for _ in range(rule_count))

2
setup.py

@ -15,7 +15,7 @@ setuptools.setup(
long_description_content_type="text/markdown",
url="https://github.com/Yepoleb/python-a2s",
packages=["a2s"],
package_data={"a2s": ["a2s/py.typed"]},
include_package_data=True,
license="MIT License",
classifiers=[
"Development Status :: 4 - Beta",

Loading…
Cancel
Save