From 2bdea5a0f94fff5014fe297a7abee3dbde5b8c53 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 27 Sep 2020 21:44:24 -0700 Subject: [PATCH] Implement TransactionConfirmation event + packet --- bot/event.go | 5 +++-- bot/ingame.go | 14 ++++++++++++++ bot/phy/phy.go | 4 ++-- bot/world/entity/entity.go | 29 ++++++++++++++++++++++++++--- data/inv/inv.go | 18 ++++++++++++++++++ data/{items => item}/gen_item.go | 0 data/{items => item}/item.go | 0 net/ptypes/inventory.go | 20 ++++++++++++++++++++ 8 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 data/inv/inv.go rename data/{items => item}/gen_item.go (100%) rename data/{items => item}/item.go (100%) diff --git a/bot/event.go b/bot/event.go index 81fe221..71fa11f 100644 --- a/bot/event.go +++ b/bot/event.go @@ -51,8 +51,9 @@ type eventBroker struct { // total - total amount of experience received from level 0. ExperienceChange func(bar float32, level int32, total int32) error - WindowsItem func(id byte, slots []entity.Slot) error - WindowsItemChange func(id byte, slotID int, slot entity.Slot) error + WindowsItem func(id byte, slots []entity.Slot) error + WindowsItemChange func(id byte, slotID int, slot entity.Slot) error + WindowConfirmation func(pkt ptypes.ConfirmTransaction) error // ServerDifficultyChange is called whenever the gamemode of the server changes. // At time of writing (1.16.3), difficulty values of 0, 1, 2, and 3 correspond diff --git a/bot/ingame.go b/bot/ingame.go index d39ddb8..5ceca71 100644 --- a/bot/ingame.go +++ b/bot/ingame.go @@ -151,6 +151,8 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { err = handleWindowItemsPacket(c, p) case data.OpenWindow: err = handleOpenWindowPacket(c, p) + case data.TransactionClientbound: + err = handleWindowConfirmationPacket(c, p) case data.DeclareRecipes: // handleDeclareRecipesPacket(g, reader) @@ -736,6 +738,18 @@ func handleOpenWindowPacket(c *Client, p pk.Packet) error { return nil } +func handleWindowConfirmationPacket(c *Client, p pk.Packet) error { + var pkt ptypes.ConfirmTransaction + if err := pkt.Decode(p); err != nil { + return err + } + + if c.Events.WindowConfirmation != nil { + return c.Events.WindowConfirmation(pkt) + } + return nil +} + func handleSetExperience(c *Client, p pk.Packet) (err error) { var ( bar pk.Float diff --git a/bot/phy/phy.go b/bot/phy/phy.go index 5492e58..31e205a 100644 --- a/bot/phy/phy.go +++ b/bot/phy/phy.go @@ -17,8 +17,8 @@ const ( playerHeight = 1.8 resetVel = 0.003 - maxYawChange = 7 - maxPitchChange = 5 + maxYawChange = 11 + maxPitchChange = 7 stepHeight = 0.6 minJumpTicks = 14 diff --git a/bot/world/entity/entity.go b/bot/world/entity/entity.go index 54d0413..bdc6d66 100644 --- a/bot/world/entity/entity.go +++ b/bot/world/entity/entity.go @@ -1,8 +1,10 @@ package entity import ( + "bytes" + "github.com/Tnze/go-mc/data/entity" - item "github.com/Tnze/go-mc/data/items" + item "github.com/Tnze/go-mc/data/item" "github.com/Tnze/go-mc/nbt" pk "github.com/Tnze/go-mc/net/packet" "github.com/google/uuid" @@ -45,7 +47,7 @@ type Entity struct { // The Slot data structure is how Minecraft represents an item and its associated data in the Minecraft Protocol type Slot struct { Present bool - ItemID int32 + ItemID item.ID Count int8 NBT interface{} } @@ -56,9 +58,11 @@ func (s *Slot) Decode(r pk.DecodeReader) error { return err } if s.Present { - if err := (*pk.VarInt)(&s.ItemID).Decode(r); err != nil { + var itemID pk.VarInt + if err := itemID.Decode(r); err != nil { return err } + s.ItemID = item.ID(itemID) if err := (*pk.Byte)(&s.Count).Decode(r); err != nil { return err } @@ -69,6 +73,25 @@ func (s *Slot) Decode(r pk.DecodeReader) error { return nil } +func (s Slot) Encode() []byte { + if !s.Present { + return pk.Boolean(false).Encode() + } + + var b bytes.Buffer + b.Write(pk.Boolean(true).Encode()) + b.Write(pk.VarInt(s.ItemID).Encode()) + b.Write(pk.Byte(s.Count).Encode()) + + if s.NBT != nil { + nbt.NewEncoder(&b).Encode(s.NBT) + } else { + b.Write([]byte{nbt.TagEnd}) + } + + return b.Bytes() +} + func (s Slot) String() string { return item.ByID[item.ID(s.ItemID)].DisplayName } diff --git a/data/inv/inv.go b/data/inv/inv.go new file mode 100644 index 0000000..8c0eb67 --- /dev/null +++ b/data/inv/inv.go @@ -0,0 +1,18 @@ +// Package inv maps window types to inventory slot information. +package inv + +type Info struct { + Name string + Start, End int // Player inventory + Slots int +} + +var ByType = map[int]Info{ + -1: Info{Name: "inventory", Start: 9, End: 44, Slots: 46}, + 0: Info{Name: "generic_9x1", Start: 1 * 9, End: 1*9 + 35, Slots: 1*9 + 36}, + 1: Info{Name: "generic_9x2", Start: 2 * 9, End: 2*9 + 35, Slots: 2*9 + 36}, + 2: Info{Name: "generic_9x3", Start: 3 * 9, End: 3*9 + 35, Slots: 3*9 + 36}, + 3: Info{Name: "generic_9x4", Start: 4 * 9, End: 4*9 + 35, Slots: 4*9 + 36}, + 4: Info{Name: "generic_9x5", Start: 5 * 9, End: 5*9 + 35, Slots: 5*9 + 36}, + 5: Info{Name: "generic_9x6", Start: 6 * 9, End: 6*9 + 35, Slots: 6*9 + 36}, +} diff --git a/data/items/gen_item.go b/data/item/gen_item.go similarity index 100% rename from data/items/gen_item.go rename to data/item/gen_item.go diff --git a/data/items/item.go b/data/item/item.go similarity index 100% rename from data/items/item.go rename to data/item/item.go diff --git a/net/ptypes/inventory.go b/net/ptypes/inventory.go index 0e2824e..3170aed 100644 --- a/net/ptypes/inventory.go +++ b/net/ptypes/inventory.go @@ -7,6 +7,7 @@ import ( "github.com/Tnze/go-mc/bot/world/entity" "github.com/Tnze/go-mc/chat" + "github.com/Tnze/go-mc/data" "github.com/Tnze/go-mc/nbt" pk "github.com/Tnze/go-mc/net/packet" ) @@ -67,3 +68,22 @@ func (p *OpenWindow) Decode(pkt pk.Packet) error { } return nil } + +type ConfirmTransaction struct { + WindowID pk.Byte + ActionID pk.Short + Accepted pk.Boolean +} + +func (p *ConfirmTransaction) Decode(pkt pk.Packet) error { + return pkt.Scan(&p.WindowID, &p.ActionID, &p.Accepted) +} + +func (p ConfirmTransaction) Encode() pk.Packet { + return pk.Marshal( + data.TransactionServerbound, + p.WindowID, + p.ActionID, + p.Accepted, + ) +}