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] 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目录下
|
||||||
|
|
||||||
|
@ -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]
|
||||||
|
}
|
||||||
|
107
bot/ingame.go
107
bot/ingame.go
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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]
|
||||||
|
}
|
||||||
|
@ -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 //饱食度
|
||||||
|
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