improve packet replay things
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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, ×tamp)
|
err = binary.Read(r, binary.BigEndian, ×tamp)
|
||||||
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++
|
||||||
|
|||||||
Reference in New Issue
Block a user