Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        public Map LoadHeader([NotNull] string fileName)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
            Map map = Load(fileName);

            map.Blocks = null;
            return(map);
        }
Beispiel #4
0
 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();
 }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
                }
            }
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        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);
                }
            }
        }
Beispiel #12
0
        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);
            }
        }