add progress

This commit is contained in:
olebeck 2023-04-29 17:12:13 +02:00
parent 3cc13a7bbf
commit b867221a66
5 changed files with 126 additions and 35 deletions

View File

@ -2,7 +2,6 @@ package handlers
import (
"bufio"
"bytes"
"io"
"net"
"os"
@ -12,7 +11,6 @@ import (
"github.com/bedrock-tool/bedrocktool/utils"
"github.com/bedrock-tool/bedrocktool/utils/crypt"
"github.com/fatih/color"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
"github.com/sirupsen/logrus"
"golang.org/x/exp/slices"
@ -79,20 +77,11 @@ func NewDebugLogger(extraVerbose bool) *utils.ProxyHandler {
proxy = pc
},
PacketFunc: func(header packet.Header, payload []byte, src, dst net.Addr) {
var pk packet.Packet
if pkFunc, ok := pool[header.PacketID]; ok {
pk = pkFunc()
} else {
pk = &packet.Unknown{PacketID: header.PacketID, Payload: payload}
pk := utils.DecodePacket(header, payload)
if pk == nil {
return
}
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 {
dmpLock.Lock()
packetsLogF.Write([]byte(utils.DumpStruct(0, pk, true, false) + "\n\n\n"))

View File

@ -1,8 +1,10 @@
package packs
import (
"fmt"
"image"
"image/color"
"sort"
"sync"
"gioui.org/f32"
@ -29,16 +31,21 @@ type Page struct {
State messages.UIState
packsList widget.List
l sync.Mutex
Packs []*packEntry
Packs map[string]*packEntry
}
type packEntry struct {
IsFinished bool
UUID string
HasIcon bool
Icon paint.ImageOp
Size string
Name string
Path string
Err error
Size uint64
Loaded uint64
Name string
Path string
Err error
}
func New(router *pages.Router) *Page {
@ -49,6 +56,7 @@ func New(router *pages.Router) *Page {
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)
}
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 {
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.Flex{Axis: layout.Horizontal}.Layout(gtx,
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 {
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.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 {
if entry.Err != nil {
return material.LabelStyle{
@ -118,8 +150,15 @@ func (p *Page) layoutFinished(gtx C, th *material.Theme) D {
layout.Flexed(1, func(gtx C) D {
p.l.Lock()
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)
})
}),
@ -137,7 +176,7 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
return margin.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
switch p.State {
case messages.UIStateFinished:
case messages.UIStateMain:
return p.layoutFinished(gtx, th)
}
return layout.Dimensions{}
@ -155,19 +194,44 @@ func (p *Page) Handler(data interface{}) messages.MessageResponse {
p.State = m
p.Router.Invalidate()
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 {
e := &packEntry{
Name: dp.Name,
Size: utils.SizeofFmt(float32(dp.Size)),
IsFinished: false,
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 {
e.Icon = paint.NewImageOpFilter(dp.Icon, paint.FilterNearest)
e.HasIcon = true
}
p.Packs = append(p.Packs, e)
e.Err = dp.Err
e.IsFinished = true
}
p.l.Unlock()
p.Router.Invalidate()
r.Ok = true
}

View File

@ -69,7 +69,17 @@ type SavingWorld struct {
type CanShowImages struct{}
type InitialPacksInfo struct {
Packs []protocol.TexturePackInfo
}
type PackDownloadProgress struct {
UUID string
LoadedAdd uint64
}
type DownloadedPack struct {
UUID string
Name string
Path string
Size int

View File

@ -1,6 +1,7 @@
package utils
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
@ -70,6 +71,8 @@ type ProxyHandler struct {
OnClientConnect func(conn minecraft.IConn)
SecondaryClientCB func(conn minecraft.IConn)
// called after server connected & downloaded resource packs
OnServerConnect func() (cancel bool)
// called after game started
ConnectCB func(err error) bool
@ -351,11 +354,6 @@ func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string,
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) {
if Options.Debug || Options.ExtraDebug {
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
@ -436,7 +434,7 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
return err
}
} else {
err = p.connectServer(ctx, serverAddress, cdp, packetFunc)
p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, packetFunc)
}
if err != nil {
for _, handler := range p.handlers {
@ -457,6 +455,16 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
}
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()
for _, handler := range p.handlers {
if handler.GameDataModifier != nil {
@ -475,7 +483,8 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
continue
}
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()
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
}