|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Text.RegularExpressions;
- using UnityEngine;
-
- namespace SUISS.Storage
- {
- public class Storage
- {
- static Storage()
- {
- Storage.storableAliases = new Dictionary<string, Type>();
- Storage._lastFileSaveDateTime = new Dictionary<string, DateTime>();
- foreach (Type type in Storage.GetAllTypes())
- {
- object[] customAttributes = type.GetCustomAttributes(typeof(StorableAlias), true);
- if (customAttributes != null)
- {
- foreach (StorableAlias storableAlias in customAttributes)
- {
- if (string.IsNullOrEmpty(storableAlias.FullName))
- {
- throw new Exception("Found a StorableAlias for " + type.FullName + " with a FullName that is null or an empty string.");
- }
- if (Storage.storableAliases.ContainsKey(storableAlias.FullName))
- {
- throw new Exception(string.Concat(new string[]
- {
- "Duplicate StorableAlias found: ",
- storableAlias.FullName,
- " is registered as alias for both ",
- Storage.storableAliases[storableAlias.FullName].FullName,
- " and ",
- type.FullName,
- "."
- }));
- }
- Storage.storableAliases[storableAlias.FullName] = type;
- }
- }
- }
- Storage._storagePath = Application.persistentDataPath;
- }
-
- private Storage(StorageLifecycle lifecycle)
- {
- this._lifecycle = lifecycle;
- this._path = null;
- if (this._lifecycle != StorageLifecycle.Session)
- {
- this._path = "Storage";
- if (this._lifecycle == StorageLifecycle.Purchases)
- {
- this._path = Path.Combine(this._path, "P");
- }
- else if (this._lifecycle != StorageLifecycle.Forever)
- {
- this._path = Path.Combine(this._path, WWW.EscapeURL(Storage.currentPlayer));
- if (this._lifecycle != StorageLifecycle.Player)
- {
- this._path = Path.Combine(this._path, "Game");
- }
- }
- }
- this.Load();
- }
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public static event Action NewGameEvent;
-
- public static bool ShouldShowDiskFullWarning { get; private set; }
-
- public static string CurrentPlayer
- {
- get
- {
- return Storage.currentPlayer;
- }
- }
-
- private static Type[] GetAllTypes()
- {
- return Assembly.GetExecutingAssembly().GetTypes();
- }
-
- public static Storage Get(StorageLifecycle lifecycle)
- {
- if (lifecycle < StorageLifecycle.Forever)
- {
- return null;
- }
- while (lifecycle >= (StorageLifecycle)Storage.storageCache.Count)
- {
- Storage.storageCache.Add(null);
- }
- if (Storage.storageCache[(int)lifecycle] == null)
- {
- Storage.storageCache[(int)lifecycle] = new Storage(lifecycle);
- }
- return Storage.storageCache[(int)lifecycle];
- }
-
- public static void ChangePlayer(string player, bool deleteOld)
- {
- if (player == null)
- {
- throw new ArgumentException("Player can't be null.", "player");
- }
- if (deleteOld)
- {
- Storage storage = Storage.Get(StorageLifecycle.Player);
- storage.Delete();
- }
- Storage.storageCache[1] = null;
- Storage.currentPlayer = player;
- }
-
- public static void NewGame()
- {
- Storage storage = Storage.Get(StorageLifecycle.Game);
- storage.Delete();
- Storage.storageCache[2] = null;
- if (Storage.NewGameEvent != null)
- {
- Storage.NewGameEvent();
- }
- }
-
- public static void NewSession()
- {
- Storage storage = Storage.Get(StorageLifecycle.Session);
- storage.Delete();
- Storage.storageCache[3] = null;
- }
-
- public static void SaveAll(bool obsolete = false)
- {
- Storage.Save(Storage.storageCache);
- }
-
- public static void Save(IEnumerable<Storage> storages)
- {
- Dictionary<string, Dictionary<string, object>> dictionary = new Dictionary<string, Dictionary<string, object>>();
- foreach (Storage storage in storages)
- {
- if (storage != null && storage._path != null)
- {
- bool flag;
- string key = storage.FindSaveFile(out flag);
- dictionary[key] = storage.Root;
- storage.DeleteOldVersions((!flag) ? 0 : -1);
- }
- }
- foreach (string text in dictionary.Keys)
- {
- Dictionary<string, object> dictionary2 = dictionary[text];
- Exception arg = null;
- string text2 = Path.Combine(Storage._storagePath, text);
- if (!Storage.SaveDictionary(dictionary2, text2, out arg))
- {
- string message = string.Format("Unable to save dictionary to {0}: {1}", text, arg);
- UnityEngine.Debug.LogError(message);
- DateTime dateTime;
- string text3 = (!Storage._lastFileSaveDateTime.TryGetValue(text2, out dateTime)) ? "Never" : dateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
- UnityEngine.Debug.LogErrorFormat("[Unable to save {0}] Previous save time: {1} ; Current time: {2}", new object[]
- {
- text,
- text3,
- DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff")
- });
- }
- else
- {
- Storage._lastFileSaveDateTime[text2] = DateTime.UtcNow;
- }
- }
- }
-
- public static void SaveLifecycle(StorageLifecycle lifecycle, bool obsolete = false)
- {
- Storage.Save(new List<Storage>
- {
- Storage.Get(lifecycle)
- });
- }
-
- public static Dictionary<string, object> LoadDictionary(string filename)
- {
- Dictionary<string, object> result = null;
- if (filename != null && File.Exists(filename))
- {
- try
- {
- using (Stream stream = File.Open(filename, FileMode.Open, FileAccess.Read))
- {
- result = (Dictionary<string, object>)Storage.DeserializeObject(stream, new byte[20], new List<string>());
- }
- }
- catch (Exception ex)
- {
- UnityEngine.Debug.LogErrorFormat("Unable to load dictionary to {0}: {1}", new object[]
- {
- filename,
- ex.ToString()
- });
- }
- }
- return result;
- }
-
- public static bool ExceptionMeansFullDisk(Exception ex)
- {
- return ex != null && !string.IsNullOrEmpty(ex.Message) && ex.Message.ToLower().Contains("disk full");
- }
-
- public static bool SaveDictionary(Dictionary<string, object> dictionary, string filename, out Exception outException)
- {
- outException = null;
- if (filename == null || dictionary == null)
- {
- return false;
- }
- try
- {
- string directoryName = Path.GetDirectoryName(filename);
- if (directoryName != null && !Directory.Exists(directoryName))
- {
- Directory.CreateDirectory(directoryName);
- }
- }
- catch (Exception innerException)
- {
- outException = new Exception("Directory creation failed.", innerException);
- return false;
- }
- string text = Path.Combine(Path.GetDirectoryName(filename), "tmp_" + Path.GetFileName(filename));
- Stream stream = null;
- try
- {
- stream = File.Open(text, FileMode.Create, FileAccess.Write);
- Storage.SerializeObject(stream, dictionary, new byte[20], new Dictionary<string, uint>());
- }
- catch (Exception ex)
- {
- if (Storage.ExceptionMeansFullDisk(ex) || Storage.ExceptionMeansFullDisk(ex.InnerException))
- {
- Storage.ShowDiskFullWarning();
- }
- outException = new Exception("Stream opening & writing failed.", ex);
- return false;
- }
- finally
- {
- try
- {
- stream.Dispose();
- }
- catch (Exception)
- {
- }
- }
- if (File.Exists(filename))
- {
- try
- {
- File.Delete(filename);
- }
- catch (Exception innerException2)
- {
- outException = new Exception("Existing save file removal failed.", innerException2);
- return false;
- }
- }
- try
- {
- File.Move(text, filename);
- }
- catch (Exception innerException3)
- {
- outException = new Exception("Temporary file renaming failed.", innerException3);
- return false;
- }
- return true;
- }
-
- public static Dictionary<string, object> CloneDictionary(Dictionary<string, object> dictionary)
- {
- if (dictionary == null)
- {
- return null;
- }
- Dictionary<string, object> dictionary2 = new Dictionary<string, object>(dictionary.Count);
- foreach (KeyValuePair<string, object> keyValuePair in dictionary)
- {
- dictionary2[keyValuePair.Key] = Storage.CloneObject(keyValuePair.Value);
- }
- return dictionary2;
- }
-
- public static List<object> CloneList(List<object> list)
- {
- if (list == null)
- {
- return null;
- }
- List<object> list2 = new List<object>(list.Count);
- foreach (object o in list)
- {
- list2.Add(Storage.CloneObject(o));
- }
- return list2;
- }
-
- public static object[] CloneArray(object[] array)
- {
- if (array == null)
- {
- return null;
- }
- object[] array2 = new object[array.Length];
- for (int i = 0; i < array.Length; i++)
- {
- array2[i] = Storage.CloneObject(array[i]);
- }
- return array2;
- }
-
- public static IStorable CloneIStorable(IStorable storable)
- {
- if (storable == null)
- {
- return null;
- }
- IDictionary<string, object> dict = storable.ToStorage();
- Type type = storable.GetType();
- ConstructorInfo constructor = type.GetConstructor(new Type[0]);
- if (constructor == null)
- {
- throw new FormatException("Type " + type.AssemblyQualifiedName + " does not have an empty constructor.");
- }
- IStorable storable2 = (IStorable)constructor.Invoke(null);
- storable2.FromStorage(dict);
- return storable2;
- }
-
- public static object CloneObject(object o)
- {
- if (o is Dictionary<string, object>)
- {
- return Storage.CloneDictionary((Dictionary<string, object>)o);
- }
- if (o is List<object>)
- {
- return Storage.CloneList((List<object>)o);
- }
- if (o is object[])
- {
- return Storage.CloneArray((object[])o);
- }
- if (o is ICloneable)
- {
- return ((ICloneable)o).Clone();
- }
- if (o is IStorable)
- {
- return Storage.CloneIStorable((IStorable)o);
- }
- if (o != null && !o.GetType().IsValueType)
- {
- UnityEngine.Debug.LogErrorFormat("\"Cloning\" type {0}", new object[]
- {
- o.GetType()
- });
- }
- return o;
- }
-
- public static bool VerifyType(object o)
- {
- return Storage.VerifyType(o, false);
- }
-
- public static bool VerifyType(object o, bool throwException)
- {
- if (object.ReferenceEquals(o, null) || o is Dictionary<string, object> || o is List<object> || o is object[] || o is string || o is bool || o is char || o is float || o is double || o is sbyte || o is byte || o is short || o is ushort || o is int || o is uint || o is long || o is ulong || o is decimal || o is IStorable)
- {
- return true;
- }
- if (throwException)
- {
- throw new ArgumentException(string.Concat(new object[]
- {
- "Value ",
- o,
- " of type ",
- o.GetType().AssemblyQualifiedName,
- " is not a storable type."
- }));
- }
- return false;
- }
-
- public static string DictToString(Dictionary<string, object> storage)
- {
- string result;
- using (Stream stream = new MemoryStream())
- {
- Storage.SerializeObject(stream, storage, new byte[20], new Dictionary<string, uint>());
- stream.Flush();
- stream.Position = 0L;
- string text = Convert.ToBase64String(Storage.ReadFully(stream));
- result = text;
- }
- return result;
- }
-
- public static Dictionary<string, object> StringToDict(string input)
- {
- byte[] buffer = Convert.FromBase64String(input);
- Dictionary<string, object> result;
- using (MemoryStream memoryStream = new MemoryStream(buffer))
- {
- memoryStream.Flush();
- memoryStream.Position = 0L;
- result = (Dictionary<string, object>)Storage.DeserializeObject(memoryStream, new byte[20], new List<string>());
- }
- return result;
- }
-
- public static bool UnityVersionIsAtLeast(string version, int major, int minor, int revision, int patch)
- {
- Regex regex = new Regex("^([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:(.)([0-9]+))?$", RegexOptions.CultureInvariant);
- Match match = regex.Match(version);
- if (!match.Success)
- {
- return true;
- }
- int num = int.Parse(match.Groups[1].ToString());
- int num2 = int.Parse(match.Groups[2].ToString());
- int num3 = int.Parse(match.Groups[3].ToString());
- int num4 = (!match.Groups[5].Success) ? 0 : int.Parse(match.Groups[5].ToString());
- if (num != major)
- {
- return num > major;
- }
- if (num2 != minor)
- {
- return num2 > minor;
- }
- if (num3 != revision)
- {
- return num3 > revision;
- }
- return num4 >= patch;
- }
-
- private static object DeserializeObject(Stream stream, byte[] buffer, List<string> stringTable)
- {
- int num = stream.ReadByte();
- if (num < 0)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- char c = (char)num;
- if (c == 'n')
- {
- return null;
- }
- if (c == '{')
- {
- int num2 = (int)Storage.ReadLength(stream);
- Dictionary<string, object> dictionary = new Dictionary<string, object>(num2);
- for (int i = 0; i < num2; i++)
- {
- string key = (string)Storage.DeserializeObject(stream, buffer, stringTable);
- object value = Storage.DeserializeObject(stream, buffer, stringTable);
- dictionary.Add(key, value);
- }
- return dictionary;
- }
- if (c == '[')
- {
- int num3 = (int)Storage.ReadLength(stream);
- List<object> list = new List<object>();
- for (int j = 0; j < num3; j++)
- {
- object item = Storage.DeserializeObject(stream, buffer, stringTable);
- list.Add(item);
- }
- return list;
- }
- if (c == ']')
- {
- int num4 = (int)Storage.ReadLength(stream);
- object[] array = new object[num4];
- for (int k = 0; k < num4; k++)
- {
- array[k] = Storage.DeserializeObject(stream, buffer, stringTable);
- }
- return array;
- }
- if (c == '$')
- {
- int num5 = (int)Storage.ReadLength(stream);
- byte[] array2 = new byte[num5];
- if (stream.Read(array2, 0, num5) != num5)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- string @string = Encoding.UTF8.GetString(array2, 0, array2.Length);
- stringTable.Add(@string);
- return @string;
- }
- else if (c == '#')
- {
- int num6 = (int)Storage.ReadLength(stream);
- if (num6 < 0 || num6 >= stringTable.Count)
- {
- throw new FormatException("String table index out of bounds.");
- }
- return stringTable[num6];
- }
- else if (c == '@')
- {
- string text = (string)Storage.DeserializeObject(stream, buffer, stringTable);
- Dictionary<string, object> dictionary2 = (Dictionary<string, object>)Storage.DeserializeObject(stream, buffer, stringTable);
- string typeFullName = Storage.GetTypeFullName(text);
- Type type;
- if (Storage.storableAliases.ContainsKey(typeFullName))
- {
- type = Storage.storableAliases[typeFullName];
- }
- else
- {
- type = Type.GetType(text);
- if (type == null)
- {
- UnityEngine.Debug.LogError(string.Format("Unable to find type {0} while deserializing. Will return Dictionary<string, object> instead.", text));
- return dictionary2;
- }
- }
- ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
- object obj;
- if (constructor == null)
- {
- obj = Activator.CreateInstance(type);
- }
- else
- {
- obj = constructor.Invoke(null);
- }
- if (obj == null)
- {
- throw new FormatException("Type " + text + " does not have an empty constructor; nor is it a struct with default constructor.");
- }
- ((IStorable)obj).FromStorage(dictionary2);
- return obj;
- }
- else
- {
- if (c == '1')
- {
- return true;
- }
- if (c == '0')
- {
- return false;
- }
- if (c == 'c')
- {
- if (stream.Read(buffer, 0, 2) != 2)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (char)((int)buffer[0] << 8 | (int)buffer[1]);
- }
- else
- {
- if (c == 'f')
- {
- Storage.UIntToFloat uintToFloat = default(Storage.UIntToFloat);
- uintToFloat.UIntValue = Storage.ReadInt(stream, buffer);
- return uintToFloat.FloatValue;
- }
- if (c == 'd')
- {
- uint num7 = Storage.ReadInt(stream, buffer);
- uint num8 = Storage.ReadInt(stream, buffer);
- return BitConverter.Int64BitsToDouble((long)((ulong)num7 << 32 | (ulong)num8));
- }
- if (c == 'b')
- {
- int num9 = stream.ReadByte();
- if (num9 < 0)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (sbyte)num9;
- }
- else if (c == 'B')
- {
- int num10 = stream.ReadByte();
- if (num10 < 0)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (byte)num10;
- }
- else if (c == 's')
- {
- if (stream.Read(buffer, 0, 2) != 2)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (short)((int)buffer[0] << 8 | (int)buffer[1]);
- }
- else if (c == 'S')
- {
- if (stream.Read(buffer, 0, 2) != 2)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (ushort)((int)buffer[0] << 8 | (int)buffer[1]);
- }
- else
- {
- if (c == 'i')
- {
- return (int)Storage.ReadInt(stream, buffer);
- }
- if (c == 'I')
- {
- return Storage.ReadInt(stream, buffer);
- }
- if (c == 'l')
- {
- if (stream.Read(buffer, 0, 8) != 8)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (long)((ulong)buffer[0] << 56 | (ulong)buffer[1] << 48 | (ulong)buffer[2] << 40 | (ulong)buffer[3] << 32 | (ulong)buffer[4] << 24 | (ulong)buffer[5] << 16 | (ulong)buffer[6] << 8 | (ulong)buffer[7]);
- }
- else if (c == 'L')
- {
- if (stream.Read(buffer, 0, 8) != 8)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (ulong)buffer[0] << 56 | (ulong)buffer[1] << 48 | (ulong)buffer[2] << 40 | (ulong)buffer[3] << 32 | (ulong)buffer[4] << 24 | (ulong)buffer[5] << 16 | (ulong)buffer[6] << 8 | (ulong)buffer[7];
- }
- else
- {
- if (c == 'a')
- {
- int[] array3 = new int[4];
- for (int l = 0; l < 4; l++)
- {
- array3[l] = (int)Storage.ReadInt(stream, buffer);
- }
- return new decimal(array3);
- }
- throw new FormatException("Unknown type (" + c + ") encountered.");
- }
- }
- }
- }
- }
-
- private static void SerializeObject(Stream stream, object o, byte[] buffer, Dictionary<string, uint> stringTable)
- {
- try
- {
- if (object.ReferenceEquals(o, null))
- {
- stream.WriteByte(110);
- }
- else if (o is Dictionary<string, object>)
- {
- Dictionary<string, object> dictionary = (Dictionary<string, object>)o;
- stream.WriteByte(123);
- WriteLength(stream, (uint)dictionary.Count, buffer);
- foreach (KeyValuePair<string, object> item in dictionary)
- {
- SerializeObject(stream, item.Key, buffer, stringTable);
- SerializeObject(stream, item.Value, buffer, stringTable);
- }
- }
- else if (o is List<object>)
- {
- List<object> list = (List<object>)o;
- stream.WriteByte(91);
- WriteLength(stream, (uint)list.Count, buffer);
- foreach (object item2 in list)
- {
- SerializeObject(stream, item2, buffer, stringTable);
- }
- }
- else if (o is object[])
- {
- object[] array = (object[])o;
- stream.WriteByte(93);
- WriteLength(stream, (uint)array.Length, buffer);
- object[] array2 = array;
- foreach (object o2 in array2)
- {
- SerializeObject(stream, o2, buffer, stringTable);
- }
- }
- else if (o is string)
- {
- string text = (string)o; uint value;
- if (stringTable.TryGetValue(text, out value))
- {
- stream.WriteByte(35);
- WriteLength(stream, value, buffer);
- }
- else
- {
- byte[] bytes = Encoding.UTF8.GetBytes(text);
- stream.WriteByte(36);
- WriteLength(stream, (uint)bytes.Length, buffer);
- stream.Write(bytes, 0, bytes.Length);
- stringTable[text] = (uint)stringTable.Count;
- }
- }
- else if (o is bool)
- {
- if ((bool)o)
- {
- stream.WriteByte(49);
- }
- else
- {
- stream.WriteByte(48);
- }
- }
- else if (o is char)
- {
- int num = (char)o;
- buffer[0] = 99;
- buffer[1] = (byte)(num >> 8);
- buffer[2] = (byte)(num & 0xFF);
- stream.Write(buffer, 0, 3);
- }
- else if (o is float)
- {
- UIntToFloat uIntToFloat = default(UIntToFloat);
- uIntToFloat.FloatValue = (float)o;
- stream.WriteByte(102);
- WriteInt(stream, uIntToFloat.UIntValue, buffer);
- }
- else if (o is double)
- {
- ulong num2 = (ulong)BitConverter.DoubleToInt64Bits((double)o);
- stream.WriteByte(100);
- WriteInt(stream, (uint)(num2 >> 32), buffer);
- WriteInt(stream, (uint)(num2 & uint.MaxValue), buffer);
- }
- else if (o is sbyte)
- {
- byte b = (byte)(sbyte)o;
- buffer[0] = 98;
- buffer[1] = b;
- stream.Write(buffer, 0, 2);
- }
- else if (o is byte)
- {
- byte b2 = (byte)o;
- buffer[0] = 66;
- buffer[1] = b2;
- stream.Write(buffer, 0, 2);
- }
- else if (o is short)
- {
- uint num3 = (uint)(short)o;
- buffer[0] = 115;
- buffer[1] = (byte)(num3 >> 8);
- buffer[2] = (byte)(num3 & 0xFF);
- stream.Write(buffer, 0, 3);
- }
- else if (o is ushort)
- {
- uint num4 = (ushort)o;
- buffer[0] = 83;
- buffer[1] = (byte)(num4 >> 8);
- buffer[2] = (byte)(num4 & 0xFF);
- stream.Write(buffer, 0, 3);
- }
- else if (o is int)
- {
- uint num5 = (uint)(int)o;
- buffer[0] = 105;
- buffer[1] = (byte)(num5 >> 24);
- buffer[2] = (byte)((num5 >> 16) & 0xFF);
- buffer[3] = (byte)((num5 >> 8) & 0xFF);
- buffer[4] = (byte)(num5 & 0xFF);
- stream.Write(buffer, 0, 5);
- }
- else if (o is uint)
- {
- uint num6 = (uint)o;
- buffer[0] = 73;
- buffer[1] = (byte)(num6 >> 24);
- buffer[2] = (byte)((num6 >> 16) & 0xFF);
- buffer[3] = (byte)((num6 >> 8) & 0xFF);
- buffer[4] = (byte)(num6 & 0xFF);
- stream.Write(buffer, 0, 5);
- }
- else if (o is long)
- {
- ulong num7 = (ulong)(long)o;
- buffer[0] = 108;
- buffer[1] = (byte)(num7 >> 56);
- buffer[2] = (byte)((num7 >> 48) & 0xFF);
- buffer[3] = (byte)((num7 >> 40) & 0xFF);
- buffer[4] = (byte)((num7 >> 32) & 0xFF);
- buffer[5] = (byte)((num7 >> 24) & 0xFF);
- buffer[6] = (byte)((num7 >> 16) & 0xFF);
- buffer[7] = (byte)((num7 >> 8) & 0xFF);
- buffer[8] = (byte)(num7 & 0xFF);
- stream.Write(buffer, 0, 9);
- }
- else if (o is ulong)
- {
- ulong num8 = (ulong)o;
- buffer[0] = 76;
- buffer[1] = (byte)(num8 >> 56);
- buffer[2] = (byte)((num8 >> 48) & 0xFF);
- buffer[3] = (byte)((num8 >> 40) & 0xFF);
- buffer[4] = (byte)((num8 >> 32) & 0xFF);
- buffer[5] = (byte)((num8 >> 24) & 0xFF);
- buffer[6] = (byte)((num8 >> 16) & 0xFF);
- buffer[7] = (byte)((num8 >> 8) & 0xFF);
- buffer[8] = (byte)(num8 & 0xFF);
- stream.Write(buffer, 0, 9);
- }
- else if (o is decimal)
- {
- decimal d = (decimal)o;
- stream.WriteByte(97);
- int[] bits = decimal.GetBits(d);
- for (int j = 0; j < 4; j++)
- {
- WriteInt(stream, (uint)bits[j], buffer);
- }
- }
- else
- {
- if (!(o is IStorable))
- {
- throw new FormatException("Can't serialize object " + o.ToString() + " because it does not implement IStorable.");
- }
- stream.WriteByte(64);
- SerializeObject(stream, o.GetType().AssemblyQualifiedName, buffer, stringTable);
- SerializeObject(stream, ((IStorable)o).ToStorage(), buffer, stringTable);
- }
- }
- catch (CaughtException)
- {
- throw;
- }
- catch (Exception ex2)
- {
- string message = string.Format("SerializeObject exception of object of type {0}", (o != null) ? o.GetType().ToString() : "null");
- throw new CaughtException(message, ex2);
- }
- }
-
- private static void WriteLength(Stream stream, uint length, byte[] buffer)
- {
- int count = 0;
- uint num;
- for (num = length; num >= 128u; num >>= 7)
- {
- buffer[count++] = (byte)(128u | (num & 127u));
- }
- buffer[count++] = (byte)num;
- stream.Write(buffer, 0, count);
- }
-
- private static uint ReadLength(Stream stream)
- {
- uint num = 0u;
- int num2 = 0;
- int num3;
- while ((num3 = stream.ReadByte()) >= 128)
- {
- if (num2 >= 4)
- {
- throw new FormatException("Invalid length.");
- }
- num |= (uint)((uint)(num3 & 127) << num2 * 7);
- num2++;
- }
- if (num3 < 0)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return num | (uint)((uint)num3 << num2 * 7);
- }
-
- private static void WriteInt(Stream stream, uint i, byte[] buffer)
- {
- buffer[0] = (byte)(i >> 24);
- buffer[1] = (byte)(i >> 16 & 255u);
- buffer[2] = (byte)(i >> 8 & 255u);
- buffer[3] = (byte)(i & 255u);
- stream.Write(buffer, 0, 4);
- }
-
- private static uint ReadInt(Stream stream, byte[] buffer)
- {
- int num = stream.Read(buffer, 0, 4);
- if (num != 4)
- {
- throw new FormatException("Unexpected end of stream.");
- }
- return (uint)((int)buffer[0] << 24 | (int)buffer[1] << 16 | (int)buffer[2] << 8 | (int)buffer[3]);
- }
-
- private static void ShowDiskFullWarning()
- {
- Storage.ShouldShowDiskFullWarning = true;
- }
-
- private static string GetTypeFullName(string assemblyQualifiedName)
- {
- int num = assemblyQualifiedName.IndexOf(',');
- if (num >= 0)
- {
- return assemblyQualifiedName.Substring(0, num);
- }
- return assemblyQualifiedName;
- }
-
- private static byte[] ReadFully(Stream stream)
- {
- byte[] array = new byte[32768];
- byte[] result;
- using (MemoryStream memoryStream = new MemoryStream())
- {
- for (; ; )
- {
- int num = stream.Read(array, 0, array.Length);
- if (num <= 0)
- {
- break;
- }
- memoryStream.Write(array, 0, num);
- }
- result = memoryStream.ToArray();
- }
- return result;
- }
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event Storage.OnSyncHandler OnSync;
-
- public StorageLifecycle Lifecycle
- {
- get
- {
- return this._lifecycle;
- }
- }
-
- public Dictionary<string, object> Root
- {
- get
- {
- if (this.OnSync != null)
- {
- this.OnSync();
- }
- return this._root;
- }
- }
-
- public DateTime CreationTimestamp
- {
- get
- {
- object obj;
- if (this._root.TryGetValue("~Creation~", out obj))
- {
- return new DateTime((long)obj, DateTimeKind.Utc);
- }
- return DateTime.MinValue;
- }
- private set
- {
- if (value.Kind != DateTimeKind.Utc)
- {
- value = value.ToUniversalTime();
- }
- this._root["~Creation~"] = value.Ticks;
- }
- }
-
- public DateTime UpdateTimestamp
- {
- get
- {
- object obj;
- if (this._root.TryGetValue("~Update~", out obj))
- {
- return new DateTime((long)obj, DateTimeKind.Utc);
- }
- return DateTime.MinValue;
- }
- private set
- {
- if (value.Kind != DateTimeKind.Utc)
- {
- value = value.ToUniversalTime();
- }
- this._root["~Update~"] = value.Ticks;
- }
- }
-
- public long Version
- {
- get
- {
- object obj;
- if (this._root.TryGetValue("~Version~", out obj))
- {
- return (long)obj;
- }
- return 0L;
- }
- private set
- {
- this._root["~Version~"] = value;
- }
- }
-
- public Dictionary<string, object> GetDictionary(string key)
- {
- if (string.IsNullOrEmpty(key))
- {
- return new Dictionary<string, object>();
- }
- object obj;
- if (this.Root.TryGetValue(key, out obj) && obj is Dictionary<string, object>)
- {
- return (Dictionary<string, object>)obj;
- }
- Dictionary<string, object> dictionary = new Dictionary<string, object>();
- this._root.Add(key, dictionary);
- return dictionary;
- }
-
- private void Load()
- {
- if (this._path == null)
- {
- this._root = new Dictionary<string, object>();
- }
- else
- {
- this._root = null;
- string[] array = this.ListSaveFiles();
- int num = array.Length - 1;
- while (this._root == null && num >= 0)
- {
- string text = array[num];
- UnityEngine.Debug.LogFormat("Loading file {0}", new object[]
- {
- text
- });
- this._root = Storage.LoadDictionary(text);
- num--;
- if (this._root == null)
- {
- UnityEngine.Debug.LogWarningFormat("Failed to load file! Will try to load a backup!", new object[0]);
- }
- else
- {
- Storage._lastFileSaveDateTime[text] = this.UpdateTimestamp;
- }
- }
- if (this._root == null)
- {
- this._root = new Dictionary<string, object>();
- }
- }
- }
-
- private void Delete()
- {
- if (this._path != null)
- {
- string[] array = this.ListSaveFiles();
- foreach (string text in array)
- {
- try
- {
- File.Delete(text);
- }
- catch (Exception ex)
- {
- UnityEngine.Debug.LogWarning("Unable to delete dictionary at " + text + ": " + ex.Message);
- }
- }
- }
- }
-
- private void DeleteOldVersions(int keepExtra)
- {
- int num = 14 + keepExtra;
- string[] array = this.ListSaveFiles();
- for (int i = 0; i < array.Length - num; i++)
- {
- try
- {
- File.Delete(array[i]);
- }
- catch (Exception ex)
- {
- UnityEngine.Debug.LogWarning("Unable to delete dictionary at " + array[i] + ": " + ex.Message);
- }
- }
- }
-
- private string FindSaveFile(out bool isNew)
- {
- DateTime creationTimestamp = this.CreationTimestamp;
- DateTime utcNow = DateTime.UtcNow;
- long num = this.Version;
- if (Math.Abs(utcNow.Ticks - creationTimestamp.Ticks) >= 864000000000L)
- {
- num += 1L;
- this.Version = num;
- creationTimestamp = utcNow;
- this.CreationTimestamp = creationTimestamp;
- isNew = true;
- }
- else
- {
- isNew = false;
- }
- this.UpdateTimestamp = utcNow;
- return Path.Combine(this._path, "Data" + ((num != 0L) ? Convert.ToString(num, CultureInfo.InvariantCulture) : string.Empty));
- }
-
- private string[] ListSaveFiles()
- {
- string[] array = null;
- string text = Path.Combine(Storage._storagePath, this._path);
- try
- {
- array = Directory.GetFiles(text, "Data*");
- for (int i = 0; i < array.Length; i++)
- {
- array[i] = Path.Combine(text, array[i]);
- }
- }
- catch (DirectoryNotFoundException)
- {
- UnityEngine.Debug.Log("Unable to find files in " + text + " becuase the folder does not exist.");
- }
- catch (Exception ex)
- {
- UnityEngine.Debug.LogWarning("Unable to get files from " + text + ": " + ex.ToString());
- }
- if (array == null)
- {
- array = new string[0];
- }
- else
- {
- string[] array2 = new string[array.Length];
- Array.Copy(array, array2, array.Length);
- array = array2;
- Exception parseException = null;
- string parseExceptionName = null;
- Array.Sort<string>(array, delegate (string file1, string file2)
- {
- long num = 0L;
- string fileName = Path.GetFileName(file1);
- if (fileName.StartsWith("Data") && fileName.Length > "Data".Length)
- {
- try
- {
- num = Convert.ToInt64(fileName.Substring("Data".Length));
- }
- catch (Exception ex2)
- {
- UnityEngine.Debug.LogWarning(string.Format("Unable to parse fileVersion of {0}: {1}", fileName, ex2));
- parseException = ex2;
- parseExceptionName = fileName;
- }
- }
- long num2 = 0L;
- string fileName2 = Path.GetFileName(file2);
- if (fileName2.StartsWith("Data") && fileName2.Length > "Data".Length)
- {
- try
- {
- num2 = Convert.ToInt64(fileName2.Substring("Data".Length));
- }
- catch (Exception ex3)
- {
- UnityEngine.Debug.LogWarning(string.Format("Unable to parse fileVersion of {0}: {1}", fileName, ex3));
- parseException = ex3;
- parseExceptionName = fileName2;
- }
- }
- if (num < num2)
- {
- return -1;
- }
- if (num > num2)
- {
- return 1;
- }
- return 0;
- });
- if (parseException != null)
- {
- string message = string.Format("Unable to parse fileVersion of {0}", parseExceptionName);
- UnityEngine.Debug.LogError(message);
- }
- }
- return array;
- }
-
- private static string _storagePath;
-
- private static Dictionary<string, Type> storableAliases;
-
- private static Dictionary<string, DateTime> _lastFileSaveDateTime;
-
- public const string RootFolder = "Storage";
-
- public const string GameFolder = "Game";
-
- public const string PurchasesFolder = "P";
-
- public const string DataFilename = "Data";
-
- private const int SerializationBufferLength = 20;
-
- private const int OldVersionCount = 14;
-
- private const long TimestampGranularity = 864000000000L;
-
- private const string CreationTimestampKey = "~Creation~";
-
- private const string UpdateTimestampKey = "~Update~";
-
- private const string VersionKey = "~Version~";
-
- private static string currentPlayer = "Player";
-
- private static List<Storage> storageCache = new List<Storage>();
-
- private StorageLifecycle _lifecycle;
-
- private string _path;
-
- private Dictionary<string, object> _root;
-
- [StructLayout(LayoutKind.Explicit)]
- private struct UIntToFloat
- {
- [FieldOffset(0)]
- public float FloatValue;
-
- [FieldOffset(0)]
- public uint UIntValue;
- }
-
- public delegate void OnSyncHandler();
-
- private class CaughtException : Exception
- {
- public CaughtException(string message, Exception ex) : base(message, ex)
- {
- }
- }
- }
- }
|