def broadcast(self): _len = self.msgs.qsize() if _len > 0: _count = min(_len, CHAR_MSG_BROADCAST_MAX_LEN) i = 0 _msgs = [] while i < _count: i += 1 try: _msgs.append(self.msgs.get_nowait()) except Queue.Empty: break except Exception as e: log.error("Broadcast error. e: %s." % (e)) cids_in_room, cids_notice = g_UserMgr.getAllianceCids( self.alliance_id) #log.info('For Test. cids_in_room: {0}, cids_notice: {1}.'.format( cids_in_room, cids_notice )) if cids_in_room and _msgs: gw_broadcast(self.broadcast_protocol, _msgs, cids_in_room) if cids_notice and _msgs: g_UserMgr.updateNotifyFlag(cids_notice) gw_broadcast('new_chat_message', [self.channel], cids_notice) reactor.callLater(CHAT_BROADCAST_INTERVAL, self.broadcast)
def random_chest(self, chest_id, chest_num): ''' @summary: 开宝箱时随机道具 @return : new_items=[[type, id, num], ...] ''' new_items = [] msg_item_ids = [] # 需要走马灯通告的道具信息 i = 0 while i < chest_num: i += 1 _item_rand = yield package_open(self.user, chest_id) if _item_rand: _item_type, _item_id, _item_num, _notice = _item_rand new_items.append((_item_type, _item_id, _item_num)) if _notice: msg_item_ids.append((_item_type, _item_id, _item_num)) if msg_item_ids: message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_RARE_ITEM, [self.user.nick_name, chest_id, msg_item_ids] ] ] gw_broadcast('sync_broadcast', [message]) log.info('random items length: {0}.'.format(len(new_items))) defer.returnValue(new_items)
def random_chest(self, chest_id, chest_num): ''' @summary: 开宝箱时随机道具 @return : new_items=[[type, id, num], ...] ''' new_items = [] msg_item_ids = [] # 需要走马灯通告的道具信息 i = 0 while i < chest_num: i += 1 _item_rand = yield package_open(self.user, chest_id) if _item_rand: _item_type, _item_id, _item_num, _notice = _item_rand new_items.append((_item_type, _item_id, _item_num)) if _notice: msg_item_ids.append((_item_type, _item_id, _item_num)) if msg_item_ids: message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_RARE_ITEM, [self.user.nick_name, chest_id, msg_item_ids]]] gw_broadcast('sync_broadcast', [message]) log.info('random items length: {0}.'.format( len(new_items) )) defer.returnValue( new_items )
def get_touch_reward(self, location): self.opened_num += 1 rate = get_lover_kiss_conf(self.opened_num)['LuxuryRewardRate'] _rand = rand_num() if _rand <= rate and self.big_reward == 0: reward = self.rand_reward_by_type(LUXURY_TYPE) self.big_reward = 1 else: reward = self.rand_reward_by_type(NORMAL_TYPE) notice = reward[-1] if notice: message = [ACHIEVE_TYPE_LOVER_KISS, self.user.nick_name, reward[0]] gw_broadcast('sync_broadcast', [message]) _item = yield item_add(self.user, ItemType=reward[1], ItemID=reward[0], ItemNum=reward[2], AddType=WAY_LOVER_KISS) self.opened_list[location] = _item[1][0][2] self.synced = False self.sync() defer.returnValue([ _item[1], self.opened_list, self.normal_rose, self.blue_rose, BLUE_ROSE_MAX_NUM - self.extra_blue_rose ])
def receive(self, user): cid = user.cid _recved = yield newYearPackage.received_today(cid) if _recved: defer.returnValue((NEWYEAR_PACKAGE_RECEIVED_ALREADY, None)) _item_rand = yield package_open(user, NEWYEAR_PACKAGE_ID) if _item_rand: user_item_id = 0 _item_type, _item_id, _item_num, _notice = _item_rand _res = yield item_add(user, ItemType=_item_type, ItemID=_item_id, ItemNum=_item_num, AddType=WAY_NEW_YEAR_PACKAGE) self.received_character_list.append( (user.lead_id, user.nick_name, _item_num)) redis.hset(DICT_NEWYEAR_PACKAGE, cid, int(time())) if _notice: message = RORATE_MESSAGE_ACHIEVE, ( ACHIEVE_TYPE_OPEN_NEWYEAR_PACKAGE, (user.nick_name, _item_num)) gw_broadcast('sync_broadcast', (message, )) defer.returnValue( (NO_ERROR, (user_item_id, _item_type, _item_id, _item_num))) else: defer.returnValue((UNKNOWN_ERROR, None))
def sync_arena_lottery(p, req): ''' 翻牌奖励进玩家背包 @param: msg_notice-0:无走马灯,1-走马灯广播''' res_err = UNKNOWN_ERROR cid, [item_type, item_id, item_num, msg_notice] = req user = g_UserMgr.getUser(cid) if not user: log.error('Can not find user. cid: {0}.'.format( cid )) defer.returnValue( res_err ) _model = ITEM_MODELs.get( item_type, None ) if not _model: log.error('Unknown item type. item_type: {0}.'.format( item_type )) defer.returnValue( UNKNOWN_ITEM_ERROR ) res_err, value = yield _model( user, ItemID=item_id, ItemNum=item_num, AddType=WAY_LOTTERY_AWARD, CapacityFlag=False ) if res_err: defer.returnValue( res_err ) # 翻牌得到稀有道具 if msg_notice: message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_LOTTERY, [user.base_att.nick_name, item_type, item_id, item_num]]] gw_broadcast('sync_broadcast', [message]) defer.returnValue( value )
def camp_randcard(self, camp_id): ''' 阵营抽卡 ''' _, curr_camp_data, next_camp_data = yield self.get_campcard_data() # 检查阵营, 累计次数 rand_time = 0 for _idx, _data in enumerate(curr_camp_data): if _data[0] == camp_id: if _data[1] >= CAMP_RAND_MAX: defer.returnValue( CAMP_RANDCARD_MAX_LIMIT ) _data[1] += 1 rand_time = _data[1] curr_camp_data[_idx] = _data break else: defer.returnValue( CAMP_RANDCARD_ID_ERROR ) # 随机伙伴 need_credits = get_campcard_cost_conf(rand_time) if not need_credits or need_credits > self.user.credits: log.error('Credits not enough. cid:{0}, need:{1}, curr: {2}.'.format( self.cid, need_credits, self.user.credits )) defer.returnValue( CHAR_CREDIT_NOT_ENOUGH ) pool_conf = get_campcard_pool_conf(camp_id, rand_time) res_err, card = self.randcard_frompool( pool_conf ) if res_err: log.error('No camp randcard pool. cid:{0}, camp_id:{1}, rand_time:{2}.'.format( self.cid, camp_id, rand_time )) defer.returnValue( res_err ) # 扣钻石 yield self.user.consume_credits( need_credits, WAY_CAMP_RANDCARD ) # 更新抽卡次数 yield redis.hset(HASH_CAMPRAND_COMMON, self.cid, dumps([int(time()), curr_camp_data, next_camp_data])) # 新增伙伴 try: new_fellows = [] # args: fellow_id, is_major, camp_id, on_troop res_err, attrib = yield self.user.fellow_mgr.create_table_data( card['ItemID'], 0, 0, 0 ) if not res_err: new_fellows.append( [attrib.attrib_id, card['ItemID']] ) conf = get_fellow_by_fid( card['ItemID'] ) if conf: syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, attrib.attrib_id, card['ItemID'], conf['QualityLevel'], conf['Star'], WAY_CAMP_RANDCARD, '') except Exception as e: log.warn('Create fellow fail! e:', e) defer.returnValue(res_err) # 阵营抽卡抽到紫卡, 全服广播 if card['Notice']: message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_RANDCARD, [self.user.nick_name, RANDCARD_TYPE_CAMP, [card['ItemID']]]]] gw_broadcast('sync_broadcast', [message]) yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_16, 1) defer.returnValue( (self.user.credits, rand_time, new_fellows) )
def random_chest_old(self, chest_id, chest_num): ''' @summary: 开宝箱时随机道具 @return : new_items=[[type, id, num], ...] ''' new_items = [] msg_item_ids = [] # 需要走马灯通告的道具信息 conf = get_random_chest_conf( chest_id ) if not conf: log.error('No random_chest conf. chest_id: {0}.'.format( chest_id )) defer.returnValue( new_items ) data = yield redis.hget( HASH_RANDOM_CHEST % chest_id, self.cid ) if data: data = loads(data) else: data = {} for _i in range(0, chest_num): chest_pool = [] for _id, _value in conf.iteritems(): _rate = _value['Rate'] + data.get(_id, data.setdefault(_id, 0)) _rate = _value['MaxRate'] if _rate > _value['MaxRate'] else _rate chest_pool.extend( [_id] * _rate ) if not chest_pool: log.error('No random_chest pool. chest_id: {0}.'.format( chest_id )) continue rand_id = random.choice( chest_pool ) # 更新rate for _id, _value in conf.iteritems(): if _id == rand_id: data[_id] = 0 new_items.append( [_value['ItemType'], _value['ItemID'], _value['ItemNum']] ) if _value['Notice']: msg_item_ids.append( [_value['ItemType'], _value['ItemID'], _value['ItemNum']] ) else: data[_id] += _value['AddRate'] yield redis.hset( HASH_RANDOM_CHEST % chest_id, self.cid, dumps(data) ) # 在线广播玩家开宝箱得到稀有道具 if msg_item_ids: message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_RARE_ITEM, [self.user.base_att.nick_name, chest_id, msg_item_ids]]] gw_broadcast('sync_broadcast', [message]) log.debug('random items length: {0}.'.format( len(new_items) )) defer.returnValue( new_items )
def gs_gm_sync_activity_notice(p, req): ''' OSS同步活动公告配置, 并写database ''' res_err = {'result': 1} all_new_conf, = req try: values = [] all_old_conf = {} # 活动公告的配置 for _new_conf in all_new_conf: _id = int(_new_conf['id']) # 注意数据类型 all_old_conf[_id] = {} new_open_time = string2datetime(_new_conf['open_time']) new_close_time= string2datetime(_new_conf['close_time']) all_old_conf[_id]['ID'] = _id all_old_conf[_id]['Title'] = _new_conf['title'] all_old_conf[_id]['Content'] = _new_conf['content'] all_old_conf[_id]['OpenTime'] = new_open_time all_old_conf[_id]['CloseTime'] = new_close_time # 获取被修改的活动信息 values.append( [_id, _new_conf['title'], _new_conf['content'], new_open_time, new_close_time] ) except Exception as e: log.exception() res_err['result'] = OSS_ACTIVITY_NOTICE_ERROR return res_err # 更新内存中的 sysconfig sysconfig['activity_notice'] = all_old_conf # 通知在线玩家公告有变更 gw_broadcast('sync_multicast', [SYNC_MULTICATE_TYPE_8, []]) # 更新db conn = MySQLdb.connect(**sysconfig_db_conf) cursor = conn.cursor() cursor.execute( 'TRUNCATE TABLE tb_activity_notice;' ) if values: sql_insert = 'INSERT INTO tb_activity_notice (ID,Title,Content,OpenTime,CloseTime) VALUES (%s,%s,%s,%s,%s);' cursor.executemany( sql_insert, values ) conn.commit() cursor.close() conn.close() return res_err
def close(self): _last_attacker_id, _last_attacker_name = 0, '' if self._last_attackers and self.life <= 0: _last_attacker_id, _last_attacker_name = self._last_attackers[ -1][:2] _cids = yield redis.zrange(RANK_WORLDBOSS_DAMAGE, 0, 3) if not _cids: defer.returnValue(None) #没有一个人杀Boss,不算拉拉拉 _dict_char_info = yield redis.hmget(DICT_WORLDBOSS_RANKER_DATA, _cids) self._char_names_last = [ loads(_info)[0] for _info in _dict_char_info if _info ] _len = len(self._char_names_last) if _len < 3: for x in xrange(3 - _len): self._char_names_last.append('') #log.warn('[ ddd ]:_cids:', _cids, '_dict_char_info:', _dict_char_info, '_len:', _len, '_char_names_last:', self._char_names_last) for _cid, _attacker in AttackerData._cache.iteritems(): if _attacker._attack_count > 0: _rank = yield _attacker.rank reward_golds, reward_farm, last_kill_golds, last_kill_fame = self.reward_to_char( _cid, _last_attacker_id, _rank + 1) if _cid in self._attackers: _attacker.reward(self.life, reward_golds, reward_farm, last_kill_golds, last_kill_fame, _last_attacker_name, _rank) self._char_name_lastkill = _last_attacker_name self.sync() res = yield self.current_rank() if res != []: first_user = g_UserMgr.getUser(res[0][0]) if first_user: msg = [11, [first_user.nick_name, first_user.lead_id]] gw_broadcast('sync_broadcast', [[3, msg]]) log.info('[ CLOSED ]WorldBoss have finished. last kill:', (_last_attacker_id, _last_attacker_name), 'last attackers:', self._last_attackers)
def get_touch_reward(self, location): self.opened_num += 1 rate = get_lover_kiss_conf(self.opened_num)['LuxuryRewardRate'] _rand = rand_num() if _rand <= rate and self.big_reward == 0: reward = self.rand_reward_by_type(LUXURY_TYPE) self.big_reward = 1 else: reward = self.rand_reward_by_type(NORMAL_TYPE) notice = reward[-1] if notice: message = [ACHIEVE_TYPE_LOVER_KISS, self.user.nick_name, reward[0]] gw_broadcast('sync_broadcast', [message]) _item = yield item_add(self.user, ItemType = reward[1], ItemID = reward[0], ItemNum = reward[2], AddType = WAY_LOVER_KISS) self.opened_list[location] = _item[1][0][2] self.synced = False self.sync() defer.returnValue( [_item[1], self.opened_list, self.normal_rose, self.blue_rose, BLUE_ROSE_MAX_NUM - self.extra_blue_rose])
def receive(self, user): cid = user.cid _recved = yield newYearPackage.received_today( cid ) if _recved: defer.returnValue((NEWYEAR_PACKAGE_RECEIVED_ALREADY, None)) _item_rand = yield package_open(user, NEWYEAR_PACKAGE_ID) if _item_rand: user_item_id = 0 _item_type, _item_id, _item_num, _notice = _item_rand _res = yield item_add(user, ItemType=_item_type, ItemID=_item_id, ItemNum=_item_num, AddType=WAY_NEW_YEAR_PACKAGE) self.received_character_list.append((user.lead_id, user.nick_name, _item_num)) redis.hset(DICT_NEWYEAR_PACKAGE, cid, int(time())) if _notice: message = RORATE_MESSAGE_ACHIEVE, (ACHIEVE_TYPE_OPEN_NEWYEAR_PACKAGE, (user.nick_name, _item_num)) gw_broadcast('sync_broadcast', (message, )) defer.returnValue((NO_ERROR, (user_item_id, _item_type, _item_id, _item_num))) else: defer.returnValue((UNKNOWN_ERROR, None))
def sync_arena_lottery(p, req): ''' 翻牌奖励进玩家背包 @param: msg_notice-0:无走马灯,1-走马灯广播''' res_err = UNKNOWN_ERROR cid, [item_type, item_id, item_num, msg_notice] = req user = g_UserMgr.getUser(cid) if not user: log.error('Can not find user. cid: {0}.'.format(cid)) defer.returnValue(res_err) _model = ITEM_MODELs.get(item_type, None) if not _model: log.error('Unknown item type. item_type: {0}.'.format(item_type)) defer.returnValue(UNKNOWN_ITEM_ERROR) res_err, value = yield _model(user, ItemID=item_id, ItemNum=item_num, AddType=WAY_LOTTERY_AWARD, CapacityFlag=False) if res_err: defer.returnValue(res_err) # 翻牌得到稀有道具 if msg_notice: message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_LOTTERY, [user.base_att.nick_name, item_type, item_id, item_num] ] ] gw_broadcast('sync_broadcast', [message]) defer.returnValue(value)
def broadcast(self): _len = self.msgs.qsize() if _len > 0: _count = min(_len, CHAR_MSG_BROADCAST_MAX_LEN) i = 0 _msgs = [] while i < _count: i += 1 try: _msgs.append( self.msgs.get_nowait() ) except Queue.Empty: break except Exception as e: log.error( "Broadcast error. e: %s." % ( e )) cids_in_room, cids_notice = g_UserMgr.getAllianceCids(self.alliance_id) #log.info('For Test. cids_in_room: {0}, cids_notice: {1}.'.format( cids_in_room, cids_notice )) if cids_in_room and _msgs: gw_broadcast(self.broadcast_protocol, _msgs, cids_in_room) if cids_notice and _msgs: g_UserMgr.updateNotifyFlag( cids_notice ) gw_broadcast('new_chat_message', [self.channel], cids_notice) reactor.callLater(CHAT_BROADCAST_INTERVAL, self.broadcast)
def close(self): _last_attacker_id, _last_attacker_name = 0, '' if self._last_attackers and self.life <= 0: _last_attacker_id, _last_attacker_name = self._last_attackers[-1][:2] _cids = yield redis.zrange(RANK_WORLDBOSS_DAMAGE, 0, 3) if not _cids: defer.returnValue(None) #没有一个人杀Boss,不算拉拉拉 _dict_char_info = yield redis.hmget(DICT_WORLDBOSS_RANKER_DATA, _cids) self._char_names_last = [loads(_info)[0] for _info in _dict_char_info if _info] _len = len(self._char_names_last) if _len < 3: for x in xrange(3 - _len): self._char_names_last.append('') #log.warn('[ ddd ]:_cids:', _cids, '_dict_char_info:', _dict_char_info, '_len:', _len, '_char_names_last:', self._char_names_last) for _cid, _attacker in AttackerData._cache.iteritems(): if _attacker._attack_count > 0: _rank = yield _attacker.rank reward_golds, reward_farm, last_kill_golds, last_kill_fame = self.reward_to_char(_cid, _last_attacker_id, _rank + 1) if _cid in self._attackers: _attacker.reward(self.life, reward_golds, reward_farm, last_kill_golds, last_kill_fame, _last_attacker_name, _rank) self._char_name_lastkill = _last_attacker_name self.sync() res = yield self.current_rank() if res != []: first_user = g_UserMgr.getUser(res[0][0]) if first_user: msg = [11, [first_user.nick_name, first_user.lead_id]] gw_broadcast('sync_broadcast', [[3, msg]]) log.info('[ CLOSED ]WorldBoss have finished. last kill:', (_last_attacker_id, _last_attacker_name), 'last attackers:', self._last_attackers)
def advanced(self, user_fellow_id): ''' 伙伴进阶 ''' attrib = self.__gsattribs.get( user_fellow_id, None ) if not attrib: log.error('Unknown user fellow id. ufid: {0}.'.format( user_fellow_id )) defer.returnValue( UNKNOWN_FELLOW_ERROR ) # 主角进阶时取sysconfig['character']的config if attrib.is_major > 0: conf = get_character_by_leadid( self.user.base_att.lead_id ) fellow_id = self.user.base_att.lead_id attrib.level = self.user.base_att.level else: conf = get_fellow_by_fid( attrib.fellow_id ) fellow_id = attrib.fellow_id if not conf: log.error('Can not find the conf. ufid: {0}.'.format( user_fellow_id )) defer.returnValue( NOT_FOUND_CONF ) # 可进阶次数限制 if attrib.advanced_level >= conf['AdvancedCount']: log.error('Fellow advanced count limit. max count: {0}.'.format( conf['AdvancedCount'] )) defer.returnValue( ADVANCED_MAX_COUNT ) advanced_conf = get_fellow_advanced( fellow_id, attrib.advanced_level+1 ) if not advanced_conf: log.error('Can not find advanced conf. user_fellow_id: {0}.'.format( user_fellow_id )) defer.returnValue( NOT_FOUND_CONF ) # 进阶时的伙伴等级限制 if advanced_conf['FellowLevelLimit'] > attrib.level: log.error('fellow level limit. user_fellow_id: {0}, need >= {1}, cur: {2}.'.format( user_fellow_id, advanced_conf['FellowLevelLimit'], attrib.level )) defer.returnValue( REQUEST_LIMIT_ERROR ) # 金币不足 if advanced_conf['Gold'] > self.user.base_att.golds: log.error('Advanced need golds: {0}, cur golds: {1}.'.format( advanced_conf['Gold'], self.user.base_att.golds )) defer.returnValue( CHAR_GOLD_NOT_ENOUGH ) # 进阶消耗的道具不足, 含消耗伙伴 items_list = split_items( advanced_conf['ItemList'] ) for _type, _id, _num in items_list: if _type == ITEM_TYPE_ITEM: total_num, item_attribs = yield self.user.bag_item_mgr.get_items( _id ) if _num > total_num: log.error('item id: {0}, need num: {1}, cur num: {2}.'.format( _id, _num, total_num )) defer.returnValue( CHAR_ITEM_NOT_ENOUGH ) elif _type == ITEM_TYPE_FELLOW: total_num, _ = self.get_fellows_by_fid( _id, user_fellow_id ) if _num > total_num: log.error('Item id: {0}, need num: {1}, cur_num: {2}.'.format( _id, _num, total_num )) defer.returnValue( FELLOW_NOT_ENOUGH ) else: log.error('Unknown advanced item. item: {0}.'.format( (_type, _id, _num) )) defer.returnValue( UNKNOWN_ITEM_ERROR ) # 扣金币、扣道具 #self.user.base_att.golds -= advanced_conf['Gold'] self.user.consume_golds( advanced_conf['Gold'], WAY_FELLOW_REFINE ) items_return = [] for _type, _id, _num in items_list: if _type == ITEM_TYPE_ITEM: res_err, used_attribs = yield self.user.bag_item_mgr.use( _id, _num ) if res_err: log.error('Use item error.') defer.returnValue( res_err ) # used_attribs-已使用的道具 for _a in used_attribs: items_return.append( [_a.attrib_id, _type, _id, _a.item_num] ) elif _type == ITEM_TYPE_FELLOW: total_num, used_attribs = self.get_fellows_by_fid( _id, user_fellow_id ) for _a in used_attribs[:_num]: self.delete_table_data( _a.attrib_id ) items_return.append( [_a.attrib_id, _type, _id, 0] ) # add syslog syslogger(LOG_FELLOW_REFINE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, user_fellow_id, \ attrib.fellow_id, attrib.advanced_level, attrib.advanced_level+1, '') # 进阶后的属性提高 attrib.advanced_level += 1 # 已上阵的伙伴或主角强化 同步camp到redis #if attrib.on_troop > 0 or attrib.is_major > 0: # yield self.user.sync_camp_to_redis(update=True) # 走马灯的成就广播之神将进阶到+5以上, 神将不含主角 if (attrib.advanced_level > 4): message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_ADVANCED, [self.user.base_att.nick_name, attrib.fellow_id, attrib.advanced_level]]] gw_broadcast('sync_broadcast', [message]) defer.returnValue( (user_fellow_id, attrib.advanced_level, self.user.base_att.golds, items_return) )
def randcard(self, card_type, rand_times): ''' @return : err, credits, res_fellow_list ''' res_err = REQUEST_LIMIT_ERROR shrine_data = yield redis.hget(HASH_SHRINE_TYPE % card_type, self.cid) if shrine_data: shrine_data = loads(shrine_data) if len(shrine_data) == 4: shrine_level, rand_count, last_free_time, last_purple_time = shrine_data first_blue, first_purple = 0, 0 else: shrine_level, rand_count, last_free_time, last_purple_time, first_blue, first_purple = shrine_data else: shrine_level, rand_count, last_free_time, last_purple_time, first_blue, first_purple = 0, 0, 0, 0, 1, 1 # 抽卡消耗的配置 _consume = get_randcard_consume_conf(card_type) if not _consume: log.error('Can not find conf.') defer.returnValue(NOT_FOUND_CONF) # 距离下一场免费抽奖所需时间 need_time = self.left_free_timestamp(last_free_time, _consume['FreeTime']) # 检查道具或钻石是否充足 user_credits = self.user.base_att.credits if (_consume['ItemType'] == ITEM_TYPE_MONEY): _rand_cost = _consume['ItemNum'] * rand_times if rand_times > 1: # 无免费抽奖时所需钻石 if (need_time > 0): _rand_cost = int( (_consume['ItemNum'] * 10 * RANDCARD_TEN_RATIO + 99) / 100) else: _rand_cost = int( (_consume['ItemNum'] * 9 * RANDCARD_TEN_RATIO + 99) / 100) # 无免费抽奖时钻石不足 if (need_time > 0) and (_rand_cost > user_credits): log.error('Not enough credits. need: {0}, cur: {1}.'.format( _rand_cost, user_credits)) defer.returnValue(CHAR_CREDIT_NOT_ENOUGH) # 有免费抽奖且是十连抽时钻石不足 elif 0 >= need_time and rand_times > 1 and (_rand_cost > user_credits): log.error('Not enough credits. need: {0}, cur: {1}.'.format( _rand_cost, user_credits)) defer.returnValue(CHAR_CREDIT_NOT_ENOUGH) elif (_consume['ItemType'] == ITEM_TYPE_ITEM): total_num, item_attribs = yield self.user.bag_item_mgr.get_items( _consume['ItemID']) # 情缘令不足 if (_consume['ItemNum'] * rand_times) > total_num: log.error('cur num: {0}.'.format(total_num)) defer.returnValue(CHAR_ITEM_NOT_ENOUGH) else: log.error('Unknown item type: {0}.'.format(_consume['ItemType'])) defer.returnValue(RANDCARD_TYPE_ERROR) # 获取抽卡池 first_flag = 0 if card_type == CARD_SHRINE_BLUE: first_flag = first_blue elif card_type == CARD_SHRINE_PURPLE: first_flag = first_purple pool = self.get_randcard_pool(card_type, shrine_level, rand_count, need_time, last_purple_time, first_flag) if not pool: defer.returnValue(NOT_FOUND_CONF) # 无免费抽卡时更新状态位 if need_time > 0 or (0 >= need_time and rand_times > 1): if card_type == CARD_SHRINE_BLUE: if first_blue: first_flag, first_blue = 0, 0 elif card_type == CARD_SHRINE_PURPLE: if first_purple: first_flag, first_purple = 0, 0 # 抽卡并扣道具或者钻石 items_return = [] card_fellow_ids = [] # 抽卡抽到的fellow msg_fellow_ids = [] # 走马灯公告的fellow cost_credits = 0 # 主要是处理十连抽 max_shrine_level = get_randcard_max_level(card_type) for i in range(0, rand_times): res_err, card = self.randcard_frompool(pool) if res_err: defer.returnValue(res_err) # 消耗道具或者钻石 if (_consume['ItemType'] == ITEM_TYPE_MONEY): if need_time > 0: cost_credits += _consume['ItemNum'] elif (_consume['ItemType'] == ITEM_TYPE_ITEM): res_err, used_attribs = yield self.user.bag_item_mgr.use( _consume['ItemID'], 1) if res_err: log.error('Use item error.') defer.returnValue(res_err) # used_attribs-已使用的道具 for _a in used_attribs: items_return.append( [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num]) card_fellow_ids.append(card['ItemId']) # 更新抽得紫卡的时间 conf = get_fellow_by_fid(card['ItemId']) if conf and conf['Quality'] == QUALITY_PURPLE: msg_fellow_ids.append(card['ItemId']) last_purple_time = int(time()) # 更新玩家的shrine数据, 含rand_count, shrine_level, 及shrine升级后更新pool shrine_level, rand_count, last_free_time = self.update_shrine( card_type, max_shrine_level, shrine_level, rand_count, last_free_time, _consume['FreeTime']) need_time = self.left_free_timestamp(last_free_time, _consume['FreeTime']) # 获取抽卡池 pool = self.get_randcard_pool(card_type, shrine_level, rand_count, need_time, last_purple_time, first_flag) # 保存redis data yield redis.hset( HASH_SHRINE_TYPE % card_type, self.cid, dumps((shrine_level, rand_count, last_free_time, last_purple_time, first_blue, first_purple))) #log.info('For Test. rand fellow_ids: {0}.'.format( card_fellow_ids )) # 抽卡类型 用于广播、syslogger if card_type == CARD_SHRINE_GREEN: _type_name = RANDCARD_TYPE_GREEN _way_name = WAY_RANDCARD_ITEM elif card_type == CARD_SHRINE_BLUE: _type_name = RANDCARD_TYPE_BLUE _way_name = WAY_RANDCARD_BLUE elif rand_times == 10: _type_name = RANDCARD_TYPE_TEN _way_name = WAY_RANDCARD_TEN else: _type_name = RANDCARD_TYPE_PURPLE _way_name = WAY_RANDCARD_PURPLE if cost_credits: # 十连抽时打折 if rand_times > 1: cost_credits = int( (cost_credits * RANDCARD_TEN_RATIO + 99) / 100) msg = [12, [self.user.nick_name, self.user.lead_id]] gw_broadcast('sync_broadcast', [[3, msg]]) yield self.user.consume_credits(cost_credits, _way_name) # 新增fellow new_fellows = [] for _id in card_fellow_ids: try: # args: fellow_id, is_major, camp_id, on_troop res_err, attrib = yield self.user.fellow_mgr.create_table_data( _id, 0, 0, 0) if not res_err: new_fellows.append([attrib.attrib_id, _id]) conf = get_fellow_by_fid(_id) if conf: syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, attrib.attrib_id, _id, conf['QualityLevel'], conf['Star'], _way_name, '') except Exception as e: log.warn('Create fellow fail! e:', e) defer.returnValue(res_err) # 情缘抽到紫卡, 全服广播 if msg_fellow_ids: message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_RANDCARD, [self.user.base_att.nick_name, _type_name, msg_fellow_ids] ] ] gw_broadcast('sync_broadcast', [message]) for _item in items_return: syslogger(LOG_ITEM_LOSE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, _item[0], _item[2], 1, WAY_RANDCARD_ITEM) status = yield self.status() yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_16, 1) defer.returnValue((self.user.base_att.credits, new_fellows, status[0], status[1], status[2], status[3], items_return))
def camp_randcard(self, camp_id): ''' 阵营抽卡 ''' _, curr_camp_data, next_camp_data = yield self.get_campcard_data() # 检查阵营, 累计次数 rand_time = 0 for _idx, _data in enumerate(curr_camp_data): if _data[0] == camp_id: if _data[1] >= CAMP_RAND_MAX: defer.returnValue(CAMP_RANDCARD_MAX_LIMIT) _data[1] += 1 rand_time = _data[1] curr_camp_data[_idx] = _data break else: defer.returnValue(CAMP_RANDCARD_ID_ERROR) # 随机伙伴 need_credits = get_campcard_cost_conf(rand_time) if not need_credits or need_credits > self.user.credits: log.error( 'Credits not enough. cid:{0}, need:{1}, curr: {2}.'.format( self.cid, need_credits, self.user.credits)) defer.returnValue(CHAR_CREDIT_NOT_ENOUGH) pool_conf = get_campcard_pool_conf(camp_id, rand_time) res_err, card = self.randcard_frompool(pool_conf) if res_err: log.error( 'No camp randcard pool. cid:{0}, camp_id:{1}, rand_time:{2}.'. format(self.cid, camp_id, rand_time)) defer.returnValue(res_err) # 扣钻石 yield self.user.consume_credits(need_credits, WAY_CAMP_RANDCARD) # 更新抽卡次数 yield redis.hset(HASH_CAMPRAND_COMMON, self.cid, dumps([int(time()), curr_camp_data, next_camp_data])) # 新增伙伴 try: new_fellows = [] # args: fellow_id, is_major, camp_id, on_troop res_err, attrib = yield self.user.fellow_mgr.create_table_data( card['ItemID'], 0, 0, 0) if not res_err: new_fellows.append([attrib.attrib_id, card['ItemID']]) conf = get_fellow_by_fid(card['ItemID']) if conf: syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, attrib.attrib_id, card['ItemID'], conf['QualityLevel'], conf['Star'], WAY_CAMP_RANDCARD, '') except Exception as e: log.warn('Create fellow fail! e:', e) defer.returnValue(res_err) # 阵营抽卡抽到紫卡, 全服广播 if card['Notice']: message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_RANDCARD, [ self.user.nick_name, RANDCARD_TYPE_CAMP, [card['ItemID']] ] ] ] gw_broadcast('sync_broadcast', [message]) yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_16, 1) defer.returnValue((self.user.credits, rand_time, new_fellows))
def randcard(self, rand_type): ''' 免费抽卡、钻石抽卡 ''' _status, _data = yield self.status() if _status < 0: defer.returnValue( LIMIT_FELLOW_NO_ERROR ) _need_time = self.left_free_timestamp( _data[3], LIMIT_FELLOW_FREE_TIME ) _last_time = _data[3] # 检查抽卡条件是否满足 _score = yield redis.zscore( SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name ) _score = int(_score) if _score else 0 _cost_flag = True # 扣钻石的标识位 if rand_type == RANDCARD_TYPE_FREE: if _need_time > 0: defer.returnValue( LIMIT_FELLOW_FREE_ERROR ) else: _last_time = int(time()) _cost_flag = False _need_time = LIMIT_FELLOW_FREE_TIME else: # 某积分的整数倍时免费钻石抽卡 if not _score or _score%RAND_COST_FREE_SCORE != 0: if self.user.credits < LIMIT_FELLOW_RAND_COST: defer.returnValue( CHAR_CREDIT_NOT_ENOUGH ) else: _cost_flag = False # 卡池升级 res_err, shrine_data = self.update_shrine(_data[1], _data[2]) if res_err: defer.returnValue( res_err ) #log.info('For Test. shrine_data: {0}, redis_data: {1}.'.format( shrine_data, _data )) # 获取抽卡池并抽卡 card_conf = self.get_randcard_frompool(_data[1], shrine_data[3]-_data[2]) if not card_conf: defer.returnValue( NOT_FOUND_CONF ) # 更新免费时间或扣钻石 yield redis.hset( HASH_LIMIT_FELLOW_SHRINE, self.cid, dumps([_data[0], shrine_data[0], shrine_data[1], _last_time]) ) if _cost_flag: yield self.user.consume_credits( LIMIT_FELLOW_RAND_COST, WAY_LIMIT_FELLOW_RANDCARD ) _score += RANDCARD_ONCE_SCORE yield redis.zadd( SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name, _score ) # 新增fellow try: # args: fellow_id, is_major, camp_id, on_troop new_fellow = [] fellow_id = card_conf['ItemId'] res_err, attrib = yield self.user.fellow_mgr.create_table_data( fellow_id, 0, 0, 0 ) if not res_err: new_fellow = [attrib.attrib_id, fellow_id] conf = get_fellow_by_fid( fellow_id ) if conf and conf['Quality'] == QUALITY_PURPLE: syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, \ attrib.attrib_id, fellow_id, conf['QualityLevel'], conf['Star'], RANDCARD_TYPE_CREDITS, '') message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_LIMIT_FELLOW, [self.user.nick_name, fellow_id]]] gw_broadcast('sync_broadcast', [message]) except Exception as e: log.warn('Create fellow fail! e:', e) defer.returnValue(res_err) _rank = yield redis.zrevrank( SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name ) _rank = int(_rank) + 1 if _rank >= 0 else 0 _ranklist = yield self.ranklist() defer.returnValue( [self.user.credits, _rank, _score, _need_time, shrine_data[2], _ranklist, new_fellow] )
def lottery_items(self, user, client_my_rank, enemy_rank, battle_status): ''' @summary: 挑战胜利后,替换双方的排名,并返回可供翻牌的道具列表。长度为3。 ''' items_list = [] # 判断是否处于结算时间 22:00-22:15 _dt_now = datetime.now() if _dt_now.hour == ARENA_RANK_REWARD_HOUR and _dt_now.minute < 15: defer.returnValue( ARENA_IN_REWARD_TIME ) # 扣斗战点 2点 if user.base_att.douzhan < PVP_NEED_DOUZHAN: log.error('user douzhan is 0. cid: {0}.'.format( user.cid )) defer.returnValue( CHAR_DOUZHAN_NOT_ENOUGH ) user.base_att.douzhan -= PVP_NEED_DOUZHAN # 获取我的排名 my_rank = yield self.get_char_rank( user.cid ) if my_rank != client_my_rank: log.error('Client arena rank info need update. cid: {0}, client_my_rank: {1}, my_rank: {2}.'.format( user.cid, client_my_rank, my_rank )) # 每日任务计数 yield user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_6, 1 ) if not battle_status: # 失败获得10声望值 user.get_prestige( 10, WAY_ARENA_BATTLE ) enemy_detail = yield self.get_rank_detail( enemy_rank, flag=False ) if not enemy_detail: log.error('No enemy rank data. cid: {0}, enemy_rank: {1}.'.format( user.cid, enemy_rank )) defer.returnValue( (items_list, user.base_att.douzhan) ) ms_send('write_mail', (enemy_detail[0], MAIL_PAGE_BATTLE, MAIL_BATTLE_1, [user.base_att.lead_id, user.base_att.nick_name])) defer.returnValue( (items_list, user.base_att.douzhan) ) # 胜利获得20声望值 user.get_prestige( 20, WAY_ARENA_BATTLE ) items_list = yield random_lottery_items( user.cid, user.base_att.level, user.base_att.vip_level ) # 名次越靠前, 数字越小; 没有排名时也直接替换 enemy_detail = yield self.get_rank_detail( enemy_rank, flag=False ) if not enemy_detail: log.error('No enemy rank data. cid: {0}, enemy_rank: {1}.'.format( user.cid, enemy_rank )) defer.returnValue( (items_list, user.base_att.douzhan) ) if my_rank == 0 or enemy_rank < my_rank: # 对方是玩家时 互换玩家信息 if enemy_detail[0] > 0: old_enemy_rank = yield self.get_char_rank( enemy_detail[0] ) if my_rank == 0: # 在排名5000(机器人总数)之外 yield redis.zrem( SET_ARENA_CID_RANK, enemy_detail[0] ) alli_send('sync_char_data', (enemy_detail[0], SYNC_ARENA_RANK, 0)) else: if old_enemy_rank == enemy_rank: ms_send('write_mail', (enemy_detail[0], MAIL_PAGE_BATTLE, MAIL_BATTLE_2, [user.base_att.lead_id, user.base_att.nick_name, my_rank])) yield redis.zadd( SET_ARENA_CID_RANK, enemy_detail[0], my_rank ) alli_send('sync_char_data', (enemy_detail[0], SYNC_ARENA_RANK, my_rank)) old_rank_detail = dumps( [enemy_detail[0], enemy_detail[1], enemy_detail[2], my_rank, 0, 0, [], enemy_detail[7]] ) yield redis.hset( HASH_ARENA_RANK, my_rank, old_rank_detail ) elif my_rank > 0: # 对手是机器人, 恢复当前排名机器人数据 old_rank_detail = dumps( [0, 0, '', my_rank, 0, 0, [], 0] ) yield redis.hset( HASH_ARENA_RANK, my_rank, old_rank_detail ) # 更新自己的rank数据 yield redis.zadd( SET_ARENA_CID_RANK, user.cid, enemy_rank ) alli_send('sync_char_data', (user.cid, SYNC_ARENA_RANK, enemy_rank)) # 保存当前的camp #yield user.sync_camp_to_redis(update=True) new_rank_detail = dumps( [user.cid, user.level, user.nick_name, enemy_rank, 0, 0, [], user.lead_id] ) yield redis.hset( HASH_ARENA_RANK, enemy_rank, new_rank_detail ) # 夺得竞技场前十名, 全服广播 if enemy_rank < 11: message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_ARENA, [user.base_att.nick_name, enemy_rank]]] gw_broadcast('sync_broadcast', [message]) elif enemy_rank > my_rank: ms_send('write_mail', (enemy_detail[0], MAIL_PAGE_BATTLE, MAIL_BATTLE_3, [user.base_att.lead_id, user.base_att.nick_name])) #开服狂欢 enemy_rank = enemy_rank if enemy_rank < my_rank else my_rank yield user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_7, enemy_rank) yield user.achievement_mgr.update_achievement_status( ACHIEVEMENT_QUEST_ID_7, enemy_rank) defer.returnValue( (items_list, user.base_att.douzhan) )
def randcard(self, card_type, rand_times): ''' @return : err, credits, res_fellow_list ''' res_err = REQUEST_LIMIT_ERROR shrine_data = yield redis.hget(HASH_SHRINE_TYPE % card_type, self.cid) if shrine_data: shrine_data = loads( shrine_data ) if len(shrine_data) == 4: shrine_level, rand_count, last_free_time, last_purple_time = shrine_data first_blue, first_purple = 0, 0 else: shrine_level, rand_count, last_free_time, last_purple_time, first_blue, first_purple = shrine_data else: shrine_level, rand_count, last_free_time, last_purple_time, first_blue, first_purple = 0, 0, 0, 0, 1, 1 # 抽卡消耗的配置 _consume = get_randcard_consume_conf( card_type ) if not _consume: log.error('Can not find conf.') defer.returnValue( NOT_FOUND_CONF ) # 距离下一场免费抽奖所需时间 need_time = self.left_free_timestamp( last_free_time, _consume['FreeTime'] ) # 检查道具或钻石是否充足 user_credits = self.user.base_att.credits if (_consume['ItemType'] == ITEM_TYPE_MONEY): _rand_cost = _consume['ItemNum']*rand_times if rand_times > 1: # 无免费抽奖时所需钻石 if (need_time > 0): _rand_cost = int((_consume['ItemNum'] * 10 * RANDCARD_TEN_RATIO + 99) / 100) else: _rand_cost = int((_consume['ItemNum'] * 9 * RANDCARD_TEN_RATIO + 99) / 100) # 无免费抽奖时钻石不足 if (need_time > 0) and (_rand_cost > user_credits): log.error('Not enough credits. need: {0}, cur: {1}.'.format( _rand_cost, user_credits )) defer.returnValue( CHAR_CREDIT_NOT_ENOUGH ) # 有免费抽奖且是十连抽时钻石不足 elif 0 >= need_time and rand_times > 1 and (_rand_cost > user_credits): log.error('Not enough credits. need: {0}, cur: {1}.'.format( _rand_cost, user_credits )) defer.returnValue( CHAR_CREDIT_NOT_ENOUGH ) elif (_consume['ItemType'] == ITEM_TYPE_ITEM): total_num, item_attribs = yield self.user.bag_item_mgr.get_items( _consume['ItemID'] ) # 情缘令不足 if (_consume['ItemNum']*rand_times) > total_num: log.error('cur num: {0}.'.format( total_num )) defer.returnValue( CHAR_ITEM_NOT_ENOUGH ) else: log.error('Unknown item type: {0}.'.format( _consume['ItemType'] )) defer.returnValue( RANDCARD_TYPE_ERROR ) # 获取抽卡池 first_flag = 0 if card_type == CARD_SHRINE_BLUE: first_flag = first_blue elif card_type == CARD_SHRINE_PURPLE: first_flag = first_purple pool = self.get_randcard_pool( card_type, shrine_level, rand_count, need_time, last_purple_time, first_flag ) if not pool: defer.returnValue( NOT_FOUND_CONF ) # 无免费抽卡时更新状态位 if need_time > 0 or (0 >= need_time and rand_times > 1): if card_type == CARD_SHRINE_BLUE: if first_blue: first_flag, first_blue = 0, 0 elif card_type == CARD_SHRINE_PURPLE: if first_purple: first_flag, first_purple = 0, 0 # 抽卡并扣道具或者钻石 items_return = [] card_fellow_ids = [] # 抽卡抽到的fellow msg_fellow_ids = [] # 走马灯公告的fellow cost_credits = 0 # 主要是处理十连抽 max_shrine_level = get_randcard_max_level( card_type ) for i in range(0, rand_times): res_err, card = self.randcard_frompool( pool ) if res_err: defer.returnValue( res_err ) # 消耗道具或者钻石 if (_consume['ItemType'] == ITEM_TYPE_MONEY): if need_time > 0: cost_credits += _consume['ItemNum'] elif (_consume['ItemType'] == ITEM_TYPE_ITEM): res_err, used_attribs = yield self.user.bag_item_mgr.use( _consume['ItemID'], 1 ) if res_err: log.error('Use item error.') defer.returnValue( res_err ) # used_attribs-已使用的道具 for _a in used_attribs: items_return.append( [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num] ) card_fellow_ids.append( card['ItemId'] ) # 更新抽得紫卡的时间 conf = get_fellow_by_fid( card['ItemId'] ) if conf and conf['Quality'] == QUALITY_PURPLE: msg_fellow_ids.append( card['ItemId'] ) last_purple_time = int(time()) # 更新玩家的shrine数据, 含rand_count, shrine_level, 及shrine升级后更新pool shrine_level, rand_count, last_free_time = self.update_shrine( card_type, max_shrine_level, shrine_level, rand_count, last_free_time, _consume['FreeTime'] ) need_time = self.left_free_timestamp( last_free_time, _consume['FreeTime'] ) # 获取抽卡池 pool = self.get_randcard_pool( card_type, shrine_level, rand_count, need_time, last_purple_time, first_flag ) # 保存redis data yield redis.hset(HASH_SHRINE_TYPE % card_type, self.cid, dumps((shrine_level, rand_count, last_free_time, last_purple_time, first_blue, first_purple))) #log.info('For Test. rand fellow_ids: {0}.'.format( card_fellow_ids )) # 抽卡类型 用于广播、syslogger if card_type == CARD_SHRINE_GREEN: _type_name = RANDCARD_TYPE_GREEN _way_name = WAY_RANDCARD_ITEM elif card_type == CARD_SHRINE_BLUE: _type_name = RANDCARD_TYPE_BLUE _way_name = WAY_RANDCARD_BLUE elif rand_times == 10: _type_name = RANDCARD_TYPE_TEN _way_name = WAY_RANDCARD_TEN else: _type_name = RANDCARD_TYPE_PURPLE _way_name = WAY_RANDCARD_PURPLE if cost_credits: # 十连抽时打折 if rand_times > 1: cost_credits = int((cost_credits * RANDCARD_TEN_RATIO + 99) / 100) msg = [12, [self.user.nick_name, self.user.lead_id]] gw_broadcast('sync_broadcast',[[3, msg]] ) yield self.user.consume_credits( cost_credits, _way_name ) # 新增fellow new_fellows = [] for _id in card_fellow_ids: try: # args: fellow_id, is_major, camp_id, on_troop res_err, attrib = yield self.user.fellow_mgr.create_table_data( _id, 0, 0, 0 ) if not res_err: new_fellows.append( [attrib.attrib_id, _id] ) conf = get_fellow_by_fid( _id ) if conf: syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, attrib.attrib_id, _id, conf['QualityLevel'], conf['Star'], _way_name, '') except Exception as e: log.warn('Create fellow fail! e:', e) defer.returnValue(res_err) # 情缘抽到紫卡, 全服广播 if msg_fellow_ids: message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_RANDCARD, [self.user.base_att.nick_name, _type_name, msg_fellow_ids]]] gw_broadcast('sync_broadcast', [message]) for _item in items_return: syslogger(LOG_ITEM_LOSE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, _item[0], _item[2], 1, WAY_RANDCARD_ITEM) status = yield self.status() yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_16, 1) defer.returnValue( (self.user.base_att.credits, new_fellows, status[0], status[1], status[2], status[3], items_return) )
def random_chest_old(self, chest_id, chest_num): ''' @summary: 开宝箱时随机道具 @return : new_items=[[type, id, num], ...] ''' new_items = [] msg_item_ids = [] # 需要走马灯通告的道具信息 conf = get_random_chest_conf(chest_id) if not conf: log.error('No random_chest conf. chest_id: {0}.'.format(chest_id)) defer.returnValue(new_items) data = yield redis.hget(HASH_RANDOM_CHEST % chest_id, self.cid) if data: data = loads(data) else: data = {} for _i in range(0, chest_num): chest_pool = [] for _id, _value in conf.iteritems(): _rate = _value['Rate'] + data.get(_id, data.setdefault(_id, 0)) _rate = _value[ 'MaxRate'] if _rate > _value['MaxRate'] else _rate chest_pool.extend([_id] * _rate) if not chest_pool: log.error( 'No random_chest pool. chest_id: {0}.'.format(chest_id)) continue rand_id = random.choice(chest_pool) # 更新rate for _id, _value in conf.iteritems(): if _id == rand_id: data[_id] = 0 new_items.append([ _value['ItemType'], _value['ItemID'], _value['ItemNum'] ]) if _value['Notice']: msg_item_ids.append([ _value['ItemType'], _value['ItemID'], _value['ItemNum'] ]) else: data[_id] += _value['AddRate'] yield redis.hset(HASH_RANDOM_CHEST % chest_id, self.cid, dumps(data)) # 在线广播玩家开宝箱得到稀有道具 if msg_item_ids: message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_RARE_ITEM, [self.user.base_att.nick_name, chest_id, msg_item_ids] ] ] gw_broadcast('sync_broadcast', [message]) log.debug('random items length: {0}.'.format(len(new_items))) defer.returnValue(new_items)
def upgrade_level(self, member, build_type): ''' 公会大殿升级, 大殿等级即公会等级 @param: build_type: 1-仙盟大殿, 2-仙盟女蜗宫, 3-仙盟商店, 4-仙盟副本, 5-仙盟任务大厅 ''' all_levels = get_all_alliance_level() if not all_levels: defer.returnValue( NOT_FOUND_CONF ) max_level = max(all_levels) if build_type == 1: # 已是最高等级 if self.__level >= max_level: defer.returnValue( ALLIANCE_LEVEL_MAX ) # 公会建设度不足 level_conf = get_alliance_level_conf( self.__level ) if not level_conf: defer.returnValue( NOT_FOUND_CONF ) need_contribution = level_conf['GuildHall'] if self.__exp < need_contribution: defer.returnValue( ALLIANCE_CONTRIBUTE_NOT_ENOUGH ) # 公会动态 self.new_action( (ALLIANCE_ACTION_9, int(time()), member.cid, member.lead_id, \ member.nick_name, member.level, [build_type, self.__level, self.__level+1]) ) # 等级+1, 扣建设度 self.__exp -= need_contribution self.__level += 1 # 推送消息给公会当前在线的玩家, 除了自己 _broadcast_cids = self.online_cids( [member.cid] ) if _broadcast_cids: gw_broadcast( 'sync_multicast', [SYNC_MULTICATE_TYPE_6, [self.__id, self.__level, self.__exp]], _broadcast_cids ) # add syslog syslogger(LOG_ALLIANCE_EXP_LOSE, member.cid, member.level, member.vip_level, \ self.__id, self.__level, need_contribution, self.__exp, WAY_ALLIANCE_HALL) # 脏数据 self.dirty() defer.returnValue( (self.__level, self.__exp) ) else: _fields = ['', '', 'GuildWelfareHall', 'GuildShop', 'GuildDungeon', 'GuildTask'] if build_type >= len(_fields): defer.returnValue( REQUEST_LIMIT_ERROR ) cur_level = self.__building_levels[build_type-2] # 已是最高等级 if cur_level >= max_level: defer.returnValue( ALLIANCE_LEVEL_MAX ) # 其它建筑等级不能超过公会等级 if cur_level >= self.__level: defer.returnValue( ALLIANCE_LEVEL_LIMIT ) # 公会建设度不足 level_conf = get_alliance_level_conf( cur_level ) if not level_conf: defer.returnValue( NOT_FOUND_CONF ) need_contribution = level_conf[_fields[build_type]] if self.__exp < need_contribution: defer.returnValue( ALLIANCE_CONTRIBUTE_NOT_ENOUGH ) # 公会动态 self.new_action( (ALLIANCE_ACTION_9, int(time()), member.cid, member.lead_id, \ member.nick_name, member.level, [build_type, cur_level, cur_level+1]) ) # 等级+1, 扣建设度 self.__exp -= need_contribution cur_level += 1 self.__building_levels[build_type-2] = cur_level yield redis.hset(HASH_ALLIANCE_LEVEL, self.__id, dumps(self.__building_levels)) # 推送消息给公会当前在线的玩家, 除了自己 _broadcast_cids = self.online_cids( [member.cid] ) if _broadcast_cids: gw_broadcast( 'sync_multicast', [SYNC_MULTICATE_TYPE_6, [self.__id, self.__level, self.__exp]], _broadcast_cids ) # add syslog syslogger(LOG_ALLIANCE_EXP_LOSE, member.cid, member.level, member.vip_level, \ self.__id, self.__level, need_contribution, self.__exp, WAY_ALLIANCE_BUILD[build_type]) # 脏数据 self.dirty() defer.returnValue( (cur_level, self.__exp) )
def random_new_jade(self, random_times): ''' 获取新的玉魄 ''' # 检查等级限制条件 if random_times == JADE_RANDOM_TIMES_TEN: if (self.user.level < JADE_RANDOM_TEN_LEVEL) and ( self.user.vip_level < JADE_RANDOM_TEN_VIP_LEVEL): defer.returnValue(JADE_RANDOM_TEN_ERROR) # 鉴玉 new_jades, new_items = [], [] msg_item_ids = [] # 需要走马灯通告的道具信息 _curr_random_level = self.random_jade_level _golds_cost, _credits_cost, _left_golds, _left_credits = 0, 0, self.user.golds, self.user.credits for _idx in range(0, random_times): cost_conf = get_jade_cost_conf(_curr_random_level) # 检查消耗数量限制 if not cost_conf: defer.returnValue(NOT_FOUND_CONF) if ITEM_TYPE_MONEY != cost_conf['CostItemType']: defer.returnValue(UNKNOWN_ITEM_ERROR) if ITEM_MONEY_GOLDS == cost_conf['CostItemID']: if _left_golds < cost_conf['CostItemNum']: defer.returnValue(CHAR_GOLD_NOT_ENOUGH) _left_golds -= cost_conf['CostItemNum'] _golds_cost += cost_conf['CostItemNum'] elif ITEM_MONEY_CREDITS == cost_conf['CostItemID']: if _left_credits < cost_conf['CostItemNum']: defer.returnValue(CHAR_CREDIT_NOT_ENOUGH) _left_credits -= cost_conf['CostItemNum'] _credits_cost += cost_conf['CostItemNum'] else: defer.returnValue(UNKNOWN_ITEM_ERROR) _chest_id = JADE_RANDOM_POOLS[_curr_random_level] _item_rand = yield package_open(self.user, _chest_id) if not _item_rand: defer.returnValue(NOT_FOUND_CONF) new_jades.append(_item_rand[:3]) if _item_rand[3]: msg_item_ids.append(_item_rand[:3]) # 鉴玉等级会有一定几率提示、不变、回到初始等级, 并有一定概率获得额外的道具 _next_level, _extra_item = self.random_next_level( _curr_random_level) if _next_level != _curr_random_level: _curr_random_level = _next_level yield redis.hset(HASH_RANDOM_JADE_LEVEL, self.cid, _next_level) if _extra_item: new_items.append(_extra_item) # 扣金币或钻石 if _golds_cost: self.user.consume_golds(_golds_cost, WAY_JADE_RANDOM) if _credits_cost: yield self.user.consume_credits(_credits_cost, WAY_JADE_RANDOM) # 更新最新等级 self.random_jade_level = _curr_random_level #log.info('For Test. _golds_cost: {0}, _credits_cost: {1}, new_jades: {2}, new_items: {3}.'.format( _golds_cost, _credits_cost, new_jades, new_items )) add_jades, add_items = [], [] q = 0 for _type, _id, _num in new_jades: _model = ITEM_MODELs.get(_type, None) if not _model: log.error('Unknown item type. cid: {0}, ItemType: {1}.'.format( self.cid, _type)) continue res_err, value = yield _model(self.user, ItemID=_id, ItemNum=_num, CapacityFlag=False, AddType=WAY_JADE_RANDOM) _quality = get_item_by_itemid(_id).get('Quality', 0) if _quality >= 2: #品质大于2,开服狂欢 q += 1 if not res_err and value: add_jades.extend(value) else: log.warn( 'User add items error. cid: {0}, res_err: {1}, value: {2}.' .format(self.cid, res_err, value)) # 开服狂欢 yield self.user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_16, q) yield self.user.achievement_mgr.update_achievement_status( ACHIEVEMENT_QUEST_ID_16, q) # 新增额外掉落的道具 for _type, _id, _num in new_items: _model = ITEM_MODELs.get(_type, None) if not _model: log.error('Unknown item type. cid: {0}, ItemType: {1}.'.format( self.cid, _type)) continue res_err, value = yield _model(self.user, ItemID=_id, ItemNum=_num, CapacityFlag=False, AddType=WAY_JADE_RANDOM) if not res_err and value: add_items.extend(value) else: log.warn( 'User add items error. cid: {0}, res_err: {1}, value: {2}.' .format(self.cid, res_err, value)) if msg_item_ids: message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_RARE_ITEM, [self.user.nick_name, _chest_id, msg_item_ids] ] ] gw_broadcast('sync_broadcast', [message]) defer.returnValue((self.user.golds, self.user.credits, _curr_random_level, add_jades, add_items))
def advanced(self, user_fellow_id): ''' 伙伴进阶 ''' attrib = self.__gsattribs.get(user_fellow_id, None) if not attrib: log.error( 'Unknown user fellow id. ufid: {0}.'.format(user_fellow_id)) defer.returnValue(UNKNOWN_FELLOW_ERROR) # 主角进阶时取sysconfig['character']的config if attrib.is_major > 0: conf = get_character_by_leadid(self.user.base_att.lead_id) fellow_id = self.user.base_att.lead_id attrib.level = self.user.base_att.level else: conf = get_fellow_by_fid(attrib.fellow_id) fellow_id = attrib.fellow_id if not conf: log.error( 'Can not find the conf. ufid: {0}.'.format(user_fellow_id)) defer.returnValue(NOT_FOUND_CONF) # 可进阶次数限制 if attrib.advanced_level >= conf['AdvancedCount']: log.error('Fellow advanced count limit. max count: {0}.'.format( conf['AdvancedCount'])) defer.returnValue(ADVANCED_MAX_COUNT) advanced_conf = get_fellow_advanced(fellow_id, attrib.advanced_level + 1) if not advanced_conf: log.error( 'Can not find advanced conf. user_fellow_id: {0}.'.format( user_fellow_id)) defer.returnValue(NOT_FOUND_CONF) # 进阶时的伙伴等级限制 if advanced_conf['FellowLevelLimit'] > attrib.level: log.error( 'fellow level limit. user_fellow_id: {0}, need >= {1}, cur: {2}.' .format(user_fellow_id, advanced_conf['FellowLevelLimit'], attrib.level)) defer.returnValue(REQUEST_LIMIT_ERROR) # 金币不足 if advanced_conf['Gold'] > self.user.base_att.golds: log.error('Advanced need golds: {0}, cur golds: {1}.'.format( advanced_conf['Gold'], self.user.base_att.golds)) defer.returnValue(CHAR_GOLD_NOT_ENOUGH) # 进阶消耗的道具不足, 含消耗伙伴 items_list = split_items(advanced_conf['ItemList']) for _type, _id, _num in items_list: if _type == ITEM_TYPE_ITEM: total_num, item_attribs = yield self.user.bag_item_mgr.get_items( _id) if _num > total_num: log.error( 'item id: {0}, need num: {1}, cur num: {2}.'.format( _id, _num, total_num)) defer.returnValue(CHAR_ITEM_NOT_ENOUGH) elif _type == ITEM_TYPE_FELLOW: total_num, _ = self.get_fellows_by_fid(_id, user_fellow_id) if _num > total_num: log.error( 'Item id: {0}, need num: {1}, cur_num: {2}.'.format( _id, _num, total_num)) defer.returnValue(FELLOW_NOT_ENOUGH) else: log.error('Unknown advanced item. item: {0}.'.format( (_type, _id, _num))) defer.returnValue(UNKNOWN_ITEM_ERROR) # 扣金币、扣道具 #self.user.base_att.golds -= advanced_conf['Gold'] self.user.consume_golds(advanced_conf['Gold'], WAY_FELLOW_REFINE) items_return = [] for _type, _id, _num in items_list: if _type == ITEM_TYPE_ITEM: res_err, used_attribs = yield self.user.bag_item_mgr.use( _id, _num) if res_err: log.error('Use item error.') defer.returnValue(res_err) # used_attribs-已使用的道具 for _a in used_attribs: items_return.append( [_a.attrib_id, _type, _id, _a.item_num]) elif _type == ITEM_TYPE_FELLOW: total_num, used_attribs = self.get_fellows_by_fid( _id, user_fellow_id) for _a in used_attribs[:_num]: self.delete_table_data(_a.attrib_id) items_return.append([_a.attrib_id, _type, _id, 0]) # add syslog syslogger(LOG_FELLOW_REFINE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, user_fellow_id, \ attrib.fellow_id, attrib.advanced_level, attrib.advanced_level+1, '') # 进阶后的属性提高 attrib.advanced_level += 1 # 已上阵的伙伴或主角强化 同步camp到redis #if attrib.on_troop > 0 or attrib.is_major > 0: # yield self.user.sync_camp_to_redis(update=True) # 走马灯的成就广播之神将进阶到+5以上, 神将不含主角 if (attrib.advanced_level > 4): message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_ADVANCED, [ self.user.base_att.nick_name, attrib.fellow_id, attrib.advanced_level ] ] ] gw_broadcast('sync_broadcast', [message]) defer.returnValue((user_fellow_id, attrib.advanced_level, self.user.base_att.golds, items_return))
def randcard(self, rand_type): ''' 免费抽卡、钻石抽卡 ''' _status, _data = yield self.status() if _status < 0: defer.returnValue(LIMIT_FELLOW_NO_ERROR) _need_time = self.left_free_timestamp(_data[3], LIMIT_FELLOW_FREE_TIME) _last_time = _data[3] # 检查抽卡条件是否满足 _score = yield redis.zscore(SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name) _score = int(_score) if _score else 0 _cost_flag = True # 扣钻石的标识位 if rand_type == RANDCARD_TYPE_FREE: if _need_time > 0: defer.returnValue(LIMIT_FELLOW_FREE_ERROR) else: _last_time = int(time()) _cost_flag = False _need_time = LIMIT_FELLOW_FREE_TIME else: # 某积分的整数倍时免费钻石抽卡 if not _score or _score % RAND_COST_FREE_SCORE != 0: if self.user.credits < LIMIT_FELLOW_RAND_COST: defer.returnValue(CHAR_CREDIT_NOT_ENOUGH) else: _cost_flag = False # 卡池升级 res_err, shrine_data = self.update_shrine(_data[1], _data[2]) if res_err: defer.returnValue(res_err) #log.info('For Test. shrine_data: {0}, redis_data: {1}.'.format( shrine_data, _data )) # 获取抽卡池并抽卡 card_conf = self.get_randcard_frompool(_data[1], shrine_data[3] - _data[2]) if not card_conf: defer.returnValue(NOT_FOUND_CONF) # 更新免费时间或扣钻石 yield redis.hset( HASH_LIMIT_FELLOW_SHRINE, self.cid, dumps([_data[0], shrine_data[0], shrine_data[1], _last_time])) if _cost_flag: yield self.user.consume_credits(LIMIT_FELLOW_RAND_COST, WAY_LIMIT_FELLOW_RANDCARD) _score += RANDCARD_ONCE_SCORE yield redis.zadd(SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name, _score) # 新增fellow try: # args: fellow_id, is_major, camp_id, on_troop new_fellow = [] fellow_id = card_conf['ItemId'] res_err, attrib = yield self.user.fellow_mgr.create_table_data( fellow_id, 0, 0, 0) if not res_err: new_fellow = [attrib.attrib_id, fellow_id] conf = get_fellow_by_fid(fellow_id) if conf and conf['Quality'] == QUALITY_PURPLE: syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, \ attrib.attrib_id, fellow_id, conf['QualityLevel'], conf['Star'], RANDCARD_TYPE_CREDITS, '') message = [ RORATE_MESSAGE_ACHIEVE, [ ACHIEVE_TYPE_LIMIT_FELLOW, [self.user.nick_name, fellow_id] ] ] gw_broadcast('sync_broadcast', [message]) except Exception as e: log.warn('Create fellow fail! e:', e) defer.returnValue(res_err) _rank = yield redis.zrevrank(SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name) _rank = int(_rank) + 1 if _rank >= 0 else 0 _ranklist = yield self.ranklist() defer.returnValue([ self.user.credits, _rank, _score, _need_time, shrine_data[2], _ranklist, new_fellow ])
def hall_contribute(self, contribute_id, member): ''' 公会成员建设大殿 ''' _data = yield redis.hget(HASH_ALLIANCE_HALL, self.__id) if _data: _data = loads( _data ) # 判断是否需要更新0点更新 _reset_timestamp = get_reset_timestamp() if _data[0] <= _reset_timestamp: _data = [int(time()), [], []] else: _data = [int(time()), [], []] # 当日已建设 if member.cid in _data[2]: defer.returnValue( ALLIANCE_HAD_HALL_CONTRIBUTE ) # 缺少配置 _contribute_conf = get_alliance_contribution_conf(contribute_id) if not _contribute_conf: defer.returnValue( NOT_FOUND_CONF ) # vip level限制 if member.vip_level < _contribute_conf['VipLevel']: defer.returnValue( CHAR_VIP_LEVEL_LIMIT ) # 所需道具是否充足 if _contribute_conf['CostItemType'] != ITEM_TYPE_MONEY: defer.returnValue( UNKNOWN_ITEM_ERROR ) # 扣道具 errorno, left_golds, left_credits = yield gs_call('gs_alliance_hall_contribute', (member.cid, _contribute_conf['CostItemID'], _contribute_conf['CostItemNum']) ) if errorno: defer.returnValue( errorno ) # 更新基本信息 _data[1].append( (member.nick_name, contribute_id) ) _data[2].append( member.cid ) yield redis.hset(HASH_ALLIANCE_HALL, self.__id, dumps(_data)) # 给奖励 需要特殊处理 _guild_num = 0 for _type, _id, _guild_num in _contribute_conf['GuildAward']: if _type != ITEM_TYPE_MONEY or _id != ITEM_GUILD_CONTRIBUTE: log.error('Unknown award type. guild award conf: {0}.'.format( _contribute_conf['GuildAward'] )) continue self.__exp += _guild_num self.dirty() # 推送消息给公会当前在线的会长/副会长, 除了自己 _broadcast_cids = self.online_lead_cids( [member.cid] ) if _broadcast_cids: gw_broadcast( 'sync_multicast', [SYNC_MULTICATE_TYPE_6, [self.__id, self.__level, self.__exp]], _broadcast_cids ) _persion_num = 0 for _type, _id, _persion_num in _contribute_conf['PersonAward']: if _type != ITEM_TYPE_MONEY or _id != ITEM_MEMBER_CONTRIBUTE: log.error('Unknown award type. person award conf: {0}.'.format( _contribute_conf['PersonAward'] )) continue member.hall_get_contribution( _persion_num ) # 公会动态 if _guild_num > 0 or _persion_num > 0: if _contribute_conf['CostItemID'] == ITEM_MONEY_GOLDS: _action_type = ALLIANCE_ACTION_6 else: _action_type = ALLIANCE_ACTION_7 self.new_action( (_action_type, int(time()), member.cid, member.lead_id, member.nick_name, \ member.level, [_contribute_conf['CostItemNum'], _guild_num, _persion_num]) ) #成就 yield gs_send('gs_update_achievement', [member.cid, ACHIEVEMENT_QUEST_ID_24, self.level]) # add syslog if _guild_num > 0: syslogger(LOG_ALLIANCE_EXP_GET, member.cid, member.level, member.vip_level, \ self.__id, _guild_num, self.__exp, WAY_ALLIANCE_HALL_CONTRIBUTE_IDS[contribute_id], '') if _persion_num > 0: syslogger(LOG_CONTRIBUTE_GET, member.cid, member.level, member.vip_level, self.__id, \ _persion_num, member.contribution, member.contribution_total, WAY_ALLIANCE_HALL_CONTRIBUTE_IDS[contribute_id], '') defer.returnValue( (self.__exp, member.contribution, member.contribution_total, left_golds, left_credits) )