123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- 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;
- namespace BossServer.server
- {
- /// <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 : Singleton<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);
- public string Name => DateTime.Now.ToString("yyyyMMddHH");
- public int MaxHp => Config.GameOnline ? 100000 : 10000; // 初始血量10w
- /// <summary>
- /// boss集合
- /// </summary>
- private Dictionary<string, Boss> Boss_dict = new();
- /// <summary>
- /// 构造函数
- /// </summary>
- public Room()
- {
- //this.Name = DateTime.Now.ToString("yyyyMMddHH");
- this.callbacks.Add(eProtocalCommand.CsLogin, On_Login);
- this.callbacks.Add(eProtocalCommand.CsReportDamage, On_ReportDamage);
- this.callbacks.Add(eProtocalCommand.CsLeaveRoom, On_Leave);
- this.callbacks.Add(eProtocalCommand.CsReportUserHp, On_ReportUserHp);
- var t = Task.Run(MsgLoop);
- Open();
- }
- /// <summary>
- /// 处理客户端上报玩家剩余血量逻辑
- /// </summary>
- /// <param name="peerId"></param>
- /// <param name="data"></param>
- void On_ReportUserHp(int peerId, sSocketData data)
- {
- var msg = CSReportUserHP.Parser.ParseFrom(data._data);
- if (this.ClientPeers.TryGetValue(peerId, out var peer))
- {
- if (peer.Properties.ContainsKey(PropertyName.Hp))
- {
- peer.Properties[PropertyName.Hp] = msg.UserHP;
- }
- else
- {
- peer.Properties.Add(PropertyName.Hp, msg.UserHP);
- }
- }
- }
- /// <summary>
- /// 处理客户端登录请求
- /// </summary>
- void On_Login(int peerId, sSocketData data)
- {
- if (this.ClientPeers.TryGetValue(peerId, out var peer))
- {
- var msg = CSEnterFight.Parser.ParseFrom(data._data);
- peer.Properties[nameof(msg.Uid)] = msg.Uid;
- peer.Properties[nameof(msg.Zoneid)] = msg.Zoneid;
- peer.Properties[PropertyName.Name] = msg.Name;
- peer.bossId = msg.BossId;
- lock (Boss_dict)
- {
- var bossKey = $"{msg.Zoneid}-{msg.BossId}";
- if (Boss_dict.TryGetValue(bossKey, out var boss))
- {
- if (boss.Ended) // boss战已结束, 尚未重新开启
- {
- WriteLine("游戏结束1");
- peer.SendEvent(eProtocalCommand.ScGameOver, new SCGameOver() { BossHp = boss.Hp, CountDown = boss.CountDownSecs });
- peer.Close();
- }
- else
- {
- var peerHp = -1; // 玩家血量, -1代表未初始化
- var exists = boss.Peers.Where(kv => kv.Value.UID == peer.UID && kv.Value.zoneid == peer.zoneid);
- if (exists.Count() < 1)
- {
- boss.Peers.Add(peerId, peer);
- }
- else
- { // 已经进入到房间中过了
- var oldPeer = exists.First().Value;
- if (oldPeer.Properties.TryGetValue(PropertyName.Hp, out var hisHp))
- {
- peerHp = int.Parse(hisHp.ToString());
- peer.Properties[PropertyName.Hp] = peerHp;
- Console.WriteLine($" 玩家记录血量:{peerHp} ");
- }
- boss.Peers.Remove(oldPeer.Id);
- boss.Peers.Add(peerId, peer);
- }
- peer.SendEvent(eProtocalCommand.ScLogin, new SCEnterFight() { BossHp = boss.Hp, BossMaxHp = boss.MaxHp, UserHP = peerHp, CountDown = boss.CountDownSecs });
- Console.WriteLine($"boss [{boss.ZoneId}] 已经初始化完毕, " + boss.Hp);
- }
- }
- else // 初始化新的boss
- {
- Console.WriteLine($"初始化 boss [{msg.Zoneid}]");
- var b = new Boss(msg.BossId, msg.Zoneid, MaxHp, BossSettle);
- b.Peers.Add(peerId, peer);
- Boss_dict.Add(b.UID, b);
- peer.SendEvent(eProtocalCommand.ScLogin, new SCEnterFight() { BossHp = b.Hp, BossMaxHp = b.MaxHp, UserHP = -1, CountDown = b.CountDownSecs });
- }
- }
- }
- }
- void BossSettle(Boss boss)
- {
- WriteLine($"结算Boss {boss.UID}");
- if (Boss_dict.ContainsKey(boss.UID))
- {
- var data = $"zoneid={boss.ZoneId}&bossid={boss.Id}";
- HttpHelper.Instance.Post(Config.Ins.SettleUrl, data);
- var t = Task.Delay(TimeSpan.FromSeconds(Config.Ins.CountDownTimes)).ContinueWith(t =>
- {
- lock (Boss_dict)
- {
- Boss_dict.Remove(boss.UID);
- }
- });
- }
- }
- /// <summary>
- /// 处理客户端上报伤害请求
- /// </summary>
- void On_ReportDamage(int peerId, sSocketData data)
- {
- if (this.ClientPeers.TryGetValue(peerId, out var peer))
- {
- var msg = CSFightReportDamage.Parser.ParseFrom(data._data);
- if (Boss_dict.TryGetValue(peer.BossKey, out var boss))
- {
- boss.DamageQueue.Writer.WriteAsync(msg.Damage);
- peer.AddDamage(msg.Damage);
- }
- }
- }
- /// <summary>
- /// 离开房间(战斗结束)
- /// </summary>
- /// <param name="data"></param>
- void On_Leave(int peerId, sSocketData data)
- {
- if (this.ClientPeers.TryGetValue(peerId, out var peer))
- {
- peer.Close();
- }
- }
- 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>
- public void Open()
- {
- Boss_dict.Clear();
- 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)
- {
- if (CurrentState == RoomState.Open)
- {
- lock (lock_peers)
- {
- this.ClientPeers.Add(p.Id, p);
- }
- }
- else
- {
- WriteLine("游戏结束2 // 这里不应该执行到!!!");
- p.SendEvent(eProtocalCommand.ScGameOver, new SCGameOver() { BossHp = 0, CountDown = 9999 });
- p.Close();
- }
- }
- public void RemovePeer(Peer p)
- {
- lock (lock_peers)
- {
- if (this.ClientPeers.ContainsKey(p.Id))
- {
- this.ClientPeers.Remove(p.Id);
- }
- }
- }
- }
- }
|