remove uncodeable_packet_hunter_proxy tool and integrate its functionality into print_replay

This commit is contained in:
adman
2026-05-10 14:09:24 +02:00
parent 57cef25e27
commit b5ee17d1ae
3 changed files with 30 additions and 133 deletions
+30 -1
View File
@@ -2,10 +2,13 @@ package print_replay
import ( import (
"bytes" "bytes"
"crypto/sha256"
_ "embed"
"encoding/binary" "encoding/binary"
"flag" "flag"
"fmt" "fmt"
"io" "io"
"log/slog"
"os" "os"
"reflect" "reflect"
@@ -17,8 +20,29 @@ var (
cmd = flag.NewFlagSet("print-replay", flag.ContinueOnError) cmd = flag.NewFlagSet("print-replay", flag.ContinueOnError)
FileFlag = cmd.String("file", "", "The tmcpr file to print") FileFlag = cmd.String("file", "", "The tmcpr file to print")
ProtocolVersion = cmd.Int("protocol", -1, "The protocol version") ProtocolVersion = cmd.Int("protocol", -1, "The protocol version")
CreateTestsPath = cmd.String("create-tests", "", "The path to create tests from failed packets, if empty no tests will be created")
) )
//go:embed failed_packet.go.tmpl
var TestSrcF string
func SaveUnCodeAbleAsTest(d proto_base.Direction, packet *proto.UnCodablePacket) {
hUntrimmed := sha256.Sum256(packet.Data)
h := hUntrimmed[:8]
f, err := os.Create(fmt.Sprintf(*CreateTestsPath+"/%v_%10x_test.go", len(packet.Data), h))
if err != nil {
panic(err)
}
//goland:noinspection GoUnhandledErrorResult
defer f.Close()
_, err = fmt.Fprintf(f, TestSrcF, packet.Err, h, d.Opposite(), packet.Data)
if err != nil {
panic(err)
}
slog.Info("Packet failed to parse", "error", packet.Err, "saved", f.Name(), "data", fmt.Sprintf("%q", packet.Data))
}
var state = proto_base.Login var state = proto_base.Login
func UnpackPacket(r io.Reader) (packet proto_base.EncodeDecodeAble, err error) { func UnpackPacket(r io.Reader) (packet proto_base.EncodeDecodeAble, err error) {
@@ -51,7 +75,7 @@ func UnpackPacket(r io.Reader) (packet proto_base.EncodeDecodeAble, err error) {
err = packet.Decode(b) err = packet.Decode(b)
if err != nil { if err != nil {
packet = &proto.UnCodablePacket{Err: err, Data: b.Bytes(), Direction: proto_base.ToClient} packet = &proto.UnCodablePacket{Err: err, Data: b.Bytes(), Direction: proto_base.ToClient}
err = nil return
} }
switch i.Name { switch i.Name {
case "success": case "success":
@@ -82,6 +106,11 @@ func Run(args []string) (err error) {
for { for {
var packet proto_base.EncodeDecodeAble var packet proto_base.EncodeDecodeAble
packet, err = UnpackPacket(f) packet, err = UnpackPacket(f)
unCodablePacket, ok := packet.(*proto.UnCodablePacket)
if ok && *CreateTestsPath != "" {
SaveUnCodeAbleAsTest(proto_base.ToClient, unCodablePacket)
}
if err != nil { if err != nil {
return return
} }
@@ -1,132 +0,0 @@
package main
import (
"crypto/sha256"
_ "embed"
"fmt"
"log/slog"
"os"
"github.com/admin-else/strom/api"
"github.com/admin-else/strom/client"
"github.com/admin-else/strom/event"
"github.com/admin-else/strom/nbt"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/proto_generated/v1_21_11"
"github.com/admin-else/strom/server"
"github.com/admin-else/strom/text"
)
//go:embed failed_packet.go.tmpl
var TestSrcF string
type Proxy struct {
Client, Servee *proto.Conn
Data nbt.Tag
}
func (p *Proxy) Start() (err error) {
p.Client.RegisterCritical(p.OnAnything)
p.Servee.RegisterCritical(p.OnAnything)
p.Servee.Register(p.OnUnCodeAble)
p.Client.Register(p.OnUnCodeAble)
p.Servee.RegisterCriticalUntilLatest(p.OnFinishConfiguration)
errChan := make(chan error)
go func() {
errChan <- p.Client.StartConn()
}()
go func() {
errChan <- p.Servee.StartConn()
}()
err = <-errChan
return
}
func (p *Proxy) OnAnything(e event.Anything) (err error) {
packet, ok := e.Val.(proto_base.EncodeDecodeAble)
if !ok {
return
}
packetInfo, ok := proto.LookupPacketInfoByType(packet)
if !ok {
return
}
switch packetInfo.Direction {
case proto_base.ToServer:
err = p.Client.Send(packet)
case proto_base.ToClient:
err = p.Servee.Send(packet)
}
return
}
func (p *Proxy) OnFinishConfiguration(packet *v1_21_11.ConfigurationToServerPacketFinishConfiguration) (err error) {
err = p.Client.Send(packet)
if err != nil {
return
}
p.Servee.SetState(proto_base.Play)
p.Client.SetState(proto_base.Play)
err = event.DontForwardErr
return
}
func (p *Proxy) OnUnCodeAble(packet *proto.UnCodablePacket) (err error) {
SaveUnCodeAbleAsTest(packet.Direction, packet)
return
}
func SaveUnCodeAbleAsTest(d proto_base.Direction, packet *proto.UnCodablePacket) {
hUntrimmed := sha256.Sum256(packet.Data)
h := hUntrimmed[:8]
f, err := os.Create(fmt.Sprintf(".failed_packets/%v_%10x_test.go", len(packet.Data), h))
if err != nil {
panic(err)
}
//goland:noinspection GoUnhandledErrorResult
defer f.Close()
_, err = fmt.Fprintf(f, TestSrcF, packet.Err, h, d.Opposite(), packet.Data)
if err != nil {
panic(err)
}
slog.Info("Packet failed to parse", "error", packet.Err, "saved", f.Name(), "data", fmt.Sprintf("%q", packet.Data))
}
var StatusResponse = server.StatusResponse{
Version: server.StatusResponseVersion{
Name: text.Pretty("STROM"),
Protocol: 772,
},
Players: server.StatusResponsePlayers{},
Description: text.Pretty("Hunt the un-code-able packets"),
Favicon: "",
EnforcesSecureChat: false,
}
func main() {
slog.SetLogLoggerLevel(slog.LevelDebug)
err := server.StartServerWithOnConn(":25566", func(serveeConn *proto.Conn) (err error) {
p := &Proxy{Servee: serveeConn, Client: nil}
acc := api.NewOfflineAccount("sigma")
_, err = server.ServeLogin(serveeConn, server.WithOtherAccount(acc), server.WithStatus(StatusResponse))
if err != nil {
return
}
c, err := client.LoginNoSrv("127.0.0.1:25565", acc)
if err != nil {
return
}
defer c.Close()
p.Client = c
err = p.Start()
return
})
if err != nil {
panic(err)
}
}