示例#1
0
        public static void LoadData <I, T>(
            string path,
            IIndexInfo <I> indexInfo,
            List <EntityIndex <T> > entities
            ) where T : class, ISerializable
        {
            var indexType = indexInfo.TypeName;

            string dataPath = Path.Combine(path, indexType, $"{indexType}.bin");

            if (!File.Exists(dataPath))
            {
                return;
            }

            using FileStream bin = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read);

            BufferReader br = null;

            foreach (var entry in entities)
            {
                T t = entry.Entity;

                // Skip this entry
                if (t == null)
                {
                    bin.Seek(entry.Length, SeekOrigin.Current);
                    continue;
                }

                var buffer = GC.AllocateUninitializedArray <byte>(entry.Length);
                if (br == null)
                {
                    br = new BufferReader(buffer);
                }
                else
                {
                    br.SwapBuffers(buffer, out _);
                }

                bin.Read(buffer.AsSpan());
                string error;

                try
                {
                    t.Deserialize(br);

                    error = br.Position != entry.Length
                        ? $"Serialized object was {entry.Length} bytes, but {br.Position} bytes deserialized"
                        : null;
                }
                catch (Exception e)
                {
                    error = e.ToString();
                }

                if (error == null)
                {
                    t.InitializeSaveBuffer(buffer);
                }
                else
                {
                    Utility.PushColor(ConsoleColor.Red);
                    Persistence.WriteConsoleLine($"***** Bad deserialize of {t.GetType()} *****");
                    Persistence.WriteConsoleLine(error);
                    Utility.PopColor();

                    Persistence.WriteConsoleLine("Delete the object and continue? (y/n)");

                    if (Console.ReadKey(true).Key != ConsoleKey.Y)
                    {
                        throw new Exception("Deserialization failed.");
                    }
                    t.Delete();
                }
            }
        }
示例#2
0
        public static void LoadData <I, T>(
            string path,
            IIndexInfo <I> indexInfo,
            List <EntityIndex <T> > entities
            ) where T : class, ISerializable
        {
            var indexType = indexInfo.TypeName;

            string dataPath = Path.Combine(path, indexType, $"{indexType}.bin");

            if (!File.Exists(dataPath) || new FileInfo(dataPath).Length == 0)
            {
                return;
            }

            using var mmf    = MemoryMappedFile.CreateFromFile(dataPath, FileMode.Open);
            using var stream = mmf.CreateViewStream();
            BufferReader br = null;

            var deleteAllFailures = false;

            foreach (var entry in entities)
            {
                T t = entry.Entity;

                var position = entry.Position;
                stream.Seek(position, SeekOrigin.Begin);

                // Skip this entry
                if (t == null)
                {
                    continue;
                }

                if (entry.Length == 0)
                {
                    t.Delete();
                    continue;
                }

                var buffer = GC.AllocateUninitializedArray <byte>(entry.Length);
                if (br == null)
                {
                    br = new BufferReader(buffer, t.LastSerialized);
                }
                else
                {
                    br.Reset(buffer, out _);
                }

                stream.Read(buffer.AsSpan());
                string error;

                try
                {
                    t.Deserialize(br);

                    error = br.Position != entry.Length
                        ? $"Serialized object was {entry.Length} bytes, but {br.Position} bytes deserialized"
                        : null;
                }
                catch (Exception e)
                {
                    error = e.ToString();
                }

                if (error == null)
                {
                    t.InitializeSaveBuffer(buffer);
                }
                else
                {
                    Console.WriteLine($"***** Bad deserialize of {t.GetType()} *****");
                    Console.WriteLine(error);

                    ConsoleKey pressedKey;

                    if (!deleteAllFailures)
                    {
                        Console.WriteLine("Delete the object and continue? (y/n/a)");
                        pressedKey = Console.ReadKey(true).Key;

                        if (pressedKey == ConsoleKey.A)
                        {
                            deleteAllFailures = true;
                        }
                        else if (pressedKey != ConsoleKey.Y)
                        {
                            throw new Exception("Deserialization failed.");
                        }
                    }

                    t.Delete();
                }
            }
        }
示例#3
0
        public static void LoadUOP(string path)
        {
            var stream       = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            var streamReader = new BinaryReader(stream);

            // Head Information Start
            if (streamReader.ReadInt32() != 0x0050594D) // Not a UOP Files
            {
                return;
            }

            if (streamReader.ReadInt32() > 5) // Bad Version
            {
                return;
            }

            // Multi ID List Array Start
            UOPHash.BuildChunkIDs(out var chunkIds);
            // Multi ID List Array End

            streamReader.ReadUInt32(); // format timestamp? 0xFD23EC43
            var startAddress = streamReader.ReadInt64();

            streamReader.ReadInt32();
            streamReader.ReadInt32();

            stream.Seek(startAddress, SeekOrigin.Begin); // Head Information End

            long nextBlock;

            do
            {
                var blockFileCount = streamReader.ReadInt32();
                nextBlock = streamReader.ReadInt64();

                var index = 0;

                do
                {
                    var offset = streamReader.ReadInt64();

                    var headerSize       = streamReader.ReadInt32();  // header length
                    var compressedSize   = streamReader.ReadInt32();  // compressed size
                    var decompressedSize = streamReader.ReadInt32();  // decompressed size

                    var filehash = streamReader.ReadUInt64();         // filename hash (HashLittle2)
                    streamReader.ReadUInt32();
                    var compressionMethod = streamReader.ReadInt16(); // compression method (0 = none, 1 = zlib)

                    index++;

                    if (offset == 0 || decompressedSize == 0 || filehash == 0x126D1E99DDEDEE0A) // Exclude housing.bin
                    {
                        continue;
                    }

                    chunkIds.TryGetValue(filehash, out var chunkID);

                    var position = stream.Position; // save current position

                    stream.Seek(offset + headerSize, SeekOrigin.Begin);

                    Span <byte> sourceData = new byte[compressedSize];

                    if (stream.Read(sourceData) != compressedSize)
                    {
                        continue;
                    }

                    Span <byte> data;

                    if (compressionMethod == 1)
                    {
                        data = new byte[decompressedSize];
                        Zlib.Unpack(data, ref decompressedSize, sourceData, compressedSize);
                    }
                    else
                    {
                        data = sourceData;
                    }

                    var tileList = new List <MultiTileEntry>();

                    // Skip the first 4 bytes
                    var reader = new BufferReader <byte>(data);

                    reader.Advance(4); // ???
                    reader.TryReadLittleEndian(out uint count);

                    for (uint i = 0; i < count; i++)
                    {
                        reader.TryReadLittleEndian(out ushort itemid);
                        reader.TryReadLittleEndian(out short x);
                        reader.TryReadLittleEndian(out short y);
                        reader.TryReadLittleEndian(out short z);
                        reader.TryReadLittleEndian(out ushort flagValue);

                        var tileFlag = flagValue switch
                        {
                            1 => TileFlag.None,
                            257 => TileFlag.Generic,
                            _ => TileFlag.Background   // 0
                        };

                        reader.TryReadLittleEndian(out uint clilocsCount);
                        reader.Advance(clilocsCount * 4); // bypass binary block

                        tileList.Add(new MultiTileEntry(itemid, x, y, z, tileFlag));
                    }

                    Components[chunkID] = new MultiComponentList(tileList);

                    stream.Seek(position, SeekOrigin.Begin); // back to position
                } while (index < blockFileCount);
            } while (stream.Seek(nextBlock, SeekOrigin.Begin) != 0);
        }
示例#4
0
        public static void Register(
            string name,
            Action <IGenericWriter> serializer,
            Action <IGenericReader> deserializer,
            int priority = Persistence.DefaultPriority
            )
        {
            BufferWriter saveBuffer = null;

            void Serialize()
            {
                saveBuffer ??= new BufferWriter(true);
                saveBuffer.Seek(0, SeekOrigin.Begin);

                serializer(saveBuffer);
            }

            void WriterSnapshot(string savePath)
            {
                var path = Path.Combine(savePath, name);

                AssemblyHandler.EnsureDirectory(path);

                string binPath = Path.Combine(path, $"{name}.bin");

                using var bin = new BinaryFileWriter(binPath, true);

                saveBuffer !.Resize((int)saveBuffer.Position);
                bin.Write(saveBuffer.Buffer);
            }

            void Deserialize(string savePath)
            {
                var path = Path.Combine(savePath, name);

                AssemblyHandler.EnsureDirectory(path);

                string binPath = Path.Combine(path, $"{name}.bin");

                if (!File.Exists(binPath))
                {
                    return;
                }

                try
                {
                    using FileStream bin = new FileStream(binPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    var br = new BufferReader(GC.AllocateUninitializedArray <byte>((int)bin.Length));
                    deserializer(br);
                }
                catch (Exception e)
                {
                    Utility.PushColor(ConsoleColor.Red);
                    Persistence.WriteConsoleLine($"***** Bad deserialize of {name} *****");
                    Persistence.WriteConsoleLine(e.ToString());
                    Utility.PopColor();
                }
            }

            Persistence.Register(Serialize, WriterSnapshot, Deserialize, priority);
        }