support Inventory and Delegate
This commit is contained in:
@ -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] Parse NBT
|
||||
|
||||
> 由于仍在开发中,部分API在未来版本中可能会变动
|
||||
|
||||
Some examples are at `/cmd` folder.
|
||||
有一些例子在cmd目录下
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
"github.com/Tnze/go-mc/bot/world/entity"
|
||||
"github.com/Tnze/go-mc/bot/world/entity/player"
|
||||
"github.com/Tnze/go-mc/net"
|
||||
)
|
||||
@ -16,7 +17,12 @@ type Client struct {
|
||||
settings Settings
|
||||
// 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
|
||||
|
||||
Inventory [46]entity.Slot
|
||||
}
|
||||
|
||||
// NewClient init and return a new Client.
|
||||
@ -32,6 +38,7 @@ func NewClient() (c *Client) {
|
||||
//init Client
|
||||
c.settings = DefaultSettings
|
||||
c.Name = "Steve"
|
||||
c.Delegate = make(chan func() error)
|
||||
|
||||
return
|
||||
}
|
||||
@ -59,3 +66,13 @@ type PlayerAbilities struct {
|
||||
type Position struct {
|
||||
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]
|
||||
}
|
||||
|
107
bot/ingame.go
107
bot/ingame.go
@ -1,13 +1,16 @@
|
||||
package bot
|
||||
|
||||
import (
|
||||
// "bytes"
|
||||
"bytes"
|
||||
"errors"
|
||||
// "math"
|
||||
// "time"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
@ -25,6 +28,12 @@ import (
|
||||
// Note that HandleGame will block if you don't recive from Events.
|
||||
func (c *Client) HandleGame() error {
|
||||
for {
|
||||
select {
|
||||
case task := <-c.Delegate:
|
||||
if err := task(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
//Read packets
|
||||
p, err := c.conn.ReadPacket()
|
||||
if err != nil {
|
||||
@ -39,6 +48,7 @@ func (c *Client) HandleGame() error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
|
||||
@ -103,8 +113,8 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
|
||||
case 0x1A:
|
||||
err = handleDisconnectPacket(c, p)
|
||||
disconnect = true
|
||||
case 0x16:
|
||||
// err = handleSetSlotPacket(g, reader)
|
||||
case data.SetSlot:
|
||||
err = handleSetSlotPacket(c, p)
|
||||
case data.SoundEffect:
|
||||
err = handleSoundEffect(c, p)
|
||||
case data.NamedSoundEffect:
|
||||
@ -170,33 +180,30 @@ func handleDisconnectPacket(c *Client, p pk.Packet) error {
|
||||
return c.Events.Disconnect(reason)
|
||||
}
|
||||
|
||||
// func handleSetSlotPacket(g *Client, r *bytes.Reader) error {
|
||||
// windowID, err := r.ReadByte()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// slot, err := pk.UnpackInt16(r)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// slotData, err := unpackSolt(r)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
func handleSetSlotPacket(c *Client, p pk.Packet) error {
|
||||
var (
|
||||
windowID pk.Byte
|
||||
slotI pk.Short
|
||||
slot entity.Slot
|
||||
)
|
||||
if err := p.Scan(&windowID, &slotI, &slot); err != nil && err != nbt.ErrEND {
|
||||
return err
|
||||
}
|
||||
|
||||
// switch int8(windowID) {
|
||||
// case 0:
|
||||
// if slot < 32 || slot > 44 {
|
||||
// // return fmt.Errorf("slot out of range")
|
||||
// break
|
||||
// }
|
||||
// fallthrough
|
||||
// case -2:
|
||||
// g.player.Inventory[slot] = slotData
|
||||
// g.events <- InventoryChangeEvent(slot)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
switch int8(windowID) {
|
||||
case 0: //if window ID is 0, it will only change the hotbar
|
||||
if slotI < 32 || slotI > 44 {
|
||||
return errors.New("server set slot error")
|
||||
}
|
||||
fallthrough
|
||||
case -2: //or if it's -2, server can change any slot without animation
|
||||
if slotI < 0 || slotI > 45 {
|
||||
return errors.New("server set slot out of range")
|
||||
}
|
||||
c.Inventory[slotI] = slot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// func handleMultiBlockChangePacket(c *Client, p pk.Packet) error {
|
||||
// if !c.settings.ReciveMap {
|
||||
@ -621,20 +628,36 @@ func handleKeepAlivePacket(c *Client, p pk.Packet) error {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func handleWindowItemsPacket(g *Client, p pk.Packet) (err error) {
|
||||
// var (
|
||||
// WindowID pk.Byte
|
||||
// solts entity.Solt
|
||||
// )
|
||||
// err = p.Scan(&WindowID, &solts)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
func handleWindowItemsPacket(c *Client, p pk.Packet) (err error) {
|
||||
r := bytes.NewReader(p.Data)
|
||||
var (
|
||||
windowID pk.Byte
|
||||
count pk.Short
|
||||
slots []entity.Slot
|
||||
)
|
||||
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 {
|
||||
// case 0: //is player inventory
|
||||
// g.Inventory = solts
|
||||
// }
|
||||
switch windowID {
|
||||
case 0: //is player's inventory
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/Tnze/go-mc/data"
|
||||
"github.com/Tnze/go-mc/nbt"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
)
|
||||
@ -37,3 +38,7 @@ func (s *Slot) Decode(r pk.DecodeReader) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Slot) String() string {
|
||||
return data.ItemNameByID[s.ItemID]
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ type Player struct {
|
||||
OnGround bool
|
||||
|
||||
HeldItem int //拿着的物品栏位
|
||||
Inventory []entity.Slot
|
||||
|
||||
Health float32 //血量
|
||||
Food int32 //饱食度
|
||||
|
1638
data/items.go
1638
data/items.go
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user