remove uncodeable_packet_hunter_proxy tool and integrate its functionality into print_replay
This commit is contained in:
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user