support multi handler for same packetID and handler priority.

This commit is contained in:
Tnze
2023-01-06 20:01:05 +08:00
parent 36bec6e63d
commit 4e23ad63a2
3 changed files with 29 additions and 40 deletions

View File

@ -1,10 +1,11 @@
package bot package bot
import ( import (
"github.com/google/uuid"
"github.com/Tnze/go-mc/data/packetid" "github.com/Tnze/go-mc/data/packetid"
"github.com/Tnze/go-mc/net" "github.com/Tnze/go-mc/net"
"github.com/Tnze/go-mc/yggdrasil/user" "github.com/Tnze/go-mc/yggdrasil/user"
"github.com/google/uuid"
) )
// Client is used to access Minecraft server // Client is used to access Minecraft server
@ -34,7 +35,7 @@ func (c *Client) Close() error {
func NewClient() *Client { func NewClient() *Client {
return &Client{ return &Client{
Auth: Auth{Name: "Steve"}, Auth: Auth{Name: "Steve"},
Events: Events{handlers: make(map[packetid.ClientboundPacketID]*handlerHeap)}, Events: Events{handlers: make([][]PacketHandler, packetid.ClientboundPacketIDGuard)},
} }
} }

View File

@ -1,24 +1,29 @@
package bot package bot
import ( import (
"sort"
"strconv"
"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"
) )
type Events struct { type Events struct {
generic *handlerHeap // for every packet generic []PacketHandler // for every packet
handlers map[packetid.ClientboundPacketID]*handlerHeap // for specific packet id only handlers [][]PacketHandler // for specific packet id only
} }
func (e *Events) AddListener(listeners ...PacketHandler) { func (e *Events) AddListener(listeners ...PacketHandler) {
for _, l := range listeners { for _, l := range listeners {
var s *handlerHeap // panic if l.ID is invalid
var ok bool if l.ID < 0 || int(l.ID) >= len(e.handlers) {
if s, ok = e.handlers[l.ID]; !ok { panic("Invalid packet ID (" + strconv.Itoa(int(l.ID)) + ")")
s = &handlerHeap{l} }
e.handlers[l.ID] = s if s := e.handlers[l.ID]; s == nil {
e.handlers[l.ID] = []PacketHandler{l}
} else { } else {
s.Push(l) e.handlers[l.ID] = append(s, l)
sortPacketHandlers(e.handlers[l.ID])
} }
} }
} }
@ -26,13 +31,8 @@ func (e *Events) AddListener(listeners ...PacketHandler) {
// AddGeneric adds listeners like AddListener, but the packet ID is ignored. // AddGeneric adds listeners like AddListener, but the packet ID is ignored.
// Generic listener is always called before specific packet listener. // Generic listener is always called before specific packet listener.
func (e *Events) AddGeneric(listeners ...PacketHandler) { func (e *Events) AddGeneric(listeners ...PacketHandler) {
for _, l := range listeners { e.generic = append(e.generic, listeners...)
if e.generic == nil { sortPacketHandlers(e.generic)
e.generic = &handlerHeap{l}
} else {
e.generic.Push(l)
}
}
} }
type ( type (
@ -44,16 +44,8 @@ type (
} }
) )
// handlerHeap is PriorityQueue<PacketHandlerFunc> func sortPacketHandlers(slice []PacketHandler) {
type handlerHeap []PacketHandler sort.SliceStable(slice, func(i, j int) bool {
return slice[i].Priority > slice[j].Priority
func (h handlerHeap) Len() int { return len(h) } })
func (h handlerHeap) Less(i, j int) bool { return h[i].Priority < h[j].Priority }
func (h handlerHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *handlerHeap) Push(x interface{}) { *h = append(*h, x.(PacketHandler)) }
func (h *handlerHeap) Pop() interface{} {
old := *h
n := len(old)
*h = old[0 : n-1]
return old[n-1]
} }

View File

@ -40,20 +40,16 @@ func (d PacketHandlerError) Unwrap() error {
func (c *Client) handlePacket(p pk.Packet) (err error) { func (c *Client) handlePacket(p pk.Packet) (err error) {
packetID := packetid.ClientboundPacketID(p.ID) packetID := packetid.ClientboundPacketID(p.ID)
if c.Events.generic != nil { for _, handler := range c.Events.generic {
for _, handler := range *c.Events.generic {
if err = handler.F(p); err != nil { if err = handler.F(p); err != nil {
return PacketHandlerError{ID: packetID, Err: err} return PacketHandlerError{ID: packetID, Err: err}
} }
} }
} for _, handler := range c.Events.handlers[packetID] {
if listeners := c.Events.handlers[packetID]; listeners != nil {
for _, handler := range *listeners {
err = handler.F(p) err = handler.F(p)
if err != nil { if err != nil {
return PacketHandlerError{ID: packetID, Err: err} return PacketHandlerError{ID: packetID, Err: err}
} }
} }
}
return return
} }