Fix optional type assuming int
This commit is contained in:
parent
bffa9f70cb
commit
df3fcb9b17
|
@ -10,21 +10,56 @@ class ConstantJson(TypedDict):
|
||||||
type: str
|
type: str
|
||||||
value: int
|
value: int
|
||||||
|
|
||||||
class GameEnumValuesJson(TypedDict):
|
class NetEnumValuesJson(TypedDict):
|
||||||
value: str
|
value: str
|
||||||
name: list[str]
|
name: list[str]
|
||||||
|
|
||||||
class GameEnumJson(TypedDict):
|
class NetEnumJson(TypedDict):
|
||||||
name: list[str]
|
name: list[str]
|
||||||
values: list[GameEnumValuesJson]
|
values: list[NetEnumValuesJson]
|
||||||
|
|
||||||
class GameMessageMemberTypeJson(TypedDict):
|
class InnerNetMessageMemberTypeJson(TypedDict):
|
||||||
kind: str
|
# TODO: define this literal as type
|
||||||
|
# so it can be reused
|
||||||
|
kind: Literal[ \
|
||||||
|
'int32', \
|
||||||
|
'tick', \
|
||||||
|
'string', \
|
||||||
|
'raw', \
|
||||||
|
'sha256', \
|
||||||
|
'data', \
|
||||||
|
'rest', \
|
||||||
|
'enum', \
|
||||||
|
'boolean', \
|
||||||
|
'tune_param', \
|
||||||
|
'snapshot_object', \
|
||||||
|
'array', \
|
||||||
|
'flags', \
|
||||||
|
'optional']
|
||||||
|
disallow_cc: bool
|
||||||
|
|
||||||
|
class NetMessageMemberTypeJson(TypedDict):
|
||||||
|
kind: Literal[ \
|
||||||
|
'int32', \
|
||||||
|
'tick', \
|
||||||
|
'string', \
|
||||||
|
'raw', \
|
||||||
|
'sha256', \
|
||||||
|
'data', \
|
||||||
|
'rest', \
|
||||||
|
'enum', \
|
||||||
|
'boolean', \
|
||||||
|
'tune_param', \
|
||||||
|
'snapshot_object', \
|
||||||
|
'array', \
|
||||||
|
'flags', \
|
||||||
|
'optional']
|
||||||
|
inner: InnerNetMessageMemberTypeJson
|
||||||
disallow_cc: bool
|
disallow_cc: bool
|
||||||
|
|
||||||
class NetMessageMemberJson(TypedDict):
|
class NetMessageMemberJson(TypedDict):
|
||||||
name: list[str]
|
name: list[str]
|
||||||
type: GameMessageMemberTypeJson
|
type: NetMessageMemberTypeJson
|
||||||
|
|
||||||
class NetMessageJson(TypedDict):
|
class NetMessageJson(TypedDict):
|
||||||
id: int
|
id: int
|
||||||
|
@ -34,7 +69,7 @@ class NetMessageJson(TypedDict):
|
||||||
|
|
||||||
class SpecJson(TypedDict):
|
class SpecJson(TypedDict):
|
||||||
constants: list[ConstantJson]
|
constants: list[ConstantJson]
|
||||||
game_enumerations: list[GameEnumJson]
|
game_enumerations: list[NetEnumJson]
|
||||||
game_messages: list[NetMessageJson]
|
game_messages: list[NetMessageJson]
|
||||||
system_messages: list[NetMessageJson]
|
system_messages: list[NetMessageJson]
|
||||||
|
|
||||||
|
@ -167,9 +202,15 @@ def generate_msg(msg: NetMessageJson, game: Literal['game', 'system']) -> None:
|
||||||
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
ftype = 'int'
|
ftype = 'int'
|
||||||
default = '0'
|
default = '0'
|
||||||
elif member['type']['kind'] == 'optional': # TODO: think about optionals
|
elif member['type']['kind'] == 'optional':
|
||||||
ftype = 'int'
|
if member['type']['inner']['kind'] == 'string': # TODO: sanitize cc
|
||||||
default = '0'
|
ftype = 'str'
|
||||||
|
default = "''"
|
||||||
|
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||||
|
ftype = 'int'
|
||||||
|
default = '0'
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Error: unknown optional type {member['type']}")
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Error: unknown type {member['type']}")
|
raise ValueError(f"Error: unknown type {member['type']}")
|
||||||
name = name_to_snake(member["name"])
|
name = name_to_snake(member["name"])
|
||||||
|
@ -208,8 +249,13 @@ def generate_msg(msg: NetMessageJson, game: Literal['game', 'system']) -> None:
|
||||||
ftype = 'int'
|
ftype = 'int'
|
||||||
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
ftype = 'int'
|
ftype = 'int'
|
||||||
elif member['type']['kind'] == 'optional': # TODO: think about optionals
|
elif member['type']['kind'] == 'optional':
|
||||||
ftype = 'int'
|
if member['type']['inner']['kind'] == 'string': # TODO: sanitize cc
|
||||||
|
ftype = 'str'
|
||||||
|
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||||
|
ftype = 'int'
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Error: unknown optional type {member['type']}")
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Error: unknown type {member['type']}")
|
raise ValueError(f"Error: unknown type {member['type']}")
|
||||||
name = name_to_snake(member["name"])
|
name = name_to_snake(member["name"])
|
||||||
|
@ -244,8 +290,13 @@ def generate_msg(msg: NetMessageJson, game: Literal['game', 'system']) -> None:
|
||||||
unpacker = 'int() # TODO: this is an array'
|
unpacker = 'int() # TODO: this is an array'
|
||||||
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
unpacker = 'int() # TODO: this is a flag'
|
unpacker = 'int() # TODO: this is a flag'
|
||||||
elif member['type']['kind'] == 'optional': # TODO: think about optional
|
elif member['type']['kind'] == 'optional':
|
||||||
unpacker = 'int() # TODO: this is a optional of type any'
|
# TODO: unpacker should not crash on missing optional fields
|
||||||
|
# check how tw code does it and be smart here
|
||||||
|
if member['type']['inner']['kind'] == 'string': # TODO: sanitize cc
|
||||||
|
unpacker = 'str() # TODO: warning this can fail because it is an optional field'
|
||||||
|
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||||
|
unpacker = 'int() # TODO: warning this can fail because it is an optional field'
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Error: unknown type {member['type']}")
|
raise ValueError(f"Error: unknown type {member['type']}")
|
||||||
name = name_to_snake(member["name"])
|
name = name_to_snake(member["name"])
|
||||||
|
@ -279,8 +330,11 @@ def get_dependencies(msg: NetMessageJson) -> str:
|
||||||
packer_deps.append('pack_int')
|
packer_deps.append('pack_int')
|
||||||
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
packer_deps.append('pack_int')
|
packer_deps.append('pack_int')
|
||||||
elif member['type']['kind'] == 'optional': # TODO: think about optional
|
elif member['type']['kind'] == 'optional':
|
||||||
packer_deps.append('pack_int')
|
if member['type']['inner']['kind'] == 'string':
|
||||||
|
packer_deps.append('pack_str')
|
||||||
|
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||||
|
packer_deps.append('pack_int')
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Error: unknown type {member['type']}")
|
raise ValueError(f"Error: unknown type {member['type']}")
|
||||||
if len(packer_deps) == 0:
|
if len(packer_deps) == 0:
|
||||||
|
@ -314,8 +368,14 @@ def pack_field(member: NetMessageMemberJson) -> str:
|
||||||
packer = 'int'
|
packer = 'int'
|
||||||
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
packer = 'int'
|
packer = 'int'
|
||||||
elif member['type']['kind'] == 'optional': # TODO: think about optional
|
elif member['type']['kind'] == 'optional':
|
||||||
packer = 'int'
|
packer = 'int'
|
||||||
|
# TODO: unpacker should allow not packing optional fields
|
||||||
|
# check how tw code does it and be smart here
|
||||||
|
if member['type']['inner']['kind'] == 'string': # TODO: sanitize cc
|
||||||
|
packer = 'str'
|
||||||
|
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||||
|
packer = 'int'
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Error: unknown type {member['type']}")
|
raise ValueError(f"Error: unknown type {member['type']}")
|
||||||
return f'pack_{packer}({field})'
|
return f'pack_{packer}({field})'
|
||||||
|
|
|
@ -9,7 +9,7 @@ class MsgInfo(PrettyPrint):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
version: str = 'default',
|
version: str = 'default',
|
||||||
password: int = 0,
|
password: str = '',
|
||||||
client_version: int = 0
|
client_version: int = 0
|
||||||
) -> None:
|
) -> None:
|
||||||
self.message_name = 'info'
|
self.message_name = 'info'
|
||||||
|
@ -17,7 +17,7 @@ class MsgInfo(PrettyPrint):
|
||||||
self.header: ChunkHeader
|
self.header: ChunkHeader
|
||||||
|
|
||||||
self.version: str = version
|
self.version: str = version
|
||||||
self.password: int = password
|
self.password: str = password
|
||||||
self.client_version: int = client_version
|
self.client_version: int = client_version
|
||||||
|
|
||||||
# first byte of data
|
# first byte of data
|
||||||
|
@ -26,11 +26,11 @@ class MsgInfo(PrettyPrint):
|
||||||
def unpack(self, data: bytes) -> bool:
|
def unpack(self, data: bytes) -> bool:
|
||||||
unpacker = Unpacker(data)
|
unpacker = Unpacker(data)
|
||||||
self.version = unpacker.get_str()
|
self.version = unpacker.get_str()
|
||||||
self.password = unpacker.get_int() # TODO: this is a optional of type any
|
self.password = unpacker.get_str() # TODO: warning this can fail because it is an optional field
|
||||||
self.client_version = unpacker.get_int() # TODO: this is a optional of type any
|
self.client_version = unpacker.get_int() # TODO: warning this can fail because it is an optional field
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pack(self) -> bytes:
|
def pack(self) -> bytes:
|
||||||
return pack_str(self.version) + \
|
return pack_str(self.version) + \
|
||||||
pack_int(self.password) + \
|
pack_str(self.password) + \
|
||||||
pack_int(self.client_version)
|
pack_int(self.client_version)
|
Loading…
Reference in a new issue