def _doClearPlayers(self): try: if ftlog.is_debug(): ftlog.debug(self._baseLogStr("<<"), "|gameSeq, agreeN:", self.gamePlay.gameSeq, self.agreeN, caller=self) needSendRes = False if self.agreeN == self.cMaxSeatNum: needSendRes = True if self.gamePlay.gameSeq == 0: needSendRes = True TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvents.EV_BEFORE_TABLE_CLEAR_PLAYERS, params={ 'table': self}), self.gameId) # tip = u"您好,此牌桌已解散。" sitUserIds = DiFangPlayersHelper.getSitPlayerIds(self) for userId in sitUserIds: self.sendRoomLeaveReq(userId, TYRoom.LEAVE_ROOM_REASON_SYSTEM, needSendRes=needSendRes) # TodoTaskHelper.sendTodoTask(self.gameId, userId, TodoTaskShowInfo(tip, True)) self.clear() return {"isOK": True} except Exception, e: ftlog.error(e) return {"isOK": False}
def _doClearPlayers(self): try: if ftlog.is_debug(): ftlog.debug(self._baseLogStr("<<"), "|gameSeq, agreeN:", self.gamePlay.gameSeq, self.agreeN, caller=self) needSendRes = False if self.agreeN == self.cMaxSeatNum: needSendRes = True if self.gamePlay.gameSeq == 0: needSendRes = True TYPluginCenter.event( TYPluginUtils.updateMsg( cmd=PluginEvents.EV_BEFORE_TABLE_CLEAR_PLAYERS, params={'table': self}), self.gameId) # tip = u"您好,此牌桌已解散。" sitUserIds = DiFangPlayersHelper.getSitPlayerIds(self) for userId in sitUserIds: self.sendRoomLeaveReq(userId, TYRoom.LEAVE_ROOM_REASON_SYSTEM, needSendRes=needSendRes) # TodoTaskHelper.sendTodoTask(self.gameId, userId, TodoTaskShowInfo(tip, True)) self.clear() return {"isOK": True} except Exception, e: ftlog.error(e) return {"isOK": False}
def getInfo(self): item = {} item["seatId"] = self.seatIndex # 德州客户端 seatId 从0开始 ! item["userId"] = self.userId if self.userId == 0: return item # user信息 if gdata.mode() == gdata.RUN_MODE_ONLINE: item["name"] = self.name else: item["name"] = '%s_%s_%s' % (self.userId, self.seatIndex, self.name) item["purl"] = self.purl item["sex"] = self.sex item["ip"] = sessiondata.getClientIp(self.userId) # 需要实时更新ip数据 # 牌桌筹码信息 item["chips"] = self.tableChips item["state"] = self.state # game信息 # 统计信息 # 手牌信息 # 状态信息 item["managed"] = self.isManaged # 以插件形式来填充palyerInfo数据 TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvents.EV_GET_PLAYER_INFO, params=TYPluginUtils.mkdict( table=self.table, userId=self.userId, player=self, playerInfo=item)), self.table.gameId) return item
def onServerHeartBeat(self): """ 处理 server heart beat, 并发出时间事件 服务器心跳每秒一次, 这个函数会识别时间, 在每分钟、小时、天、星期(周一0:00)、月、年的开始, 发出一个事件 """ now = datetime.now() last = self._now self._now = now newTimePoints = [] if last.minute != now.minute: newTimePoints.append('minute') if last.hour != now.hour: newTimePoints.append('hour') if last.day != now.day: newTimePoints.append('day') if last.weekday() != now.weekday() and now.weekday() == 0: # 周一 newTimePoints.append('week') if last.month != now.month: newTimePoints.append('month') if last.year != now.year: newTimePoints.append('year') if newTimePoints: msg = TYPluginUtils.updateMsg(cmd=PluginEvent.EV_NEW_TIME, params={ 'newTimePoints': newTimePoints, 'now': now, 'last': last}) TYPluginCenter.event(msg, self.gameId())
def __onMatchEnd(self): mconf = self.matchPlugin.match_room_confs[self.bigRoomId] rankinglist = daobase.executeRankCmd("LRANGE", self.matchPlugin.rankingKey(self.bigRoomId), 0, -1) getName = lambda userId: userdata.getAttr(userId, 'name') rankingListWithName = [(i + 1, userId, getName(userId)) for i, userId in enumerate(reversed(rankinglist))] bireport.matchFinish(self.gameId, self.roomId, mconf['start_time'].strftime('%Y-%m-%d_%H:%M:%S_') + str(self.roomId), mconf['name'].replace('\n', ' '), matchTypeId=mconf['match_id'], endTimestamp=time.time(), rewardChip=self.matchCounter['rewardChip'], rewardCoupon=self.matchCounter['rewardCoupon'], rankingList=rankingListWithName, usersLeaveMatchCount=self.matchCounter['usersLeaveMatchCount'], rebuyChip=self.matchCounter['rebuyChip'], addonChip=self.matchCounter['addonChip'], ) # for check MTT gameEnd TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_MATCH_END', params={'room': self}), self.gameId) if ftlog.is_debug(): ftlog.debug("len(self.scheduler.activeTableIds):", len(self.scheduler.activeTableIds), caller=self) # 回收决赛桌和异常牌桌 remainActiveTables = strutil.cloneData(self.scheduler.activeTableIds) for activeTableId in remainActiveTables: self.scheduler._recycleTable(activeTableId) if mconf.get('day1EndConf'): self.matchPlugin.saveDay2Players(self) self.state = self.MTT_STATE_READY
def _doHttpCommonPage(self): ''' 多封装这一层,纯粹是为了 hotfix 维护方便 ''' try: request = runhttp.getRequest() args = request.args if ftlog.is_debug(): ftlog.debug('GambleHttp._doHttpCommonPage << ', args) msg = TYPluginUtils.updateMsg( cmd=PluginEvent.EV_HTTP_COMMON_REQUEST_PAGE, params={ 'httpArgs': args, 'httpRequest': request }, result={ 'httpResult': { 'page': '', 'error': '', }, }) TYPluginCenter.event(msg, self.GAME_ID) error = msg.getResult('error') if error: ftlog.error('GambleHttp._doHttpCommonPage >>| error:', error) return self.errorpage(error) page = msg.getResult('httpResult', {}).get('page') if not page: return self.errorpage('') return page except Exception, e: ftlog.error('HTTPCommon._doHttpCommon: request.args:', args) return self.errorpage(str(e))
def end(self, extParam): '''一局结束''' if ftlog.is_debug(): ftlog.debug("<< |userId=", self.userId, "roomId=", self.table.roomId, " tableId=", self.table.tableId, caller=self) msg = TYPluginUtils.updateMsg(cmd=PluginEvents.EV_PLAYER_GAME_FRAME_END, params=TYPluginUtils.mkdict( table=self.table, player=self, extParam=extParam)) TYPluginCenter.event(msg, self.table.gameId)
def _doSit(self, msg, userId, seatId, clientId): ''' 玩家操作, 尝试在当前的某个座位上坐下 ''' if ftlog.is_debug(): ftlog.info("_doSit << |tableId, userId, seatId:", self.tableId, userId, seatId, caller=self) if ftlog.is_debug(): locList = onlinedata.getOnlineLocList(userId) ftlog.debug(self._baseLogStr("<<", userId), "|locList:", locList, caller=self) result = {"isOK": True, "userId": userId, "gameId": self.gameId, "roomId": self.bigRoomId, "tableId": self.tableId} idleSeatId = self._getValidIdleSeatId(userId, seatId - 1, result) if idleSeatId < 0: # self.room.sendTableClothRes(self.gameId, userId, self.tableType, self.tableTheme) self.sendTableInfoRes(result["seatId"], userId) self._onReSit(userId, -idleSeatId, clientId) return result if idleSeatId == 0: return result # rid, tid, sid = getOnlineLoc(userId, self.gameId) # 为了支持并发坐下,self.getValidIdleSeatId()到此函数执行前,不应该有异步操作 self.onSitOk(userId, idleSeatId, result) # if rid == 0: #旁观坐下时rid!=0 # TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_USER_FIRST_SIT', params={ # 'table': self, 'userId': userId}), self.gameId) player = self.players[idleSeatId - 1] self._playerSit(player) self.sendQuickStartRes(userId, clientId, result) self.sendTableInfoRes(result["seatId"], userId) # 发送 newUser 消息, 客户端通过该协议显示新玩家 mpNewUserRes = self.createMsgPackRes("newUser") playerInfo = player.getInfo() mpNewUserRes.updateResult(playerInfo) self.sendToAllTableUser(mpNewUserRes, exclude=[userId]) # 扩展事件. TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvents.EV_AFTER_SITDOWN, params=TYPluginUtils.mkdict( table=self, userId=userId, player=player)), self.gameId) if ftlog.is_debug(): ftlog.debug(self._baseLogStr(">>", userId), "|locList:", onlinedata.getOnlineLocList(userId), caller=self) ftlog.hinfo("_doSit >> get new seat, |tableId, userId, seatId:", self.tableId, userId, player.seatId, caller=self) return result
def doEnter(self, userId): isOk, reason = self._enter(userId) if isOk: TYPluginCenter.event( TYPluginUtils.updateMsg( cmd='EV_ENTER_ROOM', params=TYPluginUtils.mkdict(userId=userId, roomId=self.roomId)), self.gameId) return isOk, reason
def start(self): '''一局开始''' if ftlog.is_debug(): ftlog.debug("<< |userId=", self.userId, "roomId=", self.table.roomId, " tableId=", self.table.tableId, caller=self) self.setPlaying() msg = TYPluginUtils.updateMsg(cmd=PluginEvents.EV_PLAYER_GAME_FRAME_START, params=TYPluginUtils.mkdict( table=self.table, player=self)) TYPluginCenter.event(msg, self.table.gameId)
def doHandleCommonGameCmdAction(self, userId, gameId, clientId): '''把某个消息转发到 pluginCenter,以便 plugins 能处理 ''' msg = runcmd.getMsgPack() if ftlog.is_debug(): ftlog.debug("<< |userId, gameId, clientId, msg:", userId, gameId, clientId, msg, caller=self) TYPluginCenter.event(msg, gameId)
def sendLevelUpToHallTask(userId, level, now_chip_level): try: level_upgrade = int(level) - int(now_chip_level) if level_upgrade >= 1: params = { "user_id": userId, "count": level_upgrade, } cmd = 'GM_LEVEL_UPGRADE' msg = TYPluginUtils.updateMsg(cmd=cmd, params=params) TYPluginCenter.event(msg, HALL_ID) except Exception as e: ftlog.debug('onEvUserChipExp: levelUpdate to hall, e=', e)
def doHandleCommonRoomCmdAction(self, userId, gameId, roomId, clientId): room = gdata.rooms()[roomId] msg = runcmd.getMsgPack() params = msg.getKey('params') params.update({'room': room}) if ftlog.is_debug(): ftlog.debug("<< |userId, gameId, roomId, clientId, msg:", userId, gameId, roomId, clientId, msg, caller=self) TYPluginCenter.event(msg, gameId) if router.isQuery(): mo = runcmd.newOkMsgPack(1) router.responseQurery(mo)
def doRoomGM(self, roomId): msg = runcmd.getMsgPack() if ftlog.is_debug(): ftlog.info('doRoomGM msg=', msg, caller=self) room = gdata.rooms()[roomId] result = {} params = msg.getKey('params') params.update({'room': room}) evmsg = TYPluginUtils.updateMsg(cmd='EV_ROOM_GM', params=params, result=result) TYPluginCenter.event(evmsg, room.gameId) if router.isQuery(): mo = TYPluginUtils.updateMsg(cmd='room', result=result) router.responseQurery(mo)
def doHandleCommonRoomCmdAction(self, gameId, roomId, userId, clientId): msg = runcmd.getMsgPack() room = gdata.rooms()[roomId] tableId = msg.getParam("tableId") if tableId: table = room.maptable[tableId] else: table = None params = msg.getKey('params') params.update({'room': room, 'table': table}) if ftlog.is_debug(): ftlog.debug("<< |userId, gameId, roomId, tableId, clientId, msg:", userId, gameId, roomId, clientId, msg, caller=self) TYPluginCenter.event(msg, gameId)
def _doTableCall(self, msg, userId, seatId, action, clientId): ''' 桌子内部处理所有的table_call命令 具体处理函数自行判定userId和seatId是否吻合 Notes: 客户端seatId是从0开始计数的, 对应于服务端的seatIndex CL_FUNC_X 是指服务期内部通过callLater技术发送的延迟处理命令 ''' seatIndex = seatId func = msg.getParam("func") if action != "CL_FUNC": ftlog.info("handleMsg << receive tableCall, |clientId, userId, action:", clientId, userId, action, "|tableId, seatIndex", self.tableId, seatIndex, caller=self) else: ftlog.debug("<< |clientId, userId, action:", clientId, userId, action, "|tableId, seatIndex", self.tableId, seatIndex, "|funName:", func.func.func_name, caller=self) # --------------------- # 内部服务延迟调用函数, 无需验证用户(userId为-1) # --------------------- if action == "CL_FUNC": func() return # --------------------- # 玩家请求、需要验证 # --------------------- if userId <= 0: ftlog.error("userId is invalid") return # ------------------------- # 玩家游戏操作 # ------------------------- self._processTableCallAction(action, userId, seatIndex, clientId, msg) msg.getKey("params").update({"table": self}) TYPluginCenter.event(msg, self.gameId)
def doTableGM(self, gameId, roomId, tableId): msg = runcmd.getMsgPack() if ftlog.is_debug(): ftlog.info('doTableGM msg=', msg, caller=self) room = gdata.rooms()[roomId] table = room.maptable[tableId] result = {} params = msg.getKey('params') params.update({'room': room, 'table': table}) evmsg = TYPluginUtils.updateMsg(cmd="EV_TABLE_GM", params=params, result=result) TYPluginCenter.event(msg, room.gameId) if router.isQuery(): mo = TYPluginUtils.updateMsg(cmd='table', result=result) router.responseQurery(mo)
def doQuickStart(self, msg): assert self.roomId == msg.getParam("roomId") userId = msg.getParam("userId") shadowRoomId = msg.getParam("shadowRoomId") tableId = msg.getParam("tableId") clientId = msg.getParam("clientId") ftlog.hinfo("doQuickStart <<", "|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) msg = TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_QUICK_START', params=TYPluginUtils.mkdict( userId=userId, roomId=self.roomId), result={}), self.gameId) if msg.getResult("reason") != None: info = u'玩家需要验证' self.sendQuickStartRes(self.gameId, userId, msg.getResult("reason"), self.bigRoomId, 0, info) return if tableId == 0: isOk, reason = self.doEnter(userId) elif tableId == self.roomId * 10000: if userId in self._roomUsers: isOk = True # 玩家在队列里时断线重连 reason = TYRoom.ENTER_ROOM_REASON_OK else: # 服务器重启造成玩家已经不在房间对象里了 onlinedata.removeOnlineLoc(userId, self.roomId, tableId) isOk = False reason = TYRoom.ENTER_ROOM_REASON_CONFLICT else: # 防御性代码,处理快速开始online错乱 onlineSeat = onlinedata.getOnlineLocSeatId(userId, shadowRoomId, tableId) if onlineSeat == 0: # 断线重连过程中玩家因为超时、金币不足或比赛淘汰等原因已被踢出房间 isOk = False reason = TYRoom.ENTER_ROOM_REASON_CONFLICT ftlog.warn("doQuickStart conflict!", "|userId, onlineLocList:", userId, onlinedata.getOnlineLocList(userId), "|shadowRoomId, tableId:", shadowRoomId, tableId) else: ftlog.error("doQuickStart conflict!", "|onlineSeat:", onlineSeat) if onlineSeat == gdata.roomIdDefineMap()[shadowRoomId].configure['tableConf']['maxSeatN'] + 1: # 牌桌里旁观的玩家断线重连,请求转给GT self.sendTableCallObserveReq(userId, shadowRoomId, tableId, clientId) elif onlineSeat > 0: # 牌桌里坐着的玩家断线重连,请求转给GT self.querySitReq(userId, shadowRoomId, tableId, clientId) return if isOk: self._onQuickStartOk(userId) elif reason == TYRoom.ENTER_ROOM_REASON_CONFLICT: info = u'玩家已经在游戏中,状态冲突' self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, 0, info) else: self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, 0, '')
def __init__(self, room, tableId): super(DiFangTable, self).__init__(room, tableId) self.table = self # 为了和 gamePlay 里调用table属性和方法的代码保持一致 # 初始化牌桌配置、类型、座位、玩家等 self._resetTableConf() self._initTableType() self._initSeatsAndPlayers() # 初始化桌子计时器 self.tableTimer = TYTableTimer(self) # 实例化玩法逻辑处理 self.gamePlay = self.GamePlaysFactory.getInstance(self, room.roomConf.get("playMode", "classic")) # 初始化桌子全量配置 self.clear() # 清理遗留的代入金币 # self.cleanUpLastUserTableChips() TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvents.EV_AFTER_TABLE_CHILD_INIT, params={ 'table': self, 'tableType': self.tableType}), self.gameId) if ftlog.is_debug(): ftlog.info("__init__ >> |tableId:", self.tableId, caller=self)
def _doHttpCommon(self): ''' 多封装这一层,纯粹是为了 hotfix 维护方便 ''' try: request = runhttp.getRequest() args = request.args if ftlog.is_debug(): ftlog.debug('<<', args, caller=self) msg = TYPluginUtils.updateMsg(cmd='EV_HTTP_COMMON_REQUEST', params={ 'httpArgs': args, 'httpRequest': request }, result={'httpResult': {}}) TYPluginCenter.event(msg, self.GAME_ID) httpResult = msg.getResult('httpResult') if ftlog.is_debug(): ftlog.debug('>>', httpResult, caller=self) if not httpResult: httpResult = {'error': 'NotImplement'} return self.makeResponse(httpResult) except Exception, e: ftlog.error('HTTPCommon._doHttpCommon: request.args:', args) return self.makeErrorResponse(str(e), u'有异常')
def loginGame(self, userId, gameId, clientId, iscreate, isdayfirst): ''' 用户登录一个游戏, 游戏自己做一些其他的业务或数据处理 例如: 1. IOS大厅不发启动资金的补丁, 2. 麻将的记录首次登录时间 3. 游戏插件道具合并至大厅道具 ''' ftlog.hinfo('loginGame <<|userId=', userId, 'gameId=', gameId, 'clientId=', clientId, 'isdayfirst=', isdayfirst, caller=self) self.AccountClass.loginGame(userId, gameId, clientId, iscreate, isdayfirst) # 获取前端代码版本号。以这个版本号判断前端功能 # msg = runcmd.getMsgPack() # codeVer = msg.getParam('v', 0) # gamedata.setGameAttr(userId, gameId, 'codeVer', codeVer) TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_USER_LOGIN', params={ 'userId': userId, 'isCreate': iscreate, 'clientId': clientId, 'dayFirst': isdayfirst, # 'codeVer': codeVer, }), gameId)
def doLeave(self, userId, msg): ftlog.hinfo("doLeave |userId, msg:", userId, msg, caller=self) reason = msg.getParam("reason", TYRoom.LEAVE_ROOM_REASON_ACTIVE) assert isinstance(reason, int) needSendRes = msg.getParam("needSendRes", True) assert isinstance(needSendRes, bool) clientRoomId = msg.getParam("clientRoomId", self.roomId) assert isinstance(clientRoomId, int) if not self._leave(userId, reason, needSendRes): reason = TYRoom.LEAVE_ROOM_REASON_FORBIT TYPluginCenter.event( TYPluginUtils.updateMsg(cmd='EV_LEAVE_ROOM', params=TYPluginUtils.mkdict( userId=userId, roomId=self.roomId, reason=reason)), self.gameId) msgRes = MsgPack() if not pokerconf.isOpenMoreTable(sessiondata.getClientId(userId)): msgRes.setCmd("room_leave") else: msgRes.setCmd("room") msgRes.setResult("action", "leave") msgRes.setResult("reason", reason) msgRes.setResult("gameId", self.gameId) msgRes.setResult( "roomId", clientRoomId) # 处理结果返回给客户端时,部分游戏(例如德州、三顺)需要判断返回的roomId是否与本地一致 msgRes.setResult("userId", userId) if needSendRes or TYPlayer.isRobot(userId): # 需要通知机器人stop router.sendToUser(msgRes, userId)
def __sendFinalTableInfo(self, finalTableStartTime): waitingUserIds = self.scheduler.users.keys() # 防止处理过程中users变化导致数据不一致 waitingUserN = len(waitingUserIds) if ftlog.is_debug(): ftlog.debug("<< |roomId:", self.roomId, "|waitingUserN:", waitingUserN) mpToClient = MsgPack() mpToClient.setCmd("final_table_info") mpToClient.setResult('gameId', self.gameId) mpToClient.setResult('roomId', self.bigRoomId) mpToClient.setResult('finalTableStartTime', time.mktime(finalTableStartTime.timetuple())) mpToClient.setResult('nowServerTime', int(time.time())) playerInfos = [] for seatId, userId in enumerate(waitingUserIds): name = userdata.getAttr(userId, 'name') playerRoomInfo = PlayerRoomDao.getPlayerRoomRecord(userId, self.bigRoomId) if ftlog.is_debug(): ftlog.debug("get playerRoomInfo |userId, tableId:", userId, self.roomId, playerRoomInfo, caller=self) item = {} item["userId"] = userId item["seatId"] = seatId item["tableChip"] = playerRoomInfo["tableChips"] item["name"] = name playerInfos.append(item) mpToClient.setResult("players", playerInfos) router.sendToUsers(mpToClient, waitingUserIds) self.matchPlugin.refreshBuyin(self) # Send final table information to monitor_mtt.py TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_MTT_FINAL_TABLE', params={ 'roomId': self.roomId}), self.gameId)
def _getVipTableList(self, userId, clientId, tag="", isMasterRoom=False, isLiveShowRoom=False): '''获取vip房间和游轮赛房间的桌子列表''' roomList = [] vip_tableList = [] chip = userchip.getChip(userId) if ftlog.is_debug(): ftlog.debug("|roomIds:", gdata.rooms().keys(), caller=self) for room in gdata.rooms().values(): if not isinstance(room, TYVipRoom): continue ftlog.debug("|roomId:", room.roomId, caller=self) if not room.roomConf.get('visible', True): if ftlog.is_debug(): ftlog.debug("not visible", caller=self) continue if isMasterRoom != bool(room.roomConf.get("isMasterRoom")): if ftlog.is_debug(): ftlog.debug("isMasterRoom not match", caller=self) continue if isLiveShowRoom != bool(room.roomConf.get("isLiveShowRoom")): if ftlog.is_debug(): ftlog.debug("isLiveShowRoom not match", caller=self) continue if tag != room.roomConf.get("tag", ""): if ftlog.is_debug(): ftlog.debug("tag not match", caller=self) continue roomSortId = room.roomConf.get("sortId", 0) roomIndex = room.bigRoomId % 1000 if roomSortId > 0 and roomSortId < 1000: if chip >= self.VIP_ROOM_LIST_REVERSE_CHIPS: roomSortId = roomIndex else: roomSortId = 1000 - roomIndex roomInfo = {"roomId": room.bigRoomId, "roomSortId": roomSortId} roomList.append(roomInfo) if ftlog.is_debug(): ftlog.debug("|roomId, secretConf:", room.roomId, room.roomConf.get("secretConf"), caller=self) if room.isSecretRoom(): if len(self.maptable) < 1: continue table = room.maptable.values()[0] if not table.checkSecretCondition(userId, clientId): continue tableinfo = {} tableinfo["maxPlayerNum"] = table.maxSeatN tableinfo["playerNum"] = 0 tableinfo["tableId"] = 0 tableinfo["roomId"] = room.roomId tableinfo["type"] = room.roomConf["typeName"] tableinfo["sortId"] = room.roomConf.get("sortId", 0) tableinfo["isSecrect"] = True table.updateTableListInfo(tableinfo, clientId) vip_tableList.append(tableinfo) continue if not room._activeTables: room._initActiveTables() for tableId, table in room.sortedActiveTablesWithId(): tableinfo = {} tableinfo["maxPlayerNum"] = table.maxSeatN tableinfo["playerNum"] = table.playersNum tableinfo["tableId"] = tableId tableinfo["roomId"] = table.room.roomId tableinfo["type"] = table.room.roomConf["typeName"] tableinfo["sortId"] = table.room.roomConf.get("sortId", 0) tableinfo["listBG"] = room.roomConf.get("listBG", "normal") table.updateTableListInfo(tableinfo, clientId) if self.isLiveShowRoom() and not tableinfo.get("creatorId"): continue vip_tableList.append(tableinfo) # def tableListComparer(x, y): # if x["playerNum"] == x["maxPlayerNum"] : # if y["playerNum"] == y["maxPlayerNum"] : # return y["sortId"] - x["sortId"] # else : # return 1 # # if y["playerNum"] == y["maxPlayerNum"] : # return -1 # # return x["sortId"] - y["sortId"] # vip_tableList = sorted(vip_tableList, cmp=lambda x, y : tableListComparer(x, y)) TYPluginCenter.event( TYPluginUtils.updateMsg(cmd='EV_GET_VIP_TABLE_LIST', params={ 'table': self, 'vip_tableList': vip_tableList }), self.gameId) for t in vip_tableList: del t['sortId'] results = {"gameId": self.gameId} results['tables'] = vip_tableList results['roomList'] = roomList return results
def doQuickStart(self, msg): assert self.roomId == msg.getParam("roomId") userId = msg.getParam("userId") shadowRoomId = msg.getParam("shadowRoomId") tableId = msg.getParam("tableId") clientId = msg.getParam("clientId") ftlog.hinfo("doQuickStart <<", "|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) msg = TYPluginCenter.event( TYPluginUtils.updateMsg(cmd='EV_QUICK_START', params=TYPluginUtils.mkdict( userId=userId, roomId=self.roomId), result={}), self.gameId) if msg.getResult("reason") != None: info = u'玩家需要验证' self.sendQuickStartRes(self.gameId, userId, msg.getResult("reason"), self.bigRoomId, 0, info) return if tableId == 0: isOk, reason = self.doEnter(userId) elif tableId == self.roomId * 10000: if userId in self._roomUsers: isOk = True # 玩家在队列里时断线重连 reason = TYRoom.ENTER_ROOM_REASON_OK else: # 服务器重启造成玩家已经不在房间对象里了 onlinedata.removeOnlineLoc(userId, self.roomId, tableId) isOk = False reason = TYRoom.ENTER_ROOM_REASON_CONFLICT else: # 防御性代码,处理快速开始online错乱 onlineSeat = onlinedata.getOnlineLocSeatId(userId, shadowRoomId, tableId) if onlineSeat == 0: # 断线重连过程中玩家因为超时、金币不足或比赛淘汰等原因已被踢出房间 isOk = False reason = TYRoom.ENTER_ROOM_REASON_CONFLICT ftlog.warn("doQuickStart conflict!", "|userId, onlineLocList:", userId, onlinedata.getOnlineLocList(userId), "|shadowRoomId, tableId:", shadowRoomId, tableId) else: ftlog.error("doQuickStart conflict!", "|onlineSeat:", onlineSeat) if onlineSeat == gdata.roomIdDefineMap( )[shadowRoomId].configure['tableConf']['maxSeatN'] + 1: # 牌桌里旁观的玩家断线重连,请求转给GT self.sendTableCallObserveReq(userId, shadowRoomId, tableId, clientId) elif onlineSeat > 0: # 牌桌里坐着的玩家断线重连,请求转给GT self.querySitReq(userId, shadowRoomId, tableId, clientId) return if isOk: self._onQuickStartOk(userId) elif reason == TYRoom.ENTER_ROOM_REASON_CONFLICT: info = u'玩家已经在游戏中,状态冲突' self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, 0, info) else: self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, 0, '')
def __leaveMatch(self, userId, tableId=0, needSendRewardTodoTask=True): playingLen, rankingLen, enterMatchTotal, isSuccess = daobase.executeRankCmd("EVALSHA", self.userLeaveLuaSha, 0, userId) ftlog.hinfo("__leaveMatch remove user from playingRanking", "|roomId, userId, state", self.roomId, userId, self.getStateStr(), "|playingLen, rankingLen, enterMatchTotal, isSuccess", playingLen, rankingLen, enterMatchTotal, isSuccess, "|tableId, needSendRewardTodoTask", tableId, needSendRewardTodoTask, caller=self) # isSuccess 表示成功从 ranking 中删除。加这个检查是为了避免玩家被动离开的同时主动离开,导致二次发奖 if not isSuccess: return if playingLen + rankingLen != enterMatchTotal: ftlog.error(getMethodName(), "playingLen + rankingLen != enterMatchTotal", "|roomId, playingLen, rankingLen:", self.roomId, playingLen, rankingLen, "|enterMatchTotal:", enterMatchTotal) ftlog.hinfo("__leaveMatch |roomId, playingLen, rankingLen:", self.roomId, enterMatchTotal - rankingLen, rankingLen, caller=self) playingLen = enterMatchTotal - rankingLen if ftlog.is_debug(): ftlog.debug("|roomId, playingLen:", self.roomId, playingLen, caller=self) func = functools.partial(self.ranking.sendToAll) FTTimer(1, func) if playingLen < 1: # 第一名离桌 return # 奖励2到n名 rankingOrder = playingLen + 1 self.matchPlugin.rewardWinner(None, self, userId, rankingOrder, self.matchPlugin.rankingKey(self.bigRoomId), self.matchCounter, tableId, needSendRewardTodoTask) TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_USER_MATCH_END', params={ 'userId': userId, 'room': self, 'rankingOrder': rankingOrder}), self.gameId) mconf = self.matchPlugin.match_room_confs[self.bigRoomId] day1EndConf = mconf.get('day1EndConf') if day1EndConf: endPlayerN = day1EndConf.get("endPlayerN", 1) if (self.state == self.MTT_STATE_QUALIFIER and playingLen <= endPlayerN and mconf['betConfIndex'] >= mconf.get("delaySigninBlindBetPoint", 0)): self.state = self.MTT_STATE_DAY1_END ftlog.hinfo("__leaveMatch turn to MTT_STATE_DAY1_END |roomId, playingLen, state:", self.roomId, playingLen, self.getStateStr(), caller=self) self.scheduler.cancelLoop() self.matchPlugin.notifyDay1MatchEndWithPlayerN(self) else: if self.state == self.MTT_STATE_QUALIFIER and playingLen <= self.tableConf["maxSeatN"]: self.state = self.MTT_STATE_PREFINALS ftlog.hinfo("__leaveMatch turn to MTT_STATE_PREFINALS |roomId, playingLen, state:", self.roomId, playingLen, self.getStateStr(), caller=self) self.scheduler.cancelLoop() if playingLen > 1: return # 奖励第一名 userId = daobase.executeRankCmd("ZRANGE", self.matchPlugin.playingRankingKey(self.bigRoomId), -1, -1)[0] daobase.executeRankCmd("EVALSHA", self.userLeaveLuaSha, 0, userId) # 要让第一名leave,否则拆桌时会被加回队列,如果玩家强退并等到loc清除后上线,就会导致下一场比赛人数多出1人 func = functools.partial(self._leave, userId, TYRoom.LEAVE_ROOM_REASON_MATCH_END, needSendRes=False) FTTimer(0, func) # 异步执行,否则GT会死锁 ftlog.hinfo("__leaveMatch remove user from playingRanking,", "|roomId, userId", self.roomId, userId, caller=self) rankingOrder = 1 self.matchPlugin.rewardWinner(None, self, userId, rankingOrder, self.matchPlugin.rankingKey(self.bigRoomId), self.matchCounter, tableId=0) TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_USER_MATCH_END', params={ 'userId': userId, 'room': self, 'rankingOrder': rankingOrder}), self.gameId) self.state = self.MTT_STATE_IDLE func2 = functools.partial(self.__onMatchEnd) FTTimer(0, func2) # 异步执行,否则GT会死锁
def _getVipTableList(self, userId, clientId, tag="", isMasterRoom=False, isLiveShowRoom=False): '''获取vip房间和游轮赛房间的桌子列表''' roomList = [] vip_tableList = [] chip = userchip.getChip(userId) if ftlog.is_debug(): ftlog.debug("|roomIds:", gdata.rooms().keys(), caller=self) for room in gdata.rooms().values(): if not isinstance(room, TYVipRoom): continue ftlog.debug("|roomId:", room.roomId, caller=self) if not room.roomConf.get('visible', True): if ftlog.is_debug(): ftlog.debug("not visible", caller=self) continue if isMasterRoom != bool(room.roomConf.get("isMasterRoom")): if ftlog.is_debug(): ftlog.debug("isMasterRoom not match", caller=self) continue if isLiveShowRoom != bool(room.roomConf.get("isLiveShowRoom")): if ftlog.is_debug(): ftlog.debug("isLiveShowRoom not match", caller=self) continue if tag != room.roomConf.get("tag", ""): if ftlog.is_debug(): ftlog.debug("tag not match", caller=self) continue roomSortId = room.roomConf.get("sortId", 0) roomIndex = room.bigRoomId % 1000 if roomSortId > 0 and roomSortId < 1000: if chip >= self.VIP_ROOM_LIST_REVERSE_CHIPS: roomSortId = roomIndex else: roomSortId = 1000 - roomIndex roomInfo = {"roomId": room.bigRoomId, "roomSortId": roomSortId} roomList.append(roomInfo) if ftlog.is_debug(): ftlog.debug("|roomId, secretConf:", room.roomId, room.roomConf.get("secretConf"), caller=self) if room.isSecretRoom(): if len(self.maptable) < 1: continue table = room.maptable.values()[0] if not table.checkSecretCondition(userId, clientId): continue tableinfo = {} tableinfo["maxPlayerNum"] = table.maxSeatN tableinfo["playerNum"] = 0 tableinfo["tableId"] = 0 tableinfo["roomId"] = room.roomId tableinfo["type"] = room.roomConf["typeName"] tableinfo["sortId"] = room.roomConf.get("sortId", 0) tableinfo["isSecrect"] = True table.updateTableListInfo(tableinfo, clientId) vip_tableList.append(tableinfo) continue if not room._activeTables: room._initActiveTables() for tableId, table in room.sortedActiveTablesWithId(): tableinfo = {} tableinfo["maxPlayerNum"] = table.maxSeatN tableinfo["playerNum"] = table.playersNum tableinfo["tableId"] = tableId tableinfo["roomId"] = table.room.roomId tableinfo["type"] = table.room.roomConf["typeName"] tableinfo["sortId"] = table.room.roomConf.get("sortId", 0) tableinfo["listBG"] = room.roomConf.get("listBG", "normal") table.updateTableListInfo(tableinfo, clientId) if self.isLiveShowRoom() and not tableinfo.get("creatorId"): continue vip_tableList.append(tableinfo) # def tableListComparer(x, y): # if x["playerNum"] == x["maxPlayerNum"] : # if y["playerNum"] == y["maxPlayerNum"] : # return y["sortId"] - x["sortId"] # else : # return 1 # # if y["playerNum"] == y["maxPlayerNum"] : # return -1 # # return x["sortId"] - y["sortId"] # vip_tableList = sorted(vip_tableList, cmp=lambda x, y : tableListComparer(x, y)) TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_GET_VIP_TABLE_LIST', params={ 'table': self, 'vip_tableList': vip_tableList}), self.gameId) for t in vip_tableList: del t['sortId'] results = {"gameId": self.gameId} results['tables'] = vip_tableList results['roomList'] = roomList return results
def onReloadConfig(self, event): TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvent.EV_RELOAD_CONFIG, params={ 'keylist': event.keylist}), self.gameId())
def onEventHeartBeat(self, event): self.onServerHeartBeat() TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvent.EV_SERVER_HEART_BEAT, params={ 'event': event}), self.gameId())