def getConfigForClient(self, gameId, userId, clientId): if day1st.isDayFirstLogin(userId, gameId): return None clientConf = strutil.cloneData(self._clientConf) firstChargeHasSent = hallstore.isGetFirstRechargeReward(userId) if firstChargeHasSent: return None tyGame = gdata.getGame(gameId) if not tyGame: return None userGameInnings = tyGame.getPlayGameCount(userId, clientId) if userGameInnings < 5: return None isFirstRecharged = hallstore.isFirstRecharged(userId) try: if not isFirstRecharged: rechargeFactory = TodoTaskFirstRechargeFactory().decodeFromDict( self._serverConf.get("firstCharge", {}) ) product = rechargeFactory._getProduct(gameId, userId) todoTask = TodoTaskPayOrder(product) clientConf["config"]["button"]["todoTask"] = todoTask.toDict() else: rewardFactory = TodoTaskFirstRechargeRewardFactory.decodeFromDict( self._serverConf.get("firstChargeReward", {}) ) clientConf["config"]["button"]["todoTask"] = rewardFactory.newTodoTask(gameId, userId, clientId).toDict() except: ftlog.exception("TYActivityFirstCharge.getConfigForClient error") return None return clientConf
def linkMsgTime(tag2, msg): if not PERFORMANCE_NET: return msg try: i = msg.find(MSG_KEY) if i <= 0: i = msg.find(NET_KEY) if i < 0: return msg import freetime.entity.config as ftcon tag1 = ftcon.global_config["server_id"] i = msg.find(NET_KEY) if i < 0: x = msg.rfind('}') if x <= 0: return msg msg = msg[0:x] + ',"' + NET_KEY + '":["%s","%s",%0.4f]' % (tag1, tag2, time()) + msg[x:] i = msg.find(NET_KEY) else: x = msg.find(']', i) if i + 16 == x: msg = msg[0:x] + '"%s","%s",%0.4f' % (tag1, tag2, time()) + msg[x:] else: msg = msg[0:x] + ',"%s","%s",%0.4f' % (tag1, tag2, time()) + msg[x:] return msg except: ftlog.exception() return msg
def _doHotFix(hotfixpy, hotparams): ftlog.info('hotfix in :', hotfixpy, 'hotparams=', hotparams) execfile_result = {} execfile_globals = { 'results': execfile_result, 'params': hotparams } if hotfixpy.startswith('file://'): pyfile = gdata.pathBin() + '/' + hotfixpy[7:] ftlog.info('hotfix pyfile=', pyfile) import os if not os.path.isfile(pyfile): execfile_result['error'] = 'File Not Found !' + pyfile else: try: execfile(pyfile, execfile_globals, execfile_globals) except: execfile_result['error'] = ftlog.format_exc() ftlog.exception() else: # elif hotfixpy.startswith('code://') : hotcode = hotfixpy[7:] try: exec hotcode in execfile_globals, execfile_globals except: execfile_result['error'] = ftlog.format_exc() ftlog.exception() ftlog.info('hotfix out :', execfile_result) return execfile_result
def event(cls, msg, gameId): """ 发布事件 """ if gameId not in cls.map_events: return msg # cls.map_events = { # 8: {"EV_PLAYER_GAME_FRAME_END": [("Winner", onEvPlayerGameFrameEnd), ("Shark",onEvPlayerGameFrameEnd)]}, # 30: {} # } cmd = msg.getCmd() action = msg.getParam('action') ev = (cmd, action) if action else cmd receiver_plugins = msg.getKey('receiver_plugins') or [] for plugin_name, handler in cls.map_events[gameId].get(ev, []): if receiver_plugins and plugin_name not in receiver_plugins: continue if _DEBUG: debug('TYPluginCenter.event| run handler <<|gameId, ev, plugin:', gameId, ev, plugin_name) try: if handler(gameId, msg) == cls.EV_CHAIN_STOP: if _DEBUG: debug('TYPluginCenter.event| chain break |gameId, ev, plugin:', gameId, ev, plugin_name) return msg except: ftlog.exception() if _DEBUG: debug('TYPluginCenter.event| run handler >>|gameId, ev, plugin:', gameId, ev, plugin_name) return msg
def doWinlose(self, msg): matchId = msg.getParam('matchId', 0) tableId = msg.getParam('tableId', 0) ccrc = msg.getParam('ccrc', -1) ftlog.debug("<<", "|roomId, tableId, matchId:", self.roomId, tableId, matchId, caller=self) userWinloseList = msg.getParam('users') assert isinstance(userWinloseList, list) allPlayers = [] for userWinlose in userWinloseList: userId = userWinlose.get('userId', 0) seatId = userWinlose.get('seatId', 0) deltaScore = userWinlose.get('deltaScore', 0) if userId > 0: player = self.match.winlose(tableId, ccrc, seatId, userId, deltaScore, deltaScore >= 0) if player: allPlayers.append(player) try: for ele in allPlayers: # 找他的后一名 ftlog.debug('test rank my rank = ', ele.tableRank, ' and find rank = ', ele.tableRank + 1) nextRankPlayer = self._findUserByTableRank(allPlayers, ele.tableRank + 1) if not nextRankPlayer: ftlog.debug('not found') continue ftlog.debug('find yet userID = ', nextRankPlayer.userId, ' name = ', nextRankPlayer.userName) ele.beatDownUserName = nextRankPlayer.userName except: ftlog.exception()
def logTableChat(gameId, roomId, tableId, senderUserId, chatText): if not chatText: return if senderUserId <= 0: return try: username = unicode(str(userdata.getAttr(senderUserId, 'name'))) roomName = unicode(str(gdata.getRoomConfigure(roomId)['name'])) ftlog.hinfo('tableChatLog gameId=%s; room="%s"; table=%s; userId=%s; name="%s"; msg="%s"' % ( gameId, roomName, tableId, senderUserId, username, chatText)) except Exception, e: ftlog.exception('exception locals():', locals())
def _recycleTable(self, tableId): try: shadowRoomId = tableId / 10000 resultStr = self.room.queryTableManageClearPlayersReq(shadowRoomId, tableId) if resultStr: result = json.loads(resultStr) if ftlog.is_debug(): ftlog.debug("|result:", result, caller=self) self.idleTableIds.append(tableId) self.activeTableIds.remove(tableId) except: ftlog.exception()
def _checkDelivery(self, orderDeliveryResult): try: order = orderDeliveryResult.order if order.orderId.startswith('GO'): return consumeDiamond = int(order.chargeInfo.getConsume('coin', 0)) totalPriceDiamond = int(order.product.priceDiamond) * order.count if consumeDiamond < totalPriceDiamond: ftlog.warn('WARNING checkDelivery err=', 'NotEnoughDiamond', 'orderId=', order.orderId, 'userId=', order.userId, 'gameId=', order.gameId, 'productId=', order.productId, 'count=', order.count, 'price=', order.product.price, 'priceDiamond=', order.product.priceDiamond, 'totalPriceDiamond=', totalPriceDiamond, 'consumeDiamond=', consumeDiamond) return elif consumeDiamond > totalPriceDiamond: ftlog.warn('WARNING checkDelivery err=', 'OverLoadDiamond', 'orderId=', order.orderId, 'userId=', order.userId, 'gameId=', order.gameId, 'productId=', order.productId, 'count=', order.count, 'price=', order.product.price, 'priceDiamond=', order.product.priceDiamond, 'totalPriceDiamond=', totalPriceDiamond, 'consumeDiamond=', consumeDiamond) return if orderDeliveryResult.itemList: # 统计获得了多少金币 deliveryChip = TYAssetUtils.getAssetCount(orderDeliveryResult.assetItems, hallitem.ASSET_CHIP_KIND_ID) maxChip = consumeDiamond * CHECK_DIAMOND_CHIP_RATE if deliveryChip > maxChip: ftlog.warn('WARNING checkDelivery err=', 'OverMaxChip', 'orderId=', order.orderId, 'userId=', order.userId, 'gameId=', order.gameId, 'productId=', order.productId, 'count=', order.count, 'price=', order.product.price, 'priceDiamond=', order.product.priceDiamond, 'totalPriceDiamond=', totalPriceDiamond, 'consumeDiamond=', consumeDiamond, 'deliveryChip=', deliveryChip, 'maxChip=', maxChip, 'checkRate=', CHECK_DIAMOND_CHIP_RATE) except: ftlog.exception()
def doHallGameListV3_7(self, userId, gameId, clientId): template = hallgamelist2.getUITemplate(gameId, userId, clientId) if template is None: ftlog.exception('doHallGameListV3_7 error, please check clientId:', clientId) else: games, pages, _innerGames = HallHelper.encodeHallUITemplage(gameId, userId, clientId, template) mo = MsgPack() mo.setCmd('hall_game_list') mo.setResult('gameId', gameId) mo.setResult('userId', userId) mo.setResult('games', games) mo.setResult('pages', pages) router.sendToUser(mo, userId)
def doTableManage(self, msg, action): ''' 桌子同步安全操作方法 桌子内部处理所有的table_manage命令 实例桌子可以覆盖 _doTableManage 方法来进行自己的业务逻辑处理 ''' if ftlog.is_debug(): ftlog.debug("<< |params:", action, msg, caller=self) try: return self._doTableManage(msg, action) except: ftlog.exception() return {"isOK": False, "reason": TYRoom.ENTER_ROOM_REASON_INNER_ERROR}
def loadRecord(cls, gameId, userId, matchId): try: jstr = gamedata.getGameAttr(userId, gameId, cls.__buildField(matchId)) if ftlog.is_debug(): ftlog.debug('MatchRecord.loadRecord gameId=', gameId, 'userId=', userId, 'matchId=', matchId, 'data=', jstr, caller=cls) if jstr: return MatchRecord.Record.fromDict(json.loads(jstr)) except: ftlog.exception() return None
def getConfigForClient(self, gameId, userId, clientId): """ 预期实现功能。配置中,配置payOrder后台自动生成该商品的todotask """ clientConf = strutil.cloneData(self._clientConf) payOrder = clientConf["config"]["button"]["payOrder"] product, _ = hallstore.findProductByPayOrder(gameId, userId, clientId, payOrder) ftlog.debug("TYActivitySale product: ", product) payOrder = TodoTaskPayOrder(product) ftlog.debug("TYActivitySale params: ", payOrder) try: clientConf["config"]["button"]["todoTask"] = payOrder.toDict() except: ftlog.exception("getConfigForClient error, can not set todotask, clientId:", clientId) return None return clientConf
def _startTable(self, tableId, playerN=0, recyclePlayersN=0): ''' 不锁队列,启动一张桌子 recyclePlayersN表示需要从牌桌回收到队列的人数 ''' ftlog.hinfo("_startTable <<", self.baseLogStr(tableId), "|sittingUsers:", self.sittingUsers, "|playerN, recyclePlayersN:", playerN, recyclePlayersN, caller=self) sittedN = 0 userIds = set() try: while sittedN < playerN and len(self.users) > 0: # 确保无异步操作 userId = self._popOneUser() if not userId: # 队列里没有可以参与分桌的玩家 break userIds.add(userId) sittedN += 1 if ftlog.is_debug(): ftlog.debug("bring user to table", self.baseLogStr(tableId, userId), "|userIds:", userIds, caller=self) # 移到GT处理,节约GT时间 # for userId in userIds: # onlinedata.removeOnlineLoc(userId, self.room.roomId, self.room.roomId * 10000) # if ftlog.is_debug() : # ftlog.debug("|userId, locList:", userId, onlinedata.getOnlineLocList(userId), caller=self) shadowRoomId = tableId / 10000 self.room.sendTableManageGameStartReq(shadowRoomId, tableId, list(userIds), recyclePlayersN) # resultStr = self.room.queryTableManageGameStartReq(shadowRoomId, tableId, list(userIds)) # result = json.loads(resultStr) # ftlog.debug("|result:", result) except: ftlog.exception() self.sittingUsers.difference_update(userIds) ftlog.hinfo("_startTable >>", self.baseLogStr(tableId), "|sittingUsers:", self.sittingUsers, "|len(userIds):", len(userIds), caller=self)
def doWinlose(self, msg): mid = msg.getParam('matchId', 0) tableId = msg.getParam('tableId', 0) ccrc = msg.getParam('ccrc', -1) if self._logger.isDebug(): self._logger.debug('TYGroupMatchRoom.doWinlose', 'mid=', mid, 'tableId=', tableId, 'ccrc=', ccrc) userWinloseList = msg.getParam('users') assert (isinstance(userWinloseList, list)) allPlayers = [] for userWinlose in userWinloseList: userId = userWinlose.get('userId', 0) seatId = userWinlose.get('seatId', 0) deltaScore = userWinlose.get('deltaScore', 0) if userId > 0: if self._logger.isDebug(): self._logger.debug('TYGroupMatchRoom.doWinlose', 'mid=', mid, 'tableId=', tableId, 'ccrc=', ccrc, 'userId=', userId, 'seatId=', seatId, 'deltaScore=', deltaScore) player = self.match.winlose(tableId, ccrc, seatId, userId, deltaScore, deltaScore >= 0) if player: allPlayers.append(player) try: for ele in allPlayers: # 找他的后一名 nextRankPlayer = self._findUserByTableRank(allPlayers, ele.tableRank + 1) if not nextRankPlayer: continue ele.beatDownUserName = nextRankPlayer.userName except: ftlog.exception()
def requestExchange(userId, item, params, timestamp): assert (isinstance(item, TYExchangeItem)) exchangeId = _makeExchangeId() record = TYExchangeRecord(exchangeId) record.itemId = item.itemId record.itemKindId = item.kindId record.createTime = timestamp record.params = params record.errorCode = 0 record.state = TYExchangeRecord.STATE_AUDIT jstr = json.dumps(record.toDict()) _saveRecordData(userId, exchangeId, jstr) parasDict = {} parasDict["user_id"] = userId parasDict["exchange_id"] = exchangeId parasDict["prod_id"] = item.itemId parasDict["prod_kind_name"] = item.itemKind.displayName parasDict["prod_num"] = 1 parasDict["exchange_type"] = params.get("type", 0) parasDict["exchange_amount"] = params.get("count", 0) parasDict["exchange_desc"] = params.get("desc", "") parasDict["user_phone"] = params.get("phone", "") parasDict["user_name"] = params.get("uName", "") parasDict["user_addres"] = params.get("uAddres", "") gdssUrl = hallconf.getItemConf().get("exchangeGdssUrl", "http://gdss.touch4.me/?act=api.propExchange") from poker.util import webpage try: hbody, _ = webpage.webgetGdss(gdssUrl, parasDict) resJson = json.loads(hbody) except: ftlog.exception() raise TYExchangeRequestError() retcode = resJson.get("retcode", -1) retmsg = resJson.get("retmsg", '兑换请求出错') if retcode != 1: raise TYExchangeRequestError(retmsg) ftlog.debug("requestExchange userId=", userId, "exchangeId=", exchangeId, "kindId=", item.kindId) return record
def doWinlose(self, msg): mid = msg.getParam('matchId', 0) tableId = msg.getParam('tableId', 0) ccrc = msg.getParam('ccrc', -1) ftlog.debug("<<", "|roomId, tableId, matchId:", self.roomId, tableId, mid, caller=self) userWinloseList = msg.getParam('users') assert isinstance(userWinloseList, list) allPlayers = [] for userWinlose in userWinloseList: userId = userWinlose.get('userId', 0) seatId = userWinlose.get('seatId', 0) deltaScore = userWinlose.get('deltaScore', 0) if userId > 0: # ftlog.debug( # 'roomId=', rid, 'tableId=', tid, 'ccrc=', ccrc, # 'seatId=', sid, 'userId=', uid, 'deltaScore=', deltaChip) player = self.match.winlose(tableId, ccrc, seatId, userId, deltaScore, deltaScore >= 0) if player: allPlayers.append(player) # 记录玩家打败的对手,比较deltaScore # 记录玩家的名次顺序 # for i in range(0, len(allPlayers)): # player = allPlayers[i] # ftlog.debug("test rank index = ", i, "userId = ", player.userId, "oneplayer.rank = ", player.rank, 'tablerank = ', player.tableRank) try: for ele in allPlayers: # 找他的后一名 ftlog.debug('test rank my rank = ', ele.tableRank, ' and find rank = ', ele.tableRank + 1) nextRankPlayer = self._findUserByTableRank(allPlayers, ele.tableRank + 1) if not nextRankPlayer: ftlog.debug('not found') continue ftlog.debug('find yet userID = ', nextRankPlayer.userId, ' name = ', nextRankPlayer.userName) ele.beatDownUserName = nextRankPlayer.userName except: ftlog.exception()
def getConfigForClient(self, gameId, userId, clientId): try: clientConf = strutil.cloneData(self._clientConf) todoTaskDict = clientConf["config"]["firstButton"] todoTaskFactory = TodoTaskEnterGameNewFactory() todoTaskFactory.decodeFromDict(todoTaskDict) todoTask = todoTaskFactory.newTodoTask(0, 0, 0) clientConf["config"]["firstButton"] = todoTask.toDict() clientConf["config"]["firstButton"]["visible"] = 1 payOrder = clientConf["config"]["secondButton"] payOrderFac = TodoTaskPayOrderFactory() payOrderFac.decodeFromDict({"payOrder": payOrder}) todoTaskPay = payOrderFac.newTodoTask(gameId, userId, clientId) if todoTaskPay: clientConf["config"]["secondButton"] = todoTaskPay.toDict() clientConf["config"]["secondButton"]["visible"] = 1 else: return None except: ftlog.exception("getConfigForClient error, can not set todotask, clientId:", clientId) return None return clientConf
def doSit(self, msg, userId, seatId, clientId): ''' 桌子同步安全操作方法 玩家操作, 尝试再当前的某个座位上坐下 若 seatId为0, 那么需要桌子自动未玩家挑选一个座位 通常此方法由客户端发送quick_start进行快速开始触发: AppClient->ConnServer->UtilServer->RoomServer->ThisTableServer 或: AppClient->ConnServer->RoomServer->ThisTableServer 若 seatId为有效的座位号, 那么桌子需要保证玩家能够正常的坐下 通常此方法由客户端发送quick_start进行断线重连触发: AppClient->ConnServer->ThisTableServer 实例桌子可以覆盖 _doSit 方法来进行自己的业务逻辑处理 无论sit是否成功,都需要调用room.updateTableScore ''' if ftlog.is_debug(): ftlog.debug("<< |params:", userId, seatId, clientId, msg, caller=self) try: return self._doSit(msg, userId, seatId, clientId) except: ftlog.exception() return {"isOK": False, "reason": TYRoom.ENTER_ROOM_REASON_INNER_ERROR} finally: self.room.updateTableScore(self.getTableScore(), self.tableId, force=True)
def handleEvent(cls, event): try: gameId = 6 userId = event.userId conf = dizhuconf.getActivityConf("huiyuan_360") if not cls.clientCheck(gameId, userId, conf): return if not cls.dateCheck(gameId, userId, conf): return data = gamedata.getGameAttrJson(userId, gameId, cls.attr_act, {}) now = datetime.now() now_day = '%d%02d%02d' % (now.year, now.month, now.day) if not data: data = { "days": now_day, "all_count": 30, "current_count": 1, "get_count": 0 } else: if now_day == data["days"]: # 这段代码用于fix以前的bug if data["get_count"] > data["current_count"]: data["get_count"] = 0 gamedata.setGameAttr(userId, gameId, cls.attr_act, json.dumps(data)) return lastdate = datetime.strptime(data["days"], '%Y%m%d').date() if (now.date() - lastdate).days != 1: data = { "days": now_day, "all_count": 30, "current_count": 1, "get_count": 0 } else: data["days"] = now_day data["current_count"] += 1 # 这段代码用于fix以前的bug if data["get_count"] > data["current_count"]: data["get_count"] = 0 if data["current_count"] >= data["all_count"]: data = { "days": now_day, "all_count": 30, "current_count": 1, "get_count": 0 } ftlog.debug("login30 gameId=", gameId, "userId=", userId, "data=", data) gamedata.setGameAttr(userId, gameId, cls.attr_act, json.dumps(data)) except: ftlog.exception()
def reload(cls, gameId, handler_name='', handler_names=[], handlers_config=None): ''' reload 某个 gameId 的插件 @handlers_names: 指定要reload哪些plugin。不指定就reload所有(plugins越来越多,会比较慢) 不管有没有指定 reload 哪些插件,都会重新 build 事件表。 为什么不优化为只处理指定的plugins的事件? 没有必要,性能瓶颈不在这,而且全部重新build一定不会出问题,而且的而且,那样做会增加复杂性。 ''' if not cls.needLoadPlugin(): ftlog.info('reload >> |this type of server not need load plugin', '|serverId, gameId:', gdata.serverId(), gameId, caller=cls) return if cls.isOtherGameServer(gameId): ftlog.info('reload >> |', 'do not reload in other game GR/GT', '|serverId, gameId:', gdata.serverId(), gameId, caller=cls) return if not handlers_config: handlers_config = configure.getGameJson(gameId, 'plugins', {}) if not handlers_config: return # handlers_config = dict([(hc['name'], hc) for hc in handlers_config]) handlers_config_dict = dict([(hc['name'], hc) for hc in handlers_config['handlers']]) ftlog.info('<< |', cls.plugins, handlers_config, caller=cls) if handler_name: handler_names = [handler_name] handlers_config_list = [] # to be reload cls.map_events[gameId] = {} # 事件表 if handler_names: for handler_name in handler_names: if handler_name in handlers_config_dict: handlers_config_list.append( handlers_config_dict.get(handler_name)) if handler_name in cls.plugins[gameId]: del cls.plugins[gameId][handler_name] else: handlers_config_list = handlers_config['handlers'] cls.plugins[gameId] = {} # plugins 表 # 先 reload modules plugins = cls.plugins[gameId] reloadPlugins = [] for cfg in handlers_config_list: try: plugin = TYPlugin(gameId, cfg) if plugin.handlers: plugins[cfg['name']] = plugin reloadPlugins.append(plugin) except Exception as e: ftlog.exception(e) cls.buildEventMap(gameId, plugins, handlers_config, cls.map_events[gameId]) ftlog.info("TYPluginCenter.reload | " "reloadPlugins:", [plugin.name for plugin in reloadPlugins]) # onReload 时可能会有阻塞操作而让出CPU, 这时有可能会产生新的事件 # 如果在 onReload 后才 buildEventMap,则这个事件会丢(因为eventMap在build之前是空的) # 所以,把 onReload 移到 build Event Map 之后 for plugin in reloadPlugins: try: plugin.onReload() except Exception as e: ftlog.exception(e)
def safetyCall(*args, **kwargs): try: return method(*args, **kwargs) except: ftlog.exception()
def doWinLose(cls, room, table, seatId, isTimeOutKill=False): if not table._match_table_info: ftlog.warn('ErdayiMatch.doWinLoseTable roomId=', room.roomId, 'tableId=', table.tableId, 'seatId=', seatId, 'isTimeOutKill=', isTimeOutKill, 'err=', 'not matchTableInfo') return # 计算春天 dizhuseatId = table.status.diZhu if seatId != dizhuseatId: if table.seats[dizhuseatId - 1].outCardCount == 1: table.status.chuntian = 2 else: s1 = table.seats[(dizhuseatId - 1 + 1) % table.maxSeatN] s2 = table.seats[(dizhuseatId - 1 + 2) % table.maxSeatN] if s1.outCardCount == 0 and s2.outCardCount == 0: table.status.chuntian = 2 # 翻倍计算 叫地主的倍数 windoubles = table.status.callGrade # 炸弹倍数 windoubles *= pow(2, table.status.bomb) # 春天倍数 windoubles *= table.status.chuntian # 底牌倍数 windoubles *= table.status.baseCardMulti # 明牌倍数 windoubles *= table.status.show dizhuwin = 0 if seatId == dizhuseatId: dizhuwin = 1 if seatId == 0: # 流局 dizhuwin = 0 windoubles = 1 else: windoubles = abs(windoubles) userids = [seat.userId for seat in table.seats] seat_coin = [0] * len(table.seats) detalChips = [0] * len(table.seats) baseBetChip = table._match_table_info['step']['basescore'] robot_card_count = [0] * len(table.seats) # 每个座位 # 计算所有农民的输赢 for i, player in enumerate(table.players): userids.append(player.userId) if seatId == 0: detalChips[i] = -baseBetChip if i + 1 == dizhuseatId: continue detalChip = baseBetChip * windoubles # 计算本农民的倍数 seatMulti = max(table.seats[i].seatMulti, 1) * max( table.seats[dizhuseatId - 1].seatMulti, 1) detalChip *= seatMulti if dizhuwin: detalChip *= -1 detalChips[i] = detalChip detalChips[dizhuseatId - 1] -= detalChip if ftlog.is_debug(): ftlog.debug('ErdayiMatch.doWinLoseTable roomId=', room.roomId, 'tableId=', table.tableId, 'seatId=', seatId, 'dizhuseatId=', dizhuseatId, 'detalChip=', detalChip, 'dizhuDetalChip=', detalChips[dizhuseatId - 1]) punish.Punish.doWinLosePunish(table.runConfig.punishCardCount, table.runConfig.isMatch, seat_coin, detalChips, robot_card_count) seat_coin = [0] * len(table.seats) for i, seatInfo in enumerate(table._match_table_info['seats']): seat_coin[i] = seatInfo['score'] # 返回当前Table的game_win moWin = MsgPack() moWin.setCmd('table_call') moWin.setResult('action', 'game_win') moWin.setResult('isMatch', 1) moWin.setResult('gameId', table.gameId) moWin.setResult('roomId', table.roomId) moWin.setResult('tableId', table.tableId) # moWin.setResult('stat', dict(zip(tdz_stat_title, table.status))) moWin.setResult('stat', table.status.toInfoDictExt()) moWin.setResult('dizhuwin', dizhuwin) if seatId == 0: moWin.setResult('nowin', 1) moWin.setResult('slam', 0) moWin.setResult('cards', [seat.cards for seat in table.seats]) roundId = table.gameRound.number table.clear(userids) for i, player in enumerate(table.players): uid = player.userId mrank = 3 mtableRanking = 3 moWin.setResult('seat' + str(player.seatId), [ detalChips[i], seat_coin[i], 0, 0, 0, 0, mrank, mtableRanking ]) if not player.isAI: #增加经验 exp = userdata.incrExp(uid, 20) explevel = dizhuaccount.getExpLevel(exp) gamedata.setGameAttr(uid, table.gameId, 'level', explevel) if ftlog.is_debug(): ftlog.debug('ErdayiMatch.doWinLoseTable', 'addExp=', 20, 'curExp=', exp, 'curLevel=', explevel) table.gamePlay.sender.sendToAllTableUser(moWin) # 发送给match manager users = [] for i, player in enumerate(table.players): if not player.isAI: user = {} user['userId'] = player.userId user['deltaScore'] = int(detalChips[i]) user['seatId'] = player.seatId users.append(user) mnr_msg = MsgPack() mnr_msg.setCmd('room') mnr_msg.setParam('action', 'm_winlose') mnr_msg.setParam('gameId', table.gameId) mnr_msg.setParam('matchId', table.room.bigmatchId) mnr_msg.setParam('roomId', table.room.ctrlRoomId) mnr_msg.setParam('tableId', table.tableId) mnr_msg.setParam('users', users) mnr_msg.setParam('ccrc', table._match_table_info['ccrc']) if cls.WINLOSE_SLEEP > 0: FTTasklet.getCurrentFTTasklet().sleepNb(cls.WINLOSE_SLEEP) # 记录游戏winlose try: for u in users: table.room.reportBiGameEvent('TABLE_WIN', u['userId'], table.roomId, table.tableId, roundId, u['deltaScore'], 0, 0, [], 'table_win') except: if ftlog.is_debug(): ftlog.exception() router.sendRoomServer(mnr_msg, table.room.ctrlRoomId)
def reload(cls, gameId, handler_name='', handler_names=[], handlers_config=None): ''' reload 某个 gameId 的插件 @handlers_names: 指定要reload哪些plugin。不指定就reload所有(plugins越来越多,会比较慢) 不管有没有指定 reload 哪些插件,都会重新 build 事件表。 为什么不优化为只处理指定的plugins的事件? 没有必要,性能瓶颈不在这,而且全部重新build一定不会出问题,而且的而且,那样做会增加复杂性。 ''' if not cls.needLoadPlugin(): ftlog.info('reload >> |this type of server not need load plugin', '|serverId, gameId:', gdata.serverId(), gameId, caller=cls) return if cls.isOtherGameServer(gameId): ftlog.info('reload >> |', 'do not reload in other game GR/GT', '|serverId, gameId:', gdata.serverId(), gameId, caller=cls) return if not handlers_config: handlers_config = configure.getGameJson(gameId, 'plugins', {}) if not handlers_config: return # handlers_config = dict([(hc['name'], hc) for hc in handlers_config]) handlers_config_dict = dict([(hc['name'], hc) for hc in handlers_config['handlers']]) ftlog.info('<< |', cls.plugins, handlers_config, caller=cls) if handler_name: handler_names = [handler_name] handlers_config_list = [] # to be reload cls.map_events[gameId] = {} # 事件表 if handler_names: for handler_name in handler_names: if handler_name in handlers_config_dict: handlers_config_list.append(handlers_config_dict.get(handler_name)) if handler_name in cls.plugins[gameId]: del cls.plugins[gameId][handler_name] else: handlers_config_list = handlers_config['handlers'] cls.plugins[gameId] = {} # plugins 表 # 先 reload modules plugins = cls.plugins[gameId] reloadPlugins = [] for cfg in handlers_config_list: try: plugin = TYPlugin(gameId, cfg) if plugin.handlers: plugins[cfg['name']] = plugin reloadPlugins.append(plugin) except Exception as e: ftlog.exception(e) cls.buildEventMap(gameId, plugins, handlers_config, cls.map_events[gameId]) ftlog.info("TYPluginCenter.reload | " "reloadPlugins:", [plugin.name for plugin in reloadPlugins]) # onReload 时可能会有阻塞操作而让出CPU, 这时有可能会产生新的事件 # 如果在 onReload 后才 buildEventMap,则这个事件会丢(因为eventMap在build之前是空的) # 所以,把 onReload 移到 build Event Map 之后 for plugin in reloadPlugins: try: plugin.onReload() except Exception as e: ftlog.exception(e)
def handleEvent(cls, event): try: gameId = 6 userId = event.userId conf = dizhuconf.getActivityConf("dashi_send") # 检查日期在活动日期内 if not cls.dateCheck(gameId, userId, conf): cls.removeDashiItems(gameId, userId, conf) return # 检查用户当前在地主游戏中 if not cls.gameCheck(userId, gameId): return # 获得大师分段位 dashi_score = gamedata.getGameAttr(userId, gameId, 'skillscore') or 1 dashi_level = skillscore.get_skill_level(dashi_score) # 获取配置中大师分的段位限制 dashi_level_limit = conf.get("dashi_level", 1) if dashi_level < dashi_level_limit: return # 如果已经发送过大师登陆礼包,则不发送 attrname = cls.getFlagAttr(conf.get('start_date', '2015-01-01')) is_send = gamedata.getGameAttr(userId, gameId, attrname) if is_send: return # 道具生成时间 timestamp = pktimestamp.getCurrentTimestamp() # 要发送的道具列表 items = conf.get("item_send", []) for item in items: contentItem = TYContentItem.decodeFromDict(item) userAssets = hallitem.itemSystem.loadUserAssets(userId) assetKind, _, _ = userAssets.addAsset(gameId, contentItem.assetKindId, contentItem.count, timestamp, 'DIZHU_DASHI_SEND', 0) # 发送邮箱信息 mail_message = conf.get("mail", "") if mail_message: pkmessage.sendPrivate(9999, userId, 0, mail_message) # 通知用户道具和消息存在改变 if assetKind.keyForChangeNotify: datachangenotify.sendDataChangeNotify( gameId, userId, [assetKind.keyForChangeNotify, 'message']) # 成功发送大师登陆礼包,记录下来,避免重复发送 gamedata.setGameAttr(userId, gameId, attrname, 1) ftlog.debug('dashisend dashi_level=', dashi_level, 'dashi_level_limit=', dashi_level_limit, 'userId=', userId) except: ftlog.exception()
def notifyMatchOver(self, player, reason, rankRewards): ''' 通知用户比赛结束了 ''' try: if (reason == MatchFinishReason.USER_WIN or reason == MatchFinishReason.USER_LOSER): try: event_remote.publishMatchWinloseEvent( self._room.gameId, player.userId, self._room.match.matchId, reason == MatchFinishReason.USER_WIN, player.rank, player.group.startPlayerCount, rankRewards.conf if rankRewards else None) from dizhu.entity.matchhistory import MatchHistoryHandler MatchHistoryHandler.onMatchOver( player.userId, player.group.matchConf.recordId, player.rank, reason == MatchFinishReason.USER_WIN, rankRewards.conf if rankRewards else None, player.group.isGrouping) except: self._logger.error('PlayerNotifierDizhu.notifyMatchOver', 'userId=', player.userId, 'groupId=', player.group.groupId, 'reason=', reason, 'rankRewards=', rankRewards.rewards) # 比赛记录保存 try: event = { 'gameId': self._room.gameId, 'userId': player.userId, 'matchId': self._room.match.matchId, 'rank': player.rank, 'isGroup': 1 if player.group.isGrouping else 0 } MatchRecord.updateAndSaveRecord(event) except: self._logger.error('PlayerNotifierDizhu.notifyMatchOver', 'gameId=', self._room.gameId, 'userId=', player.userId, 'reason=', reason, 'matchId=', self._room.match.matchId, 'rank=', player.rank) msg = MsgPack() msg.setCmd('m_over') msg.setResult('gameId', self._room.gameId) msg.setResult('roomId', self._room.bigRoomId) msg.setResult('userId', player.userId) msg.setResult('reason', reason) msg.setResult('rank', player.rank) try: msg.setResult('beatDownUser', player.beatDownUserName) except: ftlog.debug('NobeatDownUser group match') ftlog.exception() if rankRewards or reason == MatchFinishReason.USER_WIN: msg.setResult('info', buildWinInfo(self._room, player, rankRewards)) if rankRewards.todotask: msg.setResult('todotask', rankRewards.todotask) else: msg.setResult('info', buildLoserInfo(self._room, player)) msg.setResult( 'mucount', player.group.startPlayerCount if player.group.isGrouping else player.group.totalPlayerCount) msg.setResult('date', str(datetime.now().date().today())) msg.setResult('time', time.strftime('%H:%M', time.localtime(time.time()))) msg.setResult('addInfo', '') rewardDesc = '' if rankRewards: from dizhu.bigmatch.match import BigMatch msg.setResult('reward', BigMatch.buildRewards(rankRewards)) rewardDesc = BigMatch.buildRewardsDesc(rankRewards) if rewardDesc: msg.setResult('rewardDesc', rewardDesc) msg.setResult('mname', getMatchName(self._room, player)) record = MatchRecord.loadRecord(self._room.gameId, player.userId, self._room.match.matchId) if record: msg.setResult( 'mrecord', { 'bestRank': record.bestRank, 'bestRankDate': record.bestRankDate, 'isGroup': record.isGroup, 'crownCount': record.crownCount, 'playCount': record.playCount }) else: from dizhu.activities.toolbox import Tool msg.setResult( 'mrecord', { 'bestRank': player.rank, 'bestRankDate': Tool.datetimeToTimestamp( datetime.now()), 'isGroup': 1 if player.group.isGrouping else 0, 'crownCount': 1 if player.rank == 1 else 0, 'playCount': 1 }) try: # 设置奖状分享的todotask diplomaShare shareTodoTask = dizhudiplomashare.buildDiplomaShare( player.userName, getMatchName(self._room, player), player.rank, rewardDesc, player.userId) if shareTodoTask: msg.setResult('shareTodoTask', shareTodoTask) except: ftlog.debug('NobeatDownUser group match') ftlog.exception() router.sendToUser(msg, player.userId) if reason in (MatchFinishReason.USER_NOT_ENOUGH, MatchFinishReason.RESOURCE_NOT_ENOUGH): mo = MsgPack() mo.setCmd('m_signs') mo.setResult('gameId', self._room.gameId) mo.setResult('roomId', self._room.bigRoomId) mo.setResult('userId', player.userId) mo.setResult('signs', {self._room.bigRoomId: 0}) router.sendToUser(mo, player.userId) if player.rank == 1 and self._room.roomConf.get('championLed'): ledtext = '玩家%s在斗地主"%s"中过五关斩六将夺得冠军,获得%s!' % ( player.userName, self._room.roomConf['name'], rewardDesc) user_remote.sendHallLed(DIZHU_GAMEID, ledtext, 1, 'global', []) sequence = int(player.group.instId.split('.')[1]) self.report_bi_game_event("MATCH_FINISH", player.userId, player.group.matchId, 0, sequence, 0, 0, 0, [], 'match_end') #_stage.matchingId except: self._logger.error('PlayerNotifierDizhu.notifyMatchOver', 'userId=', player.userId, 'groupId=', player.group.groupId, 'reason=', reason, 'rankRewards=', rankRewards.rewards if rankRewards else None)
def notifyMatchOver(self, player, reason, rankRewards): ''' 通知用户比赛结束了 ''' try: ftlog.info('MatchPlayerNotifierDizhu.notifyMatchOver matchId=', player.matchInst.matchId, 'instId=', player.matchInst.instId, 'userId=', player.userId, 'signinParams=', player.signinParams, 'stageIndex=', player.stage.index, 'rank=', player.rank, 'reason=', reason, 'rankRewards=', rankRewards) if (reason == MatchFinishReason.USER_WIN or reason == MatchFinishReason.USER_LOSER): try: if player.isQuit: rankRewards = None event_remote.publishMatchWinloseEvent( self._room.gameId, player.userId, self._room.match.matchId, reason == MatchFinishReason.USER_WIN, player.rank, player.matchInst.matchConf.stages[0].totalUserCount, rankRewards.conf if rankRewards else None) tempGameResult = 1 if reason == MatchFinishReason.USER_WIN else -1 hall51event.sendToHall51MatchOverEvent(player.userId, self._room.gameId, self._room.bigRoomId, tempGameResult, -1, -1) from dizhu.entity.matchhistory import MatchHistoryHandler MatchHistoryHandler.onMatchOver( player.userId, player.matchInst.matchConf.recordId, player.rank, reason == MatchFinishReason.USER_WIN, rankRewards.conf if rankRewards else None, False, player.mixId) if not rankRewards: matchutil.report_bi_game_event( 'MATCH_REWARD', player.userId, player.matchInst.matchId, 0, int(player.matchInst.instId.split('.')[1]), 0, 0, 0, [ 0, 0, 0, player.rank, int(player.mixId) if player.mixId else 0, 0 ], 'match_reward') except: ftlog.error() # 比赛记录保存 try: event = { 'gameId': self._room.gameId, 'userId': player.userId, 'matchId': self._room.match.matchId, 'rank': player.rank, 'isGroup': 0, 'mixId': player.mixId } MatchRecord.updateAndSaveRecord(event) except: ftlog.error() msg = MsgPack() msg.setCmd('m_over') msg.setResult('mixId', player.mixId) msg.setResult('gameId', self._room.gameId) msg.setResult('roomId', self._room.bigRoomId) msg.setResult('userId', player.userId) msg.setResult('reason', reason) msg.setResult('rank', player.rank) if rankRewards: msg.setResult('info', self.buildWinInfo(player, rankRewards)) else: msg.setResult('info', self.buildLoserInfo(player)) msg.setResult('mucount', player.matchInst.matchConf.stages[0].totalUserCount) msg.setResult('date', str(datetime.now().date().today())) msg.setResult('time', time.strftime('%H:%M', time.localtime(time.time()))) msg.setResult('addInfo', '') rewardDesc = '' if rankRewards: msg.setResult('reward', matchutil.buildRewards(rankRewards)) rewardDesc = matchutil.buildRewardsDesc(rankRewards) if rewardDesc: msg.setResult('rewardDesc', rewardDesc) roomName = player.matchInst.matchConf.getRoomName(player.mixId) arenaContent = dizhuhallinfo.getArenaMatchProvinceContent( player.userId, int(player.mixId) if player.mixId else self._room.bigRoomId, None) if arenaContent: roomName = arenaContent.get('showName') or roomName msg.setResult('mname', roomName) shareInfo = matchutil.buildShareInfo( self._room.gameId, sessiondata.getClientId(player.userId)) msg.setResult('shareInfo', {'erweima': shareInfo['erweima'] if shareInfo else {}}) try: msg.setResult('beatDownUser', player.beatDownUserName) if rankRewards and rankRewards.todotask: msg.setResult('todotask', rankRewards.todotask) # 设置奖状分享的todotask diplomaShare shareTodoTask = dizhudiplomashare.buildDiplomaShare( player.userName, roomName, player.rank, rewardDesc, player.userId) if shareTodoTask: msg.setResult('shareTodoTask', shareTodoTask) if rankRewards: bigImg = rankRewards.conf.get('bigImg', '') if bigImg: msg.setResult('bidImg', bigImg) if ftlog.is_debug(): ftlog.debug( 'MatchPlayerNotifierDizhu.notifyMatchOver userId=', player.userId, 'roomId=', self._room.roomId, 'bigImg=', bigImg, 'rank=', player.rank, 'rankRewards.conf=', rankRewards.conf) except: ftlog.debug('NobeatDownUser arena match') ftlog.exception() # 冠军触发抽奖逻辑 try: from dizhu.games.matchutil import MatchLottery match_lottery = MatchLottery() ret = match_lottery.checkMatchRank(player.userId, self._room.match.matchId, player.rank) if ret: msg.setResult('match_lottery', 1) except: ftlog.debug('MatchLottery arena match') ftlog.exception() ########################### # 玩家红包记录 try: from dizhu.entity import dizhushare shareInfoConf = rankRewards.conf.get('shareInfo', {}) if rankRewards else {} rewardType = shareInfoConf.get('type', '') if shareInfoConf else '' shareNum, shareTotalNum = dizhushare.arenaMatchRewardRecord( player.userId, shareInfoConf) # 常规配置 championRewards = player.matchInst.matchConf.feeRewardList championShareInfo = championRewards[0].rankRewardsList[0].conf.get( 'shareInfo', {}) if arenaContent: # 分ip奖励配置 championRewards = arenaContent.get('rank.rewards', []) if championRewards and championRewards[0].get( 'ranking', {}).get('start', 0) == 1: championShareInfo = championRewards[0].get('shareInfo', {}) rmb = 0 matchShareType = 0 if championShareInfo and championShareInfo.get( 'type', '') == MATCH_REWARD_REDENVELOPE: # 冠军奖励金额 rmb = championShareInfo.get('rmb', 0) matchShareType = 1 if shareInfoConf and str(rewardType) == MATCH_REWARD_REDENVELOPE: rmb = shareInfoConf.get('rmb', 0) shareInfoNew = { "matchShareType": matchShareType, "shareNum": shareNum if shareNum else 0, "shareTotalNum": shareTotalNum if shareTotalNum else 0, "get": 1 if str(rewardType) == MATCH_REWARD_REDENVELOPE else 0, "rmb": '{0:.2f}'.format(rmb) } msg.setResult('shareInfoNew', shareInfoNew) except Exception, e: ftlog.error('MatchPlayerNotifierDizhu.notifyMatchOver', 'gameId=', self._room.gameId, 'userId=', player.userId, 'roomId=', self._room.roomId, 'matchId=', self._room.match.matchId, 'err=', e.message) ########################### record = MatchRecord.loadRecord(self._room.gameId, player.userId, self._room.match.matchId) if record: msg.setResult( 'mrecord', { 'bestRank': record.bestRank, 'bestRankDate': record.bestRankDate, 'isGroup': record.isGroup, 'crownCount': record.crownCount, 'playCount': record.playCount }) else: from dizhu.activities.toolbox import Tool msg.setResult( 'mrecord', { 'bestRank': player.rank, 'bestRankDate': Tool.datetimeToTimestamp(datetime.now()), 'isGroup': 0, 'crownCount': 1 if player.rank == 1 else 0, 'playCount': 1 }) if not player.isQuit: router.sendToUser(msg, player.userId) # 混房冠军LED mixId = player.mixId if mixId: mixConf = MatchPlayerNotifierDizhu.getArenaMixConf( self._room.roomConf, mixId) if player.rank == 1 and mixConf.get('championLed'): clientId = sessiondata.getClientId(player.userId) arenaContent = dizhuhallinfo.getArenaMatchProvinceContent( player.userId, int(mixId) if mixId else self._room.roomId, clientId) if ftlog.is_debug(): ftlog.debug('MatchPlayerNotifierDizhu.notifyMatchOver', 'userId=', player.userId, 'roomId=', self._room.roomId, 'mixId=', mixId, 'roomName', mixConf.get('roomName'), 'rewardShow=', mixConf.get('rewardShow', rewardDesc), 'mixConf=', mixConf) # 冠军发送Led通知所有其他玩家 ledtext = dizhuled._mk_match_champion_rich_text( player.userName, arenaContent.get('name') if arenaContent else mixConf.get('roomName'), arenaContent.get('rewardShow') if arenaContent else mixConf.get('rewardShow', rewardDesc)) LedUtil.sendLed(ledtext, 'global') else: if player.rank == 1 and self._room.roomConf.get( 'championLed') and not player.isQuit: clientId = sessiondata.getClientId(player.userId) arenaContent = dizhuhallinfo.getArenaMatchProvinceContent( player.userId, int(mixId) if mixId else self._room.roomId, clientId) # 冠军发送Led通知所有其他玩家 ledtext = dizhuled._mk_match_champion_rich_text( player.userName, arenaContent.get('name') if arenaContent else roomName, arenaContent.get('rewardShow') if arenaContent else self._room.roomConf.get('rewardShow', rewardDesc)) LedUtil.sendLed(ledtext, 'global') sequence = int(player.matchInst.instId.split('.')[1]) matchutil.report_bi_game_event( 'MATCH_FINISH', player.userId, player.matchInst.matchId, 0, sequence, 0, 0, 0, [int(player.mixId) if player.mixId else 255], 'match_end')
def requestExchangeCash(userId, count, wxappId, timestamp): # 扣除奖券 userAssets = hallitem.itemSystem.loadUserAssets(userId) _, consumeCount, _ = userAssets.consumeAsset(HALL_GAMEID, hallitem.ASSET_COUPON_KIND_ID, count, timestamp, 'WX_GET_CASH', count) if consumeCount < count: raise TYExchangeRequestError('个人提现余额不足: consumeCount=%s, count=%s' % (consumeCount, count)) exchangeId = None try: exchangeId = _makeExchangeId() record = TYExchangeRecord(exchangeId) record.createTime = timestamp amount = count / 100.0 record.params = { 'type': 7, 'count': count, 'amount': amount, 'wxappId': wxappId } record.errorCode = 0 record.state = TYExchangeRecord.STATE_NORMAL jstr = json.dumps(record.toDict()) _saveRecordData(userId, exchangeId, jstr) displayName = '%.2f现金' % (amount) parasDict = {} httpAddr = gdata.httpGame() parasDict[ 'callbackAudit'] = httpAddr + '/v3/game/exchange/auditCallback' parasDict[ 'callbackShipping'] = httpAddr + '/v3/game/exchange/shippingResultCallback' parasDict['user_id'] = userId parasDict['exchange_id'] = exchangeId parasDict['prod_id'] = 'cash' parasDict['prod_kind_name'] = displayName parasDict['prod_num'] = 1 parasDict['exchange_type'] = record.params.get('type', 7) parasDict['exchange_amount'] = amount parasDict['exchange_desc'] = displayName platformId = hallconf.getPublicConf('platformId', None) if platformId: parasDict['platform_id'] = platformId # gdss那边需要 parasDict['user_phone'] = '' parasDict['user_name'] = '' parasDict['user_addres'] = '' parasDict['wxappid'] = wxappId gdssUrl = hallconf.getItemConf().get( 'exchangeGdssUrl', 'http://gdss.touch4.me/?act=api.propExchange') from poker.util import webpage try: hbody, _ = webpage.webgetGdss(gdssUrl, parasDict) resJson = json.loads(hbody) except: ftlog.exception() raise TYExchangeRequestError() retcode = resJson.get('retcode', -1) retmsg = resJson.get('retmsg', '兑换请求出错') if retcode != 1: raise TYExchangeRequestError(retmsg) record.state = TYExchangeRecord.STATE_AUDIT rStr = json.dumps(record.toDict()) _saveRecordData(userId, exchangeId, rStr) ftlog.info('requestExchangeCash', 'userId=', userId, 'count=', count, 'amount=', amount, 'wxappId=', wxappId, 'exchangeId=', exchangeId, 'retcode=', retcode, 'retmsg=', retmsg) TGHall.getEventBus().publishEvent( HallWithdrawCashEvent(userId, HALL_GAMEID, count)) return record, retmsg except: userAssets.addAsset(HALL_GAMEID, hallitem.ASSET_COUPON_KIND_ID, count, timestamp, 'WX_GET_CASH_BACK', count) # 历史提现记录对应减掉这个数额 userdata.incrAttr(userId, 'exchangedCoupon', -abs(count)) ftlog.warn('requestExchangeCash BackCoupon', 'userId=', userId, 'count=', count, 'wxappId=', wxappId, 'exchangeId=', exchangeId) raise finally: datachangenotify.sendDataChangeNotify(HALL_GAMEID, userId, 'coupon')
def notifyMatchOver(self, player, reason, rankRewards): ''' 通知用户比赛结束了 ''' try: ftlog.info('MatchPlayerNotifierDizhu.notifyMatchOver matchId=', player.matchInst.matchId, 'instId=', player.matchInst.instId, 'userId=', player.userId, 'stageIndex=', player.stage.index, 'rank=', player.rank, 'reason=', reason, 'rankRewards=', rankRewards) if (reason == MatchFinishReason.USER_WIN or reason == MatchFinishReason.USER_LOSER): try: event_remote.publishMatchWinloseEvent( self._room.gameId, player.userId, self._room.match.matchId, reason == MatchFinishReason.USER_WIN, player.rank, player.matchInst.matchConf.stages[0].totalUserCount, rankRewards.conf if rankRewards else None) from dizhu.entity.matchhistory import MatchHistoryHandler MatchHistoryHandler.onMatchOver( player.userId, player.matchInst.matchConf.recordId, player.rank, reason == MatchFinishReason.USER_WIN, rankRewards.conf if rankRewards else None, False) except: ftlog.error() # 比赛记录保存 try: event = { 'gameId': self._room.gameId, 'userId': player.userId, 'matchId': self._room.match.matchId, 'rank': player.rank, 'isGroup': 0 } MatchRecord.updateAndSaveRecord(event) except: ftlog.error() msg = MsgPack() msg.setCmd('m_over') msg.setResult('gameId', self._room.gameId) msg.setResult('roomId', self._room.bigRoomId) msg.setResult('userId', player.userId) msg.setResult('reason', reason) msg.setResult('rank', player.rank) if rankRewards: msg.setResult('info', self.buildWinInfo(player, rankRewards)) else: msg.setResult('info', self.buildLoserInfo(player)) msg.setResult('mucount', player.matchInst.matchConf.stages[0].totalUserCount) msg.setResult('date', str(datetime.now().date().today())) msg.setResult('time', time.strftime('%H:%M', time.localtime(time.time()))) msg.setResult('addInfo', '') rewardDesc = '' if rankRewards: from dizhu.bigmatch.match import BigMatch msg.setResult('reward', BigMatch.buildRewards(rankRewards)) rewardDesc = BigMatch.buildRewardsDesc(rankRewards) if rewardDesc: msg.setResult('rewardDesc', rewardDesc) msg.setResult('mname', self._room.roomConf["name"]) try: msg.setResult('beatDownUser', player.beatDownUserName) if rankRewards and rankRewards.todotask: msg.setResult('todotask', rankRewards.todotask) # 设置奖状分享的todotask diplomaShare shareTodoTask = dizhudiplomashare.buildDiplomaShare( player.userName, self._room.roomConf["name"], player.rank, rewardDesc, player.userId) if shareTodoTask: msg.setResult('shareTodoTask', shareTodoTask) except: ftlog.debug('NobeatDownUser arena match') ftlog.exception() record = MatchRecord.loadRecord(self._room.gameId, player.userId, self._room.match.matchId) if record: msg.setResult( 'mrecord', { 'bestRank': record.bestRank, 'bestRankDate': record.bestRankDate, 'isGroup': record.isGroup, 'crownCount': record.crownCount, 'playCount': record.playCount }) else: from dizhu.activities.toolbox import Tool msg.setResult( 'mrecord', { 'bestRank': player.rank, 'bestRankDate': Tool.datetimeToTimestamp( datetime.now()), 'isGroup': 0, 'crownCount': 1 if player.rank == 1 else 0, 'playCount': 1 }) router.sendToUser(msg, player.userId) if player.rank == 1 and self._room.roomConf.get('championLed'): # 冠军发送Led通知所有其他玩家 ledtext = dizhuled._mk_match_champion_rich_text( player.userName, self._room.roomConf['name'], self._room.roomConf.get('rewardShow', rewardDesc)) LedUtil.sendLed(ledtext, 'global') sequence = int(player.matchInst.instId.split('.')[1]) self.report_bi_game_event('MATCH_FINISH', player.userId, player.matchInst.matchId, 0, sequence, 0, 0, 0, [], 'match_end') except: ftlog.error()
def handleEvent(cls, event): try: winlose = event.winlose if not winlose.isWin: # 失败不弹出 return if event.skillLevelUp: # 升段不弹出 return clientGiftVer = SessionDizhuVersion.getVersionNumber(event.userId) if clientGiftVer >= 3.824: # 新礼包过滤老礼包 from poker.entity.configure import gdata roomConf = gdata.getRoomConfigure(event.roomId) newTypeOfGift = roomConf.get('newTypeOfGift', 0) if roomConf else None if ftlog.is_debug(): ftlog.debug('ChargeLead handleEvent', 'roomId=', event.roomId, 'clientVer=', clientGiftVer, 'newTypeOfGift=', newTypeOfGift, 'roomConf=', roomConf, 'newTypeOfGift=', newTypeOfGift) if newTypeOfGift: return winstreak = gamedata.getGameAttr(event.userId, event.gameId, 'winstreak') or 0 # 纪录连胜日志, 方便以后线上查询 ftlog.debug('[<ChargeLead>UserTableWinloseEvent|isWin=True]Dizhu', 'gameId=', event.gameId, 'userId=', event.userId, 'roomId=', event.roomId, 'slam=', winlose.slam, 'chunTian=', winlose.chunTian, 'skillLevelUp=', event.skillLevelUp, 'mixConfRoomId=', event.mixConfRoomId, 'winstreak=', winstreak) clientId = sessiondata.getClientId(event.userId) _, clientVer, _ = strutil.parseClientId(clientId) # 当玩家取得3的倍数连胜时或达成春天、大满贯(及以上倍数)取胜时弹出高手礼包 if winstreak % 3 == 0 or winlose.slam or winlose.chunTian: if ftlog.is_debug(): ftlog.debug('ChargeLead.handleEvent gameId=', event.gameId, 'userId=', event.userId, 'roomId=', event.roomId, 'winstreak=', winstreak, 'mixConfRoomId=', event.mixConfRoomId, 'clientId=', clientId) if clientVer >= 3.7: todotask = hallpopwnd.makeTodoTaskWinBuy(event.gameId, event.userId, clientId, event.mixConfRoomId or event.roomId) if todotask: todotask.setParam('delay', 3) TodoTaskHelper.sendTodoTask(event.gameId, event.userId, todotask) else: product, _ = hallproductselector.selectWinleadProduct(event.gameId, event.userId, clientId, event.mixConfRoomId or event.roomId) if not product: ftlog.warn('ChargeLead.handleEvent NotFoundProduct gameId=', event.gameId, 'userId=', event.userId, 'roomId=', event.roomId, 'winstreak=', winstreak, 'mixConfRoomId=', event.mixConfRoomId, 'clientId=', clientId) return cls.sendChargeLeadToDoTask(event.gameId, event.userId, product) except: ftlog.exception()
def requestExchange(userId, item, params, timestamp): assert (isinstance(item, TYExchangeItem)) exchangeId = _makeExchangeId() record = TYExchangeRecord(exchangeId) record.itemId = item.itemId record.itemKindId = item.kindId record.createTime = timestamp record.params = params record.errorCode = 0 record.state = TYExchangeRecord.STATE_NORMAL jstr = json.dumps(record.toDict()) _saveRecordData(userId, exchangeId, jstr) parasDict = {} httpAddr = gdata.httpGame() parasDict['callbackAudit'] = httpAddr + '/v3/game/exchange/auditCallback' parasDict[ 'callbackShipping'] = httpAddr + '/v3/game/exchange/shippingResultCallback' parasDict['user_id'] = userId parasDict['exchange_id'] = exchangeId parasDict['prod_id'] = item.itemId parasDict['prod_kind_name'] = item.itemKind.displayName parasDict['prod_num'] = 1 parasDict['exchange_type'] = params.get('type', 0) parasDict['exchange_amount'] = params.get('count', 0) parasDict['exchange_desc'] = params.get('desc', '') parasDict['user_phone'] = params.get('phone') parasDict['user_name'] = params.get('uName') parasDict['user_addres'] = params.get('uAddres') platformId = hallconf.getPublicConf('platformId', None) if platformId: parasDict['platform_id'] = platformId if parasDict['exchange_type'] == 5: parasDict['wxappid'] = params.get('wxappid', '') # 微信红包需要 if parasDict['exchange_type'] == 6: parasDict['user_province'] = params.get('uProvince') parasDict['user_city'] = params.get('uCity') parasDict['user_district'] = params.get('uDistrict') parasDict['user_town'] = params.get('uTown') parasDict['jd_product_id'] = params.get('jdProductId', '') gdssUrl = hallconf.getItemConf().get( 'exchangeGdssUrl', 'http://gdss.touch4.me/?act=api.propExchange') from poker.util import webpage try: hbody, _ = webpage.webgetGdss(gdssUrl, parasDict) resJson = json.loads(hbody) except: ftlog.exception() raise TYExchangeRequestError() retcode = resJson.get('retcode', -1) retmsg = resJson.get('retmsg', '兑换请求出错') if retcode != 1: raise TYExchangeRequestError(retmsg) record.state = TYExchangeRecord.STATE_AUDIT rStr = json.dumps(record.toDict()) _saveRecordData(userId, exchangeId, rStr) ftlog.info('requestExchange', 'userId=', userId, 'exchangeId=', exchangeId, 'itemId=', item.itemId, 'itemKindId=', item.kindId, 'retcode=', retcode, 'retmsg=', retmsg) return record, retmsg
def safetyCall(*args, **kwargs): try: return method(*args, **kwargs) except: ftlog.exception()
def doWinLose(cls, room, table, seatId, isTimeOutKill=False): # TODO: if not table._match_table_info: ftlog.warn('ArenaMatchIF.doWinLose roomId=', room.roomId, 'tableId=', table.tableId, 'seatId=', seatId, 'isTimeOutKill=', isTimeOutKill, 'not matchTableInfo') return # 计算春天 dizhuseatId = table.status.diZhu if seatId != dizhuseatId: if table.seats[dizhuseatId - 1].outCardCount == 1: table.status.chuntian = 2 else: s1 = table.seats[(dizhuseatId - 1 + 1) % table.maxSeatN] s2 = table.seats[(dizhuseatId - 1 + 2) % table.maxSeatN] if s1.outCardCount == 0 and s2.outCardCount == 0: table.status.chuntian = 2 # 翻倍计算 叫地主的倍数 windoubles = table.status.callGrade # 炸弹倍数 windoubles *= pow(2, table.status.bomb) # 春天倍数 windoubles *= table.status.chuntian # 底牌倍数 windoubles *= table.status.baseCardMulti # 明牌倍数 windoubles *= table.status.show dizhuwin = 0 if seatId == dizhuseatId: dizhuwin = 1 if seatId == 0: # 流局 dizhuwin = 0 windoubles = 1 else: windoubles = abs(windoubles) userids = [] detalChips = [] seat_coin = [] baseBetChip = table._match_table_info['baseScore'] robot_card_count = [0] * len(table.seats) # 每个座位 for x in xrange(len(table.seats)): uid = table.seats[x].userId userInfo = table._match_table_info['userInfos'][x] userids.append(uid) if seatId == 0: # 流局 detalChip = -baseBetChip else: if dizhuwin: if x + 1 == dizhuseatId: detalChip = baseBetChip + baseBetChip else: detalChip = -baseBetChip else: if x + 1 == dizhuseatId: detalChip = -baseBetChip - baseBetChip else: detalChip = baseBetChip detalChip *= windoubles detalChips.append(detalChip) seat_coin.append(userInfo['score'] + detalChip) robot_card_count[x] = table.seats[x].robotCardCount ftlog.info('dizhu.game_win userId=', uid, 'roomId=', room.roomId, 'tableId=', table.tableId, 'delta=', detalChip) ftlog.debug('doWinLose->after room fee->robot_card_count=', robot_card_count) # table.punishClass().doWinLosePunish(table, seat_coin, detalChips) punish.Punish.doWinLosePunish(table.runConfig.punishCardCount, table.runConfig.isMatch, seat_coin, detalChips, robot_card_count) for x in xrange(len(table.seats)): uid = table.seats[x].userId userInfo = table._match_table_info['userInfos'][x] userInfo['score'] = seat_coin[x] # 返回当前Table的game_win moWin = MsgPack() moWin.setCmd('table_call') moWin.setResult('action', 'game_win') moWin.setResult('isMatch', 1) moWin.setResult('gameId', table.gameId) moWin.setResult('roomId', table.roomId) moWin.setResult('tableId', table.tableId) # moWin.setResult('stat', dict(zip(tdz_stat_title, table.status))) moWin.setResult('stat', table.status.toInfoDictExt()) moWin.setResult('dizhuwin', dizhuwin) if seatId == 0: moWin.setResult('nowin', 1) moWin.setResult('slam', 0) moWin.setResult('cards', [seat.cards for seat in table.seats]) roundId = table.gameRound.number table.clear(userids) for x in xrange(len(userids)): uid = userids[x] mrank = 3 mtableRanking = 3 moWin.setResult('seat' + str(x + 1), [ detalChips[x], seat_coin[x], 0, 0, 0, 0, mrank, mtableRanking ]) #增加经验 exp = userdata.incrExp(uid, 20) explevel = dizhuaccount.getExpLevel(exp) gamedata.setGameAttr(uid, table.gameId, 'level', explevel) ftlog.debug('BigMatch.doWinLoseTable add 20 exp, tootle', exp, 'level', explevel) # nhWin = [] # table.makeBroadCastUsers(nhWin) # tasklet.sendUdpToMainServer(moWin, nhWin) table.gamePlay.sender.sendToAllTableUser(moWin) # 发送给match manager users = [] for x in xrange(len(userids)): user = {} user['userId'] = userids[x] user['deltaScore'] = int(detalChips[x]) user['seatId'] = x + 1 users.append(user) mnr_msg = MsgPack() mnr_msg.setCmd('room') mnr_msg.setParam('action', 'm_winlose') mnr_msg.setParam('gameId', table.gameId) mnr_msg.setParam('matchId', table.room.bigmatchId) mnr_msg.setParam('roomId', table.room.ctrlRoomId) mnr_msg.setParam('tableId', table.tableId) mnr_msg.setParam('users', users) mnr_msg.setParam('ccrc', table._match_table_info['ccrc']) if cls.WINLOSE_SLEEP > 0: FTTasklet.getCurrentFTTasklet().sleepNb(cls.WINLOSE_SLEEP) # 记录游戏winlose try: for u in users: table.room.reportBiGameEvent("TABLE_WIN", u['userId'], table.roomId, table.tableId, roundId, u['deltaScore'], 0, 0, [], 'table_win') # cls.report_bi_game_event(TyContext.BIEventId.TABLE_WIN, u['userId'], table._rid, table._id, table._roundId, u['deltaScore'], 0, 0, [], 'table_win') except: if ftlog.is_debug(): ftlog.exception() router.sendRoomServer(mnr_msg, table.room.ctrlRoomId)