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

HandlerAttribute带上消息type,消息反序列化完成再分发给处理的Handler

tanghai 12 лет назад
Родитель
Сommit
56aece6c92

+ 1 - 0
CSharp/Game/Component/Component.csproj

@@ -54,6 +54,7 @@
     <Compile Include="IHandler.cs" />
     <Compile Include="ILogic.cs" />
     <Compile Include="IType.cs" />
+    <Compile Include="KeyDefine.cs" />
     <Compile Include="LogicManager.cs" />
     <Compile Include="Message.cs" />
     <Compile Include="MessageAttribute.cs" />

+ 1 - 1
CSharp/Game/Component/EventAttribute.cs

@@ -6,6 +6,6 @@ namespace Component
 	public class EventAttribute : Attribute
 	{
 		public EventType Type { get; set; }
-		public int Number { get; set; }
+		public int Order { get; set; }
 	}
 }

+ 3 - 0
CSharp/Game/Component/EventType.cs

@@ -4,6 +4,9 @@ namespace Component
 	// 定义事件类型
 	public enum EventType: short
 	{
+		// 默认的event
+		DefaultEvent,
+
 		// 登录world前触发
 		BeforeLoginWorldEvent,
 

+ 1 - 0
CSharp/Game/Component/HandlerAttribute.cs

@@ -5,6 +5,7 @@ namespace Component
 	[AttributeUsage(AttributeTargets.Class)]
 	public class HandlerAttribute : Attribute
 	{
+		public Type Type { get; set; }
 		public int Opcode { get; set; }
 	}
 }

+ 1 - 1
CSharp/Game/Component/IHandler.cs

@@ -3,6 +3,6 @@ namespace Component
 {
 	public interface IHandler
 	{
-		void Handle(MessageEnv messageEnv, byte[] content);
+		void Handle(MessageEnv messageEnv);
 	}
 }

+ 8 - 0
CSharp/Game/Component/KeyDefine.cs

@@ -0,0 +1,8 @@
+
+namespace Component
+{
+	public static class KeyDefine
+	{
+		public const string KMessage = "message";
+	}
+}

+ 34 - 16
CSharp/Game/Component/LogicManager.cs

@@ -10,7 +10,7 @@ namespace Component
     {
 		private static readonly LogicManager instance = new LogicManager();
 
-		private Dictionary<int, IHandler> handlers;
+		private Dictionary<int, Tuple<IHandler, Type>> handlers;
 
 		private Dictionary<EventType, SortedDictionary<int, IEvent>> events;
 
@@ -34,7 +34,7 @@ namespace Component
 			Type[] types = assembly.GetTypes();
 
 			// 加载封包处理器
-			this.handlers = new Dictionary<int, IHandler>();
+			var localHandlers = new Dictionary<int, Tuple<IHandler, Type>>();
 			foreach (var type in types)
 			{
 				object[] attrs = type.GetCustomAttributes(typeof(HandlerAttribute), false);
@@ -44,16 +44,22 @@ namespace Component
 				}
 				var handler = (IHandler)Activator.CreateInstance(type);
 				int opcode = ((HandlerAttribute)attrs[0]).Opcode;
-				if (this.handlers.ContainsKey(opcode))
+				Type messageType = ((HandlerAttribute)attrs[0]).Type;
+				if (opcode == 0 || messageType == null)
+				{
+					throw new Exception(string.Format("not set opcode or type, handler name: {0}", type.Name));
+				}
+				if (localHandlers.ContainsKey(opcode))
 				{
 					throw new Exception(string.Format(
-						"same handler opcode, opcode: {0}, name: {1}", opcode, type.Name));
+						"same handler opcode, opcode: {0}, name: {1}", 
+						opcode, type.Name));
 				}
-				this.handlers[opcode] = handler;
+				localHandlers[opcode] = new Tuple<IHandler, Type>(handler, messageType);
 			}
 
 			// 加载事件处理器
-			this.events = new Dictionary<EventType, SortedDictionary<int, IEvent>>();
+			var localEvents = new Dictionary<EventType, SortedDictionary<int, IEvent>>();
 			foreach (var type in types)
 			{
 				object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
@@ -62,20 +68,30 @@ namespace Component
 					continue;
 				}
 				var evt = (IEvent)Activator.CreateInstance(type);
-				var eventType = ((EventAttribute)attrs[0]).Type;
-				var eventNumber = ((EventAttribute)attrs[0]).Number;
-				if (!this.events.ContainsKey(eventType))
+				EventType eventType = ((EventAttribute)attrs[0]).Type;
+				int eventOrder = ((EventAttribute)attrs[0]).Order;
+
+				if (eventOrder == 0 || eventType == EventType.DefaultEvent)
 				{
-					this.events[eventType] = new SortedDictionary<int, IEvent>();
+					throw new Exception(string.Format("not set order or type, event name: {0}", type.Name));
 				}
-				if (this.events[eventType].ContainsKey(eventNumber))
+
+				if (!localEvents.ContainsKey(eventType))
+				{
+					localEvents[eventType] = new SortedDictionary<int, IEvent>();
+				}
+				if (localEvents[eventType].ContainsKey(eventOrder))
 				{
 					throw new Exception(string.Format(
 						"same event number, type: {0}, number: {1}, name: {2}", 
-						eventType, eventNumber, type.Name));
+						eventType, eventOrder, type.Name));
 				}
-				this.events[eventType][eventNumber] = evt;
+				localEvents[eventType][eventOrder] = evt;
 			}
+
+			// 
+			this.handlers = localHandlers;
+			this.events = localEvents;
 		}
 
 		public void Reload()
@@ -85,16 +101,18 @@ namespace Component
 
 		public void Handle(short opcode, byte[] content)
 	    {
-		    IHandler handler = null;
-			if (!handlers.TryGetValue(opcode, out handler))
+			Tuple<IHandler, Type> tuple = null;
+			if (!handlers.TryGetValue(opcode, out tuple))
 			{
 				throw new Exception(string.Format("not found handler opcode {0}", opcode));
 			}
 
 			try
 			{
+				object message = MongoHelper.FromBson(content, tuple.Item2);
 				var messageEnv = new MessageEnv();
-				handler.Handle(messageEnv, content);
+				messageEnv[KeyDefine.KMessage] = message;
+				tuple.Item1.Handle(messageEnv);
 			}
 			catch (Exception e)
 			{

+ 8 - 2
CSharp/Game/Component/Message.cs

@@ -1,14 +1,20 @@
 
 namespace Component
 {
-	[MessageAttribute(Opcode = 1)]
 	public class CChat
 	{
 		public string Content { get; set; }
 	}
 
-	[MessageAttribute(Opcode = 2)]
 	public class CLoginWorld
 	{
 	}
+
+	public class CReloadHandler
+	{
+	}
+
+	public class CReloadConfig
+	{
+	}
 }

+ 1 - 1
CSharp/Game/Logic/Event/BeforeLoginWorldEvent.cs

@@ -3,7 +3,7 @@ using Log;
 
 namespace Logic
 {
-	[EventAttribute(Type = EventType.BeforeLoginWorldEvent, Number = 1)]
+	[EventAttribute(Type = EventType.BeforeLoginWorldEvent, Order = 1)]
 	public class CheckPlayerEvent : IEvent
 	{
 		public void Trigger(MessageEnv messageEnv)

+ 1 - 1
CSharp/Game/Logic/Event/BeforeUseItemEvent.cs

@@ -3,7 +3,7 @@ using Log;
 
 namespace Logic
 {
-	[EventAttribute(Type = EventType.BeforeUseItemEvent, Number = 1)]
+	[EventAttribute(Type = EventType.BeforeUseItemEvent, Order = 1)]
 	public class UseCountStatisticsEvent : IEvent
 	{
 		public void Trigger(MessageEnv messageEnv)

+ 3 - 3
CSharp/Game/Logic/Handler/ChatHandler.cs

@@ -5,12 +5,12 @@ using Component;
 
 namespace Logic
 {
-	[HandlerAttribute(Opcode = 1)]
+	[Handler(Type = typeof(CChat), Opcode = 1)]
 	class ChatHandler: IHandler
 	{
-		public void Handle(MessageEnv messageEnv, byte[] content)
+		public void Handle(MessageEnv messageEnv)
 		{
-			var chat = MongoHelper.FromBson<CChat>(content);
+			var chat = (CChat)messageEnv[KeyDefine.KMessage];
 
 			var world = World.World.Instance;
 			var globalConfig = world.ConfigManager.Get<GlobalConfig>(1);

+ 2 - 2
CSharp/Game/Logic/Handler/LoginWorldHandler.cs

@@ -2,10 +2,10 @@
 
 namespace Logic.Handler
 {
-	[Handler(Opcode = 2)]
+	[Handler(Type = typeof(CLoginWorld), Opcode = 2)]
 	public class LoginWorldHandler: IHandler
 	{
-		public void Handle(MessageEnv messageEnv, byte[] content)
+		public void Handle(MessageEnv messageEnv)
 		{
 			var world = World.World.Instance;
 			// 登录world前触发事件

+ 4 - 4
CSharp/Game/Logic/Handler/ReloadHandler.cs

@@ -2,20 +2,20 @@
 
 namespace Logic
 {
-	[HandlerAttribute(Opcode = 3)]
+	[Handler(Type = typeof(CReloadHandler), Opcode = 3)]
 	class ReloadHandlerHandler : IHandler
 	{
-		public void Handle(MessageEnv messageEnv, byte[] content)
+		public void Handle(MessageEnv messageEnv)
 		{
 			var world = World.World.Instance;
 			world.LogicManager.Reload();
 		}
 	}
 
-	[HandlerAttribute(Opcode = 4)]
+	[Handler(Type = typeof(CReloadConfig), Opcode = 4)]
 	class ReloadConfigHandler: IHandler
 	{
-		public void Handle(MessageEnv messageEnv, byte[] content)
+		public void Handle(MessageEnv messageEnv)
 		{
 			var world = World.World.Instance;
 			world.ConfigManager.Reload();

+ 1 - 2
CSharp/Game/WorldTest/WorldTest.cs

@@ -1,5 +1,4 @@
-using System;
-using System.Threading;
+using System.Threading;
 using Component;
 using Helper;
 using Microsoft.VisualStudio.TestTools.UnitTesting;

+ 12 - 0
CSharp/Platform/TNet/Class1.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TNet
+{
+    public class Class1
+    {
+    }
+}

+ 36 - 0
CSharp/Platform/TNet/Properties/AssemblyInfo.cs

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

+ 59 - 0
CSharp/Platform/TNet/TNet.csproj

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.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')" />
+	<PropertyGroup>
+		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+		<ProjectGuid>f6339a3f-46f7-420a-ad20-a365f724a470</ProjectGuid>
+		<OutputType>Library</OutputType>
+		<AppDesignerFolder>Properties</AppDesignerFolder>
+		<RootNamespace>TNet</RootNamespace>
+		<AssemblyName>TNet</AssemblyName>
+		<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+		<FileAlignment>512</FileAlignment>
+	</PropertyGroup>
+	<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+		<DebugSymbols>true</DebugSymbols>
+		<DebugType>full</DebugType>
+		<Optimize>false</Optimize>
+		<OutputPath>bin\Debug\</OutputPath>
+		<DefineConstants>DEBUG;TRACE</DefineConstants>
+		<ErrorReport>prompt</ErrorReport>
+		<WarningLevel>4</WarningLevel>
+	</PropertyGroup>
+	<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+		<DebugType>pdbonly</DebugType>
+ 		<Optimize>true</Optimize>
+		<OutputPath>bin\Release\</OutputPath>
+		<DefineConstants>TRACE</DefineConstants>
+		<ErrorReport>prompt</ErrorReport>
+		<WarningLevel>4</WarningLevel>
+	</PropertyGroup>
+	<ItemGroup>
+		<Reference Include="System"/>
+		
+		<Reference Include="System.Core"/>
+		<Reference Include="System.Xml.Linq"/>
+		<Reference Include="System.Data.DataSetExtensions"/>
+		
+		
+		<Reference Include="Microsoft.CSharp"/>
+ 		
+		<Reference Include="System.Data"/>
+		<Reference Include="System.Xml"/>
+	</ItemGroup>
+	<ItemGroup>
+		<Compile Include="Class1.cs" />
+
+		<Compile Include="Properties\AssemblyInfo.cs" />
+	</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>