small cleanup
This commit is contained in:
parent
aa73c86d11
commit
87cd32e280
|
@ -8,7 +8,8 @@ assignees: ''
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is,
|
||||||
|
and what server it occurs on.
|
||||||
|
|
||||||
**To Reproduce**
|
**To Reproduce**
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
|
@ -24,15 +25,20 @@ A clear and concise description of what you expected to happen.
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Desktop (please complete the following information):**
|
**Desktop (please complete the following information):**
|
||||||
- OS: [e.g. iOS]
|
- OS: [e.g. windows]
|
||||||
- Browser [e.g. chrome, safari]
|
- Version [e.g. 1.28.0-36]
|
||||||
- Version [e.g. 22]
|
- Minecraft Version [e.g. 1.19.73]
|
||||||
|
|
||||||
**Smartphone (please complete the following information):**
|
**Smartphone (please complete the following information):**
|
||||||
- Device: [e.g. iPhone6]
|
- Device: [e.g. iPhone6]
|
||||||
- OS: [e.g. iOS8.1]
|
- OS: [e.g. iOS12]
|
||||||
- Browser [e.g. stock browser, safari]
|
- Version [e.g. 1.28.0-36]
|
||||||
- Version [e.g. 22]
|
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
|
||||||
|
|
||||||
|
**attach packets.log.gpg (not always necessary)**
|
||||||
|
this file can be helpful for debugging without having to connect to the server.
|
||||||
|
it can be created by running with -extra-debug [e.g. bedrocktool.exe -extra-debug worlds -address play.mojang.com ]
|
||||||
|
be sure to only attach the .gpg file which is not publicly readable.
|
|
@ -231,6 +231,7 @@ func NewDebugLogger(extraVerbose bool) *utils.ProxyHandler {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
OnEnd: func() {
|
OnEnd: func() {
|
||||||
|
dmpLock.Lock()
|
||||||
if packetsLogF != nil {
|
if packetsLogF != nil {
|
||||||
packetsLogF.Flush()
|
packetsLogF.Flush()
|
||||||
}
|
}
|
||||||
|
@ -243,6 +244,7 @@ func NewDebugLogger(extraVerbose bool) *utils.ProxyHandler {
|
||||||
if logCrypt != nil {
|
if logCrypt != nil {
|
||||||
logCrypt.Close()
|
logCrypt.Close()
|
||||||
}
|
}
|
||||||
|
dmpLock.Unlock()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *worldsHandler) processChangeDimension(pk *packet.ChangeDimension) {
|
func (w *worldsHandler) processChangeDimension(pk *packet.ChangeDimension) {
|
||||||
if len(w.worldState.chunks) > 0 {
|
w.SaveAndReset()
|
||||||
w.SaveAndReset()
|
|
||||||
} else {
|
|
||||||
logrus.Info(locale.Loc("not_saving_empty", nil))
|
|
||||||
w.Reset(w.CurrentName())
|
|
||||||
}
|
|
||||||
dimensionID := pk.Dimension
|
dimensionID := pk.Dimension
|
||||||
if w.serverState.ispre118 && dimensionID == 0 {
|
if w.serverState.ispre118 && dimensionID == 0 {
|
||||||
dimensionID += 10
|
dimensionID += 10
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
const ViewMapID = 0x424242
|
const ViewMapID = 0x424242
|
||||||
|
|
||||||
// MapItemPacket tells the client that it has a map with id 0x424242 in the offhand
|
// MapItemPacket tells the client that it has a map with id 0x424242 in the offhand
|
||||||
var MapItemPacket packet.InventoryContent = packet.InventoryContent{
|
var MapItemPacket = packet.InventoryContent{
|
||||||
WindowID: 119,
|
WindowID: 119,
|
||||||
Content: []protocol.ItemInstance{
|
Content: []protocol.ItemInstance{
|
||||||
{
|
{
|
||||||
|
@ -112,9 +112,6 @@ func (m *MapUI) Start() {
|
||||||
MapID: ViewMapID,
|
MapID: ViewMapID,
|
||||||
Scale: 4,
|
Scale: 4,
|
||||||
MapsIncludedIn: []int64{ViewMapID},
|
MapsIncludedIn: []int64{ViewMapID},
|
||||||
Width: 0,
|
|
||||||
Height: 0,
|
|
||||||
Pixels: nil,
|
|
||||||
UpdateFlags: packet.MapUpdateFlagInitialisation,
|
UpdateFlags: packet.MapUpdateFlagInitialisation,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -248,7 +245,7 @@ func (m *MapUI) ToImage() *image.RGBA {
|
||||||
chunksX := int(max[0] - min[0] + 1) // how many chunk lengths is x coordinate
|
chunksX := int(max[0] - min[0] + 1) // how many chunk lengths is x coordinate
|
||||||
chunksY := int(max[1] - min[1] + 1)
|
chunksY := int(max[1] - min[1] + 1)
|
||||||
|
|
||||||
img2 := image.NewRGBA(image.Rect(0, 0, chunksX*16, chunksY*16))
|
img := image.NewRGBA(image.Rect(0, 0, chunksX*16, chunksY*16))
|
||||||
|
|
||||||
m.l.RLock()
|
m.l.RLock()
|
||||||
for pos, tile := range m.renderedChunks {
|
for pos, tile := range m.renderedChunks {
|
||||||
|
@ -256,13 +253,13 @@ func (m *MapUI) ToImage() *image.RGBA {
|
||||||
int((pos.X()-min.X())*16),
|
int((pos.X()-min.X())*16),
|
||||||
int((pos.Z()-min.Z())*16),
|
int((pos.Z()-min.Z())*16),
|
||||||
)
|
)
|
||||||
draw.Draw(img2, image.Rect(
|
draw.Draw(img, image.Rect(
|
||||||
px.X, px.Y,
|
px.X, px.Y,
|
||||||
px.X+16, px.Y+16,
|
px.X+16, px.Y+16,
|
||||||
), tile, image.Point{}, draw.Src)
|
), tile, image.Point{}, draw.Src)
|
||||||
}
|
}
|
||||||
m.l.RUnlock()
|
m.l.RUnlock()
|
||||||
return img2
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk, complete bool) {
|
func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk, complete bool) {
|
||||||
|
|
|
@ -4,12 +4,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
"image/png"
|
"image/png"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bedrock-tool/bedrocktool/locale"
|
"github.com/bedrock-tool/bedrocktool/locale"
|
||||||
|
@ -72,6 +74,7 @@ type serverState struct {
|
||||||
|
|
||||||
type worldsHandler struct {
|
type worldsHandler struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
wg sync.WaitGroup
|
||||||
proxy *utils.ProxyContext
|
proxy *utils.ProxyContext
|
||||||
mapUI *MapUI
|
mapUI *MapUI
|
||||||
gui utils.UI
|
gui utils.UI
|
||||||
|
@ -97,7 +100,7 @@ func NewWorldsHandler(ctx context.Context, ui utils.UI, settings WorldSettings)
|
||||||
settings: settings,
|
settings: settings,
|
||||||
}
|
}
|
||||||
w.mapUI = NewMapUI(w)
|
w.mapUI = NewMapUI(w)
|
||||||
w.Reset(w.CurrentName())
|
w.Reset()
|
||||||
|
|
||||||
return &utils.ProxyHandler{
|
return &utils.ProxyHandler{
|
||||||
Name: "Worlds",
|
Name: "Worlds",
|
||||||
|
@ -169,6 +172,7 @@ func NewWorldsHandler(ctx context.Context, ui utils.UI, settings WorldSettings)
|
||||||
},
|
},
|
||||||
OnEnd: func() {
|
OnEnd: func() {
|
||||||
w.SaveAndReset()
|
w.SaveAndReset()
|
||||||
|
w.wg.Wait()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +207,7 @@ func (w *worldsHandler) setWorldName(val string, fromUI bool) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worldsHandler) CurrentName() string {
|
func (w *worldsHandler) currentName() string {
|
||||||
worldName := "world"
|
worldName := "world"
|
||||||
if w.serverState.worldCounter > 0 {
|
if w.serverState.worldCounter > 0 {
|
||||||
worldName = fmt.Sprintf("world-%d", w.serverState.worldCounter)
|
worldName = fmt.Sprintf("world-%d", w.serverState.worldCounter)
|
||||||
|
@ -211,14 +215,14 @@ func (w *worldsHandler) CurrentName() string {
|
||||||
return worldName
|
return worldName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worldsHandler) Reset(newName string) {
|
func (w *worldsHandler) Reset() {
|
||||||
w.worldState = worldState{
|
w.worldState = worldState{
|
||||||
dimension: w.worldState.dimension,
|
dimension: w.worldState.dimension,
|
||||||
chunks: make(map[protocol.ChunkPos]*chunk.Chunk),
|
chunks: make(map[protocol.ChunkPos]*chunk.Chunk),
|
||||||
blockNBT: make(map[protocol.SubChunkPos][]map[string]any),
|
blockNBT: make(map[protocol.SubChunkPos][]map[string]any),
|
||||||
entities: make(map[uint64]*entityState),
|
entities: make(map[uint64]*entityState),
|
||||||
openItemContainers: make(map[byte]*itemContainer),
|
openItemContainers: make(map[byte]*itemContainer),
|
||||||
Name: newName,
|
Name: w.currentName(),
|
||||||
}
|
}
|
||||||
w.mapUI.Reset()
|
w.mapUI.Reset()
|
||||||
}
|
}
|
||||||
|
@ -280,155 +284,171 @@ func (w *worldState) Save(folder string) (*mcdb.DB, error) {
|
||||||
return provider, err
|
return provider, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveAndReset writes the world to a folder, resets all the chunks
|
|
||||||
func (w *worldsHandler) SaveAndReset() {
|
func (w *worldsHandler) SaveAndReset() {
|
||||||
w.worldState.cullChunks()
|
w.worldState.cullChunks()
|
||||||
if len(w.worldState.chunks) == 0 {
|
if len(w.worldState.chunks) == 0 {
|
||||||
w.Reset(w.CurrentName())
|
w.Reset()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Infof(locale.Loc("saving_world", locale.Strmap{"Name": w.worldState.Name, "Count": len(w.worldState.chunks)}))
|
worldStateCopy := w.worldState
|
||||||
w.gui.Message(messages.SavingWorld{
|
playerData := w.playerData()
|
||||||
Name: w.worldState.Name,
|
|
||||||
Chunks: len(w.worldState.chunks),
|
|
||||||
})
|
|
||||||
|
|
||||||
// open world
|
|
||||||
folder := path.Join("worlds", fmt.Sprintf("%s/%s", w.serverState.Name, w.worldState.Name))
|
|
||||||
os.RemoveAll(folder)
|
|
||||||
os.MkdirAll(folder, 0o777)
|
|
||||||
provider, err := w.worldState.Save(folder)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = provider.SaveLocalPlayerData(w.playerData())
|
|
||||||
if err != nil {
|
|
||||||
logrus.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
playerPos := w.serverState.PlayerPos.Position
|
playerPos := w.serverState.PlayerPos.Position
|
||||||
spawnPos := cube.Pos{int(playerPos.X()), int(playerPos.Y()), int(playerPos.Z())}
|
spawnPos := cube.Pos{int(playerPos.X()), int(playerPos.Y()), int(playerPos.Z())}
|
||||||
|
|
||||||
// write metadata
|
var img image.Image
|
||||||
s := provider.Settings()
|
if w.settings.SaveImage {
|
||||||
s.Spawn = spawnPos
|
img = w.mapUI.ToImage()
|
||||||
s.Name = w.worldState.Name
|
|
||||||
|
|
||||||
// set gamerules
|
|
||||||
ld := provider.LevelDat()
|
|
||||||
gd := w.proxy.Server.GameData()
|
|
||||||
ld.RandomSeed = int64(gd.WorldSeed)
|
|
||||||
for _, gr := range gd.GameRules {
|
|
||||||
switch gr.Name {
|
|
||||||
case "commandblockoutput":
|
|
||||||
ld.CommandBlockOutput = gr.Value.(bool)
|
|
||||||
case "maxcommandchainlength":
|
|
||||||
ld.MaxCommandChainLength = int32(gr.Value.(uint32))
|
|
||||||
case "commandblocksenabled":
|
|
||||||
ld.CommandsEnabled = gr.Value.(bool)
|
|
||||||
case "dodaylightcycle":
|
|
||||||
ld.DoDayLightCycle = gr.Value.(bool)
|
|
||||||
case "doentitydrops":
|
|
||||||
ld.DoEntityDrops = gr.Value.(bool)
|
|
||||||
case "dofiretick":
|
|
||||||
ld.DoFireTick = gr.Value.(bool)
|
|
||||||
case "domobloot":
|
|
||||||
ld.DoMobLoot = gr.Value.(bool)
|
|
||||||
case "domobspawning":
|
|
||||||
ld.DoMobSpawning = gr.Value.(bool)
|
|
||||||
case "dotiledrops":
|
|
||||||
ld.DoTileDrops = gr.Value.(bool)
|
|
||||||
case "doweathercycle":
|
|
||||||
ld.DoWeatherCycle = gr.Value.(bool)
|
|
||||||
case "drowningdamage":
|
|
||||||
ld.DrowningDamage = gr.Value.(bool)
|
|
||||||
case "doinsomnia":
|
|
||||||
ld.DoInsomnia = gr.Value.(bool)
|
|
||||||
case "falldamage":
|
|
||||||
ld.FallDamage = gr.Value.(bool)
|
|
||||||
case "firedamage":
|
|
||||||
ld.FireDamage = gr.Value.(bool)
|
|
||||||
case "keepinventory":
|
|
||||||
ld.KeepInventory = gr.Value.(bool)
|
|
||||||
case "mobgriefing":
|
|
||||||
ld.MobGriefing = gr.Value.(bool)
|
|
||||||
case "pvp":
|
|
||||||
ld.PVP = gr.Value.(bool)
|
|
||||||
case "showcoordinates":
|
|
||||||
ld.ShowCoordinates = gr.Value.(bool)
|
|
||||||
case "naturalregeneration":
|
|
||||||
ld.NaturalRegeneration = gr.Value.(bool)
|
|
||||||
case "tntexplodes":
|
|
||||||
ld.TNTExplodes = gr.Value.(bool)
|
|
||||||
case "sendcommandfeedback":
|
|
||||||
ld.SendCommandFeedback = gr.Value.(bool)
|
|
||||||
case "randomtickspeed":
|
|
||||||
ld.RandomTickSpeed = int32(gr.Value.(uint32))
|
|
||||||
case "doimmediaterespawn":
|
|
||||||
ld.DoImmediateRespawn = gr.Value.(bool)
|
|
||||||
case "showdeathmessages":
|
|
||||||
ld.ShowDeathMessages = gr.Value.(bool)
|
|
||||||
case "functioncommandlimit":
|
|
||||||
ld.FunctionCommandLimit = int32(gr.Value.(uint32))
|
|
||||||
case "spawnradius":
|
|
||||||
ld.SpawnRadius = int32(gr.Value.(uint32))
|
|
||||||
case "showtags":
|
|
||||||
ld.ShowTags = gr.Value.(bool)
|
|
||||||
case "freezedamage":
|
|
||||||
ld.FreezeDamage = gr.Value.(bool)
|
|
||||||
case "respawnblocksexplode":
|
|
||||||
ld.RespawnBlocksExplode = gr.Value.(bool)
|
|
||||||
case "showbordereffect":
|
|
||||||
ld.ShowBorderEffect = gr.Value.(bool)
|
|
||||||
// todo
|
|
||||||
default:
|
|
||||||
logrus.Warnf(locale.Loc("unknown_gamerule", locale.Strmap{"Name": gr.Name}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// void world
|
|
||||||
if w.settings.VoidGen {
|
|
||||||
ld.FlatWorldLayers = `{"biome_id":1,"block_layers":[{"block_data":0,"block_id":0,"count":1},{"block_data":0,"block_id":0,"count":2},{"block_data":0,"block_id":0,"count":1}],"encoding_version":3,"structure_options":null}`
|
|
||||||
ld.Generator = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if w.bp.HasContent() {
|
|
||||||
if ld.Experiments == nil {
|
|
||||||
ld.Experiments = map[string]any{}
|
|
||||||
}
|
|
||||||
ld.Experiments["data_driven_items"] = true
|
|
||||||
ld.Experiments["experiments_ever_used"] = true
|
|
||||||
ld.Experiments["saved_with_toggled_experiments"] = true
|
|
||||||
}
|
|
||||||
ld.RandomTickSpeed = 0
|
|
||||||
s.CurrentTick = 0
|
|
||||||
provider.SaveSettings(s)
|
|
||||||
if err = provider.Close(); err != nil {
|
|
||||||
logrus.Error(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.serverState.worldCounter += 1
|
w.serverState.worldCounter += 1
|
||||||
|
w.Reset()
|
||||||
|
w.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer w.wg.Done()
|
||||||
|
logrus.Infof(locale.Loc("saving_world", locale.Strmap{"Name": worldStateCopy.Name, "Count": len(worldStateCopy.chunks)}))
|
||||||
|
w.gui.Message(messages.SavingWorld{
|
||||||
|
Name: w.worldState.Name,
|
||||||
|
Chunks: len(w.worldState.chunks),
|
||||||
|
})
|
||||||
|
|
||||||
if w.settings.SaveImage {
|
// open world
|
||||||
f, _ := os.Create(folder + ".png")
|
folder := fmt.Sprintf("worlds/%s/%s", w.serverState.Name, worldStateCopy.Name)
|
||||||
png.Encode(f, w.mapUI.ToImage())
|
os.RemoveAll(folder)
|
||||||
f.Close()
|
os.MkdirAll(folder, 0o777)
|
||||||
}
|
provider, err := worldStateCopy.Save(folder)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
w.AddPacks(folder)
|
err = provider.SaveLocalPlayerData(playerData)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// zip it
|
// write metadata
|
||||||
filename := folder + ".mcworld"
|
s := provider.Settings()
|
||||||
if err := utils.ZipFolder(filename, folder); err != nil {
|
s.Spawn = spawnPos
|
||||||
logrus.Error(err)
|
s.Name = worldStateCopy.Name
|
||||||
}
|
|
||||||
logrus.Info(locale.Loc("saved", locale.Strmap{"Name": filename}))
|
// set gamerules
|
||||||
//os.RemoveAll(folder)
|
ld := provider.LevelDat()
|
||||||
w.Reset(w.CurrentName())
|
gd := w.proxy.Server.GameData()
|
||||||
w.gui.Message(messages.SetUIState(messages.UIStateMain))
|
ld.RandomSeed = int64(gd.WorldSeed)
|
||||||
|
for _, gr := range gd.GameRules {
|
||||||
|
switch gr.Name {
|
||||||
|
case "commandblockoutput":
|
||||||
|
ld.CommandBlockOutput = gr.Value.(bool)
|
||||||
|
case "maxcommandchainlength":
|
||||||
|
ld.MaxCommandChainLength = int32(gr.Value.(uint32))
|
||||||
|
case "commandblocksenabled":
|
||||||
|
ld.CommandsEnabled = gr.Value.(bool)
|
||||||
|
case "dodaylightcycle":
|
||||||
|
ld.DoDayLightCycle = gr.Value.(bool)
|
||||||
|
case "doentitydrops":
|
||||||
|
ld.DoEntityDrops = gr.Value.(bool)
|
||||||
|
case "dofiretick":
|
||||||
|
ld.DoFireTick = gr.Value.(bool)
|
||||||
|
case "domobloot":
|
||||||
|
ld.DoMobLoot = gr.Value.(bool)
|
||||||
|
case "domobspawning":
|
||||||
|
ld.DoMobSpawning = gr.Value.(bool)
|
||||||
|
case "dotiledrops":
|
||||||
|
ld.DoTileDrops = gr.Value.(bool)
|
||||||
|
case "doweathercycle":
|
||||||
|
ld.DoWeatherCycle = gr.Value.(bool)
|
||||||
|
case "drowningdamage":
|
||||||
|
ld.DrowningDamage = gr.Value.(bool)
|
||||||
|
case "doinsomnia":
|
||||||
|
ld.DoInsomnia = gr.Value.(bool)
|
||||||
|
case "falldamage":
|
||||||
|
ld.FallDamage = gr.Value.(bool)
|
||||||
|
case "firedamage":
|
||||||
|
ld.FireDamage = gr.Value.(bool)
|
||||||
|
case "keepinventory":
|
||||||
|
ld.KeepInventory = gr.Value.(bool)
|
||||||
|
case "mobgriefing":
|
||||||
|
ld.MobGriefing = gr.Value.(bool)
|
||||||
|
case "pvp":
|
||||||
|
ld.PVP = gr.Value.(bool)
|
||||||
|
case "showcoordinates":
|
||||||
|
ld.ShowCoordinates = gr.Value.(bool)
|
||||||
|
case "naturalregeneration":
|
||||||
|
ld.NaturalRegeneration = gr.Value.(bool)
|
||||||
|
case "tntexplodes":
|
||||||
|
ld.TNTExplodes = gr.Value.(bool)
|
||||||
|
case "sendcommandfeedback":
|
||||||
|
ld.SendCommandFeedback = gr.Value.(bool)
|
||||||
|
case "randomtickspeed":
|
||||||
|
ld.RandomTickSpeed = int32(gr.Value.(uint32))
|
||||||
|
case "doimmediaterespawn":
|
||||||
|
ld.DoImmediateRespawn = gr.Value.(bool)
|
||||||
|
case "showdeathmessages":
|
||||||
|
ld.ShowDeathMessages = gr.Value.(bool)
|
||||||
|
case "functioncommandlimit":
|
||||||
|
ld.FunctionCommandLimit = int32(gr.Value.(uint32))
|
||||||
|
case "spawnradius":
|
||||||
|
ld.SpawnRadius = int32(gr.Value.(uint32))
|
||||||
|
case "showtags":
|
||||||
|
ld.ShowTags = gr.Value.(bool)
|
||||||
|
case "freezedamage":
|
||||||
|
ld.FreezeDamage = gr.Value.(bool)
|
||||||
|
case "respawnblocksexplode":
|
||||||
|
ld.RespawnBlocksExplode = gr.Value.(bool)
|
||||||
|
case "showbordereffect":
|
||||||
|
ld.ShowBorderEffect = gr.Value.(bool)
|
||||||
|
// todo
|
||||||
|
default:
|
||||||
|
logrus.Warnf(locale.Loc("unknown_gamerule", locale.Strmap{"Name": gr.Name}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void world
|
||||||
|
if w.settings.VoidGen {
|
||||||
|
ld.FlatWorldLayers = `{"biome_id":1,"block_layers":[{"block_data":0,"block_id":0,"count":1},{"block_data":0,"block_id":0,"count":2},{"block_data":0,"block_id":0,"count":1}],"encoding_version":3,"structure_options":null}`
|
||||||
|
ld.Generator = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
ld.RandomTickSpeed = 0
|
||||||
|
s.CurrentTick = 0
|
||||||
|
|
||||||
|
if w.bp.HasContent() {
|
||||||
|
if ld.Experiments == nil {
|
||||||
|
ld.Experiments = map[string]any{}
|
||||||
|
}
|
||||||
|
ld.Experiments["data_driven_items"] = true
|
||||||
|
ld.Experiments["experiments_ever_used"] = true
|
||||||
|
ld.Experiments["saved_with_toggled_experiments"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
provider.SaveSettings(s)
|
||||||
|
err = provider.Close()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.settings.SaveImage {
|
||||||
|
f, _ := os.Create(folder + ".png")
|
||||||
|
png.Encode(f, img)
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
w.AddPacks(folder)
|
||||||
|
|
||||||
|
// zip it
|
||||||
|
filename := folder + ".mcworld"
|
||||||
|
err = utils.ZipFolder(filename, folder)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logrus.Info(locale.Loc("saved", locale.Strmap{"Name": filename}))
|
||||||
|
//os.RemoveAll(folder)
|
||||||
|
w.gui.Message(messages.SetUIState(messages.UIStateMain))
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *worldsHandler) AddPacks(folder string) {
|
func (w *worldsHandler) AddPacks(folder string) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ func loadPng(path string) (*image.RGBA, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return (*image.RGBA)(img.(*image.NRGBA)), err
|
return (*image.RGBA)(img.(*image.NRGBA)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LERP is a linear interpolation function
|
// LERP is a linear interpolation function
|
||||||
|
|
|
@ -53,12 +53,12 @@ type (
|
||||||
|
|
||||||
type ProxyHandler struct {
|
type ProxyHandler struct {
|
||||||
Name string
|
Name string
|
||||||
ProxyRef func(*ProxyContext)
|
ProxyRef func(pc *ProxyContext)
|
||||||
//
|
//
|
||||||
AddressAndName func(address, hostname string) error
|
AddressAndName func(address, hostname string) error
|
||||||
|
|
||||||
// called to change game data
|
// called to change game data
|
||||||
GameDataModifier func(*minecraft.GameData)
|
GameDataModifier func(gd *minecraft.GameData)
|
||||||
|
|
||||||
// called for every packet
|
// called for every packet
|
||||||
PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr)
|
PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr)
|
||||||
|
@ -210,9 +210,9 @@ func (p *ProxyContext) AddHandler(handler *ProxyHandler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProxyContext) CommandHandlerPacketCB(pk packet.Packet, toServer bool, _ time.Time) (packet.Packet, error) {
|
func (p *ProxyContext) CommandHandlerPacketCB(pk packet.Packet, toServer bool, _ time.Time) (packet.Packet, error) {
|
||||||
switch _pk := pk.(type) {
|
switch pk := pk.(type) {
|
||||||
case *packet.CommandRequest:
|
case *packet.CommandRequest:
|
||||||
cmd := strings.Split(_pk.CommandLine, " ")
|
cmd := strings.Split(pk.CommandLine, " ")
|
||||||
name := cmd[0][1:]
|
name := cmd[0][1:]
|
||||||
if h, ok := p.commands[name]; ok {
|
if h, ok := p.commands[name]; ok {
|
||||||
if h.Exec(cmd[1:]) {
|
if h.Exec(cmd[1:]) {
|
||||||
|
@ -220,13 +220,13 @@ func (p *ProxyContext) CommandHandlerPacketCB(pk packet.Packet, toServer bool, _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *packet.AvailableCommands:
|
case *packet.AvailableCommands:
|
||||||
cmds := make([]protocol.Command, len(p.commands))
|
cmds := make([]protocol.Command, 0, len(p.commands))
|
||||||
for _, ic := range p.commands {
|
for _, ic := range p.commands {
|
||||||
cmds = append(cmds, ic.Cmd)
|
cmds = append(cmds, ic.Cmd)
|
||||||
}
|
}
|
||||||
pk = &packet.AvailableCommands{
|
pk = &packet.AvailableCommands{
|
||||||
Constraints: _pk.Constraints,
|
Constraints: pk.Constraints,
|
||||||
Commands: append(_pk.Commands, cmds...),
|
Commands: append(pk.Commands, cmds...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pk, nil
|
return pk, nil
|
||||||
|
@ -321,9 +321,9 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
||||||
logrus.Infof(locale.Locm("pack_count_loaded", locale.Strmap{"Count": len(packs)}, len(packs)))
|
logrus.Infof(locale.Locm("pack_count_loaded", locale.Strmap{"Count": len(packs)}, len(packs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
_status := minecraft.NewStatusProvider("Server")
|
status := minecraft.NewStatusProvider(fmt.Sprintf("%s Proxy", name))
|
||||||
p.Listener, err = minecraft.ListenConfig{
|
p.Listener, err = minecraft.ListenConfig{
|
||||||
StatusProvider: _status,
|
StatusProvider: status,
|
||||||
ResourcePacks: packs,
|
ResourcePacks: packs,
|
||||||
AcceptedProtocols: []minecraft.Protocol{
|
AcceptedProtocols: []minecraft.Protocol{
|
||||||
//dummyProto{id: 567, ver: "1.19.60"},
|
//dummyProto{id: 567, ver: "1.19.60"},
|
||||||
|
|
Loading…
Reference in New Issue