add player inventory

This commit is contained in:
olebeck 2023-03-28 15:22:11 +02:00
parent 94e02d677c
commit d3a8219d99
6 changed files with 260 additions and 27 deletions

View File

@ -18,10 +18,6 @@ type itemContainer struct {
}
func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
if !w.experimentInventory {
return pk
}
switch pk := pk.(type) {
case *packet.ContainerOpen:
// add to open containers
@ -109,6 +105,10 @@ func (w *WorldState) processItemPacketsServer(pk packet.Packet) packet.Packet {
case *packet.ItemComponent:
w.bp.ApplyComponentEntries(pk.Items)
case *packet.MobArmourEquipment:
if pk.EntityRuntimeID == w.proxy.Server.GameData().EntityRuntimeID {
}
}
return pk
}
@ -184,18 +184,198 @@ func stackToItem(it protocol.ItemStack) item.Stack {
return nbtconv.ReadItem(it.NBTData, &s)
}
func playerData(items []protocol.ItemInstance) (ret map[string]any) {
ret = map[string]any{}
func (w *WorldState) playerData() (ret map[string]any) {
ret = map[string]any{
"format_version": "1.12.0",
"identifier": "minecraft:player",
}
if len(items) > 0 {
inv := inventory.New(len(items), nil)
for i, ii := range items {
if len(w.playerInventory) > 0 {
inv := inventory.New(len(w.playerInventory), nil)
for i, ii := range w.playerInventory {
inv.SetItem(i, stackToItem(ii.Stack))
}
ret["Inventory"] = nbtconv.InvToNBT(inv)
}
ret["format_version"] = "1.12.0"
ret["abilities"] = map[string]any{
"doorsandswitches": true,
"op": true,
"opencontainers": true,
"teleport": true,
"attackmobs": true,
"instabuild": true,
"permissionsLevel": int32(3),
"flying": false,
"lightning": false,
"playerPermissionsLevel": int32(2),
"attackplayers": true,
"build": true,
"flySpeed": float32(0.05),
"invulnerable": true,
"mayfly": true,
"mine": true,
"walkSpeed": float32(0.1),
}
type attribute struct {
Name string
Base float32
Current float32
DefaultMax float32
DefaultMin float32
Max float32
Min float32
}
ret["Attributes"] = []attribute{
{
Base: 0,
Current: 0,
DefaultMax: 1024,
DefaultMin: -1024,
Max: 1024,
Min: -1024,
Name: "minecraft:luck",
},
{
Base: 20,
Current: 20,
DefaultMax: 20,
DefaultMin: 0,
Max: 20,
Min: 0,
Name: "minecraft:health",
},
{
Base: 0,
Current: 0,
DefaultMax: 16,
DefaultMin: 0,
Max: 16,
Min: 0,
Name: "minecraft:absorption",
},
{
Base: 0,
Current: 0,
DefaultMax: 1,
DefaultMin: 0,
Max: 1,
Min: 0,
Name: "minecraft:knockback_resistance",
},
{
Base: 0.1,
Current: 0.1,
DefaultMax: 3.4028235e+38,
DefaultMin: 0,
Max: 3.4028235e+38,
Min: 0,
Name: "minecraft:movement",
},
{
Base: 0.02,
Current: 0.02,
DefaultMax: 3.4028235e+38,
DefaultMin: 0,
Max: 3.4028235e+38,
Min: 0,
Name: "minecraft:underwater_movement",
},
{
Base: 0.02,
Current: 0.02,
DefaultMax: 3.4028235e+38,
DefaultMin: 0,
Max: 3.4028235e+38,
Min: 0,
Name: "minecraft:lava_movement",
},
{
Base: 16,
Current: 16,
DefaultMax: 2048,
DefaultMin: 0,
Max: 2048,
Min: 0,
Name: "minecraft:follow_range",
},
{
Base: 1,
Current: 1,
DefaultMax: 1,
DefaultMin: 1,
Max: 1,
Min: 1,
Name: "minecraft:attack_damage",
},
{
Base: 20,
Current: 20,
DefaultMax: 20,
DefaultMin: 0,
Max: 20,
Min: 0,
Name: "minecraft:player.hunger",
},
{
Base: 0,
Current: 0,
DefaultMax: 20,
DefaultMin: 0,
Max: 20,
Min: 0,
Name: "minecraft:player.exhaustion",
},
{
Base: 5,
Current: 5,
DefaultMax: 20,
DefaultMin: 0,
Max: 20,
Min: 0,
Name: "minecraft:player.saturation",
},
{
Base: 0,
Current: 0,
DefaultMax: 24791,
DefaultMin: 0,
Max: 24791,
Min: 0,
Name: "minecraft:player.level",
},
{
Base: 0,
Current: 0,
DefaultMax: 1,
DefaultMin: 0,
Max: 1,
Min: 0,
Name: "minecraft:player.experience",
},
}
ret["Tags"] = []string{}
ret["OnGround"] = true
spawn := w.proxy.Server.GameData().PlayerPosition
ret["SpawnX"] = int32(spawn.X())
ret["SpawnY"] = int32(spawn.Y())
ret["SpawnZ"] = int32(spawn.Z())
ret["Pos"] = []float32{
float32(spawn.X()),
float32(spawn.Y()),
float32(spawn.Z()),
}
ret["Rotation"] = []float32{
w.PlayerPos.Pitch,
w.PlayerPos.Yaw,
}
return
}

View File

@ -192,6 +192,7 @@ func (c *WorldCMD) Execute(ctx context.Context, ui utils.UI) error {
return err
}
w.SaveAndReset()
ui.Message(messages.SetUIState, messages.UIStateFinished)
return nil
}
@ -292,6 +293,10 @@ func (w *WorldState) SaveAndReset() {
}
logrus.Infof(locale.Loc("saving_world", locale.Strmap{"Name": w.WorldName, "Count": len(w.chunks)}))
w.gui.Message(messages.SavingWorld, messages.SavingWorldPayload{
Name: w.WorldName,
Chunks: len(w.chunks),
})
// open world
folder := path.Join("worlds", fmt.Sprintf("%s/%s", w.ServerName, w.WorldName))
@ -335,21 +340,17 @@ func (w *WorldState) SaveAndReset() {
}
}
/*
err = provider.SaveLocalPlayerData(playerData(w.playerInventory))
if err != nil {
logrus.Error(err)
}
*/
playerPos := w.proxy.Server.GameData().PlayerPosition
spawnPos := cube.Pos{int(playerPos.X()), int(playerPos.Y()), int(playerPos.Z())}
err = provider.SaveLocalPlayerData(w.playerData())
if err != nil {
logrus.Error(err)
}
// write metadata
s := provider.Settings()
player := w.proxy.Server.GameData().PlayerPosition
s.Spawn = cube.Pos{
int(player.X()),
int(player.Y()),
int(player.Z()),
}
s.Spawn = spawnPos
s.Name = w.WorldName
// set gamerules
@ -536,6 +537,7 @@ func (w *WorldState) SaveAndReset() {
logrus.Info(locale.Loc("saved", locale.Strmap{"Name": filename}))
//os.RemoveAll(folder)
w.Reset()
w.gui.Message(messages.SetUIState, messages.UIStateMain)
}
func (w *WorldState) OnConnect(err error) bool {

View File

@ -118,9 +118,9 @@ func (p *Page) handler(name string, data interface{}) messages.MessageResponse {
p.l.Lock()
new_skin := data.(messages.NewSkinPayload)
p.Skins = append(p.Skins, new_skin)
r.Ok = true
p.l.Unlock()
p.Router.Invalidate()
r.Ok = true
}
return r
}

View File

@ -1,8 +1,13 @@
package worlds
import (
"fmt"
"image"
"sync"
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
"gioui.org/x/component"
"github.com/bedrock-tool/bedrocktool/ui/gui"
@ -23,12 +28,21 @@ type Page struct {
chunkCount int
voidGen bool
worldName string
worldsList widget.List
worlds []messages.SavingWorldPayload
l sync.Mutex
}
func New(router *pages.Router) *Page {
return &Page{
Router: router,
worldMap: &Map{},
worldsList: widget.List{
List: layout.List{
Axis: layout.Vertical,
},
},
}
}
@ -69,14 +83,36 @@ func (p *Page) Layout(gtx C, th *material.Theme) D {
return layout.Flex{
Axis: layout.Vertical,
}.Layout(gtx,
layout.Rigid(material.Label(th, 20, "World Downloader Basic UI").Layout),
layout.Flexed(1, func(gtx C) D {
return layout.Center.Layout(gtx, p.worldMap.Layout)
}),
)
case messages.UIStateFinished:
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D {
return layout.UniformInset(20).
Layout(gtx, material.Label(th, 20, "Worlds Saved").Layout)
}),
layout.Flexed(1, func(gtx C) D {
p.l.Lock()
defer p.l.Unlock()
return material.List(th, &p.worldsList).Layout(gtx, len(p.worlds), func(gtx C, index int) D {
entry := p.worlds[len(p.worlds)-index-1]
return layout.UniformInset(25).Layout(gtx, func(gtx C) D {
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
layout.Rigid(material.Label(th, th.TextSize, entry.Name).Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return layout.Dimensions{Size: image.Pt(20, 20)}
}),
layout.Rigid(material.Label(th, th.TextSize, fmt.Sprintf("%d chunks", entry.Chunks)).Layout),
)
})
})
}),
)
}
return layout.Flex{}.Layout(gtx)
return layout.Dimensions{}
}
func (u *Page) handler(name string, data interface{}) messages.MessageResponse {
@ -116,6 +152,13 @@ func (u *Page) handler(name string, data interface{}) messages.MessageResponse {
u.Router.Invalidate()
r.Ok = true
case messages.SavingWorld:
u.l.Lock()
saving_world := data.(messages.SavingWorldPayload)
u.worlds = append(u.worlds, saving_world)
u.l.Unlock()
u.Router.Invalidate()
r.Ok = true
}
return r
}

View File

@ -17,6 +17,7 @@ const (
UIStateConnect = iota
UIStateConnecting
UIStateMain
UIStateFinished
)
type HandlerFunc = func(name string, data interface{}) MessageResponse
@ -72,3 +73,10 @@ type NewSkinPayload struct {
PlayerName string
Skin *protocol.Skin
}
var SavingWorld = "saving_world"
type SavingWorldPayload struct {
Name string
Chunks int
}

View File

@ -114,9 +114,9 @@ func dmpStruct(level int, inputStruct any, withType bool, isInList bool) (s stri
if ii.Len() > 1000 {
s += "[<slice too long>]"
} else if ii.Len() == 0 {
s += typeString + "[]"
s += fmt.Sprintf("[0%s", typeName[1:])
} else {
s += typeString + "["
s += fmt.Sprintf("[%d%s{", ii.Len(), typeString[1:])
if is_elem_struct {
s += "\n"
}