Add generic event
This commit is contained in:
@ -12,6 +12,7 @@ type Player struct {
|
||||
|
||||
PlayerInfo
|
||||
WorldInfo
|
||||
isSpawn bool
|
||||
}
|
||||
|
||||
func NewPlayer(c *bot.Client, settings Settings) *Player {
|
||||
@ -19,14 +20,33 @@ func NewPlayer(c *bot.Client, settings Settings) *Player {
|
||||
c.Events.AddListener(
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.Login, F: b.handleJoinGamePacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.KeepAliveClientbound, F: b.handleKeepAlivePacket},
|
||||
bot.PacketHandler{Priority: 0, ID: packetid.PositionClientbound, F: b.handlePlayerPositionAndLook},
|
||||
)
|
||||
return b
|
||||
}
|
||||
|
||||
func (p *Player) Respawn() error {
|
||||
const PerformRespawn = 0
|
||||
return p.c.Conn.WritePacket(pk.Marshal(
|
||||
|
||||
err := p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.ClientCommand,
|
||||
pk.VarInt(PerformRespawn),
|
||||
))
|
||||
if err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return "bot/basic: " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e Error) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func (e *EventsListener) onDisconnect(p pk.Packet) error {
|
||||
if e.Disconnect != nil {
|
||||
var reason chat.Message
|
||||
if err := p.Scan(&reason); err != nil {
|
||||
return err
|
||||
return Error{err}
|
||||
}
|
||||
return e.Disconnect(reason)
|
||||
}
|
||||
@ -51,7 +51,7 @@ func (e *EventsListener) onChatMsg(p pk.Packet) error {
|
||||
var sender pk.UUID
|
||||
|
||||
if err := p.Scan(&msg, &pos, &sender); err != nil {
|
||||
return err
|
||||
return Error{err}
|
||||
}
|
||||
|
||||
return e.ChatMsg(msg, byte(pos), uuid.UUID(sender))
|
||||
@ -66,7 +66,7 @@ func (e *EventsListener) onUpdateHealth(p pk.Packet) error {
|
||||
var foodSaturation pk.Float
|
||||
|
||||
if err := p.Scan(&health, &food, &foodSaturation); err != nil {
|
||||
return err
|
||||
return Error{err}
|
||||
}
|
||||
if e.HealthChange != nil {
|
||||
if err := e.HealthChange(float32(health)); err != nil {
|
||||
|
@ -1,9 +1,10 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// WorldInfo content player info in server.
|
||||
@ -38,7 +39,7 @@ type ServInfo struct {
|
||||
|
||||
func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
|
||||
var WorldCount pk.VarInt
|
||||
var WorldNames = []pk.Identifier{}
|
||||
var WorldNames = make([]pk.Identifier, 0)
|
||||
err := packet.Scan(
|
||||
(*pk.Int)(&p.EID),
|
||||
(*pk.Boolean)(&p.Hardcore),
|
||||
@ -58,7 +59,7 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
|
||||
(*pk.Boolean)(&p.IsFlat),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
return Error{err}
|
||||
}
|
||||
|
||||
// This line should work "like" the following code but without copy things
|
||||
@ -74,10 +75,10 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
|
||||
pk.String(p.Settings.Brand),
|
||||
))
|
||||
if err != nil {
|
||||
return err
|
||||
return Error{err}
|
||||
}
|
||||
|
||||
return p.c.Conn.WritePacket(pk.Marshal(
|
||||
err = p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.Settings, // Client settings
|
||||
pk.String(p.Settings.Locale),
|
||||
pk.Byte(p.Settings.ViewDistance),
|
||||
@ -86,4 +87,8 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
|
||||
pk.UnsignedByte(p.Settings.DisplayedSkinParts),
|
||||
pk.VarInt(p.Settings.MainHand),
|
||||
))
|
||||
if err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -3,16 +3,59 @@ package basic
|
||||
import (
|
||||
"github.com/Tnze/go-mc/data/packetid"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
"log"
|
||||
)
|
||||
|
||||
func (p Player) handleKeepAlivePacket(packet pk.Packet) error {
|
||||
var KeepAliveID pk.Long
|
||||
if err := packet.Scan(&KeepAliveID); err != nil {
|
||||
return err
|
||||
return Error{err}
|
||||
}
|
||||
// Response
|
||||
return p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.KeepAliveServerbound,
|
||||
KeepAliveID,
|
||||
))
|
||||
err := p.c.Conn.WritePacket(pk.Packet{
|
||||
ID: packetid.KeepAliveServerbound,
|
||||
Data: packet.Data,
|
||||
})
|
||||
if err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Player) handlePlayerPositionAndLook(packet pk.Packet) error {
|
||||
var (
|
||||
X, Y, Z pk.Double
|
||||
Yaw, Pitch pk.Float
|
||||
Flags pk.Byte
|
||||
TeleportID pk.VarInt
|
||||
)
|
||||
if err := packet.Scan(&X, &Y, &Z, &Yaw, &Pitch, &Flags, &TeleportID); err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
|
||||
// Teleport Confirm
|
||||
err := p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.TeleportConfirm,
|
||||
TeleportID,
|
||||
))
|
||||
if err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
|
||||
if !p.isSpawn {
|
||||
// PlayerPositionAndRotation to confirm the spawn position
|
||||
err = p.c.Conn.WritePacket(pk.Marshal(
|
||||
packetid.PositionLook,
|
||||
X, Y-1.62, Z,
|
||||
Yaw, Pitch,
|
||||
pk.Boolean(true),
|
||||
))
|
||||
if err != nil {
|
||||
return Error{err}
|
||||
}
|
||||
p.isSpawn = true
|
||||
log.Print("Position confirmed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
15
bot/event.go
15
bot/event.go
@ -5,7 +5,8 @@ import (
|
||||
)
|
||||
|
||||
type Events struct {
|
||||
handlers map[int32]*handlerHeap
|
||||
generic *handlerHeap // for every packet
|
||||
handlers map[int32]*handlerHeap // for specific packet id only
|
||||
}
|
||||
|
||||
func (e *Events) AddListener(listeners ...PacketHandler) {
|
||||
@ -21,6 +22,18 @@ func (e *Events) AddListener(listeners ...PacketHandler) {
|
||||
}
|
||||
}
|
||||
|
||||
// AddGeneric adds listeners like AddListener, but the packet ID is ignored.
|
||||
// Generic listener is always called before specific packet listener.
|
||||
func (e *Events) AddGeneric(listeners ...PacketHandler) {
|
||||
for _, l := range listeners {
|
||||
if e.generic == nil {
|
||||
e.generic = &handlerHeap{l}
|
||||
} else {
|
||||
e.generic.Push(l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type PacketHandlerFunc func(p pk.Packet) error
|
||||
type PacketHandler struct {
|
||||
ID int32
|
||||
|
@ -37,6 +37,13 @@ func (d PacketHandlerError) Unwrap() error {
|
||||
}
|
||||
|
||||
func (c *Client) handlePacket(p pk.Packet) (err error) {
|
||||
if c.Events.generic != nil {
|
||||
for _, handler := range *c.Events.generic {
|
||||
if err = handler.F(p); err != nil {
|
||||
return PacketHandlerError{ID: p.ID, Err: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if listeners := c.Events.handlers[p.ID]; listeners != nil {
|
||||
for _, handler := range *listeners {
|
||||
err = handler.F(p)
|
||||
|
Reference in New Issue
Block a user