// Server sending chunk information to Client public void SendChunk(Chunk c) { // {CODE} [ChunkPos] [blockSize] [hpSize] [stateSize] | Respective data int headerSize = RegionFileHandler.chunkHeaderSize; int blockDataSize = Compression.CompressBlocks(c, NetMessage.buffer, 21 + headerSize); int hpDataSize = Compression.CompressMetadataHP(c, NetMessage.buffer, 21 + headerSize + blockDataSize); int stateDataSize = Compression.CompressMetadataState(c, NetMessage.buffer, 21 + headerSize + blockDataSize + hpDataSize); NetDecoder.WriteChunkPos(c.pos, NetMessage.buffer, 1); NetDecoder.WriteInt(blockDataSize, NetMessage.buffer, 9); NetDecoder.WriteInt(hpDataSize, NetMessage.buffer, 13); NetDecoder.WriteInt(stateDataSize, NetMessage.buffer, 17); byte[] header = c.GetHeader(); Array.Copy(header, 0, NetMessage.buffer, 21, headerSize); this.size = 21 + headerSize + blockDataSize + hpDataSize + stateDataSize; }
// Saves a chunk to RDF file using Pallete-based Compression public void SaveChunk(Chunk c) { int totalSize = 0; long seekPosition = 0; int blockSize; int hpSize; int stateSize; long chunkCode = GetLinearRegionCoords(c.pos); int lastKnownSize = 0; GetCorrectRegion(c.pos); // Reads pre-save size if is already indexed if (IsIndexed(c.pos)) { byte biome = 0; byte gen = 0; int blockdata = 0; int hpdata = 0; int statedata = 0; ReadHeader(c.pos); InterpretHeader(ref biome, ref gen, ref blockdata, ref hpdata, ref statedata); lastKnownSize = chunkHeaderSize + blockdata + hpdata + statedata; } // Saves data to buffers and gets total size blockSize = Compression.CompressBlocks(c, blockBuffer); hpSize = Compression.CompressMetadataHP(c, hpBuffer); stateSize = Compression.CompressMetadataState(c, stateBuffer); InitializeHeader(c, blockSize, hpSize, stateSize); totalSize = chunkHeaderSize + blockSize + hpSize + stateSize; // If Chunk was already saved if (IsIndexed(c.pos)) { ChunkPos regionPos = ConvertToRegion(c.pos); this.pool[regionPos].AddHole(this.pool[regionPos].index[chunkCode], lastKnownSize); seekPosition = this.pool[regionPos].FindPosition(totalSize); this.pool[regionPos].SaveHoles(); // If position in RegionFile has changed if (seekPosition != this.pool[regionPos].index[chunkCode]) { this.pool[regionPos].index[chunkCode] = seekPosition; this.pool[regionPos].UnloadIndex(); } // Saves Chunk this.pool[regionPos].Write(seekPosition, headerBuffer, chunkHeaderSize); this.pool[regionPos].Write(seekPosition + chunkHeaderSize, blockBuffer, blockSize); this.pool[regionPos].Write(seekPosition + chunkHeaderSize + blockSize, hpBuffer, hpSize); this.pool[regionPos].Write(seekPosition + chunkHeaderSize + blockSize + hpSize, stateBuffer, stateSize); } // If it's a new Chunk else { ChunkPos regionPos = ConvertToRegion(c.pos); seekPosition = this.pool[regionPos].FindPosition(totalSize); this.pool[regionPos].SaveHoles(); // Adds new chunk to Index this.pool[regionPos].index.Add(chunkCode, seekPosition); AddEntryIndex(chunkCode, seekPosition); this.pool[regionPos].indexFile.Write(indexArray, 0, 16); this.pool[regionPos].indexFile.Flush(); // Saves Chunk this.pool[regionPos].Write(seekPosition, headerBuffer, chunkHeaderSize); this.pool[regionPos].Write(seekPosition + chunkHeaderSize, blockBuffer, blockSize); this.pool[regionPos].Write(seekPosition + chunkHeaderSize + blockSize, hpBuffer, hpSize); this.pool[regionPos].Write(seekPosition + chunkHeaderSize + blockSize + hpSize, stateBuffer, stateSize); } }