diff --git a/shroudstone/replay/parser.py b/shroudstone/replay/parser.py index 2a40cd4..625ba5b 100755 --- a/shroudstone/replay/parser.py +++ b/shroudstone/replay/parser.py @@ -238,6 +238,19 @@ def process(self, chunk: pb.ReplayChunk): f"Putting player {client_id} in pre-assigned slot {client.slot_number}" ) + elif isinstance(msg, pb.PlayerAlt): + client = self.clients[client_id] + if msg.name.nickname and client.nickname is None: + client.nickname = msg.name.nickname + logger.debug( + f"Filling in player {client_id} nickname: {client.nickname} {client.uuid}" + ) + if msg.name.discriminator and client.discriminator is None: + client.discriminator = msg.name.discriminator + logger.debug( + f"Filling in player {client_id} discriminator: {client.discriminator} {client.uuid}" + ) + elif isinstance(msg, pb.ClientConnected): if not msg.HasField("uuid"): # We should have already filled in the player details in handle_player, diff --git a/shroudstone/replay/stormgate_pb2.py b/shroudstone/replay/stormgate_pb2.py index 5332e3f..bebe835 100644 --- a/shroudstone/replay/stormgate_pb2.py +++ b/shroudstone/replay/stormgate_pb2.py @@ -1,22 +1,11 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: stormgate.proto -# Protobuf Python Version: 5.27.3 """Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 27, - 3, - '', - 'stormgate.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -24,47 +13,51 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fstormgate.proto\x12\tstormgate\"\x9e\x05\n\x0bReplayChunk\x12\x11\n\ttimestamp\x18\x01 \x01(\x05\x12\x11\n\tclient_id\x18\x02 \x01(\x05\x12-\n\x05inner\x18\x03 \x01(\x0b\x32\x1e.stormgate.ReplayChunk.Wrapper\x1a\xb9\x04\n\x07Wrapper\x12=\n\x07\x63ontent\x18\x01 \x01(\x0b\x32,.stormgate.ReplayChunk.Wrapper.ReplayContent\x1a\xee\x03\n\rReplayContent\x12,\n\x0bmap_details\x18\x03 \x01(\x0b\x32\x15.stormgate.MapDetailsH\x00\x12\x36\n\x10\x63lient_connected\x18\x04 \x01(\x0b\x32\x1a.stormgate.ClientConnectedH\x00\x12#\n\x06player\x18\x0c \x01(\x0b\x32\x11.stormgate.PlayerH\x00\x12\x31\n\x0b\x63hange_slot\x18\r \x01(\x0b\x32\x1a.stormgate.LobbyChangeSlotH\x00\x12\x33\n\x0cset_variable\x18\x0f \x01(\x0b\x32\x1b.stormgate.LobbySetVariableH\x00\x12*\n\nstart_game\x18\x12 \x01(\x0b\x32\x14.stormgate.StartGameH\x00\x12\x35\n\x10player_left_game\x18\x19 \x01(\x0b\x32\x19.stormgate.PlayerLeftGameH\x00\x12<\n\x13\x63lient_disconnected\x18\x1f \x01(\x0b\x32\x1d.stormgate.ClientDisconnectedH\x00\x12\x39\n\x12\x61ssign_player_slot\x18% \x01(\x0b\x32\x1b.stormgate.AssignPlayerSlotH\x00\x42\x0e\n\x0c\x63ontent_type\"n\n\nMapDetails\x12\x12\n\nmap_folder\x18\x01 \x01(\t\x12\x10\n\x08map_name\x18\x02 \x01(\t\x12\x10\n\x08map_seed\x18\x03 \x01(\x05\x12(\n\nmatch_type\x18\x07 \x01(\x0e\x32\x14.stormgate.MatchType\"C\n\x0f\x43lientConnected\x12\x11\n\tclient_id\x18\x01 \x01(\x05\x12\x1d\n\x04uuid\x18\x02 \x01(\x0b\x32\x0f.stormgate.UUID\"\x8a\x01\n\x06Player\x12\x1d\n\x04uuid\x18\x02 \x01(\x0b\x32\x0f.stormgate.UUID\x12*\n\x04name\x18\x03 \x01(\x0b\x32\x1c.stormgate.Player.PlayerName\x1a\x35\n\nPlayerName\x12\x10\n\x08nickname\x18\x01 \x01(\t\x12\x15\n\rdiscriminator\x18\x02 \x01(\t\"\xd1\x01\n\x0fLobbyChangeSlot\x12\x35\n\x06\x63hoice\x18\x01 \x01(\x0b\x32%.stormgate.LobbyChangeSlot.SlotChoice\x1a\x86\x01\n\nSlotChoice\x12K\n\rspecific_slot\x18\x02 \x01(\x0b\x32\x32.stormgate.LobbyChangeSlot.SlotChoice.SpecificSlotH\x00\x1a\x1c\n\x0cSpecificSlot\x12\x0c\n\x04slot\x18\x01 \x01(\x05\x42\r\n\x0b\x63hoice_type\"D\n\x10LobbySetVariable\x12\x0c\n\x04slot\x18\x03 \x01(\x05\x12\x13\n\x0bvariable_id\x18\x04 \x01(\r\x12\r\n\x05value\x18\x05 \x01(\r\"\x0b\n\tStartGame\"^\n\x0ePlayerLeftGame\x12$\n\x0bplayer_uuid\x18\x01 \x01(\x0b\x32\x0f.stormgate.UUID\x12&\n\x06reason\x18\x02 \x01(\x0e\x32\x16.stormgate.LeaveReason\"u\n\x12\x43lientDisconnected\x12\x11\n\tclient_id\x18\x01 \x01(\x05\x12&\n\x06reason\x18\x02 \x01(\x0e\x32\x16.stormgate.LeaveReason\x12$\n\x0bplayer_uuid\x18\x03 \x01(\x0b\x32\x0f.stormgate.UUID\"Q\n\x10\x41ssignPlayerSlot\x12\x1d\n\x04uuid\x18\x01 \x01(\x0b\x32\x0f.stormgate.UUID\x12\x0c\n\x04slot\x18\x02 \x01(\x03\x12\x10\n\x08nickname\x18\x03 \x01(\t\"$\n\x04UUID\x12\r\n\x05part1\x18\x01 \x01(\x04\x12\r\n\x05part2\x18\x02 \x01(\x04*I\n\tMatchType\x12\x14\n\x10UnknownMatchType\x10\x00\x12\n\n\x06\x43ustom\x10\x01\x12\r\n\tRanked1v1\x10\x02\x12\x0b\n\x07\x43oop3vE\x10\x03*J\n\x0bLeaveReason\x12\x11\n\rUnknownReason\x10\x00\x12\r\n\tSurrender\x10\x01\x12\t\n\x05Leave\x10\x02\x12\x0e\n\nDisconnect\x10\x03\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fstormgate.proto\x12\tstormgate\"\xca\x05\n\x0bReplayChunk\x12\x11\n\ttimestamp\x18\x01 \x01(\x05\x12\x11\n\tclient_id\x18\x02 \x01(\x05\x12-\n\x05inner\x18\x03 \x01(\x0b\x32\x1e.stormgate.ReplayChunk.Wrapper\x1a\xe5\x04\n\x07Wrapper\x12=\n\x07\x63ontent\x18\x01 \x01(\x0b\x32,.stormgate.ReplayChunk.Wrapper.ReplayContent\x1a\x9a\x04\n\rReplayContent\x12,\n\x0bmap_details\x18\x03 \x01(\x0b\x32\x15.stormgate.MapDetailsH\x00\x12\x36\n\x10\x63lient_connected\x18\x04 \x01(\x0b\x32\x1a.stormgate.ClientConnectedH\x00\x12#\n\x06player\x18\x0c \x01(\x0b\x32\x11.stormgate.PlayerH\x00\x12\x31\n\x0b\x63hange_slot\x18\r \x01(\x0b\x32\x1a.stormgate.LobbyChangeSlotH\x00\x12\x33\n\x0cset_variable\x18\x0f \x01(\x0b\x32\x1b.stormgate.LobbySetVariableH\x00\x12*\n\nstart_game\x18\x12 \x01(\x0b\x32\x14.stormgate.StartGameH\x00\x12\x35\n\x10player_left_game\x18\x19 \x01(\x0b\x32\x19.stormgate.PlayerLeftGameH\x00\x12<\n\x13\x63lient_disconnected\x18\x1f \x01(\x0b\x32\x1d.stormgate.ClientDisconnectedH\x00\x12\x39\n\x12\x61ssign_player_slot\x18% \x01(\x0b\x32\x1b.stormgate.AssignPlayerSlotH\x00\x12*\n\nplayer_alt\x18- \x01(\x0b\x32\x14.stormgate.PlayerAltH\x00\x42\x0e\n\x0c\x63ontent_type\"n\n\nMapDetails\x12\x12\n\nmap_folder\x18\x01 \x01(\t\x12\x10\n\x08map_name\x18\x02 \x01(\t\x12\x10\n\x08map_seed\x18\x03 \x01(\x05\x12(\n\nmatch_type\x18\x07 \x01(\x0e\x32\x14.stormgate.MatchType\"C\n\x0f\x43lientConnected\x12\x11\n\tclient_id\x18\x01 \x01(\x05\x12\x1d\n\x04uuid\x18\x02 \x01(\x0b\x32\x0f.stormgate.UUID\"\x8a\x01\n\x06Player\x12\x1d\n\x04uuid\x18\x02 \x01(\x0b\x32\x0f.stormgate.UUID\x12*\n\x04name\x18\x03 \x01(\x0b\x32\x1c.stormgate.Player.PlayerName\x1a\x35\n\nPlayerName\x12\x10\n\x08nickname\x18\x01 \x01(\t\x12\x15\n\rdiscriminator\x18\x02 \x01(\t\"\xd1\x01\n\x0fLobbyChangeSlot\x12\x35\n\x06\x63hoice\x18\x01 \x01(\x0b\x32%.stormgate.LobbyChangeSlot.SlotChoice\x1a\x86\x01\n\nSlotChoice\x12K\n\rspecific_slot\x18\x02 \x01(\x0b\x32\x32.stormgate.LobbyChangeSlot.SlotChoice.SpecificSlotH\x00\x1a\x1c\n\x0cSpecificSlot\x12\x0c\n\x04slot\x18\x01 \x01(\x05\x42\r\n\x0b\x63hoice_type\"D\n\x10LobbySetVariable\x12\x0c\n\x04slot\x18\x03 \x01(\x05\x12\x13\n\x0bvariable_id\x18\x04 \x01(\r\x12\r\n\x05value\x18\x05 \x01(\r\"\x0b\n\tStartGame\"^\n\x0ePlayerLeftGame\x12$\n\x0bplayer_uuid\x18\x01 \x01(\x0b\x32\x0f.stormgate.UUID\x12&\n\x06reason\x18\x02 \x01(\x0e\x32\x16.stormgate.LeaveReason\"u\n\x12\x43lientDisconnected\x12\x11\n\tclient_id\x18\x01 \x01(\x05\x12&\n\x06reason\x18\x02 \x01(\x0e\x32\x16.stormgate.LeaveReason\x12$\n\x0bplayer_uuid\x18\x03 \x01(\x0b\x32\x0f.stormgate.UUID\"Q\n\x10\x41ssignPlayerSlot\x12\x1d\n\x04uuid\x18\x01 \x01(\x0b\x32\x0f.stormgate.UUID\x12\x0c\n\x04slot\x18\x02 \x01(\x03\x12\x10\n\x08nickname\x18\x03 \x01(\t\"w\n\tPlayerAlt\x12\x30\n\x04name\x18\x05 \x01(\x0b\x32\".stormgate.PlayerAlt.PlayerNameAlt\x1a\x38\n\rPlayerNameAlt\x12\x10\n\x08nickname\x18\x01 \x01(\t\x12\x15\n\rdiscriminator\x18\x02 \x01(\t\"$\n\x04UUID\x12\r\n\x05part1\x18\x01 \x01(\x04\x12\r\n\x05part2\x18\x02 \x01(\x04*I\n\tMatchType\x12\x14\n\x10UnknownMatchType\x10\x00\x12\n\n\x06\x43ustom\x10\x01\x12\r\n\tRanked1v1\x10\x02\x12\x0b\n\x07\x43oop3vE\x10\x03*J\n\x0bLeaveReason\x12\x11\n\rUnknownReason\x10\x00\x12\r\n\tSurrender\x10\x01\x12\t\n\x05Leave\x10\x02\x12\x0e\n\nDisconnect\x10\x03\x62\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'stormgate_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'stormgate_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - DESCRIPTOR._loaded_options = None - _globals['_MATCHTYPE']._serialized_start=1656 - _globals['_MATCHTYPE']._serialized_end=1729 - _globals['_LEAVEREASON']._serialized_start=1731 - _globals['_LEAVEREASON']._serialized_end=1805 - _globals['_REPLAYCHUNK']._serialized_start=31 - _globals['_REPLAYCHUNK']._serialized_end=701 - _globals['_REPLAYCHUNK_WRAPPER']._serialized_start=132 - _globals['_REPLAYCHUNK_WRAPPER']._serialized_end=701 - _globals['_REPLAYCHUNK_WRAPPER_REPLAYCONTENT']._serialized_start=207 - _globals['_REPLAYCHUNK_WRAPPER_REPLAYCONTENT']._serialized_end=701 - _globals['_MAPDETAILS']._serialized_start=703 - _globals['_MAPDETAILS']._serialized_end=813 - _globals['_CLIENTCONNECTED']._serialized_start=815 - _globals['_CLIENTCONNECTED']._serialized_end=882 - _globals['_PLAYER']._serialized_start=885 - _globals['_PLAYER']._serialized_end=1023 - _globals['_PLAYER_PLAYERNAME']._serialized_start=970 - _globals['_PLAYER_PLAYERNAME']._serialized_end=1023 - _globals['_LOBBYCHANGESLOT']._serialized_start=1026 - _globals['_LOBBYCHANGESLOT']._serialized_end=1235 - _globals['_LOBBYCHANGESLOT_SLOTCHOICE']._serialized_start=1101 - _globals['_LOBBYCHANGESLOT_SLOTCHOICE']._serialized_end=1235 - _globals['_LOBBYCHANGESLOT_SLOTCHOICE_SPECIFICSLOT']._serialized_start=1192 - _globals['_LOBBYCHANGESLOT_SLOTCHOICE_SPECIFICSLOT']._serialized_end=1220 - _globals['_LOBBYSETVARIABLE']._serialized_start=1237 - _globals['_LOBBYSETVARIABLE']._serialized_end=1305 - _globals['_STARTGAME']._serialized_start=1307 - _globals['_STARTGAME']._serialized_end=1318 - _globals['_PLAYERLEFTGAME']._serialized_start=1320 - _globals['_PLAYERLEFTGAME']._serialized_end=1414 - _globals['_CLIENTDISCONNECTED']._serialized_start=1416 - _globals['_CLIENTDISCONNECTED']._serialized_end=1533 - _globals['_ASSIGNPLAYERSLOT']._serialized_start=1535 - _globals['_ASSIGNPLAYERSLOT']._serialized_end=1616 - _globals['_UUID']._serialized_start=1618 - _globals['_UUID']._serialized_end=1654 + DESCRIPTOR._options = None + _MATCHTYPE._serialized_start=1821 + _MATCHTYPE._serialized_end=1894 + _LEAVEREASON._serialized_start=1896 + _LEAVEREASON._serialized_end=1970 + _REPLAYCHUNK._serialized_start=31 + _REPLAYCHUNK._serialized_end=745 + _REPLAYCHUNK_WRAPPER._serialized_start=132 + _REPLAYCHUNK_WRAPPER._serialized_end=745 + _REPLAYCHUNK_WRAPPER_REPLAYCONTENT._serialized_start=207 + _REPLAYCHUNK_WRAPPER_REPLAYCONTENT._serialized_end=745 + _MAPDETAILS._serialized_start=747 + _MAPDETAILS._serialized_end=857 + _CLIENTCONNECTED._serialized_start=859 + _CLIENTCONNECTED._serialized_end=926 + _PLAYER._serialized_start=929 + _PLAYER._serialized_end=1067 + _PLAYER_PLAYERNAME._serialized_start=1014 + _PLAYER_PLAYERNAME._serialized_end=1067 + _LOBBYCHANGESLOT._serialized_start=1070 + _LOBBYCHANGESLOT._serialized_end=1279 + _LOBBYCHANGESLOT_SLOTCHOICE._serialized_start=1145 + _LOBBYCHANGESLOT_SLOTCHOICE._serialized_end=1279 + _LOBBYCHANGESLOT_SLOTCHOICE_SPECIFICSLOT._serialized_start=1236 + _LOBBYCHANGESLOT_SLOTCHOICE_SPECIFICSLOT._serialized_end=1264 + _LOBBYSETVARIABLE._serialized_start=1281 + _LOBBYSETVARIABLE._serialized_end=1349 + _STARTGAME._serialized_start=1351 + _STARTGAME._serialized_end=1362 + _PLAYERLEFTGAME._serialized_start=1364 + _PLAYERLEFTGAME._serialized_end=1458 + _CLIENTDISCONNECTED._serialized_start=1460 + _CLIENTDISCONNECTED._serialized_end=1577 + _ASSIGNPLAYERSLOT._serialized_start=1579 + _ASSIGNPLAYERSLOT._serialized_end=1660 + _PLAYERALT._serialized_start=1662 + _PLAYERALT._serialized_end=1781 + _PLAYERALT_PLAYERNAMEALT._serialized_start=1725 + _PLAYERALT_PLAYERNAMEALT._serialized_end=1781 + _UUID._serialized_start=1783 + _UUID._serialized_end=1819 # @@protoc_insertion_point(module_scope) diff --git a/shroudstone/replay/stormgate_pb2.pyi b/shroudstone/replay/stormgate_pb2.pyi index 15608db..3cf4934 100644 --- a/shroudstone/replay/stormgate_pb2.pyi +++ b/shroudstone/replay/stormgate_pb2.pyi @@ -3,107 +3,50 @@ from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union -DESCRIPTOR: _descriptor.FileDescriptor - -class MatchType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UnknownMatchType: _ClassVar[MatchType] - Custom: _ClassVar[MatchType] - Ranked1v1: _ClassVar[MatchType] - Coop3vE: _ClassVar[MatchType] - -class LeaveReason(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UnknownReason: _ClassVar[LeaveReason] - Surrender: _ClassVar[LeaveReason] - Leave: _ClassVar[LeaveReason] - Disconnect: _ClassVar[LeaveReason] -UnknownMatchType: MatchType +Coop3vE: MatchType Custom: MatchType +DESCRIPTOR: _descriptor.FileDescriptor +Disconnect: LeaveReason +Leave: LeaveReason Ranked1v1: MatchType -Coop3vE: MatchType -UnknownReason: LeaveReason Surrender: LeaveReason -Leave: LeaveReason -Disconnect: LeaveReason - -class ReplayChunk(_message.Message): - __slots__ = ("timestamp", "client_id", "inner") - class Wrapper(_message.Message): - __slots__ = ("content",) - class ReplayContent(_message.Message): - __slots__ = ("map_details", "client_connected", "player", "change_slot", "set_variable", "start_game", "player_left_game", "client_disconnected", "assign_player_slot") - MAP_DETAILS_FIELD_NUMBER: _ClassVar[int] - CLIENT_CONNECTED_FIELD_NUMBER: _ClassVar[int] - PLAYER_FIELD_NUMBER: _ClassVar[int] - CHANGE_SLOT_FIELD_NUMBER: _ClassVar[int] - SET_VARIABLE_FIELD_NUMBER: _ClassVar[int] - START_GAME_FIELD_NUMBER: _ClassVar[int] - PLAYER_LEFT_GAME_FIELD_NUMBER: _ClassVar[int] - CLIENT_DISCONNECTED_FIELD_NUMBER: _ClassVar[int] - ASSIGN_PLAYER_SLOT_FIELD_NUMBER: _ClassVar[int] - map_details: MapDetails - client_connected: ClientConnected - player: Player - change_slot: LobbyChangeSlot - set_variable: LobbySetVariable - start_game: StartGame - player_left_game: PlayerLeftGame - client_disconnected: ClientDisconnected - assign_player_slot: AssignPlayerSlot - def __init__(self, map_details: _Optional[_Union[MapDetails, _Mapping]] = ..., client_connected: _Optional[_Union[ClientConnected, _Mapping]] = ..., player: _Optional[_Union[Player, _Mapping]] = ..., change_slot: _Optional[_Union[LobbyChangeSlot, _Mapping]] = ..., set_variable: _Optional[_Union[LobbySetVariable, _Mapping]] = ..., start_game: _Optional[_Union[StartGame, _Mapping]] = ..., player_left_game: _Optional[_Union[PlayerLeftGame, _Mapping]] = ..., client_disconnected: _Optional[_Union[ClientDisconnected, _Mapping]] = ..., assign_player_slot: _Optional[_Union[AssignPlayerSlot, _Mapping]] = ...) -> None: ... - CONTENT_FIELD_NUMBER: _ClassVar[int] - content: ReplayChunk.Wrapper.ReplayContent - def __init__(self, content: _Optional[_Union[ReplayChunk.Wrapper.ReplayContent, _Mapping]] = ...) -> None: ... - TIMESTAMP_FIELD_NUMBER: _ClassVar[int] - CLIENT_ID_FIELD_NUMBER: _ClassVar[int] - INNER_FIELD_NUMBER: _ClassVar[int] - timestamp: int - client_id: int - inner: ReplayChunk.Wrapper - def __init__(self, timestamp: _Optional[int] = ..., client_id: _Optional[int] = ..., inner: _Optional[_Union[ReplayChunk.Wrapper, _Mapping]] = ...) -> None: ... +UnknownMatchType: MatchType +UnknownReason: LeaveReason -class MapDetails(_message.Message): - __slots__ = ("map_folder", "map_name", "map_seed", "match_type") - MAP_FOLDER_FIELD_NUMBER: _ClassVar[int] - MAP_NAME_FIELD_NUMBER: _ClassVar[int] - MAP_SEED_FIELD_NUMBER: _ClassVar[int] - MATCH_TYPE_FIELD_NUMBER: _ClassVar[int] - map_folder: str - map_name: str - map_seed: int - match_type: MatchType - def __init__(self, map_folder: _Optional[str] = ..., map_name: _Optional[str] = ..., map_seed: _Optional[int] = ..., match_type: _Optional[_Union[MatchType, str]] = ...) -> None: ... +class AssignPlayerSlot(_message.Message): + __slots__ = ["nickname", "slot", "uuid"] + NICKNAME_FIELD_NUMBER: _ClassVar[int] + SLOT_FIELD_NUMBER: _ClassVar[int] + UUID_FIELD_NUMBER: _ClassVar[int] + nickname: str + slot: int + uuid: UUID + def __init__(self, uuid: _Optional[_Union[UUID, _Mapping]] = ..., slot: _Optional[int] = ..., nickname: _Optional[str] = ...) -> None: ... class ClientConnected(_message.Message): - __slots__ = ("client_id", "uuid") + __slots__ = ["client_id", "uuid"] CLIENT_ID_FIELD_NUMBER: _ClassVar[int] UUID_FIELD_NUMBER: _ClassVar[int] client_id: int uuid: UUID def __init__(self, client_id: _Optional[int] = ..., uuid: _Optional[_Union[UUID, _Mapping]] = ...) -> None: ... -class Player(_message.Message): - __slots__ = ("uuid", "name") - class PlayerName(_message.Message): - __slots__ = ("nickname", "discriminator") - NICKNAME_FIELD_NUMBER: _ClassVar[int] - DISCRIMINATOR_FIELD_NUMBER: _ClassVar[int] - nickname: str - discriminator: str - def __init__(self, nickname: _Optional[str] = ..., discriminator: _Optional[str] = ...) -> None: ... - UUID_FIELD_NUMBER: _ClassVar[int] - NAME_FIELD_NUMBER: _ClassVar[int] - uuid: UUID - name: Player.PlayerName - def __init__(self, uuid: _Optional[_Union[UUID, _Mapping]] = ..., name: _Optional[_Union[Player.PlayerName, _Mapping]] = ...) -> None: ... +class ClientDisconnected(_message.Message): + __slots__ = ["client_id", "player_uuid", "reason"] + CLIENT_ID_FIELD_NUMBER: _ClassVar[int] + PLAYER_UUID_FIELD_NUMBER: _ClassVar[int] + REASON_FIELD_NUMBER: _ClassVar[int] + client_id: int + player_uuid: UUID + reason: LeaveReason + def __init__(self, client_id: _Optional[int] = ..., reason: _Optional[_Union[LeaveReason, str]] = ..., player_uuid: _Optional[_Union[UUID, _Mapping]] = ...) -> None: ... class LobbyChangeSlot(_message.Message): - __slots__ = ("choice",) + __slots__ = ["choice"] class SlotChoice(_message.Message): - __slots__ = ("specific_slot",) + __slots__ = ["specific_slot"] class SpecificSlot(_message.Message): - __slots__ = ("slot",) + __slots__ = ["slot"] SLOT_FIELD_NUMBER: _ClassVar[int] slot: int def __init__(self, slot: _Optional[int] = ...) -> None: ... @@ -115,51 +58,115 @@ class LobbyChangeSlot(_message.Message): def __init__(self, choice: _Optional[_Union[LobbyChangeSlot.SlotChoice, _Mapping]] = ...) -> None: ... class LobbySetVariable(_message.Message): - __slots__ = ("slot", "variable_id", "value") + __slots__ = ["slot", "value", "variable_id"] SLOT_FIELD_NUMBER: _ClassVar[int] - VARIABLE_ID_FIELD_NUMBER: _ClassVar[int] VALUE_FIELD_NUMBER: _ClassVar[int] + VARIABLE_ID_FIELD_NUMBER: _ClassVar[int] slot: int - variable_id: int value: int + variable_id: int def __init__(self, slot: _Optional[int] = ..., variable_id: _Optional[int] = ..., value: _Optional[int] = ...) -> None: ... -class StartGame(_message.Message): - __slots__ = () - def __init__(self) -> None: ... +class MapDetails(_message.Message): + __slots__ = ["map_folder", "map_name", "map_seed", "match_type"] + MAP_FOLDER_FIELD_NUMBER: _ClassVar[int] + MAP_NAME_FIELD_NUMBER: _ClassVar[int] + MAP_SEED_FIELD_NUMBER: _ClassVar[int] + MATCH_TYPE_FIELD_NUMBER: _ClassVar[int] + map_folder: str + map_name: str + map_seed: int + match_type: MatchType + def __init__(self, map_folder: _Optional[str] = ..., map_name: _Optional[str] = ..., map_seed: _Optional[int] = ..., match_type: _Optional[_Union[MatchType, str]] = ...) -> None: ... + +class Player(_message.Message): + __slots__ = ["name", "uuid"] + class PlayerName(_message.Message): + __slots__ = ["discriminator", "nickname"] + DISCRIMINATOR_FIELD_NUMBER: _ClassVar[int] + NICKNAME_FIELD_NUMBER: _ClassVar[int] + discriminator: str + nickname: str + def __init__(self, nickname: _Optional[str] = ..., discriminator: _Optional[str] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + UUID_FIELD_NUMBER: _ClassVar[int] + name: Player.PlayerName + uuid: UUID + def __init__(self, uuid: _Optional[_Union[UUID, _Mapping]] = ..., name: _Optional[_Union[Player.PlayerName, _Mapping]] = ...) -> None: ... + +class PlayerAlt(_message.Message): + __slots__ = ["name"] + class PlayerNameAlt(_message.Message): + __slots__ = ["discriminator", "nickname"] + DISCRIMINATOR_FIELD_NUMBER: _ClassVar[int] + NICKNAME_FIELD_NUMBER: _ClassVar[int] + discriminator: str + nickname: str + def __init__(self, nickname: _Optional[str] = ..., discriminator: _Optional[str] = ...) -> None: ... + NAME_FIELD_NUMBER: _ClassVar[int] + name: PlayerAlt.PlayerNameAlt + def __init__(self, name: _Optional[_Union[PlayerAlt.PlayerNameAlt, _Mapping]] = ...) -> None: ... class PlayerLeftGame(_message.Message): - __slots__ = ("player_uuid", "reason") + __slots__ = ["player_uuid", "reason"] PLAYER_UUID_FIELD_NUMBER: _ClassVar[int] REASON_FIELD_NUMBER: _ClassVar[int] player_uuid: UUID reason: LeaveReason def __init__(self, player_uuid: _Optional[_Union[UUID, _Mapping]] = ..., reason: _Optional[_Union[LeaveReason, str]] = ...) -> None: ... -class ClientDisconnected(_message.Message): - __slots__ = ("client_id", "reason", "player_uuid") +class ReplayChunk(_message.Message): + __slots__ = ["client_id", "inner", "timestamp"] + class Wrapper(_message.Message): + __slots__ = ["content"] + class ReplayContent(_message.Message): + __slots__ = ["assign_player_slot", "change_slot", "client_connected", "client_disconnected", "map_details", "player", "player_alt", "player_left_game", "set_variable", "start_game"] + ASSIGN_PLAYER_SLOT_FIELD_NUMBER: _ClassVar[int] + CHANGE_SLOT_FIELD_NUMBER: _ClassVar[int] + CLIENT_CONNECTED_FIELD_NUMBER: _ClassVar[int] + CLIENT_DISCONNECTED_FIELD_NUMBER: _ClassVar[int] + MAP_DETAILS_FIELD_NUMBER: _ClassVar[int] + PLAYER_ALT_FIELD_NUMBER: _ClassVar[int] + PLAYER_FIELD_NUMBER: _ClassVar[int] + PLAYER_LEFT_GAME_FIELD_NUMBER: _ClassVar[int] + SET_VARIABLE_FIELD_NUMBER: _ClassVar[int] + START_GAME_FIELD_NUMBER: _ClassVar[int] + assign_player_slot: AssignPlayerSlot + change_slot: LobbyChangeSlot + client_connected: ClientConnected + client_disconnected: ClientDisconnected + map_details: MapDetails + player: Player + player_alt: PlayerAlt + player_left_game: PlayerLeftGame + set_variable: LobbySetVariable + start_game: StartGame + def __init__(self, map_details: _Optional[_Union[MapDetails, _Mapping]] = ..., client_connected: _Optional[_Union[ClientConnected, _Mapping]] = ..., player: _Optional[_Union[Player, _Mapping]] = ..., change_slot: _Optional[_Union[LobbyChangeSlot, _Mapping]] = ..., set_variable: _Optional[_Union[LobbySetVariable, _Mapping]] = ..., start_game: _Optional[_Union[StartGame, _Mapping]] = ..., player_left_game: _Optional[_Union[PlayerLeftGame, _Mapping]] = ..., client_disconnected: _Optional[_Union[ClientDisconnected, _Mapping]] = ..., assign_player_slot: _Optional[_Union[AssignPlayerSlot, _Mapping]] = ..., player_alt: _Optional[_Union[PlayerAlt, _Mapping]] = ...) -> None: ... + CONTENT_FIELD_NUMBER: _ClassVar[int] + content: ReplayChunk.Wrapper.ReplayContent + def __init__(self, content: _Optional[_Union[ReplayChunk.Wrapper.ReplayContent, _Mapping]] = ...) -> None: ... CLIENT_ID_FIELD_NUMBER: _ClassVar[int] - REASON_FIELD_NUMBER: _ClassVar[int] - PLAYER_UUID_FIELD_NUMBER: _ClassVar[int] + INNER_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_FIELD_NUMBER: _ClassVar[int] client_id: int - reason: LeaveReason - player_uuid: UUID - def __init__(self, client_id: _Optional[int] = ..., reason: _Optional[_Union[LeaveReason, str]] = ..., player_uuid: _Optional[_Union[UUID, _Mapping]] = ...) -> None: ... + inner: ReplayChunk.Wrapper + timestamp: int + def __init__(self, timestamp: _Optional[int] = ..., client_id: _Optional[int] = ..., inner: _Optional[_Union[ReplayChunk.Wrapper, _Mapping]] = ...) -> None: ... -class AssignPlayerSlot(_message.Message): - __slots__ = ("uuid", "slot", "nickname") - UUID_FIELD_NUMBER: _ClassVar[int] - SLOT_FIELD_NUMBER: _ClassVar[int] - NICKNAME_FIELD_NUMBER: _ClassVar[int] - uuid: UUID - slot: int - nickname: str - def __init__(self, uuid: _Optional[_Union[UUID, _Mapping]] = ..., slot: _Optional[int] = ..., nickname: _Optional[str] = ...) -> None: ... +class StartGame(_message.Message): + __slots__ = [] + def __init__(self) -> None: ... class UUID(_message.Message): - __slots__ = ("part1", "part2") + __slots__ = ["part1", "part2"] PART1_FIELD_NUMBER: _ClassVar[int] PART2_FIELD_NUMBER: _ClassVar[int] part1: int part2: int def __init__(self, part1: _Optional[int] = ..., part2: _Optional[int] = ...) -> None: ... + +class MatchType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] + +class LeaveReason(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = [] diff --git a/stormgate.proto b/stormgate.proto index 20e9cf9..85221a1 100755 --- a/stormgate.proto +++ b/stormgate.proto @@ -22,6 +22,7 @@ message ReplayChunk { PlayerLeftGame player_left_game = 25; ClientDisconnected client_disconnected = 31; AssignPlayerSlot assign_player_slot = 37; + PlayerAlt player_alt = 45; } } ReplayContent content = 1; @@ -120,6 +121,15 @@ message AssignPlayerSlot { string nickname = 3; } +// 45 - Sent by a player when they join a game +message PlayerAlt { + message PlayerNameAlt { + string nickname = 1; + string discriminator = 2; + } + PlayerNameAlt name = 5; +} + // UUIDs are encoded as 2 varints. // To recover the original UUID, encode these as unsigned 64-bit big-endian // integers and concatenate the resulting bitstrings; or in python: diff --git a/tests/replays/CL75432-2024.10.05-11.38.SGReplay b/tests/replays/CL75432-2024.10.05-11.38.SGReplay new file mode 100644 index 0000000..568bf53 Binary files /dev/null and b/tests/replays/CL75432-2024.10.05-11.38.SGReplay differ diff --git a/tests/replays/CL75432-2024.10.05-11.38.json b/tests/replays/CL75432-2024.10.05-11.38.json new file mode 100644 index 0000000..7d422d5 --- /dev/null +++ b/tests/replays/CL75432-2024.10.05-11.38.json @@ -0,0 +1 @@ +{"build_number": 75432, "map_name": "TitansCausewayV2", "players": [{"nickname": "[KeeN]VortiX", "nickname_discriminator": "7122", "uuid": "8caf1a70-95c4-4cc9-a062-2c8d1c522eaa", "faction": "Infernals", "is_ai": false, "disconnect_time": 652.1630859375, "leave_reason": "Leave"}, {"nickname": "Highdra", "nickname_discriminator": "5062", "uuid": "1fb7be1e-4147-460b-ab31-2d8f52aeb988", "faction": "Infernals", "is_ai": false, "disconnect_time": 652.0791015625, "leave_reason": "Surrender"}], "spectators": [{"nickname": "BeoMulf", "nickname_discriminator": "1519", "uuid": "dbfcfa94-c65e-477b-8285-df2214c686ac"}], "duration_seconds": 652.0791015625, "is_1v1_ladder_game": false} \ No newline at end of file diff --git a/tests/replays/CL75432-2024.10.05-11.38.txt b/tests/replays/CL75432-2024.10.05-11.38.txt new file mode 100644 index 0000000..71b8f2e --- /dev/null +++ b/tests/replays/CL75432-2024.10.05-11.38.txt @@ -0,0 +1 @@ +2024-10-05 01.38 10m52s [keen]vortix I, Highdra I - TitansCausewayV2.SGReplay \ No newline at end of file diff --git a/tests/replays/CL75432-2024.10.05-11.51.SGReplay b/tests/replays/CL75432-2024.10.05-11.51.SGReplay new file mode 100644 index 0000000..6feaa40 Binary files /dev/null and b/tests/replays/CL75432-2024.10.05-11.51.SGReplay differ diff --git a/tests/replays/CL75432-2024.10.05-11.51.json b/tests/replays/CL75432-2024.10.05-11.51.json new file mode 100644 index 0000000..9082984 --- /dev/null +++ b/tests/replays/CL75432-2024.10.05-11.51.json @@ -0,0 +1 @@ +{"build_number": 75432, "map_name": "BrokenCrown", "players": [{"nickname": "Highdra", "nickname_discriminator": "5062", "uuid": "1fb7be1e-4147-460b-ab31-2d8f52aeb988", "faction": "Vanguard", "is_ai": false, "disconnect_time": 763.3681640625, "leave_reason": "Surrender"}, {"nickname": "[KeeN]VortiX", "nickname_discriminator": "7122", "uuid": "8caf1a70-95c4-4cc9-a062-2c8d1c522eaa", "faction": "Infernals", "is_ai": false, "disconnect_time": 763.435546875, "leave_reason": "Leave"}], "spectators": [{"nickname": "BeoMulf", "nickname_discriminator": "1519", "uuid": "dbfcfa94-c65e-477b-8285-df2214c686ac"}], "duration_seconds": 763.3681640625, "is_1v1_ladder_game": false} \ No newline at end of file diff --git a/tests/replays/CL75432-2024.10.05-11.51.txt b/tests/replays/CL75432-2024.10.05-11.51.txt new file mode 100644 index 0000000..0b661eb --- /dev/null +++ b/tests/replays/CL75432-2024.10.05-11.51.txt @@ -0,0 +1 @@ +2024-10-05 01.51 12m43s Highdra V, [keen]vortix I - BrokenCrown.SGReplay \ No newline at end of file diff --git a/tests/replays/CL75432-2024.10.05-12.08.SGReplay b/tests/replays/CL75432-2024.10.05-12.08.SGReplay new file mode 100644 index 0000000..184b45e Binary files /dev/null and b/tests/replays/CL75432-2024.10.05-12.08.SGReplay differ diff --git a/tests/replays/CL75432-2024.10.05-12.08.json b/tests/replays/CL75432-2024.10.05-12.08.json new file mode 100644 index 0000000..a3f6dcf --- /dev/null +++ b/tests/replays/CL75432-2024.10.05-12.08.json @@ -0,0 +1 @@ +{"build_number": 75432, "map_name": "Boneyard", "players": [{"nickname": "LucifroN7", "nickname_discriminator": "7550", "uuid": "3736d635-81f0-4372-afb0-12e47c46a34d", "faction": "Vanguard", "is_ai": false, "disconnect_time": 579.3857421875, "leave_reason": "Surrender"}, {"nickname": "MaNa", "nickname_discriminator": "6780", "uuid": "7c15efa0-5422-430c-9ef2-a774e5325b44", "faction": "Vanguard", "is_ai": false, "disconnect_time": 579.5751953125, "leave_reason": "Leave"}], "spectators": [{"nickname": "BeoMulf", "nickname_discriminator": "1519", "uuid": "dbfcfa94-c65e-477b-8285-df2214c686ac"}], "duration_seconds": 579.3857421875, "is_1v1_ladder_game": false} \ No newline at end of file diff --git a/tests/replays/CL75432-2024.10.05-12.08.txt b/tests/replays/CL75432-2024.10.05-12.08.txt new file mode 100644 index 0000000..67f28a8 --- /dev/null +++ b/tests/replays/CL75432-2024.10.05-12.08.txt @@ -0,0 +1 @@ +2024-10-05 02.08 09m39s Lucifron7 V, Mana V - Boneyard.SGReplay \ No newline at end of file