summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/data.go36
-rw-r--r--server/level.go51
-rw-r--r--server/player.go3
-rw-r--r--server/server.go25
-rw-r--r--world/1787964105.tmp0
-rw-r--r--world/level/0.binbin18106 -> 0 bytes
-rw-r--r--world/player/Oivee.binbin30 -> 0 bytes
-rw-r--r--world/player/citrons.binbin30 -> 0 bytes
-rw-r--r--world/player/gideonnav.binbin30 -> 0 bytes
9 files changed, 71 insertions, 44 deletions
diff --git a/server/data.go b/server/data.go
index b7ed280..331ac38 100644
--- a/server/data.go
+++ b/server/data.go
@@ -2,7 +2,8 @@ package server
import (
"os"
- "encoding/binary"
+ "bufio"
+ "encoding/json"
"git.citrons.xyz/metronode/phony"
)
@@ -53,13 +54,14 @@ func (f atomicWriter) Close() error {
}
func saveDataFile[T any](from phony.Actor, name string, data T) {
- f, err := createAtomic(from, "world/" + name + ".bin")
+ f, err := createAtomic(from, "world/" + name + ".json")
if err != nil {
dataManager.errHand.OnSaveError(from, err)
return
}
defer f.Close()
- err = binary.Write(f, binary.BigEndian, data)
+ enc := json.NewEncoder(f)
+ err = enc.Encode(data)
if err != nil {
dataManager.errHand.OnSaveError(from, err)
}
@@ -68,7 +70,14 @@ func saveDataFile[T any](from phony.Actor, name string, data T) {
func loadDataFile[T any](
from phony.Actor, name string, reply func(data T, ok bool)) {
dataManager.Act(from, func() {
- f, err := os.Open("world/" + name + ".bin")
+ var (
+ data T
+ f *os.File
+ err error
+ )
+ defer from.Act(nil, func() {reply(data, err == nil)})
+
+ f, err = os.Open("world/" + name + ".json")
if err != nil {
if !os.IsNotExist(err) {
dataManager.errHand.OnLoadError(&dataManager, err)
@@ -76,12 +85,25 @@ func loadDataFile[T any](
return
}
defer f.Close()
- var data T
- err = binary.Read(f, binary.BigEndian, &data)
+
+ dec := json.NewDecoder(f)
+ err = dec.Decode(&data)
if err != nil {
dataManager.errHand.OnLoadError(&dataManager, err)
+ return
}
- from.Act(nil, func() {reply(data, err == nil)})
})
}
+func readDataField(rd *bufio.Reader, data any) error {
+ line, err := rd.ReadBytes('\n')
+ if err != nil {
+ return err
+ }
+ return json.Unmarshal(line, data)
+}
+
+func writeDataField(wr *bufio.Writer, data any) error {
+ enc := json.NewEncoder(wr)
+ return enc.Encode(data)
+}
diff --git a/server/level.go b/server/level.go
index 577d0dc..f36babe 100644
--- a/server/level.go
+++ b/server/level.go
@@ -5,6 +5,7 @@ import (
"os"
"fmt"
"bytes"
+ "bufio"
"compress/gzip"
"encoding/binary"
"git.citrons.xyz/metronode/phony"
@@ -63,25 +64,23 @@ func (l *level) load() {
id := l.Id
dataManager.Act(l, func() {
f, err := os.Open(fmt.Sprintf("world/level/%d.bin", id))
- if l.OnLevelError(&dataManager, err) != nil {
+ if l.handleLoadError(err) != nil {
return
}
defer f.Close()
var (
+ rd = bufio.NewReader(f)
info levelInfo
blocks []byte
)
- err = binary.Read(f, binary.BigEndian, &info)
- if l.OnLevelError(&dataManager, err) != nil {
- return
- }
- z, err := gzip.NewReader(f)
- if l.OnLevelError(&dataManager, err) != nil {
+ readDataField(rd, &info)
+ z, err := gzip.NewReader(rd)
+ if l.handleLoadError(err) != nil {
return
}
z.Read(make([]byte, 4))
blocks, err = io.ReadAll(z)
- if l.OnLevelError(&dataManager, err) != nil {
+ if l.handleLoadError(err) != nil {
return
}
l.Act(&dataManager, func() {
@@ -97,25 +96,34 @@ func (l *level) load() {
}
}
-func (l *level) OnLevelError(from phony.Actor, err error) error {
+func (l *level) handleLoadError(err error) error {
if err == nil {
return err
}
- l.Act(from, func() {
+ l.Act(&dataManager, func() {
l.loadingState = levelUnloaded
dataManager.errHand.OnLoadError(l, err)
- errString := err.Error()
+ errString := "load level: " + err.Error()
if os.IsNotExist(err) {
errString = "level not found"
}
+ l.LevelError(nil, errString)
+ })
+ return err
+}
+
+func (l *level) LevelError(from phony.Actor, err string) {
+ l.Act(from, func() {
for player := range l.players {
- player.OnLevelError(l, errString, l.levelInfo)
+ player.OnLevelError(l, err, l.levelInfo)
}
})
- return err
}
func (l *level) save(done func()) {
+ if done != nil {
+ defer dataManager.Act(nil, done)
+ }
if l.loadingState != levelLoaded {
return
}
@@ -127,20 +135,15 @@ func (l *level) save(done func()) {
}
defer f.Close()
- err = binary.Write(f, binary.BigEndian, l.levelInfo)
- if err != nil {
- dataManager.errHand.OnSaveError(l, err)
- return
- }
+ wr := bufio.NewWriter(f)
+ writeDataField(wr, l.levelInfo)
data := l.compressLevelData()
- _, err = io.Copy(f, data)
- if err != nil {
+ defer data.Close()
+ io.Copy(wr, data)
+ if wr.Flush() != nil {
dataManager.errHand.OnSaveError(l, err)
return
}
- if done != nil {
- dataManager.Act(nil, done)
- }
}
func (l *level) blockIndex(pos blockPos) int {
@@ -155,7 +158,7 @@ func (l *level) getBlock(pos blockPos) blockType {
return blockType(l.blocks[l.blockIndex(pos)])
}
-func (l *level) compressLevelData() io.Reader {
+func (l *level) compressLevelData() io.ReadCloser {
rd, wr := io.Pipe()
data := bytes.NewReader(bytes.Clone(l.blocks))
go func() {
diff --git a/server/player.go b/server/player.go
index bc6ee38..7f64c58 100644
--- a/server/player.go
+++ b/server/player.go
@@ -149,8 +149,9 @@ func (p *player) OnPlayerMessage(from *Server, name string, message string) {
p.SendMessage(from, fmt.Sprintf("&7<&b%s&7>&f %s", name, message))
}
-func (p *player) OnLevelData(from *level, info levelInfo, data io.Reader) {
+func (p *player) OnLevelData(from *level, info levelInfo, data io.ReadCloser) {
p.Act(from, func() {
+ defer data.Close()
if from != p.level {
return
}
diff --git a/server/server.go b/server/server.go
index 13e06f6..8499301 100644
--- a/server/server.go
+++ b/server/server.go
@@ -6,7 +6,6 @@ import (
"log"
"fmt"
"time"
- "binary"
"os/signal"
"git.citrons.xyz/metronode/classic"
"git.citrons.xyz/metronode/phony"
@@ -58,14 +57,12 @@ func NewServer(info ServerInfo) *Server {
128*blockSize,
}
} else {
- f, err := os.Open("world/world.bin")
- if err != nil {
- log.Fatal(err)
- }
- err = binary.Read(f, binary.BigEndian, &s.worldState)
- if err != nil {
- log.Fatal("read world data: %s", err)
- }
+ loaded := make(chan worldState, 1)
+ loadDataFile(s, "world", func(state worldState, ok bool) {
+ loaded <- state
+ })
+ s.worldState = <-loaded
+ }
return s
}
@@ -117,10 +114,13 @@ func (s *Server) stop() {
)
checkSaved := func() {
if savedLevels >= len(s.levels) && savedPlayers >= len(s.players) {
- close(s.stopped)
for client := range s.clients {
client.Disconnect(s, "Shutting down...")
}
+ saveDataFile(s, "world", s.worldState)
+ dataManager.Act(s, func() {
+ close(s.stopped)
+ })
}
}
for _, player := range s.players {
@@ -143,6 +143,7 @@ func (s *Server) Stop(from phony.Actor) {
func (s *Server) Save(from phony.Actor) {
s.Act(from, func() {
+ saveDataFile(s, "world", s.worldState)
for _, player := range s.players {
player.Save(s, nil)
}
@@ -229,7 +230,7 @@ func (s *Server) NewPlayer(
func (s *Server) getLevel(lvl levelId) *level {
if s.levels[lvl] == nil {
- s.levels[lvl] = loadLevel(s, lvl, lvl == s.spawnLevel)
+ s.levels[lvl] = loadLevel(s, lvl, lvl == s.SpawnLevel)
}
return s.levels[lvl]
}
@@ -247,7 +248,7 @@ func (s *Server) GetLevel(
func (s *Server) SendToSpawn(from phony.Actor, pl *player) {
s.Act(from, func() {
- pl.ChangeLevel(s, s.spawnLevel, s.spawnPos)
+ pl.ChangeLevel(s, s.SpawnLevel, s.SpawnPos)
})
}
diff --git a/world/1787964105.tmp b/world/1787964105.tmp
deleted file mode 100644
index e69de29..0000000
--- a/world/1787964105.tmp
+++ /dev/null
diff --git a/world/level/0.bin b/world/level/0.bin
deleted file mode 100644
index b514ec1..0000000
--- a/world/level/0.bin
+++ /dev/null
Binary files differ
diff --git a/world/player/Oivee.bin b/world/player/Oivee.bin
deleted file mode 100644
index dc53ce7..0000000
--- a/world/player/Oivee.bin
+++ /dev/null
Binary files differ
diff --git a/world/player/citrons.bin b/world/player/citrons.bin
deleted file mode 100644
index cef1136..0000000
--- a/world/player/citrons.bin
+++ /dev/null
Binary files differ
diff --git a/world/player/gideonnav.bin b/world/player/gideonnav.bin
deleted file mode 100644
index bad50a1..0000000
--- a/world/player/gideonnav.bin
+++ /dev/null
Binary files differ