using System;
using GameDAL.FriendRoom;
using Server.Data.Module;
using Server.Data;
using GameData;
using Server.Pack;
using MrWu.Debug;
using Server.MQ;
using Game.Player;
using MrWu.Basic;
using System.Collections;
using System.Threading.Tasks;
using System.Collections.Generic;
using StackExchange.Redis;
using System.Linq;
using GameDAL;
using GameMessage;
using Server.AliyunSDK.SLSLog;
using Server.Config;

namespace Server
{
    /// <summary>
    /// 朋友房管理
    /// </summary>
    public partial class FriendRoomManager
    {
        /// <summary>
        /// 实例
        /// </summary>
        public static FriendRoomManager instance { get; private set; }

        private FriendRoomManager()
        {
            int len = allDesks.Length;
            for (int i = 0; i < len; i++)
            {
                allDesks[i] = new Dictionary<int, Desk>();
            }
        }

        static FriendRoomManager()
        {
            instance = new FriendRoomManager();
        }

        /// <summary>
        /// 朋友房所在的厅
        /// </summary>
        private TingManager_Friend ting;

        /// <summary>
        /// 朋友房所在的城堡
        /// </summary>
        private RoomManager_Friend room;

        /// <summary>
        /// 朋友房的桌子
        /// </summary>
        public readonly Dictionary<int, Desk>[] allDesks = new Dictionary<int, Desk>[10];

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="room"></param>
        /// <param name="ting"></param>
        public void Init(RoomManager room, TingManager ting)
        {
            this.room = room as RoomManager_Friend;
            this.ting = ting as TingManager_Friend;
        }

        /// <summary>
        /// 得到一个新的房间号
        /// </summary>
        /// <returns></returns>
        private int GetNewRoomNum()
        {
            int roomnum = Room.GetRoomNum();
            return CheckRoom(roomnum, 0);
        }

        /// <summary>
        /// 检查房间号是否可用 循环检查连续100个房间，检查到可用即返回
        /// </summary>
        /// <param name="roomNum">房间号</param>
        /// <param name="checkCount">检查次数</param>
        /// <returns>小于0表示未查到可用房间(这时候应该把修改上次检查房间的值,以便下次检查) 大于表示查到某房间可用</returns>
        private int CheckRoom(int roomNum, int checkCount)
        {
            if (checkCount >= 100) //没有查询到
                return -1;
            checkCount++;

            string weiyima = null;
            ServerNode node = null;
            if (!Room.GetWeiyima(roomNum, ref weiyima, ref node))
            {
                //房间号可用
                return roomNum;
            }
            else
            {
                DeskInfo dt = null;

                if (Room.LoadRoom(weiyima, out dt))
                {
                    int isSendDis = dt.CheckDisBank();

                    if (isSendDis > 0)
                    {
                        //发送解散命令
                        PackHead head = PackHead.Create(ServerPackAgreement.disbank);

                        if (ServerHeart.instanece.IsDie(node.id, node.nodeNum))
                        {
                            Debug.Error("管理该房间的模块不在线!");
                        }
                        else
                        {
                            GlobalMQ.instance.DeliveryOne(node,
                                GlobalMQ.CreateMessage(head,
                                    JsonPack.GetJson(new KeyValuePair<int, int>(roomNum, 2 + isSendDis))), true);
                            Debug.Warning("发送解散命令!" + roomNum);
                        }
                        head.Dispose();
                        head = null;
                    }
                }
                else
                {
                    Debug.Warning("房间数据未加载成功!" + weiyima);
                }

                do
                {
                    roomNum++;
                    roomNum = roomNum % Room.MaxCnt;
                } while (roomNum == 0); //房间号从1开始

                return CheckRoom(roomNum, checkCount); // 继续找
            }
        }

        /// <summary>
        /// 玩家退出
        /// </summary>
        /// <param name="userid"></param>
        private bool QuitGame(int userid)
        {
            var tmp = PlayerCollection.Instance.FindPlayerByUserId(userid);
            if (tmp == null)
            {
                Debug.Error("玩家退出未找到玩家:" + userid);
                return false;
            }
            else
                GameManager.instance.QuitGame(tmp, "QuitGame");

            return true;
        }

        /// <summary>
        /// 获取朋友房房间号
        /// </summary>
        /// <param name="head"></param>
        /// <param name="rmdata"></param>
        /// <returns>true 表示可以创建</returns>
        private bool GetFriendRoomNum(PackHead head, CreateRoomPack rmdata)
        {
            //判断是否被锁,被锁，提示玩家被锁，并提示玩家去被锁的游戏
            try
            {
                int roomnum = GetNewRoomNum(); //房间号
                if (roomnum < 0)
                {
                    //服务器爆满，创建失败，回包给玩家 提示玩家
                    GeneralSendPack.SendErrorInfo_Socket(head.userid, 0, 3, head.GetUtil());
                    if (rmdata.isAuto == 1)
                    {
                        QuitGame(head.userid);
                    }

                    return false;
                }
                else
                {
                    Debug.Info("创建的房间号:" + roomnum + "," + rmdata.deskinfo.weiyima);
                    //按照房间号分发给模块处理,如果是本模块的直接处理
                    rmdata.deskinfo.roomNum = roomnum.ToString();
                    return true;
                }
            }
            catch (Exception e)
            {
                Debug.Error("C480D7D2-B680-4321-924F-5C8AF7DAA2B6:" + e.ToString());
                GeneralSendPack.SendErrorInfo_Socket(head.userid, 1, 37, head.GetUtil());
                return false;
            }
        }

        /// <summary>
        /// 处理创建朋友房的包
        /// </summary>
        /// <param name="pack">包裹</param>
        public void CreatFriendRoom(GamePack pack)
        {
            if (ting == null)
            {
                Debug.Error("游戏未开启朋友房功能!");
                return;
            }

            PackHead head = pack.Head;
            CreateRoomPack rmdata = JsonPack.GetData<CreateRoomPack>(pack.JsonData);

            if (head == null || rmdata == null)
            {
                Debug.Error("客户端发送的数据有问题!创建失败!");
                return;
            }

            //判断是否被锁,被锁，提示玩家被锁，并提示玩家去被锁的游戏

            if (GetFriendRoomNum(head, rmdata))
                CreatRoomLogin(head, rmdata, false, true);
        }
        
        /// <summary>
        /// 俱乐部踢出玩家
        /// </summary>
        /// <returns>状态码</returns>
        public int DoClubOutPlayer(string weiyima, int userId)
        {
            string roomnumStr = Room.GetRoomNum(weiyima);
            int roomnum = 0;
            if (!int.TryParse(roomnumStr, out roomnum))
            {
                return MessageErrCode.KickOutPlayerOfDesk_NoDesk;
            }
            Desk desk = FindDesk(roomnum);
            if (desk == null || desk.deskinfo.weiyima != weiyima)
            {
                return MessageErrCode.KickOutPlayerOfDesk_NoDesk;
            }
            
            if (!desk.deskinfo.noWar)
            {
                return MessageErrCode.KickOutPlayerOfDesk_GameInWar;
            }
            
            for (int i = 0; i < desk.Count; i++)
            {
                if (desk[i] == null) continue;
                if (desk[i].userid == userId)
                {
                    PackHead headp = PackHead.Create();
                    headp.userid = userId;
                    headp.packlx = GamePackAgreement.autoTipInfo;
                    headp.otherString = new string[] { "您被管理员踢出房间！" };
                    GeneralSendPack.SendPackToPlayer(headp, desk[i], null);
                    GameManager.instance.DoComBack(desk[i]);
                    headp.Dispose();
                    break;
                }
            }
            
            return MessageErrCode.Success;
        }

        /// <summary>
        /// 竞技比赛踢出玩家
        /// </summary>
        /// <param name="pack"></param>
        public void DoClubOutPlayer(GamePack pack)
        {
            var head = pack.Head;
            string weiyima = head.otherString[0];
            int userid = head.otherInt[0];
            string roomnumStr = Room.GetRoomNum(weiyima);
            int roomnum = 0;
            if (!int.TryParse(roomnumStr, out roomnum))
            {
                head.transfer = ServerPackAgreement.OutPlayer;
                head.packlx = ServerPackAgreement.TransFerHttp;
                head.otherString = new string[] { "房间不存在!"};
                GlobalMQ.instance.DeliveryOne(head.GetUtil(),
                    GlobalMQ.CreateMessage(head, null), true);
                return;
            }

            Desk desk = FindDesk(roomnum);
            if (desk == null || desk.deskinfo.weiyima != weiyima)
            {
                head.transfer = ServerPackAgreement.OutPlayer;
                head.packlx = ServerPackAgreement.TransFerHttp;
                head.otherString = new string[] { "房间不存在!"};
                GlobalMQ.instance.DeliveryOne(head.GetUtil(),
                    GlobalMQ.CreateMessage(head, null), true);
                return;
            }

            if (!desk.deskinfo.noWar)
            {
                head.transfer = ServerPackAgreement.OutPlayer;
                head.packlx = ServerPackAgreement.TransFerHttp;
                head.otherString = new string[] { "桌子已开战，踢出失败!"};
                GlobalMQ.instance.DeliveryOne(head.GetUtil(),
                    GlobalMQ.CreateMessage(head, null), true);
                return;
            }

            for (int i = 0; i < desk.Count; i++)
            {
                if (desk[i] == null) continue;
                if (desk[i].userid == userid)
                {
                    PackHead headp = PackHead.Create();
                    headp.userid = userid;
                    headp.packlx = GamePackAgreement.autoTipInfo;
                    headp.otherString = new string[] { "您被管理员踢出房间！" };
                    GeneralSendPack.SendPackToPlayer(headp, desk[i], null);
                    GameManager.instance.DoComBack(desk[i]);
                    head.Dispose();
                    break;
                }
            }
            
            head.transfer = ServerPackAgreement.OutPlayer;
            head.packlx = ServerPackAgreement.TransFerHttp;
            head.otherString = new string[] { "踢出成功!"};
            GlobalMQ.instance.DeliveryOne(head.GetUtil(),
                GlobalMQ.CreateMessage(head, null), true);
        }

        public void QuitGameJoinOther(GamePack pack)
        {
            var head = pack.Head;

            if (head.otherInt == null || head.otherInt.Length <= 0)
            {
                SendManager.SendErrotInfo_Http(head, 0, "数据错误！");
                return;
            }

            var player = PlayerCollection.Instance.FindPlayerByUserId(head.userid);
            if (player == null)
            {
                Debug.Error("未找到玩家!" + head.userid);
                SendManager.SendErrotInfo_Http(head, 0, "未找到玩家！");
                return;
            }

            JoinFriendRoom jfr = JsonPack.GetData<JoinFriendRoom>(pack.JsonData);
            if (head == null || jfr == null)
            {
                Debug.Error("客户端发来的数据有问题,加入玩法失败!");
                return;
            }

            PlayerState playerState = (PlayerState)player.state;
            if (playerState == PlayerState.Desk || playerState == PlayerState.Ready)
            {
                if (string.IsNullOrEmpty(player.friendWeiYiMa) || player.friendRoomNum == 0)
                {
                    SendManager.SendErrotInfo_Http(head, 0, $"你不在朋友房，不能切换房间!");
                }
                else
                {
                    //玩家退出当前游戏
                    GameManager.instance.DoComBack(player);
                    //去处理进入房间
                    head.packlx = head.otherInt[0];
                    int dealModuleId = head.packlx / Game.Data.GameData.PackCardInt;
                    Debug.Log("转发给游戏服务器:" + head.packlx);
                    GlobalMQ.instance.DeliveryEveryOne(dealModuleId, GlobalMQ.CreateMessage(head, jfr), true);
                }
            }
            else
            {
                SendManager.SendErrotInfo_Http(head, 0, $"当前状态{playerState}不能切换玩法！");
            }
        }
        
        /// <summary>
        /// 竞技比赛会长解散房间
        /// </summary>
        public int ClubDisBankCmd(string weiyima)
        {
            string roomnumStr = Room.GetRoomNum(weiyima);
            int roomnum = 0;

            if (!int.TryParse(roomnumStr, out roomnum))
            {
                return MessageErrCode.ClubDisbandNotFindDesk;
            }

            Desk desk = FindDesk(roomnum);

            if (desk == null || desk.deskinfo.weiyima != weiyima)
            {
                return MessageErrCode.ClubDisbandNotFindDesk;
            }

            DisBank(desk, 7);
            return MessageErrCode.Success;
        }

        /// <summary>
        /// 竞技比赛会长解散房间
        /// </summary>
        /// <param name="pack"></param>
        public void ClubDisBankCmd(GamePack pack)
        {
            var head = pack.Head;
            string weiyima = head.otherString[0];

            string roomnumStr = Room.GetRoomNum(weiyima);
            int roomnum = 0;

            if (!int.TryParse(roomnumStr, out roomnum))
            {
                SendManager.SendErrotInfo_Http(head, 2, 74);
                return;
            }

            Desk desk = FindDesk(roomnum);

            if (desk == null || desk.deskinfo.weiyima != weiyima)
            {
                SendManager.SendErrotInfo_Http(head, 2, 74);
                return;
            }

            DisBank(desk, 7);
            SendManager.SendErrotInfo_Http(head, 2, 75);
        }

        /// <summary>
        /// 竞技比赛因玩家比赛积分不够解散桌子
        /// </summary>
        /// <param name="pack"></param>
        public void ClubMatchDisBankByBurs(GamePack pack)
        {
            var head = pack.Head;
            string weiyima = head.otherString[0];

            string roomnumStr = Room.GetRoomNum(weiyima);
            int roomnum = 0;

            if (!int.TryParse(roomnumStr, out roomnum))
            {
                return;
            }

            Desk desk = FindDesk(roomnum);

            if (desk == null || desk.deskinfo.weiyima != weiyima)
            {
                return;
            }

            DisBank(desk, 8);
        }

        /// <summary>
        /// 竞技比赛创建桌子
        /// </summary>
        /// <param name="pack"></param>
        public void DoClubCreateDesk(GamePack pack)
        {
            if (ting == null)
            {
                Debug.Error("游戏未开启朋友房功能!");
                return;
            }

            PackHead head = pack.Head;
            JoinFriendRoom jfr = JsonPack.GetData<JoinFriendRoom>(pack.JsonData);
            if (head == null || jfr == null)
            {
                Debug.Error("客户端发来的数据有问题,加入玩法失败!");
                return;
            }

            DeskInfo dskinfo = new DeskInfo();
            dskinfo.wayid = jfr.way.weiyima;
            dskinfo.creatStyle = 5;
            dskinfo.creatUserid = jfr.way.Clubid;
            dskinfo.rule = jfr.way.dskrule;
            if (dskinfo.rule.RuleEx == null)
                dskinfo.rule.RuleEx = new DeskRuleEx();
            dskinfo.rule.RuleEx.ReadyTimeout = jfr.ReadyTimeOut;

            CreateRoomPack crp = new CreateRoomPack();
            crp.deskinfo = dskinfo;
            crp.deviceInfo = jfr.deviceInfo;
            crp.isAuto = jfr.isAuto;
            crp.ClubId = jfr.ClubId;
            crp.TaskId = jfr.TaskId;
            //获取到房间号,去创建房间
            if (instance.GetFriendRoomNum(head, crp))
            {
                instance.CreatRoomLogin(head, crp, true, true);
            }
        }

        public async Task JoinClubDesk(GamePack pack)
        {
            PackHead head = pack.Head;
            JoinFriendRoom jfr = JsonPack.GetData<JoinFriendRoom>(pack.JsonData);
            if (head == null || jfr == null)
            {
                Debug.Error("客户端发来的数据有问题,加入玩法失败!");
                return;
            }

            if (DoingUserIds.Contains(head.userid))
            {
                Debug.Error($"正在处理别的事务:{head.userid}");
                GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskDoing);
                return;
            }

            if (ting == null)
            {
                Debug.Error("游戏未开启朋友房功能!");
                GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotOpenFriend);
                return;
            }

            int userid = head.userid;
            try
            {
                DoingUserIds.Add(userid);

                //有则尝试加入房间!
                //先把房间找到->
                string strRoomNum = Room.GetRoomNum(jfr.joinweiyima);

                Debug.Info("找到房间:" + strRoomNum + "," + jfr.joinweiyima);

                //管理该房间的节点
                ServerNode node = null;

                string weiyima = null;

                //拿到房间号,先看本地有没有，没有的话则加载起来
                int roomnum = 0;
                if (int.TryParse(strRoomNum, out roomnum))
                {
                    //有房间号
                    if (Room.GetWeiyima(roomnum, ref weiyima, ref node))
                    {
                        //拿到唯一码
                        if (weiyima == jfr.joinweiyima)
                        {
                            //唯一码一致
                            if (!GameBase.instance.myUtil.Equals(node))
                            {
                                //交给管理模块处理
                                GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
                            }
                            else
                            {
                                //本模块处理 
                                //没在本地加载到本地
                                Debug.Info("本地处理");

                                DoJoinFriendRoom djfr = new DoJoinFriendRoom(head,
                                    new JoinRoom(roomnum.ToString(), weiyima) { deviceinfo = jfr.deviceInfo }, jfr,
                                    false, true);
                                await djfr.Start();

                                if (!djfr.result)
                                {
                                    //进入失败 再来一次
                                    /*
                                    jfr.lastjoinweiyima = weiyima;
                                    jfr.joinweiyima = null;
                                    */
                                    Debug.Log("加入失败的提示:" + djfr.errinfo);
                                    if (jfr.TaskId <= 0)
                                    {
                                        if (string.IsNullOrEmpty(djfr.errinfo))
                                        {
                                            SendManager.SendErrotInfo_Http(head, 1, 73);
                                        }
                                        else
                                        {
                                            SendManager.SendErrotInfo_Http(head, 0, djfr.errinfo);
                                        }
                                    }
                                    else
                                    {
                                        GeneralSendPack.SendJoinDeskResult(jfr.TaskId, djfr.errorCode);
                                    }


                                    /*
                                    head.packlx = GlobalManager.instance.myUtil.id * 10000 + head.packlx;
                                    GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
                                    */
                                    Debug.Warning("进入失败,发包再试!" + head.ip);
                                }
                                else
                                {
                                    if (jfr.TaskId <= 0)
                                    {
                                        //把玩家拉入桌子
                                        head.transfer = ServerPackAgreement.ReConnection;
                                        head.packlx = ServerPackAgreement.TransFerHttp;
                                        head.otherInt = new int[] { ServerConfigManager.Instance.ClientId };
                                        GlobalMQ.instance.DeliveryOne(head.GetUtil(),
                                            GlobalMQ.CreateMessage(head, null),
                                            true);
                                    }
                                    else
                                    {
                                        GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.Success);
                                    }
                                }
                            }

                            return;
                        }
                    }
                }
            }
            finally
            {
                DoingUserIds.Remove(userid);
            }
        }

        /// <summary>
        /// 处理加入玩法包
        /// </summary>
        /// <param name="pack"></param>
        public void DoWanFa(GamePack pack)
        {
            PackHead head = pack.Head;
            JoinFriendRoom jfr = JsonPack.GetData<JoinFriendRoom>(pack.JsonData);
            if (head == null || jfr == null)
            {
                Debug.Error("客户端发来的数据有问题,加入玩法失败!");
                return;
            }

            if (ting == null)
            {
                Debug.Error("加入玩法失败,游戏未开启朋友房功能!");
                GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotOpenFriend);
                return;
            }

            JoinWanFa djfr = new JoinWanFa(head, jfr);
            djfr.Start(head);
        }

        /// <summary>
        /// 处理加入房间包
        /// </summary>
        /// <param name="pack"></param>
        public async Task DoJoinRoom(GamePack pack)
        {
            if (ting == null)
            {
                Debug.Error("加入房间失败,游戏未开启朋友房功能!");
                return;
            }

            PackHead head = pack.Head;
            JoinRoom jr = JsonPack.GetData<JoinRoom>(pack.JsonData);

            if (head == null || jr == null)
            {
                Debug.Error("客户端发来的数据有问题,加入房间失败!");
                return;
            }

            DoJoinFriendRoom djfr = new DoJoinFriendRoom(head, jr, null, true, false);
            await djfr.Start();

            if (!djfr.result)
            {
                head.otherString = new string[] { djfr.errinfo };
                head.packlx = GamePackAgreement.TransFerPack;
                head.transfer = GameSeverAgreement.notJoinFriendRoom;
                GlobalMQ.instance.DeliveryOne(head.GetUtil(), GlobalMQ.CreateMessage(head), true);
            }

            /*
             * TTTT补: 加入房间房间的处理修改，需要外部发包通知
             *
             *
             * */
        }

        /// <summary>
        /// 处理回放
        /// </summary>
        /// <param name="pack"></param>
        [Obsolete("过时，不使用")]
        public void DoHuiFang(GamePack pack)
        {
            //过时，不使用
            //Task task = Task.Factory.StartNew(
            //    () =>
            //    {
            //        FightRecordData frd = JsonPack.GetData<FightRecordData>(pack.jsondata);

            //        frd.data = Room.LoadFightRecord(frd.weiyima, frd.index);
            //        pack.head.packlx = GameSeverAgreement.friendfightdata;

            //        //回放数据可能是空!
            //        GameNet.SendPack_Userid(pack.head.GetModuleUtil(), pack.head, frd);
            //    }
            //);
        }

        /// <summary>
        /// 创建房间并登陆
        /// </summary>
        /// <param name="head"></param>
        /// <param name="data"></param>
        protected async Task CreatRoomLogin(PackHead head, CreateRoomPack data, bool isClub, bool isCheckDoing)
        {
            Debug.Info("创建房间 赔率:" + data.deskinfo.rule.peilv);
            await new FriendRoomManager.CreateRoom(head, head.userid, data, isClub, isCheckDoing).Start();
        }

        /// <summary>
        /// 解散房间包
        /// </summary>
        /// <param name="pk"></param>
        public void DisBankDesk(GamePack pk)
        {
            if (ting == null)
            {
                Debug.Error("朋友房未开启!");
                return;
            }

            if (pk.pl.tingid != ting.id)
            {
                Debug.Error("解散房间失败,没有这个房间!" + ting.id);
                return;
            }

            DisBank(pk.pl);
        }

        /// <summary>
        /// 请求解散包
        /// </summary>
        public void placeDisBank(GamePack pk)
        {
            placeDisBank(pk.pl);
        }

        /// <summary>
        /// 请求解散回复包
        /// </summary>
        /// <param name="pk"></param>
        public void DisReponse(GamePack pk)
        {
            bool dis = JsonPack.GetData<bool>(pk.JsonData);
            DisReponse(pk.pl, dis, false);
        }

        /// <summary>
        /// 解散房间命令
        /// </summary>
        public void DisBankCmd(int roomnum, int style)
        {
            //先判断房间存在不存在,再判断是否是过期房间
            //满足条件，解散房间

            if (ting != null)
            {
                Desk desk = FindDesk(roomnum);
                if (desk == null)
                {
                    Debug.Warning("无此房间,可能已经被解散了!");
                }
                else
                {
                    //判断房间是否过期解散
                    if (desk.deskinfo == null)
                    {
                        Debug.Error("大错误,桌子数据为空!");
                        return;
                    }

                    if (style == 7)
                    {
                        Debug.Info("收到强制解散房间命令!");
                        DisBank(desk, style);
                    }
                    else
                    {
                        int isDisBank = desk.deskinfo.CheckDisBank();

                        if (isDisBank > 0)
                        {
                            Debug.Info("检查解散房间!");
                            //解散
                            DisBank(desk, 2 + isDisBank);
                        }
                        else
                        {
                            Debug.Warning("收到假的解散指令!");
                        }
                    }
                }
            }
            else
            {
                Debug.Error("未开启朋友房，收到解散指令!");
            }
        }


        /// <summary>
        /// 获取玩家的桌子
        /// </summary>
        /// <param name="pl"></param>
        /// <returns></returns>
        public Desk GetPlayerDesk(PlayerDataAsyc pl)
        {
            //内存中如果没有桌子
            Desk desk = FindDesk(pl.friendRoomNum);
            if (desk != null)
                return desk;

            //去数据库中加载桌子
            if (LoadFriendRoom(pl.friendRoomNum, pl.friendWeiYiMa))
            {
                desk = FindDesk(pl.friendRoomNum); //再从内存中加载起来
            }

            return desk;
        }

        /// <summary>
        /// 加载房间
        /// </summary>
        /// <returns></returns>
        protected bool LoadFriendRoom(int roomnum, string weiyima)
        {
            DeskInfo dskInfo = null;

            //释放房间
            void FreeRoom()
            {
                //没开启朋友房
                Debug.Info("没开启朋友房!");
                string _weiyima = null;
                ServerNode node = null;
                if (Room.GetWeiyima(roomnum, ref _weiyima, ref node)
                    && weiyima == _weiyima)
                {
                    if (Room.LoadRoom(_weiyima, out dskInfo))
                    {
                        //把数据从硬盘上加载起来
                        Debug.Info("加载朋友房数据:删除他!");
                        Desk.DisBank(dskInfo);
                    }
                }
            }

            if (ting == null)
            {
                Debug.Error("未开启朋友房!");
                FreeRoom(); //朋友房未开启,释放房间
                return false;
            }


            //加载朋友房到内存
            Desk dsk = FindDesk(roomnum);

            if (dsk == null)
            {
                //内存中没有--去加载朋友房
                Debug.Log("没找到这个朋友房:" + roomnum);
                //去数据库中拿
                DeskInfo dskinfo;
                if (Room.LoadRoom(weiyima, out dskinfo))
                {
                    //桌子数据处理完成!
                    Debug.Info($"加载朋友房数据! {dskinfo.weiyima}");
                    LoadDesk(dskinfo);
                }
                else
                {
                    //数据库中也没有
                    return false;
                }
            }

            return true;
        }

        private void SetPlayerScoreRecord(DeskInfo deskInfo)
        {
            try
            {
                if (!deskInfo.isAllOver || deskInfo.creatStyle != 5 || string.IsNullOrEmpty(deskInfo.wayid))
                {
                    return;
                }

                LuckPlayerManager.FightScore[] fightScore = new LuckPlayerManager.FightScore[deskInfo.seat.Length];
                for (int i = 0; i < deskInfo.seat.Length; i++)
                {
                    fightScore[i] = new LuckPlayerManager.FightScore()
                    {
                        UserId = deskInfo.pls[i].userid,
                        Value = (int)deskInfo.SumBurs[i].Score
                    };
                    FriendRoomStatistics.Instance.AddSessionFight(deskInfo.wayid, deskInfo.rule.peilv,
                        deskInfo.pls[i].userid, (int)deskInfo.SumBurs[i].Score);
                }

                LuckPlayerManager.Instance.AddScoreRecord(deskInfo.wayid, deskInfo.rule.peilv, deskInfo.overCnt,
                    fightScore);
            }
            catch (Exception e)
            {
                Debug.Error($"SetPlayerScoreRecord:{e.Message}");
            }
        }

        /// <summary>
        /// 解散桌子逻辑
        /// </summary>
        /// <param name="desk">要解散的桌子</param>
        /// <param name="style"> 1局数打完解散 2开战过-玩家申请解散 3超时解散(24小时未打完) 4超时解散(1小时内还没满员) 5房主解散  6玩法被删除  7竞技比赛管理解散房间  8因小局分不够解散  9托管自动解散</param>
        public void DisBank(Desk desk, int style)
        {
            // 上报
            if (desk.deskinfo != null && !desk.deskinfo.noWar)
            {
                desk.AddWarTime(); // 重新计算一下战局时长，防止漏计算
                
                List<StatisticsTrackingLogData> eLogs = new List<StatisticsTrackingLogData>();
                for (int i = 0; i < desk.PlayerCnt; i++)
                {
                    if (desk[i] != null)
                    {
                        // 用户游玩时长
                        eLogs.Add(StatisticsTrackingLogData.Create(
                            desk[i].userid.ToString(), 
                            EventTrackConst.GameFriendPlayTime, 
                            desk.totalWarTime,
                            ServerConfigManager.Instance.GameId.ToString()
                        ));
                    }
                }
                if (desk.deskinfo.creatStyle == 5)
                {
                    // 公会游玩局数
                    var clubIds = desk.Select(x => x.ClubId).Distinct();
                    foreach (var clubId in clubIds)
                    {
                        eLogs.Add(StatisticsTrackingLogData.Create(
                            clubId.ToString(), 
                            EventTrackConst.GameClubPlayCount,
                            1,
                            ServerConfigManager.Instance.GameId.ToString()
                        ));
                    }
                }
                
                // 解散原因
                eLogs.Add(StatisticsTrackingLogData.Create(
                    ServerConfigManager.Instance.GameId.ToString(), 
                    EventTrackConst.GameDisCount,
                    1,
                    style.ToString()
                ));
                
                EventTrackingUtil.OnEvent(eLogs);
            }
            
            desk.DisBank(style);
            DeskInfo deskinfo = desk.deskinfo;
            //只要是解散，都应该要算输赢分
            Room.SetSumBurs(deskinfo);

            SetPlayerScoreRecord(deskinfo);

            deskinfo.isClose = 1;
            //先发包
            desk.SendFriendRoomOver(style);
            //Debug.Info($"解散原因：{deskinfo.GetDisBankMemo(style)}");
            //修改玩家数据,修改桌子数据 --执行完玩家就离线了!
            desk.DisBankAfter(style);
            //修改链表数据

            //添加到闲置的桌子!
            ting.AddIdleing(desk);

            if (deskinfo.creatStyle == 5)
            {
                WayManager.instance.WayDeskChangeSend(deskinfo.creatUserid, deskinfo.wayid, deskinfo.weiyima, 1);
            }

            int rm = 0;
            if (!int.TryParse(desk.deskinfo.roomNum, out rm))
            {
                Debug.Error("房间号竟然不是数字!");
                return;
            }

            Debug.Info("获取到房间号:" + rm);

            int idx = rm % 10;
            if (!allDesks[idx].Remove(rm))
            {
                Debug.Error("alldesk中竟然没有此房间!");
                return;
            }
        }

        /// <summary>
        /// 根据房间号查找桌子
        /// </summary>
        /// <returns></returns>
        public Desk FindDesk(int deskNum)
        {
            if (ting == null)
                return null;

            if (deskNum < 0)
                return null;
            int idx = deskNum % 10;

            Desk desk = null;
            if (allDesks[idx].TryGetValue(deskNum, out desk))
                return desk;
            return null;
        }


        /// <summary>
        /// 请求解散房间包
        /// </summary>
        /// <param name="pl"></param>
        private void placeDisBank(PlayerDataAsyc pl)
        {
            if (pl.friendRoomNum <= 0)
            {
                Debug.Error("此玩家没有朋友房!");
                return;
            }

            Desk dsk = FindDesk(pl.friendRoomNum);

            if (dsk == null)
            {
                Debug.Error("逻辑错误,没找到这个桌子" + pl.friendRoomNum);
                return;
            }

            if (dsk.deskinfo.noWar)
            {
                Debug.Error("未开战不处理!");
                return;
            }

            if (dsk.deskinfo.isDising)
            {
                Debug.Warning("正在处理解散房间!");
                return;
            }

            if (dsk.deskinfo.rule.RuleEx != null && dsk.deskinfo.rule.RuleEx.CanRequestDissolveCnt < 0)
            {
                Debug.Log("不支持解散!");
                return;
            }

            if (dsk.deskinfo.rule.RuleEx != null && dsk.deskinfo.rule.RuleEx.CanRequestDissolveCnt > 0 &&
                dsk.deskinfo.RequestDissolveCnt >= dsk.deskinfo.rule.RuleEx.CanRequestDissolveCnt)
            {
                Debug.Log("请求解散的次数达到上限!");
                return;
            }

            dsk.deskinfo.isDising = true;
            dsk.deskinfo.DisCount = DeskInfo.DisTimeOut;
            dsk.deskinfo.RequestDissolveCnt++;
            int len = dsk.deskinfo.plsDis.Length;
            DisReponse(pl, true, true);
        }

        /// <summary>
        /// 请求立即开战
        /// </summary>
        /// <param name="pack"></param>
        public void placeOnceFight(GamePack pack)
        {
            Debug.Info("得到立即开战包:");
            placeOnceFight(pack.pl, pack.Head);
        }

        /// <summary>
        /// 请求开战
        /// </summary>
        /// <param name="pl">玩家数据</param>
        /// <param name="head">包头</param>
        private void placeOnceFight(PlayerDataAsyc pl, PackHead head)
        {
            if (ting == null)
                return;

            if (pl.friendRoomNum <= 0)
            {
                Debug.Error("玩家没有朋友房!");
                return;
            }

            Desk dsk = FindDesk(pl.friendRoomNum);

            if (dsk == null)
            {
                Debug.Error("逻辑错误,没找到这个桌子" + pl.friendRoomNum);
                return;
            }

            if (dsk.deskinfo.rule.minCnt >= dsk.deskinfo.rule.maxCnt)
            {
                Debug.Error("没有设置立即开战!");
                return;
            }

            if (!dsk.deskinfo.noWar)
            {
                Debug.Error("开战了不处理!");
                return;
            }

            if (head.otherInt == null || head.otherInt.Length < 1)
                return;

            dsk.deskinfo.OnceFight[dsk.deskinfo.seat[pl.seat]] = head.otherInt[0];
            dsk.SendOnceFight();
        }

        /// <summary>
        /// 解散回复包
        /// </summary>
        /// <param name="pl">回复的玩家</param>
        /// <param name="Dis">是否同意解散</param>
        /// <param name="source">是否是发起者</param>
        public void DisReponse(PlayerDataAsyc pl, bool Dis, bool source)
        {
            if (pl.friendRoomNum <= 0)
                return;

            Desk dsk = FindDesk(pl.friendRoomNum);
            if (!dsk.deskinfo.isDising)
                return;

            
            int len = dsk.deskinfo.plsDis.Length;
            for (int i = 0; i < len; i++)
            {
                //这个位置有人 没投票过 是这个玩家
                if (dsk.deskinfo.pls[i] != null && dsk.deskinfo.plsDis[i] == 0 &&
                    dsk.deskinfo.pls[i].userid == pl.userid)
                {
                    if (Dis)
                    {
                        if (source)
                        {
                            dsk.deskinfo.DisUserId = pl.userid;
                        }
                        
                        dsk.deskinfo.plsDis[i] = 1;
                        dsk.SendDisInfo(source ? 1 : 2, pl.userid, pl.nickname);
                    }
                    else
                    {
                        dsk.deskinfo.DisUserId = 0;
                        //拒绝解散
                        //dsk.deskinfo.plsDis[i] = -1;
                        dsk.deskinfo.isDising = false;
                        dsk.SendDisInfo(3, pl.userid, pl.nickname);

                        for (int j = 0; j < len; j++)
                        {
                            dsk.deskinfo.plsDis[j] = 0;
                        }

                        Debug.Log("告诉玩家，谁谁谁拒绝解散!");
                        return;
                    }

                    break;
                }
            }

            //检查是否全部人都同意解散
            bool isDis = true;
            for (int i = 0; i < len; i++)
            {
                if (dsk.deskinfo.pls[i] != null)
                {
                    //这个位置有人且不是同意
                    if (dsk.deskinfo.plsDis[i] != 1)
                    {
                        isDis = false;
                        break;
                    }
                }
            }

            if (isDis)
            {
                //解散房间
                Debug.Info("所有人同意解散!");
                DisBank(dsk,2);
            }
        }

        public void DeductCard(PlayerDataAsyc pl, DeskInfo info)
        {
            if (info.fangka == 0)
            {
                return;
            }

            if (info.creatStyle == 5)
            {
                //通知竞技比赛扣除竞技比赛房卡
                ClubDataChange cdc = new ClubDataChange()
                {
                    style = 1,
                    clubid = info.creatUserid,
                    value = -info.fangka
                };

                // PackHead head = PackHead.Create(ServerPackAgreement.ClubDataChange);
                // ClubDataManager.AddClubCardAsyn(info.creatUserid, -info.fangka);
                // GlobalMQ.instance.DeliveryEveryOne((int)ModuleType.ClubModule, GlobalMQ.CreateMessage(head, cdc), true,
                //     true);
                // head.Dispose();
                
                // 埋点
                EventTrackingUtil.OnEvent(StatisticsTrackingLogData.Create(
                    info.creatUserid.ToString(),
                    EventTrackConst.GamePlayCardCount, 
                    info.fangka,
                    ServerConfigManager.Instance.GameId.ToString()
                ));
            }
            else
            {
                if (pl == null)
                {
                    return;
                }

                //通知数据中心，扣除玩家的房卡
                if (info.fangka != 0)
                {
                    PlayerDataChange pdc = PlayerDataChange.Create(info.creatUserid);
                    pdc.fangkaChange = -info.fangka;
                    PlayerFun.WritePlayerDataAsync(pdc);
                    pl.fangka -= info.fangka;
                }
            }

            GameManager.instance.DelFangKa += info.fangka;
        }

        /// <summary>
        /// 创建桌子--这种是新创建的
        /// </summary>
        /// <param name="pl">创建者</param>
        /// <param name="info">桌子信息</param>
        /// <returns></returns>
        public int CreateDesk(PlayerDataAsyc pl, DeskInfo info, ref string errinfo, ref int errcode)
        {
            //DeductCard(pl, info);

            Debug.Info("创建所需的房卡数值:" + info.fangka);

            Desk desk = ting.GetDesk(DeskState.Idle, info);
            desk.Init();
            Debug.Info("创建桌子实例!" + info.creatStyle + "," + info.creatUserid + "," + desk.id);

            int deskNum = int.Parse(info.roomNum);
            AddDesk(deskNum, desk);
            Debug.Info("获取到房间号:" + deskNum);
            ting.RemoveIdle(desk);
            ting.AddQueueing(desk);

            if (EnterDesk(deskNum, pl, info.rule.pwd, info.creatStyle == 5, ref errinfo, ref errcode) == 1)
            {
                Debug.Info("玩家进入房间成功! cccdd:" + pl.ClubId);
            }
            else
            {
                Debug.Error("自己创建的房间怎么还有进不去的情况?????" + info.roomNum + "," + errinfo);
                return 0;
            }

            //Debug.Log("创建成功!");
            Debug.Log(info.ToString());
            return 1;
        }

        /// <summary>
        /// 添加desk
        /// </summary>
        /// <param name="deskNum"></param>
        /// <param name="desk"></param>
        protected void AddDesk(int deskNum, Desk desk)
        {
            if (ting == null)
            {
                Debug.Error("非朋友房不得使用!");
                return;
            }

            int idx = deskNum % 10;

            Debug.Info("添加房间...." + deskNum);

            allDesks[idx].Add(deskNum, desk);
        }

        /// <summary>
        /// 处理玩家解散房间包
        /// </summary>
        /// <param name="pl"></param>
        public void DisBank(PlayerDataAsyc pl)
        {
            //先判断
            if (pl.outline == 1)
            {
                Debug.Error("玩家离线哪里来的包!");
                return;
            }

            if (pl.friendRoomNum <= 0)
            {
                Debug.Error("玩家没有房间号!");
                return;
            }

            if (pl.state == (int)PlayerState.Desk || pl.state == (int)PlayerState.Ready)
            {
                if (!ting.isExists(pl.deskid))
                {
                    Debug.Error("解散桌子错误!没有这个桌子!");
                    return;
                }

                var desk = ting[pl.deskid];

                if (desk.CheckDisbank(pl))
                {
                    Debug.Info("解散房间的收包!");
                    DisBank(desk, 5);
                }
                else
                {
                    Debug.Warning("解散失败！");
                }
            }
            else
            {
                Debug.Warning("玩家状态不符合解散桌子!");
                return;
            }
        }


        /// <summary>
        /// 本来就有的桌子
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public void LoadDesk(DeskInfo info)
        {
            Desk desk = ting.GetDesk(DeskState.Idle, info);
            desk.Init();
            desk.LoadDesk();
            AddDesk(int.Parse(info.roomNum), desk);
            ting.RemoveIdle(desk);
            if (desk.deskinfo.nowCnt == 0)
            {
                //0表示未开战 不等于0表示开战
                ting.AddQueueing(desk);
            }
            else
            {
                desk.waitRecover = true;
                ting.AddWaring(desk);
            }
        }


        /// <summary>
        /// 删除玩法
        /// </summary>
        public void DelWay(int clubid, string wayid)
        {
            //思路 把这个玩法的所有桌子的唯一码拿到手。
            //获取到桌子信息, 判断桌子是否已经开战,如果没有开战则解散桌子
            var weiyimaArray = WayManager.instance.GetDesksWeiYiMa(clubid, wayid).Select(p => (string)p.Name)
                .ToArray(); //用这个得到唯一码
            foreach (var weiyima in weiyimaArray)
            {
                if (!string.IsNullOrEmpty(weiyima))
                {
                    var roomNum = Room.GetRoomNum(weiyima); //Room.GetRoomNum 传递唯一码获取房间号
                    if (int.TryParse(roomNum, out var roomnum))
                    {
                        var weiyimaOrig = string.Empty;
                        ServerNode node = null; //再根据房间号获取到唯一码 与 node. 返回值表示是否有这个房间。如果没这个房间输出错误信息。
                        if (Room.GetWeiyima(roomnum, ref weiyimaOrig, ref node))
                        {
                            //这个唯一码要与 刚才得到的唯一码进行对比，验证是否是同一个桌子 。   房间号是可以重复的, 桌子的唯一码却不会重复。
                            if (weiyima.Equals(weiyimaOrig))
                            {
                                //验证成功的话，FindDesk  查找到桌子
                                var desk = FindDesk(roomnum);
                                //桌子是空输出错误信息 
                                if (desk == null)
                                {
                                    Debug.Error(
                                        $"DelWay desk is null! clubid: {clubid}, wayid: {wayid}, weiyima: {weiyima}, roomNum: {roomNum}.");
                                }
                                else if (!desk.isWar)
                                {
                                    //再判断桌子是否已经开战 isWar 属性。                                                      
                                    DisBank(desk, 6); //已经开战不处理,未开战调用 DisBank()  调用解散桌子  
                                }
                            }
                        }
                    }
                }
            }
        }

        /*
         * redis中的数据解构
         *
         * friendroom.lastRoomNum  hash类型  lastDateTime 上次创建的时间 lastDateRoomNum 上次创建房间的房间号
         * friendroom.room.num string类型 房间号表 -> 存储唯一吗值
         * friendroom.唯一码 -> 房间数据
         * friendroom.唯一码_playerdata_idx -> 存储房间的玩家数据
         * friendroom.唯一码_score_idx -> 存储房间分数
         *
         * */

        /*
         *
         * 	朋友房唯一码 = 日期+时间+毫秒+房间号
         *
        {创建房间的算法}
        {
            1.房间号的算法{   --混淆游戏的火爆程度
                变量    房间增量     当前检测房间号
                1.房间增量 = 上次创建房间与当前时间的时间差 / 10 % 1000
                2.当前检测的房间号 = (上次创建房间的房间号+房间增量) % 1000000
                3.对比是否与上次创建的房间号一样，房间号+1
            }

            2.检测房间可用 传入检查的房间号 检查次数{
            拿到房间号->去检查
            检查次数+1;

            如果检查房间号发现已经检查 100 次 返回未检查到可用房间->发包玩家重试

            第一种情况2.1 房间号表有值
            {
                根据房间的唯一码去获取朋友房数据
                {
                    1.房间已经超时 应该解散(未开战,过了半个小时->执行解散(发送解散命令)  开战了->过了24小时未战斗完(解散))
                        去执行解散房间
                        检查的房间号+1 -> 继续调用检测房间方法

                    2.房间正常
                        检查的房间号+1 -> 继续调用检测房间方法
                }
                第二种情况2.2 房间号表中没值
                {
                    执行创建房间;
                }
            }



          3.创建房间->检测次数
            分布式加锁
                再做检查，已防万一已被别的程序创建！
                3.1检查发现不可用 返回创建失败->执行检查房间号,检测次数+1
                    cha
                3.2检查可用
                  1. 根据房间数据创建桌子，生成房间数据
                  2. 根据房间数据，保存到房间分数表、房间玩家数据表，房间数据表，房间唯一吗表，上次创建房间的房间号表

            分布式解锁

          4.解散房间
            判断房间号是否是自己模块管理的
                1.不是本模块管理，发包给管理的模块处理   ->有可能模块不在线，(或者不开了.....手动清楚数据,一般不应该出现这种情况)
                2.是本模块管理{

                   清楚桌子内存数据,
                    分布式 加锁
                   1.删除房间号表中的值,
                    分布式 借锁
                   2.redis桌子数据异步存储到sql.存储完成后删除redis中的桌子数据

                }
        }
         */


        /// <summary>
        /// 快速加入
        /// </summary>
        public class JoinWanFa
        {
            /// <summary>
            /// 包头
            /// </summary>
            public readonly PackHead head;

            /// <summary>
            /// 加入房间
            /// </summary>
            public readonly JoinFriendRoom jfr;

            /// <summary>
            /// 加入玩法
            /// </summary>
            /// <param name="head"></param>
            /// <param name="jfr"></param>
            public JoinWanFa(PackHead head, JoinFriendRoom jfr)
            {
                this.head = head;
                this.jfr = jfr;
            }

            /// <summary>
            /// 获取本次要计算的房间唯一码值
            /// </summary>
            /// <param name="jfr"></param>
            /// <param name="rooms"></param>
            protected void GetRoomWeiYiMa(JoinFriendRoom jfr, HashEntry[] rooms)
            {
                bool isLast = jfr.lastjoinweiyima == null;
                foreach (var item in rooms)
                {
                    if (!isLast)
                    {
                        //还没找到上次计算的房间
                        isLast = item.Name == jfr.lastjoinweiyima;
                    } //else { //找到了,找本次要运算的房间  2020-06-17 号修改,这个应该写错了，会跳过第一个房间

                    int cnt = 0;
                    if (!item.Value.TryParse(out cnt))
                    {
                        Debug.Fatal("存储的值错误,怎么存储的值非整数类型!" + jfr.way.weiyima + "," + jfr.way.Clubid);
                        continue;
                    }

                    if (isLast && cnt < jfr.way.dskrule.maxCnt)
                    {
                        //房间没满人
                        jfr.joinweiyima = item.Name; //选定要运算的房间
                        break;
                    }
                    //}
                }
            }


            /// <summary>
            /// 开始房间
            /// </summary>
            /// <returns></returns>
            public async Task Start(PackHead head)
            {
                if (jfr == null)
                {
                    Debug.Error("936983A9-02C9-4B81-A7F4-C06C7385B06B:");
                    return;
                }

                if (jfr.deviceInfo == null)
                {
                    Debug.Error("加入玩法时设备信息为空!!!");
                    GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotDeviceInfo);
                    return;
                }

                if (head.ip == null)
                {
                    Debug.Error("玩家的ip 是 空!!!");
                    GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskNotIp);
                    return;
                }

                int userid = head.userid;

                if (DoingUserIds.Contains(userid))
                {
                    Debug.Error($"正在处理别的事务:{head.userid}");
                    GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskDoing);
                    return;
                }

                Debug.Info("进入玩法!");

                HashEntry[] rooms = null;

                try
                {
                    DoingUserIds.Add(userid);
                    //如果当前进入房间有值,尝试进入房间
                    //如果当前进入房间没值,尝试计算当前要进入的房间
                    if (jfr.joinweiyima == null)
                    {
                        //没有想进入的房间,说明是从竞技比赛过来的

                        if (string.IsNullOrEmpty(jfr.way.weiyima))
                        {
                            Debug.Error("玩法的唯一码竟是空值!!!!");
                            GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.ClubJoinDeskParamError);
                            return;
                        }

                        //去找一个房间
                        rooms = WayManager.instance.GetDesksWeiYiMa(jfr.way.Clubid, jfr.way.weiyima);

                        Debug.Info("找到所有的房间:" + jfr.way.Clubid + "," + jfr.way.weiyima);

                        GetRoomWeiYiMa(jfr, rooms);
                    }

                    if (jfr.joinweiyima != null)
                    {
                        //有则尝试加入房间!
                        //先把房间找到->
                        string strRoomNum = Room.GetRoomNum(jfr.joinweiyima);

                        Debug.Info("找到房间:" + strRoomNum + "," + jfr.joinweiyima);

                        //管理该房间的节点
                        ServerNode node = null;

                        string weiyima = null;

                        //拿到房间号,先看本地有没有，没有的话则加载起来
                        int roomnum = 0;
                        if (int.TryParse(strRoomNum, out roomnum))
                        {
                            //有房间号
                            if (Room.GetWeiyima(roomnum, ref weiyima, ref node))
                            {
                                //拿到唯一码
                                if (weiyima == jfr.joinweiyima)
                                {
                                    //唯一码一致
                                    if (!GameBase.instance.myUtil.Equals(node))
                                    {
                                        //交给管理模块处理
                                        GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);
                                    }
                                    else
                                    {
                                        //本模块处理 
                                        //没在本地加载到本地
                                        Debug.Info("本地处理");

                                        DoJoinFriendRoom djfr = new DoJoinFriendRoom(head,
                                            new JoinRoom(roomnum.ToString(), weiyima) { deviceinfo = jfr.deviceInfo },
                                            jfr, false, true);
                                        djfr.IsTestPack = jfr.IsTestPack;
                                        await djfr.Start();

                                        if (!djfr.result)
                                        {
                                            //进入失败 再来一次
                                            Debug.Warning("进入失败，去创建一个房间!");
                                            jfr.lastjoinweiyima = weiyima;
                                            jfr.joinweiyima = null;
                                            var crp1 = new CreateRoomPack()
                                            {
                                                deviceInfo = jfr.deviceInfo, isAuto = jfr.isAuto, ClubId = jfr.ClubId,
                                                Score = jfr.Score,
                                                TaskId = jfr.TaskId,
                                                IsTestPack = jfr.IsTestPack,
                                                deskinfo = new DeskInfo()
                                                {
                                                    wayid = jfr.way.weiyima, creatStyle = 5,
                                                    creatUserid = jfr.way.Clubid,
                                                    rule = jfr.way.dskrule
                                                }
                                            };
                                            if (instance.GetFriendRoomNum(head, crp1))
                                            {
                                                await instance.CreatRoomLogin(head, crp1, true, false);
                                            }
                                            /*
                                            head.otherString = new string[] { djfr.errinfo};
                                            head.packlx = ServerPackAgreement.TransFerHttp;
                                            head.transfer = GameSeverAgreement.notJoinFriendRoom; */

                                            /*
                                                head.packlx = GlobalManager.instance.myUtil.id * 10000 + head.packlx;

                                                GlobalMQ.instance.DeliveryOne(node, GlobalMQ.CreateMessage(head, jfr), true);

                                                Debug.Warning("进入失败,发包再试!" + head.ip);*/
                                        }
                                        else
                                        {
                                            if (jfr.TaskId > 0)
                                            {
                                                GeneralSendPack.SendJoinDeskResult(jfr.TaskId, MessageErrCode.Success);
                                            }
                                            else
                                            {
                                                Debug.Info("把玩家拉入桌子!!!");
                                                
                                                //把玩家拉入桌子
                                                head.transfer = ServerPackAgreement.ReConnection;
                                                head.packlx = ServerPackAgreement.TransFerHttp;
                                                head.otherInt = new int[] { ServerConfigManager.Instance.ClientId };
                                                GlobalMQ.instance.DeliveryOne(head.GetUtil(),
                                                    GlobalMQ.CreateMessage(head, null), true);
                                            }
                                        }
                                    }

                                    return;
                                }
                            }
                        }
                    }

                    DeskInfo dskinfo = new DeskInfo();
                    dskinfo.wayid = jfr.way.weiyima;
                    dskinfo.creatStyle = 5;
                    dskinfo.creatUserid = jfr.way.Clubid;
                    dskinfo.rule = jfr.way.dskrule;
                    if (dskinfo.rule.RuleEx == null)
                        dskinfo.rule.RuleEx = new DeskRuleEx();
                    dskinfo.rule.RuleEx.ReadyTimeout = jfr.ReadyTimeOut;

                    Debug.Info("去创建朋友房!" + dskinfo.wayid);

                    CreateRoomPack crp = new CreateRoomPack();
                    crp.deskinfo = dskinfo;
                    crp.deviceInfo = jfr.deviceInfo;
                    crp.isAuto = jfr.isAuto;
                    crp.ClubId = jfr.ClubId;
                    crp.Score = jfr.Score;
                    crp.TaskId = jfr.TaskId;
                    crp.IsTestPack = jfr.IsTestPack;
                    //获取到房间号,去创建房间
                    if (instance.GetFriendRoomNum(head, crp))
                    {
                        await instance.CreatRoomLogin(head, crp, true, false);
                    }

                    //(head, crp);
                }
                catch (Exception e)
                {
                    Debug.Error($"报错：{e.Message} {e.StackTrace}");
                }
                finally
                {
                    DoingUserIds.Remove(userid);
                }
            }
        }
    }
}