Explorar o código

增加服务端reload工具,测试方法:
1.启动服务端,客户端登录,关闭,再登录,此时出现两个小人,点击鼠标移动小人,客户端会打印log:actor rpc response
2.打开C2M_TestActorRequestHandler.cs,修改"actor rpc response"字符串为"actor rpc response after reload",编译Server.Hotfix工程
3.unity菜单->tools->服务端管理工具, 填上服务端manager地址,帐号panda,密码panda,点击Reload按钮
4.鼠标再点击客户端,让小人移动,此时客户端会打印"actor rpc response after reload"

tanghai %!s(int64=7) %!d(string=hai) anos
pai
achega
7a19df88e9

+ 14 - 0
Proto/OuterMessage.proto

@@ -88,4 +88,18 @@ message R2C_Ping // IResponse
 
 message G2C_Test // IMessage
 {
+}
+
+message C2M_Reload // IRequest
+{
+	int32 RpcId = 90;
+	string Account = 1;
+	string Password = 2;
+}
+
+message M2C_Reload // IResponse
+{
+	int32 RpcId = 90;
+	int32 Error = 91;
+	string Message = 92;
 }

+ 29 - 28
Server/Hotfix/Handler/C2M_ReloadHandler.cs

@@ -3,32 +3,33 @@ using ETModel;
 
 namespace ETHotfix
 {
-	//[MessageHandler(AppType.Manager)]
-	//public class C2M_ReloadHandler: AMRpcHandler<C2M_Reload, M2C_Reload>
-	//{
-	//	protected override async void Run(Session session, C2M_Reload message, Action<M2C_Reload> reply)
-	//	{
-	//		M2C_Reload response = new M2C_Reload();
-	//		try
-	//		{
-	//			StartConfigComponent startConfigComponent = Game.Scene.GetComponent<StartConfigComponent>();
-	//			NetInnerComponent netInnerComponent = Game.Scene.GetComponent<NetInnerComponent>();
-	//			foreach (StartConfig startConfig in startConfigComponent.GetAll())
-	//			{
-	//				if (!message.AppType.Is(startConfig.AppType))
-	//				{
-	//					continue;
-	//				}
-	//				InnerConfig innerConfig = startConfig.GetComponent<InnerConfig>();
-	//				Session serverSession = netInnerComponent.Get(innerConfig.IPEndPoint);
-	//				await serverSession.Call(new M2A_Reload());
-	//			}
-	//			reply(response);
-	//		}
-	//		catch (Exception e)
-	//		{
-	//			ReplyError(response, e, reply);
-	//		}
-	//	}
-	//}
+	[MessageHandler(AppType.Manager)]
+	public class C2M_ReloadHandler: AMRpcHandler<C2M_Reload, M2C_Reload>
+	{
+		protected override async void Run(Session session, C2M_Reload message, Action<M2C_Reload> reply)
+		{
+			M2C_Reload response = new M2C_Reload();
+			if (message.Account != "panda" && message.Password != "panda")
+			{
+				Log.Error($"error reload account and password: {MongoHelper.ToJson(message)}");
+				return;
+			}
+			try
+			{
+				StartConfigComponent startConfigComponent = Game.Scene.GetComponent<StartConfigComponent>();
+				NetInnerComponent netInnerComponent = Game.Scene.GetComponent<NetInnerComponent>();
+				foreach (StartConfig startConfig in startConfigComponent.GetAll())
+				{
+					InnerConfig innerConfig = startConfig.GetComponent<InnerConfig>();
+					Session serverSession = netInnerComponent.Get(innerConfig.IPEndPoint);
+					await serverSession.Call(new M2A_Reload());
+				}
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
 }

+ 11 - 1
Server/Hotfix/Module/Message/NetInnerComponentSystem.cs

@@ -20,6 +20,16 @@ namespace ETHotfix
 			self.Awake(a);
 		}
 	}
+	
+	[ObjectSystem]
+	public class NetInnerComponentLoadSystem : LoadSystem<NetInnerComponent>
+	{
+		public override void Load(NetInnerComponent self)
+		{
+			self.MessagePacker = new MongoPacker();
+			self.MessageDispatcher = new InnerMessageDispatcher();
+		}
+	}
 
 	[ObjectSystem]
 	public class NetInnerComponentUpdateSystem : UpdateSystem<NetInnerComponent>
@@ -30,7 +40,7 @@ namespace ETHotfix
 		}
 	}
 
-	public static class NetInnerComponentEx
+	public static class NetInnerComponentHelper
 	{
 		public static void Awake(this NetInnerComponent self)
 		{

+ 2 - 0
Unity/Assets/Editor/ServerCommandLineEditor/ServerCommandLineEditor.cs

@@ -28,6 +28,8 @@ namespace ETEditor
 
 		private readonly List<StartConfig> startConfigs = new List<StartConfig>();
 
+		private string managerAddress;
+
 		[MenuItem("Tools/命令行配置")]
 		private static void ShowWindow()
 		{

+ 8 - 0
Unity/Assets/Editor/ServerManagerEditor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 14ae219f71c290748a6737911d468d1a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 68 - 0
Unity/Assets/Editor/ServerManagerEditor/ServerManagerEditor.cs

@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using ETModel;
+using MongoDB.Bson;
+using UnityEditor;
+using UnityEngine;
+
+namespace ETEditor
+{
+	public class ServerManagerEditor: EditorWindow
+	{
+		private string managerAddress;
+		private string account;
+		private string password;
+
+		[MenuItem("Tools/服务器管理工具")]
+		private static void ShowWindow()
+		{
+			GetWindow(typeof (ServerManagerEditor));
+		}
+
+		private void OnGUI()
+		{
+			GUILayout.BeginHorizontal();
+			
+			GUILayout.Label("Manager外网地址:");
+			managerAddress = EditorGUILayout.TextField(this.managerAddress);
+			
+			GUILayout.Label("帐号:");
+			this.account = GUILayout.TextField(this.account);
+			
+			GUILayout.Label("密码:");
+			this.password = GUILayout.TextField(this.password);
+			
+			if (GUILayout.Button("Reload"))
+			{
+				if (!Application.isPlaying)
+				{
+					Log.Error($"Reload必须先启动客户端!");
+					return;
+				}
+
+				Reload(this.managerAddress, this.account, this.password);
+			}
+			
+			GUILayout.EndHorizontal();
+		}
+
+		private static async void Reload(string address, string account, string password)
+		{
+			using (Session session = Game.Scene.GetComponent<NetOuterComponent>().Create(address))
+			{
+				try
+				{
+					await session.Call(new C2M_Reload() {Account = account, Password = password});	
+					Log.Info($"Reload服务端成功!");
+				}
+				catch (Exception e)
+				{
+					Log.Error(e);
+				}
+			}
+		}
+	}
+}

+ 11 - 0
Unity/Assets/Editor/ServerManagerEditor/ServerManagerEditor.cs.meta

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

+ 10 - 0
Unity/Assets/Scripts/Module/Message/NetOuterComponentSystem.cs

@@ -26,6 +26,16 @@ namespace ETHotfix
 		}
 	}
 	
+	[ObjectSystem]
+	public class NetOuterComponentLoadSystem : LoadSystem<NetOuterComponent>
+	{
+		public override void Load(NetOuterComponent self)
+		{
+			self.MessagePacker = new ProtobufPacker();
+			self.MessageDispatcher = new OuterMessageDispatcher();
+		}
+	}
+	
 	[ObjectSystem]
 	public class NetOuterComponentUpdateSystem : UpdateSystem<NetOuterComponent>
 	{

+ 170 - 0
Unity/Assets/Scripts/Module/Message/OuterMessage.cs

@@ -1050,6 +1050,176 @@ namespace ETModel {
 
   }
 
+  public partial class C2M_Reload : pb::IMessage {
+    private static readonly pb::MessageParser<C2M_Reload> _parser = new pb::MessageParser<C2M_Reload>(() => (C2M_Reload)MessagePool.Instance.Fetch(typeof(C2M_Reload)));
+    public static pb::MessageParser<C2M_Reload> Parser { get { return _parser; } }
+
+    private int rpcId_;
+    public int RpcId {
+      get { return rpcId_; }
+      set {
+        rpcId_ = value;
+      }
+    }
+
+    private string account_ = "";
+    public string Account {
+      get { return account_; }
+      set {
+        account_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    private string password_ = "";
+    public string Password {
+      get { return password_; }
+      set {
+        password_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Account.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Account);
+      }
+      if (Password.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(Password);
+      }
+      if (RpcId != 0) {
+        output.WriteRawTag(208, 5);
+        output.WriteInt32(RpcId);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (RpcId != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(RpcId);
+      }
+      if (Account.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Account);
+      }
+      if (Password.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Password);
+      }
+      return size;
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      account_ = "";
+      password_ = "";
+      rpcId_ = 0;
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Account = input.ReadString();
+            break;
+          }
+          case 18: {
+            Password = input.ReadString();
+            break;
+          }
+          case 720: {
+            RpcId = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public partial class M2C_Reload : pb::IMessage {
+    private static readonly pb::MessageParser<M2C_Reload> _parser = new pb::MessageParser<M2C_Reload>(() => (M2C_Reload)MessagePool.Instance.Fetch(typeof(M2C_Reload)));
+    public static pb::MessageParser<M2C_Reload> Parser { get { return _parser; } }
+
+    private int rpcId_;
+    public int RpcId {
+      get { return rpcId_; }
+      set {
+        rpcId_ = value;
+      }
+    }
+
+    private int error_;
+    public int Error {
+      get { return error_; }
+      set {
+        error_ = value;
+      }
+    }
+
+    private string message_ = "";
+    public string Message {
+      get { return message_; }
+      set {
+        message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (RpcId != 0) {
+        output.WriteRawTag(208, 5);
+        output.WriteInt32(RpcId);
+      }
+      if (Error != 0) {
+        output.WriteRawTag(216, 5);
+        output.WriteInt32(Error);
+      }
+      if (Message.Length != 0) {
+        output.WriteRawTag(226, 5);
+        output.WriteString(Message);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (RpcId != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(RpcId);
+      }
+      if (Error != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Error);
+      }
+      if (Message.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(Message);
+      }
+      return size;
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      rpcId_ = 0;
+      error_ = 0;
+      message_ = "";
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 720: {
+            RpcId = input.ReadInt32();
+            break;
+          }
+          case 728: {
+            Error = input.ReadInt32();
+            break;
+          }
+          case 738: {
+            Message = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   #endregion
 
 }

+ 8 - 0
Unity/Assets/Scripts/Module/Message/OuterOpcode.cs

@@ -40,6 +40,12 @@ namespace ETModel
 	[Message(OuterOpcode.G2C_Test)]
 	public partial class G2C_Test : IMessage {}
 
+	[Message(OuterOpcode.C2M_Reload)]
+	public partial class C2M_Reload : IRequest {}
+
+	[Message(OuterOpcode.M2C_Reload)]
+	public partial class M2C_Reload : IResponse {}
+
 }
 namespace ETModel
 {
@@ -58,5 +64,7 @@ namespace ETModel
 		 public const ushort C2R_Ping = 111;
 		 public const ushort R2C_Ping = 112;
 		 public const ushort G2C_Test = 113;
+		 public const ushort C2M_Reload = 114;
+		 public const ushort M2C_Reload = 115;
 	}
 }

+ 1 - 1
Unity/Hotfix/Module/FrameSync/OperaComponent.cs

@@ -56,7 +56,7 @@ namespace ETHotfix
 		    {
 			    M2C_TestActorResponse response = (M2C_TestActorResponse)await SessionComponent.Instance.Session.Call(
 						new C2M_TestActorRequest() { Info = "actor rpc request" });
-			    //Log.Info(response.Info);
+			    Log.Info(response.Info);
 			}
 		    catch (Exception e)
 		    {