Core: move MultiServer.py and CommonClient.py to orjson

This commit is contained in:
Fabian Dill
2025-08-03 08:20:21 +02:00
parent 84c2d70d9a
commit c6df02a355
5 changed files with 70 additions and 59 deletions

View File

@@ -31,6 +31,7 @@ if typing.TYPE_CHECKING:
from NetUtils import ServerConnection
import colorama
import orjson
import websockets
from websockets.extensions.permessage_deflate import PerMessageDeflate
try:
@@ -41,9 +42,9 @@ except ImportError:
import NetUtils
import Utils
from Utils import version_tuple, restricted_loads, Version, async_start, get_intended_text
from Utils import version_tuple, restricted_loads, Version, async_start, get_intended_text, __version__
from NetUtils import Endpoint, ClientStatus, NetworkItem, decode, encode, NetworkPlayer, Permission, NetworkSlot, \
SlotType, LocationStore, MultiData, Hint, HintStatus
SlotType, LocationStore, MultiData, Hint, HintStatus, encode_to_bytes
from BaseClasses import ItemClassification
@@ -169,7 +170,7 @@ team_slot = typing.Tuple[int, int]
class Context:
dumper = staticmethod(encode)
dumper = staticmethod(encode_to_bytes)
loader = staticmethod(decode)
simple_options = {"hint_cost": int,
@@ -453,7 +454,7 @@ class Context:
self.read_data["race_mode"] = lambda: decoded_obj.get("race_mode", 0)
mdata_ver = decoded_obj["minimum_versions"]["server"]
if mdata_ver > version_tuple:
raise RuntimeError(f"Supplied Multidata (.archipelago) requires a server of at least version {mdata_ver},"
raise RuntimeError(f"Supplied Multidata (.archipelago) requires a server of at least version {mdata_ver}, "
f"however this server is of version {version_tuple}")
self.generator_version = Version(*decoded_obj["version"])
clients_ver = decoded_obj["minimum_versions"].get("clients", {})
@@ -490,6 +491,10 @@ class Context:
self.locations = LocationStore(decoded_obj.pop("locations")) # pre-emptively free memory
self.slot_data = decoded_obj['slot_data']
for slot, data in self.slot_data.items():
if not isinstance(data, bytes):
data = encode_to_bytes(data)
data = orjson.Fragment(data)
self.slot_data[slot] = data
self.read_data[f"slot_data_{slot}"] = lambda data=data: data
self.er_hint_data = {int(player): {int(address): name for address, name in loc_data.items()}
for player, loc_data in decoded_obj["er_hint_data"].items()}
@@ -1786,11 +1791,11 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
if cmd == 'Connect':
if not args or 'password' not in args or type(args['password']) not in [str, type(None)] or \
'game' not in args:
'game' not in args or "version" not in args:
await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments", 'text': 'Connect',
"original_cmd": cmd}])
return
args["version"] = Version.from_network_dict(args["version"])
errors = set()
if ctx.password and args['password'] != ctx.password:
errors.add('InvalidPassword')
@@ -1806,7 +1811,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
if not ignore_game and args['game'] != game:
errors.add('InvalidGame')
minver = min_client_version if ignore_game else ctx.minimum_client_versions[slot]
if minver > args['version']:
if minver > args["version"]:
errors.add('IncompatibleVersion')
try:
client.items_handling = args['items_handling']
@@ -1814,7 +1819,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
errors.add('InvalidItemsHandling')
# only exact version match allowed
if ctx.compatibility == 0 and args['version'] != version_tuple:
if ctx.compatibility == 0 and args['version'] != Version(__version__):
errors.add('IncompatibleVersion')
if errors:
ctx.logger.info(f"A client connection was refused due to: {errors}, the sent connect information was {args}.")