public static Chunk generateChunk(Point chunkID) { if (chunkID.X == 0 && chunkID.Y == 0) { int test = 1; } Chunk chunk = new Chunk(chunkID.X, chunkID.Y); chunk.lastUpdate = 0; chunk.terrainPopulated = 1; chunk.structurePopulated = 1; chunk.inhabitedTime = 0; byte[] biomes = new byte[256]; for (int i = 0; i < 256; i++) { biomes[i] = (byte)i; } chunk.biomes = biomes; byte[] blocks = new byte[256]; for (int i = 0; i < 256; i++) { blocks[i] = (byte)0; } chunk.blocks = blocks; byte[] objects = new byte[256]; for (int i = 0; i < 256; i++) { objects[i] = (byte)i; } chunk.objects = objects; //Tag Entities = new Tag(TagID.List, "Entities", chunk.entities, TagID.Compound); //writeTag(Entities, fileStream); //Tag Rooms = new Tag(TagID.List, "Rooms", chunk.rooms, TagID.Compound); //writeTag(Rooms, fileStream); //Tag TileEntities = new Tag(TagID.List, "TileEntities", chunk.tileEntities, TagID.Compound); //writeTag(TileEntities, fileStream); return chunk; }
public static Chunk getChunk(byte[] chunkData) { int position = 0; int length = chunkData.Length; int layerDepth = 0; Chunk newChunk = new Chunk(); while (position < length) { Tag tempTag = readTag(chunkData, ref position); configureChunk(newChunk, tempTag, ref layerDepth); } return newChunk; }
/* public static Chunk getUnloadedChunk(byte[] chunkData) { int chunkXPos = 0; int chunkYPos = 0; bool chunkIdentified = false; bool chunkChecked = false; bool chunkAlreadyLoaded = false; int layerDepth = 1; Tag regionTag = readTag(regionFile.fileStream); //should be compound while (layerDepth > 0) { Tag currentTag = readTag(regionFile.fileStream); String tagName = currentTag.getName(); TagID tagID = currentTag.getID(); if (chunkIdentified & !chunkChecked) { int localxPos; int localyPos; if (chunkXPos >= 0) { localxPos = chunkXPos % 4; } else { localxPos = 3 + (chunkXPos + 1) % 4; } if (chunkYPos >= 0) { localyPos = chunkYPos % 4; } else { localyPos = 3 + (chunkYPos + 1) % 4; } bool isThisChunkLoaded = regionFile.chunksLoaded[localxPos + localyPos * 4]; // nummer = xpos % 4 + (ypos % 4) * 4 if (isThisChunkLoaded) { chunkAlreadyLoaded = true; } else { //chunk is not loaded and will be now newChunk.XPos = chunkXPos; newChunk.YPos = chunkYPos; newChunk.innerIndex = (byte)(localxPos + localyPos * 4); regionFile.chunksLoaded[localxPos + localyPos * 4] = true; } chunkChecked = true; } if (!chunkAlreadyLoaded) { switch (tagID) { case TagID.End: layerDepth--; if (layerDepth == 1) { //end of unloaded chunk //this means its now added return new chunk Console.WriteLine("chunk now loaded"); return newChunk; } break; case TagID.Byte: if (tagName.Equals("TerrainPopulated")) { newChunk.terrainPopulated = (sbyte)currentTag.getData(); } else if (tagName.Equals("StructurePopulated")) { newChunk.structurePopulated = (sbyte)currentTag.getData(); } break; case TagID.Short: break; case TagID.Int: if (tagName.Equals("XPos")) { byte[] data = (byte[])currentTag.getRawData(); int dataInt = BitConverter.ToInt32(data, 0); chunkXPos = dataInt; } else if (tagName.Equals("YPos")) { byte[] data = (byte[])currentTag.getRawData(); int dataInt = BitConverter.ToInt32(data, 0); chunkYPos = dataInt; chunkIdentified = true; } break; case TagID.Long: if (tagName.Equals("LastUpdate")) { byte[] data = (byte[])currentTag.getRawData(); long dataLong = BitConverter.ToInt64(data, 0); newChunk.lastUpdate = dataLong; } else if (tagName.Equals("InhabitedTime")) { byte[] data = (byte[])currentTag.getRawData(); long dataLong = BitConverter.ToInt64(data, 0); newChunk.inhabitedTime = dataLong; } break; case TagID.Float: break; case TagID.Double: break; case TagID.ByteArray: if (tagName.Equals("Biomes")) { newChunk.biomes = (byte[])currentTag.getData(); } else if (tagName.Equals("Blocks")) { newChunk.blocks = (byte[])currentTag.getData(); } else if (tagName.Equals("Objects")) { newChunk.objects = (byte[])currentTag.getData(); } break; case TagID.String: break; case TagID.List: if (tagName.Equals("Entities")) { newChunk.entities = (List<List<Tag>>)currentTag.getData(); } else if (tagName.Equals("Rooms")) { newChunk.rooms = (List<List<Tag>>)currentTag.getData(); } break; case TagID.Compound: layerDepth++; break; case TagID.IntArray: break; default: layerDepth = 0; break; } } else { switch (tagID) { case TagID.End: layerDepth--; if (layerDepth == 1) { //end of already loaded chunk chunkAlreadyLoaded = false; chunkIdentified = false; chunkChecked = false; } break; case TagID.Compound: layerDepth++; break; default: break; } } //} } return null; } */ public static byte[] saveChunk(Chunk chunk) { int position = 0; int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; List<Tag> chunkTagList = new List<Tag>(); byte[] chunkXpos = BitConverter.GetBytes(chunk.xCoordinate); Tag XPos = new Tag(TagID.Int, "XPos", chunkXpos); chunkTagList.Add(XPos); byte[] chunkYpos = BitConverter.GetBytes(chunk.yCoordinate); Tag YPos = new Tag(TagID.Int, "YPos", chunkYpos); chunkTagList.Add(YPos); byte[] chunkLastUpdate = BitConverter.GetBytes(chunk.lastUpdate); Tag LastUpdate = new Tag(TagID.Long, "LastUpdate", chunkLastUpdate); chunkTagList.Add(LastUpdate); byte terrainByte = (byte)chunk.terrainPopulated; byte[] chunkTerrainPopulated = { terrainByte }; Tag TerrainPopulated = new Tag(TagID.Byte, "TerrainPopulated", chunkTerrainPopulated); chunkTagList.Add(TerrainPopulated); byte structureByte = chunk.structurePopulated; byte[] chunkStructurePopulated = { structureByte }; Tag StructurePopulated = new Tag(TagID.Byte, "StructurePopulated", chunkStructurePopulated); chunkTagList.Add(StructurePopulated); byte[] chunkInhabitedTime = BitConverter.GetBytes(chunk.inhabitedTime); Tag InhabitedTime = new Tag(TagID.Long, "InhabitedTime", chunkInhabitedTime); chunkTagList.Add(InhabitedTime); Tag Biomes = new Tag(TagID.ByteArray, "Biomes", chunk.biomes); chunkTagList.Add(Biomes); Tag Blocks = new Tag(TagID.ByteArray, "Blocks", chunk.blocks); chunkTagList.Add(Blocks); Tag Objects = new Tag(TagID.ByteArray, "Objects", chunk.objects); chunkTagList.Add(Objects); //Tag Entities = new Tag(TagID.List, "Entities", chunk.entities, TagID.Compound); //writeTag(Entities, fileStream); //Tag Rooms = new Tag(TagID.List, "Rooms", chunk.rooms, TagID.Compound); //writeTag(Rooms, fileStream); //Tag TileEntities = new Tag(TagID.List, "TileEntities", chunk.tileEntities, TagID.Compound); //writeTag(TileEntities, fileStream); //Tag End = new Tag(TagID.End, null, null); Tag chunkTag = new Tag(TagID.Compound, "chunk", chunkTagList, TagID.Compound); writeTag(chunkTag, ref buffer, ref position); writeTag(XPos, ref buffer, ref position); writeTag(YPos, ref buffer, ref position); writeTag(LastUpdate, ref buffer, ref position); writeTag(TerrainPopulated, ref buffer, ref position); writeTag(StructurePopulated, ref buffer, ref position); writeTag(InhabitedTime, ref buffer, ref position); writeTag(Biomes, ref buffer, ref position); writeTag(Blocks, ref buffer, ref position); writeTag(Objects, ref buffer, ref position); //writeTag(End, ref buffer, ref position); byte[] trimmedBuffer = new byte[position]; Array.Copy(buffer, 0, trimmedBuffer, 0, position); return trimmedBuffer; }
public static void configureChunk(Chunk chunk, Tag tag, ref int layerDepth) { TagID tagID = tag.getID(); String tagName = tag.getName(); switch (tagID) { case TagID.End: layerDepth--; break; case TagID.Byte: if (tagName.Equals("TerrainPopulated")) { chunk.terrainPopulated = tag.getByte(); } else if (tagName.Equals("StructurePopulated")) { chunk.structurePopulated = tag.getByte(); } break; case TagID.Short: break; case TagID.Int: if (tagName.Equals("XPos")) { chunk.xCoordinate = tag.getInt(); } else if (tagName.Equals("YPos")) { chunk.yCoordinate = tag.getInt(); } break; case TagID.Long: if (tagName.Equals("LastUpdate")) { chunk.lastUpdate = tag.getLong(); } else if (tagName.Equals("InhabitedTime")) { chunk.inhabitedTime = tag.getLong(); } break; case TagID.Float: break; case TagID.Double: break; case TagID.ByteArray: if (tagName.Equals("Biomes")) { chunk.biomes = tag.getPayload(); } else if (tagName.Equals("Blocks")) { chunk.blocks = tag.getPayload(); } else if (tagName.Equals("Objects")) { chunk.objects = tag.getPayload(); } break; case TagID.String: break; case TagID.List: if (tagName.Equals("Entities")) { //chunk.entities = (List<List<Tag>>)currentTag.getData(); } else if (tagName.Equals("Rooms")) { //newChunk.rooms = (List<List<Tag>>)currentTag.getData(); } break; case TagID.Compound: layerDepth++; break; case TagID.IntArray: break; default: layerDepth = 0; break; } }
public void writeChunk(Chunk chunkToWrite) { Point chunkID = new Point(chunkToWrite.xCoordinate, chunkToWrite.yCoordinate); Point checkingRegionID = Translation.chunkCoordsToRegionCoords(chunkID); lastUsedTick = DateTime.Now.Ticks; //Makes sure the chunk is inside this specific region if (regionID.X == checkingRegionID.X && regionID.Y == checkingRegionID.Y) { Point internalChunkPos = Translation.chunkCoordsToInternalRegionChunkCoords(chunkID); int chunkIDInArrays = internalChunkPos.X + internalChunkPos.Y * 32; byte[] chunkData = TagTranslator.saveChunk(chunkToWrite); int chunkSizeInBytesInt = chunkData.Length; if (chunkSizeInBytesInt < 4096) { //update regionScheme int chunkPositionInFileInt = (1024 + (4096 * 2)) + (chunkIDInArrays * 4096); chunkPositionInFile[chunkIDInArrays] = chunkPositionInFileInt; chunkSizeInBytes[chunkIDInArrays] = chunkSizeInBytesInt; chunkIsPresent[chunkIDInArrays] = 1; //write to filestream pushByteArray(chunkData, chunkPositionInFileInt, chunkSizeInBytesInt); } else { throw new System.Exception("Chunk size too big. (Equal to or above 1024 bytes)"); } } else { throw new System.Exception("Trying to save a chunk in wrong region file."); } }