mirror of
https://github.com/ammaraskar/pyCraft.git
synced 2025-04-10 05:56:04 +02:00
Implement "player list item" packet.
This commit is contained in:
parent
6aea7b36c1
commit
f39872a7f5
@ -3,7 +3,7 @@ from zlib import compress
|
||||
|
||||
from .types import (
|
||||
VarInt, Integer, Float, Double, UnsignedShort, Long, Byte, UnsignedByte,
|
||||
String, VarIntPrefixedByteArray, Boolean
|
||||
String, VarIntPrefixedByteArray, Boolean, UUID
|
||||
)
|
||||
|
||||
|
||||
@ -280,12 +280,137 @@ class SetCompressionPacketPlayState(Packet):
|
||||
definition = [
|
||||
{'threshold': VarInt}]
|
||||
|
||||
class PlayerListItemPacket(Packet):
|
||||
id = 0x38
|
||||
packet_name = "player list item"
|
||||
|
||||
class PlayerList(object):
|
||||
__slots__ = 'players_by_uuid'
|
||||
def __init__(self):
|
||||
self.players_by_uuid = dict()
|
||||
|
||||
class PlayerListItem(object):
|
||||
__slots__ = (
|
||||
'uuid', 'name', 'properties', 'gamemode', 'ping', 'display_name')
|
||||
def __init__(self, **kwds):
|
||||
for key, val in kwds.iteritems():
|
||||
setattr(self, key, val)
|
||||
|
||||
class PlayerProperty(object):
|
||||
__slots__ = 'name', 'value', 'signature'
|
||||
def read(self, file_object):
|
||||
self.name = String.read(file_object)
|
||||
self.value = String.read(file_object)
|
||||
is_signed = Boolean.read(file_object)
|
||||
if is_signed:
|
||||
self.signature = String.read(file_object)
|
||||
else:
|
||||
self.signature = None
|
||||
|
||||
class Action(object):
|
||||
__slots__ = 'uuid'
|
||||
def read(self, file_object):
|
||||
self.uuid = UUID.read(file_object)
|
||||
self._read(file_object)
|
||||
|
||||
@classmethod
|
||||
def type_from_id(cls, action_id):
|
||||
subcls = {
|
||||
0: PlayerListItemPacket.AddPlayerAction,
|
||||
1: PlayerListItemPacket.UpdateGameModeAction,
|
||||
2: PlayerListItemPacket.UpdateLatencyAction,
|
||||
3: PlayerListItemPacket.UpdateDisplayNameAction,
|
||||
4: PlayerListItemPacket.RemovePlayerAction
|
||||
}.get(action_id)
|
||||
if subcls is None: raise ValueError(
|
||||
"Unknown player list action ID: %s." % action_id)
|
||||
return subcls
|
||||
|
||||
class AddPlayerAction(Action):
|
||||
__slots__ = 'name', 'properties', 'gamemode', 'ping', 'display_name'
|
||||
def _read(self, file_object):
|
||||
self.name = String.read(file_object)
|
||||
prop_count = VarInt.read(file_object)
|
||||
self.properties = []
|
||||
for i in range(prop_count):
|
||||
property = PlayerListItemPacket.PlayerProperty()
|
||||
property.read(file_object)
|
||||
self.properties.append(property)
|
||||
self.gamemode = VarInt.read(file_object)
|
||||
self.ping = VarInt.read(file_object)
|
||||
has_display_name = Boolean.read(file_object)
|
||||
if has_display_name:
|
||||
self.display_name = String.read(file_object)
|
||||
else:
|
||||
self.display_name = None
|
||||
def apply(self, player_list):
|
||||
player = PlayerListItemPacket.PlayerListItem(
|
||||
uuid = self.uuid,
|
||||
name = self.name,
|
||||
properties = self.properties,
|
||||
gamemode = self.gamemode,
|
||||
ping = self.ping,
|
||||
display_name = self.display_name)
|
||||
player_list.players_by_uuid[self.uuid] = player
|
||||
|
||||
class UpdateGameModeAction(Action):
|
||||
__slots__ = 'gamemode'
|
||||
def _read(self, file_object):
|
||||
self.gamemode = VarInt.read(file_object)
|
||||
def apply(self, player_list):
|
||||
player = player_list.players_by_uuid.get(self.uuid)
|
||||
if player: player.gamemode = self.gamemode
|
||||
|
||||
class UpdateLatencyAction(Action):
|
||||
__slots__ = 'ping'
|
||||
def _read(self, file_object):
|
||||
self.ping = VarInt.read(file_object)
|
||||
def apply(self, player_list):
|
||||
player = player_list.players_by_uuid.get(self.uuid)
|
||||
if player: player.ping = self.ping
|
||||
|
||||
class UpdateDisplayNameAction(Action):
|
||||
__slots__ = 'display_name'
|
||||
def _read(self, file_object):
|
||||
has_display_name = Boolean.read(file_object)
|
||||
if has_display_name:
|
||||
self.display_name = String.read(file_object)
|
||||
else:
|
||||
self.display_name = None
|
||||
def apply(self, player_list):
|
||||
player = player_list.players_by_uuid.get(self.uuid)
|
||||
if player: player.display_name = self.display_name
|
||||
|
||||
class RemovePlayerAction(Action):
|
||||
def _read(self, file_object):
|
||||
pass
|
||||
def apply(self, player_list):
|
||||
if self.uuid in player_list.players_by_uuid:
|
||||
del player_list.players_by_uuid[self.uuid]
|
||||
|
||||
def read(self, file_object):
|
||||
action_id = VarInt.read(file_object)
|
||||
self.action_type = PlayerListItemPacket.Action.type_from_id(action_id)
|
||||
action_count = VarInt.read(file_object)
|
||||
self.actions = []
|
||||
for i in range(action_count):
|
||||
action = self.action_type()
|
||||
action.read(file_object)
|
||||
self.actions.append(action)
|
||||
|
||||
def apply(self, player_list):
|
||||
for action in self.actions:
|
||||
action.apply(player_list)
|
||||
|
||||
def write(self, socket, compression_threshold=None):
|
||||
raise NotImplementedError
|
||||
|
||||
STATE_PLAYING_CLIENTBOUND = {
|
||||
0x00: KeepAlivePacket,
|
||||
0x01: JoinGamePacket,
|
||||
0x02: ChatMessagePacket,
|
||||
0x08: PlayerPositionAndLookPacket,
|
||||
0x38: PlayerListItemPacket,
|
||||
0x40: DisconnectPacketPlayState,
|
||||
0x46: SetCompressionPacketPlayState
|
||||
}
|
||||
@ -309,7 +434,6 @@ class PositionAndLookPacket(Packet):
|
||||
{'pitch': Float},
|
||||
{'on_ground': Boolean}]
|
||||
|
||||
|
||||
STATE_PLAYING_SERVERBOUND = {
|
||||
0x00: KeepAlivePacket,
|
||||
0x01: ChatPacket,
|
||||
|
Loading…
Reference in New Issue
Block a user