Compare commits
18 Commits
e13856a4ff
...
c0b14f3dd9
Author | SHA1 | Date |
---|---|---|
olebeck | c0b14f3dd9 | |
olebeck | 39be9c678b | |
olebeck | f3d1a80985 | |
olebeck | 3455793b8a | |
olebeck | d3dc870a8a | |
olebeck | bf0197dbc4 | |
olebeck | 6d95fdd1b3 | |
olebeck | 4d27ac0e47 | |
olebeck | 4e625223a7 | |
olebeck | d29f246921 | |
olebeck | eecbecd8fe | |
olebeck | 920c639866 | |
olebeck | f769573900 | |
olebeck | ef1b2b7025 | |
olebeck | fd02dd5d16 | |
olebeck | a18548ffc2 | |
olebeck | 405bb64850 | |
olebeck | f2c45d379d |
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime/debug"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
"gopkg.in/square/go-jose.v2/json"
|
||||
|
||||
|
@ -30,9 +32,31 @@ type CLI struct {
|
|||
|
||||
func (c *CLI) Init() bool {
|
||||
utils.SetCurrentUI(c)
|
||||
utils.Auth.LoginWithMicrosoftCallback = func(r io.Reader) {
|
||||
io.Copy(os.Stdout, r)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
var m = &worlds.Map{}
|
||||
|
||||
func (c *CLI) Message(data interface{}) messages.MessageResponse {
|
||||
|
||||
switch me := data.(type) {
|
||||
case messages.CanShowImages:
|
||||
return messages.MessageResponse{Ok: true}
|
||||
case messages.UpdateMap:
|
||||
m.Update(&me)
|
||||
}
|
||||
|
||||
return messages.MessageResponse{
|
||||
Ok: false,
|
||||
Data: nil,
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func (c *CLI) Start(ctx context.Context, cancel context.CancelFunc) error {
|
||||
flag.Parse()
|
||||
subcommands.Execute(ctx)
|
||||
|
@ -80,17 +104,6 @@ func main() {
|
|||
logrus.Infof(locale.Loc("bedrocktool_version", locale.Strmap{"Version": utils.Version}))
|
||||
}
|
||||
|
||||
go func() {
|
||||
newVersion, err := utils.Updater.UpdateAvailable()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
if newVersion != "" && utils.Version != "" {
|
||||
logrus.Infof(locale.Loc("update_available", locale.Strmap{"Version": newVersion}))
|
||||
}
|
||||
}()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
flag.StringVar(&utils.RealmsEnv, "realms-env", "", "realms env")
|
||||
|
@ -116,6 +129,23 @@ func main() {
|
|||
ui = &CLI{}
|
||||
}
|
||||
|
||||
utils.CurrentUI = ui
|
||||
|
||||
if utils.Version != "" {
|
||||
go func() {
|
||||
newVersion, err := utils.Updater.UpdateAvailable()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
|
||||
if newVersion != "" {
|
||||
logrus.Infof(locale.Loc("update_available", locale.Strmap{"Version": newVersion}))
|
||||
utils.UpdateAvailable = newVersion
|
||||
ui.Message(messages.UpdateAvailable{Version: newVersion})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// exit cleanup
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
@ -155,7 +185,7 @@ func (c *TransCMD) Execute(_ context.Context, ui utils.UI) error {
|
|||
Reset = "\033[0m"
|
||||
)
|
||||
if c.auth {
|
||||
utils.GetTokenSource()
|
||||
utils.Auth.GetTokenSource()
|
||||
}
|
||||
fmt.Println(BlackFg + Bold + Blue + " Trans " + Pink + " Rights " + White + " Are " + Pink + " Human " + Blue + " Rights " + Reset)
|
||||
return nil
|
||||
|
|
70
go.mod
70
go.mod
|
@ -3,45 +3,47 @@ module github.com/bedrock-tool/bedrocktool
|
|||
go 1.20
|
||||
|
||||
//replace github.com/sandertv/gophertunnel => ./gophertunnel
|
||||
replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.29.0-1
|
||||
replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.30.0-3
|
||||
|
||||
//replace github.com/df-mc/dragonfly => ./dragonfly
|
||||
replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.4-13
|
||||
replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.6-2
|
||||
|
||||
//replace gioui.org => ./gio
|
||||
replace gioui.org => github.com/olebeck/gio v0.0.0-20230427194143-c9c9d8bc704d
|
||||
replace gioui.org => github.com/olebeck/gio v0.0.0-20230607184051-9ab60b08f083
|
||||
|
||||
require (
|
||||
gioui.org v0.0.0-20230427133431-816bda7ac7bd
|
||||
gioui.org/x v0.0.0-20230426160849-752f112c7a59
|
||||
gioui.org v0.0.0-20230526230622-e3ef98dda382
|
||||
gioui.org/x v0.0.0-20230523210033-8432ec5563bb
|
||||
github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||
github.com/df-mc/dragonfly v0.9.4
|
||||
github.com/df-mc/dragonfly v0.9.6
|
||||
github.com/df-mc/goleveldb v1.1.9
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/flytam/filenamify v1.1.2
|
||||
github.com/flytam/filenamify v1.1.3
|
||||
github.com/go-gl/mathgl v1.0.0
|
||||
github.com/google/subcommands v1.2.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/jinzhu/copier v0.3.5
|
||||
github.com/miekg/dns v1.1.53
|
||||
github.com/miekg/dns v1.1.54
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.1
|
||||
github.com/repeale/fp-go v0.11.1
|
||||
github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49
|
||||
github.com/sandertv/go-raknet v1.12.0
|
||||
github.com/sandertv/gophertunnel v1.29.0
|
||||
github.com/shirou/gopsutil/v3 v3.23.3
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/sandertv/gophertunnel v1.30.0
|
||||
github.com/shirou/gopsutil/v3 v3.23.5
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
golang.design/x/lockfree v0.0.1
|
||||
golang.org/x/crypto v0.8.0
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
|
||||
golang.org/x/oauth2 v0.7.0
|
||||
golang.org/x/crypto v0.9.0
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
|
||||
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1
|
||||
golang.org/x/oauth2 v0.8.0
|
||||
golang.org/x/term v0.8.0
|
||||
golang.org/x/text v0.9.0
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 // indirect
|
||||
gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7 // indirect
|
||||
gioui.org/shader v1.0.6 // indirect
|
||||
git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0 // indirect
|
||||
github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 // indirect
|
||||
|
@ -49,33 +51,33 @@ require (
|
|||
github.com/changkun/lockfree v0.0.1 // indirect
|
||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 // indirect
|
||||
github.com/df-mc/atomic v1.10.0 // indirect
|
||||
github.com/df-mc/worldupgrader v1.0.3 // indirect
|
||||
github.com/dlclark/regexp2 v1.9.0 // indirect
|
||||
github.com/df-mc/worldupgrader v1.0.7 // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-text/typesetting v0.0.0-20230413204129-b4f0492bf7ae // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/go-text/typesetting v0.0.0-20230606200221-26abc51a6c27 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/klauspost/compress v1.15.15 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/kr/binarydist v0.1.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.4 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/segmentio/fasthash v1.0.3 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/image v0.7.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/tools v0.9.3 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa // indirect
|
||||
)
|
||||
|
|
141
go.sum
141
go.sum
|
@ -1,11 +1,11 @@
|
|||
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY=
|
||||
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc=
|
||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
||||
gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7 h1:tNJdnP5CgM39PRc+KWmBRRYX/zJ+rd5XaYxY5d5veqA=
|
||||
gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
||||
gioui.org/shader v1.0.6 h1:cvZmU+eODFR2545X+/8XucgZdTtEjR3QWW6W65b0q5Y=
|
||||
gioui.org/shader v1.0.6/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM=
|
||||
gioui.org/x v0.0.0-20230426160849-752f112c7a59 h1:IdvHx1hSmuL9xs/p3rppWJnH01RXcBhz5HvB7pj9LAg=
|
||||
gioui.org/x v0.0.0-20230426160849-752f112c7a59/go.mod h1:nMctdnZS2HKxfSXb+bCPnhw1n2LLsXoxtTarZjtIBuI=
|
||||
gioui.org/x v0.0.0-20230523210033-8432ec5563bb h1:VnqXLYSd8UsVh6hrJJi6HjYl8Ow+iyDQTnwdKTp6lvY=
|
||||
gioui.org/x v0.0.0-20230523210033-8432ec5563bb/go.mod h1:nMctdnZS2HKxfSXb+bCPnhw1n2LLsXoxtTarZjtIBuI=
|
||||
git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0 h1:bGG/g4ypjrCJoSvFrP5hafr9PPB5aw8SjcOWWila7ZI=
|
||||
git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo=
|
||||
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
|
||||
|
@ -29,27 +29,27 @@ github.com/df-mc/atomic v1.10.0 h1:0ZuxBKwR/hxcFGorKiHIp+hY7hgY+XBTzhCYD2NqSEg=
|
|||
github.com/df-mc/atomic v1.10.0/go.mod h1:Gw9rf+rPIbydMjA329Jn4yjd/O2c/qusw3iNp4tFGSc=
|
||||
github.com/df-mc/goleveldb v1.1.9 h1:ihdosZyy5jkQKrxucTQmN90jq/2lUwQnJZjIYIC/9YU=
|
||||
github.com/df-mc/goleveldb v1.1.9/go.mod h1:+NHCup03Sci5q84APIA21z3iPZCuk6m6ABtg4nANCSk=
|
||||
github.com/df-mc/worldupgrader v1.0.3 h1:3nbthy6vfSNQZdqHBR+E5Fh3mCeWmCwLtqrYDiPUG5I=
|
||||
github.com/df-mc/worldupgrader v1.0.3/go.mod h1:6ybkJ/BV9b0XkcPzcLmvgT9Nv/xgBXdDQTmRhu7b8zQ=
|
||||
github.com/dlclark/regexp2 v1.9.0 h1:pTK/l/3qYIKaRXuHnEnIf7Y5NxfRPfpb7dis6/gdlVI=
|
||||
github.com/dlclark/regexp2 v1.9.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/df-mc/worldupgrader v1.0.7 h1:t9kIiwZy8usH+H6TIkP3fvhIdDb+HRdQ3L/sEr2++Mc=
|
||||
github.com/df-mc/worldupgrader v1.0.7/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
|
||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/flytam/filenamify v1.1.2 h1:dGlfWU4zrhDlsmvob4IFcfgjG5vIjfo4UwLyec6Wx94=
|
||||
github.com/flytam/filenamify v1.1.2/go.mod h1:Dzf9kVycwcsBlr2ATg6uxjqiFgKGH+5SKFuhdeP5zu8=
|
||||
github.com/flytam/filenamify v1.1.3 h1:9k2R19mB/Nn5IrdozfiX4mnMW1WGXCF9KRD+25eDkv8=
|
||||
github.com/flytam/filenamify v1.1.3/go.mod h1:Dzf9kVycwcsBlr2ATg6uxjqiFgKGH+5SKFuhdeP5zu8=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-gl/mathgl v1.0.0 h1:t9DznWJlXxxjeeKLIdovCOVJQk/GzDEL7h/h+Ro2B68=
|
||||
github.com/go-gl/mathgl v1.0.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-text/typesetting v0.0.0-20230413204129-b4f0492bf7ae h1:LCcaQgYrnS+sx9Tc3oGUvbRBRt+5oFnKWakaxeAvNVI=
|
||||
github.com/go-text/typesetting v0.0.0-20230413204129-b4f0492bf7ae/go.mod h1:KmrpWuSMFcO2yjmyhGpnBGQHSKAoEgMTSSzvLDzCuEA=
|
||||
github.com/go-text/typesetting v0.0.0-20230606200221-26abc51a6c27 h1:eIFR7h3qIaR3W3EbpMwWY8d9yk2L/oQVNtMlxhpWtyc=
|
||||
github.com/go-text/typesetting v0.0.0-20230606200221-26abc51a6c27/go.mod h1:KmrpWuSMFcO2yjmyhGpnBGQHSKAoEgMTSSzvLDzCuEA=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20230412163830-89e4bcfa3ecc h1:9Kf84pnrmmjdRzZIkomfjowmGUhHs20jkrWYw/I6CYc=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
|
@ -68,29 +68,38 @@ github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S
|
|||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/binarydist v0.1.0 h1:6kAoLA9FMMnNGSehX0s1PdjbEaACznAv/W219j2uvyo=
|
||||
github.com/kr/binarydist v0.1.0/go.mod h1:DY7S//GCoz1BCd0B0EVrinCKAZN3pXe+MDaIZbXQVgM=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
|
||||
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
|
||||
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
|
||||
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
github.com/muhammadmuzzammil1998/jsonc v1.0.0 h1:8o5gBQn4ZA3NBA9DlTujCj2a4w0tqWrPVjDwhzkgTIs=
|
||||
github.com/muhammadmuzzammil1998/jsonc v1.0.0/go.mod h1:saF2fIVw4banK0H4+/EuqfFLpRnoy5S+ECwTOCcRcSU=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0=
|
||||
github.com/olebeck/dragonfly v0.9.4-13 h1:JF72hfG3/BBCXU1GSBaEKKXQy/gt+0mEOua3RdKXdJ8=
|
||||
github.com/olebeck/dragonfly v0.9.4-13/go.mod h1:ZNcbAATEeTNyN3Cumtwzox7STtFve469HHzL5c1K3nY=
|
||||
github.com/olebeck/gio v0.0.0-20230427194143-c9c9d8bc704d h1:D+Ryca52xv37/p0FsEWfGwAGUZ1vPWpvimA2eMfBijc=
|
||||
github.com/olebeck/gio v0.0.0-20230427194143-c9c9d8bc704d/go.mod h1:8CFQM/4LurRd9G3NUYdacFb9j2pK0LrAyVO2mAZo4mw=
|
||||
github.com/olebeck/gophertunnel v1.29.0-1 h1:3x2cZoe8O54xVFgEZqTBJpFEXlzbjlLFoo/d9cWGv+g=
|
||||
github.com/olebeck/gophertunnel v1.29.0-1/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
||||
github.com/olebeck/dragonfly v0.9.6-2 h1:q4+5qGQ40nt9zy+/ooJKm0UyvklskjkVKKiZos1SY68=
|
||||
github.com/olebeck/dragonfly v0.9.6-2/go.mod h1:/KIJwvuamZQsEcly1Eu6gDIfyAAmtC30pYWRnMYVzno=
|
||||
github.com/olebeck/gio v0.0.0-20230607184051-9ab60b08f083 h1:ZnL97gNzNlVxNj7X3fhBqi70OALUVRbw1qw97vpYyso=
|
||||
github.com/olebeck/gio v0.0.0-20230607184051-9ab60b08f083/go.mod h1:8CFQM/4LurRd9G3NUYdacFb9j2pK0LrAyVO2mAZo4mw=
|
||||
github.com/olebeck/gophertunnel v1.30.0-1 h1:GUI2WX48cJKK/UcTLSIRU1O+nG6iURV8/l2KS8GsMsk=
|
||||
github.com/olebeck/gophertunnel v1.30.0-1/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
||||
github.com/olebeck/gophertunnel v1.30.0-2 h1:JbkADJTfpCfC7nL9O08LON0k8OBahfmOdByN3dy/CQE=
|
||||
github.com/olebeck/gophertunnel v1.30.0-2/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
||||
github.com/olebeck/gophertunnel v1.30.0-3 h1:D3PP7ttzZWgyHmacVMiPslWsTj3UNeRvO1x+5kA97wE=
|
||||
github.com/olebeck/gophertunnel v1.30.0-3/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
||||
github.com/olebeck/gophertunnel v1.31.0-1 h1:MeBwKKFT9SAe8FoeAT8o53TgrkPRJL5uAxLqWY3at5A=
|
||||
github.com/olebeck/gophertunnel v1.31.0-1/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
||||
github.com/olebeck/gophertunnel v1.31.0-2 h1:m/rUr/gjMTs/pSS5jPKlSxBJlC1WVjnxu8MHrVWfdkc=
|
||||
github.com/olebeck/gophertunnel v1.31.0-2/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
||||
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=
|
||||
|
@ -98,24 +107,27 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
|||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/repeale/fp-go v0.11.1 h1:Q/e+gNyyHaxKAyfdbBqvip3DxhVWH453R+kthvSr9Mk=
|
||||
github.com/repeale/fp-go v0.11.1/go.mod h1:4KrwQJB1VRY+06CA+jTc4baZetr6o2PeuqnKr5ybQUc=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49 h1:LuxslTBxJrrNeKfqoywIERWWhH43TgiVAiPEVlhgNBA=
|
||||
github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49/go.mod h1:fY313ZGG810aWruFYcyq3coFpHDrWJVoMfSRI81y1r4=
|
||||
github.com/sandertv/go-raknet v1.12.0 h1:olUzZlIJyX/pgj/mrsLCZYjKLNDsYiWdvQ4NIm3z0DA=
|
||||
github.com/sandertv/go-raknet v1.12.0/go.mod h1:Gx+WgZBMQ0V2UoouGoJ8Wj6CDrMBQ4SB2F/ggpl5/+Y=
|
||||
github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE=
|
||||
github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU=
|
||||
github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVbozs=
|
||||
github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
|
||||
github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c=
|
||||
github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
|
||||
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
|
||||
github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y=
|
||||
github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -124,48 +136,50 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
golang.design/x/lockfree v0.0.1 h1:IHFNwZgM5bnZYWkEbzn5lWHMYr8WsRBdCJ/RBVY0xMM=
|
||||
golang.design/x/lockfree v0.0.1/go.mod h1:iaZUx6UgZaOdePjzI6wFd+seYMl1i0rsG8+xKvA8c4I=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91 h1:ryT6Nf0R83ZgD8WnFFdfI8wCeyqgdXWN4+CkFVNPAT0=
|
||||
golang.org/x/exp/shiny v0.0.0-20220827204233-334a2380cb91/go.mod h1:VjAR7z0ngyATZTELrBSkxOOHhhlnVUxDye4mcjx5h/8=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1 h1:NxHSRPlbeyFGDc6rU7YsvxV/4bXS9XhuvUt5pP63XUs=
|
||||
golang.org/x/exp/shiny v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0=
|
||||
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
|
||||
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
|
||||
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -179,11 +193,13 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -195,16 +211,17 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
|
||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
|
|
|
@ -46,7 +46,6 @@ var MutedPackets = []string{
|
|||
|
||||
var dirS2C = color.GreenString("S") + "->" + color.CyanString("C")
|
||||
var dirC2S = color.CyanString("C") + "->" + color.GreenString("S")
|
||||
var pool = packet.NewPool()
|
||||
|
||||
func NewDebugLogger(extraVerbose bool) *utils.ProxyHandler {
|
||||
var logPlain, logCrypt, logCryptEnc io.WriteCloser
|
||||
|
@ -71,13 +70,23 @@ func NewDebugLogger(extraVerbose bool) *utils.ProxyHandler {
|
|||
|
||||
var proxy *utils.ProxyContext
|
||||
|
||||
serverPool := packet.NewServerPool()
|
||||
clientPool := packet.NewClientPool()
|
||||
pool := make(packet.Pool)
|
||||
for k, v := range serverPool {
|
||||
pool[k] = v
|
||||
}
|
||||
for k, v := range clientPool {
|
||||
pool[k] = v
|
||||
}
|
||||
|
||||
return &utils.ProxyHandler{
|
||||
Name: "Debug",
|
||||
ProxyRef: func(pc *utils.ProxyContext) {
|
||||
proxy = pc
|
||||
},
|
||||
PacketFunc: func(header packet.Header, payload []byte, src, dst net.Addr) {
|
||||
pk := utils.DecodePacket(header, payload)
|
||||
pk := utils.DecodePacket(pool, header, payload)
|
||||
if pk == nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ func (s *secondaryUser) processLevelChunk(pk *packet.LevelChunk) {
|
|||
subChunkCount = int(pk.SubChunkCount)
|
||||
}
|
||||
|
||||
ch, blockNBTs, err := chunk.NetworkDecode(world.AirRID(), pk.RawPayload, subChunkCount, s.dimension.Range(), s.ispre118, s.hasCustomBlocks)
|
||||
ch, blockNBTs, err := chunk.NetworkDecode(world.AirRID(), pk.RawPayload, subChunkCount, s.ispre118, s.dimension.Range())
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package seconduser
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/df-mc/dragonfly/server/block/cube"
|
||||
"github.com/df-mc/dragonfly/server/world"
|
||||
"github.com/google/uuid"
|
||||
|
@ -14,7 +12,6 @@ type provider struct {
|
|||
|
||||
func (p *provider) Settings() *world.Settings {
|
||||
return &world.Settings{
|
||||
Mutex: sync.Mutex{},
|
||||
Name: "world",
|
||||
Spawn: cube.Pos{0, 0, 0},
|
||||
DefaultGameMode: world.GameModeCreative,
|
||||
|
|
|
@ -22,9 +22,7 @@ type secondaryUser struct {
|
|||
server *server.Server
|
||||
proxy *utils.ProxyContext
|
||||
|
||||
ispre118 bool
|
||||
hasCustomBlocks bool
|
||||
|
||||
ispre118 bool
|
||||
chunks map[world.ChunkPos]*chunk.Chunk
|
||||
blockNBTs map[protocol.BlockPos][]map[string]any
|
||||
dimension world.Dimension
|
||||
|
|
|
@ -37,7 +37,7 @@ func (w *worldsHandler) processLevelChunk(pk *packet.LevelChunk) {
|
|||
subChunkCount = int(pk.SubChunkCount)
|
||||
}
|
||||
|
||||
ch, blockNBTs, err := chunk.NetworkDecode(world.AirRID(), pk.RawPayload, subChunkCount, w.worldState.dimension.Range(), w.serverState.ispre118, w.bp.HasBlocks())
|
||||
ch, blockNBTs, err := chunk.NetworkDecode(world.AirRID(), pk.RawPayload, subChunkCount, w.serverState.ispre118, w.worldState.dimension.Range())
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 432 B |
|
@ -1,53 +0,0 @@
|
|||
package worlds_test
|
||||
|
||||
import (
|
||||
"image/png"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"testing"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
"github.com/df-mc/dragonfly/server/block/cube"
|
||||
"github.com/df-mc/dragonfly/server/world/chunk"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
data, _ := os.ReadFile("chunk.bin")
|
||||
ch, _, _ := chunk.NetworkDecode(33, data, 6, cube.Range{0, 255}, true, false)
|
||||
i := utils.Chunk2Img(ch)
|
||||
f, _ := os.Create("chunk.png")
|
||||
png.Encode(f, i)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
func Benchmark_chunk_decode(b *testing.B) {
|
||||
data, _ := os.ReadFile("chunk.bin")
|
||||
|
||||
cf, _ := os.Create("cpu.pprof")
|
||||
err := pprof.StartCPUProfile(cf)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _, err := chunk.NetworkDecode(33, data, 6, cube.Range{0, 255}, true, false)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
func Benchmark_render_chunk(b *testing.B) {
|
||||
data, _ := os.ReadFile("chunk.bin")
|
||||
ch, _, _ := chunk.NetworkDecode(33, data, 6, cube.Range{0, 255}, true, false)
|
||||
|
||||
cf, _ := os.Create("cpu.pprof")
|
||||
err := pprof.StartCPUProfile(cf)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
utils.Chunk2Img(ch)
|
||||
}
|
||||
pprof.StopCPUProfile()
|
||||
}
|
|
@ -205,14 +205,23 @@ func (s *entityState) ToServerEntity() serverEntity {
|
|||
}
|
||||
entityMetadataToNBT(s.Metadata, e.EntityType.NBT)
|
||||
|
||||
if s.Helmet != nil || s.Chestplate != nil || s.Leggings != nil || s.Boots != nil {
|
||||
e.EntityType.NBT["Armor"] = []map[string]any{
|
||||
nbtconv.WriteItem(stackToItem(s.Helmet.Stack), true),
|
||||
nbtconv.WriteItem(stackToItem(s.Chestplate.Stack), true),
|
||||
nbtconv.WriteItem(stackToItem(s.Leggings.Stack), true),
|
||||
nbtconv.WriteItem(stackToItem(s.Boots.Stack), true),
|
||||
if false {
|
||||
armor := make([]map[string]any, 4)
|
||||
if s.Helmet != nil {
|
||||
armor[0] = nbtconv.WriteItem(stackToItem(s.Helmet.Stack), true)
|
||||
}
|
||||
if s.Chestplate != nil {
|
||||
armor[1] = nbtconv.WriteItem(stackToItem(s.Chestplate.Stack), true)
|
||||
}
|
||||
if s.Leggings != nil {
|
||||
armor[2] = nbtconv.WriteItem(stackToItem(s.Leggings.Stack), true)
|
||||
}
|
||||
if s.Boots != nil {
|
||||
armor[3] = nbtconv.WriteItem(stackToItem(s.Boots.Stack), true)
|
||||
}
|
||||
e.EntityType.NBT["Armor"] = armor
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
|
||||
seconduser "github.com/bedrock-tool/bedrocktool/handlers/second-user"
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
)
|
||||
|
@ -31,7 +30,6 @@ func (c *DebugProxyCMD) Execute(ctx context.Context, ui utils.UI) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proxy.AddHandler(seconduser.NewSecondUser())
|
||||
return proxy.Run(ctx, address, hostname)
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -45,6 +45,10 @@ func (c *SkinCMD) Execute(ctx context.Context, ui utils.UI) error {
|
|||
OnClientConnect: func(conn minecraft.IConn) {
|
||||
ui.Message(messages.SetUIState(messages.UIStateConnecting))
|
||||
},
|
||||
OnServerConnect: func() (cancel bool) {
|
||||
ui.Message(messages.SetUIState(messages.UIStateMain))
|
||||
return false
|
||||
},
|
||||
})
|
||||
|
||||
if proxy.WithClient {
|
||||
|
|
|
@ -55,7 +55,6 @@ func (c *WorldCMD) Execute(ctx context.Context, ui utils.UI) error {
|
|||
SaveImage: c.SaveImage,
|
||||
}))
|
||||
|
||||
ui.Message(messages.SetUIState(messages.UIStateConnect))
|
||||
err = proxy.Run(ctx, serverAddress, hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
63
ui/gui.go
63
ui/gui.go
|
@ -1,10 +1,12 @@
|
|||
//go:build gui || android
|
||||
//go:build gui
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"image/color"
|
||||
"io"
|
||||
|
||||
"gioui.org/app"
|
||||
"gioui.org/font/gofont"
|
||||
|
@ -17,6 +19,7 @@ import (
|
|||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/packs"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/settings"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/skins"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/update"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages/worlds"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
|
@ -26,12 +29,14 @@ import (
|
|||
type GUI struct {
|
||||
utils.BaseUI
|
||||
|
||||
router pages.Router
|
||||
cancel context.CancelFunc
|
||||
router pages.Router
|
||||
cancel context.CancelFunc
|
||||
authPopup bool
|
||||
authPopupText string
|
||||
}
|
||||
|
||||
func (g *GUI) Init() bool {
|
||||
utils.SetCurrentUI(g)
|
||||
utils.Auth.LoginWithMicrosoftCallback = g.LoginWithMicrosoftCallback
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -53,7 +58,7 @@ func (g *GUI) Start(ctx context.Context, cancel context.CancelFunc) (err error)
|
|||
g.cancel = cancel
|
||||
|
||||
w := app.NewWindow(
|
||||
app.Title("Bedrocktool"),
|
||||
app.Title("Bedrocktool " + utils.Version),
|
||||
)
|
||||
|
||||
th := material.NewTheme(gofont.Collection())
|
||||
|
@ -70,25 +75,19 @@ func (g *GUI) Start(ctx context.Context, cancel context.CancelFunc) (err error)
|
|||
}
|
||||
|
||||
g.router = pages.NewRouter(ctx, w.Invalidate, th)
|
||||
|
||||
g.router.Register("Settings", settings.New(&g.router))
|
||||
g.router.Register("worlds", worlds.New(&g.router))
|
||||
g.router.Register("skins", skins.New(&g.router))
|
||||
g.router.Register("packs", packs.New(&g.router))
|
||||
g.router.Register("update", update.New(&g.router))
|
||||
|
||||
g.router.SwitchTo("Settings")
|
||||
|
||||
go func() {
|
||||
err = g.run(w)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
app.Main()
|
||||
}()
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
return err
|
||||
return g.run(w)
|
||||
}
|
||||
|
||||
func (g *GUI) run(w *app.Window) error {
|
||||
|
@ -104,7 +103,20 @@ func (g *GUI) run(w *app.Window) error {
|
|||
return e.Err
|
||||
case system.FrameEvent:
|
||||
gtx := layout.NewContext(&ops, e)
|
||||
g.router.Layout(gtx, g.router.Theme)
|
||||
layout.Stack{
|
||||
Alignment: layout.Center,
|
||||
}.Layout(gtx,
|
||||
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
|
||||
return g.router.Layout(gtx, g.router.Theme)
|
||||
}),
|
||||
layout.Stacked(func(gtx layout.Context) layout.Dimensions {
|
||||
if g.authPopup {
|
||||
return g.AuthPopup(gtx)
|
||||
}
|
||||
return layout.Dimensions{}
|
||||
}),
|
||||
)
|
||||
|
||||
e.Frame(gtx.Ops)
|
||||
}
|
||||
case <-g.router.Ctx.Done():
|
||||
|
@ -135,6 +147,29 @@ func (g *GUI) Message(data interface{}) messages.MessageResponse {
|
|||
return r
|
||||
}
|
||||
|
||||
func (g *GUI) AuthPopup(gtx layout.Context) layout.Dimensions {
|
||||
gtx.Constraints.Max = gtx.Constraints.Max.Div(2)
|
||||
return layout.Center.Layout(gtx, material.Body1(g.router.Theme, g.authPopupText).Layout)
|
||||
}
|
||||
|
||||
func (g *GUI) LoginWithMicrosoftCallback(r io.Reader) {
|
||||
g.authPopup = true
|
||||
b := bufio.NewReader(r)
|
||||
for {
|
||||
line, _, err := b.ReadLine()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
println(string(line))
|
||||
g.authPopupText += string(line) + "\n"
|
||||
g.router.Invalidate()
|
||||
if string(line) == "Authentication successful." {
|
||||
break
|
||||
}
|
||||
}
|
||||
g.authPopup = false
|
||||
}
|
||||
|
||||
func init() {
|
||||
utils.MakeGui = func() utils.UI {
|
||||
return &GUI{}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package icons
|
||||
|
||||
import (
|
||||
"gioui.org/widget"
|
||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||
)
|
||||
|
||||
func mustIcon(data []byte) widget.Icon {
|
||||
ic, err := widget.NewIcon(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return *ic
|
||||
}
|
||||
|
||||
var ActionUpdate = mustIcon(icons.ActionUpdate)
|
|
@ -96,7 +96,6 @@ func drawPackIcon(gtx C, hasImage bool, imageOp paint.ImageOp, bounds image.Poin
|
|||
}
|
||||
return D{Size: bounds}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func MulAlpha(c color.NRGBA, alpha uint8) color.NRGBA {
|
||||
|
@ -197,14 +196,12 @@ func (p *Page) layoutFinished(gtx C, th *material.Theme) D {
|
|||
}
|
||||
|
||||
func (p *Page) Layout(gtx C, th *material.Theme) D {
|
||||
margin := layout.Inset{
|
||||
return layout.Inset{
|
||||
Top: unit.Dp(25),
|
||||
Bottom: unit.Dp(25),
|
||||
Right: unit.Dp(35),
|
||||
Left: unit.Dp(35),
|
||||
}
|
||||
|
||||
return margin.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
switch p.State {
|
||||
case messages.UIStateConnecting:
|
||||
return layout.Center.Layout(gtx, material.Label(th, 100, "Connecting").Layout)
|
||||
|
|
|
@ -8,9 +8,12 @@ import (
|
|||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"gioui.org/x/component"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type HandlerFunc = func(data interface{}) messages.MessageResponse
|
||||
|
@ -39,6 +42,8 @@ type Router struct {
|
|||
*component.AppBar
|
||||
*component.ModalLayer
|
||||
NonModalDrawer, BottomBar bool
|
||||
|
||||
UpdateButton *widget.Clickable
|
||||
}
|
||||
|
||||
func NewRouter(ctx context.Context, invalidate func(), th *material.Theme) Router {
|
||||
|
@ -63,6 +68,8 @@ func NewRouter(ctx context.Context, invalidate func(), th *material.Theme) Route
|
|||
ModalNavDrawer: modalNav,
|
||||
AppBar: bar,
|
||||
NavAnim: na,
|
||||
|
||||
UpdateButton: &widget.Clickable{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +97,10 @@ func (r *Router) SwitchTo(tag string) {
|
|||
}
|
||||
|
||||
func (r *Router) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions {
|
||||
if r.UpdateButton.Clicked() {
|
||||
r.SwitchTo("update")
|
||||
}
|
||||
|
||||
for _, event := range r.AppBar.Events(gtx) {
|
||||
switch event := event.(type) {
|
||||
case component.AppBarNavigationClicked:
|
||||
|
@ -141,6 +152,18 @@ func (r *Router) Handler(data interface{}) messages.MessageResponse {
|
|||
return messages.MessageResponse{}
|
||||
}
|
||||
|
||||
func (r *Router) Execute(cmd utils.Command) {
|
||||
r.Wg.Add(1)
|
||||
go func() {
|
||||
defer r.Wg.Done()
|
||||
|
||||
err := cmd.Execute(r.Ctx, utils.CurrentUI)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
var Pages = map[string]func(*Router) Page{}
|
||||
|
||||
func Register(name string, fun func(*Router) Page) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"gioui.org/x/component"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/icons"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/settings"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||
|
@ -33,6 +34,8 @@ type Page struct {
|
|||
}
|
||||
|
||||
startButton widget.Clickable
|
||||
|
||||
actions []component.AppBarAction
|
||||
}
|
||||
|
||||
func New(router *pages.Router) *Page {
|
||||
|
@ -50,6 +53,10 @@ func New(router *pages.Router) *Page {
|
|||
p.cmdMenu.items = make(map[string]*widget.Clickable, len(utils.ValidCMDs))
|
||||
options := make([]func(layout.Context) layout.Dimensions, 0, len(utils.ValidCMDs))
|
||||
for _, name := range cmdNames {
|
||||
if _, ok := settings.Settings[name]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
item := &widget.Clickable{}
|
||||
p.cmdMenu.items[name] = item
|
||||
options = append(options, component.MenuItem(router.Theme, item, name).Layout)
|
||||
|
@ -70,7 +77,7 @@ func New(router *pages.Router) *Page {
|
|||
var _ pages.Page = &Page{}
|
||||
|
||||
func (p *Page) Actions() []component.AppBarAction {
|
||||
return []component.AppBarAction{}
|
||||
return p.actions
|
||||
}
|
||||
|
||||
func (p *Page) Overflow() []component.OverflowAction {
|
||||
|
@ -97,16 +104,7 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
|
|||
}
|
||||
|
||||
p.Router.SwitchTo(p.cmdMenu.selected)
|
||||
|
||||
p.Router.Wg.Add(1)
|
||||
go func() {
|
||||
defer p.Router.Wg.Done()
|
||||
|
||||
err := cmd.Execute(p.Router.Ctx, utils.CurrentUI)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
}()
|
||||
p.Router.Execute(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +171,17 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
|
|||
})
|
||||
}
|
||||
|
||||
func (p *Page) Handler(any) messages.MessageResponse {
|
||||
func (p *Page) Handler(m any) messages.MessageResponse {
|
||||
switch m.(type) {
|
||||
case messages.UpdateAvailable:
|
||||
p.actions = []component.AppBarAction{
|
||||
component.SimpleIconAction(p.Router.UpdateButton, &icons.ActionUpdate, component.OverflowAction{}),
|
||||
}
|
||||
|
||||
p.Router.AppBar.SetActions(p.actions, nil)
|
||||
p.Router.Invalidate()
|
||||
}
|
||||
|
||||
return messages.MessageResponse{
|
||||
Ok: false,
|
||||
Data: nil,
|
||||
|
|
|
@ -55,27 +55,24 @@ func (p *Page) NavItem() component.NavItem {
|
|||
}
|
||||
|
||||
func (p *Page) Layout(gtx C, th *material.Theme) D {
|
||||
margin := layout.Inset{
|
||||
return layout.Inset{
|
||||
Top: unit.Dp(25),
|
||||
Bottom: unit.Dp(25),
|
||||
Right: unit.Dp(35),
|
||||
Left: unit.Dp(35),
|
||||
}
|
||||
|
||||
switch p.State {
|
||||
case messages.UIStateConnect:
|
||||
// display login page
|
||||
return margin.Layout(gtx, material.Label(th, 100, "connect Client").Layout)
|
||||
case messages.UIStateConnecting:
|
||||
// display connecting to server
|
||||
return margin.Layout(gtx, material.Label(th, 100, "Connecting").Layout)
|
||||
case messages.UIStateMain:
|
||||
// show the main ui
|
||||
return margin.Layout(gtx, func(gtx C) D {
|
||||
}.Layout(gtx, func(gtx C) D {
|
||||
switch p.State {
|
||||
case messages.UIStateConnect:
|
||||
// display login page
|
||||
return material.Label(th, 100, "connect Client").Layout(gtx)
|
||||
case messages.UIStateConnecting:
|
||||
// display connecting to server
|
||||
return material.Label(th, 100, "Connecting").Layout(gtx)
|
||||
case messages.UIStateMain:
|
||||
// show the main ui
|
||||
return layout.Flex{
|
||||
Axis: layout.Vertical,
|
||||
}.Layout(gtx,
|
||||
layout.Rigid(material.Label(th, 20, "Skin Basic UI").Layout),
|
||||
layout.Flexed(1, func(gtx C) D {
|
||||
p.l.Lock()
|
||||
defer p.l.Unlock()
|
||||
|
@ -89,10 +86,9 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
|
|||
})
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return layout.Flex{}.Layout(gtx)
|
||||
}
|
||||
return D{}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Page) Handler(data interface{}) messages.MessageResponse {
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package update
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/unit"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"gioui.org/x/component"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/gui/pages"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
)
|
||||
|
||||
type (
|
||||
C = layout.Context
|
||||
D = layout.Dimensions
|
||||
)
|
||||
|
||||
type Page struct {
|
||||
*pages.Router
|
||||
|
||||
State messages.UIState
|
||||
startButton widget.Clickable
|
||||
err error
|
||||
updating bool
|
||||
}
|
||||
|
||||
func New(router *pages.Router) *Page {
|
||||
return &Page{
|
||||
Router: router,
|
||||
State: messages.UIStateMain,
|
||||
}
|
||||
}
|
||||
|
||||
var _ pages.Page = &Page{}
|
||||
|
||||
func (p *Page) Actions() []component.AppBarAction {
|
||||
return []component.AppBarAction{}
|
||||
}
|
||||
|
||||
func (p *Page) Overflow() []component.OverflowAction {
|
||||
return []component.OverflowAction{}
|
||||
}
|
||||
|
||||
func (p *Page) NavItem() component.NavItem {
|
||||
return component.NavItem{
|
||||
Name: "Update",
|
||||
//Icon: icon.OtherIcon,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Page) Layout(gtx C, th *material.Theme) D {
|
||||
if p.startButton.Clicked() && !p.updating {
|
||||
p.updating = true
|
||||
go func() {
|
||||
p.err = utils.Updater.Update()
|
||||
if p.err == nil {
|
||||
p.State = messages.UIStateFinished
|
||||
}
|
||||
p.updating = false
|
||||
p.Router.Invalidate()
|
||||
}()
|
||||
}
|
||||
|
||||
return layout.Inset{
|
||||
Top: unit.Dp(25),
|
||||
Bottom: unit.Dp(25),
|
||||
Right: unit.Dp(35),
|
||||
Left: unit.Dp(35),
|
||||
}.Layout(gtx, func(gtx C) D {
|
||||
if p.err != nil {
|
||||
return layout.Center.Layout(gtx, material.H1(th, p.err.Error()).Layout)
|
||||
}
|
||||
if p.updating {
|
||||
return layout.Center.Layout(gtx, material.H3(th, "Updating...").Layout)
|
||||
}
|
||||
switch p.State {
|
||||
case messages.UIStateMain:
|
||||
// show the main ui
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(material.Label(th, 20, fmt.Sprintf("Current: %s\nNew: %s", utils.Version, utils.UpdateAvailable)).Layout),
|
||||
layout.Rigid(material.Button(th, &p.startButton, "Do Update").Layout),
|
||||
)
|
||||
case messages.UIStateFinished:
|
||||
return layout.Center.Layout(gtx, func(gtx C) D {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(material.H3(th, "Update Finished").Layout),
|
||||
layout.Rigid(func(gtx C) D {
|
||||
return layout.Center.Layout(gtx, material.Label(th, th.TextSize, "restart the app").Layout)
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return D{}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Page) Handler(data interface{}) messages.MessageResponse {
|
||||
r := messages.MessageResponse{
|
||||
Ok: false,
|
||||
Data: nil,
|
||||
}
|
||||
return r
|
||||
}
|
|
@ -41,7 +41,7 @@ func (m *Map) HandlePointerEvent(e pointer.Event) {
|
|||
case pointer.Release:
|
||||
m.grabbed = false
|
||||
case pointer.Scroll:
|
||||
scaleFactor := -float32(math.Pow(1.01, float64(e.Scroll.Y)))
|
||||
scaleFactor := float32(math.Pow(1.01, float64(e.Scroll.Y)))
|
||||
m.transform = m.transform.Scale(e.Position.Sub(m.center), f32.Pt(scaleFactor, scaleFactor))
|
||||
m.scaleFactor *= scaleFactor
|
||||
}
|
||||
|
@ -122,8 +122,7 @@ func (m *Map) Update(u *messages.UpdateMap) {
|
|||
}
|
||||
} else {
|
||||
for _, pos := range u.UpdatedTiles {
|
||||
tile := u.Tiles[pos]
|
||||
drawTile(m.MapImage, m.BoundsMin, pos, tile)
|
||||
drawTile(m.MapImage, m.BoundsMin, pos, u.Tiles[pos])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,9 +91,7 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
|
|||
return layout.Center.Layout(gtx, material.Label(th, 100, "Connecting").Layout)
|
||||
case messages.UIStateMain:
|
||||
// show the main ui
|
||||
return layout.Flex{
|
||||
Axis: layout.Vertical,
|
||||
}.Layout(gtx,
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
//layout.Rigid(material.Label(th, th.TextSize, p.worldName).Layout),
|
||||
layout.Flexed(1, func(gtx C) D {
|
||||
return layout.Center.Layout(gtx, p.worldMap.Layout)
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"sync"
|
||||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/unit"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
"github.com/sandertv/gophertunnel/minecraft/realms"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type addressInput struct {
|
||||
Editor widget.Editor
|
||||
showRealmsList widget.Bool
|
||||
l sync.Mutex
|
||||
realmsList widget.List
|
||||
realms []realms.Realm
|
||||
realmsButtons map[int]*widget.Clickable
|
||||
loading bool
|
||||
}
|
||||
|
||||
var AddressInput = &addressInput{
|
||||
Editor: widget.Editor{
|
||||
SingleLine: true,
|
||||
},
|
||||
realmsList: widget.List{
|
||||
List: layout.List{
|
||||
Axis: layout.Vertical,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func (a *addressInput) Value() string {
|
||||
return a.Editor.Text()
|
||||
}
|
||||
|
||||
func (a *addressInput) getRealms() {
|
||||
var err error
|
||||
a.loading = true
|
||||
a.realms, err = utils.GetRealmsAPI().Realms(context.Background())
|
||||
a.realmsButtons = make(map[int]*widget.Clickable)
|
||||
for _, r := range a.realms {
|
||||
a.realmsButtons[r.ID] = &widget.Clickable{}
|
||||
}
|
||||
a.loading = false
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func MulAlpha(c color.NRGBA, alpha uint8) color.NRGBA {
|
||||
c.A = uint8(uint32(c.A) * uint32(alpha) / 0xFF)
|
||||
return c
|
||||
}
|
||||
|
||||
func (a *addressInput) Layout(th *material.Theme) layout.Widget {
|
||||
for k, c := range a.realmsButtons {
|
||||
if c.Clicked() {
|
||||
for _, r := range a.realms {
|
||||
if r.ID == k {
|
||||
a.Editor.SetText(fmt.Sprintf("realm:%s:%d", r.Name, r.ID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
e := material.Editor(th, &a.Editor, "server Address")
|
||||
return layout.UniformInset(5).Layout(gtx, e.Layout)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Width: unit.Dp(10)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical, Alignment: layout.Middle}.Layout(gtx,
|
||||
layout.Rigid(material.Label(th, th.TextSize, "list realms").Layout),
|
||||
layout.Rigid(material.Switch(th, &a.showRealmsList, "realms").Layout),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}),
|
||||
layout.Flexed(0.5, func(gtx layout.Context) layout.Dimensions {
|
||||
if a.loading {
|
||||
return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
gtx.Constraints.Max = image.Pt(20, 20)
|
||||
return material.Loader(th).Layout(gtx)
|
||||
})
|
||||
}
|
||||
|
||||
if a.showRealmsList.Value {
|
||||
if a.showRealmsList.Changed() {
|
||||
go a.getRealms()
|
||||
}
|
||||
a.l.Lock()
|
||||
defer a.l.Unlock()
|
||||
if len(a.realms) == 0 {
|
||||
return material.Label(th, th.TextSize, "you have no realms").Layout(gtx)
|
||||
}
|
||||
return material.List(th, &a.realmsList).Layout(gtx, len(a.realms), func(gtx layout.Context, index int) layout.Dimensions {
|
||||
entry := a.realms[index]
|
||||
return material.ButtonLayoutStyle{
|
||||
Background: MulAlpha(th.Palette.Bg, 0x60),
|
||||
Button: a.realmsButtons[entry.ID],
|
||||
CornerRadius: 3,
|
||||
}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.UniformInset(15).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||
layout.Rigid(material.Label(th, th.TextSize, entry.Name).Layout),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
return layout.Dimensions{}
|
||||
}),
|
||||
)
|
||||
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package settings
|
|||
|
||||
import (
|
||||
"gioui.org/layout"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"github.com/bedrock-tool/bedrocktool/subcommands"
|
||||
"github.com/bedrock-tool/bedrocktool/utils"
|
||||
|
@ -11,21 +10,21 @@ import (
|
|||
type packsSettings struct {
|
||||
packs *subcommands.ResourcePackCMD
|
||||
|
||||
serverAddress widget.Editor
|
||||
serverAddress *addressInput
|
||||
}
|
||||
|
||||
func (s *packsSettings) Init() {
|
||||
s.packs = utils.ValidCMDs["packs"].(*subcommands.ResourcePackCMD)
|
||||
s.serverAddress.SingleLine = true
|
||||
s.serverAddress = AddressInput
|
||||
}
|
||||
|
||||
func (s *packsSettings) Apply() {
|
||||
s.packs.ServerAddress = s.serverAddress.Text()
|
||||
s.packs.ServerAddress = s.serverAddress.Value()
|
||||
}
|
||||
|
||||
func (s *packsSettings) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(material.Editor(th, &s.serverAddress, "Server Address").Layout),
|
||||
layout.Rigid(s.serverAddress.Layout(th)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@ type skinsSettings struct {
|
|||
|
||||
Filter widget.Editor
|
||||
Proxy widget.Bool
|
||||
serverAddress widget.Editor
|
||||
serverAddress *addressInput
|
||||
}
|
||||
|
||||
func (s *skinsSettings) Init() {
|
||||
s.skins = utils.ValidCMDs["skins"].(*skins.SkinCMD)
|
||||
s.serverAddress.SingleLine = true
|
||||
s.serverAddress = AddressInput
|
||||
s.Filter.SingleLine = true
|
||||
s.Proxy.Value = true
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ func (s *skinsSettings) Init() {
|
|||
func (s *skinsSettings) Apply() {
|
||||
s.skins.Filter = s.Filter.Text()
|
||||
s.skins.NoProxy = !s.Proxy.Value
|
||||
s.skins.ServerAddress = s.serverAddress.Text()
|
||||
s.skins.ServerAddress = s.serverAddress.Value()
|
||||
}
|
||||
|
||||
func (s *skinsSettings) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions {
|
||||
|
@ -35,7 +35,7 @@ func (s *skinsSettings) Layout(gtx layout.Context, th *material.Theme) layout.Di
|
|||
layout.Rigid(material.CheckBox(th, &s.Proxy, "Enable Proxy").Layout),
|
||||
layout.Rigid(material.Editor(th, &s.Filter, "Player name filter").Layout),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(15)}.Layout),
|
||||
layout.Rigid(material.Editor(th, &s.serverAddress, "server Address").Layout),
|
||||
layout.Rigid(s.serverAddress.Layout(th)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ type worldSettings struct {
|
|||
voidGen widget.Bool
|
||||
saveImage widget.Bool
|
||||
PacketCapture widget.Bool
|
||||
serverAddress widget.Editor
|
||||
serverAddress *addressInput
|
||||
}
|
||||
|
||||
func (s *worldSettings) Init() {
|
||||
s.worlds = utils.ValidCMDs["worlds"].(*world.WorldCMD)
|
||||
s.serverAddress.SingleLine = true
|
||||
s.serverAddress = AddressInput
|
||||
s.voidGen.Value = true
|
||||
s.PacketCapture.Value = false
|
||||
}
|
||||
|
@ -29,9 +29,10 @@ func (s *worldSettings) Apply() {
|
|||
s.worlds.Packs = s.withPacks.Value
|
||||
s.worlds.EnableVoid = s.voidGen.Value
|
||||
s.worlds.SaveImage = s.saveImage.Value
|
||||
s.worlds.ServerAddress = s.serverAddress.Text()
|
||||
s.worlds.ServerAddress = s.serverAddress.Value()
|
||||
s.worlds.SaveEntities = true
|
||||
s.worlds.SaveInventories = true
|
||||
utils.Options.Capture = s.PacketCapture.Value
|
||||
}
|
||||
|
||||
func (s *worldSettings) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions {
|
||||
|
@ -40,7 +41,7 @@ func (s *worldSettings) Layout(gtx layout.Context, th *material.Theme) layout.Di
|
|||
layout.Rigid(material.CheckBox(th, &s.voidGen, "void Generator").Layout),
|
||||
layout.Rigid(material.CheckBox(th, &s.saveImage, "save image").Layout),
|
||||
layout.Rigid(material.CheckBox(th, &s.PacketCapture, "packet capture").Layout),
|
||||
layout.Rigid(material.Editor(th, &s.serverAddress, "server Address").Layout),
|
||||
layout.Rigid(s.serverAddress.Layout(th)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -96,3 +96,7 @@ type DownloadedPack struct {
|
|||
type FinishedDownloadingPacks struct {
|
||||
Packs []*DownloadedPack
|
||||
}
|
||||
|
||||
type UpdateAvailable struct {
|
||||
Version string
|
||||
}
|
||||
|
|
131
utils/auth.go
131
utils/auth.go
|
@ -3,35 +3,102 @@ package utils
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/sandertv/gophertunnel/minecraft/auth"
|
||||
"github.com/sandertv/gophertunnel/minecraft/realms"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const TokenFile = "token.json"
|
||||
|
||||
var gTokenSrc oauth2.TokenSource
|
||||
type authsrv struct {
|
||||
t *oauth2.Token
|
||||
src oauth2.TokenSource
|
||||
|
||||
func GetTokenSource() oauth2.TokenSource {
|
||||
if gTokenSrc != nil {
|
||||
return gTokenSrc
|
||||
}
|
||||
token := getToken()
|
||||
gTokenSrc = auth.RefreshTokenSource(&token)
|
||||
newToken, err := gTokenSrc.Token()
|
||||
LoginWithMicrosoftCallback func(io.Reader)
|
||||
}
|
||||
|
||||
var Auth authsrv
|
||||
|
||||
func (a *authsrv) HaveToken() bool {
|
||||
_, err := os.Stat(TokenFile)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (a *authsrv) Refresh() error {
|
||||
a.src = auth.RefreshTokenSource(a.t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *authsrv) writeToken() error {
|
||||
f, err := os.Create(TokenFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !token.Valid() {
|
||||
logrus.Info(locale.Loc("refreshed_token", nil))
|
||||
writeToken(newToken)
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
e := json.NewEncoder(f)
|
||||
return e.Encode(a.t)
|
||||
}
|
||||
|
||||
return gTokenSrc
|
||||
func (a *authsrv) readToken() error {
|
||||
var token oauth2.Token
|
||||
f, err := os.Open(TokenFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
e := json.NewDecoder(f)
|
||||
err = e.Decode(&token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.t = &token
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *authsrv) GetTokenSource() (src oauth2.TokenSource, err error) {
|
||||
if a.src != nil {
|
||||
return a.src, nil
|
||||
}
|
||||
if !a.HaveToken() {
|
||||
// request a new token
|
||||
r, w := io.Pipe()
|
||||
go a.LoginWithMicrosoftCallback(r)
|
||||
a.t, err = auth.RequestLiveTokenWriter(w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err := a.writeToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// read the existing token
|
||||
err := a.readToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// refresh the token if necessary
|
||||
err = a.Refresh()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if the old token isnt valid save the new one
|
||||
if !a.t.Valid() {
|
||||
newToken, err := a.src.Token()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.t = newToken
|
||||
err = a.writeToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return a.src, nil
|
||||
}
|
||||
|
||||
var RealmsEnv string
|
||||
|
@ -43,37 +110,7 @@ func GetRealmsAPI() *realms.Client {
|
|||
if RealmsEnv != "" {
|
||||
realms.RealmsAPIBase = fmt.Sprintf("https://pocket-%s.realms.minecraft.net/", RealmsEnv)
|
||||
}
|
||||
gRealmsAPI = realms.NewClient(GetTokenSource())
|
||||
gRealmsAPI = realms.NewClient(Auth.src)
|
||||
}
|
||||
return gRealmsAPI
|
||||
}
|
||||
|
||||
func writeToken(token *oauth2.Token) {
|
||||
buf, err := json.Marshal(token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.WriteFile(TokenFile, buf, 0o755)
|
||||
}
|
||||
|
||||
func getToken() oauth2.Token {
|
||||
var token oauth2.Token
|
||||
if _, err := os.Stat(TokenFile); err == nil {
|
||||
f, err := os.Open(TokenFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := json.NewDecoder(f).Decode(&token); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
_token, err := auth.RequestLiveToken()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
writeToken(_token)
|
||||
token = *_token
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
|
|
@ -54,17 +54,16 @@ func (bp *BehaviourPack) AddEntity(entity EntityIn) {
|
|||
}
|
||||
|
||||
for _, av := range entity.Attr {
|
||||
switch av.Name {
|
||||
case "minecraft:health":
|
||||
entry.MinecraftEntity.Components["minecraft:health"] = map[string]int{
|
||||
"value": int(av.Value),
|
||||
"max": int(av.Max),
|
||||
}
|
||||
case "minecraft:movement":
|
||||
entry.MinecraftEntity.Components["minecraft:movement"] = map[string]any{
|
||||
"value": av.Value,
|
||||
}
|
||||
m := map[string]int{
|
||||
"value": int(av.Value),
|
||||
"min": int(av.Min),
|
||||
}
|
||||
|
||||
if av.Max > 0 && av.Max < 0xffffff {
|
||||
m["max"] = int(av.Max)
|
||||
}
|
||||
|
||||
entry.MinecraftEntity.Components[av.Name] = m
|
||||
}
|
||||
|
||||
if scale, ok := entity.Meta[protocol.EntityDataKeyScale].(float32); ok {
|
||||
|
@ -86,8 +85,7 @@ func (bp *BehaviourPack) AddEntity(entity EntityIn) {
|
|||
AlwaysShowName := entity.Meta.Flag(protocol.EntityDataKeyFlags, protocol.EntityDataFlagAlwaysShowName)
|
||||
if AlwaysShowName {
|
||||
entry.MinecraftEntity.Components["minecraft:nameable"] = map[string]any{
|
||||
"always_show": true,
|
||||
"allow_name_tag_renaming": false,
|
||||
"always_show": true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
100
utils/input.go
100
utils/input.go
|
@ -1,26 +1,84 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
func UserInput(ctx context.Context, q string) (string, bool) {
|
||||
func UserInput(ctx context.Context, q string, validator func(string) bool) (string, bool) {
|
||||
c := make(chan string)
|
||||
oldState, _ := term.MakeRaw(int(os.Stdin.Fd()))
|
||||
defer term.Restore(int(os.Stdin.Fd()), oldState)
|
||||
go func() {
|
||||
fmt.Print(q)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
answer, _ := reader.ReadString('\n')
|
||||
r, _ := regexp.Compile(`[\n\r]`)
|
||||
answer = string(r.ReplaceAll([]byte(answer), []byte("")))
|
||||
|
||||
var answerb []byte
|
||||
var b [1]byte
|
||||
|
||||
var valid bool
|
||||
var validatorRunning atomic.Bool
|
||||
var validatorQueued atomic.Bool
|
||||
|
||||
for {
|
||||
os.Stdin.Read(b[:])
|
||||
|
||||
done := false
|
||||
switch b[0] {
|
||||
case 0x3:
|
||||
c <- ""
|
||||
return
|
||||
case 0xA:
|
||||
fallthrough
|
||||
case 0xD:
|
||||
done = true
|
||||
case 0x8:
|
||||
fallthrough
|
||||
case 0x7F:
|
||||
if len(answerb) > 0 {
|
||||
answerb = answerb[:len(answerb)-1]
|
||||
}
|
||||
default:
|
||||
if b[0] >= 0x20 {
|
||||
answerb = append(answerb, b[0])
|
||||
}
|
||||
}
|
||||
|
||||
if done {
|
||||
break
|
||||
}
|
||||
|
||||
fmt.Printf("\r%s%s\033[K", q, string(answerb))
|
||||
|
||||
if validator != nil {
|
||||
validatorQueued.Store(true)
|
||||
if validatorRunning.CompareAndSwap(false, true) {
|
||||
go func() {
|
||||
for validatorQueued.Load() {
|
||||
validatorQueued.Store(false)
|
||||
valid = validator(string(answerb))
|
||||
validatorRunning.Store(false)
|
||||
var st = "❌"
|
||||
if valid {
|
||||
st = "✅"
|
||||
}
|
||||
fmt.Printf("\r%s%s %s\033[K\033[%dD", q, string(answerb), st, 4)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print("\n\r")
|
||||
answer := string(answerb)
|
||||
c <- answer
|
||||
}()
|
||||
|
||||
|
@ -28,6 +86,9 @@ func UserInput(ctx context.Context, q string) (string, bool) {
|
|||
case <-ctx.Done():
|
||||
return "", true
|
||||
case a := <-c:
|
||||
if a == "" {
|
||||
return a, true
|
||||
}
|
||||
return a, false
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +121,7 @@ func ServerInput(ctx context.Context, server string) (string, string, error) {
|
|||
// no arg provided, interactive input
|
||||
if server == "" {
|
||||
var cancelled bool
|
||||
server, cancelled = UserInput(ctx, locale.Loc("enter_server", nil))
|
||||
server, cancelled = UserInput(ctx, locale.Loc("enter_server", nil), ValidateServerInput)
|
||||
if cancelled {
|
||||
return "", "", context.Canceled
|
||||
}
|
||||
|
@ -94,3 +155,28 @@ func ServerInput(ctx context.Context, server string) (string, string, error) {
|
|||
}
|
||||
return server, serverGetHostname(server), nil
|
||||
}
|
||||
|
||||
func ValidateServerInput(server string) bool {
|
||||
if pcapRegex.MatchString(server) {
|
||||
return true
|
||||
}
|
||||
|
||||
if realmRegex.MatchString(server) {
|
||||
return true // todo
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(server)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port in address") {
|
||||
host = server
|
||||
}
|
||||
}
|
||||
|
||||
ip := net.ParseIP(host)
|
||||
if ip != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
ips, _ := net.LookupIP(host)
|
||||
return len(ips) > 0
|
||||
}
|
||||
|
|
|
@ -63,7 +63,14 @@ func (c *InteractiveCLI) Start(ctx context.Context, cancel context.CancelFunc) e
|
|||
}
|
||||
fmt.Println(locale.Loc("use_to_run_command", nil))
|
||||
|
||||
cmd, cancelled := UserInput(ctx, locale.Loc("input_command", nil))
|
||||
cmd, cancelled := UserInput(ctx, locale.Loc("input_command", nil), func(s string) bool {
|
||||
for k := range ValidCMDs {
|
||||
if s == k {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
if cancelled {
|
||||
cancel()
|
||||
return nil
|
||||
|
|
185
utils/proxy.go
185
utils/proxy.go
|
@ -15,13 +15,14 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/bedrock-tool/bedrocktool/locale"
|
||||
"github.com/repeale/fp-go"
|
||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||
"github.com/sandertv/gophertunnel/minecraft"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/login"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||
"github.com/sandertv/gophertunnel/minecraft/resource"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
var DisconnectReason = "Connection lost"
|
||||
|
@ -93,6 +94,8 @@ type ProxyContext struct {
|
|||
|
||||
commands map[string]IngameCommand
|
||||
handlers []*ProxyHandler
|
||||
|
||||
reconnectHandler *ProxyHandler
|
||||
}
|
||||
|
||||
func NewProxy() (*ProxyContext, error) {
|
||||
|
@ -101,6 +104,7 @@ func NewProxy() (*ProxyContext, error) {
|
|||
AlwaysGetPacks: false,
|
||||
WithClient: true,
|
||||
IgnoreDisconnect: false,
|
||||
reconnectHandler: NewTransferHandler(),
|
||||
}
|
||||
if Options.PathCustomUserData != "" {
|
||||
if err := p.LoadCustomUserData(Options.PathCustomUserData); err != nil {
|
||||
|
@ -245,6 +249,8 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error {
|
|||
c2 = p.Client
|
||||
}
|
||||
|
||||
var transferingErr error = nil
|
||||
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
|
@ -260,7 +266,12 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error {
|
|||
if handler.PacketCB != nil {
|
||||
pk, err = handler.PacketCB(pk, toServer, time.Now())
|
||||
if err != nil {
|
||||
return err
|
||||
if errors.Is(err, transferingErr) {
|
||||
transferingErr = err
|
||||
err = nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if pk == nil {
|
||||
logrus.Tracef("Dropped Packet: %s", pkName)
|
||||
|
@ -277,6 +288,10 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if transferingErr != nil {
|
||||
return transferingErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,13 +324,11 @@ func (p *ProxyContext) IsClient(addr net.Addr) bool {
|
|||
var NewDebugLogger func(bool) *ProxyHandler
|
||||
var NewPacketCapturer func() *ProxyHandler
|
||||
|
||||
func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string, cdpp **login.ClientData) (err error) {
|
||||
GetTokenSource() // ask for login before listening
|
||||
|
||||
func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string, cdpp **login.ClientData, tokenSource oauth2.TokenSource) (err error) {
|
||||
var packs []*resource.Pack
|
||||
if Options.Preload {
|
||||
logrus.Info(locale.Loc("preloading_packs", nil))
|
||||
serverConn, err := connectServer(ctx, serverAddress, nil, true, func(header packet.Header, payload []byte, src, dst net.Addr) {})
|
||||
serverConn, err := connectServer(ctx, serverAddress, nil, true, nil, tokenSource)
|
||||
if err != nil {
|
||||
return fmt.Errorf(locale.Loc("failed_to_connect", locale.Strmap{"Address": serverAddress, "Err": err}))
|
||||
}
|
||||
|
@ -354,27 +367,19 @@ func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) {
|
||||
if Options.Debug || Options.ExtraDebug {
|
||||
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
|
||||
func (p *ProxyContext) packetFunc(header packet.Header, payload []byte, src, dst net.Addr) {
|
||||
if header.PacketID == packet.IDRequestNetworkSettings {
|
||||
p.clientAddr = src
|
||||
}
|
||||
if Options.Capture {
|
||||
p.AddHandler(NewPacketCapturer())
|
||||
}
|
||||
p.AddHandler(&ProxyHandler{
|
||||
Name: "Commands",
|
||||
PacketCB: p.CommandHandlerPacketCB,
|
||||
})
|
||||
|
||||
for _, handler := range p.handlers {
|
||||
if handler.AddressAndName != nil {
|
||||
handler.AddressAndName(serverAddress, name)
|
||||
}
|
||||
if handler.ProxyRef != nil {
|
||||
handler.ProxyRef(p)
|
||||
if handler.PacketFunc == nil {
|
||||
continue
|
||||
}
|
||||
handler.PacketFunc(header, payload, src, dst)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ProxyContext) connect(ctx context.Context, serverAddress string) (err error) {
|
||||
defer func() {
|
||||
for _, handler := range p.handlers {
|
||||
if handler.OnEnd != nil {
|
||||
|
@ -388,9 +393,19 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
|||
isReplay = true
|
||||
}
|
||||
|
||||
var tokenSource oauth2.TokenSource
|
||||
if !isReplay {
|
||||
// ask for login before listening
|
||||
tokenSource, err = Auth.GetTokenSource()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var cdp *login.ClientData = nil
|
||||
if p.WithClient && !isReplay {
|
||||
err = p.connectClient(ctx, serverAddress, &cdp)
|
||||
CurrentUI.Message(messages.SetUIState(messages.UIStateConnect))
|
||||
err = p.connectClient(ctx, serverAddress, &cdp, tokenSource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -400,7 +415,6 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
|||
if p.Client != nil {
|
||||
p.Listener.Disconnect(p.Client.(*minecraft.Conn), DisconnectReason)
|
||||
}
|
||||
p.Listener.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -416,25 +430,13 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
|||
handler.OnClientConnect(p.Client)
|
||||
}
|
||||
|
||||
packetFunc := func(header packet.Header, payload []byte, src, dst net.Addr) {
|
||||
if header.PacketID == packet.IDRequestNetworkSettings {
|
||||
p.clientAddr = src
|
||||
}
|
||||
for _, handler := range p.handlers {
|
||||
if handler.PacketFunc == nil {
|
||||
continue
|
||||
}
|
||||
handler.PacketFunc(header, payload, src, dst)
|
||||
}
|
||||
}
|
||||
|
||||
if isReplay {
|
||||
p.Server, err = createReplayConnector(serverAddress[5:], packetFunc)
|
||||
p.Server, err = createReplayConnector(serverAddress[5:], p.packetFunc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, packetFunc)
|
||||
p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, p.packetFunc, tokenSource)
|
||||
}
|
||||
if err != nil {
|
||||
for _, handler := range p.handlers {
|
||||
|
@ -488,56 +490,95 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
|||
}
|
||||
}
|
||||
|
||||
ctx2, cancel := context.WithCancelCause(ctx)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
doProxy := func(client bool, onErr func()) {
|
||||
doProxy := func(client bool) {
|
||||
defer wg.Done()
|
||||
if err := p.proxyLoop(ctx, client); err != nil {
|
||||
logrus.Error(err)
|
||||
if err := p.proxyLoop(ctx2, client); err != nil {
|
||||
cancel(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// server to client
|
||||
wg.Add(1)
|
||||
go doProxy(false, func() {
|
||||
p.DisconnectClient()
|
||||
})
|
||||
go doProxy(false)
|
||||
|
||||
// client to server
|
||||
if p.Client != nil {
|
||||
wg.Add(1)
|
||||
go doProxy(true, func() {
|
||||
p.DisconnectServer()
|
||||
})
|
||||
go doProxy(true)
|
||||
}
|
||||
go func() {
|
||||
wg.Wait()
|
||||
if ctx.Err() == nil {
|
||||
cancel(nil)
|
||||
}
|
||||
}()
|
||||
|
||||
/*
|
||||
wantSecondary := fp.Filter(func(handler *ProxyHandler) bool {
|
||||
return handler.SecondaryClientCB != nil
|
||||
})(p.handlers)
|
||||
|
||||
if len(wantSecondary) > 0 {
|
||||
go func() {
|
||||
for {
|
||||
c, err := p.Listener.Accept()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, handler := range wantSecondary {
|
||||
go handler.SecondaryClientCB(c.(*minecraft.Conn))
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
*/
|
||||
|
||||
<-ctx2.Done()
|
||||
err = ctx2.Err()
|
||||
if err, ok := err.(*transferingErr); ok {
|
||||
logrus.Infof("Redirect to %s", err.To)
|
||||
if p.Client != nil {
|
||||
p.Listener.Disconnect(p.Client.(*minecraft.Conn), "please reconnect")
|
||||
}
|
||||
return p.connect(ctx, err.To)
|
||||
}
|
||||
|
||||
wantSecondary := fp.Filter(func(handler *ProxyHandler) bool {
|
||||
return handler.SecondaryClientCB != nil
|
||||
})(p.handlers)
|
||||
|
||||
if len(wantSecondary) > 0 {
|
||||
go func() {
|
||||
for {
|
||||
c, err := p.Listener.Accept()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, handler := range wantSecondary {
|
||||
go handler.SecondaryClientCB(c.(*minecraft.Conn))
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
var pool = packet.NewPool()
|
||||
func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) {
|
||||
if Options.Debug || Options.ExtraDebug {
|
||||
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
|
||||
}
|
||||
if Options.Capture {
|
||||
p.AddHandler(NewPacketCapturer())
|
||||
}
|
||||
p.AddHandler(&ProxyHandler{
|
||||
Name: "Commands",
|
||||
PacketCB: p.CommandHandlerPacketCB,
|
||||
})
|
||||
|
||||
func DecodePacket(header packet.Header, payload []byte) packet.Packet {
|
||||
p.AddHandler(p.reconnectHandler)
|
||||
|
||||
for _, handler := range p.handlers {
|
||||
if handler.AddressAndName != nil {
|
||||
handler.AddressAndName(serverAddress, name)
|
||||
}
|
||||
if handler.ProxyRef != nil {
|
||||
handler.ProxyRef(p)
|
||||
}
|
||||
}
|
||||
|
||||
return p.connect(ctx, serverAddress)
|
||||
}
|
||||
|
||||
func DecodePacket(pool packet.Pool, header packet.Header, payload []byte) packet.Packet {
|
||||
var pk packet.Packet
|
||||
if pkFunc, ok := pool[header.PacketID]; ok {
|
||||
pk = pkFunc()
|
||||
|
@ -550,6 +591,6 @@ func DecodePacket(header packet.Header, payload []byte) packet.Packet {
|
|||
logrus.Errorf("%T: %s", pk, recoveredErr.(error))
|
||||
}
|
||||
}()
|
||||
pk.Marshal(protocol.NewReader(bytes.NewBuffer(payload), 0))
|
||||
pk.Marshal(protocol.NewReader(bytes.NewBuffer(payload), 0, false))
|
||||
return pk
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ func (r *replayConnector) loop() {
|
|||
|
||||
func createReplayConnector(filename string, packetFunc PacketFunc) (r *replayConnector, err error) {
|
||||
r = &replayConnector{
|
||||
pool: packet.NewPool(),
|
||||
pool: minecraft.DefaultProtocol.Packets(true),
|
||||
proto: minecraft.DefaultProtocol,
|
||||
packetFunc: packetFunc,
|
||||
spawn: make(chan struct{}),
|
||||
|
@ -315,6 +315,14 @@ func createReplayConnector(filename string, packetFunc PacketFunc) (r *replayCon
|
|||
return r, nil
|
||||
}
|
||||
|
||||
func (r *replayConnector) DisconnectOnInvalidPacket() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *replayConnector) DisconnectOnUnknownPacket() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *replayConnector) Close() error {
|
||||
r.once.Do(func() {
|
||||
close(r.close)
|
||||
|
|
|
@ -18,12 +18,22 @@ type Skin struct {
|
|||
}
|
||||
|
||||
type SkinGeometry struct {
|
||||
SkinGeometryDescription
|
||||
Bones []any `json:"bones"`
|
||||
}
|
||||
|
||||
type SkinGeometryDescription struct {
|
||||
Identifier string `json:"identifier,omitempty"`
|
||||
Texturewidth int `json:"texturewidth"`
|
||||
Textureheight int `json:"textureheight"`
|
||||
VisibleBoundsWidth float64 `json:"visible_bounds_width"`
|
||||
VisibleBoundsHeight float64 `json:"visible_bounds_height"`
|
||||
VisibleBoundsOffset []float64 `json:"visible_bounds_offset,omitempty"`
|
||||
Bones []any `json:"bones"`
|
||||
}
|
||||
|
||||
type SkinGeometry_1_12 struct {
|
||||
Description SkinGeometryDescription `json:"description"`
|
||||
Bones []any `json:"bones"`
|
||||
}
|
||||
|
||||
func (skin *Skin) Hash() uuid.UUID {
|
||||
|
@ -31,7 +41,7 @@ func (skin *Skin) Hash() uuid.UUID {
|
|||
return uuid.NewSHA1(uuid.NameSpaceURL, h)
|
||||
}
|
||||
|
||||
func (skin *Skin) getGeometry() (*SkinGeometry, string, error) {
|
||||
func (skin *Skin) getGeometry() (*SkinGeometry_1_12, string, error) {
|
||||
if !skin.HaveGeometry() {
|
||||
return nil, "", errors.New("no geometry")
|
||||
}
|
||||
|
@ -41,6 +51,10 @@ func (skin *Skin) getGeometry() (*SkinGeometry, string, error) {
|
|||
return nil, "", err
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
arr, ok := data["minecraft:geometry"].([]any)
|
||||
if !ok {
|
||||
return nil, "", errors.New("invalid geometry")
|
||||
|
@ -61,13 +75,16 @@ func (skin *Skin) getGeometry() (*SkinGeometry, string, error) {
|
|||
visible_bounds_height, _ := desc["visible_bounds_height"].(float64)
|
||||
visibleOffset, _ := desc["visible_bounds_offset"].([]float64)
|
||||
|
||||
return &SkinGeometry{
|
||||
Texturewidth: int(texture_width),
|
||||
Textureheight: int(texture_height),
|
||||
VisibleBoundsWidth: visible_bounds_width,
|
||||
VisibleBoundsHeight: visible_bounds_height,
|
||||
VisibleBoundsOffset: visibleOffset,
|
||||
Bones: geom["bones"].([]any),
|
||||
return &SkinGeometry_1_12{
|
||||
Description: SkinGeometryDescription{
|
||||
Identifier: desc["identifier"].(string),
|
||||
Texturewidth: int(texture_width),
|
||||
Textureheight: int(texture_height),
|
||||
VisibleBoundsWidth: visible_bounds_width,
|
||||
VisibleBoundsHeight: visible_bounds_height,
|
||||
VisibleBoundsOffset: visibleOffset,
|
||||
},
|
||||
Bones: geom["bones"].([]any),
|
||||
}, desc["identifier"].(string), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -103,9 +103,26 @@ func (s *SkinPack) Save(fpath, serverName string) error {
|
|||
if s2.skin.HaveGeometry() {
|
||||
geometry, geometryName, err := s2.skin.getGeometry()
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to decode geometry %s", skinName)
|
||||
} else {
|
||||
geometryJson[geometryName] = *geometry
|
||||
logrus.Warnf("failed to decode geometry %s %v", skinName, err)
|
||||
} else if geometry != nil {
|
||||
f, err := os.Create(path.Join(fpath, fmt.Sprintf("geometry-%s.json", geometryName)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e := json.NewEncoder(f)
|
||||
e.SetIndent("", "\t")
|
||||
if err := e.Encode(map[string]any{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": []*SkinGeometry_1_12{geometry},
|
||||
}); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
geometryJson[geometryName] = SkinGeometry{
|
||||
SkinGeometryDescription: geometry.Description,
|
||||
Bones: geometry.Bones,
|
||||
}
|
||||
entry.Geometry = geometryName
|
||||
}
|
||||
}
|
||||
|
@ -120,8 +137,10 @@ func (s *SkinPack) Save(fpath, serverName string) error {
|
|||
e := json.NewEncoder(f)
|
||||
e.SetIndent("", "\t")
|
||||
if err := e.Encode(geometryJson); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
||||
{ // skins.json
|
||||
|
@ -132,8 +151,10 @@ func (s *SkinPack) Save(fpath, serverName string) error {
|
|||
e := json.NewEncoder(f)
|
||||
e.SetIndent("", "\t")
|
||||
if err := e.Encode(skinsJson); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
||||
{ // manifest.json
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||
)
|
||||
|
||||
type transferingErr struct {
|
||||
To string
|
||||
}
|
||||
|
||||
func (transferingErr) Error() string {
|
||||
return "transferingErr"
|
||||
}
|
||||
|
||||
type transferHandler struct {
|
||||
p *ProxyContext
|
||||
}
|
||||
|
||||
func NewTransferHandler() *ProxyHandler {
|
||||
t := &transferHandler{}
|
||||
return &ProxyHandler{
|
||||
Name: "transfer",
|
||||
ProxyRef: func(pc *ProxyContext) {
|
||||
t.p = pc
|
||||
},
|
||||
PacketCB: t.packetCB,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *transferHandler) packetCB(pk packet.Packet, toServer bool, timeReceived time.Time) (packet.Packet, error) {
|
||||
switch pk := pk.(type) {
|
||||
case *packet.Transfer:
|
||||
var pk2 packet.Packet = nil
|
||||
if t.p.Client != nil {
|
||||
host, port, err := net.SplitHostPort(t.p.Client.ClientData().ServerAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_port, _ := strconv.Atoi(port)
|
||||
pk2 = &packet.Transfer{Address: host, Port: uint16(_port)}
|
||||
}
|
||||
|
||||
return pk2, &transferingErr{
|
||||
To: fmt.Sprintf("%s:%d", pk.Address, pk.Port),
|
||||
}
|
||||
}
|
||||
return pk, nil
|
||||
}
|
|
@ -15,6 +15,8 @@ import (
|
|||
var Version string
|
||||
var CmdName = "bedrocktool"
|
||||
|
||||
var UpdateAvailable string
|
||||
|
||||
const updateServer = "https://updates.yuv.pink/"
|
||||
|
||||
type trequester struct {
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/google/uuid"
|
||||
"github.com/sandertv/gophertunnel/minecraft"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
//"github.com/sandertv/gophertunnel/minecraft/gatherings"
|
||||
|
||||
|
@ -57,7 +58,7 @@ func CleanupName(name string) string {
|
|||
|
||||
// connections
|
||||
|
||||
func connectServer(ctx context.Context, address string, ClientData *login.ClientData, wantPacks bool, packetFunc PacketFunc) (serverConn *minecraft.Conn, err error) {
|
||||
func connectServer(ctx context.Context, address string, ClientData *login.ClientData, wantPacks bool, packetFunc PacketFunc, tokenSource oauth2.TokenSource) (serverConn *minecraft.Conn, err error) {
|
||||
cd := login.ClientData{}
|
||||
if ClientData != nil {
|
||||
cd = *ClientData
|
||||
|
@ -65,7 +66,7 @@ func connectServer(ctx context.Context, address string, ClientData *login.Client
|
|||
|
||||
logrus.Info(locale.Loc("connecting", locale.Strmap{"Address": address}))
|
||||
serverConn, err = minecraft.Dialer{
|
||||
TokenSource: GetTokenSource(),
|
||||
TokenSource: tokenSource,
|
||||
ClientData: cd,
|
||||
PacketFunc: packetFunc,
|
||||
DownloadResourcePack: func(id uuid.UUID, version string, current int, total int) bool {
|
||||
|
@ -141,6 +142,7 @@ func WriteManifest(manifest *resource.Manifest, fpath string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.Close()
|
||||
e := json.NewEncoder(w)
|
||||
e.SetIndent("", "\t")
|
||||
if err = e.Encode(manifest); err != nil {
|
||||
|
@ -188,6 +190,6 @@ func ShowFile(path string) {
|
|||
return
|
||||
}
|
||||
if runtime.GOOS == "linux" {
|
||||
|
||||
println(path)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue