def reset(signum): logger = Logger("reset_union_boss.log") logger.write("Start") try: MongoUnionBoss.drop_collection() except: logger.error(traceback.format_exc()) else: logger.write("Rest Complete.") finally: logger.close()
def load_data(self): try: self.mongo_boss = MongoUnionBoss.objects.get(id=self.union.union_id) except DoesNotExist: self.mongo_boss = MongoUnionBoss(id=self.union.union_id) self.mongo_boss.opened = {} self.mongo_boss.save()
def load_data(self): try: self.mongo_boss = MongoUnionBoss.objects.get(id=self.union.union_id) except DoesNotExist: self.mongo_boss = MongoUnionBoss(id=self.union.union_id) self.mongo_boss.save() self.union_member = UnionMember(self.char_id)
class UnionBoss(UnionLoadBase): def __init__(self, char_id): super(UnionBoss, self).__init__(char_id) if self.valid: self.load_data() def load_data(self): try: self.mongo_boss = MongoUnionBoss.objects.get(id=self.union.union_id) except DoesNotExist: self.mongo_boss = MongoUnionBoss(id=self.union.union_id) self.mongo_boss.save() self.union_member = UnionMember(self.char_id) @property def valid(self): return self.union is not None @property def max_times(self): return 3 @property def cur_times(self): return self.union_member.mongo_union_member.boss_times def incr_battle_times(self): self.union_member.mongo_union_member.boss_times += 1 self.union_member.mongo_union_member.save() @_union_manager_check(True, errormsg.UNION_NOT_EXIST, "UnionBoss Start", "has no union") def start(self, boss_id): try: boss = UNION_BOSS[boss_id] except KeyError: raise SanguoException( errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Start", "boss {0} not exist".format(boss_id) ) if not self.union.belong_to_self: raise SanguoException( errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Start", "{0} not union owner".format(self.char_id) ) if self.union.mongo_union.level < boss.union_level: raise SanguoException( errormsg.UNION_BOSS_LEVEL_NOT_ENOUGH, self.char_id, "UnionBoss Start", "union level not enough. {0} < {1}".format(self.union.mongo_union.level, boss.union_level) ) meb = MongoEmbeddedUnionBoss() meb.start_at = arrow.utcnow().timestamp meb.hp = boss.hp meb.killer = 0 meb.logs = [] self.mongo_boss.opened[str(boss_id)] = meb self.mongo_boss.save() @_union_manager_check(True, errormsg.UNION_NOT_EXIST, "UnionBoss Battle", "ha no union") def battle(self, boss_id): try: this_boss = self.mongo_boss.opened[str(boss_id)] except KeyError: raise SanguoException( errormsg.UNION_BOSS_NOT_STARTED, self.char_id, "UnionBoss Battle", "boss not started {0}".format(boss_id) ) if this_boss.hp <= 0: raise SanguoException( errormsg.UNION_BOSS_DEAD, self.char_id, "UnionBoss Battle", "boss dead {0}".format(boss_id) ) # TODO boss times limit msg = protomsg.Battle() battle = UnionBossBattle(self.char_id, boss_id, msg, this_boss.hp) remained_hp = battle.start() if remained_hp == 0: killer = self.char_id else: killer = 0 this_boss.hp = remained_hp this_boss.killer = killer eubl = MongoEmbeddedUnionBossLog() eubl.char_id = self.char_id eubl.damage = battle.get_total_damage() this_boss.logs.append(eubl) self.mongo_boss.save() self.incr_battle_times() self.after_battle(eubl.damage) if killer: self.boss_has_been_killed(boss_id) return msg def after_battle(self, damage): # 每次打完给予奖励 member = UnionMember(self.char_id) # FIXME member.add_coin(10, send_notify=False) member.add_contribute_points(10, send_notify=True) self.union.add_contribute_points(10) def boss_has_been_killed(self, boss_id): # 击杀boss后发送奖励 logs = self.get_battle_members_in_ordered(boss_id) member_ids = [log.char_id for log in logs] killer = self.mongo_boss.opened[str(boss_id)].killer m = Mail(killer) drop = make_standard_drop_from_template() drop['union_coin'] = UNION_BOSS_KILLER_REWARD.coin m.add( UNION_BOSS_KILLER_REWARD.mail_title, UNION_BOSS_KILLER_REWARD.mail_content, attachment=json.dumps(drop) ) LOWEST_RANK = max(UNION_BOSS_REWARD.keys()) UNION_BOSS_REWARD_TUPLE = UNION_BOSS_REWARD.items().sort(key=lambda item: item[0]) for index, mid in enumerate(member_ids): rank = index + 1 if rank > LOWEST_RANK: break m = Mail(mid) for _rank, _reward in UNION_BOSS_REWARD_TUPLE: if _rank >= rank: drop = make_standard_drop_from_template() drop['union_coin'] = _reward.coin m.add( _reward.mail_title.format(rank), _reward.mail_content.format(rank), attachment=json.dumps(drop) ) break # 工会获得贡献度 self.union.add_contribute_points(UNION_BOSS[boss_id].contribute_points) def get_battle_members_in_ordered(self, boss_id): this_boss = self.mongo_boss.opened[str(boss_id)] return sorted(this_boss.logs, key=lambda item: -item.damage) @_union_manager_check(True, errormsg.UNION_NOT_EXIST, "UnionBoss Get Log", "has no union") def make_log_message(self, boss_id): try: this_boss = self.mongo_boss.opened[str(boss_id)] except KeyError: raise SanguoException( errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Get Log", "no log for boss {0}".format(boss_id) ) hp = float(UNION_BOSS[boss_id].hp) msg = protomsg.UnionBossGetLogResponse() msg.ret = 0 msg.boss_id = boss_id for log in self.get_battle_members_in_ordered(boss_id): msg_log = msg.logs.add() msg_log.char_id = log.char_id msg_log.char_name = Char(log.char_id).mc.name msg_log.damage = log.damage msg_log.precent = int(log.damage/hp * 100) if this_boss.hp <= 0: this_boss.killer.MergeFrom(msg.logs[-1]) return msg @_union_manager_check(True, errormsg.UNION_NOT_EXIST, "UnionBoss Response", "has no union") def make_boss_response(self): msg = protomsg.UnionBossResponse() msg.ret = 0 msg.remained_times = self.max_times - self.cur_times union_level = self.union.mongo_union.level available_bosses = [k for k, v in UNION_BOSS.items() if union_level >= v.union_level] for b in available_bosses: msg_boss = msg.bosses.add() msg_boss.id = b if str(b) not in self.mongo_boss.opened: msg_boss.hp = UNION_BOSS[b].hp msg_boss.status = protomsg.UnionBossResponse.Boss.INACTIVE else: this_boss = self.mongo_boss.opened[str(b)] msg_boss.hp = this_boss.hp if this_boss.hp <= 0: msg_boss.status = protomsg.UnionBossResponse.Boss.DEAD else: msg_boss.status = protomsg.UnionBossResponse.Boss.ACTIVE return msg
class UnionBoss(UnionLoadBase): def __init__(self, char_id): super(UnionBoss, self).__init__(char_id) if isinstance(self.union, UnionBase): self.load_data() self.member = Member(self.char_id) def load_data(self): try: self.mongo_boss = MongoUnionBoss.objects.get(id=self.union.union_id) except DoesNotExist: self.mongo_boss = MongoUnionBoss(id=self.union.union_id) self.mongo_boss.opened = {} self.mongo_boss.save() @property def max_times(self): return 3 @property def cur_times(self): return self.member.mongo_union_member.boss_times def incr_battle_times(self): self.member.mongo_union_member.boss_times += 1 self.member.mongo_union_member.save() @union_instance_check(UnionOwner, errormsg.UNION_BOSS_ONLY_OPENED_BY_OWNER, "UnionBoss Start", "not owner") def start(self, boss_id): try: boss = UNION_BOSS[boss_id] except KeyError: raise SanguoException( errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Start", "boss {0} not exist".format(boss_id) ) if self.union.mongo_union.level < boss.union_level: raise SanguoException( errormsg.UNION_BOSS_LEVEL_NOT_ENOUGH, self.char_id, "UnionBoss Start", "union level not enough. {0} < {1}".format(self.union.mongo_union.level, boss.union_level) ) meb = MongoEmbeddedUnionBoss() meb.start_at = arrow.utcnow().timestamp meb.hp = boss.hp meb.logs = [] self.mongo_boss.opened[str(boss_id)] = meb self.mongo_boss.save() @union_instance_check(UnionBase, errormsg.UNION_NOT_EXIST, "UnionBoss Battle", "has no union") def battle(self, boss_id): try: this_boss = self.mongo_boss.opened[str(boss_id)] except KeyError: raise SanguoException( errormsg.UNION_BOSS_NOT_STARTED, self.char_id, "UnionBoss Battle", "boss not started {0}".format(boss_id) ) if self.cur_times >= self.max_times: raise SanguoException( errormsg.UNION_BOSS_NO_TIMES, self.char_id, "UnionBoss Battle", "no times" ) for i in range(5): self.load_data() this_boss = self.mongo_boss.opened[str(boss_id)] if this_boss.lock: time.sleep(0.2) else: this_boss.lock = True self.mongo_boss.save() break else: raise SanguoException( errormsg.UNION_BOSS_LOCKED, self.char_id, "UnionBoss Battle", "boss locked {0}".format(boss_id) ) if this_boss.hp <= 0: this_boss.lock = False self.mongo_boss.save() raise SanguoException( errormsg.UNION_BOSS_DEAD, self.char_id, "UnionBoss Battle", "boss dead {0}".format(boss_id) ) msg = protomsg.Battle() try: battle = UnionBossBattle(self.char_id, boss_id, msg, this_boss.hp) remained_hp = battle.start() damage = battle.get_total_damage() this_boss.hp = remained_hp if remained_hp <= 0: this_boss.killer = self.char_id finally: this_boss.lock = False self.mongo_boss.save() self.save_battle_log(this_boss, damage) self.incr_battle_times() drop_msg = self.after_battle(boss_id, damage, remained_hp<=0) if remained_hp <= 0: self.boss_has_been_killed(boss_id) self.mongo_boss.save() return msg, drop_msg def save_battle_log(self, this_boss, damage): for log in this_boss.logs: if log.char_id == self.char_id: log.damage += damage break else: boss_log = MongoEmbeddedUnionBossLog() boss_log.char_id = self.char_id boss_log.damage = damage this_boss.logs.append(boss_log) def after_battle(self, boss_id, damage, kill=False): # 每次打完给予奖励 member = Member(self.char_id) boss = UNION_BOSS[boss_id] contribute_points = int( float(damage)/boss.hp * boss.contribute_points ) lowest = 1 highest = int(boss.contribute_points * 0.05) if contribute_points < lowest: contribute_points = lowest if contribute_points > highest: contribute_points = highest coin = 9 + contribute_points member.add_coin(coin, send_notify=False) member.add_contribute_points(contribute_points, send_notify=True) if not kill: self.union.add_contribute_points(contribute_points) drop = make_standard_drop_from_template() drop['union_coin'] = coin drop['union_contribute_points'] = contribute_points return standard_drop_to_attachment_protomsg(drop) def boss_has_been_killed(self, boss_id): # 击杀boss后发送奖励 logs = self.get_battle_members_in_ordered(boss_id) member_ids = [log.char_id for log in logs] killer = self.char_id m = Mail(killer) drop = make_standard_drop_from_template() drop['union_coin'] = UNION_BOSS_KILLER_REWARD.coin m.add( UNION_BOSS_KILLER_REWARD.mail_title, UNION_BOSS_KILLER_REWARD.mail_content, attachment=json.dumps(drop) ) LOWEST_RANK = max(UNION_BOSS_REWARD.keys()) UNION_BOSS_REWARD_TUPLE = UNION_BOSS_REWARD.items() UNION_BOSS_REWARD_TUPLE.sort(key=lambda item: item[0]) for index, mid in enumerate(member_ids): rank = index + 1 if rank > LOWEST_RANK: break m = Mail(mid) for _rank, _reward in UNION_BOSS_REWARD_TUPLE: if _rank >= rank: drop = make_standard_drop_from_template() drop['union_coin'] = _reward.coin m.add( _reward.mail_title.format(rank), _reward.mail_content.format(rank), attachment=json.dumps(drop) ) break # 工会获得贡献度 self.union.add_contribute_points(UNION_BOSS[boss_id].contribute_points) def get_battle_members_in_ordered(self, boss_id): this_boss = self.mongo_boss.opened[str(boss_id)] return sorted(this_boss.logs, key=lambda item: -item.damage) @union_instance_check(UnionBase, errormsg.UNION_NOT_EXIST, "UnionBoss Get Log", "has no union") def make_log_message(self, boss_id): try: this_boss = self.mongo_boss.opened[str(boss_id)] except KeyError: raise SanguoException( errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Get Log", "no log for boss {0}".format(boss_id) ) hp = float(UNION_BOSS[boss_id].hp) msg = protomsg.UnionBossGetLogResponse() msg.ret = 0 msg.boss_id = boss_id logs = [] for log in self.get_battle_members_in_ordered(boss_id): msg_log = protomsg.UnionBossGetLogResponse.BossLog() msg_log.char_id = log.char_id msg_log.char_name = Char(log.char_id).mc.name msg_log.damage = log.damage msg_log.precent = int(log.damage/hp * 100) logs.append(msg_log) if this_boss.killer: for log in logs: if log.char_id == this_boss.killer: msg.killer.MergeFrom(log) break for log in logs[:UNION_BOSS_REWARD_LOWEST_RANK]: msg_log = msg.logs.add() msg_log.MergeFrom(log) return msg @union_instance_check(UnionBase, errormsg.UNION_NOT_EXIST, "UnionBoss Response", "has no union") def make_boss_response(self): union_level = self.union.mongo_union.level msg = protomsg.UnionBossResponse() if not UNION_LEVEL[union_level].union_boss_open: msg.ret = errormsg.UNION_BOSS_FREEZE return msg msg.ret = 0 msg.remained_times = self.max_times - self.cur_times available_bosses = [k for k, v in UNION_BOSS.items() if union_level >= v.union_level] for b in available_bosses: msg_boss = msg.bosses.add() msg_boss.id = b if str(b) not in self.mongo_boss.opened: msg_boss.hp = UNION_BOSS[b].hp msg_boss.status = protomsg.UnionBossResponse.Boss.INACTIVE else: this_boss = self.mongo_boss.opened[str(b)] msg_boss.hp = this_boss.hp if this_boss.hp <= 0: msg_boss.status = protomsg.UnionBossResponse.Boss.DEAD else: msg_boss.status = protomsg.UnionBossResponse.Boss.ACTIVE return msg
class UnionBoss(UnionLoadBase): def __init__(self, char_id): super(UnionBoss, self).__init__(char_id) if isinstance(self.union, UnionBase): self.load_data() self.member = Member(self.char_id) def load_data(self): try: self.mongo_boss = MongoUnionBoss.objects.get( id=self.union.union_id) except DoesNotExist: self.mongo_boss = MongoUnionBoss(id=self.union.union_id) self.mongo_boss.opened = {} self.mongo_boss.save() @property def max_times(self): return 3 @property def cur_times(self): return self.member.mongo_union_member.boss_times def incr_battle_times(self): self.member.mongo_union_member.boss_times += 1 self.member.mongo_union_member.save() @union_instance_check(UnionOwner, errormsg.UNION_BOSS_ONLY_OPENED_BY_OWNER, "UnionBoss Start", "not owner") def start(self, boss_id): if str(boss_id) in self.mongo_boss.opened: return try: boss = UNION_BOSS[boss_id] except KeyError: raise SanguoException(errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Start", "boss {0} not exist".format(boss_id)) if self.union.mongo_union.level < boss.union_level: raise SanguoException( errormsg.UNION_BOSS_LEVEL_NOT_ENOUGH, self.char_id, "UnionBoss Start", "union level not enough. {0} < {1}".format( self.union.mongo_union.level, boss.union_level)) meb = MongoEmbeddedUnionBoss() meb.start_at = arrow.utcnow().timestamp meb.hp = boss.hp meb.logs = [] self.mongo_boss.opened[str(boss_id)] = meb self.mongo_boss.save() @union_instance_check(UnionBase, errormsg.UNION_NOT_EXIST, "UnionBoss Battle", "has no union") def battle(self, boss_id): try: with Lock('union_boss_battle').lock(): self.load_data() try: this_boss = self.mongo_boss.opened[str(boss_id)] except KeyError: raise SanguoException( errormsg.UNION_BOSS_NOT_STARTED, self.char_id, "UnionBoss Battle", "boss not started {0}".format(boss_id)) if this_boss.hp <= 0: raise SanguoException(errormsg.UNION_BOSS_DEAD, self.char_id, "UnionBoss Battle", "boss dead {0}".format(boss_id)) if self.cur_times >= self.max_times: raise SanguoException(errormsg.UNION_BOSS_NO_TIMES, self.char_id, "UnionBoss Battle", "no times") msg = protomsg.Battle() battle = UnionBossBattle(self.char_id, boss_id, msg, this_boss.hp) remained_hp = battle.start() damage = battle.get_total_damage() this_boss.hp = remained_hp if remained_hp <= 0: this_boss.killer = self.char_id self.save_battle_log(this_boss, damage) self.incr_battle_times() drop_msg = self.after_battle(boss_id, damage, remained_hp <= 0) if remained_hp <= 0: self.boss_has_been_killed(boss_id) self.mongo_boss.save() return msg, drop_msg except LockTimeOut: raise SanguoException(errormsg.UNION_BOSS_LOCKED, self.char_id, "UnionBoss Battle", "boss locked {0}".format(boss_id)) def save_battle_log(self, this_boss, damage): for log in this_boss.logs: if log.char_id == self.char_id: log.damage += damage break else: boss_log = MongoEmbeddedUnionBossLog() boss_log.char_id = self.char_id boss_log.damage = damage this_boss.logs.append(boss_log) def after_battle(self, boss_id, damage, kill=False): # 每次打完给予奖励 member = Member(self.char_id) boss = UNION_BOSS[boss_id] contribute_points = int( float(damage) / boss.hp * boss.contribute_points) lowest = 1 highest = int(boss.contribute_points * 0.05) if contribute_points < lowest: contribute_points = lowest if contribute_points > highest: contribute_points = highest coin = 9 + contribute_points member.add_coin(coin, send_notify=False) member.add_contribute_points(contribute_points, send_notify=True) if not kill: self.union.add_contribute_points(contribute_points) drop = make_standard_drop_from_template() drop['union_coin'] = coin drop['union_contribute_points'] = contribute_points return standard_drop_to_attachment_protomsg(drop) def boss_has_been_killed(self, boss_id): # 击杀boss后发送奖励 logs = self.get_battle_members_in_ordered(boss_id) member_ids = [log.char_id for log in logs] killer = self.char_id m = Mail(killer) drop = make_standard_drop_from_template() drop['union_coin'] = UNION_BOSS_KILLER_REWARD.coin m.add(UNION_BOSS_KILLER_REWARD.mail_title, UNION_BOSS_KILLER_REWARD.mail_content, attachment=json.dumps(drop)) LOWEST_RANK = max(UNION_BOSS_REWARD.keys()) UNION_BOSS_REWARD_TUPLE = UNION_BOSS_REWARD.items() UNION_BOSS_REWARD_TUPLE.sort(key=lambda item: item[0]) for index, mid in enumerate(member_ids): rank = index + 1 if rank > LOWEST_RANK: break m = Mail(mid) for _rank, _reward in UNION_BOSS_REWARD_TUPLE: if _rank >= rank: drop = make_standard_drop_from_template() drop['union_coin'] = _reward.coin m.add(_reward.mail_title.format(rank), _reward.mail_content.format(rank), attachment=json.dumps(drop)) break # 工会获得贡献度 self.union.add_contribute_points(UNION_BOSS[boss_id].contribute_points) def get_battle_members_in_ordered(self, boss_id): this_boss = self.mongo_boss.opened[str(boss_id)] return sorted(this_boss.logs, key=lambda item: -item.damage) @union_instance_check(UnionBase, errormsg.UNION_NOT_EXIST, "UnionBoss Get Log", "has no union") def make_log_message(self, boss_id): try: this_boss = self.mongo_boss.opened[str(boss_id)] except KeyError: raise SanguoException(errormsg.INVALID_OPERATE, self.char_id, "UnionBoss Get Log", "no log for boss {0}".format(boss_id)) hp = float(UNION_BOSS[boss_id].hp) msg = protomsg.UnionBossGetLogResponse() msg.ret = 0 msg.boss_id = boss_id logs = [] for log in self.get_battle_members_in_ordered(boss_id): msg_log = protomsg.UnionBossGetLogResponse.BossLog() msg_log.char_id = log.char_id msg_log.char_name = get_char_property(log.char_id, 'name') msg_log.damage = log.damage msg_log.precent = int(log.damage / hp * 100) logs.append(msg_log) if this_boss.killer: for log in logs: if log.char_id == this_boss.killer: msg.killer.MergeFrom(log) break for log in logs[:UNION_BOSS_REWARD_LOWEST_RANK]: msg_log = msg.logs.add() msg_log.MergeFrom(log) return msg @union_instance_check(UnionBase, errormsg.UNION_NOT_EXIST, "UnionBoss Response", "has no union") def make_boss_response(self): union_level = self.union.mongo_union.level msg = protomsg.UnionBossResponse() if not UNION_LEVEL[union_level].union_boss_open: msg.ret = errormsg.UNION_BOSS_FREEZE return msg msg.ret = 0 msg.remained_times = self.max_times - self.cur_times available_bosses = [ k for k, v in UNION_BOSS.items() if union_level >= v.union_level ] for b in available_bosses: msg_boss = msg.bosses.add() msg_boss.id = b if str(b) not in self.mongo_boss.opened: msg_boss.hp = UNION_BOSS[b].hp msg_boss.status = protomsg.UnionBossResponse.Boss.INACTIVE else: this_boss = self.mongo_boss.opened[str(b)] msg_boss.hp = this_boss.hp if this_boss.hp <= 0: msg_boss.status = protomsg.UnionBossResponse.Boss.DEAD else: msg_boss.status = protomsg.UnionBossResponse.Boss.ACTIVE return msg