Просмотр исходного кода

客户端加入LitJson,不再使用Mongo序列化,只使用Protobuf-net跟LitJson

tanghai 5 лет назад
Родитель
Сommit
77b2e3042d
59 измененных файлов с 4946 добавлено и 333 удалено
  1. 3 3
      Config/StartMachineConfig.txt
  2. 4 4
      Config/StartProcessConfig.txt
  3. 7 7
      Config/StartSceneConfig.txt
  4. 4 4
      Config/StartZoneConfig.txt
  5. 3 3
      Config/UnitConfig.txt
  6. 1 0
      Server/App/Program.cs
  7. 1 2
      Server/App/Server.App.csproj
  8. 1 2
      Server/Hotfix/Server.Hotfix.csproj
  9. 1 1
      Server/Model/Module/Config/ConfigHelper.cs
  10. 5 2
      Server/Model/Server.Model.csproj
  11. 1 0
      Server/ThirdParty/Server.ThirdParty.csproj
  12. 3 3
      Unity/Assets/Bundles/Config/StartMachineConfig.txt
  13. 4 4
      Unity/Assets/Bundles/Config/StartProcessConfig.txt
  14. 7 7
      Unity/Assets/Bundles/Config/StartSceneConfig.txt
  15. 4 4
      Unity/Assets/Bundles/Config/StartZoneConfig.txt
  16. 3 3
      Unity/Assets/Bundles/Config/UnitConfig.txt
  17. 1 1
      Unity/Assets/Editor/ComponentViewEditor/ComponentViewEditor.cs
  18. 4 4
      Unity/Assets/Editor/ExcelExporterEditor/ExcelExporterEditor.cs
  19. 0 0
      Unity/Assets/Editor/Helper/MongoHelper.cs
  20. 1 1
      Unity/Assets/Editor/Helper/MongoHelper.cs.meta
  21. 34 22
      Unity/Assets/Model/Core/Helper/JsonHelper.cs
  22. 0 5
      Unity/Assets/Model/Core/Helper/StringHelper.cs
  23. 38 27
      Unity/Assets/Model/Core/Object/Object.cs
  24. 106 108
      Unity/Assets/Model/Core/Object/ObjectPool.cs
  25. 1 9
      Unity/Assets/Model/Module/Config/ACategory.cs
  26. 4 0
      Unity/Assets/ModelView/MonoBehaviour/Init.cs
  27. 2 3
      Unity/Assets/ThirdParty/LitJson.meta
  28. 40 0
      Unity/Assets/ThirdParty/LitJson/Extensions.cs
  29. 11 0
      Unity/Assets/ThirdParty/LitJson/Extensions.cs.meta
  30. 60 0
      Unity/Assets/ThirdParty/LitJson/IJsonWrapper.cs
  31. 11 0
      Unity/Assets/ThirdParty/LitJson/IJsonWrapper.cs.meta
  32. 1059 0
      Unity/Assets/ThirdParty/LitJson/JsonData.cs
  33. 11 0
      Unity/Assets/ThirdParty/LitJson/JsonData.cs.meta
  34. 65 0
      Unity/Assets/ThirdParty/LitJson/JsonException.cs
  35. 11 0
      Unity/Assets/ThirdParty/LitJson/JsonException.cs.meta
  36. 1045 0
      Unity/Assets/ThirdParty/LitJson/JsonMapper.cs
  37. 11 0
      Unity/Assets/ThirdParty/LitJson/JsonMapper.cs.meta
  38. 105 0
      Unity/Assets/ThirdParty/LitJson/JsonMockWrapper.cs
  39. 11 0
      Unity/Assets/ThirdParty/LitJson/JsonMockWrapper.cs.meta
  40. 478 0
      Unity/Assets/ThirdParty/LitJson/JsonReader.cs
  41. 11 0
      Unity/Assets/ThirdParty/LitJson/JsonReader.cs.meta
  42. 487 0
      Unity/Assets/ThirdParty/LitJson/JsonWriter.cs
  43. 11 0
      Unity/Assets/ThirdParty/LitJson/JsonWriter.cs.meta
  44. 912 0
      Unity/Assets/ThirdParty/LitJson/Lexer.cs
  45. 11 0
      Unity/Assets/ThirdParty/LitJson/Lexer.cs.meta
  46. 24 0
      Unity/Assets/ThirdParty/LitJson/Netstandard15Polyfill.cs
  47. 11 0
      Unity/Assets/ThirdParty/LitJson/Netstandard15Polyfill.cs.meta
  48. 44 0
      Unity/Assets/ThirdParty/LitJson/ParserToken.cs
  49. 11 0
      Unity/Assets/ThirdParty/LitJson/ParserToken.cs.meta
  50. 153 0
      Unity/Assets/ThirdParty/LitJson/UnityTypeBindings.cs
  51. 11 0
      Unity/Assets/ThirdParty/LitJson/UnityTypeBindings.cs.meta
  52. 3 6
      Unity/Packages/manifest.json
  53. 11 25
      Unity/Packages/packages-lock.json
  54. 4 3
      Unity/Unity.Editor.csproj
  55. 9 9
      Unity/Unity.Hotfix.csproj
  56. 3 3
      Unity/Unity.HotfixView.csproj
  57. 51 52
      Unity/Unity.Model.csproj
  58. 3 3
      Unity/Unity.ModelView.csproj
  59. 15 3
      Unity/Unity.ThirdParty.csproj

+ 3 - 3
Config/StartMachineConfig.txt

@@ -1,3 +1,3 @@
-[
-[1, {"_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1"}],
-]
+{
+{"1":{{"_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1"}},
+}

+ 4 - 4
Config/StartProcessConfig.txt

@@ -1,4 +1,4 @@
-[
-[1, {"_id":1,"MachineId":1,"InnerPort":"20001"}],
-[2, {"_id":2,"MachineId":1,"InnerPort":"20002"}],
-]
+{
+{"1":{{"_id":1,"MachineId":1,"InnerPort":"20001"}},
+{"2":{{"_id":2,"MachineId":1,"InnerPort":"20002"}},
+}

+ 7 - 7
Config/StartSceneConfig.txt

@@ -1,7 +1,7 @@
-[
-[1, {"_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002}],
-[2, {"_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003}],
-[3, {"_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004}],
-[4, {"_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location"}],
-[5, {"_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map"}],
-]
+{
+{"1":{{"_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002}},
+{"2":{{"_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003}},
+{"3":{{"_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004}},
+{"4":{{"_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location"}},
+{"5":{{"_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map"}},
+}

+ 4 - 4
Config/StartZoneConfig.txt

@@ -1,4 +1,4 @@
-[
-[1, {"_id":1,"DBConnection":"mongdb://127.0.0.1","DBName":"ET1"}],
-[2, {"_id":2,"DBConnection":"mongdb://127.0.0.1","DBName":"ET2"}],
-]
+{
+{"1":{{"_id":1,"DBConnection":"mongdb://127.0.0.1","DBName":"ET1"}},
+{"2":{{"_id":2,"DBConnection":"mongdb://127.0.0.1","DBName":"ET2"}},
+}

+ 3 - 3
Config/UnitConfig.txt

@@ -1,3 +1,3 @@
-[
-[1001, {"_id":1001,"Name":"米克尔","Desc":"带有强力攻击技能","Position":1,"Height":178,"Weight":68}],
-]
+{
+{"1001":{{"_id":1001,"Name":"米克尔","Desc":"带有强力攻击技能","Position":1,"Height":178,"Weight":68}},
+}

+ 1 - 0
Server/App/Program.cs

@@ -19,6 +19,7 @@ namespace ET
 				Game.EventSystem.Add(typeof(Game).Assembly);
 				Game.EventSystem.Add(DllHelper.GetHotfixAssembly());
 				
+				ProtobufHelper.Init();
 				MongoHelper.Init();
 				
 				// 命令行参数

+ 1 - 2
Server/App/Server.App.csproj

@@ -3,8 +3,7 @@
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>netcoreapp3.1</TargetFramework>
-    <AssemblyName>App</AssemblyName>
-    <RootNamespace>App</RootNamespace>
+    <RootNamespace>ET</RootNamespace>
     <LangVersion>7.3</LangVersion>
   </PropertyGroup>
 

+ 1 - 2
Server/Hotfix/Server.Hotfix.csproj

@@ -1,8 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
-    <AssemblyName>Hotfix</AssemblyName>
-    <RootNamespace>ETHotfix</RootNamespace>
+    <RootNamespace>ET</RootNamespace>
     <LangVersion>7.3</LangVersion>
   </PropertyGroup>
   <PropertyGroup>

+ 1 - 1
Server/Model/Module/Config/ConfigHelper.cs

@@ -21,7 +21,7 @@ namespace ET
 
 		public static T ToObject<T>(string str)
 		{
-			return MongoHelper.FromJson<T>(str);
+			return JsonHelper.FromJson<T>(str);
 		}
 	}
 }

+ 5 - 2
Server/Model/Server.Model.csproj

@@ -1,8 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
-    <AssemblyName>Model</AssemblyName>
-    <RootNamespace>Model</RootNamespace>
+    <RootNamespace>ET</RootNamespace>
     <LangVersion>7.3</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
@@ -22,6 +21,10 @@
   </PropertyGroup>
   <ItemGroup>
 
+    <Compile Include="..\..\Unity\Assets\Editor\Helper\MongoHelper.cs">
+      <Link>Base\MongoHelper.cs</Link>
+    </Compile>
+
     <Compile Include="..\..\Unity\Assets\Model\Core\**\*.cs"> 
       <Link>Core\%(RecursiveDir)%(FileName)%(Extension)</Link>
     </Compile>

+ 1 - 0
Server/ThirdParty/Server.ThirdParty.csproj

@@ -2,6 +2,7 @@
 
     <PropertyGroup>
         <TargetFramework>netcoreapp3.1</TargetFramework>
+        <RootNamespace>ET</RootNamespace>
     </PropertyGroup>
 
     <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

+ 3 - 3
Unity/Assets/Bundles/Config/StartMachineConfig.txt

@@ -1,3 +1,3 @@
-[
-[1, {"_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1"}],
-]
+{
+{"1":{{"_id":1,"InnerIP":"127.0.0.1","OuterIP":"127.0.0.1"}},
+}

+ 4 - 4
Unity/Assets/Bundles/Config/StartProcessConfig.txt

@@ -1,4 +1,4 @@
-[
-[1, {"_id":1,"MachineId":1,"InnerPort":"20001"}],
-[2, {"_id":2,"MachineId":1,"InnerPort":"20002"}],
-]
+{
+{"1":{{"_id":1,"MachineId":1,"InnerPort":"20001"}},
+{"2":{{"_id":2,"MachineId":1,"InnerPort":"20002"}},
+}

+ 7 - 7
Unity/Assets/Bundles/Config/StartSceneConfig.txt

@@ -1,7 +1,7 @@
-[
-[1, {"_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002}],
-[2, {"_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003}],
-[3, {"_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004}],
-[4, {"_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location"}],
-[5, {"_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map"}],
-]
+{
+{"1":{{"_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002}},
+{"2":{{"_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003}},
+{"3":{{"_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004}},
+{"4":{{"_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location"}},
+{"5":{{"_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map"}},
+}

+ 4 - 4
Unity/Assets/Bundles/Config/StartZoneConfig.txt

@@ -1,4 +1,4 @@
-[
-[1, {"_id":1,"DBConnection":"mongdb://127.0.0.1","DBName":"ET1"}],
-[2, {"_id":2,"DBConnection":"mongdb://127.0.0.1","DBName":"ET2"}],
-]
+{
+{"1":{{"_id":1,"DBConnection":"mongdb://127.0.0.1","DBName":"ET1"}},
+{"2":{{"_id":2,"DBConnection":"mongdb://127.0.0.1","DBName":"ET2"}},
+}

+ 3 - 3
Unity/Assets/Bundles/Config/UnitConfig.txt

@@ -1,3 +1,3 @@
-[
-[1001, {"_id":1001,"Name":"米克尔","Desc":"带有强力攻击技能","Position":1,"Height":178,"Weight":68}],
-]
+{
+{"1001":{{"_id":1001,"Name":"米克尔","Desc":"带有强力攻击技能","Position":1,"Height":178,"Weight":68}},
+}

+ 1 - 1
Unity/Assets/Editor/ComponentViewEditor/ComponentViewEditor.cs

@@ -83,7 +83,7 @@ namespace ET
             }
             catch (Exception e)
             {
-                Log.Error($"component view error: {obj.GetType().FullName}");
+                Log.Error($"component view error: {obj.GetType().FullName} {e}");
             }
         }
     }

+ 4 - 4
Unity/Assets/Editor/ExcelExporterEditor/ExcelExporterEditor.cs

@@ -234,13 +234,13 @@ namespace ET
             using (FileStream txt = new FileStream(exportPath, FileMode.Create))
             using (StreamWriter sw = new StreamWriter(txt))
             {
-                sw.WriteLine('[');
+                sw.WriteLine("{");
                 for (int i = 0; i < xssfWorkbook.NumberOfSheets; ++i)
                 {
                     ISheet sheet = xssfWorkbook.GetSheetAt(i);
                     ExportSheet(sheet, sw);
                 }
-                sw.WriteLine(']');
+                sw.WriteLine("}");
             }
 
             Log.Info($"{protoName}导表完成");
@@ -305,14 +305,14 @@ namespace ET
                     if (fieldName == "Id" || fieldName == "_id")
                     {
                         fieldName = "_id";
-                        sb.Append($"[{fieldValue}, {{");
+                        sb.Append("{\"" + fieldValue + "\":{{");
                     }
 
                     string fieldType = cellInfos[j].Type;
                     sb.Append($"\"{fieldName}\":{Convert(fieldType, fieldValue)}");
                 }
 
-                sb.Append("}],");
+                sb.Append("}},");
                 sw.WriteLine(sb.ToString());
             }
         }

+ 0 - 0
Unity/Assets/Model/Core/Helper/MongoHelper.cs → Unity/Assets/Editor/Helper/MongoHelper.cs


+ 1 - 1
Unity/Assets/Model/Core/Helper/MongoHelper.cs.meta → Unity/Assets/Editor/Helper/MongoHelper.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: baa7a22e74c5c0b46ba147e47f65febc
+guid: e9e7cfc5d7f224678b2ccfe057dfccd0
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 34 - 22
Unity/Assets/Model/Core/Helper/JsonHelper.cs

@@ -2,26 +2,38 @@
 
 namespace ET
 {
-	public static class JsonHelper
-	{
-		public static string ToJson(object obj)
-		{
-			return MongoHelper.ToJson(obj);
-		}
-
-		public static T FromJson<T>(string str)
-		{
-			return MongoHelper.FromJson<T>(str);
-		}
-
-		public static object FromJson(Type type, string str)
-		{
-			return MongoHelper.FromJson(type, str);
-		}
-
-		public static T Clone<T>(T t)
-		{
-			return FromJson<T>(ToJson(t));
-		}
-	}
+    public static class JsonHelper
+    {
+#if SERVER
+        private static readonly MongoDB.Bson.IO.JsonWriterSettings logDefineSettings = new MongoDB.Bson.IO.JsonWriterSettings() { OutputMode = MongoDB.Bson.IO.JsonOutputMode.RelaxedExtendedJson };
+#endif
+        
+        public static string ToJson(object message)
+        {
+#if SERVER
+            return MongoDB.Bson.BsonExtensionMethods.ToJson(message, logDefineSettings);
+#else
+            return LitJson.JsonMapper.ToJson(message);
+#endif
+        }
+        
+        public static object FromJson(Type type, string json)
+        {
+#if SERVER
+            return MongoDB.Bson.Serialization.BsonSerializer.Deserialize(json, type);
+#else
+            return LitJson.JsonMapper.ToObject(json, type);
+#endif
+            
+        }
+        
+        public static T FromJson<T>(string json)
+        {
+#if SERVER
+            return MongoDB.Bson.Serialization.BsonSerializer.Deserialize<T>(json);
+#else
+            return LitJson.JsonMapper.ToObject<T>(json);
+#endif
+        }
+    }
 }

+ 0 - 5
Unity/Assets/Model/Core/Helper/StringHelper.cs

@@ -58,10 +58,5 @@ namespace ET
 			}
 			return sb.ToString();
 		}
-		
-		public static string MessageToStr(object message)
-		{
-			return MongoHelper.ToJson(message);
-		}
 	}
 }

+ 38 - 27
Unity/Assets/Model/Core/Object/Object.cs

@@ -1,57 +1,68 @@
 using System;
 using System.ComponentModel;
+using MongoDB.Bson.IO;
 using MongoDB.Bson.Serialization.Attributes;
+using ProtoBuf;
 #if !SERVER
 using UnityEngine;
+
 #endif
 
 namespace ET
 {
     public abstract class Object: ISupportInitialize, IDisposable
     {
-#if UNITY_EDITOR
-		public static GameObject Global
-		{
-			get
-			{
-				return GameObject.Find("/Global");
-			}
-		}
-
-		[BsonIgnore]
-		public GameObject ViewGO { get; }
+#if UNITY_EDITOR && VIEWGO
+        public static GameObject Global => GameObject.Find("/Global");
+
+        [BsonIgnore]
+        public GameObject ViewGO
+        {
+            get;
+        }
 #endif
-		
+
         public Object()
         {
-#if UNITY_EDITOR
-			if (!this.GetType().IsDefined(typeof (HideInHierarchy), true))
-			{
-				this.ViewGO = new GameObject();
-				this.ViewGO.name = this.GetType().Name;
-				this.ViewGO.layer = LayerMask.NameToLayer("Hidden");
-				this.ViewGO.transform.SetParent(Global.transform, false);
-				this.ViewGO.AddComponent<ComponentView>().Component = this;
-			}
+#if UNITY_EDITOR && VIEWGO
+            if (!this.GetType().IsDefined(typeof (HideInHierarchy), true) && Log.NeedLog)
+            {
+                this.ViewGO = new GameObject();
+                this.ViewGO.name = this.GetType().Name;
+                this.ViewGO.layer = LayerMask.NameToLayer("Hidden");
+                this.ViewGO.transform.SetParent(Global.transform, false);
+                this.ViewGO.AddComponent<ComponentView>().Component = this;
+            }
 #endif
         }
-		
+
         public virtual void BeginInit()
         {
         }
 
+        [ProtoAfterDeserialization]
+        public virtual void AfterDeserialization()
+        {
+            this.EndInit();
+        }
+        
         public virtual void EndInit()
         {
         }
 
         public virtual void Dispose()
         {
-#if UNITY_EDITOR
-			if (this.ViewGO != null)
-			{
-				UnityEngine.Object.Destroy(this.ViewGO);
-			}
+#if UNITY_EDITOR && VIEWGO
+            if (this.ViewGO != null)
+            {
+                UnityEngine.Object.Destroy(this.ViewGO);
+            }
 #endif
         }
+
+        public override string ToString()
+        {
+            return JsonHelper.ToJson(this);
+        }
     }
 }

+ 106 - 108
Unity/Assets/Model/Core/Object/ObjectPool.cs

@@ -1,143 +1,141 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using UnityEngine;
 
 namespace ET
 {
-	public class ComponentQueue: Object
-	{
-		public string TypeName { get; }
-		
-		private readonly Queue<Object> queue = new Queue<Object>();
-
-		public ComponentQueue(string typeName)
-		{
-			this.TypeName = typeName;
-		}
-
-		public void Enqueue(Object entity)
-		{
-			this.queue.Enqueue(entity);
-		}
-
-		public Object Dequeue()
-		{
-			return this.queue.Dequeue();
-		}
-
-		public Object Peek()
-		{
-			return this.queue.Peek();
-		}
-
-		public Queue<Object> Queue
-		{
-			get
-			{
-				return this.queue;
-			}
-		}
-
-		public int Count
-		{
-			get
-			{
-				return this.queue.Count;
-			}
-		}
-
-		public override void Dispose()
-		{
-			while (this.queue.Count > 0)
-			{
-				Object component = this.queue.Dequeue();
-				component.Dispose();
-			}
-		}
-	}
-	
+    public class ComponentQueue: Object
+    {
+        public string TypeName
+        {
+            get;
+        }
+
+        private readonly Queue<Object> queue = new Queue<Object>();
+
+        public ComponentQueue(string typeName)
+        {
+            this.TypeName = typeName;
+        }
+
+        public void Enqueue(Object entity)
+        {
+            this.queue.Enqueue(entity);
+        }
+
+        public Object Dequeue()
+        {
+            return this.queue.Dequeue();
+        }
+
+        public Object Peek()
+        {
+            return this.queue.Peek();
+        }
+
+        public Queue<Object> Queue => this.queue;
+
+        public int Count => this.queue.Count;
+
+        public override void Dispose()
+        {
+            while (this.queue.Count > 0)
+            {
+                Object component = this.queue.Dequeue();
+                component.Dispose();
+            }
+        }
+    }
+
     public class ObjectPool: Object
     {
-	    private static ObjectPool instance;
-
-	    public static ObjectPool Instance
-	    {
-		    get
-		    {
-			    if (instance == null)
-			    {
-				    instance = new ObjectPool();
-			    }
-
-			    return instance;
-		    }
-	    }
-	    
+        private static ObjectPool instance;
+
+        public static ObjectPool Instance
+        {
+            get
+            {
+                if (instance == null)
+                {
+                    instance = new ObjectPool();
+                }
+
+                return instance;
+            }
+        }
+
         public readonly Dictionary<Type, ComponentQueue> dictionary = new Dictionary<Type, ComponentQueue>();
 
         public Object Fetch(Type type)
         {
-	        Object obj;
-	        if (!this.dictionary.TryGetValue(type, out ComponentQueue queue))
+            Object obj;
+            if (!this.dictionary.TryGetValue(type, out ComponentQueue queue))
             {
-	            obj = (Object)Activator.CreateInstance(type);
+                obj = (Object) Activator.CreateInstance(type);
             }
-	        else if (queue.Count == 0)
+            else if (queue.Count == 0)
             {
-	            obj = (Object)Activator.CreateInstance(type);
+                obj = (Object) Activator.CreateInstance(type);
             }
             else
             {
-	            obj = queue.Dequeue();
+                obj = queue.Dequeue();
             }
+
             return obj;
         }
 
-        public T Fetch<T>() where T: Object
-		{
-            T t = (T) this.Fetch(typeof(T));
-			return t;
-		}
-        
+        public T Fetch<T>() where T : Object
+        {
+            T t = (T) this.Fetch(typeof (T));
+            return t;
+        }
+
         public void Recycle(Object obj)
         {
             Type type = obj.GetType();
-	        ComponentQueue queue;
+            ComponentQueue queue;
             if (!this.dictionary.TryGetValue(type, out queue))
             {
                 queue = new ComponentQueue(type.Name);
-	            
-#if UNITY_EDITOR
-	            if (queue.ViewGO != null)
-	            {
-		            queue.ViewGO.transform.SetParent(this.ViewGO.transform);
-		            queue.ViewGO.name = $"{type.Name}s";
-	            }
+
+#if UNITY_EDITOR && VIEWGO
+                if (queue.ViewGO != null)
+                {
+                    queue.ViewGO.transform.SetParent(this.ViewGO.transform);
+                    queue.ViewGO.name = $"{type.Name}s";
+                }
 #endif
-				this.dictionary.Add(type, queue);
+                this.dictionary.Add(type, queue);
+            }
+
+#if UNITY_EDITOR && VIEWGO
+            if (obj.ViewGO != null)
+            {
+                obj.ViewGO.transform.SetParent(queue.ViewGO.transform);
             }
-            
-#if UNITY_EDITOR
-	        if (obj.ViewGO != null)
-	        {
-		        obj.ViewGO.transform.SetParent(queue.ViewGO.transform);
-	        }
 #endif
             queue.Enqueue(obj);
         }
 
-	    public override void Dispose()
-	    {
-		    foreach (var kv in this.dictionary)
-		    {
-			    kv.Value.Dispose();
-		    }
-		    this.dictionary.Clear();
-		    instance = null;
-	    }
+        public void Clear()
+        {
+            foreach (KeyValuePair<Type, ComponentQueue> kv in this.dictionary)
+            {
+                kv.Value.Dispose();
+            }
+
+            this.dictionary.Clear();
+        }
+
+        public override void Dispose()
+        {
+            foreach (KeyValuePair<Type, ComponentQueue> kv in this.dictionary)
+            {
+                kv.Value.Dispose();
+            }
+
+            this.dictionary.Clear();
+            instance = null;
+        }
     }
 }

+ 1 - 9
Unity/Assets/Model/Module/Config/ACategory.cs

@@ -5,17 +5,9 @@ using System.Linq;
 
 namespace ET
 {
-	public abstract class ACategory: ISupportInitialize
+	public abstract class ACategory: ProtoObject
 	{
 		public abstract Type ConfigType { get; }
-
-		public virtual void BeginInit()
-		{
-		}
-
-		public virtual void EndInit()
-		{
-		}
 	}
 
 	/// <summary>

+ 4 - 0
Unity/Assets/ModelView/MonoBehaviour/Init.cs

@@ -28,6 +28,10 @@ namespace ET
 					Game.EventSystem.Add(assembly);	
 				}
 				
+				ProtobufHelper.Init();
+				
+				Game.Options = new Options();
+				
 				Game.EventSystem.Publish(new EventType.AppStart());
 			}
 			catch (Exception e)

+ 2 - 3
Unity/Assets/ThirdParty/MongoDB.meta → Unity/Assets/ThirdParty/LitJson.meta

@@ -1,9 +1,8 @@
 fileFormatVersion: 2
-guid: 8841b3184413e144286edd6c840fa6bc
+guid: dd9c7137035334bc088fc22d2e41bb9b
 folderAsset: yes
-timeCreated: 1463841468
-licenseType: Pro
 DefaultImporter:
+  externalObjects: {}
   userData: 
   assetBundleName: 
   assetBundleVariant: 

+ 40 - 0
Unity/Assets/ThirdParty/LitJson/Extensions.cs

@@ -0,0 +1,40 @@
+using System;
+
+namespace LitJson.Extensions {
+
+    /// <summary>
+    /// 拓展方法
+    /// </summary>
+	public static class Extensions {
+
+		public static void WriteProperty(this JsonWriter w,string name,long value){
+			w.WritePropertyName(name);
+			w.Write(value);
+		}
+		
+		public static void WriteProperty(this JsonWriter w,string name,string value){
+			w.WritePropertyName(name);
+			w.Write(value);
+		}
+		
+		public static void WriteProperty(this JsonWriter w,string name,bool value){
+			w.WritePropertyName(name);
+			w.Write(value);
+		}
+		
+		public static void WriteProperty(this JsonWriter w,string name,double value){
+			w.WritePropertyName(name);
+			w.Write(value);
+		}
+
+	}
+
+    /// <summary>
+    /// 跳过序列化的标签
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
+    public sealed class JsonIgnore : Attribute
+    {
+
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/Extensions.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 375fea2d63470574e9d753d6935171e8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 60 - 0
Unity/Assets/ThirdParty/LitJson/IJsonWrapper.cs

@@ -0,0 +1,60 @@
+#region Header
+/**
+ * IJsonWrapper.cs
+ *   Interface that represents a type capable of handling all kinds of JSON
+ *   data. This is mainly used when mapping objects through JsonMapper, and
+ *   it's implemented by JsonData.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System.Collections;
+using System.Collections.Specialized;
+
+
+namespace LitJson
+{
+    public enum JsonType
+    {
+        None,
+
+        Object,
+        Array,
+        String,
+        Int,
+        Long,
+        Double,
+        Boolean
+    }
+
+    public interface IJsonWrapper : IList, IOrderedDictionary
+    {
+        bool IsArray   { get; }
+        bool IsBoolean { get; }
+        bool IsDouble  { get; }
+        bool IsInt     { get; }
+        bool IsLong    { get; }
+        bool IsObject  { get; }
+        bool IsString  { get; }
+
+        bool     GetBoolean ();
+        double   GetDouble ();
+        int      GetInt ();
+        JsonType GetJsonType ();
+        long     GetLong ();
+        string   GetString ();
+
+        void SetBoolean  (bool val);
+        void SetDouble   (double val);
+        void SetInt      (int val);
+        void SetJsonType (JsonType type);
+        void SetLong     (long val);
+        void SetString   (string val);
+
+        string ToJson ();
+        void   ToJson (JsonWriter writer);
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/IJsonWrapper.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1a217e0837c088749b629a606721fb4d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1059 - 0
Unity/Assets/ThirdParty/LitJson/JsonData.cs

@@ -0,0 +1,1059 @@
+#region Header
+/**
+ * JsonData.cs
+ *   Generic type to hold JSON data (objects, arrays, and so on). This is
+ *   the default type returned by JsonMapper.ToObject().
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+
+
+namespace LitJson
+{
+    public class JsonData : IJsonWrapper, IEquatable<JsonData>
+    {
+        #region Fields
+        private IList<JsonData>               inst_array;
+        private bool                          inst_boolean;
+        private double                        inst_double;
+        private int                           inst_int;
+        private long                          inst_long;
+        private IDictionary<string, JsonData> inst_object;
+        private string                        inst_string;
+        private string                        json;
+        private JsonType                      type;
+
+        // Used to implement the IOrderedDictionary interface
+        private IList<KeyValuePair<string, JsonData>> object_list;
+        #endregion
+
+
+        #region Properties
+        public int Count {
+            get { return EnsureCollection ().Count; }
+        }
+
+        public bool IsArray {
+            get { return type == JsonType.Array; }
+        }
+
+        public bool IsBoolean {
+            get { return type == JsonType.Boolean; }
+        }
+
+        public bool IsDouble {
+            get { return type == JsonType.Double; }
+        }
+
+        public bool IsInt {
+            get { return type == JsonType.Int; }
+        }
+
+        public bool IsLong {
+            get { return type == JsonType.Long; }
+        }
+
+        public bool IsObject {
+            get { return type == JsonType.Object; }
+        }
+
+        public bool IsString {
+            get { return type == JsonType.String; }
+        }
+
+        public ICollection<string> Keys {
+            get { EnsureDictionary (); return inst_object.Keys; }
+        }
+        
+        /// <summary>
+        /// Determines whether the json contains an element that has the specified key.
+        /// </summary>
+        /// <param name="key">The key to locate in the json.</param>
+        /// <returns>true if the json contains an element that has the specified key; otherwise, false.</returns>
+        public Boolean ContainsKey(String key) {
+            EnsureDictionary();
+            return this.inst_object.Keys.Contains(key);
+        }
+        #endregion
+
+
+        #region ICollection Properties
+        int ICollection.Count {
+            get {
+                return Count;
+            }
+        }
+
+        bool ICollection.IsSynchronized {
+            get {
+                return EnsureCollection ().IsSynchronized;
+            }
+        }
+
+        object ICollection.SyncRoot {
+            get {
+                return EnsureCollection ().SyncRoot;
+            }
+        }
+        #endregion
+
+
+        #region IDictionary Properties
+        bool IDictionary.IsFixedSize {
+            get {
+                return EnsureDictionary ().IsFixedSize;
+            }
+        }
+
+        bool IDictionary.IsReadOnly {
+            get {
+                return EnsureDictionary ().IsReadOnly;
+            }
+        }
+
+        ICollection IDictionary.Keys {
+            get {
+                EnsureDictionary ();
+                IList<string> keys = new List<string> ();
+
+                foreach (KeyValuePair<string, JsonData> entry in
+                         object_list) {
+                    keys.Add (entry.Key);
+                }
+
+                return (ICollection) keys;
+            }
+        }
+
+        ICollection IDictionary.Values {
+            get {
+                EnsureDictionary ();
+                IList<JsonData> values = new List<JsonData> ();
+
+                foreach (KeyValuePair<string, JsonData> entry in
+                         object_list) {
+                    values.Add (entry.Value);
+                }
+
+                return (ICollection) values;
+            }
+        }
+        #endregion
+
+
+
+        #region IJsonWrapper Properties
+        bool IJsonWrapper.IsArray {
+            get { return IsArray; }
+        }
+
+        bool IJsonWrapper.IsBoolean {
+            get { return IsBoolean; }
+        }
+
+        bool IJsonWrapper.IsDouble {
+            get { return IsDouble; }
+        }
+
+        bool IJsonWrapper.IsInt {
+            get { return IsInt; }
+        }
+
+        bool IJsonWrapper.IsLong {
+            get { return IsLong; }
+        }
+
+        bool IJsonWrapper.IsObject {
+            get { return IsObject; }
+        }
+
+        bool IJsonWrapper.IsString {
+            get { return IsString; }
+        }
+        #endregion
+
+
+        #region IList Properties
+        bool IList.IsFixedSize {
+            get {
+                return EnsureList ().IsFixedSize;
+            }
+        }
+
+        bool IList.IsReadOnly {
+            get {
+                return EnsureList ().IsReadOnly;
+            }
+        }
+        #endregion
+
+
+        #region IDictionary Indexer
+        object IDictionary.this[object key] {
+            get {
+                return EnsureDictionary ()[key];
+            }
+
+            set {
+                if (! (key is String))
+                    throw new ArgumentException (
+                        "The key has to be a string");
+
+                JsonData data = ToJsonData (value);
+
+                this[(string) key] = data;
+            }
+        }
+        #endregion
+
+
+        #region IOrderedDictionary Indexer
+        object IOrderedDictionary.this[int idx] {
+            get {
+                EnsureDictionary ();
+                return object_list[idx].Value;
+            }
+
+            set {
+                EnsureDictionary ();
+                JsonData data = ToJsonData (value);
+
+                KeyValuePair<string, JsonData> old_entry = object_list[idx];
+
+                inst_object[old_entry.Key] = data;
+
+                KeyValuePair<string, JsonData> entry =
+                    new KeyValuePair<string, JsonData> (old_entry.Key, data);
+
+                object_list[idx] = entry;
+            }
+        }
+        #endregion
+
+
+        #region IList Indexer
+        object IList.this[int index] {
+            get {
+                return EnsureList ()[index];
+            }
+
+            set {
+                EnsureList ();
+                JsonData data = ToJsonData (value);
+
+                this[index] = data;
+            }
+        }
+        #endregion
+
+
+        #region Public Indexers
+        public JsonData this[string prop_name] {
+            get {
+                EnsureDictionary ();
+                return inst_object[prop_name];
+            }
+
+            set {
+                EnsureDictionary ();
+
+                KeyValuePair<string, JsonData> entry =
+                    new KeyValuePair<string, JsonData> (prop_name, value);
+
+                if (inst_object.ContainsKey (prop_name)) {
+                    for (int i = 0; i < object_list.Count; i++) {
+                        if (object_list[i].Key == prop_name) {
+                            object_list[i] = entry;
+                            break;
+                        }
+                    }
+                } else
+                    object_list.Add (entry);
+
+                inst_object[prop_name] = value;
+
+                json = null;
+            }
+        }
+
+        public JsonData this[int index] {
+            get {
+                EnsureCollection ();
+
+                if (type == JsonType.Array)
+                    return inst_array[index];
+
+                return object_list[index].Value;
+            }
+
+            set {
+                EnsureCollection ();
+
+                if (type == JsonType.Array)
+                    inst_array[index] = value;
+                else {
+                    KeyValuePair<string, JsonData> entry = object_list[index];
+                    KeyValuePair<string, JsonData> new_entry =
+                        new KeyValuePair<string, JsonData> (entry.Key, value);
+
+                    object_list[index] = new_entry;
+                    inst_object[entry.Key] = value;
+                }
+
+                json = null;
+            }
+        }
+        #endregion
+
+
+        #region Constructors
+        public JsonData ()
+        {
+        }
+
+        public JsonData (bool boolean)
+        {
+            type = JsonType.Boolean;
+            inst_boolean = boolean;
+        }
+
+        public JsonData (double number)
+        {
+            type = JsonType.Double;
+            inst_double = number;
+        }
+
+        public JsonData (int number)
+        {
+            type = JsonType.Int;
+            inst_int = number;
+        }
+
+        public JsonData (long number)
+        {
+            type = JsonType.Long;
+            inst_long = number;
+        }
+
+        public JsonData (object obj)
+        {
+            if (obj is Boolean) {
+                type = JsonType.Boolean;
+                inst_boolean = (bool) obj;
+                return;
+            }
+
+            if (obj is Double) {
+                type = JsonType.Double;
+                inst_double = (double) obj;
+                return;
+            }
+
+            if (obj is Int32) {
+                type = JsonType.Int;
+                inst_int = (int) obj;
+                return;
+            }
+
+            if (obj is Int64) {
+                type = JsonType.Long;
+                inst_long = (long) obj;
+                return;
+            }
+
+            if (obj is String) {
+                type = JsonType.String;
+                inst_string = (string) obj;
+                return;
+            }
+
+            throw new ArgumentException (
+                "Unable to wrap the given object with JsonData");
+        }
+
+        public JsonData (string str)
+        {
+            type = JsonType.String;
+            inst_string = str;
+        }
+        #endregion
+
+
+        #region Implicit Conversions
+        public static implicit operator JsonData (Boolean data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (Double data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (Int32 data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (Int64 data)
+        {
+            return new JsonData (data);
+        }
+
+        public static implicit operator JsonData (String data)
+        {
+            return new JsonData (data);
+        }
+        #endregion
+
+
+        #region Explicit Conversions
+        public static explicit operator Boolean (JsonData data)
+        {
+            if (data.type != JsonType.Boolean)
+                throw new InvalidCastException (
+                    "Instance of JsonData doesn't hold a double");
+
+            return data.inst_boolean;
+        }
+
+        public static explicit operator Double (JsonData data)
+        {
+            if (data.type != JsonType.Double)
+                throw new InvalidCastException (
+                    "Instance of JsonData doesn't hold a double");
+
+            return data.inst_double;
+        }
+
+       public static explicit operator Int32(JsonData data)
+        {
+            if (data.type != JsonType.Int && data.type != JsonType.Long)
+            {
+                throw new InvalidCastException(
+                    "Instance of JsonData doesn't hold an int");
+            }
+
+            // cast may truncate data... but that's up to the user to consider
+            return data.type == JsonType.Int ? data.inst_int : (int)data.inst_long;
+        }
+
+        public static explicit operator Int64(JsonData data)
+        {
+            if (data.type != JsonType.Long && data.type != JsonType.Int)
+            {
+                throw new InvalidCastException(
+                    "Instance of JsonData doesn't hold a long");
+            }
+
+            return data.type == JsonType.Long ? data.inst_long : data.inst_int;
+        }
+
+        public static explicit operator String (JsonData data)
+        {
+            if (data.type != JsonType.String)
+                throw new InvalidCastException (
+                    "Instance of JsonData doesn't hold a string");
+
+            return data.inst_string;
+        }
+        #endregion
+
+
+        #region ICollection Methods
+        void ICollection.CopyTo (Array array, int index)
+        {
+            EnsureCollection ().CopyTo (array, index);
+        }
+        #endregion
+
+
+        #region IDictionary Methods
+        void IDictionary.Add (object key, object value)
+        {
+            JsonData data = ToJsonData (value);
+
+            EnsureDictionary ().Add (key, data);
+
+            KeyValuePair<string, JsonData> entry =
+                new KeyValuePair<string, JsonData> ((string) key, data);
+            object_list.Add (entry);
+
+            json = null;
+        }
+
+        void IDictionary.Clear ()
+        {
+            EnsureDictionary ().Clear ();
+            object_list.Clear ();
+            json = null;
+        }
+
+        bool IDictionary.Contains (object key)
+        {
+            return EnsureDictionary ().Contains (key);
+        }
+
+        IDictionaryEnumerator IDictionary.GetEnumerator ()
+        {
+            return ((IOrderedDictionary) this).GetEnumerator ();
+        }
+
+        void IDictionary.Remove (object key)
+        {
+            EnsureDictionary ().Remove (key);
+
+            for (int i = 0; i < object_list.Count; i++) {
+                if (object_list[i].Key == (string) key) {
+                    object_list.RemoveAt (i);
+                    break;
+                }
+            }
+
+            json = null;
+        }
+        #endregion
+
+
+        #region IEnumerable Methods
+        IEnumerator IEnumerable.GetEnumerator ()
+        {
+            return EnsureCollection ().GetEnumerator ();
+        }
+        #endregion
+
+
+        #region IJsonWrapper Methods
+        bool IJsonWrapper.GetBoolean ()
+        {
+            if (type != JsonType.Boolean)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a boolean");
+
+            return inst_boolean;
+        }
+
+        double IJsonWrapper.GetDouble ()
+        {
+            if (type != JsonType.Double)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a double");
+
+            return inst_double;
+        }
+
+        int IJsonWrapper.GetInt ()
+        {
+            if (type != JsonType.Int)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold an int");
+
+            return inst_int;
+        }
+
+        long IJsonWrapper.GetLong ()
+        {
+            if (type != JsonType.Long)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a long");
+
+            return inst_long;
+        }
+
+        string IJsonWrapper.GetString ()
+        {
+            if (type != JsonType.String)
+                throw new InvalidOperationException (
+                    "JsonData instance doesn't hold a string");
+
+            return inst_string;
+        }
+
+        void IJsonWrapper.SetBoolean (bool val)
+        {
+            type = JsonType.Boolean;
+            inst_boolean = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetDouble (double val)
+        {
+            type = JsonType.Double;
+            inst_double = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetInt (int val)
+        {
+            type = JsonType.Int;
+            inst_int = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetLong (long val)
+        {
+            type = JsonType.Long;
+            inst_long = val;
+            json = null;
+        }
+
+        void IJsonWrapper.SetString (string val)
+        {
+            type = JsonType.String;
+            inst_string = val;
+            json = null;
+        }
+
+        string IJsonWrapper.ToJson ()
+        {
+            return ToJson ();
+        }
+
+        void IJsonWrapper.ToJson (JsonWriter writer)
+        {
+            ToJson (writer);
+        }
+        #endregion
+
+
+        #region IList Methods
+        int IList.Add (object value)
+        {
+            return Add (value);
+        }
+
+        void IList.Clear ()
+        {
+            EnsureList ().Clear ();
+            json = null;
+        }
+
+        bool IList.Contains (object value)
+        {
+            return EnsureList ().Contains (value);
+        }
+
+        int IList.IndexOf (object value)
+        {
+            return EnsureList ().IndexOf (value);
+        }
+
+        void IList.Insert (int index, object value)
+        {
+            EnsureList ().Insert (index, value);
+            json = null;
+        }
+
+        void IList.Remove (object value)
+        {
+            EnsureList ().Remove (value);
+            json = null;
+        }
+
+        void IList.RemoveAt (int index)
+        {
+            EnsureList ().RemoveAt (index);
+            json = null;
+        }
+        #endregion
+
+
+        #region IOrderedDictionary Methods
+        IDictionaryEnumerator IOrderedDictionary.GetEnumerator ()
+        {
+            EnsureDictionary ();
+
+            return new OrderedDictionaryEnumerator (
+                object_list.GetEnumerator ());
+        }
+
+        void IOrderedDictionary.Insert (int idx, object key, object value)
+        {
+            string property = (string) key;
+            JsonData data  = ToJsonData (value);
+
+            this[property] = data;
+
+            KeyValuePair<string, JsonData> entry =
+                new KeyValuePair<string, JsonData> (property, data);
+
+            object_list.Insert (idx, entry);
+        }
+
+        void IOrderedDictionary.RemoveAt (int idx)
+        {
+            EnsureDictionary ();
+
+            inst_object.Remove (object_list[idx].Key);
+            object_list.RemoveAt (idx);
+        }
+        #endregion
+
+
+        #region Private Methods
+        private ICollection EnsureCollection ()
+        {
+            if (type == JsonType.Array)
+                return (ICollection) inst_array;
+
+            if (type == JsonType.Object)
+                return (ICollection) inst_object;
+
+            throw new InvalidOperationException (
+                "The JsonData instance has to be initialized first");
+        }
+
+        private IDictionary EnsureDictionary ()
+        {
+            if (type == JsonType.Object)
+                return (IDictionary) inst_object;
+
+            if (type != JsonType.None)
+                throw new InvalidOperationException (
+                    "Instance of JsonData is not a dictionary");
+
+            type = JsonType.Object;
+            inst_object = new Dictionary<string, JsonData> ();
+            object_list = new List<KeyValuePair<string, JsonData>> ();
+
+            return (IDictionary) inst_object;
+        }
+
+        private IList EnsureList ()
+        {
+            if (type == JsonType.Array)
+                return (IList) inst_array;
+
+            if (type != JsonType.None)
+                throw new InvalidOperationException (
+                    "Instance of JsonData is not a list");
+
+            type = JsonType.Array;
+            inst_array = new List<JsonData> ();
+
+            return (IList) inst_array;
+        }
+
+        private JsonData ToJsonData (object obj)
+        {
+            if (obj == null)
+                return null;
+
+            if (obj is JsonData)
+                return (JsonData) obj;
+
+            return new JsonData (obj);
+        }
+
+        private static void WriteJson (IJsonWrapper obj, JsonWriter writer)
+        {
+            if (obj == null) {
+                writer.Write (null);
+                return;
+            }
+
+            if (obj.IsString) {
+                writer.Write (obj.GetString ());
+                return;
+            }
+
+            if (obj.IsBoolean) {
+                writer.Write (obj.GetBoolean ());
+                return;
+            }
+
+            if (obj.IsDouble) {
+                writer.Write (obj.GetDouble ());
+                return;
+            }
+
+            if (obj.IsInt) {
+                writer.Write (obj.GetInt ());
+                return;
+            }
+
+            if (obj.IsLong) {
+                writer.Write (obj.GetLong ());
+                return;
+            }
+
+            if (obj.IsArray) {
+                writer.WriteArrayStart ();
+                foreach (object elem in (IList) obj)
+                    WriteJson ((JsonData) elem, writer);
+                writer.WriteArrayEnd ();
+
+                return;
+            }
+
+            if (obj.IsObject) {
+                writer.WriteObjectStart ();
+
+                foreach (DictionaryEntry entry in ((IDictionary) obj)) {
+                    writer.WritePropertyName ((string) entry.Key);
+                    WriteJson ((JsonData) entry.Value, writer);
+                }
+                writer.WriteObjectEnd ();
+
+                return;
+            }
+        }
+        #endregion
+
+
+        public int Add (object value)
+        {
+            JsonData data = ToJsonData (value);
+
+            json = null;
+
+            return EnsureList ().Add (data);
+        }
+
+        public bool Remove(object obj)
+        {
+            json = null;
+            if(IsObject)
+            {
+                JsonData value = null;
+                if (inst_object.TryGetValue((string)obj, out value))
+                    return inst_object.Remove((string)obj) && object_list.Remove(new KeyValuePair<string, JsonData>((string)obj, value));
+                else
+                    throw new KeyNotFoundException("The specified key was not found in the JsonData object.");
+            }
+            if(IsArray)
+            {
+                return inst_array.Remove(ToJsonData(obj));
+            }
+            throw new InvalidOperationException (
+                    "Instance of JsonData is not an object or a list.");
+        }
+
+        public void Clear ()
+        {
+            if (IsObject) {
+                ((IDictionary) this).Clear ();
+                return;
+            }
+
+            if (IsArray) {
+                ((IList) this).Clear ();
+                return;
+            }
+        }
+
+        public bool Equals (JsonData x)
+        {
+            if (x == null)
+                return false;
+
+            if (x.type != this.type)
+            {
+                // further check to see if this is a long to int comparison
+                if ((x.type != JsonType.Int && x.type != JsonType.Long)
+                    || (this.type != JsonType.Int && this.type != JsonType.Long))
+                {
+                    return false;
+                }
+            }
+
+            switch (this.type) {
+            case JsonType.None:
+                return true;
+
+            case JsonType.Object:
+                return this.inst_object.Equals (x.inst_object);
+
+            case JsonType.Array:
+                return this.inst_array.Equals (x.inst_array);
+
+            case JsonType.String:
+                return this.inst_string.Equals (x.inst_string);
+
+            case JsonType.Int:
+            {
+                if (x.IsLong)
+                {
+                    if (x.inst_long < Int32.MinValue || x.inst_long > Int32.MaxValue)
+                        return false;
+                    return this.inst_int.Equals((int)x.inst_long);
+                }
+                return this.inst_int.Equals(x.inst_int);
+            }
+
+            case JsonType.Long:
+            {
+                if (x.IsInt)
+                {
+                    if (this.inst_long < Int32.MinValue || this.inst_long > Int32.MaxValue)
+                        return false;
+                    return x.inst_int.Equals((int)this.inst_long);
+                }
+                return this.inst_long.Equals(x.inst_long);
+            }
+
+            case JsonType.Double:
+                return this.inst_double.Equals (x.inst_double);
+
+            case JsonType.Boolean:
+                return this.inst_boolean.Equals (x.inst_boolean);
+            }
+
+            return false;
+        }
+
+        public JsonType GetJsonType ()
+        {
+            return type;
+        }
+
+        public void SetJsonType (JsonType type)
+        {
+            if (this.type == type)
+                return;
+
+            switch (type) {
+            case JsonType.None:
+                break;
+
+            case JsonType.Object:
+                inst_object = new Dictionary<string, JsonData> ();
+                object_list = new List<KeyValuePair<string, JsonData>> ();
+                break;
+
+            case JsonType.Array:
+                inst_array = new List<JsonData> ();
+                break;
+
+            case JsonType.String:
+                inst_string = default (String);
+                break;
+
+            case JsonType.Int:
+                inst_int = default (Int32);
+                break;
+
+            case JsonType.Long:
+                inst_long = default (Int64);
+                break;
+
+            case JsonType.Double:
+                inst_double = default (Double);
+                break;
+
+            case JsonType.Boolean:
+                inst_boolean = default (Boolean);
+                break;
+            }
+
+            this.type = type;
+        }
+
+        public string ToJson ()
+        {
+            if (json != null)
+                return json;
+
+            StringWriter sw = new StringWriter ();
+            JsonWriter writer = new JsonWriter (sw);
+            writer.Validate = false;
+
+            WriteJson (this, writer);
+            json = sw.ToString ();
+
+            return json;
+        }
+
+        public void ToJson (JsonWriter writer)
+        {
+            bool old_validate = writer.Validate;
+
+            writer.Validate = false;
+
+            WriteJson (this, writer);
+
+            writer.Validate = old_validate;
+        }
+
+        public override string ToString ()
+        {
+            switch (type) {
+            case JsonType.Array:
+                return "JsonData array";
+
+            case JsonType.Boolean:
+                return inst_boolean.ToString ();
+
+            case JsonType.Double:
+                return inst_double.ToString ();
+
+            case JsonType.Int:
+                return inst_int.ToString ();
+
+            case JsonType.Long:
+                return inst_long.ToString ();
+
+            case JsonType.Object:
+                return "JsonData object";
+
+            case JsonType.String:
+                return inst_string;
+            }
+
+            return "Uninitialized JsonData";
+        }
+    }
+
+
+    internal class OrderedDictionaryEnumerator : IDictionaryEnumerator
+    {
+        IEnumerator<KeyValuePair<string, JsonData>> list_enumerator;
+
+
+        public object Current {
+            get { return Entry; }
+        }
+
+        public DictionaryEntry Entry {
+            get {
+                KeyValuePair<string, JsonData> curr = list_enumerator.Current;
+                return new DictionaryEntry (curr.Key, curr.Value);
+            }
+        }
+
+        public object Key {
+            get { return list_enumerator.Current.Key; }
+        }
+
+        public object Value {
+            get { return list_enumerator.Current.Value; }
+        }
+
+
+        public OrderedDictionaryEnumerator (
+            IEnumerator<KeyValuePair<string, JsonData>> enumerator)
+        {
+            list_enumerator = enumerator;
+        }
+
+
+        public bool MoveNext ()
+        {
+            return list_enumerator.MoveNext ();
+        }
+
+        public void Reset ()
+        {
+            list_enumerator.Reset ();
+        }
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/JsonData.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: df135f702bdb16c4ea644ca96368175d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 65 - 0
Unity/Assets/ThirdParty/LitJson/JsonException.cs

@@ -0,0 +1,65 @@
+#region Header
+/**
+ * JsonException.cs
+ *   Base class throwed by LitJSON when a parsing error occurs.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+
+
+namespace LitJson
+{
+    public class JsonException :
+#if NETSTANDARD1_5
+        Exception
+#else
+        ApplicationException
+#endif
+    {
+        public JsonException () : base ()
+        {
+        }
+
+        internal JsonException (ParserToken token) :
+            base (String.Format (
+                    "Invalid token '{0}' in input string", token))
+        {
+        }
+
+        internal JsonException (ParserToken token,
+                                Exception inner_exception) :
+            base (String.Format (
+                    "Invalid token '{0}' in input string", token),
+                inner_exception)
+        {
+        }
+
+        internal JsonException (int c) :
+            base (String.Format (
+                    "Invalid character '{0}' in input string", (char) c))
+        {
+        }
+
+        internal JsonException (int c, Exception inner_exception) :
+            base (String.Format (
+                    "Invalid character '{0}' in input string", (char) c),
+                inner_exception)
+        {
+        }
+
+
+        public JsonException (string message) : base (message)
+        {
+        }
+
+        public JsonException (string message, Exception inner_exception) :
+            base (message, inner_exception)
+        {
+        }
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/JsonException.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8dffd6f51ff858946bb25cc9188dfc6e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1045 - 0
Unity/Assets/ThirdParty/LitJson/JsonMapper.cs

@@ -0,0 +1,1045 @@
+#region Header
+
+/**
+ * JsonMapper.cs
+ *   JSON to .Net object and object to JSON conversions.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Runtime.Serialization;
+using LitJson.Extensions;
+
+namespace LitJson
+{
+    internal struct PropertyMetadata
+    {
+        public MemberInfo Info;
+        public bool IsField;
+        public Type Type;
+    }
+
+    internal struct ArrayMetadata
+    {
+        private Type element_type;
+        private bool is_array;
+        private bool is_list;
+
+        public Type ElementType
+        {
+            get
+            {
+                if (element_type == null)
+                    return typeof (JsonData);
+
+                return element_type;
+            }
+
+            set
+            {
+                element_type = value;
+            }
+        }
+
+        public bool IsArray
+        {
+            get
+            {
+                return is_array;
+            }
+            set
+            {
+                is_array = value;
+            }
+        }
+
+        public bool IsList
+        {
+            get
+            {
+                return is_list;
+            }
+            set
+            {
+                is_list = value;
+            }
+        }
+    }
+
+    internal struct ObjectMetadata
+    {
+        private Type element_type;
+        private bool is_dictionary;
+
+        private IDictionary<string, PropertyMetadata> properties;
+
+        public Type ElementType
+        {
+            get
+            {
+                if (element_type == null)
+                    return typeof (JsonData);
+
+                return element_type;
+            }
+
+            set
+            {
+                element_type = value;
+            }
+        }
+
+        public bool IsDictionary
+        {
+            get
+            {
+                return is_dictionary;
+            }
+            set
+            {
+                is_dictionary = value;
+            }
+        }
+
+        public IDictionary<string, PropertyMetadata> Properties
+        {
+            get
+            {
+                return properties;
+            }
+            set
+            {
+                properties = value;
+            }
+        }
+    }
+
+    internal delegate void ExporterFunc(object obj, JsonWriter writer);
+
+    public delegate void ExporterFunc<T>(T obj, JsonWriter writer);
+
+    internal delegate object ImporterFunc(object input);
+
+    public delegate TValue ImporterFunc<TJson, TValue>(TJson input);
+
+    public delegate IJsonWrapper WrapperFactory();
+
+    public class JsonMapper
+    {
+        #region Fields
+
+        private static readonly int max_nesting_depth;
+
+        private static readonly IFormatProvider datetime_format;
+
+        private static readonly IDictionary<Type, ExporterFunc> base_exporters_table;
+        private static readonly IDictionary<Type, ExporterFunc> custom_exporters_table;
+
+        private static readonly IDictionary<Type,
+            IDictionary<Type, ImporterFunc>> base_importers_table;
+
+        private static readonly IDictionary<Type,
+            IDictionary<Type, ImporterFunc>> custom_importers_table;
+
+        private static readonly IDictionary<Type, ArrayMetadata> array_metadata;
+        private static readonly object array_metadata_lock = new Object();
+
+        private static readonly IDictionary<Type,
+            IDictionary<Type, MethodInfo>> conv_ops;
+
+        private static readonly object conv_ops_lock = new Object();
+
+        private static readonly IDictionary<Type, ObjectMetadata> object_metadata;
+        private static readonly object object_metadata_lock = new Object();
+
+        private static readonly IDictionary<Type,
+            IList<PropertyMetadata>> type_properties;
+
+        private static readonly object type_properties_lock = new Object();
+
+        private static readonly JsonWriter static_writer;
+        private static readonly object static_writer_lock = new Object();
+
+        #endregion
+
+        #region Constructors
+
+        static JsonMapper()
+        {
+            max_nesting_depth = 100;
+
+            array_metadata = new Dictionary<Type, ArrayMetadata>();
+            conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>>();
+            object_metadata = new Dictionary<Type, ObjectMetadata>();
+            type_properties = new Dictionary<Type,
+                IList<PropertyMetadata>>();
+
+            static_writer = new JsonWriter();
+
+            datetime_format = DateTimeFormatInfo.InvariantInfo;
+
+            base_exporters_table = new Dictionary<Type, ExporterFunc>();
+            custom_exporters_table = new Dictionary<Type, ExporterFunc>();
+
+            base_importers_table = new Dictionary<Type,
+                IDictionary<Type, ImporterFunc>>();
+            custom_importers_table = new Dictionary<Type,
+                IDictionary<Type, ImporterFunc>>();
+
+            RegisterBaseExporters();
+            RegisterBaseImporters();
+        }
+
+        #endregion
+
+        #region Private Methods
+
+        private static void AddArrayMetadata(Type type)
+        {
+            if (array_metadata.ContainsKey(type))
+                return;
+
+            ArrayMetadata data = new ArrayMetadata();
+
+            data.IsArray = type.IsArray;
+
+            if (type.GetInterface("System.Collections.IList") != null)
+                data.IsList = true;
+
+            foreach (PropertyInfo p_info in type.GetProperties())
+            {
+                if (p_info.Name != "Item")
+                    continue;
+
+                ParameterInfo[] parameters = p_info.GetIndexParameters();
+
+                if (parameters.Length != 1)
+                    continue;
+
+                if (parameters[0].ParameterType == typeof (int))
+                    data.ElementType = p_info.PropertyType;
+            }
+
+            lock (array_metadata_lock)
+            {
+                try
+                {
+                    array_metadata.Add(type, data);
+                }
+                catch (ArgumentException)
+                {
+                    return;
+                }
+            }
+        }
+
+        private static void AddObjectMetadata(Type type)
+        {
+            if (object_metadata.ContainsKey(type))
+                return;
+
+            ObjectMetadata data = new ObjectMetadata();
+
+            if (type.GetInterface("System.Collections.IDictionary") != null)
+                data.IsDictionary = true;
+
+            data.Properties = new Dictionary<string, PropertyMetadata>();
+
+            foreach (PropertyInfo p_info in type.GetProperties())
+            {
+                if (p_info.Name == "Item")
+                {
+                    ParameterInfo[] parameters = p_info.GetIndexParameters();
+
+                    if (parameters.Length != 1)
+                        continue;
+
+                    if (parameters[0].ParameterType == typeof (string))
+                        data.ElementType = p_info.PropertyType;
+
+                    continue;
+                }
+
+                PropertyMetadata p_data = new PropertyMetadata();
+                p_data.Info = p_info;
+                p_data.Type = p_info.PropertyType;
+
+                data.Properties.Add(p_info.Name, p_data);
+            }
+
+            foreach (FieldInfo f_info in type.GetFields())
+            {
+                PropertyMetadata p_data = new PropertyMetadata();
+                p_data.Info = f_info;
+                p_data.IsField = true;
+                p_data.Type = f_info.FieldType;
+
+                data.Properties.Add(f_info.Name, p_data);
+            }
+
+            lock (object_metadata_lock)
+            {
+                try
+                {
+                    object_metadata.Add(type, data);
+                }
+                catch (ArgumentException)
+                {
+                    return;
+                }
+            }
+        }
+
+        private static void AddTypeProperties(Type type)
+        {
+            if (type_properties.ContainsKey(type))
+                return;
+
+            IList<PropertyMetadata> props = new List<PropertyMetadata>();
+
+            foreach (PropertyInfo p_info in type.GetProperties())
+            {
+                if (p_info.Name == "Item")
+                    continue;
+
+                PropertyMetadata p_data = new PropertyMetadata();
+                p_data.Info = p_info;
+                p_data.IsField = false;
+                props.Add(p_data);
+            }
+
+            foreach (FieldInfo f_info in type.GetFields())
+            {
+                PropertyMetadata p_data = new PropertyMetadata();
+                p_data.Info = f_info;
+                p_data.IsField = true;
+
+                props.Add(p_data);
+            }
+
+            lock (type_properties_lock)
+            {
+                try
+                {
+                    type_properties.Add(type, props);
+                }
+                catch (ArgumentException)
+                {
+                    return;
+                }
+            }
+        }
+
+        private static MethodInfo GetConvOp(Type t1, Type t2)
+        {
+            lock (conv_ops_lock)
+            {
+                if (!conv_ops.ContainsKey(t1))
+                    conv_ops.Add(t1, new Dictionary<Type, MethodInfo>());
+            }
+
+            if (conv_ops[t1].ContainsKey(t2))
+                return conv_ops[t1][t2];
+
+            MethodInfo op = t1.GetMethod("op_Implicit", new Type[] { t2 });
+
+            lock (conv_ops_lock)
+            {
+                try
+                {
+                    conv_ops[t1].Add(t2, op);
+                }
+                catch (ArgumentException)
+                {
+                    return conv_ops[t1][t2];
+                }
+            }
+
+            return op;
+        }
+
+        private static object ReadValue(Type inst_type, JsonReader reader)
+        {
+            reader.Read();
+
+            if (reader.Token == JsonToken.ArrayEnd)
+                return null;
+
+            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
+            Type value_type = underlying_type ?? inst_type;
+
+            if (reader.Token == JsonToken.Null)
+            {
+#if NETSTANDARD1_5
+                if (inst_type.IsClass() || underlying_type != null) {
+                    return null;
+                }
+#else
+                if (inst_type.IsClass || underlying_type != null)
+                {
+                    return null;
+                }
+#endif
+
+                throw new JsonException(String.Format("Can't assign null to an instance of type {0}",
+                    inst_type));
+            }
+
+            if (reader.Token == JsonToken.Double ||
+                reader.Token == JsonToken.Int ||
+                reader.Token == JsonToken.Long ||
+                reader.Token == JsonToken.String ||
+                reader.Token == JsonToken.Boolean)
+            {
+                Type json_type = reader.Value.GetType();
+
+                if (value_type.IsAssignableFrom(json_type))
+                    return reader.Value;
+
+                // If there's a custom importer that fits, use it
+                if (custom_importers_table.ContainsKey(json_type) &&
+                    custom_importers_table[json_type].ContainsKey(value_type))
+                {
+                    ImporterFunc importer =
+                            custom_importers_table[json_type][value_type];
+
+                    return importer(reader.Value);
+                }
+
+                // Maybe there's a base importer that works
+                if (base_importers_table.ContainsKey(json_type) &&
+                    base_importers_table[json_type].ContainsKey(value_type))
+                {
+                    ImporterFunc importer =
+                            base_importers_table[json_type][value_type];
+
+                    return importer(reader.Value);
+                }
+
+                // Maybe it's an enum
+#if NETSTANDARD1_5
+                if (value_type.IsEnum())
+                    return Enum.ToObject (value_type, reader.Value);
+#else
+                if (value_type.IsEnum)
+                    return Enum.ToObject(value_type, reader.Value);
+#endif
+                // Try using an implicit conversion operator
+                MethodInfo conv_op = GetConvOp(value_type, json_type);
+
+                if (conv_op != null)
+                    return conv_op.Invoke(null,
+                        new object[] { reader.Value });
+
+                // No luck
+                throw new JsonException(String.Format("Can't assign value '{0}' (type {1}) to type {2}",
+                    reader.Value, json_type, inst_type));
+            }
+
+            object instance = null;
+
+            if (reader.Token == JsonToken.ArrayStart)
+            {
+                AddArrayMetadata(inst_type);
+                ArrayMetadata t_data = array_metadata[inst_type];
+
+                if (!t_data.IsArray && !t_data.IsList)
+                    throw new JsonException(String.Format("Type {0} can't act as an array",
+                        inst_type));
+
+                IList list;
+                Type elem_type;
+
+                if (!t_data.IsArray)
+                {
+                    list = (IList) Activator.CreateInstance(inst_type);
+                    elem_type = t_data.ElementType;
+                }
+                else
+                {
+                    list = new ArrayList();
+                    elem_type = inst_type.GetElementType();
+                }
+
+                while (true)
+                {
+                    object item = ReadValue(elem_type, reader);
+                    if (item == null && reader.Token == JsonToken.ArrayEnd)
+                        break;
+
+                    list.Add(item);
+                }
+
+                if (t_data.IsArray)
+                {
+                    int n = list.Count;
+                    instance = Array.CreateInstance(elem_type, n);
+
+                    for (int i = 0; i < n; i++)
+                        ((Array) instance).SetValue(list[i], i);
+                }
+                else
+                    instance = list;
+            }
+            else if (reader.Token == JsonToken.ObjectStart)
+            {
+                AddObjectMetadata(value_type);
+                ObjectMetadata t_data = object_metadata[value_type];
+
+                instance = Activator.CreateInstance(value_type);
+
+                while (true)
+                {
+                    reader.Read();
+
+                    if (reader.Token == JsonToken.ObjectEnd)
+                        break;
+
+                    string property = (string) reader.Value;
+
+                    if (t_data.Properties.ContainsKey(property))
+                    {
+                        PropertyMetadata prop_data =
+                                t_data.Properties[property];
+
+                        if (prop_data.IsField)
+                        {
+                            ((FieldInfo) prop_data.Info).SetValue(instance, ReadValue(prop_data.Type, reader));
+                        }
+                        else
+                        {
+                            PropertyInfo p_info =
+                                    (PropertyInfo) prop_data.Info;
+
+                            if (p_info.CanWrite)
+                                p_info.SetValue(instance,
+                                    ReadValue(prop_data.Type, reader),
+                                    null);
+                            else
+                                ReadValue(prop_data.Type, reader);
+                        }
+                    }
+                    else
+                    {
+                        if (!t_data.IsDictionary)
+                        {
+                            if (!reader.SkipNonMembers)
+                            {
+                                throw new JsonException(String.Format("The type {0} doesn't have the " +
+                                    "property '{1}'",
+                                    inst_type, property));
+                            }
+
+                            ReadSkip(reader);
+                            continue;
+                        }
+
+                        var dicTypes = instance.GetType().GetGenericArguments();
+                        var converter = System.ComponentModel.TypeDescriptor.GetConverter(dicTypes[0]);
+                        object key = property;
+                        if (converter != null)
+                        {
+                            key = converter.ConvertFromString(property);
+                            t_data.ElementType = dicTypes[1];
+                        }
+
+                        ((IDictionary) instance).Add(key, ReadValue(t_data.ElementType, reader));
+                    }
+                }
+            }
+
+            return instance;
+        }
+
+        private static IJsonWrapper ReadValue(WrapperFactory factory,
+            JsonReader reader)
+        {
+            reader.Read();
+
+            if (reader.Token == JsonToken.ArrayEnd ||
+                reader.Token == JsonToken.Null)
+                return null;
+
+            IJsonWrapper instance = factory();
+
+            if (reader.Token == JsonToken.String)
+            {
+                instance.SetString((string) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Double)
+            {
+                instance.SetDouble((double) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Int)
+            {
+                instance.SetInt((int) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Long)
+            {
+                instance.SetLong((long) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.Boolean)
+            {
+                instance.SetBoolean((bool) reader.Value);
+                return instance;
+            }
+
+            if (reader.Token == JsonToken.ArrayStart)
+            {
+                instance.SetJsonType(JsonType.Array);
+
+                while (true)
+                {
+                    IJsonWrapper item = ReadValue(factory, reader);
+                    if (item == null && reader.Token == JsonToken.ArrayEnd)
+                        break;
+
+                    ((IList) instance).Add(item);
+                }
+            }
+            else if (reader.Token == JsonToken.ObjectStart)
+            {
+                instance.SetJsonType(JsonType.Object);
+
+                while (true)
+                {
+                    reader.Read();
+
+                    if (reader.Token == JsonToken.ObjectEnd)
+                        break;
+
+                    string property = (string) reader.Value;
+
+                    ((IDictionary) instance)[property] = ReadValue(factory, reader);
+                }
+            }
+
+            return instance;
+        }
+
+        private static void ReadSkip(JsonReader reader)
+        {
+            ToWrapper(delegate { return new JsonMockWrapper(); }, reader);
+        }
+
+        private static void RegisterBaseExporters()
+        {
+            base_exporters_table[typeof (byte)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((byte) obj)); };
+
+            base_exporters_table[typeof (char)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToString((char) obj)); };
+
+            base_exporters_table[typeof (DateTime)] =
+                    delegate(object obj, JsonWriter writer)
+                    {
+                        writer.Write(Convert.ToString((DateTime) obj,
+                            datetime_format));
+                    };
+
+            base_exporters_table[typeof (decimal)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write((decimal) obj); };
+
+            base_exporters_table[typeof (sbyte)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((sbyte) obj)); };
+
+            base_exporters_table[typeof (short)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((short) obj)); };
+
+            base_exporters_table[typeof (ushort)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((ushort) obj)); };
+
+            base_exporters_table[typeof (uint)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToUInt64((uint) obj)); };
+
+            base_exporters_table[typeof (ulong)] =
+                    delegate(object obj, JsonWriter writer) { writer.Write((ulong) obj); };
+
+            base_exporters_table[typeof (DateTimeOffset)] =
+                    delegate(object obj, JsonWriter writer)
+                    {
+                        writer.Write(((DateTimeOffset) obj).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz", datetime_format));
+                    };
+        }
+
+        private static void RegisterBaseImporters()
+        {
+            ImporterFunc importer;
+
+            importer = delegate(object input) { return Convert.ToByte((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (byte), importer);
+
+            importer = delegate(object input) { return Convert.ToUInt64((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (ulong), importer);
+
+            importer = delegate(object input) { return Convert.ToInt64((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (long), importer);
+
+            importer = delegate(object input) { return Convert.ToSByte((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (sbyte), importer);
+
+            importer = delegate(object input) { return Convert.ToInt16((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (short), importer);
+
+            importer = delegate(object input) { return Convert.ToUInt16((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (ushort), importer);
+
+            importer = delegate(object input) { return Convert.ToUInt32((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (uint), importer);
+
+            importer = delegate(object input) { return Convert.ToSingle((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (float), importer);
+
+            importer = delegate(object input) { return Convert.ToDouble((int) input); };
+            RegisterImporter(base_importers_table, typeof (int),
+                typeof (double), importer);
+
+            importer = delegate(object input) { return Convert.ToDecimal((double) input); };
+            RegisterImporter(base_importers_table, typeof (double),
+                typeof (decimal), importer);
+
+            importer = delegate(object input) { return Convert.ToSingle((double) input); };
+            RegisterImporter(base_importers_table, typeof (double),
+                typeof (float), importer);
+
+            importer = delegate(object input) { return Convert.ToUInt32((long) input); };
+            RegisterImporter(base_importers_table, typeof (long),
+                typeof (uint), importer);
+
+            importer = delegate(object input) { return Convert.ToChar((string) input); };
+            RegisterImporter(base_importers_table, typeof (string),
+                typeof (char), importer);
+
+            importer = delegate(object input) { return Convert.ToDateTime((string) input, datetime_format); };
+            RegisterImporter(base_importers_table, typeof (string),
+                typeof (DateTime), importer);
+
+            importer = delegate(object input) { return DateTimeOffset.Parse((string) input, datetime_format); };
+            RegisterImporter(base_importers_table, typeof (string),
+                typeof (DateTimeOffset), importer);
+        }
+
+        private static void RegisterImporter(
+            IDictionary<Type, IDictionary<Type, ImporterFunc>> table,
+            Type json_type, Type value_type, ImporterFunc importer)
+        {
+            if (!table.ContainsKey(json_type))
+                table.Add(json_type, new Dictionary<Type, ImporterFunc>());
+
+            table[json_type][value_type] = importer;
+        }
+
+        private static void WriteValue(object obj, JsonWriter writer,
+            bool writer_is_private,
+            int depth)
+        {
+            if (depth > max_nesting_depth)
+                throw new JsonException(String.Format("Max allowed object depth reached while " +
+                    "trying to export from type {0}",
+                    obj.GetType()));
+
+            if (obj == null)
+            {
+                writer.Write(null);
+                return;
+            }
+
+            if (obj is IJsonWrapper)
+            {
+                if (writer_is_private)
+                    writer.TextWriter.Write(((IJsonWrapper) obj).ToJson());
+                else
+                    ((IJsonWrapper) obj).ToJson(writer);
+
+                return;
+            }
+
+            if (obj is String)
+            {
+                writer.Write((string) obj);
+                return;
+            }
+
+            if (obj is Double)
+            {
+                writer.Write((double) obj);
+                return;
+            }
+
+            if (obj is Single)
+            {
+                writer.Write((float) obj);
+                return;
+            }
+
+            if (obj is Int32)
+            {
+                writer.Write((int) obj);
+                return;
+            }
+
+            if (obj is Boolean)
+            {
+                writer.Write((bool) obj);
+                return;
+            }
+
+            if (obj is Int64)
+            {
+                writer.Write((long) obj);
+                return;
+            }
+
+            if (obj is Array)
+            {
+                writer.WriteArrayStart();
+
+                foreach (object elem in (Array) obj)
+                    WriteValue(elem, writer, writer_is_private, depth + 1);
+
+                writer.WriteArrayEnd();
+
+                return;
+            }
+
+            if (obj is IList)
+            {
+                writer.WriteArrayStart();
+                foreach (object elem in (IList) obj)
+                    WriteValue(elem, writer, writer_is_private, depth + 1);
+                writer.WriteArrayEnd();
+
+                return;
+            }
+
+#if UNITY_2018_3_OR_NEWER
+            if (obj is IDictionary dictionary) {
+#else
+            if (obj is IDictionary)
+            {
+                var dictionary = obj as IDictionary;
+#endif
+                writer.WriteObjectStart();
+                foreach (DictionaryEntry entry in dictionary)
+                {
+#if UNITY_2018_3_OR_NEWER
+                    var propertyName = entry.Key is string key ?
+                        key
+                        : Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
+#else
+                    var propertyName = entry.Key is string? (entry.Key as string) : Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
+#endif
+                    writer.WritePropertyName(propertyName);
+                    WriteValue(entry.Value, writer, writer_is_private,
+                        depth + 1);
+                }
+
+                writer.WriteObjectEnd();
+
+                return;
+            }
+
+            Type obj_type = obj.GetType();
+
+            // See if there's a custom exporter for the object
+            if (custom_exporters_table.ContainsKey(obj_type))
+            {
+                ExporterFunc exporter = custom_exporters_table[obj_type];
+                exporter(obj, writer);
+
+                return;
+            }
+
+            // If not, maybe there's a base exporter
+            if (base_exporters_table.ContainsKey(obj_type))
+            {
+                ExporterFunc exporter = base_exporters_table[obj_type];
+                exporter(obj, writer);
+
+                return;
+            }
+
+            // Last option, let's see if it's an enum
+            if (obj is Enum)
+            {
+                Type e_type = Enum.GetUnderlyingType(obj_type);
+
+                if (e_type == typeof (long)
+                    || e_type == typeof (uint)
+                    || e_type == typeof (ulong))
+                    writer.Write((ulong) obj);
+                else
+                    writer.Write((int) obj);
+
+                return;
+            }
+
+            // Okay, so it looks like the input should be exported as an
+            // object
+            AddTypeProperties(obj_type);
+            IList<PropertyMetadata> props = type_properties[obj_type];
+
+            writer.WriteObjectStart();
+            writer.WritePropertyName("_t");
+            writer.Write(obj_type.Name);
+            foreach (PropertyMetadata p_data in props)
+            {
+                var skipAttributesList = p_data.Info.GetCustomAttributes(typeof (IgnoreDataMemberAttribute), true);
+                var skipAttributes = skipAttributesList as ICollection<Attribute>;
+                if (skipAttributes.Count > 0)
+                {
+                    continue;
+                }
+
+                if (p_data.IsField)
+                {
+                    writer.WritePropertyName(p_data.Info.Name);
+                    WriteValue(((FieldInfo) p_data.Info).GetValue(obj),
+                        writer, writer_is_private, depth + 1);
+                }
+                else
+                {
+                    PropertyInfo p_info = (PropertyInfo) p_data.Info;
+
+                    if (p_info.CanRead)
+                    {
+                        writer.WritePropertyName(p_data.Info.Name);
+                        WriteValue(p_info.GetValue(obj, null),
+                            writer, writer_is_private, depth + 1);
+                    }
+                }
+            }
+
+            writer.WriteObjectEnd();
+        }
+
+        #endregion
+
+        public static string ToJson(object obj)
+        {
+            lock (static_writer_lock)
+            {
+                static_writer.Reset();
+
+                WriteValue(obj, static_writer, true, 0);
+
+                return static_writer.ToString();
+            }
+        }
+
+        public static void ToJson(object obj, JsonWriter writer)
+        {
+            WriteValue(obj, writer, false, 0);
+        }
+
+        public static JsonData ToObject(JsonReader reader)
+        {
+            return (JsonData) ToWrapper(delegate { return new JsonData(); }, reader);
+        }
+
+        public static JsonData ToObject(TextReader reader)
+        {
+            JsonReader json_reader = new JsonReader(reader);
+
+            return (JsonData) ToWrapper(delegate { return new JsonData(); }, json_reader);
+        }
+
+        public static JsonData ToObject(string json)
+        {
+            return (JsonData) ToWrapper(delegate { return new JsonData(); }, json);
+        }
+
+        public static T ToObject<T>(JsonReader reader)
+        {
+            return (T) ReadValue(typeof (T), reader);
+        }
+
+        public static T ToObject<T>(TextReader reader)
+        {
+            JsonReader json_reader = new JsonReader(reader);
+
+            return (T) ReadValue(typeof (T), json_reader);
+        }
+
+        public static T ToObject<T>(string json)
+        {
+            JsonReader reader = new JsonReader(json);
+
+            return (T) ReadValue(typeof (T), reader);
+        }
+
+        public static object ToObject(string json, Type ConvertType)
+        {
+            JsonReader reader = new JsonReader(json);
+
+            return ReadValue(ConvertType, reader);
+        }
+
+        public static IJsonWrapper ToWrapper(WrapperFactory factory,
+            JsonReader reader)
+        {
+            return ReadValue(factory, reader);
+        }
+
+        public static IJsonWrapper ToWrapper(WrapperFactory factory,
+            string json)
+        {
+            JsonReader reader = new JsonReader(json);
+
+            return ReadValue(factory, reader);
+        }
+
+        public static void RegisterExporter<T>(ExporterFunc<T> exporter)
+        {
+            ExporterFunc exporter_wrapper =
+                    delegate(object obj, JsonWriter writer) { exporter((T) obj, writer); };
+
+            custom_exporters_table[typeof (T)] = exporter_wrapper;
+        }
+
+        public static void RegisterImporter<TJson, TValue>(
+            ImporterFunc<TJson, TValue> importer)
+        {
+            ImporterFunc importer_wrapper =
+                    delegate(object input) { return importer((TJson) input); };
+
+            RegisterImporter(custom_importers_table, typeof (TJson),
+                typeof (TValue), importer_wrapper);
+        }
+
+        public static void UnregisterExporters()
+        {
+            custom_exporters_table.Clear();
+        }
+
+        public static void UnregisterImporters()
+        {
+            custom_importers_table.Clear();
+        }
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/JsonMapper.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2ab543118874f8841859d5562afc4ad8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 105 - 0
Unity/Assets/ThirdParty/LitJson/JsonMockWrapper.cs

@@ -0,0 +1,105 @@
+#region Header
+/**
+ * JsonMockWrapper.cs
+ *   Mock object implementing IJsonWrapper, to facilitate actions like
+ *   skipping data more efficiently.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+
+
+namespace LitJson
+{
+    public class JsonMockWrapper : IJsonWrapper
+    {
+        public bool IsArray   { get { return false; } }
+        public bool IsBoolean { get { return false; } }
+        public bool IsDouble  { get { return false; } }
+        public bool IsInt     { get { return false; } }
+        public bool IsLong    { get { return false; } }
+        public bool IsObject  { get { return false; } }
+        public bool IsString  { get { return false; } }
+
+        public bool     GetBoolean ()  { return false; }
+        public double   GetDouble ()   { return 0.0; }
+        public int      GetInt ()      { return 0; }
+        public JsonType GetJsonType () { return JsonType.None; }
+        public long     GetLong ()     { return 0L; }
+        public string   GetString ()   { return ""; }
+
+        public void SetBoolean  (bool val)      {}
+        public void SetDouble   (double val)    {}
+        public void SetInt      (int val)       {}
+        public void SetJsonType (JsonType type) {}
+        public void SetLong     (long val)      {}
+        public void SetString   (string val)    {}
+
+        public string ToJson ()                  { return ""; }
+        public void   ToJson (JsonWriter writer) {}
+
+
+        bool IList.IsFixedSize { get { return true; } }
+        bool IList.IsReadOnly  { get { return true; } }
+
+        object IList.this[int index] {
+            get { return null; }
+            set {}
+        }
+
+        int  IList.Add (object value)       { return 0; }
+        void IList.Clear ()                 {}
+        bool IList.Contains (object value)  { return false; }
+        int  IList.IndexOf (object value)   { return -1; }
+        void IList.Insert (int i, object v) {}
+        void IList.Remove (object value)    {}
+        void IList.RemoveAt (int index)     {}
+
+
+        int    ICollection.Count          { get { return 0; } }
+        bool   ICollection.IsSynchronized { get { return false; } }
+        object ICollection.SyncRoot       { get { return null; } }
+
+        void ICollection.CopyTo (Array array, int index) {}
+
+
+        IEnumerator IEnumerable.GetEnumerator () { return null; }
+
+
+        bool IDictionary.IsFixedSize { get { return true; } }
+        bool IDictionary.IsReadOnly  { get { return true; } }
+
+        ICollection IDictionary.Keys   { get { return null; } }
+        ICollection IDictionary.Values { get { return null; } }
+
+        object IDictionary.this[object key] {
+            get { return null; }
+            set {}
+        }
+
+        void IDictionary.Add (object k, object v) {}
+        void IDictionary.Clear ()                 {}
+        bool IDictionary.Contains (object key)    { return false; }
+        void IDictionary.Remove (object key)      {}
+
+        IDictionaryEnumerator IDictionary.GetEnumerator () { return null; }
+
+
+        object IOrderedDictionary.this[int idx] {
+            get { return null; }
+            set {}
+        }
+
+        IDictionaryEnumerator IOrderedDictionary.GetEnumerator () {
+            return null;
+        }
+        void IOrderedDictionary.Insert   (int i, object k, object v) {}
+        void IOrderedDictionary.RemoveAt (int i) {}
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/JsonMockWrapper.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c5f89b15adfb6c14fa4c1b50113ff553
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 478 - 0
Unity/Assets/ThirdParty/LitJson/JsonReader.cs

@@ -0,0 +1,478 @@
+#region Header
+/**
+ * JsonReader.cs
+ *   Stream-like access to JSON text.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+
+namespace LitJson
+{
+    public enum JsonToken
+    {
+        None,
+
+        ObjectStart,
+        PropertyName,
+        ObjectEnd,
+
+        ArrayStart,
+        ArrayEnd,
+
+        Int,
+        Long,
+        Double,
+
+        String,
+
+        Boolean,
+        Null
+    }
+
+
+    public class JsonReader
+    {
+        #region Fields
+        private static readonly IDictionary<int, IDictionary<int, int[]>> parse_table;
+
+        private Stack<int>    automaton_stack;
+        private int           current_input;
+        private int           current_symbol;
+        private bool          end_of_json;
+        private bool          end_of_input;
+        private Lexer         lexer;
+        private bool          parser_in_string;
+        private bool          parser_return;
+        private bool          read_started;
+        private TextReader    reader;
+        private bool          reader_is_owned;
+        private bool          skip_non_members;
+        private object        token_value;
+        private JsonToken     token;
+        #endregion
+
+
+        #region Public Properties
+        public bool AllowComments {
+            get { return lexer.AllowComments; }
+            set { lexer.AllowComments = value; }
+        }
+
+        public bool AllowSingleQuotedStrings {
+            get { return lexer.AllowSingleQuotedStrings; }
+            set { lexer.AllowSingleQuotedStrings = value; }
+        }
+
+        public bool SkipNonMembers {
+            get { return skip_non_members; }
+            set { skip_non_members = value; }
+        }
+
+        public bool EndOfInput {
+            get { return end_of_input; }
+        }
+
+        public bool EndOfJson {
+            get { return end_of_json; }
+        }
+
+        public JsonToken Token {
+            get { return token; }
+        }
+
+        public object Value {
+            get { return token_value; }
+        }
+        #endregion
+
+
+        #region Constructors
+        static JsonReader ()
+        {
+            parse_table = PopulateParseTable ();
+        }
+
+        public JsonReader (string json_text) :
+            this (new StringReader (json_text), true)
+        {
+        }
+
+        public JsonReader (TextReader reader) :
+            this (reader, false)
+        {
+        }
+
+        private JsonReader (TextReader reader, bool owned)
+        {
+            if (reader == null)
+                throw new ArgumentNullException ("reader");
+
+            parser_in_string = false;
+            parser_return    = false;
+
+            read_started = false;
+            automaton_stack = new Stack<int> ();
+            automaton_stack.Push ((int) ParserToken.End);
+            automaton_stack.Push ((int) ParserToken.Text);
+
+            lexer = new Lexer (reader);
+
+            end_of_input = false;
+            end_of_json  = false;
+
+            skip_non_members = true;
+
+            this.reader = reader;
+            reader_is_owned = owned;
+        }
+        #endregion
+
+
+        #region Static Methods
+        private static IDictionary<int, IDictionary<int, int[]>> PopulateParseTable ()
+        {
+            // See section A.2. of the manual for details
+            IDictionary<int, IDictionary<int, int[]>> parse_table = new Dictionary<int, IDictionary<int, int[]>> ();
+
+            TableAddRow (parse_table, ParserToken.Array);
+            TableAddCol (parse_table, ParserToken.Array, '[',
+                            '[',
+                            (int) ParserToken.ArrayPrime);
+
+            TableAddRow (parse_table, ParserToken.ArrayPrime);
+            TableAddCol (parse_table, ParserToken.ArrayPrime, '"',
+                            (int) ParserToken.Value,
+
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, '[',
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, ']',
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, '{',
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Number,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.True,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.False,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+            TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Null,
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest,
+                            ']');
+
+            TableAddRow (parse_table, ParserToken.Object);
+            TableAddCol (parse_table, ParserToken.Object, '{',
+                            '{',
+                            (int) ParserToken.ObjectPrime);
+
+            TableAddRow (parse_table, ParserToken.ObjectPrime);
+            TableAddCol (parse_table, ParserToken.ObjectPrime, '"',
+                            (int) ParserToken.Pair,
+                            (int) ParserToken.PairRest,
+                            '}');
+            TableAddCol (parse_table, ParserToken.ObjectPrime, '}',
+                            '}');
+
+            TableAddRow (parse_table, ParserToken.Pair);
+            TableAddCol (parse_table, ParserToken.Pair, '"',
+                            (int) ParserToken.String,
+                            ':',
+                            (int) ParserToken.Value);
+
+            TableAddRow (parse_table, ParserToken.PairRest);
+            TableAddCol (parse_table, ParserToken.PairRest, ',',
+                            ',',
+                            (int) ParserToken.Pair,
+                            (int) ParserToken.PairRest);
+            TableAddCol (parse_table, ParserToken.PairRest, '}',
+                            (int) ParserToken.Epsilon);
+
+            TableAddRow (parse_table, ParserToken.String);
+            TableAddCol (parse_table, ParserToken.String, '"',
+                            '"',
+                            (int) ParserToken.CharSeq,
+                            '"');
+
+            TableAddRow (parse_table, ParserToken.Text);
+            TableAddCol (parse_table, ParserToken.Text, '[',
+                            (int) ParserToken.Array);
+            TableAddCol (parse_table, ParserToken.Text, '{',
+                            (int) ParserToken.Object);
+
+            TableAddRow (parse_table, ParserToken.Value);
+            TableAddCol (parse_table, ParserToken.Value, '"',
+                            (int) ParserToken.String);
+            TableAddCol (parse_table, ParserToken.Value, '[',
+                            (int) ParserToken.Array);
+            TableAddCol (parse_table, ParserToken.Value, '{',
+                            (int) ParserToken.Object);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Number,
+                            (int) ParserToken.Number);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.True,
+                            (int) ParserToken.True);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.False,
+                            (int) ParserToken.False);
+            TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Null,
+                            (int) ParserToken.Null);
+
+            TableAddRow (parse_table, ParserToken.ValueRest);
+            TableAddCol (parse_table, ParserToken.ValueRest, ',',
+                            ',',
+                            (int) ParserToken.Value,
+                            (int) ParserToken.ValueRest);
+            TableAddCol (parse_table, ParserToken.ValueRest, ']',
+                            (int) ParserToken.Epsilon);
+
+            return parse_table;
+        }
+
+        private static void TableAddCol (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken row, int col,
+                                         params int[] symbols)
+        {
+            parse_table[(int) row].Add (col, symbols);
+        }
+
+        private static void TableAddRow (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken rule)
+        {
+            parse_table.Add ((int) rule, new Dictionary<int, int[]> ());
+        }
+        #endregion
+
+
+        #region Private Methods
+        private void ProcessNumber (string number)
+        {
+            if (number.IndexOf ('.') != -1 ||
+                number.IndexOf ('e') != -1 ||
+                number.IndexOf ('E') != -1) {
+
+                double n_double;
+                if (double.TryParse (number, NumberStyles.Any, CultureInfo.InvariantCulture, out n_double)) {
+                    token = JsonToken.Double;
+                    token_value = n_double;
+
+                    return;
+                }
+            }
+
+            int n_int32;
+            if (int.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int32)) {
+                token = JsonToken.Int;
+                token_value = n_int32;
+
+                return;
+            }
+
+            long n_int64;
+            if (long.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int64)) {
+                token = JsonToken.Long;
+                token_value = n_int64;
+
+                return;
+            }
+
+            ulong n_uint64;
+            if (ulong.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_uint64))
+            {
+                token = JsonToken.Long;
+                token_value = n_uint64;
+
+                return;
+            }
+
+            // Shouldn't happen, but just in case, return something
+            token = JsonToken.Int;
+            token_value = 0;
+        }
+
+        private void ProcessSymbol ()
+        {
+            if (current_symbol == '[')  {
+                token = JsonToken.ArrayStart;
+                parser_return = true;
+
+            } else if (current_symbol == ']')  {
+                token = JsonToken.ArrayEnd;
+                parser_return = true;
+
+            } else if (current_symbol == '{')  {
+                token = JsonToken.ObjectStart;
+                parser_return = true;
+
+            } else if (current_symbol == '}')  {
+                token = JsonToken.ObjectEnd;
+                parser_return = true;
+
+            } else if (current_symbol == '"')  {
+                if (parser_in_string) {
+                    parser_in_string = false;
+
+                    parser_return = true;
+
+                } else {
+                    if (token == JsonToken.None)
+                        token = JsonToken.String;
+
+                    parser_in_string = true;
+                }
+
+            } else if (current_symbol == (int) ParserToken.CharSeq) {
+                token_value = lexer.StringValue;
+
+            } else if (current_symbol == (int) ParserToken.False)  {
+                token = JsonToken.Boolean;
+                token_value = false;
+                parser_return = true;
+
+            } else if (current_symbol == (int) ParserToken.Null)  {
+                token = JsonToken.Null;
+                parser_return = true;
+
+            } else if (current_symbol == (int) ParserToken.Number)  {
+                ProcessNumber (lexer.StringValue);
+
+                parser_return = true;
+
+            } else if (current_symbol == (int) ParserToken.Pair)  {
+                token = JsonToken.PropertyName;
+
+            } else if (current_symbol == (int) ParserToken.True)  {
+                token = JsonToken.Boolean;
+                token_value = true;
+                parser_return = true;
+
+            }
+        }
+
+        private bool ReadToken ()
+        {
+            if (end_of_input)
+                return false;
+
+            lexer.NextToken ();
+
+            if (lexer.EndOfInput) {
+                Close ();
+
+                return false;
+            }
+
+            current_input = lexer.Token;
+
+            return true;
+        }
+        #endregion
+
+
+        public void Close ()
+        {
+            if (end_of_input)
+                return;
+
+            end_of_input = true;
+            end_of_json  = true;
+
+            if (reader_is_owned)
+            {
+                using(reader){}
+            }
+
+            reader = null;
+        }
+
+        public bool Read ()
+        {
+            if (end_of_input)
+                return false;
+
+            if (end_of_json) {
+                end_of_json = false;
+                automaton_stack.Clear ();
+                automaton_stack.Push ((int) ParserToken.End);
+                automaton_stack.Push ((int) ParserToken.Text);
+            }
+
+            parser_in_string = false;
+            parser_return    = false;
+
+            token       = JsonToken.None;
+            token_value = null;
+
+            if (! read_started) {
+                read_started = true;
+
+                if (! ReadToken ())
+                    return false;
+            }
+
+
+            int[] entry_symbols;
+
+            while (true) {
+                if (parser_return) {
+                    if (automaton_stack.Peek () == (int) ParserToken.End)
+                        end_of_json = true;
+
+                    return true;
+                }
+
+                current_symbol = automaton_stack.Pop ();
+
+                ProcessSymbol ();
+
+                if (current_symbol == current_input) {
+                    if (! ReadToken ()) {
+                        if (automaton_stack.Peek () != (int) ParserToken.End)
+                            throw new JsonException (
+                                "Input doesn't evaluate to proper JSON text");
+
+                        if (parser_return)
+                            return true;
+
+                        return false;
+                    }
+
+                    continue;
+                }
+
+                try {
+
+                    entry_symbols =
+                        parse_table[current_symbol][current_input];
+
+                } catch (KeyNotFoundException e) {
+                    throw new JsonException ((ParserToken) current_input, e);
+                }
+
+                if (entry_symbols[0] == (int) ParserToken.Epsilon)
+                    continue;
+
+                for (int i = entry_symbols.Length - 1; i >= 0; i--)
+                    automaton_stack.Push (entry_symbols[i]);
+            }
+        }
+
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/JsonReader.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 080fd553d3da08047ab0298cbfdb2e52
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 487 - 0
Unity/Assets/ThirdParty/LitJson/JsonWriter.cs

@@ -0,0 +1,487 @@
+#region Header
+/**
+ * JsonWriter.cs
+ *   Stream-like facility to output JSON text.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+
+namespace LitJson
+{
+    internal enum Condition
+    {
+        InArray,
+        InObject,
+        NotAProperty,
+        Property,
+        Value
+    }
+
+    internal class WriterContext
+    {
+        public int  Count;
+        public bool InArray;
+        public bool InObject;
+        public bool ExpectingValue;
+        public int  Padding;
+    }
+
+    public class JsonWriter
+    {
+        #region Fields
+        private static readonly NumberFormatInfo number_format;
+
+        private WriterContext        context;
+        private Stack<WriterContext> ctx_stack;
+        private bool                 has_reached_end;
+        private char[]               hex_seq;
+        private int                  indentation;
+        private int                  indent_value;
+        private StringBuilder        inst_string_builder;
+        private bool                 pretty_print;
+        private bool                 validate;
+        private bool                 lower_case_properties;
+        private TextWriter           writer;
+        #endregion
+
+
+        #region Properties
+        public int IndentValue {
+            get { return indent_value; }
+            set {
+                indentation = (indentation / indent_value) * value;
+                indent_value = value;
+            }
+        }
+
+        public bool PrettyPrint {
+            get { return pretty_print; }
+            set { pretty_print = value; }
+        }
+
+        public TextWriter TextWriter {
+            get { return writer; }
+        }
+
+        public bool Validate {
+            get { return validate; }
+            set { validate = value; }
+        }
+
+        public bool LowerCaseProperties {
+            get { return lower_case_properties; }
+            set { lower_case_properties = value; }
+        }
+        #endregion
+
+
+        #region Constructors
+        static JsonWriter ()
+        {
+            number_format = NumberFormatInfo.InvariantInfo;
+        }
+
+        public JsonWriter ()
+        {
+            inst_string_builder = new StringBuilder ();
+            writer = new StringWriter (inst_string_builder);
+
+            Init ();
+        }
+
+        public JsonWriter (StringBuilder sb) :
+            this (new StringWriter (sb))
+        {
+        }
+
+        public JsonWriter (TextWriter writer)
+        {
+            if (writer == null)
+                throw new ArgumentNullException ("writer");
+
+            this.writer = writer;
+
+            Init ();
+        }
+        #endregion
+
+
+        #region Private Methods
+        private void DoValidation (Condition cond)
+        {
+            if (! context.ExpectingValue)
+                context.Count++;
+
+            if (! validate)
+                return;
+
+            if (has_reached_end)
+                throw new JsonException (
+                    "A complete JSON symbol has already been written");
+
+            switch (cond) {
+            case Condition.InArray:
+                if (! context.InArray)
+                    throw new JsonException (
+                        "Can't close an array here");
+                break;
+
+            case Condition.InObject:
+                if (! context.InObject || context.ExpectingValue)
+                    throw new JsonException (
+                        "Can't close an object here");
+                break;
+
+            case Condition.NotAProperty:
+                if (context.InObject && ! context.ExpectingValue)
+                    throw new JsonException (
+                        "Expected a property");
+                break;
+
+            case Condition.Property:
+                if (! context.InObject || context.ExpectingValue)
+                    throw new JsonException (
+                        "Can't add a property here");
+                break;
+
+            case Condition.Value:
+                if (! context.InArray &&
+                    (! context.InObject || ! context.ExpectingValue))
+                    throw new JsonException (
+                        "Can't add a value here");
+
+                break;
+            }
+        }
+
+        private void Init ()
+        {
+            has_reached_end = false;
+            hex_seq = new char[4];
+            indentation = 0;
+            indent_value = 4;
+            pretty_print = false;
+            validate = true;
+            lower_case_properties = false;
+
+            ctx_stack = new Stack<WriterContext> ();
+            context = new WriterContext ();
+            ctx_stack.Push (context);
+        }
+
+        private static void IntToHex (int n, char[] hex)
+        {
+            int num;
+
+            for (int i = 0; i < 4; i++) {
+                num = n % 16;
+
+                if (num < 10)
+                    hex[3 - i] = (char) ('0' + num);
+                else
+                    hex[3 - i] = (char) ('A' + (num - 10));
+
+                n >>= 4;
+            }
+        }
+
+        private void Indent ()
+        {
+            if (pretty_print)
+                indentation += indent_value;
+        }
+
+
+        private void Put (string str)
+        {
+            if (pretty_print && ! context.ExpectingValue)
+                for (int i = 0; i < indentation; i++)
+                    writer.Write (' ');
+
+            writer.Write (str);
+        }
+
+        private void PutNewline ()
+        {
+            PutNewline (true);
+        }
+
+        private void PutNewline (bool add_comma)
+        {
+            if (add_comma && ! context.ExpectingValue &&
+                context.Count > 1)
+                writer.Write (',');
+
+            if (pretty_print && ! context.ExpectingValue)
+                writer.Write (Environment.NewLine);
+        }
+
+        private void PutString (string str)
+        {
+            Put (String.Empty);
+
+            writer.Write ('"');
+            writer.Write(str);
+            writer.Write('"');
+            return;
+/*
+            int n = str.Length;
+            for (int i = 0; i < n; i++) {
+                switch (str[i]) {
+                case '\n':
+                    writer.Write ("\\n");
+                    continue;
+
+                case '\r':
+                    writer.Write ("\\r");
+                    continue;
+
+                case '\t':
+                    writer.Write ("\\t");
+                    continue;
+
+                case '"':
+                case '\\':
+                    writer.Write ('\\');
+                    writer.Write (str[i]);
+                    continue;
+
+                case '\f':
+                    writer.Write ("\\f");
+                    continue;
+
+                case '\b':
+                    writer.Write ("\\b");
+                    continue;
+                }
+
+                if ((int) str[i] >= 32 && (int) str[i] <= 126) {
+                    writer.Write (str[i]);
+                    continue;
+                }
+
+                // Default, turn into a \uXXXX sequence
+                IntToHex ((int) str[i], hex_seq);
+                writer.Write ("\\u");
+                writer.Write (hex_seq);
+            }
+
+            writer.Write ('"');
+*/
+        }
+
+        private void Unindent ()
+        {
+            if (pretty_print)
+                indentation -= indent_value;
+        }
+        #endregion
+
+
+        public override string ToString ()
+        {
+            if (inst_string_builder == null)
+                return String.Empty;
+
+            return inst_string_builder.ToString ();
+        }
+
+        public void Reset ()
+        {
+            has_reached_end = false;
+
+            ctx_stack.Clear ();
+            context = new WriterContext ();
+            ctx_stack.Push (context);
+
+            if (inst_string_builder != null)
+                inst_string_builder.Remove (0, inst_string_builder.Length);
+        }
+
+        public void Write (bool boolean)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (boolean ? "true" : "false");
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (decimal number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (double number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            string str = Convert.ToString (number, number_format);
+            Put (str);
+
+            if (str.IndexOf ('.') == -1 &&
+                str.IndexOf ('E') == -1)
+                writer.Write (".0");
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write(float number)
+        {
+            DoValidation(Condition.Value);
+            PutNewline();
+
+            string str = Convert.ToString(number, number_format);
+            Put(str);
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (int number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (long number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (string str)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            if (str == null)
+                Put ("null");
+            else
+                PutString (str);
+
+            context.ExpectingValue = false;
+        }
+
+        public void Write (ulong number)
+        {
+            DoValidation (Condition.Value);
+            PutNewline ();
+
+            Put (Convert.ToString (number, number_format));
+
+            context.ExpectingValue = false;
+        }
+
+        public void WriteArrayEnd ()
+        {
+            DoValidation (Condition.InArray);
+            PutNewline (false);
+
+            ctx_stack.Pop ();
+            if (ctx_stack.Count == 1)
+                has_reached_end = true;
+            else {
+                context = ctx_stack.Peek ();
+                context.ExpectingValue = false;
+            }
+
+            Unindent ();
+            Put ("]");
+        }
+
+        public void WriteArrayStart ()
+        {
+            DoValidation (Condition.NotAProperty);
+            PutNewline ();
+
+            Put ("[");
+
+            context = new WriterContext ();
+            context.InArray = true;
+            ctx_stack.Push (context);
+
+            Indent ();
+        }
+
+        public void WriteObjectEnd ()
+        {
+            DoValidation (Condition.InObject);
+            PutNewline (false);
+
+            ctx_stack.Pop ();
+            if (ctx_stack.Count == 1)
+                has_reached_end = true;
+            else {
+                context = ctx_stack.Peek ();
+                context.ExpectingValue = false;
+            }
+
+            Unindent ();
+            Put ("}");
+        }
+
+        public void WriteObjectStart ()
+        {
+            DoValidation (Condition.NotAProperty);
+            PutNewline ();
+
+            Put ("{");
+
+            context = new WriterContext ();
+            context.InObject = true;
+            ctx_stack.Push (context);
+
+            Indent ();
+        }
+
+        public void WritePropertyName (string property_name)
+        {
+            DoValidation (Condition.Property);
+            PutNewline ();
+            string propertyName = (property_name == null || !lower_case_properties)
+                ? property_name
+                : property_name.ToLowerInvariant();
+
+            PutString (propertyName);
+
+            if (pretty_print) {
+                if (propertyName.Length > context.Padding)
+                    context.Padding = propertyName.Length;
+
+                for (int i = context.Padding - propertyName.Length;
+                     i >= 0; i--)
+                    writer.Write (' ');
+
+                writer.Write (": ");
+            } else
+                writer.Write (':');
+
+            context.ExpectingValue = true;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/JsonWriter.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5f513552508ac234f87fbbd28be78e5c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 912 - 0
Unity/Assets/ThirdParty/LitJson/Lexer.cs

@@ -0,0 +1,912 @@
+#region Header
+/**
+ * Lexer.cs
+ *   JSON lexer implementation based on a finite state machine.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+
+namespace LitJson
+{
+    internal class FsmContext
+    {
+        public bool  Return;
+        public int   NextState;
+        public Lexer L;
+        public int   StateStack;
+    }
+
+
+    internal class Lexer
+    {
+        #region Fields
+        private delegate bool StateHandler (FsmContext ctx);
+
+        private static readonly int[]          fsm_return_table;
+        private static readonly StateHandler[] fsm_handler_table;
+
+        private bool          allow_comments;
+        private bool          allow_single_quoted_strings;
+        private bool          end_of_input;
+        private FsmContext    fsm_context;
+        private int           input_buffer;
+        private int           input_char;
+        private TextReader    reader;
+        private int           state;
+        private StringBuilder string_buffer;
+        private string        string_value;
+        private int           token;
+        private int           unichar;
+        #endregion
+
+
+        #region Properties
+        public bool AllowComments {
+            get { return allow_comments; }
+            set { allow_comments = value; }
+        }
+
+        public bool AllowSingleQuotedStrings {
+            get { return allow_single_quoted_strings; }
+            set { allow_single_quoted_strings = value; }
+        }
+
+        public bool EndOfInput {
+            get { return end_of_input; }
+        }
+
+        public int Token {
+            get { return token; }
+        }
+
+        public string StringValue {
+            get { return string_value; }
+        }
+        #endregion
+
+
+        #region Constructors
+        static Lexer ()
+        {
+            PopulateFsmTables (out fsm_handler_table, out fsm_return_table);
+        }
+
+        public Lexer (TextReader reader)
+        {
+            allow_comments = true;
+            allow_single_quoted_strings = true;
+
+            input_buffer = 0;
+            string_buffer = new StringBuilder (128);
+            state = 1;
+            end_of_input = false;
+            this.reader = reader;
+
+            fsm_context = new FsmContext ();
+            fsm_context.L = this;
+        }
+        #endregion
+
+
+        #region Static Methods
+        private static int HexValue (int digit)
+        {
+            switch (digit) {
+            case 'a':
+            case 'A':
+                return 10;
+
+            case 'b':
+            case 'B':
+                return 11;
+
+            case 'c':
+            case 'C':
+                return 12;
+
+            case 'd':
+            case 'D':
+                return 13;
+
+            case 'e':
+            case 'E':
+                return 14;
+
+            case 'f':
+            case 'F':
+                return 15;
+
+            default:
+                return digit - '0';
+            }
+        }
+
+        private static void PopulateFsmTables (out StateHandler[] fsm_handler_table, out int[] fsm_return_table)
+        {
+            // See section A.1. of the manual for details of the finite
+            // state machine.
+            fsm_handler_table = new StateHandler[28] {
+                State1,
+                State2,
+                State3,
+                State4,
+                State5,
+                State6,
+                State7,
+                State8,
+                State9,
+                State10,
+                State11,
+                State12,
+                State13,
+                State14,
+                State15,
+                State16,
+                State17,
+                State18,
+                State19,
+                State20,
+                State21,
+                State22,
+                State23,
+                State24,
+                State25,
+                State26,
+                State27,
+                State28
+            };
+
+            fsm_return_table = new int[28] {
+                (int) ParserToken.Char,
+                0,
+                (int) ParserToken.Number,
+                (int) ParserToken.Number,
+                0,
+                (int) ParserToken.Number,
+                0,
+                (int) ParserToken.Number,
+                0,
+                0,
+                (int) ParserToken.True,
+                0,
+                0,
+                0,
+                (int) ParserToken.False,
+                0,
+                0,
+                (int) ParserToken.Null,
+                (int) ParserToken.CharSeq,
+                (int) ParserToken.Char,
+                0,
+                0,
+                (int) ParserToken.CharSeq,
+                (int) ParserToken.Char,
+                0,
+                0,
+                0,
+                0
+            };
+        }
+
+        private static char ProcessEscChar (int esc_char)
+        {
+            switch (esc_char) {
+            case '"':
+            case '\'':
+            case '\\':
+            case '/':
+                return Convert.ToChar (esc_char);
+
+            case 'n':
+                return '\n';
+
+            case 't':
+                return '\t';
+
+            case 'r':
+                return '\r';
+
+            case 'b':
+                return '\b';
+
+            case 'f':
+                return '\f';
+
+            default:
+                // Unreachable
+                return '?';
+            }
+        }
+
+        private static bool State1 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r')
+                    continue;
+
+                if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 3;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case '"':
+                    ctx.NextState = 19;
+                    ctx.Return = true;
+                    return true;
+
+                case ',':
+                case ':':
+                case '[':
+                case ']':
+                case '{':
+                case '}':
+                    ctx.NextState = 1;
+                    ctx.Return = true;
+                    return true;
+
+                case '-':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 2;
+                    return true;
+
+                case '0':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 4;
+                    return true;
+
+                case 'f':
+                    ctx.NextState = 12;
+                    return true;
+
+                case 'n':
+                    ctx.NextState = 16;
+                    return true;
+
+                case 't':
+                    ctx.NextState = 9;
+                    return true;
+
+                case '\'':
+                    if (! ctx.L.allow_single_quoted_strings)
+                        return false;
+
+                    ctx.L.input_char = '"';
+                    ctx.NextState = 23;
+                    ctx.Return = true;
+                    return true;
+
+                case '/':
+                    if (! ctx.L.allow_comments)
+                        return false;
+
+                    ctx.NextState = 25;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State2 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char >= '1' && ctx.L.input_char<= '9') {
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 3;
+                return true;
+            }
+
+            switch (ctx.L.input_char) {
+            case '0':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 4;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State3 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case ',':
+                case ']':
+                case '}':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+
+                case '.':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 5;
+                    return true;
+
+                case 'e':
+                case 'E':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 7;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private static bool State4 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char == ' ' ||
+                ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+            }
+
+            switch (ctx.L.input_char) {
+            case ',':
+            case ']':
+            case '}':
+                ctx.L.UngetChar ();
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            case '.':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 5;
+                return true;
+
+            case 'e':
+            case 'E':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 7;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State5 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 6;
+                return true;
+            }
+
+            return false;
+        }
+
+        private static bool State6 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') {
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case ',':
+                case ']':
+                case '}':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+
+                case 'e':
+                case 'E':
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    ctx.NextState = 7;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State7 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') {
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 8;
+                return true;
+            }
+
+            switch (ctx.L.input_char) {
+            case '+':
+            case '-':
+                ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                ctx.NextState = 8;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State8 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') {
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+
+                if (ctx.L.input_char == ' ' ||
+                    ctx.L.input_char >= '\t' && ctx.L.input_char<= '\r') {
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                switch (ctx.L.input_char) {
+                case ',':
+                case ']':
+                case '}':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 1;
+                    return true;
+
+                default:
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State9 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'r':
+                ctx.NextState = 10;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State10 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'u':
+                ctx.NextState = 11;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State11 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'e':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State12 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'a':
+                ctx.NextState = 13;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State13 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'l':
+                ctx.NextState = 14;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State14 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 's':
+                ctx.NextState = 15;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State15 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'e':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State16 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'u':
+                ctx.NextState = 17;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State17 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'l':
+                ctx.NextState = 18;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State18 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'l':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State19 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                switch (ctx.L.input_char) {
+                case '"':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 20;
+                    return true;
+
+                case '\\':
+                    ctx.StateStack = 19;
+                    ctx.NextState = 21;
+                    return true;
+
+                default:
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State20 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case '"':
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State21 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case 'u':
+                ctx.NextState = 22;
+                return true;
+
+            case '"':
+            case '\'':
+            case '/':
+            case '\\':
+            case 'b':
+            case 'f':
+            case 'n':
+            case 'r':
+            case 't':
+                ctx.L.string_buffer.Append (
+                    ProcessEscChar (ctx.L.input_char));
+                ctx.NextState = ctx.StateStack;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State22 (FsmContext ctx)
+        {
+            int counter = 0;
+            int mult    = 4096;
+
+            ctx.L.unichar = 0;
+
+            while (ctx.L.GetChar ()) {
+
+                if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9' ||
+                    ctx.L.input_char >= 'A' && ctx.L.input_char <= 'F' ||
+                    ctx.L.input_char >= 'a' && ctx.L.input_char <= 'f') {
+
+                    ctx.L.unichar += HexValue (ctx.L.input_char) * mult;
+
+                    counter++;
+                    mult /= 16;
+
+                    if (counter == 4) {
+                        ctx.L.string_buffer.Append (
+                            Convert.ToChar (ctx.L.unichar));
+                        ctx.NextState = ctx.StateStack;
+                        return true;
+                    }
+
+                    continue;
+                }
+
+                return false;
+            }
+
+            return true;
+        }
+
+        private static bool State23 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                switch (ctx.L.input_char) {
+                case '\'':
+                    ctx.L.UngetChar ();
+                    ctx.Return = true;
+                    ctx.NextState = 24;
+                    return true;
+
+                case '\\':
+                    ctx.StateStack = 23;
+                    ctx.NextState = 21;
+                    return true;
+
+                default:
+                    ctx.L.string_buffer.Append ((char) ctx.L.input_char);
+                    continue;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State24 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case '\'':
+                ctx.L.input_char = '"';
+                ctx.Return = true;
+                ctx.NextState = 1;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State25 (FsmContext ctx)
+        {
+            ctx.L.GetChar ();
+
+            switch (ctx.L.input_char) {
+            case '*':
+                ctx.NextState = 27;
+                return true;
+
+            case '/':
+                ctx.NextState = 26;
+                return true;
+
+            default:
+                return false;
+            }
+        }
+
+        private static bool State26 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == '\n') {
+                    ctx.NextState = 1;
+                    return true;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State27 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == '*') {
+                    ctx.NextState = 28;
+                    return true;
+                }
+            }
+
+            return true;
+        }
+
+        private static bool State28 (FsmContext ctx)
+        {
+            while (ctx.L.GetChar ()) {
+                if (ctx.L.input_char == '*')
+                    continue;
+
+                if (ctx.L.input_char == '/') {
+                    ctx.NextState = 1;
+                    return true;
+                }
+
+                ctx.NextState = 27;
+                return true;
+            }
+
+            return true;
+        }
+        #endregion
+
+
+        private bool GetChar ()
+        {
+            if ((input_char = NextChar ()) != -1)
+                return true;
+
+            end_of_input = true;
+            return false;
+        }
+
+        private int NextChar ()
+        {
+            if (input_buffer != 0) {
+                int tmp = input_buffer;
+                input_buffer = 0;
+
+                return tmp;
+            }
+
+            return reader.Read ();
+        }
+
+        public bool NextToken ()
+        {
+            StateHandler handler;
+            fsm_context.Return = false;
+
+            while (true) {
+                handler = fsm_handler_table[state - 1];
+
+                if (! handler (fsm_context))
+                    throw new JsonException (input_char);
+
+                if (end_of_input)
+                    return false;
+
+                if (fsm_context.Return) {
+                    string_value = string_buffer.ToString ();
+                    string_buffer.Remove (0, string_buffer.Length);
+                    token = fsm_return_table[state - 1];
+
+                    if (token == (int) ParserToken.Char)
+                        token = input_char;
+
+                    state = fsm_context.NextState;
+
+                    return true;
+                }
+
+                state = fsm_context.NextState;
+            }
+        }
+
+        private void UngetChar ()
+        {
+            input_buffer = input_char;
+        }
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/Lexer.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e6ee4aa34aec6b54e89d18efe8d5a6f9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 24 - 0
Unity/Assets/ThirdParty/LitJson/Netstandard15Polyfill.cs

@@ -0,0 +1,24 @@
+#if NETSTANDARD1_5
+using System;
+using System.Reflection;
+namespace LitJson
+{
+    internal static class Netstandard15Polyfill
+    {
+        internal static Type GetInterface(this Type type, string name)
+        {
+            return type.GetTypeInfo().GetInterface(name); 
+        }
+
+        internal static bool IsClass(this Type type)
+        {
+            return type.GetTypeInfo().IsClass;
+        }
+
+        internal static bool IsEnum(this Type type)
+        {
+            return type.GetTypeInfo().IsEnum;
+        }
+    }
+}
+#endif

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/Netstandard15Polyfill.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2f416728c938e684090c453d56c2678e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 44 - 0
Unity/Assets/ThirdParty/LitJson/ParserToken.cs

@@ -0,0 +1,44 @@
+#region Header
+/**
+ * ParserToken.cs
+ *   Internal representation of the tokens used by the lexer and the parser.
+ *
+ * The authors disclaim copyright to this source code. For more details, see
+ * the COPYING file included with this distribution.
+ **/
+#endregion
+
+
+namespace LitJson
+{
+    internal enum ParserToken
+    {
+        // Lexer tokens (see section A.1.1. of the manual)
+        None = System.Char.MaxValue + 1,
+        Number,
+        True,
+        False,
+        Null,
+        CharSeq,
+        // Single char
+        Char,
+
+        // Parser Rules (see section A.2.1 of the manual)
+        Text,
+        Object,
+        ObjectPrime,
+        Pair,
+        PairRest,
+        Array,
+        ArrayPrime,
+        Value,
+        ValueRest,
+        String,
+
+        // End of input
+        End,
+
+        // The empty rule
+        Epsilon
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/ParserToken.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 13415f19664e8ac4eaab52d5335cbc36
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 153 - 0
Unity/Assets/ThirdParty/LitJson/UnityTypeBindings.cs

@@ -0,0 +1,153 @@
+using System;
+
+using LitJson.Extensions;
+
+namespace LitJson
+{
+
+#if !NOT_CLIENT
+#endif
+    /// <summary>
+    /// Unity内建类型拓展
+    /// </summary>
+    public static class UnityTypeBindings
+    {
+
+        static bool registerd;
+
+        static UnityTypeBindings()
+        {
+            Register();
+        }
+
+        public static void Register()
+        {
+
+            if (registerd) return;
+            registerd = true;
+
+
+            // 注册Type类型的Exporter
+            JsonMapper.RegisterExporter<Type>((v, w) =>
+            {
+                w.Write(v.FullName);
+            });
+
+            JsonMapper.RegisterImporter<string, Type>((s) =>
+            {
+                return Type.GetType(s);
+            });
+#if !NOT_CLIENT
+            // 注册Vector2类型的Exporter
+            Action<UnityEngine.Vector2, JsonWriter> writeVector2 = (v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("x", v.x);
+                w.WriteProperty("y", v.y);
+                w.WriteObjectEnd();
+            };
+
+            JsonMapper.RegisterExporter<UnityEngine.Vector2>((v, w) =>
+            {
+                writeVector2(v, w);
+            });
+
+            // 注册Vector3类型的Exporter
+            Action<UnityEngine.Vector3, JsonWriter> writeVector3 = (v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("x", v.x);
+                w.WriteProperty("y", v.y);
+                w.WriteProperty("z", v.z);
+                w.WriteObjectEnd();
+            };
+
+            JsonMapper.RegisterExporter<UnityEngine.Vector3>((v, w) =>
+            {
+                writeVector3(v, w);
+            });
+
+            // 注册Vector4类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.Vector4>((v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("x", v.x);
+                w.WriteProperty("y", v.y);
+                w.WriteProperty("z", v.z);
+                w.WriteProperty("w", v.w);
+                w.WriteObjectEnd();
+            });
+
+            // 注册Quaternion类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.Quaternion>((v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("x", v.x);
+                w.WriteProperty("y", v.y);
+                w.WriteProperty("z", v.z);
+                w.WriteProperty("w", v.w);
+                w.WriteObjectEnd();
+            });
+
+            // 注册Color类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.Color>((v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("r", v.r);
+                w.WriteProperty("g", v.g);
+                w.WriteProperty("b", v.b);
+                w.WriteProperty("a", v.a);
+                w.WriteObjectEnd();
+            });
+
+            // 注册Color32类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.Color32>((v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("r", v.r);
+                w.WriteProperty("g", v.g);
+                w.WriteProperty("b", v.b);
+                w.WriteProperty("a", v.a);
+                w.WriteObjectEnd();
+            });
+
+            // 注册Bounds类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.Bounds>((v, w) =>
+            {
+                w.WriteObjectStart();
+
+                w.WritePropertyName("center");
+                writeVector3(v.center, w);
+
+                w.WritePropertyName("size");
+                writeVector3(v.size, w);
+
+                w.WriteObjectEnd();
+            });
+
+            // 注册Rect类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.Rect>((v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("x", v.x);
+                w.WriteProperty("y", v.y);
+                w.WriteProperty("width", v.width);
+                w.WriteProperty("height", v.height);
+                w.WriteObjectEnd();
+            });
+
+            // 注册RectOffset类型的Exporter
+            JsonMapper.RegisterExporter<UnityEngine.RectOffset>((v, w) =>
+            {
+                w.WriteObjectStart();
+                w.WriteProperty("top", v.top);
+                w.WriteProperty("left", v.left);
+                w.WriteProperty("bottom", v.bottom);
+                w.WriteProperty("right", v.right);
+                w.WriteObjectEnd();
+            });
+#endif
+        }
+
+    }
+}

+ 11 - 0
Unity/Assets/ThirdParty/LitJson/UnityTypeBindings.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f127a589d0f45ec4bb223bb418674d84
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 6
Unity/Packages/manifest.json

@@ -9,13 +9,10 @@
     "com.unity.ide.rider": "2.0.7",
     "com.unity.ide.visualstudio": "2.0.5",
     "com.unity.ide.vscode": "1.2.3",
-    "com.unity.multiplayer-hlapi": "1.0.6",
-    "com.unity.purchasing": "2.2.1",
-    "com.unity.test-framework": "1.1.20",
-    "com.unity.textmeshpro": "3.0.1",
-    "com.unity.timeline": "1.2.10",
+    "com.unity.multiplayer-hlapi": "1.0.8",
+    "com.unity.textmeshpro": "3.0.3",
+    "com.unity.timeline": "1.4.6",
     "com.unity.ugui": "1.0.0",
-    "com.unity.xr.legacyinputhelpers": "2.1.7",
     "com.unity.modules.ai": "1.0.0",
     "com.unity.modules.androidjni": "1.0.0",
     "com.unity.modules.animation": "1.0.0",

+ 11 - 25
Unity/Packages/packages-lock.json

@@ -46,7 +46,7 @@
     },
     "com.unity.ext.nunit": {
       "version": "1.0.6",
-      "depth": 1,
+      "depth": 2,
       "source": "registry",
       "dependencies": {},
       "url": "https://packages.unity.cn"
@@ -75,7 +75,7 @@
       "url": "https://packages.unity.cn"
     },
     "com.unity.multiplayer-hlapi": {
-      "version": "1.0.6",
+      "version": "1.0.8",
       "depth": 0,
       "source": "registry",
       "dependencies": {
@@ -83,18 +83,9 @@
       },
       "url": "https://packages.unity.cn"
     },
-    "com.unity.purchasing": {
-      "version": "2.2.1",
-      "depth": 0,
-      "source": "registry",
-      "dependencies": {
-        "com.unity.ugui": "1.0.0"
-      },
-      "url": "https://packages.unity.cn"
-    },
     "com.unity.test-framework": {
       "version": "1.1.20",
-      "depth": 0,
+      "depth": 1,
       "source": "registry",
       "dependencies": {
         "com.unity.ext.nunit": "1.0.6",
@@ -104,7 +95,7 @@
       "url": "https://packages.unity.cn"
     },
     "com.unity.textmeshpro": {
-      "version": "3.0.1",
+      "version": "3.0.3",
       "depth": 0,
       "source": "registry",
       "dependencies": {
@@ -113,10 +104,15 @@
       "url": "https://packages.unity.cn"
     },
     "com.unity.timeline": {
-      "version": "1.2.10",
+      "version": "1.4.6",
       "depth": 0,
       "source": "registry",
-      "dependencies": {},
+      "dependencies": {
+        "com.unity.modules.director": "1.0.0",
+        "com.unity.modules.animation": "1.0.0",
+        "com.unity.modules.audio": "1.0.0",
+        "com.unity.modules.particlesystem": "1.0.0"
+      },
       "url": "https://packages.unity.cn"
     },
     "com.unity.ugui": {
@@ -128,16 +124,6 @@
         "com.unity.modules.imgui": "1.0.0"
       }
     },
-    "com.unity.xr.legacyinputhelpers": {
-      "version": "2.1.7",
-      "depth": 0,
-      "source": "registry",
-      "dependencies": {
-        "com.unity.modules.vr": "1.0.0",
-        "com.unity.modules.xr": "1.0.0"
-      },
-      "url": "https://packages.unity.cn"
-    },
     "nuget.mono-cecil": {
       "version": "0.1.6-preview",
       "depth": 1,

+ 4 - 3
Unity/Unity.Editor.csproj

@@ -85,6 +85,7 @@
      <Compile Include="Assets\Editor\Proto2CsEditor\InnerProto2CS.cs" />
      <Compile Include="Assets\Editor\RsyncEditor\RsyncConfig.cs" />
      <Compile Include="Assets\Editor\ComponentViewEditor\TypeDrawer\StringTypeDrawer.cs" />
+     <Compile Include="Assets\Editor\Helper\MongoHelper.cs" />
      <None Include="Assets\Editor\Unity.Editor.asmdef" />
  <Reference Include="UnityEngine">
  <HintPath>/Applications/Unity/Hub/Editor/2020.2.2f1c1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.dll</HintPath>
@@ -335,6 +336,9 @@
  <Reference Include="Pathfinding.Ionic.Zip.Reduced">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/DotNetZip/Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
  </Reference>
+ <Reference Include="CommandLine">
+ <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
+ </Reference>
  <Reference Include="Pathfinding.ClipperLib">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Clipper/Pathfinding.ClipperLib.dll</HintPath>
  </Reference>
@@ -347,9 +351,6 @@
  <Reference Include="Pathfinding.Poly2Tri">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Poly2Tri/Pathfinding.Poly2Tri.dll</HintPath>
  </Reference>
- <Reference Include="CommandLine">
- <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
- </Reference>
  <Reference Include="MongoDB.Bson">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/MongoDB.Bson.dll</HintPath>
  </Reference>

+ 9 - 9
Unity/Unity.Hotfix.csproj

@@ -52,24 +52,24 @@
     <ImplicitlyExpandDesignTimeFacades>false</ImplicitlyExpandDesignTimeFacades>
   </PropertyGroup>
   <ItemGroup>
+     <Compile Include="Assets\Hotfix\Module\Message\NetThreadComponentSystem.cs" />
      <Compile Include="Assets\Hotfix\Scene\LoginHelper.cs" />
      <Compile Include="Assets\Hotfix\Module\Numeric\NumericChangeEvent_NotifyWatcher.cs" />
      <Compile Include="Assets\Hotfix\Unit\M2C_CreateUnitsHandler.cs" />
      <Compile Include="Assets\Hotfix\Module\Config\ConfigComponentSystem.cs" />
+     <Compile Include="Assets\Hotfix\Module\Message\SessionIdleCheckerComponentSystem.cs" />
+     <Compile Include="Assets\Hotfix\Module\Message\NetKcpComponentSystem.cs" />
      <Compile Include="Assets\Hotfix\Module\Numeric\NumericWatcher_Hp_ShowUI.cs" />
+     <Compile Include="Assets\Hotfix\Module\Message\OuterMessageDispatcher.cs" />
      <Compile Include="Assets\Hotfix\Move\M2C_PathfindingResultHandler.cs" />
      <Compile Include="Assets\Hotfix\Unit\UnitComponent.cs" />
      <Compile Include="Assets\Hotfix\Unit\UnitFactory.cs" />
      <Compile Include="Assets\Hotfix\Scene\MapHelper.cs" />
+     <Compile Include="Assets\Hotfix\Module\Message\MessageDispatcherComponentSystem.cs" />
+     <Compile Include="Assets\Hotfix\Module\Message\PingComponentSystem.cs" />
      <Compile Include="Assets\Hotfix\Unit\TurnComponentSystem.cs" />
      <Compile Include="Assets\Hotfix\Session\SessionComponentSystem.cs" />
-     <Compile Include="Assets\Hotfix\Module\Message\PingComponentSystem.cs" />
-     <Compile Include="Assets\Hotfix\Module\Message\NetKcpComponentSystem.cs" />
-     <Compile Include="Assets\Hotfix\Module\Message\MessageDispatcherComponentSystem.cs" />
      <Compile Include="Assets\Hotfix\Module\Message\SessionAcceptTimeoutComponentSystem.cs" />
-     <Compile Include="Assets\Hotfix\Module\Message\OuterMessageDispatcher.cs" />
-     <Compile Include="Assets\Hotfix\Module\Message\SessionIdleCheckerComponentSystem.cs" />
-     <Compile Include="Assets\Hotfix\Module\Message\NetThreadComponentSystem.cs" />
      <None Include="Assets\Hotfix\Unity.Hotfix.asmdef" />
  <Reference Include="UnityEngine">
  <HintPath>/Applications/Unity/Hub/Editor/2020.2.2f1c1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.dll</HintPath>
@@ -320,6 +320,9 @@
  <Reference Include="Pathfinding.Ionic.Zip.Reduced">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/DotNetZip/Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
  </Reference>
+ <Reference Include="CommandLine">
+ <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
+ </Reference>
  <Reference Include="Pathfinding.ClipperLib">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Clipper/Pathfinding.ClipperLib.dll</HintPath>
  </Reference>
@@ -332,9 +335,6 @@
  <Reference Include="Pathfinding.Poly2Tri">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Poly2Tri/Pathfinding.Poly2Tri.dll</HintPath>
  </Reference>
- <Reference Include="CommandLine">
- <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
- </Reference>
  <Reference Include="MongoDB.Bson">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/MongoDB.Bson.dll</HintPath>
  </Reference>

+ 3 - 3
Unity/Unity.HotfixView.csproj

@@ -326,6 +326,9 @@
  <Reference Include="Pathfinding.Ionic.Zip.Reduced">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/DotNetZip/Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
  </Reference>
+ <Reference Include="CommandLine">
+ <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
+ </Reference>
  <Reference Include="Pathfinding.ClipperLib">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Clipper/Pathfinding.ClipperLib.dll</HintPath>
  </Reference>
@@ -338,9 +341,6 @@
  <Reference Include="Pathfinding.Poly2Tri">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Poly2Tri/Pathfinding.Poly2Tri.dll</HintPath>
  </Reference>
- <Reference Include="CommandLine">
- <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
- </Reference>
  <Reference Include="MongoDB.Bson">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/MongoDB.Bson.dll</HintPath>
  </Reference>

+ 51 - 52
Unity/Unity.Model.csproj

@@ -54,11 +54,17 @@
   <ItemGroup>
      <Compile Include="Assets\Model\Helper\PathHelper.cs" />
      <Compile Include="Assets\Model\Unit\TurnComponent.cs" />
+     <Compile Include="Assets\Model\Core\DoubleMap.cs" />
      <Compile Include="Assets\Model\Core\Entity\EntitySceneFactory.cs" />
+     <Compile Include="Assets\Model\Module\Message\MessagePackHelper.cs" />
      <Compile Include="Assets\Model\Module\Message\MessageProxy.cs" />
      <Compile Include="Assets\Model\EventType.cs" />
+     <Compile Include="Assets\Model\Core\UnOrderMultiMapSet.cs" />
      <Compile Include="Assets\Model\Core\Entity\SceneType.cs" />
+     <Compile Include="Assets\Model\Module\Message\SessionIdleCheckerComponent.cs" />
+     <Compile Include="Assets\Model\Core\Helper\NetworkHelper.cs" />
      <Compile Include="Assets\Model\Module\Message\MessageDispatcherComponent.cs" />
+     <Compile Include="Assets\Model\Module\ActorLocation\ActorResponse.cs" />
      <Compile Include="Assets\Model\Module\Message\OpcodeTypeComponent.cs" />
      <Compile Include="Assets\Model\Core\Async\ETCancellationToken.cs" />
      <Compile Include="Assets\Model\Core\Object\IAwakeSystem.cs" />
@@ -69,6 +75,7 @@
      <Compile Include="Assets\Model\Config\UnitConfig.cs" />
      <Compile Include="Assets\Model\Module\CoroutineLock\CoroutineLockQueueType.cs" />
      <Compile Include="Assets\Model\Unit\Unit.cs" />
+     <Compile Include="Assets\Model\Module\Message\MessageSerializeHelper.cs" />
      <Compile Include="Assets\Model\Core\Object\IUpdateSystem.cs" />
      <Compile Include="Assets\Model\Core\Object\EventSystem.cs" />
      <Compile Include="Assets\Model\Module\Message\IMessage.cs" />
@@ -76,12 +83,14 @@
      <Compile Include="Assets\Model\Module\Resource\ResourcesComponent.cs" />
      <Compile Include="Assets\Model\Core\Object\IDestroySystem.cs" />
      <Compile Include="Assets\Model\Core\Helper\MethodInfoHelper.cs" />
+     <Compile Include="Assets\Model\Module\Network\Kcp.cs" />
      <Compile Include="Assets\Model\Core\Helper\FileHelper.cs" />
+     <Compile Include="Assets\Model\Core\Log\UnityLogger.cs" />
      <Compile Include="Assets\Model\Core\Object\HideInHierarchy.cs" />
-     <Compile Include="Assets\Model\Core\Helper\MongoHelper.cs" />
      <Compile Include="Assets\Model\Module\Config\ConfigAttribute.cs" />
      <Compile Include="Assets\Model\Core\Async\AsyncETVoidMethodBuilder.cs" />
      <Compile Include="Assets\Model\Module\Config\ACategory.cs" />
+     <Compile Include="Assets\Model\Module\Message\PingComponent.cs" />
      <Compile Include="Assets\Model\Core\Object\EntityCreateComponet.cs" />
      <Compile Include="Assets\Model\Module\Message\RpcException.cs" />
      <Compile Include="Assets\Model\Module\Message\IMessageDispatcher.cs" />
@@ -90,38 +99,54 @@
      <Compile Include="Assets\Model\Core\Object\IStartSystem.cs" />
      <Compile Include="Assets\Model\Core\Event\IEvent.cs" />
      <Compile Include="Assets\Model\Module\Message\SessionCallbackComponent.cs" />
+     <Compile Include="Assets\Model\Module\Network\Circularbuffer.cs" />
+     <Compile Include="Assets\Model\Generate\OuterProtoMessage.cs" />
      <Compile Include="Assets\Model\Module\ActorLocation\IActorLocationMessage.cs" />
      <Compile Include="Assets\Model\Core\Async\AsyncMethodBuilderAttribute.cs" />
+     <Compile Include="Assets\Model\Core\MultiDictionary.cs" />
      <Compile Include="Assets\Model\Module\UnityWebRequest\UnityWebRequestRenewalAsync.cs" />
      <Compile Include="Assets\Model\Core\Entity\TimerComponent.cs" />
      <Compile Include="Assets\Model\Module\CoroutineLock\CoroutineLockType.cs" />
      <Compile Include="Assets\Model\Define.cs" />
      <Compile Include="Assets\Model\Core\Helper\ByteHelper.cs" />
      <Compile Include="Assets\Model\Core\Async\IAwaiter.cs" />
+     <Compile Include="Assets\Model\Core\ThreadSynchronizationContext.cs" />
+     <Compile Include="Assets\Model\Core\Log\LogHelper.cs" />
+     <Compile Include="Assets\Model\Core\MultiMapSet.cs" />
      <Compile Include="Assets\Model\Session\SessionComponent.cs" />
      <Compile Include="Assets\Model\Core\Object\ILoadSystem.cs" />
      <Compile Include="Assets\Model\Core\Entity\Scene.cs" />
      <Compile Include="Assets\Model\Core\Object\ILateUpdateSystem.cs" />
+     <Compile Include="Assets\Model\Core\Log\ILog.cs" />
+     <Compile Include="Assets\Model\Core\Log\Log.cs" />
+     <Compile Include="Assets\Model\Core\ProcessHelper.cs" />
      <Compile Include="Assets\Model\Core\Helper\JsonHelper.cs" />
      <Compile Include="Assets\Model\Core\Helper\RandomHelper.cs" />
+     <Compile Include="Assets\Model\Module\Message\NetKcpComponent.cs" />
      <Compile Include="Assets\Model\Module\Actor\IActorMessage.cs" />
      <Compile Include="Assets\Model\Core\Helper\IdGenerater.cs" />
+     <Compile Include="Assets\Model\Core\Log\FileLogger.cs" />
      <Compile Include="Assets\Model\Core\Async\AsyncETTaskCompletedMethodBuilder.cs" />
      <Compile Include="Assets\Model\Module\UnityWebRequest\UnityWebRequestAsync.cs" />
      <Compile Include="Assets\Model\Module\Message\MessageHandlerAttribute.cs" />
      <Compile Include="Assets\Model\Core\Event\EventAttribute.cs" />
-     <Compile Include="Assets\Model\Config\StartMachineConfig.cs" />
      <Compile Include="Assets\Model\Core\Object\NoObjectPool.cs" />
+     <Compile Include="Assets\Model\Config\StartMachineConfig.cs" />
      <Compile Include="Assets\Model\Config\StartZoneConfig.cs" />
      <Compile Include="Assets\Model\Core\Object\Object.cs" />
      <Compile Include="Assets\Model\Module\Message\OpcodeHelper.cs" />
      <Compile Include="Assets\Model\Module\Numeric\INumericWatcher.cs" />
      <Compile Include="Assets\Model\Config\StartSceneConfig.cs" />
+     <Compile Include="Assets\Model\Module\Network\KService.cs" />
      <Compile Include="Assets\Model\Module\CoroutineLock\CoroutineLockComponent.cs" />
      <Compile Include="Assets\Model\Core\Object\EntityFactory.cs" />
      <Compile Include="Assets\Model\Core\Object\IChangeSystem.cs" />
+     <Compile Include="Assets\Model\Module\Network\AService.cs" />
+     <Compile Include="Assets\Model\Base\Options.cs" />
      <Compile Include="Assets\Model\Core\Helper\ZipHelper.cs" />
      <Compile Include="Assets\Model\Module\Message\MessageAttribute.cs" />
+     <Compile Include="Assets\Model\Core\UnOrderMultiMap.cs" />
+     <Compile Include="Assets\Model\Core\Object\TimeInfo.cs" />
      <Compile Include="Assets\Model\Module\Numeric\NumericWatcherComponent.cs" />
      <Compile Include="Assets\Model\Core\Async\AsyncETTaskMethodBuilder.cs" />
      <Compile Include="Assets\Model\Core\Helper\MD5Helper.cs" />
@@ -130,79 +155,53 @@
      <Compile Include="Assets\Model\Core\Helper\ObjectHelper.cs" />
      <Compile Include="Assets\Model\Module\Message\IMHandler.cs" />
      <Compile Include="Assets\Model\Module\CoroutineLock\CoroutineLockQueue.cs" />
+     <Compile Include="Assets\Model\Module\Message\SessionAcceptTimeoutComponent.cs" />
      <Compile Include="Assets\Model\Module\Numeric\NumericComponent.cs" />
      <Compile Include="Assets\Model\Module\Message\Session.cs" />
      <Compile Include="Assets\Model\Core\Object\NoMemoryCheck.cs" />
+     <Compile Include="Assets\Model\Core\ObjectWait.cs" />
      <Compile Include="Assets\Model\Core\Object\Entity.cs" />
      <Compile Include="Assets\Model\Core\Async\ETVoid.cs" />
+     <Compile Include="Assets\Model\Core\MultiMap.cs" />
      <Compile Include="Assets\Model\Module\Numeric\NumericWatcherAttribute.cs" />
+     <Compile Include="Assets\Model\Core\LogType.cs" />
      <Compile Include="Assets\Model\Module\Config\AConfigComponent.cs" />
      <Compile Include="Assets\Model\Core\Async\ETTaskCompleted.cs" />
+     <Compile Include="Assets\Model\Core\HashSetComponent.cs" />
+     <Compile Include="Assets\Model\Core\Pool.cs" />
      <Compile Include="Assets\Model\Core\Object\ObjectSystemAttribute.cs" />
      <Compile Include="Assets\Model\Module\Config\ConfigHelper.cs" />
-     <Compile Include="Assets\Model\Config\StartProcessConfig.cs" />
      <Compile Include="Assets\Model\Core\Entity\Game.cs" />
+     <Compile Include="Assets\Model\Config\StartProcessConfig.cs" />
+     <Compile Include="Assets\Model\Core\StructBsonSerialize.cs" />
      <Compile Include="Assets\Model\Module\CoroutineLock\CoroutineLock.cs" />
      <Compile Include="Assets\Model\Module\Message\ErrorCode.cs" />
+     <Compile Include="Assets\Model\Module\NetworkTCP\PacketParser.cs" />
+     <Compile Include="Assets\Model\Generate\OuterProtoOpcode.cs" />
+     <Compile Include="Assets\Model\Core\Object\ProtoObject.cs" />
+     <Compile Include="Assets\Model\Module\Message\ProtobufHelper.cs" />
+     <Compile Include="Assets\Model\Module\Message\NetThreadComponent.cs" />
      <Compile Include="Assets\Model\Core\Helper\TimeHelper.cs" />
      <Compile Include="Assets\Model\Core\Object\ISerializeToEntity.cs" />
      <Compile Include="Assets\Model\Core\Object\ComponentView.cs" />
+     <Compile Include="Assets\Model\Core\QueueDictionary.cs" />
+     <Compile Include="Assets\Model\Module\Network\KChannel.cs" />
      <Compile Include="Assets\Model\Core\Object\EntityEventAttribute.cs" />
+     <Compile Include="Assets\Model\Module\NetworkTCP\TService.cs" />
+     <Compile Include="Assets\Model\Core\MultiMapComponent.cs" />
      <Compile Include="Assets\Model\Helper\PositionHelper.cs" />
+     <Compile Include="Assets\Model\Core\ListComponent.cs" />
+     <Compile Include="Assets\Model\Core\Log\NLogger.cs" />
      <Compile Include="Assets\Model\Core\Async\ETTaskCompletionSource.cs" />
      <Compile Include="Assets\Model\Core\Helper\StringHelper.cs" />
+     <Compile Include="Assets\Model\Module\Message\MessagePool.cs" />
      <Compile Include="Assets\Model\Module\Config\IConfig.cs" />
+     <Compile Include="Assets\Model\Module\Message\ResponseTypeAttribute.cs" />
      <Compile Include="Assets\Model\Module\Resource\AssetsBundleLoaderAsync.cs" />
      <Compile Include="Assets\Model\Core\Object\ObjectPool.cs" />
      <Compile Include="Assets\Model\Core\Async\ETTaskHelper.cs" />
-     <Compile Include="Assets\Model\Core\UnOrderMultiMapSet.cs" />
-     <Compile Include="Assets\Model\Module\Network\KService.cs" />
-     <Compile Include="Assets\Model\Core\QueueDictionary.cs" />
-     <Compile Include="Assets\Model\Core\ListComponent.cs" />
-     <Compile Include="Assets\Model\Module\ActorLocation\ActorResponse.cs" />
-     <Compile Include="Assets\Model\Core\Log\ILog.cs" />
-     <Compile Include="Assets\Model\Module\NetworkTCP\PacketParser.cs" />
-     <Compile Include="Assets\Model\Module\Network\AService.cs" />
-     <Compile Include="Assets\Model\Core\ThreadSynchronizationContext.cs" />
-     <Compile Include="Assets\Model\Core\Log\UnityLogger.cs" />
-     <Compile Include="Assets\Model\Core\Log\LogHelper.cs" />
-     <Compile Include="Assets\Model\Core\MultiMapSet.cs" />
-     <Compile Include="Assets\Model\Core\LogType.cs" />
-     <Compile Include="Assets\Model\Base\Options.cs" />
-     <Compile Include="Assets\Model\Module\Network\Circularbuffer.cs" />
-     <Compile Include="Assets\Model\Module\Network\KChannel.cs" />
-     <Compile Include="Assets\Model\Core\Log\FileLogger.cs" />
-     <Compile Include="Assets\Model\Core\Log\NLogger.cs" />
-     <Compile Include="Assets\Model\Module\Message\MessageSerializeHelper.cs" />
-     <Compile Include="Assets\Model\Module\Message\SessionAcceptTimeoutComponent.cs" />
-     <Compile Include="Assets\Model\Core\HashSetComponent.cs" />
-     <Compile Include="Assets\Model\Core\Pool.cs" />
-     <Compile Include="Assets\Model\Core\Log\Log.cs" />
-     <Compile Include="Assets\Model\Module\Message\MessagePool.cs" />
-     <Compile Include="Assets\Model\Core\Object\ProtoObject.cs" />
-     <Compile Include="Assets\Model\Core\DoubleMap.cs" />
-     <Compile Include="Assets\Model\Module\Message\ProtobufHelper.cs" />
-     <Compile Include="Assets\Model\Module\Message\ResponseTypeAttribute.cs" />
-     <Compile Include="Assets\Model\Core\ProcessHelper.cs" />
-     <Compile Include="Assets\Model\Module\Network\Kcp.cs" />
-     <Compile Include="Assets\Model\Core\UnOrderMultiMap.cs" />
-     <Compile Include="Assets\Model\Module\Message\NetThreadComponent.cs" />
-     <Compile Include="Assets\Model\Core\Object\TimeInfo.cs" />
-     <Compile Include="Assets\Model\Module\Message\NetKcpComponent.cs" />
-     <Compile Include="Assets\Model\Core\MultiDictionary.cs" />
-     <Compile Include="Assets\Model\Module\Message\PingComponent.cs" />
-     <Compile Include="Assets\Model\Module\NetworkTCP\TService.cs" />
      <Compile Include="Assets\Model\Module\NetworkTCP\TChannel.cs" />
-     <Compile Include="Assets\Model\Module\Message\SessionIdleCheckerComponent.cs" />
-     <Compile Include="Assets\Model\Core\ObjectWait.cs" />
-     <Compile Include="Assets\Model\Core\StructBsonSerialize.cs" />
-     <Compile Include="Assets\Model\Core\MultiMapComponent.cs" />
-     <Compile Include="Assets\Model\Core\Helper\NetworkHelper.cs" />
-     <Compile Include="Assets\Model\Module\Message\MessagePackHelper.cs" />
-     <Compile Include="Assets\Model\Core\MultiMap.cs" />
      <Compile Include="Assets\Model\Module\Network\AChannel.cs" />
-     <Compile Include="Assets\Model\Generate\OuterProtoMessage.cs" />
-     <Compile Include="Assets\Model\Generate\OuterProtoOpcode.cs" />
      <None Include="Assets\Model\Unity.Model.asmdef" />
  <Reference Include="UnityEngine">
  <HintPath>/Applications/Unity/Hub/Editor/2020.2.2f1c1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.dll</HintPath>
@@ -453,6 +452,9 @@
  <Reference Include="Pathfinding.Ionic.Zip.Reduced">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/DotNetZip/Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
  </Reference>
+ <Reference Include="CommandLine">
+ <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
+ </Reference>
  <Reference Include="Pathfinding.ClipperLib">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Clipper/Pathfinding.ClipperLib.dll</HintPath>
  </Reference>
@@ -465,9 +467,6 @@
  <Reference Include="Pathfinding.Poly2Tri">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Poly2Tri/Pathfinding.Poly2Tri.dll</HintPath>
  </Reference>
- <Reference Include="CommandLine">
- <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
- </Reference>
  <Reference Include="MongoDB.Bson">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/MongoDB.Bson.dll</HintPath>
  </Reference>

+ 3 - 3
Unity/Unity.ModelView.csproj

@@ -321,6 +321,9 @@
  <Reference Include="Pathfinding.Ionic.Zip.Reduced">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/DotNetZip/Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
  </Reference>
+ <Reference Include="CommandLine">
+ <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
+ </Reference>
  <Reference Include="Pathfinding.ClipperLib">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Clipper/Pathfinding.ClipperLib.dll</HintPath>
  </Reference>
@@ -333,9 +336,6 @@
  <Reference Include="Pathfinding.Poly2Tri">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Poly2Tri/Pathfinding.Poly2Tri.dll</HintPath>
  </Reference>
- <Reference Include="CommandLine">
- <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
- </Reference>
  <Reference Include="MongoDB.Bson">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/MongoDB.Bson.dll</HintPath>
  </Reference>

+ 15 - 3
Unity/Unity.ThirdParty.csproj

@@ -148,6 +148,18 @@
      <Compile Include="Assets\ThirdParty\protobuf-net\Meta\TypeModel.cs" />
      <Compile Include="Assets\ThirdParty\protobuf-net\DiscriminatedUnion.Serializable.cs" />
      <Compile Include="Assets\ThirdParty\protobuf-net\Serializers\FieldDecorator.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\JsonReader.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\Netstandard15Polyfill.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\Extensions.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\ParserToken.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\JsonException.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\IJsonWrapper.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\JsonWriter.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\UnityTypeBindings.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\JsonData.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\Lexer.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\JsonMapper.cs" />
+     <Compile Include="Assets\ThirdParty\LitJson\JsonMockWrapper.cs" />
      <None Include="Assets\ThirdParty\Unity.ThirdParty.asmdef" />
  <Reference Include="UnityEngine">
  <HintPath>/Applications/Unity/Hub/Editor/2020.2.2f1c1/Unity.app/Contents/Managed/UnityEngine/UnityEngine.dll</HintPath>
@@ -398,6 +410,9 @@
  <Reference Include="Pathfinding.Ionic.Zip.Reduced">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/DotNetZip/Pathfinding.Ionic.Zip.Reduced.dll</HintPath>
  </Reference>
+ <Reference Include="CommandLine">
+ <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
+ </Reference>
  <Reference Include="Pathfinding.ClipperLib">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Clipper/Pathfinding.ClipperLib.dll</HintPath>
  </Reference>
@@ -410,9 +425,6 @@
  <Reference Include="Pathfinding.Poly2Tri">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/AstarPathfindingProject/Poly2Tri/Pathfinding.Poly2Tri.dll</HintPath>
  </Reference>
- <Reference Include="CommandLine">
- <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/CommandLine.dll</HintPath>
- </Reference>
  <Reference Include="MongoDB.Bson">
  <HintPath>/Users/tanghai/Documents/ET/Unity/Assets/Plugins/MongoDB.Bson.dll</HintPath>
  </Reference>