فهرست منبع

1.Realm Gate等服务器进程需要连接外网,所以需要监听两个端口,一个UDP对外,一个TCP对内
2.配置文件使用组件模式
3.Bson需要对继承的类进行注册,添加了BsonClassMapRegister类,在运行程序前注册

tanghai 9 سال پیش
والد
کامیت
7942886611
34فایلهای تغییر یافته به همراه464 افزوده شده و 209 حذف شده
  1. 14 9
      Server/App/Program.cs
  2. 9 0
      Server/App/Server.App.csproj
  3. 5 0
      Server/App/Start.txt
  4. 1 0
      Server/Controller/Message/C2G_LoginGateHandler.cs
  5. 6 3
      Server/Controller/Message/C2R_LoginHandler.cs
  6. 1 0
      Server/Controller/Message/R2G_GetLoginKeyHandler.cs
  7. 5 5
      Server/Model/Component/AppManagerComponent.cs
  8. 2 2
      Server/Model/Component/LogToClientComponent.cs
  9. 0 34
      Server/Model/Component/OptionsComponent.cs
  10. 6 6
      Server/Model/Component/RealmGateAddressComponent.cs
  11. 87 0
      Server/Model/Component/StartConfigComponent.cs
  12. 12 3
      Server/Model/Server.Model.csproj
  13. 103 36
      Unity/Assets/Editor/ServerCommandLineEditor/UI/ServerCommandLineEditor.cs
  14. 10 2
      Unity/Assets/Plugins/Base/Object/Component.cs
  15. 2 2
      Unity/Assets/Plugins/Base/Object/Component.cs.meta
  16. 2 0
      Unity/Assets/Plugins/Base/Object/Entity.cs
  17. 1 0
      Unity/Assets/Plugins/Base/Object/Object.cs
  18. 1 0
      Unity/Assets/Scripts/Component/MessageComponent.cs
  19. 6 3
      Unity/Assets/Scripts/Component/MessageDispatherComponent.cs
  20. 37 0
      Unity/Assets/Scripts/Component/NetInnerComponent.cs
  21. 12 0
      Unity/Assets/Scripts/Component/NetInnerComponent.cs.meta
  22. 37 0
      Unity/Assets/Scripts/Component/NetOuterComponent.cs
  23. 12 0
      Unity/Assets/Scripts/Component/NetOuterComponent.cs.meta
  24. 3 23
      Unity/Assets/Scripts/Component/NetworkComponent.cs
  25. 2 0
      Unity/Assets/Scripts/Init.cs
  26. 21 0
      Unity/Assets/Scripts/Other/BsonClassMapRegister.cs
  27. 12 0
      Unity/Assets/Scripts/Other/BsonClassMapRegister.cs.meta
  28. 0 37
      Unity/Assets/Scripts/Other/CommandLine.cs
  29. 15 35
      Unity/Assets/Scripts/Other/Options.cs
  30. 25 0
      Unity/Assets/Scripts/Other/StartConfig.cs
  31. 0 0
      Unity/Assets/Scripts/Other/StartConfig.cs.meta
  32. 3 4
      Unity/Controller/Event/InitSceneStartEvent_InitGame.cs
  33. 4 2
      Unity/Unity.CSharp.Plugins.csproj
  34. 8 3
      Unity/Unity.CSharp.csproj

+ 14 - 9
Server/App/Program.cs

@@ -1,6 +1,4 @@
 using System;
-using System.IO;
-using System.Reflection;
 using Base;
 using Model;
 using Object = Base.Object;
@@ -15,33 +13,40 @@ namespace App
 			{
 				Log.Info("server start........................");
 
+				BsonClassMapRegister.Register();
+
 				Object.ObjectManager.Register("Base", typeof(Game).Assembly);
 				Object.ObjectManager.Register("Model", typeof(ErrorCode).Assembly);
 				Object.ObjectManager.Register("Controller", DllHelper.GetController());
 
-				Options options = Game.Scene.AddComponent<OptionsComponent, string[]>(args).Options;
+				StartConfig startConfig = Game.Scene.AddComponent<StartConfigComponent, string[]>(args).MyConfig;
 				
 				Game.Scene.AddComponent<EventComponent>();
 				Game.Scene.AddComponent<TimerComponent>();
-				Game.Scene.AddComponent<NetworkComponent, NetworkProtocol, string, int>(options.Protocol, options.Host, options.Port);
-				Game.Scene.AddComponent<MessageDispatherComponent, string>(options.AppType);
-				
+
+				InnerConfig innerConfig = startConfig.Config.GetComponent<InnerConfig>();
+				Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
+				Game.Scene.AddComponent<MessageDispatherComponent, string>(startConfig.Options.AppType);
+
 				// 根据不同的AppType添加不同的组件
-				switch (options.AppType)
+				OuterConfig outerConfig = startConfig.Config.GetComponent<OuterConfig>();
+				switch (startConfig.Options.AppType)
 				{
 					case AppType.Manager:
+						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
 						Game.Scene.AddComponent<AppManagerComponent>();
 						break;
 					case AppType.Realm:
+						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
 						Game.Scene.AddComponent<RealmGateAddressComponent>();
 						break;
 					case AppType.Gate:
+						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
 						Game.Scene.AddComponent<GateSessionKeyComponent>();
 						break;
 					default:
-						throw new Exception($"命令行参数没有设置正确的AppType: {options.AppType}");
+						throw new Exception($"命令行参数没有设置正确的AppType: {startConfig.Options.AppType}");
 				}
-				
 
 				while (true)
 				{

+ 9 - 0
Server/App/Server.App.csproj

@@ -33,6 +33,10 @@
     <WarningLevel>4</WarningLevel>
   </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="System" />
     <Reference Include="System.Core" />
   </ItemGroup>
@@ -58,6 +62,11 @@
       <Name>Server.Model</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Start.txt">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+  </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.

+ 5 - 0
Server/App/Start.txt

@@ -0,0 +1,5 @@
+{ "_t" : "StartConfig", "Options" : { "_id" : 1, "AppType" : "Manager" }, "IP" : "192.168.12.112", "Config" : { "_id" : NumberLong("9223372036854775804"), "Type" : "StartConfig", "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("9223372036854775803"), "Host" : "127.0.0.1", "Port" : 10000 }, { "_t" : "OuterConfig", "_id" : NumberLong("9223372036854775802"), "Host" : "127.0.0.1", "Port" : 10001 }] } }
+{ "_t" : "StartConfig", "Options" : { "_id" : 2, "AppType" : "Realm" }, "IP" : "192.168.12.112", "Config" : { "_id" : NumberLong("9223372036854775804"), "Type" : "StartConfig", "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("9223372036854775803"), "Host" : "127.0.0.1", "Port" : 10002 }, { "_t" : "OuterConfig", "_id" : NumberLong("9223372036854775802"), "Host" : "127.0.0.1", "Port" : 10003 }] } }
+{ "_t" : "StartConfig", "Options" : { "_id" : 3, "AppType" : "Gate" }, "IP" : "192.168.12.112", "Config" : { "_id" : NumberLong("9223372036854775804"), "Type" : "StartConfig", "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("9223372036854775803"), "Host" : "127.0.0.1", "Port" : 10004 }, { "_t" : "OuterConfig", "_id" : NumberLong("9223372036854775802"), "Host" : "127.0.0.1", "Port" : 10005 }] } }
+{ "_t" : "StartConfig", "Options" : { "_id" : 4, "AppType" : "Gate" }, "IP" : "192.168.12.112", "Config" : { "_id" : NumberLong("9223372036854775804"), "Type" : "StartConfig", "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("9223372036854775803"), "Host" : "127.0.0.1", "Port" : 10006 }, { "_t" : "OuterConfig", "_id" : NumberLong("9223372036854775802"), "Host" : "127.0.0.1", "Port" : 10007 }] } }
+{ "_t" : "StartConfig", "Options" : { "_id" : 5, "AppType" : "Gate" }, "IP" : "192.168.12.112", "Config" : { "_id" : NumberLong("9223372036854775804"), "Type" : "StartConfig", "components" : [{ "_t" : "InnerConfig", "_id" : NumberLong("9223372036854775803"), "Host" : "127.0.0.1", "Port" : 10008 }, { "_t" : "OuterConfig", "_id" : NumberLong("9223372036854775802"), "Host" : "127.0.0.1", "Port" : 10009 }] } }

+ 1 - 0
Server/Controller/Message/C2G_LoginGateHandler.cs

@@ -9,6 +9,7 @@ namespace Controller
 	{
 		protected override void Run(Entity scene, C2G_LoginGate message, Action<G2C_LoginGate> reply)
 		{
+			Log.Info(MongoHelper.ToJson(message));
 			bool isCheckOK = Game.Scene.GetComponent<GateSessionKeyComponent>().Check(message.Key);
 			G2C_LoginGate g2CLoginGate = new G2C_LoginGate();
 			if (!isCheckOK)

+ 6 - 3
Server/Controller/Message/C2R_LoginHandler.cs

@@ -18,13 +18,16 @@ namespace Controller
 			}
 
 			// 随机分配一个Gate
-			string gateAddress = Game.Scene.GetComponent<RealmGateAddressComponent>().GetAddress();
-			Entity gateSession = Game.Scene.GetComponent<NetworkComponent>().Get(gateAddress);
+			Entity config = Game.Scene.GetComponent<RealmGateAddressComponent>().GetAddress();
+			Log.Info($"gate address: {MongoHelper.ToJson(config)}");
+			string innerAddress = $"{config.GetComponent<InnerConfig>().Host}:{config.GetComponent<InnerConfig>().Port}";
+			Entity gateSession = Game.Scene.GetComponent<NetInnerComponent>().Get(innerAddress);
 			
 			// 向gate请求一个key,客户端可以拿着这个key连接gate
 			G2R_GetLoginKey g2RGetLoginKey = await gateSession.GetComponent<MessageComponent>().Call<R2G_GetLoginKey, G2R_GetLoginKey>(new R2G_GetLoginKey());
 			
-			r2CLogin = new R2C_Login {Address = gateAddress, Key = g2RGetLoginKey.Key};
+			string outerAddress = $"{config.GetComponent<OuterConfig>().Host}:{config.GetComponent<OuterConfig>().Port}";
+			r2CLogin = new R2C_Login {Address = outerAddress, Key = g2RGetLoginKey.Key};
 			reply(r2CLogin);
 		}
 	}

+ 1 - 0
Server/Controller/Message/R2G_GetLoginKeyHandler.cs

@@ -9,6 +9,7 @@ namespace Controller
 	{
 		protected override void Run(Entity scene, R2G_GetLoginKey message, Action<G2R_GetLoginKey> reply)
 		{
+			Log.Info(MongoHelper.ToJson(message));
 			long key = Game.Scene.GetComponent<GateSessionKeyComponent>().Get();
 			G2R_GetLoginKey g2RGetLoginKey = new G2R_GetLoginKey(key);
 			reply(g2RGetLoginKey);

+ 5 - 5
Server/Model/Component/AppManagerComponent.cs

@@ -22,20 +22,20 @@ namespace Model
 		public void Awake()
 		{
 			string[] ips = NetHelper.GetAddressIPs();
-			CommandLines commandLines = Game.Scene.GetComponent<OptionsComponent>().AllOptions;
-			foreach (Options options in commandLines.Options)
+			StartConfig[] startConfigs = Game.Scene.GetComponent<StartConfigComponent>().GetAll();
+			foreach (StartConfig startConfig in startConfigs)
 			{
-				if (!ips.Contains(options.IP))
+				if (!ips.Contains(startConfig.IP))
 				{
 					continue;
 				}
 
-				if (options.AppType == AppType.Manager)
+				if (startConfig.Options.AppType == AppType.Manager)
 				{
 					continue;
 				}
 
-				string arguments = $"--appType={options.AppType} --id={options.Id} --Protocol={options.Protocol} --Host={options.Host} --Port={options.Port}";
+				string arguments = $"--id={startConfig.Options.Id} --appType={startConfig.Options.AppType}";
 
 				ProcessStartInfo info = new ProcessStartInfo(@"App.exe", arguments)
 				{

+ 2 - 2
Server/Model/Component/LogToClientComponent.cs

@@ -18,8 +18,8 @@ namespace Model
 
 		public void Awake()
 		{
-			this.appType = Game.Scene.GetComponent<OptionsComponent>().Options.AppType;
-			this.appId = Game.Scene.GetComponent<OptionsComponent>().Options.Id;
+			this.appType = Game.Scene.GetComponent<StartConfigComponent>().MyConfig.Options.AppType;
+			this.appId = Game.Scene.GetComponent<StartConfigComponent>().MyConfig.Options.Id;
 			Log.Callback.Add(this.Id, this.LogToClient);
 		}
 

+ 0 - 34
Server/Model/Component/OptionsComponent.cs

@@ -1,34 +0,0 @@
-using System;
-using System.IO;
-using Base;
-using CommandLine;
-
-namespace Model
-{
-	[ObjectEvent]
-	public class OptionsComponentEvent : ObjectEvent<OptionsComponent>, IAwake<string[]>
-	{
-		public void Awake(string[] args)
-		{
-			this.GetValue().Awake(args);
-		}
-	}
-
-	public class OptionsComponent: Component
-	{
-		public CommandLines AllOptions = new CommandLines();
-
-		public Options Options = new Options();
-
-		public void Awake(string[] args)
-		{
-			string s = File.ReadAllText("./CommandLineConfig.txt");
-			this.AllOptions = MongoHelper.FromJson<CommandLines>(s);
-
-			if (!Parser.Default.ParseArguments(args, this.Options))
-			{
-				throw new Exception($"命令行格式错误!");
-			}
-		}
-	}
-}

+ 6 - 6
Server/Model/Component/RealmGateAddressComponent.cs

@@ -14,22 +14,22 @@ namespace Model
 
 	public class RealmGateAddressComponent : Component
 	{
-		private readonly List<string> GateAddress = new List<string>();
+		private readonly List<Entity> GateAddress = new List<Entity>();
 
 		public void Awake()
 		{
-			CommandLines commandLines = this.GetComponent<OptionsComponent>().AllOptions;
-			foreach (Options options in commandLines.Options)
+			StartConfig[] startConfigs = this.GetComponent<StartConfigComponent>().GetAll();
+			foreach (StartConfig config in startConfigs)
 			{
-				if (options.AppType != "Gate")
+				if (config.Options.AppType != "Gate")
 				{
 					continue;
 				}
-				this.GateAddress.Add($"{options.Host}:{options.Port}");
+				this.GateAddress.Add(config.Config);
 			}
 		}
 
-		public string GetAddress()
+		public Entity GetAddress()
 		{
 			int n = RandomHelper.RandomNumber(0, this.GateAddress.Count);
 			return this.GateAddress[n];

+ 87 - 0
Server/Model/Component/StartConfigComponent.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Base;
+using CommandLine;
+using MongoDB.Bson.Serialization;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class OptionsComponentEvent : ObjectEvent<StartConfigComponent>, IAwake<string[]>
+	{
+		public void Awake(string[] args)
+		{
+			this.GetValue().Awake(args);
+		}
+	}
+
+	public class StartConfigComponent: Component
+	{
+		private readonly List<StartConfig> allConfigs = new List<StartConfig>();
+
+		private readonly Dictionary<int, StartConfig> configDict = new Dictionary<int, StartConfig>();
+
+		public StartConfig MyConfig { get; private set; }
+
+		public void Awake(string[] args)
+		{
+			//StartConfig sc = new StartConfig();
+			////sc.IP = "192.168.12.112";
+			////sc.Options.AppType = "Realm";
+			////sc.Options.Id = 1;
+			//
+			//InnerConfig inneConfig = sc.Config.AddComponent<InnerConfig>();
+			////inneConfig.Host = "127.0.0.1";
+			////inneConfig.Port = 10002;
+			//
+			//OuterConfig outerConfig = sc.Config.AddComponent<OuterConfig>();
+			////outerConfig.Host = "127.0.0.1";
+			////outerConfig.Port = 10003;
+			//
+			//string s3 = MongoHelper.ToJson(sc);
+			//StartConfig s4 = MongoHelper.FromJson<StartConfig>(s3);
+
+			//BsonClassMap.RegisterClassMap<OuterConfig>();
+			//BsonClassMap.RegisterClassMap<InnerConfig>();
+
+			string[] ss = File.ReadAllText("./Start.txt").Split('\n');
+			foreach (string s in ss)
+			{
+				string s2 = s.Trim();
+				if (s2 == "")
+				{
+					continue;
+				}
+				try
+				{
+					StartConfig startConfig = MongoHelper.FromJson<StartConfig>(s2);
+					this.allConfigs.Add(startConfig);
+					this.configDict.Add(startConfig.Options.Id, startConfig);
+				}
+				catch (Exception)
+				{
+					Log.Error($"config错误: {s2}");
+				}
+			}
+
+			Options options = new Options();
+			if (!Parser.Default.ParseArguments(args, options))
+			{
+				throw new Exception($"命令行格式错误!");
+			}
+
+			this.MyConfig = this.Get(options.Id);
+		}
+
+		public StartConfig Get(int id)
+		{
+			return this.configDict[id];
+		}
+
+		public StartConfig[] GetAll()
+		{
+			return this.allConfigs.ToArray();
+		}
+	}
+}

+ 12 - 3
Server/Model/Server.Model.csproj

@@ -53,6 +53,12 @@
     <Compile Include="..\..\Unity\Assets\Scripts\Component\MessageDispatherComponent.cs">
       <Link>Component\MessageDispatherComponent.cs</Link>
     </Compile>
+    <Compile Include="..\..\Unity\Assets\Scripts\Component\NetInnerComponent.cs">
+      <Link>Component\NetInnerComponent.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Unity\Assets\Scripts\Component\NetOuterComponent.cs">
+      <Link>Component\NetOuterComponent.cs</Link>
+    </Compile>
     <Compile Include="..\..\Unity\Assets\Scripts\Component\NetworkComponent.cs">
       <Link>Component\NetworkComponent.cs</Link>
     </Compile>
@@ -71,8 +77,8 @@
     <Compile Include="..\..\Unity\Assets\Scripts\Message\OpcodeHelper.cs">
       <Link>Message\OpcodeHelper.cs</Link>
     </Compile>
-    <Compile Include="..\..\Unity\Assets\Scripts\Other\CommandLine.cs">
-      <Link>Other\CommandLine.cs</Link>
+    <Compile Include="..\..\Unity\Assets\Scripts\Other\BsonClassMapRegister.cs">
+      <Link>Other\BsonClassMapRegister.cs</Link>
     </Compile>
     <Compile Include="..\..\Unity\Assets\Scripts\Other\EntityType.cs">
       <Link>Other\EntityType.cs</Link>
@@ -80,11 +86,14 @@
     <Compile Include="..\..\Unity\Assets\Scripts\Other\Options.cs">
       <Link>Other\Options.cs</Link>
     </Compile>
+    <Compile Include="..\..\Unity\Assets\Scripts\Other\StartConfig.cs">
+      <Link>Other\StartConfig.cs</Link>
+    </Compile>
     <Compile Include="Component\AppManagerComponent.cs" />
     <Compile Include="Component\LogToClientComponent.cs" />
     <Compile Include="Component\GateSessionKeyComponent.cs" />
     <Compile Include="Component\RealmGateAddressComponent.cs" />
-    <Compile Include="Component\OptionsComponent.cs" />
+    <Compile Include="Component\StartConfigComponent.cs" />
     <Compile Include="Helper\DllHelper.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>

+ 103 - 36
Unity/Assets/Editor/ServerCommandLineEditor/UI/ServerCommandLineEditor.cs

@@ -1,8 +1,10 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using Base;
 using Model;
+using MongoDB.Bson.Serialization;
 using UnityEditor;
 using UnityEngine;
 
@@ -10,63 +12,94 @@ namespace MyEditor
 {
 	public class ServerCommandLineEditor : EditorWindow
 	{
-		private const string Path = @"..\Server\Bin\Debug\CommandLineConfig.txt";
+		private const string Path = @"..\Server\App\Start.txt";
 
 		private int copyNum = 1;
 
-		private NetworkProtocol protocol;
+		private string AppType = Model.AppType.Realm;
 
-		private CommandLines commandLines;
+		private List<StartConfig> startConfigs = new List<StartConfig>();
 
 		[MenuItem("Tools/服务端命令行配置")]
-		static void ShowWindow()
+		private static void ShowWindow()
 		{
+			BsonClassMapRegister.Register();
 			GetWindow(typeof(ServerCommandLineEditor));
 		}
 
-		void OnEnable()
+		private void OnEnable()
 		{
 			if (!File.Exists(Path))
 			{
-				this.commandLines = new CommandLines();
 				return;
 			}
-			string s = File.ReadAllText(Path);
-			this.commandLines = MongoHelper.FromJson<CommandLines>(s);
+
+			string s2 = "";
+			try
+			{
+				string[] ss = File.ReadAllText(Path).Split('\n');
+				foreach (string s in ss)
+				{
+					s2 = s.Trim();
+					if (s2 == "")
+					{
+						continue;
+					}
+
+					StartConfig startConfig = MongoHelper.FromJson<StartConfig>(s2);
+					this.startConfigs.Add(startConfig);
+				}
+			}
+			catch (Exception e)
+			{
+				Log.Error($"加载配置失败! {s2} \n {e}");
+			}
 		}
 
-		void OnGUI()
+		private void OnGUI()
 		{
-			for (int i = 0; i < this.commandLines.Options.Count; ++i)
+			for (int i = 0; i < this.startConfigs.Count; ++i)
 			{
-				Options options = this.commandLines.Options[i];
+				StartConfig startConfig = this.startConfigs[i];
 				GUILayout.BeginHorizontal();
 				GUILayout.Label($"Id:");
-				options.Id = EditorGUILayout.IntField(options.Id);
+				startConfig.Options.Id = EditorGUILayout.IntField(startConfig.Options.Id);
 				GUILayout.Label($"服务器IP:");
-				options.IP = EditorGUILayout.TextField(options.IP);
+				startConfig.IP = EditorGUILayout.TextField(startConfig.IP);
 				GUILayout.Label($"AppType:");
-				options.AppType = EditorGUILayout.TextField(options.AppType);
-				GUILayout.Label($"Protocol:");
-				options.Protocol = (NetworkProtocol)EditorGUILayout.EnumPopup(options.Protocol);
-				GUILayout.Label($"Host:");
-				options.Host = EditorGUILayout.TextField(options.Host);
-				GUILayout.Label($"Port:");
-				options.Port = EditorGUILayout.IntField(options.Port);
+				startConfig.Options.AppType = EditorGUILayout.TextField(startConfig.Options.AppType);
+
+				InnerConfig innerConfig = startConfig.Config.GetComponent<InnerConfig>();
+				if (innerConfig != null)
+				{
+					GUILayout.Label($"Host:");
+					innerConfig.Host = EditorGUILayout.TextField(innerConfig.Host);
+					GUILayout.Label($"Port:");
+					innerConfig.Port = EditorGUILayout.IntField(innerConfig.Port);
+				}
+
+				OuterConfig outerConfig = startConfig.Config.GetComponent<OuterConfig>();
+				if (outerConfig != null)
+				{
+					GUILayout.Label($"OuterHost:");
+					outerConfig.Host = EditorGUILayout.TextField(outerConfig.Host);
+					GUILayout.Label($"OuterHost:");
+					outerConfig.Port = EditorGUILayout.IntField(outerConfig.Port);
+				}
+
+
 				if (GUILayout.Button("删除"))
 				{
-					this.commandLines.Options.Remove(options);
+					this.startConfigs.Remove(startConfig);
 					break;
 				}
 				if (GUILayout.Button("复制"))
 				{
 					for (int j = 1; j < this.copyNum + 1; ++j)
 					{
-						Options newOptions = (Options)options.Clone();
-						newOptions.Id += j;
-						newOptions.Port += j;
-						newOptions.Protocol = this.protocol;
-						this.commandLines.Options.Add(newOptions);
+						StartConfig newStartConfig = (StartConfig)startConfig.Clone();
+						newStartConfig.Options.Id += j;
+						this.startConfigs.Add(newStartConfig);
 					}
 					break;
 				}
@@ -75,27 +108,61 @@ namespace MyEditor
 
 			GUILayout.BeginHorizontal();
 			this.copyNum = EditorGUILayout.IntField("复制数量: ", this.copyNum);
-			this.protocol = (NetworkProtocol)EditorGUILayout.EnumPopup("协议: ", this.protocol);
 			GUILayout.EndHorizontal();
 
 			GUILayout.BeginHorizontal();
+
+			GUILayout.Label($"添加的AppType:");
+			this.AppType = EditorGUILayout.TextField(this.AppType);
+
 			if (GUILayout.Button("添加"))
 			{
-				Options newOptions = new Options();
-				newOptions.Protocol = this.protocol;
-				this.commandLines.Options.Add(newOptions);
+				StartConfig newStartConfig = new StartConfig();
+
+				newStartConfig.Options.AppType = this.AppType;
+				newStartConfig.Config.AddComponent<InnerConfig>();
+
+				if (this.AppType == Model.AppType.Gate || this.AppType == Model.AppType.Realm || this.AppType == Model.AppType.Manager)
+				{
+					newStartConfig.Config.AddComponent<OuterConfig>();
+				}
+
+				this.startConfigs.Add(newStartConfig);
 			}
+			GUILayout.EndHorizontal();
+
+			GUILayout.BeginHorizontal();
 
 			if (GUILayout.Button("保存"))
 			{
-				File.WriteAllText(Path, MongoHelper.ToJson(this.commandLines));
+				using (StreamWriter sw = new StreamWriter(new FileStream(Path, FileMode.Create)))
+				{
+					foreach (StartConfig startConfig in this.startConfigs)
+					{
+						sw.Write(MongoHelper.ToJson(startConfig));
+						sw.Write('\n');
+					}
+				}
 			}
 
 			if (GUILayout.Button("启动"))
 			{
-				Options options = this.commandLines.Manager;
+				StartConfig startConfig = null;
+				foreach (StartConfig config in this.startConfigs)
+				{
+					if (config.Options.AppType == Model.AppType.Manager)
+					{
+						startConfig = config;
+					}
+				}
+
+				if (startConfig == null)
+				{
+					Log.Error("没有配置Manager!");
+					return;
+				}
 				
-				string arguments = $"--appType={options.AppType} --id={options.Id} --Protocol={options.Protocol} --Host={options.Host} --Port={options.Port}";
+				string arguments = $"--id={startConfig.Options.Id} --appType={startConfig.Options.AppType}";
 
 				ProcessStartInfo info = new ProcessStartInfo(@"App.exe", arguments)
 				{
@@ -107,11 +174,11 @@ namespace MyEditor
 			GUILayout.EndHorizontal();
 		}
 
-		void OnDisable()
+		private void OnDisable()
 		{
 		}
 
-		void OnDestroy()
+		private void OnDestroy()
 		{
 		}
 	}

+ 10 - 2
Unity/Assets/Plugins/Base/Object/Component.cs

@@ -1,10 +1,13 @@
-namespace Base
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace Base
 {
 	/// <summary>
 	/// Component的Id与Owner Entity Id一样
 	/// </summary>
-	public abstract class Component: Object
+	public abstract class Component : Object
 	{
+		[BsonIgnore]
 		public Entity Owner { get; set; }
 
 		protected Component()
@@ -24,6 +27,11 @@
 
 		public override void Dispose()
 		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
 			base.Dispose();
 
 			ObjectManager.Remove(this.Id);

+ 2 - 2
Unity/Assets/Plugins/Base/Object/Component.cs.meta

@@ -1,6 +1,6 @@
 fileFormatVersion: 2
-guid: adf193ef36db369469293a2f53c76aa4
-timeCreated: 1474942922
+guid: 596cc447d1a588e47b6105622727b588
+timeCreated: 1477040243
 licenseType: Pro
 MonoImporter:
   serializedVersion: 2

+ 2 - 0
Unity/Assets/Plugins/Base/Object/Entity.cs

@@ -12,6 +12,8 @@ namespace Base
 
 		[BsonElement, BsonIgnoreIfNull]
 		private HashSet<Component> components = new HashSet<Component>();
+
+		[BsonIgnore]
 		private Dictionary<Type, Component> componentDict = new Dictionary<Type, Component>();
 
 		public Entity(string entityType)

+ 1 - 0
Unity/Assets/Plugins/Base/Object/Object.cs

@@ -6,6 +6,7 @@ namespace Base
 {
 	public abstract class Object: IDisposable, ISupportInitialize
 	{
+		[BsonIgnore]
 		public static ObjectManager ObjectManager = new ObjectManager();
 
 		[BsonId]

+ 1 - 0
Unity/Assets/Scripts/Component/MessageComponent.cs

@@ -166,6 +166,7 @@ namespace Model
 			where Response : AResponse
 		{
 			this.SendMessage(++RpcId, request);
+			
 			var tcs = new TaskCompletionSource<Response>();
 			this.requestCallback[RpcId] = (bytes, offset, count) =>
 			{

+ 6 - 3
Unity/Assets/Scripts/Component/MessageDispatherComponent.cs

@@ -117,6 +117,7 @@ namespace Model
 				try
 				{
                     message = MongoHelper.FromBson<Message>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+					Log.Info(MongoHelper.ToJson(message));
                 }
 			    catch (Exception ex)
 			    {
@@ -142,6 +143,7 @@ namespace Model
 				try
 				{
 					request = MongoHelper.FromBson<Request>(messageInfo.MessageBytes, messageInfo.Offset, messageInfo.Count);
+					Log.Info(MongoHelper.ToJson(request));
 				}
 				catch (Exception ex)
 				{
@@ -149,9 +151,10 @@ namespace Model
 				}
 
 				action(entity, request, response =>
-				{
-					entity.GetComponent<MessageComponent>().Reply(messageInfo.RpcId, response);
-				});
+					{
+						entity.GetComponent<MessageComponent>().Reply(messageInfo.RpcId, response); 
+					} 
+				);
 			});
 		}
 

+ 37 - 0
Unity/Assets/Scripts/Component/NetInnerComponent.cs

@@ -0,0 +1,37 @@
+using Base;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class NetInnerComponentEvent : ObjectEvent<NetInnerComponent>, IUpdate, IAwake, IAwake<string, int>
+	{
+		public void Update()
+		{
+			NetworkComponent component = this.GetValue();
+			component.Update();
+		}
+
+		public void Awake()
+		{
+			this.GetValue().Awake();
+		}
+
+		public void Awake(string host, int port)
+		{
+			this.GetValue().Awake(host, port);
+		}
+	}
+
+	public class NetInnerComponent : NetworkComponent
+	{
+		public void Awake()
+		{
+			this.Awake(NetworkProtocol.TCP);
+		}
+
+		public void Awake(string host, int port)
+		{
+			this.Awake(NetworkProtocol.TCP, host, port);
+		}
+	}
+}

+ 12 - 0
Unity/Assets/Scripts/Component/NetInnerComponent.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 1ab11b2f08956d1499373e40ab1eba6b
+timeCreated: 1477015901
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 37 - 0
Unity/Assets/Scripts/Component/NetOuterComponent.cs

@@ -0,0 +1,37 @@
+using Base;
+
+namespace Model
+{
+	[ObjectEvent]
+	public class NetOuterComponentEvent : ObjectEvent<NetOuterComponent>, IUpdate, IAwake, IAwake<string, int>
+	{
+		public void Update()
+		{
+			NetworkComponent component = this.GetValue();
+			component.Update();
+		}
+
+		public void Awake()
+		{
+			this.GetValue().Awake();
+		}
+
+		public void Awake(string host, int port)
+		{
+			this.GetValue().Awake(host, port);
+		}
+	}
+
+	public class NetOuterComponent : NetworkComponent
+	{
+		public void Awake()
+		{
+			this.Awake(NetworkProtocol.UDP);
+		}
+
+		public void Awake(string host, int port)
+		{
+			this.Awake(NetworkProtocol.UDP, host, port);
+		}
+	}
+}

+ 12 - 0
Unity/Assets/Scripts/Component/NetOuterComponent.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 2540893057b627148a6fe09470765227
+timeCreated: 1477015901
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 23
Unity/Assets/Scripts/Component/NetworkComponent.cs

@@ -4,34 +4,14 @@ using Base;
 
 namespace Model
 {
-	[ObjectEvent]
-	public class NetworkComponentEvent : ObjectEvent<NetworkComponent>, IUpdate, IAwake<NetworkProtocol>, IAwake<NetworkProtocol, string, int>
-	{
-		public void Update()
-		{
-			NetworkComponent component = this.GetValue();
-			component.Update();
-		}
-
-		public void Awake(NetworkProtocol protocol)
-		{
-			this.GetValue().Awake(protocol);
-		}
-
-		public void Awake(NetworkProtocol protocol, string host, int port)
-		{
-			this.GetValue().Awake(protocol, host, port);
-		}
-	}
-
-	public class NetworkComponent: Component
+	public abstract class NetworkComponent: Component
 	{
 		private AService Service;
 
 		private readonly Dictionary<long, Entity> sessions = new Dictionary<long, Entity>();
 		private readonly Dictionary<string, Entity> adressSessions = new Dictionary<string, Entity>();
 
-		public void Awake(NetworkProtocol protocol)
+		protected void Awake(NetworkProtocol protocol)
 		{
 			switch (protocol)
 			{
@@ -46,7 +26,7 @@ namespace Model
 			}
 		}
 
-		public void Awake(NetworkProtocol protocol, string host, int port)
+		protected void Awake(NetworkProtocol protocol, string host, int port)
 		{
 			switch (protocol)
 			{

+ 2 - 0
Unity/Assets/Scripts/Init.cs

@@ -1,5 +1,6 @@
 using System.Reflection;
 using Base;
+using MongoDB.Bson.Serialization;
 using UnityEngine;
 using Object = Base.Object;
 
@@ -9,6 +10,7 @@ namespace Model
 	{
 		private void Start()
 		{
+			BsonClassMapRegister.Register();
 			Object.ObjectManager.Register("Base", typeof(Game).Assembly);
 			Object.ObjectManager.Register("Model", typeof(Init).Assembly);
 			Object.ObjectManager.Register("Controller", DllHelper.GetController());

+ 21 - 0
Unity/Assets/Scripts/Other/BsonClassMapRegister.cs

@@ -0,0 +1,21 @@
+using MongoDB.Bson.Serialization;
+
+namespace Model
+{
+	public static class BsonClassMapRegister
+	{
+		private static bool isRegister;
+
+		public static void Register()
+		{
+			if (isRegister)
+			{
+				return;
+			}
+			isRegister = true;
+
+			BsonClassMap.RegisterClassMap<InnerConfig>();
+			BsonClassMap.RegisterClassMap<OuterConfig>();
+		}
+	}
+}

+ 12 - 0
Unity/Assets/Scripts/Other/BsonClassMapRegister.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 134d0d7bf9f397e48849fe72d43bee76
+timeCreated: 1477036759
+licenseType: Pro
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 0 - 37
Unity/Assets/Scripts/Other/CommandLine.cs

@@ -1,37 +0,0 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using MongoDB.Bson.Serialization.Attributes;
-
-namespace Model
-{
-	public class CommandLines: ISupportInitialize
-	{
-		[BsonIgnore]
-		public Options Manager { get; private set; }
-
-		[BsonIgnore]
-		public Options Realm { get; private set; }
-		
-		public List<Options> Options = new List<Options>();
-
-		public void BeginInit()
-		{
-		}
-
-		public void EndInit()
-		{
-			foreach (Options options in this.Options)
-			{
-				if (options.AppType == AppType.Realm)
-				{
-					this.Realm = options;
-				}
-
-				if (options.AppType == AppType.Manager)
-				{
-					this.Manager = options;
-				}
-			}
-		}
-	}
-}

+ 15 - 35
Unity/Assets/Scripts/Other/Options.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Text;
 using Base;
+using MongoDB.Bson.Serialization.Attributes;
 #if SERVER
 using CommandLine;
 #endif
@@ -14,46 +15,11 @@ namespace Model
 #endif
 		public int Id { get; set; }
 
-#if SERVER
-		[Option("IP", Required = false, HelpText = "进程运行的服务器ip.")]
-#endif
-		public string IP { get; set; }
-
 #if SERVER
 		[Option("appType", Required = true, HelpText = "AppType: realm gate")]
 #endif
 		public string AppType { get; set; }
 
-#if SERVER
-		[Option("protocol", Required = false, HelpText = "Protocol, tcp or udp.", DefaultValue = NetworkProtocol.UDP)]
-#endif
-		public NetworkProtocol Protocol { get; set; }
-
-#if SERVER
-		[Option("host", Required = true, HelpText = "Host.")]
-#endif
-		public string Host { get; set; }
-
-#if SERVER
-		[Option("port", Required = true, HelpText = "Port.")]
-#endif
-		public int Port { get; set; }
-
-#if SERVER
-		[Option("gateHost", Required = false, HelpText = "GateHost.")]
-#endif
-		public string GateHost { get; set; }
-
-#if SERVER
-		[Option("gatePort", Required = false, HelpText = "GatePort.")]
-#endif
-		public int GatePort { get; set; }
-
-#if SERVER
-		[Option('v', HelpText = "Print details during execution.")]
-#endif
-		public bool Verbose { get; set; }
-
 #if SERVER
 		[HelpOption]
 #endif
@@ -71,4 +37,18 @@ namespace Model
 			return MongoHelper.FromBson<Options>(MongoHelper.ToBson(this));
 		}
 	}
+
+	[BsonIgnoreExtraElements]
+	public class InnerConfig: Component
+	{
+		public string Host { get; set; }
+		public int Port { get; set; }
+	}
+
+	[BsonIgnoreExtraElements]
+	public class OuterConfig: Component
+	{
+		public string Host { get; set; }
+		public int Port { get; set; }
+	}
 }

+ 25 - 0
Unity/Assets/Scripts/Other/StartConfig.cs

@@ -0,0 +1,25 @@
+using System;
+using Base;
+
+namespace Model
+{
+	public class StartConfig: ICloneable
+	{
+		public Options Options { get; set; }
+
+		public string IP { get; set; }
+
+		public Entity Config { get; set; }
+
+		public StartConfig()
+		{
+			this.Options = new Options();
+			this.Config = new Entity("StartConfig");
+		}
+
+		public object Clone()
+		{
+			return MongoHelper.FromJson<StartConfig>(MongoHelper.ToJson(this));
+		}
+	}
+}

+ 0 - 0
Unity/Assets/Scripts/Other/CommandLine.cs.meta → Unity/Assets/Scripts/Other/StartConfig.cs.meta


+ 3 - 4
Unity/Controller/Event/InitSceneStartEvent_InitGame.cs

@@ -13,17 +13,16 @@ namespace Controller
 		public async void Run()
 		{
 			Game.Scene.AddComponent<MessageDispatherComponent, string>("Client");
-			NetworkComponent networkComponent = Game.Scene.AddComponent<NetworkComponent, NetworkProtocol>(NetworkProtocol.TCP);
-			Entity session = networkComponent.Get("127.0.0.1:10001");
+			NetworkComponent networkComponent = Game.Scene.AddComponent<NetOuterComponent>();
+			Entity session = networkComponent.Get("127.0.0.1:10003");
 
 			try
 			{
-				// 订阅服务端日志, 服务端收到这个消息会将之后的日志转发给客户端
-				await session.GetComponent<MessageComponent>().Call<C2R_SubscribeLog, R2C_SubscribeLog>(new C2R_SubscribeLog());
 				R2C_Login s2CLogin = await session.GetComponent<MessageComponent>().Call<C2R_Login, R2C_Login>(new C2R_Login {Account = "abcdef", Password = "111111"});
 				networkComponent.Remove(session.Id);
 
 				// 连接Gate
+				Log.Debug(MongoHelper.ToJson(s2CLogin));
 				Entity gateSession = networkComponent.Get(s2CLogin.Address);
 				await gateSession.GetComponent<MessageComponent>().Call<C2G_LoginGate, G2C_LoginGate>(new C2G_LoginGate(s2CLogin.Key));
 				Log.Info("连接Gate验证成功!");

+ 4 - 2
Unity/Unity.CSharp.Plugins.csproj

@@ -13,11 +13,13 @@
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <TargetFrameworkProfile>Unity Full v3.5</TargetFrameworkProfile>
-    <CompilerResponseFile></CompilerResponseFile>
+    <CompilerResponseFile>
+    </CompilerResponseFile>
     <UnityProjectType>GamePlugins:3</UnityProjectType>
     <UnityBuildTarget>StandaloneWindows:5</UnityBuildTarget>
     <UnityVersion>5.4.1f1</UnityVersion>
-    <RootNamespace></RootNamespace>
+    <RootNamespace>
+    </RootNamespace>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugType>pdbonly</DebugType>

+ 8 - 3
Unity/Unity.CSharp.csproj

@@ -13,11 +13,13 @@
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <TargetFrameworkProfile>Unity Full v3.5</TargetFrameworkProfile>
-    <CompilerResponseFile></CompilerResponseFile>
+    <CompilerResponseFile>
+    </CompilerResponseFile>
     <UnityProjectType>Game:1</UnityProjectType>
     <UnityBuildTarget>StandaloneWindows:5</UnityBuildTarget>
     <UnityVersion>5.4.1f1</UnityVersion>
-    <RootNamespace></RootNamespace>
+    <RootNamespace>
+    </RootNamespace>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -84,6 +86,8 @@
     <Compile Include="Assets\Scripts\Component\KVComponent.cs" />
     <Compile Include="Assets\Scripts\Component\MessageComponent.cs" />
     <Compile Include="Assets\Scripts\Component\MessageDispatherComponent.cs" />
+    <Compile Include="Assets\Scripts\Component\NetInnerComponent.cs" />
+    <Compile Include="Assets\Scripts\Component\NetOuterComponent.cs" />
     <Compile Include="Assets\Scripts\Component\NetworkComponent.cs" />
     <Compile Include="Assets\Scripts\Component\Scene.cs" />
     <Compile Include="Assets\Scripts\Component\TimeComponent.cs" />
@@ -100,7 +104,8 @@
     <Compile Include="Assets\Scripts\Message\ErrorCode.cs" />
     <Compile Include="Assets\Scripts\Message\Message.cs" />
     <Compile Include="Assets\Scripts\Message\OpcodeHelper.cs" />
-    <Compile Include="Assets\Scripts\Other\CommandLine.cs" />
+    <Compile Include="Assets\Scripts\Other\BsonClassMapRegister.cs" />
+    <Compile Include="Assets\Scripts\Other\StartConfig.cs" />
     <Compile Include="Assets\Scripts\Other\EntityType.cs" />
     <Compile Include="Assets\Scripts\Other\GameException.cs" />
     <Compile Include="Assets\Scripts\Other\Options.cs" />