Add packets for entity interaction and trade list
This commit is contained in:
parent
af1db24cd5
commit
b72c335ff7
27
game.py
27
game.py
|
@ -20,7 +20,7 @@ from protocol.packets import (
|
|||
ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
|
||||
ClientWindowConfirmationPacket, EntityMetadataPacket,
|
||||
SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
|
||||
EntityActionPacket, EntityTeleport,
|
||||
EntityActionPacket, EntityTeleport, InteractEntityPacket, TradeListPacket
|
||||
)
|
||||
|
||||
from protocol.types import Slot
|
||||
|
@ -338,6 +338,7 @@ class Game:
|
|||
register(self.handle_entity_teleport, EntityTeleport)
|
||||
register(self.handle_update_health, clientbound.play.UpdateHealthPacket)
|
||||
#register(self.handle_entity_velocity, clientbound.play.EntityVelocityPacket)
|
||||
register(self.handle_trade_list, TradeListPacket)
|
||||
|
||||
#register(self.handle_packet, Packet, early=True)
|
||||
|
||||
|
@ -535,6 +536,16 @@ class Game:
|
|||
print(str(k) + ':', v, mobs.MOB_NAMES[v.type])
|
||||
reply = str(count) + ' monsters'
|
||||
|
||||
if command == 'villagers':
|
||||
all_mobs = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type)
|
||||
count = 0
|
||||
for k, v in all_mobs:
|
||||
type_name = mobs.MOB_NAMES[v.type]
|
||||
if type_name != 'villager' : continue
|
||||
count += 1
|
||||
print(str(k) + ':', v, type_name)
|
||||
reply = str(count) + ' villagers'
|
||||
|
||||
if command == 'threats':
|
||||
distance = int(data) if data else 20
|
||||
p = utils.pint(self.g.pos)
|
||||
|
@ -757,6 +768,9 @@ class Game:
|
|||
if command == 'use':
|
||||
self.use_item(0)
|
||||
|
||||
if command == 'interact' and data:
|
||||
self.interact(int(data))
|
||||
|
||||
if command == 'test':
|
||||
reply = 'ok'
|
||||
self.select_next_item()
|
||||
|
@ -1115,6 +1129,17 @@ class Game:
|
|||
packet.hand = hand
|
||||
self.g.connection.write_packet(packet)
|
||||
|
||||
def interact(self, eid):
|
||||
packet = InteractEntityPacket()
|
||||
packet.entity_id = eid
|
||||
packet.type = 0
|
||||
packet.hand = 0
|
||||
packet.sneaking = False
|
||||
self.g.connection.write_packet(packet)
|
||||
|
||||
def handle_trade_list(self, packet):
|
||||
print(packet)
|
||||
|
||||
def tick(self):
|
||||
if self.g.breaking:
|
||||
self.animate()
|
||||
|
|
|
@ -18,6 +18,7 @@ def get_packets(old_get_packets):
|
|||
mc_packets.add(packets.EntityPositionRotationPacket)
|
||||
mc_packets.add(packets.DestroyEntitiesPacket)
|
||||
mc_packets.add(packets.EntityTeleport)
|
||||
mc_packets.add(packets.TradeListPacket)
|
||||
|
||||
|
||||
return mc_packets
|
||||
|
|
|
@ -8,7 +8,7 @@ from minecraft.networking.types import (
|
|||
Float, Direction, PositionAndLook
|
||||
)
|
||||
|
||||
from protocol.types import Nbt, Slot, Entry
|
||||
from protocol.types import Nbt, Slot, Entry, Trade
|
||||
|
||||
import blocks
|
||||
|
||||
|
@ -391,3 +391,48 @@ class EntityActionPacket(Packet):
|
|||
{'action_id': VarInt},
|
||||
{'jump_boost': VarInt},
|
||||
]
|
||||
|
||||
class InteractEntityPacket(Packet):
|
||||
# Sent when the client attacks or right-clicks another entity
|
||||
# https://wiki.vg/Protocol#Interact_Entity
|
||||
|
||||
id = 0x0E
|
||||
packet_name = 'interact entity'
|
||||
|
||||
definition = [
|
||||
{'entity_id': VarInt},
|
||||
{'type': VarInt},
|
||||
#{'target_x': Float},
|
||||
#{'target_y': Float},
|
||||
#{'target_z': Float},
|
||||
{'hand': VarInt},
|
||||
{'sneaking': Boolean},
|
||||
]
|
||||
|
||||
class TradeListPacket(Packet):
|
||||
# The list of trades a villager NPC is offering.
|
||||
# https://wiki.vg/Protocol#Trade_List
|
||||
|
||||
id = 0x26
|
||||
packet_name = 'trade list'
|
||||
fields = (
|
||||
'window_id',
|
||||
'size',
|
||||
'trades',
|
||||
'villager_level',
|
||||
'experience',
|
||||
'is_regular_villager',
|
||||
'can_restock',
|
||||
)
|
||||
|
||||
def read(self, file_object):
|
||||
self.window_id = VarInt.read(file_object)
|
||||
self.size = Byte.read(file_object)
|
||||
self.trades = []
|
||||
for _ in range(self.size):
|
||||
trade = Trade.read(file_object)
|
||||
self.trades.append(trade)
|
||||
self.villager_level = VarInt.read(file_object)
|
||||
self.experience = VarInt.read(file_object)
|
||||
self.is_regular_villager = Boolean.read(file_object)
|
||||
self.can_restock = Boolean.read(file_object)
|
||||
|
|
|
@ -172,3 +172,42 @@ class Entry(Type):
|
|||
except KeyError:
|
||||
return None
|
||||
return Entry(index, type, value)
|
||||
|
||||
|
||||
class Trade(Type):
|
||||
fields = (
|
||||
'input_item_1',
|
||||
'output_item',
|
||||
'has_second_item',
|
||||
'input_item_2',
|
||||
'trade_disabled',
|
||||
'num_uses',
|
||||
'max_num_uses',
|
||||
'xp',
|
||||
'special_price',
|
||||
'price_multiplier',
|
||||
'demand',
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__dict__)
|
||||
def __repr__(self):
|
||||
inner_str = ', '.join('%s=%s' % (a, getattr(self, a, None)) for a in self.fields if hasattr(self, a))
|
||||
return 'Trade(%s)' % inner_str
|
||||
|
||||
@staticmethod
|
||||
def read(file_object):
|
||||
trade = Trade()
|
||||
trade.input_item_1 = Slot.read(file_object)
|
||||
trade.output_item = Slot.read(file_object)
|
||||
trade.has_second_item = Boolean.read(file_object)
|
||||
if trade.has_second_item:
|
||||
trade.input_item_2 = Slot.read(file_object)
|
||||
trade.trade_disabled = Boolean.read(file_object)
|
||||
trade.num_uses = Integer.read(file_object)
|
||||
trade.max_num_uses = Integer.read(file_object)
|
||||
trade.xp = Integer.read(file_object)
|
||||
trade.special_price = Integer.read(file_object)
|
||||
trade.price_multiplier = Float.read(file_object)
|
||||
trade.demand = Integer.read(file_object)
|
||||
return trade
|
||||
|
|
Loading…
Reference in New Issue
Block a user