//Writes the passed struct/struct pointer to the data folder
//with the name key.nether.
func (mw *MsgpackSystem) Write(key string, v interface{}) error {
	f, err := os.Create(filepath.Join(mw.path, "data", key+".nether"))
	if err != nil {
		return err
	}
	defer f.Close()
	return msgpack.NewEncoder(f).Encode(v)
}
//Saves the chunk back to storage.
func (mw *MsgpackSystem) SaveChunk(x, z int, chunk *Chunk) {
	reg := mw.region(x>>5, z>>5)
	reg.Lock()
	rx := x & 0x1F
	rz := z & 0x1F
	idx := rx | (rz << 5)
	if off := reg.Offsets[idx]; off != 0 {
		for i := off; i < off+reg.SectionCounts[idx]; i++ {
			reg.usedLocations[i] = false
		}
	}
	reg.Unlock()

	var buf bytes.Buffer
	gz := gzip.NewWriter(&buf)
	msgpack.NewEncoder(gz).Encode(chunk)
	gz.Close()

	reg.Lock()
	offset := len(reg.usedLocations)
	count := (buf.Len() / regionSectionSize) + 1
check:
	for i := 3; i < len(reg.usedLocations); i++ {
		if !reg.usedLocations[i] {
			for j := 1; j < count; j++ {
				if reg.usedLocations[i+j] {
					continue check
				}
			}
			offset = i
			break
		}
	}
	if len(reg.usedLocations) < offset+count {
		temp := reg.usedLocations
		reg.usedLocations = make([]bool, offset+count)
		copy(reg.usedLocations, temp)
	}
	for i := offset; i < offset+count; i++ {
		reg.usedLocations[i] = true
	}
	reg.Offsets[idx] = offset
	reg.SectionCounts[idx] = count
	reg.needsSave = true

	reg.chunkcount++
	reg.Unlock()

	mw.nsLock.Lock()
	mw.needsSave = true
	mw.nsLock.Unlock()

	n, err := reg.file.WriteAt(buf.Bytes(), int64(offset)*regionSectionSize)
	if err != nil || n != buf.Len() {
		panic(err)
	}
}
func (mw *MsgpackSystem) writeLevel(level string) {
	f, err := os.Create(level)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	err = msgpack.NewEncoder(f).Encode(mw)
	if err != nil {
		panic(err)
	}
}
Exemplo n.º 4
0
//Loads the world by name using the passed system if
//the world doesn't exists.
func LoadWorld(name string, system System, gen Generator, dimension Dimension, tryClose chan TryClose) *World {
	metapath := filepath.Join("./worlds/", name, "netherrack.meta")
	_, err := os.Stat(metapath)
	if err == nil {
		//Load the world
		return GetWorld(name, tryClose)
	}

	//Create the world
	meta := netherrackMeta{
		SystemName:    system.SystemName(),
		GeneratorName: gen.Name(),
	}
	os.MkdirAll(filepath.Join("./worlds/", name), 0777)
	f, err := os.Create(metapath)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	msgpack.NewEncoder(f).Encode(&meta)

	w := &World{
		Name:      name,
		system:    system,
		generator: gen,
		tryClose:  tryClose,
	}
	w.worldData.Dimension = dimension
	w.init()
	w.system.Init(filepath.Join("./worlds/", w.Name))
	w.generator.Save(w)
	w.system.Write("levelData", &w.worldData)
	go w.run()

	return w
}
func (r *region) Save() {
	r.file.Seek(0, 0)
	msgpack.NewEncoder(r.file).Encode(r)
}