Kaynağa Gözat

Merge branch 'Dev' into d1

WangBo 8 yıl önce
ebeveyn
işleme
4b1eb20e08
100 değiştirilmiş dosya ile 4548 ekleme ve 3994 silme
  1. 6 0
      .gitignore
  2. 230 0
      Client-Server.sln
  3. 9 716
      Client-Server.sln.DotSettings
  4. 13 0
      Client-Server.sln.DotSettings.user
  5. BIN
      Config/BuffConfig.txt
  6. 9 6
      Config/StartConfig/127.0.0.1.txt
  7. 6 6
      Config/StartConfig/192.168.12.112.txt
  8. 6 6
      Config/StartConfig/192.168.9.182.txt
  9. 2 2
      Config/StartConfig/Benchmark.txt
  10. 2 0
      Config/StartConfig/BenchmarkClient.txt
  11. 1 1
      Config/StartConfig/LocalAllServer.txt
  12. 85 0
      Doc/组件设计.md
  13. 131 0
      Doc/网络层设计.md
  14. 27 0
      Doc/运行指南.md
  15. BIN
      Excel/UnitConfig.xlsx
  16. 0 28
      README
  17. 56 0
      README.md
  18. 2 2
      Run.sh
  19. 3 0
      Server/App/App.config
  20. 5 4
      Server/App/NLog.config
  21. 3041 0
      Server/App/NLog.xsd
  22. 36 10
      Server/App/Program.cs
  23. 0 35
      Server/App/Properties/AssemblyInfo.cs
  24. 8 0
      Server/App/Properties/launchSettings.json
  25. 20 63
      Server/App/Server.App.csproj
  26. 0 7
      Server/App/Server.App.csproj.user
  27. 0 144
      Server/Base/DoubleMap.cs
  28. 0 12
      Server/Base/Helper/ArrayHelper.cs
  29. 0 64
      Server/Base/Helper/ByteHelper.cs
  30. 0 30
      Server/Base/Helper/EnumHelper.cs
  31. 0 56
      Server/Base/Helper/FileHelper.cs
  32. 0 16
      Server/Base/Helper/IdGenerater.cs
  33. 0 19
      Server/Base/Helper/MD5Helper.cs
  34. 0 26
      Server/Base/Helper/MethodInfoHelper.cs
  35. 0 67
      Server/Base/Helper/MongoHelper.cs
  36. 0 22
      Server/Base/Helper/NetHelper.cs
  37. 0 83
      Server/Base/Helper/ProtobufHelper.cs
  38. 0 35
      Server/Base/Helper/RandomHelper.cs
  39. 0 62
      Server/Base/Helper/StringHelper.cs
  40. 0 36
      Server/Base/Helper/TimeHelper.cs
  41. 0 97
      Server/Base/Helper/ZipHelper.cs
  42. 1 1
      Server/Base/Logger/NLogAdapter.cs
  43. 0 111
      Server/Base/MultiMap.cs
  44. 0 84
      Server/Base/Network/AChannel.cs
  45. 0 32
      Server/Base/Network/AService.cs
  46. 0 84
      Server/Base/Network/TNet/PacketParser.cs
  47. 0 129
      Server/Base/Network/TNet/TBuffer.cs
  48. 0 245
      Server/Base/Network/TNet/TChannel.cs
  49. 0 38
      Server/Base/Network/TNet/TPoller.cs
  50. 0 100
      Server/Base/Network/TNet/TService.cs
  51. 0 243
      Server/Base/Network/TNet/TSocket.cs
  52. 0 33
      Server/Base/Network/UNet/Library.cs
  53. 0 109
      Server/Base/Network/UNet/NativeMethods.cs
  54. 0 76
      Server/Base/Network/UNet/NativeStructs.cs
  55. 0 27
      Server/Base/Network/UNet/UAddress.cs
  56. 0 100
      Server/Base/Network/UNet/UChannel.cs
  57. 0 72
      Server/Base/Network/UNet/UPacket.cs
  58. 0 214
      Server/Base/Network/UNet/UPoller.cs
  59. 0 94
      Server/Base/Network/UNet/UService.cs
  60. 0 168
      Server/Base/Network/UNet/USocket.cs
  61. 0 41
      Server/Base/Network/UNet/USocketManager.cs
  62. 0 35
      Server/Base/Properties/AssemblyInfo.cs
  63. 0 47
      Server/Base/QueueDictionary.cs
  64. 59 93
      Server/Base/Server.Base.csproj
  65. 0 35
      Server/Base/TryLocker.cs
  66. 16 0
      Server/Hotfix/Handler/Actor_TestHandler.cs
  67. 15 0
      Server/Hotfix/Handler/Actor_TestRequestHandler.cs
  68. 56 0
      Server/Hotfix/Handler/Actor_TransferHandler.cs
  69. 30 0
      Server/Hotfix/Handler/C2G_EnterMapHandler.cs
  70. 10 5
      Server/Hotfix/Handler/C2G_LoginGateHandler.cs
  71. 1 1
      Server/Hotfix/Handler/C2M_ReloadHandler.cs
  72. 10 10
      Server/Hotfix/Handler/C2R_LoginHandler.cs
  73. 0 0
      Server/Hotfix/Handler/C2R_PingHandler.cs
  74. 36 0
      Server/Hotfix/Handler/DBQueryBatchRequestHandler.cs
  75. 36 0
      Server/Hotfix/Handler/DBQueryJsonRequestHandler.cs
  76. 32 0
      Server/Hotfix/Handler/DBQueryRequestHandler.cs
  77. 39 0
      Server/Hotfix/Handler/DBSaveBatchRequestHandler.cs
  78. 33 0
      Server/Hotfix/Handler/DBSaveRequestHandler.cs
  79. 0 0
      Server/Hotfix/Handler/G2G_LockReleaseRequestHandler.cs
  80. 0 0
      Server/Hotfix/Handler/G2G_LockRequestHandler.cs
  81. 41 0
      Server/Hotfix/Handler/G2M_CreateUnitHandler.cs
  82. 1 1
      Server/Hotfix/Handler/M2A_ReloadHandler.cs
  83. 27 0
      Server/Hotfix/Handler/M2M_TrasferUnitRequest.cs
  84. 1 1
      Server/Hotfix/Handler/ObjectAddRequestHandler.cs
  85. 3 3
      Server/Hotfix/Handler/ObjectGetRequestHandler.cs
  86. 1 1
      Server/Hotfix/Handler/ObjectLockRequestHandler.cs
  87. 0 0
      Server/Hotfix/Handler/ObjectRemoveRequestHandler.cs
  88. 1 1
      Server/Hotfix/Handler/ObjectUnLockRequestHandler.cs
  89. 2 1
      Server/Hotfix/Handler/R2G_GetLoginKeyHandler.cs
  90. 15 0
      Server/Hotfix/Helper/HotfixHelper.cs
  91. 18 0
      Server/Hotfix/Helper/MessageHelper.cs
  92. 52 0
      Server/Hotfix/Other/EntityActorHandler.cs
  93. 57 0
      Server/Hotfix/Other/InnerMessageDispatcher.cs
  94. 40 0
      Server/Hotfix/Other/OuterMessageDispatcher.cs
  95. 0 35
      Server/Hotfix/Properties/AssemblyInfo.cs
  96. 17 64
      Server/Hotfix/Server.Hotfix.csproj
  97. 105 0
      Server/Hotfix/System/ActorComponentSystem.cs
  98. 45 0
      Server/Hotfix/System/NetInnerComponentSystem.cs
  99. 45 0
      Server/Hotfix/System/NetOuterComponentSystem.cs
  100. 5 5
      Server/Hotfix/System/RealmGateAddressComponentSystem.cs

+ 6 - 0
.gitignore

@@ -36,3 +36,9 @@ _ReSharper.CSharp/
 /.vs
 /Server/.vs/
 /Unity/.vs/
+/Tools/MongoDB
+/Excel/md5.txt
+/Release
+.idea/
+/Unity/Logs
+/netcoreapp2.0

+ 230 - 0
Client-Server.sln

@@ -0,0 +1,230 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.15
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Plugins", "Unity\Unity.Plugins.csproj", "{D1FDB199-0FB7-099D-3771-C6A942E4E326}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity", "Unity\Unity.csproj", "{CF118143-7E37-744F-BE45-3F55345FEC40}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Hotfix", "Unity\Hotfix\Unity.Hotfix.csproj", "{40533600-4E69-4F7D-A924-E1A3B4127255}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{914C77C9-212A-4DD0-8D9A-074620E77FAA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{46008B91-6EC0-448B-8D1A-D8C6D2EEBEF4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ThirdParty", "ThirdParty", "{78640FA0-9F11-412D-A639-61F03D02407A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ENet", "Server\ThirdParty\ENet\ENet.vcxproj", "{C9992B7C-313E-4C9F-A954-640D01EDFB58}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Editor", "Unity\Unity.Editor.csproj", "{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Editor.Plugins", "Unity\Unity.Editor.Plugins.csproj", "{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.App", "Server\App\Server.App.csproj", "{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.Base", "Server\Base\Server.Base.csproj", "{909B117C-7709-4F48-A142-40CE26FF99C9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.Model", "Server\Model\Server.Model.csproj", "{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.Hotfix", "Server\Hotfix\Server.Hotfix.csproj", "{C305ED5B-8425-47A1-BEE1-85830CADC27A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MongodbDriver", "MongodbDriver", "{4940CE10-6652-4AC6-9D30-CF200A217643}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDB.Bson", "Server\ThirdParty\MongodbDriver\DotNetCoreDriver\MongoDB.Bson\MongoDB.Bson.csproj", "{BC611535-3BDA-45C5-8765-9E242E312B8F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDB.Driver", "Server\ThirdParty\MongodbDriver\DotNetCoreDriver\MongoDB.Driver\MongoDB.Driver.csproj", "{6D19C1F8-085C-422E-8DAF-2E49024DB08C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDB.Driver.Core", "Server\ThirdParty\MongodbDriver\DotNetCoreDriver\MongoDB.Driver.Core\MongoDB.Driver.Core.csproj", "{831276B2-B7EB-4FD0-93E5-4D2109C78950}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Debug|x64.Build.0 = Debug|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Debug|x86.Build.0 = Debug|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Release|x64.ActiveCfg = Release|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Release|x64.Build.0 = Release|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Release|x86.ActiveCfg = Release|Any CPU
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326}.Release|x86.Build.0 = Release|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Debug|x64.Build.0 = Debug|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Debug|x86.Build.0 = Debug|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Release|x64.ActiveCfg = Release|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Release|x64.Build.0 = Release|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Release|x86.ActiveCfg = Release|Any CPU
+		{CF118143-7E37-744F-BE45-3F55345FEC40}.Release|x86.Build.0 = Release|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Debug|x64.Build.0 = Debug|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Debug|x86.Build.0 = Debug|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Release|Any CPU.Build.0 = Release|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Release|x64.ActiveCfg = Release|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Release|x64.Build.0 = Release|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Release|x86.ActiveCfg = Release|Any CPU
+		{40533600-4E69-4F7D-A924-E1A3B4127255}.Release|x86.Build.0 = Release|Any CPU
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Debug|Any CPU.ActiveCfg = Debug|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Debug|Any CPU.Build.0 = Debug|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Debug|x64.ActiveCfg = Debug|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Debug|x64.Build.0 = Debug|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Debug|x86.ActiveCfg = Debug|Win32
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Debug|x86.Build.0 = Debug|Win32
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Release|Any CPU.ActiveCfg = Release|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Release|Any CPU.Build.0 = Release|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Release|x64.ActiveCfg = Release|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Release|x64.Build.0 = Release|x64
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Release|x86.ActiveCfg = Release|Win32
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58}.Release|x86.Build.0 = Release|Win32
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Debug|x64.Build.0 = Debug|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Debug|x86.Build.0 = Debug|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Release|x64.ActiveCfg = Release|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Release|x64.Build.0 = Release|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Release|x86.ActiveCfg = Release|Any CPU
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}.Release|x86.Build.0 = Release|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Debug|x64.Build.0 = Debug|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Debug|x86.Build.0 = Debug|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Release|x64.ActiveCfg = Release|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Release|x64.Build.0 = Release|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Release|x86.ActiveCfg = Release|Any CPU
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}.Release|x86.Build.0 = Release|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Debug|x64.Build.0 = Debug|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Debug|x86.Build.0 = Debug|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Release|x64.ActiveCfg = Release|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Release|x64.Build.0 = Release|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Release|x86.ActiveCfg = Release|Any CPU
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8}.Release|x86.Build.0 = Release|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Debug|x64.Build.0 = Debug|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Debug|x86.Build.0 = Debug|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Release|x64.ActiveCfg = Release|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Release|x64.Build.0 = Release|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Release|x86.ActiveCfg = Release|Any CPU
+		{909B117C-7709-4F48-A142-40CE26FF99C9}.Release|x86.Build.0 = Release|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Debug|x64.Build.0 = Debug|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Debug|x86.Build.0 = Debug|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Release|x64.ActiveCfg = Release|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Release|x64.Build.0 = Release|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Release|x86.ActiveCfg = Release|Any CPU
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D}.Release|x86.Build.0 = Release|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Debug|x64.Build.0 = Debug|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Debug|x86.Build.0 = Debug|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Release|x64.ActiveCfg = Release|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Release|x64.Build.0 = Release|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Release|x86.ActiveCfg = Release|Any CPU
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A}.Release|x86.Build.0 = Release|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Debug|x64.Build.0 = Debug|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Debug|x86.Build.0 = Debug|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Release|x64.ActiveCfg = Release|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Release|x64.Build.0 = Release|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Release|x86.ActiveCfg = Release|Any CPU
+		{BC611535-3BDA-45C5-8765-9E242E312B8F}.Release|x86.Build.0 = Release|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Debug|x64.Build.0 = Debug|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Debug|x86.Build.0 = Debug|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Release|x64.ActiveCfg = Release|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Release|x64.Build.0 = Release|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Release|x86.ActiveCfg = Release|Any CPU
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C}.Release|x86.Build.0 = Release|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Debug|x64.Build.0 = Debug|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Debug|x86.Build.0 = Debug|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Release|Any CPU.Build.0 = Release|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Release|x64.ActiveCfg = Release|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Release|x64.Build.0 = Release|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Release|x86.ActiveCfg = Release|Any CPU
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{D1FDB199-0FB7-099D-3771-C6A942E4E326} = {914C77C9-212A-4DD0-8D9A-074620E77FAA}
+		{CF118143-7E37-744F-BE45-3F55345FEC40} = {914C77C9-212A-4DD0-8D9A-074620E77FAA}
+		{40533600-4E69-4F7D-A924-E1A3B4127255} = {914C77C9-212A-4DD0-8D9A-074620E77FAA}
+		{78640FA0-9F11-412D-A639-61F03D02407A} = {46008B91-6EC0-448B-8D1A-D8C6D2EEBEF4}
+		{C9992B7C-313E-4C9F-A954-640D01EDFB58} = {78640FA0-9F11-412D-A639-61F03D02407A}
+		{C17F48D3-964E-E97C-3D2E-966F7A6C6D93} = {914C77C9-212A-4DD0-8D9A-074620E77FAA}
+		{81A6E58E-BFF2-F1C8-1C4E-6316985F642C} = {914C77C9-212A-4DD0-8D9A-074620E77FAA}
+		{69F1AA11-D05A-4843-B0DD-56B5E2E212A8} = {46008B91-6EC0-448B-8D1A-D8C6D2EEBEF4}
+		{909B117C-7709-4F48-A142-40CE26FF99C9} = {46008B91-6EC0-448B-8D1A-D8C6D2EEBEF4}
+		{EE38E3D2-3D2A-4061-BD50-AE8568126C7D} = {46008B91-6EC0-448B-8D1A-D8C6D2EEBEF4}
+		{C305ED5B-8425-47A1-BEE1-85830CADC27A} = {46008B91-6EC0-448B-8D1A-D8C6D2EEBEF4}
+		{4940CE10-6652-4AC6-9D30-CF200A217643} = {78640FA0-9F11-412D-A639-61F03D02407A}
+		{BC611535-3BDA-45C5-8765-9E242E312B8F} = {4940CE10-6652-4AC6-9D30-CF200A217643}
+		{6D19C1F8-085C-422E-8DAF-2E49024DB08C} = {4940CE10-6652-4AC6-9D30-CF200A217643}
+		{831276B2-B7EB-4FD0-93E5-4D2109C78950} = {4940CE10-6652-4AC6-9D30-CF200A217643}
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {EABC01E3-3EB5-47EF-B46E-AAD8BB3585F1}
+	EndGlobalSection
+EndGlobal

+ 9 - 716
Server/Server.sln.DotSettings → Client-Server.sln.DotSettings

@@ -1,13 +1,8 @@
 <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
 	<s:String x:Key="/Default/CodeEditing/Intellisense/ClrSymbolsFilterFactory/StoredFilters/@EntryValue">&lt;root&gt;&lt;filter&gt;&lt;namespace_mask&gt;Boo&lt;/namespace_mask&gt;&lt;has_type_parameters&gt;Any&lt;/has_type_parameters&gt;&lt;element_kind&gt;Any&lt;/element_kind&gt;&lt;/filter&gt;&lt;/root&gt;</s:String>
 	<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/AutoCompleteBasicCompletion/@EntryValue">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/CompletionFilters/PersistFilterState/@EntryValue">True</s:Boolean>
-	
 	<s:String x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/NonCompletingCharacters/@EntryValue">&lt;&gt;</s:String>
-	
-	
 	<s:Boolean x:Key="/Default/CodeEditing/Localization/CSharpLocalizationOptions/DontAnalyseVerbatimStrings/@EntryValue">False</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Emin_002Ejs/@EntryIndexedValue">True</s:Boolean>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeThisQualifier/@EntryIndexedValue">DO_NOT_SHOW</s:String>
@@ -34,18 +29,11 @@
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedMember_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseNullPropagation/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">DO_NOT_SHOW</s:String>
-	
-	<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Unity/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Unity"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSRemoveCodeRedundancies&gt;True&lt;/CSRemoveCodeRedundancies&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;DISABLED&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;IMPLICIT_EXCEPT_SIMPLE_TYPES&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSMakeAutoPropertyGetOnly&gt;True&lt;/CSMakeAutoPropertyGetOnly&gt;&lt;CSUseAutoProperty&gt;True&lt;/CSUseAutoProperty&gt;&lt;RemoveCodeRedundancies&gt;True&lt;/RemoveCodeRedundancies&gt;&lt;/Profile&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Unity/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Unity"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSRemoveCodeRedundancies&gt;True&lt;/CSRemoveCodeRedundancies&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;DISABLED&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;IMPLICIT_EXCEPT_SIMPLE_TYPES&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSMakeAutoPropertyGetOnly&gt;True&lt;/CSMakeAutoPropertyGetOnly&gt;&lt;CSUseAutoProperty&gt;True&lt;/CSUseAutoProperty&gt;&lt;RemoveCodeRedundancies&gt;True&lt;/RemoveCodeRedundancies&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier="False" ArrangeTypeMemberAccessModifier="False" SortModifiers="True" RemoveRedundantParentheses="False" AddMissingParentheses="False" ArrangeAttributes="False" /&gt;&lt;/Profile&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">tanghai</s:String>
-	
-	
+	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/APPLY_ON_COMPLETION/@EntryValue">True</s:Boolean>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">All</s:String>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_FIRST_ARG_BY_PAREN/@EntryValue">True</s:Boolean>
-	
-	
-	
-	
-	
 	<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CONTINUOUS_INDENT_MULTIPLIER/@EntryValue">2</s:Int64>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_ATTRIBUTE_STYLE/@EntryValue">JOIN</s:String>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FIXED_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
@@ -54,14 +42,10 @@
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_IFELSE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_USING_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_WHILE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String>
-	
-	
-	
 	<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
 	<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">False</s:Boolean>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MODIFIERS_ORDER/@EntryValue">private public protected internal new abstract virtual override sealed static readonly extern unsafe volatile async</s:String>
-	
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_WHILE_ON_NEW_LINE/@EntryValue">True</s:Boolean>
@@ -73,8 +57,6 @@
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_DECLARATION_LPAR/@EntryValue">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_FIRST_TYPE_PARAMETER_CONSTRAINT/@EntryValue">True</s:Boolean>
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_FOR_STMT_HEADER_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
 	<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">150</s:Int64>
@@ -87,7 +69,6 @@
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/XmlFormatter/TagAttributeIndenting/@EntryValue">TwoSteps</s:String>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/XmlFormatter/TagSpaceBeforeHeaderEnd1/@EntryValue">False</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/XmlFormatter/WrapBeforeAttr/@EntryValue">False</s:Boolean>
-	
 	<s:String x:Key="/Default/CodeStyle/CSharpMemberOrderPattern/CustomPattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-8" ?&gt;&#xD;
 &#xD;
 &lt;!--&#xD;
@@ -313,16 +294,17 @@ II.2.12 &lt;HandlesEvent /&gt;&#xD;
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/EventHandlerPatternLong/@EntryValue">$object$_On$event$</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
-	
 	<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Position/@EntryValue">BOTH_SIDES</s:String>
-	
-	
-	
-	
+	<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=AAEDA4BE1B62904F98E5EA2E32B739DB/@KeyIndexDefined">True</s:Boolean>
+	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=AAEDA4BE1B62904F98E5EA2E32B739DB/AbsolutePath/@EntryValue">D:\Source\Egametang\Unity\Unity.sln.DotSettings</s:String>
+	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=AAEDA4BE1B62904F98E5EA2E32B739DB/RelativePath/@EntryValue"></s:String>
+	<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileAAEDA4BE1B62904F98E5EA2E32B739DB/@KeyIndexDefined">True</s:Boolean>
+	<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileAAEDA4BE1B62904F98E5EA2E32B739DB/RelativePriority/@EntryValue">1</s:Double>
 	<s:Boolean x:Key="/Default/Environment/OpenDocument/OpenDocumentAfterModification/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/AutoExpandResults/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/MergeOccurences/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/OpenPreviewTabForSelectedItemInFindResults/@EntryValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpFileLayoutPatternsUpgrade/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
@@ -602,984 +584,295 @@ II.2.12 &lt;HandlesEvent /&gt;&#xD;
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/ConflictingActions/=UnitTestSession_002ERepeatPreviousRun/Shortcuts/=Control_002BU_0020Control_002BU/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/ConflictingActions/=UnitTestSession_002ERepeatPreviousRun/Shortcuts/=Control_002BU_0020U/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Add/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BBack/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF10/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF2/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF3/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF4/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF5/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF6/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF8/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BF9/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BG/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BM/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BMultiply/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BNext/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BO/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BOem7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BOemcomma/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BOemPeriod/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BP/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BPageUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BPause/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BR/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BReturn/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BS/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BSubtract/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Alt_002BW/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=B/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Back/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BA/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAdd/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BA/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BB/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BC/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BD/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BE/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF1/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF10/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF5/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BF6/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BG/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BH/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BI/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BInsert/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BJ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BL/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BM/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BNext/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BO/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BOem6/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BOemPeriod/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BP/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BPageUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BPause/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BQ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BR/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BS/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BSpace/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BT/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BU/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BV/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BW/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BX/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BY/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BAlt_002BZ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BB/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BBack/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BC/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD1/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD2/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD3/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD4/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD5/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD6/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD8/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BD9/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BDelete/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BDivide/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BE/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BEnd/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF1/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF10/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF2/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF4/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF5/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF6/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BF9/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BG/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BH/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BHome/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BI/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BInsert/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BJ/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BK/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BL/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BM/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BN/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BNext/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BO/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOem1/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOem6/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOem7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOemBackslash/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOemcomma/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOemOpenBrackets/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOemPeriod/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BOemplus/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BP/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BPageUp/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BPause/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BQ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BR/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BReturn/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BS/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BSpace/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BSubtract/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BT/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BTab/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BU/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BV/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BW/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BX/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BY/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Control_002BZ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Delete/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Down/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=End/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Escape/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F1/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F10/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F12/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F2/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F4/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F5/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F6/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F8/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=F9/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Home/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=I/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Insert/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Left/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Next/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=O/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=PageUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Return/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Right/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BA/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BB/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BBack/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BC/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BD/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BD3/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BD4/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BEnd/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BF/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BF10/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BF6/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BF7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BH/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BHome/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BL/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BN/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BOemcomma/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BOemPeriod/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BP/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BQ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BR/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BReturn/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BS/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BT/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BV/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BAlt_002BW/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BBack/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BA/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BC/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BP/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BR/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BS/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BAlt_002BW/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BB/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BC/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BD/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BD1/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BD2/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BD3/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BD7/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BD8/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BE/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BEnd/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BF10/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BF5/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BF6/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BF9/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BG/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BH/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BHome/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BI/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BInsert/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BJ/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BL/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BM/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BN/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BNext/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BO/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BOem6/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BOemcomma/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BOemOpenBrackets/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BOemPeriod/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BP/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BPageUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BR/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BReturn/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BS/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BSpace/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BSubtract/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BT/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BTab/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BU/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BV/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BW/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BX/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BY/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BControl_002BZ/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BDelete/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BDown/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BEnd/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BEscape/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF1/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF11/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF12/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF4/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF5/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF6/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF7/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF8/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BF9/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BHome/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BInsert/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BLeft/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BNext/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BPageUp/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BReturn/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BRight/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BSpace/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BTab/@KeyIndexDefined">True</s:Boolean>
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Shift_002BUp/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Subtract/@KeyIndexDefined">True</s:Boolean>
-	
 	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Tab/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Up/@KeyIndexDefined">True</s:Boolean>
-	
-	
-	</wpf:ResourceDictionary>
+	<s:Boolean x:Key="/Default/Housekeeping/VsActionManager/KeyboardShortcutToVsCommand/=Up/@KeyIndexDefined">True</s:Boolean></wpf:ResourceDictionary>

+ 13 - 0
Client-Server.sln.DotSettings.user

@@ -0,0 +1,13 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+	<s:String x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntelliSenseCompletingCharacters/CSharpCompletingCharacters/NonCompletingCharacters/@EntryValue"></s:String>
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AC2G_005FEnterMapHandler_002Ecs_002Fl_003AServer_003FHotfix_003FHandler_003FC2G_005FEnterMapHandler_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInnerOpcode_002Ecs_002Fl_003AServer_003FModel_003FEntity_003FMessage_003FInnerOpcode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APlayer_002Ecs_002Fl_003AUnity_003FAssets_003FScripts_003FEntity_003FPlayer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APlayerComponent_002Ecs_002Fl_003AUnity_003FAssets_003FScripts_003FComponent_003FPlayerComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APlayerFactory_002Ecs_002Fl_003AUnity_003FAssets_003FScripts_003FFactory_003FPlayerFactory_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUnitComponent_002Ecs_002Fl_003AUnity_003FAssets_003FScripts_003FComponent_003FUnitComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+	<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Unity/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Unity"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSRemoveCodeRedundancies&gt;True&lt;/CSRemoveCodeRedundancies&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;DISABLED&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;IMPLICIT_EXCEPT_SIMPLE_TYPES&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSMakeAutoPropertyGetOnly&gt;True&lt;/CSMakeAutoPropertyGetOnly&gt;&lt;CSUseAutoProperty&gt;True&lt;/CSUseAutoProperty&gt;&lt;RemoveCodeRedundancies&gt;True&lt;/RemoveCodeRedundancies&gt;&lt;CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" /&gt;&lt;/Profile&gt;</s:String>
+	<s:String x:Key="/Default/Housekeeping/Layout/DialogWindows/RefactoringWizardWindow/Location/@EntryValue">247,-4</s:String>
+	<s:Int64 x:Key="/Default/Environment/SearchAndNavigation/DefaultOccurrencesGroupingIndex/@EntryValue">0</s:Int64>
+	<s:String x:Key="/Default/Profiling/Configurations/=1/@EntryIndexedValue">&lt;data&gt;&lt;HostParameters type="LocalHostParameters" /&gt;&lt;Argument type="StandaloneArgument"&gt;&lt;Arguments IsNull="False"&gt;&lt;/Arguments&gt;&lt;FileName IsNull="False"&gt;&lt;/FileName&gt;&lt;WorkingDirectory IsNull="False"&gt;&lt;/WorkingDirectory&gt;&lt;Scope&gt;&lt;ProcessFilters /&gt;&lt;/Scope&gt;&lt;/Argument&gt;&lt;Info type="TimelineInfo" /&gt;&lt;HostOptions type="HostOptions"&gt;&lt;HostTempPath IsNull="False"&gt;&lt;/HostTempPath&gt;&lt;/HostOptions&gt;&lt;/data&gt;</s:String>
+	</wpf:ResourceDictionary>

BIN
Config/BuffConfig.txt


+ 9 - 6
Config/StartConfig/127.0.0.1.txt

@@ -1,6 +1,9 @@
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "127.0.0.1", "Port" : 20000 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "127.0.0.1", "Port" : 10000 }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "*" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "127.0.0.1", "Port" : 20001 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "127.0.0.1", "Port" : 10001 }], "AppId" : 2, "AppType" : "Realm", "ServerIP" : "*" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "127.0.0.1", "Port" : 20002 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "127.0.0.1", "Port" : 10002 }], "AppId" : 3, "AppType" : "Gate", "ServerIP" : "*" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "127.0.0.1", "Port" : 20003 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "127.0.0.1", "Port" : 10003 }], "AppId" : 4, "AppType" : "Gate", "ServerIP" : "*" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "127.0.0.1", "Port" : 20004 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "127.0.0.1", "Port" : 10004 }], "AppId" : 5, "AppType" : "Gate", "ServerIP" : "*" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "127.0.0.1", "Port" : 20005 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "127.0.0.1", "Port" : 10005 }], "AppId" : 6, "AppType" : "Gate", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20000 }, { "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10000, "Host2" : null }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98565862653976"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 10001 }], "AppId" : 2, "AppType" : "Location", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20001 }, { "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10002, "Host2" : null }], "AppId" : 3, "AppType" : "Realm", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20002 }, { "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10003, "Host2" : null }], "AppId" : 4, "AppType" : "Gate", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20003 }, { "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10004, "Host2" : null }], "AppId" : 5, "AppType" : "Gate", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20004 }, { "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10005, "Host2" : null }], "AppId" : 6, "AppType" : "Gate", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20005 }, { "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10006, "Host2" : null }], "AppId" : 7, "AppType" : "Gate", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98565723062316"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20006 }], "AppId" : 8, "AppType" : "Map", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98565723062316"), "components" : [{ "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20007 }], "AppId" : 9, "AppType" : "Map", "ServerIP" : "*" }

+ 6 - 6
Config/StartConfig/192.168.12.112.txt

@@ -1,6 +1,6 @@
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.12.112", "Port" : 20000 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.12.188", "Port" : 10000 }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "192.168.12.112" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.12.112", "Port" : 20001 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.12.188", "Port" : 10001 }], "AppId" : 2, "AppType" : "Realm", "ServerIP" : "192.168.12.112" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.12.112", "Port" : 20002 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.12.188", "Port" : 10002 }], "AppId" : 3, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.12.112", "Port" : 20003 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.12.188", "Port" : 10003 }], "AppId" : 4, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.12.112", "Port" : 20004 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.12.188", "Port" : 10004 }], "AppId" : 5, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.12.112", "Port" : 20005 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.12.188", "Port" : 10005 }], "AppId" : 6, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.12.112", "Port" : 20000 }, { "_t" : "OuterConfig", "Host" : "192.168.12.188", "Port" : 10000, "Host2" : null }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "192.168.12.112" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.12.112", "Port" : 20001 }, { "_t" : "OuterConfig", "Host" : "192.168.12.188", "Port" : 10001, "Host2" : null }], "AppId" : 2, "AppType" : "Realm", "ServerIP" : "192.168.12.112" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.12.112", "Port" : 20002 }, { "_t" : "OuterConfig", "Host" : "192.168.12.188", "Port" : 10002, "Host2" : null }], "AppId" : 3, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.12.112", "Port" : 20003 }, { "_t" : "OuterConfig", "Host" : "192.168.12.188", "Port" : 10003, "Host2" : null }], "AppId" : 4, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.12.112", "Port" : 20004 }, { "_t" : "OuterConfig", "Host" : "192.168.12.188", "Port" : 10004, "Host2" : null }], "AppId" : 5, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.12.112", "Port" : 20005 }, { "_t" : "OuterConfig", "Host" : "192.168.12.188", "Port" : 10005, "Host2" : null }], "AppId" : 6, "AppType" : "Gate", "ServerIP" : "192.168.12.112" }

+ 6 - 6
Config/StartConfig/192.168.9.182.txt

@@ -1,6 +1,6 @@
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.9.182", "Port" : 20000 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.9.182", "Port" : 10000 }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "192.168.9.182" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.9.182", "Port" : 20001 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.9.182", "Port" : 10001 }], "AppId" : 2, "AppType" : "Realm", "ServerIP" : "192.168.9.182" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.9.182", "Port" : 20002 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.9.182", "Port" : 10002 }], "AppId" : 3, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.9.182", "Port" : 20003 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.9.182", "Port" : 10003 }], "AppId" : 4, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.9.182", "Port" : 20004 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.9.182", "Port" : 10004 }], "AppId" : 5, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832366182402"), "Host" : "192.168.9.182", "Port" : 20005 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832366182403"), "Host" : "192.168.9.182", "Port" : 10005 }], "AppId" : 6, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.9.182", "Port" : 20000 }, { "_t" : "OuterConfig", "Host" : "192.168.9.182", "Port" : 10000, "Host2" : null }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "192.168.9.182" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.9.182", "Port" : 20001 }, { "_t" : "OuterConfig", "Host" : "192.168.9.182", "Port" : 10001, "Host2" : null }], "AppId" : 2, "AppType" : "Realm", "ServerIP" : "192.168.9.182" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.9.182", "Port" : 20002 }, { "_t" : "OuterConfig", "Host" : "192.168.9.182", "Port" : 10002, "Host2" : null }], "AppId" : 3, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.9.182", "Port" : 20003 }, { "_t" : "OuterConfig", "Host" : "192.168.9.182", "Port" : 10003, "Host2" : null }], "AppId" : 4, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.9.182", "Port" : 20004 }, { "_t" : "OuterConfig", "Host" : "192.168.9.182", "Port" : 10004, "Host2" : null }], "AppId" : 5, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }
+{ "_t" : "StartConfig", "_id" : NumberLong("96832366182401"), "components" : [{ "_t" : "InnerConfig", "Host" : "192.168.9.182", "Port" : 20005 }, { "_t" : "OuterConfig", "Host" : "192.168.9.182", "Port" : 10005, "Host2" : null }], "AppId" : 6, "AppType" : "Gate", "ServerIP" : "192.168.9.182" }

+ 2 - 2
Config/StartConfig/Benchmark.txt

@@ -1,2 +1,2 @@
-{ "_t" : "StartConfig", "_id" : NumberLong("96832337674244"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96832337674245"), "Host" : "127.0.0.1", "Port" : 20000 }, { "_t" : "OuterConfig", "_id" : NumberLong("96832337674246"), "Host" : "127.0.0.1", "Port" : 10000 }], "AppId" : 1, "AppType" : "AllServer", "ServerIP" : "*" }
-{ "_t" : "StartConfig", "_id" : NumberLong("96866810789911"), "components" : [{ "_t" : "ClientConfig", "_id" : NumberLong("96866810789912"), "Host" : "127.0.0.1", "Port" : 10000 }], "AppId" : 2, "AppType" : "Benchmark", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98808811814943"), "components" : [{ "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10000, "Host2" : null }, { "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20000 }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98808818892845"), "components" : [{ "_t" : "ClientConfig", "Host" : "127.0.0.1", "Port" : 10000 }], "AppId" : 2, "AppType" : "Benchmark", "ServerIP" : "*" }

+ 2 - 0
Config/StartConfig/BenchmarkClient.txt

@@ -0,0 +1,2 @@
+{ "_t" : "StartConfig", "_id" : NumberLong("98813417750535"), "components" : [{ "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10000, "Host2" : null }, { "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20003 }], "AppId" : 1, "AppType" : "Manager", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98813420503048"), "components" : [{ "_t" : "ClientConfig", "Host" : "127.0.0.1", "Port" : 10002 }], "AppId" : 2, "AppType" : "Benchmark", "ServerIP" : "*" }

+ 1 - 1
Config/StartConfig/LocalAllServer.txt

@@ -1 +1 @@
-{ "_t" : "StartConfig", "_id" : NumberLong("96871765901315"), "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("96871765901316"), "Host" : "127.0.0.1", "Port" : 20000 }, { "_t" : "OuterConfig", "_id" : NumberLong("96871765901317"), "Host" : "127.0.0.1", "Port" : 10001 }], "AppId" : 1, "AppType" : "AllServer", "ServerIP" : "*" }
+{ "_t" : "StartConfig", "_id" : NumberLong("98547768819754"), "components" : [{ "_t" : "OuterConfig", "Host" : "127.0.0.1", "Port" : 10002, "Host2" : null }, { "_t" : "InnerConfig", "Host" : "127.0.0.1", "Port" : 20000 }, { "_t" : "HttpConfig", "Url" : "", "AppId" : 0, "AppKey" : "", "ManagerSystemUrl" : "" }, { "_t" : "DBConfig", "ConnectionString" : null, "DBName" : null }], "AppId" : 1, "AppType" : "AllServer", "ServerIP" : "*" }

+ 85 - 0
Doc/组件设计.md

@@ -0,0 +1,85 @@
+# 组件设计
+
+在代码复用和组织数据方面,面向对象可能是大家第一反应。面向对象三大特性继承,封装,多态,在一定程度上能解决不少代码复用,数据复用的问题。不过面向对象不是万能的,它也有极大的缺陷:
+### 1. 数据组织耦合性及强
+一旦父类中增加或删除某个字段,可能要影响到所有子类,影响到所有子类相关的逻辑。这显得非常不灵活,在一套复杂的继承体系中,往父类中改变字段会变得越来越麻烦,比方说ABC是D的子类,某天发现需要增加一个AB都有的数据,但是C没有,那么这个数据肯定不好放到父类中,只能将AB抽象出来一个父类E,E继承于D,AB共有的字段加到E中,一旦继承结构发生了变化,可能接口也要改变,比方说之前有个接口传入参数类型是E,当AB不在需要共用的那个字段,那么需要调整继承关系,让AB重新继承D,那么这个接口的传入参数类型需要改成D,其中的逻辑代码很可能也要发生调整。更可怕的是游戏逻辑变化非常复杂,非常频繁,可能今天加了个字段,明天又删掉了,假如每次都要去调整继承结构,这简直就是噩梦。继承结构面对频繁的数据结构调整感觉很无力。还有个严重的问题,继承结构无法运行时增加删除字段,比如玩家Player平常是走路,使用坐骑后就骑马。问题是坐骑的相关信息就需要一直挂在Player对象上面。这就显得很不灵活,我不骑马的时候内存中为啥要有马的数据?
+### 2. 接口逻辑难以复用,难以热插拔。
+面向对象处理相同行为所使用的方法是继承相同的父类或者接口。问题是接口并没有实现代码,而是需要其子类自己去写相关实现。很显然相同的功能,每个子类都可能写一份相似的代码。这导致接口的实现代码无法复用。还有个问题,一个类实现了一个接口,那么这个接口就永远粘在了这个类身上,你想甩掉她都不行,还是以骑马为例,玩家Player可以进行骑行,那么可能继承一个骑行的接口,问题是,当我这个Player从坐骑上下来时,玩家Player身上还是有骑行的接口,根本没法动态删掉这个接口!可能例子举得不是很对,但是道理表述的应该很清楚了。
+### 3. 使用面向对象可能导致灾难性后果
+游戏开发中有新人有老人,有技术好的,有技术差的。人都是喜欢偷懒的,当你发现调整继承关系麻烦的时候,有可能AB中增加一个字段为了省事直接就放到父类D中去了。导致C莫名奇妙的多了一个无用的字段。关键还没法发现,最后导致父类D越来越大,到最后有可能干脆就不用ABC了,直接让所有对象都变成D,方便嘛!是的,很多游戏就是这么干的,开发到最后根本就不管继承关系了,因为想管也管不了了。    
+  
+面向对象在面对复杂的游戏逻辑时会很无力,所以很多游戏开发者又倒退了回去,使用面向过程进行开发游戏,面向过程,简单粗暴,不考虑复杂的继承,不考虑抽象,不考虑多态,是开发届的freestyle,挽起袖子就开撸,但同时,代码逻辑的复用性,数据的复用性也大大降低。面向过程也不是一种好的游戏开发模式。
+
+组件模式很好的解决了面向对象以及面向过程的种种缺陷,在游戏客户端中使用非常广泛,Unity3d,虚幻4,等等都使用了组件模式。组件模式的特点:
+1.高度模块化,一个组件就是一份数据加一段逻辑
+2.组件可热插拔,需要就加上,不需要就删除
+3.类型之间依赖极少,任何类型增加或删除组件不会影响到其它类型。
+
+目前只有极少有服务端使用了组件的设计,守望先锋服务端应该是使用了组件的设计,守望先锋的开发人员称之为ECS架构,其实就是组件模式的一个变种,E就是Entity,C就是Component,S是System,其实就是将组件Component的逻辑与数据剥离,逻辑部分叫System,话题扯远了,还是回到ET框架来把。
+
+ET框架使用了组件的设计。一切都是Entity和Component,任何对象继承于Entity都可以挂载组件,例如玩家对象:
+```C#
+public sealed class Player : Entity
+{
+	public string Account { get; private set; }
+	public long UnitId { get; set; }
+	
+	public void Awake(string account)
+	{
+		this.Account = account;
+	}
+	
+	public override void Dispose()
+	{
+		if (this.Id == 0)
+		{
+			return;
+		}
+		base.Dispose();
+	}
+}
+```
+给玩家对象挂载个移动组件MoveComponent,这样玩家就可以移动了,给玩家挂上一个背包组件,玩家就可以管理物品了,给玩家挂上技能组件,那么玩家就可以施放技能了,加上Buff组件就可以管理buff了。
+```C#
+player.AddComponent<MoveComponent>();
+player.AddComponent<ItemsComponent>();
+player.AddComponent<SpellComponent>();
+player.AddComponent<BuffComponent>();
+```
+组件是高度可以复用的,比如一个NPC,他也可以移动,给NPC也挂上MoveComponent就行了,有的NPC也可以施放技能,那么给它挂上SpellComponent,NPC不需要背包,那么就不用挂ItemsComponent了
+
+ET框架模块全部做成了组件的形式,一个进程也是由不同的组件拼接而成。比方说Loginserver需要对外连接也需要与服务器内部进行连接,那么login server挂上
+```C#
+// 内网网络组件NetInnerComponent,处理对内网连接
+Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
+// 外网网络组件NetOuterComponent,处理与客户端连接
+Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
+```
+比如battle server就不需要对外网连接(外网消息由gateserver转发),那么很自然的只需要挂载一个内网组件即可。
+```C#
+// 内网网络组件NetInnerComponent处理对内网连接
+Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
+```
+类似Unity3d的组件,ET框架也提供了组件事件,例如Awake,Start,Update等。要给一个Component或者Entity加上这些事件,必须写一个辅助类。比如NetInnerComponent组件需要Awake跟Update方法,那么添加一个这样的类即可:
+```C#
+	[ObjectEvent]
+	public class NetInnerComponentEvent : ObjectEvent<NetInnerComponent>, IAwake, IUpdate
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+
+		public void Update()
+		{
+			this.Get().Update();
+		}
+	}
+```
+这样,NetInnerComponent在AddComponent之后会调用其Awake方法,并且每帧调用Update方法。
+ET没有像Unity使用反射去实现这种功能,反射性能比较差,而且这样实现的好处是这个类可以放到热更dll中,这样组件的Awake Start,Update方法以及其它方法都可以放到热更层中。只有数据放在model层,方便热更修复逻辑bug。
+
+组件式开发最大的好处就是不管菜鸟还是高手,开发一个功能都能很快的知道怎么组织数据怎么组织逻辑。可以完全放弃面向对象。使用面向对象开发最头疼的就是我该继承哪个类呢?之前做过最恐怖的就是虚幻三,虚幻三的继承结构非常多层,完全不知道自己需要从哪里开始继承。最后可能导致一个非常小的功能,继承了一个及其巨大的类,这在虚幻三开发中屡见不鲜。所以虚幻4改用了组件模式。组件模式的模块隔离性非常好,技术菜鸟某个组件写得非常差,也不会影响到其它模块,大不了重写这个组件就好了。
+
+
+

+ 131 - 0
Doc/网络层设计.md

@@ -0,0 +1,131 @@
+# 网络层设计
+
+ET框架提供了一个比较强大的网络消息层,发送消息订阅消息都及其方便,非常清晰简单。
+
+#### 1.普通消息的发送
+主要有两个组件,NetOuterComponent处理客户端的连接,NetInnerComponent处理服务端内部的连接
+这两个组件可以根据地址获取连接,每个连接都封装成了一个Session对象,Session对象有两个方法用来发送消息:
+``` C#
+// 根据地址创建或者获取一个连接
+Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(innerAddress);
+
+// 只发送不等待返回
+session.Send(new R2G_GetLoginKey());
+
+// 发送R2G_GetLoginKey消息,并且等待消息返回一个G2R_GetLoginKey消息
+G2R_GetLoginKey g2RGetLoginKey = await session.Call<G2R_GetLoginKey>(new R2G_GetLoginKey() {Account = "zhangsan"});
+Log.Debug("打印响应的消息内容: " + g2RGetLoginKey.ToJson())
+```
+由于C#强大的async await语法,ET框架发送rpc消息显得非常简洁,发送前后逻辑得以连贯,不用拆成两段逻辑,正因为这个特性,C#非常适合写分布式框架,因 为其实分布式无非就是进程间网络消息的处理。假如没有这个功能,你想想,发送消息写在一个地方,你还得订阅一个返回消息处理,两块代码就不连贯。更可怕的是连续多个rpc请求:
+``` C#
+// 客户端发送帐号密码给login server验证,并且等待login响应消息返回,login会分配一个网关给客户端
+R2C_Login r2CLogin = await session.Call<R2C_Login>(new C2R_Login() { Account = "a", Password = "b" });
+// 客户端连接网关
+Session gateSession = Game.Scene.GetComponent<NetOuterComponent>().Create(r2CLogin.Address);
+// 客户端发送消息给网关,等待网关验证返回
+G2C_LoginGate g2CLoginGate = await gateSession.Call<G2C_LoginGate>(new C2G_LoginGate(r2CLogin.Key));
+Log.Info("登陆gate成功!");
+// 获取玩家的物品信息
+G2C_Items items = await gateSession.Call<G2C_Items>(new C2G_Items());
+```
+可以看到登录完loginserver,立即登录gateserver,登录完成后又查询了玩家的物品信息,整个流程看起来非常连贯,假如没有async await,这段代码就得拆成至少4块放到4个函数中。分布式服务器连续rpc调用非常多,没有async await这种协程的语法支持是不可想像的。所以有人用nodejs,java写游戏服务器,我是无法理解的,写单服还可以,写分布式服务器,呵呵!
+#### 2.普通消息订阅
+上面是发送消息,服务器怎么订阅处理某个消息呢?非常简洁:
+```C#
+// 处理login rpc消息,并且返回response
+[MessageHandler(AppType.Login)]
+public class C2R_LoginHandler : AMRpcHandler<C2R_Login, R2C_Login>
+{
+	protected override async void Run(Session session, C2R_Login message, Action<R2C_Login> reply)
+	{
+		R2C_Login response = new R2C_Login();
+		try
+		{
+			Log.Debug(message.ToJson());
+			reply(response);
+		}
+		catch (Exception e)
+		{
+			ReplyError(response, e, reply);
+		}
+	}
+}
+```
+rpc消息只需要在hotfix dll中加个类,类继承于AMRpcHandler,实现虚方法即可,ET使用了声明式订阅消息的手法,一个rpc消息处理类,只需要加上MessageHandlerAttribute就可以自动被框架发现并且注册到框架中,并不需要手动用函数去注册。上面这个类MessageHandlerAttribute设置了AppType.Login,这个参数表示只有Login服务器才会注册这个rpc处理类。是不是非常简单呢?同样的,注册非rpc消息,只需要添加一个类继承于AMHandler即可。整个消息处理类不会包含任何状态,所以是可以热更新的。
+
+#### 3.actor消息发送
+ET框架还提供了类似Erlang语言的分布式消息机制,不管对象在任何进程,只需要挂载ActorComponent组件,任何进程都可以拿着这个对象的id,向这个对象发送消息,消息会发送到该对象所在的进程并且交给该对象处理。发送Actor消息与普通消息不同, 要发送actor消息,server必须挂上ActorProxyComponent组件:
+```c#
+// 从ActorProxyComponent组件中获取actorproxy
+ActorProxy actorProxy = Game.Scene.GetComponent<ActorProxyComponent>().Get(id);
+// 向对象发送消息
+actorProxy.Send(new Actor_Test());
+// 向对象发送rpc消息
+ActorRpc_TestResponse response = await actorProxy.Call<ActorRpc_TestResponse>(ActorRpc_TestRequest());
+```
+
+#### 4.actor订阅处理
+订阅actor消息与普通消息类似,只需要继承AMActorHandler,并且加上ActorMessageHandler的标签。有点不同的是AMActorHandler需要提供Actor的类型,例如下面这个actor消息它是发给Player对象的
+```c#
+[ActorMessageHandler(AppType.Map)]
+public class Actor_TestHandler : AMActorHandler<Player, Actor_Test>
+{
+	protected override async Task<bool> Run(Player player, Actor_Test message)
+	{
+		Log.Debug(message.Info);
+
+		player.GetComponent<UnitGateComponent>().GetActorProxy().Send(message);
+		return true;
+	}
+}
+```
+同样订阅ActorRpc消息,需要继承AMActorRpcHandler,同样使用reply返回响应消息。
+```c#
+[ActorMessageHandler(AppType.Map)]
+public class ActorRpc_TestRequestHandler : AMActorRpcHandler<Player, ActorRpc_TestRequest, ActorRpc_TestResponse>
+{
+	protected override async Task<bool> Run(Player entity, ActorRpc_TestRequest message, Action<ActorRpc_TestResponse> reply)
+	{
+		reply(new ActorRpc_TestResponse() {response = "response actor rpc"});
+		return true;
+	}
+}
+```
+
+#### 5.rpc消息的异常处理
+ET框架消息层提供了强大的异常处理机制,所有rpc响应消息都继承与AResponse,AResponse带有error跟错误信息,
+```
+public abstract class AResponse: AMessage
+{
+	public uint RpcId;
+	public int Error = 0;
+	public string Message = "";
+}
+```
+可以捕获RpcException异常,通过ErrorCode做不同的异常处理,比方说客户端登录:
+```
+try
+{
+	R2C_Login r2CLogin = await session.Call<R2C_Login>(new C2R_Login() { Account = "a", Password = "b" });
+}
+catch (RpcException e)
+{
+	if (e.Error == ErrorCode.ERR_AccountNotFound)
+	{
+		Log.Debug("帐号不存在");
+		return;
+	}
+	if (e.Error == ErrorCode.PasswordError;)
+	{
+		Log.Debug("密码错误");
+		return;
+	}
+}
+```
+ET框架最方便的是异常信息会跨进程传递,比如,A进程向B进程发起了Rpc请求,B进程在响应之前需要请求C,C进程响应B之前需要请求D,结果,D进程在处理过程中发生了一个异常,这个异常会从D->C->B->A, A进程在try catch中捕获了这个异常,这个异常会带有BCD整个过程的堆栈信息,查分布式异常bug会变得非常简单。
+
+#### 总结
+本文详细介绍了ET框架的网络层使用,ET框架提供了非常完善的分布式网络层,强大的分布式异常处理机制。因为协程的使用,ET发送消息以及远程调用及其简单方便,做分布式开发就跟开发单机一样方便。
+
+
+

+ 27 - 0
Doc/运行指南.md

@@ -0,0 +1,27 @@
+##### 1.visual studio必须使用vs2017,其它版本不支持,VS2017需要勾选安装以下内容:
+.net 桌面开发   
+使用C++的桌面开发,VC++ 2017 v141工具集,对C++的xp支持  
+visual studio tools for unity  .netcore2.0
+##### 2. unity一定要安装 unity 2017.1.0p5到2017.1.2,其它版本不支持
+
+##### 3. 启动unity2017, 菜单 File->open project->open 选中Egametang/Unity文件夹,点击选择文件夹按钮。
+
+##### 4.用vs2017打开Egametang/Unity/Unity.sln 编译(一定要编译,右键VS解决方案,全部编译)
+
+##### 5.用vs2017打开Egametang/Server/Server.sln 编译(一定要编译,右键VS解决方案,全部编译)
+
+##### 6.打开Unity->tools菜单->命令行配置,选择LocalAllServer.txt 这是启动单一App的方式,如果要启动一组多App服务器,在命令行工具中选择127.0.0.1.txt,点击启动即可,具体配置都可以自己用这个命令行配置工具修改
+##### 7.点击工具中的启动,这样就启动了服务端(也可以用VS启动,方便单步调试)
+##### 8.运行Unity,输入帐号,点击登录这时日志 连接Gate成功,表示运行OK!
+  
+## 测试帧同步  
+##### 1. Unity->tools菜单->打包->PC打包, 打出一个PC包在Release目录下
+##### 2. 运行Unity 登录 进入大厅 进入场景
+##### 3. 运行PC包 登录 进入大厅   这时会出现两个小人(重叠在一起)
+##### 4. 点击鼠标右键即可移动人物
+
+# 注意事项:
+VS2017 15.4版本有bug,会提示Hotfix找不到Assembly-CSharp.dll,需要将Hotfix工程引用的Unity跟Unity.Plugin去掉,直接引用这两个工程生成的dll。  
+
+一般出错原因都是 1.没编译。2.中文目录。3.vs没有安装vs tools或者不是最新的vs tools。4.没安装.netcore2.0
+

BIN
Excel/UnitConfig.xlsx


+ 0 - 28
README

@@ -1,28 +0,0 @@
-2017-4-17: IOS il2cpp p/invoke调用有很多bug,必须修改代码绕过去,增加了安卓和ios使用的enet库,安卓和ios都测试通过,方便大家使用
-
-2017-3-30: unity升级到5.5.2,增加vs调试启动参数,很多人问我,所以加上去了。增加主线程同步上下文,mongodb异步函数就能回调到主线程
-
-2017-2-17: 使用ILRuntime提供Unity C#代码热更新支持,并且抹平了Mono层和ILRuntime层差异,使用起来风格与原来用法保持一致, 扔掉你的lua代码吧!
-
-
-ET框架:一个Unity客户端和分布式游戏服务器框架
-
-无缝大世界功能正在开发
-
-01.客户端服务端共用代码
-02.服务器使用组件设计,一切皆是组件
-03.单APP设计,各种服务器都是一个同样的App,在启动时根据命令行的AppType,不同的服务器挂载不同的逻辑组件,挂载不同的消息handler,挂载不同的配置
-04.跨平台设计,既可以在windows上跑,也可以在linux上跑,windows用vs开发方便单步调试
-05.框架支持不停服重新加载逻辑dll,也就是服务器热更新
-06.一行配置即可将所有种类服务器集中到一个进程中,开发时,只需要启动一个进程,不用再启动一堆的服务进程
-07.及其方便检查CPU占用和内存泄漏检查,vs自带分析工具,不用再为性能和内存泄漏检查而烦恼
-08.提供及其方便的网络rpc调用,使用async await语法的异步rpc
-09.使用NLog库,打log及其方便,开发时,可以将所有服务器log打到一个文件中,再也不用一个个文件搜索log了
-10.统一使用Mongodb的bson做序列化,消息和配置文件全部都是bson或者json,并且以后使用mongodb做数据库,再也不用做格式转换了。
-11.提供rsync同步工具,可以windows上开发测试完之后,一键同步代码到linux,linux一键编译运行
-12.提供命令行配置工具,配置分布式服务器及其简单
-
-linux工具安装命令: sudo aptitude install git-core screen cmake build-essential pkg-config
-
-Email: egametang@gmail.com
-QQ   : 80081771

+ 56 - 0
README.md

@@ -0,0 +1,56 @@
+__讨论QQ群 : 474643097__
+
+### 1.可用VS单步调试的分布式服务端,N变1  
+一般来说,分布式服务端要启动很多进程,一旦进程多了,单步调试就变得非常困难,导致服务端开发基本上靠打log来查找问题。平常开发游戏逻辑也得开启一大堆进程,不仅启动慢,而且查找问题及其不方便,要在一堆堆日志里面查问题,这感觉非常糟糕,这么多年也没人解决这个问题。ET框架使用了类似守望先锋的组件设计,所有服务端内容都拆成了一个个组件,启动时根据服务器类型挂载自己所需要的组件。这有点类似电脑,电脑都模块化的拆成了内存,CPU,主板等等零件,搭配不同的零件就能组装成一台不同的电脑,例如家用台式机需要内存,CPU,主板,显卡,显示器,硬盘。而公司用的服务器却不需要显示器和显卡,网吧的电脑可能不需要硬盘等。正因为这样的设计,ET框架可以将所有的服务器组件都挂在一个服务器进程上,那么这个服务器进程就有了所有服务器的功能,一个进程就可以作为整组分布式服务器使用。这也类似电脑,台式机有所有的电脑组件,那它也完全可以当作公司服务器使用,也可以当作网吧电脑。  
+### 2.随意可拆分功能的分布式服务端,1变N  
+分布式服务端要开发多种类型的服务器进程,比如Login server,gate server,battle server,chat server friend server等等一大堆各种server,传统开发方式需要预先知道当前的功能要放在哪个服务器上,当功能越来越多的时候,比如聊天功能之前在一个中心服务器上,之后需要拆出来单独做成一个服务器,这时会牵扯到大量迁移代码的工作,烦不胜烦。ET框架在平常开发的时候根本不太需要关心当前开发的这个功能会放在什么server上,只用一个进程进行开发,功能开发成组件的形式。发布的时候使用一份多进程的配置即可发布成多进程的形式,是不是很方便呢?随便你怎么拆分服务器。只需要修改极少的代码就可以进行拆分。不同的server挂上不同的组件就行了嘛!  
+### 3.跨平台的分布式服务端  
+ET框架使用C#做服务端,现在C#是完全可以跨平台的,在linux上安装.netcore,即可,不需要修改任何代码,就能跑起来。性能方面,现在.netcore的性能非常强,比lua,python,js什么快的多了。做游戏服务端完全不在话下。平常我们开发的时候用VS在windows上开发调试,发布的时候发布到linux上即可。ET框架还提供了一键同步工具,打开unity->tools->rsync同步,即可同步代码到linux上,  
+```bash
+./Run.sh Config/StartConfig/192.168.12.188.txt 
+```
+即可编译启动服务器。  
+### 4.提供协程支持  
+C#天生支持异步变同步语法 async和await,比lua,python的协程强大的多,新版python以及javascript语言甚至照搬了C#的协程语法。分布式服务端大量服务器之间的远程调用,没有异步语法的支持,开发将非常麻烦。所以java没有异步语法,做单服还行,不适合做大型分布式游戏服务端。例如:  
+
+```c#
+// 发送C2R_Ping并且等待响应消息R2C_Ping
+R2C_Ping pong = await session.Call<R2C_Ping>(new C2R_Ping());
+Log.Debug("收到R2C_Ping");
+
+// 向mongodb查询一个id为1的Player,并且等待返回
+Player player = await Game.Scene.GetComponent<DBProxyComponent>().Query<Player>(1);
+Log.Debug($"打印player name: {player.Name}")
+```
+可以看出,有了async await,所有的服务器间的异步操作将变得非常连贯,不用再拆成多段逻辑。大大简化了分布式服务器开发  
+### 5.提供类似erlang的actor消息机制  
+erlang语言一大优势就是位置透明的消息机制,用户完全不用关心对象在哪个进程,拿到id就可以对对象发送消息。ET框架也提供了actor消息机制,实体对象只需要挂上ActorComponent组件,这个实体对象就成了一个Actor,任何服务器只需要知道这个实体对象的id就可以向其发送消息,完全不用关心这个实体对象在哪个server,在哪台物理机器上。其实现原理也很简单,ET框架提供了一个位置服务器,所有挂载ActorComoponet的实体对象都会将自己的id跟位置注册到这个位置服务器,其它服务器向这个实体对象发送消息的时候如果不知道这个实体对象的位置,会先去位置服务器查询,查询到位置再进行发送。
+### 6.提供服务器不停服动态更新逻辑功能  
+热更是游戏服务器不可缺少的功能,ET框架使用的组件设计,可以做成守望先锋的设计,组件只有成员,无方法,将所有方法做成扩展方法放到热更dll中,运行时重新加载dll即可热更所有逻辑。
+### 7.客户端热更新一键切换  
+因为ios的限制,之前unity热更新一般使用lua,导致unity3d开发人员要写两种代码,麻烦的要死。之后幸好出了ILRuntime库,利用ILRuntime库,unity3d可以利用C#语言加载热更新dll进行热更新。ILRuntime一个缺陷就是开发时候不支持VS debug,这有点不爽。ET框架使用了一个预编译指令ILRuntime,可以无缝切换。平常开发的时候不使用ILRuntime,而是使用Assembly.Load加载热更新动态库,这样可以方便用VS单步调试。在发布的时候,定义预编译指令ILRuntime就可以无缝切换成使用ILRuntime加载热更新动态库。这样开发起来及其方便,再也不用使用狗屎lua了
+### 8.客户端服务端用同一种语言,并且共享代码  
+下载ET框架,打开服务端工程,可以看到服务端引用了客户端很多代码,通过引用客户端代码的方式实现了双端共享代码。例如客户端服务端之间的网络消息两边完全共用一个文件即可,添加一个消息只需要修改一遍。  
+### 9.UDP TCP协议无缝切换  
+ET框架不但支持TCP,而且支持可靠的UDP协议,UDP支持是封装了ENet库,ENet也是英雄联盟所使用的网络库,其特点是快速,并且网络丢包的情况下性能也非常好,这个我们做过测试TCP在丢包5%的情况下,moba游戏就卡的不行了,但是使用ENet,丢包20%仍然不会感到卡。非常强大。  
+
+### 10 还有很多很多功能,我就不详细介绍了  
+a.及其方便检查CPU占用和内存泄漏检查,vs自带分析工具,不用再为性能和内存泄漏检查而烦恼  
+b.使用NLog库,打log及其方便,平常开发时,可以将所有服务器log打到一个文件中,再也不用一个个文件搜索log了  
+c.统一使用Mongodb的bson做序列化,消息和配置文件全部都是bson或者json,并且以后使用mongodb做数据库,再也不用做格式转换了。  
+d.提供一个强大的ai行为树工具  
+e.提供一个同步工具  
+f.提供命令行配置工具,配置分布式非常简单  
+
+ET框架的服务端是一个强大灵活的分布式服务端架构,完全可以满足绝大部分大型游戏需求。使用这套框架,客户端开发者就可以自己完成双端开发,节省大量人力物力,节省大量沟通时间。  
+
+使用方法:  
+[运行指南](https://github.com/egametang/Egametang/blob/master/Doc/%E8%BF%90%E8%A1%8C%E6%8C%87%E5%8D%97.md)    
+[组件式设计](https://github.com/egametang/Egametang/blob/master/Doc/%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1.md)   
+[网络层设计](https://github.com/egametang/Egametang/blob/master/Doc/%E7%BD%91%E7%BB%9C%E5%B1%82%E8%AE%BE%E8%AE%A1.md)   
+
+群友源码分析:  
+[框架服务端运行流程](http://www.cnblogs.com/fancybit/p/et1.html)   
+[ET启动配置](http://www.cnblogs.com/fancybit/p/et2.html)   
+
+__讨论QQ群 : 474643097__

+ 2 - 2
Run.sh

@@ -8,9 +8,9 @@ then
 fi
 
 xbuild ./Server/Server.sln
-cd Bin
+cd netcoreapp2.0
 cmake ..
 make
 
 ps -ef | grep App.exe | awk '{print $2}' | xargs kill -9
-mono --debug App.exe --appId=1 --appType=Manager --config=../$1
+dotnet App.dll --appId=1 --appType=Manager --config=../$1

+ 3 - 0
Server/App/App.config

@@ -3,4 +3,7 @@
     <startup> 
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
     </startup>
+	<runtime>
+		<gcServer enabled="true" />
+	</runtime>
 </configuration>

+ 5 - 4
Server/App/NLog.config

@@ -7,27 +7,28 @@
 		<target name="all" xsi:type="File"
 			fileName="${basedir}/../Logs/Log.txt"
 			deleteOldFileOnStartup="false"
-		layout="${longdate} ${var:appType} ${var:appId} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
+			layout="${longdate} ${var:appTypeFormat} ${var:appIdFormat} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
 	</targets>
+	
 	<targets>
 		<target name="debug" xsi:type="File"
 			fileName="${basedir}/../Logs/Log-${var:appType}-${var:appId}-Debug.txt"
 			deleteOldFileOnStartup="false"
-			layout="${longdate} ${var:appType} ${var:appId} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
+			layout="${longdate} ${var:appTypeFormat} ${var:appIdFormat} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
 	</targets>
 
 	<targets>
 		<target name="info" xsi:type="File"
 			fileName="${basedir}/../Logs/Log-${var:appType}-${var:appId}-Info.txt"
 			deleteOldFileOnStartup="false"
-			layout="${longdate} ${var:appType} ${var:appId} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
+			layout="${longdate} ${var:appTypeFormat} ${var:appIdFormat} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}" />
 	</targets>
 	
 	<targets>
 		<target name="error" xsi:type="File"
 			fileName="${basedir}/../Logs/Log-${var:appType}-${var:appId}-Error.txt"
 			deleteOldFileOnStartup="false"
-			layout="${longdate} ${var:appType} ${var:appId} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message} ${stacktrace:format=Flat:topFrames=100:skipFrames=2}" />
+			layout="${longdate} ${var:appTypeFormat} ${var:appIdFormat} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message} ${stacktrace:format=Flat:topFrames=100:skipFrames=0}" />
 	</targets>
 	
 	<rules>

+ 3041 - 0
Server/App/NLog.xsd

@@ -0,0 +1,3041 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema id="NLog" targetNamespace="http://www.nlog-project.org/schemas/NLog.xsd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.nlog-project.org/schemas/NLog.xsd">
+  <xs:element name="nlog" type="NLogConfiguration" />
+  <xs:complexType name="NLogConfiguration">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="extensions" type="NLogExtensions" />
+      <xs:element name="include" type="NLogInclude" />
+      <xs:element name="variable" type="NLogVariable" />
+      <xs:element name="targets" type="NLogTargets" />
+      <xs:element name="rules" type="NLogRules" />
+      <xs:element name="time" type="TimeSource" />
+    </xs:choice>
+    <xs:attribute name="autoReload" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Watch config file for changes and reload automatically.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="internalLogToConsole" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Print internal NLog messages to the console. Default value is: false</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="internalLogToConsoleError" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Print internal NLog messages to the console error output. Default value is: false</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="internalLogFile" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Write internal NLog messages to the specified file.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="internalLogLevel" type="NLogLevel">
+      <xs:annotation>
+        <xs:documentation>Log level threshold for internal log messages. Default value is: Info.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="globalThreshold" type="NLogLevel">
+      <xs:annotation>
+        <xs:documentation>Global log level threshold for application log messages. Messages below this level won't be logged..</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="throwExceptions" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Throw an exception when there is an internal error. Default value is: false.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="throwConfigExceptions" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Throw an exception when there is a configuration error. If not set, determined by throwExceptions.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="keepVariablesOnReload" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Gets or sets a value indicating whether Variables should be kept on configuration reload. Default value is: false.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="internalLogToTrace" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Write internal NLog messages to the System.Diagnostics.Trace. Default value is: false.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="internalLogIncludeTimestamp" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Write timestamps for internal NLog messages. Default value is: true.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="useInvariantCulture" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Use InvariantCulture as default culture instead of CurrentCulture.  Default value is: false.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLogTargets">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="default-wrapper" type="WrapperTargetBase" />
+      <xs:element name="default-target-parameters" type="Target" />
+      <xs:element name="target" type="Target" />
+      <xs:element name="wrapper-target" type="WrapperTargetBase" />
+      <xs:element name="compound-target" type="CompoundTargetBase" />
+    </xs:choice>
+    <xs:attribute name="async" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes).</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLogRules">
+    <xs:sequence minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="logger" type="NLogLoggerRule" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="NLogExtensions">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="add" type="NLogExtensionsAdd" />
+    </xs:choice>
+  </xs:complexType>
+  <xs:complexType name="NLogExtensionsAdd">
+    <xs:attribute name="prefix" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Prefix for targets/layout renderers/filters/conditions loaded from this assembly.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="assemblyFile" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Load NLog extensions from the specified file (*.dll)</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="assembly" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Load NLog extensions from the specified assembly. Assembly name should be fully qualified.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLogLoggerRule">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="filters" type="NLogFilters" />
+    </xs:choice>
+    <xs:attribute name="name" use="optional">
+      <xs:annotation>
+        <xs:documentation>Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name*</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="levels" type="NLogLevelList">
+      <xs:annotation>
+        <xs:documentation>Comma separated list of levels that this rule matches.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="minlevel" type="NLogLevel">
+      <xs:annotation>
+        <xs:documentation>Minimum level that this rule matches.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="maxlevel" type="NLogLevel">
+      <xs:annotation>
+        <xs:documentation>Maximum level that this rule matches.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="level" type="NLogLevel">
+      <xs:annotation>
+        <xs:documentation>Level that this rule matches.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="writeTo" type="NLogTargetIDList">
+      <xs:annotation>
+        <xs:documentation>Comma separated list of target names.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="final" type="xs:boolean" default="false">
+      <xs:annotation>
+        <xs:documentation>Ignore further rules if this one matches.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="enabled" type="xs:boolean" default="true">
+      <xs:annotation>
+        <xs:documentation>Enable or disable logging rule. Disabled rules are ignored.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLogFilters">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="when" type="when" />
+      <xs:element name="whenContains" type="whenContains" />
+      <xs:element name="whenEqual" type="whenEqual" />
+      <xs:element name="whenNotContains" type="whenNotContains" />
+      <xs:element name="whenNotEqual" type="whenNotEqual" />
+      <xs:element name="whenRepeated" type="whenRepeated" />
+    </xs:choice>
+  </xs:complexType>
+  <xs:simpleType name="NLogLevel">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Off" />
+      <xs:enumeration value="Trace" />
+      <xs:enumeration value="Debug" />
+      <xs:enumeration value="Info" />
+      <xs:enumeration value="Warn" />
+      <xs:enumeration value="Error" />
+      <xs:enumeration value="Fatal" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="LineEndingMode">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Default" />
+      <xs:enumeration value="CRLF" />
+      <xs:enumeration value="CR" />
+      <xs:enumeration value="LF" />
+      <xs:enumeration value="None" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLogLevelList">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="(|Trace|Debug|Info|Warn|Error|Fatal)(,(Trace|Debug|Info|Warn|Error|Fatal))*" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="NLogInclude">
+    <xs:attribute name="file" type="SimpleLayoutAttribute" use="required">
+      <xs:annotation>
+        <xs:documentation>Name of the file to be included. You could use * wildcard. The name is relative to the name of the current config file.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="ignoreErrors" type="xs:boolean" use="optional" default="false">
+      <xs:annotation>
+        <xs:documentation>Ignore any errors in the include file.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLogVariable">
+    <xs:attribute name="name" type="xs:string" use="required">
+      <xs:annotation>
+        <xs:documentation>Variable name.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="value" type="SimpleLayoutAttribute" use="required">
+      <xs:annotation>
+        <xs:documentation>Variable value.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:simpleType name="NLogTargetIDList">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="(|([a-zA-Z][a-zA-Z0-9_\-]*))(,([a-zA-Z][a-zA-Z0-9_\-]*))*" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="Target" abstract="true"></xs:complexType>
+  <xs:complexType name="TargetRef">
+    <xs:attribute name="name" type="xs:string" use="required" />
+  </xs:complexType>
+  <xs:complexType name="WrapperTargetBase" abstract="true">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="target" type="Target" minOccurs="1" maxOccurs="1" />
+          <xs:element name="wrapper-target" type="WrapperTargetBase" minOccurs="1" maxOccurs="1" />
+          <xs:element name="compound-target" type="CompoundTargetBase" minOccurs="1" maxOccurs="1" />
+          <xs:element name="target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" />
+          <xs:element name="wrapper-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" />
+          <xs:element name="compound-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" />
+        </xs:choice>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="CompoundTargetBase" abstract="true">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="target" type="Target" minOccurs="1" maxOccurs="unbounded" />
+          <xs:element name="wrapper-target" type="WrapperTargetBase" minOccurs="1" maxOccurs="1" />
+          <xs:element name="compound-target" type="CompoundTargetBase" minOccurs="1" maxOccurs="1" />
+          <xs:element name="target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" />
+          <xs:element name="wrapper-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" />
+          <xs:element name="compound-target-ref" type="TargetRef" minOccurs="1" maxOccurs="1" />
+        </xs:choice>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Filter" abstract="true"></xs:complexType>
+  <xs:complexType name="TimeSource" abstract="true"></xs:complexType>
+  <xs:simpleType name="SimpleLayoutAttribute">
+    <xs:restriction base="xs:string">
+      <xs:pattern value=".*" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="Condition">
+    <xs:restriction base="xs:string">
+      <xs:minLength value="1" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="AsyncWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="batchSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="fullBatchSizeWriteLimit" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="overflowAction" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction" />
+          <xs:element name="queueLimit" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="timeToSleepBetweenBatches" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="batchSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Number of log events that should be processed in a batch by the lazy writer thread.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="fullBatchSizeWriteLimit" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Limit of full s to write before yielding into  Performance is better when writing many small batches, than writing a single large batch</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="overflowAction" type="NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when the lazy writer thread request queue count exceeds the set limit.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="queueLimit" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Limit on the number of requests in the lazy writer thread request queue.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="timeToSleepBetweenBatches" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Time in milliseconds to sleep between batches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Grow" />
+      <xs:enumeration value="Discard" />
+      <xs:enumeration value="Block" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="AutoFlushWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="asyncFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="asyncFlush" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Delay the flush until the LogEvent has been confirmed as written</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="condition" type="Condition">
+          <xs:annotation>
+            <xs:documentation>Condition expression. Log events who meet this condition will cause a flush on the wrapped target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="BufferingWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="bufferSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="flushTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="slidingTimeout" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="bufferSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Number of log events to be buffered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="flushTimeout" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="slidingTimeout" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to use sliding timeout.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Chainsaw">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" />
+          <xs:element name="maxMessageSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="newLine" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="onConnectionOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetConnectionsOverflowAction" />
+          <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetOverflowAction" />
+          <xs:element name="maxConnections" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="connectionCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="address" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="maxQueueSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.NLogViewerParameterInfo" />
+          <xs:element name="ndcItemSeparator" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeNLogData" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeNdc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeCallSite" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="appInfo" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="includeSourceInfo" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Encoding to be used.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Instance of  that is used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="lineEnding" type="LineEndingMode">
+          <xs:annotation>
+            <xs:documentation>End of line value if a newline is appended at the end of log message .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxMessageSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum message size in bytes.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="newLine" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to append newline at the end of log message.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onConnectionOverflow" type="NLog.Targets.NetworkTargetConnectionsOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action that should be taken if the will be more connections than .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onOverflow" type="NLog.Targets.NetworkTargetOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action that should be taken if the message is larger than maxMessageSize.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxConnections" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum current connections. 0 = no maximum.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="keepConnection" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to keep connection open whenever possible.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="connectionCacheSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Size of the connection cache (number of connections which are kept alive).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="address" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Network address.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxQueueSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum queue size.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ndcItemSeparator" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>NDC item separator.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdlc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include  dictionary contents.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeNLogData" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include NLog-specific extensions to log4j schema.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeNdc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include  stack contents.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include  dictionary contents.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeCallSite" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include call site (class and method name) in the information sent over the network.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="appInfo" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>AppInfo field. By default it's the friendly name of the current AppDomain.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeSourceInfo" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include source info (file name and line number) in the information sent over the network.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.NetworkTargetConnectionsOverflowAction">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="AllowNewConnnection" />
+      <xs:enumeration value="DiscardMessage" />
+      <xs:enumeration value="Block" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Targets.NetworkTargetOverflowAction">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Error" />
+      <xs:enumeration value="Split" />
+      <xs:enumeration value="Discard" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="NLog.Targets.NLogViewerParameterInfo">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+      <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+    </xs:choice>
+    <xs:attribute name="layout" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Layout that should be use to calcuate the value for the parameter.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="name" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Viewer parameter name.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="ColoredConsole">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="useDefaultRowHighlightingRules" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="highlight-row" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleRowHighlightingRule" />
+          <xs:element name="highlight-word" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleWordHighlightingRule" />
+          <xs:element name="detectConsoleAvailable" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="errorStream" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Text to be rendered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="useDefaultRowHighlightingRules" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to use default row highlighting rules.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="detectConsoleAvailable" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The encoding for writing messages to the .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="errorStream" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.ConsoleOutputColor">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Black" />
+      <xs:enumeration value="DarkBlue" />
+      <xs:enumeration value="DarkGreen" />
+      <xs:enumeration value="DarkCyan" />
+      <xs:enumeration value="DarkRed" />
+      <xs:enumeration value="DarkMagenta" />
+      <xs:enumeration value="DarkYellow" />
+      <xs:enumeration value="Gray" />
+      <xs:enumeration value="DarkGray" />
+      <xs:enumeration value="Blue" />
+      <xs:enumeration value="Green" />
+      <xs:enumeration value="Cyan" />
+      <xs:enumeration value="Red" />
+      <xs:enumeration value="Magenta" />
+      <xs:enumeration value="Yellow" />
+      <xs:enumeration value="White" />
+      <xs:enumeration value="NoChange" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="NLog.Targets.ConsoleRowHighlightingRule">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" />
+      <xs:element name="backgroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" />
+      <xs:element name="foregroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" />
+    </xs:choice>
+    <xs:attribute name="condition" type="Condition">
+      <xs:annotation>
+        <xs:documentation>Condition that must be met in order to set the specified foreground and background color.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="backgroundColor" type="NLog.Targets.ConsoleOutputColor">
+      <xs:annotation>
+        <xs:documentation>Background color.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="foregroundColor" type="NLog.Targets.ConsoleOutputColor">
+      <xs:annotation>
+        <xs:documentation>Foreground color.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLog.Targets.ConsoleWordHighlightingRule">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+      <xs:element name="regex" minOccurs="0" maxOccurs="1" type="xs:string" />
+      <xs:element name="text" minOccurs="0" maxOccurs="1" type="xs:string" />
+      <xs:element name="wholeWords" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+      <xs:element name="compileRegex" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+      <xs:element name="backgroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" />
+      <xs:element name="foregroundColor" minOccurs="0" maxOccurs="1" type="NLog.Targets.ConsoleOutputColor" />
+    </xs:choice>
+    <xs:attribute name="ignoreCase" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Indicates whether to ignore case when comparing texts.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="regex" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Regular expression to be matched. You must specify either text or regex.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="text" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Text to be matched. You must specify either text or regex.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="wholeWords" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Indicates whether to match whole words only.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="compileRegex" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="backgroundColor" type="NLog.Targets.ConsoleOutputColor">
+      <xs:annotation>
+        <xs:documentation>Background color.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="foregroundColor" type="NLog.Targets.ConsoleOutputColor">
+      <xs:annotation>
+        <xs:documentation>Foreground color.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="Console">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="error" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="detectConsoleAvailable" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Text to be rendered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="error" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to send the log messages to the standard error instead of the standard output.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="detectConsoleAvailable" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The encoding for writing messages to the .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Database">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="useTransactions" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="dbUserName" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="dbProvider" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="dbPassword" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="dbDatabase" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="connectionStringName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="connectionString" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="dbHost" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="installConnectionString" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="install-command" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseCommandInfo" />
+          <xs:element name="uninstall-command" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseCommandInfo" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseParameterInfo" />
+          <xs:element name="commandText" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="commandType" minOccurs="0" maxOccurs="1" type="System.Data.CommandType" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="useTransactions" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="dbUserName" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="dbProvider" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the database provider.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="dbPassword" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="keepConnection" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to keep the database connection open between the log events.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="dbDatabase" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="connectionStringName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the connection string (as specified in &lt;connectionStrings&gt; configuration section.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="connectionString" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="dbHost" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="installConnectionString" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="commandText" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Text of the SQL command to be run on each log level.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="commandType" type="System.Data.CommandType">
+          <xs:annotation>
+            <xs:documentation>Type of the SQL command to be run on each log level.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="System.Data.CommandType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Text" />
+      <xs:enumeration value="StoredProcedure" />
+      <xs:enumeration value="TableDirect" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="NLog.Targets.DatabaseCommandInfo">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="commandType" minOccurs="0" maxOccurs="1" type="System.Data.CommandType" />
+      <xs:element name="connectionString" minOccurs="0" maxOccurs="1" type="Layout" />
+      <xs:element name="ignoreFailures" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+      <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.DatabaseParameterInfo" />
+      <xs:element name="text" minOccurs="0" maxOccurs="1" type="Layout" />
+    </xs:choice>
+    <xs:attribute name="commandType" type="System.Data.CommandType">
+      <xs:annotation>
+        <xs:documentation>Type of the command.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="connectionString" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Connection string to run the command against. If not provided, connection string from the target is used.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="ignoreFailures" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Indicates whether to ignore failures.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="text" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Command text.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="NLog.Targets.DatabaseParameterInfo">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+      <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+      <xs:element name="precision" minOccurs="0" maxOccurs="1" type="xs:byte" />
+      <xs:element name="scale" minOccurs="0" maxOccurs="1" type="xs:byte" />
+      <xs:element name="size" minOccurs="0" maxOccurs="1" type="xs:integer" />
+    </xs:choice>
+    <xs:attribute name="layout" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Layout that should be use to calcuate the value for the parameter.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="name" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Database parameter name.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="precision" type="xs:byte">
+      <xs:annotation>
+        <xs:documentation>Database parameter precision.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="scale" type="xs:byte">
+      <xs:annotation>
+        <xs:documentation>Database parameter scale.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="size" type="xs:integer">
+      <xs:annotation>
+        <xs:documentation>Database parameter size.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="Debugger">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Text to be rendered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Debug">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="EventLog">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="category" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="eventId" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="log" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="machineName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="source" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.EventLogTargetOverflowAction" />
+          <xs:element name="entryType" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="maxKilobytes" minOccurs="0" maxOccurs="1" type="xs:long" />
+          <xs:element name="maxMessageLength" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="category" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout that renders event Category.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="eventId" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout that renders event ID.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="log" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the Event Log to write to. This can be System, Application or any user-defined name.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="machineName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the machine on which Event Log service is running.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="source" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Value to be used as the event Source.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onOverflow" type="NLog.Targets.EventLogTargetOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action to take if the message is larger than the  option.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="entryType" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Optional entrytype. When not set, or when not convertable to  then determined by </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxKilobytes" type="xs:long">
+          <xs:annotation>
+            <xs:documentation>Maximum Event log size in kilobytes. If null, the value won't be set. Default is 512 Kilobytes as specified by Eventlog API</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxMessageLength" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Message length limit to write to the Event Log.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.EventLogTargetOverflowAction">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Truncate" />
+      <xs:enumeration value="Split" />
+      <xs:enumeration value="Discard" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="FallbackGroup">
+    <xs:complexContent>
+      <xs:extension base="CompoundTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="returnToFirstOnSuccess" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="returnToFirstOnSuccess" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to return to the first target after any successful write.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="File">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" />
+          <xs:element name="archiveNumbering" minOccurs="0" maxOccurs="1" type="NLog.Targets.ArchiveNumberingMode" />
+          <xs:element name="archiveFileName" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="archiveEvery" minOccurs="0" maxOccurs="1" type="NLog.Targets.FileArchivePeriod" />
+          <xs:element name="archiveAboveSize" minOccurs="0" maxOccurs="1" type="xs:long" />
+          <xs:element name="enableArchiveFileCompression" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="maxArchiveFiles" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="forceManaged" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="archiveFileKind" minOccurs="0" maxOccurs="1" type="NLog.Targets.FilePathKind" />
+          <xs:element name="cleanupFileName" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="discardAll" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="fileNameKind" minOccurs="0" maxOccurs="1" type="NLog.Targets.FilePathKind" />
+          <xs:element name="forceMutexConcurrentWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="maxLogFilenames" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="writeFooterOnArchivingOnly" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="fileName" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="archiveDateFormat" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="archiveOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="createDirs" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="fileAttributes" minOccurs="0" maxOccurs="1" type="NLog.Targets.Win32FileAttributes" />
+          <xs:element name="deleteOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="replaceFileContentsOnEachWrite" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="enableFileDelete" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="concurrentWriteAttempts" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="concurrentWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="keepFileOpen" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="networkWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="openFileCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="openFileCacheTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="bufferSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="autoFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="concurrentWriteAttemptDelay" minOccurs="0" maxOccurs="1" type="xs:integer" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Text to be rendered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>File encoding.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="lineEnding" type="LineEndingMode">
+          <xs:annotation>
+            <xs:documentation>Line ending mode.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveNumbering" type="NLog.Targets.ArchiveNumberingMode">
+          <xs:annotation>
+            <xs:documentation>Way file archives are numbered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveFileName" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Name of the file to be used for an archive.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveEvery" type="NLog.Targets.FileArchivePeriod">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to automatically archive log files every time the specified time passes.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveAboveSize" type="xs:long">
+          <xs:annotation>
+            <xs:documentation>Size in bytes above which log files will be automatically archived. Warning: combining this with  isn't supported. We cannot create multiple archive files, if they should have the same name. Choose: </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="enableArchiveFileCompression" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to compress archive files into the zip archive format.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxArchiveFiles" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum number of archive files that should be kept.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="forceManaged" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Gets or set a value indicating whether a managed file stream is forced, instead of using the native implementation.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveFileKind" type="NLog.Targets.FilePathKind">
+          <xs:annotation>
+            <xs:documentation>Is the  an absolute or relative path?</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="cleanupFileName" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="discardAll" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Whether or not this target should just discard all data that its asked to write. Mostly used for when testing NLog Stack except final write</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="fileNameKind" type="NLog.Targets.FilePathKind">
+          <xs:annotation>
+            <xs:documentation>Is the  an absolute or relative path?</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="forceMutexConcurrentWrites" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Value indicationg whether file creation calls should be synchronized by a system global mutex.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxLogFilenames" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum number of log filenames that should be stored as existing.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="writeFooterOnArchivingOnly" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether the footer should be written only when the file is archived.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="fileName" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Name of the file to write to.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveDateFormat" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Value specifying the date format to use when archiving files.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="archiveOldFileOnStartup" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to archive old log file on startup.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="createDirs" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to create directories if they do not exist.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="fileAttributes" type="NLog.Targets.Win32FileAttributes">
+          <xs:annotation>
+            <xs:documentation>File attributes (Windows only).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="deleteOldFileOnStartup" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to delete old log file on startup.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="replaceFileContentsOnEachWrite" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to replace file contents on each write instead of appending log message at the end.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="enableFileDelete" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to enable log file(s) to be deleted.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="concurrentWriteAttempts" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Number of times the write is appended on the file before NLog discards the log message.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="concurrentWrites" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether concurrent writes to the log file by multiple processes on the same host.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="keepFileOpen" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to keep log file open instead of opening and closing it on each logging event.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="networkWrites" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether concurrent writes to the log file by multiple processes on different network hosts.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="openFileCacheSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="openFileCacheTimeout" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="bufferSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Log file buffer size in bytes.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="autoFlush" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to automatically flush the file buffers after each log message.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="concurrentWriteAttemptDelay" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Delay in milliseconds to wait before attempting to write to the file again.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.ArchiveNumberingMode">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Sequence" />
+      <xs:enumeration value="Rolling" />
+      <xs:enumeration value="Date" />
+      <xs:enumeration value="DateAndSequence" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Targets.FileArchivePeriod">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="None" />
+      <xs:enumeration value="Year" />
+      <xs:enumeration value="Month" />
+      <xs:enumeration value="Day" />
+      <xs:enumeration value="Hour" />
+      <xs:enumeration value="Minute" />
+      <xs:enumeration value="Sunday" />
+      <xs:enumeration value="Monday" />
+      <xs:enumeration value="Tuesday" />
+      <xs:enumeration value="Wednesday" />
+      <xs:enumeration value="Thursday" />
+      <xs:enumeration value="Friday" />
+      <xs:enumeration value="Saturday" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Targets.FilePathKind">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Unknown" />
+      <xs:enumeration value="Relative" />
+      <xs:enumeration value="Absolute" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Targets.Win32FileAttributes">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="ReadOnly" />
+      <xs:enumeration value="Hidden" />
+      <xs:enumeration value="System" />
+      <xs:enumeration value="Archive" />
+      <xs:enumeration value="Device" />
+      <xs:enumeration value="Normal" />
+      <xs:enumeration value="Temporary" />
+      <xs:enumeration value="SparseFile" />
+      <xs:enumeration value="ReparsePoint" />
+      <xs:enumeration value="Compressed" />
+      <xs:enumeration value="NotContentIndexed" />
+      <xs:enumeration value="Encrypted" />
+      <xs:enumeration value="WriteThrough" />
+      <xs:enumeration value="NoBuffering" />
+      <xs:enumeration value="DeleteOnClose" />
+      <xs:enumeration value="PosixSemantics" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="FilteringWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="condition" type="Condition">
+          <xs:annotation>
+            <xs:documentation>Condition expression. Log events who meet this condition will be forwarded to the wrapped target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="ImpersonatingWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="domain" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="impersonationLevel" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.SecurityImpersonationLevel" />
+          <xs:element name="logOnProvider" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.LogOnProviderType" />
+          <xs:element name="logOnType" minOccurs="0" maxOccurs="1" type="NLog.Targets.Wrappers.SecurityLogOnType" />
+          <xs:element name="password" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="revertToSelf" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="userName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="domain" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Windows domain name to change context to.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="impersonationLevel" type="NLog.Targets.Wrappers.SecurityImpersonationLevel">
+          <xs:annotation>
+            <xs:documentation>Required impersonation level.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="logOnProvider" type="NLog.Targets.Wrappers.LogOnProviderType">
+          <xs:annotation>
+            <xs:documentation>Type of the logon provider.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="logOnType" type="NLog.Targets.Wrappers.SecurityLogOnType">
+          <xs:annotation>
+            <xs:documentation>Logon Type.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="password" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>User account password.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="revertToSelf" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to revert to the credentials of the process instead of impersonating another user.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="userName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Username to change context to.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.Wrappers.SecurityImpersonationLevel">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Anonymous" />
+      <xs:enumeration value="Identification" />
+      <xs:enumeration value="Impersonation" />
+      <xs:enumeration value="Delegation" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Targets.Wrappers.LogOnProviderType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Default" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Targets.Wrappers.SecurityLogOnType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Interactive" />
+      <xs:enumeration value="Network" />
+      <xs:enumeration value="Batch" />
+      <xs:enumeration value="Service" />
+      <xs:enumeration value="NetworkClearText" />
+      <xs:enumeration value="NewCredentials" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="LimitingWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="interval" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="messageLimit" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="interval" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Interval in which messages will be written up to the  number of messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="messageLimit" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum allowed number of messages written per .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="LogReceiverService">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="endpointAddress" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="endpointConfigurationName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="useOneWayContract" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="clientId" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="includeEventProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" />
+          <xs:element name="useBinaryEncoding" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="endpointAddress" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Endpoint address.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="endpointConfigurationName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the endpoint configuration in WCF configuration file.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="useOneWayContract" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="clientId" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Client ID.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeEventProperties" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include per-event properties in the payload sent to the server.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="useBinaryEncoding" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to use binary message encoding.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="NLog.Targets.MethodCallParameter">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+      <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+      <xs:element name="parameterType" minOccurs="0" maxOccurs="1" type="xs:string" />
+      <xs:element name="type" minOccurs="0" maxOccurs="1" type="xs:string" />
+      <xs:element name="enableGroupLayout" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+    </xs:choice>
+    <xs:attribute name="layout" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Layout that should be use to calculate the value for the parameter.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="name" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Name of the parameter.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="parameterType" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Type of the parameter.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="type" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Type of the parameter. Obsolete alias for </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="enableGroupLayout" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Parameter can combine multiple LogEvents into a single parameter value</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="Mail">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="html" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="addNewLines" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="cc" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="to" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="bcc" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="body" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="subject" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="from" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="timeout" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="priority" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="replaceNewlineWithBrTagInHtml" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="smtpServer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="smtpAuthentication" minOccurs="0" maxOccurs="1" type="NLog.Targets.SmtpAuthenticationMode" />
+          <xs:element name="smtpUserName" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="smtpPassword" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="enableSsl" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="smtpPort" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="useSystemNetMailSettings" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="pickupDirectoryLocation" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="deliveryMethod" minOccurs="0" maxOccurs="1" type="System.Net.Mail.SmtpDeliveryMethod" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Text to be rendered.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="html" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to send message as HTML instead of plain text.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Encoding to be used for sending e-mail.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="addNewLines" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to add new lines between log entries.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="cc" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="to" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="bcc" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="body" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Mail message body (repeated for each log message send in one mail).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="subject" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Mail subject.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="from" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Sender's email address (e.g. joe@domain.com).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="timeout" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Indicates the SMTP client timeout.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="priority" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Priority used for sending mails.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="replaceNewlineWithBrTagInHtml" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether NewLine characters in the body should be replaced with  tags.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="smtpServer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>SMTP Server to be used for sending.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="smtpAuthentication" type="NLog.Targets.SmtpAuthenticationMode">
+          <xs:annotation>
+            <xs:documentation>SMTP Authentication mode.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="smtpUserName" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="smtpPassword" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="enableSsl" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="smtpPort" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Port number that SMTP Server is listening on.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="useSystemNetMailSettings" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether the default Settings from System.Net.MailSettings should be used.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="pickupDirectoryLocation" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Folder where applications save mail messages to be processed by the local SMTP server.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="deliveryMethod" type="System.Net.Mail.SmtpDeliveryMethod">
+          <xs:annotation>
+            <xs:documentation>Specifies how outgoing email messages will be handled.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.SmtpAuthenticationMode">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="None" />
+      <xs:enumeration value="Basic" />
+      <xs:enumeration value="Ntlm" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="System.Net.Mail.SmtpDeliveryMethod">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Network" />
+      <xs:enumeration value="SpecifiedPickupDirectory" />
+      <xs:enumeration value="PickupDirectoryFromIis" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="Memory">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="MethodCall">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="className" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="methodName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="className" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Class name.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="methodName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Network">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" />
+          <xs:element name="maxMessageSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="newLine" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="onConnectionOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetConnectionsOverflowAction" />
+          <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetOverflowAction" />
+          <xs:element name="address" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="connectionCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="maxConnections" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="maxQueueSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Encoding to be used.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="lineEnding" type="LineEndingMode">
+          <xs:annotation>
+            <xs:documentation>End of line value if a newline is appended at the end of log message .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxMessageSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum message size in bytes.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="newLine" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to append newline at the end of log message.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onConnectionOverflow" type="NLog.Targets.NetworkTargetConnectionsOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action that should be taken if the will be more connections than .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onOverflow" type="NLog.Targets.NetworkTargetOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action that should be taken if the message is larger than maxMessageSize.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="address" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Network address.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="connectionCacheSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Size of the connection cache (number of connections which are kept alive).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="keepConnection" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to keep connection open whenever possible.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxConnections" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum current connections. 0 = no maximum.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxQueueSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum queue size.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="NLogViewer">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="lineEnding" minOccurs="0" maxOccurs="1" type="LineEndingMode" />
+          <xs:element name="maxMessageSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="newLine" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="onConnectionOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetConnectionsOverflowAction" />
+          <xs:element name="onOverflow" minOccurs="0" maxOccurs="1" type="NLog.Targets.NetworkTargetOverflowAction" />
+          <xs:element name="maxConnections" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="keepConnection" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="connectionCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="address" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="maxQueueSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.NLogViewerParameterInfo" />
+          <xs:element name="ndcItemSeparator" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeNLogData" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeNdc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeCallSite" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="appInfo" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="includeSourceInfo" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Encoding to be used.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Instance of  that is used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="lineEnding" type="LineEndingMode">
+          <xs:annotation>
+            <xs:documentation>End of line value if a newline is appended at the end of log message .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxMessageSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum message size in bytes.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="newLine" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to append newline at the end of log message.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onConnectionOverflow" type="NLog.Targets.NetworkTargetConnectionsOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action that should be taken if the will be more connections than .</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="onOverflow" type="NLog.Targets.NetworkTargetOverflowAction">
+          <xs:annotation>
+            <xs:documentation>Action that should be taken if the message is larger than maxMessageSize.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxConnections" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum current connections. 0 = no maximum.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="keepConnection" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to keep connection open whenever possible.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="connectionCacheSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Size of the connection cache (number of connections which are kept alive).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="address" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Network address.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxQueueSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Maximum queue size.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ndcItemSeparator" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>NDC item separator.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdlc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include  dictionary contents.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeNLogData" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include NLog-specific extensions to log4j schema.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeNdc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include  stack contents.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include  dictionary contents.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeCallSite" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include call site (class and method name) in the information sent over the network.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="appInfo" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>AppInfo field. By default it's the friendly name of the current AppDomain.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeSourceInfo" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include source info (file name and line number) in the information sent over the network.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Null">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="formatMessage" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="formatMessage" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to perform layout calculation.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="OutputDebugString">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="PerfCounter">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="autoCreate" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="categoryName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="counterHelp" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="counterName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="counterType" minOccurs="0" maxOccurs="1" type="System.Diagnostics.PerformanceCounterType" />
+          <xs:element name="incrementValue" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="instanceName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="autoCreate" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether performance counter should be automatically created.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="categoryName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the performance counter category.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="counterHelp" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Counter help text.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="counterName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the performance counter.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="counterType" type="System.Diagnostics.PerformanceCounterType">
+          <xs:annotation>
+            <xs:documentation>Performance counter type.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="incrementValue" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>The value by which to increment the counter.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="instanceName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Performance counter instance name.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="System.Diagnostics.PerformanceCounterType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="NumberOfItems32" />
+      <xs:enumeration value="NumberOfItems64" />
+      <xs:enumeration value="NumberOfItemsHEX32" />
+      <xs:enumeration value="NumberOfItemsHEX64" />
+      <xs:enumeration value="RateOfCountsPerSecond32" />
+      <xs:enumeration value="RateOfCountsPerSecond64" />
+      <xs:enumeration value="CountPerTimeInterval32" />
+      <xs:enumeration value="CountPerTimeInterval64" />
+      <xs:enumeration value="RawFraction" />
+      <xs:enumeration value="RawBase" />
+      <xs:enumeration value="AverageTimer32" />
+      <xs:enumeration value="AverageBase" />
+      <xs:enumeration value="AverageCount64" />
+      <xs:enumeration value="SampleFraction" />
+      <xs:enumeration value="SampleCounter" />
+      <xs:enumeration value="SampleBase" />
+      <xs:enumeration value="CounterTimer" />
+      <xs:enumeration value="CounterTimerInverse" />
+      <xs:enumeration value="Timer100Ns" />
+      <xs:enumeration value="Timer100NsInverse" />
+      <xs:enumeration value="ElapsedTime" />
+      <xs:enumeration value="CounterMultiTimer" />
+      <xs:enumeration value="CounterMultiTimerInverse" />
+      <xs:enumeration value="CounterMultiTimer100Ns" />
+      <xs:enumeration value="CounterMultiTimer100NsInverse" />
+      <xs:enumeration value="CounterMultiBase" />
+      <xs:enumeration value="CounterDelta32" />
+      <xs:enumeration value="CounterDelta64" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="PostFilteringWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="defaultFilter" minOccurs="0" maxOccurs="1" type="Condition" />
+          <xs:element name="when" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.Wrappers.FilteringRule" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="defaultFilter" type="Condition">
+          <xs:annotation>
+            <xs:documentation>Default filter to be applied when no specific rule matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="NLog.Targets.Wrappers.FilteringRule">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="exists" minOccurs="0" maxOccurs="1" type="Condition" />
+      <xs:element name="filter" minOccurs="0" maxOccurs="1" type="Condition" />
+    </xs:choice>
+    <xs:attribute name="exists" type="Condition">
+      <xs:annotation>
+        <xs:documentation>Condition to be tested.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="filter" type="Condition">
+      <xs:annotation>
+        <xs:documentation>Resulting filter to be applied when the condition matches.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="RandomizeGroup">
+    <xs:complexContent>
+      <xs:extension base="CompoundTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="RepeatingWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="repeatCount" minOccurs="0" maxOccurs="1" type="xs:integer" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="repeatCount" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Number of times to repeat each log message.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="RetryingWrapper">
+    <xs:complexContent>
+      <xs:extension base="WrapperTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="retryCount" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="retryDelayMilliseconds" minOccurs="0" maxOccurs="1" type="xs:integer" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="retryCount" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Number of retries that should be attempted on the wrapped target in case of a failure.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="retryDelayMilliseconds" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Time to wait between retries in milliseconds.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="RoundRobinGroup">
+    <xs:complexContent>
+      <xs:extension base="CompoundTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="SplitGroup">
+    <xs:complexContent>
+      <xs:extension base="CompoundTargetBase">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Trace">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout used to format log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="WebService">
+    <xs:complexContent>
+      <xs:extension base="Target">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="includeBOM" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="parameter" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="escapeDataNLogLegacy" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="escapeDataRfc3986" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="header" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.MethodCallParameter" />
+          <xs:element name="methodName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="namespace" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="preAuthenticate" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="protocol" minOccurs="0" maxOccurs="1" type="NLog.Targets.WebServiceProtocol" />
+          <xs:element name="url" minOccurs="0" maxOccurs="1" type="xs:anyURI" />
+          <xs:element name="xmlRoot" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="xmlRootNamespace" minOccurs="0" maxOccurs="1" type="xs:string" />
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the target.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeBOM" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Should we include the BOM (Byte-order-mark) for UTF? Influences the  property. This will only work for UTF-8.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Target supports reuse of internal buffers, and doesn't have to constantly allocate new buffers Required for legacy NLog-targets, that expects buffers to remain stable after Write-method exit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="encoding" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Encoding.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="escapeDataNLogLegacy" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Value whether escaping be done according to the old NLog style (Very non-standard)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="escapeDataRfc3986" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Value whether escaping be done according to Rfc3986 (Supports Internationalized Resource Identifiers - IRIs)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="methodName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Web service method name. Only used with Soap.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="namespace" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Web service namespace. Only used with Soap.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="preAuthenticate" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to pre-authenticate the HttpWebRequest (Requires 'Authorization' in  parameters)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="protocol" type="NLog.Targets.WebServiceProtocol">
+          <xs:annotation>
+            <xs:documentation>Protocol to be used when calling web service.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="url" type="xs:anyURI">
+          <xs:annotation>
+            <xs:documentation>Web service URL.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="xmlRoot" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Name of the root XML element, if POST of XML document chosen. If so, this property must not be null. (see  and ).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="xmlRootNamespace" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>(optional) root namespace of the XML document, if POST of XML document chosen. (see  and ).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Targets.WebServiceProtocol">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Soap11" />
+      <xs:enumeration value="Soap12" />
+      <xs:enumeration value="HttpPost" />
+      <xs:enumeration value="HttpGet" />
+      <xs:enumeration value="JsonPost" />
+      <xs:enumeration value="XmlPost" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="CompoundLayout">
+    <xs:complexContent>
+      <xs:extension base="Layout">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="layout" minOccurs="0" maxOccurs="unbounded" type="Layout" />
+        </xs:choice>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Layout">
+    <xs:choice minOccurs="0" maxOccurs="unbounded" />
+  </xs:complexType>
+  <xs:complexType name="CsvLayout">
+    <xs:complexContent>
+      <xs:extension base="Layout">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="column" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.CsvColumn" />
+          <xs:element name="customColumnDelimiter" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="delimiter" minOccurs="0" maxOccurs="1" type="NLog.Layouts.CsvColumnDelimiterMode" />
+          <xs:element name="quoteChar" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="quoting" minOccurs="0" maxOccurs="1" type="NLog.Layouts.CsvQuotingMode" />
+          <xs:element name="withHeader" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer layout.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header layout.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Body layout (can be repeated multiple times).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="customColumnDelimiter" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom').</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="delimiter" type="NLog.Layouts.CsvColumnDelimiterMode">
+          <xs:annotation>
+            <xs:documentation>Column delimiter.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="quoteChar" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Quote Character.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="quoting" type="NLog.Layouts.CsvQuotingMode">
+          <xs:annotation>
+            <xs:documentation>Quoting mode.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="withHeader" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether CVS should include header.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="NLog.Layouts.CsvColumnDelimiterMode">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Auto" />
+      <xs:enumeration value="Comma" />
+      <xs:enumeration value="Semicolon" />
+      <xs:enumeration value="Tab" />
+      <xs:enumeration value="Pipe" />
+      <xs:enumeration value="Space" />
+      <xs:enumeration value="Custom" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="NLog.Layouts.CsvQuotingMode">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="All" />
+      <xs:enumeration value="Nothing" />
+      <xs:enumeration value="Auto" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="NLog.Layouts.CsvColumn">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+      <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+    </xs:choice>
+    <xs:attribute name="layout" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Layout of the column.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="name" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Name of the column.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="JsonLayout">
+    <xs:complexContent>
+      <xs:extension base="Layout">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="attribute" minOccurs="0" maxOccurs="unbounded" type="NLog.Layouts.JsonAttribute" />
+          <xs:element name="excludeProperties" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="renderEmptyObject" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="suppressSpaces" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="excludeProperties" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>List of property names to exclude when  is true</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeAllProperties" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Option to include all properties from the log events</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include contents of the  dictionary.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdlc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include contents of the  dictionary.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="renderEmptyObject" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Option to render the empty object value {}</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="suppressSpaces" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Option to suppress the extra spaces in the output json</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="NLog.Layouts.JsonAttribute">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="encode" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+      <xs:element name="escapeUnicode" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+      <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+      <xs:element name="name" minOccurs="0" maxOccurs="1" type="xs:string" />
+    </xs:choice>
+    <xs:attribute name="encode" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Determines wether or not this attribute will be Json encoded.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="escapeUnicode" type="xs:boolean">
+      <xs:annotation>
+        <xs:documentation>Indicates whether to escape non-ascii characters</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="layout" type="SimpleLayoutAttribute">
+      <xs:annotation>
+        <xs:documentation>Layout that will be rendered as the attribute's value.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="name" type="xs:string">
+      <xs:annotation>
+        <xs:documentation>Name of the attribute.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="LayoutWithHeaderAndFooter">
+    <xs:complexContent>
+      <xs:extension base="Layout">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+        </xs:choice>
+        <xs:attribute name="footer" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Footer layout.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="header" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Header layout.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Body layout (can be repeated multiple times).</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="Log4JXmlEventLayout">
+    <xs:complexContent>
+      <xs:extension base="Layout">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="includeAllProperties" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeMdc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="includeMdlc" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+        </xs:choice>
+        <xs:attribute name="includeAllProperties" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Option to include all properties from the log events</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include contents of the  dictionary.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="includeMdlc" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to include contents of the  dictionary.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="SimpleLayout">
+    <xs:complexContent>
+      <xs:extension base="Layout">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="text" minOccurs="0" maxOccurs="1" type="xs:string" />
+        </xs:choice>
+        <xs:attribute name="text" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Layout text.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="when">
+    <xs:complexContent>
+      <xs:extension base="Filter">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" />
+          <xs:element name="condition" minOccurs="0" maxOccurs="1" type="Condition" />
+        </xs:choice>
+        <xs:attribute name="action" type="FilterResult">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when filter matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="condition" type="Condition">
+          <xs:annotation>
+            <xs:documentation>Condition expression.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:simpleType name="FilterResult">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="Neutral" />
+      <xs:enumeration value="Log" />
+      <xs:enumeration value="Ignore" />
+      <xs:enumeration value="LogFinal" />
+      <xs:enumeration value="IgnoreFinal" />
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:complexType name="whenContains">
+    <xs:complexContent>
+      <xs:extension base="Filter">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" />
+          <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="substring" minOccurs="0" maxOccurs="1" type="xs:string" />
+        </xs:choice>
+        <xs:attribute name="action" type="FilterResult">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when filter matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ignoreCase" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout to be used to filter log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="substring" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Substring to be matched.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="whenEqual">
+    <xs:complexContent>
+      <xs:extension base="Filter">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" />
+          <xs:element name="compareTo" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+        </xs:choice>
+        <xs:attribute name="action" type="FilterResult">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when filter matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="compareTo" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>String to compare the layout to.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ignoreCase" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout to be used to filter log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="whenNotContains">
+    <xs:complexContent>
+      <xs:extension base="Filter">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" />
+          <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="substring" minOccurs="0" maxOccurs="1" type="xs:string" />
+        </xs:choice>
+        <xs:attribute name="action" type="FilterResult">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when filter matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ignoreCase" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout to be used to filter log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="substring" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Substring to be matched.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="whenNotEqual">
+    <xs:complexContent>
+      <xs:extension base="Filter">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" />
+          <xs:element name="compareTo" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="ignoreCase" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+        </xs:choice>
+        <xs:attribute name="action" type="FilterResult">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when filter matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="compareTo" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>String to compare the layout to.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ignoreCase" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Indicates whether to ignore case when comparing strings.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout to be used to filter log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="whenRepeated">
+    <xs:complexContent>
+      <xs:extension base="Filter">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="action" minOccurs="0" maxOccurs="1" type="FilterResult" />
+          <xs:element name="layout" minOccurs="0" maxOccurs="1" type="Layout" />
+          <xs:element name="defaultFilterCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="filterCountMessageAppendFormat" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="filterCountPropertyName" minOccurs="0" maxOccurs="1" type="xs:string" />
+          <xs:element name="maxFilterCacheSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="maxLength" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferDefaultLength" minOccurs="0" maxOccurs="1" type="xs:integer" />
+          <xs:element name="optimizeBufferReuse" minOccurs="0" maxOccurs="1" type="xs:boolean" />
+          <xs:element name="timeoutSeconds" minOccurs="0" maxOccurs="1" type="xs:integer" />
+        </xs:choice>
+        <xs:attribute name="action" type="FilterResult">
+          <xs:annotation>
+            <xs:documentation>Action to be taken when filter matches.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="layout" type="SimpleLayoutAttribute">
+          <xs:annotation>
+            <xs:documentation>Layout to be used to filter log messages.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="defaultFilterCacheSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Default number of unique filter values to expect, will automatically increase if needed</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="filterCountMessageAppendFormat" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Append FilterCount to the  when an event is no longer filtered</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="filterCountPropertyName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>Insert FilterCount value into  when an event is no longer filtered</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxFilterCacheSize" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Max number of unique filter values to expect simultaneously</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="maxLength" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Max length of filter values, will truncate if above limit</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferDefaultLength" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>Default buffer size for the internal buffers</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="optimizeBufferReuse" type="xs:boolean">
+          <xs:annotation>
+            <xs:documentation>Reuse internal buffers, and doesn't have to constantly allocate new buffers</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="timeoutSeconds" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>How long before a filter expires, and logging is accepted again</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="AccurateLocal">
+    <xs:complexContent>
+      <xs:extension base="TimeSource">
+        <xs:choice minOccurs="0" maxOccurs="unbounded" />
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="AccurateUTC">
+    <xs:complexContent>
+      <xs:extension base="TimeSource">
+        <xs:choice minOccurs="0" maxOccurs="unbounded" />
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="FastLocal">
+    <xs:complexContent>
+      <xs:extension base="TimeSource">
+        <xs:choice minOccurs="0" maxOccurs="unbounded" />
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="FastUTC">
+    <xs:complexContent>
+      <xs:extension base="TimeSource">
+        <xs:choice minOccurs="0" maxOccurs="unbounded" />
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+</xs:schema>

+ 36 - 10
Server/App/Program.cs

@@ -10,25 +10,34 @@ namespace App
 		private static void Main(string[] args)
 		{
 			// 异步方法全部会回掉到主线程
-			SynchronizationContext.SetSynchronizationContext(new OneThreadSynchronizationContext());
+			OneThreadSynchronizationContext contex = new OneThreadSynchronizationContext();
+			SynchronizationContext.SetSynchronizationContext(contex);
 
 			try
 			{
-				ObjectEvents.Instance.Register("Model", typeof(Game).Assembly);
-				ObjectEvents.Instance.Register("Hotfix", DllHelper.GetHotfixAssembly());
+				ObjectEvents.Instance.Add("Model", typeof(Game).Assembly);
+				ObjectEvents.Instance.Add("Hotfix", DllHelper.GetHotfixAssembly());
 
 				Options options = Game.Scene.AddComponent<OptionComponent, string[]>(args).Options;
 				StartConfig startConfig = Game.Scene.AddComponent<StartConfigComponent, string, int>(options.Config, options.AppId).StartConfig;
 
+				if (!options.AppType.Is(startConfig.AppType))
+				{
+					Log.Error("命令行参数apptype与配置不一致");
+					return;
+				}
+
 				IdGenerater.AppId = options.AppId;
 
 				LogManager.Configuration.Variables["appType"] = startConfig.AppType.ToString();
 				LogManager.Configuration.Variables["appId"] = startConfig.AppId.ToString();
+				LogManager.Configuration.Variables["appTypeFormat"] = $"{startConfig.AppType,-8}";
+				LogManager.Configuration.Variables["appIdFormat"] = $"{startConfig.AppId:D3}";
 
 				Log.Info("server start........................");
 
 				Game.Scene.AddComponent<OpcodeTypeComponent>();
-				Game.Scene.AddComponent<MessageDispatherComponent, AppType>(startConfig.AppType);
+				Game.Scene.AddComponent<MessageDispatherComponent>();
 
 				// 根据不同的AppType添加不同的组件
 				OuterConfig outerConfig = startConfig.GetComponent<OuterConfig>();
@@ -44,34 +53,51 @@ namespace App
 					case AppType.Realm:
 						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
 						Game.Scene.AddComponent<ActorManagerComponent>();
-						Game.Scene.AddComponent<ActorComponent>();
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
+						Game.Scene.AddComponent<LocationProxyComponent>();
 						Game.Scene.AddComponent<RealmGateAddressComponent>();
 						break;
 					case AppType.Gate:
+						Game.Scene.AddComponent<PlayerComponent>();
 						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
 						Game.Scene.AddComponent<ActorManagerComponent>();
-						Game.Scene.AddComponent<ActorComponent>();
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
+						Game.Scene.AddComponent<LocationProxyComponent>();
+						Game.Scene.AddComponent<ActorProxyComponent>();
 						Game.Scene.AddComponent<GateSessionKeyComponent>();
 						break;
 					case AppType.Location:
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<LocationComponent>();
 						break;
+					case AppType.Map:
+						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
+						Game.Scene.AddComponent<ActorManagerComponent>();
+						Game.Scene.AddComponent<UnitComponent>();
+						Game.Scene.AddComponent<LocationProxyComponent>();
+						Game.Scene.AddComponent<ActorProxyComponent>();
+						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
+						Game.Scene.AddComponent<ServerFrameComponent>();
+						break;
 					case AppType.AllServer:
+						Game.Scene.AddComponent<ActorProxyComponent>();
+						Game.Scene.AddComponent<PlayerComponent>();
+						Game.Scene.AddComponent<UnitComponent>();
+						Game.Scene.AddComponent<DBComponent>();
+						Game.Scene.AddComponent<DBProxyComponent>();
 						Game.Scene.AddComponent<LocationComponent>();
 						Game.Scene.AddComponent<ActorMessageDispatherComponent>();
+						Game.Scene.AddComponent<ActorManagerComponent>();
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
-						Game.Scene.AddComponent<AppManagerComponent>();
 						Game.Scene.AddComponent<LocationProxyComponent>();
-						Game.Scene.AddComponent<ActorManagerComponent>();
-						Game.Scene.AddComponent<ActorComponent>();
+						Game.Scene.AddComponent<AppManagerComponent>();
 						Game.Scene.AddComponent<RealmGateAddressComponent>();
 						Game.Scene.AddComponent<GateSessionKeyComponent>();
+						Game.Scene.AddComponent<ConfigComponent>();
+						Game.Scene.AddComponent<ServerFrameComponent>();
 						break;
 					case AppType.Benchmark:
 						Game.Scene.AddComponent<NetOuterComponent>();
@@ -86,7 +112,7 @@ namespace App
 					try
 					{
 						Thread.Sleep(1);
-						Game.Poller.Update();
+						contex.Update();
 						ObjectEvents.Instance.Update();
 					}
 					catch (Exception e)

+ 0 - 35
Server/App/Properties/AssemblyInfo.cs

@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("Server.App")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Server.App")]
-[assembly: AssemblyCopyright("Copyright ©  2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-//将 ComVisible 设置为 false 将使此程序集中的类型
-//对 COM 组件不可见。  如果需要从 COM 访问此程序集中的类型,
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("3f8dc04c-9e05-403f-b6a5-36293eb99937")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
-// 方法是按如下所示使用“*”: :
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 8 - 0
Server/App/Properties/launchSettings.json

@@ -0,0 +1,8 @@
+{
+  "profiles": {
+    "Server.App": {
+      "commandName": "Project",
+      "workingDirectory": "../../netcoreapp2.0"
+    }
+  }
+}

+ 20 - 63
Server/App/Server.App.csproj

@@ -1,77 +1,34 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{3F8DC04C-9E05-403F-B6A5-36293EB99937}</ProjectGuid>
     <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>App</RootNamespace>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
     <AssemblyName>App</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <RootNamespace>App</RootNamespace>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\Bin\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;SERVER</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DefineConstants>TRACE;DEBUG;NETCOREAPP2_0;SERVER</DefineConstants>
+    <OutputPath>..\..\</OutputPath>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\Bin\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <DefineConstants>TRACE;RELEASE;NETCOREAPP2_0;SERVER</DefineConstants>
+    <OutputPath>..\..\</OutputPath>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="MongoDB.Bson, Version=2.3.0.157, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\Lib\MongoDB.Bson.dll</HintPath>
-    </Reference>
-    <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\Lib\NLog.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
+    <PackageReference Include="NLog" Version="5.0.0-beta11" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="App.config" />
+    <ProjectReference Include="..\Model\Server.Model.csproj" />
   </ItemGroup>
+
   <ItemGroup>
-    <None Include="NLog.config">
+    <None Update="NLog.config">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Base\Server.Base.csproj">
-      <Project>{e5078ec6-2b0e-4711-be8b-d99f69638316}</Project>
-      <Name>Server.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Model\Server.Model.csproj">
-      <Project>{820d3488-76b9-4ee8-872a-be06c2350b20}</Project>
-      <Name>Server.Model</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
+
+</Project>

+ 0 - 7
Server/App/Server.App.csproj.user

@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
-    <StartArguments>--appId=1 --appType=AllServer --config=../Config/StartConfig/LocalAllServer.txt</StartArguments>
-    <StartAction>Project</StartAction>
-  </PropertyGroup>
-</Project>

+ 0 - 144
Server/Base/DoubleMap.cs

@@ -1,144 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Model
-{
-	public class DoubleMap<K, V>
-	{
-		private readonly Dictionary<K, V> kv = new Dictionary<K, V>();
-		private readonly Dictionary<V, K> vk = new Dictionary<V, K>();
-
-		public DoubleMap()
-		{
-		}
-
-		public DoubleMap(int capacity)
-		{
-			kv = new Dictionary<K, V>(capacity);
-			vk = new Dictionary<V, K>(capacity);
-		}
-
-		public void ForEach(Action<K, V> action)
-		{
-			if (action == null)
-			{
-				return;
-			}
-			Dictionary<K, V>.KeyCollection keys = kv.Keys;
-			foreach (K key in keys)
-			{
-				action(key, kv[key]);
-			}
-		}
-
-		public List<K> Keys
-		{
-			get
-			{
-				return new List<K>(kv.Keys);
-			}
-		}
-
-		public List<V> Values
-		{
-			get
-			{
-				return new List<V>(vk.Keys);
-			}
-		}
-
-		public void Add(K key, V value)
-		{
-			if (key == null || value == null || kv.ContainsKey(key) || vk.ContainsKey(value))
-			{
-				return;
-			}
-			kv.Add(key, value);
-			vk.Add(value, key);
-		}
-
-		public V GetValueByKey(K key)
-		{
-			if (key != null && kv.ContainsKey(key))
-			{
-				return kv[key];
-			}
-			return default(V);
-		}
-
-		public K GetKeyByValue(V value)
-		{
-			if (value != null && vk.ContainsKey(value))
-			{
-				return vk[value];
-			}
-			return default(K);
-		}
-
-		public void RemoveByKey(K key)
-		{
-			if (key == null)
-			{
-				return;
-			}
-			V value;
-			if (!kv.TryGetValue(key, out value))
-			{
-				return;
-			}
-
-			kv.Remove(key);
-			vk.Remove(value);
-		}
-
-		public void RemoveByValue(V value)
-		{
-			if (value == null)
-			{
-				return;
-			}
-
-			K key;
-			if (!vk.TryGetValue(value, out key))
-			{
-				return;
-			}
-
-			kv.Remove(key);
-			vk.Remove(value);
-		}
-
-		public void Clear()
-		{
-			kv.Clear();
-			vk.Clear();
-		}
-
-		public bool ContainsKey(K key)
-		{
-			if (key == null)
-			{
-				return false;
-			}
-			return kv.ContainsKey(key);
-		}
-
-		public bool ContainsValue(V value)
-		{
-			if (value == null)
-			{
-				return false;
-			}
-			return vk.ContainsKey(value);
-		}
-
-		public bool Contains(K key, V value)
-		{
-			if (key == null || value == null)
-			{
-				return false;
-			}
-			return kv.ContainsKey(key) && vk.ContainsKey(value);
-		}
-	}
-}

+ 0 - 12
Server/Base/Helper/ArrayHelper.cs

@@ -1,12 +0,0 @@
-namespace Model
-{
-	public static class ObjectHelper
-	{
-		public static void Swap<T>(ref T t1, ref T t2)
-		{
-			T t3 = t1;
-			t1 = t2;
-			t2 = t3;
-		}
-	}
-}

+ 0 - 64
Server/Base/Helper/ByteHelper.cs

@@ -1,64 +0,0 @@
-using System;
-using System.Text;
-
-namespace Model
-{
-	public static class ByteHelper
-	{
-		public static string ToHex(this byte b)
-		{
-			return b.ToString("X2");
-		}
-
-		public static string ToHex(this byte[] bytes)
-		{
-			StringBuilder stringBuilder = new StringBuilder();
-			foreach (byte b in bytes)
-			{
-				stringBuilder.Append(b.ToString("X2"));
-			}
-			return stringBuilder.ToString();
-		}
-
-		public static string ToHex(this byte[] bytes, string format)
-		{
-			StringBuilder stringBuilder = new StringBuilder();
-			foreach (byte b in bytes)
-			{
-				stringBuilder.Append(b.ToString(format));
-			}
-			return stringBuilder.ToString();
-		}
-
-		public static string ToHex(this byte[] bytes, int offset, int count)
-		{
-			StringBuilder stringBuilder = new StringBuilder();
-			for (int i = offset; i < offset + count; ++i)
-			{
-				stringBuilder.Append(bytes[i].ToString("X2"));
-			}
-			return stringBuilder.ToString();
-		}
-
-		public static string ToStr(this byte[] bytes)
-		{
-			return Encoding.Default.GetString(bytes);
-		}
-
-		public static string ToStr(this byte[] bytes, int offset, int count)
-		{
-			return Encoding.Default.GetString(bytes, offset, count);
-		}
-
-		public static string Utf8ToStr(this byte[] bytes, int offset, int count)
-		{
-			return Encoding.UTF8.GetString(bytes, offset, count);
-		}
-
-		public static byte[] Reverse(this byte[] bytes)
-		{
-			Array.Reverse(bytes);
-			return bytes;
-		}
-	}
-}

+ 0 - 30
Server/Base/Helper/EnumHelper.cs

@@ -1,30 +0,0 @@
-using System;
-
-namespace Model
-{
-	public static class EnumHelper
-	{
-		public static int EnumIndex<T>(int value)
-		{
-			int i = 0;
-			foreach (object v in Enum.GetValues(typeof (T)))
-			{
-				if ((int) v == value)
-				{
-					return i;
-				}
-				++i;
-			}
-			return -1;
-		}
-
-		public static T FromString<T>(string str)
-		{
-            if (!Enum.IsDefined(typeof(T), str))
-            {
-                return default(T);
-            }
-            return (T)Enum.Parse(typeof(T), str);
-        }
-    }
-}

+ 0 - 56
Server/Base/Helper/FileHelper.cs

@@ -1,56 +0,0 @@
-using System;
-using System.IO;
-
-namespace Model
-{
-	public static class FileHelper
-	{
-		public static void CleanDirectory(string dir)
-		{
-			foreach (string subdir in Directory.GetDirectories(dir))
-			{
-				Directory.Delete(subdir, true);		
-			}
-
-			foreach (string subFile in Directory.GetFiles(dir))
-			{
-				File.Delete(subFile);
-			}
-		}
-
-		public static void CopyDirectory(string srcDir, string tgtDir)
-		{
-			DirectoryInfo source = new DirectoryInfo(srcDir);
-			DirectoryInfo target = new DirectoryInfo(tgtDir);
-	
-			if (target.FullName.StartsWith(source.FullName, StringComparison.CurrentCultureIgnoreCase))
-			{
-				throw new Exception("父目录不能拷贝到子目录!");
-			}
-	
-			if (!source.Exists)
-			{
-				return;
-			}
-	
-			if (!target.Exists)
-			{
-				target.Create();
-			}
-	
-			FileInfo[] files = source.GetFiles();
-	
-			for (int i = 0; i < files.Length; i++)
-			{
-				File.Copy(files[i].FullName, target.FullName + @"\" + files[i].Name, true);
-			}
-	
-			DirectoryInfo[] dirs = source.GetDirectories();
-	
-			for (int j = 0; j < dirs.Length; j++)
-			{
-				CopyDirectory(dirs[j].FullName, target.FullName + @"\" + dirs[j].Name);
-			}
-		}
-	}
-}

+ 0 - 16
Server/Base/Helper/IdGenerater.cs

@@ -1,16 +0,0 @@
-namespace Model
-{
-	public static class IdGenerater
-	{
-		public static long AppId { private get; set; }
-
-		private static ushort value;
-
-		public static long GenerateId()
-		{
-			long time = TimeHelper.ClientNowSeconds();
-
-			return (AppId << 48) + (time << 16) + ++value;
-		}
-	}
-}

+ 0 - 19
Server/Base/Helper/MD5Helper.cs

@@ -1,19 +0,0 @@
-using System.IO;
-using System.Security.Cryptography;
-
-namespace Model
-{
-	public static class MD5Helper
-	{
-		public static string FileMD5(string filePath)
-		{
-			byte[] retVal;
-            using (FileStream file = new FileStream(filePath, FileMode.Open))
-			{
-				MD5 md5 = new MD5CryptoServiceProvider();
-				retVal = md5.ComputeHash(file);
-			}
-			return retVal.ToHex("x2");
-		}
-	}
-}

+ 0 - 26
Server/Base/Helper/MethodInfoHelper.cs

@@ -1,26 +0,0 @@
-using System.Reflection;
-
-namespace Model
-{
-	public static class MethodInfoHelper
-	{
-		public static void Run(this MethodInfo methodInfo, object obj, params object[] param)
-		{
-
-			if (methodInfo.IsStatic)
-			{
-				object[] p = new object[param.Length + 1];
-				p[0] = obj;
-				for (int i = 0; i < param.Length; ++i)
-				{
-					p[i + 1] = param[i];
-				}
-				methodInfo.Invoke(null, p);
-			}
-			else
-			{
-				methodInfo.Invoke(obj, param);
-			}
-		}
-	}
-}

+ 0 - 67
Server/Base/Helper/MongoHelper.cs

@@ -1,67 +0,0 @@
-using System;
-using System.IO;
-using MongoDB.Bson;
-using MongoDB.Bson.IO;
-using MongoDB.Bson.Serialization;
-
-namespace Model
-{
-	public static class MongoHelper
-	{
-		public static string ToJson(object obj)
-		{
-			return obj.ToJson();
-		}
-
-		public static string ToJson(object obj, JsonWriterSettings settings)
-		{
-			return obj.ToJson(settings);
-		}
-
-		public static T FromJson<T>(string str)
-		{
-			return BsonSerializer.Deserialize<T>(str);
-		}
-
-		public static object FromJson(Type type, string str)
-		{
-			return BsonSerializer.Deserialize(str, type);
-		}
-
-		public static byte[] ToBson(object obj)
-		{
-			return obj.ToBson();
-		}
-
-		public static object FromBson(Type type, byte[] bytes)
-		{
-			return BsonSerializer.Deserialize(bytes, type);
-		}
-
-		public static object FromBson(Type type, byte[] bytes, int index, int count)
-		{
-			using (MemoryStream memoryStream = new MemoryStream(bytes, index, count))
-			{
-				return BsonSerializer.Deserialize(memoryStream, type);
-			}
-		}
-
-		public static T FromBson<T>(byte[] bytes)
-		{
-			using (MemoryStream memoryStream = new MemoryStream(bytes))
-			{
-				return (T) BsonSerializer.Deserialize(memoryStream, typeof (T));
-			}
-		}
-
-		public static T FromBson<T>(byte[] bytes, int index, int count)
-		{
-			return (T) FromBson(typeof (T), bytes, index, count);
-		}
-
-		public static T Clone<T>(T t)
-		{
-			return FromBson<T>(ToBson(t));
-		}
-	}
-}

+ 0 - 22
Server/Base/Helper/NetHelper.cs

@@ -1,22 +0,0 @@
-using System.Collections.Generic;
-using System.Net;
-
-namespace Model
-{
-	public static class NetHelper
-	{
-		public static string[] GetAddressIPs()
-		{
-			//获取本地的IP地址
-			List<string> addressIPs = new List<string>();
-			foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
-			{
-				if (address.AddressFamily.ToString() == "InterNetwork")
-				{
-					addressIPs.Add(address.ToString());
-				}
-			}
-			return addressIPs.ToArray();
-		}
-	}
-}

+ 0 - 83
Server/Base/Helper/ProtobufHelper.cs

@@ -1,83 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.IO;
-using ProtoBuf;
-
-namespace Model
-{
-	public static class ProtobufHelper
-	{
-		public static byte[] ToBytes(object message)
-		{
-			using (MemoryStream ms = new MemoryStream())
-			{
-				Serializer.Serialize(ms, message);
-				return ms.ToArray();
-			}
-		}
-
-		public static T FromBytes<T>(byte[] bytes)
-		{
-			T t;
-			using (MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length))
-			{
-				t = Serializer.Deserialize<T>(ms);
-			}
-			ISupportInitialize iSupportInitialize = t as ISupportInitialize;
-			if (iSupportInitialize == null)
-			{
-				return t;
-			}
-			iSupportInitialize.EndInit();
-			return t;
-		}
-
-		public static T FromBytes<T>(byte[] bytes, int index, int length)
-		{
-			T t;
-			using (MemoryStream ms = new MemoryStream(bytes, index, length))
-			{
-				t = Serializer.Deserialize<T>(ms);
-			}
-			ISupportInitialize iSupportInitialize = t as ISupportInitialize;
-			if (iSupportInitialize == null)
-			{
-				return t;
-			}
-			iSupportInitialize.EndInit();
-			return t;
-		}
-
-		public static object FromBytes(Type type, byte[] bytes)
-		{
-			object t;
-			using (MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length))
-			{
-				t = Serializer.NonGeneric.Deserialize(type, ms);
-			}
-			ISupportInitialize iSupportInitialize = t as ISupportInitialize;
-			if (iSupportInitialize == null)
-			{
-				return t;
-			}
-			iSupportInitialize.EndInit();
-			return t;
-		}
-
-		public static object FromBytes(Type type, byte[] bytes, int index, int length)
-		{
-			object t;
-			using (MemoryStream ms = new MemoryStream(bytes, index, length))
-			{
-				t = Serializer.NonGeneric.Deserialize(type, ms);
-			}
-			ISupportInitialize iSupportInitialize = t as ISupportInitialize;
-			if (iSupportInitialize == null)
-			{
-				return t;
-			}
-			iSupportInitialize.EndInit();
-			return t;
-		}
-	}
-}

+ 0 - 35
Server/Base/Helper/RandomHelper.cs

@@ -1,35 +0,0 @@
-using System;
-
-namespace Model
-{
-	public static class RandomHelper
-	{
-		private static readonly Random random = new Random();
-
-		public static UInt64 RandUInt64()
-		{
-			var bytes = new byte[8];
-			random.NextBytes(bytes);
-			return BitConverter.ToUInt64(bytes, 0);
-		}
-
-		public static Int64 RandInt64()
-		{
-			var bytes = new byte[8];
-			random.NextBytes(bytes);
-			return BitConverter.ToInt64(bytes, 0);
-		}
-
-		/// <summary>
-		/// 获取lower与Upper之间的随机数
-		/// </summary>
-		/// <param name="lower"></param>
-		/// <param name="upper"></param>
-		/// <returns></returns>
-		public static int RandomNumber(int lower, int upper)
-		{
-			int value = random.Next(lower, upper);
-			return value;
-		}
-	}
-}

+ 0 - 62
Server/Base/Helper/StringHelper.cs

@@ -1,62 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Text;
-
-namespace Model
-{
-	public static class StringHelper
-	{
-		public static IEnumerable<byte> ToBytes(this string str)
-		{
-			byte[] byteArray = Encoding.Default.GetBytes(str);
-			return byteArray;
-		}
-
-		public static byte[] ToByteArray(this string str)
-		{
-			byte[] byteArray = Encoding.Default.GetBytes(str);
-			return byteArray;
-		}
-
-	    public static byte[] ToUtf8(this string str)
-	    {
-            byte[] byteArray = Encoding.UTF8.GetBytes(str);
-            return byteArray;
-        }
-
-		public static byte[] HexToBytes(this string hexString)
-		{
-			if (hexString.Length % 2 != 0)
-			{
-				throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
-			}
-
-			var hexAsBytes = new byte[hexString.Length / 2];
-			for (int index = 0; index < hexAsBytes.Length; index++)
-			{
-				string byteValue = "";
-				byteValue += hexString[index * 2];
-				byteValue += hexString[index * 2 + 1];
-				hexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
-			}
-			return hexAsBytes;
-		}
-
-		public static string Fmt(this string text, params object[] args)
-		{
-			return string.Format(text, args);
-		}
-
-		public static string ListToString<T>(this List<T> list)
-		{
-			StringBuilder sb = new StringBuilder();
-			foreach (T t in list)
-			{
-				sb.Append(t);
-				sb.Append(",");
-			}
-			return sb.ToString();
-		}
-	}
-}

+ 0 - 36
Server/Base/Helper/TimeHelper.cs

@@ -1,36 +0,0 @@
-using System;
-
-namespace Model
-{
-	public static class TimeHelper
-	{
-		private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-		/// <summary>
-		/// 客户端时间
-		/// </summary>
-		/// <returns></returns>
-		public static long ClientNow()
-		{
-			return Convert.ToInt64((DateTime.UtcNow - epoch).TotalMilliseconds);
-		}
-
-		public static long ClientNowSeconds()
-		{
-			return Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds);
-		}
-
-		public static long ClientNowTicks()
-		{	
-			return Convert.ToInt64((DateTime.UtcNow - epoch).Ticks);
-		}
-
-		/// <summary>
-		/// 登陆前是客户端时间,登陆后是同步过的服务器时间
-		/// </summary>
-		/// <returns></returns>
-		public static long Now()
-		{
-			return ClientNow();
-		}
-    }
-}

+ 0 - 97
Server/Base/Helper/ZipHelper.cs

@@ -1,97 +0,0 @@
-using System.IO;
-using ICSharpCode.SharpZipLib.Zip.Compression;
-
-namespace Model
-{
-	public static class ZipHelper
-	{
-		public static byte[] Compress(byte[] content)
-		{
-			//return content;
-			Deflater compressor = new Deflater();
-			compressor.SetLevel(Deflater.BEST_COMPRESSION);
-
-			compressor.SetInput(content);
-			compressor.Finish();
-
-			using (MemoryStream bos = new MemoryStream(content.Length))
-			{
-				var buf = new byte[1024];
-				while (!compressor.IsFinished)
-				{
-					int n = compressor.Deflate(buf);
-					bos.Write(buf, 0, n);
-				}
-				return bos.ToArray();
-			}
-		}
-
-		public static byte[] Decompress(byte[] content)
-		{
-			return Decompress(content, 0, content.Length);
-		}
-
-		public static byte[] Decompress(byte[] content, int offset, int count)
-		{
-			//return content;
-			Inflater decompressor = new Inflater();
-			decompressor.SetInput(content, offset, count);
-
-			using (MemoryStream bos = new MemoryStream(content.Length))
-			{
-				var buf = new byte[1024];
-				while (!decompressor.IsFinished)
-				{
-					int n = decompressor.Inflate(buf);
-					bos.Write(buf, 0, n);
-				}
-				return bos.ToArray();
-			}
-		}
-	}
-}
-
-/*
-using System.IO;
-using System.IO.Compression;
-
-namespace Model
-{
-	public static class ZipHelper
-	{
-		public static byte[] Compress(byte[] content)
-		{
-			using (MemoryStream ms = new MemoryStream())
-			using (DeflateStream stream = new DeflateStream(ms, CompressionMode.Compress, true))
-			{
-				stream.Write(content, 0, content.Length);
-				return ms.ToArray();
-			}
-		}
-
-		public static byte[] Decompress(byte[] content)
-		{
-			return Decompress(content, 0, content.Length);
-		}
-
-		public static byte[] Decompress(byte[] content, int offset, int count)
-		{
-			using (MemoryStream ms = new MemoryStream())
-			using (DeflateStream stream = new DeflateStream(new MemoryStream(content, offset, count), CompressionMode.Decompress, true))
-			{
-				byte[] buffer = new byte[1024];
-				while (true)
-				{
-					int bytesRead = stream.Read(buffer, 0, 1024);
-					if (bytesRead == 0)
-					{
-						break;
-					}
-					ms.Write(buffer, 0, bytesRead);
-				}
-				return ms.ToArray();
-			}
-		}
-	}
-}
-*/

+ 1 - 1
Server/Base/Logger/NLogAdapter.cs

@@ -4,7 +4,7 @@ namespace Model
 {
 	public class NLogAdapter: ALogDecorater, ILog
 	{
-		private readonly Logger logger = LogManager.GetCurrentClassLogger();
+		private readonly Logger logger = LogManager.GetLogger("Logger");
 
 		public NLogAdapter(ALogDecorater decorater = null): base(decorater)
 		{

+ 0 - 111
Server/Base/MultiMap.cs

@@ -1,111 +0,0 @@
-using System.Collections.Generic;
-
-namespace Model
-{
-	public class MultiMap<T, K>
-	{
-		private readonly SortedDictionary<T, List<K>> dictionary = new SortedDictionary<T, List<K>>();
-
-		public SortedDictionary<T, List<K>>.KeyCollection Keys
-		{
-			get
-			{
-				return this.dictionary.Keys;
-			}
-		}
-
-		public void Add(T t, K k)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				list = new List<K>();
-			}
-			list.Add(k);
-			this.dictionary[t] = list;
-		}
-
-		public bool Remove(T t, K k)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				return false;
-			}
-			if (!list.Remove(k))
-			{
-				return false;
-			}
-			if (list.Count == 0)
-			{
-				this.dictionary.Remove(t);
-			}
-			return true;
-		}
-
-		public bool Remove(T t)
-		{
-			return this.dictionary.Remove(t);
-		}
-
-		/// <summary>
-		/// 不返回内部的list,copy一份出来
-		/// </summary>
-		/// <param name="t"></param>
-		/// <returns></returns>
-		public K[] GetAll(T t)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				return new K[0];
-			}
-			var newList = new List<K>();
-			foreach (K k in list)
-			{
-				newList.Add(k);
-			}
-			return newList.ToArray();
-		}
-
-		/// <summary>
-		/// 返回内部的list
-		/// </summary>
-		/// <param name="t"></param>
-		/// <returns></returns>
-		public List<K> this[T t]
-		{
-			get
-			{
-				List<K> list;
-				this.dictionary.TryGetValue(t, out list);
-				return list;
-			}
-		}
-
-		public K GetOne(T t)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if ((list != null) && (list.Count > 0))
-			{
-				return list[0];
-			}
-			return default(K);
-		}
-
-		public bool Contains(T t, K k)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				return false;
-			}
-			return list.Contains(k);
-		}
-	}
-}

+ 0 - 84
Server/Base/Network/AChannel.cs

@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	[Flags]
-	public enum PacketFlags
-	{
-		None = 0,
-		Reliable = 1 << 0,
-		Unsequenced = 1 << 1,
-		NoAllocate = 1 << 2
-	}
-
-	public enum ChannelType
-	{
-		Connect,
-		Accept,
-	}
-
-	public abstract class AChannel: IDisposable
-	{
-		public long Id { get; private set; }
-
-		public ChannelType ChannelType { get; }
-
-		protected AService service;
-
-		public string RemoteAddress { get; protected set; }
-
-		private event Action<AChannel, SocketError> errorCallback;
-
-		public event Action<AChannel, SocketError> ErrorCallback
-		{
-			add
-			{
-				this.errorCallback += value;
-			}
-			remove
-			{
-				this.errorCallback -= value;
-			}
-		}
-
-		protected void OnError(AChannel channel, SocketError e)
-		{
-			this.errorCallback(channel, e);
-		}
-
-
-		protected AChannel(AService service, ChannelType channelType)
-		{
-			this.Id = IdGenerater.GenerateId();
-			this.ChannelType = channelType;
-			this.service = service;
-		}
-		
-		/// <summary>
-		/// 发送消息
-		/// </summary>
-		public abstract void Send(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable);
-
-		public abstract void Send(List<byte[]> buffers, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable);
-
-		/// <summary>
-		/// 接收消息
-		/// </summary>
-		public abstract Task<byte[]> Recv();
-
-		public virtual void Dispose()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-
-			this.service.Remove(this.Id);
-
-			this.Id = 0;
-		}
-	}
-}

+ 0 - 32
Server/Base/Network/AService.cs

@@ -1,32 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	public enum NetworkProtocol
-	{
-		TCP,
-		UDP
-	}
-
-	public abstract class AService: IDisposable
-	{
-		/// <summary>
-		/// 将函数调用加入IService线程
-		/// </summary>
-		/// <param name="action"></param>
-		public abstract void Add(Action action);
-
-		public abstract AChannel GetChannel(long id);
-
-		public abstract Task<AChannel> AcceptChannel();
-
-		public abstract AChannel ConnectChannel(string host, int port);
-
-		public abstract void Remove(long channelId);
-
-		public abstract void Update();
-
-		public abstract void Dispose();
-	}
-}

+ 0 - 84
Server/Base/Network/TNet/PacketParser.cs

@@ -1,84 +0,0 @@
-using System;
-
-namespace Model
-{
-	internal enum ParserState
-	{
-		PacketSize,
-		PacketBody
-	}
-
-	internal class PacketParser
-	{
-		private readonly TBuffer buffer;
-
-		private uint packetSize;
-		private readonly byte[] packetSizeBuffer = new byte[4];
-		private ParserState state;
-		private byte[] packet;
-		private bool isOK;
-
-		public PacketParser(TBuffer buffer)
-		{
-			this.buffer = buffer;
-		}
-
-		private void Parse()
-		{
-			if (this.isOK)
-			{
-				return;
-			}
-
-			bool finish = false;
-			while (!finish)
-			{
-				switch (this.state)
-				{
-					case ParserState.PacketSize:
-						if (this.buffer.Count < 4)
-						{
-							finish = true;
-						}
-						else
-						{
-							this.buffer.RecvFrom(this.packetSizeBuffer);
-							this.packetSize = BitConverter.ToUInt32(this.packetSizeBuffer, 0);
-							if (packetSize > 1024 * 1024)
-							{
-								throw new Exception($"packet too large, size: {this.packetSize}");
-							}
-							this.state = ParserState.PacketBody;
-						}
-						break;
-					case ParserState.PacketBody:
-						if (this.buffer.Count < this.packetSize)
-						{
-							finish = true;
-						}
-						else
-						{
-							this.packet = new byte[this.packetSize];
-							this.buffer.RecvFrom(this.packet);
-							this.isOK = true;
-							this.state = ParserState.PacketSize;
-							finish = true;
-						}
-						break;
-				}
-			}
-		}
-
-		public byte[] GetPacket()
-		{
-			this.Parse();
-			if (!this.isOK)
-			{
-				return null;
-			}
-			byte[] result = this.packet;
-			this.isOK = false;
-			return result;
-		}
-	}
-}

+ 0 - 129
Server/Base/Network/TNet/TBuffer.cs

@@ -1,129 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Model
-{
-	public class TBuffer
-	{
-		public const int ChunkSize = 8192;
-
-		private readonly LinkedList<byte[]> bufferList = new LinkedList<byte[]>();
-
-		public int LastIndex { get; set; }
-
-		public int FirstIndex { get; set; }
-
-		public TBuffer()
-		{
-			this.bufferList.AddLast(new byte[ChunkSize]);
-		}
-
-		public int Count
-		{
-			get
-			{
-				int c = 0;
-				if (this.bufferList.Count == 0)
-				{
-					c = 0;
-				}
-				else
-				{
-					c = (this.bufferList.Count - 1) * ChunkSize + this.LastIndex - this.FirstIndex;
-				}
-				if (c < 0)
-				{
-					Log.Error("TBuffer count < 0: {0}, {1}, {2}".Fmt(bufferList.Count, this.LastIndex, this.FirstIndex));
-				}
-				return c;
-			}
-		}
-
-		public void AddLast()
-		{
-			this.bufferList.AddLast(new byte[ChunkSize]);
-		}
-
-		public void RemoveFirst()
-		{
-			this.bufferList.RemoveFirst();
-		}
-
-		public byte[] First
-		{
-			get
-			{
-				if (this.bufferList.First == null)
-				{
-					this.AddLast();
-				}
-				return this.bufferList.First.Value;
-			}
-		}
-
-		public byte[] Last
-		{
-			get
-			{
-				if (this.bufferList.Last == null)
-				{
-					this.AddLast();
-				}
-				return this.bufferList.Last.Value;
-			}
-		}
-
-		public void RecvFrom(byte[] buffer)
-		{
-			if (this.Count < buffer.Length || buffer.Length == 0)
-			{
-				throw new Exception($"bufferList size < n, bufferList: {this.Count} buffer length: {buffer.Length}");
-			}
-			int alreadyCopyCount = 0;
-			while (alreadyCopyCount < buffer.Length)
-			{
-				int n = buffer.Length - alreadyCopyCount;
-				if (ChunkSize - this.FirstIndex > n)
-				{
-					Array.Copy(this.bufferList.First.Value, this.FirstIndex, buffer, alreadyCopyCount, n);
-					this.FirstIndex += n;
-					alreadyCopyCount += n;
-				}
-				else
-				{
-					Array.Copy(this.bufferList.First.Value, this.FirstIndex, buffer, alreadyCopyCount, ChunkSize - this.FirstIndex);
-					alreadyCopyCount += ChunkSize - this.FirstIndex;
-					this.FirstIndex = 0;
-					this.bufferList.RemoveFirst();
-				}
-			}
-		}
-
-		public void SendTo(byte[] buffer)
-		{
-			int alreadyCopyCount = 0;
-			while (alreadyCopyCount < buffer.Length)
-			{
-				if (this.LastIndex == ChunkSize)
-				{
-					this.bufferList.AddLast(new byte[ChunkSize]);
-					this.LastIndex = 0;
-				}
-
-				int n = buffer.Length - alreadyCopyCount;
-				if (ChunkSize - this.LastIndex > n)
-				{
-					Array.Copy(buffer, alreadyCopyCount, this.bufferList.Last.Value, this.LastIndex, n);
-					this.LastIndex += buffer.Length - alreadyCopyCount;
-					alreadyCopyCount += n;
-				}
-				else
-				{
-					Array.Copy(buffer, alreadyCopyCount, this.bufferList.Last.Value, this.LastIndex, ChunkSize - this.LastIndex);
-					alreadyCopyCount += ChunkSize - this.LastIndex;
-					this.LastIndex = ChunkSize;
-				}
-			}
-		}
-	}
-}

+ 0 - 245
Server/Base/Network/TNet/TChannel.cs

@@ -1,245 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	public class TChannel : AChannel
-	{
-		private readonly TSocket socket;
-
-		private readonly TBuffer recvBuffer = new TBuffer();
-		private readonly TBuffer sendBuffer = new TBuffer();
-
-		private bool isSending;
-		private readonly PacketParser parser;
-		private bool isConnected;
-		private TaskCompletionSource<byte[]> recvTcs;
-
-		/// <summary>
-		/// connect
-		/// </summary>
-		public TChannel(TSocket socket, string host, int port, TService service) : base(service, ChannelType.Connect)
-		{
-			this.socket = socket;
-			this.parser = new PacketParser(this.recvBuffer);
-			this.RemoteAddress = host + ":" + port;
-			
-			bool result = this.socket.ConnectAsync(host, port);
-			if (!result)
-			{
-				this.OnConnected(this.Id, SocketError.Success);
-				return;
-			}
-			this.socket.OnConn += e => OnConnected(this.Id, e);
-		}
-
-		/// <summary>
-		/// accept
-		/// </summary>
-		public TChannel(TSocket socket, TService service) : base(service, ChannelType.Accept)
-		{
-			this.socket = socket;
-			this.parser = new PacketParser(this.recvBuffer);
-			this.RemoteAddress = socket.RemoteAddress;
-			this.OnAccepted();
-		}
-
-		public override void Dispose()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-
-			long id = this.Id;
-
-			base.Dispose();
-
-			this.socket.Dispose();
-			this.service.Remove(id);
-		}
-
-		private void OnAccepted()
-		{
-			this.isConnected = true;
-			this.StartSend();
-			this.StartRecv();
-		}
-
-		private void OnConnected(long channelId, SocketError error)
-		{
-			if (this.service.GetChannel(channelId) == null)
-			{
-				return;
-			}
-			if (error != SocketError.Success)
-			{
-				Log.Error($"connect error: {error}");
-				return;
-			}
-			this.isConnected = true;
-			this.StartSend();
-			this.StartRecv();
-		}
-
-		public override void Send(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
-		{
-			if (this.Id == 0)
-			{
-				throw new Exception("TChannel已经被Dispose, 不能发送消息");
-			}
-			byte[] size = BitConverter.GetBytes(buffer.Length);
-			this.sendBuffer.SendTo(size);
-			this.sendBuffer.SendTo(buffer);
-			if (!this.isSending && this.isConnected)
-			{
-				this.StartSend();
-			}
-		}
-
-		public override void Send(List<byte[]> buffers, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
-		{
-			if (this.Id == 0)
-			{
-				throw new Exception("TChannel已经被Dispose, 不能发送消息");
-			}
-			int size = buffers.Select(b => b.Length).Sum();
-			byte[] sizeBuffer = BitConverter.GetBytes(size);
-			this.sendBuffer.SendTo(sizeBuffer);
-			foreach (byte[] buffer in buffers)
-			{
-				this.sendBuffer.SendTo(buffer);
-			}
-			if (!this.isSending && this.isConnected)
-			{
-				this.StartSend();
-			}
-		}
-
-		private void StartSend()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-			// 没有数据需要发送
-			if (this.sendBuffer.Count == 0)
-			{
-				this.isSending = false;
-				return;
-			}
-
-			this.isSending = true;
-
-			int sendSize = TBuffer.ChunkSize - this.sendBuffer.FirstIndex;
-			if (sendSize > this.sendBuffer.Count)
-			{
-				sendSize = this.sendBuffer.Count;
-			}
-
-			if (!this.socket.SendAsync(this.sendBuffer.First, this.sendBuffer.FirstIndex, sendSize))
-			{
-				this.OnSend(sendSize, SocketError.Success);
-				return;
-			}
-			this.socket.OnSend = this.OnSend;
-		}
-
-		private void OnSend(int n, SocketError error)
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-			this.socket.OnSend = null;
-			if (error != SocketError.Success)
-			{
-				this.OnError(this, error);
-				return;
-			}
-			this.sendBuffer.FirstIndex += n;
-			if (this.sendBuffer.FirstIndex == TBuffer.ChunkSize)
-			{
-				this.sendBuffer.FirstIndex = 0;
-				this.sendBuffer.RemoveFirst();
-			}
-
-			this.StartSend();
-		}
-
-		private void StartRecv()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-			int size = TBuffer.ChunkSize - this.recvBuffer.LastIndex;
-			
-			if (!this.socket.RecvAsync(this.recvBuffer.Last, this.recvBuffer.LastIndex, size))
-			{
-				this.OnRecv(size, SocketError.Success);
-			}
-			this.socket.OnRecv = this.OnRecv;
-		}
-
-		private void OnRecv(int n, SocketError error)
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-			this.socket.OnRecv = null;
-			if (error != SocketError.Success)
-			{
-				this.OnError(this, error);
-				return;
-			}
-
-			if (n == 0)
-			{
-				this.OnError(this, error);
-				return;
-			}
-			
-			this.recvBuffer.LastIndex += n;
-			if (this.recvBuffer.LastIndex == TBuffer.ChunkSize)
-			{
-				this.recvBuffer.AddLast();
-				this.recvBuffer.LastIndex = 0;
-			}
-			
-			if (this.recvTcs != null)
-			{
-				byte[] packet = this.parser.GetPacket();
-				if (packet != null)
-				{
-					var tcs = this.recvTcs;
-					this.recvTcs = null;
-					tcs.SetResult(packet);
-				}
-			}
-
-			StartRecv();
-		}
-
-		public override Task<byte[]> Recv()
-		{
-			if (this.Id == 0)
-			{
-				throw new Exception("TChannel已经被Dispose, 不能接收消息");
-			}
-			
-			byte[] packet = this.parser.GetPacket();
-			if (packet != null)
-			{
-				return Task.FromResult(packet);
-			}
-			
-			recvTcs = new TaskCompletionSource<byte[]>();
-			return recvTcs.Task;
-		}
-	}
-}

+ 0 - 38
Server/Base/Network/TNet/TPoller.cs

@@ -1,38 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Model
-{
-	public class TPoller
-	{
-		// 线程同步队列,发送接收socket回调都放到该队列,由poll线程统一执行
-		private Queue<Action> queue = new Queue<Action>();
-
-		private Queue<Action> localQueue = new Queue<Action>();
-
-		private readonly object lockObject = new object();
-
-		public void Add(Action action)
-		{
-			lock (lockObject)
-			{
-				this.queue.Enqueue(action);
-			}
-		}
-
-		public void Update()
-		{
-			lock (lockObject)
-			{
-				localQueue = queue;
-				queue = new Queue<Action>();
-			}
-
-			while (this.localQueue.Count > 0)
-			{
-				Action a = this.localQueue.Dequeue();
-				a();
-			}
-		}
-	}
-}

+ 0 - 100
Server/Base/Network/TNet/TService.cs

@@ -1,100 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	public sealed class TService: AService
-	{
-		private TPoller poller = new TPoller();
-		private readonly TSocket acceptor;
-
-		private readonly Dictionary<long, TChannel> idChannels = new Dictionary<long, TChannel>();
-
-		/// <summary>
-		/// 即可做client也可做server
-		/// </summary>
-		/// <param name="host"></param>
-		/// <param name="port"></param>
-		public TService(string host, int port)
-		{
-			this.acceptor = new TSocket(this.poller, host, port);
-		}
-
-		public TService()
-		{
-		}
-
-		public override void Dispose()
-		{
-			if (this.poller == null)
-			{
-				return;
-			}
-
-			foreach (long id in this.idChannels.Keys.ToArray())
-			{
-				TChannel channel = this.idChannels[id];
-				channel.Dispose();
-			}
-			this.acceptor?.Dispose();
-			this.poller = null;
-		}
-
-		public override void Add(Action action)
-		{
-			this.poller.Add(action);
-		}
-
-		public override AChannel GetChannel(long id)
-		{
-			TChannel channel = null;
-			this.idChannels.TryGetValue(id, out channel);
-			return channel;
-		}
-
-		public override async Task<AChannel> AcceptChannel()
-		{
-			if (this.acceptor == null)
-			{
-				throw new Exception("service construct must use host and port param");
-			}
-			TSocket socket = new TSocket(this.poller);
-			await this.acceptor.AcceptAsync(socket);
-			TChannel channel = new TChannel(socket, this);
-			this.idChannels[channel.Id] = channel;
-			return channel;
-		}
-
-		public override AChannel ConnectChannel(string host, int port)
-		{
-			TSocket newSocket = new TSocket(this.poller);
-			TChannel channel = new TChannel(newSocket, host, port, this);
-			this.idChannels[channel.Id] = channel;
-
-			return channel;
-		}
-
-
-		public override void Remove(long id)
-		{
-			TChannel channel;
-			if (!this.idChannels.TryGetValue(id, out channel))
-			{
-				return;
-			}
-			if (channel == null)
-			{
-				return;
-			}
-			this.idChannels.Remove(id);
-			channel.Dispose();
-		}
-		
-		public override void Update()
-		{
-			this.poller.Update();
-		}
-	}
-}

+ 0 - 243
Server/Base/Network/TNet/TSocket.cs

@@ -1,243 +0,0 @@
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	/// <summary>
-	/// 封装Socket,将回调push到主线程处理
-	/// </summary>
-	public sealed class TSocket: IDisposable
-	{
-		private readonly TPoller poller;
-		private Socket socket;
-		private readonly SocketAsyncEventArgs innArgs = new SocketAsyncEventArgs();
-		private readonly SocketAsyncEventArgs outArgs = new SocketAsyncEventArgs();
-
-		public Action<SocketError> OnConn;
-		public Action<int, SocketError> OnRecv;
-		public Action<int, SocketError> OnSend;
-		public Action<SocketError> OnDisconnect;
-
-		public TSocket(TPoller poller)
-		{
-			this.poller = poller;
-			this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-			this.innArgs.Completed += this.OnComplete;
-			this.outArgs.Completed += this.OnComplete;
-		}
-
-		public TSocket(TPoller poller, string host, int port): this(poller)
-		{
-			try
-			{
-				this.Bind(host, port);
-				this.Listen(100);
-			}
-			catch (Exception e)
-			{
-				throw new Exception($"socket bind error: {host} {port}", e);
-			}
-		}
-		
-		public Socket Socket
-		{
-			get
-			{
-				return this.socket;
-			}
-		}
-
-		public string RemoteAddress
-		{
-			get
-			{
-				IPEndPoint ipEndPoint = (IPEndPoint)this.socket.RemoteEndPoint;
-				return ipEndPoint.Address + ":" + ipEndPoint.Port;
-			}
-		}
-
-		public void Dispose()
-		{
-			if (this.socket == null)
-			{
-				return;
-			}
-			
-			this.socket.Close();
-			this.innArgs.Dispose();
-			this.outArgs.Dispose();
-			this.socket = null;
-		}
-
-		private void Bind(string host, int port)
-		{
-			this.socket.Bind(new IPEndPoint(IPAddress.Parse(host), port));
-		}
-
-		private void Listen(int backlog)
-		{
-			this.socket.Listen(backlog);
-		}
-
-		public Task<bool> AcceptAsync(TSocket accpetSocket)
-		{
-			if (this.socket == null)
-			{
-				throw new Exception($"TSocket已经被Dispose,不能接收连接!");
-			}
-			var tcs = new TaskCompletionSource<bool>();
-			this.innArgs.UserToken = tcs;
-			this.innArgs.AcceptSocket = accpetSocket.socket;
-			if (!this.socket.AcceptAsync(this.innArgs))
-			{
-				OnAcceptComplete(this.innArgs);
-			}
-			return tcs.Task;
-		}
-
-		private void OnAcceptComplete(SocketAsyncEventArgs e)
-		{
-			if (this.socket == null)
-			{
-				return;
-			}
-			var tcs = (TaskCompletionSource<bool>)e.UserToken;
-			e.UserToken = null;
-			if (e.SocketError != SocketError.Success)
-			{
-				tcs.SetException(new Exception($"socket error: {e.SocketError}"));
-				return;
-			}
-			tcs.SetResult(true);
-		}
-
-		private void OnComplete(object sender, SocketAsyncEventArgs e)
-		{
-			Action action;
-			switch (e.LastOperation)
-			{
-				case SocketAsyncOperation.Connect:
-					action = () => OnConnectComplete(e);
-					break;
-				case SocketAsyncOperation.Receive:
-					action = () => OnRecvComplete(e);
-					break;
-				case SocketAsyncOperation.Send:
-					action = () => OnSendComplete(e);
-					break;
-				case SocketAsyncOperation.Disconnect:
-					action = () => OnDisconnectComplete(e);
-					break;
-				case SocketAsyncOperation.Accept:
-					action = () => OnAcceptComplete(e);
-					break;
-				default:
-					throw new Exception($"socket error: {e.LastOperation}");
-			}
-
-			// 回调到主线程处理
-			this.poller.Add(action);
-		}
-
-		public bool ConnectAsync(string host, int port)
-		{
-			this.outArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(host), port);
-			if (this.socket.ConnectAsync(this.outArgs))
-			{
-				return true;
-			}
-			OnConnectComplete(this.outArgs);
-			return false;
-		}
-
-		private void OnConnectComplete(SocketAsyncEventArgs e)
-		{
-			if (this.socket == null)
-			{
-				return;
-			}
-			if (this.OnConn == null)
-			{
-				return;
-			}
-			this.OnConn(e.SocketError);
-		}
-
-		public bool RecvAsync(byte[] buffer, int offset, int count)
-		{
-			try
-			{
-				this.innArgs.SetBuffer(buffer, offset, count);
-			}
-			catch (Exception e)
-			{
-				throw new Exception($"socket set buffer error: {buffer.Length}, {offset}, {count}", e);
-			}
-			if (this.socket.ReceiveAsync(this.innArgs))
-			{
-				return true;
-			}
-			OnRecvComplete(this.innArgs);
-			return false;
-		}
-
-		private void OnRecvComplete(SocketAsyncEventArgs e)
-		{
-			if (this.socket == null)
-			{
-				return;
-			}
-			if (this.OnRecv == null)
-			{
-				return;
-			}
-			this.OnRecv(e.BytesTransferred, e.SocketError);
-		}
-
-		public bool SendAsync(byte[] buffer, int offset, int count)
-		{
-			try
-			{
-				this.outArgs.SetBuffer(buffer, offset, count);
-			}
-			catch (Exception e)
-			{
-				throw new Exception($"socket set buffer error: {buffer.Length}, {offset}, {count}", e);
-			}
-			if (this.socket.SendAsync(this.outArgs))
-			{
-				return true;
-			}
-			OnSendComplete(this.outArgs);
-			return false;
-		}
-
-		private void OnSendComplete(SocketAsyncEventArgs e)
-		{
-			if (this.socket == null)
-			{
-				return;
-			}
-			if (this.OnSend == null)
-			{
-				return;
-			}
-			this.OnSend(e.BytesTransferred, e.SocketError);
-		}
-
-		private void OnDisconnectComplete(SocketAsyncEventArgs e)
-		{
-			if (this.socket == null)
-			{
-				return;
-			}
-			if (this.OnDisconnect == null)
-			{
-				return;
-			}
-			this.OnDisconnect(e.SocketError);
-		}
-	}
-}

+ 0 - 33
Server/Base/Network/UNet/Library.cs

@@ -1,33 +0,0 @@
-using System;
-
-namespace Model
-{
-	internal static class Library
-	{
-		public static void Initialize()
-		{
-			int ret = NativeMethods.enet_initialize();
-			if (ret < 0)
-			{
-				throw new Exception($"Initialization failed, ret: {ret}");
-			}
-		}
-
-		public static void Deinitialize()
-		{
-			NativeMethods.enet_deinitialize();
-		}
-
-		public static uint Time
-		{
-			get
-			{
-				return NativeMethods.enet_time_get();
-			}
-			set
-			{
-				NativeMethods.enet_time_set(value);
-			}
-		}
-	}
-}

+ 0 - 109
Server/Base/Network/UNet/NativeMethods.cs

@@ -1,109 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Model
-{
-	public static class NativeMethods
-	{
-#if UNITY_IOS && !UNITY_EDITOR
-		private const string LIB = "__Internal";
-#else
-		private const string LIB = "ENet";
-#endif
-
-		public const int ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255;
-		public const int ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xfff;
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_address_set_host(ref ENetAddress address, string hostName);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_address_get_host(ref ENetAddress address, StringBuilder hostName, uint nameLength);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_address_get_host_ip(ref ENetAddress address, StringBuilder hostIp, uint ipLength);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_deinitialize();
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_initialize();
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern IntPtr enet_host_create(
-				ref ENetAddress address, uint peerLimit, uint channelLimit, uint incomingBandwidth, uint outgoingBandwidth);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern IntPtr enet_host_create(IntPtr address, uint peerLimit, uint channelLimit, uint incomingBandwidth, uint outgoingBandwidth);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_host_destroy(IntPtr host);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern IntPtr enet_host_connect(IntPtr host, ref ENetAddress address, uint channelCount, uint data);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_host_broadcast(IntPtr host, byte channelID, IntPtr packet);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_host_compress(IntPtr host, IntPtr compressor);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_host_compress_with_range_coder(IntPtr host);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_host_channel_limit(IntPtr host, uint channelLimit);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_host_bandwidth_limit(IntPtr host, uint incomingBandwidth, uint outgoingBandwidth);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_host_flush(IntPtr host);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_host_check_events(IntPtr host, ref ENetEvent ev);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_host_service(IntPtr host, IntPtr ev, uint timeout);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern uint enet_time_get();
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_time_set(uint newTimeBase);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern IntPtr enet_packet_create(byte[] data, uint dataLength, PacketFlags flags);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_packet_destroy(IntPtr packet);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_packet_resize(IntPtr packet, uint dataLength);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_peer_throttle_configure(IntPtr peer, uint interval, uint acceleration, uint deceleration);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern int enet_peer_send(IntPtr peer, byte channelID, IntPtr packet);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern IntPtr enet_peer_receive(IntPtr peer, out byte channelID);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_peer_reset(IntPtr peer);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_peer_ping(IntPtr peer);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_peer_disconnect_now(IntPtr peer, uint data);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_peer_disconnect(IntPtr peer, uint data);
-
-		[DllImport(LIB, CallingConvention = CallingConvention.Cdecl)]
-		internal static extern void enet_peer_disconnect_later(IntPtr peer, uint data);
-	}
-}

+ 0 - 76
Server/Base/Network/UNet/NativeStructs.cs

@@ -1,76 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace Model
-{
-	internal enum EventType
-	{
-		None = 0,
-		Connect = 1,
-		Disconnect = 2,
-		Receive = 3
-	}
-
-	internal enum PeerState
-	{
-		Uninitialized = -1,
-		Disconnected = 0,
-		Connecting = 1,
-		AcknowledgingConnect = 2,
-		ConnectionPending = 3,
-		ConnectionSucceeded = 4,
-		Connected = 5,
-		DisconnectLater = 6,
-		Disconnecting = 7,
-		AcknowledgingDisconnect = 8,
-		Zombie = 9
-	}
-
-	[StructLayout(LayoutKind.Sequential)]
-	internal struct ENetAddress
-	{
-		public uint Host;
-		public ushort Port;
-	}
-
-	// ENetEvent
-	[StructLayout(LayoutKind.Sequential)]
-	internal struct ENetEvent
-	{
-		public EventType Type;
-		public IntPtr Peer;
-		public byte ChannelID;
-		public uint Data;
-		public IntPtr Packet;
-	}
-
-	[StructLayout(LayoutKind.Sequential)]
-	internal class ENetListNode
-	{
-		public IntPtr Next;
-		public IntPtr Previous;
-	}
-
-	[StructLayout(LayoutKind.Sequential)]
-	internal struct ENetPacket
-	{
-		public IntPtr ReferenceCount; // size_t
-		public uint Flags;
-		public IntPtr Data;
-		public IntPtr DataLength; // size_t
-	}
-
-	[StructLayout(LayoutKind.Sequential)]
-	internal struct ENetPeer
-	{
-		public ENetListNode DispatchList;
-		public IntPtr Host;
-		public ushort OutgoingPeerID;
-		public ushort IncomingPeerID;
-		public uint ConnectID;
-		public byte OutgoingSessionID;
-		public byte IncomingSessionID;
-		public ENetAddress Address;
-		public IntPtr Data;
-	}
-}

+ 0 - 27
Server/Base/Network/UNet/UAddress.cs

@@ -1,27 +0,0 @@
-using System;
-using System.Net;
-
-namespace Model
-{
-	internal struct UAddress
-	{
-		private readonly uint ip;
-		private readonly ushort port;
-
-		public UAddress(string host, int port)
-		{
-			IPAddress address = IPAddress.Parse(host);
-			this.ip = BitConverter.ToUInt32(address.GetAddressBytes(), 0);
-			this.port = (ushort) port;
-		}
-
-		public ENetAddress Struct
-		{
-			get
-			{
-				ENetAddress address = new ENetAddress { Host = this.ip, Port = this.port };
-				return address;
-			}
-		}
-	}
-}

+ 0 - 100
Server/Base/Network/UNet/UChannel.cs

@@ -1,100 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	internal class UChannel: AChannel
-	{
-		private readonly USocket socket;
-
-		private TaskCompletionSource<byte[]> recvTcs;
-
-		/// <summary>
-		/// connect
-		/// </summary>
-		public UChannel(USocket socket, string host, int port, UService service): base(service, ChannelType.Connect)
-		{
-			this.socket = socket;
-			this.service = service;
-			this.RemoteAddress = host + ":" + port;
-			this.socket.ConnectAsync(host, (ushort)port);
-			this.socket.Received += this.OnRecv;
-			this.socket.Disconnect += () => { this.OnError(this, SocketError.SocketError); };
-		}
-
-		/// <summary>
-		/// accept
-		/// </summary>
-		public UChannel(USocket socket, UService service) : base(service, ChannelType.Accept)
-		{
-			this.socket = socket;
-			this.service = service;
-			this.RemoteAddress = socket.RemoteAddress;
-			this.socket.Received += this.OnRecv;
-			this.socket.Disconnect += () => { this.OnError(this, SocketError.SocketError); };
-		}
-
-		public override void Dispose()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-			base.Dispose();
-			this.socket.Dispose();
-		}
-
-		public override void Send(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
-		{
-			if (this.Id == 0)
-			{
-				throw new Exception("UChannel已经被Dispose, 不能发送消息");
-			}
-			this.socket.SendAsync(buffer, channelID, flags);
-		}
-
-		public override void Send(List<byte[]> buffers, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
-		{
-			if (this.Id == 0)
-			{
-				throw new Exception("UChannel已经被Dispose, 不能发送消息");
-			}
-			int size = buffers.Select(b => b.Length).Sum();
-			var buffer = new byte[size];
-			int index = 0;
-			foreach (byte[] bytes in buffers)
-			{
-				Array.Copy(bytes, 0, buffer, index, bytes.Length);
-				index += bytes.Length;
-			}
-			this.socket.SendAsync(buffer, channelID, flags);
-		}
-
-		public override Task<byte[]> Recv()
-		{
-			if (this.Id == 0)
-			{
-				throw new Exception("UChannel已经被Dispose, 不能接收消息");
-			}
-			
-			var recvQueue = this.socket.RecvQueue;
-			if (recvQueue.Count > 0)
-			{
-				return Task.FromResult(recvQueue.Dequeue());
-			}
-
-			recvTcs = new TaskCompletionSource<byte[]>();
-			return recvTcs.Task;
-		}
-
-		private void OnRecv()
-		{
-			var tcs = this.recvTcs;
-			this.recvTcs = null;
-			tcs?.SetResult(this.socket.RecvQueue.Dequeue());
-		}
-	}
-}

+ 0 - 72
Server/Base/Network/UNet/UPacket.cs

@@ -1,72 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace Model
-{
-	internal sealed class UPacket: IDisposable
-	{
-		public UPacket(IntPtr packet)
-		{
-			this.PacketPtr = packet;
-		}
-
-		public UPacket(byte[] data, PacketFlags flags = PacketFlags.None)
-		{
-			if (data == null)
-			{
-				throw new ArgumentNullException(nameof(data));
-			}
-			this.PacketPtr = NativeMethods.enet_packet_create(data, (uint) data.Length, flags);
-			if (this.PacketPtr == IntPtr.Zero)
-			{
-				throw new Exception("Packet creation call failed");
-			}
-		}
-
-		~UPacket()
-		{
-			this.Dispose(false);
-		}
-
-		public void Dispose()
-		{
-			this.Dispose(true);
-		}
-
-		private void Dispose(bool disposing)
-		{
-			if (this.PacketPtr == IntPtr.Zero)
-			{
-				return;
-			}
-
-			NativeMethods.enet_packet_destroy(this.PacketPtr);
-			this.PacketPtr = IntPtr.Zero;
-		}
-
-		private ENetPacket Struct
-		{
-			get
-			{
-				return (ENetPacket) Marshal.PtrToStructure(this.PacketPtr, typeof (ENetPacket));
-			}
-			set
-			{
-				Marshal.StructureToPtr(value, this.PacketPtr, false);
-			}
-		}
-
-		public IntPtr PacketPtr { get; set; }
-
-		public byte[] Bytes
-		{
-			get
-			{
-				ENetPacket enetPacket = this.Struct;
-				var bytes = new byte[(long) enetPacket.DataLength];
-				Marshal.Copy(enetPacket.Data, bytes, 0, (int) enetPacket.DataLength);
-				return bytes;
-			}
-		}
-	}
-}

+ 0 - 214
Server/Base/Network/UNet/UPoller.cs

@@ -1,214 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	internal sealed class UPoller : IDisposable
-	{
-		static UPoller()
-		{
-			Library.Initialize();
-		}
-
-		public USocketManager USocketManager { get; }
-		private readonly Queue<IntPtr> connQueue = new Queue<IntPtr>();
-
-		private IntPtr host;
-
-		// 线程同步队列,发送接收socket回调都放到该队列,由poll线程统一执行
-		private Queue<Action> concurrentQueue = new Queue<Action>();
-		private Queue<Action> localQueue;
-		private readonly object lockObject = new object();
-
-		private ENetEvent eNetEventCache;
-
-		private TaskCompletionSource<USocket> AcceptTcs { get; set; }
-
-		public UPoller(string hostName, ushort port)
-		{
-			try
-			{
-				this.USocketManager = new USocketManager();
-
-				UAddress address = new UAddress(hostName, port);
-				ENetAddress nativeAddress = address.Struct;
-				this.host = NativeMethods.enet_host_create(ref nativeAddress,
-						NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID, 0, 0, 0);
-
-				if (this.host == IntPtr.Zero)
-				{
-					throw new Exception("Host creation call failed.");
-				}
-
-				NativeMethods.enet_host_compress_with_range_coder(this.host);
-			}
-			catch (Exception e)
-			{
-				throw new Exception($"UPoll construct error, address: {hostName}:{port}", e);
-			}
-		}
-
-		public UPoller()
-		{
-			this.USocketManager = new USocketManager();
-
-			this.host = NativeMethods.enet_host_create(IntPtr.Zero, NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID, 0, 0, 0);
-
-			if (this.host == IntPtr.Zero)
-			{
-				throw new Exception("Host creation call failed.");
-			}
-
-			NativeMethods.enet_host_compress_with_range_coder(this.host);
-		}
-
-		public void Dispose()
-		{
-			if (this.host == IntPtr.Zero)
-			{
-				return;
-			}
-
-			NativeMethods.enet_host_destroy(this.host);
-
-			this.host = IntPtr.Zero;
-		}
-
-		public IntPtr Host
-		{
-			get
-			{
-				return this.host;
-			}
-		}
-
-		public void Flush()
-		{
-			NativeMethods.enet_host_flush(this.host);
-		}
-
-		public void Add(Action action)
-		{
-			lock (lockObject)
-			{
-				this.concurrentQueue.Enqueue(action);
-			}
-		}
-
-		public Task<USocket> AcceptAsync()
-		{
-			if (this.AcceptTcs != null)
-			{
-				throw new Exception("do not accept twice!");
-			}
-			
-			// 如果有请求连接缓存的包,从缓存中取
-			if (this.connQueue.Count > 0)
-			{
-				IntPtr ptr = this.connQueue.Dequeue();
-
-				USocket socket = new USocket(ptr, this);
-				this.USocketManager.Add(ptr, socket);
-				return Task.FromResult(socket);
-			}
-
-			this.AcceptTcs = new TaskCompletionSource<USocket>();
-			return this.AcceptTcs.Task;
-		}
-
-		private void OnAccepted(ENetEvent eEvent)
-		{
-			if (eEvent.Type == EventType.Disconnect)
-			{
-				this.AcceptTcs.TrySetException(new Exception("socket disconnected in accpet"));
-			}
-
-			USocket socket = new USocket(eEvent.Peer, this);
-			this.USocketManager.Add(socket.PeerPtr, socket);
-			socket.OnAccepted();
-
-			var tcs = this.AcceptTcs;
-			this.AcceptTcs = null;
-			tcs.SetResult(socket);
-		}
-
-		private void OnEvents()
-		{
-			lock (lockObject)
-			{
-				localQueue = concurrentQueue;
-				concurrentQueue = new Queue<Action>();
-			}
-
-			while (this.localQueue.Count > 0)
-			{
-				Action a = this.localQueue.Dequeue();
-				a();
-			}
-		}
-
-		private int Service()
-		{
-			int ret = NativeMethods.enet_host_service(this.host, IntPtr.Zero, 0);
-			return ret;
-		}
-
-		public void Update()
-		{
-			this.OnEvents();
-
-			if (this.Service() < 0)
-			{
-				return;
-			}
-
-			while (true)
-			{
-				if (NativeMethods.enet_host_check_events(this.host, ref this.eNetEventCache) <= 0)
-				{
-					return;
-				}
-
-				switch (this.eNetEventCache.Type)
-				{
-					case EventType.Connect:
-						{
-							// 这是一个connect peer
-							if (this.USocketManager.ContainsKey(this.eNetEventCache.Peer))
-							{
-								USocket uSocket = this.USocketManager[this.eNetEventCache.Peer];
-								uSocket.OnConnected();
-								break;
-							}
-
-							// 这是accept peer
-							if (this.AcceptTcs != null)
-							{
-								this.OnAccepted(this.eNetEventCache);
-								break;
-							}
-
-							// 如果server端没有acceptasync,则请求放入队列
-							this.connQueue.Enqueue(this.eNetEventCache.Peer);
-							break;
-						}
-					case EventType.Receive:
-						{
-							USocket uSocket = this.USocketManager[this.eNetEventCache.Peer];
-							uSocket.OnReceived(this.eNetEventCache);
-							break;
-						}
-					case EventType.Disconnect:
-						{
-							USocket uSocket = this.USocketManager[this.eNetEventCache.Peer];
-							this.USocketManager.Remove(uSocket.PeerPtr);
-							uSocket.PeerPtr = IntPtr.Zero;
-							uSocket.OnDisconnect(this.eNetEventCache);
-							break;
-						}
-				}
-			}
-		}
-	}
-}

+ 0 - 94
Server/Base/Network/UNet/UService.cs

@@ -1,94 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Model
-{
-	public sealed class UService: AService
-	{
-		private UPoller poller;
-
-		private readonly Dictionary<long, UChannel> idChannels = new Dictionary<long, UChannel>();
-
-		/// <summary>
-		/// 即可做client也可做server
-		/// </summary>
-		public UService(string host, int port)
-		{
-			this.poller = new UPoller(host, (ushort)port);
-		}
-
-		/// <summary>
-		/// 只能做client
-		/// </summary>
-		public UService()
-		{
-			this.poller = new UPoller();
-		}
-
-		public override void Dispose()
-		{
-			if (this.poller == null)
-			{
-				return;
-			}
-
-			foreach (long id in this.idChannels.Keys.ToArray())
-			{
-				UChannel channel = this.idChannels[id];
-				channel.Dispose();
-			}
-			
-			this.poller = null;
-		}
-
-		public override void Add(Action action)
-		{
-			this.poller.Add(action);
-		}
-		
-		public override async Task<AChannel> AcceptChannel()
-		{
-			USocket socket = await this.poller.AcceptAsync();
-			UChannel channel = new UChannel(socket, this);
-			this.idChannels[channel.Id] = channel;
-			return channel;
-		}
-
-		public override AChannel ConnectChannel(string host, int port)
-		{
-			USocket newSocket = new USocket(this.poller);
-			UChannel channel = new UChannel(newSocket, host, port, this);
-			this.idChannels[channel.Id] = channel;
-			return channel;
-		}
-
-		public override AChannel GetChannel(long id)
-		{
-			UChannel channel = null;
-			this.idChannels.TryGetValue(id, out channel);
-			return channel;
-		}
-
-		public override void Remove(long id)
-		{
-			UChannel channel;
-			if (!this.idChannels.TryGetValue(id, out channel))
-			{
-				return;
-			}
-			if (channel == null)
-			{
-				return;
-			}
-			this.idChannels.Remove(id);
-			channel.Dispose();
-		}
-
-		public override void Update()
-		{
-			this.poller.Update();
-		}
-	}
-}

+ 0 - 168
Server/Base/Network/UNet/USocket.cs

@@ -1,168 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-using System.Runtime.InteropServices;
-
-namespace Model
-{
-	internal class BufferInfo
-	{
-		public byte[] Buffer { get; set; }
-		public byte ChannelID { get; set; }
-		public PacketFlags Flags { get; set; }
-	}
-
-	internal sealed class USocket: IDisposable
-	{
-		private readonly UPoller poller;
-		public IntPtr PeerPtr { get; set; }
-		private readonly Queue<byte[]> recvQueue = new Queue<byte[]>();
-		private readonly Queue<BufferInfo> sendQueue = new Queue<BufferInfo>();
-		private bool isConnected;
-		private Action disconnect;
-		private Action received;
-
-		public event Action Received
-		{
-			add
-			{
-				this.received += value;
-			}
-			remove
-			{
-				this.received -= value;
-			}
-		}
-
-		public event Action Disconnect
-		{
-			add
-			{
-				this.disconnect += value;
-			}
-			remove
-			{
-				this.disconnect -= value;
-			}
-		}
-
-		public USocket(IntPtr peerPtr, UPoller poller)
-		{
-			this.poller = poller;
-			this.PeerPtr = peerPtr;
-		}
-
-		public USocket(UPoller poller)
-		{
-			this.poller = poller;
-		}
-
-		public void Dispose()
-		{
-			if (this.PeerPtr == IntPtr.Zero)
-			{
-				return;
-			}
-
-			poller.USocketManager.Remove(this.PeerPtr);
-			NativeMethods.enet_peer_disconnect_now(this.PeerPtr, 0);
-			this.PeerPtr = IntPtr.Zero;
-		}
-
-		public string RemoteAddress
-		{
-			get
-			{
-				ENetPeer peer = this.Struct;
-				IPAddress ipaddr = new IPAddress(peer.Address.Host);
-				return $"{ipaddr}:{peer.Address.Port}";
-			}
-		}
-
-		private ENetPeer Struct
-		{
-			get
-			{
-				if (this.PeerPtr == IntPtr.Zero)
-				{
-					return new ENetPeer();
-				}
-				ENetPeer peer = (ENetPeer)Marshal.PtrToStructure(this.PeerPtr, typeof(ENetPeer));
-				return peer;
-			}
-			set
-			{
-				Marshal.StructureToPtr(value, this.PeerPtr, false);
-			}
-		}
-		
-		public Queue<byte[]> RecvQueue
-		{
-			get
-			{
-				return recvQueue;
-			}
-		}
-
-		public void ConnectAsync(string host, ushort port)
-		{
-			UAddress address = new UAddress(host, port);
-			ENetAddress nativeAddress = address.Struct;
-
-			this.PeerPtr = NativeMethods.enet_host_connect(this.poller.Host, ref nativeAddress, 2, 0);
-			if (this.PeerPtr == IntPtr.Zero)
-			{
-				throw new Exception($"host connect call failed, {host}:{port}");
-			}
-			this.poller.USocketManager.Add(this.PeerPtr, this);
-		}
-
-		public void SendAsync(byte[] data, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
-		{
-			if (this.PeerPtr == IntPtr.Zero)
-			{
-				throw new Exception($"USocket 已经被Dispose,不能发送数据!");
-			}
-			if (!isConnected)
-			{
-				sendQueue.Enqueue(new BufferInfo { Buffer = data, ChannelID = channelID, Flags = flags });
-				return;
-			}
-			UPacket packet = new UPacket(data, flags);
-			NativeMethods.enet_peer_send(this.PeerPtr, channelID, packet.PacketPtr);
-			// enet_peer_send函数会自动删除packet,设置为0,防止Dispose或者析构函数再次删除
-			packet.PacketPtr = IntPtr.Zero;
-		}
-
-		internal void OnConnected()
-		{
-			isConnected = true;
-			while (this.sendQueue.Count > 0)
-			{
-				BufferInfo info = this.sendQueue.Dequeue();
-				this.SendAsync(info.Buffer, info.ChannelID, info.Flags);
-			}
-		}
-
-		internal void OnAccepted()
-		{
-			isConnected = true;
-		}
-
-		internal void OnReceived(ENetEvent eNetEvent)
-		{
-			// 将包放到缓存队列
-			using (UPacket packet = new UPacket(eNetEvent.Packet))
-			{
-				byte[] bytes = packet.Bytes;
-				this.RecvQueue.Enqueue(bytes);
-			}
-			this.received();
-		}
-
-		internal void OnDisconnect(ENetEvent eNetEvent)
-		{
-			disconnect();
-		}
-	}
-}

+ 0 - 41
Server/Base/Network/UNet/USocketManager.cs

@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Model
-{
-	internal class USocketManager
-	{
-		private readonly Dictionary<IntPtr, USocket> sockets = new Dictionary<IntPtr, USocket>();
-
-		public void Add(IntPtr peerPtr, USocket uSocket)
-		{
-			this.sockets.Add(peerPtr, uSocket);
-		}
-
-		public void Remove(IntPtr peerPtr)
-		{
-			this.sockets.Remove(peerPtr);
-		}
-
-		public bool ContainsKey(IntPtr peerPtr)
-		{
-			if (this.sockets.ContainsKey(peerPtr))
-			{
-				return true;
-			}
-			return false;
-		}
-
-		public USocket this[IntPtr peerPtr]
-		{
-			get
-			{
-				if (!this.sockets.ContainsKey(peerPtr))
-				{
-					throw new KeyNotFoundException("No Peer Key");
-				}
-				return this.sockets[peerPtr];
-			}
-		}
-	}
-}

+ 0 - 35
Server/Base/Properties/AssemblyInfo.cs

@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("Base")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Base")]
-[assembly: AssemblyCopyright("Copyright ©  2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-//将 ComVisible 设置为 false 将使此程序集中的类型
-//对 COM 组件不可见。  如果需要从 COM 访问此程序集中的类型,
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("e5078ec6-2b0e-4711-be8b-d99f69638316")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
-// 方法是按如下所示使用“*”: :
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 47
Server/Base/QueueDictionary.cs

@@ -1,47 +0,0 @@
-using System.Collections.Generic;
-
-namespace Model
-{
-	public class QueueDictionary<T, K>
-	{
-		private readonly List<T> list = new List<T>();
-		private readonly Dictionary<T, K> dictionary = new Dictionary<T, K>();
-
-		public void Add(T t, K k)
-		{
-			this.list.Add(t);
-			this.dictionary.Add(t, k);
-		}
-
-		public bool Remove(T t)
-		{
-			this.list.Remove(t);
-			this.dictionary.Remove(t);
-			return true;
-		}
-
-		public int Count
-		{
-			get
-			{
-				return this.list.Count;
-			}
-		}
-
-		public T FirstKey
-		{
-			get
-			{
-				return this.list[0];
-			}
-		}
-
-		public K this[T t]
-		{
-			get
-			{
-				return this.dictionary[t];
-			}
-		}
-	}
-}

+ 59 - 93
Server/Base/Server.Base.csproj

@@ -1,102 +1,68 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{E5078EC6-2B0E-4711-BE8B-D99F69638316}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Base</RootNamespace>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
     <AssemblyName>Base</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
+    <RootNamespace>Model</RootNamespace>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\Bin\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;SERVER</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DefineConstants>TRACE;DEBUG;NETCOREAPP2_0;SERVER</DefineConstants>
+    <OutputPath>..\..\</OutputPath>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\Bin\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <DefineConstants>TRACE;RELEASE;NETCOREAPP2_0;SERVER</DefineConstants>
+    <OutputPath>..\..\</OutputPath>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="ICSharpCode.SharpZipLib">
-      <HintPath>..\Lib\ICSharpCode.SharpZipLib.dll</HintPath>
-    </Reference>
-    <Reference Include="MongoDB.Bson">
-      <HintPath>..\Lib\MongoDB.Bson.dll</HintPath>
-    </Reference>
-    <Reference Include="NLog">
-      <HintPath>..\Lib\NLog.dll</HintPath>
-    </Reference>
-    <Reference Include="protobuf-net">
-      <HintPath>..\Lib\protobuf-net.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\DoubleMap.cs" Link="DoubleMap.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\EQueue.cs" Link="EQueue.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\ArrayHelper.cs" Link="Helper\ArrayHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\ByteHelper.cs" Link="Helper\ByteHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\EnumHelper.cs" Link="Helper\EnumHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\FileHelper.cs" Link="Helper\FileHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\IdGenerater.cs" Link="Helper\IdGenerater.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\MD5Helper.cs" Link="Helper\MD5Helper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\MethodInfoHelper.cs" Link="Helper\MethodInfoHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\NetHelper.cs" Link="Helper\NetHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\ProtobufHelper.cs" Link="Helper\ProtobufHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\RandomHelper.cs" Link="Helper\RandomHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\StringHelper.cs" Link="Helper\StringHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\TimeHelper.cs" Link="Helper\TimeHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\ZipHelper.cs" Link="Helper\ZipHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\MultiMap.cs" Link="MultiMap.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\AChannel.cs" Link="Network\AChannel.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\AService.cs" Link="Network\AService.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\TNet\PacketParser.cs" Link="Network\TNet\PacketParser.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\TNet\TBuffer.cs" Link="Network\TNet\TBuffer.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\TNet\TChannel.cs" Link="Network\TNet\TChannel.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\TNet\TService.cs" Link="Network\TNet\TService.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\Library.cs" Link="Network\UNet\Library.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\NativeMethods.cs" Link="Network\UNet\NativeMethods.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\NativeStructs.cs" Link="Network\UNet\NativeStructs.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\UAddress.cs" Link="Network\UNet\UAddress.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\UChannel.cs" Link="Network\UNet\UChannel.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\UPacket.cs" Link="Network\UNet\UPacket.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\UPoller.cs" Link="Network\UNet\UPoller.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\UService.cs" Link="Network\UNet\UService.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\USocket.cs" Link="Network\UNet\USocket.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\Network\UNet\USocketManager.cs" Link="Network\UNet\USocketManager.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\QueueDictionary.cs" Link="QueueDictionary.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\TryLocker.cs" Link="TryLocker.cs" />
   </ItemGroup>
+
   <ItemGroup>
-    <Compile Include="DoubleMap.cs" />
-    <Compile Include="Helper\ArrayHelper.cs" />
-    <Compile Include="Helper\ByteHelper.cs" />
-    <Compile Include="Helper\EnumHelper.cs" />
-    <Compile Include="Helper\FileHelper.cs" />
-    <Compile Include="Helper\IdGenerater.cs" />
-    <Compile Include="Helper\MD5Helper.cs" />
-    <Compile Include="Helper\MethodInfoHelper.cs" />
-    <Compile Include="Helper\MongoHelper.cs" />
-    <Compile Include="Helper\NetHelper.cs" />
-    <Compile Include="Helper\ProtobufHelper.cs" />
-    <Compile Include="Helper\RandomHelper.cs" />
-    <Compile Include="Helper\StringHelper.cs" />
-    <Compile Include="Helper\TimeHelper.cs" />
-    <Compile Include="Helper\ZipHelper.cs" />
-    <Compile Include="Log.cs" />
-    <Compile Include="Logger\ALogDecorater.cs" />
-    <Compile Include="Logger\ILog.cs" />
-    <Compile Include="Logger\NLogAdapter.cs" />
-    <Compile Include="Logger\StackInfoDecorater.cs" />
-    <Compile Include="LogType.cs" />
-    <Compile Include="MultiMap.cs" />
-    <Compile Include="Network\AChannel.cs" />
-    <Compile Include="Network\AService.cs" />
-    <Compile Include="Network\TNet\PacketParser.cs" />
-    <Compile Include="Network\TNet\TBuffer.cs" />
-    <Compile Include="Network\TNet\TChannel.cs" />
-    <Compile Include="Network\TNet\TPoller.cs" />
-    <Compile Include="Network\TNet\TService.cs" />
-    <Compile Include="Network\TNet\TSocket.cs" />
-    <Compile Include="Network\UNet\Library.cs" />
-    <Compile Include="Network\UNet\NativeMethods.cs" />
-    <Compile Include="Network\UNet\NativeStructs.cs" />
-    <Compile Include="Network\UNet\UAddress.cs" />
-    <Compile Include="Network\UNet\UChannel.cs" />
-    <Compile Include="Network\UNet\UPacket.cs" />
-    <Compile Include="Network\UNet\UPoller.cs" />
-    <Compile Include="Network\UNet\UService.cs" />
-    <Compile Include="Network\UNet\USocket.cs" />
-    <Compile Include="Network\UNet\USocketManager.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="QueueDictionary.cs" />
-    <Compile Include="TryLocker.cs" />
+    <Folder Include="Helper\" />
+    <Folder Include="Network\TNet\" />
+    <Folder Include="Network\UNet\" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
+
+  <ItemGroup>
+    <PackageReference Include="NLog" Version="5.0.0-beta11" />
+    <PackageReference Include="protobuf-net" Version="2.3.2" />
+    <PackageReference Include="SharpZipLib" Version="1.0.0-alpha2" />
+  </ItemGroup>
+
+</Project>

+ 0 - 35
Server/Base/TryLocker.cs

@@ -1,35 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Model
-{
-	public class TryLock : IDisposable
-	{
-		private object locked;
-
-		public bool HasLock { get; private set; }
-
-		public TryLock(object obj)
-		{
-			if (!Monitor.TryEnter(obj))
-			{
-				return;
-			}
-
-			this.HasLock = true;
-			this.locked = obj;
-		}
-
-		public void Dispose()
-		{
-			if (!this.HasLock)
-			{
-				return;
-			}
-
-			Monitor.Exit(this.locked);
-			this.locked = null;
-			this.HasLock = false;
-		}
-	}
-}

+ 16 - 0
Server/Hotfix/Handler/Actor_TestHandler.cs

@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+using Model;
+
+namespace Hotfix
+{
+	[ActorMessageHandler(AppType.Map)]
+	public class Actor_TestHandler : AMActorHandler<Unit, Actor_Test>
+	{
+		protected override async Task Run(Unit unit, Actor_Test message)
+		{
+			Log.Debug(message.Info);
+
+			unit.GetComponent<UnitGateComponent>().GetActorProxy().Send(message);
+		}
+	}
+}

+ 15 - 0
Server/Hotfix/Handler/Actor_TestRequestHandler.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Threading.Tasks;
+using Model;
+
+namespace Hotfix
+{
+	[ActorMessageHandler(AppType.Map)]
+	public class Actor_TestRequestHandler : AMActorRpcHandler<Unit, Actor_TestRequest, Actor_TestResponse>
+	{
+		protected override async Task Run(Unit unit, Actor_TestRequest message, Action<Actor_TestResponse> reply)
+		{
+			reply(new Actor_TestResponse() {response = "response actor rpc"});
+		}
+	}
+}

+ 56 - 0
Server/Hotfix/Handler/Actor_TransferHandler.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Threading.Tasks;
+using Model;
+
+namespace Hotfix
+{
+	[ActorMessageHandler(AppType.Map)]
+	public class Actor_TransferHandler : AMActorRpcHandler<Unit, Actor_TransferRequest, Actor_TransferResponse>
+	{
+		protected override async Task Run(Unit unit, Actor_TransferRequest message, Action<Actor_TransferResponse> reply)
+		{
+			Actor_TransferResponse response = new Actor_TransferResponse();
+
+			try
+			{
+				long unitId = unit.Id;
+
+
+				// 先在location锁住unit的地址
+				await Game.Scene.GetComponent<LocationProxyComponent>().Lock(unitId);
+
+				// 删除unit actorcomponent,让其它进程发送过来的消息找不到actor,重发
+				unit.RemoveComponent<ActorComponent>();
+				
+				int mapIndex = message.MapIndex;
+
+				StartConfigComponent startConfigComponent = Game.Scene.GetComponent<StartConfigComponent>();
+
+				// 考虑AllServer情况
+				if (startConfigComponent.Count == 1)
+				{
+					mapIndex = 0;
+				}
+
+				// 传送到map
+				StartConfig mapConfig = startConfigComponent.MapConfigs[mapIndex];
+				string address = mapConfig.GetComponent<InnerConfig>().Address;
+				Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(address);
+
+				// 只删除不disponse否则M2M_TrasferUnitRequest无法序列化Unit
+				Game.Scene.GetComponent<UnitComponent>().RemoveNoDispose(unitId);
+				await session.Call<M2M_TrasferUnitResponse>(new M2M_TrasferUnitRequest() { Unit = unit });
+				unit.Dispose();
+
+				// 解锁unit的地址,并且更新unit的地址
+				await Game.Scene.GetComponent<LocationProxyComponent>().UnLock(unitId, mapConfig.AppId);
+
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 30 - 0
Server/Hotfix/Handler/C2G_EnterMapHandler.cs

@@ -0,0 +1,30 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Gate)]
+	public class C2G_EnterMapHandler : AMRpcHandler<C2G_EnterMap, G2C_EnterMap>
+	{
+		protected override async void Run(Session session, C2G_EnterMap message, Action<G2C_EnterMap> reply)
+		{
+			G2C_EnterMap response = new G2C_EnterMap();
+			try
+			{
+				Player player = session.GetComponent<SessionPlayerComponent>().Player;
+				// 在map服务器上创建战斗Unit
+				string mapAddress = Game.Scene.GetComponent<StartConfigComponent>().MapConfigs[0].GetComponent<InnerConfig>().Address;
+				Session mapSession = Game.Scene.GetComponent<NetInnerComponent>().Get(mapAddress);
+				M2G_CreateUnit createUnit = await mapSession.Call<M2G_CreateUnit>(new G2M_CreateUnit() { PlayerId = player.Id, GateSessionId = session.Id });
+				player.UnitId = createUnit.UnitId;
+				response.UnitId = createUnit.UnitId;
+				response.Count = createUnit.Count;
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 10 - 5
Server/Hotfix/Message/C2G_LoginGateHandler.cs → Server/Hotfix/Handler/C2G_LoginGateHandler.cs

@@ -11,16 +11,21 @@ namespace Hotfix
 			G2C_LoginGate response = new G2C_LoginGate();
 			try
 			{
-				bool isCheckOK = Game.Scene.GetComponent<GateSessionKeyComponent>().Check(message.Key);
-				if (!isCheckOK)
+				string account = Game.Scene.GetComponent<GateSessionKeyComponent>().Get(message.Key);
+				if (account == null)
 				{
 					response.Error = ErrorCode.ERR_ConnectGateKeyError;
 					response.Message = "Gate key验证失败!";
+					reply(response);
+					return;
 				}
-				reply(response);
+				Player player = EntityFactory.Create<Player, string>(account);
+				Game.Scene.GetComponent<PlayerComponent>().Add(player);
+				session.AddComponent<SessionPlayerComponent>().Player = player;
+				await session.AddComponent<ActorComponent, IEntityActorHandler>(new GateSessionEntityActorHandler()).AddLocation();
 
-				await Game.Scene.GetComponent<TimerComponent>().WaitAsync(5000);
-				session.Dispose();
+				response.PlayerId = player.Id;
+				reply(response);
 			}
 			catch (Exception e)
 			{

+ 1 - 1
Server/Hotfix/Message/C2M_ReloadHandler.cs → Server/Hotfix/Handler/C2M_ReloadHandler.cs

@@ -21,7 +21,7 @@ namespace Hotfix
 					}
 					InnerConfig innerConfig = startConfig.GetComponent<InnerConfig>();
 					Session serverSession = netInnerComponent.Get(innerConfig.Address);
-					await serverSession.Call<M2A_Reload, A2M_Reload>(new M2A_Reload());
+					await serverSession.Call<A2M_Reload>(new M2A_Reload());
 				}
 				reply(response);
 			}

+ 10 - 10
Server/Hotfix/Message/C2R_LoginHandler.cs → Server/Hotfix/Handler/C2R_LoginHandler.cs

@@ -4,29 +4,29 @@ using Model;
 namespace Hotfix
 {
 	[MessageHandler(AppType.Realm)]
-	public class C2R_LoginHandler: AMRpcHandler<C2R_Login, R2C_Login>
+	public class C2R_LoginHandler : AMRpcHandler<C2R_Login, R2C_Login>
 	{
 		protected override async void Run(Session session, C2R_Login message, Action<R2C_Login> reply)
 		{
 			R2C_Login response = new R2C_Login();
 			try
 			{
-				if (message.Account != "abcdef" || message.Password != "111111")
-				{
-					response.Error = ErrorCode.ERR_AccountOrPasswordError;
-					reply(response);
-					return;
-				}
+				//if (message.Account != "abcdef" || message.Password != "111111")
+				//{
+				//	response.Error = ErrorCode.ERR_AccountOrPasswordError;
+				//	reply(response);
+				//	return;
+				//}
 
 				// 随机分配一个Gate
 				StartConfig config = Game.Scene.GetComponent<RealmGateAddressComponent>().GetAddress();
 				//Log.Debug($"gate address: {MongoHelper.ToJson(config)}");
 				string innerAddress = $"{config.GetComponent<InnerConfig>().Host}:{config.GetComponent<InnerConfig>().Port}";
 				Session gateSession = Game.Scene.GetComponent<NetInnerComponent>().Get(innerAddress);
-				
+
 				// 向gate请求一个key,客户端可以拿着这个key连接gate
-				G2R_GetLoginKey g2RGetLoginKey = await gateSession.Call<R2G_GetLoginKey, G2R_GetLoginKey>(new R2G_GetLoginKey());
-				
+				G2R_GetLoginKey g2RGetLoginKey = await gateSession.Call<G2R_GetLoginKey>(new R2G_GetLoginKey() {Account = message.Account});
+
 				string outerAddress = $"{config.GetComponent<OuterConfig>().Host}:{config.GetComponent<OuterConfig>().Port}";
 
 				response.Address = outerAddress;

+ 0 - 0
Server/Hotfix/Message/C2R_PingHandler.cs → Server/Hotfix/Handler/C2R_PingHandler.cs


+ 36 - 0
Server/Hotfix/Handler/DBQueryBatchRequestHandler.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.DB)]
+	public class DBQueryBatchRequestHandler : AMRpcHandler<DBQueryBatchRequest, DBQueryBatchResponse>
+	{
+		protected override async void Run(Session session, DBQueryBatchRequest message, Action<DBQueryBatchResponse> reply)
+		{
+			DBQueryBatchResponse response = new DBQueryBatchResponse();
+			try
+			{
+				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
+				List<Entity> entitys = await dbCacheComponent.GetBatch(message.CollectionName, message.IdList);
+
+				response.Entitys = entitys;
+
+				if (message.NeedCache)
+				{
+					foreach (Entity entity in entitys)
+					{
+						dbCacheComponent.AddToCache(entity, message.CollectionName);
+					}
+				}
+
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 36 - 0
Server/Hotfix/Handler/DBQueryJsonRequestHandler.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.DB)]
+	public class DBQueryJsonRequestHandler : AMRpcHandler<DBQueryJsonRequest, DBQueryJsonResponse>
+	{
+		protected override async void Run(Session session, DBQueryJsonRequest message, Action<DBQueryJsonResponse> reply)
+		{
+			DBQueryJsonResponse response = new DBQueryJsonResponse();
+			try
+			{
+				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
+				List<Entity> entitys = await dbCacheComponent.GetJson(message.CollectionName, message.Json);
+
+				response.Entitys = entitys;
+
+				if (message.NeedCache)
+				{
+					foreach (Entity entity in entitys)
+					{
+						dbCacheComponent.AddToCache(entity, message.CollectionName);
+					}
+				}
+
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 32 - 0
Server/Hotfix/Handler/DBQueryRequestHandler.cs

@@ -0,0 +1,32 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.DB)]
+	public class DBQueryRequestHandler : AMRpcHandler<DBQueryRequest, DBQueryResponse>
+	{
+		protected override async void Run(Session session, DBQueryRequest message, Action<DBQueryResponse> reply)
+		{
+			DBQueryResponse response = new DBQueryResponse();
+			try
+			{
+				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
+				Entity entity = await dbCacheComponent.Get(message.CollectionName, message.Id);
+
+				response.Entity = entity;
+
+				if (message.NeedCache && entity != null)
+				{
+					dbCacheComponent.AddToCache(entity, message.CollectionName);
+				}
+
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 39 - 0
Server/Hotfix/Handler/DBSaveBatchRequestHandler.cs

@@ -0,0 +1,39 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.DB)]
+	public class DBSaveBatchRequestHandler : AMRpcHandler<DBSaveBatchRequest, DBSaveBatchResponse>
+	{
+		protected override async void Run(Session session, DBSaveBatchRequest message, Action<DBSaveBatchResponse> reply)
+		{
+			DBSaveBatchResponse response = new DBSaveBatchResponse();
+			try
+			{
+				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
+
+				if (message.CollectionName == "")
+				{
+					message.CollectionName = message.Entitys[0].GetType().Name;
+				}
+
+				if (message.NeedCache)
+				{
+					foreach (Entity entity in message.Entitys)
+					{
+						dbCacheComponent.AddToCache(entity, message.CollectionName);
+					}
+				}
+
+				await dbCacheComponent.AddBatch(message.Entitys, message.CollectionName);
+
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 33 - 0
Server/Hotfix/Handler/DBSaveRequestHandler.cs

@@ -0,0 +1,33 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.DB)]
+	public class DBSaveRequestHandler : AMRpcHandler<DBSaveRequest, DBSaveResponse>
+	{
+		protected override async void Run(Session session, DBSaveRequest message, Action<DBSaveResponse> reply)
+		{
+			DBSaveResponse response = new DBSaveResponse();
+			try
+			{
+				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
+				if (message.CollectionName == "")
+				{
+					message.CollectionName = message.Entity.GetType().Name;
+				}
+
+				if (message.NeedCache)
+				{
+					dbCacheComponent.AddToCache(message.Entity, message.CollectionName);
+				}
+				await dbCacheComponent.Add(message.Entity, message.CollectionName);
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 0 - 0
Server/Hotfix/Message/G2G_LockReleaseRequestHandler.cs → Server/Hotfix/Handler/G2G_LockReleaseRequestHandler.cs


+ 0 - 0
Server/Hotfix/Message/G2G_LockRequestHandler.cs → Server/Hotfix/Handler/G2G_LockRequestHandler.cs


+ 41 - 0
Server/Hotfix/Handler/G2M_CreateUnitHandler.cs

@@ -0,0 +1,41 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Map)]
+	public class G2M_CreateUnitHandler : AMRpcHandler<G2M_CreateUnit, M2G_CreateUnit>
+	{
+		protected override async void Run(Session session, G2M_CreateUnit message, Action<M2G_CreateUnit> reply)
+		{
+			M2G_CreateUnit response = new M2G_CreateUnit();
+			try
+			{
+				Unit unit = EntityFactory.Create<Unit>();
+				await unit.AddComponent<ActorComponent, IEntityActorHandler>(new MapUnitEntityActorHandler()).AddLocation();
+				unit.AddComponent<UnitGateComponent, long>(message.GateSessionId);
+				Game.Scene.GetComponent<UnitComponent>().Add(unit);
+				response.UnitId = unit.Id;
+
+				response.Count = Game.Scene.GetComponent<UnitComponent>().Count;
+				reply(response);
+
+				if (response.Count == 2)
+				{
+					Actor_CreateUnits actorCreateUnits = new Actor_CreateUnits();
+					Unit[] units = Game.Scene.GetComponent<UnitComponent>().GetAll();
+					foreach (Unit u in units)
+					{
+						actorCreateUnits.Units.Add(new UnitInfo() {UnitId = u.Id, X = (int)(u.Position.X * 1000), Z = (int)(u.Position.Z * 1000) });
+					}
+					Log.Debug($"{MongoHelper.ToJson(actorCreateUnits)}");
+					MessageHelper.Broadcast(actorCreateUnits);
+				}
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 1 - 1
Server/Hotfix/Message/M2A_ReloadHandler.cs → Server/Hotfix/Handler/M2A_ReloadHandler.cs

@@ -11,7 +11,7 @@ namespace Hotfix
 			A2M_Reload response = new A2M_Reload();
 			try
 			{
-				ObjectEvents.Instance.Register("Hotfix", DllHelper.GetHotfixAssembly());
+				ObjectEvents.Instance.Add("Hotfix", DllHelper.GetHotfixAssembly());
 				reply(response);
 			}
 			catch (Exception e)

+ 27 - 0
Server/Hotfix/Handler/M2M_TrasferUnitRequest.cs

@@ -0,0 +1,27 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Map)]
+	public class M2M_TrasferUnitRequestHandler : AMRpcHandler<M2M_TrasferUnitRequest, M2M_TrasferUnitResponse>
+	{
+		protected override void Run(Session session, M2M_TrasferUnitRequest message, Action<M2M_TrasferUnitResponse> reply)
+		{
+			M2M_TrasferUnitResponse response = new M2M_TrasferUnitResponse();
+			try
+			{
+				Unit unit = message.Unit;
+				Log.Debug(MongoHelper.ToJson(message.Unit));
+				// 这里不需要注册location,因为unlock会更新位置
+				unit.AddComponent<ActorComponent>();
+				Game.Scene.GetComponent<UnitComponent>().Add(unit);
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 1 - 1
Server/Hotfix/Message/ObjectAddRequestHandler.cs → Server/Hotfix/Handler/ObjectAddRequestHandler.cs

@@ -11,7 +11,7 @@ namespace Hotfix
 			ObjectAddResponse response = new ObjectAddResponse();
 			try
 			{
-				Game.Scene.GetComponent<LocationComponent>().Add(message.Key, session.RemoteAddress);
+				Game.Scene.GetComponent<LocationComponent>().Add(message.Key, message.AppId);
 				reply(response);
 			}
 			catch (Exception e)

+ 3 - 3
Server/Hotfix/Message/ObjectGetRequestHandler.cs → Server/Hotfix/Handler/ObjectGetRequestHandler.cs

@@ -11,12 +11,12 @@ namespace Hotfix
 			ObjectGetResponse response = new ObjectGetResponse();
 			try
 			{
-				string location = await Game.Scene.GetComponent<LocationComponent>().GetAsync(message.Key);
-				if (location == "")
+				int appId = await Game.Scene.GetComponent<LocationComponent>().GetAsync(message.Key);
+				if (appId == 0)
 				{
 					response.Error = ErrorCode.ERR_ActorLocationNotFound;
 				}
-				response.Location = location;
+				response.AppId = appId;
 				reply(response);
 			}
 			catch (Exception e)

+ 1 - 1
Server/Hotfix/Message/ObjectLockRequestHandler.cs → Server/Hotfix/Handler/ObjectLockRequestHandler.cs

@@ -11,7 +11,7 @@ namespace Hotfix
 			ObjectLockResponse response = new ObjectLockResponse();
 			try
 			{
-				Game.Scene.GetComponent<LocationComponent>().Add(message.Key, session.RemoteAddress);
+				Game.Scene.GetComponent<LocationComponent>().LockAsync(message.Key, message.LockAppId, message.Time);
 				reply(response);
 			}
 			catch (Exception e)

+ 0 - 0
Server/Hotfix/Message/ObjectRemoveRequestHandler.cs → Server/Hotfix/Handler/ObjectRemoveRequestHandler.cs


+ 1 - 1
Server/Hotfix/Message/ObjectUnLockRequestHandler.cs → Server/Hotfix/Handler/ObjectUnLockRequestHandler.cs

@@ -11,7 +11,7 @@ namespace Hotfix
 			ObjectUnLockResponse response = new ObjectUnLockResponse();
 			try
 			{
-				Game.Scene.GetComponent<LocationComponent>().UnLock(message.Key);
+				Game.Scene.GetComponent<LocationComponent>().UpdateAndUnLock(message.Key, message.UnLockAppId, message.AppId);
 				reply(response);
 			}
 			catch (Exception e)

+ 2 - 1
Server/Hotfix/Message/R2G_GetLoginKeyHandler.cs → Server/Hotfix/Handler/R2G_GetLoginKeyHandler.cs

@@ -11,7 +11,8 @@ namespace Hotfix
 			G2R_GetLoginKey response = new G2R_GetLoginKey();
 			try
 			{
-				long key = Game.Scene.GetComponent<GateSessionKeyComponent>().Get();
+				long key = RandomHelper.RandInt64();
+				Game.Scene.GetComponent<GateSessionKeyComponent>().Add(key, message.Account);
 				response.Key = key;
 				reply(response);
 			}

+ 15 - 0
Server/Hotfix/Helper/HotfixHelper.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Reflection;
+
+namespace Hotfix
+{
+	public static class HotfixHelper
+	{
+		public static object Create(object old)
+		{
+			Assembly assembly = typeof(HotfixHelper).Assembly;
+			string objectName = old.GetType().FullName;
+			return Activator.CreateInstance(assembly.GetType(objectName));
+		}
+	}
+}

+ 18 - 0
Server/Hotfix/Helper/MessageHelper.cs

@@ -0,0 +1,18 @@
+using Model;
+
+namespace Hotfix
+{
+	public static class MessageHelper
+	{
+		public static void Broadcast(AActorMessage message)
+		{
+			Unit[] units = Game.Scene.GetComponent<UnitComponent>().GetAll();
+			ActorProxyComponent actorProxyComponent = Game.Scene.GetComponent<ActorProxyComponent>();
+			foreach (Unit unit in units)
+			{
+				long gateSessionId = unit.GetComponent<UnitGateComponent>().GateSessionId;
+				actorProxyComponent.Get(gateSessionId).Send(message);
+			}
+		}
+	}
+}

+ 52 - 0
Server/Hotfix/Other/EntityActorHandler.cs

@@ -0,0 +1,52 @@
+using System.Threading.Tasks;
+using Model;
+
+namespace Hotfix
+{
+    /// <summary>
+    /// gate session收到的消息直接转发给客户端
+    /// </summary>
+    public class GateSessionEntityActorHandler : IEntityActorHandler
+    {
+        public async Task Handle(Session session, Entity entity, ActorRequest message)
+        {
+            ((Session)entity).Send(message.AMessage);
+            ActorResponse response = new ActorResponse
+            {
+                RpcId = message.RpcId
+            };
+            session.Reply(response);
+        }
+    }
+
+    public class CommonEntityActorHandler : IEntityActorHandler
+    {
+        public async Task Handle(Session session, Entity entity, ActorRequest message)
+        {
+            await Game.Scene.GetComponent<ActorMessageDispatherComponent>().Handle(session, entity, message);
+        }
+    }
+
+    /// <summary>
+    /// 玩家收到帧同步消息交给帧同步组件处理
+    /// </summary>
+    public class MapUnitEntityActorHandler : IEntityActorHandler
+    {
+        public async Task Handle(Session session, Entity entity, ActorRequest message)
+        {
+            if (message.AMessage is AFrameMessage aFrameMessage)
+            {
+				// 客户端发送不需要设置Frame消息的id,在这里统一设置,防止客户端被破解发个假的id过来
+	            aFrameMessage.Id = entity.Id;
+				Game.Scene.GetComponent<ServerFrameComponent>().Add(aFrameMessage);
+	            ActorResponse response = new ActorResponse
+	            {
+		            RpcId = message.RpcId
+	            };
+	            session.Reply(response);
+				return;
+            }
+            await Game.Scene.GetComponent<ActorMessageDispatherComponent>().Handle(session, entity, message);
+        }
+    }
+}

+ 57 - 0
Server/Hotfix/Other/InnerMessageDispatcher.cs

@@ -0,0 +1,57 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	public class InnerMessageDispatcher: IMessageDispatcher
+	{
+		public void Dispatch(Session session, ushort opcode, int offset, byte[] messageBytes, AMessage message)
+		{
+			// 收到actor rpc request
+			if (message is ActorRpcRequest actorRpcRequest)
+			{
+				Entity entity = Game.Scene.GetComponent<ActorManagerComponent>().Get(actorRpcRequest.Id);
+				if (entity == null)
+				{
+					Log.Warning($"not found actor: {actorRpcRequest.Id}");
+					ActorRpcResponse response = new ActorRpcResponse
+					{
+						RpcId = actorRpcRequest.RpcId,
+						Error = ErrorCode.ERR_NotFoundActor
+					};
+					session.Reply(response);
+					return;
+				}
+				entity.GetComponent<ActorComponent>().Add(new ActorMessageInfo() { Session = session, Message = actorRpcRequest });
+				return;
+			}
+
+			// 收到actor消息分发给actor自己去处理
+			if (message is ActorRequest actorRequest)
+			{
+				Entity entity = Game.Scene.GetComponent<ActorManagerComponent>().Get(actorRequest.Id);
+				if (entity == null)
+				{
+					Log.Warning($"not found actor: {actorRequest.Id}");
+					ActorResponse response = new ActorResponse
+					{
+						RpcId = actorRequest.RpcId,
+						Error = ErrorCode.ERR_NotFoundActor
+					};
+					session.Reply(response);
+					return;
+				}
+				entity.GetComponent<ActorComponent>().Add(new ActorMessageInfo() { Session = session, Message = actorRequest });
+				return;
+			}
+
+			if (message is AMessage || message is ARequest)
+			{
+				Game.Scene.GetComponent<MessageDispatherComponent>().Handle(session, message);
+				return;
+			}
+
+			throw new Exception($"message type error: {message.GetType().FullName}");
+		}
+	}
+}

+ 40 - 0
Server/Hotfix/Other/OuterMessageDispatcher.cs

@@ -0,0 +1,40 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	public class OuterMessageDispatcher: IMessageDispatcher
+	{
+		public async void Dispatch(Session session, ushort opcode, int offset, byte[] messageBytes, AMessage message)
+		{
+			// gate session收到actor消息直接转发给actor自己去处理
+			if (message is AActorMessage)
+			{
+				long unitId = session.GetComponent<SessionPlayerComponent>().Player.UnitId;
+				ActorProxy actorProxy = Game.Scene.GetComponent<ActorProxyComponent>().Get(unitId);
+				actorProxy.Send(message);
+				return;
+			}
+
+			// gate session收到actor rpc消息,先向actor 发送rpc请求,再将请求结果返回客户端
+			if (message is AActorRequest aActorRequest)
+			{
+				long unitId = session.GetComponent<SessionPlayerComponent>().Player.UnitId;
+				ActorProxy actorProxy = Game.Scene.GetComponent<ActorProxyComponent>().Get(unitId);
+				uint rpcId = aActorRequest.RpcId;
+				AResponse response = await actorProxy.Call<AResponse>(aActorRequest);
+				response.RpcId = rpcId;
+				session.Reply(response);
+				return;
+			}
+
+			if (message != null)
+			{
+				Game.Scene.GetComponent<MessageDispatherComponent>().Handle(session, message);
+				return;
+			}
+
+			throw new Exception($"message type error: {message.GetType().FullName}");
+		}
+	}
+}

+ 0 - 35
Server/Hotfix/Properties/AssemblyInfo.cs

@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("Controller")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Controller")]
-[assembly: AssemblyCopyright("Copyright ©  2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-//将 ComVisible 设置为 false 将使此程序集中的类型
-//对 COM 组件不可见。  如果需要从 COM 访问此程序集中的类型,
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("3878bd71-2f75-4edf-882f-bc708154b1b0")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
-// 方法是按如下所示使用“*”: :
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.*")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 17 - 64
Server/Hotfix/Server.Hotfix.csproj

@@ -1,71 +1,24 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{3878BD71-2F75-4EDF-882F-BC708154B1B0}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Hotfix</RootNamespace>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
     <AssemblyName>Hotfix</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
+    <RootNamespace>Hotfix</RootNamespace>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\Bin\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;SERVER</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DefineConstants>TRACE;DEBUG;NETCOREAPP2_0;SERVER</DefineConstants>
+    <OutputPath>..\..\</OutputPath>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\Bin\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <DefineConstants>TRACE;RELEASE;NETCOREAPP2_0;SERVER</DefineConstants>
+    <OutputPath>..\..\</OutputPath>
   </PropertyGroup>
+
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Component\RealmGateAddressComponentE.cs" />
-    <Compile Include="Message\C2G_LoginGateHandler.cs" />
-    <Compile Include="Message\C2R_PingHandler.cs" />
-    <Compile Include="Message\G2G_LockReleaseRequestHandler.cs" />
-    <Compile Include="Message\ObjectGetRequestHandler.cs" />
-    <Compile Include="Message\ObjectUnLockRequestHandler.cs" />
-    <Compile Include="Message\ObjectLockRequestHandler.cs" />
-    <Compile Include="Message\ObjectRemoveRequestHandler.cs" />
-    <Compile Include="Message\ObjectAddRequestHandler.cs" />
-    <Compile Include="Message\M2A_ReloadHandler.cs" />
-    <Compile Include="Message\C2M_ReloadHandler.cs" />
-    <Compile Include="Message\G2G_LockRequestHandler.cs" />
-    <Compile Include="Message\R2G_GetLoginKeyHandler.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Message\C2R_LoginHandler.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Base\Server.Base.csproj">
-      <Project>{e5078ec6-2b0e-4711-be8b-d99f69638316}</Project>
-      <Name>Server.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Model\Server.Model.csproj">
-      <Project>{820d3488-76b9-4ee8-872a-be06c2350b20}</Project>
-      <Name>Server.Model</Name>
-    </ProjectReference>
+    <ProjectReference Include="..\Base\Server.Base.csproj" />
+    <ProjectReference Include="..\Model\Server.Model.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
+
+</Project>

+ 105 - 0
Server/Hotfix/System/ActorComponentSystem.cs

@@ -0,0 +1,105 @@
+using System;
+using System.Threading.Tasks;
+using Model;
+
+namespace Hotfix
+{
+	[ObjectEvent]
+	public class ActorComponentEvent : ObjectEvent<ActorComponent>, IAwake, IAwake<IEntityActorHandler>, ILoad
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+
+		public void Awake(IEntityActorHandler iEntityActorHandler)
+		{
+			this.Get().Awake(iEntityActorHandler);
+		}
+
+		public void Load()
+		{
+		}
+	}
+
+	/// <summary>
+	/// 挂上这个组件表示该Entity是一个Actor, 它会将Entity位置注册到Location Server, 接收的消息将会队列处理
+	/// </summary>
+	public static class ActorComponentSystem
+	{
+		public static void Awake(this ActorComponent self)
+		{
+			self.entityActorHandler = new CommonEntityActorHandler();
+			self.queue = new EQueue<ActorMessageInfo>();
+			self.actorId = self.Entity.Id;
+			Game.Scene.GetComponent<ActorManagerComponent>().Add(self.Entity);
+			self.HandleAsync();
+		}
+
+		public static void Awake(this ActorComponent self, IEntityActorHandler iEntityActorHandler)
+		{
+			self.entityActorHandler = iEntityActorHandler;
+			self.queue = new EQueue<ActorMessageInfo>();
+			self.actorId = self.Entity.Id;
+			Game.Scene.GetComponent<ActorManagerComponent>().Add(self.Entity);
+			self.HandleAsync();
+		}
+
+		// 热更新要重新创建接口,以便接口也能实现热更新
+		public static void Load(this ActorComponent self)
+		{
+			self.entityActorHandler = (IEntityActorHandler) HotfixHelper.Create(self.entityActorHandler);
+		}
+
+		public static async Task AddLocation(this ActorComponent self)
+		{
+			await Game.Scene.GetComponent<LocationProxyComponent>().Add(self.actorId);
+		}
+
+		public static async Task RemoveLocation(this ActorComponent self)
+		{
+			await Game.Scene.GetComponent<LocationProxyComponent>().Remove(self.actorId);
+		}
+
+		public static void Add(this ActorComponent self, ActorMessageInfo info)
+		{
+			self.queue.Enqueue(info);
+
+			if (self.tcs == null)
+			{
+				return;
+			}
+
+			var t = self.tcs;
+			self.tcs = null;
+			t.SetResult(self.queue.Dequeue());
+		}
+
+		private static Task<ActorMessageInfo> GetAsync(this ActorComponent self)
+		{
+			if (self.queue.Count > 0)
+			{
+				return Task.FromResult(self.queue.Dequeue());
+			}
+
+			self.tcs = new TaskCompletionSource<ActorMessageInfo>();
+			return self.tcs.Task;
+		}
+
+		private static async void HandleAsync(this ActorComponent self)
+		{
+			while (true)
+			{
+				try
+				{
+					ActorMessageInfo info = await self.GetAsync();
+					await self.entityActorHandler.Handle(info.Session, self.Entity, info.Message);
+				}
+				catch (Exception e)
+				{
+					Log.Error(e.ToString());
+				}
+			}
+		}
+	}
+}

+ 45 - 0
Server/Hotfix/System/NetInnerComponentSystem.cs

@@ -0,0 +1,45 @@
+using Model;
+
+namespace Hotfix
+{
+	[ObjectEvent]
+	public class NetInnerComponentEvent : ObjectEvent<NetInnerComponent>, IAwake, IAwake<string, int>, IUpdate
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+
+		public void Awake(string a, int b)
+		{
+			this.Get().Awake(a, b);
+		}
+
+		public void Update()
+		{
+			this.Get().Update();
+		}
+	}
+	
+	public static class NetInnerComponentSystem
+	{
+		public static void Awake(this NetInnerComponent self)
+		{
+			self.Awake(NetworkProtocol.TCP);
+			self.MessagePacker = new MongoPacker();
+			self.MessageDispatcher = new InnerMessageDispatcher();
+		}
+
+		public static void Awake(this NetInnerComponent self, string host, int port)
+		{
+			self.Awake(NetworkProtocol.TCP, host, port);
+			self.MessagePacker = new MongoPacker();
+			self.MessageDispatcher = new InnerMessageDispatcher();
+		}
+
+		public static void Update(this NetInnerComponent self)
+		{
+			self.Update();
+		}
+	}
+}

+ 45 - 0
Server/Hotfix/System/NetOuterComponentSystem.cs

@@ -0,0 +1,45 @@
+using Model;
+
+namespace Hotfix
+{
+	[ObjectEvent]
+	public class NetOuterComponentEvent : ObjectEvent<NetOuterComponent>, IAwake, IAwake<string, int>, IUpdate
+	{
+		public void Awake()
+		{
+			this.Get().Awake();
+		}
+
+		public void Awake(string a, int b)
+		{
+			this.Get().Awake(a, b);
+		}
+
+		public void Update()
+		{
+			this.Get().Update();
+		}
+	}
+
+	public static class NetOuterComponentSystem
+	{
+		public static void Awake(this NetOuterComponent self)
+		{
+			self.Awake(NetworkProtocol.TCP);
+			self.MessagePacker = new MongoPacker();
+			self.MessageDispatcher = new OuterMessageDispatcher();
+		}
+
+		public static void Awake(this NetOuterComponent self, string host, int port)
+		{
+			self.Awake(NetworkProtocol.TCP, host, port);
+			self.MessagePacker = new MongoPacker();
+			self.MessageDispatcher = new OuterMessageDispatcher();
+		}
+
+		public static void Update(this NetOuterComponent self)
+		{
+			self.Update();
+		}
+	}
+}

+ 5 - 5
Server/Hotfix/Component/RealmGateAddressComponentE.cs → Server/Hotfix/System/RealmGateAddressComponentSystem.cs

@@ -3,17 +3,17 @@
 namespace Hotfix
 {
 	[ObjectEvent]
-	public class RealmGateAddressComponentEvent : ObjectEvent<RealmGateAddressComponent>, IAwake
+	public class RealmGateAddressComponentEvent : ObjectEvent<RealmGateAddressComponent>, IStart
 	{
-		public void Awake()
+		public void Start()
 		{
-			this.Get().Awake();
+			this.Get().Start();
 		}
 	}
 	
-	public static class RealmGateAddressComponentE
+	public static class RealmGateAddressComponentSystem
 	{
-		public static void Awake(this RealmGateAddressComponent component)
+		public static void Start(this RealmGateAddressComponent component)
 		{
 			StartConfig[] startConfigs = component.GetComponent<StartConfigComponent>().GetAll();
 			foreach (StartConfig config in startConfigs)

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor