def gainAssistance(self, gameId, userId): ''' 领取江湖救急 @param gameId: gameId @param userId: userId @return: consumeCount, finalCount, sendChip ''' # 检查金币数量是否符合领取江湖救急的条件 userAllChip = pkuserchip.getUserChipAll(userId) assistanceChipUpperLimit = self._vipSystem.getAssistanceChipUpperLimit() if userAllChip >= assistanceChipUpperLimit: raise TYAssistanceChipTooMuchException(userAllChip, assistanceChipUpperLimit) timestamp = pktimestamp.getCurrentTimestamp() # 发放江湖救急金 userAssets = hallitem.itemSystem.loadUserAssets(userId) _assetKind, consumeCount, final = userAssets.consumeAsset(gameId, 'game:assistance', 1, timestamp, 'VIP_GOT_ASSISTANCE', 0) assistanceChip = self._vipSystem.getAssistanceChip() if consumeCount >= 1 and assistanceChip > 0: pkuserchip.incrChip(userId, gameId, assistanceChip, pkdaoconst.CHIP_NOT_ENOUGH_OP_MODE_NONE, 'VIP_GOT_ASSISTANCE', 0, 0) ftlog.debug('TYUserVipSystemImpl.gainAssistance gameId=', gameId, 'userId=', userId, 'consumeCount=', consumeCount, 'assistanceChip=', assistanceChip) return consumeCount, final, assistanceChip
def getGoodCard(self, cardCountPerHand): """发一个人的好牌 """ count = self.getGoodCardCount(cardCountPerHand) ftlog.debug( 'count:', count ) color = random.randint(0, self.__card_count -1) cards = [] cLen = len(self.cardTiles[color]) if count > cLen: count = cLen # 发好牌 for _ in range(count): cards.append(self.cardTiles[color].pop(0)) # 发第二门 count1 = (cardCountPerHand - count) / 2 color = (color + 1) % self.__card_count for _ in range(count1): cards.append(self.cardTiles[color].pop(0)) # 发最后一门 left = cardCountPerHand - count - count1 color = (color + 1) % self.__card_count for _ in range(left): cards.append(self.cardTiles[color].pop(0)) return cards
def get_play_mode_config_by_clientId(clientId): """根据clientId获取自建桌支持的玩法列表""" key = 'room.other' intClientId = pokerconf.clientIdToNumber(clientId) play_mode_list = configure.getTcContentByClientId(key, None, intClientId, []) ftlog.debug('get_play_mode_config_by_clientId | clientId:', clientId, '| intClientId:', intClientId, '| play_mode_list:', play_mode_list) return play_mode_list
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 _initMysqlPool(name, dbhost, dbport, dbname, dbuser, dbpwd): ftlog.debug('MYSQL INIT : ', name, dbhost, dbport, dbname, dbuser, dbpwd) rconn = adbapi.ConnectionPool('pymysql', db=dbname, user=dbuser, passwd=dbpwd, host=dbhost, port=dbport, charset='utf8', use_unicode=True, cp_reconnect=True) mysql_pool_map[name] = rconn ftlog.debug('MYSQL', name, rconn)
def __notifyRobotSigninMatch(self, player): ftlog.debug("<< |roomId, instId, playerId :", self.roomId, player.inst.instId, player.userId, caller=self) # if hasattr(player.inst, "calledRobot") : #同一个比赛实例只召唤一次机器人 # return if player.inst.state >= player.inst.STATE_PREPARE: return if self.roomConf.get('hasrobot'): # player.inst.calledRobot = True #同一个比赛实例只召唤一次机器人 startConf = player.inst.conf.start if self.roomConf["robotUserMaxCount"] == -1: if startConf.isTimingType(): minsize = startConf.userMinCount else: minsize = startConf.userCount - 2 else: minsize = self.roomConf["robotUserMaxCount"] cur_p = len(player.inst.playerMap) if cur_p >= minsize: return mo = MsgPack() mo.setCmd('robotmgr') mo.setAction('callmatch') mo.setParam('gameId', self.gameId) mo.setParam('roomId', self.roomId) mo.setParam('robotCount', 4) router.sendRobotServer(mo, player.userId) func = functools.partial(self.__notifyRobotSigninMatch, player) FTTimer(15, func)
def enterFriendTable(self, userId, gameId, clientId, ftId): """进入自建桌,插件实现具体功能""" if ftlog.is_debug(): ftlog.debug('MAJIANG enterFriendTable userId:', userId , ' gameId:', gameId , ' clientId:', clientId , ' ftId:', ftId) tableId0, roomId0 = CreateTableData.getTableIdByCreateTableNo(ftId) if ftlog.is_debug(): ftlog.debug('MAJIANG enterFriendTable ftId:', ftId , ' roomId:', roomId0 , ' tableId:', tableId0) if not tableId0 or not roomId0: from difang.majiang2.entity.util import sendPopTipMsg sendPopTipMsg(userId, '您要进入的朋友场房间不存在,请核对房间号') return config = { "type": "game", "pluginParams": { "gameType": 11, "ftId": ftId } } todotask = TodoTaskEnterGameNew(GAMEID, config) mo = MsgPack() mo.setCmd('todo_tasks') mo.setResult('gameId', gameId) mo.setResult('pluginId', GAMEID) mo.setResult('userId', userId) mo.setResult('tasks', TodoTaskHelper.encodeTodoTasks(todotask)) router.sendToUser(mo, userId)
def checkCanTriggleFiveStartRate(userId, clientId, timestamp): ver, channelName = _parseClientId(clientId) channel = _channels.get(channelName) if ftlog.is_debug(): ftlog.debug('fivestarrate.checkCanTriggleFiveStartRate userId=', userId, 'clientId=', clientId, 'timestamp=', timestamp, 'channelName=', channelName, 'channel=', channel) if not channel: return False, None clientConf = hallconf.getFiveStarClientConf(clientId) if clientConf.get('disable', 0): if ftlog.is_debug(): ftlog.debug('fivestarrate.checkCanTriggleFiveStartRate userId=', userId, 'clientId=', clientId, 'timestamp=', timestamp, 'clientConf=', clientConf) return False, channel fsRate = _loadFiveStarRate(userId, channel) if _canPopFiveStarRate(userId, ver, fsRate, timestamp): return True, channel return False, channel
def addUserItemByKindId(cls, userId, gameId, clientId, kindId, count): timestamp = pktimestamp.getCurrentTimestamp() userAssets = hallitem.itemSystem.loadUserAssets(userId) calcGameId = strutil.getGameIdFromHallClientId(clientId) userAssets.addAsset(calcGameId, kindId, count, timestamp, 'MAJIANG_FANGKA_INVITE_REWARD', 0) datachangenotify.sendDataChangeNotify(gameId, userId, 'item') ftlog.debug('addUserItemByKindId userId:', userId, ' gameId:', gameId, 'kindId', kindId, 'count', count)
def checkin(self, gameId, userId, timestamp=None): ''' @return: checkinOk, checkinDays ''' if timestamp is None: timestamp = pktimestamp.getCurrentTimestamp() status = self._dao.loadStatus(userId) checkinDays, canCheckin = self.calcCheckinState(status, timestamp) if canCheckin and self.isScriptDoGetReward(userId): canCheckin = 0 if ftlog.is_debug(): ftlog.debug('TYDailyCheckin.checkin gameId=', gameId, 'userId=', userId, 'timestamp=', datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S'), 'checkinDays=', checkinDays, 'canCheckin=', canCheckin, 'firstCheckinTime=', status.firstCheckinTime if status else None, 'lastCheckinTime=', status.lastCheckinTime if status else None) if not canCheckin: return 0, checkinDays if not status: status = TYDailyCheckinStatus(timestamp, timestamp) else: status.lastCheckinTime = timestamp if checkinDays == 0: status.firstCheckinTime = timestamp self._dao.saveStatus(userId, status) ftlog.debug('TYDailyCheckin.checkin ok gameId=', gameId, 'userId=', userId, 'timestamp=', datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')) return 1, checkinDays
def getAllDropTilesInGrabTing(self): """获取所有的听牌解""" dropTiles = [] tingInfos = None if self.GRAB_CHI_TING in self.__extend: tingInfos = self.__extend[self.GRAB_CHI_TING][0][self.TING] if self.GRAB_PENG_TING in self.__extend: tingInfos = self.__extend[self.GRAB_PENG_TING][0][self.TING] if self.GRAB_GANG_TING in self.__extend: tingInfos = self.__extend[self.GRAB_GANG_TING][0][self.TING] if self.GRAB_ZHAN_TING in self.__extend: tingInfos = self.__extend[self.GRAB_ZHAN_TING][0][self.TING] if not tingInfos: return dropTiles ftlog.debug('getWinNodesByDropTile tingInfos:', tingInfos) for tingSolution in tingInfos: dropTiles.append(tingSolution['dropTile']) ftlog.debug('MTableStateExtendInfo.getAllDropTilesInGrabTing dropTiles:', dropTiles) return dropTiles
def connect_agent_eachother(server_id): """ Agent进程调用,监听自己的端口,并与其他Agent建立连接 """ ftlog.debug('connect_agent_eachother', server_id) myconf = ftcon.server_map[server_id] myip = myconf['ip'] agentids = ftcon.server_type_map.get('AG', None) for agentid in agentids: agent = ftcon.server_map.get(agentid, None) ip = agent['ip'] inner_port = agent['protocols']['server']['a2s'] outer_port = agent['protocols']['server']['a2a'] if agentid == server_id: # listen inner port for inner process factory = Factory() factory.protocol = A2SProtocol reactor.listenTCP(inner_port, factory) ftlog.info('Agent Start, listen for services port', inner_port) # listen outer port for other agent factory = Factory() factory.protocol = A2AProtocol reactor.listenTCP(outer_port, factory) ftlog.info('Agent Start, listen for agent port', outer_port) else: # 只连接比自己的ID大的agent,这样节省一半的连接,n*(n-1)/2 if cmp(agentid, server_id) > 0: factory = FTReconnectFactory() factory.protocol = A2AProtocol if ip == myip: ip = '127.0.0.1' reactor.connectTCP(ip, outer_port, factory) ftlog.info('Agent connect Agent', agentid, server_id)
def uploadVideo(uploadUrl, token, uploadPath, videoData): filename = os.path.basename(uploadPath) formItems = [] formItems.append(FormItemData('token', token)) formItems.append(FormItemData('key', uploadPath)) formItems.append(FormItemFile('file', videoData, filename)) # formItems.append(FormItemFile('fileBinaryData', videoData, filename)) boundary = genBoundary() uploadData = encodeFormItems(boundary, formItems) headers = { 'Content-Type': ['multipart/form-data; charset=utf-8; boundary=%s' % (boundary)] } try: code, body = http.runHttp(method='POST', url=uploadUrl, header=headers, body=uploadData, connect_timeout=5, timeout=5) if ftlog.is_debug(): ftlog.debug('uploader.uploadVideo uploadUrl=', uploadUrl, 'uploadPath=', uploadPath, 'token=', token, 'ret=', (code, body)) if code == 200: return 0, body ftlog.info('uploader.uploadVideo Res uploadUrl=', uploadUrl, 'uploadPath=', uploadPath, 'token=', token, 'ret=', code) return -1, '上传失败' except: return -2, '上传失败'
def onTimer(self, event): if self.isbusy == 0: # 已经关闭 return dws = [] dwq = [] for x in xrange(len(self._delayWrite)): dw = self._delayWrite[x] dw[0] = dw[0] - 1 if dw[0] <= 0: dws.append(dw[1]) else: dwq.append(dw) self._delayWrite = dwq self._onTimer(event) # 执行延迟时间到时的发送消息 for msg in dws: try: self.writeMsg(msg) except: ftlog.error() self.stop() return # 执行延迟时间到时的事件 mqueue = self._msgQueue ftlog.debug('timer hc=', event.count, 'len(mqueue)=', len(mqueue)) if len(mqueue) > 0: self._msgQueue = [] for msg in mqueue: self.onMsg(msg) if not self.isbusy: return
def isPairs(cls, tiles, magicTiles): if len(tiles[MHand.TYPE_CHI]) != 0: return False if len(tiles[MHand.TYPE_PENG]) != 0: return False if len(tiles[MHand.TYPE_GANG]) != 0: return False pairTiles = copy.deepcopy(tiles[MHand.TYPE_HAND]) haveMagicCount = 0 for magicTile in magicTiles: while magicTile in pairTiles: pairTiles.remove(magicTile) haveMagicCount += 1 ftlog.debug("win_rule_zhaotong::isPairs pairTiles = ", pairTiles, "haveMagicCount =", haveMagicCount) tileArr = MTile.changeTilesToValueArr(pairTiles) for count in tileArr: if count % 2 == 0: continue else: if haveMagicCount <= 0: return False else: haveMagicCount -= 1 continue return True
def loginGame(userId, gameId, clientId, iscreate, isdayfirst): """ 用户登录一个游戏, 游戏自己做一些其他的业务或数据处理 """ ftlog.debug('userId =', userId, 'gameId =', gameId, 'clientId =', clientId, 'iscreate =', iscreate, 'isdayfirst =', isdayfirst) if isdayfirst: gamedata.setGameAttr(userId, gameId, "day_play_game_count", 0)
def saveToGameData(cls, userId, gameDataKey, replayKey, gameId): """ 往gamedata下添加数据 """ replayDBKey = 'replay:%s' % (gameId) ftlog.debug("MJCreateTableRecord_saveToGameData userId", userId , "gameDataKey", gameDataKey , "replayKey", replayKey , "replayDBKey", replayDBKey) if daobase.executeUserCmd(userId, 'HEXISTS', gameDataKey, 'game_record'): ftlog.debug("MJCreateTableRecord_saveToGameData1") recordData = daobase.executeUserCmd(userId, 'HGET', gameDataKey, 'game_record') ftlog.debug("MJCreateTableRecord_saveToGameData2,recordData type = ", type(recordData), "content =", recordData) recordList = json.loads(str(recordData)) ftlog.debug("MJCreateTableRecord_saveToGameData2,recordList type = ", type(recordList), "content =", recordList) if recordList and isinstance(recordList, dict): while len(recordList['recordIndex']) >= 20: wastedReplayKey = recordList['recordIndex'].pop(0) hasKey = daobase.executeRePlayCmd('HEXISTS', replayDBKey, wastedReplayKey) if hasKey: daobase.executeRePlayCmd('HDEL', replayDBKey, wastedReplayKey) recordList['recordIndex'].append(replayKey) ftlog.debug("MJCreateTableRecord_saveToGameData3") daobase.executeUserCmd(userId, 'HSET', gameDataKey, 'game_record', json.dumps(recordList)) else: recordData = {"recordIndex": []} recordData['recordIndex'].append(replayKey) daobase.executeUserCmd(userId, 'HSET', gameDataKey, 'game_record', json.dumps(recordData))
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 getWinNodesByDropTile(self, dropTile): tingInfos = None if self.TING in self.__extend: tingInfos = self.__extend[self.TING] if self.GRAB_CHI_TING in self.__extend: tingInfos = self.__extend[self.GRAB_CHI_TING][0][self.TING] if self.GRAB_PENG_TING in self.__extend: tingInfos = self.__extend[self.GRAB_PENG_TING][0][self.TING] if self.GRAB_GANG_TING in self.__extend: tingInfos = self.__extend[self.GRAB_GANG_TING][0][self.TING] if self.GRAB_ZHAN_TING in self.__extend: tingInfos = self.__extend[self.GRAB_ZHAN_TING][0][self.TING] if not tingInfos: ftlog.error('getWinNodesByDropTile tingInfos is None, need check:', self.__extend) return None ftlog.debug('getWinNodesByDropTile tingInfos:', tingInfos) for tingSolution in tingInfos: if tingSolution['dropTile'] == dropTile: return tingSolution['winNodes'] return None
def getConf(userId, gameId, clientId): _skinsConf = hallconf.getCustomSkinsConf() skinsTemplate = _skinsConf.get('templates', {}) if ftlog.is_debug(): ftlog.debug('customSkins conf =', skinsTemplate.get('default', {})) result = decodeConf(userId, gameId, clientId, skinsTemplate.get('default', {})) return result
def getGrabTingAction(self, tingInfo, seatId, tableTileMgr, withHandTiles = False): """获取消息中需要的听牌通知""" ting_action = [] tings = tingInfo.get('ting', []) for tingNode in tings: ting = [] ting.append(tingNode['dropTile']) tips = [] winNodes = tingNode['winNodes'] for node in winNodes: tip = [] tip.append(node['winTile']) #tip.append(1)#番数 TODO tip.append(node['result']) dropCount = 0 #宝牌中的也算 abandoneMagicTiles = tableTileMgr.getAbandonedMagics() if (node['winTile'] in abandoneMagicTiles): dropCount +=1 dropCount += tableTileMgr.getVisibleTilesCount(node['winTile'],withHandTiles,seatId) tip.append(4 - dropCount)# 数量 tips.append(tip) ting.append(tips) ting_action.append(ting) ftlog.debug('MajiangTable.getTingAction seatId:', seatId, ' return ting_action:', ting_action) return ting_action
def _exchange(self, gameid, userid, actkey, exchangeid): info = self._exchanges.get(exchangeid) if not info: return {'result': 'fail', 'tip': "unknown productId"} buynum = self.get_exchange_buynum(userid, actkey, info) if buynum >= info['limitTimes']: return {'result': 'fail', 'tip': '兑换次数已满'} if not self.alter_user_credit(userid, actkey, -info['price']): return {'result': 'fail', 'tip': '您的积分不足'} daobase.executeUserCmd(userid, 'HINCRBY', actkey, self.FIELD_EXCHANGE_NUM.format(exchangeid), 1) userAssets = hallitem.itemSystem.loadUserAssets(userid) assetList = userAssets.sendContent(gameid, info['content'], 1, True, timestamp.getCurrentTimestamp(), "ACTIVITY_CREDIT_EXCHANGE", exchangeid) response = self._query(userid, actkey) ftlog.debug('TYActCreditExchange._exchange gameId=', gameid, 'userId=', userid, 'activityId=', self.getid(), 'reward=', TYAssetUtils.buildContents(assetList), 'buynum=', buynum + 1, 'credit=', response['credit']) changeNames = TYAssetUtils.getChangeDataNames(assetList) datachangenotify.sendDataChangeNotify(gameid, userid, changeNames) response['result'] = 'ok' response['tip'] = '兑换成功,您获得' + TYAssetUtils.buildContentsString(assetList) return response
def get_kvs(cls, tasklet, uid, gid): ''' attrs = ['lastlogin', 'nslogin', 'play_game_count', 'win_game_count', 'draw_game_count', 'lose_game_count', 'bang_count', 'highest_lose_chip', 'highest_win_chip', 'highest_chip_record', 'day_win_game_count', 'day_win_sequence_count', 'day_max_win_sequence_count', 'big_pattern_history', 'best_pattern', 'online_records', 'guobiao_play_game_count', 'guobiao_win_game_count', 'guobiao_draw_game_count', 'guobiao_lose_game_count', 'guobiao_bang_count', 'guobiao_highest_lose_chip', 'guobiao_highest_win_chip', 'guobiao_highest_chip_record', 'win_sequence_count', 'max_win_sequence_count', 'guobiao_best_pattern', 'guobiao_online_records', 'max_degree_week_duration', 'max_degree_week_duration_ts', 'master_point', 'week_master_point', 'week_master_point_ts', 'day_play_game_count'] ''' attrs = ['win_sequence_count', 'max_win_sequence_count', 'guobiao_best_pattern'] values = gamedata.getGameAttrs(uid, gid, attrs) for i, value in enumerate(values): if value is None: ftlog.debug(attrs[i], 'is None') values[i] = cls.get_default_value(attrs[i])[1] else: values[i] = cls.parse_content_from_redis(attrs[i], value) kvs = dict(zip(attrs, values)) cls.check_attrs_timestamp(tasklet, uid, gid, kvs) kvs['chip'] = userchip.getChip(uid) kvs['exp'] = userdata.getExp(uid) kvs['charm'] = userdata.getCharm(uid) if not kvs['chip']: kvs['chip'] = 0 if not kvs['exp']: kvs['exp'] = 0 if not kvs['charm']: kvs['charm'] = 0 return kvs
def doSomeLogic(self): if not startup.IS_INIT_OK: print 'not init OK !!' try: self.finish() except: pass return try: taskarg = ftsvr.getTaskRunArg() heads = str(taskarg["userheader1"]) ftlog.debug('WriteTcpRequest 1->', taskarg, heads) _type, _group, rec_id = heads.split('_') global_conf = ftcon.getConf("freetime:global") data_dir = global_conf["data_path"] type_conf = ftcon.getConf("freetime:log_type") log_conf = type_conf[_type] rec_type = int(log_conf["rec_type"]) reserved_size = int(log_conf["reserved_size"]) log_size = int(log_conf["record_size"]) + reserved_size + self.EXTRA_SIZE record_count = log_conf["single_file_record_count"] body = base64.b64decode(taskarg["pack"]) ftlog.debug('WriteTcpRequest 2->', body) cur_time = int(time.time()) record = "tu" + struct.pack("<BIQ", rec_type, cur_time, int(rec_id)) + body + struct.pack( "<%ds" % reserved_size, str()) + "yo" self.writeFile(data_dir, _type, _group, int(rec_id), record_count, log_size, record) except: ftlog.error() finally: try: self.finish() except: pass
def onTableChat(self, gameId, msg): if ftlog.is_debug(): ftlog.debug("<< |msg", msg, caller=self) table = msg.getParam("table") userId = msg.getParam("userId") seatIndex = msg.getParam("seatId") isFace = msg.getParam("isFace") voiceIdx = msg.getParam("voiceIdx") chatMsg = msg.getParam("msg") player = table.players[seatIndex] if player.userId != userId: ftlog.warn(table._baseLogStr("onTableChat player.userId != userId!", userId), "|seatIndex, player:", seatIndex, player.userId, caller=self) return False if isFace == 0: # 纯文本内容 chatMsg = keywords.replace(chatMsg[:80]) # 80个字符长度限制 if difangConf.isEnableLogChatMsg(gameId): hallchatlog.reportChatLog(userId, chatMsg, self.gameId, table.roomId, table.tableId, seatIndex, userName=player.name, roomName=table.room.roomConf.get('name')) ftlog.info('onTableChat |gameId, tableId, userId, name, chatMsg:', gameId, table.tableId, player.userId, player.name, chatMsg, caller=self) self.sendTableChatResToAll(table, player, isFace, voiceIdx, chatMsg)
def makeTodoTaskZhuanyun_(gameId, userId, clientId, benefitsSend, userBenefits, roomId): from hall.entity import hallproductselector if ftlog.is_debug(): ftlog.debug('hallpopwnd.makeTodoTaskZhuanyun gameId=', gameId, 'userId=', userId, 'clientId=', clientId, 'benefitsSend=', benefitsSend, 'userBenefits=', userBenefits.__dict__, 'roomId=', roomId) clientOs, _clientVer, _ = strutil.parseClientId(clientId) clientOs = clientOs.lower() if clientOs != 'winpc': return TodoTaskHelper.makeZhuanyunTodoTaskNew(gameId, userId, clientId, benefitsSend, userBenefits, roomId) product, _ = hallproductselector.selectLessbuyProduct(gameId, userId, clientId, roomId) if not product: return None user_diamond = pkuserdata.getAttr(userId, 'diamond') if user_diamond >= int(product.priceDiamond): chip = product.getMinFixedAssetCount(hallitem.ASSET_CHIP_KIND_ID) show_str = u'运气不好,来个转运礼包!%s元得%s万金币。' % (product.price, chip) buy_type = 'consume' btn_txt = u'兑换' else: show_str = u'运气不好~,买点金币战个痛快吧!' buy_type = 'charge' btn_txt = u'去充值' orderShow = TodoTaskOrderShow.makeByProduct(show_str, '', product, buy_type) orderShow.setParam('sub_action_btn_text', btn_txt) return orderShow
def user_to_get_gift(self, userId, gameId, clientId): ''' 领红包 ''' ftlog.debug("user_to_get_gift..begin") return doGetGift(userId, gameId, clientId)
def doWinlose(self, msg): tableId = msg.getParam('tableId', 0) if ftlog.is_debug(): ftlog.debug('TYRelaxationMatchRoom.doWinlose', 'tableId=', tableId) userWinloseList = msg.getParam('users') assert (isinstance(userWinloseList, list)) for userWinlose in userWinloseList: userId = userWinlose.get('userId', 0) seatId = userWinlose.get('seatId', 0) isWin = userWinlose.get('isWin', 0) deltaScore = userWinlose.get('deltaScore', 0) if userId > 0: if ftlog.is_debug(): ftlog.debug('TYRelaxationMatchRoom.doWinlose', 'tableId=', tableId, 'userId=', userId, 'seatId=', seatId, 'deltaScore=', deltaScore, 'isWin=', isWin) player = self.match.findPlayer(userId) self.match.winlose(player, deltaScore, isWin) # 归还桌子以及更新比赛排名 table = self.match.findTable(tableId) if table: self.match.tableController.notifyTableClearTable(table) self.match.returnTable(table)
def shuffle(self, goodPointCount, handTileCount, piguTrick=[]): """ 洗牌器 添加特殊逻辑,宝牌 """ super(MTableTileJixi, self).shuffle(goodPointCount, handTileCount) ftlog.debug('MTableTileJixi.shuffle changed tile:', self.__magic_tile)
def adjustTablePlayers(self, msg): '''一局游戏结束, 调整牌桌玩家,拆桌或者拉人''' tableId = msg.getParam("tableId") playersN = msg.getParam("playersN") cardLevel = msg.getParam("cardLevel") isWinner = msg.getParam("isWinner") if ftlog.is_debug(): ftlog.debug("<<", self.baseLogStr(tableId), '|msg:', msg, caller=self) if playersN == 3: # 三缺一 for userId in self.users: if self.users[userId].get("teamMate") == None and \ self.users[userId]["isWinner"] != isWinner and \ self.users[userId]["cardLevel"] == cardLevel: self._startTable(tableId, [userId], cardLevel) return elif playersN == 2: # 缺对手 for userId in self.users: teamMate = self.users[userId].get("teamMate") if teamMate != None and \ self.users[userId]["isWinner"] != isWinner and \ self.users[userId]["cardLevel"] == cardLevel: self._startTable(tableId, [userId, teamMate], cardLevel) return # 拉人失败,通知GT拆桌 self._recycleTable(tableId)
def onSitOk(self, userId, idleSeatId, result): '''坐下条件成功后的处理 Return: player:新空座位上的player ''' ftlog.hinfo('onSitOk << |userId, tableId, seatId:', userId, self.tableId, idleSeatId, "|observers:", self.observers, caller=self) # 设置玩家坐在座位上, 为了支持并发坐下,此设置需要在异步操作前完成!!! seat = self.table.seats[idleSeatId - 1] seat.userId = userId seat.setWaitingState() if ftlog.is_debug(): ftlog.debug("|seats:", self.table.seats, caller=self) if userId in self.table.observers: del self.table.observers[userId] onlinedata.removeOnlineLoc(userId, self.roomId, self.tableId) # 设置玩家的在线状态 if ftlog.is_debug(): ftlog.debug("before addOnlineLoc. |tableId, onlineSeatId:", self.tableId, onlinedata.getOnlineLocSeatId(userId, self.roomId, self.tableId), caller=self) onlinedata.addOnlineLoc(userId, self.roomId, self.tableId, idleSeatId) if ftlog.is_debug(): ftlog.debug("after addOnlineLoc. |tableId, onlineSeatId:", self.tableId, onlinedata.getOnlineLocSeatId(userId, self.roomId, self.tableId), caller=self) # 记录当前座位的userId, 以便对玩家的金币做恢复处理 self.table.recordSeatUserId(idleSeatId, userId) result["seatId"] = idleSeatId result["reason"] = TYRoom.ENTER_ROOM_REASON_OK ftlog.hinfo('onSitOk >> |userId, tableId, seatId:', userId, self.tableId, idleSeatId, "|observers:", self.observers, caller=self)
def updateRankScore(cls, userId, timestamp): ''' 更新排行分数 :param timestamp: 时间戳 :param rmb: 活动期间RMB消费总数 :param dashifen: 活动期间大师分增长数量 ''' ## record top 10 recorder = RankingTopNRecorder() recorder.recordTopN(10) if not recorder.oldRankingList: ftlog.debug("DumplingsUtil.updateRankScore: ", "userId=", userId, "err=", "NotOldRankingList") return score = cls.getScoreNum(userId) hallranking.rankingSystem.setUserByInputType( 6, cls.RANK_TYPE_DDZ_DUMPLINGS, userId, score, timestamp) ftlog.debug("DumplingsUtil.updateRankScore: ", "userId=", userId, "score=", score) ## diff top 10 newRankingUser, oldRankingUser = recorder.updateHasChange() ftlog.debug("DumplingsUtil.updateRankScore: updateHasChange()", "userId=", userId, "newRankingUser="******"oldRankingUser=", oldRankingUser) if newRankingUser and oldRankingUser: RankingPriorityLedSender.addingLed(newRankingUser, oldRankingUser) # 积分发奖类型,自动实时发奖 cls._creditTypeSendRewardsIfNeed(userId) # 日志记录 OnlineLogging.loggingCredit(userId)
def _moveChipToTablechipBuyUser(userId, roomId, tableId, seatId, isSupportBuyin, buyinChip, minCoin, clientId): ftlog.debug( '_moveChipToTablechipBuyUser->userId, roomId, tableId, seatId, isSupportBuyin, buyinChip=', userId, roomId, tableId, seatId, isSupportBuyin, buyinChip, clientId) if isSupportBuyin: # 坐下操作, 进行带入金币操作 isbuyinall = dizhuconf.getIsTableBuyInAll(clientId) ftlog.debug('_moveChipToTablechipBuyUser->isbuyinall=', isbuyinall) if isbuyinall or buyinChip <= 0: chip, user_chip_final, delta_chip = userchip.moveAllChipToTableChip( userId, DIZHU_GAMEID, 'TABLE_SITDOWN_SET_TCHIP', roomId, clientId, tableId) else: minchip = min(minCoin, buyinChip) maxchip = max(minCoin, buyinChip) chip, user_chip_final, delta_chip = userchip.setTableChipToRange( userId, DIZHU_GAMEID, minchip, maxchip, 'TABLE_SITDOWN_SET_TCHIP', roomId, clientId, tableId) ftlog.debug( '_moveChipToTablechipBuyUser->userId, roomId, tableId, chip, user_chip_final, delta_chip=', userId, roomId, tableId, chip, user_chip_final, delta_chip) else: chip = userchip.getChip(userId) return chip
def isAnsigui(self): """ 暗四归:默认为半频道 半频道:手上有三张一样的字,这三张字必须是只能在手上,胡第四张,胡的牌型不是七对 全频道:手里有四张一样的字,或者有三张一样在手上胡第四张,胡的牌型不是七对,都算暗四归 """ # 默认为半频道 pinDao = self.tableConfig.get(MTDefine.PIN_DAO, 2) handTileCountArr = [0 for _ in range(MTile.TILE_MAX_VALUE)] for tile in self.__player_hand_tiles_with_hu[self.winSeatId]: handTileCountArr[tile] += 1 if pinDao == 1: for handTileCount in handTileCountArr: if handTileCount == 4: ftlog.debug('MKawuxingOneResult.isAnsigui result: True') return True elif pinDao == 2 and handTileCountArr[self.winTile] == 4: ftlog.debug('MKawuxingOneResult.isAnsigui result: True') return True ftlog.debug('MKawuxingOneResult.isAnsigui result: False') return False
def updateProcessor(self, actionID, seatId, state, tile, pattern=None): """ 用户做出了选择,state为0,表示放弃 用户的选择集合明确 """ if actionID != self.actionID: # 不是本轮处理的牌 ftlog.debug('timeout dropcard processor update') return False ftlog.debug('MQiangGangHuProcessor.updateProcessor actionID:', actionID, ' seatId:', seatId, ' state:', state, ' tile:', tile) # if self.__processors[seatId]['response'] == 0: # # 已经做过选择,再发送过来就不处理了 # ftlog.debug( 'MQiangGangHuProcessor.updateProcessor response = 0, already responsed' ) # return False self.__processors[seatId]['state'] = state # 用户已做出选择 self.__processors[seatId]['response'] = 0 ftlog.debug('MQiangGangHuProcessor.updateProcessor end:', self.__processors) return self.isBiggestPriority(state, seatId)
def _reloadConf(): global _lnConfig _lnConfig = hallconf.getLocalNotificationConf() ftlog.debug( 'halllocalnotification._reloadConf successed local_notification=', _lnConfig)
def getChestRewards(userId, chestId): """ 获取宝箱物品 """ rewards = [] chestConf = config.getChestConf(chestId) if not chestConf: ftlog.error("getChestRewards error", userId, chestId) return rewards # 计算金币、珍珠个数 coinCount = random.randint(chestConf["coinRange"][0], chestConf["coinRange"][1]) pearlCount = random.randint(chestConf["pearlRange"][0], chestConf["pearlRange"][1]) if coinCount > 0: coin = {"name": CHIP_KINDID, "count": coinCount} rewards.append(coin) if pearlCount > 0: pearl = {"name": PEARL_KINDID, "count": pearlCount} rewards.append(pearl) # 根据宝箱物品等级确定物品范围 chestDropList = getChestDropList(chestConf) # 根据稀有度划分技能卡片、技能升星卡、火炮皮肤、(黄/紫)水晶 skillCardRareMap = {} starCardRareMap = {} gunSkinPile = [] crystalItems = [] for chestDrop in chestDropList: chestDropType = dict(chestDrop)["type"] if chestDropType == ItemType.Skill: rare = dict(chestDrop)["rare"] skillCardRareMap.setdefault(rare, []).append(chestDrop) elif chestDropType == ItemType.Star: rare = dict(chestDrop)["rare"] starCardRareMap.setdefault(rare, []).append(chestDrop) elif chestDropType == ItemType.GunSkin: gunSkinPile.append(chestDrop) elif chestDropType == ItemType.Crystal: crystalItems.append(chestDrop) if ftlog.is_debug(): ftlog.debug("getChestRewards->skillCardRareMap =", skillCardRareMap, "starCardRareMap =", starCardRareMap) # 确定技能卡片概率、随机次数、最小数、最大数 nCardRate = 1 if random.randint(1, 10000) <= chestConf["nCardRate"] else 0 rCardRate = 1 if random.randint(1, 10000) <= chestConf["rCardRate"] else 0 srCardRate = 1 if random.randint(1, 10000) <= chestConf["srCardRate"] else 0 skillCardRare = {1: [nCardRate, chestConf["nCardRandom"], chestConf["nCardRange"][0], chestConf["nCardRange"][1]], 2: [rCardRate, chestConf["rCardRandom"], chestConf["rCardRange"][0], chestConf["rCardRange"][1]], 3: [srCardRate, chestConf["srCardRandom"], chestConf["srCardRange"][0], chestConf["srCardRange"][1]]} if ftlog.is_debug(): ftlog.debug("getChestRewards->skillCardRare =", skillCardRare) # 非水晶宝箱第一次开宝箱必定出合金飞弹技能卡片(已废弃2020.09.25) # openChestCount = gamedata.getGameAttr(userId, FISH_GAMEID, GameData.openChestCount) # if not util.isCrystalChest(chestId) and not openChestCount: # itemList = [{"name": 1145, "count": 1}] # rewards = _mergeItemList(rewards, itemList) # ftlog.debug("getChestRewards->assignCardList =", rewards) # 根据权重随机出具体的技能卡片 for rare, skillCardDropList in skillCardRareMap.iteritems(): if not skillCardRare[rare][0]: continue for randomCount in xrange(skillCardRare[rare][1]): minSkillCard = skillCardRare[rare][2] maxSkillCard = skillCardRare[rare][3] skillCardList = _randomItemInWeight(skillCardDropList, minSkillCard, maxSkillCard) rewards = _mergeItemList(rewards, skillCardList) if ftlog.is_debug(): ftlog.debug("getChestRewards->skillCardList =", rewards) # 判断是否达到保底条件,给予指定稀有度范围且保底数量的随机技能卡片 if chestConf["cardCertain"]: skillCardDropList = [] for rare in chestConf["cardCertainRateRange"]: skillCardDropList.extend(skillCardRareMap.get(rare, [])) skillCardIdList = [skillCardDrop["kindId"] for skillCardDrop in skillCardDropList if skillCardDrop] rewardList = [reward["name"] for reward in rewards if reward] if skillCardIdList and not (set(skillCardIdList) & set(rewardList)): cardCertainList = [{"name": random.choice(skillCardIdList), "count": chestConf["cardCertainNum"]}] rewards = _mergeItemList(rewards, cardCertainList) if ftlog.is_debug(): ftlog.debug("getChestRewards->cardCertainList =", cardCertainList) # 确定技能升星卡片概率、随机次数、最小数、最大数 nStarCardRate = 1 if random.randint(1, 10000) <= chestConf["nStarCardRate"] else 0 rStarCardRate = 1 if random.randint(1, 10000) <= chestConf["rStarCardRate"] else 0 srStarCardRate = 1 if random.randint(1, 10000) <= chestConf["srStarCardRate"] else 0 starCardRare = {1: [nStarCardRate, chestConf["nStarCardRandom"], chestConf["nStarCardRange"][0], chestConf["nStarCardRange"][1]], 2: [rStarCardRate, chestConf["rStarCardRandom"], chestConf["rStarCardRange"][0], chestConf["rStarCardRange"][1]], 3: [srStarCardRate, chestConf["srStarCardRandom"], chestConf["srStarCardRange"][0], chestConf["srStarCardRange"][1]]} if ftlog.is_debug(): ftlog.debug("getChestRewards->starCardRare =", starCardRare) # 根据权重随机出具体的技能升星卡片 for rare, starCardDropList in starCardRareMap.iteritems(): if not starCardRare[rare][0]: continue for randomCount in xrange(starCardRare[rare][1]): minStarCard = starCardRare[rare][2] maxStarCard = starCardRare[rare][3] starCardList = _randomItemInWeight(starCardDropList, minStarCard, maxStarCard) rewards = _mergeItemList(rewards, starCardList) if ftlog.is_debug(): ftlog.debug("getChestRewards->starCardList =", rewards) # 判断是否达到保底条件,给予指定稀有度范围且保底数量的随机技能升星卡片 if chestConf["starCardCertain"]: starCardDropList = [] for rare in chestConf["starCardCertainRateRange"]: starCardDropList.extend(starCardRareMap.get(rare, [])) starCardIdList = [starCardDrop["kindId"] for starCardDrop in starCardDropList if starCardDrop] rewardList = [reward["name"] for reward in rewards if reward] if starCardIdList and not (set(starCardIdList) & set(rewardList)): starCardCertainList = [{"name": random.choice(starCardIdList), "count": chestConf["starCardCertainNum"]}] rewards = _mergeItemList(rewards, starCardCertainList) if ftlog.is_debug(): ftlog.debug("getChestRewards->starCardCertainList =", starCardCertainList) # 确定火炮皮肤概率、随机次数、最小数、最大数 gunSkinRate = 1 if random.randint(1, 10000) <= chestConf["gunSkinRate"] else 0 gunSkinRare = [gunSkinRate, chestConf["gunSkinRandom"], chestConf["gunSkinRange"][0], chestConf["gunSkinRange"][1]] if ftlog.is_debug(): ftlog.debug("getChestRewards->gunSkinRare =", gunSkinRare) # 根据权重随机出具体的火炮皮肤 if gunSkinRate: for randomCount in xrange(gunSkinRare[1]): minGunSkin = starCardRare[2] maxGunSkin = starCardRare[3] gunSkinList = _randomItemInWeight(gunSkinPile, minGunSkin, maxGunSkin) rewards = _mergeItemList(rewards, gunSkinList) if ftlog.is_debug(): ftlog.debug("getChestRewards->gunSkinList =", rewards) # 确定(黄/紫)水晶概率,随机次数,最小数,最大数 crystalRate = 1 if random.randint(1, 10000) <= chestConf["crystalRate"] else 0 crystalData = [crystalRate, chestConf["crystalRandom"], chestConf["crystalRange"][0], chestConf["crystalRange"][1]] if ftlog.is_debug(): ftlog.debug("getChestRewards->crystalData =", crystalData) # 根据权重随机出具体的水晶 if crystalRate: for randomCount in xrange(crystalData[1]): minCrystal = crystalData[2] maxCrystal = crystalData[3] crystals = _randomItemInWeight(crystalItems, minCrystal, maxCrystal) rewards = _mergeItemList(rewards, crystals) if ftlog.is_debug(): ftlog.debug("getChestRewards->crystals =", rewards) # 计算奖券个数 couponRate = 1 if random.randint(1, 10000) <= chestConf["couponRate"] else 0 if couponRate: couponCount = random.randint(chestConf["couponRange"][0], chestConf["couponRange"][1]) if couponCount > 0: coupon = {"name": COUPON_KINDID, "count": couponCount} rewards.append(coupon) # 计算海星个数 starfishRate = 1 if random.randint(1, 10000) <= chestConf["starfishRate"] else 0 if starfishRate: starfishCount = random.randint(chestConf["starfishRange"][0], chestConf["starfishRange"][1]) if starfishCount > 0: starfish = {"name": STARFISH_KINDID, "count": starfishCount} rewards.append(starfish) # 计算冷却个数 coolDownRate = 1 if random.randint(1, 10000) <= chestConf["coolDownRate"] else 0 if coolDownRate: coolDownCount = random.randint(chestConf["coolDownRange"][0], chestConf["coolDownRange"][1]) if coolDownCount > 0: coolDown = {"name": SKILLCD_KINDID, "count": coolDownCount} rewards.append(coolDown) # 计算青铜招财珠个数 bronzeBulletRate = 1 if random.randint(1, 10000) <= chestConf["bronzeBulletRate"] else 0 if bronzeBulletRate: bronzeBulletCount = random.randint(chestConf["bronzeBulletRange"][0], chestConf["bronzeBulletRange"][1]) if bronzeBulletCount > 0: bronzeBullet = {"name": BRONZE_BULLET_KINDID, "count": bronzeBulletCount} rewards.append(bronzeBullet) # 计算白银招财珠个数 silverBulletRate = 1 if random.randint(1, 10000) <= chestConf["silverBulletRate"] else 0 if silverBulletRate: silverBulletCount = random.randint(chestConf["silverBulletRange"][0], chestConf["silverBulletRange"][1]) if silverBulletCount > 0: silverBullet = {"name": SILVER_BULLET_KINDID, "count": silverBulletCount} rewards.append(silverBullet) # 计算黄金招财珠个数 goldBulletRate = 1 if random.randint(1, 10000) <= chestConf["goldBulletRate"] else 0 if goldBulletRate: goldBulletCount = random.randint(chestConf["goldBulletRange"][0], chestConf["goldBulletRange"][1]) if goldBulletCount > 0: goldBullet = {"name": GOLD_BULLET_KINDID, "count": goldBulletCount} rewards.append(goldBullet) # 计算红宝石个数 rubyRate = 1 if random.randint(1, 10000) <= chestConf["rubyRate"] else 0 if rubyRate: rubyCount = random.randint(chestConf["rubyRange"][0], chestConf["rubyRange"][1]) if rubyCount > 0: ruby = {"name": RUBY_KINDID, "count": rubyCount} rewards.append(ruby) # 计算物品个数 for _item in chestConf.get("itemsData", []): rate = 1 if random.randint(1, 10000) <= _item["rate"] else 0 if rate: count = random.randint(_item["min"], _item["max"]) if count > 0: val = {"name": _item["kindId"], "count": count} rewards.append(val) _convertOverflowCardToCoin(userId, rewards) return rewards
def getChestList(userId): """ 获取宝箱列表 """ module_tip.resetModuleTip(userId, "chest") userBag = hallitem.itemSystem.loadUserAssets(userId).getUserBag() chestItemList = userBag.getAllTypeItem(TYChestItem) chestItemList = sorted(chestItemList, key=lambda chestItem: chestItem.order) chestList = [] openedChestList = [] for chestItem in chestItemList: if not chestItem.chestId: ftlog.error("chest item error", userId) continue openingOrder = [chestItemTmp.order for chestItemTmp in chestItemList if chestItemTmp.state == 1] chestConf = config.getChestConf(chestItem.chestId) chest = {} if chestItem.totalTime <= 0: chestItem.state = ChestState.Opened if chestItem.state == ChestState.WaitOpen and not openingOrder: chestItem.state = ChestState.Opening if chestItem.state == ChestState.WaitOpen: chestTimeLeft = chestItem.totalTime elif chestItem.state == ChestState.Opening: chestTimeLeft = chestItem.beginTime + chestItem.totalTime - pktimestamp.getCurrentTimestamp() + CHEST_OPEN_DELAY_TIME else: chestTimeLeft = 0 if chestItem.state == ChestState.Opening and chestTimeLeft <= 0: chestItem.state = ChestState.Opened noOpenOrderList = [chestItemTmp.order for chestItemTmp in chestItemList if chestItemTmp.state == 0] if noOpenOrderList: nextOpeningChestItem = None for noOpenOrder in noOpenOrderList: if noOpenOrder > chestItem.order: nextOpeningChestItem = [chestItemImp for chestItemImp in chestItemList if chestItemImp.order == noOpenOrder][0] break if not nextOpeningChestItem: nextOpeningChestItem = [chestItemImp for chestItemImp in chestItemList if chestItemImp.order == noOpenOrderList[0]][0] if nextOpeningChestItem: nextOpeningChestItem.state = ChestState.Opening nextOpeningChestItem.beginTime = chestItem.beginTime + chestItem.totalTime userBag.updateItem(FISH_GAMEID, nextOpeningChestItem, pktimestamp.getCurrentTimestamp()) for chestTmp in chestList: if chestTmp["order"] == nextOpeningChestItem.order: chestTmp["state"] = 1 chestTmp["timeLeft"] = nextOpeningChestItem.beginTime + nextOpeningChestItem.totalTime - \ pktimestamp.getCurrentTimestamp() + CHEST_OPEN_DELAY_TIME break chestTimeLeft = max(0, chestTimeLeft) chest["order"] = chestItem.order chest["state"] = chestItem.state chest["chestId"] = chestItem.chestId chest["itemId"] = chestItem.itemId chest["kindId"] = chestItem.kindId chest["desc"] = chestItem.itemKind.desc chest["createTime"] = chestItem.createTime chest["timeLeft"] = chestTimeLeft chest["totalTime"] = chestItem.totalTime chest["openCoin"] = chestConf["openCoin"] chest["diamond"] = _needCoinAsOpenChest(chestItem.chestId, chestTimeLeft) chest["info"] = getChestInfo(chestItem.chestId) chestList.append(chest) userBag.updateItem(FISH_GAMEID, chestItem, pktimestamp.getCurrentTimestamp()) if chestItem.state == ChestState.Opened: openedChestList.append(chestItem.itemId) ftlog.debug("getChestList->", chestList) module_tip.addModuleTipEvent(userId, "chest", openedChestList) return chestList
def _onConfChanged(event): if _inited and event.isChanged('game:9999:free:tc'): ftlog.debug('hallfree._onConfChanged') _reloadConf()
def _onConfChanged(event): if _inited and event.isChanged('game:9999:fivestar:0'): ftlog.debug('fivestarrate._onConfChanged') _reloadConf()
def getWinnerResultsForLuoSiHu(self, winSeatId, isFlow=False): winnerResults = [] # 不需要根据和牌牌型计算的番型,先计算 maxFan = self.tableConfig.get(MTDefine.MAX_FAN, 0) """清一色""" if self.__tile_pattern_checker.isQingyise(): self.fanXing[self.QINGYISE]["index"] = 1 winnerResults.append(self.processFanXingResult(self.QINGYISE)) """碰碰胡""" for pattern in self.__win_patterns[winSeatId]: if self.__tile_pattern_checker.isPengpenghu(pattern): if self.isJinGouDiao(): winnerResults.append( self.processFanXingResult(self.JINGOUDIAO, 0, 2)) else: winnerResults.append( self.processFanXingResult(self.PENGPENGHU)) # 个别番型和和牌牌型有关,算分时选取分数最大的情况 #winnerResultsByPattern = [] maxPatternScore = 0 bestWinnerResultsByPattern = [] ftlog.info('MLuosihuOneResult.getWinnerResults winSeatId', self.__win_patterns[winSeatId]) for pattern in self.__win_patterns[winSeatId]: ftlog.info('MLuosihuOneResult.getWinnerResults win_pattern=', pattern) # pattern内,全部是手牌(包含最后一张牌) eachWinnerResultsByPattern = [] """七对""" if self.__tile_pattern_checker.isQidui(pattern): self.fanXing[self.QIDUI]["index"] = 1 eachWinnerResultsByPattern.append( self.processFanXingResult(self.QIDUI)) """豪华七对""" hu_tiles = self.tableTileMgr.players[winSeatId].copyHuArray() tempcount = 0 if len(hu_tiles) > 0: tiles = self.allPlayerTiles[ self. winSeatId] # self.tableTileMgr.players[self.winSeatId].copyTiles() handTiles = tiles[MHand.TYPE_HAND] tempcount = MTile.getTileCount(hu_tiles[-1], handTiles) ftlog.debug('MLuosihuOneResult.getWinnerResults hu_tiles=', hu_tiles, tempcount) if self.__tile_pattern_checker.isQiduiHao( pattern) and tempcount >= 3: self.fanXing[self.QIDUIHAO]["index"] = 2 eachWinnerResultsByPattern.append( self.processFanXingResult(self.QIDUIHAO)) ftlog.info( 'MLuosihuOneResult.getWinnerResults eachWinnerResultsByPattern=', eachWinnerResultsByPattern) bestWinnerResult = [] maxScore = 0 for result in eachWinnerResultsByPattern: tempResult = [] tempResult.append(result) calctempResult = [] calctempResult.extend(tempResult) tempScore, _ = self.getScoreByResults(calctempResult) if tempScore > maxScore: maxScore = tempScore bestWinnerResult = tempResult # 计算当前牌型的赢牌奖励分数,选取最大值的牌型 calceachWinnerResultsByPattern = [] #calceachWinnerResultsByPattern.extend(winnerResults) calceachWinnerResultsByPattern.extend(bestWinnerResult) tempScore, _ = self.getScoreByResults( calceachWinnerResultsByPattern) if tempScore > maxPatternScore: # 分数相同就不管了 maxPatternScore = tempScore bestWinnerResultsByPattern = calceachWinnerResultsByPattern winnerResults.extend(bestWinnerResultsByPattern) ftlog.info('MLuosihuOneResult.getWinnerResults luosihu winnerResults=', winnerResults) return winnerResults
def isQidui(self, tiles): handTiles = copy.deepcopy(tiles[MHand.TYPE_HAND]) handTilesArr = MTile.changeTilesToValueArr(handTiles) if len(handTiles) != 14: return False, [] pattern = [] for tile in range(MTile.TILE_MAX_VALUE): if handTilesArr[tile] == 1 or handTilesArr[tile] == 3: # 只要出现单数,必然不是七对 return False, [] if handTilesArr[tile] == 2: pattern.append([tile, tile]) if handTilesArr[tile] == 4: # 和LuosihuOneResult配合 pattern.extend([[tile, tile], [tile, tile]]) return True, pattern if __name__ == "__main__": tiles = [[11, 11, 13, 13, 15, 15, 18, 18, 19, 19, 24, 24, 24, 24], [], [], [], [], []] rule = MWinRuleLuosihu() result, pattern = rule.isHu(tiles, 24, True, MWinRule.WIN_BY_MYSELF, [], [], 0, 0, 10) ftlog.debug(result, pattern) assert [[11, 11], [13, 13], [15, 15], [18, 18], [19, 19], [24, 24], [24, 24]] == pattern
msg = MsgPack() msg.setCmd('hall_duobao') msg.setResult('action', 'duobao_myrecord') msg.setResult('gameId', gameId) msg.setResult('userId', userId) msg.setResult('pageId', pageId) msg.setResult('recordList', recordList) msg.setResult('totalLength', totalLength) msg.setResult('ec', ec) msg.setResult('info', info) router.sendToUser(msg, userId) if ftlog.is_debug(): ftlog.debug('doDuobaoMyRecord', 'userId=', userId, 'pageId=', pageId, 'recordList=', recordList, 'totalLength=', totalLength) @markCmdActionMethod(cmd='hall_duobao', action='duobao_rewardRecord', clientIdVer=0) def doDuobaoMyRewardRecord(self): ''' 一元夺宝查询我的领奖记录 ''' msg = runcmd.getMsgPack() gameId = msg.getParam("gameId") userId = msg.getParam("userId") from hall.entity import hall1yuanduobao rewardRecordList = hall1yuanduobao.duobaoRewardRecord(userId)
def _onConfChanged(event): if _inited and event.isModuleChanged('exit_plugin_remind'): ftlog.debug('_onConfChanged') _reloadConf()
def queryExitPluginRemind(userId, _gameId, clientId, gamesUserCanSee): ''' 获取推荐的快开配置 ''' global _ordersMap templateName = hallconf.getExitPluginRemindTemplateName(clientId) ftlog.debug('templateName:', templateName) templates = _ordersMap.get('templates', []) for template in templates: ftlog.debug('template:', template) if template.get('name', '') == templateName: # 找到当前的模板了 remindGames = template.get('remindGames', []) # 首先获取可以引导去哪些游戏 gameIds = [] for remindGame in remindGames: gameId = remindGame.get('gameId', 0) if (gameId != 0) and (gameId not in gameIds) and (gameId in gamesUserCanSee) and (gameId != _gameId): gameIds.append(gameId) # 第二,获取目标游戏的游戏行为 mostGameId = 0 # 玩儿的最多的游戏一个,进入次数最多的游戏 mostGameLoginSum = 0 lastGameId = 0 # 上次玩儿的游戏一个,通过游戏的进入时间判断,时间最大的 lastAuthTime = 0 leastGameId = 0 # 最长时间没玩儿的游戏一个,通过游戏进入时间判断,时间最小的 leastAuthTime = 0 neverGames = [] # 没玩儿的游戏若干,没有游戏记录的,游戏登录次数为0的 for game in gameIds: loginSum = gamedata.getGameAttr(userId, game, 'loginsum') if 0 == loginSum: neverGames.append(game) else: if loginSum > mostGameLoginSum: mostGameId = game mostGameLoginSum = loginSum authorTimeStr = gamedata.getGameAttr(userId, game, 'authorTime') _lastAuthTime = 0 if authorTimeStr: _lastAuthTime = pktimestamp.timestrToTimestamp(authorTimeStr, '%Y-%m-%d %H:%M:%S.%f') if _lastAuthTime and (_lastAuthTime > lastAuthTime): lastGameId = game lastAuthTime = _lastAuthTime if 0 == leastAuthTime or (_lastAuthTime and (_lastAuthTime < leastAuthTime)): leastAuthTime = _lastAuthTime leastGameId = game ftlog.debug('mostGameId:', mostGameId , ' lastGameId:', lastGameId , ' leastGameId:', leastGameId , ' neverGames:', neverGames) choices = [] if mostGameId: choices.append(TYPE_MOST) if lastGameId: choices.append(TYPE_LAST) if leastGameId: choices.append(TYPE_LEAST) if neverGames: choices.append(TYPE_NEVER) if not choices: return cType = random.choice(choices) cGame = 0 if TYPE_MOST == cType: cGame = mostGameId elif TYPE_LAST == cType: cGame = lastGameId elif TYPE_LEAST == cType: cGame = leastGameId elif TYPE_NEVER == cType: cGame = random.choice(neverGames) ftlog.debug('cType:', cType , ' cGame:', cGame) reminds = [] for remindGame in remindGames: gameId = remindGame.get('gameId', 0) if gameId == cGame: reminds.append(remindGame) if reminds: remind = random.choice(reminds) ftlog.debug('remind:', remind) # 第四,选择游戏进行引导挽留 return sendExitPluginRemindMsg(userId, _gameId, clientId, remind, cType) return '1'
def getVcTemplateConf(clientId, moduleName, tempKeyName=None, needDict=0): """根据clientId获取虚配置""" tname1 = configure.getVcTemplate(moduleName, clientId) ftlog.debug('getVcTemplateConf->', clientId, moduleName, tname1) return tname1
def _onConfChanged(event): if _inited and event.isChanged('game:9999:public:0'): ftlog.debug('startChip._onConfChanged') _reloadConf()
def lineReceived(self, data): if performance.PERFORMANCE_NET: data = performance.linkMsgTime('LR', data) ftlog.debug('S2AProtocol->lineReceived', FTTasklet.concurrent_task_count, time(), data) src, dst, query_id, userheader1, userheader2, msg = agentmsg.unpack( data) if src == None or dst == None: ftlog.info("ERROR, recive a error format message") return if self.peer_id == 0: self.peer_id = src ftcon.serverid_protocol_map[self.peer_id] = self ftlog.info('receive register, agentid=', self.peer_id) return _countProtocolPack(1, self) # send过来的数据 if query_id == '': self._runTasklet(data=msg, src=src, dst=dst, userheader1=userheader1, userheader2=userheader2, time_recv=time()) else: querysrc, _ = query_id.split('.') server_id = ftcon.global_config["server_id"] # query本服务的请求 if querysrc != server_id: self._runTasklet(data=msg, src=src, dst=dst, query_id=query_id, userheader1=userheader1, userheader2=userheader2, time_recv=time()) # response回来的请求 else: if userheader1 == 'RQ': # 本进程内, 异步查询本进程的其他消息接口 self._runTasklet(data=msg, src=src, dst=dst, query_id=query_id, userheader1=userheader1, userheader2=userheader2, time_recv=time()) else: d, c, t = None, None, 0 # ftlog.debug('lineReceived', query_id, id(_LIVE_MESSAGES), id(self)) if query_id in _LIVE_MESSAGES: d, c, t = _LIVE_MESSAGES[query_id] del _LIVE_MESSAGES[query_id] else: if query_id in _FAILED_MESSAGES: del _FAILED_MESSAGES[query_id] ftlog.warn('QUERY TOO SLOW !!', query_id, msg) if len(_FAILED_MESSAGES) > 100: _FAILED_MESSAGES.clear() else: ftlog.warn('NOT KNOW of query_id->', query_id, msg) if d and c: try: c.cancel() d.callback((msg, t, time())) except: ftlog.error(msg)
def _onItemCountChanged(event): if _inited: ftlog.debug('hallfree._onItemCountChanged', event.userId) datachangenotify.sendDataChangeNotify(HALL_GAMEID, event.userId, ['free', 'promotion_loc'])
def _onConfChanged(event): if _inited and event.isChanged('game:9999:local_notification:0'): ftlog.debug('halllocalnotification._onConfChanged') _reloadConf()
def _onConfChanged(event): if _inited and event.isChanged('game:9999:flipcardluck:0'): ftlog.debug('hallflipcardluck._onConfChanged') _reloadConf()
class DuobaoTcpHandler(BaseMsgPackChecker): @markCmdActionMethod(cmd='hall_duobao', action='duobao_bet', clientIdVer=0) def doDuobaoBet(self): ''' 一元夺宝下注 ''' msg = runcmd.getMsgPack() gameId = msg.getParam("gameId") userId = msg.getParam("userId") duobaoId = msg.getParam("duobaoId") issue = msg.getParam("issue") num = msg.getParam("num") ec = 0 info = '投注成功' luckyCodeList = [] myBetCount = 0 totalBetCount = 0 coupon = 0 try: from hall.entity import hall1yuanduobao luckyCodeList, myBetCount, totalBetCount, coupon = hall1yuanduobao.duobaoBet(userId, duobaoId, issue, num) except TYBizException, e: ec = e.errorCode info = e.message ftlog.info('doDuobaoBet failer', 'userId=', userId, 'duobaoId=', duobaoId, 'issue=', issue, 'num=', num, 'ec=', ec, 'info=', info) msg = MsgPack() msg.setCmd('hall_duobao') msg.setResult('action', 'duobao_bet') msg.setResult('gameId', gameId) msg.setResult('userId', userId) msg.setResult('duobaoId', duobaoId) msg.setResult('issue', issue) msg.setResult('num', num) msg.setResult('ec', ec) msg.setResult('info', info) msg.setResult('luckyCodeList', luckyCodeList) msg.setResult('myBetCount', myBetCount) msg.setResult('totalBetCount', totalBetCount) msg.setResult('coupon', coupon) router.sendToUser(msg, userId) if ftlog.is_debug(): ftlog.debug('doDuobaoBet', 'userId=', userId, 'duobaoId=', duobaoId, 'issue=', issue, 'num=', num, 'luckyCodeList=', luckyCodeList, 'myBetCount=', myBetCount, 'totalBetCount=', totalBetCount, 'coupon=', coupon)
def isHu(self, tiles, tile, isTing, getTileType, magicTiles=[], tingNodes=[], curSeatId=0, winSeatId=0, actionID=0, isGangKai=False, isForHu=True): if self.tableTileMgr.playMode == "luosihu-luosihu" and isForHu: if not isTing: if not self.tableTileMgr.players[winSeatId].isWon(): return False, [], 0 allTiles = MHand.copyAllTilesToListButHu(tiles) tilesArr = MTile.changeTilesToValueArr(allTiles) # 需要缺一门: 定缺的时候约定的那门 if self.absenceColor: if MTile.getTileCountByColor(tilesArr, self.absenceColor[winSeatId]) > 0: return False, [], 0 result, pattern = self.isQidui(tiles) if result: if self.tableTileMgr.playMode == "luosihu-luosihu": self.fanXing[self.QIDUI]["index"] = 1 return True, pattern, self.fanXing[self.QIDUI]["index"] result, pattern = MWin.isHu(tiles[MHand.TYPE_HAND], magicTiles) if result: ftlog.debug('MWinRuleLuosihu.isHu result=', result, ' getTileType=', getTileType, ' pattern=', pattern) player = self.tableTileMgr.players[winSeatId] self.winSeatId = winSeatId self.__tile_pattern_checker = MTilePatternCheckerFactory.getTilePatternChecker( MPlayMode.LUOSIHU) playersAllTiles = [[] for _ in range(self.tableTileMgr.playCount)] self.__win_patterns = [[] for _ in range(self.tableTileMgr.playCount)] self.__win_patterns[winSeatId] = [pattern] for seatId in range(self.tableTileMgr.playCount): if seatId == winSeatId: playersAllTiles[seatId] = copy.deepcopy(tiles) else: playersAllTiles[seatId] = self.tableTileMgr.players[ seatId].copyTiles() self.setAllPlayerTiles(playersAllTiles) # 判断和牌的时候 self.__tile_pattern_checker.initChecker(playersAllTiles, tile, self.tableTileMgr, True, curSeatId, winSeatId, actionID) winnerResult = [] if self.tableTileMgr.playMode == "luosihu-ctxuezhan": winnerResult = self.getWinnerResultsForXueZhanDaoDi(winSeatId) elif self.tableTileMgr.playMode == "luosihu-xuezhan": winnerResult = self.getWinnerResultsForLuoSiHuXueZhan( winSeatId) elif self.tableTileMgr.playMode == "luosihu-luosihu": winnerResult = self.getWinnerResultsForLuoSiHu(winSeatId) finalResult = [] finalResult.extend(winnerResult) maxFan = self.tableConfig.get(MTDefine.MAX_FAN, 0) winScore, indexFan = self.getScoreByResults(finalResult, maxFan) ftlog.debug('MWinRuleLuosihu.isHu player.guoHuPoint :', winScore, ' finalResult=', finalResult, ' indexFan') # 过胡判断 if getTileType == MWinRule.WIN_BY_MYSELF: return True, pattern, indexFan if player.guoHuPoint >= winScore and self.tableTileMgr.playMode == "luosihu-ctxuezhan": return False, [], 0 player.totalWinPoint = winScore return True, pattern, indexFan return False, [], 0
def sendLed(gameId, msgstr, ismgr=0, scope="hall", clientIds=None, isStopServer=False): """ 发送LED @param gameId: 游戏gameId,gameId部分起到了过滤/范围的作用 @param msgstr: LED消息内容 @param ismgr: 是否是GDSS发的,默认非GDSS发送的 @param scope: string类型,LED显示级别/范围,详见http://192.168.10.93:8090/pages/viewpage.action?pageId=1281059 scope摘要 - "6": 只在地主插件里面播放 - "hall": 在大厅界面播放 - "hall6": 在大厅和地主插件里面播放 - "global": 在大厅任何界面都播放 @param clientIds: 不发送的clientId集合,默认全发送 @param isStopServer: 是否是停服led """ assert isinstance(msgstr, basestring) clientIds = clientIds or [] closeLedGameIds = hallconf.getPublicConf("closeLedGameIds", []) if not isStopServer and closeLedGameIds and gameId in closeLedGameIds: if ftlog.is_debug(): ftlog.debug("led.sendLed closed", "gameId=", gameId, "msgstr=", msgstr, "scope=", scope, "ismgr=", ismgr, "isStopServer=", isStopServer) return None if ftlog.is_debug(): ftlog.debug("led.sendLed gameId=", gameId, "msgstr=", msgstr, "scope=", scope, "ismgr=", ismgr, "isStopServer=", isStopServer) try: msgDict = decodeMsg(gameId, msgstr) # 每条LED所包含的数据内容 msg = [0, gameId, msgDict, scope, clientIds, isStopServer] leds = _LEDS kmsg = "m:" + str(gameId) ktime = "t:" + str(gameId) if ismgr: leds[kmsg] = [msg] leds[ktime] = datetime.now() else: if not kmsg in leds: leds[kmsg] = [] leds[ktime] = None timeout = leds[ktime] if timeout != None: timeouts = hallconf.getHallPublic().get( "led.manager.timeout", 30) secondes = (datetime.now() - timeout).seconds if secondes < timeouts: if ftlog.is_debug(): ftlog.warn("led.sendLed Failed gameId=", gameId, "msgstr=", msgstr, "ismgr=", ismgr, "scope=", scope, "timeouts=", timeouts, "secondes=", secondes) return msgq = leds[kmsg] msgq.append(msg) ledlength = 3 leds[ktime] = datetime.now() leds[kmsg] = msgq[-ledlength:] if ftlog.is_debug(): ftlog.debug("led.sendLed gameId=", gameId, "msgstr=", msgstr, "ismgr=", ismgr, "msg=", msg, "leds=", _LEDS) return msg except: ftlog.error("led.sendLed gameId=", gameId, "msgstr=", msgstr, "scope=", scope, "ismgr=", ismgr, "leds=", _LEDS) return None
def getWinnerResultsForXueZhanDaoDi(self, winSeatId, isFlow=False): """血战到底""" """和牌时,计算胜者的牌对整个牌桌的分数影响""" winnerResults = [] # 不需要根据和牌牌型计算的番型,先计算 maxFan = self.tableConfig.get(MTDefine.MAX_FAN, 0) if self.__tile_pattern_checker.isGangshangpao(): winnerResults.append(self.processFanXingResult(self.GANGSHANGPAO)) """金钩胡 1番 不和对对胡一起算""" for pattern in self.__win_patterns[winSeatId]: if self.checkDaDiaoChe( ) and not self.__tile_pattern_checker.isPengpenghu(pattern): winnerResults.append(self.processFanXingResult(self.JINGOUHU)) """根的番计算 龙七对,清龙七对 根要减1""" hasGen, winnerGen = self.getWinnerGen() if hasGen: if self.__tile_pattern_checker.isQiduiHao(pattern): winnerGen -= 1 winnerResults.append( self.processFanXingResult(self.GEN, 0, winnerGen)) # 个别番型和和牌牌型有关,算分时选取分数最大的情况 maxPatternScore = 0 bestWinnerResultsByPattern = [] ftlog.info('MLuosihuOneResult.getWinnerResults winSeatId', self.__win_patterns[winSeatId]) for pattern in self.__win_patterns[winSeatId]: ftlog.info('MLuosihuOneResult.getWinnerResults win_pattern=', pattern) # pattern内,全部是手牌(包含最后一张牌) eachWinnerResultsByPattern = [] """碰碰胡 2番""" if self.__tile_pattern_checker.isPengpenghu(pattern): self.fanXing[self.PENGPENGHU]["index"] = 2 eachWinnerResultsByPattern.append( self.processFanXingResult(self.PENGPENGHU)) """清一色 2番""" if self.__tile_pattern_checker.isQingyise(): eachWinnerResultsByPattern.append( self.processFanXingResult(self.QINGYISE)) """清一色碰碰胡 3番""" if self.__tile_pattern_checker.isPengpenghu( pattern) and self.__tile_pattern_checker.isQingyise(): eachWinnerResultsByPattern.append( self.processFanXingResult(self.QINGYISEPENGPENGHU)) """七对 2番""" if self.__tile_pattern_checker.isQidui(pattern): eachWinnerResultsByPattern.append( self.processFanXingResult(self.QIDUI)) """清七对 3番""" if self.__tile_pattern_checker.isQingyise( ) and self.__tile_pattern_checker.isQidui(pattern): eachWinnerResultsByPattern.append( self.processFanXingResult(self.QINGQIDUI)) """龙七对 3番""" if self.__tile_pattern_checker.isQiduiHao(pattern): eachWinnerResultsByPattern.append( self.processFanXingResult(self.QIDUIHAO)) """清龙七对 4番""" if self.__tile_pattern_checker.isQiduiHao( pattern) and self.__tile_pattern_checker.isQingyise(): eachWinnerResultsByPattern.append( self.processFanXingResult(self.QINGQIDUIHAO)) if self.tableConfig.get(MTDefine.JIANGDUI, 0): """全幺九 3番""" if self.isYaoJiu(pattern): self.fanXing[self.YAOJIU]["index"] = 3 eachWinnerResultsByPattern.append( self.processFanXingResult(self.YAOJIU)) """将对 3番""" if self.__tile_pattern_checker.isPengpenghu( pattern) and self.isJiangDui(): self.fanXing[self.JIANGDUI]["index"] = 3 eachWinnerResultsByPattern.append( self.processFanXingResult(self.JIANGDUI)) """将七对 4番""" if self.__tile_pattern_checker.isQiduiHao( pattern) and self.isJiangDui(): eachWinnerResultsByPattern.append( self.processFanXingResult(self.JIANGQIDUI)) ftlog.debug( 'MLuosihuOneResult.getWinnerResults eachWinnerResultsByPattern= ', eachWinnerResultsByPattern, len(eachWinnerResultsByPattern)) # 计算当前牌型的赢牌奖励分数,选取最大值的牌型 bestWinnerResult = [] maxScore = 0 for result in eachWinnerResultsByPattern: tempResult = [] tempResult.append(result) calctempResult = [] calctempResult.extend(tempResult) tempScore, _ = self.getScoreByResults(calctempResult) if tempScore > maxScore: maxScore = tempScore bestWinnerResult = tempResult calceachWinnerResultsByPattern = [] calceachWinnerResultsByPattern.extend(winnerResults) calceachWinnerResultsByPattern.extend(bestWinnerResult) tempScore, _ = self.getScoreByResults( calceachWinnerResultsByPattern) if tempScore > maxPatternScore: # 分数相同就不管了 maxPatternScore = tempScore bestWinnerResultsByPattern = calceachWinnerResultsByPattern winnerResults.extend(bestWinnerResultsByPattern) ftlog.info( 'MLuosihuOneResult.getWinnerResults xuezhandaodi winnerResults=', winnerResults) return winnerResults
def _doActiveOutCard(self, reducedCards): cardNote = self.buildCardNote() if ftlog.is_debug(): ftlog.debug('>>> AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote) cards = self.checkWinCard(reducedCards, cardNote, 11) if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'checkWinCard', 'checkWinCard=', self.toHumanCards(cards)) # 剩余最大一手牌+任意一手牌 if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'checkWinCard=', cards, 'desc=', 'checkWinCard', 'cards=', self.toHumanCards(cards), 'out=', self.toHumanCards(cards)) return cards # 剩余一手牌 cards = self.checkValidCardsWithHandReducedCards(reducedCards) if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'checkValidCardsWithHandReducedCards', 'cards=', self.toHumanCards(cards)) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'checkValidCardsWithHandReducedCards' 'cards=', self.toHumanCards(cards), 'out=', self.toHumanCards(cards)) return cards nextSeat = self.player.seat.next enemySeat = nextSeat if not self.isFriend(nextSeat) else self.player.seat.next.next if nextSeat != enemySeat: # 队友剩单牌,出最小的牌 if len(nextSeat.status.cards) == 1: cards = self.findNCards(reducedCards, 1, True, False) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'PassFriend1', 'out=', self.toHumanCards(cards)) return cards elif len(nextSeat.status.cards) == 2: # 队友剩对子,出最小的对子 cards = self.findNCards(reducedCards, 2, False, False) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'PassFriend2', 'out=', self.toHumanCards(cards)) return cards # 查找飞机,三顺,双顺,单顺,三带单,三带对 cards = self.findFirstCards(reducedCards, [CardTypeFeijiDai1, CardTypeFeijiDai2, CardTypeSanShun, CardTypeShuangShun, CardTypeDanShun, CardTypeSanDai1, CardTypeSanDai2]) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'findFirstCards', 'out=', self.toHumanCards(cards)) return cards reverse = True if enemySeat == nextSeat else False enemyCardCount = len(enemySeat.status.cards) # 敌人报牌了 if enemyCardCount <= 2: if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard EnemyAlarm handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'enemyAlarm%s' % (enemyCardCount), 'enemyCardCount=', enemyCardCount) if enemyCardCount == 2: # 敌人剩双数,优先出单牌,捡小牌出 cards = self.findNCards(reducedCards, 1, True, False) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'enemyAlarm%s Out1' % (enemyCardCount), 'enemyCardCount=', enemyCardCount, 'out=', self.toHumanCards(cards)) return cards # 出对子 cards = self.findNCards(reducedCards, 2, False, reverse) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard EnemyAlarm2 Out2 handCards=', reducedCards.cards, 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'enemyAlarm%s Out2' % (enemyCardCount), 'enemyCardCount=', enemyCardCount, 'out=', self.toHumanCards(cards)) return cards else: # 敌人剩单张,优先出对子,捡小的出 cards = self.findNCards(reducedCards, 2, False, False) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard Out2 handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'enemyAlarm%s Out2' % (enemyCardCount), 'enemyCardCount=', enemyCardCount, 'out=', self.toHumanCards(cards)) return cards # 出单牌 cards = self.findNCards(reducedCards, 1, True, reverse) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard Out2 handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'enemyAlarm%s Out2' % (enemyCardCount), 'enemyCardCount=', enemyCardCount, 'out=', self.toHumanCards(cards)) return cards if nextSeat == enemySeat: if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'NextIsEnemy Ding') prevCards = None # 下家是敌人,顶牌 for i in xrange(4): cards = self._findDingNCardsGTPoint(reducedCards, i + 1, False, -1, self.DING_POINT) if cards: if not prevCards: prevCards = cards if i < 2 and self.cardRule.cardToPoint(cards[0]) >= self.ACTIVE_MAX_POINT: continue if i == 3 and prevCards: break if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'NextIsEnemy Ding', 'out=', self.toHumanCards(cards)) return cards if prevCards: if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'NextIsEnemy Ding PrevCards', 'out=', self.toHumanCards(prevCards)) return prevCards if ftlog.is_debug(): ftlog.debug('AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'OutMinCard') # 下家是队友,或者自己是地主,从小牌开始出 prevCards = None for i in xrange(4): cards = self.findNCards(reducedCards, i + 1, False, False) if cards: if not prevCards: prevCards = cards if i < 2 and self.cardRule.cardToPoint(cards[0]) >= self.ACTIVE_MAX_POINT: continue if i == 3 and prevCards: break ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'OutMinCard', 'out=', cards) return cards if prevCards: ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'OutMinCard PrevCards', 'out=', cards) return prevCards cards = self.findNCards(reducedCards, 1, True, False) if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doActiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'cardNote=', cardNote, 'desc=', 'ChaiDanpai', 'out=', self.toHumanCards(cards)) return cards
def _doPassiveOutCard(self, reducedCards): cardNote = self.buildCardNote() topValidCard = self.table.gameRound.topValidCards topSeat = self.table.gameRound.topSeat if ftlog.is_debug(): ftlog.debug('>>> AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', self.table.gameRound.topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote) # 双王或炸弹必胜 cards = self.checkBombOrHuojianWinCard(reducedCards, cardNote) if cards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard checkBombOrHuojianWinCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'first checkBombOrHuojianWinCard', 'out=', self.toHumanCards(cards)) return cards found = self.cardRule.findGreaterValidCards(topValidCard, reducedCards.cards[:], True) # 管不住 if not found: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard findGreaterCardsByValidCardsPass handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'NoGreaterCards', 'out=', []) return [] cards = found.cards # 管牌后就出完了 remCards = self.removeCards(reducedCards.cards[:], cards) if not remCards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'NotRemCards', 'cards=', self.toHumanCards(cards), 'out=', self.toHumanCards(cards)) return cards remReducedCards = ReducedCards.reduceHandCards(self.cardRule, remCards) # 管牌后剩余双王或炸弹必胜 winCards = self.checkBombOrHuojianWinCard(remReducedCards, cardNote) if winCards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'remCards checkBombOrHuojianWinCard', 'remCards=', remCards, 'cards=', self.toHumanCards(cards), 'out=', self.toHumanCards(cards)) return cards dizhuCardCount = len(self.table.gameRound.dizhuSeat.status.cards) topCardCount = len(topValidCard.reducedCards.cards) # 队友出的牌 if self.isFriend(self.table.gameRound.topSeat): if ftlog.is_debug(): ftlog.debug('AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'FriendIsTopSeat', 'cards=', self.toHumanCards(cards)) if self._isHuojianOrZhadan(cards): if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'HuojianOrZhadan cannot kill friend', 'cards=', self.toHumanCards(cards), 'out=', []) return [] # 如果队友是下家则不管 if self.player.seat.next == self.table.gameRound.topSeat: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'Friend continue outCards', 'out=', []) return [] if topCardCount > 2: # 只跟队友出单牌和对子 if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'Friend Out > 2', 'out=', []) return [] # 如果队友出的对子,地主剩单张则不管 if topCardCount == 2 and dizhuCardCount == 1: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'Firend out 2Cards dizhu rem 1Cards', 'out=', []) return [] # 队友出的单牌或者对牌,地主剩对应张数的牌,需要顶最大的 if topCardCount == dizhuCardCount: chaiPai = True if topCardCount == 1 else False dingCards = self.findNCardsByGTPoint(reducedCards, topCardCount, topValidCard.reducedCards.groups[0].point, chaiPai, True) if dingCards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'Firend out %sCards dizhu rem %sCards Ding' % (topCardCount, topCardCount), 'out=', self.toHumanCards(dingCards)) return dingCards # 队友的牌>=跟牌点数则不跟 if topValidCard.reducedCards.groups[0].point >= self.FOLLOW_FRIEND_MAX_POINT: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'NotFollow Firend out %sCards >= FOLLOW_FRIEND_MAX_POINT %s' % (topCardCount, self.FOLLOW_FRIEND_MAX_POINT), 'cards=', self.toHumanCards(cards), 'out=', []) return [] # 顶牌 dingCards = self._findDingNCardsGTPoint(reducedCards, topCardCount, False, topValidCard.reducedCards.groups[0].point, self.DING_POINT) if dingCards: if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'Firend out %sCards Ding' % (topCardCount), 'cards=', self.toHumanCards(cards), 'out=', self.toHumanCards(dingCards)) return dingCards else: if len(cards) == 1: if (cards[0] in (52, 53) and reducedCards.buckets[13].cardCount > 0 and reducedCards.buckets[14].cardCount > 0): # 出的王牌,并且手里有双王,敌人手牌 > 5不出 if len(self.table.gameRound.topSeat.status.cards) > 5: # 不出 if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'HasHuojian enemyCards > 5', 'cards=', self.toHumanCards(cards), 'out=', []) return [] else: # 出双王 if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'HasHuojian enemyCards <= 5', 'cards=', self.toHumanCards(cards), 'out=', [52, 53]) return [52, 53] # 敌人出牌单牌,大王可以管,小王在外面,并且出牌的敌人手牌>5,则不出 if (cards[0] == 53 and cardNote[13] > 0 and len(self.table.gameRound.topSeat.status.cards) > 5): if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(topValidCard.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'MinKing not Out keep MaxKing', 'cards=', self.toHumanCards(cards), 'out=', []) return [] if ftlog.is_debug(): ftlog.debug('<<< AIPlayer._doPassiveOutCard handCards=', self.toHumanCards(reducedCards.cards), 'seatIndex=', self.player.seat.seatIndex, 'topSeatIndex=', topSeat.seatIndex, 'topCards=', self.toHumanCards(self.table.gameRound.topValidCards.reducedCards.cards), 'cardNote=', cardNote, 'desc=', 'Normal', 'cards=', self.toHumanCards(cards), 'out=', self.toHumanCards(cards)) return cards
def clearPassHuBySeatId(self, seatId): ftlog.debug("clearPassHuBySeatId passHuArr = ", self.__pass_hu, "seatId=", seatId) self.__pass_hu[seatId] = []
def _onConfChanged(event): if _inited and event.isChanged('game:9999:ranking:0'): ftlog.debug('hallranking._onConfChanged') _reloadConf()
def hasChi(self, tiles, tile): """是否有吃牌解 参数说明; tiles - 玩家的所有牌,包括手牌,吃牌,碰牌,杠牌,胡牌 tile - 待吃的牌 """ if tile >= MTile.TILE_DONG_FENG: return [] #是否允许会牌参与,如果不允许,删除会牌 tilesForChi = copy.deepcopy(tiles[MHand.TYPE_HAND]) if not self.tableTileMgr.allowMagicChiPengGang(): magicTile = self.tableTileMgr.getMagicTile() while magicTile in tilesForChi: tilesForChi.remove(magicTile) chiSolutions = MChi.hasChi(tilesForChi, tile) magicTiles = self.tableTileMgr.getMagicTiles(False) if len(magicTiles) == 0: return chiSolutions if not self.tableTileMgr.canUseMagicTile(MTableState.TABLE_STATE_CHI): return chiSolutions magicTile = magicTiles[0] tileArr = MTile.changeTilesToValueArr(tiles[MHand.TYPE_HAND]) magicCount = tileArr[magicTile] tileArr[magicTile] = 0 ftlog.debug('MChiRule.hasChi tile:', tile, ' magicCount:', magicCount) if magicCount == 0 or (tileArr[tile] == 0): return chiSolutions if MTile.getValue(tile) <= 7: # +1[-] +2[+] ==> [tile, magic, tile+2] if tileArr[tile + 1] == 0 and tileArr[tile + 2] > 0: chiSolutions.append([tile, magicTile, tile + 2]) # +1[+] +2[-] ==> [tile, tile + 1, magicTile] if tileArr[tile + 1] > 0 and tileArr[tile + 2] == 0: chiSolutions.append([tile, tile + 1, magicTile]) if (tileArr[tile + 1] + tileArr[tile + 2]) == 0 and magicCount >= 2: chiSolutions.append([tile, magicTile, magicTile]) if MTile.getValue(tile) >= 3: # -2[+] -1[-] ==> [tile - 2, magicTile, tile] if tileArr[tile - 2] > 0 and tileArr[tile - 1] == 0: chiSolutions.append([tile - 2, magicTile, tile]) # -2[0] -1[+] ==> [magicTile, tile - 1, tile] if tileArr[tile - 2] == 0 and tileArr[tile - 1] > 0: chiSolutions.append([magicTile, tile - 1, tile]) if (tileArr[tile - 2] + tileArr[tile - 1]) == 0 and magicCount >= 2: chiSolutions.append([magicTile, magicTile, tile]) if MTile.getValue(tile) >= 2 and MTile.getValue(tile) <= 8: # -1[-] 1[+] ==> magicTile, tile, tile + 1 if tileArr[tile - 1] == 0 and tileArr[tile + 1] > 0: chiSolutions.append([magicTile, tile, tile + 1]) # -1[+] 1[-] ==> [tile - 1, tile, magicTile] if tileArr[tile - 1] > 0 and tileArr[tile + 1] == 0: chiSolutions.append([tile - 1, tile, magicTile]) if (tileArr[tile + 1] + tileArr[tile - 1]) == 0 and magicCount >= 2: chiSolutions.append([magicTile, tile, magicTile]) return chiSolutions