func (s *chunkStoreAlpha) WriteChunk(writer IChunkWriter) (err error) { nbtWriter, ok := writer.(*nbtChunkWriter) if !ok { return fmt.Errorf("%T is incorrect IChunkWriter implementation for %T", writer, s) } destName := s.chunkPath(writer.ChunkLoc()) dirName, _ := path.Split(destName) if err = os.MkdirAll(dirName, 0777); err != nil { return } file, err := util.OpenFileUniqueName(destName, os.O_WRONLY, 0666) if err != nil { return } defer file.Close() gzipWriter := gzip.NewWriter(file) defer gzipWriter.Close() if err = nbt.Write(gzipWriter, nbtWriter.RootTag()); err != nil { return } // Atomically move the newly written file into place. return os.Rename(file.Name(), destName) }
// serializeChunkData produces the compressed chunk NBT data. func serializeChunkData(w *nbtChunkWriter) (chunkData []byte, err error) { // Reserve room for the chunk data header at the start. buffer := bytes.NewBuffer(make([]byte, chunkDataHeaderSize, chunkDataGuessSize)) zlibWriter := zlib.NewWriter(buffer) if err = nbt.Write(zlibWriter, w.RootTag()); err != nil { zlibWriter.Close() return nil, err } if err = zlibWriter.Close(); err != nil { return nil, err } chunkData = buffer.Bytes() // Write chunk data header header := chunkDataHeader{ DataSize: uint32(len(chunkData)) - chunkDataHeaderSize, Version: chunkCompressionZlib, } buffer = bytes.NewBuffer(chunkData[:0]) if err = binary.Write(buffer, binary.BigEndian, header); err != nil { return nil, err } return chunkData, nil }
// Creates a new world at 'worldPath' func CreateWorld(worldPath string) (err error) { source := rand.NewSource(time.Now().Unix()) seed := source.Int63() data := &nbt.Compound{ map[string]nbt.ITag{ "Data": &nbt.Compound{ map[string]nbt.ITag{ "Time": &nbt.Long{0}, "rainTime": &nbt.Int{0}, "thunderTime": &nbt.Int{0}, "version": &nbt.Int{19132}, // TODO: What should this be? "thundering": &nbt.Byte{0}, "raining": &nbt.Byte{0}, "LevelName": &nbt.String{"world"}, // TODO: Should be specifyable "SpawnX": &nbt.Int{0}, // TODO: Figure this out from chunk generator? "SpawnY": &nbt.Int{75}, // TODO: Figure this out from chunk generator? "SpawnZ": &nbt.Int{0}, // TODO: Figure this out from chunk generator? "LastPlayed": &nbt.Long{0}, "SizeOnDisk": &nbt.Long{0}, // Needs to be accurate? "RandomSeed": &nbt.Long{seed}, }, }, }, } if err = os.MkdirAll(worldPath, 0777); err != nil { return } filename := path.Join(worldPath, "level.dat") file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0666) if err != nil { return err } gzipWriter := gzip.NewWriter(file) err = nbt.Write(gzipWriter, data) gzipWriter.Close() file.Close() return nil }
func (world *WorldStore) WritePlayerData(user string, data *nbt.Compound) (err error) { playerDir := path.Join(world.WorldPath, "players") if err = os.MkdirAll(playerDir, 0777); err != nil { return } filename := path.Join(world.WorldPath, "players", user+".dat") file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { return err } defer file.Close() gzipWriter := gzip.NewWriter(file) err = nbt.Write(gzipWriter, data) gzipWriter.Close() return }