private int WriteMetadata([NotNull] Stream stream, [NotNull] Map map) { if (stream == null) { throw new ArgumentNullException("stream"); } if (map == null) { throw new ArgumentNullException("map"); } BinaryWriter writer = new BinaryWriter(stream); int metaCount = 0; lock (map.Metadata.SyncRoot) { foreach (var entry in map.Metadata) { WriteMetadataEntry(entry.Group, entry.Key, entry.Value, writer); metaCount++; } } //extensions if (_extensions.Count > 0) { metaCount += _extensions.Values.Sum(ex => ex.Serialize(map, stream, this)); } return(metaCount); }
public Map Load([NotNull] string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream mapStream = File.OpenRead(fileName)) { BinaryReader reader = new BinaryReader(mapStream); Map map = LoadHeaderInternal(reader); // read the layer index int layerCount = reader.ReadByte(); if (layerCount < 1) { throw new MapFormatException("No data layers found."); } mapStream.Seek(25 * layerCount, SeekOrigin.Current); // read metadata int metaSize = reader.ReadInt32(); using (DeflateStream ds = new DeflateStream(mapStream, CompressionMode.Decompress)) { BinaryReader br = new BinaryReader(ds); for (int i = 0; i < metaSize; i++) { string group = ReadLengthPrefixedString(br).ToLowerInvariant(); string key = ReadLengthPrefixedString(br).ToLowerInvariant(); string newValue = ReadLengthPrefixedString(br); string oldValue; IConverterExtension ex; if (_extensions.TryGetValue(group, out ex)) { ex.Deserialize(group, key, newValue, map); } else { if (map.Metadata.TryGetValue(key, group, out oldValue) && oldValue != newValue) { Logger.Log(LogType.Warning, "MapFCMv3.LoadHeader: Duplicate metadata entry found for [{0}].[{1}]. " + "Old value (overwritten): \"{2}\". New value: \"{3}\"", group, key, oldValue, newValue); } map.Metadata[group, key] = newValue; } } map.Blocks = new byte[map.Volume]; ds.Read(map.Blocks, 0, map.Blocks.Length); //map.RemoveUnknownBlocktypes(); } return(map); } }
public Map LoadHeader([NotNull] string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } Map map = Load(fileName); map.Blocks = null; return(map); }
public bool Save([NotNull] Map mapToSave, [NotNull] string fileName) { if (mapToSave == null) { throw new ArgumentNullException("mapToSave"); } if (fileName == null) { throw new ArgumentNullException("fileName"); } throw new NotImplementedException(); }
static void LoadBlocks([NotNull] Map map, [NotNull] Stream mapStream) { mapStream.Seek(0, SeekOrigin.Begin); // Setup a GZipStream to decompress and read the map file GZipStream gs = new GZipStream(mapStream, CompressionMode.Decompress, true); BinaryReader bs = new BinaryReader(gs); int blockCount = IPAddress.HostToNetworkOrder(bs.ReadInt32()); if (blockCount != map.Volume) { throw new Exception("Map dimensions in the metadata do not match dimensions of the block array."); } map.Blocks = new byte[blockCount]; bs.Read(map.Blocks, 0, map.Blocks.Length); //map.RemoveUnknownBlocktypes(); }
static Map LoadHeaderInternal([NotNull] Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } BinaryReader bs = new BinaryReader(stream); // Read in the magic number if (bs.ReadByte() != 0xbe || bs.ReadByte() != 0xee || bs.ReadByte() != 0xef) { throw new MapFormatException("MinerCPP map header is incorrect."); } // Read in the map dimesions // Saved in big endian for who-know-what reason. // XYZ(?) int width = IPAddress.NetworkToHostOrder(bs.ReadInt16()); int height = IPAddress.NetworkToHostOrder(bs.ReadInt16()); int length = IPAddress.NetworkToHostOrder(bs.ReadInt16()); // ReSharper disable UseObjectOrCollectionInitializer Map map = new Map(null, width, length, height, false); // ReSharper restore UseObjectOrCollectionInitializer // Read in the spawn location // XYZ(?) map.Spawn = new Position { X = IPAddress.NetworkToHostOrder(bs.ReadInt16()), Z = IPAddress.NetworkToHostOrder(bs.ReadInt16()), Y = IPAddress.NetworkToHostOrder(bs.ReadInt16()), R = bs.ReadByte(), L = bs.ReadByte() }; // Skip over the block count, totally useless bs.ReadInt32(); return(map); }
public bool Save([NotNull] Map mapToSave, [NotNull] string fileName) { if (mapToSave == null) { throw new ArgumentNullException("mapToSave"); } if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream mapStream = File.Create(fileName)) { using (GZipStream gs = new GZipStream(mapStream, CompressionMode.Compress)) { BinaryWriter bs = new BinaryWriter(gs); // Write out the magic number bs.Write(new byte[] { 0xbe, 0xee, 0xef }); // Save the map dimensions // XYZ(?) bs.Write((ushort)IPAddress.HostToNetworkOrder((short)mapToSave.Width)); bs.Write((ushort)IPAddress.HostToNetworkOrder((short)mapToSave.Height)); bs.Write((ushort)IPAddress.HostToNetworkOrder((short)mapToSave.Length)); // Save the spawn location bs.Write(IPAddress.HostToNetworkOrder(mapToSave.Spawn.X)); bs.Write(IPAddress.HostToNetworkOrder(mapToSave.Spawn.Z)); bs.Write(IPAddress.HostToNetworkOrder(mapToSave.Spawn.Y)); // Save the spawn orientation bs.Write(mapToSave.Spawn.R); bs.Write(mapToSave.Spawn.L); // Write out the block count (which is totally useless, can't stress that enough.) bs.Write(IPAddress.HostToNetworkOrder(mapToSave.Blocks.Length)); // Write out the map data MapUtility.WriteAll(mapToSave.Blocks, bs); return(true); } } }
static Map LoadMeta([NotNull] Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } INIFile metaFile = new INIFile(stream); if (metaFile.IsEmpty) { throw new Exception("Metadata file is empty or incorrectly formatted."); } if (!metaFile.Contains("size", "x", "y", "z")) { throw new Exception("Metadata file is missing map dimensions."); } int width = Int32.Parse(metaFile["size", "x"]); int length = Int32.Parse(metaFile["size", "z"]); int height = Int32.Parse(metaFile["size", "y"]); Map map = new Map(null, width, length, height, false); if (!map.ValidateHeader()) { throw new MapFormatException("One or more of the map dimensions are invalid."); } if (metaFile.Contains("spawn", "x", "y", "z", "h")) { map.Spawn = new Position { X = (short)(Int16.Parse(metaFile["spawn", "x"]) * 32 + 16), Y = (short)(Int16.Parse(metaFile["spawn", "z"]) * 32 + 16), Z = (short)(Int16.Parse(metaFile["spawn", "y"]) * 32 + 16), R = Byte.Parse(metaFile["spawn", "h"]), L = 0 }; } return(map); }
static Map LoadHeaderInternal([NotNull] BinaryReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } if (reader.ReadInt32() != Identifier || reader.ReadByte() != Revision) { throw new MapFormatException(); } // read dimensions int width = reader.ReadInt16(); int height = reader.ReadInt16(); int length = reader.ReadInt16(); // ReSharper disable UseObjectOrCollectionInitializer Map map = new Map(null, width, length, height, false); // ReSharper restore UseObjectOrCollectionInitializer // read spawn map.Spawn = new Position { X = (short)reader.ReadInt32(), Z = (short)reader.ReadInt32(), Y = (short)reader.ReadInt32(), R = reader.ReadByte(), L = reader.ReadByte() }; // read modification/creation times map.DateModified = DateTimeUtil.ToDateTimeLegacy(reader.ReadUInt32()); map.DateCreated = DateTimeUtil.ToDateTimeLegacy(reader.ReadUInt32()); // read UUID map.Guid = new Guid(reader.ReadBytes(16)); return(map); }
public Map Load([NotNull] string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream mapStream = File.OpenRead(fileName)) { GZipStream gs = new GZipStream(mapStream, CompressionMode.Decompress, true); NBTag tag = NBTag.ReadStream(gs); NBTag mapTag = tag["Map"]; // ReSharper disable UseObjectOrCollectionInitializer Map map = new Map(null, mapTag["Width"].GetShort(), mapTag["Length"].GetShort(), mapTag["Height"].GetShort(), false); map.Spawn = new Position { X = mapTag["Spawn"][0].GetShort(), Z = mapTag["Spawn"][1].GetShort(), Y = mapTag["Spawn"][2].GetShort(), R = 0, L = 0 }; // ReSharper restore UseObjectOrCollectionInitializer if (!map.ValidateHeader()) { throw new MapFormatException("One or more of the map dimensions are invalid."); } map.Blocks = mapTag["Blocks"].GetBytes(); //map.RemoveUnknownBlocktypes(); return(map); } }
public Map Load([NotNull] string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream mapStream = File.OpenRead(fileName)) { // Setup a GZipStream to decompress and read the map file using (GZipStream gs = new GZipStream(mapStream, CompressionMode.Decompress, true)) { Map map = LoadHeaderInternal(gs); if (!map.ValidateHeader()) { throw new MapFormatException("One or more of the map dimensions are invalid."); } // Read in the map data map.Blocks = new byte[map.Volume]; mapStream.Read(map.Blocks, 0, map.Blocks.Length); return(map); } } }
public bool Save([NotNull] Map mapToSave, [NotNull] string fileName) { if (mapToSave == null) { throw new ArgumentNullException("mapToSave"); } if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream mapStream = File.Create(fileName)) { BinaryWriter writer = new BinaryWriter(mapStream); writer.Write(Identifier); writer.Write(Revision); writer.Write((short)mapToSave.Width); writer.Write((short)mapToSave.Height); writer.Write((short)mapToSave.Length); writer.Write((int)mapToSave.Spawn.X); writer.Write((int)mapToSave.Spawn.Z); writer.Write((int)mapToSave.Spawn.Y); writer.Write(mapToSave.Spawn.R); writer.Write(mapToSave.Spawn.L); mapToSave.DateModified = DateTime.UtcNow; writer.Write((uint)mapToSave.DateModified.ToUnixTimeLegacy()); writer.Write((uint)mapToSave.DateCreated.ToUnixTimeLegacy()); writer.Write(mapToSave.Guid.ToByteArray()); writer.Write((byte)1); // layer count // skip over index and metacount long indexOffset = mapStream.Position; writer.Seek(29, SeekOrigin.Current); byte[] blocksCache = mapToSave.Blocks; int metaCount, compressedLength; long offset; using (DeflateStream ds = new DeflateStream(mapStream, CompressionMode.Compress, true)) { using (BufferedStream bs = new BufferedStream(ds)) { // write metadata metaCount = WriteMetadata(bs, mapToSave); offset = mapStream.Position; bs.Flush(); MapUtility.WriteAll(blocksCache, bs); compressedLength = (int)(mapStream.Position - offset); } } // come back to write the index writer.BaseStream.Seek(indexOffset, SeekOrigin.Begin); writer.Write((byte)0); // data layer type (Blocks) writer.Write(offset); // offset, in bytes, from start of stream writer.Write(compressedLength); // compressed length, in bytes writer.Write(0); // general purpose field writer.Write(1); // element size writer.Write(blocksCache.Length); // element count writer.Write(metaCount); return(true); } }