Пример #1
0
    def make_refresh(self, tp, set_timestamp=False, save=True, send_notify=True):
        club_level = get_club_property(self.server_id, self.char_id, 'level')
        goods = ConfigStore.refresh(tp, club_level)

        try:
            tp_doc = self.doc['tp'][str(tp)]
        except KeyError:
            tp_doc = MongoStore.document_tp()

        if set_timestamp:
            tp_doc['refresh_at'] = arrow.utcnow().timestamp

        tp_doc['goods'] = {str(_id): {'index': _index, 'times': 0} for _id, _index in goods}
        self.doc['tp'][str(tp)] = tp_doc

        if save:
            MongoStore.db(self.server_id).update_one(
                {'_id': self.char_id},
                {'$set': {
                    'tp.{0}'.format(tp): tp_doc
                }}
            )

        if send_notify:
            self.send_notify(tp=tp)
Пример #2
0
    def level_up(self, add_level):
        assert add_level > 0

        from core.club import get_club_property
        max_level = min(self.config.max_level, get_club_property(self.server_id, self.char_id, 'level') * 2)
        if self.level >= max_level:
            raise GameException(ConfigErrorMessage.get_error_id("UNIT_REACH_MAX_LEVEL"))

        old_level = self.level

        if add_level == 1:
            using_items = self.config.levels[self.level].update_item_need
            resource_classified = ResourceClassification.classify(using_items)
            resource_classified.check_exist(self.server_id, self.char_id)
            resource_classified.remove(self.server_id, self.char_id, message="Unit.level_up:{0}".format(self.id))

            self.level += 1
        else:
            # 这里要反过来试,如果正向试的话, 可能需要试5次,此时有点慢
            # 反过来只对 只是升一两次的情况比较慢,但这种可以接受
            can_add_level = max_level - self.level
            if add_level > can_add_level:
                add_level = can_add_level

            def _try_up(_add):
                _using_items = []
                this_level = self.level

                for _ in range(_add):
                    items = self.config.levels[this_level].update_item_need
                    _using_items.extend(items)
                    this_level += 1

                rc = ResourceClassification.classify(_using_items)
                rc.check_exist(self.server_id, self.char_id)
                rc.remove(self.server_id, self.char_id, message="Unit.level_up:{0}".format(self.id))

            for i in range(add_level, 0, -1):
                try:
                    _try_up(i)
                except GameException as e:
                    if i == 1:
                        # 只升一级都报错
                        raise e
                else:
                    # 没有raise GameException 资源是够的
                    self.level += i
                    break

        if self.level != old_level:
            MongoUnit.db(self.server_id).update_one(
                {'_id': self.char_id},
                {'$set': {
                    'units.{0}.level'.format(self.id): self.level
                }}
            )

        # 升级可能会导致其他的unit属性改变(加成)
        # 所以在UnitManage 里统一load一次unit
        return self.level - old_level
Пример #3
0
    def make_refresh(self,
                     tp,
                     set_timestamp=False,
                     save=True,
                     send_notify=True):
        club_level = get_club_property(self.server_id, self.char_id, 'level')
        goods = ConfigStore.refresh(tp, club_level)

        try:
            tp_doc = self.doc['tp'][str(tp)]
        except KeyError:
            tp_doc = MongoStore.document_tp()

        if set_timestamp:
            tp_doc['refresh_at'] = arrow.utcnow().timestamp

        tp_doc['goods'] = {
            str(_id): {
                'index': _index,
                'times': 0
            }
            for _id, _index in goods
        }
        self.doc['tp'][str(tp)] = tp_doc

        if save:
            MongoStore.db(self.server_id).update_one(
                {'_id': self.char_id}, {'$set': {
                    'tp.{0}'.format(tp): tp_doc
                }})

        if send_notify:
            self.send_notify(tp=tp)
Пример #4
0
def get_members_ordered_by_explore_point(server_id, char_id, names=True, limit=None):
    """

    :rtype: (list[_ExploreMember], _ExploreMember | None)
    """
    docs = MongoUnionMember.db(server_id).find(
        {'explore_point': {'$gt': 0}}
    ).sort('explore_point', -1)

    result = []
    """:type: list[_ExploreMember]"""
    self_info = None
    """:type: _ExploreMember | None"""

    for index, doc in enumerate(docs):
        rank = index + 1
        if limit and rank > limit:
            break

        obj = _ExploreMember()
        obj.rank = rank
        obj.id = doc['_id']
        obj.explore_point = doc['explore_point']

        result.append(obj)

        if doc['_id'] == char_id:
            self_info = obj

    if names:
        # find names
        char_ids = [r.id for r in result]
        names = batch_get_club_property(server_id, char_ids, 'name')
        for r in result:
            r.name = names[r.id]

    if char_id == 0:
        return result, None

    if self_info:
        return result, self_info

    doc = MongoUnionMember.db(server_id).find_one({'_id': char_id}, {'explore_point': 1})
    if not doc:
        return result, None

    self_info = _ExploreMember()
    self_info.id = char_id
    self_info.name = get_club_property(server_id, char_id, 'name')
    self_info.explore_point = doc.get('explore_point', 0)
    if not self_info.explore_point:
        self_info.rank = 0
        return result, self_info

    rank = MongoUnionMember.db(server_id).find(
        {'explore_point': {'$gt': self_info.explore_point}}
    ).count()

    self_info.rank = rank
    return result, self_info
Пример #5
0
    def start(self, dungeon_id, formation_slots=None):
        grade_conf = ConfigDungeonGrade.get(dungeon_id)
        if not grade_conf:
            raise GameException(ConfigErrorMessage.get_error_id("DUNGEON_NOT_EXIST"))

        map_name = ConfigDungeon.get(grade_conf.belong).map_name

        club_level = get_club_property(self.server_id, self.char_id, 'level')
        if grade_conf.need_level > club_level:
            raise GameException(ConfigErrorMessage.get_error_id("DUNGEON_CLUB_LEVEL_NOT_ENOUGH"))

        f = Formation(self.server_id, self.char_id)
        if formation_slots:
            f.sync_slots(formation_slots)

        Energy(self.server_id, self.char_id).check(ConfigDungeon.get(grade_conf.belong).cost)

        ri = TimesInfo(self.server_id, self.char_id, grade_conf.belong)
        if not ri.remained_match_times:
            # 购买
            self.buy_times(grade_conf.belong)

        club_one = Club(self.server_id, self.char_id)
        club_two = ConfigNPCFormation.get(grade_conf.npc)
        msg = ClubMatch(club_one, club_two, 6, f.get_skill_sequence(), {}).start()
        msg.key = str(dungeon_id)
        msg.map_name = map_name
        return msg
Пример #6
0
    def start(self, dungeon_id, formation_slots=None):
        grade_conf = ConfigDungeonGrade.get(dungeon_id)
        if not grade_conf:
            raise GameException(
                ConfigErrorMessage.get_error_id("DUNGEON_NOT_EXIST"))

        map_name = ConfigDungeon.get(grade_conf.belong).map_name

        club_level = get_club_property(self.server_id, self.char_id, 'level')
        if grade_conf.need_level > club_level:
            raise GameException(
                ConfigErrorMessage.get_error_id(
                    "DUNGEON_CLUB_LEVEL_NOT_ENOUGH"))

        f = Formation(self.server_id, self.char_id)
        if formation_slots:
            f.sync_slots(formation_slots)

        Energy(self.server_id,
               self.char_id).check(ConfigDungeon.get(grade_conf.belong).cost)

        ri = TimesInfo(self.server_id, self.char_id, grade_conf.belong)
        if not ri.remained_match_times:
            # 购买
            self.buy_times(grade_conf.belong)

        club_one = Club(self.server_id, self.char_id)
        club_two = ConfigNPCFormation.get(grade_conf.npc)
        msg = ClubMatch(club_one, club_two, 6, f.get_skill_sequence(),
                        {}).start()
        msg.key = str(dungeon_id)
        msg.map_name = map_name
        return msg
Пример #7
0
    def get_level_reward_item_status(self, _id, level=None):
        if _id in self.doc['level_reward']:
            return WELFARE_HAS_GOT

        if level is None:
            level = get_club_property(self.server_id, self.char_id, 'level')

        if level >= _id:
            return WELFARE_CAN_GET

        return WELFARE_CAN_NOT
Пример #8
0
    def __init__(self, server_id, char_id):
        self.server_id = server_id
        self.char_id = char_id
        self.doc = MongoChampionship.db(self.server_id).find_one(
            {'_id': self.char_id})
        if not self.doc:
            self.doc = MongoChampionship.document()
            self.doc['_id'] = self.char_id
            MongoChampionship.db(self.server_id).insert_one(self.doc)

        self.club_level = get_club_property(self.server_id, self.char_id,
                                            'level')
Пример #9
0
    def post(self, content):
        from core.club import get_club_property

        if self.CD(self.server_id, self.char_id).get_cd_seconds():
            raise GameException(ConfigErrorMessage.get_error_id("CHAT_TOO_FAST"))

        if len(content) > 300:
            raise GameException(ConfigErrorMessage.get_error_id("CHAT_TOO_LARGE"))

        try:
            with self.LOCK(self.server_id, self.char_id).lock(3, 3):
                now = arrow.utcnow().timestamp

                message = {
                    'msg_id': make_string_id(),
                    'club_id': str(self.char_id),
                    'name': get_club_property(self.server_id, self.char_id, 'name'),
                    'content': content,
                    'post_at': now,
                    'approval': 0,
                    'last_update_at': now,
                }

                _data = self.make_notify_data(message=message)
                self.broadcast(_data)

                self.doc['value'].insert(0, message)
                if len(self.doc['value']) > 100:
                    self.doc['value'].sort(key=lambda item: -item['last_update_at'])
                    removed = self.doc['value'].pop(-1)

                    remove_notify = self.REMOVE_NOTIFY()
                    remove_notify.msg_id = removed['msg_id']

                    WinningChatApprovalMark(self.server_id, self.char_id, removed['msg_id']).delete()

                    self.broadcast(MessageFactory.pack(remove_notify))

                MongoCommon.db(self.server_id).update_one(
                    {'_id': self.get_id()},
                    {'$set': {
                        'value': self.doc['value']
                    }}
                )

        except LockTimeOut:
            raise GameException(ConfigErrorMessage.get_error_id("SERVER_BUSY"))

        self.CD(self.server_id, self.char_id).set(GlobalConfig.value("LEADERBOARD_CHAT_INTERVAL"))
Пример #10
0
    def get_leader_board(self, amount=30):
        docs = MongoTower.db(self.server_id).find(
            {'today_max_star': {'$ne': 0}},
            {'today_max_star': 1}
        ).sort('today_max_star', -1).limit(amount)

        info = []
        for doc in docs:
            _id = doc['_id']
            name = get_club_property(self.server_id, _id, 'name')
            star = doc['today_max_star']

            info.append((_id, name, star))

        return info
Пример #11
0
    def join(self):
        if self.doc['joined']:
            return

        diamond = GlobalConfig.value("LEVEL_GROWING_ACTIVITY_JOIN_COST_DIAMOND")
        vip_need = GlobalConfig.value("LEVEL_GROWING_ACTIVITY_JOIN_VIP_LIMIT")

        VIP(self.server_id, self.char_id).check(vip_need)

        cost = [(money_text_to_item_id('diamond'), diamond), ]
        rc = ResourceClassification.classify(cost)
        rc.check_exist(self.server_id, self.char_id)
        rc.remove(self.server_id, self.char_id)

        current_level = get_club_property(self.server_id, self.char_id, 'level')
        self._update(current_level, joined=True)
        self.send_notify()
Пример #12
0
    def level_up(self, exp_pool, up_level):
        from core.club import get_club_property
        max_level = min(
            ConfigStaffLevelNew.MAX_LEVEL,
            get_club_property(self.server_id, self.char_id, 'level') * 2)
        if self.level >= max_level:
            raise GameException(
                ConfigErrorMessage.get_error_id("STAFF_ALREADY_MAX_LEVEL"))

        target_level = self.level + up_level
        if target_level > max_level:
            target_level = max_level

        old_level = self.level
        while self.level < target_level:
            config = ConfigStaffLevelNew.get(self.level)
            up_need_exp = config.exp - self.level_exp

            if exp_pool < up_need_exp:
                self.level_exp += exp_pool
                exp_pool = 0
                break

            exp_pool -= up_need_exp
            self.level += 1
            self.level_exp = 0

        MongoStaff.db(self.server_id).update_one({'_id': self.char_id}, {
            '$set': {
                'staffs.{0}.level'.format(self.id): self.level,
                'staffs.{0}.level_exp'.format(self.id): self.level_exp
            }
        })

        self.calculate()
        self.make_cache()

        staff_level_up_signal.send(sender=None,
                                   server_id=self.server_id,
                                   char_id=self.char_id,
                                   staff_id=self.id,
                                   staff_oid=self.oid,
                                   new_level=self.level)

        return exp_pool, self.level - old_level
Пример #13
0
    def level_up(self, exp_pool, up_level):
        from core.club import get_club_property
        max_level = min(ConfigStaffLevelNew.MAX_LEVEL, get_club_property(self.server_id, self.char_id, 'level') * 2)
        if self.level >= max_level:
            raise GameException(ConfigErrorMessage.get_error_id("STAFF_ALREADY_MAX_LEVEL"))

        target_level = self.level + up_level
        if target_level > max_level:
            target_level = max_level

        old_level = self.level
        while self.level < target_level:
            config = ConfigStaffLevelNew.get(self.level)
            up_need_exp = config.exp - self.level_exp

            if exp_pool < up_need_exp:
                self.level_exp += exp_pool
                exp_pool = 0
                break

            exp_pool -= up_need_exp
            self.level += 1
            self.level_exp = 0

        MongoStaff.db(self.server_id).update_one(
            {'_id': self.char_id},
            {'$set': {
                'staffs.{0}.level'.format(self.id): self.level,
                'staffs.{0}.level_exp'.format(self.id): self.level_exp
            }}
        )

        self.calculate()
        self.make_cache()

        staff_level_up_signal.send(
            sender=None,
            server_id=self.server_id,
            char_id=self.char_id,
            staff_id=self.id,
            staff_oid=self.oid,
            new_level=self.level
        )

        return exp_pool, self.level - old_level
Пример #14
0
    def send_level_reward_notify(self, _id=None):
        if _id:
            act = ACT_UPDATE
            ids = [_id]
        else:
            act = ACT_INIT
            ids = ConfigWelfareLevelReward.INSTANCES.keys()

        level = get_club_property(self.server_id, self.char_id, 'level')

        notify = WelfareLevelRewardNotify()
        notify.act = act
        for i in ids:
            notify_item = notify.items.add()
            notify_item.id = i
            notify_item.status = self.get_level_reward_item_status(i, level=level)

        MessagePipe(self.char_id).put(msg=notify)
Пример #15
0
    def refresh(self):
        club_level = get_club_property(self.server_id, self.char_id, 'level')
        vip_level = VIP(self.server_id, self.char_id).level
        passed_challenge_ids = Challenge(self.server_id, self.char_id).get_passed_challenge_ids()

        task_ids = []
        for k, v in ConfigTaskDaily.INSTANCES.iteritems():
            if club_level < v.club_level:
                continue

            if vip_level < v.vip_level:
                continue

            if v.challenge_id and v.challenge_id not in passed_challenge_ids:
                continue

            task_ids.append(k)

        return task_ids
Пример #16
0
    def add_building_exp(self, building_id, exp, help_from_char_id=None):
        building = self.get_building_object(building_id)
        level_up = building.add_exp(exp)

        self.doc['buildings'][str(building_id)]['level'] = building.level
        self.doc['buildings'][str(building_id)]['exp'] = building.exp

        operation = {
            '$set': {
                'buildings.{0}.level'.format(building_id): building.level,
                'buildings.{0}.exp'.format(building_id): building.exp,
            }
        }

        if help_from_char_id:
            slots = []
            for _, s in building.slots.iteritems():
                if s.open and not s.finished:
                    slots.append(s)

            if slots:
                slot = random.choice(slots)

                log = (
                    4,
                    (get_club_property(self.server_id, help_from_char_id,
                                       'name'), str(exp)),
                    0,
                )
                operation['$push'] = {
                    'buildings.{0}.slots.{1}.report'.format(
                        building_id, slot.id):
                    log
                }

        MongoTerritory.db(self.server_id).update_one({'_id': self.char_id},
                                                     operation)

        if level_up:
            self.try_unlock_slot()

        self.send_notify(building_id=building_id)
Пример #17
0
    def refresh(self):
        club_level = get_club_property(self.server_id, self.char_id, 'level')
        vip_level = VIP(self.server_id, self.char_id).level
        passed_challenge_ids = Challenge(
            self.server_id, self.char_id).get_passed_challenge_ids()

        task_ids = []
        for k, v in ConfigTaskDaily.INSTANCES.iteritems():
            if club_level < v.club_level:
                continue

            if vip_level < v.vip_level:
                continue

            if v.challenge_id and v.challenge_id not in passed_challenge_ids:
                continue

            task_ids.append(k)

        return task_ids
Пример #18
0
    def try_unlock(self, send_notify=True):
        doc = MongoUnit.db(self.server_id).find_one(
            {'_id': self.char_id},
            {'units': 1}
        )

        unlocked_unit_ids = []

        club_level = get_club_property(self.server_id, self.char_id, 'level')
        for unit_id, config in ConfigUnitUnLock.INSTANCES.iteritems():
            if str(unit_id) in doc['units']:
                continue

            if config.need_club_level > club_level:
                continue

            condition_unit_level = True
            for _uid, _lv in config.need_unit_level:
                this_unit_level = doc['units'].get(str(_uid), {}).get('level', 0)
                if _lv > this_unit_level:
                    condition_unit_level = False
                    break

            if condition_unit_level:
                unlocked_unit_ids.append(unit_id)

        if not unlocked_unit_ids:
            return

        updater = {
            'units.{0}'.format(i): MongoUnit.document_unit() for i in unlocked_unit_ids
            }
        MongoUnit.db(self.server_id).update_one(
            {'_id': self.char_id},
            {'$set': updater}
        )

        if send_notify:
            self.send_notify(ids=unlocked_unit_ids)

        self.after_units_change_for_trig_signal()
Пример #19
0
    def add_building_exp(self, building_id, exp, help_from_char_id=None):
        building = self.get_building_object(building_id)
        level_up = building.add_exp(exp)

        self.doc['buildings'][str(building_id)]['level'] = building.level
        self.doc['buildings'][str(building_id)]['exp'] = building.exp

        operation = {
            '$set': {
                'buildings.{0}.level'.format(building_id): building.level,
                'buildings.{0}.exp'.format(building_id): building.exp,
            }
        }

        if help_from_char_id:
            slots = []
            for _, s in building.slots.iteritems():
                if s.open and not s.finished:
                    slots.append(s)

            if slots:
                slot = random.choice(slots)

                log = (
                    4,
                    (get_club_property(self.server_id, help_from_char_id, 'name'), str(exp)),
                    0,
                )
                operation['$push'] = {
                    'buildings.{0}.slots.{1}.report'.format(building_id, slot.id): log
                }

        MongoTerritory.db(self.server_id).update_one(
            {'_id': self.char_id},
            operation
        )

        if level_up:
            self.try_unlock_slot()

        self.send_notify(building_id=building_id)
Пример #20
0
    def join(self):
        if self.doc['joined']:
            return

        diamond = GlobalConfig.value(
            "LEVEL_GROWING_ACTIVITY_JOIN_COST_DIAMOND")
        vip_need = GlobalConfig.value("LEVEL_GROWING_ACTIVITY_JOIN_VIP_LIMIT")

        VIP(self.server_id, self.char_id).check(vip_need)

        cost = [
            (money_text_to_item_id('diamond'), diamond),
        ]
        rc = ResourceClassification.classify(cost)
        rc.check_exist(self.server_id, self.char_id)
        rc.remove(self.server_id, self.char_id)

        current_level = get_club_property(self.server_id, self.char_id,
                                          'level')
        self._update(current_level, joined=True)
        self.send_notify()
Пример #21
0
    def try_unlock(self, send_notify=True):
        doc = MongoUnit.db(self.server_id).find_one({'_id': self.char_id},
                                                    {'units': 1})

        unlocked_unit_ids = []

        club_level = get_club_property(self.server_id, self.char_id, 'level')
        for unit_id, config in ConfigUnitUnLock.INSTANCES.iteritems():
            if str(unit_id) in doc['units']:
                continue

            if config.need_club_level > club_level:
                continue

            condition_unit_level = True
            for _uid, _lv in config.need_unit_level:
                this_unit_level = doc['units'].get(str(_uid),
                                                   {}).get('level', 0)
                if _lv > this_unit_level:
                    condition_unit_level = False
                    break

            if condition_unit_level:
                unlocked_unit_ids.append(unit_id)

        if not unlocked_unit_ids:
            return

        updater = {
            'units.{0}'.format(i): MongoUnit.document_unit()
            for i in unlocked_unit_ids
        }
        MongoUnit.db(self.server_id).update_one({'_id': self.char_id},
                                                {'$set': updater})

        if send_notify:
            self.send_notify(ids=unlocked_unit_ids)

        self.after_units_change_for_trig_signal()
Пример #22
0
 def __init__(self, server_id, char_id):
     self.server_id = server_id
     self.char_id = char_id
     self.name = get_club_property(server_id, char_id, 'name')
Пример #23
0
    def equipment_level_up(self, slot_id, times=1):
        from core.staff import StaffManger
        from core.formation import Formation
        from core.plunder import Plunder

        this_slot = self.doc['slots'][slot_id]
        item_id = this_slot['item_id']

        if get_item_type(item_id) != TYPE_EQUIPMENT:
            raise GameException(ConfigErrorMessage.get_error_id("INVALID_OPERATE"))

        equip = Equipment.load_from_slot_data(this_slot)
        level = equip.level

        if equip.is_special:
            if level >= ConfigEquipmentSpecialLevel.MAX_LEVEL:
                raise GameException(ConfigErrorMessage.get_error_id("EQUIPMENT_SELF_REACH_MAX_LEVEL"))

            station_level_limit = Plunder(self.server_id, self.char_id).get_station_level() * 2
            if level >= station_level_limit:
                raise GameException(ConfigErrorMessage.get_error_id("EQUIPMENT_SPECIAL_REACH_MAX_LEVEL"))

            max_level = min(ConfigEquipmentSpecialLevel.MAX_LEVEL, station_level_limit)
        else:
            config = ConfigEquipmentNew.get(item_id)
            if level >= config.max_level:
                raise GameException(ConfigErrorMessage.get_error_id("EQUIPMENT_SELF_REACH_MAX_LEVEL"))

            club_level_limit = get_club_property(self.server_id, self.char_id, 'level') * 2
            if level >= club_level_limit:
                raise GameException(ConfigErrorMessage.get_error_id("EQUIPMENT_REACH_MAX_LEVEL"))

            max_level = min(config.max_level, club_level_limit)

        can_add_level = max_level - level
        if times > can_add_level:
            times = can_add_level

        def do_level_up(_add):
            _item_needs = equip.get_level_up_needs_items(_add)

            resource_classified = ResourceClassification.classify(_item_needs)
            resource_classified.check_exist(self.server_id, self.char_id)
            resource_classified.remove(self.server_id, self.char_id,
                                       message="Bag.equipment_level_up:{0}".format(item_id))

        old_level = level
        error_code = 0

        for i in range(times, 0, -1):
            try:
                do_level_up(i)
            except GameException as e:
                error_code = e.error_id
            else:
                level += i
                break

        if level > old_level:
            self.doc['slots'][slot_id]['level'] = level

            MongoBag.db(self.server_id).update_one(
                {'_id': self.char_id},
                {'$set': {
                    'slots.{0}.level'.format(slot_id): level
                }}
            )

            ValueLogEquipmentLevelUpTimes(self.server_id, self.char_id).record(value=level - old_level)
            self.send_notify(slot_ids=[slot_id])

            sm = StaffManger(self.server_id, self.char_id)
            staff_id = sm.find_staff_id_with_equip(slot_id)
            if staff_id:
                s_obj = sm.get_staff_object(staff_id)
                s_obj.calculate()
                s_obj.make_cache()
                sm.send_notify(ids=[staff_id])

                fm = Formation(self.server_id, self.char_id)
                if staff_id in fm.in_formation_staffs():
                    Club(self.server_id, self.char_id).send_notify()

                    task_condition_trig_signal.send(
                        sender=None,
                        server_id=self.server_id,
                        char_id=self.char_id,
                        condition_name='core.formation.Formation'
                    )

        return error_code, level != old_level, Equipment.load_from_slot_data(self.doc['slots'][slot_id])
Пример #24
0
def explore_leader_board(request):
    server_id = request._game_session.server_id
    char_id = request._game_session.char_id

    members, self_member = get_members_ordered_by_explore_point(server_id,
                                                                char_id,
                                                                limit=10)
    unions, self_union = get_unions_ordered_by_explore_point(
        server_id, char_id)

    response = UnionExploreLeaderboardResponse()
    response.ret = 0

    if self_member:
        response.my_club.rank = self_member.rank
        response.my_club.id = str(self_member.id)
        response.my_club.name = self_member.name
        response.my_club.explore_point = self_member.explore_point
    else:
        response.my_club.rank = 0
        response.my_club.id = str(char_id)
        response.my_club.name = get_club_property(server_id, char_id, 'name')
        response.my_club.explore_point = 0

    if self_union:
        response.my_union.rank = self_union.rank
        response.my_union.id = self_union.id
        response.my_union.name = self_union.name
        response.my_union.explore_point = self_union.explore_point
    else:
        _union = Union(server_id, char_id)
        _union_id = _union.get_joined_union_id()
        if not _union_id:
            raise GameException(
                ConfigErrorMessage.get_error_id("INVALID_OPERATE"))

        response.my_union.rank = 0
        response.my_union.id = _union_id
        response.my_union.name = _union.union_doc['name']
        response.my_union.explore_point = 0

    for i in range(10):
        try:
            m = members[i]
        except IndexError:
            break

        res_club = response.club.add()
        res_club.rank = m.rank
        res_club.id = str(m.id)
        res_club.name = m.name
        res_club.explore_point = m.explore_point

    for i in range(10):
        try:
            u = unions[i]
        except IndexError:
            break

        res_union = response.union.add()
        res_union.rank = u.rank
        res_union.id = u.id
        res_union.name = u.name
        res_union.explore_point = u.explore_point

    return ProtobufResponse(response)
Пример #25
0
    def level_up(self, add_level):
        assert add_level > 0

        from core.club import get_club_property
        max_level = min(
            self.config.max_level,
            get_club_property(self.server_id, self.char_id, 'level') * 2)
        if self.level >= max_level:
            raise GameException(
                ConfigErrorMessage.get_error_id("UNIT_REACH_MAX_LEVEL"))

        old_level = self.level

        if add_level == 1:
            using_items = self.config.levels[self.level].update_item_need
            resource_classified = ResourceClassification.classify(using_items)
            resource_classified.check_exist(self.server_id, self.char_id)
            resource_classified.remove(self.server_id,
                                       self.char_id,
                                       message="Unit.level_up:{0}".format(
                                           self.id))

            self.level += 1
        else:
            # 这里要反过来试,如果正向试的话, 可能需要试5次,此时有点慢
            # 反过来只对 只是升一两次的情况比较慢,但这种可以接受
            can_add_level = max_level - self.level
            if add_level > can_add_level:
                add_level = can_add_level

            def _try_up(_add):
                _using_items = []
                this_level = self.level

                for _ in range(_add):
                    items = self.config.levels[this_level].update_item_need
                    _using_items.extend(items)
                    this_level += 1

                rc = ResourceClassification.classify(_using_items)
                rc.check_exist(self.server_id, self.char_id)
                rc.remove(self.server_id,
                          self.char_id,
                          message="Unit.level_up:{0}".format(self.id))

            for i in range(add_level, 0, -1):
                try:
                    _try_up(i)
                except GameException as e:
                    if i == 1:
                        # 只升一级都报错
                        raise e
                else:
                    # 没有raise GameException 资源是够的
                    self.level += i
                    break

        if self.level != old_level:
            MongoUnit.db(self.server_id).update_one(
                {'_id': self.char_id},
                {'$set': {
                    'units.{0}.level'.format(self.id): self.level
                }})

        # 升级可能会导致其他的unit属性改变(加成)
        # 所以在UnitManage 里统一load一次unit
        return self.level - old_level
Пример #26
0
    def search(self, check_cd=True, replace_search_index=None, send_notify=True):
        if check_cd and self.get_search_cd():
            raise GameException(ConfigErrorMessage.get_error_id("PLUNDER_SEARCH_IN_CD"))

        def _query_real(_level_low, _level_high):
            _skip_char_ids = [_s['id'] for _s in self.doc['search']]
            _skip_char_ids.append(self.char_id)

            _condition = {'$and': [
                {'_id': {'$nin': _skip_char_ids}},
                {'level': {'$gte': _level_low}},
                {'level': {'$lte': _level_high}}
            ]}

            _docs = MongoCharacter.db(self.server_id).find(_condition, {'_id': 1})
            _ids = []
            for _doc in _docs:
                _ids.append(_doc['_id'])

            return _ids

        self_club_level = get_club_property(self.server_id, self.char_id, 'level')
        level_low = self_club_level - GlobalConfig.value("PLUNDER_SEARCH_LEVEL_RANGE_LOW")
        level_high = self_club_level + GlobalConfig.value("PLUNDER_SEARCH_LEVEL_RANGE_HIGH")

        real_ids = _query_real(level_low, level_high)
        # filter by active and loss_percent
        condition = {'$and': [
            {'_id': {'$in': real_ids}},
            {'active': True},
            {'loss_percent': {'$lt': PLUNDER_MAX_LOST}}
        ]}

        docs = MongoPlunder.db(self.server_id).find(condition, {'_id': 1})
        result_ids = []
        for doc in docs:
            if PlunderMatchCD(self.server_id, self.char_id, doc['_id']).get_cd_seconds():
                continue

            result_ids.append(doc['_id'])

        random.shuffle(result_ids)

        search_docs = []
        for i in result_ids:
            search_docs.append({'id': i, 'spied': False})
            if len(search_docs) == 2:
                break

        need_npc_amount = 2 - len(search_docs)
        if need_npc_amount:
            for i in range(need_npc_amount):
                config_plunder_npc = ConfigPlunderNPC.get_by_level(self_club_level)
                npc_doc = config_plunder_npc.to_doc(self.doc['level'])

                search_docs.append(npc_doc)

        if replace_search_index:
            self.doc['search'][replace_search_index] = search_docs[0]
            updater = {
                'search.{0}'.format(replace_search_index): self.doc['search'][replace_search_index]
            }
        else:
            self.doc['search'] = search_docs
            updater = {'search': search_docs}

        MongoPlunder.db(self.server_id).update_one(
            {'_id': self.char_id},
            {'$set': updater}
        )

        if check_cd:
            self.set_search_cd()

        if send_notify:
            self.send_search_notify()
Пример #27
0
    def search(self,
               check_cd=True,
               replace_search_index=None,
               send_notify=True):
        if check_cd and self.get_search_cd():
            raise GameException(
                ConfigErrorMessage.get_error_id("PLUNDER_SEARCH_IN_CD"))

        def _query_real(_level_low, _level_high):
            _skip_char_ids = [_s['id'] for _s in self.doc['search']]
            _skip_char_ids.append(self.char_id)

            _condition = {
                '$and': [{
                    '_id': {
                        '$nin': _skip_char_ids
                    }
                }, {
                    'level': {
                        '$gte': _level_low
                    }
                }, {
                    'level': {
                        '$lte': _level_high
                    }
                }]
            }

            _docs = MongoCharacter.db(self.server_id).find(
                _condition, {'_id': 1})
            _ids = []
            for _doc in _docs:
                _ids.append(_doc['_id'])

            return _ids

        self_club_level = get_club_property(self.server_id, self.char_id,
                                            'level')
        level_low = self_club_level - GlobalConfig.value(
            "PLUNDER_SEARCH_LEVEL_RANGE_LOW")
        level_high = self_club_level + GlobalConfig.value(
            "PLUNDER_SEARCH_LEVEL_RANGE_HIGH")

        real_ids = _query_real(level_low, level_high)
        # filter by active and loss_percent
        condition = {
            '$and': [{
                '_id': {
                    '$in': real_ids
                }
            }, {
                'active': True
            }, {
                'loss_percent': {
                    '$lt': PLUNDER_MAX_LOST
                }
            }]
        }

        docs = MongoPlunder.db(self.server_id).find(condition, {'_id': 1})
        result_ids = []
        for doc in docs:
            if PlunderMatchCD(self.server_id, self.char_id,
                              doc['_id']).get_cd_seconds():
                continue

            result_ids.append(doc['_id'])

        random.shuffle(result_ids)

        search_docs = []
        for i in result_ids:
            search_docs.append({'id': i, 'spied': False})
            if len(search_docs) == 2:
                break

        need_npc_amount = 2 - len(search_docs)
        if need_npc_amount:
            for i in range(need_npc_amount):
                config_plunder_npc = ConfigPlunderNPC.get_by_level(
                    self_club_level)
                npc_doc = config_plunder_npc.to_doc(self.doc['level'])

                search_docs.append(npc_doc)

        if replace_search_index:
            self.doc['search'][replace_search_index] = search_docs[0]
            updater = {
                'search.{0}'.format(replace_search_index):
                self.doc['search'][replace_search_index]
            }
        else:
            self.doc['search'] = search_docs
            updater = {'search': search_docs}

        MongoPlunder.db(self.server_id).update_one({'_id': self.char_id},
                                                   {'$set': updater})

        if check_cd:
            self.set_search_cd()

        if send_notify:
            self.send_search_notify()
Пример #28
0
def get_members_ordered_by_explore_point(server_id,
                                         char_id,
                                         names=True,
                                         limit=None):
    """

    :rtype: (list[_ExploreMember], _ExploreMember | None)
    """
    docs = MongoUnionMember.db(server_id).find({
        'explore_point': {
            '$gt': 0
        }
    }).sort('explore_point', -1)

    result = []
    """:type: list[_ExploreMember]"""
    self_info = None
    """:type: _ExploreMember | None"""

    for index, doc in enumerate(docs):
        rank = index + 1
        if limit and rank > limit:
            break

        obj = _ExploreMember()
        obj.rank = rank
        obj.id = doc['_id']
        obj.explore_point = doc['explore_point']

        result.append(obj)

        if doc['_id'] == char_id:
            self_info = obj

    if names:
        # find names
        char_ids = [r.id for r in result]
        names = batch_get_club_property(server_id, char_ids, 'name')
        for r in result:
            r.name = names[r.id]

    if char_id == 0:
        return result, None

    if self_info:
        return result, self_info

    doc = MongoUnionMember.db(server_id).find_one({'_id': char_id},
                                                  {'explore_point': 1})
    if not doc:
        return result, None

    self_info = _ExploreMember()
    self_info.id = char_id
    self_info.name = get_club_property(server_id, char_id, 'name')
    self_info.explore_point = doc.get('explore_point', 0)
    if not self_info.explore_point:
        self_info.rank = 0
        return result, self_info

    rank = MongoUnionMember.db(server_id).find({
        'explore_point': {
            '$gt': self_info.explore_point
        }
    }).count()

    self_info.rank = rank
    return result, self_info