improve packet replay things

This commit is contained in:
adman
2026-07-20 12:56:19 +02:00
parent a347aedfc2
commit 126ff5bca0
2 changed files with 45 additions and 28 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"testing" "testing"
generated "github.com/admin-else/strom/proto_generated/%v" generated "github.com/admin-else/strom/mc/proto_generated/%v"
) )
// Error: %v // Error: %v
+43 -26
View File
@@ -8,6 +8,7 @@ import (
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
"go/format"
"io" "io"
"log/slog" "log/slog"
"os" "os"
@@ -32,32 +33,42 @@ var (
//go:embed failed_packet.go.tmpl //go:embed failed_packet.go.tmpl
var TestSrcF string var TestSrcF string
func SaveUnCodeAbleAsTest(packet *proto.UnCodablePacket) { func SaveUnCodeAbleAsTest(packet *proto.UnCodablePacket) (err error) {
if packet.Info.Type == nil {
slog.Warn("skipping test for unknown packet id", "packet_id", packet.Info.PacketId, "state", packet.Info.State, "error", packet.Err)
return
}
hUntrimmed := sha256.Sum256(packet.Data) hUntrimmed := sha256.Sum256(packet.Data)
h := hUntrimmed[:8] h := hUntrimmed[:8]
f, err := os.Create(fmt.Sprintf(*CreateTestsPath+"/%v_%10x_test.go", len(packet.Data), h)) if err = os.MkdirAll(*CreateTestsPath, 0755); err != nil {
if err != nil { return
panic(err)
} }
ret, err := data.LookUpVersionByProtocolVersion(packet.Info.ProtocolVersion) ret, err := data.LookUpVersionByProtocolVersion(packet.Info.ProtocolVersion)
if err != nil { if err != nil {
panic(err) return
} }
goPackage := "v" + strings.ReplaceAll(ret.MinecraftVersion, ".", "_") goPackage := "v" + strings.ReplaceAll(ret.MinecraftVersion, ".", "_")
typeName := reflect.TypeOf(packet.Info.Type).Elem().Name()
//goland:noinspection GoUnhandledErrorResult src := fmt.Sprintf(TestSrcF, goPackage, packet.Err, h, typeName, packet.Data)
defer f.Close() formatted, formatErr := format.Source([]byte(src))
_, err = fmt.Fprintf(f, TestSrcF, goPackage, packet.Err, h, reflect.TypeOf(packet.Info.Type).Elem().Name(), packet.Data) if formatErr != nil {
if err != nil { formatted = []byte(src)
panic(err)
} }
slog.Info("Packet failed to parse", "error", packet.Err, "saved", f.Name(), "data", fmt.Sprintf("%q", packet.Data))
filePath := fmt.Sprintf(*CreateTestsPath+"/%v_%10x_test.go", len(packet.Data), h)
if err = os.WriteFile(filePath, formatted, 0644); err != nil {
return
}
slog.Info("Packet failed to parse", "error", packet.Err, "saved", filePath, "data", fmt.Sprintf("%q", packet.Data))
return
} }
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, i proto_base.PacketInfo, err error) {
var timestamp, length uint32 var timestamp, length uint32
err = binary.Read(r, binary.BigEndian, &timestamp) err = binary.Read(r, binary.BigEndian, &timestamp)
if err != nil { if err != nil {
@@ -87,23 +98,28 @@ func UnpackPacket(r io.Reader) (packet proto_base.EncodeDecodeAble, err error) {
// indexafterid represents how many bytes we've read so far // indexafterid represents how many bytes we've read so far
indexafterid := int(b.Size()) - b.Len() indexafterid := int(b.Size()) - b.Len()
i, ok := proto.LookUpTypeByPacketInfo(proto_base.ToClient, state, packetId, int32(*ProtocolVersion)) var ok bool
i, ok = proto.LookUpTypeByPacketInfo(proto_base.ToClient, state, packetId, int32(*ProtocolVersion))
if !ok { if !ok {
packet = &proto.UnCodablePacket{Err: proto.BadPacketIdErr, Data: packetData, Info: i} packet = &proto.UnCodablePacket{Err: proto.BadPacketIdErr, Data: packetData, Info: i}
return return
} }
packet = reflect.New(reflect.TypeOf(i.Type).Elem()).Interface().(proto_base.EncodeDecodeAble)
err = packet.Decode(b)
if err != nil {
packet = &proto.UnCodablePacket{Err: err, Data: packetData[indexafterid:], Info: i}
return
}
switch i.Name { switch i.Name {
case "success": case "success":
state = proto_base.Configuration state = proto_base.Configuration
case "finish_configuration": case "finish_configuration":
state = proto_base.Play state = proto_base.Play
} }
packet = reflect.New(reflect.TypeOf(i.Type).Elem()).Interface().(proto_base.EncodeDecodeAble)
err = packet.Decode(b)
if err != nil {
packet = &proto.UnCodablePacket{Err: err, Data: packetData[indexafterid:], Info: i}
return
}
if b.Len() != 0 {
packet = &proto.UnCodablePacket{Err: proto.PacketNotFullyDecodedErr, Data: packetData[indexafterid:], Info: i}
return
}
return return
} }
@@ -137,21 +153,22 @@ func Run(args []string) (err error) {
var totalPackets, failedPackets int var totalPackets, failedPackets int
for { for {
var packet proto_base.EncodeDecodeAble var packet proto_base.EncodeDecodeAble
packet, err = UnpackPacket(f) var info proto_base.PacketInfo
packet, info, err = UnpackPacket(f)
unCodablePacket, ok := packet.(*proto.UnCodablePacket) unCodablePacket, ok := packet.(*proto.UnCodablePacket)
if ok { if ok {
slog.Error("failed to decode packet", "error", err, "packet_name", info.Name)
if *CreateTestsPath != "" { if *CreateTestsPath != "" {
SaveUnCodeAbleAsTest(unCodablePacket) err = SaveUnCodeAbleAsTest(unCodablePacket)
if err != nil {
slog.Error("failed to save uncodable packet as test", "error", err)
}
} }
failedPackets++ failedPackets++
} }
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Packet: %#v\n", packet) fmt.Printf("Packet: %#v\n", packet)
} if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
if errors.Is(err, io.EOF) {
break break
} }
totalPackets++ totalPackets++