diff --git a/bot/screen/inventory.go b/bot/screen/inventory.go new file mode 100644 index 0000000..8da3e2b --- /dev/null +++ b/bot/screen/inventory.go @@ -0,0 +1,8 @@ +package screen + +type Inventory struct { +} + +func (inv Inventory) SetSlot(i int, id int32, count byte, NBT interface{}) { + panic("implement me") +} diff --git a/bot/screen/screen.go b/bot/screen/screen.go new file mode 100644 index 0000000..d03689b --- /dev/null +++ b/bot/screen/screen.go @@ -0,0 +1,90 @@ +package screen + +import ( + "io" + + "github.com/Tnze/go-mc/bot" + "github.com/Tnze/go-mc/chat" + "github.com/Tnze/go-mc/data/packetid" + pk "github.com/Tnze/go-mc/net/packet" +) + +type Manager struct { + Screens map[byte]Container +} + +func NewManager(c *bot.Client) *Manager { + m := &Manager{Screens: make(map[byte]Container)} + m.Screens[0] = &Inventory{} + c.Events.AddListener( + bot.PacketHandler{Priority: 64, ID: packetid.OpenWindow, F: m.onOpenScreen}, + ) + return m +} + +func (m *Manager) onOpenScreen(p pk.Packet) error { + var ( + ContainerID pk.VarInt + Type pk.VarInt + Title chat.Message + ) + if err := p.Scan(&ContainerID, &Type, &Title); err != nil { + return Error{err} + } + // TODO: Create the specified container + return nil +} + +func (m *Manager) onSetContentPacket(p pk.Packet) error { + var ( + ContainerID pk.UnsignedByte + Count pk.Short + SlotData []slot + ) + if err := p.Scan( + &ContainerID, + &Count, pk.Ary{ + Len: &Count, + Ary: &SlotData, + }); err != nil { + return Error{err} + } + container := m.Screens[byte(ContainerID)] + for i, v := range SlotData { + container.SetSlot(i, int32(v.id), byte(v.count), v.nbt) + } + return nil +} + +type slot struct { + present pk.Boolean + id pk.VarInt + count pk.Byte + nbt interface{} +} + +func (s *slot) ReadFrom(r io.Reader) (n int64, err error) { + return pk.Tuple{ + &s.present, pk.Opt{Has: &s.present, + Field: pk.Tuple{ + &s.id, &s.count, pk.NBT(&s.nbt), + }, + }, + }.ReadFrom(r) +} + +type Container interface { + SetSlot(i int, id int32, count byte, NBT interface{}) +} + +type Error struct { + Err error +} + +func (e Error) Error() string { + return "bot/screen: " + e.Err.Error() +} + +func (e Error) Unwrap() error { + return e.Err +}