Example #1
0
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)
}
Example #2
0
// 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
}
Example #3
0
// 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
}
Example #4
0
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
}