Add TeleportConfirmPacket and AnimationPacketServerBound packets. Add PlayerPositionAndLookPacket.PositionAndLook utility class. Fix a bug causing Disconnect packets to be ignored in some circumstances.

This commit is contained in:
joo 2016-03-28 05:08:01 +01:00
parent d966709204
commit e1626ea7e0
2 changed files with 67 additions and 8 deletions

View File

@ -225,14 +225,19 @@ class NetworkingThread(threading.Thread):
while True: while True:
if self.interrupt: if self.interrupt:
break break
# Attempt to write out as many as 300 packets as possible every # Attempt to write out as many as 300 packets as possible every
# 0.05 seconds (20 ticks per second) # 0.05 seconds (20 ticks per second)
num_packets = 0 num_packets = 0
self.connection._write_lock.acquire() self.connection._write_lock.acquire()
try:
while self.connection._pop_packet(): while self.connection._pop_packet():
num_packets += 1 num_packets += 1
if num_packets >= 300: if num_packets >= 300:
break break
exc_info = None
except:
exc_info = sys.exc_info()
self.connection._write_lock.release() self.connection._write_lock.release()
# Read and react to as many as 50 packets # Read and react to as many as 50 packets
@ -241,7 +246,6 @@ class NetworkingThread(threading.Thread):
self.connection.file_object) self.connection.file_object)
while packet: while packet:
num_packets += 1 num_packets += 1
try: try:
self.connection.reactor.react(packet) self.connection.reactor.react(packet)
for listener in self.connection.packet_listeners: for listener in self.connection.packet_listeners:
@ -254,6 +258,9 @@ class NetworkingThread(threading.Thread):
packet = self.connection.reactor.read_packet( packet = self.connection.reactor.read_packet(
self.connection.file_object) self.connection.file_object)
if exc_info is not None:
raise exc_info[0], exc_info[1], exc_info[2]
time.sleep(0.05) time.sleep(0.05)
@ -415,6 +422,10 @@ class PlayingReactor(PacketReactor):
self.connection.write_packet(keep_alive_packet) self.connection.write_packet(keep_alive_packet)
if packet.packet_name == "player position and look": if packet.packet_name == "player position and look":
teleport_confirm = packets.TeleportConfirmPacket()
teleport_confirm.teleport_id = packet.teleport_id
self.connection.write_packet(teleport_confirm)
'''
position_response = packets.PositionAndLookPacket() position_response = packets.PositionAndLookPacket()
position_response.x = packet.x position_response.x = packet.x
position_response.feet_y = packet.y position_response.feet_y = packet.y
@ -422,8 +433,8 @@ class PlayingReactor(PacketReactor):
position_response.yaw = packet.yaw position_response.yaw = packet.yaw
position_response.pitch = packet.pitch position_response.pitch = packet.pitch
position_response.on_ground = True position_response.on_ground = True
self.connection.write_packet(position_response) self.connection.write_packet(position_response)
'''
self.connection.spawned = True self.connection.spawned = True
''' '''

View File

@ -76,6 +76,7 @@ class Packet(object):
def __init__(self, context=None, **kwargs): def __init__(self, context=None, **kwargs):
self.context = context self.context = context
self.set_values(**kwargs)
@property @property
def context(self): def context(self):
@ -321,6 +322,32 @@ class PlayerPositionAndLookPacket(Packet):
{'teleport_id': VarInt} if context.protocol_version >= 107 else {}, {'teleport_id': VarInt} if context.protocol_version >= 107 else {},
]) ])
FLAG_REL_X = 0x01
FLAG_REL_Y = 0x02
FLAG_REL_Z = 0x04
FLAG_REL_YAW = 0x08
FLAG_REL_PITCH = 0x10
class PositionAndLook(object):
__slots__ = 'x', 'y', 'z', 'yaw', 'pitch'
def __init__(self, **kwds):
for attr in self.__slots__:
setattr(self, attr, kwds.get(attr))
# Update a PositionAndLook instance using this packet.
def apply(self, target):
if self.flags & self.FLAG_REL_X: target.x += self.x
else: target.x = self.x
if self.flags & self.FLAG_REL_Y: target.y += self.y
else: target.y = self.y
if self.flags & self.FLAG_REL_Z: target.z += self.z
else: target.z = self.z
if self.flags & self.FLAG_REL_YAW: target.yaw += self.yaw
else: target.yaw = self.yaw
if self.flags & self.FLAG_REL_PITCH: target.pitch += self.pitch
else: target.pitch = self.pitch
self.yaw %= 360
self.pitch %= 360
class DisconnectPacketPlayState(Packet): class DisconnectPacketPlayState(Packet):
get_id = staticmethod(lambda context: get_id = staticmethod(lambda context:
@ -606,10 +633,31 @@ class PositionAndLookPacket(Packet):
{'pitch': Float}, {'pitch': Float},
{'on_ground': Boolean}] {'on_ground': Boolean}]
class TeleportConfirmPacket(Packet):
# Note: added between protocol versions 47 and 107.
id = 0x00
packet_name = "teleport confirm"
definition = [
{'teleport_id': VarInt}]
class AnimationPacketServerbound(Packet):
get_id = staticmethod(lambda context:
0x1A if context.protocol_version >= 107 else
0x0A)
packet_name = "animation"
get_definition = staticmethod(lambda context: [
{'hand': VarInt} if context.protocol_version >= 107 else {}])
HAND_MAIN = 0
HAND_OFF = 1
def state_playing_serverbound(context): def state_playing_serverbound(context):
return { packets = {
KeepAlivePacketServerbound, KeepAlivePacketServerbound,
ChatPacket, ChatPacket,
PositionAndLookPacket PositionAndLookPacket,
AnimationPacketServerbound,
} }
if context.protocol_version >= 107: packets |= {
TeleportConfirmPacket,
}
return packets