Phase4
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 9s
CI / Go — node-agent tests (push) Failing after 9s
CI / Go — edge-gateway build (push) Successful in 13s

This commit is contained in:
smueller
2026-06-26 12:32:27 +02:00
parent 9b061c3ee7
commit 4262464cd5
101 changed files with 4024 additions and 74 deletions

View File

@@ -0,0 +1,114 @@
package world
import (
"fmt"
"os"
"path/filepath"
"strings"
)
// Summary describes a discovered Minecraft world directory.
type Summary struct {
Name string `json:"name"`
Path string `json:"path"`
SizeBytes int64 `json:"sizeBytes"`
HasLevelDat bool `json:"hasLevelDat"`
}
// ValidateWorld checks that a world directory contains level.dat.
func ValidateWorld(dataPath, worldName string) error {
worldName = strings.TrimSpace(worldName)
if worldName == "" || strings.Contains(worldName, "..") || strings.ContainsAny(worldName, `/\`) {
return fmt.Errorf("invalid world name")
}
worldDir := filepath.Join(dataPath, worldName)
levelDat := filepath.Join(worldDir, "level.dat")
info, err := os.Stat(levelDat)
if err != nil {
return fmt.Errorf("level.dat not found in world directory")
}
if info.IsDir() {
return fmt.Errorf("level.dat is not a file")
}
return nil
}
// ListWorlds scans the server data directory for world folders.
func ListWorlds(dataPath, activeWorldName string) ([]Summary, error) {
entries, err := os.ReadDir(dataPath)
if err != nil {
return nil, err
}
worlds := make([]Summary, 0)
for _, entry := range entries {
if !entry.IsDir() || strings.HasPrefix(entry.Name(), ".") {
continue
}
worldPath := filepath.Join(dataPath, entry.Name())
levelDat := filepath.Join(worldPath, "level.dat")
hasLevelDat := false
if info, err := os.Stat(levelDat); err == nil && !info.IsDir() {
hasLevelDat = true
}
size, err := dirSize(worldPath)
if err != nil {
return nil, err
}
worlds = append(worlds, Summary{
Name: entry.Name(),
Path: entry.Name(),
SizeBytes: size,
HasLevelDat: hasLevelDat,
})
}
if activeWorldName != "" {
found := false
for _, world := range worlds {
if world.Name == activeWorldName {
found = true
break
}
}
if !found {
if err := ValidateWorld(dataPath, activeWorldName); err == nil {
size, sizeErr := dirSize(filepath.Join(dataPath, activeWorldName))
if sizeErr != nil {
return nil, sizeErr
}
worlds = append(worlds, Summary{
Name: activeWorldName,
Path: activeWorldName,
SizeBytes: size,
HasLevelDat: true,
})
}
}
}
return worlds, nil
}
func dirSize(root string) (int64, error) {
var total int64
err := filepath.Walk(root, func(_ string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
total += info.Size()
}
return nil
})
return total, err
}