Пример #1
0
        public static void WriteSnapshot(string path, Action <IGenericWriter> serializer)
        {
            AssemblyHandler.EnsureDirectory(Path.GetDirectoryName(path));

            using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.None);
            serializer(new BinaryFileWriter(fs, true));
        }
Пример #2
0
        public static void Deserialize(string path, Action <IGenericReader> deserializer, bool ensure = true)
        {
            AssemblyHandler.EnsureDirectory(Path.GetDirectoryName(path));

            if (!File.Exists(path))
            {
                if (ensure)
                {
                    new FileInfo(path).Create().Close();
                }

                return;
            }

            using FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            // TODO: Support files larger than 2GB
            var buffer = GC.AllocateUninitializedArray <byte>((int)fs.Length);

            try
            {
                deserializer(new BufferReader(buffer));
            }
            catch (Exception e)
            {
                Console.WriteLine("[Persistence]: Failed to deserialize");
                Console.WriteLine(e);
            }
        }
Пример #3
0
        // Do not use this in "Parse" methods, it may cause a stack overflow
        public static string TryParse(Type type, string value, out object constructed)
        {
            constructed = null;
            var isSerial = IsType(type, OfSerial);

            if (isSerial) // mutate into int32
            {
                type = OfInt;
            }

            if (value == "(-null-)" && !type.IsValueType)
            {
                value = null;
            }

            if (IsType(type, OfEnum))
            {
                try
                {
                    constructed = Enum.Parse(type, value ?? "", true);
                    return(null);
                }
                catch
                {
                    return("That is not a valid enumeration member.");
                }
            }

            if (IsType(type, OfType))
            {
                try
                {
                    constructed = AssemblyHandler.FindTypeByName(value);

                    return(constructed == null ? "No type with that name was found." : null);
                }
                catch
                {
                    return("No type with that name was found.");
                }
            }

            if (value == null)
            {
                constructed = null;
                return(null);
            }

            if (IsType(type, OfString))
            {
                constructed = value;
                return(null);
            }

            if (value.StartsWithOrdinal("0x") && IsNumeric(type))
            {
                try
                {
                    constructed = Convert.ChangeType(Convert.ToUInt64(value[2..], 16), type);
Пример #4
0
        internal static void LoadRegions()
        {
            var path = Path.Join(Core.BaseDirectory, "Data/regions.json");

            var failures = new List <string>();
            var count    = 0;

            logger.Information("Loading regions");

            var stopwatch = Stopwatch.StartNew();
            var regions   = JsonConfig.Deserialize <List <DynamicJson> >(path);

            if (regions == null)
            {
                throw new JsonException($"Failed to deserialize {path}.");
            }

            foreach (var json in regions)
            {
                var type = AssemblyHandler.FindTypeByName(json.Type);

                if (type == null || !typeof(Region).IsAssignableFrom(type))
                {
                    failures.Add($"\tInvalid region type {json.Type}");
                    continue;
                }

                var region = type.CreateInstance <Region>(json, JsonConfig.DefaultOptions);
                region?.Register();
                count++;
            }

            stopwatch.Stop();

            if (failures.Count == 0)
            {
                logger.Information(
                    "Regions loaded ({Count} regions, {FailureCount} failures) ({Duration:F2} seconds)",
                    count,
                    failures.Count,
                    stopwatch.Elapsed.TotalSeconds
                    );
            }
            else
            {
                logger.Warning(
                    "Failed loading regions ({Count} regions, {FailureCount} failures) ({Duration:F2} seconds)",
                    count,
                    failures.Count,
                    stopwatch.Elapsed.TotalSeconds
                    );

                logger.Warning("{Failures}", failures);
            }
        }
Пример #5
0
        private static List <Tuple <ConstructorInfo, string> > ReadTypes(BinaryReader tdbReader)
        {
            int count = tdbReader.ReadInt32();

            List <Tuple <ConstructorInfo, string> > types = new List <Tuple <ConstructorInfo, string> >(count);

            for (int i = 0; i < count; ++i)
            {
                string typeName = tdbReader.ReadString();

                Type t = AssemblyHandler.FindFirstTypeForName(typeName);

                if (t == null)
                {
                    Console.WriteLine("failed");

                    if (!Core.Service)
                    {
                        Console.WriteLine("Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName);

                        if (Console.ReadKey(true).Key == ConsoleKey.Y)
                        {
                            types.Add(null);
                            Console.Write("World: Loading...");
                            continue;
                        }

                        Console.WriteLine("Types will not be deleted. An exception will be thrown.");
                    }
                    else
                    {
                        Console.WriteLine("Error: Type '{0}' was not found.", typeName);
                    }

                    throw new Exception($"Bad type '{typeName}'");
                }

                ConstructorInfo ctor = t.GetConstructor(m_SerialTypeArray);

                if (ctor != null)
                {
                    types.Add(new Tuple <ConstructorInfo, string>(ctor, typeName));
                }
                else
                {
                    throw new Exception($"Type '{t}' does not have a serialization constructor");
                }
            }

            return(types);
        }
Пример #6
0
        internal static void LoadRegions()
        {
            var path = Path.Join(Core.BaseDirectory, "Data/regions.json");

            var failures = new List <string>();
            var count    = 0;

            Console.Write("Regions: Loading...");

            var stopwatch = Stopwatch.StartNew();
            var regions   = JsonConfig.Deserialize <List <DynamicJson> >(path);

            if (regions == null)
            {
                throw new JsonException($"Failed to deserialize {path}.");
            }

            foreach (var json in regions)
            {
                var type = AssemblyHandler.FindTypeByName(json.Type);

                if (type == null || !typeof(Region).IsAssignableFrom(type))
                {
                    failures.Add($"\tInvalid region type {json.Type}");
                    continue;
                }

                var region = type.CreateInstance <Region>(json, JsonConfig.DefaultOptions);
                region?.Register();
                count++;
            }

            stopwatch.Stop();

            Utility.PushColor(failures.Count > 0 ? ConsoleColor.Yellow : ConsoleColor.Green);
            Console.Write(failures.Count > 0 ? "done with failures" : "done");
            Utility.PopColor();
            Console.WriteLine(
                " ({0} regions, {1} failures) ({2:F2} seconds)",
                count,
                failures.Count,
                stopwatch.Elapsed.TotalSeconds
                );

            if (failures.Count > 0)
            {
                Utility.PushColor(ConsoleColor.Red);
                Console.WriteLine(string.Join(Environment.NewLine, failures));
                Utility.PopColor();
            }
        }
Пример #7
0
        public static void WriteEntities <I, T>(
            IIndexInfo <I> indexInfo,
            Dictionary <I, T> entities,
            List <Type> types,
            string savePath,
            out Dictionary <string, int> counts
            ) where T : class, ISerializable
        {
            counts = new Dictionary <string, int>();

            var typeName = indexInfo.TypeName;

            var path = Path.Combine(savePath, typeName);

            AssemblyHandler.EnsureDirectory(path);

            string idxPath = Path.Combine(path, $"{typeName}.idx");
            string tdbPath = Path.Combine(path, $"{typeName}.tdb");
            string binPath = Path.Combine(path, $"{typeName}.bin");

            using var idx = new BinaryFileWriter(idxPath, false);
            using var tdb = new BinaryFileWriter(tdbPath, false);
            using var bin = new BinaryFileWriter(binPath, true);

            idx.Write(entities.Count);
            foreach (var e in entities.Values)
            {
                long start = bin.Position;

                idx.Write(e.TypeRef);
                idx.Write(e.Serial);
                idx.Write(start);

                e.SerializeTo(bin);

                idx.Write((int)(bin.Position - start));

                var type = e.GetType().FullName;
                if (type != null)
                {
                    counts[type] = (counts.TryGetValue(type, out var count) ? count : 0) + 1;
                }
            }

            tdb.Write(types.Count);
            for (int i = 0; i < types.Count; ++i)
            {
                tdb.Write(types[i].FullName);
            }
        }
Пример #8
0
        private static List <Tuple <ConstructorInfo, string> > ReadTypes <I>(BinaryReader tdbReader)
        {
            var constructorTypes = new[] { typeof(I) };

            var count = tdbReader.ReadInt32();

            var types = new List <Tuple <ConstructorInfo, string> >(count);

            for (var i = 0; i < count; ++i)
            {
                var typeName = tdbReader.ReadString();

                var t = AssemblyHandler.FindTypeByFullName(typeName, false);

                if (t?.IsAbstract != false)
                {
                    Persistence.WriteConsoleLine("failed");

                    var issue = t?.IsAbstract == true ? "marked abstract" : "not found";

                    Persistence.WriteConsoleLine($"Error: Type '{typeName}' was {issue}. Delete all of those types? (y/n)");

                    if (Console.ReadKey(true).Key == ConsoleKey.Y)
                    {
                        types.Add(null);
                        Persistence.WriteConsole("Loading...");
                        continue;
                    }

                    Persistence.WriteConsoleLine("Types will not be deleted. An exception will be thrown.");

                    throw new Exception($"Bad type '{typeName}'");
                }

                var ctor = t.GetConstructor(constructorTypes);

                if (ctor != null)
                {
                    types.Add(new Tuple <ConstructorInfo, string>(ctor, typeName));
                }
                else
                {
                    throw new Exception($"Type '{t}' does not have a serialization constructor");
                }
            }

            return(types);
        }
        private void init()
        {
            List <IAccept> acs = AssemblyHandler.CreateInstance <IAccept>();

            foreach (IAccept ac in acs)
            {
                this.receiveMsgCallBack += ac.acceptMessage;
            }

            List <IServer> ses = AssemblyHandler.CreateInstance <IServer>();

            foreach (IServer se in ses)
            {
                se.init(this);
            }
        }
Пример #10
0
        public static void LoadRegions()
        {
            var path = Path.Join(Core.BaseDirectory, "Data/regions.json");

            // Json Deserialization options for custom objects
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.Converters.Add(new MapConverterFactory());
            options.Converters.Add(new Point3DConverterFactory());
            options.Converters.Add(new Rectangle3DConverterFactory());

            List <string> failures = new List <string>();
            int           count    = 0;

            Console.Write("Regions: Loading...");

            var stopwatch = Stopwatch.StartNew();
            List <DynamicJson> regions = JsonConfig.Deserialize <List <DynamicJson> >(path);

            foreach (var json in regions)
            {
                Type type = AssemblyHandler.FindFirstTypeForName(json.Type);

                if (type == null || !typeof(Region).IsAssignableFrom(type))
                {
                    failures.Add($"\tInvalid region type {json.Type}");
                    continue;
                }

                var region = ActivatorUtil.CreateInstance(type, json, options) as Region;
                region?.Register();
                count++;
            }

            stopwatch.Stop();

            Console.ForegroundColor = failures.Count > 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
            Console.Write("done{0}. ", failures.Count > 0 ? " with failures" : "");
            Console.ResetColor();
            Console.WriteLine("({0} regions, {1} failures) ({2:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds);
            if (failures.Count > 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(string.Join("\n", failures));
                Console.ResetColor();
            }
        }
Пример #11
0
        public static void Serialize(string path, Action <IGenericWriter> serializer)
        {
            AssemblyHandler.EnsureDirectory(Path.GetDirectoryName(path));

            using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.None);
            var writer = new BinaryFileWriter(fs, true);

            try
            {
                serializer(writer);
            }
            catch (Exception e)
            {
                Console.WriteLine("[Persistence]: Failed to serialize");
                Console.WriteLine(e);
            }
        }
Пример #12
0
        public static void LoadRegions()
        {
            var path = Path.Join(Core.BaseDirectory, "Data/regions.json");

            var failures = new List <string>();
            var count    = 0;

            Console.Write("Regions: Loading...");

            var stopwatch = Stopwatch.StartNew();
            var regions   = JsonConfig.Deserialize <List <DynamicJson> >(path);

            foreach (var json in regions)
            {
                var type = AssemblyHandler.FindFirstTypeForName(json.Type);

                if (type == null || !typeof(Region).IsAssignableFrom(type))
                {
                    failures.Add($"\tInvalid region type {json.Type}");
                    continue;
                }

                var region = type.CreateInstance <Region>(json, JsonConfig.DefaultOptions);
                region?.Register();
                count++;
            }

            stopwatch.Stop();

            Console.ForegroundColor = failures.Count > 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
            Console.Write("done{0}. ", failures.Count > 0 ? " with failures" : "");
            Console.ResetColor();
            Console.WriteLine(
                "({0} regions, {1} failures) ({2:F2} seconds)",
                count,
                failures.Count,
                stopwatch.Elapsed.TotalSeconds
                );
            if (failures.Count > 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(string.Join("\n", failures));
                Console.ResetColor();
            }
        }
Пример #13
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 buffer = GC.AllocateUninitializedArray <byte>((int)bin.Length);
                    bin.Read(buffer);
                    deserializer(new BufferReader(buffer));
                }
                catch (Exception e)
                {
                    Utility.PushColor(ConsoleColor.Red);
                    Console.WriteLine($"***** Bad deserialize of {name} *****");
                    Console.WriteLine(e.ToString());
                    Utility.PopColor();
                }
            }

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