def _calc_receive(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") #添加对战记录 transfer_business.add_battle_record( data, req.rival_user_id, req.rival_user_name, req.rival_level, req.rival_icon, TransferRecordInfo.DEFEND_WIN if req.win else TransferRecordInfo.DEFEND_LOSE, req.self_rank, req.rival_rank) #向用户推送 transfer = data.transfer.get(True) transfer_records = data.transfer_record_list.get_all(True) push_res = transfer_arena_pb2.QueryTransferArenaRes() push_res.status = 0 push_res.arena_info.remain_times = transfer.get_remain_times() push_res.arena_info.cd_end_time = transfer.get_cd_end_time(timer.now) for transfer_record in transfer_records: pack.pack_transfer_record(transfer_record, push_res.arena_info.records.add()) push_response = push_res.SerializeToString() GlobalObject().root.callChild("portal", "push_transfer_record", data.id, push_response) res = internal_pb2.InternalTransferNoticeRes() res.status = 0 defer = DataBase().commit(data) defer.addCallback(self._receive_succeed, req, res, timer) return defer
def _calc_query_player_info(self, data, req, timer): # if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") plunder = data.plunder.get() rival_id = plunder.get_plunder_rival_id(req.user_id) if rival_id != 0: #在之前匹配的4个rival中,直接打包返回 rival = data.rival_list.get(rival_id) defer = Deferred() if rival.union_id != 0: defer.addCallback(self._query_union_info, data, plunder, rival, req, timer) else: defer.addCallback(self._pack_query_player_response, data, plunder, rival, req, timer) defer.addErrback(self._query_player_failed, req, timer) defer.callback(0) else: rival_id = plunder.generate_specify_rival_id() rival = data.rival_list.get(rival_id) if rival is None: rival = RivalInfo.create(rival_id, data.id) data.rival_list.add(rival) #去新匹配 user = data.user.get(True) plunder = data.plunder.get() invalid_rival = [data.id] plunder_matcher = PlunderMatcher(user.level, invalid_rival) defer = plunder_matcher.match_specify(data, plunder, req.user_id, user.country) defer.addCallback(self._query_union_info, data, plunder, rival, req, timer) return defer
def _calc_increase(self, data, req, timer): """ """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") node_id = NodeInfo.generate_id(data.id, req.node.basic_id) node = data.node_list.get(node_id) use_gold = req.node.increase.use_gold rate = req.node.increase.rate duration = req.node.increase.total_time if use_gold: item = None else: item_id = ItemInfo.generate_id(data.id, req.item.basic_id) item = data.item_list.get(item_id) if not increase_business.increase(data, node, rate, use_gold, duration, item, timer.now): raise Exception("Increase failed") #记录次数 trainer = data.trainer.get() trainer.add_daily_increase_item_num(1) return DataBase().commit(data)
def _calc_buy(self, data, req, timer): res = transfer_arena_pb2.BuyChallengeTimesRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") ret = Ret() if not transfer_business.buy_attack_times(data, timer.now, ret): if ret.get() == "NO_ENOUGH_GOLD": res.ret = transfer_arena_pb2.BuyChallengeTimesRes.NO_ENOUGH_GOLD return self._buy_succeed(data, req, res, timer) elif ret.get() == "UPPER_LIMIT": res.ret = transfer_arena_pb2.BuyChallengeTimesRes.UPPER_LIMIT return self._buy_succeed(data, req, res, timer) transfer = data.transfer.get() transfer_records = data.transfer_record_list.get_all(True) res.ret = transfer_arena_pb2.BuyChallengeTimesRes.OK res.arena_info.remain_times = transfer.get_remain_times() res.arena_info.cd_end_time = transfer.get_cd_end_time(timer.now) for transfer_record in transfer_records: pack.pack_transfer_record(transfer_record, res.arena_info.records.add()) resource = data.resource.get(True) pack.pack_resource_info(resource, res.resource) defer = DataBase().commit(data) defer.addCallback(self._buy_succeed, req, res, timer) return defer
def _calc_choose_card(self, data, req, timer): """ """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") cost_gold = 0 if req.HasField("cost_gold"): cost_gold = req.cost_gold if not pray_business.choose_card(data, req.choose_index, cost_gold): raise Exception("Choose card failed") for item in req.item: compare.check_item(data, item) pray = data.pray.get() #if cost_gold != 0: # log = log_formater.output_gold(data, -cost_gold, log_formater.CHOOSE_CARD, # "Choose card by gold", choose_index = (pray.get_choose_card_num() + 1)) # logger.notice(log) if pray.is_need_broadcast(): #祈福最后一次是翻倍的奖励发广播 try: self._add_pray_broadcast(data.user.get(), pray) except: logger.warning("Send pray broadcast failed") return DataBase().commit(data)
def _calc_treasure_draw(self, data, basic_data, req, type,timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get() resource = data.resource.get() draw = data.draw.get() resource.update_current_resource(timer.now) item_list = [] if not draw_business.treasure_draw( basic_data, data, user, resource, draw, item_list, req, timer.now): raise Exception("Treasure draw failed") #添加抽奖得到的英雄和物品 if not item_business.gain_item(data, item_list, "trun draw ", log_formater.DRAW): raise Exception("Gain item failed") alltimes = draw.total_treasure_draw_num res = self._pack_treasure_draw_response(data, item_list, resource, alltimes, timer.now) defer = DataBase().commit(data) defer.addCallback(self._draw_treasure_succeed, type, req, res, timer) return defer
def _calc_upgrade(self, data, req, timer): """进行升级 """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") node_basic_id = req.node.basic_id node_id = NodeInfo.generate_id(data.id, node_basic_id) node = data.node_list.get(node_id) gold = 0 if req.HasField("gold"): gold = req.gold if not exploitation_business.finish_upgrade_event( data, node, timer.now, gold): raise Exception("Finish upgrade event failed") resource = data.resource.get(True) res = self._pack_upgrade_response(data, resource, node, timer.now) map_business.check_map_data(data) defer = DataBase().commit(data) defer.addCallback(self._upgrade_succeed, req, res, timer) return defer
def _calc_buy_energy(self, data, req, timer): """ """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") energy = data.energy.get() energy.update_current_energy(timer.now) need_gold, original_gold = energy_business.buy_energy( data, energy, timer.now) if need_gold < 0: raise Exception("Buy energy failed") #记录次数 trainer = data.trainer.get() trainer.add_daily_buy_energy_num(1) log = log_formater.output_gold(data, -need_gold, log_formater.BUY_ENERGY, "Buy energy by gold", before_gold=original_gold, energy=energy.get_energy_num_of_buy()) logger.notice(log) return DataBase().commit(data)
def update_activity(basic_data, data, now): """更新所有活动信息 """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, now): raise Exception("Update across day info failed") #遍历活动基础数据,若在有效期内而未添加的活动,进行创建 basic_activities = basic_data.activity_list.get_all() for basic_activity in basic_activities: activity_id = ActivityInfo.generate_id(data.id, basic_activity.id) if (data.activity_list.get(activity_id) is None and basic_activity.is_living(now)): #应有的活动未被创建 basic_steps = get_basic_activity_steps(basic_data, basic_activity) if not add_activity(basic_data, data, basic_activity.id, basic_activity, basic_steps): raise Exception("Update activity and add new activity failed") delete = [] for activity in data.activity_list.get_all(): if _update_one_activity(basic_data, data, activity, now): delete.append(activity) for activity in delete: if data.activity_list.get(activity.id) is not None: try: data.activity_list.delete(activity.id) except: pass return True
def _calc_query_pvp_players(self, data, req, timer): user = data.user.get() if not user.allow_pvp: raise Exception("PVP is not unlock[user_level=%d]" % user.level) if not account_business.update_across_day_info(data, timer.now, True): logger.warning("Update across day info failed") return False user = data.user.get(True) resource = data.resource.get() invalid_rival = [data.id] plunder_matcher = PlunderMatcher(user.level, invalid_rival) plunder = data.plunder.get() #刷新扣除金钱 if req.HasField("cost_money"): resource.cost_money(req.cost_money) if req.type == 1: #掠夺 plunder_matcher.add_condition(data, plunder) #匹配对手 defer = plunder_matcher.match(plunder, user.country) defer.addCallback(self._pack_pvp_players_response, data, plunder, plunder_matcher, req, timer) return defer elif req.type == 2: #仇家 res = map_pb2.QueryPlayersRes() res.status = 0 plunder_business.update_plunder_enemy(data) plunder_enemy_list = data.plunder_record_list.get_all() for plunder_enemy in plunder_enemy_list: pack.pack_plunder_record(plunder_enemy, res.players.add()) res.attack_num = plunder.attack_num res.left_reset_num = plunder.get_left_reset_num() defer = DataBase().commit(data) defer.addCallback(self._query_pvp_players_succeed, req, res, timer) return defer elif req.type == 3: #指定查询 rival_id = plunder.generate_specify_rival_id() rival = data.rival_list.get(rival_id) if rival is None: rival = RivalInfo.create(rival_id, data.id) data.rival_list.add(rival) #查询对手 defer = plunder_matcher.query_specify_user(req.str, rival) defer.addCallback(self._pack_pvp_players_response, data, plunder, plunder_matcher, req, timer) return defer
def _calc_refresh_pray(self, data, req, timer): """ """ if req.pray_type == PrayInfo.PRAY_ALL: #到期自动触发刷新 pray = data.pray.get() if pray.is_able_to_reset(timer.now): pray.reset(timer.now) logger.debug("reset pray info") else: pray.calc_next_refresh_time(timer.now) logger.warning("calc next pray refresh time") else: #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") #玩家手动触发,刷新制定祈福类型 cost_gold = 0 if req.HasField("cost_gold"): cost_gold = req.cost_gold building_level = 0 #找出寺庙 for building in data.building_list.get_all(True): if building.is_temple(): building_level = building.level break if building_level == 0: raise Exception("Refresh pray failed, no temple") original_gold = pray_business.refresh_pray(data, req.pray_type, building_level, cost_gold, timer.now)[1] if not pray_business.refresh_pray(data, req.pray_type, building_level, cost_gold, timer.now)[0]: raise Exception("Refresh pray failed") if cost_gold != 0: log = log_formater.output_gold(data, -cost_gold, log_formater.REFRESH_PRAY, "Refresh pray by gold", before_gold=original_gold, pray_type=req.pray_type) logger.notice(log) return DataBase().commit(data)
def _calc_end_conscript(self, data, req, timer, force): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 res = conscript_pb2.EndConscriptRes() res.status = 0 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get(True) resource = data.resource.get() conscript_building_id = BuildingInfo.generate_id( data.id, req.building.city_basic_id, req.building.location_index, req.building.basic_id) conscript_building = data.building_list.get(conscript_building_id) conscript = data.conscript_list.get(conscript_building_id) work_heroes = [] #来征兵的英雄 work_heroes_id = conscript_building.get_working_hero() for hero_id in work_heroes_id: if hero_id == 0: work_heroes.append(None) else: hero = data.hero_list.get(hero_id) work_heroes.append(hero) ret = Ret() if not conscript_business.end_conscript(data, conscript, conscript_building, resource, user, work_heroes, timer.now, force): if ret.get() == "NOT_CONSCRIPTING": res.ret = conscript_pb2.EndConscriptRes.NOT_CONSCRIPTING pack.pack_conscript_info(conscript, res.conscript, timer.now) pack.pack_building_info(conscript_building, res.building, timer.now) return self._end_conscript_succeed(data, req, res, timer) elif ret.get() == "CANNT_END": res.ret = conscript_pb2.EndConscriptRes.CANNT_END pack.pack_conscript_info(conscript, res.conscript, timer.now) pack.pack_building_info(conscript_building, res.building, timer.now) return self._end_conscript_succeed(data, req, res, timer) else: raise Exception('End conscript failed') #由于网络原因导致end_conscript一直重发,此处不check,直接返回 #compare.check_conscript(data, req.conscript) res.ret = conscript_pb2.EndConscriptRes.OK pack.pack_resource_info(data.resource.get(True), res.resource) defer = DataBase().commit(data) defer.addCallback(self._end_conscript_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 _calc_buy_goods(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") shop_id = ShopInfo.generate_id(data.id, req.goods.type) shop = data.shop_list.get(shop_id) if not shop_business.buy_goods(data, shop, req.goods.id, timer.now): raise Exception("Buy Goods failed") compare.check_item(data, req.item) defer = DataBase().commit(data) return defer
def _calc_start(self, data, req, timer): union = data.union.get(True) if not union.is_belong_to_target_union(req.union_id): #玩家不属于联盟 res = union_battle_pb2.StartUnionBattleRes() res.status = 0 res.ret = union_pb2.UNION_NOT_MATCHED defer = DataBase().commit(data) defer.addCallback(self._start_succeed, req, res, timer) return defer #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") #参战队伍 & 英雄 teams = [] heroes = [] for team_info in req.battle.attack_teams: team_id = TeamInfo.generate_id(data.id, team_info.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 not union_battle_business.is_able_to_start_battle( data, teams, heroes, timer.now, req.cost_gold): raise Exception("Not able to start battle") #开战,请求本方联盟核实信息 user = data.user.get(True) union_req = internal_union_pb2.InternalStartUnionBattleReq() union_req.is_attack_side = True union_req.attacker_user_id = data.id defer = GlobalObject().remote['gunion'].callRemote( "start_battle", req.union_id, union_req.SerializeToString()) defer.addCallback(self._calc_start_result, data, teams, heroes, req, timer) return defer
def _calc_refresh_goods(self, data, req, types, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") shops = [] index = 1 if req.HasField("index"): index = req.index for type in types: shop_id = ShopInfo.generate_id(data.id, type, index) shops.append(data.shop_list.get(shop_id)) is_refresh_with_item = False refresh_item = None if req.HasField("item"): #用刷新代币刷新商铺 is_refresh_with_item = True item_id = ItemInfo.generate_id(data.id, req.item.basic_id) refresh_item = data.item_list.get(item_id) if refresh_item is None: raise Exception("Item not exist") free = False if shops[0].is_able_to_refresh_free(timer.now): free = True goods = [] if not shop_business.refresh_goods(data, shops, goods, timer.now, refresh_item, free): raise Exception("Refresh goods failed") if is_refresh_with_item: compare.check_item(data, req.item) resource = data.resource.get(True) #任意选择一个商店的刷新次数 res = self._pack_refresh_goods_response(goods, shops[0], resource, req, timer.now) defer = DataBase().commit(data) defer.addCallback(self._refresh_goods_succeed, types, req, res, timer) return defer
def _calc_query(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") transfer = data.transfer.get(True) transfer_records = data.transfer_record_list.get_all(True) res = transfer_arena_pb2.QueryTransferArenaRes() res.status = 0 res.arena_info.remain_times = transfer.get_remain_times() res.arena_info.cd_end_time = transfer.get_cd_end_time(timer.now) for transfer_record in transfer_records: pack.pack_transfer_record(transfer_record, res.arena_info.records.add()) defer = DataBase().commit(data) defer.addCallback(self._query_succeed, req, res, timer) return defer
def _calc_upgrade_equipment(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") cost_gold = 0 if req.HasField("gold"): cost_gold = req.gold if not hero_business.equipment_upgrade( data, req.hero.basic_id, req.type, cost_gold, timer.now): raise Exception("Upgrade equipment failed") #验证 compare.check_hero(data, req.hero, with_equipment_type = req.type) for item_info in req.items: compare.check_item(data, item_info) return DataBase().commit(data)
def _calc_refresh_arena(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get() if not user.allow_pvp_arena: raise Exception("Arena is not unlock[user_level=%d]" % user.level) arena = data.arena.get() if not arena_business.refresh_arena(data, arena, timer.now): raise Exception("Refresh arena failed") #匹配对手 arena_matcher = ArenaMatcher() defer = arena_matcher.match(data, arena) defer.addCallback(self._pack_refresh_arena_response, data, arena, arena_matcher, req, timer) return defer
def _calc_finish_visit(self, data, req, timer): """结束探访逻辑 """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") node_basic_id = req.node.basic_id node_id = NodeInfo.generate_id(data.id, node_basic_id) node = data.node_list.get(node_id) gold = 0 if req.HasField("gold"): gold = req.gold candidate = [] if not visit_business.finish_visit_event(data, node, req.visit_id, timer.now, gold): raise Exception("Finish visit failed") #验证 if req.HasField("hero"): compare.check_hero(data, req.hero) if req.HasField("item"): compare.check_item(data, req.item) #获得S级武将要播广播 if req.visit_id != 0: hero_basic_id = data_loader.EventVisitBasicInfo_dict[ req.visit_id].heroBasicId if hero_basic_id != 0 and hero_business.is_need_broadcast( hero_basic_id): try: self._add_get_hero_broadcast(data.user.get(), hero_basic_id) except: logger.warning("Send get hero broadcast failed") return DataBase().commit(data)
def _calc_refresh_melee(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get() melee = data.melee.get() if not melee.is_able_to_unlock(user): raise Exception("Melee is not unlock[user_level=%d]" % user.level) arena = data.arena.get(True) melee.node_id = arena.node_id if not melee_business.refresh_melee(data, melee, timer.now): raise Exception("Refresh melee failed") #匹配对手 melee_matcher = MeleeMatcher() defer = melee_matcher.match(data, melee) defer.addCallback(self._pack_refresh_melee_response, data, melee, melee_matcher, req, timer) return defer
def _calc_enchant_equipment(self, data, req, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") #精炼后的装备 id if req.type == HeroInfo.EQUIPMENT_TYPE_WEAPON: dest_equipment_id = req.hero.equipment_weapon_id elif req.type == HeroInfo.EQUIPMENT_TYPE_ARMOR: dest_equipment_id = req.hero.equipment_armor_id elif req.type == HeroInfo.EQUIPMENT_TYPE_TREASURE: dest_equipment_id = req.hero.equipment_treasure_id else: raise Exception("Invalid input equipment type[type=%d]" % req.type) #精炼消耗的材料 cost_item = [] for item_info in req.items: item_id = ItemInfo.generate_id(data.id, item_info.basic_id) item = data.item_list.get(item_id) cost_num = item.num - item_info.num cost_item.append((item.id, cost_num)) #精炼消耗的元宝 cost_gold = 0 if req.HasField("gold"): cost_gold = req.gold if not hero_business.equipment_enchant( data, req.hero.basic_id, req.type, dest_equipment_id, cost_item, cost_gold, timer.now): raise Exception("Enchant equipment failed") #验证 compare.check_hero(data, req.hero, with_equipment_type = req.type) for item_info in req.items: compare.check_item(data, item_info) return DataBase().commit(data)
def _calc_buy_attack_num(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) item = None if req.HasField("item"): item_id = ItemInfo.generate_id(data.id, req.item.basic_id) item = data.item_list.get(item_id) need_gold, original_gold = anneal_business.buy_attack_num( data, anneal, item, timer.now) if need_gold < 0: raise Exception("Buy attack num failed") #记录次数 #trainer = data.trainer.get() #trainer.add_daily_buy_attack_num(1) if req.HasField("item"): compare.check_item(data, req.item) if need_gold > 0: log = log_formater.output_gold( data, -need_gold, log_formater.BUY_ATTACK_NUM, "Buy attack num by gold", before_gold=original_gold, attack_num=anneal.get_attack_num_of_buy()) logger.notice(log) return DataBase().commit(data)
def _calc_start_battle(self, data, req, timer): res = transfer_arena_pb2.StartTransferArenaBattleRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") ret = Ret() if not transfer_business.start_battle(data, req.target_id, timer.now, ret): if ret.get() == "NO_CHALLENGE_TIMES": res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.NO_CHALLENGE_TIMES elif ret.get() == "COOLING": res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.COOLING elif ret.get() == "TARGET_ERROR": res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.TARGET_ERROR return self._start_battle_succeed(data, req, res, timer) res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.OK defer = DataBase().commit(data) defer.addCallback(self._start_battle_succeed, req, res, timer) return defer
def _calc_exchange(self, data, req, timer): """ """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") resource = data.resource.get() original_gold = resource.gold resource.update_current_resource(timer.now) lack_money = 0 if req.HasField("lack_money"): lack_money = req.lack_money lack_food = 0 if req.HasField("lack_food"): lack_food = req.lack_food need_gold = resource.gold_exchange_resource(lack_money, lack_food) if need_gold < 0: raise Exception("Gold exchange resource failed") # if req.use_gold != gold: # raise Exception("Exchange with error gold[need gold=%d][use gold=%d]" % # (gold, req.use_gold)) log = log_formater.output_gold(data, -need_gold, log_formater.EXCHANGE_MONEY_FOOD, "Exchange money food by gold", money=lack_money, food=lack_food, before_gold=original_gold) logger.notice(log) return DataBase().commit(data)
def _calc_draw(self, data, basic_data, req, type, timer): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get() resource = data.resource.get() draw = data.draw.get() resource.update_current_resource(timer.now) is_draw_with_item = False draw_item = None if req.HasField("item"): #用抽奖券抽 is_draw_with_item = True item_id = ItemInfo.generate_id(data.id, req.item.basic_id) draw_item = data.item_list.get(item_id) if draw_item is None: raise Exception("Item not exist") hero_list = [] item_list = [] if type == self._TYPE_GOLD_DRAW: if not draw_business.draw_with_gold( basic_data, data, user, resource, draw, hero_list, item_list, timer.now, draw_item, req.free): raise Exception("Draw with gold failed") elif type == self._TYPE_MONEY_DRAW: if not draw_business.draw_with_money( user, resource, draw, hero_list, item_list, timer.now, draw_item, req.free): raise Exception("Draw with money failed") elif type == self._TYPE_GOLD_MULTI_DRAW: if not draw_business.multi_draw_with_gold( basic_data, data, user, resource, draw, hero_list, item_list, timer.now, draw_item): raise Exception("Multi draw with gold failed") elif type == self._TYPE_MONEY_MULTI_DRAW: if not draw_business.multi_draw_with_money( user, resource, draw, hero_list, item_list, timer.now, draw_item): raise Exception("Multi draw with money failed") #elif type == self._TYPE_TREASURE_DRAW: # pass #elif type == self._TYPE_TREASURE_MULTI_DRAW: # pass else: raise Exception("Invalid draw type[type=%d]" % type) #添加抽奖得到的英雄和物品 for (hero_basic_id, hero_num) in hero_list: if not hero_business.gain_hero(data, hero_basic_id, hero_num): raise Exception("Gain hero failed") if not item_business.gain_item(data, item_list, "draw ", log_formater.DRAW): raise Exception("Gain item failed") if is_draw_with_item: compare.check_item(data, req.item) #获得S级武将要播广播 for (hero_basic_id, hero_num) in hero_list: if hero_business.is_need_broadcast(hero_basic_id): try: self._add_get_hero_broadcast(data.user.get(), draw, hero_basic_id) except: logger.warning("Send get hero broadcast failed") #构造返回 if type == self._TYPE_GOLD_DRAW or type == self._TYPE_GOLD_MULTI_DRAW: free_num = draw.gold_draw_free_num free_time = draw.gold_draw_free_time else: free_num = draw.money_draw_free_num free_time = draw.money_draw_free_time res = self._pack_draw_response(data, hero_list, item_list, resource, free_num, free_time, timer.now) defer = DataBase().commit(data) defer.addCallback(self._draw_succeed, type, req, res, timer) return defer
def _calc_trigger_event(self, data, type, req, timer): """触发事件 Args: data type req timer """ #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") change_nodes = [] new_items = [] new_mails = [] #触发战争事件 if type == self.WAR_EVENT: if not war_business.trigger_war_event( data, timer.now, change_nodes, new_items, new_mails): raise Exception("Trigger war event failed") elif type == self.SPECIFIED_EVENT: if not req.HasField("type"): raise Exception("Trigger specified event failed, no type") if not event_business.trigger_specified_event( data, req.type, timer.now, change_nodes): raise Exception("Trigger specified event failed") #compare.check_user(data, req.monarch, with_level = True) #记录次数 trainer = data.trainer.get() trainer.add_daily_event_num(req.type, 1) elif type == self.LUCKY_EVENT: if not event_business.trigger_lucky_event(data, timer.now, change_nodes): raise Exception("Trigger lucky event failed") #为新刷出的敌方节点匹配敌人 #不合法的敌人:自己,以及已经在地图上出现过的 PVP 敌人 invalid_rival = [data.id] for node in data.node_list.get_all(True): if node.is_rival_pvp() and node.is_enemy_complete(): rival_id = node.id rival = data.rival_list.get(rival_id, True) invalid_rival.append(rival.rival_id) user = data.user.get(True) matcher = RivalMatcher(user.level, invalid_rival) energy = data.energy.get() if (req.type == NodeInfo.EVENT_TYPE_SCOUT or req.type == NodeInfo.EVENT_TYPE_JUNGLE ) and energy.total_trigger_scout_num == 1: #第一次侦察事件刷出的敌人 node_enemy_scores = [100, 101, 102] #硬编码,初始三个node上固定敌人 energy.total_trigger_scout_num += 1 i = 0 for node in data.node_list.get_all(): if node.is_lack_enemy_detail(): node.rival_score_min = node_enemy_scores[i] node.rival_score_max = node_enemy_scores[i] i = i + 1 matcher.add_condition(data, node) defer = matcher.match(user.country, only_pve=True) pattern = 1 #为初次刷新的敌人添加 debuff 效果,为了让玩家初次攻击可以轻易取胜 for node in data.node_list.get_all(): if node.is_enemy_complete(): rival_id = node.rival_id rival = data.rival_list.get(rival_id) buff_id = data_loader.InitUserBasicInfo_dict[ pattern].enemyBuffId rival.set_buff(buff_id) else: for node in change_nodes: if node.is_lack_enemy_detail(): matcher.add_condition(data, node) defer = matcher.match(user.country) defer.addCallback(self._pack_event_response, data, new_items, new_mails, change_nodes, type, req, timer) return defer
def _update_offline_info(self, basic_data, data, now): """更新所有离线数据 """ if not account_business.update_across_day_info(data, now, True): logger.warning("Update across day info failed") return False user = data.user.get() #更新战斗信息 battles = data.battle_list.get_all() for battle in battles: if not battle.is_appoint and battle.is_able_to_finish(now): if battle.is_revenge(): node = None else: node = data.node_list.get(battle.node_id) if not battle_business.lose_battle(data, node, now): return False if battle.is_appoint: #有些错误导致节点委任已结束,但是战斗还处于委任状态 node = data.node_list.get(battle.node_id) if not node.is_in_battle(): battle.finish() #检查所有未完成的充值,尝试完成漏单 pay_business.try_check_all_order(data, now) #更新世界boss worldboss = data.worldboss.get() worldboss_business.update_worldboss(data, basic_data, worldboss, user.level, now) if worldboss.is_arised(): worldboss_process = WorldBossProcessor() worldboss_process.query_common_worldboss(data, worldboss) #tips:以下为临时修复数据逻辑 #更新队伍信息(由于委任丢失,导致部队和英雄锁死) teams = data.team_list.get_all() for team in teams: if team.is_in_battle(): node_id = NodeInfo.generate_id(data.id, team.battle_node_basic_id) node = data.node_list.get(node_id, True) if not node.is_in_battle() or not node.is_visible( ) or not node.is_enemy_complete(): #部队复位 team.clear_in_battle() #英雄复位 for hero_id in team.get_heroes(): hero = data.hero_list.get(hero_id) if hero is not None: hero.clear_in_battle() #battle信息清空 battle = data.battle_list.get(node.id) if battle is None: #node复位 node.clear_in_battle() break if battle.is_appoint: own_soldier_info = battle.get_own_soldier_info() enemy_soldier_info = battle.get_enemy_soldier_info() if not battle_business.lose_battle( data, node, now, enemy_soldier_info, own_soldier_info): raise Exception("Fix appoint battle failed") logger.debug("Fix appoint battle[node basic id=%d]" % node.basic_id) else: battle.finish() #node复位 node.clear_in_battle() if team.is_in_anneal_sweep(): #英雄复位 for hero_id in team.get_heroes(): hero = data.hero_list.get(hero_id) if hero is not None: hero.clear_in_anneal_sweep() team.clear_in_anneal_sweep() anneal = data.anneal.get() if anneal.is_in_sweep(): anneal.finish_sweep() #修复节点(战斗信息已经丢失,但节点还处于战斗状态) nodes = data.node_list.get_all() for node in nodes: if node.is_in_battle(): battle = data.battle_list.get(node.id) if battle is not None and battle.is_able_to_start(): node.clear_in_battle() if node.is_rival_exist() and node.rival_id == 0: if node.is_key_node(): node.clear_key_node() #修复地下城dungeon dungeon = data.dungeon.get() if dungeon.is_dungeon_open(): node = data.node_list.get(dungeon.node_id) if not node.is_rival_exist(): dungeon.close() #修复征兵 conscripts = data.conscript_list.get_all() for conscript in conscripts: if conscript.conscript_num == 0: building = data.building_list.get(conscript.building_id) if building.has_working_hero() and not building.is_upgrade: logger.notice("Auto fix conscripts[user_id=%d]" % data.id) heroes_id = utils.split_to_int(building.hero_ids) building.hero_ids = "0#0#0" for hero_id in heroes_id: if hero_id == 0: continue hero = data.hero_list.get(hero_id) hero.finish_working() #修复研究科技 ministerhouse_id = int( float(data_loader.OtherBasicInfo_dict['building_ministerhouse']. value)) ministerhouse_list = building_business.get_buildings_by_basic_id( data, ministerhouse_id) #丞相府 ministerhouse = ministerhouse_list[0] if len( ministerhouse_list) > 0 else None if ministerhouse != None and not ministerhouse.is_upgrade and ministerhouse.hero_ids != "0#0#0": technologys = data.technology_list.get_all() #获取正在升级的内政科技 interior = [ t for t in technologys if t.type == t.INTERIOR_TECH_TYPE and t.is_upgrade ] if len(interior) == 0: logger.notice("Auto fix interior technology[user_id=%d]" % data.id) heroes_id = utils.split_to_int(ministerhouse.hero_ids) ministerhouse.hero_ids = "0#0#0" for hero_id in heroes_id: if hero_id == 0: continue hero = data.hero_list.get(hero_id) hero.finish_working() generalhouse_id = int( float(data_loader.OtherBasicInfo_dict['building_generalhouse']. value)) generalhouse_list = building_business.get_buildings_by_basic_id( data, generalhouse_id) #将军府 generalhouse = generalhouse_list[0] if len( generalhouse_list) > 0 else None if generalhouse != None and not generalhouse.is_upgrade and generalhouse.hero_ids != "0#0#0": technologys = data.technology_list.get_all() #获取正在升级的战斗科技 battle = [ t for t in technologys if t.type != t.INTERIOR_TECH_TYPE and t.is_upgrade ] if len(battle) == 0: logger.notice("Auto fix battle technology[user_id=%d]" % data.id) heroes_id = utils.split_to_int(generalhouse.hero_ids) generalhouse.hero_ids = "0#0#0" for hero_id in heroes_id: if hero_id == 0: continue hero = data.hero_list.get(hero_id) hero.finish_working() #修复英雄工作状态 heroes = data.hero_list.get_all() for hero in heroes: if hero.place_type == hero.PLACE_TYPE_BUILDING: building = data.building_list.get(hero.place_id) if building is not None and not building.is_heroes_working( [hero]): hero.finish_working() elif hero.place_type == hero.PLACE_TYPE_NODE: node = data.node_list.get(hero.place_id) heroes_id = utils.split_to_int(node.exploit_team) if hero.id not in heroes_id: hero.finish_working() buildings = data.building_list.get_all() for building in buildings: heroes_id = utils.split_to_int(building.hero_ids) for hero_id in heroes_id: if hero_id == 0: continue hero = data.hero_list.get(hero_id) if hero.place_type == hero.PLACE_TYPE_INVALID: hero.assign_working_in_building(building.id, now) return True
def _calc_finish_research(self, data, req, timer, force): """ """ res = technology_pb2.UpgradeTechRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get(True) resource = data.resource.get() technology_id = TechnologyInfo.generate_id(data.id, req.tech.basic_id, req.tech.type) technology = data.technology_list.get(technology_id) research_building = data.building_list.get(technology.building_id) if research_building is None: logger.fatal("research building is None[building_id=%d]" % technology.building_id) research_heroes = [] # 参与研究的英雄 research_heroes_id = research_building.get_working_hero() for hero_id in research_heroes_id: if hero_id == 0: research_heroes.append(None) else: hero = data.hero_list.get(hero_id) research_heroes.append(hero) resource.update_current_resource(timer.now) #结束研究 ret = Ret() if not technology_business.finish_research( data, technology, user, research_building, research_heroes, resource, timer.now, force, ret): if ret.get() == "NOT_UPGRADING": res.ret = technology_pb2.UpgradeTechRes.NOT_UPGRADING pack.pack_technology_info(technology, res.tech, timer.now) return self._finish_research_succeed(data, req, res, timer) elif ret.get() == "CANNT_FINISH": res.ret = technology_pb2.UpgradeTechRes.CANNT_FINISH pack.pack_technology_info(technology, res.tech, timer.now) return self._finish_research_succeed(data, req, res, timer) else: raise Exception("Finish research technology failed") #前置依赖科技 pre_technology_id = technology_business.get_pre_technology_id( data.id, technology.basic_id, technology.type) pre_technology = None if pre_technology_id != 0: pre_technology = data.technology_list.get(pre_technology_id) #升级完成的后续处理 #兵种科技 if technology.is_soldier_technology(): #删除前置依赖科技 if pre_technology_id != 0: data.technology_list.delete(pre_technology_id) #兵种科技研究完成后,会将原有兵种升级 soldier_id = technology_business.get_related_soldier_id( data.id, req.tech.basic_id) soldier = data.soldier_list.get(soldier_id) #所有配置相关兵种的英雄 related_heroes = [ hero.get() for hero in data.hero_list if hero.get(True).soldier_basic_id == soldier.basic_id ] soldier = technology_business.post_research_for_soldier_technology( data, data.id, technology, timer.now, soldier, related_heroes) if not soldier: raise Exception( "Post process for research soldier technology failed") #战斗科技 elif technology.is_battle_technology(): #删除前置依赖科技 if pre_technology_id != 0: data.technology_list.delete(pre_technology_id) soldier_basic_ids = data_loader.BattleTechnologyBasicInfo_dict[ technology.basic_id].soldierBasicInfoId related_heroes = [] #所带兵种的战力受该科技影响的英雄 for soldier_basic_id in soldier_basic_ids: for hero in data.hero_list: if hero.get(True).soldier_basic_id == soldier_basic_id: related_heroes.append(hero.get()) if not technology_business.post_research_for_battle_technology( data, technology, related_heroes): raise Exception( "Post process for research battle technology failed") #内政科技 elif technology.is_interior_technology(): #遍历所有建筑,更新建筑产量或容量 for building in data.building_list.get_all(): building_heroes = [] #建筑中驻守的英雄 build_hero_ids = building.get_working_hero() for hero_id in build_hero_ids: if hero_id == 0: building_heroes.append(None) else: hero = data.hero_list.get(hero_id) building_heroes.append(hero) if not building_business.update_building_with_interior_technology( building, building_heroes, resource, data, technology, pre_technology): raise Exception( "Post process for research interior technology failed") #删除前置依赖科技 if pre_technology_id != 0: data.technology_list.delete(pre_technology_id) #验证 compare.check_technology(data, req.tech) #记录次数 trainer = data.trainer.get() trainer.add_daily_tech_upgrade_num(1) #科技升级的广播 try: self._add_technology_broadcast(user, technology) except: logger.warning("Send technology broadcast failed") res.ret = technology_pb2.UpgradeTechRes.OK pack.pack_resource_info(data.resource.get(True), res.resource) defer = DataBase().commit(data) defer.addCallback(self._finish_research_succeed, req, res, timer) return defer
def _calc_finish_upgrade(self, data, req, timer, force): """建筑升级完成 1 完成建筑升级,更新建筑信息,包括结算英雄参与建造升级获得的经验 2 指派新的驻守英雄 3 更新建筑升级完成的影响(农田、市场、兵营、城防) """ res = building_pb2.UpgradeBuildingRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get(True) resource = data.resource.get() upgrade_building_id = BuildingInfo.generate_id( data.id, req.building.city_basic_id, req.building.location_index, req.building.basic_id) upgrade_building = data.building_list.get(upgrade_building_id) build_heroes = [] #参与升级的英雄 build_hero_ids = upgrade_building.get_working_hero() for hero_id in build_hero_ids: if hero_id == 0: build_heroes.append(None) else: hero = data.hero_list.get(hero_id) build_heroes.append(hero) #更新资源 resource.update_current_resource(timer.now) #如果不处于升级状态 """if upgrade_building.is_upgrade == False: return DataBase().commit(data)""" #建筑结束升级状态 包括结算参与建造的英雄获得的经验 结算主公获得的经验 ret = Ret() if not building_business.finish_upgrade(data, upgrade_building, resource, user, build_heroes, timer.now, force, ret): if ret.get() == "NOT_UPGRADING": res.ret = building_pb2.UpgradeBuildingRes.NOT_UPGRADING pack.pack_building_info(upgrade_building, res.building, timer.now) return self._finish_upgrade_succeed(data, req, res, timer) elif ret.get() == "CANNT_FINISH": res.ret = building_pb2.UpgradeBuildingRes.CANNT_FINISH pack.pack_building_info(upgrade_building, res.building, timer.now) return self._finish_upgrade_succeed(data, req, res, timer) else: raise Exception("Finish upgrade building failed") defense = None conscript = None if upgrade_building.is_defense(): defense = data.defense_list.get(upgrade_building.id) elif upgrade_building.is_barrack(): conscript = data.conscript_list.get(upgrade_building.id) #所有生效的内政科技 interior_technologys = [ tech for tech in data.technology_list.get_all(True) if tech.is_interior_technology() and not tech.is_upgrade ] #升级完成之后的处理 new_technology = [] new_defense = [] new_conscript = [] if not building_business.post_upgrade( data, upgrade_building, timer.now, build_heroes, interior_technologys, resource, defense, conscript, new_technology, new_defense, new_conscript): raise Exception("Post process for upgrade failed") #可能解锁出已经完成研究的兵种科技,因此可能会解锁新的兵种 for technology in new_technology: data.technology_list.add(technology) if technology.is_soldier_technology(): soldier = technology_business.post_research_for_soldier_technology( data, data.id, technology, timer.now, new=True) if soldier is None: raise Exception( "Post process for soldier technology failed") data.soldier_list.add(soldier) for defense in new_defense: data.defense_list.add(defense) for conscript in new_conscript: data.conscript_list.add(conscript) #检查请求 compare.check_user(data, req.monarch, with_level=True) res.ret = building_pb2.UpgradeBuildingRes.OK pack.pack_resource_info(data.resource.get(True), res.resource) defer = DataBase().commit(data) defer.addCallback(self._finish_upgrade_succeed, req, res, timer) return defer