update 1.19.2 bot basic events

This commit is contained in:
Tnze
2022-11-26 01:30:08 +08:00
parent 822d76a4b1
commit 6a3589ad61

View File

@ -1,117 +1,136 @@
package basic package basic
import ( import (
"time"
"github.com/google/uuid"
"github.com/Tnze/go-mc/bot" "github.com/Tnze/go-mc/bot"
"github.com/Tnze/go-mc/chat" "github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/data/packetid" "github.com/Tnze/go-mc/data/packetid"
pk "github.com/Tnze/go-mc/net/packet" pk "github.com/Tnze/go-mc/net/packet"
"io"
) )
type EventsListener struct { type EventsListener struct {
GameStart func() error GameStart func() error
ChatMsg func(c *PlayerMessage) error ChatMsg func(c *PlayerMessage) error
SystemMsg func(c chat.Message, pos byte) error SystemMsg func(c chat.Message, overlay bool) error
Disconnect func(reason chat.Message) error Disconnect func(reason chat.Message) error
HealthChange func(health float32) error HealthChange func(health float32) error
Death func() error Death func() error
} }
// Attach your event listener to the client.
// The functions are copied when attaching, and modify on [EventListener] doesn't affect after that.
func (e EventsListener) Attach(c *bot.Client) { func (e EventsListener) Attach(c *bot.Client) {
c.Events.AddListener(
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundLogin, F: e.onJoinGame},
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundSystemChat, F: e.onSystemMsg},
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundPlayerChat, F: e.onPlayerMsg},
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundDisconnect, F: e.onDisconnect},
bot.PacketHandler{Priority: 64, ID: packetid.ClientboundSetHealth, F: e.onUpdateHealth},
)
}
func (e *EventsListener) onJoinGame(_ pk.Packet) error {
if e.GameStart != nil { if e.GameStart != nil {
return e.GameStart() attachJoinGameHandler(c, e.GameStart)
}
if e.ChatMsg != nil {
attachPlayerMsg(c, e.ChatMsg)
}
if e.SystemMsg != nil {
attachSystemMsg(c, e.SystemMsg)
}
if e.Disconnect != nil {
attachDisconnect(c, e.Disconnect)
}
if e.HealthChange != nil || e.Death != nil {
attachUpdateHealth(c, e.HealthChange, e.Death)
} }
return nil
} }
func (e *EventsListener) onDisconnect(p pk.Packet) error { func attachJoinGameHandler(c *bot.Client, handler func() error) {
if e.Disconnect != nil { c.Events.AddListener(bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundLogin,
F: func(_ pk.Packet) error {
return handler()
},
})
}
type PlayerMessage struct {
}
func (p *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
// SignedMessageHeader
// MessageSignature
// SignedMessageBody
// Optional<Component>
// FilterMask
panic("implement me")
}
type ChatType struct {
ID int32
Name chat.Message
TargetName *chat.Message
}
func (c *ChatType) ReadFrom(r io.Reader) (n int64, err error) {
var hasTargetName pk.Boolean
n1, err := (*pk.VarInt)(&c.ID).ReadFrom(r)
if err != nil {
return n1, err
}
n2, err := c.Name.ReadFrom(r)
if err != nil {
return n1 + n2, err
}
n3, err := hasTargetName.ReadFrom(r)
if err != nil {
return n1 + n2 + n3, err
}
if hasTargetName {
c.TargetName = new(chat.Message)
n4, err := c.TargetName.ReadFrom(r)
return n1 + n2 + n3 + n4, err
}
return n1 + n2 + n3, nil
}
func attachPlayerMsg(c *bot.Client, handler func(c *PlayerMessage) error) {
c.Events.AddListener(bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundPlayerChat,
F: func(p pk.Packet) error {
var message PlayerMessage
var chatType ChatType
if err := p.Scan(&message, &chatType); err != nil {
return Error{err}
}
return handler(&message)
},
})
}
func attachSystemMsg(c *bot.Client, handler func(c chat.Message, overlay bool) error) {
c.Events.AddListener(bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundSystemChat,
F: func(p pk.Packet) error {
var msg chat.Message
var pos pk.Boolean
if err := p.Scan(&msg, &pos); err != nil {
return Error{err}
}
return handler(msg, bool(pos))
},
})
}
func attachDisconnect(c *bot.Client, handler func(reason chat.Message) error) {
c.Events.AddListener(bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundDisconnect,
F: func(p pk.Packet) error {
var reason chat.Message var reason chat.Message
if err := p.Scan(&reason); err != nil { if err := p.Scan(&reason); err != nil {
return Error{err} return Error{err}
} }
return e.Disconnect(reason) return handler(reason)
}
return nil
}
type PlayerMessage struct {
SignedMessage chat.Message
Unsigned bool
UnsignedMessage chat.Message
Position int32
Sender uuid.UUID
SenderDisplayName chat.Message
HasSenderTeam bool
SenderTeamName chat.Message
TimeStamp time.Time
}
func (e *EventsListener) onPlayerMsg(p pk.Packet) error {
if e.ChatMsg != nil {
var message PlayerMessage
var senderDisplayName pk.String
var senderTeamName pk.String
var timeStamp pk.Long
var salt pk.Long
var signature pk.ByteArray
if err := p.Scan(&message.SignedMessage,
(*pk.Boolean)(&message.Unsigned),
pk.Opt{
Has: &message.Unsigned,
Field: &message.UnsignedMessage,
}, },
(*pk.VarInt)(&message.Position), })
(*pk.UUID)(&message.Sender),
&senderDisplayName,
(*pk.Boolean)(&message.HasSenderTeam),
pk.Opt{
Has: &message.HasSenderTeam,
Field: &senderTeamName,
},
&timeStamp,
&salt,
&signature); err != nil {
return Error{err}
}
if err := message.SenderDisplayName.UnmarshalJSON([]byte(senderDisplayName)); err != nil {
return Error{err}
}
if err := message.SenderTeamName.UnmarshalJSON([]byte(senderDisplayName)); err != nil {
return Error{err}
}
return e.ChatMsg(&message)
}
return nil
}
func (e *EventsListener) onSystemMsg(p pk.Packet) error {
if e.SystemMsg != nil {
var msg chat.Message
var pos pk.VarInt
if err := p.Scan(&msg, &pos); err != nil {
return Error{err}
}
return e.SystemMsg(msg, byte(pos))
}
return nil
} }
func (e *EventsListener) onUpdateHealth(p pk.Packet) error { func attachUpdateHealth(c *bot.Client, healthChangeHandler func(health float32) error, deathHandler func() error) {
if e.ChatMsg != nil { c.Events.AddListener(bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundSetHealth,
F: func(p pk.Packet) error {
var health pk.Float var health pk.Float
var food pk.VarInt var food pk.VarInt
var foodSaturation pk.Float var foodSaturation pk.Float
@ -119,16 +138,41 @@ func (e *EventsListener) onUpdateHealth(p pk.Packet) error {
if err := p.Scan(&health, &food, &foodSaturation); err != nil { if err := p.Scan(&health, &food, &foodSaturation); err != nil {
return Error{err} return Error{err}
} }
if e.HealthChange != nil { var healthChangeErr, deathErr error
if err := e.HealthChange(float32(health)); err != nil { if healthChangeHandler != nil {
return err healthChangeErr = healthChangeHandler(float32(health))
} }
if deathHandler != nil && health <= 0 {
healthChangeErr = deathHandler()
} }
if e.Death != nil && health <= 0 { return updateHealthError{healthChangeErr, deathErr}
if err := e.Death(); err != nil { },
return err })
} }
type updateHealthError struct {
healthChangeErr, deathErr error
}
func (u updateHealthError) Unwrap() error {
if u.healthChangeErr != nil {
return u.healthChangeErr
} }
if u.deathErr != nil {
return u.deathErr
} }
return nil return nil
} }
func (u updateHealthError) Error() string {
switch {
case u.healthChangeErr != nil && u.deathErr != nil:
return "[" + u.healthChangeErr.Error() + ", " + u.deathErr.Error() + "]"
case u.healthChangeErr != nil:
return u.healthChangeErr.Error()
case u.deathErr != nil:
return u.deathErr.Error()
default:
return "nil"
}
}