123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- using CSharpUtil;
- using CSharpUtil.Net;
- using ProtoDataBuff;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Channels;
- using System.Threading.Tasks;
- using static System.Console;
- using pb = global::Google.Protobuf;
- using MultiDup;
- namespace BattleRoom
- {
- /// <summary>
- /// 房间状态
- /// </summary>
- enum RoomState
- {
- /// <summary>
- /// 开启状态(可以连接登入)
- /// </summary>
- Open,
- /// <summary>
- /// 已关闭(不可继续登录)
- /// </summary>
- Close,
- }
- enum TargetType
- {
- /// <summary>
- /// 所有
- /// </summary>
- All,
- /// <summary>
- /// 其他人
- /// </summary>
- Others,
- }
- class PropertyName
- {
- public const string Uid = nameof(Uid);
- public const string Name = nameof(Name);
- public const string Zoneid = nameof(Zoneid);
- public const string Hp = nameof(Hp);
- public const string MaxHp = nameof(MaxHp);
- public const string TotalDamage = nameof(TotalDamage);
- }
- /// <summary>
- /// 房间对象
- /// </summary>
- class Room
- {
- /// <summary>
- /// 房间状态字段
- /// </summary>
- public RoomState CurrentState = RoomState.Close;
- /// <summary>
- /// 客户端
- /// </summary>
- public Dictionary<int, Peer> ClientPeers = new Dictionary<int, Peer>();
- /// <summary>
- /// 消息分发
- /// </summary>
- private Dictionary<eProtocalCommand, Action<int, sSocketData>> callbacks = new Dictionary<eProtocalCommand, Action<int, sSocketData>>();
- /// <summary>
- /// 客户端消息队列
- /// </summary>
- public Channel<KeyValuePair<int, sSocketData>> MsgChannel = Channel.CreateBounded<KeyValuePair<int, sSocketData>>(1000);
- /// <summary>
- /// 房间编号
- /// </summary>
- public int Id { get; }
- /// <summary>
- /// 玩家id集合
- /// </summary>
- public List<string> PlayerUids = new List<string>();
- /// <summary>
- /// 战斗服务器端口
- /// </summary>
- public int BattleServerPort = 6006;
- /// <summary>
- /// 战斗服务器IP地址
- /// </summary>
- public string BattleServerIp = "192.168.10.17";
- /// <summary>
- /// 构造函数
- /// </summary>
- public Room(int RoomId, IEnumerable<string> uids)
- {
- Id = RoomId;
- PlayerUids = uids.ToList();
- callbacks.Add(eProtocalCommand.CsLeaveRoom, On_Leave);
- callbacks.Add(eProtocalCommand.CsBtStatus, On_BtStatus);
- callbacks.Add(eProtocalCommand.CsBtPosition, On_BtPosition);
- callbacks.Add(eProtocalCommand.CsBtBroadCast, On_BtBroadCast);
- callbacks.Add(eProtocalCommand.CsBtPeopleList, On_PeopleList);
- var t = Task.Run(MsgLoop);
- Open();
- }
- void On_PeopleList(int peerId, sSocketData data)
- {
- var msg = CS_BT_PeopleList.Parser.ParseFrom(data._data);
- if (ClientPeers.TryGetValue(peerId, out var peer))
- {
- Console.WriteLine($"{msg.Uid} 在请求队友列表.");
- var info = new SC_BT_PeopleList() { NewerUid = "", Zoneid = msg.Zoneid };
- info.PlayerUids.AddRange(PlayerUids);
- peer.SendEvent(eProtocalCommand.ScBtPeopleList, info);
- }
- }
- void On_BtStatus(int peerId, sSocketData data)
- {
- var msg = CS_BT_Status.Parser.ParseFrom(data._data);
- if (ClientPeers.TryGetValue(peerId, out var peer))
- {
- var info = new SC_BT_Status() { PropertyName = msg.PropertyName, Value = msg.Value, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
- this.Broadcast(TargetType.Others, eProtocalCommand.ScBtStatus, info);
- }
- }
- void On_BtPosition(int peerId, sSocketData data)
- {
- var msg = CS_BT_Position.Parser.ParseFrom(data._data);
- if (ClientPeers.TryGetValue(peerId, out var peer))
- {
- var info = new SC_BT_Position() { X = msg.X, Y = msg.Y, Z = msg.Z, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
- this.Broadcast(TargetType.All, eProtocalCommand.ScBtPostion, info);
- }
- }
- void On_BtBroadCast(int peerId, sSocketData data)
- {
- var msg = CS_BT_BroadCast.Parser.ParseFrom(data._data);
- if (ClientPeers.TryGetValue(peerId, out var peer))
- {
- var info = new SC_BT_BroadCast() { Msg = msg.Msg, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
- this.Broadcast(TargetType.Others, eProtocalCommand.ScBtBroadCast, info);
- }
- }
- void On_BtOver(int peerId, sSocketData data)
- {
- var msg = CS_BT_Over.Parser.ParseFrom(data._data);
- if (ClientPeers.TryGetValue(peerId, out var peer))
- {
- var info = new SC_BT_Over() { Msg = msg.Msg, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
- this.Broadcast(TargetType.Others, eProtocalCommand.ScGameOver, info);
- }
- }
- /// <summary>
- /// 离开房间(战斗结束)
- /// </summary>
- /// <param name="data"></param>
- void On_Leave(int peerId, sSocketData data)
- {
- if (this.ClientPeers.TryGetValue(peerId, out var peer))
- {
- Broadcast(TargetType.All, eProtocalCommand.ScMdLeaveRoom, new SC_MD_LeaveRoom() { Uid = peer.UID, Zoneid = peer.zoneid });
- peer.Close();
- RemovePeer(peerId);
- }
- }
- #region 网络
- async void MsgLoop()
- {
- while (true)
- {
- var msg = await MsgChannel.Reader.ReadAsync();
- if (callbacks.ContainsKey(msg.Value._protocallType))
- {
- callbacks[msg.Value._protocallType](msg.Key, msg.Value);
- }
- else
- {
- // 未找到消息处理逻辑
- }
- }
- }
- /// <summary>
- /// 广播消息
- /// </summary>
- /// <param name="targetType"></param>
- /// <param name="msgType"></param>
- /// <param name="msg"></param>
- private void Broadcast(TargetType targetType, eProtocalCommand msgType, pb::IMessage msg)
- {
- switch (targetType)
- {
- case TargetType.All:
- this.ClientPeers.Values.ToList().ForEach(p => p.SendEvent(msgType, msg));
- break;
- case TargetType.Others:
- this.ClientPeers.Values.ToList().ForEach(p =>p.SendEvent(msgType, msg));
- break;
- }
- }
- #endregion
- /// <summary>
- /// 开启
- /// </summary>
- public void Open()
- {
- this.CurrentState = RoomState.Open;
- }
- public void Close()
- {
- this.CurrentState = RoomState.Close;
- Task.Delay(TimeSpan.FromMinutes(1)).ContinueWith(t => Open());
- }
- private object lock_peers = new object();
- public void AddPeer(Peer p)
- {
- Console.WriteLine("加入房间ing");
- if (CurrentState == RoomState.Open)
- {
- lock (lock_peers)
- {
- p.CurrentState = ClientState.InRoom;
- p.room = this;
- this.ClientPeers.Add(p.Id, p);
- }
- }
- else
- {
- WriteLine("游戏结束2 // 这里不应该执行到!!!");
- p.SendEvent(eProtocalCommand.ScGameOver, new SC_MD_EnterRoom() { });
- p.Close();
- }
- }
- public void RemovePeer(Peer p)
- {
- lock (lock_peers)
- {
- if (this.ClientPeers.ContainsKey(p.Id))
- {
- this.ClientPeers.Remove(p.Id);
- }
- }
- }
- public void RemovePeer(int peerId)
- {
- lock (lock_peers)
- {
- if (this.ClientPeers.ContainsKey(peerId))
- {
- this.ClientPeers.Remove(peerId);
- }
- }
- }
- }
- }
|