diff --git a/client/config_ignorer.go b/client/config_ignorer.go index c144b5e..cc320af 100644 --- a/client/config_ignorer.go +++ b/client/config_ignorer.go @@ -16,11 +16,6 @@ type ConfigIgnorer struct { } func (c *ConfigIgnorer) OnStart() (err error) { - c.RegisterCritical(c.Default) - c.RegisterUntilLatest(c.OnKnownPacks) - c.RegisterUntilLatest(c.OnFinish) - c.RegisterUntilLatest(c.OnPing) - c.RegisterUntilLatest(c.OnKeepAlive) return } @@ -54,7 +49,14 @@ func (c *ConfigIgnorer) OnKeepAlive(packet *v1_21_8.ConfigurationToClientPacketK } func IgnoreConfig(c *proto.Conn) (err error) { - err = c.Start(&ConfigIgnorer{c}) + ci := &ConfigIgnorer{c} + ci.RegisterCritical(ci.Default) + ci.RegisterUntilLatest(ci.OnKnownPacks) + ci.RegisterUntilLatest(ci.OnFinish) + ci.RegisterUntilLatest(ci.OnPing) + ci.RegisterUntilLatest(ci.OnKeepAlive) + + err = ci.Start() if err != nil { err = errors.Join(err, errors.New("failed to ignore config")) } diff --git a/client/login.go b/client/login.go index 761cdb4..f04e629 100644 --- a/client/login.go +++ b/client/login.go @@ -124,37 +124,35 @@ func (s *LoginClient) OnSuccess(success *v1_21_8.LoginToClientPacketSuccess) (er } func (s *LoginClient) OnStart() (err error) { - s.RegisterCritical(s.OnDefault) - s.RegisterCritical(s.OnCycle) - s.RegisterCritical(s.OnClose) - s.RegisterUntilLatest(s.OnCompress) - s.RegisterUntilLatest(s.OnEncrypt) - s.RegisterUntilLatest(s.OnDisconnect) - s.RegisterUntilLatest(s.OnSuccess) - - p, err := MakeHandshakePacket(s.Conn, proto_base.Login) - if err != nil { - return - } - if s.ServerHost == "" && s.ServerPort == 0 { - p.ServerHost = s.ServerHost - p.ServerPort = s.ServerPort - } - - err = s.Send(p) - if err != nil { - return - } - s.SetState(proto_base.Login) - err = s.Send(&v1_21_8.LoginToServerPacketLoginStart{Username: s.Account.Name, PlayerUUID: s.Account.Uuid}) return } func Login(c *proto.Conn, account *api.Account) (err error) { - err = c.Start(&LoginClient{ + lc := &LoginClient{ Conn: c, Account: account, - }) + } + lc.RegisterCritical(lc.OnDefault) + lc.RegisterCritical(lc.OnCycle) + lc.RegisterCritical(lc.OnClose) + lc.RegisterUntilLatest(lc.OnCompress) + lc.RegisterUntilLatest(lc.OnEncrypt) + lc.RegisterUntilLatest(lc.OnDisconnect) + lc.RegisterUntilLatest(lc.OnSuccess) + + p, err := MakeHandshakePacket(lc.Conn, proto_base.Login) + if err != nil { + return + } + + err = lc.Send(p) + if err != nil { + return + } + lc.SetState(proto_base.Login) + err = lc.Send(&v1_21_8.LoginToServerPacketLoginStart{Username: lc.Account.Name, PlayerUUID: lc.Account.Uuid}) + + err = lc.Start() if err != nil { err = errors.Join(FailedToLoginErr, err) } @@ -166,10 +164,7 @@ func ConnectAndLogin(connectTo string, account *api.Account) (c *proto.Conn, err if err != nil { return } - err = c.Start(&LoginClient{ - Conn: c, - Account: account, - }) + err = Login(c, account) if err != nil { err = errors.Join(FailedToLoginErr, err) } diff --git a/client/status.go b/client/status.go index 14aa67c..f022b98 100644 --- a/client/status.go +++ b/client/status.go @@ -16,29 +16,21 @@ type StatusClient struct { *proto.Conn Status string PingSendTime, PingReceiveTime time.Time + DoPingRoundTripTime bool } func (s *StatusClient) OnStart() (err error) { - s.RegisterUntilLatest(s.OnStatus) - s.RegisterUntilLatest(s.OnPong) - - p, err := MakeHandshakePacket(s.Conn, proto_base.Status) - if err != nil { - return - } - err = s.Send(p) - if err != nil { - return - } - s.SetState(proto_base.Status) - err = s.Send(&v1_21_8.StatusToServerPacketPingStart{}) return } func (s *StatusClient) OnStatus(p *v1_21_8.StatusToClientPacketServerInfo) (err error) { s.Status = p.Response s.PingSendTime = time.Now() - err = s.Send(&v1_21_8.StatusToServerPacketPing{Time: s.PingSendTime.UnixMilli()}) + if s.DoPingRoundTripTime { + err = s.Send(&v1_21_8.StatusToServerPacketPing{Time: s.PingSendTime.UnixMilli()}) + } else { + err = event.HandlerDoneErr{} + } return } @@ -63,7 +55,22 @@ func StatusRaw(addr string) (s *StatusClient, err error) { s = &StatusClient{ Conn: c, } - err = s.Start(s) + s.Loop = event.NewLoop() + s.RegisterUntilLatest(s.OnStatus) + s.RegisterUntilLatest(s.OnPong) + + p, err := MakeHandshakePacket(s.Conn, proto_base.Status) + if err != nil { + return + } + err = s.Send(p) + if err != nil { + return + } + s.SetState(proto_base.Status) + err = s.Send(&v1_21_8.StatusToServerPacketPingStart{}) + + err = s.StartConn() return } diff --git a/event/event_bus.go b/event/event_bus.go index 9938cf0..158ad59 100644 --- a/event/event_bus.go +++ b/event/event_bus.go @@ -15,12 +15,8 @@ const ( TimePerLoop = time.Second / LoopsPerSecond ) -type Handler interface { - OnStart() (err error) -} - type Loop struct { - handlerFunctions map[reflect.Type][]reflect.Value + HandlerFunctions map[reflect.Type][]reflect.Value Ctx context.Context ErrChan chan error @@ -105,13 +101,13 @@ func (l *Loop) RegisterCritical(h any) { } func (l *Loop) RegisterDirect(k reflect.Type, h reflect.Value) { - l.handlerFunctions[k] = append(l.handlerFunctions[k], h) + l.HandlerFunctions[k] = append(l.HandlerFunctions[k], h) } // FireFound triggers all handlers registered for the specified event type and returns if handlers were found or an error occurred. func (l *Loop) FireFound(event any) (found bool, err error) { var handlers []reflect.Value - if handlers, found = l.handlerFunctions[reflect.TypeOf(event)]; found { + if handlers, found = l.HandlerFunctions[reflect.TypeOf(event)]; found { for _, handler := range handlers { errV := handler.Call([]reflect.Value{reflect.ValueOf(event)})[0] if !errV.IsNil() { @@ -143,11 +139,9 @@ func (l *Loop) Fire(event any) (err error) { return } -func (l *Loop) startLoop(handler Handler) (err error) { +func (l *Loop) startLoop() (err error) { _ = *l // exit early on nil loop - l.handlerFunctions = make(map[reflect.Type][]reflect.Value) - err = handler.OnStart() - for err == nil { + for { tickStartTime := time.Now() err = l.Fire(Tick{}) if err != nil { @@ -165,13 +159,19 @@ func (l *Loop) startLoop(handler Handler) (err error) { return } -func (l *Loop) Start(handler Handler) (err error) { - l.ErrChan = make(chan error) - l.Ctx, l.cancel = context.WithCancel(context.Background()) +func (l *Loop) Start() (err error) { go func() { - l.ErrChan <- l.startLoop(handler) + l.ErrChan <- l.startLoop() }() err = <-l.ErrChan l.cancel() return } + +func NewLoop() (l *Loop) { + l = &Loop{} + l.ErrChan = make(chan error) + l.Ctx, l.cancel = context.WithCancel(context.Background()) + l.HandlerFunctions = make(map[reflect.Type][]reflect.Value) + return +} diff --git a/proto/connection.go b/proto/connection.go index 5477fd8..af42aa8 100644 --- a/proto/connection.go +++ b/proto/connection.go @@ -54,14 +54,13 @@ type Conn struct { Version string ProtocolVersion int32 - handler event.Handler receiveRoutine bool packetCh chan proto_base.EncodeDecodeAble } -func (c *Conn) OnStart() (err error) { +func (c *Conn) StartConn() (err error) { c.RegisterCritical(c.OnTick) - return c.handler.OnStart() + return c.Loop.Start() } func (c *Conn) ReceiveJob() { @@ -235,10 +234,9 @@ func (c *Conn) OnTick(_ event.Tick) (err error) { return } -func (c *Conn) Start(handler event.Handler) (err error) { +func (c *Conn) Start() (err error) { if c.Loop == nil { c.Loop = &event.Loop{} } - c.handler = handler - return c.Loop.Start(c) + return c.Loop.Start() } diff --git a/proto_generated/v1_21_11/proto.go b/proto_generated/v1_21_11/proto.go index 45cd8f1..aebec77 100644 --- a/proto_generated/v1_21_11/proto.go +++ b/proto_generated/v1_21_11/proto.go @@ -16635,30 +16635,15 @@ func (ret *PlayToClientPacketEntityUpdateAttributes) Encode(w io.Writer) (err er } type PlayToClientPacketEntityVelocity struct { - EntityId int32 - Velocity proto_base.LpVec3d + Val proto_base.ToDo } func (ret *PlayToClientPacketEntityVelocity) Decode(r io.Reader) (err error) { - ret.EntityId, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } - err = ret.Velocity.Decode(r) - if err != nil { - return - } + err = proto_base.ToDoError return } func (ret *PlayToClientPacketEntityVelocity) Encode(w io.Writer) (err error) { - err = proto_base.EncodeVarInt(w, ret.EntityId) - if err != nil { - return - } - err = ret.Velocity.Encode(w) - if err != nil { - return - } + err = proto_base.ToDoError return } @@ -20435,111 +20420,15 @@ func (ret *PlayToClientPacketSoundEffect) Encode(w io.Writer) (err error) { } type PlayToClientPacketSpawnEntity struct { - EntityId int32 - ObjectUUID uuid.UUID - Type int32 - X float64 - Y float64 - Z float64 - Velocity proto_base.LpVec3d - Pitch int8 - Yaw int8 - HeadPitch int8 - ObjectData int32 + Val proto_base.ToDo } func (ret *PlayToClientPacketSpawnEntity) Decode(r io.Reader) (err error) { - ret.EntityId, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } - _, err = io.ReadFull(r, ret.ObjectUUID[:]) - if err != nil { - return - } - ret.Type, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.X) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Y) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Z) - if err != nil { - return - } - err = ret.Velocity.Decode(r) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Pitch) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Yaw) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.HeadPitch) - if err != nil { - return - } - ret.ObjectData, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } + err = proto_base.ToDoError return } func (ret *PlayToClientPacketSpawnEntity) Encode(w io.Writer) (err error) { - err = proto_base.EncodeVarInt(w, ret.EntityId) - if err != nil { - return - } - _, err = w.Write(ret.ObjectUUID[:]) - if err != nil { - return - } - err = proto_base.EncodeVarInt(w, ret.Type) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.X) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Y) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Z) - if err != nil { - return - } - err = ret.Velocity.Encode(w) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Pitch) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Yaw) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.HeadPitch) - if err != nil { - return - } - err = proto_base.EncodeVarInt(w, ret.ObjectData) - if err != nil { - return - } + err = proto_base.ToDoError return } diff --git a/proto_generated/v1_21_9/proto.go b/proto_generated/v1_21_9/proto.go index 1a133fc..cf1ef18 100644 --- a/proto_generated/v1_21_9/proto.go +++ b/proto_generated/v1_21_9/proto.go @@ -16458,30 +16458,15 @@ func (ret *PlayToClientPacketEntityUpdateAttributes) Encode(w io.Writer) (err er } type PlayToClientPacketEntityVelocity struct { - EntityId int32 - Velocity proto_base.LpVec3d + Val proto_base.ToDo } func (ret *PlayToClientPacketEntityVelocity) Decode(r io.Reader) (err error) { - ret.EntityId, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } - err = ret.Velocity.Decode(r) - if err != nil { - return - } + err = proto_base.ToDoError return } func (ret *PlayToClientPacketEntityVelocity) Encode(w io.Writer) (err error) { - err = proto_base.EncodeVarInt(w, ret.EntityId) - if err != nil { - return - } - err = ret.Velocity.Encode(w) - if err != nil { - return - } + err = proto_base.ToDoError return } @@ -20258,111 +20243,15 @@ func (ret *PlayToClientPacketSoundEffect) Encode(w io.Writer) (err error) { } type PlayToClientPacketSpawnEntity struct { - EntityId int32 - ObjectUUID uuid.UUID - Type int32 - X float64 - Y float64 - Z float64 - Velocity proto_base.LpVec3d - Pitch int8 - Yaw int8 - HeadPitch int8 - ObjectData int32 + Val proto_base.ToDo } func (ret *PlayToClientPacketSpawnEntity) Decode(r io.Reader) (err error) { - ret.EntityId, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } - _, err = io.ReadFull(r, ret.ObjectUUID[:]) - if err != nil { - return - } - ret.Type, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.X) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Y) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Z) - if err != nil { - return - } - err = ret.Velocity.Decode(r) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Pitch) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.Yaw) - if err != nil { - return - } - err = binary.Read(r, binary.BigEndian, &ret.HeadPitch) - if err != nil { - return - } - ret.ObjectData, err = proto_base.DecodeVarInt(r) - if err != nil { - return - } + err = proto_base.ToDoError return } func (ret *PlayToClientPacketSpawnEntity) Encode(w io.Writer) (err error) { - err = proto_base.EncodeVarInt(w, ret.EntityId) - if err != nil { - return - } - _, err = w.Write(ret.ObjectUUID[:]) - if err != nil { - return - } - err = proto_base.EncodeVarInt(w, ret.Type) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.X) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Y) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Z) - if err != nil { - return - } - err = ret.Velocity.Encode(w) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Pitch) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.Yaw) - if err != nil { - return - } - err = binary.Write(w, binary.BigEndian, ret.HeadPitch) - if err != nil { - return - } - err = proto_base.EncodeVarInt(w, ret.ObjectData) - if err != nil { - return - } + err = proto_base.ToDoError return } diff --git a/proto_generator/native_decoder.go b/proto_generator/native_decoder.go index b8008d8..0b90205 100644 --- a/proto_generator/native_decoder.go +++ b/proto_generator/native_decoder.go @@ -577,7 +577,7 @@ func (g *Generator) RegisterDecoderNatives() { "varlong": VarLongDecoder, "anonymousNbt": DefaultDecoder, "anonOptionalNbt": DefaultDecoder, // I have no idea what the difference is between these two - "lpVec3": DefaultDecoder, + "lpVec3": ToDoDecoder, "UUID": UUIDDecoder, "restBuffer": DefaultDecoder, diff --git a/proto_generator/native_encoder.go b/proto_generator/native_encoder.go index fdf4bdc..01c8dbe 100644 --- a/proto_generator/native_encoder.go +++ b/proto_generator/native_encoder.go @@ -373,7 +373,7 @@ func (g *Generator) RegisterEncoderNatives() { "anonOptionalNbt": DefaultEncoder, // I have no idea what the difference is between these two "UUID": UUIDEncoder, "restBuffer": DefaultEncoder, - "lpVec3": DefaultEncoder, + "lpVec3": ToDoEncoder, "string": StringEncoder, "f32": SimpleTypeEncoder, diff --git a/server/config_server.go b/server/config_server.go index 0209c47..a3cbbd8 100644 --- a/server/config_server.go +++ b/server/config_server.go @@ -21,7 +21,7 @@ func (c *ConfigServer) Default(event event.Anything) (err error) { return } -func (c *ConfigServer) OnStart() (err error) { +func ServeConfig(c *proto.Conn) (err error) { n, err := data.LoadRegistry(c.Version) if err != nil { return @@ -64,7 +64,8 @@ func (c *ConfigServer) OnStart() (err error) { return } err = c.Send(&v1_21_8.ConfigurationToClientPacketFinishConfiguration{}) - return + cs := &ConfigServer{c} + return cs.Start() } func (c *ConfigServer) OnFinishConfiguration(_ *v1_21_8.ConfigurationToServerPacketFinishConfiguration) (err error) { @@ -72,9 +73,3 @@ func (c *ConfigServer) OnFinishConfiguration(_ *v1_21_8.ConfigurationToServerPac err = event.HandlerDoneErr{} return } - -func ServeConfig(c *proto.Conn) (err error) { - cs := &ConfigServer{c} - err = cs.Start(cs) - return -} diff --git a/server/login_server.go b/server/login_server.go index bf0f016..edc06f6 100644 --- a/server/login_server.go +++ b/server/login_server.go @@ -112,18 +112,6 @@ func (l *LoginServer) OnDefault(event event.Unhandled) (err error) { return } -func (l *LoginServer) OnStart() (err error) { - return -} - -func (l *LoginServer) OnCycle(_ event.Tick) (err error) { - return -} - -func (l *LoginServer) OnClose(_ event.Close) (err error) { - return -} - type LoginServerSetting func(*LoginServer) func WithOtherAccount(a *api.Account) LoginServerSetting { @@ -170,10 +158,16 @@ func WithCompatibleVersions(versions ...int32) LoginServerSetting { func ServeLogin(c *proto.Conn, settings ...LoginServerSetting) (ret *LoginServer, err error) { ret = &LoginServer{Conn: c} + ret.RegisterCritical(ret.OnDefault) + ret.RegisterUntilLatest(ret.OnHandshake) + ret.RegisterUntilLatest(ret.OnLoginStart) + ret.RegisterUntilLatest(ret.OnLoginAcknowledged) + ret.RegisterUntilLatest(ret.OnStatusRequest) + ret.RegisterUntilLatest(ret.OnStatusPing) for _, s := range settings { s(ret) } ret.CompressionThreshold = 256 - err = ret.Start(ret) + err = ret.Start() return } diff --git a/server/server.go b/server/server.go index db7535c..c1b6631 100644 --- a/server/server.go +++ b/server/server.go @@ -5,7 +5,6 @@ import ( "log/slog" "net" - "github.com/admin-else/strom/event" "github.com/admin-else/strom/proto" "github.com/admin-else/strom/proto_base" "github.com/admin-else/strom/text" @@ -23,7 +22,9 @@ func Servee(c net.Conn) (ret *proto.Conn) { return } -type Factory func(c *proto.Conn) (h event.Handler, err error) +type ConnAcceptor func(c net.Conn) (err error) + +type Factory func(c *proto.Conn) (h ConnAcceptor, err error) func ServeClient(cNet net.Conn, factory Factory) { c := Servee(cNet) @@ -32,7 +33,7 @@ func ServeClient(cNet net.Conn, factory Factory) { if err != nil { return } - err = c.Start(h) + err = h(c) if errors.Is(err, StatusServedErr) { return } diff --git a/server/status.go b/server/status.go index f04e588..438b976 100644 --- a/server/status.go +++ b/server/status.go @@ -48,14 +48,6 @@ type StatusServer struct { Status string } -func (p *StatusServer) OnStart() (err error) { - return -} - -func (p *StatusServer) Default(_ any) (err error) { - return -} - func (p *StatusServer) OnStatusRequest(_ *v1_21_8.StatusToServerPacketPingStart) (err error) { return p.Send(&v1_21_8.StatusToClientPacketServerInfo{Response: p.Status}) } @@ -73,6 +65,8 @@ func ServeStatus(c *proto.Conn, s StatusResponse) (err error) { Conn: c, Status: string(status), } - err = server.Start(server) + server.RegisterUntilLatest(server.OnStatusRequest) + server.RegisterUntilLatest(server.OnStatusPing) + err = server.Start() return } diff --git a/tools/cli/main.go b/tools/cli/main.go index 5cadaeb..786ae60 100644 --- a/tools/cli/main.go +++ b/tools/cli/main.go @@ -28,21 +28,24 @@ func Help(args []string) (err error) { } func mainE() (err error) { + slog.SetLogLoggerLevel(slog.LevelDebug) subcommands["help"] = Help // this is here because if it isn't tools/cli/main.go:17:5: initialization cycle for subcommands // tools/cli/main.go:17:5: subcommands refers to Help // tools/cli/main.go:22:6: Help refers to subcommands + args := os.Args + args = []string{"TEST", "status", "-addr", "tcpshield.1f2d.net:25565"} - if len(os.Args) < 2 { + if len(args) < 2 { err = ExpectedASubcommandErr return } - f, ok := subcommands[os.Args[1]] + f, ok := subcommands[args[1]] if !ok { err = UnknownSubcommandErr return } - err = f(os.Args[2:]) + err = f(args[2:]) return }