def _calc_upgrade_star(self, data, req, timer): """重现客户端升星计算逻辑,和请求进行比较 """ res = hero_pb2.UpdateHeroRes() res.status = 0 hero_id = HeroInfo.generate_id(data.id, req.hero.basic_id) hero = data.hero_list.get(hero_id) item_id = ItemInfo.generate_id(data.id, req.item[0].basic_id) item = data.item_list.get(item_id) if hero is None or item is None: raise Exception("Hero or item not exist") #消耗精魄 soul_num = 0 open_flags = account_business.get_flags() if "HeroUpStarUseSoul" in open_flags: soul_num = data_loader.HeroStarLevelBasicInfo_dict[ req.hero.star_level].soul #使用灵魂石 consume_num = data_loader.HeroStarLevelBasicInfo_dict[ req.hero.star_level].perceptivity ret = hero_business.star_upgrade(data, hero, item, consume_num, soul_num, timer.now) if ret != hero_pb2.HERO_OK: res.ret = ret return self._upgrade_star_succeed(data, req, res, timer) #和请求进行比较 if req.hero.star_level != hero.star: raise Exception("Unexpect hero star[expect star=%d]" % hero.star) #验证 compare.check_hero(data, req.hero, with_star=True) compare.check_item(data, req.item[0]) resource = data.resource.get() resource.update_current_resource(timer.now) res.ret = hero_pb2.HERO_OK pack.pack_resource_info(resource, res.resource) try: if hero.is_need_broadcast_star_level(): self._add_upgrade_star_level_broadcast(data.user.get(), hero) except: logger.warning("Send upgrade star level broadcast failed") defer = DataBase().commit(data) defer.addCallback(self._upgrade_star_succeed, req, res, timer) return defer
def _calc_query_anneal(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") anneal = data.anneal.get() anneal.update_current_attack_num(timer.now) if 'is_open_new_anneal' in account_business.get_flags(): anneal.try_forward_floor() if timer.now < anneal.next_refresh_time: #刷新攻击次数 anneal_business.refresh_attack_num(anneal, timer.now) return DataBase().commit(data)
def _pack_finish_appoint_response(self, matcher, data, node_list, items, heroes, mails, req, timer): """构造返回 args: items : list((num, basic_id)元组) heroes: list((basic_id, level, exp, battle_node_basic_id )元组) Returns: res[protobuf]: 向客户端的返回的响应 """ resource = data.resource.get(True) user = data.user.get(True) conscript_list = data.conscript_list.get_all(True) res = appoint_pb2.FinishAppointRes() res.status = 0 res.ret = appoint_pb2.FinishAppointRes.OK pack.pack_resource_info(resource, res.resource) pack.pack_monarch_info(user, res.monarch) for conscript in conscript_list: pack.pack_conscript_info(conscript, res.conscripts.add(), timer.now) for node in node_list: pack.pack_node_info(data, node, res.nodes.add(), timer.now) for item in items: pack.pack_item_info(item, res.items.add()) for hero in heroes: hero_message = res.heros.add() hero_message.basic_id = hero[0] hero_message.level = hero[1] hero_message.exp = hero[2] hero_message.battle_node_id = hero[3] for mail in mails: pack.pack_mail_info(mail, res.mails.add(), timer.now) if 'is_battle_cost_energy' in account_business.get_flags(): energy = data.energy.get() energy.update_current_energy(timer.now) pack.pack_energy_info(energy, res.energy, timer.now) map_business.check_map_data(data) defer = DataBase().commit(data) defer.addCallback(self._finish_appoint_succeed, req, res, timer) return defer
def _calc_reborn(self, data, req, timer): res = hero_pb2.RebornHeroRes() res.status = 0 if req.type == hero_pb2.RebornHeroReq.PERFECT: ret = hero_business.is_able_to_perfect_reborn_hero(data, timer.now) if ret != True: res.return_ret = ret return self._reborn_succeed(data, req, res, timer) is_perfect = True else: is_perfect = False open_flags = account_business.get_flags() if "HeroUpStarUseSoul" in open_flags: #分解 if not hero_business.resolve_hero(data, req.hero.basic_id, is_perfect, timer.now): res.return_ret = hero_pb2.RebornHeroRes.REBORN_ERROR return self._reborn_succeed(data, req, res, timer) else: if not hero_business.reborn_hero(data, req.hero.basic_id, is_perfect, timer.now): res.return_ret = hero_pb2.RebornHeroRes.REBORN_ERROR return self._reborn_succeed(data, req, res, timer) ''' if not compare.check_hero_r(data, req.hero, True, True, True, 0, -1, True, True, True): res.return_ret = hero_pb2.RebornHeroRes.REBORN_ERROR return self._reborn_succeed(data, req, res, timer) ''' #for item in req.items: # if not compare.check_item_r(data, item): # res.return_ret = hero_pb2.RebornHeroRes.REBORN_ERROR # return self._reborn_succeed(data, req, res, timer) resource = data.resource.get() resource.update_current_resource(timer.now) res.return_ret = hero_pb2.RebornHeroRes.REBORN_SUCCESS pack.pack_resource_info(resource, res.resource) defer = DataBase().commit(data) defer.addCallback(self._reborn_succeed, req, res, timer) return defer
def _calc_start_sweep(self, data, req, timer): """ """ #参战team/英雄 teams = [] heroes = [] for team in req.teams: team_id = TeamInfo.generate_id(data.id, team.index) team = data.team_list.get(team_id) if team is None: continue teams.append(team) for hero_id in team.get_heroes(): if hero_id != 0: hero = data.hero_list.get(hero_id) heroes.append(hero) if len(teams) == 0: raise Exception("Sweep teams is NULL") if 'is_open_new_anneal' in account_business.get_flags(): mode = req.anneal_type else: mode = AnnealInfo.NORMAL_MODE total_time = req.total_time if req.HasField('total_time') else None attack_num = req.attack_num if req.HasField('attack_num') else None anneal = data.anneal.get() if not anneal_business.start_sweep(data, anneal, req.direction, req.floor, total_time, attack_num, teams, heroes, timer.now, mode): raise Exception("Start anneal sweep failed") defer = DataBase().commit(data) defer.addCallback(self._start_sweep_succeed, anneal, req, timer) return defer
def is_hero_star_ok(data, hero, index): """英雄的星级是否满足条件""" hero_star_unlock_1 = int(float(data_loader.OtherBasicInfo_dict['hero_star_unlock_1'].value)) - 1 hero_star_unlock_2 = int(float(data_loader.OtherBasicInfo_dict['hero_star_unlock_2'].value)) - 1 hero_star_unlock_3 = int(float(data_loader.OtherBasicInfo_dict['hero_star_unlock_3'].value)) - 1 hero_star_unlock_4 = int(float(data_loader.OtherBasicInfo_dict['hero_star_unlock_4'].value)) - 1 hero_star_unlock_5 = int(float(data_loader.OtherBasicInfo_dict['hero_star_unlock_5'].value)) - 1 hero_star_unlock_6 = int(float(data_loader.OtherBasicInfo_dict['hero_star_unlock_6'].value)) - 1 flags = account_business.get_flags() if 'star_level_disassemble' in flags: if hero.star < 20: return 0 <= index <= hero_star_unlock_1 elif hero.star < 30: return 0 <= index <= hero_star_unlock_2 elif hero.star < 40: return 0 <= index <= hero_star_unlock_3 elif hero.star < 50: return 0 <= index <= hero_star_unlock_4 elif hero.star < 60: return 0 <= index <= hero_star_unlock_5 elif hero.star == 60: return 0 <= index <= hero_star_unlock_6 else: if hero.star == 1: return 0 <= index <= hero_star_unlock_1 elif hero.star == 2: return 0 <= index <= hero_star_unlock_2 elif hero.star == 3: return 0 <= index <= hero_star_unlock_3 elif hero.star == 4: return 0 <= index <= hero_star_unlock_4 elif hero.star == 5: return 0 <= index <= hero_star_unlock_5 return False
def _pack_user_info(self, data, basic_data, req, timer, first_init, arena_matcher=None, melee_matcher=None): """打包所有用户数据 Args: data[UserData]: 用户数据 req[protobuf]: 请求 Returns: res[protobuf] """ res = init_pb2.InitRes() res.status = 0 res.first_init = first_init info = res.info user = data.user.get(True) pay = data.pay.get(True) pack.pack_monarch_info(user, info.monarch) union = data.union.get(True) resource = data.resource.get(True) if union.is_belong_to_union(): info.monarch.union_id = union.union_id info.union_battle_stage = UnionBattleStagePatcher().patch( union.union_id) pack.pack_resource_info(data.resource.get(True), info.resource) for item in data.item_list.get_all(True): pack.pack_item_info(item, info.items.add()) for hero in data.hero_list.get_all(True): pack.pack_hero_info(hero, info.heroes.add(), timer.now) for team in data.team_list.get_all(True): pack.pack_team_info(team, info.teams.add()) pack.pack_map_info(data, data.map.get(True), info.map, timer.now) for city in data.city_list.get_all(True): pack.pack_city_info(city, info.cities.add()) for building in data.building_list.get_all(True): pack.pack_building_info(building, info.buildings.add(), timer.now) for technology in data.technology_list.get_all(True): pack.pack_technology_info(technology, info.techs.add(), timer.now) for conscript in data.conscript_list.get_all(True): pack.pack_conscript_info(conscript, info.conscripts.add(), timer.now) assert len(data.defense_list) == 1 pack.pack_money_draw_info(data.draw.get(True), info.money_draw, timer.now) pack.pack_gold_draw_info(data.draw.get(True), info.gold_draw, timer.now) for mission in data.mission_list: pack.pack_mission_info(mission.get(True), info.missions.add()) #邮件看产生时间顺序给出 # data.mail.sort(cmp = None, key=lambda x:x.time, reverse = False) for mail in data.mail_list.get_all(True): pack.pack_mail_info(mail, info.mails.add(), timer.now) pack.pack_sign_info(data.sign.get(True), info.sign_in) #演武场 arena = data.arena.get(True) arena_ranking = 0 if arena_matcher is not None: arena_ranking = arena_matcher.rank pack.pack_arena_info(user, arena, info.arena, timer.now, arena_ranking) #if user.allow_pvp_arena and arena.is_arena_active(timer.now): # #胜场奖励 # if arena.is_able_to_get_win_num_reward(): # pack.pack_arena_reward_info(arena, info.arena.win_num_reward) # #对手信息 # if arena.rivals_user_id != '': # rivals_id = arena.generate_arena_rivals_id() # for rival_id in rivals_id: # rival = data.rival_list.get(rival_id, True) # pack.pack_arena_player(rival, info.arena.rivals.add()) # #系统选定的对战对手 # choose_rival_id = arena.get_choose_rival_id() # choose_rival = data.rival_list.get(choose_rival_id, True) # info.arena.choosed_user_id = choose_rival.rival_id # #对战记录 # record_list = data.arena_record_list.get_all(True) # for record in record_list: # pack.pack_arena_record(record, info.arena.records.add()) flags = account_business.get_flags() if 'is_open_melee' in flags: #乱斗场 melee = data.melee.get(True) melee_ranking = 0 if melee_matcher is not None: melee_ranking = melee_matcher.rank pack.pack_melee_info(user, melee, info.melee_arena, timer.now, melee_ranking) #if melee.is_able_to_unlock(user) and melee.is_arena_active(timer.now): # #胜场奖励 # if melee.is_able_to_get_win_num_reward(): # pack.pack_arena_reward_info(melee, info.melee_arena.win_num_reward) # #对手信息 # if melee.rivals_user_id != '': # rivals_id = melee.generate_arena_rivals_id() # for rival_id in rivals_id: # rival = data.rival_list.get(rival_id, True) # pack.pack_melee_player(rival, info.melee_arena.rivals.add()) # #对战记录 # record_list = data.melee_record_list.get_all(True) # for record in record_list: # pack.pack_arena_record(record, info.melee_arena.records.add()) ##乱斗场阵容 #(heroes_list, positions_list) = melee.get_heroes_position() #if len(heroes_list) > 0: # info.melee_team.index = 0 #for hero_basic_id in heroes_list: # (info.melee_team.heroes.add()).basic_id = hero_basic_id #for position in positions_list: # info.melee_team.hero_positions.append(position) #政令 energy = data.energy.get(True) pack.pack_energy_info(energy, info.energy_info, timer.now) #祈福 pray = data.pray.get(True) pack.pack_pray_info(pray, info.pray, timer.now) #红包 chest = data.chest.get(True) pack.pack_chest_info(chest, info.chest, timer.now) #试炼场 anneal = data.anneal.get(True) pack.pack_anneal_info(data, anneal, info.anneal, timer.now) #打包新手引导进度信息 pack.pack_guide_info(data.user.get(True), info.guide) #将星盘 herostar_list = data.herostar_list.get_all(True) for herostar in herostar_list: info.hero_star.append(herostar.star_id) #世界boss #pack.pack_worldboss_info(data.worldboss.get(True), user, info.world_boss, timer.now) #功能开关 #flags = account_business.get_flags() pack.pack_flag_info(flags, info.flags) #扩展副本 dungeons = data.expand_dungeon_list.get_all() for dungeon in dungeons: dungeon.daily_update(timer.now) pack.pack_expand_dungeon_info(dungeon, user, info.expand_dungeons.add(), 0, timer.now, brief=True) #主界面的按钮提示 pack.pack_button_tips(basic_data, data, info, timer.now) #lua #pack.pack_luas(info.luas) logger.notice( "Submit Role[user_id=%d][level=%d][name=%s][vip=%d][status=LOGIN][create_time=%d][last_login_time=%d][money=%d][food=%d][gold=%d][pay_count=%d][pay_amount=%.2f]" % (user.id, user.level, user.name, user.vip_level, user.create_time, user.last_login_time, resource.money, resource.food, resource.gold, pay.pay_count, pay.pay_amount)) #log = log_formater.output_gold(data, 0, log_formater.INIT_RESOURCE_GOLD, # "Gain gold from init resource", before_gold = data.resource.get(True).gold) #logger.notice(log) return self._init_succeed(data, req, res, timer)
def pack_worldboss_info(worldboss, user, message, now): """打包世界boss信息 """ open_flags = account_business.get_flags() if "is_server_open_worldboss" not in open_flags: message.status = WorldBossInfo.DISABLE return True if not worldboss.is_unlock(): message.status = WorldBossInfo.LOCKED message.limit_level = int(float(data_loader.OtherBasicInfo_dict["unlock_worldboss_level"].value)) return message.kill_user_name = base64.b64decode(worldboss.kill_user_name) message.kill_user_id = worldboss.kill_user_id if not worldboss.is_arised(): message.status = WorldBossInfo.INACTIVE message.end_time = 3600 #当前没有boss,一小时后再访问,以免当天更新了boss return else: if now < worldboss.start_time: message.status = WorldBossInfo.BEFORE_BATTLE message.end_time = worldboss.start_time - now + (user.id % 220) elif now > worldboss.end_time: message.status = WorldBossInfo.AFTER_BATTLE message.end_time = utils.get_start_second(now) + 86400 - now#第二天的开始时间即为当天的结束时间 else: message.status = WorldBossInfo.IN_BATTLE message.end_time = worldboss.end_time - now + (user.id % 220) message.total_soldier_num = worldboss.total_soldier_num message.current_soldier_num = worldboss.current_soldier_num message.description = base64.b64decode(worldboss.description) #若未开启,不需要传其他内容 if message.status == WorldBossInfo.BEFORE_BATTLE: return with_detail = True if message.status == WorldBossInfo.AFTER_BATTLE: with_detail = False #if worldboss.is_killed(): # return #阵容 teams = worldboss_business.generate_array_detail(worldboss, user) for i in range(3): team = message.first_teams.add() team.index = i team = message.second_teams.add() team.index = i team = message.third_teams.add() team.index = i for i in range(len(teams[0])): team = message.first_teams[i/3] pack_hero_info(teams[0][i], team.heroes.add(), now, False, with_detail) for i in range(len(teams[1])): team = message.second_teams[i/3] pack_hero_info(teams[1][i], team.heroes.add(), now, False, with_detail) for i in range(len(teams[2])): team = message.third_teams[i/3] pack_hero_info(teams[2][i], team.heroes.add(), now, False, with_detail) #阵容是否可被攻击 for can_attack in worldboss.get_can_attack_arrays_index(): message.can_attack_teams_index.append(can_attack) #阵容的战功系数 for ratio in worldboss.get_arrays_merit_ratio(): message.teams_coefficient.append(ratio)
def win_battle(data, node, enemy_soldier_info, own_soldier_info, change_nodes, now, new_arena_records = [], is_legendcity = False, is_unionboss = False, is_plunder = False): """战斗胜利 1 获得战利品 2 获得经验:用户经验,英雄经验 3 返还存活士兵 4 更新统计信息 5 结算节点影响 Args: change_nodes[list(NodeInfo) out]: 发生变化的节点列表 """ if node == None: #通过邮件复仇、试炼场,不存在node node_id = NodeInfo.generate_id(data.id, 0) #0表示主城 else: node_id = node.id battle = data.battle_list.get(node_id) if battle is None: logger.warning("Battle is not exist[battle node id=%d]" % node_id) return False node = data.node_list.get(node_id) rival = data.rival_list.get(battle.rival_id) force = False #如果dependence节点所在key node已不可见,强制结束战斗 if node is not None and node.is_dependency(): parent_basic_id = MapGraph().get_parent(node.basic_id) parent_id = NodeInfo.generate_id(data.id, parent_basic_id) parent = data.node_list.get(parent_id, True) if not parent.is_visible() or not parent.is_own_side(): force = True if not battle.is_able_to_finish(now, force): logger.warning("Not able to finish battle[battle node id=%d][battle rival id=%d]" % (battle.node_id, battle.rival_id)) return False #获得战利品 resource = data.resource.get() resource.update_current_resource(now) resource.gain_money(battle.reward_money) resource.gain_food(battle.reward_food) if not item_business.gain_item(data, battle.get_reward_items(), "win battle", log_formater.WIN_BATTLE): return False if not rival.is_melee_player(): #返还己方存活士兵 if not _reclaim_soldier(data, battle, now, own_soldier_info): return False #用户获得经验,扣除政令 if 'is_battle_cost_energy' in account_business.get_flags(): energy = data.energy.get() energy.update_current_energy(now) if not energy.cost_energy(battle.reward_user_exp, None, now): return False if not user_business.level_upgrade(data, battle.reward_user_exp, now, "exp win battle", log_formater.EXP_WIN_BATTLE): return False #参战英雄获得经验 heroes_id = battle.get_battle_hero() exp = int(battle.reward_hero_exp / len(heroes_id)) if len(heroes_id) > 0 else 0 for hero_id in heroes_id: hero = data.hero_list.get(hero_id) if not hero_business.level_upgrade(data, hero, exp, now): return False #更新统计信息 if not _update_statistics(data, battle, True, rival, node, enemy_soldier_info, own_soldier_info): return False #如果是复仇成功,更新邮件 mail_id = battle.mail_id if mail_id != 0: mail = data.mail_list.get(mail_id) if not mail_business.use_mail_to_revenge_succeed(data, mail, now): return False rival.clear() #如果是演武场的对手 if rival.is_arena_player(): arena = data.arena.get() record = arena_business.calc_arena_battle_finish(data, arena, True, rival) new_arena_records.append(record) rival.clear() #如果是乱斗场的对手 if rival.is_melee_player(): melee = data.melee.get() record = melee_business.calc_melee_battle_finish(data, melee, True, rival) new_arena_records.append(record) rival.clear() #如果是试炼场 if rival.is_anneal_rival(): rival.clear() #如果是世界boss if rival.is_worldboss_rival(): rival.clear() if (not is_legendcity and not is_unionboss and not is_plunder and node.event_type not in ( NodeInfo.EVENT_TYPE_EXPAND_DUNGEON, NodeInfo.EVENT_TYPE_ARENA, NodeInfo.EVENT_TYPE_WORLDBOSS) and node.basic_id != 0 and not _update_node_of_win_battle(data, node, now, change_nodes)): logger.warning("Update node of win battle failed") return False #取消战斗状态 if node is not None: node.clear_in_battle() return battle.finish()