From d63cc1de3f7225b31c5aa5b51427c97147823850 Mon Sep 17 00:00:00 2001 From: Lukas <77849373+qwqtoday@users.noreply.github.com> Date: Wed, 1 May 2024 20:01:02 +0800 Subject: [PATCH] implementing storing chest data into Manager.Screens in bot/screen (#279) --- bot/msg/chat.go | 24 ++++++ bot/screen/chest.go | 39 ++++++++++ bot/screen/events.go | 4 +- bot/screen/screen.go | 20 ++++- data/inventory/inventory.go | 143 ++++++++++++++++++++++++++++++++++++ 5 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 bot/screen/chest.go create mode 100644 data/inventory/inventory.go diff --git a/bot/msg/chat.go b/bot/msg/chat.go index c6c6c8f..8208cde 100644 --- a/bot/msg/chat.go +++ b/bot/msg/chat.go @@ -175,6 +175,30 @@ func (m *Manager) SendMessage(msg string) error { return err } +// SendMessage send chat message to server. +// Doesn't support sending message with signature currently. +func (m *Manager) SendCommand(command string) error { + if len(command) > 256 { + return errors.New("message length greater than 256") + } + var salt int64 + if err := binary.Read(rand.Reader, binary.BigEndian, &salt); err != nil { + return err + } + + err := m.c.Conn.WritePacket(pk.Marshal( + packetid.ServerboundChatCommand, + pk.String(command), + pk.Long(time.Now().UnixMilli()), + pk.Long(salt), + pk.Ary[pk.VarInt]{Ary: []pk.Tuple{}}, + sign.HistoryUpdate{ + Acknowledged: pk.NewFixedBitSet(20), + }, + )) + return err +} + var ( InvalidChatPacket = errors.New("invalid chat packet") ValidationFailed error = bot.DisconnectErr(chat.TranslateMsg("multiplayer.disconnect.chat_validation_failed")) diff --git a/bot/screen/chest.go b/bot/screen/chest.go new file mode 100644 index 0000000..7123a7f --- /dev/null +++ b/bot/screen/chest.go @@ -0,0 +1,39 @@ +package screen + +import ( + "errors" + + "github.com/Tnze/go-mc/chat" + "github.com/Tnze/go-mc/data/inventory" +) + +type Chest struct { + Type inventory.InventoryID + Title chat.Message + Slots []Slot + Rows int +} + +func (c *Chest) onSetSlot(i int, slot Slot) error { + if i < 0 || i >= len(c.Slots) { + return errors.New("slot index out of bounds") + } + c.Slots[i] = slot + return nil +} + +func (c *Chest) onClose() error { + return nil +} + +func (c *Chest) Container() []Slot { + return c.Slots[0 : c.Rows*9] +} + +func (c *Chest) Main() []Slot { + return c.Slots[c.Rows*9 : c.Rows*9+27] +} + +func (c *Chest) Hotbar() []Slot { + return c.Slots[c.Rows*9+27 : (c.Rows+4)*9] +} diff --git a/bot/screen/events.go b/bot/screen/events.go index e538706..26ff050 100644 --- a/bot/screen/events.go +++ b/bot/screen/events.go @@ -1,7 +1,9 @@ package screen +import "github.com/Tnze/go-mc/chat" + type EventsListener struct { - Open func(id int) error + Open func(id int, container_type int32, title chat.Message) error SetSlot func(id, index int) error Close func(id int) error } diff --git a/bot/screen/screen.go b/bot/screen/screen.go index 1e913c4..7be47dd 100644 --- a/bot/screen/screen.go +++ b/bot/screen/screen.go @@ -81,11 +81,23 @@ func (m *Manager) onOpenScreen(p pk.Packet) error { if err := p.Scan(&ContainerID, &Type, &Title); err != nil { return Error{err} } - //if c, ok := m.Screens[byte(ContainerID)]; ok { - // TODO: Create the specified container - //} + if _, ok := m.Screens[int(ContainerID)]; !ok { + TypeInt32 := int32(Type) + if TypeInt32 < 6 { + Rows := TypeInt32 + 1 + chest := Chest{ + Type: TypeInt32, + Slots: make([]Slot, 9*Rows), + Rows: int(Rows), + Title: Title, + } + m.Screens[int(ContainerID)] = &chest + } + } else { + return errors.New("container id already exists in screens") + } if m.events.Open != nil { - if err := m.events.Open(int(ContainerID)); err != nil { + if err := m.events.Open(int(ContainerID), int32(Type), Title); err != nil { return Error{err} } } diff --git a/data/inventory/inventory.go b/data/inventory/inventory.go new file mode 100644 index 0000000..a45cf0f --- /dev/null +++ b/data/inventory/inventory.go @@ -0,0 +1,143 @@ +package inventory + +type InventoryID = int32 + +const ( + Generic9x1 InventoryID = iota + Generic9x2 + Generic9x3 + Generic9x4 + Generic9x5 + Generic9x6 + Generic3x3 + Crafter3x3 + Anvil + Beacon + BlastFurnace + BrewingStand + Crafting + Enchantment + Furnace + Grindstone + Hopper + Lectern + Loom + Merchant + ShulkerBox + Smithing + Smoker + Cartography + Stonecutter +) + +func IDToName(t InventoryID) string { + switch t { + case Generic9x1: + return "generic_9x1" + case Generic9x2: + return "generic_9x2" + case Generic9x3: + return "generic_9x3" + case Generic9x4: + return "generic_9x4" + case Generic9x5: + return "generic_9x5" + case Generic9x6: + return "generic_9x6" + case Generic3x3: + return "generic_3x3" + case Crafter3x3: + return "crafter_3x3" + case Anvil: + return "anvil" + case Beacon: + return "beacon" + case BlastFurnace: + return "blast_furnace" + case BrewingStand: + return "brewing_stand" + case Crafting: + return "crafting" + case Enchantment: + return "enchantment" + case Furnace: + return "furnace" + case Grindstone: + return "grindstone" + case Hopper: + return "hopper" + case Lectern: + return "lectern" + case Loom: + return "loom" + case Merchant: + return "merchant" + case ShulkerBox: + return "shulker_box" + case Smithing: + return "smithing" + case Smoker: + return "smoker" + case Cartography: + return "cartography" + case Stonecutter: + return "stonecutter" + } + return "" +} + +func NameToID(name string) InventoryID { + switch name { + case "generic_9x1": + return Generic9x1 + case "generic_9x2": + return Generic9x2 + case "generic_9x3": + return Generic9x3 + case "generic_9x4": + return Generic9x4 + case "generic_9x5": + return Generic9x5 + case "generic_9x6": + return Generic9x6 + case "generic_3x3": + return Generic3x3 + case "crafter_3x3": + return Crafter3x3 + case "anvil": + return Anvil + case "beacon": + return Beacon + case "blast_furnace": + return BlastFurnace + case "brewing_stand": + return BrewingStand + case "crafting": + return Crafting + case "enchantment": + return Enchantment + case "furnace": + return Furnace + case "grindstone": + return Grindstone + case "hopper": + return Hopper + case "lectern": + return Lectern + case "loom": + return Loom + case "merchant": + return Merchant + case "shulker_box": + return ShulkerBox + case "smithing": + return Smithing + case "smoker": + return Smoker + case "cartography": + return Cartography + case "stonecutter": + return Stonecutter + } + return -1 +}