allow custom user data (untested)
This commit is contained in:
parent
4d4eb37647
commit
6670d575d7
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
"github.com/bedrock-tool/bedrocktool/utils/crypt"
|
||||
"gopkg.in/square/go-jose.v2/json"
|
||||
|
||||
_ "github.com/bedrock-tool/bedrocktool/subcommands"
|
||||
_ "github.com/bedrock-tool/bedrocktool/subcommands/skins"
|
||||
|
@ -65,6 +66,7 @@ func main() {
|
|||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
flag.StringVar(&utils.RealmsEnv, "", "", "realms env")
|
||||
flag.BoolVar(&utils.GDebug, "debug", false, locale.Loc("debug_mode", nil))
|
||||
flag.BoolVar(&utils.GPreloadPacks, "preload", false, locale.Loc("preload_packs", nil))
|
||||
flag.BoolVar(&extraDebug, "extra-debug", false, locale.Loc("extra_debug", nil))
|
||||
|
@ -189,6 +191,38 @@ func (c *TransCMD) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
|||
return 0
|
||||
}
|
||||
|
||||
type CreateCustomDataCMD struct {
|
||||
path string
|
||||
}
|
||||
|
||||
func (*CreateCustomDataCMD) Name() string { return "create-customdata" }
|
||||
func (*CreateCustomDataCMD) Synopsis() string { return "" }
|
||||
|
||||
func (c *CreateCustomDataCMD) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&c.path, "path", "customdata.json", "where to save")
|
||||
}
|
||||
|
||||
func (c *CreateCustomDataCMD) Usage() string {
|
||||
return c.Name() + ": " + c.Synopsis() + "\n"
|
||||
}
|
||||
|
||||
func (c *CreateCustomDataCMD) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
var data utils.CustomClientData
|
||||
fio, err := os.Create(c.path)
|
||||
if err == nil {
|
||||
defer fio.Close()
|
||||
var bdata []byte
|
||||
bdata, err = json.MarshalIndent(&data, "", "\t")
|
||||
fio.Write(bdata)
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
utils.RegisterCommand(&TransCMD{})
|
||||
utils.RegisterCommand(&CreateCustomDataCMD{})
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,7 +3,7 @@ module github.com/bedrock-tool/bedrocktool
|
|||
go 1.19
|
||||
|
||||
//replace github.com/sandertv/gophertunnel => ./gophertunnel
|
||||
replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.27.2-1
|
||||
replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.27.2-2
|
||||
|
||||
//replace github.com/df-mc/dragonfly => ./dragonfly
|
||||
replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.2-1
|
||||
|
@ -29,6 +29,7 @@ require (
|
|||
golang.org/x/image v0.3.0
|
||||
golang.org/x/oauth2 v0.4.0
|
||||
golang.org/x/text v0.6.0
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
|
@ -54,5 +55,4 @@ require (
|
|||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
)
|
||||
|
|
2
go.sum
2
go.sum
|
@ -64,6 +64,8 @@ github.com/olebeck/dragonfly v0.9.2-1 h1:/bYHMZ2yvwrLp2SQvsupbRimqDPGJ5utA2Oq857
|
|||
github.com/olebeck/dragonfly v0.9.2-1/go.mod h1:hGGjGbLxpcn7nVTZOrk8kPfeGGntaMOqqcbuugZauyI=
|
||||
github.com/olebeck/gophertunnel v1.27.2-1 h1:p+q8XubWgnk37uhjO2e06+A4g7S91jyXbvkQlVL4Xb4=
|
||||
github.com/olebeck/gophertunnel v1.27.2-1/go.mod h1:hgVpDdaLDP/39Z/YqEU0WFi/DHRDHqvBs3XGqkB4tnU=
|
||||
github.com/olebeck/gophertunnel v1.27.2-2 h1:ycI1ChA2L0ttr74Qkhy+0nGm01PUlHD0IklSj6+BAkI=
|
||||
github.com/olebeck/gophertunnel v1.27.2-2/go.mod h1:hgVpDdaLDP/39Z/YqEU0WFi/DHRDHqvBs3XGqkB4tnU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
|
|
@ -44,7 +44,8 @@ func dumpPacket(f io.WriteCloser, toServer bool, payload []byte) {
|
|||
}
|
||||
|
||||
type CaptureCMD struct {
|
||||
serverAddress string
|
||||
serverAddress string
|
||||
pathCustomUserData string
|
||||
}
|
||||
|
||||
func (*CaptureCMD) Name() string { return "capture" }
|
||||
|
@ -52,6 +53,7 @@ func (*CaptureCMD) Synopsis() string { return locale.Loc("capture_synopsis", nil
|
|||
|
||||
func (c *CaptureCMD) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&c.serverAddress, "address", "", "remote server address")
|
||||
f.StringVar(&c.pathCustomUserData, "userdata", "", locale.Loc("custom_user_data", nil))
|
||||
}
|
||||
|
||||
func (c *CaptureCMD) Usage() string {
|
||||
|
@ -66,7 +68,6 @@ func (c *CaptureCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interfac
|
|||
}
|
||||
|
||||
os.Mkdir("captures", 0o775)
|
||||
|
||||
fio, err := os.Create("captures/" + hostname + "-" + time.Now().Format("2006-01-02_15-04-05") + ".pcap2")
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
|
@ -75,7 +76,10 @@ func (c *CaptureCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interfac
|
|||
defer fio.Close()
|
||||
utils.WriteReplayHeader(fio)
|
||||
|
||||
proxy := utils.NewProxy()
|
||||
proxy, err := utils.NewProxy(c.pathCustomUserData)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
proxy.PacketFunc = func(header packet.Header, payload []byte, src, dst net.Addr) {
|
||||
IsfromClient := src.String() == proxy.Client.LocalAddr().String()
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@ import (
|
|||
)
|
||||
|
||||
type ChatLogCMD struct {
|
||||
Address string
|
||||
verbose bool
|
||||
Address string
|
||||
verbose bool
|
||||
pathCustomUserData string
|
||||
}
|
||||
|
||||
func (*ChatLogCMD) Name() string { return "chat-log" }
|
||||
|
@ -26,6 +27,7 @@ func (*ChatLogCMD) Synopsis() string { return locale.Loc("chat_log_synopsis", ni
|
|||
func (c *ChatLogCMD) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&c.Address, "address", "", "remote server address")
|
||||
f.BoolVar(&c.verbose, "v", false, "verbose")
|
||||
f.StringVar(&c.pathCustomUserData, "userdata", "", locale.Loc("custom_user_data", nil))
|
||||
}
|
||||
|
||||
func (c *ChatLogCMD) Usage() string {
|
||||
|
@ -46,7 +48,10 @@ func (c *ChatLogCMD) Execute(ctx context.Context, flags *flag.FlagSet, _ ...inte
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
proxy := utils.NewProxy()
|
||||
proxy, err := utils.NewProxy(c.pathCustomUserData)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
proxy.PacketCB = func(pk packet.Packet, proxy *utils.ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) {
|
||||
if text, ok := pk.(*packet.Text); ok {
|
||||
logLine := text.Message
|
||||
|
|
|
@ -13,8 +13,9 @@ import (
|
|||
)
|
||||
|
||||
type DebugProxyCMD struct {
|
||||
Address string
|
||||
filter string
|
||||
Address string
|
||||
filter string
|
||||
pathCustomUserData string
|
||||
}
|
||||
|
||||
func (*DebugProxyCMD) Name() string { return "debug-proxy" }
|
||||
|
@ -23,6 +24,7 @@ func (*DebugProxyCMD) Synopsis() string { return locale.Loc("debug_proxy_synopsi
|
|||
func (c *DebugProxyCMD) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&c.Address, "address", "", locale.Loc("remote_address", nil))
|
||||
f.StringVar(&c.filter, "filter", "", locale.Loc("packet_filter", nil))
|
||||
f.StringVar(&c.pathCustomUserData, "userdata", "", locale.Loc("custom_user_data", nil))
|
||||
}
|
||||
|
||||
func (c *DebugProxyCMD) Usage() string {
|
||||
|
@ -53,7 +55,11 @@ func (c *DebugProxyCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...inter
|
|||
}
|
||||
}
|
||||
|
||||
proxy := utils.NewProxy()
|
||||
proxy, err := utils.NewProxy(c.pathCustomUserData)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return 1
|
||||
}
|
||||
if err := proxy.Run(ctx, address); err != nil {
|
||||
logrus.Error(err)
|
||||
return 1
|
||||
|
|
|
@ -19,6 +19,7 @@ type SkinProxyCMD struct {
|
|||
server_address string
|
||||
filter string
|
||||
only_with_geometry bool
|
||||
pathCustomUserData string
|
||||
}
|
||||
|
||||
func (*SkinProxyCMD) Name() string { return "skins-proxy" }
|
||||
|
@ -28,6 +29,7 @@ func (c *SkinProxyCMD) SetFlags(f *flag.FlagSet) {
|
|||
f.StringVar(&c.server_address, "address", "", locale.Loc("remote_address", nil))
|
||||
f.StringVar(&c.filter, "filter", "", locale.Loc("name_prefix", nil))
|
||||
f.BoolVar(&c.only_with_geometry, "only-geom", false, locale.Loc("only_with_geometry", nil))
|
||||
f.StringVar(&c.pathCustomUserData, "userdata", "", locale.Loc("custom_user_data", nil))
|
||||
}
|
||||
|
||||
func (c *SkinProxyCMD) Usage() string {
|
||||
|
@ -41,7 +43,11 @@ func (c *SkinProxyCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interf
|
|||
return 1
|
||||
}
|
||||
|
||||
proxy := utils.NewProxy()
|
||||
proxy, err := utils.NewProxy(c.pathCustomUserData)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return 1
|
||||
}
|
||||
|
||||
s := NewSkinsSession(proxy, hostname)
|
||||
s.OnlyIfHasGeometry = c.only_with_geometry
|
||||
|
|
|
@ -143,7 +143,7 @@ func (c *SkinCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}
|
|||
return 1
|
||||
}
|
||||
|
||||
proxy := utils.NewProxy()
|
||||
proxy, _ := utils.NewProxy("")
|
||||
proxy.WithClient = false
|
||||
proxy.ConnectCB = func(proxy *utils.ProxyContext) {
|
||||
logrus.Info(locale.Loc("ctrl_c_to_exit", nil))
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
"golang.design/x/lockfree"
|
||||
|
||||
|
@ -254,6 +255,13 @@ func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk) {
|
|||
m.SchedRedraw()
|
||||
}
|
||||
|
||||
func (w *WorldState) ProcessAnimate(pk *packet.Animate) {
|
||||
if pk.ActionType == packet.AnimateActionSwingArm {
|
||||
w.ui.ChangeZoom()
|
||||
w.proxy.SendPopup(locale.Loc("zoom_level", locale.Strmap{"Level": w.ui.zoomLevel}))
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WorldState) processMapPacketsClient(pk packet.Packet, forward *bool) packet.Packet {
|
||||
switch pk := pk.(type) {
|
||||
case *packet.MovePlayer:
|
||||
|
|
|
@ -60,14 +60,20 @@ type WorldState struct {
|
|||
ispre118 bool
|
||||
|
||||
// settings
|
||||
voidgen bool
|
||||
voidGen bool
|
||||
withPacks bool
|
||||
saveImage bool
|
||||
experimentInventory bool
|
||||
}
|
||||
|
||||
func NewWorldState() *WorldState {
|
||||
func NewWorldState(ctx context.Context, proxy *utils.ProxyContext, ServerName string) *WorldState {
|
||||
w := &WorldState{
|
||||
ctx: ctx,
|
||||
proxy: proxy,
|
||||
ui: nil,
|
||||
bp: behaviourpack.New(ServerName),
|
||||
ServerName: ServerName,
|
||||
|
||||
chunks: make(map[protocol.ChunkPos]*chunk.Chunk),
|
||||
blockNBT: make(map[protocol.SubChunkPos][]map[string]any),
|
||||
openItemContainers: make(map[byte]*itemContainer),
|
||||
|
@ -111,6 +117,7 @@ type WorldCMD struct {
|
|||
enableVoid bool
|
||||
saveImage bool
|
||||
experimentInventory bool
|
||||
pathCustomUserData string
|
||||
}
|
||||
|
||||
func (*WorldCMD) Name() string { return "worlds" }
|
||||
|
@ -122,6 +129,7 @@ func (c *WorldCMD) SetFlags(f *flag.FlagSet) {
|
|||
f.BoolVar(&c.enableVoid, "void", true, locale.Loc("enable_void", nil))
|
||||
f.BoolVar(&c.saveImage, "image", false, locale.Loc("save_image", nil))
|
||||
f.BoolVar(&c.experimentInventory, "inv", false, locale.Loc("test_block_inv", nil))
|
||||
f.StringVar(&c.pathCustomUserData, "userdata", "", locale.Loc("custom_user_data", nil))
|
||||
}
|
||||
|
||||
func (c *WorldCMD) Usage() string {
|
||||
|
@ -135,16 +143,18 @@ func (c *WorldCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{
|
|||
return 1
|
||||
}
|
||||
|
||||
w := NewWorldState()
|
||||
w.voidgen = c.enableVoid
|
||||
w.ServerName = hostname
|
||||
proxy, err := utils.NewProxy(c.pathCustomUserData)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return 1
|
||||
}
|
||||
|
||||
w := NewWorldState(ctx, proxy, hostname)
|
||||
w.voidGen = c.enableVoid
|
||||
w.withPacks = c.packs
|
||||
w.saveImage = c.saveImage
|
||||
w.experimentInventory = c.experimentInventory
|
||||
w.ctx = ctx
|
||||
w.bp = behaviourpack.New(w.ServerName)
|
||||
|
||||
proxy := utils.NewProxy()
|
||||
proxy.AlwaysGetPacks = true
|
||||
proxy.ConnectCB = w.OnConnect
|
||||
proxy.PacketCB = func(pk packet.Packet, proxy *utils.ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) {
|
||||
|
@ -167,7 +177,7 @@ func (c *WorldCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{
|
|||
return pk, nil
|
||||
}
|
||||
|
||||
err = proxy.Run(ctx, serverAddress)
|
||||
err = w.proxy.Run(ctx, serverAddress)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
} else {
|
||||
|
@ -176,13 +186,6 @@ func (c *WorldCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{
|
|||
return 0
|
||||
}
|
||||
|
||||
func (w *WorldState) ProcessAnimate(pk *packet.Animate) {
|
||||
if pk.ActionType == packet.AnimateActionSwingArm {
|
||||
w.ui.ChangeZoom()
|
||||
w.proxy.SendPopup(locale.Loc("zoom_level", locale.Strmap{"Level": w.ui.zoomLevel}))
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WorldState) SetPlayerPos(Position mgl32.Vec3, Pitch, Yaw, HeadYaw float32) {
|
||||
last := w.PlayerPos
|
||||
w.PlayerPos = TPlayerPos{
|
||||
|
@ -336,7 +339,7 @@ func (w *WorldState) SaveAndReset() {
|
|||
ld.RandomSeed = int64(gd.WorldSeed)
|
||||
|
||||
// void world
|
||||
if w.voidgen {
|
||||
if w.voidGen {
|
||||
ld.FlatWorldLayers = `{"biome_id":1,"block_layers":[{"block_data":0,"block_id":0,"count":1},{"block_data":0,"block_id":0,"count":2},{"block_data":0,"block_id":0,"count":1}],"encoding_version":3,"structure_options":null}`
|
||||
ld.Generator = 2
|
||||
}
|
||||
|
@ -508,9 +511,9 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext) {
|
|||
|
||||
proxy.AddCommand(utils.IngameCommand{
|
||||
Exec: func(cmdline []string) bool {
|
||||
w.voidgen = !w.voidgen
|
||||
w.voidGen = !w.voidGen
|
||||
var s string
|
||||
if w.voidgen {
|
||||
if w.voidGen {
|
||||
s = locale.Loc("void_generator_true", nil)
|
||||
} else {
|
||||
s = locale.Loc("void_generator_false", nil)
|
||||
|
|
|
@ -2,6 +2,7 @@ package utils
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
|
@ -33,10 +34,15 @@ func GetTokenSource() oauth2.TokenSource {
|
|||
return gTokenSrc
|
||||
}
|
||||
|
||||
var RealmsEnv string
|
||||
|
||||
var gRealmsAPI *realms.Client
|
||||
|
||||
func GetRealmsAPI() *realms.Client {
|
||||
if gRealmsAPI == nil {
|
||||
if RealmsEnv != "" {
|
||||
realms.RealmsAPIBase = fmt.Sprintf("https://pocket-%s.realms.minecraft.net/", RealmsEnv)
|
||||
}
|
||||
gRealmsAPI = realms.NewClient(GetTokenSource())
|
||||
}
|
||||
return gRealmsAPI
|
||||
|
|
|
@ -3,6 +3,8 @@ package utils
|
|||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"os"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -14,6 +16,18 @@ func Img2rgba(img *image.RGBA) []color.RGBA {
|
|||
return *(*[]color.RGBA)(unsafe.Pointer(&header))
|
||||
}
|
||||
|
||||
func loadPng(path string) (*image.RGBA, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
img, err := png.Decode(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return (*image.RGBA)(img.(*image.NRGBA)), err
|
||||
}
|
||||
|
||||
// LERP is a linear interpolation function
|
||||
func LERP(p1, p2, alpha float64) float64 {
|
||||
return (1-alpha)*p1 + alpha*p2
|
||||
|
|
157
utils/proxy.go
157
utils/proxy.go
|
@ -2,9 +2,12 @@ package utils
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -20,29 +23,24 @@ import (
|
|||
|
||||
var DisconnectReason = "Connection lost"
|
||||
|
||||
type dummyProto struct {
|
||||
id int32
|
||||
ver string
|
||||
}
|
||||
|
||||
func (p dummyProto) ID() int32 { return p.id }
|
||||
func (p dummyProto) Ver() string { return p.ver }
|
||||
func (p dummyProto) Packets() packet.Pool { return packet.NewPool() }
|
||||
func (p dummyProto) ConvertToLatest(pk packet.Packet, _ *minecraft.Conn) []packet.Packet {
|
||||
return []packet.Packet{pk}
|
||||
}
|
||||
|
||||
func (p dummyProto) ConvertFromLatest(pk packet.Packet, _ *minecraft.Conn) []packet.Packet {
|
||||
return []packet.Packet{pk}
|
||||
}
|
||||
type (
|
||||
PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr)
|
||||
PacketCallback func(pk packet.Packet, proxy *ProxyContext, toServer bool, timeReceived time.Time) (packet.Packet, error)
|
||||
ConnectCallback func(proxy *ProxyContext)
|
||||
IngameCommand struct {
|
||||
Exec func(cmdline []string) bool
|
||||
Cmd protocol.Command
|
||||
}
|
||||
)
|
||||
|
||||
type ProxyContext struct {
|
||||
Server *minecraft.Conn
|
||||
Client *minecraft.Conn
|
||||
Listener *minecraft.Listener
|
||||
commands map[string]IngameCommand
|
||||
AlwaysGetPacks bool
|
||||
WithClient bool
|
||||
Server *minecraft.Conn
|
||||
Client *minecraft.Conn
|
||||
Listener *minecraft.Listener
|
||||
commands map[string]IngameCommand
|
||||
AlwaysGetPacks bool
|
||||
WithClient bool
|
||||
CustomClientData *login.ClientData
|
||||
|
||||
// called for every packet
|
||||
PacketFunc PacketFunc
|
||||
|
@ -52,11 +50,88 @@ type ProxyContext struct {
|
|||
PacketCB PacketCallback
|
||||
}
|
||||
|
||||
type (
|
||||
PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr)
|
||||
PacketCallback func(pk packet.Packet, proxy *ProxyContext, toServer bool, timeReceived time.Time) (packet.Packet, error)
|
||||
ConnectCallback func(proxy *ProxyContext)
|
||||
)
|
||||
func NewProxy(pathCustomData string) (*ProxyContext, error) {
|
||||
p := &ProxyContext{
|
||||
commands: make(map[string]IngameCommand),
|
||||
WithClient: true,
|
||||
}
|
||||
if pathCustomData != "" {
|
||||
if err := p.LoadCustomUserData(pathCustomData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *ProxyContext) AddCommand(cmd IngameCommand) {
|
||||
p.commands[cmd.Cmd.Name] = cmd
|
||||
}
|
||||
|
||||
type CustomClientData struct {
|
||||
// skin things
|
||||
CapeFilename string
|
||||
SkinFilename string
|
||||
SkinGeometryFilename string
|
||||
PlayFabID string
|
||||
PersonaSkin bool
|
||||
PremiumSkin bool
|
||||
TrustedSkin bool
|
||||
ArmSize string
|
||||
|
||||
// misc
|
||||
IsEditorMode bool
|
||||
LanguageCode string
|
||||
}
|
||||
|
||||
func (p *ProxyContext) LoadCustomUserData(path string) error {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var customData CustomClientData
|
||||
err = json.NewDecoder(f).Decode(&customData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.CustomClientData = &login.ClientData{
|
||||
PlayFabID: customData.PlayFabID,
|
||||
PersonaSkin: customData.PersonaSkin,
|
||||
PremiumSkin: customData.PremiumSkin,
|
||||
TrustedSkin: customData.TrustedSkin,
|
||||
ArmSize: customData.ArmSize,
|
||||
}
|
||||
|
||||
if customData.SkinFilename != "" {
|
||||
img, err := loadPng(customData.SkinFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.CustomClientData.SkinData = base64.RawStdEncoding.EncodeToString(img.Pix)
|
||||
p.CustomClientData.SkinImageWidth = img.Rect.Dx()
|
||||
p.CustomClientData.SkinImageHeight = img.Rect.Dy()
|
||||
}
|
||||
|
||||
if customData.CapeFilename != "" {
|
||||
img, err := loadPng(customData.CapeFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.CustomClientData.CapeData = base64.RawStdEncoding.EncodeToString(img.Pix)
|
||||
p.CustomClientData.CapeImageWidth = img.Rect.Dx()
|
||||
p.CustomClientData.CapeImageHeight = img.Rect.Dy()
|
||||
}
|
||||
|
||||
if customData.SkinGeometryFilename != "" {
|
||||
data, err := os.ReadFile(customData.SkinGeometryFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.CustomClientData.SkinGeometry = base64.RawStdEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProxyContext) SendMessage(text string) {
|
||||
if p.Client != nil {
|
||||
|
@ -76,15 +151,6 @@ func (p *ProxyContext) SendPopup(text string) {
|
|||
}
|
||||
}
|
||||
|
||||
type IngameCommand struct {
|
||||
Exec func(cmdline []string) bool
|
||||
Cmd protocol.Command
|
||||
}
|
||||
|
||||
func (p *ProxyContext) AddCommand(cmd IngameCommand) {
|
||||
p.commands[cmd.Cmd.Name] = cmd
|
||||
}
|
||||
|
||||
func (p *ProxyContext) CommandHandlerPacketCB(pk packet.Packet, proxy *ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) {
|
||||
switch _pk := pk.(type) {
|
||||
case *packet.CommandRequest:
|
||||
|
@ -146,13 +212,6 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool, packetCBs [
|
|||
}
|
||||
}
|
||||
|
||||
func NewProxy() *ProxyContext {
|
||||
return &ProxyContext{
|
||||
commands: make(map[string]IngameCommand),
|
||||
WithClient: true,
|
||||
}
|
||||
}
|
||||
|
||||
var ClientAddr net.Addr
|
||||
|
||||
func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error) {
|
||||
|
@ -182,9 +241,6 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error
|
|||
p.Listener, err = minecraft.ListenConfig{
|
||||
StatusProvider: _status,
|
||||
ResourcePacks: packs,
|
||||
AcceptedProtocols: []minecraft.Protocol{
|
||||
dummyProto{id: 544, ver: "1.19.20"},
|
||||
},
|
||||
}.Listen("raknet", ":19132")
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -208,6 +264,11 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error
|
|||
cd := p.Client.ClientData()
|
||||
cdp = &cd
|
||||
}
|
||||
|
||||
if p.CustomClientData != nil {
|
||||
cdp = p.CustomClientData
|
||||
}
|
||||
|
||||
p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, p.PacketFunc)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(locale.Loc("failed_to_connect", locale.Strmap{"Address": serverAddress, "Err": err}))
|
||||
|
@ -229,9 +290,9 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error
|
|||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
cbs := []PacketCallback{
|
||||
p.CommandHandlerPacketCB,
|
||||
}
|
||||
|
||||
var cbs []PacketCallback
|
||||
cbs = append(cbs, p.CommandHandlerPacketCB)
|
||||
if p.PacketCB != nil {
|
||||
cbs = append(cbs, p.PacketCB)
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ func createReplayConnection(ctx context.Context, filename string, onConnect Conn
|
|||
f.Seek(-4, io.SeekCurrent)
|
||||
}
|
||||
|
||||
proxy := NewProxy()
|
||||
proxy, _ := NewProxy("")
|
||||
proxy.Server = minecraft.NewConn()
|
||||
|
||||
gameStarted := false
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue