private async void RunAsync(Session session, L2M_TeamLose message, Action <M2L_TeamLose> reply)
        {
            M2L_TeamLose response = new M2L_TeamLose();

            try
            {
                var roomComponent = Game.Scene.GetComponent <RoomComponent>();
                var room          = roomComponent.Get(message.RoomId);
                if (room == null)
                {
                    response.Error = ErrorCode.ERR_RoomIdNotFound;
                    reply(response);
                    return;
                }
                // 告知失去房間訊息
                M2C_TeamLose m2c_TeamLose = new M2C_TeamLose();
                m2c_TeamLose.LoseType = TeamLoseType.Disband;
                List <MapUnit> broadcastMapUnits = new List <MapUnit>();
                broadcastMapUnits.AddRange(room.GetAll());
                MapMessageHelper.BroadcastTarget(m2c_TeamLose, broadcastMapUnits);

                // 讓隊員清空Map相關訊息
                var proxy      = Game.Scene.GetComponent <CacheProxyComponent>();
                var playerSync = proxy.GetMemorySyncSolver <Player>();
                var mapUnits   = room.GetAll();
                for (int i = 0; i < mapUnits?.Count; i++)
                {
                    // Player移除mapUnitId
                    var targetPlayer = playerSync.Get <Player>(mapUnits[i].Uid);
                    targetPlayer?.LeaveRoom();
                    await playerSync.Update(targetPlayer);

                    // 中斷指定玩家與Map的連接
                    mapUnits[i].GetComponent <MapUnitGateComponent>().IsDisconnect = true;
                    // TODO:G2M_TeamDisband抄C2M_TeamDisbandHandler
                    Game.Scene.GetComponent <MapUnitComponent>().Remove(mapUnits[i].Id);
                }

                // 刪除房間實體
                await roomComponent.DestroyRoom(room.Id);

                reply(response);
            }
            catch (Exception e)
            {
                ReplyError(response, e, reply);
            }
        }
        public static async void KickMember(RoomTeamComponent roomTeamComponent, MapUnit kickMember, TeamLoseType loseType)
        {
            if (kickMember == null)
            {
                return;
            }

            //廣播給指定玩家失去房間
            M2C_TeamLose m2c_TeamLose = new M2C_TeamLose();

            m2c_TeamLose.LoseType = loseType;
            List <MapUnit> broadcastMapUnits = new List <MapUnit>();

            broadcastMapUnits.Add(kickMember);
            MapMessageHelper.BroadcastTarget(m2c_TeamLose, broadcastMapUnits);

            //Player移除mapUnitId
            var proxy      = Game.Scene.GetComponent <CacheProxyComponent>();
            var playerSync = proxy.GetMemorySyncSolver <Player>();
            var player     = playerSync.Get <Player>(kickMember.Uid);

            player?.LeaveRoom();
            await playerSync.Update(player);

            //中斷指定玩家與Map的連接
            var mapUnitGateComponent = kickMember?.GetComponent <MapUnitGateComponent>();

            if (mapUnitGateComponent != null)
            {
                mapUnitGateComponent.IsDisconnect = true;
            }
            Game.Scene.GetComponent <MapUnitComponent>().Remove(kickMember.Id);

            if (m2c_TeamLose.LoseType != TeamLoseType.LoadingTimeOut)
            {
                //廣播給離開玩家外的玩家 成員異動
                M2C_TeamModifyMember m2c_TeamModifyMember = new M2C_TeamModifyMember();
                m2c_TeamModifyMember.Uid = kickMember.Uid;
                MapMessageHelper.BroadcastRoom(roomTeamComponent.RoomEntity.Id, m2c_TeamModifyMember, kickMember.Uid);
            }
        }
        private async ETTask RunAsync(Session session, C2G_TeamReservationCancel message, Action <G2C_TeamReservationCancel> reply)
        {
            G2C_TeamReservationCancel response = new G2C_TeamReservationCancel();

            try
            {
                //取得自身資料
                Player player = session.GetComponent <SessionPlayerComponent>().Player;
                User   user   = await UserDataHelper.FindOneUser((player?.uid).GetValueOrDefault());

                if (user == null)
                {
                    response.Error = ErrorCode.ERR_AccountDoesntExist;
                    reply(response);
                    return;
                }

                //判斷是否為發起人
                var reservationComponent = Game.Scene.GetComponent <ReservationComponent>();
                var reservation          = reservationComponent.GetByReservationId(message.ReservationId);
                if (reservation.allData.SenderUid != player.uid)
                {
                    response.Error = ErrorCode.ERR_ReservationIsNotLeader;
                    reply(response);
                    return;
                }

                if (reservation.room != null)
                {
                    if (reservation.room.State != RoomState.Ready && reservation.room.State != RoomState.Start)
                    {
                        response.Error = ErrorCode.ERR_ReservationRoomStateCanNotToRemove;
                        reply(response);
                        return;
                    }
                    else
                    {
                        //告知失去房間訊息
                        M2C_TeamLose m2c_TeamLose = new M2C_TeamLose();
                        m2c_TeamLose.LoseType = TeamLoseType.Disband;
                        List <MapUnit> broadcastMapUnits = new List <MapUnit>();
                        broadcastMapUnits.AddRange(reservation.room.GetAll());
                        MapMessageHelper.BroadcastTarget(m2c_TeamLose, broadcastMapUnits);

                        //讓隊員清空Map相關訊息
                        var proxy      = Game.Scene.GetComponent <CacheProxyComponent>();
                        var playerSync = proxy.GetMemorySyncSolver <Player>();
                        var mapUnits   = reservation.room.GetAll();
                        for (int i = 0; i < mapUnits?.Count; i++)
                        {
                            //Player移除mapUnitId
                            var targetPlayer = playerSync.Get <Player>(mapUnits[i].Uid);
                            targetPlayer?.LeaveRoom();

                            //中斷指定玩家與Map的連接
                            mapUnits[i].GetComponent <MapUnitGateComponent>().IsDisconnect = true;
                            //TODO:G2M_TeamDisband抄C2M_TeamDisbandHandler
                            Game.Scene.GetComponent <MapUnitComponent>().Remove(mapUnits[i].Id);
                        }

                        //刪除房間實體
                        var roomComponent = Game.Scene.GetComponent <RoomComponent>();
                        await roomComponent.DestroyRoom(reservation.room.Id);
                    }
                }

                //刪除預約實體(DB會一起刪除)
                await reservationComponent.DestroyReservation(message.ReservationId);

                //回傳資料
                response.Error = ErrorCode.ERR_Success;
                reply(response);
            }
            catch (Exception e)
            {
                ReplyError(response, e, reply);
            }
        }
        protected override async ETTask Run(MapUnit mapUnit, C2M_TeamLeave message, Action <M2C_TeamLeave> reply)
        {
            await ETTask.CompletedTask;

            M2C_TeamLeave response = new M2C_TeamLeave();

            try
            {
                //判斷房間是否合法
                Room room = mapUnit.Room;
                if (room == null)
                {
                    response.Error = ErrorCode.ERR_RoomIdNotFound;
                    reply(response);
                    return;
                }

                if (room.Type != RoomType.Team)
                {
                    response.Error = ErrorCode.ERR_RoonTypeError;
                    reply(response);
                    return;
                }

                var roomTeamComponent = room.GetComponent <RoomTeamComponent>();
                if (roomTeamComponent == null)
                {
                    response.Error = ErrorCode.ERR_RoomTeamComponentNull;
                    reply(response);
                    return;
                }

                //刪除MapUnit訊息
                M2C_MapUnitDestroy m2C_MapUnitDestroy = new M2C_MapUnitDestroy();
                m2C_MapUnitDestroy.MapUnitId = mapUnit.Id;

                //廣播刪除MapUnit訊息(不包含自己)
                List <MapUnit> broadcastMapUnits = new List <MapUnit>();
                broadcastMapUnits.AddRange(room.GetAll());
                for (int i = 0; i < broadcastMapUnits.Count; i++)
                {
                    //過濾自己
                    if (broadcastMapUnits[i].Uid == mapUnit.Uid)
                    {
                        broadcastMapUnits.RemoveAt(i);
                        break;
                    }
                }
                MapMessageHelper.BroadcastTarget(m2C_MapUnitDestroy, broadcastMapUnits);

                //對全體廣播離開組隊訊息(不包含自己)
                M2C_TeamModifyMember m2c_TeamModifyMember = new M2C_TeamModifyMember();
                m2c_TeamModifyMember.Uid = mapUnit.Uid;
                MapMessageHelper.BroadcastTarget(m2c_TeamModifyMember, broadcastMapUnits);

                //廣播給自己失去房間
                M2C_TeamLose m2c_TeamLose = new M2C_TeamLose();
                m2c_TeamLose.LoseType = TeamLoseType.Other;
                MapMessageHelper.BroadcastTarget(m2c_TeamLose, mapUnit);

                bool isLeader = mapUnit.Uid == roomTeamComponent.Data.LeaderUid;

                //對全體廣播更換隊長(不包含自己)
                if (isLeader)
                {
                    M2C_TeamModifyData m2c_TeamModifyData = new M2C_TeamModifyData();
                    m2c_TeamModifyData.Data = roomTeamComponent.Data;
                    MapMessageHelper.BroadcastTarget(m2c_TeamModifyData, broadcastMapUnits);
                }

                //Player移除mapUnitId
                var proxy      = Game.Scene.GetComponent <CacheProxyComponent>();
                var playerSync = proxy.GetMemorySyncSolver <Player>();
                var player     = playerSync.Get <Player>(mapUnit.Uid);
                player?.LeaveRoom();
                await playerSync.Update(player);

                //先Response才釋放mapUnit
                reply(response);

                //中斷指定玩家與Map的連接
                mapUnit.GetComponent <MapUnitGateComponent>().IsDisconnect = true;
                Game.Scene.GetComponent <MapUnitComponent>().Remove(mapUnit.Id);
            }
            catch (Exception e)
            {
                ReplyError(response, e, reply);
            }
        }
        protected override async ETTask Run(MapUnit mapUnit, C2M_TeamDisband message, Action <M2C_TeamDisband> reply)
        {
            await ETTask.CompletedTask;

            M2C_TeamDisband response = new M2C_TeamDisband();

            try
            {
                Room room = mapUnit.Room;

                if (room == null)
                {
                    response.Error = ErrorCode.ERR_RoomIdNotFound;
                    reply(response);
                    return;
                }

                if (room.Type != RoomType.Team)
                {
                    response.Error = ErrorCode.ERR_RoonTypeError;
                    reply(response);
                    return;
                }

                var roomTeamComponent = room.GetComponent <RoomTeamComponent>();
                if (roomTeamComponent == null)
                {
                    response.Error = ErrorCode.ERR_RoomTeamComponentNull;
                    reply(response);
                    return;
                }

                if (roomTeamComponent.Data?.LeaderUid != mapUnit.Uid)
                {
                    response.Error = ErrorCode.ERR_RoomTeamIsNotLeader;
                    reply(response);
                    return;
                }
                response.Error = 0;
                reply(response);

                //告知失去房間訊息
                M2C_TeamLose m2c_TeamLose = new M2C_TeamLose();
                m2c_TeamLose.LoseType = TeamLoseType.Disband;
                List <MapUnit> broadcastMapUnits = new List <MapUnit>();
                broadcastMapUnits.AddRange(room.GetAll());
                MapMessageHelper.BroadcastTarget(m2c_TeamLose, broadcastMapUnits);

                //讓隊員清空Map相關訊息
                var mapUnits   = room.GetAll();
                var proxy      = Game.Scene.GetComponent <CacheProxyComponent>();
                var playerSync = proxy.GetMemorySyncSolver <Player>();
                for (int i = 0; i < mapUnits?.Count; i++)
                {
                    //Player移除mapUnitId
                    var player = playerSync.Get <Player>(mapUnits[i].Uid);
                    player?.LeaveRoom();
                    await playerSync.Update(player);

                    //中斷指定玩家與Map的連接
                    mapUnits[i].GetComponent <MapUnitGateComponent>().IsDisconnect = true;
                    Game.Scene.GetComponent <MapUnitComponent>().Remove(mapUnits[i].Id);
                }

                //刪除房間實體
                var roomComponent = Game.Scene.GetComponent <RoomComponent>();
                await roomComponent.DestroyRoom(room.Id);
            }
            catch (Exception e)
            {
                ReplyError(response, e, reply);
            }
        }