bedrocktool/subcommands/capture.go

78 lines
1.8 KiB
Go
Raw Normal View History

2022-09-04 14:53:21 +00:00
package subcommands
2022-04-03 20:12:21 +00:00
import (
"bytes"
"context"
"encoding/binary"
2022-04-03 20:12:21 +00:00
"flag"
2023-04-01 22:22:50 +00:00
"fmt"
"io"
2022-04-03 20:12:21 +00:00
"net"
"os"
2022-10-14 22:42:43 +00:00
"sync"
2022-04-03 20:12:21 +00:00
"time"
"github.com/bedrock-tool/bedrocktool/locale"
2022-09-04 14:53:21 +00:00
"github.com/bedrock-tool/bedrocktool/utils"
2022-09-04 14:26:32 +00:00
2022-04-03 20:12:21 +00:00
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)
func init() {
2022-09-04 14:26:32 +00:00
utils.RegisterCommand(&CaptureCMD{})
2022-04-03 20:12:21 +00:00
}
2023-01-29 21:20:13 +00:00
var dumpLock sync.Mutex
2022-10-14 22:42:43 +00:00
2023-01-29 21:20:13 +00:00
func dumpPacket(f io.WriteCloser, toServer bool, payload []byte) {
dumpLock.Lock()
defer dumpLock.Unlock()
2022-10-14 22:42:43 +00:00
f.Write([]byte{0xAA, 0xAA, 0xAA, 0xAA})
2023-01-29 21:20:13 +00:00
packetSize := uint32(len(payload))
binary.Write(f, binary.LittleEndian, packetSize)
binary.Write(f, binary.LittleEndian, toServer)
2023-02-08 11:00:36 +00:00
binary.Write(f, binary.LittleEndian, time.Now().UnixMilli())
2023-04-01 22:22:50 +00:00
f.Write(payload)
2022-10-14 22:42:43 +00:00
f.Write([]byte{0xBB, 0xBB, 0xBB, 0xBB})
2022-04-03 20:12:21 +00:00
}
type CaptureCMD struct {
2023-03-06 01:03:31 +00:00
ServerAddress string
}
func (*CaptureCMD) Name() string { return "capture" }
func (*CaptureCMD) Synopsis() string { return locale.Loc("capture_synopsis", nil) }
2023-01-29 21:20:13 +00:00
func (c *CaptureCMD) SetFlags(f *flag.FlagSet) {
2023-03-06 01:03:31 +00:00
f.StringVar(&c.ServerAddress, "address", "", "remote server address")
2023-03-05 21:50:58 +00:00
}
func (c *CaptureCMD) Execute(ctx context.Context, ui utils.UI) error {
2023-03-06 01:03:31 +00:00
address, hostname, err := utils.ServerInput(ctx, c.ServerAddress)
2022-04-03 20:12:21 +00:00
if err != nil {
return err
2022-04-03 20:12:21 +00:00
}
os.Mkdir("captures", 0o775)
2023-04-01 22:22:50 +00:00
fio, err := os.Create(fmt.Sprintf("captures/%s-%s.pcap2", hostname, time.Now().Format("2006-01-02_15-04-05")))
2022-04-03 20:12:21 +00:00
if err != nil {
return err
2022-04-03 20:12:21 +00:00
}
defer fio.Close()
2023-02-08 11:00:36 +00:00
utils.WriteReplayHeader(fio)
2022-04-03 20:12:21 +00:00
2023-03-06 01:03:31 +00:00
proxy, err := utils.NewProxy()
2023-02-12 21:22:44 +00:00
if err != nil {
2023-04-01 22:22:50 +00:00
return err
2023-02-12 21:22:44 +00:00
}
2022-09-04 14:26:32 +00:00
proxy.PacketFunc = func(header packet.Header, payload []byte, src, dst net.Addr) {
2023-01-29 22:07:42 +00:00
IsfromClient := src.String() == proxy.Client.LocalAddr().String()
buf := bytes.NewBuffer(nil)
header.Write(buf)
buf.Write(payload)
2023-01-29 21:20:13 +00:00
dumpPacket(fio, IsfromClient, buf.Bytes())
2022-09-04 13:24:55 +00:00
}
2022-08-13 14:30:46 +00:00
2023-04-01 22:22:50 +00:00
return proxy.Run(ctx, address)
2022-04-03 20:12:21 +00:00
}