diff --git a/CSharp/Game/Controller/Callback/BuffTimeoutCallback.cs b/CSharp/Game/Controller/Action/BuffTimeoutAction.cs similarity index 76% rename from CSharp/Game/Controller/Callback/BuffTimeoutCallback.cs rename to CSharp/Game/Controller/Action/BuffTimeoutAction.cs index a288cd0a748b98f9cc4ae8cc133d12b2ec03f91c..356bb80330e26bb2769b3b0f0343458a4c8aa233 100644 --- a/CSharp/Game/Controller/Callback/BuffTimeoutCallback.cs +++ b/CSharp/Game/Controller/Action/BuffTimeoutAction.cs @@ -4,8 +4,8 @@ using MongoDB.Bson; namespace Controller { - [Callback(CallbackType.BuffTimeoutCallback)] - public class BuffTimeoutCallback: IEvent + [Action(ActionType.BuffTimeoutAction)] + public class BuffTimeoutAction: IEventSync { public void Run(Env env) { diff --git a/CSharp/Game/Controller/Action/MessageAction.cs b/CSharp/Game/Controller/Action/MessageAction.cs new file mode 100644 index 0000000000000000000000000000000000000000..bbbef3f665eb9136f63ffb44c28570531d584115 --- /dev/null +++ b/CSharp/Game/Controller/Action/MessageAction.cs @@ -0,0 +1,20 @@ +using Common.Event; +using Model; +using MongoDB.Bson; + +namespace Controller +{ + [Action(ActionType.MessageAction)] + public class MessageAction : IEventSync + { + public void Run(Env env) + { + Unit unit = World.Instance.GetComponent().Get(ObjectId.Empty); + if (unit == null) + { + return; + } + unit.GetComponent().Add(env); + } + } +} \ No newline at end of file diff --git a/CSharp/Game/Controller/Controller.csproj b/CSharp/Game/Controller/Controller.csproj index 4a1daa4e6ab4d6af8d62bea812f56bef13a0957e..6a66c388be9afeb348ed4882d3d230750dba2bc9 100644 --- a/CSharp/Game/Controller/Controller.csproj +++ b/CSharp/Game/Controller/Controller.csproj @@ -48,12 +48,14 @@ + - + + diff --git a/CSharp/Game/Controller/Event/AfterAddBuff.cs b/CSharp/Game/Controller/Event/AfterAddBuff.cs index 8a50dfee8561a64396123ba4ec9a869ca064447d..9215be2285652d8a5379766a89f7dd912e379839 100644 --- a/CSharp/Game/Controller/Event/AfterAddBuff.cs +++ b/CSharp/Game/Controller/Event/AfterAddBuff.cs @@ -4,7 +4,7 @@ using Model; namespace Controller { [Event(EventType.AfterAddBuff)] - public class AddBuffToTimer: IEvent + public class AddBuffToTimer: IEventSync { public void Run(Env env) { diff --git a/CSharp/Game/Controller/Message/CMsgLogin.cs b/CSharp/Game/Controller/Message/CMsgLogin.cs new file mode 100644 index 0000000000000000000000000000000000000000..9c28fe1487c967d8b24322fb3cf2f51a4cbe76c3 --- /dev/null +++ b/CSharp/Game/Controller/Message/CMsgLogin.cs @@ -0,0 +1,16 @@ +using System; +using System.Threading.Tasks; +using Common.Event; +using Model; + +namespace Controller.Message +{ + [Message(1)] + internal class CMsgLogin: IEventAsync + { + public Task RunAsync(Env env) + { + throw new NotImplementedException(); + } + } +} diff --git a/CSharp/Game/Model/Buff.cs b/CSharp/Game/Model/Buff.cs index 65bc666cbaad51083b843f759f9ce09dd576af57..d2f18828b06f905ec00d903f522ccf2481e80769 100644 --- a/CSharp/Game/Model/Buff.cs +++ b/CSharp/Game/Model/Buff.cs @@ -63,7 +63,7 @@ namespace Model env[EnvKey.OwnerId] = this.OwnerId; env[EnvKey.BuffId] = this.Id; this.TimerId = World.Instance.GetComponent() - .Add(this.Expiration, CallbackType.BuffTimeoutCallback, env); + .Add(this.Expiration, ActionType.BuffTimeoutAction, env); } } @@ -101,7 +101,7 @@ namespace Model env[EnvKey.OwnerId] = this.OwnerId; env[EnvKey.BuffId] = this.Id; this.TimerId = World.Instance.GetComponent() - .Add(this.Expiration, CallbackType.BuffTimeoutCallback, env); + .Add(this.Expiration, ActionType.BuffTimeoutAction, env); } } diff --git a/CSharp/Game/Model/Component/ActorComponent.cs b/CSharp/Game/Model/Component/ActorComponent.cs new file mode 100644 index 0000000000000000000000000000000000000000..0c7070e7f1e9bcc68d6ad88bb2f4be10ace82a7e --- /dev/null +++ b/CSharp/Game/Model/Component/ActorComponent.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Common.Base; +using Common.Event; + +namespace Model +{ + public class ActorComponent : Component + { + private readonly Queue msgEnvQueue = new Queue(); + + public Action msgAction = () => {}; + + public async void Run() + { + while (true) + { + Env env = await this.Get(); + var message = env.Get(EnvKey.Message); + int opcode = BitConverter.ToUInt16(message, 0); + await World.Instance.GetComponent>().Run(opcode, env); + } + } + + public void Add(Env msgEnv) + { + this.msgEnvQueue.Enqueue(msgEnv); + msgAction(); + } + + private Task Get() + { + var tcs = new TaskCompletionSource(); + if (this.msgEnvQueue.Count > 0) + { + Env env = this.msgEnvQueue.Dequeue(); + tcs.SetResult(env); + } + else + { + msgAction = () => + { + msgAction = () => { }; + Env msg = this.msgEnvQueue.Dequeue(); + tcs.SetResult(msg); + }; + } + return tcs.Task; + } + } +} diff --git a/CSharp/Game/Model/Component/EventComponent.cs b/CSharp/Game/Model/Component/EventComponent.cs index 50a5919cf4320a8fccc771d63bfb6a8b037255db..b1651d01557d469dc527789e683aabd361afdab5 100644 --- a/CSharp/Game/Model/Component/EventComponent.cs +++ b/CSharp/Game/Model/Component/EventComponent.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Threading.Tasks; using Common.Base; using Common.Event; @@ -9,11 +10,14 @@ namespace Model public class EventComponent: Component, IAssemblyLoader where AttributeType : AEventAttribute { - private Dictionary> events; + private Dictionary> eventSyncs; + + private Dictionary> eventAsyncs; public void Load(Assembly assembly) { - this.events = new Dictionary>(); + this.eventSyncs = new Dictionary>(); + this.eventAsyncs = new Dictionary>(); Type[] types = assembly.GetTypes(); foreach (Type t in types) @@ -24,35 +28,63 @@ namespace Model continue; } object obj = Activator.CreateInstance(t); - IEvent iEvent = obj as IEvent; - if (iEvent == null) + IEventSync iEventSync = obj as IEventSync; + if (iEventSync != null) { - throw new Exception(string.Format("event not inherit IEvent interface: {0}", - obj.GetType().FullName)); - } + AEventAttribute iEventAttribute = (AEventAttribute)attrs[0]; - AEventAttribute iEventAttribute = (AEventAttribute) attrs[0]; + if (!this.eventSyncs.ContainsKey(iEventAttribute.Type)) + { + this.eventSyncs.Add(iEventAttribute.Type, new List()); + } + this.eventSyncs[iEventAttribute.Type].Add(iEventSync); + continue; + } - if (!this.events.ContainsKey(iEventAttribute.Type)) + IEventAsync iEventAsync = obj as IEventAsync; + // ReSharper disable once InvertIf + if (iEventAsync != null) { - this.events.Add(iEventAttribute.Type, new List()); + AEventAttribute iEventAttribute = (AEventAttribute)attrs[0]; + + if (!this.eventAsyncs.ContainsKey(iEventAttribute.Type)) + { + this.eventAsyncs.Add(iEventAttribute.Type, new List()); + } + this.eventAsyncs[iEventAttribute.Type].Add(iEventAsync); + continue; } - this.events[iEventAttribute.Type].Add(iEvent); + + throw new Exception( + string.Format("event not inherit IEventSync or IEventAsync interface: {0}", + obj.GetType().FullName)); } } - public void Run(int type, Env env) + public async Task Run(int type, Env env) { - List iEventDict = null; - if (!this.events.TryGetValue(type, out iEventDict)) + List iEventSyncs = null; + if (this.eventSyncs.TryGetValue(type, out iEventSyncs)) { - return; + foreach (IEventSync iEventSync in iEventSyncs) + { + iEventSync.Run(env); + } } - foreach (var iEvent in iEventDict) + List iEventAsyncs = null; + // ReSharper disable once InvertIf + if (this.eventAsyncs.TryGetValue(type, out iEventAsyncs)) { - iEvent.Run(env); + foreach (IEventAsync iEventAsync in iEventAsyncs) + { + await iEventAsync.RunAsync(env); + } } + + throw new Exception( + string.Format("no event handler, AttributeType: {0} type: {1}", + typeof(AttributeType).Name, type)); } } } \ No newline at end of file diff --git a/CSharp/Game/Model/Component/ServiceComponent.cs b/CSharp/Game/Model/Component/ServiceComponent.cs index 1a0f5fd774663ecb7bd90962ad8e3b74e09a2b35..3331ccfb8285d42576e4b9c4ac4c6063e47c493a 100644 --- a/CSharp/Game/Model/Component/ServiceComponent.cs +++ b/CSharp/Game/Model/Component/ServiceComponent.cs @@ -16,10 +16,10 @@ namespace Model switch (protocol) { case NetworkProtocol.TCP: - this.service = new TService("127.0.0.1", 8888); + this.service = new TService(host, port); break; case NetworkProtocol.UDP: - this.service = new UService("127.0.0.1", 8888); + this.service = new UService(host, port); break; default: throw new ArgumentOutOfRangeException("protocol"); @@ -37,7 +37,7 @@ namespace Model { while (true) { - IChannel channel = await this.service.GetChannel(); + AChannel channel = await this.service.GetChannel(); ProcessChannel(channel); } } @@ -46,15 +46,16 @@ namespace Model /// 接收分发封包 /// /// - private static async void ProcessChannel(IChannel channel) + private static async void ProcessChannel(AChannel channel) { while (true) { byte[] message = await channel.RecvAsync(); Env env = new Env(); + env[EnvKey.Channel] = channel; env[EnvKey.Message] = message; - int opcode = BitConverter.ToUInt16(message, 0); - World.Instance.GetComponent>().Run(opcode, env); + await World.Instance.GetComponent>() + .Run(ActionType.MessageAction, env); } } } diff --git a/CSharp/Game/Model/Component/TimerComponent.cs b/CSharp/Game/Model/Component/TimerComponent.cs index 62894c61299202acaaacb601b85203ef8f23de46..ee98954c6ed425775d675d6899d9e90b14670f8c 100644 --- a/CSharp/Game/Model/Component/TimerComponent.cs +++ b/CSharp/Game/Model/Component/TimerComponent.cs @@ -71,7 +71,7 @@ namespace Model continue; } this.Remove(id); - World.Instance.GetComponent>() + World.Instance.GetComponent>() .Run(timer.CallbackId, timer.Env); } } diff --git a/CSharp/Game/Model/EnvKey.cs b/CSharp/Game/Model/EnvKey.cs index b952a42b4cd567e750535a0e854f224cf720ac2a..73aa6b045aa5d0947205ccb19eb3fb4b3bd176cd 100644 --- a/CSharp/Game/Model/EnvKey.cs +++ b/CSharp/Game/Model/EnvKey.cs @@ -7,5 +7,6 @@ public const string Buff = "Buff"; public const string BuffId = "BuffId"; public const string Message = "Message"; + public const string Channel = "Channel"; } } \ No newline at end of file diff --git a/CSharp/Game/Model/EventAttribute.cs b/CSharp/Game/Model/EventAttribute.cs index 7655b254ab345b6d6428dc725c593f31486fbaaf..6349b1eb0a19aefadbea34c525548a8a8b75de8c 100644 --- a/CSharp/Game/Model/EventAttribute.cs +++ b/CSharp/Game/Model/EventAttribute.cs @@ -9,9 +9,9 @@ namespace Model } } - public class CallbackAttribute: AEventAttribute + public class ActionAttribute: AEventAttribute { - public CallbackAttribute(int type): base(type) + public ActionAttribute(int type): base(type) { } } diff --git a/CSharp/Game/Model/EventType.cs b/CSharp/Game/Model/EventType.cs index e41767b206214436d11030c2458e37f17252315e..5febed87c36a3d026271c19e7b3f042305eaa026 100644 --- a/CSharp/Game/Model/EventType.cs +++ b/CSharp/Game/Model/EventType.cs @@ -8,8 +8,9 @@ public const int AfterRemoveBuff = 3; } - public static class CallbackType + public static class ActionType { - public const int BuffTimeoutCallback = 0; + public const int BuffTimeoutAction = 0; + public const int MessageAction = 1; } } \ No newline at end of file diff --git a/CSharp/Game/Model/Model.csproj b/CSharp/Game/Model/Model.csproj index 34ce89c904fc2058c63e75ed7f5f5ae026c826d4..515cf538c0190461b1a5491658a4c11a8be3dc3c 100644 --- a/CSharp/Game/Model/Model.csproj +++ b/CSharp/Game/Model/Model.csproj @@ -45,6 +45,7 @@ + diff --git a/CSharp/Game/MongoDBTest/MongoDBTest.cs b/CSharp/Game/MongoDBTest/MongoDBTest.cs index 3dafab0a5d0ecaec728da6d6a582b3a3e3121d87..1bd1723cd99ffefb3c5e2a21810f31cab7a286b6 100644 --- a/CSharp/Game/MongoDBTest/MongoDBTest.cs +++ b/CSharp/Game/MongoDBTest/MongoDBTest.cs @@ -23,7 +23,7 @@ namespace MongoDBTest // 加载配置 world.AddComponent(); - world.AddComponent>(); + world.AddComponent>(); world.AddComponent>(); world.AddComponent(); world.AddComponent(); diff --git a/CSharp/Platform/Common/Common.csproj b/CSharp/Platform/Common/Common.csproj index 7bba0fc518a746f8278609103a6a8ec81cd037ff..a3e3e80a663506e68dc64a12157909c3b006178e 100644 --- a/CSharp/Platform/Common/Common.csproj +++ b/CSharp/Platform/Common/Common.csproj @@ -66,7 +66,8 @@ - + + diff --git a/CSharp/Platform/Common/Event/IEventAsync.cs b/CSharp/Platform/Common/Event/IEventAsync.cs new file mode 100644 index 0000000000000000000000000000000000000000..0d42cf4c893a532c3d554b76c91f7ebc95f39cfe --- /dev/null +++ b/CSharp/Platform/Common/Event/IEventAsync.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Common.Event +{ + public interface IEventAsync + { + Task RunAsync(Env env); + } +} \ No newline at end of file diff --git a/CSharp/Platform/Common/Event/IEvent.cs b/CSharp/Platform/Common/Event/IEventSync.cs similarity index 60% rename from CSharp/Platform/Common/Event/IEvent.cs rename to CSharp/Platform/Common/Event/IEventSync.cs index a4a36dd1ada1dc881890f36ea27a39b53d79412c..9dd1baf2addf630d9c4f698b0af3617b2c6df26d 100644 --- a/CSharp/Platform/Common/Event/IEvent.cs +++ b/CSharp/Platform/Common/Event/IEventSync.cs @@ -1,6 +1,6 @@ namespace Common.Event { - public interface IEvent + public interface IEventSync { void Run(Env env); } diff --git a/CSharp/Platform/Network/AChannel.cs b/CSharp/Platform/Network/AChannel.cs new file mode 100644 index 0000000000000000000000000000000000000000..03a4fdef90e527faf548dfd353a98529aef3ce00 --- /dev/null +++ b/CSharp/Platform/Network/AChannel.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using Common.Base; + +namespace Network +{ + [Flags] + public enum PacketFlags + { + None = 0, + Reliable = 1 << 0, + Unsequenced = 1 << 1, + NoAllocate = 1 << 2 + } + + public abstract class AChannel: Entity, IDisposable + { + /// + /// 发送消息 + /// + public abstract void SendAsync(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable); + + /// + /// 接收消息 + /// + public abstract Task RecvAsync(); + + public abstract Task DisconnnectAsync(); + + public abstract string RemoteAddress { get; } + + public abstract void Dispose(); + } +} \ No newline at end of file diff --git a/CSharp/Platform/Network/IChannel.cs b/CSharp/Platform/Network/IChannel.cs deleted file mode 100644 index c02470cd4714750180fbaf4a2531013a044f221d..0000000000000000000000000000000000000000 --- a/CSharp/Platform/Network/IChannel.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Network -{ - [Flags] - public enum PacketFlags - { - None = 0, - Reliable = 1 << 0, - Unsequenced = 1 << 1, - NoAllocate = 1 << 2 - } - - public interface IChannel: IDisposable - { - /// - /// 发送消息 - /// - void SendAsync(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable); - - /// - /// 接收消息 - /// - Task RecvAsync(); - - Task DisconnnectAsync(); - - string RemoteAddress { get; } - } -} \ No newline at end of file diff --git a/CSharp/Platform/Network/IService.cs b/CSharp/Platform/Network/IService.cs index d6d72e30201634eee036a3e7dd3a98fc02e0c27e..d2cfcffdce9aee1d47b2ad34f3f78c9e84c0c421 100644 --- a/CSharp/Platform/Network/IService.cs +++ b/CSharp/Platform/Network/IService.cs @@ -17,11 +17,11 @@ namespace Network /// void Add(Action action); - Task GetChannel(string host, int port); + Task GetChannel(string host, int port); - Task GetChannel(); + Task GetChannel(); - void Remove(IChannel channel); + void Remove(AChannel channel); void RunOnce(int timeout); diff --git a/CSharp/Platform/Network/Network.csproj b/CSharp/Platform/Network/Network.csproj index a9fd5d5013f198ce0df34ccbd0429eb181bb228b..761e2cbacfa7bdc3e0adc18aedb7307d907d524e 100644 --- a/CSharp/Platform/Network/Network.csproj +++ b/CSharp/Platform/Network/Network.csproj @@ -41,7 +41,13 @@ - + + + + + {19f8f043-1f99-4550-99df-dea5c7d77e55} + Common +