Update all tests, docs and code to use new packet names.

This commit is contained in:
joo 2017-08-09 20:53:54 +01:00
parent f1ae765458
commit 46e058dd08
7 changed files with 137 additions and 57 deletions

View File

@ -13,9 +13,9 @@ Writing Packets
The packet class uses a lot of magic to work, here is how to use them.
Look up the particular packet you need to deal with, for this example
let's go with the ``KeepAlivePacket``
let's go with the ``serverbound.play.KeepAlivePacket``
.. autoclass:: minecraft.networking.packets.KeepAlivePacket
.. autoclass:: minecraft.networking.packets.serverbound.play.KeepAlivePacket
:undoc-members:
:inherited-members:
:exclude-members: read, write, context, get_definition, get_id, id, packet_name, set_values
@ -23,16 +23,18 @@ let's go with the ``KeepAlivePacket``
Pay close attention to the definition attribute, and how our class variable corresponds to
the name given from the definition::
packet = KeepAlivePacket()
from minecraft.networking.packets import serverbound
packet = serverbound.play.KeepAlivePacket()
packet.keep_alive_id = random.randint(0, 5000)
connection.write_packet(packet)
and just like that, the packet will be written out to the server.
It is possible to implement your own custom packets by subclassing
:class:`minecraft.networking.packets.Packet`. Read the docstrings and
follow the examples in packets.py for more details on how to do advanced tasks
like having a packet that is compatible across multiple protocol versions.
:class:`minecraft.networking.packets.Packet`. Read the docstrings and in
packets.py and follow the examples in its subpackages for more details on
how to do advanced tasks like having a packet that is compatible across
multiple protocol versions.
Listening for Certain Packets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -50,12 +52,12 @@ An example of this can be found in the ``start.py`` headless client, it is recre
print "Position: " + str(chat_packet.position)
print "Data: " + chat_packet.json_data
from minecraft.networking.packets import ChatMessagePacket
from minecraft.networking.packets.clientbound.play import ChatMessagePacket
connection.register_packet_listener(print_chat, ChatMessagePacket)
The field names ``position`` and ``json_data`` are inferred by again looking at the definition attribute as before
.. autoclass:: minecraft.networking.packets.ChatMessagePacket
.. autoclass:: minecraft.networking.packets.clientbound.play.ChatMessagePacket
:undoc-members:
:inherited-members:
:exclude-members: read, write, context, get_definition, get_id, id, packet_name, set_values
:exclude-members: read, write, context, get_definition, get_id, id, packet_name, set_values

View File

@ -14,6 +14,7 @@ import json
from future.utils import raise_
from .types import VarInt
from .packets import clientbound, serverbound
from . import packets
from . import encryption
from .. import SUPPORTED_PROTOCOL_VERSIONS
@ -224,7 +225,7 @@ class Connection(object):
elif handle_ping is not None:
self.reactor.handle_ping = handle_ping
request_packet = packets.RequestPacket()
request_packet = serverbound.status.RequestPacket()
self.write_packet(request_packet)
def connect(self):
@ -248,7 +249,7 @@ class Connection(object):
# process of determining the server's version, and immediately
# connect.
self._handshake(next_state=STATE_PLAYING)
login_start_packet = packets.LoginStartPacket()
login_start_packet = serverbound.login.LoginStartPacket()
if self.auth_token:
login_start_packet.name = self.auth_token.profile.name
else:
@ -259,7 +260,7 @@ class Connection(object):
# Determine the server's protocol version by first performing a
# status query.
self._handshake(next_state=STATE_STATUS)
self.write_packet(packets.RequestPacket())
self.write_packet(serverbound.status.RequestPacket())
self.reactor = PlayingStatusReactor(self)
self._start_network_thread()
@ -297,7 +298,7 @@ class Connection(object):
self.socket = None
def _handshake(self, next_state=STATE_PLAYING):
handshake = packets.HandShakePacket()
handshake = serverbound.handshake.HandShakePacket()
handshake.protocol_version = self.context.protocol_version
handshake.server_address = self.options.address
handshake.server_port = self.options.port
@ -411,7 +412,7 @@ class PacketReactor(object):
TIME_OUT = 0
# Handshaking is considered the "default" state
get_clientbound_packets = staticmethod(packets.state_handshake_clientbound)
get_clientbound_packets = staticmethod(clientbound.handshake.get_packets)
def __init__(self, connection):
self.connection = connection
@ -473,7 +474,7 @@ class PacketReactor(object):
class LoginReactor(PacketReactor):
get_clientbound_packets = staticmethod(packets.state_login_clientbound)
get_clientbound_packets = staticmethod(clientbound.login.get_packets)
def react(self, packet):
if packet.packet_name == "encryption request":
@ -489,7 +490,7 @@ class LoginReactor(PacketReactor):
if self.connection.auth_token is not None:
self.connection.auth_token.join(server_id)
encryption_response = packets.EncryptionResponsePacket()
encryption_response = serverbound.login.EncryptionResponsePacket()
encryption_response.shared_secret = encrypted_secret
encryption_response.verify_token = token
@ -519,7 +520,7 @@ class LoginReactor(PacketReactor):
class PlayingReactor(PacketReactor):
get_clientbound_packets = staticmethod(packets.state_playing_clientbound)
get_clientbound_packets = staticmethod(clientbound.play.get_packets)
def react(self, packet):
if packet.packet_name == "set compression":
@ -527,17 +528,17 @@ class PlayingReactor(PacketReactor):
self.connection.options.compression_enabled = True
if packet.packet_name == "keep alive":
keep_alive_packet = packets.KeepAlivePacketServerbound()
keep_alive_packet = serverbound.play.KeepAlivePacket()
keep_alive_packet.keep_alive_id = packet.keep_alive_id
self.connection.write_packet(keep_alive_packet)
if packet.packet_name == "player position and look":
if self.connection.context.protocol_version >= 107:
teleport_confirm = packets.TeleportConfirmPacket()
teleport_confirm = serverbound.play.TeleportConfirmPacket()
teleport_confirm.teleport_id = packet.teleport_id
self.connection.write_packet(teleport_confirm)
else:
position_response = packets.PositionAndLookPacket()
position_response = serverbound.play.PositionAndLookPacket()
position_response.x = packet.x
position_response.feet_y = packet.y
position_response.z = packet.z
@ -552,7 +553,7 @@ class PlayingReactor(PacketReactor):
class StatusReactor(PacketReactor):
get_clientbound_packets = staticmethod(packets.state_status_clientbound)
get_clientbound_packets = staticmethod(clientbound.status.get_packets)
def __init__(self, connection, do_ping=False):
super(StatusReactor, self).__init__(connection)
@ -562,7 +563,7 @@ class StatusReactor(PacketReactor):
if packet.packet_name == "response":
status_dict = json.loads(packet.json_response)
if self.do_ping:
ping_packet = packets.PingPacket()
ping_packet = serverbound.status.PingPacket()
# NOTE: it may be better to depend on the `monotonic' package
# or something similar for more accurate time measurement.
ping_packet.time = int(1000 * timeit.default_timer())

View File

@ -0,0 +1,76 @@
import unittest
from minecraft.networking import packets
from minecraft.networking.packets import clientbound
from minecraft.networking.packets import serverbound
class LegacyPacketNamesTest(unittest.TestCase):
def test_legacy_packets_equal_current_packets(self):
self.assertEqual(packets.state_handshake_clientbound,
clientbound.handshake.get_packets)
self.assertEqual(packets.HandShakePacket,
serverbound.handshake.HandShakePacket)
self.assertEqual(packets.state_handshake_serverbound,
serverbound.handshake.get_packets)
self.assertEqual(packets.ResponsePacket,
clientbound.status.ResponsePacket)
self.assertEqual(packets.PingPacketResponse,
clientbound.status.PingResponsePacket)
self.assertEqual(packets.state_status_clientbound,
clientbound.status.get_packets)
self.assertEqual(packets.RequestPacket,
serverbound.status.RequestPacket)
self.assertEqual(packets.PingPacket,
serverbound.status.PingPacket)
self.assertEqual(packets.state_status_serverbound,
serverbound.status.get_packets)
self.assertEqual(packets.DisconnectPacket,
clientbound.login.DisconnectPacket)
self.assertEqual(packets.EncryptionRequestPacket,
clientbound.login.EncryptionRequestPacket)
self.assertEqual(packets.LoginSuccessPacket,
clientbound.login.LoginSuccessPacket)
self.assertEqual(packets.SetCompressionPacket,
clientbound.login.SetCompressionPacket)
self.assertEqual(packets.state_login_clientbound,
clientbound.login.get_packets)
self.assertEqual(packets.LoginStartPacket,
serverbound.login.LoginStartPacket)
self.assertEqual(packets.EncryptionResponsePacket,
serverbound.login.EncryptionResponsePacket)
self.assertEqual(packets.state_login_serverbound,
serverbound.login.get_packets)
self.assertEqual(packets.KeepAlivePacketClientbound,
clientbound.play.KeepAlivePacket)
self.assertEqual(packets.KeepAlivePacketServerbound,
serverbound.play.KeepAlivePacket)
self.assertEqual(packets.JoinGamePacket,
clientbound.play.JoinGamePacket)
self.assertEqual(packets.ChatMessagePacket,
clientbound.play.ChatMessagePacket)
self.assertEqual(packets.PlayerPositionAndLookPacket,
clientbound.play.PlayerPositionAndLookPacket)
self.assertEqual(packets.DisconnectPacketPlayState,
clientbound.play.DisconnectPacket)
self.assertEqual(packets.SetCompressionPacketPlayState,
clientbound.play.SetCompressionPacket)
self.assertEqual(packets.PlayerListItemPacket,
clientbound.play.PlayerListItemPacket)
self.assertEqual(packets.MapPacket,
clientbound.play.MapPacket)
self.assertEqual(packets.state_playing_clientbound,
clientbound.play.get_packets)
self.assertEqual(packets.ChatPacket,
serverbound.play.ChatPacket)
self.assertEqual(packets.PositionAndLookPacket,
serverbound.play.PositionAndLookPacket)
self.assertEqual(packets.TeleportConfirmPacket,
serverbound.play.TeleportConfirmPacket)
self.assertEqual(packets.AnimationPacketServerbound,
serverbound.play.AnimationPacket)
self.assertEqual(packets.state_playing_serverbound,
serverbound.play.get_packets)

View File

@ -4,6 +4,8 @@ from minecraft import SUPPORTED_MINECRAFT_VERSIONS
from minecraft.networking import connection
from minecraft.networking import types
from minecraft.networking import packets
from minecraft.networking.packets import clientbound
from minecraft.networking.packets import serverbound
from future.utils import raise_
@ -170,19 +172,19 @@ class FakeServer(threading.Thread):
self.packets_handshake = {
p.get_id(self.context): p for p in
packets.state_handshake_serverbound(self.context)}
serverbound.handshake.get_packets(self.context)}
self.packets_login = {
p.get_id(self.context): p for p in
packets.state_login_serverbound(self.context)}
serverbound.login.get_packets(self.context)}
self.packets_playing = {
p.get_id(self.context): p for p in
packets.state_playing_serverbound(self.context)}
serverbound.play.get_packets(self.context)}
self.packets_status = {
p.get_id(self.context): p for p in
packets.state_status_serverbound(self.context)}
serverbound.status.get_packets(self.context)}
self.listen_socket = socket.socket()
self.listen_socket.bind(('0.0.0.0', 0))
@ -216,7 +218,7 @@ class FakeServer(threading.Thread):
def run_handshake(self, client_socket, client_file):
self.packets = self.packets_handshake
packet = self.read_packet_filtered(client_file)
assert isinstance(packet, packets.HandShakePacket)
assert isinstance(packet, serverbound.handshake.HandShakePacket)
if packet.next_state == 1:
return self.run_handshake_status(
packet, client_socket, client_file)
@ -240,7 +242,7 @@ class FakeServer(threading.Thread):
else:
msg = "Outdated server! I'm still on %s" \
% self.minecraft_version
packet = packets.DisconnectPacket(
packet = clientbound.login.DisconnectPacket(
self.context, json_data=json.dumps({'text': msg}))
self.write_packet(packet, client_socket)
return True
@ -248,15 +250,15 @@ class FakeServer(threading.Thread):
def run_login(self, client_socket, client_file):
self.packets = self.packets_login
packet = self.read_packet_filtered(client_file)
assert isinstance(packet, packets.LoginStartPacket)
assert isinstance(packet, serverbound.login.LoginStartPacket)
if self.compression_threshold is not None:
self.write_packet(packets.SetCompressionPacket(
self.write_packet(clientbound.login.SetCompressionPacket(
self.context, threshold=self.compression_threshold),
client_socket)
self.compression_enabled = True
packet = packets.LoginSuccessPacket(
packet = clientbound.login.LoginSuccessPacket(
self.context, UUID='{fake uuid}', Username=packet.name)
self.write_packet(packet, client_socket)
@ -265,21 +267,21 @@ class FakeServer(threading.Thread):
def run_playing(self, client_socket, client_file):
self.packets = self.packets_playing
packet = packets.JoinGamePacket(
packet = clientbound.play.JoinGamePacket(
self.context, entity_id=0, game_mode=0, dimension=0, difficulty=2,
max_players=1, level_type='default', reduced_debug_info=False)
self.write_packet(packet, client_socket)
keep_alive_id = 1076048782
packet = packets.KeepAlivePacketClientbound(
packet = clientbound.play.KeepAlivePacket(
self.context, keep_alive_id=keep_alive_id)
self.write_packet(packet, client_socket)
packet = self.read_packet_filtered(client_file)
assert isinstance(packet, packets.KeepAlivePacketServerbound)
assert isinstance(packet, serverbound.play.KeepAlivePacket)
assert packet.keep_alive_id == keep_alive_id
packet = packets.DisconnectPacketPlayState(
packet = clientbound.play.DisconnectPacket(
self.context, json_data=json.dumps({'text': 'Test complete.'}))
self.write_packet(packet, client_socket)
return False
@ -288,9 +290,9 @@ class FakeServer(threading.Thread):
self.packets = self.packets_status
packet = self.read_packet(client_file)
assert isinstance(packet, packets.RequestPacket)
assert isinstance(packet, serverbound.status.RequestPacket)
packet = packets.ResponsePacket(self.context)
packet = clientbound.status.ResponsePacket(self.context)
packet.json_response = json.dumps({
'version': {
'name': self.minecraft_version,
@ -307,9 +309,9 @@ class FakeServer(threading.Thread):
packet = self.read_packet(client_file)
except EOFError:
return False
assert isinstance(packet, packets.PingPacket)
assert isinstance(packet, serverbound.status.PingPacket)
res_packet = packets.PingPacketResponse(self.context)
res_packet = clientbound.status.PingResponsePacket(self.context)
res_packet.time = packet.time
self.write_packet(res_packet, client_socket)
return False
@ -317,9 +319,9 @@ class FakeServer(threading.Thread):
def read_packet_filtered(self, client_file):
while True:
packet = self.read_packet(client_file)
if isinstance(packet, packets.PositionAndLookPacket):
if isinstance(packet, serverbound.play.PositionAndLookPacket):
continue
if isinstance(packet, packets.AnimationPacketServerbound):
if isinstance(packet, serverbound.play.AnimationPacket):
continue
return packet

View File

@ -8,7 +8,7 @@ from minecraft import SUPPORTED_PROTOCOL_VERSIONS
from minecraft.networking.connection import ConnectionContext
from minecraft.networking.types import VarInt
from minecraft.networking.packets import (
PacketBuffer, ChatPacket, KeepAlivePacket, PacketListener)
PacketBuffer, PacketListener, KeepAlivePacket, serverbound)
class PacketBufferTest(unittest.TestCase):
@ -41,7 +41,7 @@ class PacketSerializatonTest(unittest.TestCase):
for protocol_version in SUPPORTED_PROTOCOL_VERSIONS:
context = ConnectionContext(protocol_version=protocol_version)
packet = ChatPacket(context)
packet = serverbound.play.ChatPacket(context)
packet.message = u"κόσμε"
packet_buffer = PacketBuffer()
@ -53,7 +53,7 @@ class PacketSerializatonTest(unittest.TestCase):
packet_id = VarInt.read(packet_buffer)
self.assertEqual(packet_id, packet.id)
deserialized = ChatPacket(context)
deserialized = serverbound.play.ChatPacket(context)
deserialized.read(packet_buffer)
self.assertEqual(packet.message, deserialized.message)
@ -63,7 +63,7 @@ class PacketSerializatonTest(unittest.TestCase):
context = ConnectionContext(protocol_version=protocol_version)
msg = ''.join(choice(string.ascii_lowercase) for i in range(500))
packet = ChatPacket(context)
packet = serverbound.play.ChatPacket(context)
packet.message = msg
self.write_read_packet(packet, 20)
@ -90,7 +90,7 @@ class PacketSerializatonTest(unittest.TestCase):
packet_id = VarInt.read(packet_buffer)
self.assertEqual(packet_id, packet.id)
deserialized = ChatPacket(context)
deserialized = serverbound.play.ChatPacket(context)
deserialized.read(packet_buffer)
self.assertEqual(packet.message, deserialized.message)
@ -107,9 +107,10 @@ class PacketListenerTest(unittest.TestCase):
for protocol_version in SUPPORTED_PROTOCOL_VERSIONS:
context = ConnectionContext(protocol_version=protocol_version)
listener = PacketListener(test_packet, ChatPacket)
listener = PacketListener(test_packet, serverbound.play.ChatPacket)
packet = ChatPacket(context).set_values(message=message)
packet = serverbound.play.ChatPacket(context).set_values(
message=message)
uncalled_packet = KeepAlivePacket().set_values(keep_alive_id=0)
listener.call_packet(packet)

View File

@ -1,9 +1,9 @@
import unittest
from minecraft.networking.types import (UUID, VarInt, String, Boolean)
from minecraft.networking.packets import PacketBuffer
from minecraft.networking.packets import PlayerPositionAndLookPacket
from minecraft.networking.packets import PlayerListItemPacket
from minecraft.networking.packets import MapPacket
from minecraft.networking.packets.clientbound.play import (
PlayerPositionAndLookPacket, PlayerListItemPacket, MapPacket
)
from minecraft.networking.connection import ConnectionContext

View File

@ -6,9 +6,7 @@ except ImportError:
from minecraft.networking.connection import (
LoginReactor, PlayingReactor, ConnectionContext
)
from minecraft.networking.packets import (
EncryptionRequestPacket, PlayerPositionAndLookPacket
)
from minecraft.networking.packets import clientbound
class LoginReactorTest(unittest.TestCase):
@ -18,7 +16,7 @@ class LoginReactorTest(unittest.TestCase):
connection = mock.MagicMock()
reactor = LoginReactor(connection)
packet = EncryptionRequestPacket()
packet = clientbound.login.EncryptionRequestPacket()
packet.server_id = "123"
packet.public_key = b"asdf"
packet.verify_token = b"23"
@ -41,7 +39,7 @@ class LoginReactorTest(unittest.TestCase):
connection = mock.MagicMock()
reactor = LoginReactor(connection)
packet = EncryptionRequestPacket()
packet = clientbound.login.EncryptionRequestPacket()
packet.server_id = "-"
packet.public_key = b"asdf"
packet.verify_token = b"23"
@ -62,7 +60,7 @@ class LoginReactorTest(unittest.TestCase):
class PlayingReactorTest(unittest.TestCase):
def get_position_packet(self):
packet = PlayerPositionAndLookPacket()
packet = clientbound.play.PlayerPositionAndLookPacket()
packet.x = 1.0
packet.y = 2.0
packet.z = 3.0