add progress
This commit is contained in:
parent
3cc13a7bbf
commit
b867221a66
|
@ -2,7 +2,6 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -12,7 +11,6 @@ import (
|
||||||
"github.com/bedrock-tool/bedrocktool/utils"
|
"github.com/bedrock-tool/bedrocktool/utils"
|
||||||
"github.com/bedrock-tool/bedrocktool/utils/crypt"
|
"github.com/bedrock-tool/bedrocktool/utils/crypt"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
|
||||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
@ -79,20 +77,11 @@ func NewDebugLogger(extraVerbose bool) *utils.ProxyHandler {
|
||||||
proxy = pc
|
proxy = pc
|
||||||
},
|
},
|
||||||
PacketFunc: func(header packet.Header, payload []byte, src, dst net.Addr) {
|
PacketFunc: func(header packet.Header, payload []byte, src, dst net.Addr) {
|
||||||
var pk packet.Packet
|
pk := utils.DecodePacket(header, payload)
|
||||||
if pkFunc, ok := pool[header.PacketID]; ok {
|
if pk == nil {
|
||||||
pk = pkFunc()
|
return
|
||||||
} else {
|
|
||||||
pk = &packet.Unknown{PacketID: header.PacketID, Payload: payload}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if recoveredErr := recover(); recoveredErr != nil {
|
|
||||||
logrus.Errorf("%T: %s", pk, recoveredErr.(error))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
pk.Marshal(protocol.NewReader(bytes.NewBuffer(payload), 0))
|
|
||||||
|
|
||||||
if packetsLogF != nil {
|
if packetsLogF != nil {
|
||||||
dmpLock.Lock()
|
dmpLock.Lock()
|
||||||
packetsLogF.Write([]byte(utils.DumpStruct(0, pk, true, false) + "\n\n\n"))
|
packetsLogF.Write([]byte(utils.DumpStruct(0, pk, true, false) + "\n\n\n"))
|
||||||
|
|
Binary file not shown.
|
@ -1,8 +1,10 @@
|
||||||
package packs
|
package packs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
|
@ -29,16 +31,21 @@ type Page struct {
|
||||||
State messages.UIState
|
State messages.UIState
|
||||||
packsList widget.List
|
packsList widget.List
|
||||||
l sync.Mutex
|
l sync.Mutex
|
||||||
Packs []*packEntry
|
Packs map[string]*packEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
type packEntry struct {
|
type packEntry struct {
|
||||||
|
IsFinished bool
|
||||||
|
UUID string
|
||||||
|
|
||||||
HasIcon bool
|
HasIcon bool
|
||||||
Icon paint.ImageOp
|
Icon paint.ImageOp
|
||||||
Size string
|
|
||||||
Name string
|
Size uint64
|
||||||
Path string
|
Loaded uint64
|
||||||
Err error
|
Name string
|
||||||
|
Path string
|
||||||
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(router *pages.Router) *Page {
|
func New(router *pages.Router) *Page {
|
||||||
|
@ -49,6 +56,7 @@ func New(router *pages.Router) *Page {
|
||||||
Axis: layout.Vertical,
|
Axis: layout.Vertical,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Packs: make(map[string]*packEntry),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +88,25 @@ func drawPackIcon(ops *op.Ops, imageOp paint.ImageOp, bounds image.Point) {
|
||||||
paint.PaintOp{}.Add(ops)
|
paint.PaintOp{}.Add(ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MulAlpha(c color.NRGBA, alpha uint8) color.NRGBA {
|
||||||
|
c.A = uint8(uint32(c.A) * uint32(alpha) / 0xFF)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
func drawPackEntry(gtx C, th *material.Theme, entry *packEntry) D {
|
func drawPackEntry(gtx C, th *material.Theme, entry *packEntry) D {
|
||||||
|
var size = ""
|
||||||
|
var colorSize = th.Palette.Fg
|
||||||
|
if entry.IsFinished {
|
||||||
|
size = utils.SizeofFmt(float32(entry.Size))
|
||||||
|
} else {
|
||||||
|
size = fmt.Sprintf("%s / %s %.02f%%",
|
||||||
|
utils.SizeofFmt(float32(entry.Size)),
|
||||||
|
utils.SizeofFmt(float32(entry.Size)),
|
||||||
|
float32(entry.Loaded)/float32(entry.Size)*100,
|
||||||
|
)
|
||||||
|
colorSize = color.NRGBA{0x00, 0xc9, 0xc9, 0xff}
|
||||||
|
}
|
||||||
|
|
||||||
return layout.UniformInset(5).Layout(gtx, func(gtx C) D {
|
return layout.UniformInset(5).Layout(gtx, func(gtx C) D {
|
||||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
|
@ -93,7 +119,13 @@ func drawPackEntry(gtx C, th *material.Theme, entry *packEntry) D {
|
||||||
layout.Flexed(1, func(gtx C) D {
|
layout.Flexed(1, func(gtx C) D {
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
layout.Rigid(material.Label(th, th.TextSize, entry.Name).Layout),
|
layout.Rigid(material.Label(th, th.TextSize, entry.Name).Layout),
|
||||||
layout.Rigid(material.Label(th, th.TextSize, entry.Size).Layout),
|
layout.Rigid(material.LabelStyle{
|
||||||
|
Text: size,
|
||||||
|
Color: colorSize,
|
||||||
|
SelectionColor: MulAlpha(th.Palette.ContrastBg, 0x60),
|
||||||
|
TextSize: th.TextSize,
|
||||||
|
Shaper: th.Shaper,
|
||||||
|
}.Layout),
|
||||||
layout.Rigid(func(gtx C) D {
|
layout.Rigid(func(gtx C) D {
|
||||||
if entry.Err != nil {
|
if entry.Err != nil {
|
||||||
return material.LabelStyle{
|
return material.LabelStyle{
|
||||||
|
@ -118,8 +150,15 @@ func (p *Page) layoutFinished(gtx C, th *material.Theme) D {
|
||||||
layout.Flexed(1, func(gtx C) D {
|
layout.Flexed(1, func(gtx C) D {
|
||||||
p.l.Lock()
|
p.l.Lock()
|
||||||
defer p.l.Unlock()
|
defer p.l.Unlock()
|
||||||
return material.List(th, &p.packsList).Layout(gtx, len(p.Packs), func(gtx C, index int) D {
|
|
||||||
entry := p.Packs[len(p.Packs)-index-1]
|
keys := make([]string, 0, len(p.Packs))
|
||||||
|
for k := range p.Packs {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
|
||||||
|
return material.List(th, &p.packsList).Layout(gtx, len(keys), func(gtx C, index int) D {
|
||||||
|
entry := p.Packs[keys[index]]
|
||||||
return drawPackEntry(gtx, th, entry)
|
return drawPackEntry(gtx, th, entry)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
@ -137,7 +176,7 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
|
||||||
|
|
||||||
return margin.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
return margin.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
switch p.State {
|
switch p.State {
|
||||||
case messages.UIStateFinished:
|
case messages.UIStateMain:
|
||||||
return p.layoutFinished(gtx, th)
|
return p.layoutFinished(gtx, th)
|
||||||
}
|
}
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
|
@ -155,19 +194,44 @@ func (p *Page) Handler(data interface{}) messages.MessageResponse {
|
||||||
p.State = m
|
p.State = m
|
||||||
p.Router.Invalidate()
|
p.Router.Invalidate()
|
||||||
r.Ok = true
|
r.Ok = true
|
||||||
case messages.FinishedDownloadingPacks:
|
|
||||||
p.State = messages.UIStateFinished
|
case messages.InitialPacksInfo:
|
||||||
|
p.State = messages.UIStateMain
|
||||||
|
p.l.Lock()
|
||||||
for _, dp := range m.Packs {
|
for _, dp := range m.Packs {
|
||||||
e := &packEntry{
|
e := &packEntry{
|
||||||
Name: dp.Name,
|
IsFinished: false,
|
||||||
Size: utils.SizeofFmt(float32(dp.Size)),
|
UUID: dp.UUID,
|
||||||
|
Name: dp.SubPackName + "v" + dp.Version,
|
||||||
|
Size: dp.Size,
|
||||||
}
|
}
|
||||||
|
p.Packs[e.UUID] = e
|
||||||
|
}
|
||||||
|
p.l.Unlock()
|
||||||
|
p.Router.Invalidate()
|
||||||
|
|
||||||
|
case messages.PackDownloadProgress:
|
||||||
|
p.l.Lock()
|
||||||
|
e := p.Packs[m.UUID]
|
||||||
|
e.Loaded += m.LoadedAdd
|
||||||
|
if e.Loaded == e.Size {
|
||||||
|
e.IsFinished = true
|
||||||
|
}
|
||||||
|
p.l.Unlock()
|
||||||
|
p.Router.Invalidate()
|
||||||
|
|
||||||
|
case messages.FinishedDownloadingPacks:
|
||||||
|
p.l.Lock()
|
||||||
|
for _, dp := range m.Packs {
|
||||||
|
e := p.Packs[dp.UUID]
|
||||||
if dp.Icon != nil {
|
if dp.Icon != nil {
|
||||||
e.Icon = paint.NewImageOpFilter(dp.Icon, paint.FilterNearest)
|
e.Icon = paint.NewImageOpFilter(dp.Icon, paint.FilterNearest)
|
||||||
e.HasIcon = true
|
e.HasIcon = true
|
||||||
}
|
}
|
||||||
p.Packs = append(p.Packs, e)
|
e.Err = dp.Err
|
||||||
|
e.IsFinished = true
|
||||||
}
|
}
|
||||||
|
p.l.Unlock()
|
||||||
p.Router.Invalidate()
|
p.Router.Invalidate()
|
||||||
r.Ok = true
|
r.Ok = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,17 @@ type SavingWorld struct {
|
||||||
|
|
||||||
type CanShowImages struct{}
|
type CanShowImages struct{}
|
||||||
|
|
||||||
|
type InitialPacksInfo struct {
|
||||||
|
Packs []protocol.TexturePackInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type PackDownloadProgress struct {
|
||||||
|
UUID string
|
||||||
|
LoadedAdd uint64
|
||||||
|
}
|
||||||
|
|
||||||
type DownloadedPack struct {
|
type DownloadedPack struct {
|
||||||
|
UUID string
|
||||||
Name string
|
Name string
|
||||||
Path string
|
Path string
|
||||||
Size int
|
Size int
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -70,6 +71,8 @@ type ProxyHandler struct {
|
||||||
OnClientConnect func(conn minecraft.IConn)
|
OnClientConnect func(conn minecraft.IConn)
|
||||||
SecondaryClientCB func(conn minecraft.IConn)
|
SecondaryClientCB func(conn minecraft.IConn)
|
||||||
|
|
||||||
|
// called after server connected & downloaded resource packs
|
||||||
|
OnServerConnect func() (cancel bool)
|
||||||
// called after game started
|
// called after game started
|
||||||
ConnectCB func(err error) bool
|
ConnectCB func(err error) bool
|
||||||
|
|
||||||
|
@ -351,11 +354,6 @@ func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProxyContext) connectServer(ctx context.Context, serverAddress string, cdp *login.ClientData, packetFunc PacketFunc) (err error) {
|
|
||||||
p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, packetFunc)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) {
|
func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) {
|
||||||
if Options.Debug || Options.ExtraDebug {
|
if Options.Debug || Options.ExtraDebug {
|
||||||
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
|
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
|
||||||
|
@ -436,7 +434,7 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = p.connectServer(ctx, serverAddress, cdp, packetFunc)
|
p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, packetFunc)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, handler := range p.handlers {
|
for _, handler := range p.handlers {
|
||||||
|
@ -457,6 +455,16 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
||||||
}
|
}
|
||||||
defer p.Server.Close()
|
defer p.Server.Close()
|
||||||
|
|
||||||
|
for _, handler := range p.handlers {
|
||||||
|
if handler.OnServerConnect == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cancel := handler.OnServerConnect()
|
||||||
|
if cancel {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gd := p.Server.GameData()
|
gd := p.Server.GameData()
|
||||||
for _, handler := range p.handlers {
|
for _, handler := range p.handlers {
|
||||||
if handler.GameDataModifier != nil {
|
if handler.GameDataModifier != nil {
|
||||||
|
@ -475,7 +483,8 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !handler.ConnectCB(nil) {
|
if !handler.ConnectCB(nil) {
|
||||||
return errors.New("Cancelled")
|
logrus.Info("Disconnecting")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,3 +534,22 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pool = packet.NewPool()
|
||||||
|
|
||||||
|
func DecodePacket(header packet.Header, payload []byte) packet.Packet {
|
||||||
|
var pk packet.Packet
|
||||||
|
if pkFunc, ok := pool[header.PacketID]; ok {
|
||||||
|
pk = pkFunc()
|
||||||
|
} else {
|
||||||
|
pk = &packet.Unknown{PacketID: header.PacketID, Payload: payload}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if recoveredErr := recover(); recoveredErr != nil {
|
||||||
|
logrus.Errorf("%T: %s", pk, recoveredErr.(error))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
pk.Marshal(protocol.NewReader(bytes.NewBuffer(payload), 0))
|
||||||
|
return pk
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue