support Inventory and Delegate

This commit is contained in:
JunDao
2019-05-19 17:44:49 +08:00
parent 2c41d9b901
commit 438285676d
6 changed files with 1163 additions and 857 deletions

View File

@ -13,6 +13,8 @@ There's some library in Go support you to create your Minecraft client or server
- [x] Simple MC robot lib - [x] Simple MC robot lib
- [x] Parse NBT - [x] Parse NBT
> 由于仍在开发中部分API在未来版本中可能会变动
Some examples are at `/cmd` folder. Some examples are at `/cmd` folder.
有一些例子在cmd目录下 有一些例子在cmd目录下

View File

@ -1,6 +1,7 @@
package bot package bot
import ( import (
"github.com/Tnze/go-mc/bot/world/entity"
"github.com/Tnze/go-mc/bot/world/entity/player" "github.com/Tnze/go-mc/bot/world/entity/player"
"github.com/Tnze/go-mc/net" "github.com/Tnze/go-mc/net"
) )
@ -16,7 +17,12 @@ type Client struct {
settings Settings settings Settings
// wd world //the map data // wd world //the map data
// Delegate allows you push a function to let HandleGame run.
// Do not send at the same goroutin!
Delegate chan func() error
Events eventBroker Events eventBroker
Inventory [46]entity.Slot
} }
// NewClient init and return a new Client. // NewClient init and return a new Client.
@ -32,6 +38,7 @@ func NewClient() (c *Client) {
//init Client //init Client
c.settings = DefaultSettings c.settings = DefaultSettings
c.Name = "Steve" c.Name = "Steve"
c.Delegate = make(chan func() error)
return return
} }
@ -59,3 +66,13 @@ type PlayerAbilities struct {
type Position struct { type Position struct {
X, Y, Z int X, Y, Z int
} }
//HotBar return the hotbar of inventory
func (c *Client) HotBar() []entity.Slot {
return c.Inventory[36:45]
}
// MainInventory return the main inventory slots
func (c *Client) MainInventory() []entity.Slot {
return c.Inventory[9:36]
}

View File

@ -1,13 +1,16 @@
package bot package bot
import ( import (
// "bytes" "bytes"
"errors"
// "math" // "math"
// "time" // "time"
"fmt" "fmt"
"github.com/Tnze/go-mc/bot/world/entity"
"github.com/Tnze/go-mc/chat" "github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/data" "github.com/Tnze/go-mc/data"
"github.com/Tnze/go-mc/nbt"
pk "github.com/Tnze/go-mc/net/packet" pk "github.com/Tnze/go-mc/net/packet"
) )
@ -25,6 +28,12 @@ import (
// Note that HandleGame will block if you don't recive from Events. // Note that HandleGame will block if you don't recive from Events.
func (c *Client) HandleGame() error { func (c *Client) HandleGame() error {
for { for {
select {
case task := <-c.Delegate:
if err := task(); err != nil {
return err
}
default:
//Read packets //Read packets
p, err := c.conn.ReadPacket() p, err := c.conn.ReadPacket()
if err != nil { if err != nil {
@ -40,6 +49,7 @@ func (c *Client) HandleGame() error {
} }
} }
} }
}
func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) { func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
switch p.ID { switch p.ID {
@ -103,8 +113,8 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
case 0x1A: case 0x1A:
err = handleDisconnectPacket(c, p) err = handleDisconnectPacket(c, p)
disconnect = true disconnect = true
case 0x16: case data.SetSlot:
// err = handleSetSlotPacket(g, reader) err = handleSetSlotPacket(c, p)
case data.SoundEffect: case data.SoundEffect:
err = handleSoundEffect(c, p) err = handleSoundEffect(c, p)
case data.NamedSoundEffect: case data.NamedSoundEffect:
@ -170,33 +180,30 @@ func handleDisconnectPacket(c *Client, p pk.Packet) error {
return c.Events.Disconnect(reason) return c.Events.Disconnect(reason)
} }
// func handleSetSlotPacket(g *Client, r *bytes.Reader) error { func handleSetSlotPacket(c *Client, p pk.Packet) error {
// windowID, err := r.ReadByte() var (
// if err != nil { windowID pk.Byte
// return err slotI pk.Short
// } slot entity.Slot
// slot, err := pk.UnpackInt16(r) )
// if err != nil { if err := p.Scan(&windowID, &slotI, &slot); err != nil && err != nbt.ErrEND {
// return err return err
// } }
// slotData, err := unpackSolt(r)
// if err != nil {
// return err
// }
// switch int8(windowID) { switch int8(windowID) {
// case 0: case 0: //if window ID is 0, it will only change the hotbar
// if slot < 32 || slot > 44 { if slotI < 32 || slotI > 44 {
// // return fmt.Errorf("slot out of range") return errors.New("server set slot error")
// break }
// } fallthrough
// fallthrough case -2: //or if it's -2, server can change any slot without animation
// case -2: if slotI < 0 || slotI > 45 {
// g.player.Inventory[slot] = slotData return errors.New("server set slot out of range")
// g.events <- InventoryChangeEvent(slot) }
// } c.Inventory[slotI] = slot
// return nil }
// } return nil
}
// func handleMultiBlockChangePacket(c *Client, p pk.Packet) error { // func handleMultiBlockChangePacket(c *Client, p pk.Packet) error {
// if !c.settings.ReciveMap { // if !c.settings.ReciveMap {
@ -621,20 +628,36 @@ func handleKeepAlivePacket(c *Client, p pk.Packet) error {
// return nil // return nil
// } // }
func handleWindowItemsPacket(g *Client, p pk.Packet) (err error) { func handleWindowItemsPacket(c *Client, p pk.Packet) (err error) {
// var ( r := bytes.NewReader(p.Data)
// WindowID pk.Byte var (
// solts entity.Solt windowID pk.Byte
// ) count pk.Short
// err = p.Scan(&WindowID, &solts) slots []entity.Slot
// if err != nil { )
// return if err := windowID.Decode(r); err != nil {
// } return err
}
if err := count.Decode(r); err != nil {
return err
}
for i := 0; i < int(count); i++ {
var slot entity.Slot
if err := slot.Decode(r); err != nil && err != nbt.ErrEND {
return err
}
slots = append(slots, slot)
}
// switch WindowID { switch windowID {
// case 0: //is player inventory case 0: //is player's inventory
// g.Inventory = solts if len(slots) != len(c.Inventory) {
// } return errors.New("inventory len not match")
}
for i, v := range slots { //copy this Inventory to player's Inventory
c.Inventory[i] = v
}
}
return nil return nil
} }

View File

@ -1,6 +1,7 @@
package entity package entity
import ( import (
"github.com/Tnze/go-mc/data"
"github.com/Tnze/go-mc/nbt" "github.com/Tnze/go-mc/nbt"
pk "github.com/Tnze/go-mc/net/packet" pk "github.com/Tnze/go-mc/net/packet"
) )
@ -37,3 +38,7 @@ func (s *Slot) Decode(r pk.DecodeReader) error {
} }
return nil return nil
} }
func (s Slot) String() string {
return data.ItemNameByID[s.ItemID]
}

View File

@ -12,7 +12,6 @@ type Player struct {
OnGround bool OnGround bool
HeldItem int //拿着的物品栏位 HeldItem int //拿着的物品栏位
Inventory []entity.Slot
Health float32 //血量 Health float32 //血量
Food int32 //饱食度 Food int32 //饱食度

File diff suppressed because it is too large Load Diff