summaryrefslogtreecommitdiff
path: root/server/level.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/level.go')
-rw-r--r--server/level.go51
1 files changed, 27 insertions, 24 deletions
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() {