2017-08-08 15:07:33 +02:00
|
|
|
from minecraft.networking.packets import (
|
2018-01-13 02:03:04 +01:00
|
|
|
Packet, AbstractKeepAlivePacket, AbstractPluginMessagePacket
|
2017-08-08 15:07:33 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
from minecraft.networking.types import (
|
2018-06-20 06:32:35 +02:00
|
|
|
Integer, FixedPointInteger, UnsignedByte, Byte, Boolean, UUID, Short,
|
2019-05-13 21:58:59 +02:00
|
|
|
VarInt, Double, Float, String, Enum, Difficulty, Dimension, GameMode,
|
2019-05-15 14:51:31 +02:00
|
|
|
Angle
|
2017-08-08 15:07:33 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
from .combat_event_packet import CombatEventPacket
|
|
|
|
from .map_packet import MapPacket
|
|
|
|
from .player_list_item_packet import PlayerListItemPacket
|
|
|
|
from .player_position_and_look_packet import PlayerPositionAndLookPacket
|
|
|
|
from .spawn_object_packet import SpawnObjectPacket
|
2018-01-13 02:03:04 +01:00
|
|
|
from .block_change_packet import BlockChangePacket, MultiBlockChangePacket
|
2018-05-27 14:28:01 +02:00
|
|
|
from .explosion_packet import ExplosionPacket
|
2019-05-13 21:58:59 +02:00
|
|
|
from .sound_effect_packet import SoundEffectPacket
|
2019-05-15 02:28:56 +02:00
|
|
|
from . face_player_packet import FacePlayerPacket
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
# Formerly known as state_playing_clientbound.
|
|
|
|
def get_packets(context):
|
|
|
|
packets = {
|
|
|
|
KeepAlivePacket,
|
|
|
|
JoinGamePacket,
|
2018-08-12 11:47:50 +02:00
|
|
|
ServerDifficultyPacket,
|
2017-08-08 15:07:33 +02:00
|
|
|
ChatMessagePacket,
|
|
|
|
PlayerPositionAndLookPacket,
|
|
|
|
MapPacket,
|
|
|
|
PlayerListItemPacket,
|
2017-08-09 10:14:29 +02:00
|
|
|
DisconnectPacket,
|
2017-08-08 15:07:33 +02:00
|
|
|
SpawnPlayerPacket,
|
|
|
|
EntityVelocityPacket,
|
|
|
|
UpdateHealthPacket,
|
|
|
|
CombatEventPacket,
|
|
|
|
ExplosionPacket,
|
|
|
|
SpawnObjectPacket,
|
|
|
|
BlockChangePacket,
|
|
|
|
MultiBlockChangePacket,
|
2018-08-12 11:39:11 +02:00
|
|
|
RespawnPacket,
|
2017-08-24 03:14:53 +02:00
|
|
|
PluginMessagePacket,
|
2018-11-09 20:07:41 +01:00
|
|
|
PlayerListHeaderAndFooterPacket,
|
2019-05-15 14:51:31 +02:00
|
|
|
EntityLookPacket
|
2017-08-08 15:07:33 +02:00
|
|
|
}
|
|
|
|
if context.protocol_version <= 47:
|
|
|
|
packets |= {
|
2017-08-09 10:14:29 +02:00
|
|
|
SetCompressionPacket,
|
2017-08-08 15:07:33 +02:00
|
|
|
}
|
2019-05-13 21:58:59 +02:00
|
|
|
if context.protocol_version >= 94:
|
|
|
|
packets |= {
|
|
|
|
SoundEffectPacket,
|
|
|
|
}
|
2019-05-15 02:28:56 +02:00
|
|
|
if context.protocol_version >= 352:
|
|
|
|
packets |= {
|
|
|
|
FacePlayerPacket
|
|
|
|
}
|
2017-08-08 15:07:33 +02:00
|
|
|
return packets
|
|
|
|
|
|
|
|
|
|
|
|
class KeepAlivePacket(AbstractKeepAlivePacket):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-11 08:43:08 +02:00
|
|
|
return 0x20 if context.protocol_version >= 471 else \
|
|
|
|
0x21 if context.protocol_version >= 389 else \
|
2018-07-19 02:59:48 +02:00
|
|
|
0x20 if context.protocol_version >= 345 else \
|
2018-01-13 02:03:04 +01:00
|
|
|
0x1F if context.protocol_version >= 332 else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x20 if context.protocol_version >= 318 else \
|
|
|
|
0x1F if context.protocol_version >= 107 else \
|
|
|
|
0x00
|
|
|
|
|
|
|
|
|
|
|
|
class JoinGamePacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2018-07-19 02:59:48 +02:00
|
|
|
return 0x25 if context.protocol_version >= 389 else \
|
|
|
|
0x24 if context.protocol_version >= 345 else \
|
2018-01-13 02:03:04 +01:00
|
|
|
0x23 if context.protocol_version >= 332 else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x24 if context.protocol_version >= 318 else \
|
|
|
|
0x23 if context.protocol_version >= 107 else \
|
|
|
|
0x01
|
|
|
|
|
|
|
|
packet_name = "join game"
|
|
|
|
get_definition = staticmethod(lambda context: [
|
|
|
|
{'entity_id': Integer},
|
|
|
|
{'game_mode': UnsignedByte},
|
|
|
|
{'dimension': Integer if context.protocol_version >= 108 else Byte},
|
2019-05-11 08:43:08 +02:00
|
|
|
{'difficulty': UnsignedByte} if context.protocol_version < 464 else {},
|
2017-08-08 15:07:33 +02:00
|
|
|
{'max_players': UnsignedByte},
|
|
|
|
{'level_type': String},
|
2019-05-11 08:43:08 +02:00
|
|
|
{'render_distance': VarInt} if context.protocol_version >= 468 else {},
|
2019-05-13 17:49:20 +02:00
|
|
|
{'reduced_debug_info': Boolean},
|
2018-08-12 11:47:50 +02:00
|
|
|
])
|
|
|
|
|
2018-08-13 01:41:21 +02:00
|
|
|
# JoinGamePacket.Difficulty is an alias for Difficulty
|
|
|
|
Difficulty = Difficulty
|
|
|
|
|
|
|
|
# JoinGamePacket.Gamemode is an alias for Gamemode
|
2018-08-15 23:29:18 +02:00
|
|
|
GameMode = GameMode
|
2018-08-13 01:41:21 +02:00
|
|
|
|
|
|
|
# JoinGamePacket.Dimension is an alias for Dimension
|
|
|
|
Dimension = Dimension
|
|
|
|
|
2018-08-12 11:47:50 +02:00
|
|
|
|
|
|
|
class ServerDifficultyPacket(Packet):
|
2018-08-12 12:04:40 +02:00
|
|
|
@staticmethod
|
2018-08-12 11:47:50 +02:00
|
|
|
def get_id(context):
|
|
|
|
return 0x0D if context.protocol_version >= 332 else \
|
|
|
|
0x0E if context.protocol_version >= 318 else \
|
2018-08-12 23:56:16 +02:00
|
|
|
0x0D if context.protocol_version >= 70 else \
|
2018-08-12 11:47:50 +02:00
|
|
|
0x41
|
|
|
|
|
|
|
|
packet_name = 'server difficulty'
|
|
|
|
get_definition = staticmethod(lambda context: [
|
2019-05-13 18:22:53 +02:00
|
|
|
{'difficulty': UnsignedByte},
|
|
|
|
{'is_locked': Boolean} if context.protocol_version >= 464 else {},
|
2018-08-12 11:47:50 +02:00
|
|
|
])
|
2017-08-08 15:07:33 +02:00
|
|
|
|
2018-08-13 01:41:21 +02:00
|
|
|
# ServerDifficultyPacket.Difficulty is an alias for Difficulty
|
|
|
|
Difficulty = Difficulty
|
2017-08-08 15:07:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
class ChatMessagePacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2018-01-13 02:03:04 +01:00
|
|
|
return 0x0E if context.protocol_version >= 343 else \
|
|
|
|
0x0F if context.protocol_version >= 332 else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x10 if context.protocol_version >= 317 else \
|
|
|
|
0x0F if context.protocol_version >= 107 else \
|
|
|
|
0x02
|
|
|
|
|
|
|
|
packet_name = "chat message"
|
|
|
|
definition = [
|
|
|
|
{'json_data': String},
|
|
|
|
{'position': Byte}]
|
|
|
|
|
2017-08-24 03:14:53 +02:00
|
|
|
class Position(Enum):
|
|
|
|
CHAT = 0 # A player-initiated chat message.
|
|
|
|
SYSTEM = 1 # The result of running a command.
|
|
|
|
GAME_INFO = 2 # Displayed above the hotbar in vanilla clients.
|
|
|
|
|
2017-08-08 15:07:33 +02:00
|
|
|
|
2017-08-09 10:14:29 +02:00
|
|
|
class DisconnectPacket(Packet):
|
2017-08-08 15:07:33 +02:00
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-11 08:43:08 +02:00
|
|
|
return 0x1A if context.protocol_version >= 471 else \
|
|
|
|
0x1B if context.protocol_version >= 345 else \
|
2018-01-13 02:03:04 +01:00
|
|
|
0x1A if context.protocol_version >= 332 else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x1B if context.protocol_version >= 318 else \
|
|
|
|
0x1A if context.protocol_version >= 107 else \
|
|
|
|
0x40
|
|
|
|
|
|
|
|
packet_name = "disconnect"
|
|
|
|
|
|
|
|
definition = [
|
|
|
|
{'json_data': String}]
|
|
|
|
|
|
|
|
|
2017-08-09 10:14:29 +02:00
|
|
|
class SetCompressionPacket(Packet):
|
2017-08-08 15:07:33 +02:00
|
|
|
# Note: removed between protocol versions 47 and 107.
|
|
|
|
id = 0x46
|
|
|
|
packet_name = "set compression"
|
|
|
|
definition = [
|
|
|
|
{'threshold': VarInt}]
|
|
|
|
|
|
|
|
|
|
|
|
class SpawnPlayerPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
|
|
|
return 0x05 if context.protocol_version >= 67 else \
|
|
|
|
0x0C
|
|
|
|
|
|
|
|
packet_name = 'spawn player'
|
|
|
|
get_definition = staticmethod(lambda context: [
|
|
|
|
{'entity_id': VarInt},
|
|
|
|
{'player_UUID': UUID},
|
2018-06-20 06:32:35 +02:00
|
|
|
{'x': Double} if context.protocol_version >= 100
|
|
|
|
else {'x': FixedPointInteger},
|
|
|
|
{'y': Double} if context.protocol_version >= 100
|
|
|
|
else {'y': FixedPointInteger},
|
|
|
|
{'z': Double} if context.protocol_version >= 100
|
|
|
|
else {'z': FixedPointInteger},
|
2019-05-15 14:51:31 +02:00
|
|
|
{'yaw': Angle},
|
|
|
|
{'pitch': Angle},
|
2017-08-08 15:07:33 +02:00
|
|
|
# TODO: read entity metadata
|
|
|
|
{'current_item': Short} if context.protocol_version <= 49 else {}
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
class EntityVelocityPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-11 08:43:08 +02:00
|
|
|
return 0x45 if context.protocol_version >= 471 else \
|
|
|
|
0x41 if context.protocol_version >= 461 else \
|
|
|
|
0x42 if context.protocol_version >= 451 else \
|
|
|
|
0x41 if context.protocol_version >= 389 else \
|
2018-07-19 02:59:48 +02:00
|
|
|
0x40 if context.protocol_version >= 352 else \
|
2018-01-13 02:03:04 +01:00
|
|
|
0x3F if context.protocol_version >= 345 else \
|
|
|
|
0x3E if context.protocol_version >= 336 else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x3D if context.protocol_version >= 332 else \
|
|
|
|
0x3B if context.protocol_version >= 86 else \
|
|
|
|
0x3C if context.protocol_version >= 77 else \
|
|
|
|
0x3B if context.protocol_version >= 67 else \
|
|
|
|
0x12
|
|
|
|
|
|
|
|
packet_name = 'entity velocity'
|
|
|
|
get_definition = staticmethod(lambda context: [
|
|
|
|
{'entity_id': VarInt},
|
|
|
|
{'velocity_x': Short},
|
|
|
|
{'velocity_y': Short},
|
|
|
|
{'velocity_z': Short}
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
class UpdateHealthPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-11 08:43:08 +02:00
|
|
|
return 0x48 if context.protocol_version >= 471 else \
|
|
|
|
0x44 if context.protocol_version >= 461 else \
|
|
|
|
0x45 if context.protocol_version >= 451 else \
|
|
|
|
0x44 if context.protocol_version >= 389 else \
|
2018-07-19 02:59:48 +02:00
|
|
|
0x43 if context.protocol_version >= 352 else \
|
2018-01-13 02:03:04 +01:00
|
|
|
0x42 if context.protocol_version >= 345 else \
|
|
|
|
0x41 if context.protocol_version >= 336 else \
|
2017-08-08 15:07:33 +02:00
|
|
|
0x40 if context.protocol_version >= 318 else \
|
|
|
|
0x3E if context.protocol_version >= 86 else \
|
|
|
|
0x3F if context.protocol_version >= 77 else \
|
|
|
|
0x3E if context.protocol_version >= 67 else \
|
|
|
|
0x06
|
|
|
|
|
|
|
|
packet_name = 'update health'
|
|
|
|
get_definition = staticmethod(lambda context: [
|
|
|
|
{'health': Float},
|
|
|
|
{'food': VarInt},
|
|
|
|
{'food_saturation': Float}
|
|
|
|
])
|
|
|
|
|
|
|
|
|
2018-08-12 11:39:11 +02:00
|
|
|
class RespawnPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-13 18:22:53 +02:00
|
|
|
return 0x3A if context.protocol_version >= 471 else \
|
|
|
|
0x38 if context.protocol_version >= 461 else \
|
|
|
|
0x39 if context.protocol_version >= 451 else \
|
|
|
|
0x38 if context.protocol_version >= 389 else \
|
2018-08-12 11:39:11 +02:00
|
|
|
0x37 if context.protocol_version >= 352 else \
|
|
|
|
0x36 if context.protocol_version >= 345 else \
|
|
|
|
0x35 if context.protocol_version >= 336 else \
|
|
|
|
0x34 if context.protocol_version >= 332 else \
|
|
|
|
0x35 if context.protocol_version >= 318 else \
|
|
|
|
0x33 if context.protocol_version >= 70 else \
|
|
|
|
0x07
|
|
|
|
|
|
|
|
packet_name = 'respawn'
|
|
|
|
get_definition = staticmethod(lambda context: [
|
|
|
|
{'dimension': Integer},
|
2019-05-13 18:22:53 +02:00
|
|
|
{'difficulty': UnsignedByte} if context.protocol_version < 464 else {},
|
2018-08-12 11:39:11 +02:00
|
|
|
{'game_mode': UnsignedByte},
|
2019-05-13 18:22:53 +02:00
|
|
|
{'level_type': String},
|
2018-08-12 11:39:11 +02:00
|
|
|
])
|
|
|
|
|
2018-08-13 01:41:21 +02:00
|
|
|
# RespawnPacket.Difficulty is an alias for Difficulty.
|
|
|
|
Difficulty = Difficulty
|
|
|
|
|
|
|
|
# RespawnPacket.Dimension is an alias for Dimension.
|
|
|
|
Dimension = Dimension
|
|
|
|
|
|
|
|
# RespawnPacket.Gamemode is an alias for Gamemode.
|
2018-08-15 23:29:18 +02:00
|
|
|
GameMode = GameMode
|
2018-08-13 01:41:21 +02:00
|
|
|
|
2018-08-12 11:39:11 +02:00
|
|
|
|
2017-08-24 03:14:53 +02:00
|
|
|
class PluginMessagePacket(AbstractPluginMessagePacket):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-11 08:43:08 +02:00
|
|
|
return 0x18 if context.protocol_version >= 471 else \
|
|
|
|
0x19 if context.protocol_version >= 345 else \
|
2018-01-13 02:03:04 +01:00
|
|
|
0x18 if context.protocol_version >= 332 else \
|
2017-08-24 03:14:53 +02:00
|
|
|
0x19 if context.protocol_version >= 318 else \
|
|
|
|
0x18 if context.protocol_version >= 70 else \
|
|
|
|
0x3F
|
2018-11-09 20:07:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
class PlayerListHeaderAndFooterPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
2019-05-11 08:43:08 +02:00
|
|
|
return 0x53 if context.protocol_version >= 471 else \
|
|
|
|
0x5F if context.protocol_version >= 461 else \
|
|
|
|
0x50 if context.protocol_version >= 451 else \
|
|
|
|
0x4F if context.protocol_version >= 441 else \
|
|
|
|
0x4E if context.protocol_version >= 393 else \
|
2018-11-09 20:07:41 +01:00
|
|
|
0x4A if context.protocol_version >= 338 else \
|
|
|
|
0x49 if context.protocol_version >= 335 else \
|
|
|
|
0x47 if context.protocol_version >= 110 else \
|
|
|
|
0x48 if context.protocol_version >= 107 else \
|
|
|
|
0x47
|
|
|
|
|
|
|
|
packet_name = 'player list header and footer'
|
|
|
|
definition = [
|
|
|
|
{'header': String},
|
|
|
|
{'footer': String}]
|
2019-05-15 14:51:31 +02:00
|
|
|
|
|
|
|
|
|
|
|
class EntityLookPacket(Packet):
|
|
|
|
@staticmethod
|
|
|
|
def get_id(context):
|
|
|
|
return 0x2A if context.protocol_version >= 389 else \
|
|
|
|
0x29 if context.protocol_version >= 345 else \
|
|
|
|
0x28 if context.protocol_version >= 318 else \
|
|
|
|
0x27 if context.protocol_version >= 94 else \
|
|
|
|
0x28 if context.protocol_version >= 70 else \
|
|
|
|
0x16
|
|
|
|
|
|
|
|
packet_name = 'entity look'
|
|
|
|
definition = [
|
|
|
|
{'entity_id': VarInt},
|
|
|
|
{'yaw': Angle},
|
|
|
|
{'pitch': Angle},
|
|
|
|
{'on_ground': Boolean}
|
2019-05-15 14:59:23 +02:00
|
|
|
]
|