def vip_packs_info(self, msgtype, body): req = poem_pb.VipPacksInfoRequest() req.ParseFromString(body) rsp = poem_pb.VipPacksInfo() p = self.player now = int(time.time()) today = datedate.fromtimestamp(now) configs = get_config(VipPacksConfig) if req.type == VipPackType.Daily: try: config = get_config(VipConfig)[req.vip or p.vip] except KeyError: config = get_config(VipConfig)[p.vip] group = [config.day_giftID] else: group = [i.ID for i in get_config( VipPacksByGroupConfig).get(req.type, [])] for each in group: config = configs[each] if config.gift_type != VipPackType.Daily: if now < config.gift_starttime or now > config.gift_lasttime: continue info = dict(config._asdict()) info["rewards"] = build_reward(parse_reward(info["rewards"])) # 同组共用一个限购数据 count = get_vip_pack_rest_count(p, each, today=today) info["count"] = count rsp.packs.add(**info) return success_msg(msgtype, rsp)
def resolve_gold(self, msgtype, body): # 炼银处理 from config.configs import get_config from config.configs import VipConfig from config.configs import GoldenFingerConfig from config.configs import GoldFingerLvLimitConfig p = self.player items = get_config(GoldenFingerConfig) vipcfg = get_config(VipConfig) resolvegold = get_config(GoldFingerLvLimitConfig)[1] golden_finger_count = vipcfg[p.vip].golden_finger_count cur_time = p.resolvegold_time + 1 if p.level < resolvegold.openlv: return fail_msg(msgtype, reason='等级不足') if p.resolvegold_time >= golden_finger_count: return fail_msg(msgtype, reason='炼银次数已用尽') item = items[cur_time] if p.gold < item.golden: return fail_msg(msgtype, reason='钻石不足') from reward.base import apply_reward from reward.constants import RewardType cost = dict(gold=item.golden) reward = dict(money=item.silver) apply_reward(p, reward, cost, type=RewardType.ResolveGold) p.resolvegold_time += 1 from task.manager import on_golden_finger on_golden_finger(p) p.save() p.sync() return self.resolve_gold_msg(msgtype, "")
def patch_noob_tasks(p): groups = get_config(TaskByGroupConfig) configs = get_config(TaskConfig) for group in get_sorted_noob_group(): tasks = groups.get(group) flag = False rest = [] for task in tasks: task = configs.get(task.ID) if task.ID in p.taskrewards: flag = True elif p.tasks.get(task.ID, {}).get("plan", 0) < task.goal: flag = True else: rest.append(task) if flag and rest: for each in rest: if each.cond == TaskCond.Levelup: if p.tasks.get(each.ID, {}).get("plan", 0) >= each.goal: p.taskrewards.add(each.ID) else: for task in tasks: try: p.taskrewards.remove(task.ID) except KeyError: pass p.save()
def on_mine_change(player, type=None): if not type: types = [poem_pb.MineType1, poem_pb.MineType2] else: types = [type] for type in types: pets = [player.pets[p] for p in player.lineups.get( get_lineuptype_by_type(type), []) if p] if not pets: return mine_level = getattr(player, 'mine_level%d' % type) if not mine_level: return config = get_config(MineConfig).get(mine_level) if not config: return curr_productivity = getattr(player, "mine_productivity%d" % type) productivity = getattr(config, "mine_productivity%d" % type) pet_configs = get_config(PetConfig) infos = [pet_configs[i.prototypeID] for i in pets] configs = get_config(MineProductivity) percent = 0 for info in infos: c = configs[info.mtype, info.rarity] percent += getattr(c, "productivity%d" % type) productivity = int(productivity * (1 + (percent / float(100)))) if curr_productivity != productivity: # 改变前先将计算当前产出 init_rob_count(player) cost_player_products(player, 0, type) assert productivity, "not productivity" setattr(player, "mine_productivity%d" % type, productivity) player.save() player.sync()
def get_loops(self): configs = get_config(CityCampaignGroupByTypeConfig).get( self.city_campaign_type, []) if not configs: raise StopIteration configs = get_config(CityCampaignConfig) now = datetime.now() today = now.date() day = today.weekday() + 1 count = 0 while True: weekday = (day + count) % 7 or 7 for config in configs.get(weekday, []): if config.type != self.city_campaign_type: continue now = datetime.now() today = now.date() date = today + timedelta(days=count) __start_time = timetime(*map(int, config.start.split(":", 1))) __final_time = timetime(*map(int, config.final.split(":", 1))) start = datetime.combine(date, __start_time) final = datetime.combine(date, __final_time) if now > final: continue self.__start = time.mktime(start.timetuple()) self.__final = time.mktime(final.timetuple()) yield self.__start, self.__final, None count += 1
def enchant_equip(p, equipID, locks=None, ex=False): if not locks: locks = [] equip = p.equips[equipID] info = get_config(NewEquipConfig).get(equip.prototypeID) if not info: return advance_config = get_config(EquipAdvanceConfig).get(equip.step) if not advance_config: return configs = get_config(EnchantByQualityConfig) group = configs.get(advance_config.color) if not group: return if ex: prob = "gold_prob" else: prob = "prob" for index in range(equip.slugs): if index in locks: try: attr = equip.enchants[index] except IndexError: attr = info.enchID else: attr = weighted_random2([[i.ID, getattr(i, prob)] for i in group]) try: equip.enchants[index] = attr except IndexError: equip.enchants.append(attr) update_ranking_equip(p, equip) from task.manager import on_enhant_equip on_enhant_equip(p) equip.save() equip.sync()
def get_ambition_additions_by_raw(ambition, vip_ambition): additions = defaultdict(int) random_ambitions = get_config(RandomAmbitionConfig) attrs = { 1: "ATK", 2: "DEF", 3: "HP", 4: "CRIT", 5: "DODGE", } for configs, ambition_value in [(get_config(AmbitionConfig), ambition), (get_config(VipAmbitionConfig), vip_ambition)]: for index, each in enumerate(ambition_value or '', 1): config = configs.get(index) if not config: continue attr = attrs.get(config.attr_type) if not attr: continue step = int(each) random_ambition = random_ambitions.get(step) if not random_ambition: continue value = getattr(random_ambition, attr) additions[attr.lower()] += value return additions
def faction_donate(self, msgtype, body): p = self.player if not p.factionID: return fail_msg(msgtype, msgTips.FAIL_MSG_FACTION_HAS_NOT_FACTION) if p.todayfp_donate >= p.todayfp_donate_max: return fail_msg(msgtype, msgTips.FAIL_MSG_FACTION_EXCEED_DAILY_DONATE_LIMIT) req = poem_pb.FactionDonate() req.ParseFromString(body) config = get_config(FactionDonateConfig)[1] fp = req.gold / config.arg1 * config.arg2 if req.gold < config.arg1 or \ req.gold % 10 != 0 or \ (p.todayfp_donate + fp) > p.todayfp_donate_max: return fail_msg(msgtype, msgTips.FAIL_MSG_FACTION_DONATE_AMOUNT_INVALID) try: cc = get_config(FactionDonateConfig)[3] apply_reward(p, {'fp': fp / cc.arg1 * cc.arg2}, cost={'gold': req.gold}, type=RewardType.DonateFaction) except AttrNotEnoughError: return fail_msg(msgtype, msgTips.FAIL_MSG_FACTION_NOT_ENOUGH_GOLD) totalfp = Faction.incr_attribute(p.factionID, 'totalfp', fp) p.totalfp += fp p.todayfp_donate += fp p.save() p.sync() rsp = poem_pb.FactionDonateResponse() rsp.totalfp = totalfp return success_msg(msgtype, rsp)
def add_specpacks(role, specPacks): from config.configs import get_config packs = get_config(SpecpackConfig) equipList = [] petList = [] args_for_equips = [] args_for_pets = [] for packID, count in specPacks: pack = packs[packID] if pack.ref_type == RewardItemType.Equip: equipList.append([pack.ref_id, count]) args_for_equips.append({ 'level': pack.e_level, 'step': pack.e_step, }) elif pack.ref_type == RewardItemType.Pet: petList.append([pack.ref_id, count]) petInfo = get_config(PetConfig)[pack.ref_id] add_star = (pack.p_star - 1) * petInfo.need_patch args_for_pets.append({ 'level': pack.p_level, 'breaklevel': pack.p_star, 'add_star': add_star }) result = {} if equipList: result.update(add_equips(role, equipList, args=args_for_equips)) if petList: result.update(add_pets(role, petList, args=args_for_pets)) return result
def trigger_chest_recv(self, msgtype, body): p = self.player if not check_trigger_event_type(p, EventType.Chest): return fail_msg(msgtype, reason="无触发事件或错误的事件类型") req = poem_pb.TriggerChestRecvRequest() req.ParseFromString(body) config = get_config(TriggerEventConfig)[p.trigger_event] chest = get_config(TriggerChestConfig).get(config.event_param) if not chest: return fail_msg(msgtype, reason="不存在的宝箱") if req.is_double: cost = {"gold": get_cons_value("TriggerChestDoubleCost")} gain = {} for i in range(get_cons_value("TriggerChestMultiple")): gain = combine_reward([chest.reward], [], data=gain) else: cost = {} gain = parse_reward([chest.reward]) try: apply_reward(p, gain, cost=cost, type=RewardType.TriggerChest) except AttrNotEnoughError: return fail_msg(msgtype, reason="钻石不足") p.trigger_event = 0 p.save() p.sync() rsp = poem_pb.TriggerChestRecv() build_reward_msg(rsp, gain) return success_msg(msgtype, rsp)
def get_monster_groups(fbID): groups = {} fbinfos = get_config(FbInfoConfig) groupinfos = get_config(GroupConfig) groupcount = 5 monstercount = 4 fbinfo = fbinfos[fbID] for groupindex in range(1, groupcount + 1): groupID = getattr(fbinfo, 'group{}'.format(groupindex)) if not groupID: break groupinfo = groupinfos[groupID] monsters = {} realindex = 0 for monsterindex in range(1, monstercount + 1): monsterID = getattr(groupinfo, 'monster_id{}'.format(monsterindex)) monsterlevel = getattr(groupinfo, 'monster_level{}'.format(monsterindex)) if not monsterID: continue else: realindex += 1 monsters[realindex] = (monsterlevel, monsterID) groups[groupindex] = monsters return groups
def trigger_store_buy(self, msgtype, body): p = self.player if not check_trigger_event_type(p, EventType.Store): return fail_msg(msgtype, reason="无触发事件或错误的事件类型") config = get_config(TriggerEventConfig)[p.trigger_event] goods = get_config(TriggerStoreConfig).get(config.event_param) if not goods: return fail_msg(msgtype, reason="没有这个商品") cost = parse_reward([{ 'count': goods.discount_price, 'type': goods.discount_price_type}]) gain = parse_reward([goods.reward]) try: apply_reward(p, gain, cost=cost, type=RewardType.TriggerStore) except AttrNotEnoughError as e: if e.attr == "gold": return fail_msg(msgtype, reason="钻石不足") elif e.attr == "money": return fail_msg(msgtype, reason="金币不足") else: return fail_msg(msgtype, reason="消耗不足") p.trigger_event = 0 p.save() p.sync() return success_msg(msgtype, "")
def modifyfbId(playerId): ''' 修改用户副本进度 ''' from scene.constants import FbType from scene.manager import set_fb_score, sync_scene_infos from config.configs import get_config, FbInfoByTypeConfig, FbInfoConfig from entity.manager import g_entityManager player = g_entityManager.get_player(int(playerId)) if not player: return FAILURE fbID = int(request.GET.getone("fbId") or 0) if not fbID: configs = get_config(FbInfoByTypeConfig).get(FbType.Normal, [])\ + get_config(FbInfoByTypeConfig).get(FbType.Guide, [])\ + get_config(FbInfoByTypeConfig).get(FbType.Advanced, []) for c in configs: if c.ID not in player.fbscores: set_fb_score(player, c.ID, 3) else: configs = get_config(FbInfoConfig) if fbID in configs: set_fb_and_prev_score(player, fbID, 3) else: return json.dumps('failure') player.save() sync_scene_infos(player, FbType.Normal) sync_scene_infos(player, FbType.Advanced) return SUCCESS
def pay_handler(entityID, username, goodsid, amount=None): goodsid = str(goodsid) # 必须是字符串 label = username2label(username) sdktype = username2type(username) sdkconfigs = get_config(RechargeBySdktypeConfig).get(sdktype, []) labconfigs = get_config(RechargeByLabelConfig).get(label, []) configs = get_config(RechargeConfig) ids = {e.id for e in sdkconfigs} & {e.id for e in labconfigs} good = {configs[e].goodsid: configs[e] for e in ids}.get(goodsid) if not good: logger.error("error goodsid %r", goodsid) return p = g_entityManager.get_player(entityID) if p: level = p.level reward = give_goods(p, good, amount=amount) get_gold = reward.get("gold", 0) else: # patch 离线玩家,需要计算可获得金额 p = Player.simple_load( entityID, ["userID", "level", "bought_recharges", "offline_recharges"]) level = p.level if p.offline_recharges: p.offline_recharges.append([good.id, amount]) else: p.offline_recharges = [[good.id, amount]] is_first = (good.id not in (p.bought_recharges or set())) \ and (good.id not in ({i for i, j in p.offline_recharges} or set())) from reward.manager import open_reward, RewardType reward = open_reward(RewardType.Recharge, good, is_first, amount) rs = reward.apply_after() # 仅计算可获金额,并不发货 get_gold = rs.get("gold", 0) p.save() return {"username": username, "level": level, "get_gold": get_gold}
def reset_dlc_progress(p, sceneID): scene = get_config(SceneInfoConfig)[sceneID] dlcID = get_config(DlcFbInfoConfig)[scene.fbs[0]].dlcID progress = p.dlc_progress.get(dlcID, []) configs = get_config(FbInfoConfig) if progress: reseted = [] for i in progress: c = configs.get(i) if not c: continue if c.sceneID != sceneID: reseted.append(i) p.dlc_progress[dlcID] = reseted for i in get_config(FbInfoBySceneConfig).get(sceneID, []): if i.ID in p.dlc_dispatch: for petID in p.dlc_dispatch[i.ID].get("pets", []): pp = p.pets.get(petID) if pp: pp.dispatched = 0 pp.save() pp.sync() del p.dlc_dispatch[i.ID] p.dlc_detail_cache.clear() p.save()
def challenge(self, player): """挑战""" from lineup.constants import LineupType p = player floor = p.climb_tower_floor + 1 max_retry = 5 retry = 0 config = get_config(ClimbTowerAccreditConfig).get(floor, None) if not config: config = get_config(ClimbTowerConfig)[floor] t = config.zombie_id if floor in self.floors: self.floors[floor].cleanup() f = self.floors[floor].idx # 如果派驻满了而且有空闲对手 while retry < max_retry and self.floors[floor].is_full() \ and f.count() > self.floors[floor].lock.count(): start = random.randint(0, f.count()) targets = f.pool.execute('ZRANGE', f.key, start, start + 10) logger.debug('climb_tower targets: %s' % targets) for m in targets: if int(m) == player.entityID or self.floors[floor].lock.exists(m): continue logger.debug('challenge player') return get_opponent_detail(int(m), type=LineupType.Accredit) retry += 1 logger.debug('challenge zombie') return get_opponent_detail(t)
def get_zombies_by_power(low_or_current, high=None, count=None, hide=True, group=None, must=False): if count == 0: return configs = get_config(PvpGroupConfig) power_range = get_power_range(low_or_current, high) powers = get_config(PvpGroupByPowerConfig) result = [] for power in power_range: by_power = powers.get(power, []) for each in by_power: config = configs.get(each.ID) if count is not None and len(result) >= count: break if not config: continue if hide and not config.visible: continue if group and config.group != group: continue result.append(config.ID) return result
def run(): ranks = self.BossCampaignRanking.get_range_by_score( "-inf", "+inf", withscores=True) configs = get_config(FriendfbRewardConfig) group = get_config(FriendfbRewardByFbIDConfig).get( self.config.fbID, []) configs = [configs[e.ID] for e in group] rank = 1 for index, entityID in enumerate(ranks, 0): if index % 2 == 1: continue for r in configs: start, end = r.range if rank >= start and (not end or rank <= end): p = g_entityManager.get_player(entityID) rewards = { self.identification: { "rewards": r.rewards, "damage": ranks[rank], "rank": rank } } if p: give_reward(p, rewards=rewards) else: keep_reward(entityID, rewards) break rank += 1
def give_ranking_reward(sdate=None): if sdate: date = datetime.strptime(sdate, "%Y-%m-%d").date() else: date = datedate.today() sdate = datetime.strftime(date, "%Y-%m-%d") sceneID = get_sceneID(date=date) url = "/".join( [urljoin(PROXY["host"], PROXY["port"]), "give_gve_ranking_reward"]) pending = [] group = get_config(GveRankingRewardBySceneIDConfig).get(sceneID) configs = get_config(GveRankingRewardConfig) for rank, (regionID, groupID, score) in enumerate( get_group_ranking(sceneID, count=50, date=date), 1): for config in group: config = configs.get(config.ID) start, end = config.range if rank >= start and rank <= end: g = Group.simple_load(groupID, ["name", "members"]) g.members.load() data = { "group_name": encode_utf8(g.name), "group_damage": score, "group_rank": rank, "configID": config.ID, "date": sdate, } for entityID in g.members: uri = "/".join([url, str(entityID)]) uri = set_query_string(uri, regionID=regionID) pending.append([uri, data]) for uri, data in pending: get_poolmanager().urlopen("POST", uri, body=urlencode(data))
def trigger_chests_recv(self, msgtype, body): p = self.player if not check_trigger_event_type(p, EventType.Chests): return fail_msg(msgtype, reason="无触发事件或错误的事件类型") config = get_config(TriggerEventConfig)[p.trigger_event] chest = get_config(TriggerChestsConfig).get(config.event_param) if len(p.trigger_chests) > 0: cost = {"gold": get_cons_value("TriggerChestsMoreCost")} else: cost = {} rests = set(range(len(chest.rewards))) - p.trigger_chests if not rests: return fail_msg(msgtype, reason="已经没有宝箱了") index = choice_one(list(rests)) is_best = False if index == 0: p.trigger_event = 0 is_best = True gain = parse_reward([chest.rewards[index]]) try: apply_reward(p, gain, cost=cost, type=RewardType.TriggerChests) except AttrNotEnoughError: return fail_msg(msgtype, reason="钻石不足") p.trigger_chests.add(index) p.save() p.sync() rsp = poem_pb.TriggerChestsRecv(is_best=is_best) build_reward_msg(rsp, gain) return success_msg(msgtype, rsp)
def break_cost(prototypeID, breaklevel): """突破所需材料数*系数*piece_amount/100=升到breaklevel级所需要的星魄数""" b_config = get_config(BreakConfig)[breaklevel - 1] p_config = get_config(PetConfig)[prototypeID] # need_patch is piece_amount cost = p_config.need_patch * p_config.camount * b_config.amount / 100 return cost
def get_dlc_score(p, dlcID): dlc = get_config(DlcConfig)[dlcID] scores = 0 for i in dlc.scenes: fbs = get_config(FbInfoBySceneConfig).get(i, []) for f in fbs: scores += get_fb_score(p, f.ID) return scores
def is_last_of_scene(player, fbID): curr = get_config(FbInfoConfig)[fbID] scene = get_config(SceneInfoConfig)[curr.sceneID] if not scene.fbs: return False if fbID == scene.fbs[-1]: return all(map(lambda s: s in player.fbscores, scene.fbs[:-1])) return False
def on_end_dlc_fb(task, today, player, fbID, count=1): from config.configs import get_config, DlcFbInfoConfig dlc_fb = get_config(DlcFbInfoConfig).get(fbID) dlc_task = get_config(DlcTaskConfig).get(task.ID) if dlc_fb.dlcID != dlc_task.dlcID: return if dlc_fb and (not task.arg2 or dlc_fb.type in task.arg2): return _set_plan(player, task, today, value=count)
def reload_relations(p, sames): # {{ 取出该批同名将修改所影响的同名将 same_to_relations = get_config(AntiRelationConfig) # 同名将对应羁绊 relation_configs = get_config(RelationConfig) # 羁绊配置 pet_configs = get_config(PetConfig) need_reloads = set() for s in sames: relations = same_to_relations.get(s) if not relations: continue relations = relations.relas for each in relations: relation = relation_configs.get(each) if not relation: continue need_reloads.add(relation.same) # }} relas_by_same = get_config(RelationBySameConfig) # 同名将 dd = {} for same in need_reloads: same_pets = p.sames.get(same, []) if not same_pets: continue relations = relas_by_same.get(same, []) if not relations: continue relations_data = {} for relation in relations: relation = relation_configs.get(relation.ID) needs = set() for need in relation.units: needs.add(pet_configs[need].same) multi = 1 if len(needs & set(p.sames)) == len(needs): bests = {} for need in needs: for each in p.sames.get(need, []): pet = p.pets.get(each) if not pet: continue info = pet_configs.get(pet.prototypeID) if not bests.get(need, False): bests[need] = (info.rarity >= 5) if all(bests.values()): multi = 2 relations_data[relation.ID] = multi for each in same_pets: pet = p.pets.get(each) if not pet: continue dd.setdefault(each, {}).update(relations_data) dirty_pets = [] for k, v in dd.items(): pet = p.pets[k] if pet.activated_relations != v: pet.activated_relations = v dirty_pets.append(pet) return dirty_pets
def get_refresh_cost(player, fbID, today=None): from config.configs import get_config, RefreshFbCostConfig configs = get_config(RefreshFbCostConfig) used = get_refresh_used_count(player, fbID, today) configs = get_config(RefreshFbCostConfig) config = configs.get(used + 1) if not config: config = configs[max(configs)] return config.cost
def on_fund_bought_count_change(origin, current): """开服基金购买触发全民福利广播""" types = get_config(FundRewardByTypeConfig).get(FundRewardType.Full, []) configs = get_config(FundRewardConfig) for each in types: config = configs[each.ID] if origin < config.parm and current >= config.parm: proxy.boardcast_fund_change() break
def give_reward(self, date=None): if not date: now = int(time.time()) tm = date = datedate.fromtimestamp(now).strftime("%Y-%m-%d") else: tm = date ranking = get_ranking_backup(self.type) key = ranking.key ll = get_config(RankingCampaignRewardByGroupConfig).get( self.config.group, []) configs = get_config(RankingCampaignRewardConfig) configs = [configs[i.id] for i in ll] key = "%s{%s}" % (key, tm) limit = get_ranking_limit(self.type) if limit is not None: rankers = ranking.get_range_by_score(limit, "+inf", withscores=True) else: rankers = ranking.get_range_by_score("-inf", "+inf", withscores=True) rankers = convert_list_to_dict(rankers, dictcls=OrderedDict).items() for rank, (entityID, score) in enumerate(rankers, 1): config = None for c in configs: start, end = c.range if start: if start > rank: continue if end: if end < rank: continue config = c if not config: continue title, content, ID = get_mail("RankingReward") content = content.format(self.config.day, self.config.title, rank) if self.type in get_faction_types(): f = Faction.simple_load(entityID, ["leaderID", "memberset"]) for i in set(f.memberset): if i == f.leaderID: rewards = parse_reward(config.rewards) else: rewards = parse_reward(config.rewards2) try: proxy.ranking_send_mail(i, title, content, rewards, key, ID) except AttributeError: pass else: rewards = parse_reward(config.rewards) try: proxy.ranking_send_mail(entityID, title, content, rewards, key, ID) except AttributeError: pass
def get_pet_base_dodge(prototypeID, level, breaklevel, activated_relations): from config.configs import get_config, PetConfig, BreakConfig info = get_config(PetConfig)[prototypeID] binfo = get_config(BreakConfig).get(breaklevel) if not binfo: binfo = get_config(BreakConfig)[max(get_config(BreakConfig))] unit = info.mdodge * binfo.bdodge / float(100) base = calc_base(info.dodgeMin, unit, level) / float(100) return base + get_rela_value(base, activated_relations, "eva")
def get_pet_base_hp(prototypeID, level, breaklevel, activated_relations): from config.configs import get_config, PetConfig, BreakConfig info = get_config(PetConfig)[prototypeID] binfo = get_config(BreakConfig).get(breaklevel) if not binfo: binfo = get_config(BreakConfig)[max(get_config(BreakConfig))] bk = getattr(info, "%s_break" % "hp", [0, 0, 0, 0, 0])[breaklevel - 1] base = calc_base(info.hpMin, info.mhp * binfo.bhp / float(100), level) + bk return base + get_rela_value(base, activated_relations, "hp")