def sendToUser(self, userId): # 针对day2比赛: # day1结束后,没有通知day2 build榜的机制,所以这里在玩家获取榜的时候build一次 if self.room.isDay2Match(): self.__buildRankData() # if not self.canSend(): # return # 加个检查,防止极特殊情况下,前端在开赛前请求榜导致异常 if not self.rankResultsForSend: return userRank = self.userRanking.get(userId, -1) # if userRank < 0: # return # clientVer = sessiondata.getClientIdVer(userId) # if TyContext.ClientUtils.isWinPcClient(user.clientId) or user.clientVer < 3.6: # if clientVer < 3.6: # self.rankResultsForSend['pos'] = userRank + 1 # TYPluginUtils.sendMessage(self.gameId, userId, 'matchRank', self.rankResultsForSend, logInfo=False) # else: if userRank >= 0: self.rankResultsForSend_3_6['pos'] = userRank + 1 self.rankResultsForSend_3_6['ranks'][0].update(self.ranks[userRank]) TYPluginUtils.sendMessage(self.gameId, userId, 'matchRank', self.rankResultsForSend_3_6, logInfo=False) else: self.rankResultsForSend['pos'] = userRank + 1 TYPluginUtils.sendMessage(self.gameId, userId, 'matchRank', self.rankResultsForSend, logInfo=False)
def doGetRankList(self, userId, msg): results = {} self.matchPlugin.checkMatchStartTime(self.bigRoomId) self.matchPlugin.getRankList(self.gameId, userId, self.bigRoomId, results) TYPluginUtils.sendMessage(self.gameId, [userId], 'linerMatchRank', results)
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 doGetDescription(self, userId): if ftlog.is_debug(): ftlog.debug("<<", "|userId, roomId:", userId, self.roomId, caller=self) match_desc = {} self.matchPlugin.getMatchDes(userId, self.bigRoomId, match_desc) TYPluginUtils.sendMessage(self.gameId, [userId], 'm_des', result={'roomId': self.bigRoomId, 'm_type': self.roomConf['typeName'], 'desc': match_desc}) rooms = [{"desc": self.matchConf["signinDesc"], "roomId": self.bigRoomId}] TYPluginUtils.sendMessage(self.gameId, [userId], 'm_rooms', result={'rooms': rooms, 'selected': self.bigRoomId})
def doGetDescription(self, userId): ftlog.debug("<<", "|userId, roomId:", userId, self.roomId, caller=self) match_desc = {} self.matchPlugin.checkMatchStartTime(self.bigRoomId) self.matchPlugin.getMatchDes(userId, self.bigRoomId, match_desc) # 每次取m_des的时候 取一次服务器当前的时间 match_desc.update({'nowServerTime': int(time.time())}) TYPluginUtils.sendMessage(self.gameId, [userId], 'm_des', result={ 'roomId': self.bigRoomId, 'm_type': self.roomConf['typeName'], 'desc': match_desc })
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 _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 getGameInfo(cls, userId, gameId, clientId): ''' 获取 gamedta,用来在 bind_game/user_info中返回给前端 ''' if ftlog.is_debug(): ftlog.debug('<<|gameId, userId, clientId:', gameId, userId, clientId, caller=cls) # matchScores = None # if gdata.games()[gameId].RANKING_ID_MTT: # matchScores = hallranking.rankingSystem.getRankingUser(gdata.games()[gameId].RANKING_ID_MTT, userId).score # if matchScores == None: # matchScores = 0 # gameData = { # 'headUrl': userdata.getAttr(userId, 'purl'), # 'gameTime': 0, #TODO: # 'matchScores': matchScores, } # keys = ['photo', 'lastlogin', 'winChips', 'loginsum'] # values = gamedata.getGameAttrs(userId, gameId, ['photo', 'lastlogin', 'accwinchips', 'loginsum']) # gameData.update(dict(zip(keys, values))) # cls.addGameData(userId, gameId, clientId, gameData) plugin.TYPluginCenter.event(TYPluginUtils.updateMsg(cmd='EV_GET_GAME_DATA', params={'userId': userId, 'gamedata': gameData}), gameId) if ftlog.is_debug(): ftlog.debug('>>|gameId, userId, clientId, gdata:', gameId, userId, clientId, gameData, caller=cls) return gameData
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 _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 __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 _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 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 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 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 _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 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 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 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 doGetDescription(self, userId): if ftlog.is_debug(): ftlog.debug("<<", "|userId, roomId:", userId, self.roomId, caller=self) if self.state == self.MTT_STATE_START: return match_desc = {} self.matchPlugin.getMatchDes(userId, self.bigRoomId, match_desc) # day1比赛显示day2比赛的奖励 mconf = self.matchPlugin.match_room_confs[self.bigRoomId] day1EndConf = mconf.get('day1EndConf') if day1EndConf: day2BigRoomId = day1EndConf["day2BigRoomId"] match_desc['rank'] = self.matchPlugin.mdes[day2BigRoomId]['rank'] TYPluginUtils.sendMessage(self.gameId, [userId], 'm_des', result={'roomId': self.bigRoomId, 'm_type': self.roomConf['typeName'], 'desc': match_desc})
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 sendToUser(self, userId): # 针对day2比赛: # day1结束后,没有通知day2 build榜的机制,所以这里在玩家获取榜的时候build一次 if self.room.isDay2Match(): self.__buildRankData() # if not self.canSend(): # return # 加个检查,防止极特殊情况下,前端在开赛前请求榜导致异常 if not self.rankResultsForSend: return userRank = self.userRanking.get(userId, -1) # if userRank < 0: # return # clientVer = sessiondata.getClientIdVer(userId) # if TyContext.ClientUtils.isWinPcClient(user.clientId) or user.clientVer < 3.6: # if clientVer < 3.6: # self.rankResultsForSend['pos'] = userRank + 1 # TYPluginUtils.sendMessage(self.gameId, userId, 'matchRank', self.rankResultsForSend, logInfo=False) # else: if userRank >= 0: self.rankResultsForSend_3_6['pos'] = userRank + 1 self.rankResultsForSend_3_6['ranks'][0].update( self.ranks[userRank]) TYPluginUtils.sendMessage(self.gameId, userId, 'matchRank', self.rankResultsForSend_3_6, logInfo=False) else: self.rankResultsForSend['pos'] = userRank + 1 TYPluginUtils.sendMessage(self.gameId, userId, 'matchRank', self.rankResultsForSend, logInfo=False)
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 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 getGameInfo(cls, userId, gameId, clientId): ''' 获取 gamedta,用来在 bind_game/user_info中返回给前端 ''' if ftlog.is_debug(): ftlog.debug('<<|gameId, userId, clientId:', gameId, userId, clientId, caller=cls) # matchScores = None # if gdata.games()[gameId].RANKING_ID_MTT: # matchScores = hallranking.rankingSystem.getRankingUser(gdata.games()[gameId].RANKING_ID_MTT, userId).score # if matchScores == None: # matchScores = 0 # gameData = { # 'headUrl': userdata.getAttr(userId, 'purl'), # 'gameTime': 0, #TODO: # 'matchScores': matchScores, } # keys = ['photo', 'lastlogin', 'winChips', 'loginsum'] # values = gamedata.getGameAttrs(userId, gameId, ['photo', 'lastlogin', 'accwinchips', 'loginsum']) # gameData.update(dict(zip(keys, values))) # cls.addGameData(userId, gameId, clientId, gameData) plugin.TYPluginCenter.event( TYPluginUtils.updateMsg(cmd='EV_GET_GAME_DATA', params={ 'userId': userId, 'gamedata': gameData }), gameId) if ftlog.is_debug(): ftlog.debug('>>|gameId, userId, clientId, gdata:', gameId, userId, clientId, gameData, caller=cls) return gameData
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 __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 __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 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 onEventHeartBeat(self, event): self.onServerHeartBeat() TYPluginCenter.event(TYPluginUtils.updateMsg(cmd=PluginEvent.EV_SERVER_HEART_BEAT, params={ 'event': event}), self.gameId())
def doGetRankList(self, userId, msg): tableId = msg.getParam("tableId") table = self.maptable[tableId] results = self.matchPlugin.getRankList(userId, self.roomId, table) TYPluginUtils.sendMessage(self.gameId, [userId], 'matchRank', results)
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