Support convert advancements and pets' owner
This commit is contained in:
120
examples/playerdataconvert/playerdata.go
Normal file
120
examples/playerdataconvert/playerdata.go
Normal file
@ -0,0 +1,120 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Tnze/go-mc/nbt"
|
||||
"github.com/Tnze/go-mc/nbt/dynbt"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func readPlayerdata(dir string, m map[uuid.UUID]UserCache) {
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to open playerdata folder: %v", err)
|
||||
return
|
||||
}
|
||||
for _, files := range entries {
|
||||
filename := files.Name()
|
||||
if ext := filepath.Ext(filename); ext != ".dat" {
|
||||
fmt.Fprintf(os.Stderr, "Unkown file type: %s\n", ext)
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse old UUID from filename
|
||||
oldID, err := uuid.Parse(strings.TrimSuffix(filename, ".dat"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to parse filename as uuid: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
nbtdata, err := readNbtData(filepath.Join(dir, filename))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to read %s nbt data\n", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
// Read old UUID from nbt
|
||||
uuidInts := nbtdata.Get("UUID").IntArray()
|
||||
uuidBytes, err := intArrayToUUID(uuidInts)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to read %s UUID\n", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
// Does they matche?
|
||||
if oldID != uuidBytes {
|
||||
fmt.Fprintf(os.Stderr, "UUID in filename and nbt data don't match, what happend?\n")
|
||||
}
|
||||
|
||||
if ver := uuidBytes.Version(); ver != 3 { // v3 is for offline players
|
||||
fmt.Printf("Ignoring UUID: %v version: %d\n", uuidBytes, ver)
|
||||
continue
|
||||
}
|
||||
|
||||
newUser, ok := m[oldID]
|
||||
if !ok {
|
||||
fmt.Printf("Skip user: %v\n", oldID)
|
||||
continue
|
||||
}
|
||||
|
||||
// Update UUID
|
||||
ints := uuidToIntArray(newUser.UUID)
|
||||
nbtdata.Set("UUID", dynbt.NewIntArray(ints[:]))
|
||||
|
||||
// Create new .dat file
|
||||
err = writeNbtData(dir, newUser.UUID.String(), &nbtdata)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to write %s's .dat file: %v\n", newUser.Name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readNbtData(filepath string) (nbtdata dynbt.Value, err error) {
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return nbtdata, fmt.Errorf("failed to open userdata: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
r, err := gzip.NewReader(file)
|
||||
if err != nil {
|
||||
return nbtdata, fmt.Errorf("failed to decompress userdata: %w", err)
|
||||
}
|
||||
|
||||
_, err = nbt.NewDecoder(r).Decode(&nbtdata)
|
||||
if err != nil {
|
||||
return nbtdata, fmt.Errorf("failed to parse userdata: %w", err)
|
||||
}
|
||||
return nbtdata, nil
|
||||
}
|
||||
|
||||
func writeNbtData(dir string, id string, nbtdata *dynbt.Value) error {
|
||||
newDatFilePath := filepath.Join(dir, id+".dat")
|
||||
file, err := os.Create(newDatFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w := gzip.NewWriter(file)
|
||||
err = nbt.NewEncoder(w).Encode(&nbtdata, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user