move some stuff and add registercritical
This commit is contained in:
@@ -16,7 +16,7 @@ type ConfigIgnorer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigIgnorer) OnStart() (err error) {
|
func (c *ConfigIgnorer) OnStart() (err error) {
|
||||||
c.Register(c.Default)
|
c.RegisterCritical(c.Default)
|
||||||
c.RegisterUntilLatest(c.OnKnownPacks)
|
c.RegisterUntilLatest(c.OnKnownPacks)
|
||||||
c.RegisterUntilLatest(c.OnFinish)
|
c.RegisterUntilLatest(c.OnFinish)
|
||||||
c.RegisterUntilLatest(c.OnPing)
|
c.RegisterUntilLatest(c.OnPing)
|
||||||
|
|||||||
+3
-3
@@ -124,9 +124,9 @@ func (s *LoginClient) OnSuccess(success *v1_21_8.LoginToClientPacketSuccess) (er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *LoginClient) OnStart() (err error) {
|
func (s *LoginClient) OnStart() (err error) {
|
||||||
s.Register(s.OnDefault)
|
s.RegisterCritical(s.OnDefault)
|
||||||
s.Register(s.OnCycle)
|
s.RegisterCritical(s.OnCycle)
|
||||||
s.Register(s.OnClose)
|
s.RegisterCritical(s.OnClose)
|
||||||
s.RegisterUntilLatest(s.OnCompress)
|
s.RegisterUntilLatest(s.OnCompress)
|
||||||
s.RegisterUntilLatest(s.OnEncrypt)
|
s.RegisterUntilLatest(s.OnEncrypt)
|
||||||
s.RegisterUntilLatest(s.OnDisconnect)
|
s.RegisterUntilLatest(s.OnDisconnect)
|
||||||
|
|||||||
+26
-2
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -60,7 +61,7 @@ func (e HandlerDoneErr) Unwrap() error {
|
|||||||
var ErrDontForward = errors.New("dont forward")
|
var ErrDontForward = errors.New("dont forward")
|
||||||
var WhileClosingErr = errors.New("error while closing")
|
var WhileClosingErr = errors.New("error while closing")
|
||||||
|
|
||||||
func ValidateHandler(h any) (hv reflect.Value, eventType reflect.Type) {
|
func ValidateHandler(h any) (eventType reflect.Type, hv reflect.Value) {
|
||||||
hv = reflect.ValueOf(h)
|
hv = reflect.ValueOf(h)
|
||||||
if hv.Kind() != reflect.Func {
|
if hv.Kind() != reflect.Func {
|
||||||
panic("expected method")
|
panic("expected method")
|
||||||
@@ -75,8 +76,31 @@ func ValidateHandler(h any) (hv reflect.Value, eventType reflect.Type) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register registers a handler that will not close the loop if it returns an error.
|
||||||
|
// Instead, it will log it to slog.Error
|
||||||
|
// Warning: If a bad handler is passed in the program will panic.
|
||||||
func (l *Loop) Register(h any) {
|
func (l *Loop) Register(h any) {
|
||||||
hv, eventType := ValidateHandler(h)
|
l.RegisterCustomType(ValidateHandler(h))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterCustomType registers a handler that will not close the loop if it returns an error.
|
||||||
|
// Instead, it will log it to slog.Error
|
||||||
|
// Warning: If a bad handler is passed in the program will panic.
|
||||||
|
func (l *Loop) RegisterCustomType(eventType reflect.Type, hv reflect.Value) {
|
||||||
|
handleFunc := func(packet any) error {
|
||||||
|
v := hv.Call([]reflect.Value{reflect.ValueOf(packet)})[0]
|
||||||
|
if !v.IsNil() {
|
||||||
|
slog.Error("handler failed", v.Interface().(error))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
l.RegisterDirect(eventType, reflect.ValueOf(handleFunc))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterCritical registers a handler that will close the loop if it returns an error.
|
||||||
|
// Warning: If a bad handler is passed in the program will panic.
|
||||||
|
func (l *Loop) RegisterCritical(h any) {
|
||||||
|
eventType, hv := ValidateHandler(h)
|
||||||
l.RegisterDirect(eventType, hv)
|
l.RegisterDirect(eventType, hv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ func (s *StdinHandler) ScanJob() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *StdinHandler) OnStart() (err error) {
|
func (s *StdinHandler) OnStart() (err error) {
|
||||||
s.Register(s.OnTick)
|
s.RegisterCritical(s.OnTick)
|
||||||
s.stdInChan = make(chan Stdin)
|
s.stdInChan = make(chan Stdin)
|
||||||
go s.ScanJob()
|
go s.ScanJob()
|
||||||
return
|
return
|
||||||
|
|||||||
+1
-48
@@ -7,7 +7,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"reflect"
|
"reflect"
|
||||||
"slices"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/admin-else/strom/data"
|
"github.com/admin-else/strom/data"
|
||||||
@@ -60,54 +59,8 @@ type Conn struct {
|
|||||||
packetCh chan proto_base.EncodeDecodeAble
|
packetCh chan proto_base.EncodeDecodeAble
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) RegisterUntilLatest(h any) {
|
|
||||||
c.RegisterUntil(h, LatestVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) RegisterUntil(h any, until string) {
|
|
||||||
hv, eventType := event.ValidateHandler(h)
|
|
||||||
c.RegisterDirect(eventType, hv)
|
|
||||||
if !eventType.Implements(reflect.TypeFor[proto_base.EncodeDecodeAble]()) {
|
|
||||||
panic("expected method with argument that implements proto_base.EncodeDecodeAble")
|
|
||||||
}
|
|
||||||
packetInfo, found := LookupPacketInfoByType(reflect.Zero(eventType).Interface().(proto_base.EncodeDecodeAble))
|
|
||||||
if !found {
|
|
||||||
panic("packet not found")
|
|
||||||
}
|
|
||||||
versionInfo, err := data.LookUpVersionByProtocolVersion(packetInfo.ProtocolVersion)
|
|
||||||
if err != nil {
|
|
||||||
panic("protocol version not found")
|
|
||||||
}
|
|
||||||
startIndex := slices.Index(proto_generated.SupportedVersions, versionInfo.MinecraftVersion)
|
|
||||||
endIndex := slices.Index(proto_generated.SupportedVersions, until)
|
|
||||||
for i := startIndex + 1; i <= endIndex; i++ {
|
|
||||||
versionName := proto_generated.SupportedVersions[i]
|
|
||||||
versionInfo, err = data.LookUpVersionByName(versionName)
|
|
||||||
if err != nil {
|
|
||||||
panic("protocol version not found")
|
|
||||||
}
|
|
||||||
var newPacketInfo proto_base.PacketInfo
|
|
||||||
newPacketInfo, found = LookupPacketInfoByNameProtocolVersionAndState(packetInfo.Name, versionInfo.Version, packetInfo.State)
|
|
||||||
if !found {
|
|
||||||
panic("packet not found")
|
|
||||||
}
|
|
||||||
newT := reflect.TypeOf(newPacketInfo.Type)
|
|
||||||
if !SmartConvertibleTo(newT, reflect.TypeOf(packetInfo.Type)) {
|
|
||||||
panic(fmt.Sprintf("packet %v is not convertible to %v", newT, reflect.TypeOf(packetInfo.Type)))
|
|
||||||
}
|
|
||||||
handleFunc := func(packet any) error {
|
|
||||||
v := hv.Call([]reflect.Value{SmartConvert(reflect.ValueOf(packet), reflect.TypeOf(packetInfo.Type))})[0]
|
|
||||||
if v.IsNil() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return v.Interface().(error)
|
|
||||||
}
|
|
||||||
c.RegisterDirect(newT, reflect.ValueOf(handleFunc))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Conn) OnStart() (err error) {
|
func (c *Conn) OnStart() (err error) {
|
||||||
c.Register(c.OnTick)
|
c.RegisterCritical(c.OnTick)
|
||||||
return c.handler.OnStart()
|
return c.handler.OnStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
package proto
|
package proto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/admin-else/strom/data"
|
||||||
|
"github.com/admin-else/strom/event"
|
||||||
|
"github.com/admin-else/strom/proto_base"
|
||||||
|
"github.com/admin-else/strom/proto_generated"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SmartConvertibleTo(from, to reflect.Type) bool {
|
func SmartConvertibleTo(from, to reflect.Type) bool {
|
||||||
@@ -40,3 +47,75 @@ func SmartConvert(from reflect.Value, to reflect.Type) (ret reflect.Value) {
|
|||||||
return from.Convert(to)
|
return from.Convert(to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterUntilLatest registers a handler for all versions between the passed in packet version and the latest supported version.
|
||||||
|
// Warning: If a bad handler is passed in, the program will panic.
|
||||||
|
func (c *Conn) RegisterUntilLatest(h any) {
|
||||||
|
c.registerUntil(h, LatestVersion, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUntil registers a handler for all versions between the passed in packet version and the specified version.
|
||||||
|
// Warning: If a bad handler is passed in, the program will panic.
|
||||||
|
func (c *Conn) RegisterUntil(h any, until string) {
|
||||||
|
c.registerUntil(h, until, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterCriticalUntilLatest registers a handler for all versions between the passed in packet version and the latest supported version.
|
||||||
|
// If this handler returns an error, the connection will be closed.
|
||||||
|
// Warning: If a bad handler is passed in, the program will panic.
|
||||||
|
func (c *Conn) RegisterCriticalUntilLatest(h any) {
|
||||||
|
c.registerUntil(h, LatestVersion, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterCriticalUntil registers a handler for all versions between the passed in packet version and the specified version.
|
||||||
|
// If this handler returns an error, the connection will be closed.
|
||||||
|
// Warning: If a bad handler is passed in, the program will panic.
|
||||||
|
func (c *Conn) RegisterCriticalUntil(h any, until string) {
|
||||||
|
c.registerUntil(h, until, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) registerUntil(h any, until string, critical bool) {
|
||||||
|
eventType, hv := event.ValidateHandler(h)
|
||||||
|
c.RegisterDirect(eventType, hv)
|
||||||
|
if !eventType.Implements(reflect.TypeFor[proto_base.EncodeDecodeAble]()) {
|
||||||
|
panic("expected method with argument that implements proto_base.EncodeDecodeAble")
|
||||||
|
}
|
||||||
|
packetInfo, found := LookupPacketInfoByType(reflect.Zero(eventType).Interface().(proto_base.EncodeDecodeAble))
|
||||||
|
if !found {
|
||||||
|
panic("packet not found")
|
||||||
|
}
|
||||||
|
versionInfo, err := data.LookUpVersionByProtocolVersion(packetInfo.ProtocolVersion)
|
||||||
|
if err != nil {
|
||||||
|
panic("protocol version not found")
|
||||||
|
}
|
||||||
|
startIndex := slices.Index(proto_generated.SupportedVersions, versionInfo.MinecraftVersion)
|
||||||
|
endIndex := slices.Index(proto_generated.SupportedVersions, until)
|
||||||
|
for i := startIndex + 1; i <= endIndex; i++ {
|
||||||
|
versionName := proto_generated.SupportedVersions[i]
|
||||||
|
versionInfo, err = data.LookUpVersionByName(versionName)
|
||||||
|
if err != nil {
|
||||||
|
panic("protocol version not found")
|
||||||
|
}
|
||||||
|
var newPacketInfo proto_base.PacketInfo
|
||||||
|
newPacketInfo, found = LookupPacketInfoByNameProtocolVersionAndState(packetInfo.Name, versionInfo.Version, packetInfo.State)
|
||||||
|
if !found {
|
||||||
|
panic("packet not found")
|
||||||
|
}
|
||||||
|
newT := reflect.TypeOf(newPacketInfo.Type)
|
||||||
|
if !SmartConvertibleTo(newT, reflect.TypeOf(packetInfo.Type)) {
|
||||||
|
panic(fmt.Sprintf("packet %v is not convertible to %v", newT, reflect.TypeOf(packetInfo.Type)))
|
||||||
|
}
|
||||||
|
handleFunc := func(packet any) error {
|
||||||
|
v := hv.Call([]reflect.Value{SmartConvert(reflect.ValueOf(packet), reflect.TypeOf(packetInfo.Type))})[0]
|
||||||
|
if v.IsNil() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return v.Interface().(error)
|
||||||
|
}
|
||||||
|
if critical {
|
||||||
|
c.RegisterCustomType(newT, reflect.ValueOf(handleFunc))
|
||||||
|
} else {
|
||||||
|
c.RegisterDirect(newT, reflect.ValueOf(handleFunc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (p *ProxyClient) OnCycle(_ event.Tick) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProxyClient) OnStart(_ event.Start) (err error) {
|
func (p *ProxyClient) OnStart() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ func (p *Proxy) OnCycle(_ event.Tick) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) OnStart(_ event.Start) (err error) {
|
func (p *Proxy) OnStart() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user