Room.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using CSharpUtil;
  2. using CSharpUtil.Net;
  3. using ProtoDataBuff;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Threading.Channels;
  8. using System.Threading.Tasks;
  9. using static System.Console;
  10. using pb = global::Google.Protobuf;
  11. using MultiDup;
  12. namespace BattleRoom
  13. {
  14. /// <summary>
  15. /// 房间状态
  16. /// </summary>
  17. enum RoomState
  18. {
  19. /// <summary>
  20. /// 开启状态(可以连接登入)
  21. /// </summary>
  22. Open,
  23. /// <summary>
  24. /// 已关闭(不可继续登录)
  25. /// </summary>
  26. Close,
  27. }
  28. enum TargetType
  29. {
  30. /// <summary>
  31. /// 所有
  32. /// </summary>
  33. All,
  34. /// <summary>
  35. /// 其他人
  36. /// </summary>
  37. Others,
  38. }
  39. class PropertyName
  40. {
  41. public const string Uid = nameof(Uid);
  42. public const string Name = nameof(Name);
  43. public const string Zoneid = nameof(Zoneid);
  44. public const string Hp = nameof(Hp);
  45. public const string MaxHp = nameof(MaxHp);
  46. public const string TotalDamage = nameof(TotalDamage);
  47. }
  48. /// <summary>
  49. /// 房间对象
  50. /// </summary>
  51. class Room
  52. {
  53. /// <summary>
  54. /// 房间状态字段
  55. /// </summary>
  56. public RoomState CurrentState = RoomState.Close;
  57. /// <summary>
  58. /// 客户端
  59. /// </summary>
  60. public Dictionary<int, Peer> ClientPeers = new Dictionary<int, Peer>();
  61. /// <summary>
  62. /// 消息分发
  63. /// </summary>
  64. private Dictionary<eProtocalCommand, Action<int, sSocketData>> callbacks = new Dictionary<eProtocalCommand, Action<int, sSocketData>>();
  65. /// <summary>
  66. /// 客户端消息队列
  67. /// </summary>
  68. public Channel<KeyValuePair<int, sSocketData>> MsgChannel = Channel.CreateBounded<KeyValuePair<int, sSocketData>>(1000);
  69. /// <summary>
  70. /// 房间编号
  71. /// </summary>
  72. public int Id { get; }
  73. /// <summary>
  74. /// 玩家id集合
  75. /// </summary>
  76. public List<string> PlayerUids = new List<string>();
  77. /// <summary>
  78. /// 战斗服务器端口
  79. /// </summary>
  80. public int BattleServerPort = 6006;
  81. /// <summary>
  82. /// 战斗服务器IP地址
  83. /// </summary>
  84. public string BattleServerIp = "192.168.10.17";
  85. /// <summary>
  86. /// 构造函数
  87. /// </summary>
  88. public Room(int RoomId, IEnumerable<string> uids)
  89. {
  90. Id = RoomId;
  91. PlayerUids = uids.ToList();
  92. callbacks.Add(eProtocalCommand.CsLeaveRoom, On_Leave);
  93. callbacks.Add(eProtocalCommand.CsBtStatus, On_BtStatus);
  94. callbacks.Add(eProtocalCommand.CsBtPosition, On_BtPosition);
  95. callbacks.Add(eProtocalCommand.CsBtBroadCast, On_BtBroadCast);
  96. callbacks.Add(eProtocalCommand.CsBtPeopleList, On_PeopleList);
  97. var t = Task.Run(MsgLoop);
  98. Open();
  99. }
  100. void On_PeopleList(int peerId, sSocketData data)
  101. {
  102. var msg = CS_BT_PeopleList.Parser.ParseFrom(data._data);
  103. if (ClientPeers.TryGetValue(peerId, out var peer))
  104. {
  105. Console.WriteLine($"{msg.Uid} 在请求队友列表.");
  106. var info = new SC_BT_PeopleList() { NewerUid = "", Zoneid = msg.Zoneid };
  107. info.PlayerUids.AddRange(PlayerUids);
  108. peer.SendEvent(eProtocalCommand.ScBtPeopleList, info);
  109. }
  110. }
  111. void On_BtStatus(int peerId, sSocketData data)
  112. {
  113. var msg = CS_BT_Status.Parser.ParseFrom(data._data);
  114. if (ClientPeers.TryGetValue(peerId, out var peer))
  115. {
  116. var info = new SC_BT_Status() { PropertyName = msg.PropertyName, Value = msg.Value, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
  117. this.Broadcast(TargetType.Others, eProtocalCommand.ScBtStatus, info);
  118. }
  119. }
  120. void On_BtPosition(int peerId, sSocketData data)
  121. {
  122. var msg = CS_BT_Position.Parser.ParseFrom(data._data);
  123. if (ClientPeers.TryGetValue(peerId, out var peer))
  124. {
  125. var info = new SC_BT_Position() { X = msg.X, Y = msg.Y, Z = msg.Z, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
  126. this.Broadcast(TargetType.All, eProtocalCommand.ScBtPostion, info);
  127. }
  128. }
  129. void On_BtBroadCast(int peerId, sSocketData data)
  130. {
  131. var msg = CS_BT_BroadCast.Parser.ParseFrom(data._data);
  132. if (ClientPeers.TryGetValue(peerId, out var peer))
  133. {
  134. var info = new SC_BT_BroadCast() { Msg = msg.Msg, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
  135. this.Broadcast(TargetType.Others, eProtocalCommand.ScBtBroadCast, info);
  136. }
  137. }
  138. void On_BtOver(int peerId, sSocketData data)
  139. {
  140. var msg = CS_BT_Over.Parser.ParseFrom(data._data);
  141. if (ClientPeers.TryGetValue(peerId, out var peer))
  142. {
  143. var info = new SC_BT_Over() { Msg = msg.Msg, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
  144. this.Broadcast(TargetType.Others, eProtocalCommand.ScGameOver, info);
  145. }
  146. }
  147. /// <summary>
  148. /// 离开房间(战斗结束)
  149. /// </summary>
  150. /// <param name="data"></param>
  151. void On_Leave(int peerId, sSocketData data)
  152. {
  153. if (this.ClientPeers.TryGetValue(peerId, out var peer))
  154. {
  155. Broadcast(TargetType.All, eProtocalCommand.ScMdLeaveRoom, new SC_MD_LeaveRoom() { Uid = peer.UID, Zoneid = peer.zoneid });
  156. peer.Close();
  157. RemovePeer(peerId);
  158. }
  159. }
  160. #region 网络
  161. async void MsgLoop()
  162. {
  163. while (true)
  164. {
  165. var msg = await MsgChannel.Reader.ReadAsync();
  166. if (callbacks.ContainsKey(msg.Value._protocallType))
  167. {
  168. callbacks[msg.Value._protocallType](msg.Key, msg.Value);
  169. }
  170. else
  171. {
  172. // 未找到消息处理逻辑
  173. }
  174. }
  175. }
  176. /// <summary>
  177. /// 广播消息
  178. /// </summary>
  179. /// <param name="targetType"></param>
  180. /// <param name="msgType"></param>
  181. /// <param name="msg"></param>
  182. private void Broadcast(TargetType targetType, eProtocalCommand msgType, pb::IMessage msg)
  183. {
  184. switch (targetType)
  185. {
  186. case TargetType.All:
  187. this.ClientPeers.Values.ToList().ForEach(p => p.SendEvent(msgType, msg));
  188. break;
  189. case TargetType.Others:
  190. this.ClientPeers.Values.ToList().ForEach(p =>p.SendEvent(msgType, msg));
  191. break;
  192. }
  193. }
  194. #endregion
  195. /// <summary>
  196. /// 开启
  197. /// </summary>
  198. public void Open()
  199. {
  200. this.CurrentState = RoomState.Open;
  201. }
  202. public void Close()
  203. {
  204. this.CurrentState = RoomState.Close;
  205. Task.Delay(TimeSpan.FromMinutes(1)).ContinueWith(t => Open());
  206. }
  207. private object lock_peers = new object();
  208. public void AddPeer(Peer p)
  209. {
  210. Console.WriteLine("加入房间ing");
  211. if (CurrentState == RoomState.Open)
  212. {
  213. lock (lock_peers)
  214. {
  215. p.CurrentState = ClientState.InRoom;
  216. p.room = this;
  217. this.ClientPeers.Add(p.Id, p);
  218. }
  219. }
  220. else
  221. {
  222. WriteLine("游戏结束2 // 这里不应该执行到!!!");
  223. p.SendEvent(eProtocalCommand.ScGameOver, new SC_MD_EnterRoom() { });
  224. p.Close();
  225. }
  226. }
  227. public void RemovePeer(Peer p)
  228. {
  229. lock (lock_peers)
  230. {
  231. if (this.ClientPeers.ContainsKey(p.Id))
  232. {
  233. this.ClientPeers.Remove(p.Id);
  234. }
  235. }
  236. }
  237. public void RemovePeer(int peerId)
  238. {
  239. lock (lock_peers)
  240. {
  241. if (this.ClientPeers.ContainsKey(peerId))
  242. {
  243. this.ClientPeers.Remove(peerId);
  244. }
  245. }
  246. }
  247. }
  248. }