Пример #1
0
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()
Пример #2
0
 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()
Пример #3
0
    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)
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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