def maze_step(self, msgtype, body): p = self.player req = poem_pb.MazeStepRequest() req.ParseFromString(body) count = p.maze_rest_count if req.onekey else 1 # check count if count > p.maze_rest_count: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) gains = {} attr = {} mazes = [] incr = {} results = step_mazes(p, attr, incr, count) count = len(results) rsp = poem_pb.MazeStepResponse() for each in results: drop = each.get("drop", 0) if drop: maze_drop = open_reward(RewardType.MazeDrop, drop) rewards = maze_drop.apply_after() gains = combine_reward(rewards, {}, data=gains) if each.get("append", False): mazes.append(each) drop = get_cons_value("MazeMustDropID") must_drop = open_reward(RewardType.MazeDrop, drop) rewards = must_drop.apply_after() gains = combine_reward(rewards, {}, data=gains) rsp.events.add(**each) rsp.rewards = build_reward(gains) for each in mazes: p.mazes.append(each) apply_reward(p, gains, type=RewardType.MazeDrop) for each, value in attr.items(): setattr(p, each, value) for each, value in incr.items(): setattr(p, each, getattr(p, each) + value) if "mall_silver_open_remain" in attr: try: del p.malls[MallType.Silver] except KeyError: pass if "mall_golden_open_remain" in attr: try: del p.malls[MallType.Golden] except KeyError: pass p.touch_mazes() p.maze_step_count += count on_maze_count(p, count) p.save() p.sync() return success_msg(msgtype, rsp)
def treasure_end(self, msgtype, body): p = self.player req = poem_pb.EndTreasure() req.ParseFromString(body) if not PlayerTreasureLock.unlock(p.entityID, req.verify_code): logger.debug("verify_code %s", req.verify_code) return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) if not p.treasure_cache: logger.debug("not treasure_cache") return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) rewards = [] for type, subtype, count in p.treasure_cache: if type == TreasureGrid.TreasureGridTypeReward: rewards.append(poem_pb.RewardData( type=subtype, count=count)) r1 = parse_reward(req.rewards) r2 = parse_reward(rewards) logger.debug("reward %r %r", r1, r2) if not compare_reward(r1, r2): logger.debug("compare reward fail") return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) config = get_config(TreasureChestConfig)[p.treasure_type] gain_chest = bool(req.gain_chest) if gain_chest: reward = open_reward(RewardType.Treasure, config.drop) result = reward.apply_after() else: result = {} result = combine_reward(r1, result) rsp = poem_pb.EndTreasureResponse() finisheds = [] finisheds.append(gain_chest) finisheds.append(bool(req.kill_monster)) need = get_cons_value("TreasureNeedBuffCount") finisheds.append(len(req.rewards) >= need) rsp.stars = len(filter(lambda s: s, finisheds)) if rsp.stars == len(finisheds): rewardex = open_reward(RewardType.Treasure, config.dropex) rsp.rewardsex = build_reward(rewardex.apply(p)) rsp.finisheds = finisheds apply_reward(p, result, type=RewardType.Treasure) build_reward_msg(rsp, result) now = int(time.time()) p.treasure_used_count += 1 p.treasure_cd = now + 10 * 60 p.treasure_cache = [] refresh_treasure(p) on_treasure_count(p) p.save() p.sync() return success_msg(msgtype, rsp)
def maze_case_recv(self, msgtype, body): p = self.player req = poem_pb.MazeEventRequest() req.ParseFromString(body) index = req.index or 0 try: event = p.mazes[index] except IndexError: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) count = 1 cost = {} if req.treble: count = 3 cost = {"gold": p.maze_case_cost} if event.get("type") != MazeEventType.Case: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) drop = event.get("argv", 0) drops = [drop] * count if drop: reward = open_reward(RewardType.MazeDrop, *drops) if cost: reward.cost_after(p, **cost) result = reward.apply(p) p.mazes.remove(event) p.touch_mazes() p.save() p.sync() rsp = poem_pb.MazeCaseResponse() build_reward_msg(rsp, result) return success_msg(msgtype, rsp)
def onekey_tap(p): drops = [] counting = 0 while p.tap_rest_count: # 杀死当前怪需要多少次点击 need = len(p.tap_hurts[p.tap_hurts_index:]) counting += need logger.debug("tap rest count %r", p.tap_rest_count) logger.debug("need tap %r", need) if p.tap_rest_count >= need: # kill count = need monster = get_config(TapMonsterConfig)[p.tap_monster] drops.append(monster.drop) next_monster(p) logger.debug("kill monster") else: count = p.tap_rest_count p.tap_hurts_index += count logger.debug("hit monster %r times", count) p.tap_rest_count -= count logger.debug("tap rest count %r", p.tap_rest_count) logger.debug("tap hurts index %r", p.tap_hurts_index) reward = open_reward(RewardType.Tap, *drops) result = reward.apply(p) p.save() p.sync() return result, counting
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 giftkey(self, msgtype, body): from protocol.poem_pb import Giftkey, GiftkeyResponse from config.configs import get_config, GiftkeyConfig from reward.manager import open_reward, build_reward_msg, RewardType from giftkey import use_key, InvalidGiftkeyError, ExceedUseCountError, ExceedDeallineError player = self.player req = Giftkey() req.ParseFromString(body) try: giftID = use_key(player, req.key) except InvalidGiftkeyError: return fail_msg(msgtype, reason='无效的兑换码') except ExceedUseCountError: return fail_msg(msgtype, reason='已经达到最大兑换次数了') except ExceedDeallineError: return fail_msg(msgtype, reason='已经超过有效期了') gift = get_config(GiftkeyConfig)[giftID] reward = open_reward(RewardType.Giftkey, gift) result = reward.apply(player) player.save() player.sync() rsp = GiftkeyResponse() build_reward_msg(rsp, result) gm_logger.info( {'giftkey': { 'entityID': player.entityID, 'giftkey': req.key }}) return success_msg(msgtype, rsp)
def friend_friendfb_end(self, msgtype, body): p = self.player req = poem_pb.EndFriendfb() req.ParseFromString(body) if not PlayerFightLock.unlock(p.entityID, req.verify_code): return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) assert p.cache_friendfbID, "impossible" rsp = poem_pb.EndFriendfbResponse() try: createtime, hp, fbID = simple_load_friendfb( p.cache_friendfbID, 'createtime', 'hp', 'fbID') except DoesNotExistsException: error_code = msgTips.FAIL_MSG_FRIENDFB_ALREADY_DISAPPEARED else: if hp <= 0: error_code = msgTips.FAIL_MSG_FRIENDFB_ALREADY_DEAD # return fail_msg(msgtype, reason='BOSS已经被击杀了') else: from pvp.manager import send_fight_verify from fightverifier.direct_verifier import verify send_fight_verify(p, req.fight) if not verify(p, req.fight): return fail_msg(msgtype, msgTips.FAIL_MSG_FIGHT_VERIFY_FAILED) error_code = 0 now = int(time.time()) if if_boss(p.cache_friendfbID) and\ not if_boss_campaign_opened(p.cache_friendfbID) or \ not if_boss(p.cache_friendfbID) and \ now > createtime + FRIENDFB_INTERVAL: error_code = msgTips.FAIL_MSG_FRIENDFB_ALREADY_DISAPPEARED # NOQA else: info = get_config(FriendfbConfig)[fbID] if info.drop: r = open_reward(RewardType.Friendfb, info.drop) result = r.apply(p) build_reward_msg(rsp, result) damage = max(req.fight.total_damage or 0, 0) hp = hurt_boss(p, fbID, p.cache_friendfbID, damage) if hp <= 0: if if_boss(p.cache_friendfbID): # 提前发奖 bc = get_boss_campaign(p.cache_friendfbID) proxy.notify_boss_campaign_end(bc.config.ID) entityID = bc.get_by_rank(1) proxy.sync_on_task_change(entityID, TaskCond.FriendfbFirst, p.cache_friendfbID) else: give_reward(p.cache_friendfbID) on_friendfb_count(p, fbID) else: p.friendfb_deads.add(p.cache_friendfbID) p.friendfb_deadtimes[fbID] = now p.friendfb_buff = 0 p.save() p.sync() rsp.error_code = error_code return success_msg(msgtype, rsp)
def on_sign_up(task, today, player): result = _set_plan(player, task, today) if result: from reward.manager import open_reward, RewardType reward = open_reward(RewardType.Task, task.drop) reward.apply(player) player.taskrewards.remove(task.ID) return False # 防止递归检查下一个任务
def spar_request(self, msgtype, body): p = self.player req = poem_pb.SparRequest() req.ParseFromString(body) config = get_config(SparConfig).get(req.ID) if not config: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) logger.debug(req) spar_count = p.spar_counts.get(req.ID, 0) count = config.onekeycount if req.onekey else 1 # cost = config.onekeycost if req.onekey else 1 if not count: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) drops = [] for i in range(count): if spar_count >= config.dropex_use_count: drops.append(config.dropex) spar_count = 0 else: drops.append(config.drop) spar_count += 1 if not drops: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) try: reward = open_reward(RewardType.Spar, *drops) reward.cost_after( p, matList=[[config.itemID, count]], money=config.money*count) result = reward.apply(p) except AttrNotEnoughError: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) except MatNotEnoughError: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) rsp = poem_pb.SparResponse() build_reward_msg(rsp, result) on_pet_spar(p, rsp.rewards) on_equip_spar(p, rsp.rewards) p.spar_counts[req.ID] = spar_count from task.manager import on_spar_count on_spar_count(p, spar_count) p.save() p.sync() logger.debug(rsp) count = config.dropex_use_count - p.spar_counts.get(req.ID, 0) info = config._asdict() if count == 0: info['tips'] = config.final_tips else: info['tips'] = config.tips.format(count + 1) rsp.item = poem_pb.SparItem(**info) return success_msg(msgtype, rsp)
def city_contend_drop_event(self, msgtype, body): p = self.player if not p.factionID: return fail_msg(msgtype, msgTips.FAIL_MSG_FACTION_HAS_NOT_FACTION) if not g_campaignManager.city_contend_campaign.is_open(): return fail_msg(msgtype, msgTips.FAIL_MSG_CITY_CAMPAIGN_CLOSED) if not g_cityContend.check_event(p, CityContendEventType.Drop): return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) event = g_cityContend.get_current_step(p) if g_cityContend.is_top_faction(p.factionID): result = open_reward(RewardType.CityContend, event["argv"]) else: result = open_reward(RewardType.CityContend, event["argv"]) rewards = result.apply(p) rsp = poem_pb.CityContendDropEventResponse() combine_reward(rewards, {}, p.city_contend_rewards) rsp.rewards = build_reward(p.city_contend_rewards) p.city_contend_step += 1 p.city_contend_total_step += 1 p.save() p.sync() return success_msg(msgtype, rsp)
def end_tap(p, count): if p.tap_rest_count < count: return False hurts = p.tap_hurts[:p.tap_hurts_index + count] monster = get_config(TapMonsterConfig).get(p.tap_monster) if sum(hurts) < monster.hp: return False reward = open_reward(RewardType.Tap, monster.drop) result = reward.apply(p) p.tap_hurts_index = 0 p.tap_rest_count -= count p.tap_hurts = [] p.save() p.sync() return result
def visit(p, count): gain = {} cost = {} configs = get_config(VisitConfig) incr_groups = get_config(VisitIncrByGroupConfig) choices = [] campaign = g_campaignManager.visit_campaign campaign_opened = campaign.is_open() luck = {} for i in range(count): weighted_samples = [] rewards = None for k, config in configs.items(): if config.flag and campaign_opened: current = campaign.get_current() incr_configs = incr_groups.get(current.reward_group) VISIT_COUNT = incr_visit_flag() for incr_config in incr_configs: if VISIT_COUNT % incr_config.count == 0: choice = incr_config reward = open_reward(RewardType.Visit, choice.drop) rewards = reward.apply_after() combine_reward(rewards, {}, data=luck) break if rewards: break else: weighted_samples.append([config, config.prob]) if not rewards: choice = weighted_random2(weighted_samples) rewards = choice.rewards choices.append(choice.id) gain_pious = {"pious": 1} gain = combine_reward(rewards, gain_pious, data=gain) if p.visit_free_rest_count < count: count = count - p.visit_free_rest_count if p.dream: cost["dream"] = min(p.dream, count) count -= cost["dream"] if count: cost["gold"] = p.visit_cost * count return gain, cost, choices, luck
def cleanfbs(p, fbID, count, cost): assert count > 0 items = [] rewards = {} useless = poem_pb.EnterFbResponse() # cost_ = dict(cost) # cost.clear() for i in range(count): item = poem_pb.CleanFbRspStruct() set_fb_score(p, fbID, 3) item.curFbInfo = poem_pb.FbInfo(**get_fb_info(p, fbID)) reward = open_reward(RewardType.FB, p, fbID, False, useless) result = filter_cleanfb_reward(reward) item.rewards = build_reward(result) rewards = combine_reward(rewards, result) # combine_reward(cost_, [], cost) items.append(item) apply_reward(p, rewards, cost=cost, type=RewardType.CleanFB) p.save() p.sync() return items
def uproar_reset(p): """训练家之丘重置""" configs = get_config(UproarConfig) p.uproar_targets.clear() p.uproar_chests.clear() map(p.uproar_targets.pop, p.uproar_targets.keys()) map(p.uproar_chests.pop, p.uproar_chests.keys()) for n, config in configs.items()[:10]: targetID = -config.robot p.uproar_targets[n] = targetID money = int(p.level * (config.money_base + random.randint(0, 10))) must = {'jiutian': config.jiutian, 'money': money} reward = open_reward(RewardType.Uproar, config.dropID, {}) drop = reward.apply_after() p.uproar_chests[n] = {"must": must, "drop": drop} p.uproar_targets_cache = [] p.uproar_chests_cache = [] p.uproar_details_cache.clear() for targetID in p.uproar_targets.values(): if targetID > 0: target = get_detail(targetID) if target: p.uproar_details_cache[targetID] = target p.uproar_chests_cache = [] p.uproar_targets_done = set() p.uproar_chests_done = set() p.uproar_targets_team.clear() for pet in p.pets.values(): if pet.uproar_dead: pet.uproar_dead = False pet.restHP = 0 pet.save() pet.sync() # 重置敌方属性加成 p.uproar_enemy_buff = 0 p.uproar_enemy_min_power = 0 p.save() p.sync()
def use_mat(self, msgtype, body): p = self.player req = poem_pb.UseMatRequest() req.ParseFromString(body) config = get_config(MatConfig).get(req.matID) if not config: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) rsp = poem_pb.UseMatResponse() if config.type == MatType.Drop: drop = config.arg attr = "" elif config.type in USEINGS: drop = 0 attr = USEINGS.get(config.type) elif config.type == MatType.RipeningAgent: if p.seed_state == poem_pb.SeedStateNormal or\ p.seed_state == poem_pb.SeedStateRipening or\ p.seed_state == poem_pb.SeedStateRoot: return fail_msg(msgtype, reason="无法使用!") p.seed_state = poem_pb.SeedStateRipening p.seed_state_last_change_time = 0 p.seed_state_next_change_time = 0 p.seed_state_ripening_time = 0 drop = 0 attr = '' else: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) reward = open_reward(RewardType.UseMat, drop) reward.cost_after(p, matList=[[req.matID, 1]]) result = reward.apply(p) if attr: value = getattr(p, attr, 0) + config.arg setattr(p, attr, value) rsp.tips = config.tips build_reward_msg(rsp, result) p.save() p.sync() return success_msg(msgtype, rsp)
def create_player(player): config = get_config(CreatePlayerConfig)[player.sex, player.career] player.mats[config.prototypeID] = 1 player.prototypeID = config.prototypeID player.mats[config.borderID] = 1 player.borderID = config.borderID player.money = config.money player.gold = config.gold player.level = config.level player.createtime = datetime.now() player.last_check_mail_time = time.mktime(player.createtime.timetuple()) player.sp = config.sp player.spmax = player.sp player.petmax = config.petmax player.new_role = True player.add_pets(*[{"prototypeID": p} for p in config.petIDs]) player.skillpoint = player.skillpoint_max player.maze_rest_count = player.maze_most_count player.lottery_gold_accumulating = config.accumulating # # 新号过滤已过期签到天数 # player.check_in_over_count = max(player.createtime.day - 1, 0) # player.check_in_used_count = player.check_in_over_count from task.manager import trigger_seven_task trigger_seven_task(player) init_lineups(player) if config.drop: from reward.manager import open_reward, RewardType reward = open_reward(RewardType.CreatePlayer, config.drop) reward.apply(player) # wish if get_cons_value("WishNewPlayerExperienceFlag"): player.wish_experience_time = time.mktime( player.createtime.timetuple()) + get_cons_value( "WishNewPlayerExperienceTime") player.save() return player
def give_goods(player, goods, amount=None): rest = 0 famount = float(goods.amount) if amount is not None and famount != amount: if amount > famount: rest = amount - famount else: # 当充值金额不足,选择同类型的满足金额的商品,多出金额返还 sdktype = username2type(player.username) label = username2label(player.username) sdkconfigs = get_config(RechargeBySdktypeConfig).get(sdktype, []) labconfigs = get_config(RechargeByLabelConfig).get(label, []) typconfigs = get_config(RechargeByTypeConfig).get(goods.type, []) ids = {e.id for e in sdkconfigs} & {e.id for e in labconfigs} ids = ids & {e.id for e in typconfigs} configs = get_config(RechargeConfig) configs = [configs[e] for e in ids] configs = sorted(configs, key=lambda s: float(s.amount), reverse=True) for config in configs: if float(config.amount) < amount: goods = config rest = amount - famount break else: goods = None rest = amount if goods: is_first = goods.id not in player.bought_recharges if goods.type == RechargeType.LimitedPacks: reward_type = RewardType.LimitedPacks elif goods.type == RechargeType.TimeLimitedPacks: reward_type = RewardType.TimeLimitedPacks elif goods.type == RechargeType.TriggerPacks1: reward_type = RewardType.TriggerPacks1 elif goods.type == RechargeType.TriggerPacks2: reward_type = RewardType.TriggerPacks2 else: reward_type = RewardType.Recharge credits = (famount + rest) * 10 else: is_first = False reward_type = RewardType.Recharge credits = rest * 10 reward = open_reward(reward_type, goods, is_first, rest * 10) result = reward.apply(player) logger.debug("recharge result {}".format(result)) # 不使用golden是因为有些商品是礼包,不包含钻石 __vip = player.vip player.credits += credits if player.vip != __vip: # VIP改变导致活动副本次数改变 from scene.manager import sync_scene_infos sync_scene_infos(player, FbType.Campaign) from explore.ambition import reload_vip_ambition reload_vip_ambition(player) if not player.bought_recharges: player.first_recharge_numb = result.get("gold", 0) if goods: if goods.type == RechargeType.MonthlyCard30: if not player.monthly_card_30: player.monthly_card_30 = 30 from task.manager import on_monthly_card on_monthly_card(player) elif goods.type == RechargeType.Monthcard1: player.monthcard1 += MonthCardDays elif goods.type == RechargeType.Monthcard2: player.monthcard2 += MonthCardDays elif goods.type == RechargeType.Weekscard1: player.weekscard1 += WeeksCardDays elif goods.type == RechargeType.Weekscard2: player.weekscard2 += WeeksCardDays elif goods.type == RechargeType.LimitedPacks: now = int(time.time()) player.limited_packs_used_count += 1 player.limited_packs_last_time = now elif goods.type == RechargeType.TimeLimitedPacks: now = int(time.time()) player.timelimited_packs_last_time = now elif goods.type in (RechargeType.TriggerPacks1, RechargeType.TriggerPacks2): # 支付回调问题 # NOTE # player.trigger_packs_buy_count += 1 pass # 记录首次充值获得的金额数 player.bought_recharges.add(goods.id) from campaign.manager import on_recharge on_recharge(player, goods.golden) from task.manager import on_vip_level on_vip_level(player) player.save() player.sync() return result
def lottery(self, msgtype, body): req = poem_pb.LotteryRequest() req.ParseFromString(body) p = self.player from entity.manager import save_guide save_guide(p, req.guide_type) # 保存新手引导进度 logger.debug("req: {}".format(req)) LOTTERY_ID2TYPE = { LotteryType.Lottery1: ("A", "ball", 1), LotteryType.Lottery2: ("B", "ball", 10), LotteryType.Lottery3: ("C", "gold", 1), LotteryType.Lottery4: ("D", "gold", 10), } kind_cfg = get_config(LotteryFunctionConfig)[req.type] if req.type not in LOTTERY_ID2TYPE: return fail_msg(msgtype, reason="类型不对") if p.level < kind_cfg.level: return fail_msg(msgtype, reason="等级不足") kind, cost_type, cost_count = LOTTERY_ID2TYPE[req.type] cost = kind_cfg.Price if req.type == LotteryType.Lottery2: if p.ball < 10: cost_count = p.ball cost = p.ball now = time.time() loterry_hero_count = getattr( p, "loterry_hero_count_{}".format(kind)) loterry_hero_gold_first = getattr( p, "loterry_hero_gold_first_{}".format(kind)) loterry_hero_used_free_count = getattr( p, "loterry_hero_used_free_count_{}".format(kind)) or 0 loterry_hero_cd = getattr( p, "loterry_hero_cd_{}".format(kind)) cd = datetime.fromtimestamp(loterry_hero_cd).strftime('%Y-%m-%d %H:%M') logger.debug('loterry_hero_cd: {}'.format(cd)) cd = datetime.fromtimestamp(loterry_hero_cd).strftime('%Y-%m-%d %H:%M') logger.debug('loterry_hero_cd: {}'.format(cd)) key = "NormalGold{}".format(kind) if loterry_hero_cd <= now and \ loterry_hero_used_free_count < kind_cfg.FreeTimes: # 免费 if not loterry_hero_count: # 引导抽 key = "FirstFree{}".format(kind) ID = kind_cfg.rangeset[1] elif loterry_hero_count == 1: # 首抽 key = "NormalFree{}".format(kind) ID = kind_cfg.rangeset[2] else: # 普通 key = "NormalFree{}".format(kind) ID = kind_cfg.rangeset[0] else: # 付费 if not loterry_hero_count: # 引导抽 key = "FirstGold{}".format(kind) ID = kind_cfg.rangeset[1] if not ID: ID = kind_cfg.rangeset[2] elif loterry_hero_count == 1: # 首抽 key = "FirstGold{}".format(kind) ID = kind_cfg.rangeset[2] else: key = "NormalGold{}".format(kind) ID = kind_cfg.rangeset[0] loterry_hero_count += 1 logger.debug( '\nused_free_count_A: {},\ \nused_free_count_B: {},\ \nused_free_count_C: {},\ \nused_free_count_D: {}'.format( p.loterry_hero_used_free_count_A, p.loterry_hero_used_free_count_B, p.loterry_hero_used_free_count_C, p.loterry_hero_used_free_count_D)) logger.debug('loterry_hero_key: {}'.format(key)) costs = {} if "Free" in key: cost = 0 loterry_hero_used_free_count += 1 loterry_hero_cd = now + kind_cfg.ColdDown else: costs = {cost_type: cost} if p.lottery_campaign_discount < 10: gold = costs.get("gold", 0) if gold: gold = int(gold * p.lottery_campaign_discount / float(10)) costs["gold"] = gold try: from reward.base import check_cost_attr check_cost_attr(p, costs) except AttrNotEnoughError: return fail_msg(msgtype, reason="材料不足") loterry_hero_gold_first = False if not ID: ID = kind_cfg.rangeset[0] attr_drop = get_config(AttributeDroppackConfig)[ID] dropID = attr_drop.RewardDroppack if cost_type == "gold": if cost_count > 1: if p.lottery_gold_accumulating10 >= abs( attr_drop.Accumulating): dropID = attr_drop.AccumDroppack if attr_drop.Accumulating > 0: p.lottery_gold_accumulating10 -= attr_drop.Accumulating else: if p.lottery_gold_accumulating >= abs( attr_drop.Accumulating): dropID = attr_drop.AccumDroppack if attr_drop.Accumulating > 0: p.lottery_gold_accumulating -= attr_drop.Accumulating else: if cost_count > 1: if p.lottery_money_accumulating10 >= abs( attr_drop.Accumulating): dropID = attr_drop.AccumDroppack if attr_drop.Accumulating > 0: p.lottery_money_accumulating10 -= \ attr_drop.Accumulating else: if p.lottery_money_accumulating >= abs( attr_drop.Accumulating): dropID = attr_drop.AccumDroppack if attr_drop.Accumulating > 0: p.lottery_money_accumulating -= attr_drop.Accumulating logger.debug("DropID:{}".format(dropID)) rsp = poem_pb.LotteryResponse() reward = open_reward(RewardType.Lottery, rsp, dropID, cost_count) from campaign.manager import g_campaignManager if g_campaignManager.hot_lottery_campaign.is_open() and\ req.type == LotteryType.Lottery4: campaign_config = g_campaignManager.hot_lottery_campaign.\ get_current() hot_configs = get_config(HotLotteryCampaignConfig).get( campaign_config.group, []) hot_rewards = weighted_random2([ [i.rewards, i.prob] for i in hot_configs]) reward.add(parse_reward(hot_rewards)) rsp.hot_rewards = hot_rewards reward.cost_after(p, **costs) extra = {} result = reward.apply(p, extra=extra) logger.debug("result {}:".format(result)) # Save setattr( p, "loterry_hero_count_{}".format(kind), loterry_hero_count) setattr( p, "loterry_hero_gold_first_{}".format(kind), loterry_hero_gold_first) setattr( p, "loterry_hero_used_free_count_{}".format(kind), loterry_hero_used_free_count) setattr( p, "loterry_hero_cd_{}".format(kind), loterry_hero_cd) is_first_consume = int(not p.consume_count and bool( p.lottery_count) and (cost_type == "gold")) role_custom.info(player=p, type=role_custom.Consume, arg1=ujson.dumps({ "type": RewardType.Lottery, "kind": req.type, "cost": costs, "is_first_consume": is_first_consume, })) p.lottery_count += cost_count from task.manager import on_lottery on_lottery(p, cost_count, (cost_type == "gold")) if kind == "D": from task.manager import on_lottery10 on_lottery10(p) ACCUMULATING_DELTA = 1 if cost_type == "gold": if cost_count > 1: p.lottery_gold_accumulating10 += \ ACCUMULATING_DELTA * kind_cfg.Price else: p.lottery_gold_accumulating += \ ACCUMULATING_DELTA * kind_cfg.Price p.consume_count += 1 else: if cost_count > 1: p.lottery_money_accumulating10 += \ ACCUMULATING_DELTA * kind_cfg.Price else: p.lottery_money_accumulating += \ ACCUMULATING_DELTA * kind_cfg.Price if "FirstFree" not in key: save_guide(p, "FAKE_GOLDEN_LOTTERY") from task.manager import on_collect_pet1 from task.manager import on_collect_pet2 pets = extra.get("pets", []) on_collect_pet1(p, *pets) on_collect_pet2(p, *pets) p.save() p.sync() from chat.manager import on_news_pet_quality_lottery from chat.manager import on_news_pet_special_lottery from chat.manager import on_news_equip_quality_lottery on_news_pet_quality_lottery(p, rsp.rewards) on_news_pet_special_lottery(p, rsp.rewards) on_news_equip_quality_lottery(p, rsp.rewards) return success_msg(msgtype, rsp)
def battle(self, p, fight, rsp): treasures = get_config(CityTreasureConfig) self_message = "" full_message = "" red_message = "" red_count = 0 horn = False target = p.city_contend_cache_target if self.is_top_faction(p.factionID): message_configs = get_config(CityContendDefendMessageConfig) message_config = message_configs.get(p.city_contend_count) if not message_config: message_config = message_configs[max(message_configs)] if fight.fightResult: event = self.get_current_step(p) drop = event["argv"] reward = open_reward(RewardType.CityContendDefend, drop) rewards = reward.apply(p) combine_reward(rewards, {}, p.city_contend_rewards) try: target_name = target.get("name", u"").decode("utf-8") target_faction_name = (target.get( "faction_name", u"") or u"").decode("utf-8") except UnicodeEncodeError: target_name = target.get("name", u"") target_faction_name = target.get("faction_name", u"") self_message = message_config.single_defend_win_desc.format( target_faction_name, target_name ) # {{ 使用每日PVP for each in fight.player_team: pet = p.pets[each.entityID] if each.restHP == 0: pet.daily_dead = True else: pet.daily_restHP = each.restHP pet.save() pet.sync() # }} rsp.rewards = build_reward(rewards) else: sub = p.city_contend_treasure * get_cons_value( "CityContendFailPunish") / float(100) p.city_contend_treasure = max( p.city_contend_treasure - sub, 1) # {{ 每日PVP now = int(time.time()) p.daily_dead_cd = now + get_cons_value("DailyDeadCD") # }} try: target_name = target.get("name", u"").decode("utf-8") target_faction_name = (target.get( "faction_name", u"") or u"").decode("utf-8") except UnicodeEncodeError: target_name = target.get("name", u"") target_faction_name = target.get("faction_name", u"") self_message = message_config.single_defend_lose_desc.format( target_faction_name, target_name ) module = RedModuleType.CityContendDefend else: message_configs = get_config(CityContendAttackMessageConfig) message_config = message_configs.get(p.city_contend_count + 1) if not message_config: message_config = message_configs[max(message_configs)] if fight.fightResult: p.city_contend_count += 1 self_count = CityContendAttackRanking.update_score( p.entityID, p.city_contend_count) count = CityContendAttackRanking.pool.execute( "ZCOUNT", CityContendAttackRanking.key, self_count, "+inf") CityContendFactionRanking.incr_score( p.factionID, 1) treasure = treasures.get( p.city_contend_cache_target.get("level", 1)) if not treasure: treasure = treasures[max(treasures)] money = treasure.attack_treasure * get_cons_value( "CityContendAttackMoney") soul = treasure.attack_treasure * get_cons_value( "CityContendAttackSoul") event = self.get_current_step(p) drop = event["argv"] gain = {"money": money, "soul": soul} reward = open_reward( RewardType.CityContendAttack, drop ) drop_reward = reward.apply_after() total_reward = apply_reward( p, combine_reward(gain, drop_reward), type=RewardType.CityContendAttack) combine_reward(total_reward, {}, p.city_contend_rewards) p.city_contend_total_treasure += treasure.attack_treasure rsp.rewards = build_reward(drop_reward) rsp.treasure_rewards = build_reward(gain) rsp.treasure_count = treasure.attack_treasure if not message_config.multiple1 or message_config.multiple1 \ and count == 1: full_message = message_config.attack_count_desc.format( p.faction_name, p.name, p.city_contend_count ) horn = message_config.horn1 try: target_name = target.get("name", u"").decode("utf-8") except UnicodeEncodeError: target_name = target.get("name", u"") self_message = message_config.single_attack_win_desc.format( target_name ) if not message_config.multiple2 or message_config.multiple2 \ and count == 1: red_count = message_config.red_paper_count red_drop = message_config.red_paper red_message = message_config.red_paper_desc.format( p.faction_name, p.name, p.city_contend_count, red_count ) # {{ 使用每日PVP for each in fight.player_team: pet = p.pets[each.entityID] if each.restHP == 0: pet.daily_dead = True else: pet.daily_restHP = each.restHP pet.save() pet.sync() # }} else: # {{ 每日PVP now = int(time.time()) p.daily_dead_cd = now + get_cons_value("DailyDeadCD") # }} # FIXME try: target_name = target.get("name", u"").decode("utf-8") except UnicodeEncodeError: target_name = target.get("name", u"") self_message = message_config.single_attack_lose_desc.format( target_name ) module = RedModuleType.CityContendAttack if self_message: g_redManager.send_red_message( p, self_message, to_self=True, module=module) if full_message: _type = RedType.Horn if horn else RedType.Normal g_redManager.send_red_message( p, full_message, type=_type, module=module) if red_message and red_count: g_redManager.send_red_message( p, red_message, red_drop=red_drop, red_count=red_count, type=RedType.Red, module=module) p.save() p.sync()
def flowerboss_friendfb_end(self, msgtype, body): p = self.player req = poem_pb.EndFriendfb() req.ParseFromString(body) if not PlayerFightLock.unlock(p.entityID, req.verify_code): return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) assert p.cache_friendfbID, "impossible" from campaign.manager import g_campaignManager flower_boss_friendfbID = "bosscampaign:%d" % g_campaignManager.flower_boss_campaign.flower_boss_config_id if p.cache_friendfbID != flower_boss_friendfbID: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) rsp = poem_pb.EndFriendfbResponse() try: createtime, hp, fbID = simple_load_friendfb( p.cache_friendfbID, 'createtime', 'hp', 'fbID') except DoesNotExistsException: error_code = msgTips.FAIL_MSG_FRIENDFB_ALREADY_DISAPPEARED else: if hp <= 0: error_code = msgTips.FAIL_MSG_FRIENDFB_ALREADY_DEAD # return fail_msg(msgtype, reason='BOSS已经被击杀了') else: from pvp.manager import send_fight_verify from fightverifier.direct_verifier import verify send_fight_verify(p, req.fight) if not verify(p, req.fight): return fail_msg(msgtype, msgTips.FAIL_MSG_FIGHT_VERIFY_FAILED) error_code = 0 now = int(time.time()) if if_boss(p.cache_friendfbID) and\ not if_boss_campaign_opened(p.cache_friendfbID) or \ not if_boss(p.cache_friendfbID) and \ now > createtime + FRIENDFB_INTERVAL: error_code = msgTips.FAIL_MSG_FRIENDFB_ALREADY_DISAPPEARED # NOQA else: damage = max(req.fight.total_damage or 0, 0) info = get_config(FriendfbConfig)[fbID] if info.drop: from config.configs import HandselMulRewardConfig mr_configs = get_config(HandselMulRewardConfig) mr_id = g_campaignManager.flower_boss_campaign.get_mulreward_id( ) mr_config = mr_configs[mr_id] mr = mr_config.mulreward import math r = open_reward(RewardType.Flower315Campaign, info.drop, int(math.ceil(mr * damage))) result = r.apply(p) build_reward_msg(rsp, result) start_time, end_time = g_campaignManager.flower_boss_campaign.get_current_time( ) if p.flower_boss_campaign_last_time < start_time or p.flower_boss_campaign_last_time > end_time: p.flower_boss_campaign_total_hurt = 0 p.flower_boss_campaign_total_hurt += damage p.flower_boss_campaign_last_time = now hp = hurt_boss(p, fbID, p.cache_friendfbID, damage) if hp <= 0: if if_boss(p.cache_friendfbID): # 提前发奖 bc = get_boss_campaign(p.cache_friendfbID) proxy.notify_boss_campaign_end(bc.config.ID) entityID = bc.get_by_rank(1) proxy.sync_on_task_change(entityID, TaskCond.FriendfbFirst, p.cache_friendfbID) else: give_reward(p.cache_friendfbID) on_friendfb_count(p, fbID) else: p.friendfb_deads.add(p.cache_friendfbID) p.friendfb_deadtimes[fbID] = now p.friendfb_buff = 0 p.save() p.sync() rsp.error_code = error_code return success_msg(msgtype, rsp)
def uproar_forward(p): """匹配玩家""" configs = get_config(UproarConfig) ranking = PlayerPowerRanking # 前 10 级宝箱未领取完不处理 if max(p.uproar_chests_done | set([0])) < 10: return # 检查等级限制 level = get_config(LevelupConfig).get(p.level, None) if level and not level.uproar: return # 战力向下浮动 20% 取玩家 if p.uproar_enemy_min_power == 0: p.uproar_enemy_min_power = p.max_power - (p.max_power * 0.3) current_floor = max(p.uproar_targets_done | set([0])) if current_floor == 10: # 通关前 10 首次匹配 p.uproar_targets.clear() p.uproar_chests.clear() map(p.uproar_targets.pop, p.uproar_targets.keys()) map(p.uproar_chests.pop, p.uproar_chests.keys()) targets = ranking.get_by_score_range(p.uproar_enemy_min_power, '+inf', desc=False, limit=15) if len(targets): p.uproar_enemy_min_power = targets[-1][1] else: # 匹配不到重复第一名 target = ranking.get_by_rank(1) power = ranking.get_score(target) targets = [(target, power)] # NOTE 假数据 while len(targets) < 15: targets.append(targets[-1]) logger.debug('enter uproar no limit mode') config = configs.values()[-1] for n, (target, power) in enumerate(targets, start=11): p.uproar_targets[n] = target money = int(p.level * (config.money_base + random.randint(0, 10))) must = {'jiutian': config.jiutian, 'money': money} reward = open_reward(RewardType.Uproar, config.dropID, {}) drop = reward.apply_after() p.uproar_chests[n] = {"must": must, "drop": drop} p.uproar_details_cache.clear() p.uproar_targets_team.clear() else: # 保留三个已通关历史 logger.debug('uproar forward') prev = set(sorted(p.uproar_targets.keys())[:6]) if prev & p.uproar_targets_done == prev: limit = 3 targets = ranking.get_by_score_range(p.uproar_enemy_min_power, '+inf', desc=False, limit=limit) if len(targets): p.uproar_enemy_min_power = targets[-1][1] else: # 匹配不到重复第一名 target = ranking.get_by_rank(1) power = ranking.get_score(target) targets = [(target, power)] * limit # 删除前三个,再补三个 droped = min(len(targets), limit) to_drop = sorted(list(prev))[:droped] for k in to_drop: p.uproar_details_cache.pop(p.uproar_targets[k], None) p.uproar_targets_team.pop(p.uproar_targets[k], None) map(p.uproar_targets.pop, to_drop) start = max(p.uproar_targets.keys()) + 1 config = configs.values()[-1] for n, (target, power) in enumerate(targets, start=start): p.uproar_targets[n] = target money = int(p.level * (config.money_base + random.randint(0, 10))) must = {'jiutian': config.jiutian, 'money': money} reward = open_reward(RewardType.Uproar, config.dropID, {}) drop = reward.apply_after() p.uproar_chests[n] = {"must": must, "drop": drop} for targetID in p.uproar_targets.values(): if targetID > 0: target = get_detail(targetID) if target: p.uproar_details_cache[targetID] = target for pet in p.pets.values(): if pet.uproar_dead: pet.uproar_dead = False pet.restHP = 0 pet.save() pet.sync() # 打过了第一名,每一关敌方属性加成 10% last_target = p.last_target in p.uproar_targets first = ranking.get_by_rank(1) if last_target and p.uproar_targets[p.last_target] == first: p.uproar_enemy_buff += 10 p.save() p.sync()
def battle(self, p, targetID, fight, raw, rsp): target_win_count = 0 # 对手连胜次数 max_win_count = 0 history = None # 战斗记录 shutdown = False self_message = "" full_message = "" horn = False red_message = "" red_count = 0 self_shutdown_message = "" full_shutdown_message = "" peer_shutdown_message = "" count = 0 rsp.before_daily_win_count = p.daily_win_count if fight.fightResult: # 胜利 # 终结对手连胜 target_win_count = int(self.pool.execute( "GETSET", "daily_win_count_p{%d}" % targetID, 0) or 0) self.pool.execute("SET", "daily_dead_p{%d}" % targetID, 1) # 添加自己连胜 daily_win_count = int(self.pool.execute( "INCRBY", "daily_win_count_p{%d}" % p.entityID, 1) or 0) p.clear_daily_win_count() # 更新最大连胜次数 if p.daily_win_count > p.daily_max_win_count: p.daily_max_win_count = p.daily_win_count count = update_daily_rank( PlayerDailyRankRanking, p.entityID, p.daily_max_win_count) # PlayerDailyRankRanking.update_score( # p.entityID, p.daily_max_win_count) # 连胜任务 from task.manager import on_dailypvp_count on_dailypvp_count(p, p.daily_max_win_count) # 取全服最大次数 top = PlayerDailyRankRanking.get_range_by_score( "-inf", "+inf", withscores=True, count=1) if top: max_win_count = top[1] rsp.max_win_count = max_win_count daily_win_config = get_config(DailyWinConfig).get( p.daily_win_count) if not daily_win_config and \ p.daily_win_count > max(get_config(DailyWinConfig)): daily_win_config = get_config( DailyWinConfig)[max(get_config(DailyWinConfig))] if daily_win_config: if not daily_win_config.multiple or ( daily_win_config.multiple and count == 1): self_message = daily_win_config.single_desc full_message = daily_win_config.all_desc horn = daily_win_config.horn if daily_win_config.red_paper: red_message = daily_win_config.red_paper_desc red_count = daily_win_config.red_paper_count red_drop = daily_win_config.red_paper daily_lose_config = get_config(DailyLoseConfig).get( target_win_count) if not daily_lose_config and \ target_win_count > max(get_config(DailyLoseConfig)): daily_lose_config = get_config( DailyLoseConfig)[max(get_config(DailyLoseConfig))] if daily_lose_config: self_shutdown_message = daily_lose_config.single_win_desc peer_shutdown_message = daily_lose_config.single_lose_desc full_shutdown_message = daily_lose_config.all_desc # 增加胜利次数 p.daily_kill_count += 1 # 奖励加成系数 multi = min(40, 2 * daily_win_count) + min( 80, target_win_count * 4) shutdown = target_win_count > 2 history = { "active": False, "name": p.name, "win": not fight.fightResult, "faction_name": p.faction_name, "daily_win_count": p.daily_win_count, "fight": raw.encode("base64"), "prototypeID": p.prototypeID, "borderID": p.borderID, "shutdown": shutdown} for each in fight.player_team: pet = p.pets[each.entityID] if each.restHP == 0: pet.daily_dead = True else: pet.daily_restHP = each.restHP pet.save() pet.sync() else: if not p.daily_rank: PlayerDailyRankRanking.update_score( p.entityID, p.daily_max_win_count) # 自己连胜被终结 daily_win_count = int(self.pool.execute( "GETSET", "daily_win_count_p{%d}" % p.entityID, 0) or 0) # 死亡 self.pool.execute("SET", "daily_dead_p{%d}" % p.entityID, 1) p.clear_daily_win_count() # 奖励加成系数 multi = 0 daily_lose_config = get_config(DailyLoseConfig).get( daily_win_count) if not daily_lose_config and \ daily_win_count > max(get_config(DailyLoseConfig)): daily_lose_config = get_config( DailyLoseConfig)[max(get_config(DailyLoseConfig))] if daily_lose_config: self_shutdown_message = daily_lose_config.single_lose_desc peer_shutdown_message = daily_lose_config.single_win_desc full_shutdown_message = daily_lose_config.all_desc # 取对手数据 data = g_entityManager.get_players_info( [targetID], [ "entityID", "name", "daily_win_count", "faction_name", "prototypeID", "borderID"])[0] # 终结连胜 shutdown = target_win_count > 2 data.update({ "active": True, "shutdown": shutdown, "win": fight.fightResult, "fight": raw.encode("base64") }) # 自己的战斗记录 p.daily_histories.appendleft(data) p.daily_histories.ltrim(0, MAX_HIST_LEN - 1) # 更新排名 p.daily_rank = PlayerDailyRankRanking.get_rank(p.entityID) rewards = {} reward = open_reward( RewardType.DailyPVP, get_cons_value("DailyPVPDrop")) rewards = reward.apply_after() # 奖励加成 if multi: for k, v in rewards.items(): if isinstance(v, int) and k != 'exp': rewards[k] = int(v * (100 + multi) / float(100)) # 记录累计奖励 apply_reward(p, rewards, type=RewardType.DailyPVP) combine_reward(rewards, [], data=p.daily_rewards) p.daily_rewards = dict(p.daily_rewards) p.daily_count += 1 p.daily_cache_targetID = 0 p.save() p.sync() # 添加直播 self.add_live({ "self_name": p.name, "self_prototypeID": p.prototypeID, "self_borderID": p.borderID, "peer_name": data["name"], "peer_prototypeID": data["prototypeID"], "peer_borderID": data["borderID"], "is_win": fight.fightResult, }, top=p.daily_rank and p.daily_rank <= 5) rsp.daily_win_count = p.daily_win_count rsp.rewards = build_reward(rewards) if self_message: self_message = self_message.format(data["name"], p.daily_win_count) g_redManager.send_red_message( p, self_message, to_self=True, type=RedType.Normal) if full_message: full_message = full_message.format( p.name, data["name"], p.daily_win_count) _type = RedType.Horn if horn else RedType.Normal g_redManager.send_red_message( p, full_message, type=_type) if red_count and red_message: if daily_win_count == 1: red_message = red_message.format( p.name, red_count) else: red_message = red_message.format( p.name, daily_win_count, red_count) g_redManager.send_red_message( p, red_message, red_drop=red_drop, red_count=red_count, type=RedType.Red) if full_shutdown_message: if fight.fightResult: full_shutdown_message = full_shutdown_message.format( p.name, data["name"], target_win_count) else: full_shutdown_message = full_shutdown_message.format( data["name"], p.name, daily_win_count) _type = RedType.Horn if horn else RedType.Normal g_redManager.send_red_message( p, full_shutdown_message, type=_type) if fight.fightResult: if self_shutdown_message: self_shutdown_message = self_shutdown_message.format( data["name"], target_win_count) g_redManager.send_red_message( p.entityID, self_shutdown_message, to_self=True, type=RedType.Normal) if peer_shutdown_message: peer_shutdown_message = peer_shutdown_message.format( p.name, target_win_count) g_redManager.send_red_message( data["entityID"], peer_shutdown_message, to_self=True, type=RedType.Normal) else: if self_shutdown_message: self_shutdown_message = self_shutdown_message.format( data["name"], daily_win_count) g_redManager.send_red_message( p.entityID, self_shutdown_message, to_self=True, type=RedType.Normal) if peer_shutdown_message: peer_shutdown_message = peer_shutdown_message.format( p.name, daily_win_count) g_redManager.send_red_message( data["entityID"], peer_shutdown_message, to_self=True, type=RedType.Normal) proxy.sync_daily_rank(targetID, history) return rewards