From 1001c809e505f9681c1d4f7785e0e7bf23c87f65 Mon Sep 17 00:00:00 2001 From: Admin Else <74665496+admin-else@users.noreply.github.com> Date: Tue, 4 Aug 2026 22:16:34 +0200 Subject: [PATCH] strom: fix RegisterUntilLow to panic on reverse range, use dual-range registrations - RegisterUntilLow now panics if startIndex > endIndex (programmer must address version incompatibility explicitly, not silently skip) - Replace per-version RegisterCritical handlers with dual-range RegisterUntil: modern range (v1_21_8->latest) + legacy range (v1_8->1.12.2) - Remove v1_12_2 handler duplicates (covered by upward range from v1_8) - Move legacy chat handling into chat.Module.SendMessage (protocol<764 uses v1_8.PlayToServerPacketChat instead of v1_21_11) - Skip chat signing init for pre-1.19 versions --- mc/bot/chat/mod.go | 10 +++++++++- mc/client/login.go | 41 ++++----------------------------------- mc/client/status.go | 26 ++----------------------- mc/proto/smart_convert.go | 5 ++++- 4 files changed, 19 insertions(+), 63 deletions(-) diff --git a/mc/bot/chat/mod.go b/mc/bot/chat/mod.go index 79bee4f..ae34a53 100644 --- a/mc/bot/chat/mod.go +++ b/mc/bot/chat/mod.go @@ -15,6 +15,7 @@ import ( "github.com/admin-else/strom/mc/api" "github.com/admin-else/strom/mc/proto" "github.com/admin-else/strom/mc/proto_generated/v1_21_11" + "github.com/admin-else/strom/mc/proto_generated/v1_8" "github.com/google/uuid" ) @@ -43,6 +44,9 @@ func Start(c *proto.Conn, acc *api.Account) (*Module, error) { } func (m *Module) initSigning(acc *api.Account) (err error) { + if m.Conn.ProtocolVersion < 764 { + return nil + } keys, err := acc.FetchKeys() if err != nil { return fmt.Errorf("fetch profile keys: %w", err) @@ -80,8 +84,12 @@ func (m *Module) initSigning(acc *api.Account) (err error) { } // SendMessage sends a chat message. If signing is enabled, the message is signed; -// otherwise it is sent unsigned. +// otherwise it is sent unsigned. For pre-1.19 protocol versions, uses the legacy +// chat packet format (plain string). func (m *Module) SendMessage(message string) (err error) { + if m.Conn.ProtocolVersion < 764 { + return m.Conn.Send(&v1_8.PlayToServerPacketChat{Message: message}) + } if m.canSign { return m.sendSigned(message) } diff --git a/mc/client/login.go b/mc/client/login.go index 7e07c35..4d367c9 100644 --- a/mc/client/login.go +++ b/mc/client/login.go @@ -16,7 +16,6 @@ import ( "github.com/admin-else/strom/mc/proto_base" "github.com/admin-else/strom/mc/proto_generated/v1_21_8" "github.com/admin-else/strom/mc/proto_generated/v1_8" - "github.com/admin-else/strom/mc/proto_generated/v1_12_2" "github.com/admin-else/strom/mc/proto_generated/v26_2" "github.com/admin-else/strom/mc/text" "github.com/google/uuid" @@ -140,31 +139,6 @@ func (s *LoginClient) OnSuccessV1_8(success *v1_8.LoginToClientPacketSuccess) (e return } -func (s *LoginClient) OnDisconnectV1_12_2(packet *v1_12_2.LoginToClientPacketDisconnect) (err error) { - var reason text.Component - err = json.Unmarshal([]byte(packet.Reason), &reason) - if err != nil { - return - } - err = KickedDuringLoginErr{reason} - return -} - -func (s *LoginClient) OnCompressV1_12_2(packet *v1_12_2.LoginToClientPacketCompress) (err error) { - s.SetCompressionThreshold(packet.Threshold) - return -} - -func (s *LoginClient) OnSuccessV1_12_2(success *v1_12_2.LoginToClientPacketSuccess) (err error) { - s.GivenAccount = &v1_21_8.LoginToClientPacketSuccess{ - Uuid: uuid.MustParse(success.Uuid), - Username: success.Username, - } - s.SetState(proto_base.Play) - err = event.HandlerDoneErr{} - return -} - func (s *LoginClient) OnSuccess(success *v1_21_8.LoginToClientPacketSuccess) (err error) { s.GivenAccount = success if s.ProtocolVersion >= 764 { @@ -207,17 +181,10 @@ func LoginRawAddr(c *proto.Conn, account *api.Account, hostAddr string) (err err } lc.RegisterCritical(lc.OnDefault) lc.RegisterCritical(lc.OnClose) - lc.RegisterCriticalUntilLatest(lc.OnCompress) - lc.RegisterCriticalUntilLatest(lc.OnEncrypt) - lc.RegisterCriticalUntilLatest(lc.OnDisconnect) - lc.RegisterCriticalUntil("26.1", lc.OnSuccess) - lc.RegisterCriticalUntilLatest(lc.OnSuccess26_2) - lc.RegisterCritical(lc.OnCompressV1_8) - lc.RegisterCritical(lc.OnDisconnectV1_8) - lc.RegisterCritical(lc.OnSuccessV1_8) - lc.RegisterCritical(lc.OnCompressV1_12_2) - lc.RegisterCritical(lc.OnDisconnectV1_12_2) - lc.RegisterCritical(lc.OnSuccessV1_12_2) + lc.RegisterUntil("26.2", lc.OnCompress, lc.OnEncrypt, lc.OnDisconnect) + lc.RegisterUntil("26.1", lc.OnSuccess) + lc.RegisterUntilLatest(lc.OnSuccess26_2) + lc.RegisterUntil("1.12.2", lc.OnCompressV1_8, lc.OnDisconnectV1_8, lc.OnSuccessV1_8) var p proto_base.EncodeDecodeAble if hostAddr != "" { diff --git a/mc/client/status.go b/mc/client/status.go index eaa53e7..144aed1 100644 --- a/mc/client/status.go +++ b/mc/client/status.go @@ -10,7 +10,6 @@ import ( "github.com/admin-else/strom/mc/proto_base" "github.com/admin-else/strom/mc/proto_generated/v1_21_8" "github.com/admin-else/strom/mc/proto_generated/v1_8" - "github.com/admin-else/strom/mc/proto_generated/v1_12_2" "github.com/admin-else/strom/mc/server" ) @@ -55,23 +54,6 @@ func (s *StatusClient) OnPongV1_8(p *v1_8.StatusToClientPacketPing) (err error) return } -func (s *StatusClient) OnStatusV1_12_2(p *v1_12_2.StatusToClientPacketServerInfo) (err error) { - s.Status = p.Response - s.PingSendTime = time.Now() - if s.DoPingRoundTripTime { - err = s.Send(&v1_21_8.StatusToServerPacketPing{Time: s.PingSendTime.UnixMilli()}) - } else { - err = event.HandlerDoneErr{} - } - return -} - -func (s *StatusClient) OnPongV1_12_2(p *v1_12_2.StatusToClientPacketPing) (err error) { - s.PingReceiveTime = time.Now() - err = event.HandlerDoneErr{} - return -} - // StatusRaw returns a StatusClient that is not connected to a server. // So ignore the resource leak warning. And maybe attach a warn ignore comment. // It does not resolve SRV records. @@ -93,12 +75,8 @@ func StatusRawWithVersion(ctx context.Context, addr, version string) (s *StatusC s = &StatusClient{ Conn: c, } - s.RegisterCriticalUntilLatest(s.OnStatus) - s.RegisterCriticalUntilLatest(s.OnPong) - s.RegisterCritical(s.OnStatusV1_8) - s.RegisterCritical(s.OnPongV1_8) - s.RegisterCritical(s.OnStatusV1_12_2) - s.RegisterCritical(s.OnPongV1_12_2) + s.RegisterUntil("26.2", s.OnStatus, s.OnPong) + s.RegisterUntil("1.12.2", s.OnStatusV1_8, s.OnPongV1_8) p, err := MakeHandshakePacketAddr(s.Conn, proto_base.Status, addr) if err != nil { diff --git a/mc/proto/smart_convert.go b/mc/proto/smart_convert.go index 2247bbb..a213dfd 100644 --- a/mc/proto/smart_convert.go +++ b/mc/proto/smart_convert.go @@ -116,6 +116,9 @@ func (c *Conn) RegisterUntilLow(eventType reflect.Type, hv reflect.Value, until } startIndex := slices.Index(proto_generated.SupportedVersions, versionInfo.MinecraftVersion) endIndex := slices.Index(proto_generated.SupportedVersions, until) + if startIndex > endIndex { + panic(fmt.Sprintf("handler version %s is above until version %s", versionInfo.MinecraftVersion, until)) + } for i := startIndex + 1; i <= endIndex; i++ { versionName := proto_generated.SupportedVersions[i] versionInfo, err = data.LookUpVersionByName(versionName) @@ -125,7 +128,7 @@ func (c *Conn) RegisterUntilLow(eventType reflect.Type, hv reflect.Value, until var newPacketInfo proto_base.PacketInfo newPacketInfo, found = LookupPacketInfoByNameProtocolVersionStateAndDirection(packetInfo.Name, versionInfo.Version, packetInfo.State, packetInfo.Direction) if !found { - panic("packet not found in future version") + panic("packet not found in version " + versionName) } newT := reflect.TypeOf(newPacketInfo.Type) if !SmartConvertibleTo(newT, reflect.TypeOf(packetInfo.Type)) {