using System; using System.Collections.Generic; namespace ET { /// /// 消息分发组件 /// [FriendOf(typeof(MessageDispatcherComponent))] public static class MessageDispatcherComponentHelper { [ObjectSystem] public class MessageDispatcherComponentAwakeSystem: AwakeSystem { protected override void Awake(MessageDispatcherComponent self) { MessageDispatcherComponent.Instance = self; self.Load(); } } [ObjectSystem] public class MessageDispatcherComponentLoadSystem: LoadSystem { protected override void Load(MessageDispatcherComponent self) { self.Load(); } } [ObjectSystem] public class MessageDispatcherComponentDestroySystem: DestroySystem { protected override void Destroy(MessageDispatcherComponent self) { MessageDispatcherComponent.Instance = null; self.Handlers.Clear(); } } private static void Load(this MessageDispatcherComponent self) { self.Handlers.Clear(); HashSet types = EventSystem.Instance.GetTypes(typeof (MessageHandlerAttribute)); foreach (Type type in types) { IMHandler iMHandler = Activator.CreateInstance(type) as IMHandler; if (iMHandler == null) { Log.Error($"message handle {type.Name} 需要继承 IMHandler"); continue; } object[] attrs = type.GetCustomAttributes(typeof(MessageHandlerAttribute), false); foreach (object attr in attrs) { MessageHandlerAttribute messageHandlerAttribute = attr as MessageHandlerAttribute; Type messageType = iMHandler.GetMessageType(); ushort opcode = NetServices.Instance.GetOpcode(messageType); if (opcode == 0) { Log.Error($"消息opcode为0: {messageType.Name}"); continue; } MessageDispatcherInfo messageDispatcherInfo = new (messageHandlerAttribute.SceneType, iMHandler); self.RegisterHandler(opcode, messageDispatcherInfo); } } } private static void RegisterHandler(this MessageDispatcherComponent self, ushort opcode, MessageDispatcherInfo handler) { if (!self.Handlers.ContainsKey(opcode)) { self.Handlers.Add(opcode, new List()); } self.Handlers[opcode].Add(handler); } public static void Handle(this MessageDispatcherComponent self, Session session, object message) { List actions; ushort opcode = NetServices.Instance.GetOpcode(message.GetType()); if (!self.Handlers.TryGetValue(opcode, out actions)) { Log.Error($"消息没有处理: {opcode} {message}"); return; } SceneType sceneType = session.DomainScene().SceneType; foreach (MessageDispatcherInfo ev in actions) { if (ev.SceneType != sceneType) { continue; } try { ev.IMHandler.Handle(session, message); } catch (Exception e) { Log.Error(e); } } } } }