dim manager test 1
This commit is contained in:
53
server/dimension/loadmanager.go
Normal file
53
server/dimension/loadmanager.go
Normal file
@ -0,0 +1,53 @@
|
||||
package dimension
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
|
||||
"github.com/Tnze/go-mc/level"
|
||||
)
|
||||
|
||||
type manager struct {
|
||||
storage
|
||||
elements map[level.ChunkPos]*list.Element
|
||||
activeChunks *list.List
|
||||
|
||||
chunkLoadQueue []level.ChunkPos
|
||||
chunkUnloadQueue []level.ChunkPos
|
||||
}
|
||||
|
||||
type chunkHandler struct {
|
||||
level.ChunkPos
|
||||
*level.Chunk
|
||||
}
|
||||
|
||||
func (m *manager) refresh(players [][2]int) {
|
||||
m.chunkLoadQueue = m.chunkLoadQueue[:0]
|
||||
m.chunkUnloadQueue = m.chunkUnloadQueue[:0]
|
||||
|
||||
newActives := list.New()
|
||||
const N = 16
|
||||
for _, p := range players {
|
||||
for i := 1 - N; i < N; i++ {
|
||||
for j := 1 - N; j < N; j++ {
|
||||
pos := level.ChunkPos{
|
||||
X: p[0] + i,
|
||||
Z: p[1] + j,
|
||||
}
|
||||
if e := m.elements[pos]; e != nil {
|
||||
// chunk exist, move into newActives
|
||||
v := m.activeChunks.Remove(e)
|
||||
m.elements[pos] = newActives.PushBack(v)
|
||||
} else {
|
||||
// not exist, load from storage
|
||||
m.chunkLoadQueue = append(m.chunkLoadQueue, pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for e := m.activeChunks.Front(); e != nil; e = e.Next() {
|
||||
pos := e.Value.(chunkHandler).ChunkPos
|
||||
m.chunkUnloadQueue = append(m.chunkUnloadQueue, pos)
|
||||
m.elements[pos] = newActives.PushBack(e.Value)
|
||||
}
|
||||
m.activeChunks = newActives
|
||||
}
|
74
server/dimension/pool.go
Normal file
74
server/dimension/pool.go
Normal file
@ -0,0 +1,74 @@
|
||||
package dimension
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Tnze/go-mc/level"
|
||||
"github.com/Tnze/go-mc/save"
|
||||
"github.com/Tnze/go-mc/save/region"
|
||||
)
|
||||
|
||||
// TODO: Cache regions and chunks
|
||||
type storage struct {
|
||||
regionDir string
|
||||
}
|
||||
|
||||
func (s *storage) GetChunk(pos level.ChunkPos) (lc *level.Chunk, err error) {
|
||||
filename := fmt.Sprintf("r.%d.%d.mca", pos.X>>5, pos.Z>>5)
|
||||
|
||||
var r *region.Region
|
||||
r, err = region.Open(filepath.Join(s.regionDir, filename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
err2 := r.Close()
|
||||
if err == nil && err2 != nil {
|
||||
err = err2
|
||||
}
|
||||
}()
|
||||
|
||||
sector, err := r.ReadSector(region.In(pos.X, pos.Z))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sc save.Chunk
|
||||
err = sc.Load(sector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return level.ChunkFromSave(&sc)
|
||||
}
|
||||
|
||||
func (s *storage) PutChunk(pos level.ChunkPos, c *level.Chunk) (err error) {
|
||||
var sc save.Chunk
|
||||
err = level.ChunkToSave(c, &sc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var data []byte
|
||||
data, err = sc.Data(1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("r.%d.%d.mca", pos.X>>5, pos.Z>>5)
|
||||
var r *region.Region
|
||||
r, err = region.Open(filepath.Join(s.regionDir, filename))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
err2 := r.Close()
|
||||
if err == nil && err2 != nil {
|
||||
err = err2
|
||||
}
|
||||
}()
|
||||
x, z := region.In(pos.X, pos.Z)
|
||||
err = r.WriteSector(x, z, data)
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user