Exemple #1
0
    def _isObserver(self, userId):
        """
        陈龙和才哥需求: 在德州和三张里观战时, 不能加好友。原因是好多恶意玩家用这个做宣传。
        跟辉哥商量过了, 没什么好办法实现~ 只能在这里写死 gameId

        by WangTao
        """

        locList = onlinedata.getOnlineLocList(userId)
        gameIds = {8, 30}

        for onlineLoc in locList:
            roomId, tableId, seatId = onlineLoc
            onlineGameId = strutil.getGameIdFromInstanceRoomId(roomId)

            if onlineGameId not in gameIds:
                continue

            # 判断是否观战状态。 只适用三张和德州
            if roomId and tableId and seatId:
                roomConf = gdata.getRoomConfigure(roomId)
                maxSeatN = roomConf['tableConf']['maxSeatN']
                if seatId == maxSeatN + 1:  # is observe
                    ftlog.info(
                        "FriendTcpHandler._isObserver| is observer"
                        "| userId, loc:", userId, onlineLoc)
                    return True

        return False
Exemple #2
0
    def _isObserver(self, userId):
        """
        陈龙和才哥需求: 在德州和三张里观战时, 不能加好友。原因是好多恶意玩家用这个做宣传。
        跟辉哥商量过了, 没什么好办法实现~ 只能在这里写死 gameId

        by WangTao
        """

        locList = onlinedata.getOnlineLocList(userId)
        gameIds = {8, 30}

        for onlineLoc in locList:
            roomId, tableId, seatId = onlineLoc
            onlineGameId = strutil.getGameIdFromInstanceRoomId(roomId)

            if onlineGameId not in gameIds:
                continue

            # 判断是否观战状态。 只适用三张和德州
            if roomId and tableId and seatId:
                roomConf = gdata.getRoomConfigure(roomId)
                maxSeatN = roomConf['tableConf']['maxSeatN']
                if seatId == maxSeatN + 1:  # is observe
                    ftlog.info("FriendTcpHandler._isObserver| is observer"
                               "| userId, loc:", userId, onlineLoc)
                    return True

        return False
Exemple #3
0
def createFT(userId, nRound, playMode, canDouble, goodCard=0):
    '''
    创建自建桌
    @param userId: 谁创建
    @param conf: 桌子配置
    '''
    # 获取creatorConf
    creatorConf = getCreatorConf(userId)
    # 收取创建自建桌费用
    if not creatorConf:
        raise TYBizException(-1, '不支持自建桌')
     
    roundConf = creatorConf.getRoundConf(nRound)
    if not roundConf:
        raise TYBizException(-1, '不支持的局数: %s' % (nRound))
     
    playModeConf = creatorConf.getPlayModeConf(playMode)
    if not playModeConf:
        raise TYBizException(-1, '不支持的玩法: %s' % (playMode))
    
    # check loc
    locList = onlinedata.getOnlineLocList(userId)
    for loc in locList:
        roomId, _, _ = loc
        gameId = strutil.getGameIdFromInstanceRoomId(roomId)
        if gameId == DIZHU_GAMEID:
            raise TYBizException(-1, '正在其他桌游戏')
        
    ctrlRoomIds = collectCtrlRoomIdsByFTPlayMode(playMode)
    if not ctrlRoomIds:
        ftlog.warn('ft_service.createFT userId=', userId,
                   'nRound=', nRound,
                   'playMode=', playMode,
                   'canDouble=', canDouble)
        raise TYBizException(-1, '不支持的玩法: %s' % (playMode))
    
    ctrlRoomId = ctrlRoomIds[random.randint(0, len(ctrlRoomIds) - 1)]
    if ftlog.is_debug():
        ftlog.debug('ft_service.createFT userId=', userId,
                    'nRound=', nRound,
                    'playMode=', playMode,
                    'canDouble=', canDouble,
                    'goodCard=', goodCard,
                    'ctrlRoomId=', ctrlRoomId,
                    'ctrlRoomIds=', ctrlRoomIds)
    
    fee = None
    if roundConf.fee > 0:
        fee = {'itemId':creatorConf.cardAssetKindId, 'count':roundConf.fee}
    return ft_room_remote.createFT(ctrlRoomId,
                                   userId,
                                   nRound,
                                   playModeConf.toDict(),
                                   canDouble,
                                   fee,
                                   goodCard)
Exemple #4
0
 def makeSitReq(cls, userId, shadowRoomId, tableId, clientId):
     mpSitReq = MsgPack()
     mpSitReq.setCmd("table")
     mpSitReq.setParam("action", "sit")
     mpSitReq.setParam("userId", userId)
     mpSitReq.setParam("roomId", shadowRoomId)
     mpSitReq.setParam("tableId", tableId)
     mpSitReq.setParam("clientId", clientId)
     mpSitReq.setParam("gameId", strutil.getGameIdFromInstanceRoomId(shadowRoomId))
     if ftlog.is_debug():
         ftlog.debug(str(mpSitReq), caller=cls)
     return mpSitReq
Exemple #5
0
def lockUserForMatch(gameId, userId, bigRoomId, instId, ctrlRoomId, tableId,
                     seatId, clientId):
    if ftlog.is_debug():
        ftlog.debug("match_remote.lockUserForMatch gameId=", gameId, "userId=",
                    userId, "bigRoomId=", bigRoomId, "instId=", instId,
                    "ctrlRoomId=", ctrlRoomId, "tableId=", tableId, "seatId=",
                    seatId, "clientId=", clientId)
    if not clientId:
        clientId = sessiondata.getClientId(userId)
    loc = None
    locList = onlinedata.getOnlineLocList(userId)
    for roomId, tableId, seatId in locList:
        try:
            roomGameId = strutil.getGameIdFromInstanceRoomId(roomId)
            if (roomGameId == gameId and tableId != 0 and seatId != 0):
                loc = [roomGameId, roomId, tableId, seatId]
        except:
            ftlog.error("match_remote.lockUserForMatch userId=", userId,
                        "gameId=", gameId, "clientId=", clientId, "roomId=",
                        roomId)
    if loc:
        # 检查loc
        if strutil.getBigRoomIdFromInstanceRoomId(loc[1]) != bigRoomId:
            ftlog.debug("match_remote.lockUserForMatch Fail gameId=", gameId,
                        "userId=", userId, "bigRoomId=", bigRoomId, "instId=",
                        instId, "ctrlRoomId=", ctrlRoomId, "tableId=", tableId,
                        "seatId=", seatId, "clientId=", clientId, "loc=", loc)
            return False

    userMatchInfo = loadUserMatchInfo(gameId, userId, bigRoomId)
    if not userMatchInfo:
        # 此处有异常,正常要有userMatchInfo
        userMatchInfo = UserMatchInfo(gameId, userId, bigRoomId)
        userMatchInfo.ctrlRoomId = ctrlRoomId
        userMatchInfo.instId = instId
        userMatchInfo.state = UserMatchInfo.ST_SIGNIN

    userMatchInfo.ctrlRoomId = ctrlRoomId
    userMatchInfo.state = UserMatchInfo.ST_PLAYING

    saveUserMatchInfo(userMatchInfo)

    room = gdata.rooms()[ctrlRoomId]
    player = room.match.findPlayer(userId)
    if not player or not player.isQuit:
        onlinedata.setBigRoomOnlineLoc(userId, ctrlRoomId, tableId, seatId)

    ftlog.info("match_remote.lockUserForMatch ok gameId=", gameId, "userId=",
               userId, "bigRoomId=", bigRoomId, "instId=", instId,
               "ctrlRoomId=", ctrlRoomId, "tableId=", tableId, "seatId=",
               seatId, "isQuit=", player.isQuit if player else -1, "clientId=",
               clientId)
    return True
Exemple #6
0
 def makeSitReq(cls, userId, shadowRoomId, tableId, clientId):
     """在子类中调用此方法"""
     mpSitReq = MsgPack()
     mpSitReq.setCmd("table")
     mpSitReq.setParam("action", "sit")
     mpSitReq.setParam("userId", userId)
     mpSitReq.setParam("roomId", shadowRoomId)
     mpSitReq.setParam("tableId", tableId)
     mpSitReq.setParam("clientId", clientId)
     mpSitReq.setParam("gameId", strutil.getGameIdFromInstanceRoomId(shadowRoomId))
     if ftlog.is_debug():
         ftlog.debug(str(mpSitReq), caller=cls)
     return mpSitReq
Exemple #7
0
def getOnlineLocListByGameId(userId, gameId, clientId):
    ret = []
    locList = onlinedata.getOnlineLocList(userId)
    for roomId, tableId, seatId in locList:
        try:
            roomGameId = strutil.getGameIdFromInstanceRoomId(roomId)
            if (roomGameId == gameId and tableId != 0 and seatId != 0):
                ret.append((roomGameId, roomId, tableId, seatId))
        except:
            ftlog.error('dizhuonlinedata.getOnlineLocListByGameId userId=',
                        userId, 'gameId=', gameId, 'clientId=', clientId,
                        'roomId=', roomId)
    return ret
Exemple #8
0
 def makeTableManageReq(cls, userId, shadowRoomId, tableId, clientId, action, params=None):
     mpReq = MsgPack()
     mpReq.setCmd("table_manage")
     mpReq.setParam("action", action)
     mpReq.setParam("userId", userId)
     mpReq.setParam("gameId", strutil.getGameIdFromInstanceRoomId(shadowRoomId))
     mpReq.setParam("roomId", shadowRoomId)
     mpReq.setParam("tableId", tableId)
     mpReq.setParam("clientId", clientId)
     if params:
         mpReq.updateParam(params)
     if ftlog.is_debug():
         ftlog.debug(str(mpReq), caller=cls)
     return mpReq
 def doTableCall2(self, userId, roomId, tableId, clientId):
     """渔场内的函数调用"""
     if strutil.getGameIdFromInstanceRoomId(roomId) == FISH_GAMEID:
         table = None
         msg = runcmd.getMsgPack()
         try:
             room = gdata.rooms()[roomId]
             table = room.maptable[tableId]
             action = msg.getParam("action")
             seatId = msg.getParam("seatId", -1) # 旁观时没有seatId参数
             assert isinstance(seatId, int)
             table.doTableCallOwn(msg, userId, seatId, action, clientId)
         except:
             ftlog.error("doTableCall2 error clear table", userId, msg, traceback.format_exc())
             table and table._clearTable()
Exemple #10
0
def getOnlineLoc(userId, gameId, roomId=0, tableId=0, locList=None):
    if not locList:
        locList = onlinedata.getOnlineLocList(userId)

    for onlineLoc in locList:
        if gameId != strutil.getGameIdFromInstanceRoomId(onlineLoc[0]):
            continue

        if roomId == 0:
            return onlineLoc

        if gdata.getBigRoomId(onlineLoc[0]) == gdata.getBigRoomId(roomId):
            if tableId == 0:
                return onlineLoc

            if onlineLoc[1] == tableId:
                return onlineLoc

    return [0, 0, 0]
Exemple #11
0
def getOnlineLoc(userId, gameId, roomId=0, tableId=0, locList=None):
    if not locList:
        locList = onlinedata.getOnlineLocList(userId)

    for onlineLoc in locList:
        if gameId != strutil.getGameIdFromInstanceRoomId(onlineLoc[0]):
            continue

        if roomId == 0:
            return onlineLoc

        if gdata.getBigRoomId(onlineLoc[0]) == gdata.getBigRoomId(roomId):
            if tableId == 0:
                return onlineLoc

            if onlineLoc[1] == tableId:
                return onlineLoc

    return [0, 0, 0]
Exemple #12
0
def _leaveFromMatchs(userId):
    from dizhu.servers.util.rpc import match_remote
    from dizhu.servers.util.rpc.match_remote import UserMatchInfo
    userMatchInfoMap = match_remote.loadAllUserMatchInfo(DIZHU_GAMEID, userId)
    if ftlog.is_debug():
        ftlog.debug('dizhuonlinedata._leaveFromMatchs userId=', userId,
                    'infos=', [(rid, umi.state)
                               for rid, umi in userMatchInfoMap.iteritems()])
    for _, userMatchInfo in userMatchInfoMap.iteritems():
        if userMatchInfo.state == UserMatchInfo.ST_SIGNIN:
            msg = MsgPack()
            msg.setCmdAction('room', 'leave')
            msg.setParam('userId', userId)
            msg.setParam('roomId', userMatchInfo.ctrlRoomId)
            msg.setParam(
                'gameId',
                strutil.getGameIdFromInstanceRoomId(userMatchInfo.ctrlRoomId))
            msg.setParam('reason', TYRoom.LEAVE_ROOM_REASON_LOST_CONNECTION)
            router.sendRoomServer(msg, userMatchInfo.ctrlRoomId)
Exemple #13
0
def checkUserQuitLoc(gameId, userId, roomId, clientId):
    gid = strutil.getBigRoomIdFromInstanceRoomId(roomId)
    ret = daobase.executeUserCmd(
        userId, 'HGET', 'quitol' + ':' + str(gameId) + ':' + str(userId),
        str(gid))
    retDict = strutil.loads(ret) if ret else None
    if retDict:
        rid = retDict.get('roomId')
        tid = retDict.get('tableId')
        sid = retDict.get('seatId')
        gid = strutil.getGameIdFromInstanceRoomId(rid)
        if gid > 0 and rid > 0 and tid > 0:
            # 到具体的房间或桌子的服务上去查询, 是否是真的在桌子上
            if tid == rid * 10000:  # 玩家在队列房间或者比赛房间的等待队列中, 此处不做一致性检查,玩家发起quick_start时检查。
                return 1
            else:
                try:
                    seatId, isObserving = roommgr.doCheckUserLoc(
                        userId, gid, rid, tid, clientId)
                except:
                    ftlog.error()
                    return -1
                ftlog.debug('_checkUserLoc->userId=', userId, 'seatId=',
                            seatId, 'isObserving=', isObserving)
                if seatId > 0 or isObserving == 1:
                    # 还在桌子上游戏
                    return 1
                else:
                    # 已经不再桌子上了, 清理所有的桌子带入金币
                    if sid > 0:
                        from poker.entity.dao import userchip
                        userchip.moveAllTableChipToChip(
                            userId, gid, 'TABLE_TCHIP_TO_CHIP', 0, clientId,
                            tid)
                    # 清理当前的在线数据
                    _removeUserQuitLoc(gameId, userId, rid)
                    return 0
        else:
            # 到这儿, 数据是错误的, 删除处理
            _removeUserQuitLoc(gameId, userId, rid)
            return 0
Exemple #14
0
 def makeTableManageReq(cls,
                        userId,
                        shadowRoomId,
                        tableId,
                        clientId,
                        action,
                        params=None):
     mpReq = MsgPack()
     mpReq.setCmd("table_manage")
     mpReq.setParam("action", action)
     mpReq.setParam("userId", userId)
     mpReq.setParam("gameId",
                    strutil.getGameIdFromInstanceRoomId(shadowRoomId))
     mpReq.setParam("roomId", shadowRoomId)
     mpReq.setParam("tableId", tableId)
     mpReq.setParam("clientId", clientId)
     if params:
         mpReq.updateParam(params)
     if ftlog.is_debug():
         ftlog.debug(str(mpReq), caller=cls)
     return mpReq
Exemple #15
0
    def doUserOffline(self, userId, clientId):
        evt = OnLineTcpChangedEvent(userId, HALL_GAMEID, 0)
        TGHall.getEventBus().publishEvent(evt)
        # 补发room_leave消息
        olist = onlinedata.getOnlineLocList(userId)
        ftlog.debug('doUserOffline onlines->', olist)
        for ol in olist:
            roomId, _, _ = ol[0], ol[1], ol[2]
            if roomId > 0:
                msg = MsgPack()
                msg.setCmdAction('room', 'leave')
                msg.setParam('userId', userId)
                msg.setParam('roomId', roomId)
                msg.setParam('gameId',
                             strutil.getGameIdFromInstanceRoomId(roomId))
                msg.setParam('clientId', clientId)
                msg.setParam('reason',
                             TYRoom.LEAVE_ROOM_REASON_LOST_CONNECTION)
                router.sendRoomServer(msg, roomId)

        # offline_geoc处理
        onlinedata.setUserGeoOffline(userId, HALL_GAMEID)
        # 通知push服务
        self._notifyPushUserOnlineStateChanged(userId, 0, clientId)
Exemple #16
0
def _getFriendGameInfo(userId,
                       gameIds,
                       for_level_info,
                       for_winchip,
                       for_online_info=1):
    uid = int(userId)
    datas = {}
    gid, rid, tid, sid = 0, 0, 0, 0
    state = daoconst.OFFLINE
    if for_online_info:
        loclist = onlinedata.getOnlineLocList(uid)
        state = onlinedata.getOnlineState(uid)
        if len(loclist) > 0:
            _rid, _tid, _sid = loclist[0]
            # gid表示用户在哪个游戏中
            gid = strutil.getGameIdFromInstanceRoomId(_rid)
            # 检查是否可加入游戏
            if TYGame(gid).canJoinGame(userId, _rid, _tid, _sid):
                # rid/tid/sid表示用户所在的游戏是否可加入游戏
                # 分享出来的都是可以加入游戏的牌桌信息
                rid = _rid
                tid = _tid
                sid = _sid
            if ftlog.is_debug():
                ftlog.debug('getFriendGameInfo userId:', userId, ' gameId:',
                            gid, ' roomId:', _rid, ' tableId:', _tid,
                            ' seatId:', _sid, ' can not join game....')
        if state == daoconst.OFFLINE:
            offline_time = gamedata.getGameAttr(uid, HALL_GAMEID,
                                                'offlineTime')
            if not offline_time:  # 取不到离线时间,取上线时间
                offline_time = userdata.getAttr(uid, 'authorTime')
            if offline_time:
                offline_time = pktimestamp.parseTimeMs(offline_time)
                delta = datetime.now() - offline_time
                delta = delta.days * 24 * 60 + delta.seconds / 60  # 分钟数
            else:  # 异常情况
                delta = 24 * 60
            datas['offline_time'] = delta if delta > 0 else 1
        if rid > 0:
            try:
                room = gdata.roomIdDefineMap().get(rid, None)
                if room:
                    datas['room_name'] = room.configure['name']
            except:
                ftlog.error()
    # 构造回传给SDK的游戏数据
    datas.update({
        'uid': uid,
        'gid': gid,
        'rid': rid,
        'tid': tid,
        'sid': sid,
        'state': state
    })

    if for_level_info:
        datas['level_game_id'] = 0
        datas['level'] = 0
        datas['level_pic'] = ''
        try:
            for gameId in gameIds:
                if gameId not in gdata.games():
                    continue
                dashifen_info = gdata.games()[gameId].getDaShiFen(uid, '')
                if dashifen_info:
                    level = dashifen_info['level']
                    if level > 0 and level > datas['level']:
                        datas['level_game_id'] = gameId
                        datas['level'] = level
                        level_pic = dashifen_info.get('picbig')
                        datas[
                            'level_pic'] = level_pic if level_pic else dashifen_info.get(
                                'pic')
        except:
            ftlog.error()

    if for_winchip:
        datas['winchip'] = 0
        datas['winchips'] = 0
        try:
            for gameId in gameIds:
                winchips, todaychips = gamedata.getGameAttrs(
                    userId, gameId, ['winchips', 'todaychips'], False)
                winchips = strutil.parseInts(winchips)
                yest_winchip = 0
                todaychips = strutil.loads(todaychips, ignoreException=True)
                if todaychips and 'today' in todaychips and 'chips' in todaychips and 'last' in todaychips:
                    if pktimestamp.formatTimeDayInt() == todaychips['today']:
                        yest_winchip = todaychips['last']
                    elif pktimestamp.formatTimeYesterDayInt(
                    ) == todaychips['today']:
                        yest_winchip = todaychips['chips']
                datas['winchip'] += yest_winchip
                datas['winchips'] += winchips
        except:
            ftlog.error()
    return datas
Exemple #17
0
def _checkUserLoc(userId, clientId, matchGameId=0):
    '''Why:
           玩家断线重连时,loc的信息可能与table不一致,conn server需要与table server通讯检查一致性;
           导致不一致的原因:服务端重启(特别是roomId、tableId变更)
           如果玩家在队列房间或者比赛房间的等待队列中, 此处不做一致性检查,等玩家发起quick_start时由room server检查
       What:
           与table server通讯检查桌子对象里是否有这个玩家的数据
           如果不一致,则回收牌桌金币并清空loc;
       Return:
           如果玩家在房间队列里,返回gameId.roomId.roomId*10000.1
           如果玩家在座位上,返回gameId.roomId.tableId.seatId
           如果玩家在旁观,返回gameId.roomId.tableId.0
           玩家不在table对象里,返回0.0.0.0
    '''
    truelocs = []
    loclist = _getOnlineLocList(userId)
    for locs in loclist:
        rid, tid, sid = locs[0], locs[1], locs[2]
        gid = strutil.getGameIdFromInstanceRoomId(rid)
        if gid > 0 and rid > 0 and tid > 0:
            # 到具体的房间或桌子的服务上去查询, 是否是真的在桌子上
            if tid == rid * 10000:  # 玩家在队列房间或者比赛房间的等待队列中, 此处不做一致性检查,玩家发起quick_start时检查。
                truelocs.append('%d.%d.%d.%d' % (gid, rid, tid, sid))
            else:
                seatId, isObserving = 0, 0
                try:
                    seatId, isObserving = roommgr.doCheckUserLoc(
                        userId, gid, rid, tid, clientId)
                except:
                    ftlog.error()
                    continue
                ftlog.debug('_checkUserLoc->userId=', userId, 'seatId=',
                            seatId, 'isObserving=', isObserving)
                if seatId > 0 or isObserving == 1:
                    # 还在桌子上游戏, 返回断线重连的信息
                    if matchGameId > 0:
                        if matchGameId == gid:
                            truelocs.append('%d.%d.%d.%d' %
                                            (gid, rid, tid, seatId))
                    else:
                        truelocs.append('%d.%d.%d.%d' %
                                        (gid, rid, tid, seatId))
                else:
                    # 已经不再桌子上了, 清理所有的桌子带入金币
                    if sid > 0:
                        from poker.entity.dao import userchip
                        userchip.moveAllTableChipToChip(
                            userId, gid, 'TABLE_TCHIP_TO_CHIP', 0, clientId,
                            tid)
                    # 清理当前的在线数据
                    _removeOnlineLoc(userId, rid, tid)
        else:
            # 到这儿, 数据是错误的, 删除处理
            _removeOnlineLoc(userId, rid, tid)
    ftlog.debug('_checkUserLoc->', userId, clientId, truelocs)
    if pokerconf.isOpenMoreTable(clientId):
        # 新的客户端协议, 对于断线重连支持的时列表格式, 即客户端可以进行多开
        return strutil.dumps(truelocs)
    else:
        # 老的客户端, 只支持一个桌子
        if truelocs:
            return truelocs[0]
        return '0.0.0.0'
Exemple #18
0
def _getFriendGameInfo(userId, gameIds, for_level_info, for_winchip, for_online_info=1):
    uid = int(userId)
    datas = {}
    gid, rid, tid, sid = 0, 0, 0, 0
    state = daoconst.OFFLINE
    if for_online_info:
        loclist = onlinedata.getOnlineLocList(uid)
        state = onlinedata.getOnlineState(uid)
        if len(loclist) > 0:
            _rid, _tid, _sid = loclist[0]
            # gid表示用户在哪个游戏中
            gid = strutil.getGameIdFromInstanceRoomId(_rid)
            # 检查是否可加入游戏
            if TYGame(gid).canJoinGame(userId, _rid, _tid, _sid):
                # rid/tid/sid表示用户所在的游戏是否可加入游戏
                # 分享出来的都是可以加入游戏的牌桌信息
                rid = _rid
                tid = _tid
                sid = _sid
            if ftlog.is_debug():
                ftlog.debug('getFriendGameInfo userId:', userId, ' gameId:', gid, ' roomId:', _rid, ' tableId:', _tid,
                            ' seatId:', _sid, ' can not join game....')
        if state == daoconst.OFFLINE:
            offline_time = gamedata.getGameAttr(uid, HALL_GAMEID, 'offlineTime')
            if not offline_time:  # 取不到离线时间,取上线时间
                offline_time = userdata.getAttr(uid, 'authorTime')
            if offline_time:
                offline_time = pktimestamp.parseTimeMs(offline_time)
                delta = datetime.now() - offline_time
                delta = delta.days * 24 * 60 + delta.seconds / 60  # 分钟数
            else:  # 异常情况
                delta = 24 * 60
            datas['offline_time'] = delta if delta > 0 else 1
        if rid > 0:
            try:
                room = gdata.roomIdDefineMap().get(rid, None)
                if room:
                    datas['room_name'] = room.configure['name']
            except:
                ftlog.error()
    # 构造回传给SDK的游戏数据
    datas.update({'uid': uid, 'gid': gid, 'rid': rid, 'tid': tid, 'sid': sid, 'state': state})

    if for_level_info:
        datas['level_game_id'] = 0
        datas['level'] = 0
        datas['level_pic'] = ''
        try:
            for gameId in gameIds:
                if gameId not in gdata.games():
                    continue
                dashifen_info = gdata.games()[gameId].getDaShiFen(uid, '')
                if dashifen_info:
                    level = dashifen_info['level']
                    if level > 0 and level > datas['level']:
                        datas['level_game_id'] = gameId
                        datas['level'] = level
                        level_pic = dashifen_info.get('picbig')
                        datas['level_pic'] = level_pic if level_pic else dashifen_info.get('pic')
        except:
            ftlog.error()

    if for_winchip:
        datas['winchip'] = 0
        datas['winchips'] = 0
        try:
            for gameId in gameIds:
                winchips, todaychips = gamedata.getGameAttrs(userId, gameId, ['winchips', 'todaychips'], False)
                winchips = strutil.parseInts(winchips)
                yest_winchip = 0
                todaychips = strutil.loads(todaychips, ignoreException=True)
                if todaychips and 'today' in todaychips and 'chips' in todaychips and 'last' in todaychips:
                    if pktimestamp.formatTimeDayInt() == todaychips['today']:
                        yest_winchip = todaychips['last']
                    elif pktimestamp.formatTimeYesterDayInt() == todaychips['today']:
                        yest_winchip = todaychips['chips']
                datas['winchip'] += yest_winchip
                datas['winchips'] += winchips
        except:
            ftlog.error()
    return datas
    def onCmdQuickStart(cls, msg, userId, gameId, roomId, tableId, clientId,
                        kindId):
        """UT server中处理来自客户端的quick_start请求  
        Args:
            msg
                cmd : quick_start
                if roomId == 0:
                    表示快速开始,服务器为玩家选择房间,然后将请求转给GR
                    
                if roomId > 0 and tableId == 0 : 
                    表示玩家选择了房间,将请求转给GR
                    
                if roomId > 0 and tableId == roomId * 10000 :
                    表示玩家在队列里断线重连,将请求转给GR
                    
                if roomId > 0 and tableId > 0:
                    if onlineSeatId > 0: 
                        表示玩家在牌桌里断线重连,将请求转给GT
                    else:
                        表示玩家选择了桌子,将请求转给GR
        """
        assert isinstance(userId, int) and userId > 0
        assert isinstance(roomId, int) and roomId >= 0
        assert isinstance(tableId, int) and tableId >= 0
        if ftlog.is_debug():
            ftlog.debug("onCmdQuickStart->", userId, "msg =", msg, "roomId =",
                        roomId, "tableId =", tableId, "clientId =", clientId)
        isRobot = userId < config.ROBOT_MAX_USER_ID
        if not isRobot and not util.isUsableClientVersion(userId):
            cls.onQuickStartFailed(cls.ENTER_ROOM_REASON_VERSION_DISABLE,
                                   userId, clientId, roomId)
            return

        # 单开, 无论何时quick_start进入都检查loc
        if not pokerconf.isOpenMoreTable(clientId):
            locList = onlinedata.getOnlineLocList(userId)
            if ftlog.is_debug():
                ftlog.debug("onCmdQuickStart->getOnlineLocList->", userId,
                            locList)
            try:
                for lRoomId, lTableId, lSeatId in locList:
                    roomGameId = strutil.getGameIdFromInstanceRoomId(lRoomId)
                    if roomGameId == FISH_GAMEID:
                        roomId = lRoomId
                        tableId = lTableId
                        ftlog.info(
                            "onCmdQuickStart->reconnect roomId, tableId->",
                            userId, roomId, tableId)
                    else:
                        cls.onQuickStartFailed(
                            cls.ENTER_ROOM_REASON_STATE_ERROR, userId,
                            clientId, roomId)
                        return
                    break
            except:
                ftlog.warn("onCmdQuickStart->error", userId, roomId, tableId)

        redState = gamedata.getGameAttrInt(userId, FISH_GAMEID,
                                           GameData.redState)
        if isRobot is False and redState == 0:
            ctrlRoomId = config.getCommonValueByKey("newbieRoomId")
            chosenTableId = 0
            shadowRoomId = None
            if gdata.getBigRoomId(roomId) == gdata.getBigRoomId(
                    ctrlRoomId) and tableId:
                chosenTableId = tableId
                shadowRoomId = tableId / 10000
            TYRoomMixin.queryRoomQuickStartReq(
                msg, ctrlRoomId, chosenTableId,
                shadowRoomId=shadowRoomId)  # 请求转给GR
            return

        if roomId == 0:  # 玩家点击快速开始
            chosenRoomId, reason = cls._chooseRoom(userId, gameId)
            ftlog.info("onCmdQuickStart->chosenRoomId", chosenRoomId,
                       "userId =", userId, "reason =", reason)
            if reason == cls.ENTER_ROOM_REASON_OK:
                TYRoomMixin.queryRoomQuickStartReq(msg, chosenRoomId,
                                                   0)  # 请求转给GR
            else:
                cls.onQuickStartFailed(reason, userId, clientId, roomId)
            return

        if tableId == 0:  # 玩家只选择了房间
            bigRoomId = gdata.getBigRoomId(roomId)
            if bigRoomId == 0:
                cls.onQuickStartFailed(cls.ENTER_ROOM_REASON_ROOM_ID_ERROR,
                                       userId, clientId, roomId)
                return
            ctrlRoomIds = gdata.bigRoomidsMap()[bigRoomId]
            ctrlRoomId = ctrlRoomIds[userId % len(ctrlRoomIds)]
            reason = cls.canQuickEnterRoom(userId, gameId, ctrlRoomId, kindId)
            if reason == cls.ENTER_ROOM_REASON_OK:
                roomConf = gdata.roomIdDefineMap()[roomId].configure
                fee = roomConf.get("fee_%s" % kindId, {}) or roomConf.get(
                    "fee", {})
                rewards = fee.get("rewards", [])
                if fee:
                    _consume = [{"name": fee["kindId"], "count": fee["count"]}]
                    ret = util.consumeItems(userId, _consume, "ROOM_GAME_FEE")
                    if ret and rewards:
                        util.addRewards(userId, rewards,
                                        "BI_NFISH_VOUCHER_REWARDS", kindId)
                TYRoomMixin.queryRoomQuickStartReq(msg, ctrlRoomId,
                                                   0)  # 请求转给GR或GT
            else:
                cls.onQuickStartFailed(reason, userId, clientId, roomId)
            return

        if tableId == roomId * 10000:  # 玩家在队列里断线重连
            TYRoomMixin.queryRoomQuickStartReq(msg, roomId, tableId)  # 请求转给GR
            return

        onlineSeat = onlinedata.getOnlineLocSeatId(userId, roomId, tableId)

        if onlineSeat:
            TYRoomMixin.querySitReq(userId, roomId, tableId, clientId,
                                    {"seatId": onlineSeat})  # 玩家断线重连,请求转给GT
        else:  # 玩家选择了桌子
            shadowRoomId = tableId / 10000
            ctrlRoomId = gdata.roomIdDefineMap()[shadowRoomId].parentId
            TYRoomMixin.queryRoomQuickStartReq(
                msg, ctrlRoomId, tableId, shadowRoomId=shadowRoomId)  # 请求转给GR