Эх сурвалжийг харах

增加了位置组件和位置服务器,任何Actor都会注册自己的位置到位置服务器

tanghai 8 жил өмнө
parent
commit
c6612ab9c1

+ 5 - 0
Server/App/Program.cs

@@ -51,9 +51,14 @@ namespace App
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
 						Game.Scene.AddComponent<GateSessionKeyComponent>();
 						break;
+					case AppType.Location:
+						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
+						Game.Scene.AddComponent<LocationComponent>();
+						break;
 					case AppType.AllServer:
 						Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);
 						Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);
+						Game.Scene.AddComponent<LocationComponent>();
 						Game.Scene.AddComponent<AppManagerComponent>();
 						Game.Scene.AddComponent<RealmGateAddressComponent>();
 						Game.Scene.AddComponent<GateSessionKeyComponent>();

+ 23 - 0
Server/Hotfix/Message/ObjectAddRequestHandler.cs

@@ -0,0 +1,23 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Location)]
+	public class ObjectAddRequestHandler : AMRpcHandler<ObjectAddRequest, ObjectAddResponse>
+	{
+		protected override void Run(Session session, ObjectAddRequest message, Action<ObjectAddResponse> reply)
+		{
+			ObjectAddResponse response = new ObjectAddResponse();
+			try
+			{
+				Game.Scene.GetComponent<LocationComponent>().Add(message.Key, session.RemoteAddress);
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 24 - 0
Server/Hotfix/Message/ObjectGetRequestHandler.cs

@@ -0,0 +1,24 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Location)]
+	public class ObjectGetRequestHandler : AMRpcHandler<ObjectGetRequest, ObjectGetResponse>
+	{
+		protected override async void Run(Session session, ObjectGetRequest message, Action<ObjectGetResponse> reply)
+		{
+			ObjectGetResponse response = new ObjectGetResponse();
+			try
+			{
+				string location = await Game.Scene.GetComponent<LocationComponent>().GetAsync(message.Key);
+				response.Location = location;
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 23 - 0
Server/Hotfix/Message/ObjectLockRequestHandler.cs

@@ -0,0 +1,23 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Location)]
+	public class ObjectLockRequestHandler : AMRpcHandler<ObjectLockRequest, ObjectLockResponse>
+	{
+		protected override void Run(Session session, ObjectLockRequest message, Action<ObjectLockResponse> reply)
+		{
+			ObjectLockResponse response = new ObjectLockResponse();
+			try
+			{
+				Game.Scene.GetComponent<LocationComponent>().Add(message.Key, session.RemoteAddress);
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 23 - 0
Server/Hotfix/Message/ObjectRemoveRequestHandler.cs

@@ -0,0 +1,23 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Location)]
+	public class ObjectRemoveRequestHandler : AMRpcHandler<ObjectRemoveRequest, ObjectRemoveResponse>
+	{
+		protected override void Run(Session session, ObjectRemoveRequest message, Action<ObjectRemoveResponse> reply)
+		{
+			ObjectRemoveResponse response = new ObjectRemoveResponse();
+			try
+			{
+				Game.Scene.GetComponent<LocationComponent>().Remove(message.Key);
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 23 - 0
Server/Hotfix/Message/ObjectUnLockRequestHandler.cs

@@ -0,0 +1,23 @@
+using System;
+using Model;
+
+namespace Hotfix
+{
+	[MessageHandler(AppType.Location)]
+	public class ObjectUnLockRequestHandler : AMRpcHandler<ObjectUnLockRequest, ObjectUnLockResponse>
+	{
+		protected override void Run(Session session, ObjectUnLockRequest message, Action<ObjectUnLockResponse> reply)
+		{
+			ObjectUnLockResponse response = new ObjectUnLockResponse();
+			try
+			{
+				Game.Scene.GetComponent<LocationComponent>().UnLock(message.Key);
+				reply(response);
+			}
+			catch (Exception e)
+			{
+				ReplyError(response, e, reply);
+			}
+		}
+	}
+}

+ 5 - 0
Server/Hotfix/Server.Hotfix.csproj

@@ -38,6 +38,11 @@
     <Compile Include="Message\C2G_LoginGateHandler.cs" />
     <Compile Include="Message\C2R_PingHandler.cs" />
     <Compile Include="Message\G2G_LockReleaseRequestHandler.cs" />
+    <Compile Include="Message\ObjectGetRequestHandler.cs" />
+    <Compile Include="Message\ObjectUnLockRequestHandler.cs" />
+    <Compile Include="Message\ObjectLockRequestHandler.cs" />
+    <Compile Include="Message\ObjectRemoveRequestHandler.cs" />
+    <Compile Include="Message\ObjectAddRequestHandler.cs" />
     <Compile Include="Message\M2A_ReloadHandler.cs" />
     <Compile Include="Message\C2M_ReloadHandler.cs" />
     <Compile Include="Message\G2G_LockRequestHandler.cs" />

+ 193 - 0
Server/Model/Component/LocationComponent.cs

@@ -0,0 +1,193 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Model
+{
+	public abstract class LocationTask : SceneEntity
+	{
+		protected LocationTask()
+		{
+		}
+
+		protected LocationTask(long id) : base(id)
+		{
+		}
+
+		public abstract void Run();
+	}
+
+	public sealed class LocationLockTask : LocationTask
+	{
+		private readonly string key;
+
+		private readonly TaskCompletionSource<bool> tcs;
+
+		public LocationLockTask(string key)
+		{
+			this.key = key;
+			this.tcs = new TaskCompletionSource<bool>();
+		}
+
+		public Task<bool> Task
+		{
+			get
+			{
+				return this.tcs.Task;
+			}
+		}
+
+		public override void Run()
+		{
+			try
+			{
+				Scene.GetComponent<LocationComponent>().Lock(this.key);
+				this.tcs.SetResult(true);
+			}
+			catch (Exception e)
+			{
+				this.tcs.SetException(e);
+			}
+		}
+	}
+
+	public sealed class LocationQueryTask : LocationTask
+	{
+		private readonly string key;
+
+		private readonly TaskCompletionSource<string> tcs;
+
+		public LocationQueryTask(string key)
+		{
+			this.key = key;
+			this.tcs = new TaskCompletionSource<string>();
+		}
+
+		public Task<string> Task
+		{
+			get
+			{
+				return this.tcs.Task;
+			}
+		}
+
+		public override void Run()
+		{
+			try
+			{
+				string location = Scene.GetComponent<LocationComponent>().Get(key);
+				this.tcs.SetResult(location);
+			}
+			catch (Exception e)
+			{
+				this.tcs.SetException(e);
+			}
+		}
+	}
+
+	public class LocationComponent : Component
+	{
+		private readonly Dictionary<string, string> locations = new Dictionary<string, string>();
+
+		private readonly HashSet<string> lockSet = new HashSet<string>();
+
+		private readonly Dictionary<string, Queue<LocationTask>> taskQueues = new Dictionary<string,Queue<LocationTask>>();
+
+		public void Add(string key, string address)
+		{
+			this.locations[key] = address;
+		}
+
+		public void Remove(string key)
+		{
+			this.locations.Remove(key);
+		}
+
+		public string Get(string key)
+		{
+			this.locations.TryGetValue(key, out string location);
+			return location;
+		}
+
+		public void Lock(string key)
+		{
+			if (this.lockSet.Contains(key))
+			{
+				return;
+			}
+			this.lockSet.Add(key);
+		}
+
+		public void UnLock(string key)
+		{
+			this.lockSet.Remove(key);
+
+			if (!this.taskQueues.TryGetValue(key, out Queue<LocationTask> tasks))
+			{
+				return;
+			}
+
+			while (true)
+			{
+				if (tasks.Count <= 0)
+				{
+					this.taskQueues.Remove(key);
+					return;
+				}
+				if (this.lockSet.Contains(key))
+				{
+					return;
+				}
+
+				LocationTask task = tasks.Dequeue();
+				task.Run();
+			}
+		}
+
+		public Task<bool> LockAsync(string key)
+		{
+			if (!this.lockSet.Contains(key))
+			{
+				this.Lock(key);
+				return Task.FromResult(true);
+			}
+
+			LocationLockTask task = new LocationLockTask(key);
+			this.AddTask(key, task);
+			return task.Task;
+		}
+
+		public Task<string> GetAsync(string key)
+		{
+			if (!this.lockSet.Contains(key))
+			{
+				this.locations.TryGetValue(key, out string location);
+				return Task.FromResult(location);
+			}
+
+			LocationQueryTask task = new LocationQueryTask(key);
+			this.AddTask(key, task);
+			return task.Task;
+		}
+
+		public void AddTask(string key, LocationTask task)
+		{
+			if (!this.taskQueues.TryGetValue(key, out Queue<LocationTask> tasks))
+			{
+				tasks = new Queue<LocationTask>();
+				this.taskQueues[key] = tasks;
+			}
+			task.Scene = this.GetOwner<Scene>();
+			tasks.Enqueue(task);
+		}
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+			base.Dispose();
+		}
+	}
+}

+ 1 - 0
Server/Model/Entity/DBEntity.cs

@@ -5,6 +5,7 @@ namespace Model
 	[BsonIgnoreExtraElements]
 	[BsonKnownTypes(typeof(RechargeRecord))]
 	[BsonKnownTypes(typeof(Recharge))]
+	[BsonKnownTypes(typeof(DBSceneEntity))]
 	public class DBEntity: Entity
 	{
 		protected DBEntity()

+ 19 - 0
Server/Model/Entity/DBSceneEntity.cs

@@ -0,0 +1,19 @@
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace Model
+{
+	// 需要记录自己所在Scene的继承这个类
+	public class DBSceneEntity : DBEntity
+	{
+		[BsonIgnore]
+		public Scene Scene { get; set; }
+
+		protected DBSceneEntity()
+		{
+		}
+
+		protected DBSceneEntity(long id) : base(id)
+		{
+		}
+	}
+}

+ 35 - 10
Server/Model/Entity/Message/InnerMessage.cs

@@ -1,13 +1,16 @@
 using System.Collections.Generic;
-
using MongoDB.Bson.Serialization.Attributes;
+
using MongoDB.Bson.Serialization.Attributes;
 
-
// 服务器内部消息 Opcode从10000开始
 
-
namespace Model
{
	[Message(Opcode.R2G_GetLoginKey)]
	[BsonIgnoreExtraElements]
	public class R2G_GetLoginKey : ARequest
	{
	}
+// 服务器内部消息 Opcode从10000开始
+
+
+namespace Model
{
	[Message(Opcode.R2G_GetLoginKey)]
	[BsonIgnoreExtraElements]
	public class R2G_GetLoginKey : ARequest
	{
	}
 
 
	[Message(Opcode.G2R_GetLoginKey)]
	[BsonIgnoreExtraElements]
	public class G2R_GetLoginKey : AResponse
	{
		public long Key;
-
		public G2R_GetLoginKey()
		{
		}
-		
		public G2R_GetLoginKey(long key)
		{
			this.Key = key;
		}
	}
+
		public G2R_GetLoginKey()
		{
		}
+
+		public G2R_GetLoginKey(long key)
		{
			this.Key = key;
		}
	}
 
 
	[Message(Opcode.M2A_Reload)]
	[BsonIgnoreExtraElements]
	public class M2A_Reload : ARequest
	{
	}
 
@@ -22,8 +25,9 @@ using System.Collections.Generic;
 
 
	[Message(Opcode.G2G_LockReleaseResponse)]
	[BsonIgnoreExtraElements]
	public class G2G_LockReleaseResponse : AResponse
	{
	}
 
	[Message(Opcode.DBSaveRequest)]
	[BsonIgnoreExtraElements]
	public class DBSaveRequest : ARequest
	{
		public bool NeedCache = true;
-
		public string CollectionName = "";
-		
		public Entity Entity;
	}
+
		public string CollectionName = "";
+
+		public Entity Entity;
	}
 
 
 
	[Message(Opcode.DBSaveBatchResponse)]
	[BsonIgnoreExtraElements]
	public class DBSaveBatchResponse : AResponse
	{
	}
@@ -36,9 +40,30 @@ using System.Collections.Generic;
 
 
	[Message(Opcode.DBQueryResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryResponse : AResponse
	{
		public Entity Entity;
	}
 
-
	[Message(Opcode.DBQueryBatchRequest)]
	[BsonIgnoreExtraElements]
	public class DBQueryBatchRequest : ARequest
	{
		public string CollectionName { get; set; }
		public List<long> IdList { get; set; }
		public bool NeedCache = true;
	}
-	
	[Message(Opcode.DBQueryBatchResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryBatchResponse : AResponse
	{
		public List<Entity> Entitys;
	}
+
	[Message(Opcode.DBQueryBatchRequest)]
	[BsonIgnoreExtraElements]
	public class DBQueryBatchRequest : ARequest
	{
		public string CollectionName { get; set; }
		public List<long> IdList { get; set; }
		public bool NeedCache = true;
	}
+
+	[Message(Opcode.DBQueryBatchResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryBatchResponse : AResponse
	{
		public List<Entity> Entitys;
	}
 
 
	[Message(Opcode.DBQueryJsonRequest)]
	[BsonIgnoreExtraElements]
	public class DBQueryJsonRequest : ARequest
	{
		public string CollectionName { get; set; }
		public string Json { get; set; }
		public bool NeedCache = true;
	}
 
-	[Message(Opcode.DBQueryJsonResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryJsonResponse : AResponse
	{
		public List<Entity> Entitys;
	}
}
+	[Message(Opcode.DBQueryJsonResponse)]
	[BsonIgnoreExtraElements]
	public class DBQueryJsonResponse : AResponse
	{
		public List<Entity> Entitys;
	}
+
+	[Message(Opcode.ObjectAddRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectAddRequest : ARequest
	{
		public string Key { get; set; }
	}
+
+	[Message(Opcode.ObjectAddResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectAddResponse : AResponse
	{
	}
+
+	[Message(Opcode.ObjectRemoveRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectRemoveRequest : ARequest
	{
		public string Key { get; set; }
	}
+
+	[Message(Opcode.ObjectRemoveResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectRemoveResponse : AResponse
	{
	}
+
+	[Message(Opcode.ObjectLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectLockRequest : ARequest
	{
		public string Key { get; set; }
	}
+
+	[Message(Opcode.ObjectLockResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectLockResponse : AResponse
	{
	}
+
+	[Message(Opcode.ObjectUnLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockRequest : ARequest
	{
		public string Key { get; set; }
	}
+
+	[Message(Opcode.ObjectUnLockResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockResponse : AResponse
	{
	}
+
+	[Message(Opcode.ObjectGetRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectGetRequest : ARequest
	{
		public string Key { get; set; }
	}
+
+	[Message(Opcode.ObjectGetResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectGetResponse : AResponse
	{
		public string Location { get; set; }
	}
}

+ 11 - 0
Server/Model/Entity/Message/Opcode.cs

@@ -21,6 +21,17 @@
 		public const ushort DBQueryJsonRequest = 65;
 		public const ushort DBQueryJsonResponse = 66;
 
+		public const ushort ObjectAddRequest = 70;
+		public const ushort ObjectAddResponse = 71;
+		public const ushort ObjectRemoveRequest = 72;
+		public const ushort ObjectRemoveResponse = 73;
+		public const ushort ObjectLockRequest = 74;
+		public const ushort ObjectLockResponse = 75;
+		public const ushort ObjectUnLockRequest = 76;
+		public const ushort ObjectUnLockResponse = 77;
+		public const ushort ObjectGetRequest = 78;
+		public const ushort ObjectGetResponse = 79;
+
 		public const ushort C2R_Login = 1000;
 		public const ushort R2C_Login = 1002;
 		public const ushort R2C_ServerLog = 1003;

+ 19 - 0
Server/Model/Entity/SceneEntity.cs

@@ -0,0 +1,19 @@
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace Model
+{
+	// 需要记录自己所在Scene的继承这个类
+	public class SceneEntity : Entity
+	{
+		[BsonIgnore]
+		public Scene Scene { get; set; }
+
+		protected SceneEntity()
+		{
+		}
+
+		protected SceneEntity(long id) : base(id)
+		{
+		}
+	}
+}

+ 5 - 4
Server/Model/Message/AppType.cs

@@ -10,13 +10,14 @@ namespace Model
 		Manager = 1,
 		Realm = 2,
 		Gate = 4,
+		Location = 8,
 
-		Benchmark = 8,
-		Client = 16,
-		Robot = 32,
+		Benchmark = 16,
+		Client = 32,
+		Robot = 64,
 
 		// 7
-		AllServer = Manager | Realm | Gate
+		AllServer = Manager | Realm | Gate | Location
 	}
 
 	public static class AppTypeHelper

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

@@ -66,6 +66,7 @@
     <Compile Include="Component\NetworkComponent.cs" />
     <Compile Include="Component\RobotComponent.cs" />
     <Compile Include="Component\TimerComponent.cs" />
+    <Compile Include="Component\LocationComponent.cs" />
     <Compile Include="Component\UnitComponent.cs" />
     <Compile Include="Component\Unit\MasterComponent.cs" />
     <Compile Include="Component\Unit\LockComponent.cs" />
@@ -82,6 +83,8 @@
     <Compile Include="Config\ICategory.cs" />
     <Compile Include="Entity\Config\BuffConfig.cs" />
     <Compile Include="Entity\Config\StartConfig.cs" />
+    <Compile Include="Entity\SceneEntity.cs" />
+    <Compile Include="Entity\DBSceneEntity.cs" />
     <Compile Include="Entity\DBEntity.cs" />
     <Compile Include="Entity\DBTask.cs" />
     <Compile Include="Entity\DBTaskQueue.cs" />

+ 9 - 0
Unity/Assets/Bundles/Unit.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 16b8671bdf883ae41b46bfa33ad75d46
+folderAsset: yes
+timeCreated: 1499149176
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Unity/Assets/Res/Scenes.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e49f438c1d69d61448301cd85b12138a
+folderAsset: yes
+timeCreated: 1499148953
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Unity/Assets/Res/Unit.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d8216925aec124948b7aa2b0798d80f6
+folderAsset: yes
+timeCreated: 1499149187
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: