Handle entity metadata

This commit is contained in:
Tanner Collin 2020-09-23 00:00:28 -06:00
parent 97f248b0c6
commit 43f4eb3517
4 changed files with 79 additions and 5 deletions

16
game.py
View File

@ -10,7 +10,7 @@ from panda3d.core import LPoint3f
from minecraft.networking.packets import Packet, clientbound, serverbound from minecraft.networking.packets import Packet, clientbound, serverbound
from minecraft.networking.types import BlockFace from minecraft.networking.types import BlockFace
from protocol.packets import TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket, HeldItemChangePacket, PickItemPacket, OpenWindowPacket, ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket, ClientWindowConfirmationPacket from protocol.packets import TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket, HeldItemChangePacket, PickItemPacket, OpenWindowPacket, ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket, ClientWindowConfirmationPacket, EntityMetadataPacket
from protocol.types import Slot from protocol.types import Slot
import utils import utils
@ -188,6 +188,10 @@ class Game:
register(self.handle_break_ack, AcknowledgePlayerDiggingPacket) register(self.handle_break_ack, AcknowledgePlayerDiggingPacket)
register(self.handle_window, OpenWindowPacket) register(self.handle_window, OpenWindowPacket)
register(self.handle_window_confirmation, ClientWindowConfirmationPacket) register(self.handle_window_confirmation, ClientWindowConfirmationPacket)
register(self.handle_spawn_object, clientbound.play.SpawnObjectPacket)
register(self.handle_entity_metadata, EntityMetadataPacket)
#register(self.handle_packet, Packet, early=True)
self.g.chat.set_handler(self.handle_chat) self.g.chat.set_handler(self.handle_chat)
@ -492,6 +496,16 @@ class Game:
packet2.accepted = packet.accepted packet2.accepted = packet.accepted
self.g.connection.write_packet(packet2) self.g.connection.write_packet(packet2)
def handle_spawn_object(self, packet):
print(packet)
print(packet.type_id)
def handle_entity_metadata(self, packet):
print(packet)
def handle_packet(self, packet):
print(packet)
def tick(self): def tick(self):
if self.g.breaking: if self.g.breaking:
self.animate() self.animate()

View File

@ -20,6 +20,7 @@ def get_packets(old_get_packets):
mc_packets.add(packets.ClickWindowPacket) mc_packets.add(packets.ClickWindowPacket)
mc_packets.add(packets.ClientWindowConfirmationPacket) mc_packets.add(packets.ClientWindowConfirmationPacket)
mc_packets.add(packets.ServerWindowConfirmationPacket) mc_packets.add(packets.ServerWindowConfirmationPacket)
mc_packets.add(packets.EntityMetadataPacket)
return mc_packets return mc_packets
return lambda x: wrapper(old_get_packets, x) return lambda x: wrapper(old_get_packets, x)

View File

@ -4,10 +4,11 @@ from minecraft.networking.packets import Packet, PacketBuffer
from minecraft.networking.types import ( from minecraft.networking.types import (
VarInt, Integer, UnsignedByte, Position, Vector, MutableRecord, VarInt, Integer, UnsignedByte, Position, Vector, MutableRecord,
attribute_alias, multi_attribute_alias, Long, Boolean, VarLong, attribute_alias, multi_attribute_alias, Long, Boolean, VarLong,
Short, UnsignedLong, Byte, BlockFace, String Short, UnsignedLong, Byte, BlockFace, String, UUID, Angle, Double,
Float,
) )
from protocol.types import Nbt, Slot from protocol.types import Nbt, Slot, Entry
class ChunkDataPacket(Packet): class ChunkDataPacket(Packet):
@ -286,3 +287,23 @@ class ServerWindowConfirmationPacket(Packet):
{'action_number': Short}, {'action_number': Short},
{'accepted': Boolean}, {'accepted': Boolean},
] ]
class EntityMetadataPacket(Packet):
# Updates one or more metadata properties for an existing entity
# https://wiki.vg/Protocol#Entity_Metadata
id = 0x44
packet_name = 'entity metadata'
fields = 'entity_id', 'metadata'
class Entry:
__slots__ = 'index', 'type', 'value'
def read(self, file_object):
self.entity_id = VarInt.read(file_object)
self.metadata = []
for _ in range(99):
entry = Entry.read(file_object)
if not entry: break
self.metadata.append(entry)

View File

@ -4,7 +4,8 @@ import struct
from minecraft.networking.types.basic import ( from minecraft.networking.types.basic import (
Type, Byte, Short, Integer, Long, Float, Double, Type, Byte, Short, Integer, Long, Float, Double,
ShortPrefixedByteArray, Boolean, VarInt, TrailingByteArray ShortPrefixedByteArray, Boolean, VarInt, TrailingByteArray,
Position, String, UnsignedByte
) )
from minecraft.networking.types.utility import Vector from minecraft.networking.types.utility import Vector
@ -39,6 +40,8 @@ class Nbt(Type):
@staticmethod @staticmethod
def read(file_object): def read(file_object):
type_id = Byte.read(file_object) type_id = Byte.read(file_object)
if type_id == TAG_End:
return None
if type_id != TAG_Compound: if type_id != TAG_Compound:
raise Exception("Invalid NBT header") raise Exception("Invalid NBT header")
name = ShortPrefixedByteArray.read(file_object).decode('utf-8') name = ShortPrefixedByteArray.read(file_object).decode('utf-8')
@ -118,7 +121,8 @@ class Slot(Type):
present = Boolean.read(file_object) present = Boolean.read(file_object)
item_id = VarInt.read(file_object) if present else None item_id = VarInt.read(file_object) if present else None
item_count = Byte.read(file_object) if present else None item_count = Byte.read(file_object) if present else None
nbt = TrailingByteArray.read(file_object) if present else None print('slot read', present, item_id, item_count)
nbt = Nbt.read(file_object) if present else None
return Slot(present, item_id, item_count, nbt) return Slot(present, item_id, item_count, nbt)
@staticmethod @staticmethod
@ -127,3 +131,37 @@ class Slot(Type):
VarInt.send(value.item_id, socket) VarInt.send(value.item_id, socket)
Byte.send(value.item_count, socket) Byte.send(value.item_count, socket)
TrailingByteArray.send(value.nbt, socket) TrailingByteArray.send(value.nbt, socket)
class Entry(Type):
types = {
0: Byte,
1: VarInt,
2: Float,
3: String,
6: Slot,
7: Boolean,
9: Position,
}
def __init__(self, index, type, value):
self.index = index
self.type = type
self.value = value
def __str__(self):
return str(self.__dict__)
def __repr__(self):
return 'Entry(index={}, type={}, value={}'.format(
self.index, self.type, self.value)
@staticmethod
def read(file_object):
index = UnsignedByte.read(file_object)
if index == 0xff: return None
type = VarInt.read(file_object)
try:
value = Entry.types[type].read(file_object)
except KeyError:
return None
return Entry(index, type, value)