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"
"testing"
generated "github.com/admin-else/strom/proto_generated/%v"
generated "github.com/admin-else/strom/mc/proto_generated/%v"
)
// Error: %v
+43 -26
View File
@@ -8,6 +8,7 @@ import (
"errors"
"flag"
"fmt"
"go/format"
"io"
"log/slog"
"os"
@@ -32,32 +33,42 @@ var (
//go:embed failed_packet.go.tmpl
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)
h := hUntrimmed[:8]
f, err := os.Create(fmt.Sprintf(*CreateTestsPath+"/%v_%10x_test.go", len(packet.Data), h))
if err != nil {
panic(err)
if err = os.MkdirAll(*CreateTestsPath, 0755); err != nil {
return
}
ret, err := data.LookUpVersionByProtocolVersion(packet.Info.ProtocolVersion)
if err != nil {
panic(err)
return
}
goPackage := "v" + strings.ReplaceAll(ret.MinecraftVersion, ".", "_")
typeName := reflect.TypeOf(packet.Info.Type).Elem().Name()
//goland:noinspection GoUnhandledErrorResult
defer f.Close()
_, err = fmt.Fprintf(f, TestSrcF, goPackage, packet.Err, h, reflect.TypeOf(packet.Info.Type).Elem().Name(), packet.Data)
if err != nil {
panic(err)
src := fmt.Sprintf(TestSrcF, goPackage, packet.Err, h, typeName, packet.Data)
formatted, formatErr := format.Source([]byte(src))
if formatErr != nil {
formatted = []byte(src)
}
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
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
err = binary.Read(r, binary.BigEndian, &timestamp)
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 := 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 {
packet = &proto.UnCodablePacket{Err: proto.BadPacketIdErr, Data: packetData, Info: i}
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 {
case "success":
state = proto_base.Configuration
case "finish_configuration":
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
}
@@ -137,21 +153,22 @@ func Run(args []string) (err error) {
var totalPackets, failedPackets int
for {
var packet proto_base.EncodeDecodeAble
packet, err = UnpackPacket(f)
var info proto_base.PacketInfo
packet, info, err = UnpackPacket(f)
unCodablePacket, ok := packet.(*proto.UnCodablePacket)
if ok {
slog.Error("failed to decode packet", "error", err, "packet_name", info.Name)
if *CreateTestsPath != "" {
SaveUnCodeAbleAsTest(unCodablePacket)
err = SaveUnCodeAbleAsTest(unCodablePacket)
if err != nil {
slog.Error("failed to save uncodable packet as test", "error", err)
}
}
failedPackets++
}
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Packet: %#v\n", packet)
}
if errors.Is(err, io.EOF) {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
break
}
totalPackets++