support multi handler for same packetID and handler priority.
This commit is contained in:
@ -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)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
bot/event.go
46
bot/event.go
@ -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]
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user