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.info(getMethodName(), "<<", "|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) if tableId == self.roomId * 10000: isOk = True # 玩家在队列里时断线重连 player = self.match.findPlayer(userId) if player is None or not player.group: # if player is None or not player.group: ftlog.warn(getMethodName(), '|room=', self.roomId, 'userId=', userId, 'not found player') onlinedata.removeOnlineLoc(userId, self.roomId, tableId) isOk = False else: isOk = False if isOk: reason = self.ENTER_ROOM_REASON_OK self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, self.match.tableId) # 如果用户已经被分组则发送等待信息 if player.group: self.match.playerNotifier.notifyMatchWait(player, player.group) else: reason = self.ENTER_ROOM_REASON_INNER_ERROR info = u'在线状态错误或其他系统内部错误' self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, 0, info)
def doQuickStart(self, msg): ''' Note: 1> 由于不同游戏评分机制不同,例如德州会根据游戏阶段评分,所以把桌子评分存到redis里,方便各游戏服务器自由刷新。 2> 为了防止同一张桌子同时被选出来分配座位,选桌时会把tableScore里选出的桌子删除,玩家坐下成功后再添加回去,添回去之前无需刷新该桌子的评分。 3> 玩家自选桌时,可能选中一张正在分配座位的桌子,此时需要休眠后重试,只到该桌子完成分配或者等待超时。 ''' assert self.roomId == msg.getParam("roomId") userId = msg.getParam("userId") shadowRoomId = msg.getParam("shadowRoomId") tableId = msg.getParam("tableId") exceptTableId = msg.getParam('exceptTableId') clientId = msg.getParam("clientId") ftlog.hinfo(getMethodName(), "<<", "|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) if tableId == 0: # 服务器为玩家选择桌子并坐下 shadowRoomId = choice(self.roomDefine.shadowRoomIds) tableId = self.getBestTableId(userId, shadowRoomId, exceptTableId) else: # 玩家自选桌子坐下 assert isinstance(shadowRoomId, int) and gdata.roomIdDefineMap()[ shadowRoomId].bigRoomId == self.roomDefine.bigRoomId tableId = self.enterOneTable(userId, shadowRoomId, tableId) if not tableId: ftlog.error(getMethodName(), "getFreeTableId timeout", "|userId, roomId, tableId:", userId, self.roomId, tableId) return if ftlog.is_debug(): ftlog.info(getMethodName(), "after choose table", "|userId, shadowRoomId, tableId:", userId, shadowRoomId, tableId) extParams = msg.getKey('params') self.querySitReq(userId, shadowRoomId, tableId, clientId, extParams)
def doShutDown(self): ftlog.debug(getMethodName(), '<<', "|roomId:", self.roomId) for table in self.maptable.values(): table.doShutDown() if ftlog.is_debug(): ftlog.debug(getMethodName(), '>>', "|roomId:", self.roomId) self._doShutDown() self.runStatus = TYRoom.ROOM_STATUS_SHUTDOWN_DONE
def testLockedDecorator(self): print getMethodName() self.assertEqual(133, self.room.syncChooseTableAndSit(123)) print "=" * 30 with self.assertRaises(TypeError): self.room.syncChooseTableAndSit("123")
def testLockedDecorator(self): print getMethodName() self.assertEqual(133, self.room.syncChooseTableAndSit(123)) print "=" * 30 with self.assertRaises(TypeError) : self.room.syncChooseTableAndSit("123")
def doReloadConf(self, roomDefine): if ftlog.is_debug(): ftlog.info(getMethodName(), '<<', "|roomDefine.configure:", roomDefine.configure) self.__define = roomDefine for table in self.maptable.values(): table.doReloadConf(self.tableConf) if ftlog.is_debug(): ftlog.debug(getMethodName(), '>>', "|roomId:", self.roomId)
def dispatchQuickStart(cls, msg, userId, gameId, roomId, tableId, playMode, clientId): clientVersion = 4.0 if clientVersion >= 4.0: return MajiangQuickStartV4_0.onCmdQuickStart( msg, userId, gameId, roomId, tableId, playMode, clientId) ftlog.error(getMethodName(), "unsupported client:", clientVersion)
def enter(self, userId): '''玩家进入队列''' if self.users.get(userId) != None: ftlog.error(getMethodName(), "already in queue!", self.baseLogStr(None, userId)) return False onlinedata.addOnlineLoc(userId, self.room.roomId, self.room.roomId * 10000, 1) cardLevel, isWinner, isToBeBanker = \ gamedata.getGameAttrs(userId, self.room.gameId, ["cardLevel", "isWinner", "isToBeBanker"]) if cardLevel == None: # 新玩家, 必须初始化cardLevel cardLevel, isWinner, isToBeBanker = 2, False, False gamedata.setGameAttrs(userId, self.room.gameId, ["cardLevel", "isWinner", "isToBeBanker"], [2, False, False]) # 修改users数据的代码段中不允许有异步操作 self.users[userId] = {"enterTime": time.time()} self.users[userId]["cardLevel"], self.users[userId]["isWinner"], self.users[userId]["isToBeBanker"] = \ cardLevel, isWinner, isToBeBanker self.matchTeamMate(userId) if ftlog.is_debug(): ftlog.debug(">>", self.baseLogStr(None, userId), "|self.users[userId]:", self.users[userId], "|locList:", onlinedata.getOnlineLocList(userId), caller=self) return True
def doQuickStart(self, msg): ''' Note: 1> 每个房间一张桌子 2> 房间分为激活和非激活状态 3> 选择激活房间中人数最少的 ''' 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, caller=self) if tableId == 0: # 选择激活房间中人数最少的 shadowRoomId = self.roomDefine.shadowRoomIds[0] for rid in self.roomDefine.shadowRoomIds[1:]: if rid in self.isActive and \ len(self.roomUsers[rid]) < len(self.roomUsers[shadowRoomId]): shadowRoomId = rid break tableId = shadowRoomId * 10000 + 1 if not tableId: ftlog.error(getMethodName(), "getFreeTableId timeout", "|userId, roomId, tableId:", userId, self.roomId, tableId) return if ftlog.is_debug(): ftlog.info("after choose table", "|userId, shadowRoomId, tableId:", userId, shadowRoomId, tableId, caller=self) self.doEnter(userId) self.roomUsers[shadowRoomId].add(userId) self.userCountTotal += 1 if ftlog.is_debug(): ftlog.debug("|shadowRoomId, userId, self.roomUsers[shadowRoomId]", shadowRoomId, userId, self.roomUsers[shadowRoomId], "|self.userCountTotal:", self.userCountTotal, caller=self) # 增加active room if self.roomConf["openTableRatio"] * self.tableConf["maxSeatN"] * len(self.isActive) <= self.userCountTotal: if ftlog.is_debug(): ftlog.debug("|userId, self.roomDefine.shadowRoomIds[1:]:", userId, self.roomDefine.shadowRoomIds[1:], caller=self) for rid in self.roomDefine.shadowRoomIds[1:]: if rid not in self.isActive: self.isActive.add(rid) if ftlog.is_debug(): ftlog.debug("add active room |shadowRoomId, userId, self.roomUsers[shadowRoomId]", shadowRoomId, userId, self.roomUsers[shadowRoomId], "|self.userCountTotal, self.isActive:", self.userCountTotal, self.isActive, caller=self) break extParams = msg.getKey('params') self.sendSitReq(userId, shadowRoomId, tableId, clientId, extParams)
def doQuickStart(self, msg): ''' Note: 1> 由于不同游戏评分机制不同,例如德州会根据游戏阶段评分,所以把桌子评分存到redis里,方便各游戏服务器自由刷新。 2> 为了防止同一张桌子同时被选出来分配座位,选桌时会把tableScore里选出的桌子删除,玩家坐下成功后再添加回去,添回去之前无需刷新该桌子的评分。 3> 玩家自选桌时,可能选中一张正在分配座位的桌子,此时需要休眠后重试,只到该桌子完成分配或者等待超时。 ''' assert self.roomId == msg.getParam("roomId") userId = msg.getParam("userId") gameId = msg.getParam("gameId") shadowRoomId = msg.getParam("shadowRoomId") tableId = msg.getParam("tableId") exceptTableId = msg.getParam("exceptTableId") clientId = msg.getParam("clientId") showHuafei = msg.getParam("showHuafei") ftlog.info(getMethodName(), "<<", "|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) ftlog.info(getMethodName(), self.roomDefine.shadowRoomIds) if tableId == 0: # 服务器为玩家选择桌子并坐下 # if gameId == 60: # shadowRoomId = self.getShadowRoomIdx(self.roomDefine, clientId, showHuafei) # else: shadowRoomId = self.getShadowRoomIdStrategy() tableId = self.getBestTableId(userId, shadowRoomId, exceptTableId) else: # 玩家自选桌子坐下 assert (isinstance(shadowRoomId, int) and gdata.roomIdDefineMap()[shadowRoomId].bigRoomId == self.roomDefine.bigRoomId) tableId = self.enterOneTable(userId, shadowRoomId, tableId) if not tableId: ftlog.error(getMethodName(), "getFreeTableId timeout", "|userId, roomId, tableId:", userId, self.roomId, tableId) return if ftlog.is_debug(): ftlog.info(getMethodName(), "after choose table", "|userId, shadowRoomId, tableId:", userId, shadowRoomId, tableId) extParams = msg.getKey('params') self.querySitReq(userId, shadowRoomId, tableId, clientId, extParams)
def testLog(self): @catchedmethod def errorFun(): "" + 1 ftlog.debug(file=__file__) print "=" * 30 ftlog.info(getMethodName()) print "=" * 30 ftlog.warn(getMethodName()) print "=" * 30 ftlog.error(getMethodName()) print "=" * 30 errorFun()
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.info(getMethodName(), "<<", "|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) if tableId == self.roomId * 10000: isOk = True # 玩家在队列里时断线重连 player = self.match.findPlayer(userId) if ftlog.is_debug(): ftlog.debug('TYArenaMatchRoom.doQuickStart reconnect userId=', userId, 'tableId=', tableId, 'player=', player.__dict__ if player else None) if player is None: ftlog.warn(getMethodName(), '|room=', self.roomId, 'userId=', userId, 'not found player') onlinedata.removeOnlineLoc(userId, self.roomId, tableId) isOk = False else: isOk = False if isOk: reason = self.ENTER_ROOM_REASON_OK self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, self.match.tableId) # 如果用户已经被分组则发送等待信息 if player.stage and player.state in (MatchPlayer.STATE_WAIT, MatchPlayer.STATE_RISE): self.match.playerNotifier.notifyMatchWait(player) else: reason = self.ENTER_ROOM_REASON_INNER_ERROR info = u'在线状态错误或其他系统内部错误' self.sendQuickStartRes(self.gameId, userId, reason, self.bigRoomId, 0, info)
def initMatch(self): ftlog.info(getMethodName(), '<< |roomId=', self.roomId) assert (self.matchPlugin.getMatch(self.roomId) is None) conf = MatchConfig.parse(self.gameId, self.roomId, self.bigmatchId, self.roomConf["name"], self.matchConf) # conf.tableId = self.maptable.values()[0]._id conf.tableId = self.roomId * 10000 # 用来表示玩家在房间队列的特殊tableId conf.seatId = 1 tableManager = TableManager(self.gameId, conf.tableSeatCount) shadowRoomIds = self.roomDefine.shadowRoomIds ftlog.info(getMethodName(), 'before add IdleTables.', '|roomId=', self.roomId, 'roomIds=', list(shadowRoomIds)) for roomId in shadowRoomIds: count = self.roomDefine.configure['gameTableCount'] baseid = roomId * 10000 ftlog.info(getMethodName(), 'adding IdleTables of one shadowRoom.', '|roomId=', self.roomId, 'shadowRoomId=', roomId, 'tableCount=', count, 'baseid=', baseid) tableManager.addTables(roomId, baseid, count) random.shuffle(tableManager._idleTables) match = self.matchPlugin.buildMatch(conf, self) match.tableManager = tableManager if gdata.mode() == gdata.RUN_MODE_ONLINE: playerCapacity = int(tableManager.getAllTableCount() * tableManager.tableSeatCount * 0.9) ftlog.info(getMethodName(), '<< |roomId=', self.roomId, 'allTableCount=', tableManager.getAllTableCount(), 'tableSeatCount=', tableManager.tableSeatCount, 'playerCapacity=', playerCapacity, 'matchUserMaxCount=', conf.start.userMaxCount) assert (playerCapacity > conf.start.userMaxCount) match.load() self.match = match self.matchPlugin.setMatch(self.roomId, match)
def testTimer(self): print "call %s" % getMethodName() def fun1(x): print "call %s" % getMethodName() print x*10 func = functools.partial(fun1, 1) timer = FTTimer(1, func) stackless.tasklet(mainloop)() stackless.run()
def enter(self, userId): '''玩家进入队列''' if self.users.get(userId) != None: ftlog.error(getMethodName(), "already in queue!", self.baseLogStr(None, userId)) return False self.users[userId] = {"enterTime": time.time()} onlinedata.addOnlineLoc(userId, self.room.roomId, self.room.roomId * 10000, 1) if ftlog.is_debug(): ftlog.debug(">>", self.baseLogStr(None, userId), "|locList:", onlinedata.getOnlineLocList(userId), caller=self) return True
def reportBiGameEvent(self, eventId, userId, roomId, tableId, roundId, detalChip, state1, state2, cardlist, tag=''): try: finalUserChip = userchip.getChip(userId) finalTableChip = 0 clientId = sessiondata.getClientId(userId) bireport.reportGameEvent(eventId, userId, self.gameId, roomId, tableId, roundId, detalChip, state1, state2, cardlist, clientId, finalTableChip, finalUserChip) if ftlog.is_debug(): ftlog.debug('tag=', tag, 'eventId=', eventId, 'userId=', userId, 'gameId=', self.gameId, 'roomId=', roomId, 'tableId=', tableId, 'roundId=', roundId, 'detalChip=', detalChip, caller=self) except: ftlog.error(getMethodName(), 'tag=', tag, 'eventId=', eventId, 'userId=', userId, 'gameId=', self.gameId)
def handleMatchException(cls, room, ex, uid, mo): ftlog.warn(getMethodName(), "<<|roomId, userId:", room.roomId, uid, ex.message) if isinstance(ex, SigninFeeNotEnoughException): cls._handleSigninFeeNotEnoughException(room, ex, uid, mo) elif isinstance( ex, (SigninNotStartException, SigninStoppedException, SigninFullException, MatchExpiredException, ClientVersionException, MatchSigninConditionException)): cls._handleSigninException(room, ex, uid, mo) else: mo.setError(ex.errorCode, ex.message) router.sendToUser(mo, uid)
def testTimer(self): print "call %s" % getMethodName() def fun1(x): print "call %s" % getMethodName() print x * 10 func = functools.partial(fun1, 1) timer = FTTimer(1, func) stackless.tasklet(mainloop)() stackless.run()
def doQuickStart(self, msg): ''' Note: 1> 由于不同游戏评分机制不同,例如德州会根据游戏阶段评分,所以把桌子评分存到redis里,方便各游戏服务器自由刷新。 2> 为了防止同一张桌子同时被选出来分配座位,选桌时会把tableScore里选出的桌子删除,玩家坐下成功后再添加回去,添回去之前无需刷新该桌子的评分。 3> 玩家自选桌时,可能选中一张正在分配座位的桌子,此时需要休眠后重试,只到该桌子完成分配或者等待超时。 4> 贵宾室为了凑桌,当一张桌子被取走需要等待返回,这样需要锁一下房间对象。 ''' 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, caller=self) # if tableId and tableId not in self._activeTables: #此方法不可行,GR的_activeTables是空的,实际数据在GT里 # ftlog.warn("tableId not in self._activeTables, tableId:", tableId) # tableId = 0 if tableId == 0: # 服务器为玩家选择桌子并坐下 shadowRoomId = choice(self.roomDefine.shadowRoomIds) tableId = self.getBestTableId(userId, shadowRoomId) # else: # 玩家自选桌子坐下 # assert isinstance(shadowRoomId, int) and gdata.roomIdDefineMap()[shadowRoomId].bigRoomId == self.roomDefine.bigRoomId # tableId = self.enterOneTable(userId, shadowRoomId, tableId) if not tableId: ftlog.error(getMethodName(), "getFreeTableId timeout", "|userId, roomId, tableId:", userId, self.roomId, tableId) return if ftlog.is_debug(): ftlog.info("after choose table", "|userId, shadowRoomId, tableId:", userId, shadowRoomId, tableId, caller=self) extParams = msg.getKey('params') self.doEnter(userId) self.querySitReq(userId, shadowRoomId, tableId, clientId, extParams)
def getPlayingLen(self): """由于playing 列表有未知问题,改用enterMatchTotal - rankingLen来反推,并报异常方便查错。 """ # 这种方式比分别访问3次 redis 快3倍左右。访问3次redis需要将近1秒 playingLen, rankingLen, enterMatchTotal = daobase.executeRankCmd("EVALSHA", self.getPlayinLenLuaSha, 0) if playingLen + rankingLen != enterMatchTotal: ftlog.error(getMethodName(), "playingLen + rankingLen != enterMatchTotal", "|roomId, playingLen, rankingLen:", self.roomId, playingLen, rankingLen, "|enterMatchTotal:", enterMatchTotal) if ftlog.is_debug(): ftlog.info(">>", "|roomId, playingLen, rankingLen:", self.roomId, enterMatchTotal - rankingLen, rankingLen, caller=self) return enterMatchTotal - rankingLen
def keepAlive(mysql_pool_map): global _keep_count, _keep_alive_seconds # ftlog.debug('MYSQL keepAlive', len(mysql_pool_map), _keep_count) _keep_count += 1 if _keep_count == 1 : if len(mysql_pool_map) > 0 : FTTimer(_keep_alive_seconds, _keepAlive, mysql_pool_map) return sqlstr = 'select %d' % (_keep_count) for dbkey in mysql_pool_map.keys() : conn = mysql_pool_map[dbkey] try: defertool.setDefaultCallback(conn.runQuery(sqlstr), __file__, ftlog.getMethodName(), sqlstr) except: ftlog.error('ERROR MYSQL of', dbkey, 'has connection error ! close !! ') FTTimer(_keep_alive_seconds, _keepAlive, mysql_pool_map)
def syncChooseTableAndSit(self, userId): print "call %s()" % getMethodName() result = userId + 10 print "return %s " % result return result
def fun1(x): print "call %s" % getMethodName() print x * 10
def fun1(x): print "call %s" % getMethodName() print x*10
def doQuickStart(self, msg): """ Note: 1> 由于不同游戏评分机制不同,例如德州会根据游戏阶段评分,所以把桌子评分存到redis里,方便各游戏服务器自由刷新。 2> 为了防止同一张桌子同时被选出来分配座位,选桌时会把tableScore里选出的桌子删除,玩家坐下成功后再添加回去,添回去之前无需刷新该桌子的评分。 3> 玩家自选桌时,可能选中一张正在分配座位的桌子,此时需要休眠后重试,只到该桌子完成分配或者等待超时。 """ assert self.roomId == msg.getParam("roomId") userId = msg.getParam("userId") shadowRoomId = msg.getParam("shadowRoomId") tableId = msg.getParam("tableId") clientId = msg.getParam("clientId") ftlog.hinfo(getMethodName(), "->|userId, clientId, roomId, shadowRoomId, tableId:", userId, clientId, self.roomId, shadowRoomId, tableId) if self.runStatus != self.ROOM_STATUS_RUN: FishQuickStart.onQuickStartFailed( FishQuickStart.ENTER_ROOM_REASON_MAINTENANCE, userId, clientId, self.roomId) return if tableId == 0: # 服务器为玩家选择桌子并坐下 _, _, details = bireport.getRoomOnLineUserCount(FISH_GAMEID, True) complete = False roomIds = self.roomDefine.shadowRoomIds # 按VIP等级分桌 vipRoomConf = OrderedDict({6: -3, 3: -6, 1: -8, 0: -10}) vipLevel = hallvip.userVipSystem.getVipInfo(userId).get("level", 0) index = 0 for level in vipRoomConf: if vipLevel >= level: index = vipRoomConf[level] break for roomId in roomIds[index:]: tableCount = self.roomDefine.configure["gameTableCount"] maxSeatN = self.tableConf["maxSeatN"] if details.get(str(roomId)) < int(tableCount * maxSeatN * 0.9): shadowRoomId = roomId complete = True break if not complete: shadowRoomId = choice(self.roomDefine.shadowRoomIds) tableId = self.getBestTableId(userId, shadowRoomId) else: # 玩家自选桌子坐下 assert isinstance(shadowRoomId, int) and gdata.roomIdDefineMap( )[shadowRoomId].bigRoomId == self.roomDefine.bigRoomId tableId = self.enterOneTable(userId, shadowRoomId, tableId) if not tableId: ftlog.error(getMethodName(), "getFreeTableId timeout", "|userId, roomId, tableId:", userId, self.roomId, tableId) return if ftlog.is_debug(): ftlog.info(getMethodName(), "after choose table", "|userId, shadowRoomId, tableId:", userId, shadowRoomId, tableId) extParams = msg.getKey("params") self.querySitReq(userId, shadowRoomId, tableId, clientId, extParams)
def dispatchQuickStart(cls, msg, userId, gameId, roomId, tableId, playMode, clientId): clientVersion = 4.0 if clientVersion >= 4.0: return MajiangQuickStartV4_0.onCmdQuickStart(msg, userId, gameId, roomId, tableId, playMode, clientId) ftlog.error(getMethodName(), "unsupported client:", clientVersion)
def doShutDown(self): ftlog.debug(getMethodName(), '<<', "|roomId:", self.roomId) for table in self.maptable.values(): table.doShutDown() if ftlog.is_debug(): ftlog.debug(getMethodName(), '>>', "|roomId:", self.roomId)
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 doQuickStart(self, msg): ''' Note: 1> 每个房间一张桌子 2> 房间分为激活和非激活状态 3> 选择激活房间中人数最少的 ''' 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, caller=self) if tableId == 0: # 选择激活房间中人数最少的 shadowRoomId = self.roomDefine.shadowRoomIds[0] for rid in self.roomDefine.shadowRoomIds[1:]: if rid in self.isActive and \ len(self.roomUsers[rid]) < len(self.roomUsers[shadowRoomId]): shadowRoomId = rid break tableId = shadowRoomId * 10000 + 1 if not tableId: ftlog.error(getMethodName(), "getFreeTableId timeout", "|userId, roomId, tableId:", userId, self.roomId, tableId) return if ftlog.is_debug(): ftlog.info("after choose table", "|userId, shadowRoomId, tableId:", userId, shadowRoomId, tableId, caller=self) self.doEnter(userId) self.roomUsers[shadowRoomId].add(userId) self.userCountTotal += 1 if ftlog.is_debug(): ftlog.debug("|shadowRoomId, userId, self.roomUsers[shadowRoomId]", shadowRoomId, userId, self.roomUsers[shadowRoomId], "|self.userCountTotal:", self.userCountTotal, caller=self) # 增加active room if self.roomConf["openTableRatio"] * self.tableConf["maxSeatN"] * len( self.isActive) <= self.userCountTotal: if ftlog.is_debug(): ftlog.debug("|userId, self.roomDefine.shadowRoomIds[1:]:", userId, self.roomDefine.shadowRoomIds[1:], caller=self) for rid in self.roomDefine.shadowRoomIds[1:]: if rid not in self.isActive: self.isActive.add(rid) if ftlog.is_debug(): ftlog.debug( "add active room |shadowRoomId, userId, self.roomUsers[shadowRoomId]", shadowRoomId, userId, self.roomUsers[shadowRoomId], "|self.userCountTotal, self.isActive:", self.userCountTotal, self.isActive, caller=self) break extParams = msg.getKey('params') self.sendSitReq(userId, shadowRoomId, tableId, clientId, extParams)