任务25:退出房间功能与网关user的ActorID

这节的效果是玩家可以匹配后进入房间等待三人齐备好开始游戏,等待中可以退出房间,再重新匹配进入房间。

前面学过,每当玩家进入地图,Map就给网关发送了Actor_MatchSucess_M2G消息,从而更新了网关user的ActorDI。

\Server\Hotfix\Landlords\Handler\Gate\M2G_MatchSucess_Handler.cs

//gate更新ActorID
user.ActorID = message.GamerID;

这个GamerID正是Map通过消息传递过来的Map上gamer的InstanceId。

所以玩家到了哪个地图,就会在地图上创建gamer后,把gamer的InstanceId传送给网关存入网关上user的ActorDI。

这就意味着,不论玩家到了哪个地图,我们在任何一个端中,都可以通过网关用user.ActorID构建ActorMessageSender,给Map上的gamer发送消息。

服务端增加 C2G_ReturnLobby_Ntt_Handler

前端用户点退出房间按钮,向网关发送了这条消息 \Server\Hotfix\Landlords\Handler\Gate\C2G_ReturnLobby_NttHandler.cs

using ETModel;
using System.Net;

namespace ETHotfix
{
    [MessageHandler(AppType.Gate)]
    public class C2G_ReturnLobby_NttHandler : AMHandler<C2G_ReturnLobby_Ntt>
    {
        protected override async ETTask Run(Session session, C2G_ReturnLobby_Ntt message)
        {
            //验证Session
            if (!GateHelper.SignSession(session))
            {
                return;
            }

            User user = session.GetComponent<SessionUserComponent>().User;
            StartConfigComponent config = Game.Scene.GetComponent<StartConfigComponent>();
            ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent<ActorMessageSenderComponent>();
            
            //通知Map服务器玩家离开房间
            if (user.ActorID != 0)
            {
                ActorMessageSender actorProxy = actorProxyComponent.Get(user.ActorID);
                actorProxy.Send(new Actor_PlayerExitRoom_G2M());

                user.ActorID = 0;
            }
            await ETTask.CompletedTask;
        }
    }
}

服务端增加 G2M_PlayerExitRoom_Handler

\Server\Hotfix\Landlords\Handler\Map\G2M_PlayerExitRoom_Handler.cs

using System;
using System.Threading.Tasks;
using ETModel;

namespace ETHotfix
{
    //Gate通知Map玩家退出房间
    [ActorMessageHandler(AppType.Map)]
    public class G2M_PlayerExitRoom_Handler : AMActorHandler<Gamer, Actor_PlayerExitRoom_G2M>
    {
        protected override async ETTask Run(Gamer gamer, Actor_PlayerExitRoom_G2M message)
        {
            Room room;
            if (Game.Scene.GetComponent<LandMatchComponent>().Playing.TryGetValue(gamer.UserID,out room))
            {
                gamer.isOffline = true;
                //玩家断开添加自动出牌组件
                //...
            }
            else //玩家不在游戏中 处于待机状态
            {
                Game.Scene.GetComponent<LandMatchComponent>().Waiting.TryGetValue(gamer.UserID,out room);
                //房间移除玩家
                room.Remove(gamer.UserID);
                Game.Scene.GetComponent<LandMatchComponent>().Waiting.Remove(gamer.UserID);
                //消息广播给其他人
                room.Broadcast(new Actor_GamerExitRoom_Ntt() { UserID = gamer.UserID });  
                gamer.Dispose();
            }
            await ETTask.CompletedTask;
        }
    }
}

InnerMessage.proto 增加Actor_PlayerExitRoom_G2M

//Gate通知Map玩家离开房间
message Actor_PlayerExitRoom_G2M // IActorMessage
{
    int32 RpcId = 90;
    int64 ActorId = 94;
}

前端增加Actor_GamerExitRoom_NttHandler

using ETModel;

namespace ETModel
{
    [MessageHandler]
    public class Actor_GamerExitRoom_NttHandler : AMHandler<Actor_GamerExitRoom_Ntt>
    {
        protected override async ETTask Run(ETModel.Session session, Actor_GamerExitRoom_Ntt message)
        {
            UI uiRoom = Game.Scene.GetComponent<UIComponent>().Get(LandUIType.LandRoom);
            LandRoomComponent landlordsRoomComponent = uiRoom.GetComponent<LandRoomComponent>();
            landlordsRoomComponent.RemoveGamer(message.UserID);

            await ETTask.CompletedTask;
        }
    }
}

最后就可以进行前后端运行测试了,可以看到后端的输出反馈

posted @ 2023-02-11 08:47  Domefy  阅读(31)  评论(0)    收藏  举报