def sendMasterGiftTodoTask(userId, gameId, clientId, pic, pay_order, roomId): """ 推送高手礼包弹窗 @param pay_order 挑选商品模板 """ if not TYPlayer.isHuman(userId): return product, _ = hallstore.findProductByPayOrder(gameId, userId, clientId, pay_order) if not product: ftlog.error('userId =', userId, 'clientId =', clientId, 'pay_order =', pay_order, 'can not find suitable product!') return todotask = TodoTaskPayOrder(product) task = { 'action': 'cache_wnd_gaoshou', 'params': { 'pic': pic, 'tasks': [todotask.toDict()] } } mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userId) mo.setResult('tasks', [task]) router.sendToUser(mo, userId)
def sendBuyDiamondTodoTask(userId, gameId, clientId, pay_order): """ 幸运大抽奖,钻石购买 @param pay_order 挑选商品模板 """ if not TYPlayer.isHuman(userId): return product, _ = hallstore.findProductByPayOrder(gameId, userId, clientId, pay_order) if not product: ftlog.error('userId =', userId, 'clientId =', clientId, 'pay_order =', pay_order, 'can not find suitable product!') return try: product = product.clone() except: product = strutil.cloneData(product) desc = u'您的钻石不够哦~\n现在' + unicode(product.price) + u'元立得' + unicode( product.priceDiamond) + u'钻石!' product.content.desc = str(product.priceDiamond) + '钻石' client_ver = sessiondata.getClientIdVer(userId) if client_ver < 3.74: # 客户端bug,小于3.74的版本转换一下 product.priceDiamond = product.price todotasks = TodoTaskOrderShow.makeByProduct(desc, '', product) TodoTaskHelper.sendTodoTask(gameId, userId, todotasks)
def doSignin(self, userId, feeIndex=0): """ 比赛报名 """ if self.match.matchConf.discountTime: startTime = util.getTimestampFromStr(self.match.matchConf.discountTime[0]) endTime = util.getTimestampFromStr(self.match.matchConf.discountTime[1]) if startTime <= int(time.time()) <= endTime: feeIndex = 1 if self._logger.isDebug(): self._logger.debug("doSignin", "userId=", userId, "feeIndex=", feeIndex) mo = MsgPack() mo.setCmd("m_signin") mo.setResult("gameId", self.gameId) mo.setResult("roomId", self.roomId) mo.setResult("userId", userId) try: if userId > config.ROBOT_MAX_USER_ID: self.matchPlugin.ensureCanSignInMatch(self, userId, mo) signer = self.match.signin(userId, feeIndex) if signer: mo.setResult("signin", 1) mo.setResult("signinPlayerCount", self.match.signerCount) if userId > config.ROBOT_MAX_USER_ID: self.reportBiGameEvent("MATCH_SIGN_UP", userId, self.roomId, 0, 0, 0, 0, 0, [], "match_signin") else: raise SigninException() router.sendToUser(mo, userId) if TYPlayer.isHuman(userId): self._notifyRobotSigninMatch(signer) except MatchException, e: self.matchPlugin.handleMatchException(self, e, userId, mo)
def doHeartBeat(self): if self._state == self.STATE_IDLE: return FTTimer(1, self.doHeartBeat) if len(self.users) == 0: return if ftlog.is_debug(): ftlog.debug("<<", self.baseLogStr(), caller=self) # ftlog.debug("|first user, enter time, now, wait_time:", self.users.keys()[0], self.users[self.users.keys()[0]], time.time(), self.wait_time) if self._state == self.STATE_LOOP: if len(self.users) >= self.n_start: self._tryStartNewTable(self.n_start) return if time.time() - self.users[self.users.keys()[0]]["enterTime"] < self.wait_time: return if len(self.users) >= self.minTriggerLen: self._tryStartNewTable(self.minTriggerLen) return if TYPlayer.isRobot(self.users.keys()[0]): return if len(self.room._roomUsers) < self.n_start: self.notifyRobot()
def enterFriendTable(userId, gameId, clientId, ftId): """进入自建桌""" if ftlog.is_debug(): ftlog.debug('hall_friend_table.enterFriendTable userId:', userId, ' pluginId:', gameId, ' clientId:', clientId, ' ftId:', ftId) pluginId = queryFriendTable(ftId) if not pluginId: TodoTaskHelper.sendTodoTask(HALL_GAMEID, userId, TodoTaskPopTip('该房间不存在')) return if TYPlayer.isRobot(userId): isValidPluginId = True else: isValidPluginId = False from hall.entity import hallgamelist2 template = hallgamelist2.getUITemplate(gameId, userId, clientId) for version in template.versionList: if pluginId == version.game.gameId: isValidPluginId = True break if not isValidPluginId: TodoTaskHelper.sendTodoTask(HALL_GAMEID, userId, TodoTaskPopTip('该安装包不支持此房间号所对应的玩法')) return ftlog.info('hall_friend_table.enterFriendTable userId:', userId, ' lead to pluginId:', pluginId) pluginId = int(pluginId) TYGame(pluginId).enterFriendTable(userId, gameId, clientId, ftId)
def doCallDizhuTimeOut(self, player): ''' 叫地主超时 ''' ftlog.debug('doCallDizhuTimeOut...') if not player or self.table.status.state != DizhuState.TABLE_STATE_CALLING: ftlog.warn('ERROR !!, doCallDizhuTimeOut table.status=', self.table.status, player) return assert (self.table.status.callGrade < 3) if TYPlayer.isHuman(player.userId): # 真实玩家超时默认不叫地主 call = 0 else: # AI必须叫地主 if self.table.status.callGrade <= 0: call = 1 else: call = self.table.status.callGrade + 1 # 系统主动替玩家进行叫地主, 1分 self.doCallDizhu(player, -1, call, DizhuPlayer.TUGUAN_TYPE_TIMEOUT)
def sendFreeChipTodoTask(userid, gameId, cache=False, direct=True): """ 推送 免费金币 added by nick.kai.lee Args: userid: 玩家userid cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendFreeChipTodoTask:', userid) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder task = MahjongTodoTaskBuilder.dict_free_chip(userid, cache) if not task: return False, None ftlog.debug('sendFreeChipTodoTask:', task) if False == direct: return True, task mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None
def sendMarketEstimateTodoTask(userid, gameId, url, des, cache=False, direct=True): """ 推送麻将五星好评Cache 发送五星好评的数据,客户端缓存,什么时候激活五星好评由客户端实现 @param des 五星好评内容 """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendMarketEstimateTodoTask:', userid, url, des, cache, direct) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder task = MahjongTodoTaskBuilder.dict_market_estimate(userid, url, des, cache) if not task: return False, None if True == direct: mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None else: return True, task
def sendFreeChipTodoTask(userid, gameId, cache = False, direct = True): """ 推送 免费金币 added by nick.kai.lee Args: userid: 玩家userid cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendFreeChipTodoTask:', userid) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder task = MahjongTodoTaskBuilder.dict_free_chip(userid, cache) if not task: return False, None ftlog.debug('sendFreeChipTodoTask:', task) if False == direct: return True, task mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None
def doHeartBeat(self): if self._state == self.STATE_IDLE: return FTTimer(1, self.doHeartBeat) if len(self.users) == 0: return if ftlog.is_debug(): ftlog.debug("<<", self.baseLogStr(), caller=self) # ftlog.debug("|first user, enter time, now, wait_time:", self.users.keys()[0], self.users[self.users.keys()[0]], time.time(), self.wait_time) if self._state == self.STATE_LOOP: if len(self.users) >= self.n_start: self._tryStartNewTable(self.n_start) return if time.time() - self.users[self.users.keys() [0]]["enterTime"] < self.wait_time: return if len(self.users) >= self.minTriggerLen: self._tryStartNewTable(self.minTriggerLen) return if TYPlayer.isRobot(self.users.keys()[0]): return if len(self.room._roomUsers) < self.n_start: self.notifyRobot()
def sendTodoTaskInviteFriends(userId, gameId, invite_uids, play_mode, roomId, tableId, info_str, purl): """ 邀请好友来牌桌 @param name 发送邀请的用户名 @param invite_uids 被邀请的玩家uid列表 @param table 牌桌对象 """ ftlog.debug('userId =', userId, 'roomId =', roomId, 'tableId =', tableId, 'invite_uids =', invite_uids, 'info_str =', info_str) if not TYPlayer.isHuman(userId): ftlog.debug('robot is not supported!') return for uid in invite_uids: last_gameId = onlinedata.getLastGameId(uid) if last_gameId == gameId: # 如果玩家在麻将里 sendFriendInviteTodotask(uid, userId, gameId, play_mode, roomId, tableId, info_str, purl) elif last_gameId == 9999: # 如果玩家在大厅主界面 sendFriendInviteEnterGameTodotask(uid, gameId, play_mode, roomId, tableId, info_str) else: # 在其它游戏里,直接忽略 ftlog.debug('last_gameId is not 7 or 9999', 'last_gameId =', last_gameId) return from majiang2.entity import util util.sendPrivateMessage(uid, info_str)
def sendLocalPushTodoTask(userid, gameId, hour, minute, second, direct=True): """ 推送 本地推送push added by nick.kai.lee 向客户端推送闹钟push的注册,比如每次客户端登录时都会推送一次"本地推送的功能" Args: userid: 玩家userid cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendLocalPushTodoTask:', userid) from difang.majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder from datetime import datetime now = datetime.now() # alarm3个元素,days,seconds,microseconds, seconds遇到过去的时间会自动获得明天这个时间点的时间差 alarm = datetime(datetime.now().year, datetime.now().month, datetime.now().day, hour, minute, second) # 推送内容 import random content = random.choice([ "还记得上次在拜雀神中抽取的大奖么?机会又来了!", "修复老年痴呆,拯救弱智儿童,途游麻将提高智商值得你拥有!", "主人,您的任务奖励还没领取呢,去看看吧!", "优惠降临!充值送豪礼,下班来放松玩玩吧!", "幸运大抽奖可以免费领取金币了,快来领取吧!", "您有一份礼包未签收,快去活动中心看看吧!", "点我速领500金币~", "工作一天了,让麻将小莲帮你放松放松~", "亲,每隔10分钟1场免费定时赛,100奖券随便拿!", "您可以领取每日奖励了,它将会很快过期,快回到途游麻将领取吧!", "雀神爷爷说马上就要发红包了,你准备好了么?", "您获取的奖券兑换话费了嘛?", "大哥,您的贵宾桌我们已经为您准备好了!静候您的光临!", "您的好友邀请您一起对战途游麻将!" ]) task = MahjongTodoTaskBuilder.dict_reg_push_alarm(userid, content, (alarm - now).seconds, [True, False, True, False, True, False], "", {}, 3) if not task: return False, None ftlog.debug('sendLocalPushTodoTask:', task) if False == direct: return True, task mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None
def sendLocalPushTodoTask(userid, gameId, hour, minute, second, direct = True): """ 推送 本地推送push added by nick.kai.lee 向客户端推送闹钟push的注册,比如每次客户端登录时都会推送一次"本地推送的功能" Args: userid: 玩家userid cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendLocalPushTodoTask:', userid) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder from datetime import datetime now = datetime.now() #alarm3个元素,days,seconds,microseconds, seconds遇到过去的时间会自动获得明天这个时间点的时间差 alarm = datetime(datetime.now().year, datetime.now().month, datetime.now().day, hour, minute, second) # 推送内容 import random content = random.choice([ "还记得上次在拜雀神中抽取的大奖么?机会又来了!", "修复老年痴呆,拯救弱智儿童,途游麻将提高智商值得你拥有!", "主人,您的任务奖励还没领取呢,去看看吧!", "优惠降临!充值送豪礼,下班来放松玩玩吧!", "幸运大抽奖可以免费领取金币了,快来领取吧!", "您有一份礼包未签收,快去活动中心看看吧!", "点我速领500金币~", "工作一天了,让麻将小莲帮你放松放松~", "亲,每隔10分钟1场免费定时赛,100奖券随便拿!", "您可以领取每日奖励了,它将会很快过期,快回到途游麻将领取吧!", "雀神爷爷说马上就要发红包了,你准备好了么?", "您获取的奖券兑换话费了嘛?", "大哥,您的贵宾桌我们已经为您准备好了!静候您的光临!", "您的好友邀请您一起对战途游麻将!" ]) task = MahjongTodoTaskBuilder.dict_reg_push_alarm(userid, content, (alarm-now).seconds, [True, False, True, False, True, False], "", {}, 3 ) if not task: return False, None ftlog.debug('sendLocalPushTodoTask:', task) if False == direct: return True, task mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None
def doSignin(self, userId, feeIndex=0): """ 比赛报名,扣费 """ if self.match.matchConf.discountTime: startTime = util.getTimestampFromStr( self.match.matchConf.discountTime[0]) endTime = util.getTimestampFromStr( self.match.matchConf.discountTime[1]) if startTime <= int(time.time()) <= endTime: feeIndex = 1 if self._logger.isDebug(): self._logger.debug("doSignin", "userId=", userId, "feeIndex=", feeIndex, "status=", self.runStatus) mo = MsgPack() mo.setCmd("m_signin") mo.setResult("gameId", self.gameId) mo.setResult("roomId", self.roomId) mo.setResult("userId", userId) mo.setResult("matchType", "point") try: if self.runStatus != self.ROOM_STATUS_RUN: raise MaintenanceException() else: playedTimes = self.matchMaster.userPlayedTimes.get(userId, 0) maxGameTimes = self.match.matchConf.start.maxGameTimes if playedTimes >= maxGameTimes > -1: raise RunOutSigninChanceException() else: isIn, _, _, _ = util.isInFishTable(userId) if isIn: raise SigninException() else: if userId > config.ROBOT_MAX_USER_ID: self.matchPlugin.ensureCanSignInMatch( self, userId, mo) signer = self.match.signin(userId, feeIndex) if signer: mo.setResult("signin", 1) mo.setResult("signinPlayerCount", self.match.signerCount) if userId > config.ROBOT_MAX_USER_ID: self.reportBiGameEvent("MATCH_SIGN_UP", userId, self.roomId, 0, 0, 0, 0, 0, [], "match_signin") else: raise SigninException() router.sendToUser(mo, userId) if TYPlayer.isHuman(userId): self._notifyRobotSigninMatch(signer) except MatchException, e: self.matchPlugin.handleMatchException(self, e, userId, mo)
def initUser(self, isNextBuyin, isUsingScore, randomIndex=0): ''' 从redis里获取并初始化player数据, 远程操作 ''' ret = super(DizhuPlayerHeroMatch, self).initUser(isNextBuyin, isUsingScore) if TYPlayer.isRobot(self.userId): from dizhu.wx_resource import wx_resource wx_resource.initRobotSetting() wxUserInfo = wx_resource.getRobot(randomIndex) self.datas['sex'] = wxUserInfo['sex'] self.datas['name'] = wxUserInfo['name'] self.datas['purl'] = wxUserInfo['purl'] self.clientId = 'robot_3.7_-hall6-robot' return ret
def doSignin(self, userId, signinParams, feeIndex=0): ftlog.debug("<<", "|userId, roomId, signinParams:", userId, self.roomId, feeIndex, signinParams, caller=self) try: mo = MsgPack() mo.setCmd('m_signin') self.matchPlugin.ensureCanSignInMatch(self, userId, mo) player = self.match.signin(userId, signinParams, feeIndex) if TYPlayer.isHuman(userId): self.__notifyRobotSigninMatch(player) self.reportBiGameEvent("MATCH_SIGN_UP", userId, self.roomId, 0, 0, 0, 0, 0, [], 'match_signin') except MatchException, e: self.matchPlugin.handleMatchException(self, e, userId, mo)
def doSignin(self, userId, signinParams, feeIndex=0): if self._logger.isDebug(): self._logger.debug('TYErdayiMatchRoom.doSignin', 'userId=', userId, 'feeIndex=', feeIndex, 'signinParams=', signinParams) try: mo = MsgPack() mo.setCmd('m_signin') self.matchPlugin.ensureCanSignInMatch(self, userId, mo) signer = self.match.signin(userId, feeIndex) if TYPlayer.isHuman(userId): self._notifyRobotSigninMatch(signer) except MatchException, e: self.matchPlugin.handleMatchException(self, e, userId, mo)
def sendAlmsTodoTask(userid, gameId, cache=False, direct=True): """ 推送麻将救济金Cache added by nick.kai.lee 发送麻将救济金数据,客户端是否缓存由cache决定,cache为True时不是立即激活, 什么时候激活转运礼包由客户端实现 Args: userid: 玩家userid cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendAlmsTodoTask:', userid, cache, direct) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder from hall.entity import hallbenefits _, userBenefits = hallbenefits.benefitsSystem.sendBenefits(gameId, userid) benefitsStrs = [] benefitsStrs.append('送您%s金币翻本吧!' % (userBenefits.sendChip)) privilegeName = userBenefits.privilege.name if userBenefits.privilege else '' if userBenefits.extSendChip > 0: benefitsStrs.append('您是%s再加赠%s金币' % (privilegeName, userBenefits.extSendChip)) benefitsStrs.append( '(%s每天%s次,今天第%s次)' % (privilegeName, userBenefits.totalMaxTimes, userBenefits.times)) if userBenefits.privilege and userBenefits.privilege.desc: benefitsStrs.append('\n%s' % (userBenefits.privilege.desc)) task = MahjongTodoTaskBuilder.dict_general_box(userid, '\n'.join(benefitsStrs), cache) if not task: return False, None # task['params']['buttons'][0]['tasks'].append({}) ftlog.debug('sendAlmsTodoTask:', task) if False == direct: return True, task mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None
def doFirstCallDizhu(self, player): ''' 延迟发送, 触发第一个叫地主的玩家 ''' ftlog.debug('doFirstCallDizhu...') if self.table.status.state != DizhuState.TABLE_STATE_CALLING: ftlog.warn('ERROR !!, doFirstCallDizhu table.status=', self.table.status, player) return for seat in self.table.seats: if TYPlayer.isRobot(seat.userId): seat.isRobot = 1 self._doNextCall(0)
def sendTuoGuanRes(self, seatId): robots = [] for seat in self.table.seats: if TYPlayer.isRobot(seat.userId): continue robots.append(seat.isRobot) mo = self.createMsgPackRes('table_call', 'rb') mo.setResult('robots', robots) mo.setResult('seatId', seatId) ccount = len(self.table.seats[seatId - 1].cards) if ccount > 2: mo.setResult('tuoguantip', "我托管,我包赔!有钱就是这么任性!!") self.sendToAllTableUser(mo)
def sendChuPaiNextRes(self, seatId, opTime): super(DizhuMillionHeroMatchSender, self).sendChuPaiNextRes(seatId, opTime) # 收到next命令cancel所有的seatOpTimer self.table.cancelAllSeatOpTimers() # 机器人出牌,延时2秒 player = self.table.players[seatId - 1] if TYPlayer.isRobot(player.userId): params = { 'seatId': seatId, 'userId': player.userId, 'ccrc': self.table.status.cardCrc } self.table.seatOpTimers[seatId - 1].setup(random.randint(2, 4), 'AI_OUTCARD_TIMEUP', params)
def process_interactive_expression(cls, userId, gameId, seatId, chat_msg, target_player_uid, base_chip): """处理消费金币的表情""" config = cls.get_interactive_expression_config(base_chip) emoId = str(chat_msg.get('emoId', -1)) if emoId not in config: ftlog.warn('chat msg illegal', chat_msg, config) return False info = config[emoId] # 底分限制 chip = userchip.getChip(userId) if chip < info['chip_limit'] + info['cost']: ftlog.warn('insufficient', chip, info['chip_limit'], info['cost']) return False if TYPlayer.isHuman(userId): from difang.majiang2.entity.util import Util clientId = Util.getClientId(userId) trueDelta, _ = userchip.incrChip(userId , gameId , -info['cost'] , 0 , "EMOTICON_CONSUME" , chat_msg['emoId'] , clientId ) if trueDelta != -info['cost']: # 失败 ftlog.warn('coin not enougth: ', chip, info['chip_limit'], info['cost']) return False bireport.gcoin('out.interactive_expression', gameId, info['cost']) # 处理魅力值 # charm = incrCharm(userId, info['charm']) # hallranking.rankingSystem.setUserByInputType(gameId # , TYRankingInputTypes.CHARM # , userId # , charm) # if TYPlayer.isHuman(target_player_uid): # charm = incrCharm(target_player_uid, info['ta_charm']) # hallranking.rankingSystem.setUserByInputType(gameId # , TYRankingInputTypes.CHARM # , target_player_uid # , charm) return True
def _checkIfForceRobot(self, player, tuoGuanType): ''' 每次超时均检查是否需要强制进入托管状态 ''' if TYPlayer.isRobot(player.userId): return seat = self.table.seats[player.seatIndex] if tuoGuanType == DizhuPlayer.TUGUAN_TYPE_USERACT: # 用户出牌 seat.timeOutCount = 0 elif tuoGuanType == DizhuPlayer.TUGUAN_TYPE_TIMEOUT: # 正常操作超时 seat.timeOutCount = seat.timeOutCount + 1 ftlog.debug('_checkIfForceRobot->userId=', player.userId, 'seat.timeOutCount=', seat.timeOutCount, 'die=', self.table.runConfig.robotTimes) if seat.timeOutCount >= self.table.runConfig.robotTimes: self._doTuoGuan(player, True)
def doSignin(self, userId, signinParams, feeIndex=0): if self._logger.isDebug(): self._logger.debug('TYGroupMatchRoom.doSignin', 'userId=', userId, 'feeIndex=', feeIndex, 'signinParams=', signinParams) try: mo = MsgPack() mo.setCmd('m_signin') self.matchPlugin.ensureCanSignInMatch(self, userId, mo) signer = self.match.signin(userId, signinParams, feeIndex) if TYPlayer.isHuman(userId): self._notifyRobotSigninMatch(signer) self.reportBiGameEvent('MATCH_SIGN_UP', userId, self.roomId, 0, 0, 0, 0, 0, [], 'match_signin') except MatchException, e: self.matchPlugin.handleMatchException(self, e, userId, mo)
def process_interactive_expression(cls, userId, gameId, seatId, chat_msg, target_player_uid, base_chip): """处理消费金币的表情""" config = cls.get_interactive_expression_config(base_chip) emoId = str(chat_msg.get('emoId', -1)) if emoId not in config: ftlog.warn('chat msg illegal', chat_msg, config) return False info = config[emoId] # 底分限制 chip = userchip.getChip(userId) if chip < info['chip_limit'] + info['cost']: ftlog.warn('insufficient', chip, info['chip_limit'], info['cost']) return False if TYPlayer.isHuman(userId): from difang.majiang2.entity.util import Util clientId = Util.getClientId(userId) trueDelta, _ = userchip.incrChip(userId, gameId, -info['cost'], 0, "EMOTICON_CONSUME", chat_msg['emoId'], clientId) if trueDelta != -info['cost']: # 失败 ftlog.warn('coin not enougth: ', chip, info['chip_limit'], info['cost']) return False bireport.gcoin('out.interactive_expression', gameId, info['cost']) # 处理魅力值 # charm = incrCharm(userId, info['charm']) # hallranking.rankingSystem.setUserByInputType(gameId # , TYRankingInputTypes.CHARM # , userId # , charm) # if TYPlayer.isHuman(target_player_uid): # charm = incrCharm(target_player_uid, info['ta_charm']) # hallranking.rankingSystem.setUserByInputType(gameId # , TYRankingInputTypes.CHARM # , target_player_uid # , charm) return True
def doTableGameStartGT(roomId, tableId, roundId, dizhuUserId, baseCardType, roomMutil, basebet, basemulti, userIds): # 触发游戏开始的事件, 在此事件监听中处理用户的winrate以及其他任务或属性的调整和设定 # 更新宝箱的状态 tbinfos = {} datas = {'tbinfos': tbinfos} for userId in userIds: if TYPlayer.isRobot(userId): continue try: tbinfo = _doTableGameStartUT1(userId, roomId, tableId, dizhuUserId, baseCardType, roomMutil, basebet, basemulti) tbinfos.update(tbinfo) except: ftlog.error('table_winlose.doTableGameStartGT userId=', userId, 'roomId=', roomId, 'tableId=', tableId) return datas
def sendChangeFortuneTodoTask(userid, gameId, roomid, insert, cache=False, direct=True): """ 推送麻将转运礼包Cache added by nick.kai.lee 发送转运礼包的数据,客户端是否缓存由cache决定,cache为True时不是立即激活, 什么时候激活转运礼包由客户端实现 Args: userid: 玩家userid roomid: 房间id insert: 插入的task dict类型 cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendChangeFortuneTodoTask:', userid, roomid, insert, cache, direct) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder task = MahjongTodoTaskBuilder.dict_change_fortune(userid, gameId, roomid, cache) if not task: return False, None if isinstance(insert, dict): task['params']['buttons'][1]['tasks'].append(insert) ftlog.debug('sendChangeFortuneTodoTask:', task) if True == direct: mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None else: return True, task
def sendAlmsTodoTask(userid, gameId, cache = False, direct = True): """ 推送麻将救济金Cache added by nick.kai.lee 发送麻将救济金数据,客户端是否缓存由cache决定,cache为True时不是立即激活, 什么时候激活转运礼包由客户端实现 Args: userid: 玩家userid cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendAlmsTodoTask:', userid, cache, direct) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder from hall.entity import hallbenefits _, userBenefits = hallbenefits.benefitsSystem.sendBenefits(gameId, userid) benefitsStrs = [] benefitsStrs.append('送您%s金币翻本吧!' % (userBenefits.sendChip)) privilegeName = userBenefits.privilege.name if userBenefits.privilege else '' if userBenefits.extSendChip > 0: benefitsStrs.append('您是%s再加赠%s金币' % (privilegeName, userBenefits.extSendChip)) benefitsStrs.append('(%s每天%s次,今天第%s次)' % (privilegeName, userBenefits.totalMaxTimes, userBenefits.times)) if userBenefits.privilege and userBenefits.privilege.desc: benefitsStrs.append('\n%s' % (userBenefits.privilege.desc)) task = MahjongTodoTaskBuilder.dict_general_box(userid, '\n'.join(benefitsStrs), cache) if not task: return False, None # task['params']['buttons'][0]['tasks'].append({}) ftlog.debug('sendAlmsTodoTask:', task) if False == direct: return True, task mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None
def sendBuyDiamondTodoTask(userId, gameId, clientId, pay_order): """ 幸运大抽奖,钻石购买 @param pay_order 挑选商品模板 """ if not TYPlayer.isHuman(userId): return product, _ = hallstore.findProductByPayOrder(gameId, userId, clientId, pay_order) if not product: ftlog.error('userId =', userId, 'clientId =', clientId, 'pay_order =', pay_order, 'can not find suitable product!') return try: product = product.clone() except: product = strutil.cloneData(product) desc = u'您的钻石不够哦~\n现在' + unicode(product.price) +u'元立得' + unicode(product.priceDiamond) +u'钻石!' product.content.desc = str(product.priceDiamond) + '钻石' client_ver = sessiondata.getClientIdVer(userId) if client_ver < 3.74: # 客户端bug,小于3.74的版本转换一下 product.priceDiamond = product.price todotasks = TodoTaskOrderShow.makeByProduct(desc, '', product) TodoTaskHelper.sendTodoTask(gameId, userId, todotasks)
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 sendChangeFortuneTodoTask(userid, gameId, roomid, insert, cache = False, direct = True): """ 推送麻将转运礼包Cache added by nick.kai.lee 发送转运礼包的数据,客户端是否缓存由cache决定,cache为True时不是立即激活, 什么时候激活转运礼包由客户端实现 Args: userid: 玩家userid roomid: 房间id insert: 插入的task dict类型 cache: action命名是否是缓存形式,默认不缓存 direct: 是否直接发送,False则return dict """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendChangeFortuneTodoTask:', userid, roomid, insert, cache, direct) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder task = MahjongTodoTaskBuilder.dict_change_fortune(userid, gameId, roomid, cache) if not task: return False, None if isinstance(insert, dict): task['params']['buttons'][1]['tasks'].append(insert) ftlog.debug('sendChangeFortuneTodoTask:', task) if True == direct: mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None else: return True, task
def _do_room__leave(self, msg): userId = msg.getParam('userId') reason = msg.getParam('reason', TYRoom.LEAVE_ROOM_REASON_ACTIVE) needSendRes = msg.getParam('needSendRes', True) clientRoomId = msg.getParam('clientRoomId', self.roomId) # 兼容老客户端 bigRoomId = gdata.getBigRoomId(clientRoomId) if clientRoomId == bigRoomId: clientRoomId = self._choiceTableRoom(userId) if not self.leaveRoom(userId, clientRoomId, reason): reason = TYRoom.LEAVE_ROOM_REASON_FORBIT mp = MsgPack() mp.setCmd('room_leave') mp.setResult('reason', reason) mp.setResult('gameId', self.gameId) mp.setResult( 'roomId', clientRoomId) # 处理结果返回给客户端时,部分游戏(例如德州、三顺)需要判断返回的roomId是否与本地一致 mp.setResult('userId', userId) if needSendRes or TYPlayer.isRobot(userId): # 需要通知机器人stop router.sendToUser(mp, userId)
def sendMarketEstimateTodoTask(userid, gameId, url, des, cache = False, direct = True): """ 推送麻将五星好评Cache 发送五星好评的数据,客户端缓存,什么时候激活五星好评由客户端实现 @param des 五星好评内容 """ if not TYPlayer.isHuman(userid): return False, None ftlog.debug('sendMarketEstimateTodoTask:', userid, url, des, cache, direct) from majiang2.entity.todotasks_builder.todotasks_builder import MahjongTodoTaskBuilder task = MahjongTodoTaskBuilder.dict_market_estimate(userid, url, des, cache) if not task: return False, None if True == direct: mo = MsgPack() mo.setCmd('majiang_todotasks') mo.setResult('gameId', gameId) mo.setResult('userId', userid) mo.setResult('tasks', [task]) router.sendToUser(mo, userid) return True, None else: return True, task
def doInitTableUserData(userId, bigRoomId, tableId, isNextBuyin, buyinchip, isMatch=False): clientId = sessiondata.getClientId(userId) isSupportBuyin = dizhuconf.isSupportBuyin(clientId) exp, suaddress, susex, suname, sucoin, charm = userdata.getAttrs( userId, ['exp', 'address', 'sex', 'name', 'coin', 'charm']) sugold, slevel, swinrate, winchips, starid, winstreak = gamedata.getGameAttrs( userId, DIZHU_GAMEID, ['gold', 'level', 'winrate', 'winchips', 'starid', 'winstreak']) ftlog.debug('isSupportBuyin=', isSupportBuyin, 'userdata->', suaddress, susex, suname, sucoin, exp, charm) ftlog.debug('gamedata->', sugold, slevel, swinrate, winchips, starid) swinrate = strutil.loads(swinrate, ignoreException=True, execptionValue={ 'pt': 0, 'wt': 0 }) suchip = userchip.getChip(userId) buyin_tip = '' if not isSupportBuyin or isMatch: buyinMark = 0 buyin_chip = suchip else: buyinMark = 1 buyin_chip = userchip.getTableChip(userId, DIZHU_GAMEID, tableId) buyinconf = dizhuconf.getBuyInConf() if buyin_chip == buyinchip: if isNextBuyin: buyin_tip = buyinconf.get('tip_auto', '') else: buyin_tip = buyinconf.get('tip', '').format(BUYIN_CHIP=buyinchip) else: if suchip <= 0: if isNextBuyin: buyin_tip = buyinconf.get('tip_auto_all_next', '') else: buyin_tip = buyinconf.get('tip_auto_all', '') suchip = buyin_chip tbplaytimes, tbplaycount = treasurebox.getTreasureBoxState( userId, bigRoomId) try: if TYPlayer.isRobot(userId): supic, isBeauty = '', False else: supic, isBeauty = halluser.getUserHeadUrl(userId, clientId) except: supic, isBeauty = '', False slevel = _recoverUserAttr(slevel, int, 0) datas = {} datas['uid'] = userId datas['address'] = _recoverUserAttr(suaddress, unicode, '') datas['sex'] = _recoverUserAttr(susex, int, 0) datas['name'] = _recoverUserAttr(suname, unicode, '') datas['coin'] = _recoverUserAttr(sucoin, int, 0) datas['headUrl'] = '' datas['purl'] = supic datas['isBeauty'] = isBeauty datas['chip'] = suchip datas['buyinMark'] = buyinMark datas['buyinChip'] = buyin_chip datas['buyinTip'] = buyin_tip datas['exp'] = _recoverUserAttr(exp, int, 0) datas['gold'] = _recoverUserAttr(sugold, int, 0) datas['vipzuan'] = [] datas['tbc'] = tbplaycount datas['tbt'] = tbplaytimes datas['level'] = slevel datas['wins'] = swinrate.get('wt', 0) datas['plays'] = swinrate.get('pt', 0) datas['winchips'] = _recoverUserAttr(winchips, int, 0) datas['nextexp'] = dizhuaccount.getGameUserNextExp(slevel) datas['title'] = dizhuaccount.getGameUserTitle(slevel) datas['medals'] = _buildUserMedals() datas['skillScoreInfo'] = skillscore.score_info(userId) datas['charm'] = 0 if charm == None else _recoverUserAttr(charm, int, 0) datas['vipInfo'] = hallvip.userVipSystem.getVipInfo(userId) datas['starid'] = 0 if starid == None else _recoverUserAttr(starid, int, 0) datas['winstreak'] = 0 if winstreak == None else _recoverUserAttr( winstreak, int, 0) datas['gameClientVer'] = SessionDizhuVersion.getVersionNumber(userId) # TODO 查询用户增值位 datas['wearedItems'] = [] userBag = hallitem.itemSystem.loadUserAssets(userId).getUserBag() timestamp = pktimestamp.getCurrentTimestamp() memberCardItem = userBag.getItemByKindId(hallitem.ITEM_MEMBER_NEW_KIND_ID) datas[ 'memberExpires'] = memberCardItem.expiresTime if memberCardItem else 0 item = userBag.getItemByKindId(hallitem.ITEM_CARD_NOTE_KIND_ID) cardNoteCount = 0 if item and not item.isDied(timestamp): cardNoteCount = max(1, item.balance(timestamp)) ftlog.debug('DizhuPlayer->userId=', userId, 'isSupportBuyin=', isSupportBuyin, 'cardNoteCount=', cardNoteCount, 'clientId=', clientId, 'data=', datas) return isSupportBuyin, cardNoteCount, clientId, datas
def _doTableCall(self, msg, userId, seatId, action, clientId): """ 继承父类,处理table_call消息 单独处理自建桌的分享/解散 """ if not self.CheckSeatId(seatId, userId): ftlog.warn("MajiangFriendTable.doTableCall, delay msg action:", action , ' seatId:', seatId , ' messange:', msg) return if action == 'next_round': if self.logic_table.isStart(): return self.logic_table.sendMsgTableInfo(seatId) beginGame = self.logic_table.playerReady(seatId, True) self.logic_table.msgProcessor.create_table_succ_response(userId, seatId, 'ready', 1 if (userId == self.__table_owner) else 0, self.logic_table.getBroadCastUIDs()) for player in self.logic_table.player: if not player: continue if not TYPlayer.isHuman(player.userId): beginGame = self.logic_table.playerReady(player.curSeatId, True) if beginGame: # 纪录上一局的日志 给GM使用 # addOneResult(tableNo, seats, deltaScore, totalScore, curRound, totalRound, gameId, roomId, tableId) if self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] > 1: roundResult = self.logic_table.tableResult.results[-1] deltaScore = roundResult.score totalScore = self.logic_table.tableResult.score curRound = self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] - 1 totalRound = self.logic_table.tableConfig[MFTDefine.ROUND_COUNT] seats = self.logic_table.getSeats() ftlog.debug('MajiangFriendTable.doTableCall nextRound stat tableNo', self.ftId, 'seats', seats, 'deltaScore:', deltaScore, 'totalScore:', totalScore, 'gameId:', self.gameId, 'roomId:', self.roomId, 'tableId', self.tableId) hall_friend_table.addOneResult(self.ftId, seats, deltaScore, totalScore, curRound, totalRound, self.gameId, self.roomId, self.tableId) else: ftlog.debug('MajiangFriendTable.doTableCall nextRound stat log error') else: ftlog.debug('MajiangFriendTable.doTableCall nextRound stat log error not begin') elif action == 'ready': # 返回房主建房成功消息,准备状态 # 玩家准备结束 游戏正式开始 beginGame = self.logic_table.playerReady(seatId, True) self.logic_table.msgProcessor.create_table_succ_response(userId, seatId, 'ready', 1 if (userId == self.__table_owner) else 0, self.logic_table.getBroadCastUIDs()) if beginGame and self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] > 0: # 纪录开局日志 gameBegin(tableNo, seats, gameId, roomId, tableId) seats = self.logic_table.getSeats() ftlog.debug('MajiangFriendTable._doTableCall log game begin tableNo:', self.__ftId, 'seats:', seats, 'gameId:', self.gameId, 'roomId:', self.roomId, 'tableId', self.tableId) hall_friend_table.gameBegin(self.__ftId, seats, self.gameId, self.gameId, self.tableId) else: ftlog.debug('MajiangFriendTable._doTableCall log game begin not ready cur round:', self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT]) elif action == 'create_table_user_leave': if (self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] > 0): util.sendPopTipMsg(userId, "游戏已开始,不能解散") return # 房主解散,由前端主动发送,存在隐患,后续修改。房主建房后,掉线,房主的房间状态将不对,TODO if userId == self.__table_owner: ftlog.debug('MajiangFriendTable.create_table_user_leave owner leave...') # 解散时,给大家提示 for player in self.logic_table.player: if not player: continue # 通知 util.sendPopTipMsg(player.userId, "房主解散房间") # 归还剩余房卡道具 ftlog.debug('MajiangFriendTable.doTableCall leftCardCount:', self.logic_table.tableConfig[MFTDefine.LEFT_CARD_COUNT] , ' tableOwner:', self.__table_owner) if self.logic_table.tableConfig[MFTDefine.LEFT_CARD_COUNT] > 0: itemId = self.room.roomConf.get('create_item', None) if itemId: user_remote.resumeItemFromTable(self.__table_owner , self.gameId , itemId , self.logic_table.tableConfig[MFTDefine.LEFT_CARD_COUNT] , self.roomId , self.tableId) # 解散牌桌 self.clearTable(True) else: ftlog.debug('MajiangFriendTable.create_table_user_leave player leave...') util.sendPopTipMsg(userId, "您已退出房间") self.kickOffUser(userId, seatId, True) elif action == 'create_table_dissolution': if self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] == 0: ftlog.debug( 'MajiangFriendTable._doTableCall create_table_dissolution game not start, can not dissolved...') return # 投票解散牌桌 if self.voteHost != MTDefine.INVALID_SEAT: ftlog.debug('MajiangFriendTable._doTableCall create_table_dissolution ', self.voteHost, ' already dissolved...') return self.__vote_host = seatId self.__vote_info[seatId] = {'userId': userId, 'seatId': seatId, 'vote': self.DISSOLVE_AGREE} self.__vote_time_out = self.getTableConfig('dissolve_vote_time_out', 60) ftlog.debug('MajiangFriendTable.create_table_dissolution voteInfo:', self.voteInfo) # 广播解散投票消息 self.logic_table.msgProcessor.create_table_dissolve_vote(userId , seatId , self.maxSeatN , self.get_leave_vote_info() , self.get_leave_vote_info_detail() , self.logic_table.player[seatId].name , self.__vote_time_out , self.logic_table.getBroadCastUIDs()) elif action == 'user_leave_vote': ftlog.debug('MajiangFriendTable._doTableCall voteInfo:', self.voteInfo) if self.voteHost == MTDefine.INVALID_SEAT: ftlog.debug( 'MajiangFriendTable._doTableCall user_leave_vote, voteHost is invalid, no need process this message...') return vote = msg.getParam('vote', 0) self.__vote_info[seatId] = {'userId': userId, 'seatId': seatId, 'vote': vote} self.logic_table.msgProcessor.create_table_dissolve_vote(userId , seatId , self.maxSeatN , self.get_leave_vote_info() , self.get_leave_vote_info_detail() , self.logic_table.player[self.voteHost].name , self.__vote_time_out , self.logic_table.getBroadCastUIDs()) # 计算投票结果 self.dissolveDecision() elif action == 'create_friend_invite': # 微信邀请todotask下发 contentStr = ','.join(self.__params_desc) util.sendTableInviteShareTodoTask(userId , self.gameId , self.ftId , self.playMode , self.logic_table.tableConfig[MFTDefine.CARD_COUNT] , contentStr) elif action == 'friend_table_ready_time_out': # 准备超时,回收牌桌 self.clearTable(True) else: super(MajiangFriendTable, self)._doTableCall(msg, userId, seatId, action, clientId)
def doChuPai(self, player, cards, mcrc, tuoGuanType): ftlog.debug('doChuPai tid=', self.table.tableId, 'the mcrc=', mcrc, 'ccrc=', self.table.status.cardCrc, 'cards=', cards, 'mcrc=', mcrc, 'tuoGuanType=', tuoGuanType) if not player or self.table.status.state != DizhuState.TABLE_STATE_PLAYING: ftlog.warn('ERROR !!, doChuPai table.status=', self.table.status, player) return # 清理超时的次数 seat = self.table.seats[player.seatIndex] #seat.robotCardCount = 0 # 首先校验出牌的CRC if mcrc >= 0 and mcrc != self.table.status.cardCrc: ftlog.warn('doChuPai the ccrc error ! mcrc=', mcrc, 'ccrc=', self.table.status.cardCrc) self.sender.sendTableInfoRes(player.userId, player.clientId, 0) return # 托管出牌处理 ftlog.debug("doChuPai userId=", player.userId, "card=", cards, "tuoGuanType=", tuoGuanType) if tuoGuanType != DizhuPlayer.TUGUAN_TYPE_USERACT: cards = self.punish.doRobotAutoCard(player.seatId, tuoGuanType) # 出牌数据校验 canOutCard, cards = self._doChuPaiVerifyCard(player.seatId, cards) ftlog.debug('doChuPai tid=', self.table.tableId, 'canOutCard=', canOutCard, 'cards=', cards) if not canOutCard: ftlog.warn('ERROR cardOp verifyCard error') return if not cards and self.table.status.topSeatId == player.seatId: ftlog.warn( 'ERROR GameTable->doChuPai the top seat must chupai, but cards is none !' ) return precard = seat.cards[:] # 出牌牌型校验 validCards = self.card.validateCards(cards, None) delayNextStep = False if cards: if not validCards: ftlog.warn('ERROR GameTable->doChuPai the cards is invalid!', 'tableId=', self.table.tableId, 'seat=', (player.userId, player.seatId), 'cards=', cards) return # 如果是管牌,并且(牌型不对或者牌型管不住TOPCARD)则忽略出牌 if (self.table.status.topSeatId != 0 and self.table.status.topSeatId != player.seatId and (not validCards or not self._isGreaterThan( validCards, self.table.status.topCardList))): ftlog.warn('doChuPai seatId=', player.seatId, 'cards=', cards, 'topseat=', self.table.status.topSeatId, 'topcards=', self.table.status.topCardList, 'validCards=', validCards) cards = [] validCards = None if cards: if validCards: if validCards.isHuoJian(): # 火箭, 倍数翻倍 delayNextStep = True self.table.status.bomb += 1 seat.couponCard[0] += 1 elif validCards.isZhaDan(): # 炸弹, 倍数翻倍 delayNextStep = True self.table.status.bomb += 1 seat.couponCard[1] += 1 elif validCards.isFeiJiDai1() or validCards.isFeiJiDai2(): # 飞机 seat.couponCard[2] += 1 # 出牌处理 self._outCard(player, seat, cards) # 如果出的是火箭, 那么记录另外两个玩家的ID, 需要进行快速不出牌处理 if self.card.isDoubleKing(cards): for x in xrange(len(self.table.seats)): if x != player.seatIndex: self._doubleKingNoCard[x + 1] = 1 # 记录最后出牌的信息 seat.outCardCount += 1 self.table.status.topValidCard = validCards self.table.status.topCardList = cards self.table.status.topSeatId = player.seatId # 清除当前的计时器 ftlog.debug('doChuPai tid=', self.table.tableId, 'seat.cards=', seat.cards, 'topSeatId=', player.seatId, 'outCards=', cards) self.table.tableTimer.cancel() # 刷新上一次出牌 seat.lastOutCards = seat.outCards seat.outCards = cards # 发送出牌的响应消息 self.sender.sendChuPaiRes(player.seatId, player.userId, cards, precard, tuoGuanType) # 牌局记录器处理 self.table.gameRound.outCard(player.seatIndex, cards[:], self.calcCurTotalMulti()) # BI日志汇报 if TYPlayer.isRobot(player.userId): player.clientId = 'robot_3.7_-hall6-robot' bireport.reportCardEvent('TABLE_CARD', player.userId, self.table.gameId, self.table.roomId, self.table.tableId, self.table.gameRound.number, 0, 0, 0, cards, player.clientId, 0, 0) if delayNextStep: interval = dizhuconf.getPublic().get('bombNextDelay', 0) if interval > 0: FTTasklet.getCurrentFTTasklet().sleepNb(interval) self.nextStep(player)
def _doNext(self, isFirst): ftlog.debug('_doNext-->isFirst=', isFirst, 'self.table.status.nowOper=', self.table.status.nowOper) # 查找下一个出牌的玩家座位ID if isFirst == 0: # 非第一次出牌, 查找 nsid = self._findNextPlayerSeatId() else: # 第一次, 出牌, 固定为地主出牌 self.table.status.nowOper = self.table.status.diZhu nsid = self.table.status.nowOper if nsid <= 0: ftlog.warn('doNext can not found next player...') return ftlog.debug('_doNext-->isFirst=', isFirst, 'nsid=', nsid) # 出牌的简单的crc校验码处理 self.table.status.cardCrc += 1 self.table.status.nowOper = nsid # 出牌计时器处理 tuoGuanType = DizhuPlayer.TUGUAN_TYPE_USERACT autocard = 0 seat = self.table.seats[nsid - 1] opTime = self.table.runConfig.optimeFirst if isFirst else self.table.runConfig.optime opTime -= self.opTimePunishMatch(seat) if (seat.isRobot == 1) and TYPlayer.isHuman(seat.userId): # 如果是托管状态, 那么最短时间超时, 由超时处理中,处理是否出牌 tuoGuanType = DizhuPlayer.TUGUAN_TYPE_ALREADY_TUOGUAN latetime = self.table.runConfig.optimeAlreadyTuoGuan ftlog.debug('autocard 1...') autocard = 1 else: # 正常出牌超时控制 tuoGuanType = DizhuPlayer.TUGUAN_TYPE_TIMEOUT latetime = opTime # 只剩一张牌时,自动出牌 if len(seat.cards) == 1: tuoGuanType = DizhuPlayer.TUGUAN_TYPE_SYS_FAST_CARD latetime = self.table.runConfig.optimeOnlyOneCard ftlog.debug('autocard 2...') autocard = 1 # 如果上家出的是火箭, 那么自动不出牌 if nsid in self._doubleKingNoCard: tuoGuanType = DizhuPlayer.TUGUAN_TYPE_SYS_FAST_CARD latetime = self.table.runConfig.optimeDoubleKing ftlog.debug('autocard 3...') autocard = 1 del self._doubleKingNoCard[nsid] params = { 'tuoGuanType': tuoGuanType, 'seatId': nsid, 'userId': seat.userId, 'ccrc': self.table.status.cardCrc } ftlog.debug('params:', params, ' latetime:', latetime, ' autocard:', autocard) if autocard or (not TYPlayer.isRobot(seat.userId)): # 真实玩家启动出牌超时计时器 self.table.tableTimer.setup(latetime, 'CL_TIMEUP', params) # 牌局记录器处理 self.table.gameRound.next(nsid - 1, 0, opTime) if autocard: # 自动出牌, 不发送next消息 return # 发送下一个出牌的消息至客户端 self.sender.sendChuPaiNextRes(nsid, opTime)
def _doTableCall(self, msg, userId, seatId, action, clientId): """ 继承父类,处理table_call消息 单独处理自建桌的分享/解散 """ if not self.CheckSeatId(seatId, userId): ftlog.warn("MajiangFriendTable.doTableCall, delay msg action:", action, ' seatId:', seatId, ' messange:', msg) return if action == 'next_round': if self.logic_table.isStart(): return self.logic_table.sendMsgTableInfo(seatId) beginGame = self.logic_table.playerReady(seatId, True) self.logic_table.msgProcessor.create_table_succ_response( userId, seatId, 'ready', 1 if (userId == self.__table_owner) else 0, self.logic_table.getBroadCastUIDs()) for player in self.logic_table.player: if not player: continue if not TYPlayer.isHuman(player.userId): beginGame = self.logic_table.playerReady( player.curSeatId, True) if beginGame: # 纪录上一局的日志 给GM使用 # addOneResult(tableNo, seats, deltaScore, totalScore, curRound, totalRound, gameId, roomId, tableId) if self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] > 1: roundResult = self.logic_table.tableResult.results[-1] deltaScore = roundResult.score totalScore = self.logic_table.tableResult.score curRound = self.logic_table.tableConfig[ MFTDefine.CUR_ROUND_COUNT] - 1 totalRound = self.logic_table.tableConfig[ MFTDefine.ROUND_COUNT] seats = self.logic_table.getSeats() ftlog.debug( 'MajiangFriendTable.doTableCall nextRound stat tableNo', self.ftId, 'seats', seats, 'deltaScore:', deltaScore, 'totalScore:', totalScore, 'gameId:', self.gameId, 'roomId:', self.roomId, 'tableId', self.tableId) hall_friend_table.addOneResult(self.ftId, seats, deltaScore, totalScore, curRound, totalRound, self.gameId, self.roomId, self.tableId) else: ftlog.debug( 'MajiangFriendTable.doTableCall nextRound stat log error' ) else: ftlog.debug( 'MajiangFriendTable.doTableCall nextRound stat log error not begin' ) elif action == 'ready': # 返回房主建房成功消息,准备状态 # 玩家准备结束 游戏正式开始 beginGame = self.logic_table.playerReady(seatId, True) self.logic_table.msgProcessor.create_table_succ_response( userId, seatId, 'ready', 1 if (userId == self.__table_owner) else 0, self.logic_table.getBroadCastUIDs()) if beginGame and self.logic_table.tableConfig[ MFTDefine.CUR_ROUND_COUNT] > 0: # 纪录开局日志 gameBegin(tableNo, seats, gameId, roomId, tableId) seats = self.logic_table.getSeats() ftlog.debug( 'MajiangFriendTable._doTableCall log game begin tableNo:', self.__ftId, 'seats:', seats, 'gameId:', self.gameId, 'roomId:', self.roomId, 'tableId', self.tableId) hall_friend_table.gameBegin(self.__ftId, seats, self.gameId, self.gameId, self.tableId) else: ftlog.debug( 'MajiangFriendTable._doTableCall log game begin not ready cur round:', self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT]) elif action == 'create_table_user_leave': if (self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] > 0): util.sendPopTipMsg(userId, "游戏已开始,不能解散") return # 房主解散,由前端主动发送,存在隐患,后续修改。房主建房后,掉线,房主的房间状态将不对,TODO if userId == self.__table_owner: ftlog.debug( 'MajiangFriendTable.create_table_user_leave owner leave...' ) # 解散时,给大家提示 for player in self.logic_table.player: if not player: continue # 通知 util.sendPopTipMsg(player.userId, "房主解散房间") # 归还剩余房卡道具 ftlog.debug( 'MajiangFriendTable.doTableCall leftCardCount:', self.logic_table.tableConfig[MFTDefine.LEFT_CARD_COUNT], ' tableOwner:', self.__table_owner) if self.logic_table.tableConfig[MFTDefine.LEFT_CARD_COUNT] > 0: itemId = self.room.roomConf.get('create_item', None) if itemId: user_remote.resumeItemFromTable( self.__table_owner, self.gameId, itemId, self.logic_table.tableConfig[ MFTDefine.LEFT_CARD_COUNT], self.roomId, self.tableId) # 解散牌桌 self.clearTable(True) else: ftlog.debug( 'MajiangFriendTable.create_table_user_leave player leave...' ) util.sendPopTipMsg(userId, "您已退出房间") self.kickOffUser(userId, seatId, True) elif action == 'create_table_dissolution': if self.logic_table.tableConfig[MFTDefine.CUR_ROUND_COUNT] == 0: ftlog.debug( 'MajiangFriendTable._doTableCall create_table_dissolution game not start, can not dissolved...' ) return # 投票解散牌桌 if self.voteHost != MTDefine.INVALID_SEAT: ftlog.debug( 'MajiangFriendTable._doTableCall create_table_dissolution ', self.voteHost, ' already dissolved...') return self.__vote_host = seatId self.__vote_info[seatId] = { 'userId': userId, 'seatId': seatId, 'vote': self.DISSOLVE_AGREE } self.__vote_time_out = self.getTableConfig( 'dissolve_vote_time_out', 60) ftlog.debug( 'MajiangFriendTable.create_table_dissolution voteInfo:', self.voteInfo) # 广播解散投票消息 self.logic_table.msgProcessor.create_table_dissolve_vote( userId, seatId, self.maxSeatN, self.get_leave_vote_info(), self.get_leave_vote_info_detail(), self.logic_table.player[seatId].name, self.__vote_time_out, self.logic_table.getBroadCastUIDs()) elif action == 'user_leave_vote': ftlog.debug('MajiangFriendTable._doTableCall voteInfo:', self.voteInfo) if self.voteHost == MTDefine.INVALID_SEAT: ftlog.debug( 'MajiangFriendTable._doTableCall user_leave_vote, voteHost is invalid, no need process this message...' ) return vote = msg.getParam('vote', 0) self.__vote_info[seatId] = { 'userId': userId, 'seatId': seatId, 'vote': vote } self.logic_table.msgProcessor.create_table_dissolve_vote( userId, seatId, self.maxSeatN, self.get_leave_vote_info(), self.get_leave_vote_info_detail(), self.logic_table.player[self.voteHost].name, self.__vote_time_out, self.logic_table.getBroadCastUIDs()) # 计算投票结果 self.dissolveDecision() elif action == 'create_friend_invite': # 微信邀请todotask下发 contentStr = ','.join(self.__params_desc) util.sendTableInviteShareTodoTask( userId, self.gameId, self.ftId, self.playMode, self.logic_table.tableConfig[MFTDefine.CARD_COUNT], contentStr) elif action == 'friend_table_ready_time_out': # 准备超时,回收牌桌 self.clearTable(True) else: super(MajiangFriendTable, self)._doTableCall(msg, userId, seatId, action, clientId)
def doSitDown(self, userId, seatId, msg, clientId): """ 用户坐到某个桌子上,逻辑处理:如果是非重连用户,将用户坐下的消息广播给 其它已经坐下的用户,然后将当前的桌子信息发送给新来用户 继承自table类 这是的seatId为游戏的座位号 返回值: 1)是否做下 2)是否断线重连 """ ftlog.debug('>>MajiangQuickTable.doSitDown seatId =', seatId, ', userId = ', userId, ' tableId:', self.tableId) if (seatId != -1) and (userId != self.seats[seatId][TYSeat.INDEX_SEATE_USERID]): onlinedata.removeOnlineLoc(userId, self.roomId, self.tableId) ftlog.warn('reconnecting user id is not matched', 'seats =', self.seats, ' tableId:', self.tableId) return False frameSeatId = self.findIdleSeat(userId) ftlog.debug('MajiangQuickTable.doSitDown userId:', userId, ' findSeatId:', frameSeatId) sitRe = True if 0 == frameSeatId: ftlog.debug('MajiangQuickTable.doSitDown now seats:', self.seats) sendPopTipMsg(userId, '对不起,该房间已满员') self.logic_table.msgProcessor.quick_start_err(userId) sitRe = False elif 0 > frameSeatId: # 补发tableInfo seatId = self.getSeatIdByUserId(userId) if seatId < 0: onlinedata.removeOnlineLoc(userId, self.roomId, self.tableId) else: self.sendMsgTableInfo(msg, userId, seatId, True) elif frameSeatId > 0: isReady = self.getTableConfig(MTDefine.READY_AFTER_SIT, 0) gameSeatId = self.changeFrameSeatToMJSeatId(frameSeatId) # 设置座位的状态 self.seats[gameSeatId][TYSeat.INDEX_SEATE_USERID] = userId # 快速桌用户坐下就是准备状态 self.seats[gameSeatId][ TYSeat.INDEX_SEATE_STATE] = TYSeat.SEAT_STATE_READY if isReady else TYSeat.SEAT_STATE_WAIT # 添加玩家 tPlayer = TYPlayer(self, gameSeatId) self.players[gameSeatId] = tPlayer ftlog.debug('MajiangQuickTable.doSitDown user:'******' seat in:', gameSeatId , ' now seats:', self.seats , ' now playersNum:', self.playersNum) # 向牌桌添加用户:联网/机器人 if TYPlayer.isHuman(userId): locResult = onlinedata.addOnlineLoc(userId, self.roomId, self.tableId, frameSeatId) ftlog.info('MajiangQuickTable.doSitDown, add online loc userId:', userId , ' roomId:', self.roomId , ' tableId:', self.tableId , ' frameSeatId:', frameSeatId , ' locResult:', locResult) _name, _purl, _sex, _coin = userdata.getAttrs(userId, ['name', 'purl', 'sex', 'coin']) player = MPlayer(_name, _sex, userId, 0, _purl, _coin, clientId) # 快速桌 默认坐下就是准备状态 默认非托管状态 self.logic_table.addPlayer(player, gameSeatId, isReady, False) # 发送location消息 self.logic_table.msgProcessor.send_location_message(gameSeatId, userId) else: from difang.majiang2.resource import resource robot = resource.getRobotByUserId(userId) if robot: player = MPlayer(robot['name'], robot['sex'], userId, 0, robot['purl'], robot['coin']) # 机器人默认准备 默认托管状态 self.logic_table.addPlayer(player, gameSeatId, True, True) # 座位号调整,框架返回时进行了加1的操作,调整还原 self.room.updateTableScore(self.getTableScore(), self.tableId) self.sendMsgTableInfo(msg, userId, self.getSeatIdByUserId(userId), False) if self.playersNum != self.maxSeatN: # 一次召唤一个机器人 self.setTimerOfDispatchRobot() uids = self.logic_table.getBroadCastUIDs() self.logic_table.msgProcessor.sendTableEvent(self.playersNum, userId, gameSeatId, uids) else: # 人满了,启动定时器 self.setTimerHandleAutoDecideAction() return sitRe