/// <summary> /// 检查匹配状态 每当有新排队玩家加入时执行一次 /// </summary> /// <param name="self"></param> public static async void MatchingCheck(this LandlordsComponent self) { //如果有空房间 且 正在排队的玩家>0 LandlordsRoom room = self.GetFreeLandlordsRoom(); if (room != null) { while (self.MatchingQueue.Count > 0 && room.Count < 3) { self.JoinRoom(room, self.MatchingQueue.Dequeue()); } } //else 如果没有空房间 且 正在排队的玩家>=3 else if (self.MatchingQueue.Count >= 3) { //创建新房间 room = ComponentFactory.Create <LandlordsRoom>(); await room.AddComponent <MailBoxComponent>().AddLocation(); self.FreeLandlordsRooms.Add(room.Id, room); while (self.MatchingQueue.Count > 0 && room.Count < 3) { self.JoinRoom(room, self.MatchingQueue.Dequeue()); } } }
protected override void Run(Gamer gamer, Actor_GamerReady_Landlords message) { LandlordsComponent landordsMatchComponent = Game.Scene.GetComponent <LandlordsComponent>(); LandlordsRoom room = landordsMatchComponent.GetWaitingRoom(gamer); if (room != null) { //找到玩家的座位顺序 设置其准备状态为真 int seatIndex = room.GetGamerSeat(gamer.UserID); if (seatIndex >= 0) { room.isReadys[seatIndex] = true; //广播通知全房间玩家 room.Broadcast(new Actor_GamerReady_Landlords() { UserID = gamer.UserID }); //检测开始游戏 room.CheckGameStart(); } else { Log.Error("玩家不在正确的座位上"); } } }
/// <summary> /// 斗地主游戏开始 /// </summary> /// <param name="self"></param> public static void GameStart(this LandlordsRoom self) { //更改房间状态 从空闲房间移除 添加到游戏中房间列表 LandlordsComponent Match = Game.Scene.GetComponent <LandlordsComponent>(); Match.FreeLandlordsRooms.Remove(self.Id); Match.GamingLandlordsRooms.Add(self.Id, self); //更该玩家状态 for (int i = 0; i < self.gamers.Length; i++) { Gamer gamer = self.gamers[i]; Match.Waiting.Remove(gamer.UserID); Match.Playing.Add(gamer.UserID, self); } //添加组件 self.AddComponent <DeckComponent>(); self.AddComponent <DeskCardsCacheComponent>(); self.AddComponent <OrderControllerComponent>(); self.AddComponent <GameControllerComponent, RoomConfig>(GateHelper.GetLandlordsConfig(RoomLevel.Lv100)); //开始游戏 self.GetComponent <GameControllerComponent>().StartGame(); }
/// <summary> /// 返回未开始游戏的房间 用于处理准备消息 /// </summary> /// <param name="self"></param> /// <param name="gamer"></param> /// <returns></returns> public static LandlordsRoom GetWaitingRoom(this LandlordsComponent self, Gamer gamer) { LandlordsRoom room; if (!self.Waiting.TryGetValue(gamer.UserID, out room)) { Log.Error("玩家不在待机的房间中"); } return(room); }
/// <summary> /// 匹配队列广播 /// </summary> /// <param name="self"></param> /// <param name="message"></param> public static void Broadcast(this LandlordsComponent self, IActorMessage message) { foreach (Gamer gamer in self.MatchingQueue) { //像Gate服务器中User绑定的Seesion发送Actor消息 ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent <ActorMessageSenderComponent>(); ActorMessageSender actorProxy = actorProxyComponent.Get(gamer.ActorIDofClient); //转发给客户端的Acror消息要写在Hotfix.proto里面 Log.Debug("转发给了客户端一条消息,客户端Session:" + gamer.ActorIDofClient.ToString()); actorProxy.Send(message); } }
/// <summary> /// 斗地主匹配队列人数加一 /// 队列模式 所以没有插队/离队操作 /// 队列满足匹配条件时 创建新房间 /// </summary> /// <param name="self"></param> /// <param name="gamer"></param> public static void AddGamerToMatchingQueue(this LandlordsComponent self, Gamer gamer) { //添加玩家到队列 self.MatchingQueue.Enqueue(gamer); Log.Debug("一位玩家加入队列"); //广播通知所有匹配中的玩家 self.Broadcast(new Actor_LandlordsMatcherPlusOne() { MatchingNumber = self.MatchingQueue.Count }); //检查匹配状态 self.MatchingCheck(); }
/// <summary> /// 加入房间 /// </summary> /// <param name="self"></param> /// <param name="room"></param> /// <param name="matcher"></param> public static void JoinRoom(this LandlordsComponent self, LandlordsRoom room, Gamer gamer) { //玩家可能掉线 if (gamer == null) { return; } //玩家加入房间 成为已经进入房间的玩家 //绑定玩家与房间 以后可以通过玩家UserID找到所在房间 self.Waiting[gamer.UserID] = room; //为玩家添加座位 room.Add(gamer); //房间广播 Log.Info($"玩家{gamer.UserID}进入房间"); Actor_GamerEnterRoom_Ntt broadcastMessage = new Actor_GamerEnterRoom_Ntt(); foreach (Gamer _gamer in room.gamers) { if (_gamer == null) { //添加空位 broadcastMessage.Gamers.Add(new GamerInfo()); continue; } //添加玩家信息 //GamerInfo info = new GamerInfo() { UserID = _gamer.UserID, IsReady = room.IsGamerReady(gamer) }; GamerInfo info = new GamerInfo() { UserID = _gamer.UserID }; broadcastMessage.Gamers.Add(info); } //广播房间内玩家消息 每次有人进入房间都会收到一次广播 room.Broadcast(broadcastMessage); //通知Gate服务器玩家匹配成功 参数:Gamer的InstanceId //Gate服务器将Actor类消息转发给Gamer ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent <ActorMessageSenderComponent>(); ActorMessageSender gamerActorProxy = actorProxyComponent.Get(gamer.ActorIDofUser); gamerActorProxy.Send(new Actor_LandlordsMatchSucess() { ActorIDofGamer = gamer.InstanceId }); }
protected override async void Run(Session session, G2M_EnterMatch_Landords message) { //Log.Debug("Map服务器收到第一条消息"); LandlordsComponent matchComponent = Game.Scene.GetComponent <LandlordsComponent>(); //玩家是否已经开始游戏 if (matchComponent.Playing.ContainsKey(message.UserID)) { LandlordsRoom room; matchComponent.Playing.TryGetValue(message.UserID, out room); Gamer gamer = room.GetGamerFromUserID(message.UserID); //更新玩家的属性 gamer.ActorIDofUser = message.ActorIDofUser; gamer.ActorIDofClient = message.ActorIDofClient; //帮助玩家恢复牌桌 //向Gate上的User发送匹配成功消息 使User更新绑定的ActorID //Map上的Gamer需要保存User的InstanceID给其发消息 //生成Gamer的时候 需要设置ActorIDofUser ActorMessageSender actorProxy = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(gamer.ActorIDofUser); actorProxy.Send(new Actor_LandlordsMatchSucess() { ActorIDofGamer = gamer.InstanceId }); } else { //新建玩家 Gamer newgamer = ComponentFactory.Create <Gamer, long>(message.UserID); newgamer.ActorIDofUser = message.ActorIDofUser; newgamer.ActorIDofClient = message.ActorIDofClient; //为Gamer添加组件 await newgamer.AddComponent <MailBoxComponent>().AddLocation(); //添加玩家到匹配队列 广播一遍正在匹配中的玩家 matchComponent.AddGamerToMatchingQueue(newgamer); } }
public static async void Start(this TrusteeshipComponent self) { //找到玩家所在房间 LandlordsComponent landordsMatchComponent = Game.Scene.GetComponent <LandlordsComponent>(); Gamer gamer = self.GetParent <Gamer>(); LandlordsRoom room = landordsMatchComponent.GetGamingRoom(self.GetParent <Gamer>()); ActorMessageSender actorProxy = Game.Scene.GetComponent <ActorMessageSenderComponent>().Get(gamer.InstanceId); OrderControllerComponent orderController = room.GetComponent <OrderControllerComponent>(); //这个托管组件是通过定时器实现的 while (true) { //延迟1秒 await Game.Scene.GetComponent <TimerComponent>().WaitAsync(3000); if (self.IsDisposed) { return; } if (gamer.UserID != orderController?.CurrentAuthority) { continue; } //给Map上的Gamer发送Actor消息 //自动提示出牌 Actor_GamerPrompt_Back response = (Actor_GamerPrompt_Back)await actorProxy.Call(new Actor_GamerPrompt_Req()); if (response.Error > 0 || response.Cards.Count == 0) { actorProxy.Send(new Actor_GamerDontPlay_Ntt()); } else { await actorProxy.Call(new Actor_GamerPlayCard_Req() { Cards = response.Cards }); } } }
/// <summary> /// 获取一个可以添加座位的房间 没有则返回null /// </summary> /// <param name="self"></param> /// <returns></returns> public static LandlordsRoom GetFreeLandlordsRoom(this LandlordsComponent self) { return(self.FreeLandlordsRooms.Where(p => p.Value.Count < 3).FirstOrDefault().Value); }