Пример #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)
}
Пример #2
0
// serializeChunkData produces the compressed chunk NBT data.
func serializeChunkData(w *nbtChunkWriter) (chunkData []byte, err os.Error) {
	// Reserve room for the chunk data header at the start.
	buffer := bytes.NewBuffer(make([]byte, chunkDataHeaderSize, chunkDataGuessSize))

	if zlibWriter, err := zlib.NewWriter(buffer); err != nil {
		return nil, err
	} else {
		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
}
Пример #3
0
func (is *ItemSlot) MinecraftMarshal(writer io.Writer, ps *PacketSerializer) error {
	err := ps.writeUint16(writer, uint16(is.ItemTypeId))
	if err != nil {
		return err
	}

	if is.ItemTypeId != -1 {
		err = ps.writeUint8(writer, uint8(is.Count))
		if err != nil {
			return err
		}
		err = ps.writeUint16(writer, uint16(is.Data))
		if err != nil {
			return err
		}

		if _, requiresNbt := nbtItemIds[is.ItemTypeId]; requiresNbt {
			// Write NBT data.
			if is.Nbt == nil || len(is.Nbt) == 0 {
				// No tags.
				err = ps.writeUint16(writer, uint16(0xffff))
				if err != nil {
					return err
				}
			} else {
				// Have tags.
				var buf bytes.Buffer

				zWriter := gzip.NewWriter(&buf)

				err = nbt.Write(zWriter, is.Nbt)
				if err != nil {
					return err
				}

				err = zWriter.Close()
				if err != nil {
					return err
				}

				data := buf.Bytes()

				err = ps.writeUint16(writer, uint16(len(data)))
				if err != nil {
					return err
				}

				_, err = writer.Write(data)
				if err != nil {
					return err
				}
			}
		}
	}

	return nil
}
Пример #4
0
// Creates a new world at 'worldPath'
func CreateWorld(worldPath string) (err os.Error) {
	source := rand.NewSource(time.Nanoseconds())
	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, err := gzip.NewWriter(file)
	if err != nil {
		return err
	}

	err = nbt.Write(gzipWriter, data)
	gzipWriter.Close()
	file.Close()

	return nil
}
Пример #5
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
}