diff --git a/bot/provider/basic.go b/bot/provider/basic.go index 870f9e72d..c71f5de44 100644 --- a/bot/provider/basic.go +++ b/bot/provider/basic.go @@ -13,6 +13,7 @@ import ( "github.com/Edouard127/go-mc/data/entity" "github.com/Edouard127/go-mc/data/enums" "github.com/Edouard127/go-mc/data/packetid" + "github.com/Edouard127/go-mc/internal/util" "github.com/Edouard127/go-mc/level/block" "github.com/Edouard127/go-mc/maths" pk "github.com/Edouard127/go-mc/net/packet" @@ -29,7 +30,7 @@ type Player struct { PlayerInfo world.PlayerInfo WorldInfo world.WorldInfo EntityPlayer *core.EntityPlayer - Transactions *transactions.Transactions + Transactions *util.Queue[[]*transactions.SlotAction] Abilities *Abilities // Player info @@ -67,7 +68,7 @@ func NewPlayer(settings basic.Settings, clientWorld *world.World, info data.Auth EntityPlayer: core.NewEntityPlayer(info.Name, 0, uuid.MustParse(info.UUID), 116, 0, 0, 0, 0, 0), Controller: &core.Controller{}, Manager: screen.NewManager(), - Transactions: transactions.NewTransactions(), + Transactions: util.NewQueue[[]*transactions.SlotAction](), Abilities: NewAbilities(), IsSpawn: false, } @@ -106,13 +107,12 @@ func (pl *Player) Chat(c *Client, msg string) error { } func RunTransactions(c *Client, cancel context.CancelFunc) error { - if t := c.Player.Transactions.Next(); t == nil { - return nil - } else { - for _, v := range t.Packets { - if err := c.Conn.WritePacket(*v); err != nil { - return err - } + var next []*transactions.SlotAction + for c.Player.Transactions.Len() > 0 { + next = c.Player.Transactions.Pop() + + for i := range next { + c.Conn.WritePacket(pk.Marshal(packetid.SPacketClickWindow, pk.UnsignedByte(c.Player.Manager.CurrentScreen.GetType()), pk.VarInt(c.Player.Manager.StateID), next[i])) } } diff --git a/bot/provider/events.go b/bot/provider/events.go index 024dd13a0..30d285de4 100644 --- a/bot/provider/events.go +++ b/bot/provider/events.go @@ -293,24 +293,17 @@ func SetContainerContent(c *Client, p pk.Packet, cancel context.CancelFunc) erro state pk.VarInt data []Slot item Slot + err error ) if err := p.Scan(&id, &state, pk.Array(&data), &item); err != nil { return fmt.Errorf("failed to scan SetContainerContent: %w", err) } - var container screen.Container + container := screen.Containers[int(id)] - c.Player.Manager.StateID = int32(state) - - if id == 0 { - container = c.Player.Manager.Inventory - } else { - container = c.Player.Manager.Screens[int(id)] - } - - for i, data := range data { - err := container.SetSlot(i, data) + for i := range data { + err = container.SetSlot(i, &data[i]) if err != nil { return err } @@ -366,15 +359,7 @@ func SetContainerSlot(c *Client, p pk.Packet, cancel context.CancelFunc) error { c.Player.Manager.StateID = int32(stateId) - var container screen.Container - - if containerId == 0 { - container = c.Player.Manager.Inventory - } else { - container = c.Player.Manager.Screens[int(containerId)] - } - - return container.SetSlot(int(slotId), data) + return screen.Containers[int(containerId)].SetSlot(int(slotId), &data) } func SetCooldown(c *Client, p pk.Packet, cancel context.CancelFunc) error { diff --git a/bot/screen/constants.go b/bot/screen/constants.go index 8048bc09d..e2cdf4200 100644 --- a/bot/screen/constants.go +++ b/bot/screen/constants.go @@ -34,7 +34,7 @@ const ( // Mode 3 const ( MiddleClick Button = iota + 2 - _ // Just so my IDE doesn't scream at me because of the comment + _ ) // Mode 4 @@ -56,5 +56,5 @@ const ( // Mode 6 const ( DoubleClick Button = iota - _ // Just so my IDE doesn't scream at me because of the comment + _ ) diff --git a/bot/screen/screen.go b/bot/screen/screen.go index dba3b028e..287b1d516 100644 --- a/bot/screen/screen.go +++ b/bot/screen/screen.go @@ -3,68 +3,51 @@ package screen import ( "github.com/Edouard127/go-mc/data/grids" "github.com/Edouard127/go-mc/data/item" - "github.com/Edouard127/go-mc/data/slots" ) type Manager struct { - Cursor item.Item + CurrentScreen grids.Container HeldItem item.Item - CurrentScreen *Container - Screens map[int]Container Inventory *grids.GenericInventory - // The last state received from the server - StateID int32 + StateID int32 // The last state received from the server } func NewManager() *Manager { - inventory := new(grids.GenericInventory) - return &Manager{ - Screens: fillContainers(inventory), - Inventory: inventory, - } + return &Manager{Inventory: Containers[0].(*grids.GenericInventory)} } func (m *Manager) OpenScreen(id int32) { - c := m.Screens[int(id)] - m.CurrentScreen = &c + m.CurrentScreen = Containers[int(id)] } func (m *Manager) CloseScreen() { m.CurrentScreen = nil - m.Cursor = item.Item{} } -func fillContainers(inventory *grids.GenericInventory) map[int]Container { - return map[int]Container{ - 1: grids.NewGeneric9x1(inventory), - 2: grids.NewGeneric9x2(inventory), - 3: grids.NewGeneric9x3(inventory), - 4: grids.NewGeneric9x4(inventory), - 5: grids.NewGeneric9x5(inventory), - 6: grids.NewGeneric9x6(inventory), - 7: grids.NewGeneric3x3(inventory), - 8: grids.NewAnvil(inventory), - 9: grids.NewBeacon(inventory), - 10: grids.NewBlastFurnace(inventory), - 11: grids.NewBrewingStand(inventory), - 12: grids.NewCraftingTable(inventory), - 13: grids.NewEnchantmentTable(inventory), - 14: grids.NewFurnace(inventory), - 15: grids.NewGrindstone(inventory), - 16: grids.NewHopper(inventory), - 17: grids.InitGenericContainer("nil", 0, 0, inventory), // TODO: This is the only one that is not a container, I don't know why mojang did this. - 18: grids.NewLoom(inventory), - 19: grids.NewMerchant(inventory), - 20: grids.NewShulkerBox(inventory), - 21: grids.NewSmithingTable(inventory), - 22: grids.NewSmoker(inventory), - 23: grids.NewCartographyTable(inventory), - 24: grids.NewStonecutter(inventory), - } -} - -type Container interface { - GetSlot(int) *slots.Slot - SetSlot(int, slots.Slot) error - OnClose() error +var Containers = map[int]grids.Container{ + 0: new(grids.GenericInventory), + 1: grids.NewGeneric9x1(), + 2: grids.NewGeneric9x2(), + 3: grids.NewGeneric9x3(), + 4: grids.NewGeneric9x4(), + 5: grids.NewGeneric9x5(), + 6: grids.NewGeneric9x6(), + 7: grids.NewGeneric3x3(), + 8: grids.NewAnvil(), + 9: grids.NewBeacon(), + 10: grids.NewBlastFurnace(), + 11: grids.NewBrewingStand(), + 12: grids.NewCraftingTable(), + 13: grids.NewEnchantmentTable(), + 14: grids.NewFurnace(), + 15: grids.NewGrindstone(), + 16: grids.NewHopper(), + 17: grids.InitGenericContainer("nil", 0, 0), // TODO: This is the only one that is not a container, I don't know why mojang did this. + 18: grids.NewLoom(), + 19: grids.NewMerchant(), + 20: grids.NewShulkerBox(), + 21: grids.NewSmithingTable(), + 22: grids.NewSmoker(), + 23: grids.NewCartographyTable(), + 24: grids.NewStonecutter(), } diff --git a/bot/screen/screen_test.go b/bot/screen/screen_test.go new file mode 100644 index 000000000..fc3e0e230 --- /dev/null +++ b/bot/screen/screen_test.go @@ -0,0 +1,22 @@ +package screen + +import ( + "fmt" + "github.com/Edouard127/go-mc/data/slots" + "github.com/Edouard127/go-mc/nbt" + "testing" +) + +func TestNewManager(t *testing.T) { + m := NewManager() + m.Inventory.SetSlot(2, &slots.Slot{ + Index: 6969, + ID: 0, + Count: 0, + NBT: nbt.RawMessage{}, + }) + Containers[2].SetSlot(2, &slots.Slot{Index: 420}) + fmt.Println(m.Inventory.GetSlot(2)) + m.Inventory.OpenWith(Containers[2]) + fmt.Println(m.Inventory.GetSlot(2)) +} diff --git a/data/grids/anvil.go b/data/grids/anvil.go deleted file mode 100644 index 69737a3d5..000000000 --- a/data/grids/anvil.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Anvil struct { - *Generic -} - -func NewAnvil(inventory *GenericInventory) *Anvil { - return &Anvil{InitGenericContainer("minecraft:anvil", 8, 3, inventory)} -} diff --git a/data/grids/beacon.go b/data/grids/beacon.go deleted file mode 100644 index bbcc14035..000000000 --- a/data/grids/beacon.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Beacon struct { - *Generic -} - -func NewBeacon(inventory *GenericInventory) *Beacon { - return &Beacon{InitGenericContainer("minecraft:beacon", 9, 1, inventory)} -} diff --git a/data/grids/blast_furnace.go b/data/grids/blast_furnace.go deleted file mode 100644 index fd1bc9368..000000000 --- a/data/grids/blast_furnace.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type BlastFurnace struct { - *Generic -} - -func NewBlastFurnace(inventory *GenericInventory) *BlastFurnace { - return &BlastFurnace{InitGenericContainer("minecraft:blast_furnace", 10, 3, inventory)} -} diff --git a/data/grids/brewing_stand.go b/data/grids/brewing_stand.go deleted file mode 100644 index d3cb54815..000000000 --- a/data/grids/brewing_stand.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type BrewingStand struct { - *Generic -} - -func NewBrewingStand(inventory *GenericInventory) *BrewingStand { - return &BrewingStand{InitGenericContainer("minecraft:brewing_stand", 11, 5, inventory)} -} diff --git a/data/grids/cartography_table.go b/data/grids/cartography_table.go deleted file mode 100644 index d1eab8cc1..000000000 --- a/data/grids/cartography_table.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type CartographyTable struct { - *Generic -} - -func NewCartographyTable(inventory *GenericInventory) *CartographyTable { - return &CartographyTable{InitGenericContainer("minecraft:cartography", 23, 3, inventory)} -} diff --git a/data/grids/crafting_table.go b/data/grids/crafting_table.go deleted file mode 100644 index 31aef1ce1..000000000 --- a/data/grids/crafting_table.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type CraftingTable struct { - *Generic -} - -func NewCraftingTable(inventory *GenericInventory) *CraftingTable { - return &CraftingTable{InitGenericContainer("minecraft:crafting", 12, 10, inventory)} -} diff --git a/data/grids/enchantment_table.go b/data/grids/enchantment_table.go deleted file mode 100644 index 8011c7576..000000000 --- a/data/grids/enchantment_table.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type EnchantmentTable struct { - *Generic -} - -func NewEnchantmentTable(inventory *GenericInventory) *EnchantmentTable { - return &EnchantmentTable{InitGenericContainer("minecraft:enchantment", 13, 2, inventory)} -} diff --git a/data/grids/furnace.go b/data/grids/furnace.go deleted file mode 100644 index b512e013d..000000000 --- a/data/grids/furnace.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Furnace struct { - *Generic -} - -func NewFurnace(inventory *GenericInventory) *Furnace { - return &Furnace{InitGenericContainer("minecraft:furnace", 13, 4, inventory)} -} diff --git a/data/grids/generic.go b/data/grids/generic.go index a38fdcc02..460515d8e 100644 --- a/data/grids/generic.go +++ b/data/grids/generic.go @@ -4,44 +4,49 @@ import ( "github.com/Edouard127/go-mc/data/slots" ) +type Container interface { + GetSlot(int) *slots.Slot + SetSlot(int, *slots.Slot) error + OnClose() error + GetType() int + GetSize() int +} + type Generic struct { - Name string // Name of the grid. - Type int // Type is the int corresponding to the window type. - Size int - Data []slots.Slot - Inventory *GenericInventory + Name string // Name of the grid. + Type int // Type is the int corresponding to the window type. + Size int + Data []*slots.Slot } -func InitGenericContainer(name string, id, size int, inventory *GenericInventory) *Generic { +func InitGenericContainer(name string, id, size int) *Generic { return &Generic{ - Name: name, - Type: id, - Size: size, - Data: make([]slots.Slot, size), - Inventory: inventory, + Name: name, + Type: id, + Size: size, + Data: make([]*slots.Slot, size), } } func (g *Generic) OnClose() error { return nil } func (g *Generic) GetSlot(i int) *slots.Slot { - if i < 0 || i >= len(g.Inventory.Slots) { + if i < 0 || i >= len(g.Data) { return nil } - if i < g.Size { - return &g.Data[i] - } else { - return &g.Inventory.Slots[g.Size : g.Size+35][i] - } + return g.Data[i] } -func (g *Generic) SetSlot(i int, s slots.Slot) error { - if i < g.Size { - g.Data[i] = s - } else { - g.Inventory.Slots[g.Size : g.Size+35][i] = s - } - +func (g *Generic) SetSlot(i int, s *slots.Slot) error { + g.Data[i] = s return nil } + +func (g *Generic) GetType() int { + return g.Type +} + +func (g *Generic) GetSize() int { + return g.Size +} diff --git a/data/grids/generic3x3.go b/data/grids/generic3x3.go deleted file mode 100644 index aacb36392..000000000 --- a/data/grids/generic3x3.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic3x3 struct { - *Generic -} - -func NewGeneric3x3(inventory *GenericInventory) *Generic3x3 { - return &Generic3x3{InitGenericContainer("minecraft:generic_3x3", 7, 9, inventory)} -} diff --git a/data/grids/generic9x1.go b/data/grids/generic9x1.go deleted file mode 100644 index d729abf75..000000000 --- a/data/grids/generic9x1.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic9x1 struct { - *Generic -} - -func NewGeneric9x1(inventory *GenericInventory) *Generic9x1 { - return &Generic9x1{InitGenericContainer("minecraft:generic_9x1", 1, 9, inventory)} -} diff --git a/data/grids/generic9x2.go b/data/grids/generic9x2.go deleted file mode 100644 index a1de13c3d..000000000 --- a/data/grids/generic9x2.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic9x2 struct { - *Generic -} - -func NewGeneric9x2(inventory *GenericInventory) *Generic9x2 { - return &Generic9x2{InitGenericContainer("minecraft:generic_9x2", 2, 18, inventory)} -} diff --git a/data/grids/generic9x3.go b/data/grids/generic9x3.go deleted file mode 100644 index dcc17eaf8..000000000 --- a/data/grids/generic9x3.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic9x3 struct { - *Generic -} - -func NewGeneric9x3(inventory *GenericInventory) *Generic9x3 { - return &Generic9x3{InitGenericContainer("minecraft:generic_9x3", 3, 27, inventory)} -} diff --git a/data/grids/generic9x4.go b/data/grids/generic9x4.go deleted file mode 100644 index dff3f7148..000000000 --- a/data/grids/generic9x4.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic9x4 struct { - *Generic -} - -func NewGeneric9x4(inventory *GenericInventory) *Generic9x4 { - return &Generic9x4{InitGenericContainer("minecraft:generic_9x4", 4, 36, inventory)} -} diff --git a/data/grids/generic9x5.go b/data/grids/generic9x5.go deleted file mode 100644 index 4953bd7bd..000000000 --- a/data/grids/generic9x5.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic9x5 struct { - *Generic -} - -func NewGeneric9x5(inventory *GenericInventory) *Generic9x4 { - return &Generic9x4{InitGenericContainer("minecraft:generic_9x5", 5, 45, inventory)} -} diff --git a/data/grids/generic9x6.go b/data/grids/generic9x6.go deleted file mode 100644 index 74560cb5f..000000000 --- a/data/grids/generic9x6.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Generic9x6 struct { - *Generic -} - -func NewGeneric9x6(inventory *GenericInventory) *Generic9x6 { - return &Generic9x6{InitGenericContainer("minecraft:generic_9x6", 6, 54, inventory)} -} diff --git a/data/grids/generics.go b/data/grids/generics.go new file mode 100644 index 000000000..1a7953ef6 --- /dev/null +++ b/data/grids/generics.go @@ -0,0 +1,185 @@ +package grids + +type Generic3x3 struct { + *Generic +} + +func NewGeneric3x3() *Generic3x3 { + return &Generic3x3{InitGenericContainer("minecraft:generic_3x3", 7, 9)} +} + +type Generic9x1 struct { + *Generic +} + +func NewGeneric9x1() *Generic9x1 { + return &Generic9x1{InitGenericContainer("minecraft:generic_9x1", 1, 9)} +} + +type Generic9x2 struct { + *Generic +} + +func NewGeneric9x2() *Generic9x2 { + return &Generic9x2{InitGenericContainer("minecraft:generic_9x2", 2, 18)} +} + +type Generic9x3 struct { + *Generic +} + +func NewGeneric9x3() *Generic9x3 { + return &Generic9x3{InitGenericContainer("minecraft:generic_9x3", 3, 27)} +} + +type Generic9x4 struct { + *Generic +} + +func NewGeneric9x4() *Generic9x4 { + return &Generic9x4{InitGenericContainer("minecraft:generic_9x4", 4, 36)} +} + +type Generic9x5 struct { + *Generic +} + +func NewGeneric9x5() *Generic9x4 { + return &Generic9x4{InitGenericContainer("minecraft:generic_9x5", 5, 45)} +} + +type Generic9x6 struct { + *Generic +} + +func NewGeneric9x6() *Generic9x6 { + return &Generic9x6{InitGenericContainer("minecraft:generic_9x6", 6, 54)} +} + +type Anvil struct { + *Generic +} + +func NewAnvil() *Anvil { + return &Anvil{InitGenericContainer("minecraft:anvil", 8, 3)} +} + +type Beacon struct { + *Generic +} + +func NewBeacon() *Beacon { + return &Beacon{InitGenericContainer("minecraft:beacon", 9, 1)} +} + +type BlastFurnace struct { + *Generic +} + +func NewBlastFurnace() *BlastFurnace { + return &BlastFurnace{InitGenericContainer("minecraft:blast_furnace", 10, 3)} +} + +type BrewingStand struct { + *Generic +} + +func NewBrewingStand() *BrewingStand { + return &BrewingStand{InitGenericContainer("minecraft:brewing_stand", 11, 5)} +} + +type CartographyTable struct { + *Generic +} + +func NewCartographyTable() *CartographyTable { + return &CartographyTable{InitGenericContainer("minecraft:cartography", 23, 3)} +} + +type CraftingTable struct { + *Generic +} + +func NewCraftingTable() *CraftingTable { + return &CraftingTable{InitGenericContainer("minecraft:crafting", 12, 10)} +} + +type EnchantmentTable struct { + *Generic +} + +func NewEnchantmentTable() *EnchantmentTable { + return &EnchantmentTable{InitGenericContainer("minecraft:enchantment", 13, 2)} +} + +type Furnace struct { + *Generic +} + +func NewFurnace() *Furnace { + return &Furnace{InitGenericContainer("minecraft:furnace", 13, 4)} +} + +type Grindstone struct { + *Generic +} + +func NewGrindstone() *Grindstone { + return &Grindstone{InitGenericContainer("minecraft:grindstone", 15, 3)} +} + +type Hopper struct { // Also minecart with hopper + *Generic +} + +func NewHopper() *Hopper { + return &Hopper{InitGenericContainer("minecraft:hopper", 16, 5)} +} + +type Loom struct { + *Generic +} + +func NewLoom() *Loom { + return &Loom{InitGenericContainer("minecraft:loom", 18, 4)} +} + +type Merchant struct { + *Generic +} + +func NewMerchant() *Merchant { + return &Merchant{InitGenericContainer("minecraft:merchant", 19, 3)} +} + +type ShulkerBox struct { + *Generic +} + +func NewShulkerBox() *ShulkerBox { + return &ShulkerBox{InitGenericContainer("minecraft:shulker_box", 20, 27)} +} + +type SmithingTable struct { + *Generic +} + +func NewSmithingTable() *SmithingTable { + return &SmithingTable{InitGenericContainer("minecraft:smithing", 21, 4)} +} + +type Smoker struct { + *Generic +} + +func NewSmoker() *Smoker { + return &Smoker{InitGenericContainer("minecraft:smoker", 22, 3)} +} + +type Stonecutter struct { + *Generic +} + +func NewStonecutter() *Stonecutter { + return &Stonecutter{InitGenericContainer("minecraft:stonecutter", 23, 2)} +} diff --git a/data/grids/grindstone.go b/data/grids/grindstone.go deleted file mode 100644 index 17e6273f5..000000000 --- a/data/grids/grindstone.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Grindstone struct { - *Generic -} - -func NewGrindstone(inventory *GenericInventory) *Grindstone { - return &Grindstone{InitGenericContainer("minecraft:grindstone", 15, 3, inventory)} -} diff --git a/data/grids/hopper.go b/data/grids/hopper.go deleted file mode 100644 index 8e6fb261c..000000000 --- a/data/grids/hopper.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Hopper struct { // Also minecart with hopper - *Generic -} - -func NewHopper(inventory *GenericInventory) *Hopper { - return &Hopper{InitGenericContainer("minecraft:hopper", 16, 5, inventory)} -} diff --git a/data/grids/inventory.go b/data/grids/inventory.go index f7809fac8..224d8e3e3 100644 --- a/data/grids/inventory.go +++ b/data/grids/inventory.go @@ -7,22 +7,36 @@ import ( ) type GenericInventory struct { - Slots [46]slots.Slot + Offset Container + Slots [46]*slots.Slot } -func (g *GenericInventory) OnClose() error { return nil } +func (g *GenericInventory) OpenWith(c Container) { g.Offset = c } +func (g *GenericInventory) OnClose() error { + var err error + if g.Offset != nil { + err = g.Offset.OnClose() + g.Offset = nil + } + return err +} -func (g *GenericInventory) GetSlot(i int) *slots.Slot { return &g.Slots[i] } -func (g *GenericInventory) GetItem(i int) item.Item { return g.Slots[i].Item() } -func (g *GenericInventory) SetSlot(i int, s slots.Slot) error { - if i < 0 || i >= len(g.Slots) { +func (g *GenericInventory) GetSlot(i int) *slots.Slot { return g.slotOffset(i) } +func (g *GenericInventory) SetSlot(i int, s *slots.Slot) error { + if i < 0 || g.Offset != nil && i >= g.Offset.GetSize()+g.GetSize() || i >= g.GetSize() { return fmt.Errorf("slot index %d out of bounds. maximum index is %d", i, len(g.Slots)-1) } + if g.Offset != nil && i < g.Offset.GetSize() { + return g.Offset.SetSlot(i, s) + } g.Slots[i] = s return nil } +func (g *GenericInventory) GetItem(i int) item.Item { return g.slotOffset(i).Item() } +func (g *GenericInventory) GetType() int { return 0 } +func (g *GenericInventory) GetSize() int { return len(g.Slots) } -func (g *GenericInventory) GetCraftingOutput() item.Item { return g.Slots[0].Item() } +func (g *GenericInventory) GetCraftingOutput() item.Item { return g.slotOffset(0).Item() } func (g *GenericInventory) GetCraftingInput() []item.Item { return g.itemsOf(1, 4) } func (g *GenericInventory) GetArmor() []item.Item { return g.itemsOf(4, 8) } func (g *GenericInventory) GetInventory() []item.Item { return g.itemsOf(9, 35) } @@ -30,8 +44,8 @@ func (g *GenericInventory) GetHotbar() []item.Item { return g.itemsOf(36, func (g *GenericInventory) GetOffhand() item.Item { return g.Slots[45].Item() } func (g *GenericInventory) itemsOf(start, end int) (items []item.Item) { - for _, slot := range g.Slots[start:end] { - items = append(items, slot.Item()) + for i := start; i < end; i++ { + items = append(items, g.slotOffset(i).Item()) } return } @@ -52,13 +66,21 @@ func (g *GenericInventory) predicate(nth, start, end int, predicate func(item.It if predicate == nil { return } - for i := range g.Slots[start:end] { - if predicate(g.Slots[i].Item()) { + for i := start; i < end; i++ { + if predicate(g.slotOffset(i).Item()) { nth-- if nth == 0 { - return g.Slots[i].Item() + return g.slotOffset(i).Item() } } } return } + +func (g *GenericInventory) slotOffset(index int) *slots.Slot { + if g.Offset != nil && g.Offset.GetSize() < index+1 { + return g.Offset.GetSlot(index) + } + + return g.Slots[index] +} diff --git a/data/grids/loom.go b/data/grids/loom.go deleted file mode 100644 index b19bbe9df..000000000 --- a/data/grids/loom.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Loom struct { - *Generic -} - -func NewLoom(inventory *GenericInventory) *Loom { - return &Loom{InitGenericContainer("minecraft:loom", 18, 4, inventory)} -} diff --git a/data/grids/merchant.go b/data/grids/merchant.go deleted file mode 100644 index 9f9c6d38d..000000000 --- a/data/grids/merchant.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Merchant struct { - *Generic -} - -func NewMerchant(inventory *GenericInventory) *Merchant { - return &Merchant{InitGenericContainer("minecraft:merchant", 19, 3, inventory)} -} diff --git a/data/grids/shulker_box.go b/data/grids/shulker_box.go deleted file mode 100644 index 832801e6d..000000000 --- a/data/grids/shulker_box.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type ShulkerBox struct { - *Generic -} - -func NewShulkerBox(inventory *GenericInventory) *ShulkerBox { - return &ShulkerBox{InitGenericContainer("minecraft:shulker_box", 20, 27, inventory)} -} diff --git a/data/grids/smithing_table.go b/data/grids/smithing_table.go deleted file mode 100644 index 69747ec7d..000000000 --- a/data/grids/smithing_table.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type SmithingTable struct { - *Generic -} - -func NewSmithingTable(inventory *GenericInventory) *SmithingTable { - return &SmithingTable{InitGenericContainer("minecraft:smithing", 21, 4, inventory)} -} diff --git a/data/grids/smoker.go b/data/grids/smoker.go deleted file mode 100644 index c62d42b3c..000000000 --- a/data/grids/smoker.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Smoker struct { - *Generic -} - -func NewSmoker(inventory *GenericInventory) *Smoker { - return &Smoker{InitGenericContainer("minecraft:smoker", 22, 3, inventory)} -} diff --git a/data/grids/stonecutter.go b/data/grids/stonecutter.go deleted file mode 100644 index 45d59a705..000000000 --- a/data/grids/stonecutter.go +++ /dev/null @@ -1,9 +0,0 @@ -package grids - -type Stonecutter struct { - *Generic -} - -func NewStonecutter(inventory *GenericInventory) *Stonecutter { - return &Stonecutter{InitGenericContainer("minecraft:stonecutter", 23, 2, inventory)} -} diff --git a/internal/util/queue.go b/internal/util/queue.go new file mode 100644 index 000000000..f0cba17d1 --- /dev/null +++ b/internal/util/queue.go @@ -0,0 +1,25 @@ +package util + +type Queue[T any] []T + +func NewQueue[T any]() *Queue[T] { + return &Queue[T]{} +} + +func (q *Queue[T]) Push(v T) { + *q = append(*q, v) +} + +func (q *Queue[T]) Pop() (v T) { + h := *q + l := len(h) + if l == 0 { + return + } + v, *q = h[0], h[1:l] + return +} + +func (q *Queue[T]) Len() int { + return len(*q) +} diff --git a/maths/enumfacing.go b/maths/enumfacing.go index af5cbc8e2..3d291e424 100644 --- a/maths/enumfacing.go +++ b/maths/enumfacing.go @@ -35,7 +35,7 @@ func GetClosestFacing(eyePos, blockPos Vec3d) EnumFacing { var closest EnumFacing var minDiff float64 for _, side := range GetVisibleSides(eyePos, blockPos) { - diff := eyePos.DistanceTo(blockPos.Add(side.Vector().AddScalar(0.5))) + diff := eyePos.DistanceTo(blockPos.Add(side.Vector().AddScalar(0.5, 0.5, 0.5))) if minDiff == 0 || diff < minDiff { minDiff = diff closest = side @@ -46,7 +46,7 @@ func GetClosestFacing(eyePos, blockPos Vec3d) EnumFacing { func GetVisibleSides(eyePos, blockPos Vec3d) []EnumFacing { var sides []EnumFacing - blockCenter := blockPos.AddScalar(0.5) + blockCenter := blockPos.AddScalar(0.5, 0.5, 0.5) axis := checkAxis(eyePos.X-blockCenter.X, WEST) if axis != -1 { sides = append(sides, axis) diff --git a/maths/raytrace.go b/maths/raytrace.go index 63359d1d8..fe6657d59 100644 --- a/maths/raytrace.go +++ b/maths/raytrace.go @@ -12,7 +12,8 @@ func RayTraceBlocks(start, end Vec3d) []Vec3d { return result } for i := 0; i < int(distance); i++ { - result = append(result, start.Add(diff.MulScalar(float64(i)/distance))) + idk := float64(i) / distance + result = append(result, start.Add(diff.MulScalar(idk, idk, idk))) } return result } diff --git a/maths/vec3.go b/maths/vec3.go index 121769f79..ac1a533d5 100644 --- a/maths/vec3.go +++ b/maths/vec3.go @@ -11,7 +11,7 @@ type Vec3i = Vec3[int] type Vec3f = Vec3[float32] type Vec3d = Vec3[float64] -type Vec3[T constraints.Integer | constraints.Float] struct { +type Vec3[T constraints.Signed | constraints.Float] struct { X, Y, Z T } diff --git a/net/transactions/actions.go b/net/transactions/actions.go index b95a32a31..725329413 100644 --- a/net/transactions/actions.go +++ b/net/transactions/actions.go @@ -5,60 +5,39 @@ import ( "github.com/Edouard127/go-mc/data/slots" ) -func LeftClick(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.LeftClick, 0, &slots.Slot{Index: item.Index})). - Build() +func LeftClick(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.LeftClick, item.GetIndex(), 0, &slots.Slot{Index: item.Index})} } -func DoubleClick(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.DoubleClick, 6, &slots.Slot{Index: item.Index})). - Build() +func RightClick(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.RightClick, item.GetIndex(), 0, &slots.Slot{Index: item.Index})} } -func RightClick(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.RightClick, 0, &slots.Slot{Index: item.Index})). - Build() +func DoubleClick(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.DoubleClick, item.GetIndex(), 6, &slots.Slot{Index: item.Index})} } -func Drop(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.Drop, 4, &slots.Slot{Index: item.Index})). - Build() +func Drop(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.Drop, item.GetIndex(), 4, &slots.Slot{Index: item.Index})} } -func DropAll(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.ControlDrop, 4, &slots.Slot{Index: item.Index})). - Build() +func DropAll(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.ControlDrop, item.GetIndex(), 4, &slots.Slot{Index: item.Index})} } -func Swap(item1 *slots.Slot, item2 *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item1.GetIndex(), screen.LeftClick, 0, item1, &slots.Slot{Index: item2.Index})). - AddAction(NewSlotAction(item2.GetIndex(), screen.LeftClick, 0, item1, item2)). // move item1 to item2 - AddAction(NewSlotAction(item1.GetIndex(), screen.LeftClick, 0, item2, &slots.Slot{Index: item2.Index})). // move item2 to item1 - AddAction(NewSlotAction(-999, screen.LeftClick, 4, &slots.Slot{}, &slots.Slot{})). // exit - Build() +func Swap(item1 *slots.Slot, item2 *slots.Slot) []*SlotAction { + return []*SlotAction{ + NewSlotAction(screen.LeftClick, item1.GetIndex(), 0, item1, &slots.Slot{Index: item2.Index}), + NewSlotAction(screen.LeftClick, item2.GetIndex(), 0, item1, item2), + NewSlotAction(screen.LeftClick, item1.GetIndex(), 0, item2, &slots.Slot{Index: item2.Index}), + NewSlotAction(screen.LeftClick, -999, 4, &slots.Slot{}, &slots.Slot{}), + } } -func SwapWithHotbar(item *slots.Slot, hotbarIndex int) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.LeftClick, 0, item, &slots.Slot{Index: hotbarIndex})). - AddAction(NewSlotAction(hotbarIndex, screen.LeftClick, 0, item, &slots.Slot{Index: item.Index})). - Build() +func SwapWithOffhand(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.SwapHand, item.GetIndex(), 2, item, &slots.Slot{Index: 40})} } -func SwapWithOffhand(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.SwapHand, 2, item, &slots.Slot{Index: 40})). - Build() -} - -func QuickMove(item *slots.Slot) *Transaction { - return NewTransactionBuilder(). - AddAction(NewSlotAction(item.GetIndex(), screen.ShiftLeftClick, 1, &slots.Slot{Index: item.Index})). - Build() +func QuickMove(item *slots.Slot) []*SlotAction { + return []*SlotAction{NewSlotAction(screen.ShiftLeftClick, item.GetIndex(), 1, &slots.Slot{Index: item.Index})} } diff --git a/net/transactions/builder.go b/net/transactions/builder.go deleted file mode 100644 index f1e5749b2..000000000 --- a/net/transactions/builder.go +++ /dev/null @@ -1,34 +0,0 @@ -package transactions - -import ( - "github.com/Edouard127/go-mc/data/packetid" - pk "github.com/Edouard127/go-mc/net/packet" -) - -type TransactionBuilder struct { - WindowID pk.UnsignedByte - StateID pk.VarInt - Actions []*SlotAction -} - -type Transaction struct { - Packets []*pk.Packet -} - -func NewTransactionBuilder() *TransactionBuilder { - return &TransactionBuilder{} -} - -func (t *TransactionBuilder) AddAction(action ...*SlotAction) *TransactionBuilder { - t.Actions = append(t.Actions, action...) - return t -} - -func (t *TransactionBuilder) Build() *Transaction { - packets := make([]*pk.Packet, 0, len(t.Actions)) - for _, action := range t.Actions { - p := pk.Marshal(packetid.SPacketClickWindow, t.WindowID, t.StateID, action) - packets = append(packets, &p) - } - return &Transaction{Packets: packets} -} diff --git a/net/transactions/slot_action.go b/net/transactions/slot_action.go index d682ac0e7..ecce18518 100644 --- a/net/transactions/slot_action.go +++ b/net/transactions/slot_action.go @@ -1,6 +1,7 @@ package transactions import ( + "fmt" "github.com/Edouard127/go-mc/bot/screen" "github.com/Edouard127/go-mc/data/slots" pk "github.com/Edouard127/go-mc/net/packet" @@ -11,29 +12,45 @@ type SlotAction struct { Slot pk.Short Button pk.Byte Mode pk.VarInt + Changed ChangedSlots Item *slots.Slot - Changed []*slots.Slot } -func NewSlotAction(slot int, button screen.Button, mode screen.Mode, cursor *slots.Slot, items ...*slots.Slot) *SlotAction { +func NewSlotAction(button screen.Button, slot int, mode screen.Mode, cursor *slots.Slot, items ...*slots.Slot) *SlotAction { return &SlotAction{ Slot: pk.Short(slot), Button: pk.Byte(button), Mode: pk.VarInt(mode), - Item: cursor, Changed: items, + Item: cursor, } } func (s *SlotAction) WriteTo(w io.Writer) (n int64, err error) { - n, err = pk.Tuple{ - &s.Slot, &s.Button, &s.Mode, - }.WriteTo(w) - n0, err := pk.VarInt(len(s.Changed)).WriteTo(w) + return pk.Tuple{&s.Slot, &s.Button, &s.Mode, &s.Changed, s.Item}.WriteTo(w) +} + +func (s *SlotAction) Validate() error { + if s.Slot < 0 && s.Slot != -999 { + return fmt.Errorf("slot %d is less than 0", s.Slot) + } + if s.Button < 0 || s.Button > 40 { + return fmt.Errorf("button %d is less than 0", s.Button) + } + if s.Mode < 0 || s.Mode > 6 { + return fmt.Errorf("mode %d is not in range [0, 6]", s.Mode) + } + return nil +} + +type ChangedSlots []*slots.Slot + +func (c ChangedSlots) WriteTo(w io.Writer) (n int64, err error) { + n0, err := pk.VarInt(len(c)).WriteTo(w) if err != nil { return n + n0, err } - for _, v := range s.Changed { + for _, v := range c { n1, err := pk.Short(v.Index).WriteTo(w) if err != nil { return n + n1, err @@ -44,20 +61,5 @@ func (s *SlotAction) WriteTo(w io.Writer) (n int64, err error) { } n += n1 + n2 } - n3, err := s.Item.WriteTo(w) - n += n0 + n3 return } - -/*func (s *SlotAction) Validate() basic.Error { - if s.Slot < 0 { - return basic.NewError(basic.InvalidSlot, fmt.Sprintf("slot %d is less than 0", s.Slot)) - } - if s.Button < 0 { - return basic.NewError(basic.InvalidButton, fmt.Sprintf("button %d is less than 0", s.Button)) - } - if s.Mode < 0 || s.Mode > 2 { - return basic.NewError(basic.InvalidMode, fmt.Sprintf("mode %d is not in range [0, 2]", s.Mode)) - } - return basic.NoError -}*/ diff --git a/net/transactions/transactions.go b/net/transactions/transactions.go deleted file mode 100644 index 6455d5091..000000000 --- a/net/transactions/transactions.go +++ /dev/null @@ -1,33 +0,0 @@ -package transactions - -type Transactions struct { - list []*Transaction -} - -func NewTransactions() *Transactions { - return &Transactions{ - list: make([]*Transaction, 0), - } -} - -func (t *Transactions) Next() *Transaction { - if len(t.list) == 0 { - return nil - } - tr := t.list[0] - t.list = t.list[1:] - return tr -} - -func (t *Transactions) Post(tr ...*Transaction) { - t.list = append(t.list, tr...) -} - -func (t *Transactions) Delete(tr *Transaction) { - for i, v := range t.list { - if v == tr { - t.list = append(t.list[:i], t.list[i+1:]...) - return - } - } -}