Example #1
0
    def get_honor_reward(self, honor_id):
        config = ConfigArenaHonorReward.get(honor_id)
        if not config:
            raise GameException(ConfigErrorMessage.get_error_id("BAD_MESSAGE"))

        if honor_id > self.get_honor_points():
            raise GameException(ConfigErrorMessage.get_error_id("ARENA_HONOR_REWARD_POINT_NOT_ENOUGH"))

        reward_info = self.get_today_honor_reward_info()
        if honor_id in reward_info:
            raise GameException(ConfigErrorMessage.get_error_id("ARENA_HONOR_REWARD_ALREADY_GOT"))

        resource_classified = ResourceClassification.classify(config.reward)
        resource_classified.add(self.server_id, self.char_id, message="Arena.get_honor_reward:{0}".format(honor_id))

        today_key = str(get_start_time_of_today().timestamp)
        MongoArena.db(self.server_id).update_one(
            {'_id': str(self.char_id)},
            {
                '$push': {
                    'honor_rewards.{0}'.format(today_key): honor_id
                }
            }
        )

        reward_info.append(honor_id)
        self.send_honor_notify(reward_info=reward_info)
        return resource_classified
Example #2
0
 def remove_point(self, point):
     new_point = self.check_point(point)
     MongoArena.db(self.server_id).update_one(
         {'_id': str(self.char_id)},
         {'$set': {'point': new_point}}
     )
     self.send_notify()
Example #3
0
    def try_create_arena_npc(cls, server_id):
        if MongoArena.db(server_id).count():
            return

        with ArenaLock(server_id, None).lock(hold_seconds=20):
            # 这里要进行double-check
            # 考虑这种情况:
            # 有两个并发的 try_create_arena_npc 调用
            # A先进入,B稍晚进入
            # B 首先判断到 MongoArena 没有记录
            # 然后等待锁, 此时A已经获取了锁,并且最终填充完数据后,B获得锁
            # 此时B必须再进行一次检查,否则B就会生成多余数据
            # double-check 在 多线程的 单例模式 中,也是必备
            if MongoArena.db(server_id).count():
                return

            npcs = []

            for _K, v in ConfigArenaNPC.INSTANCES.iteritems():
                for _ in range(v.amount):
                    npc_id = random.choice(v.npcs)
                    _id = "npc:{0}:{1}".format(npc_id, make_string_id())

                    doc = MongoArena.document()
                    doc['_id'] = _id
                    doc['search_index'] = ConfigArenaSearchRange.START_INDEX
                    npcs.append(doc)

                    score = random.randint(v.score_low, v.score_high)
                    ArenaScore(server_id, _id).set_score(score)

            MongoArena.db(server_id).insert_many(npcs)
Example #4
0
 def remove_point(self, point):
     new_point = self.check_point(point)
     MongoArena.db(self.server_id).update_one(
         {'_id': str(self.char_id)}, {'$set': {
             'point': new_point
         }})
     self.send_notify()
Example #5
0
 def add_point(self, point):
     assert point > 0
     MongoArena.db(self.server_id).update_one({'_id': str(self.char_id)},
                                              {'$inc': {
                                                  'point': point
                                              }})
     self.send_notify()
Example #6
0
    def refresh(self):
        cd = self.get_refresh_cd()
        if cd:
            # 就是要花钱了
            ti = TimesInfo(self.server_id, self.char_id)
            if not ti.remained_reset_times:
                raise GameException(
                    ConfigErrorMessage.get_error_id(
                        "ARENA_NO_SEARCH_RESET_TIMES"))

            cost = [
                (money_text_to_item_id('diamond'), ti.reset_cost),
            ]
            rc = ResourceClassification.classify(cost)
            rc.check_exist(self.server_id, self.char_id)
            rc.remove(self.server_id, self.char_id, message="Arena.refresh")

            ValueLogArenaSearchResetTimes(self.server_id,
                                          self.char_id).record()
        else:
            ArenaRefreshCD(self.server_id,
                           self.char_id).set(ARENA_REFRESH_CD_SECONDS)

        rival = self.search_rival()

        MongoArena.db(self.server_id).update_one({'_id': str(self.char_id)},
                                                 {'$set': {
                                                     'rival': rival
                                                 }})

        self.send_notify()
Example #7
0
    def try_create_arena_npc(cls, server_id):
        if MongoArena.db(server_id).count():
            return

        with ArenaLock(server_id, None).lock(hold_seconds=20):
            # 这里要进行double-check
            # 考虑这种情况:
            # 有两个并发的 try_create_arena_npc 调用
            # A先进入,B稍晚进入
            # B 首先判断到 MongoArena 没有记录
            # 然后等待锁, 此时A已经获取了锁,并且最终填充完数据后,B获得锁
            # 此时B必须再进行一次检查,否则B就会生成多余数据
            # double-check 在 多线程的 单例模式 中,也是必备
            if MongoArena.db(server_id).count():
                return

            npcs = []

            for _K, v in ConfigArenaNPC.INSTANCES.iteritems():
                for _ in range(v.amount):
                    npc_id = random.choice(v.npcs)
                    _id = "npc:{0}:{1}".format(npc_id, make_string_id())

                    doc = MongoArena.document()
                    doc['_id'] = _id
                    doc['search_index'] = ConfigArenaSearchRange.START_INDEX
                    npcs.append(doc)

                    score = random.randint(v.score_low, v.score_high)
                    ArenaScore(server_id, _id).set_score(score)

            MongoArena.db(server_id).insert_many(npcs)
Example #8
0
    def get_honor_reward(self, honor_id):
        config = ConfigArenaHonorReward.get(honor_id)
        if not config:
            raise GameException(ConfigErrorMessage.get_error_id("BAD_MESSAGE"))

        if honor_id > self.get_honor_points():
            raise GameException(
                ConfigErrorMessage.get_error_id(
                    "ARENA_HONOR_REWARD_POINT_NOT_ENOUGH"))

        reward_info = self.get_today_honor_reward_info()
        if honor_id in reward_info:
            raise GameException(
                ConfigErrorMessage.get_error_id(
                    "ARENA_HONOR_REWARD_ALREADY_GOT"))

        resource_classified = ResourceClassification.classify(config.reward)
        resource_classified.add(
            self.server_id,
            self.char_id,
            message="Arena.get_honor_reward:{0}".format(honor_id))

        today_key = str(get_start_time_of_today().timestamp)
        MongoArena.db(self.server_id).update_one(
            {'_id': str(self.char_id)},
            {'$push': {
                'honor_rewards.{0}'.format(today_key): honor_id
            }})

        reward_info.append(honor_id)
        self.send_honor_notify(reward_info=reward_info)
        return resource_classified
Example #9
0
    def refresh(self):
        cd = self.get_refresh_cd()
        if cd:
            # 就是要花钱了
            ti = TimesInfo(self.server_id, self.char_id)
            if not ti.remained_reset_times:
                raise GameException(ConfigErrorMessage.get_error_id("ARENA_NO_SEARCH_RESET_TIMES"))

            cost = [(money_text_to_item_id('diamond'), ti.reset_cost), ]
            rc = ResourceClassification.classify(cost)
            rc.check_exist(self.server_id, self.char_id)
            rc.remove(self.server_id, self.char_id, message="Arena.refresh")

            ValueLogArenaSearchResetTimes(self.server_id, self.char_id).record()
        else:
            ArenaRefreshCD(self.server_id, self.char_id).set(ARENA_REFRESH_CD_SECONDS)

        rival = self.search_rival()

        MongoArena.db(self.server_id).update_one(
            {'_id': str(self.char_id)},
            {'$set': {
                'rival': rival
            }}
        )

        self.send_notify()
Example #10
0
 def add_point(self, point):
     assert point > 0
     MongoArena.db(self.server_id).update_one(
         {'_id': str(self.char_id)},
         {'$inc': {
             'point': point
         }}
     )
     self.send_notify()
Example #11
0
    def send_notify(self):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}
        )

        ti = TimesInfo(self.server_id, self.char_id)

        notify = ArenaNotify()
        notify.my_rank = self.get_current_rank()
        notify.remained_match_times = ti.remained_match_times

        notify.refresh_cd = self.get_refresh_cd()
        notify.remained_refresh_times = ti.remained_reset_times
        notify.refresh_cost = ti.reset_cost

        notify.remained_buy_times = ti.remained_buy_times
        notify.buy_cost = ti.buy_cost
        notify.point = doc['point']
        notify.max_rank = self.get_max_rank()
        notify.my_score = ArenaScore(self.server_id, self.char_id).score

        if doc['rival']:
            rival_club = ArenaClub(self.server_id, doc['rival'])

            notify.rival.id = str(rival_club.id)
            notify.rival.name = rival_club.name
            notify.rival.club_flag = rival_club.flag
            notify.rival.level = rival_club.level
            notify.rival.power = rival_club.power
            notify.rival.rank = Arena(self.server_id, doc['rival']).get_current_rank()
            notify.rival.score = ArenaScore(self.server_id, doc['rival']).score

        MessagePipe(self.char_id).put(msg=notify)
Example #12
0
    def send_notify(self):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)})

        ti = TimesInfo(self.server_id, self.char_id)

        notify = ArenaNotify()
        notify.my_rank = self.get_current_rank()
        notify.remained_match_times = ti.remained_match_times

        notify.refresh_cd = self.get_refresh_cd()
        notify.remained_refresh_times = ti.remained_reset_times
        notify.refresh_cost = ti.reset_cost

        notify.remained_buy_times = ti.remained_buy_times
        notify.buy_cost = ti.buy_cost
        notify.point = doc['point']
        notify.max_rank = self.get_max_rank()
        notify.my_score = ArenaScore(self.server_id, self.char_id).score

        if doc['rival']:
            rival_club = ArenaClub(self.server_id, doc['rival'])

            notify.rival.id = str(rival_club.id)
            notify.rival.name = rival_club.name
            notify.rival.club_flag = rival_club.flag
            notify.rival.level = rival_club.level
            notify.rival.power = rival_club.power
            notify.rival.rank = Arena(self.server_id,
                                      doc['rival']).get_current_rank()
            notify.rival.score = ArenaScore(self.server_id, doc['rival']).score

        MessagePipe(self.char_id).put(msg=notify)
Example #13
0
    def get_today_honor_reward_info(self):
        today_key = str(get_start_time_of_today().timestamp)
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'honor_rewards.{0}'.format(today_key): 1})

        return doc.get('honor_rewards', {}).get(today_key, [])
Example #14
0
def send_rank_reward(*args):
    logger = Logger("arena_send_rank_reward")
    logger.write("Start")

    try:
        for sid in Server.duty_server_ids():
            MongoArena.db(sid).update_many({}, {'$set': {'continue_win': 0}})

            Arena.send_rank_reward(sid)
            logger.write("Server {0} Finish".format(sid))
    except:
        logger.error(traceback.format_exc())
    else:
        logger.write("Done")
    finally:
        logger.close()
Example #15
0
    def get_today_honor_reward_info(self):
        today_key = str(get_start_time_of_today().timestamp)
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'honor_rewards.{0}'.format(today_key): 1}
        )

        return doc.get('honor_rewards', {}).get(today_key, [])
Example #16
0
    def get_max_rank(self):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}, {'max_rank': 1})

        max_rank = doc['max_rank']
        if max_rank:
            return max_rank

        return self.get_current_rank()
Example #17
0
    def get_max_rank(self):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'max_rank': 1}
        )

        max_rank = doc['max_rank']
        if max_rank:
            return max_rank

        return self.get_current_rank()
Example #18
0
    def check_point(self, point):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}, {'point': 1})

        current_point = doc.get('point', 0)
        new_point = current_point - point
        if new_point < 0:
            raise GameException(
                ConfigErrorMessage.get_error_id("ARENA_POINT_NOT_ENOUGH"))

        return new_point
Example #19
0
def send_rank_reward(*args):
    logger = Logger("arena_send_rank_reward")
    logger.write("Start")

    try:
        for sid in Server.duty_server_ids():
            MongoArena.db(sid).update_many(
                {},
                {'$set': {
                    'continue_win': 0
                }}
            )

            Arena.send_rank_reward(sid)
            logger.write("Server {0} Finish".format(sid))
    except:
        logger.error(traceback.format_exc())
    else:
        logger.write("Done")
    finally:
        logger.close()
Example #20
0
    def check_point(self, point):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'point': 1}
        )

        current_point = doc.get('point', 0)
        new_point = current_point - point
        if new_point < 0:
            raise GameException(ConfigErrorMessage.get_error_id("ARENA_POINT_NOT_ENOUGH"))

        return new_point
Example #21
0
    def try_add_self_in_arena(self):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'honor_rewards': 1}
        )

        if doc:
            # 清理过期的 honor_rewards 记录
            honor_rewards = doc.get('honor_rewards', {})
            if not honor_rewards:
                return

            today_key = str(get_start_time_of_today().timestamp)

            unset = {}
            for k in honor_rewards.keys():
                if k != today_key:
                    unset['honor_rewards.{0}'.format(k)] = 1

            if unset:
                MongoArena.db(self.server_id).update_one(
                    {'_id': str(self.char_id)},
                    {'$unset': unset}
                )

            return

        doc = MongoArena.document()
        doc['_id'] = str(self.char_id)
        doc['search_index'] = ConfigArenaSearchRange.START_INDEX
        MongoArena.db(self.server_id).insert_one(doc)

        ArenaScore(self.server_id, self.char_id).set_score(ARENA_DEFAULT_SCORE)
Example #22
0
    def try_add_self_in_arena(self):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}, {'honor_rewards': 1})

        if doc:
            # 清理过期的 honor_rewards 记录
            honor_rewards = doc.get('honor_rewards', {})
            if not honor_rewards:
                return

            today_key = str(get_start_time_of_today().timestamp)

            unset = {}
            for k in honor_rewards.keys():
                if k != today_key:
                    unset['honor_rewards.{0}'.format(k)] = 1

            if unset:
                MongoArena.db(self.server_id).update_one(
                    {'_id': str(self.char_id)}, {'$unset': unset})

            return

        doc = MongoArena.document()
        doc['_id'] = str(self.char_id)
        doc['search_index'] = ConfigArenaSearchRange.START_INDEX
        MongoArena.db(self.server_id).insert_one(doc)

        ArenaScore(self.server_id, self.char_id).set_score(ARENA_DEFAULT_SCORE)
Example #23
0
    def send_rank_reward(cls, server_id):
        char_ids = Club.get_recent_login_char_ids(server_id)

        # 加上一分钟,确保已经到了第二天
        # 定时任务要是 23:59:59 启动,那天数判断就错了
        weekday = arrow.utcnow().to(settings.TIME_ZONE).replace(minutes=1).weekday()

        for cid in char_ids:
            arena = Arena(server_id, cid)
            rank = arena.get_current_rank()

            # 每日奖励
            config = ConfigArenaRankReward.get(rank)
            rc = ResourceClassification.classify(config.reward)

            m = MailManager(server_id, cid)
            m.add(
                config.mail_title,
                config.mail_content,
                attachment=rc.to_json(),
            )

            if weekday == 0:
                # 周一发周奖励
                config_weekly = ConfigArenaRankRewardWeekly.get(rank)
                rc = ResourceClassification.classify(config_weekly.reward)

                m = MailManager(server_id, cid)
                m.add(
                    config_weekly.mail_title,
                    config_weekly.mail_content,
                    attachment=rc.to_json()
                )

        if weekday == 0:
            docs = MongoArena.db(server_id).find(
                {'_id': {'$regex': '^\d+$'}},
                {'_id': 1}
            )

            default_score_doc = MongoArenaScore.db(server_id).find_one({'_id': ARENA_DEFAULT_SCORE})
            for doc in docs:
                if doc['_id'] in default_score_doc['char_ids']:
                    continue

                ArenaScore(server_id, int(doc['_id'])).set_score(ARENA_DEFAULT_SCORE)
Example #24
0
    def send_rank_reward(cls, server_id):
        char_ids = Club.get_recent_login_char_ids(server_id)

        # 加上一分钟,确保已经到了第二天
        # 定时任务要是 23:59:59 启动,那天数判断就错了
        weekday = arrow.utcnow().to(
            settings.TIME_ZONE).replace(minutes=1).weekday()

        for cid in char_ids:
            arena = Arena(server_id, cid)
            rank = arena.get_current_rank()

            # 每日奖励
            config = ConfigArenaRankReward.get(rank)
            rc = ResourceClassification.classify(config.reward)

            m = MailManager(server_id, cid)
            m.add(
                config.mail_title,
                config.mail_content,
                attachment=rc.to_json(),
            )

            if weekday == 0:
                # 周一发周奖励
                config_weekly = ConfigArenaRankRewardWeekly.get(rank)
                rc = ResourceClassification.classify(config_weekly.reward)

                m = MailManager(server_id, cid)
                m.add(config_weekly.mail_title,
                      config_weekly.mail_content,
                      attachment=rc.to_json())

        if weekday == 0:
            docs = MongoArena.db(server_id).find({'_id': {
                '$regex': '^\d+$'
            }}, {'_id': 1})

            default_score_doc = MongoArenaScore.db(server_id).find_one(
                {'_id': ARENA_DEFAULT_SCORE})
            for doc in docs:
                if doc['_id'] in default_score_doc['char_ids']:
                    continue

                ArenaScore(server_id,
                           int(doc['_id'])).set_score(ARENA_DEFAULT_SCORE)
Example #25
0
    def match(self, formation_slots=None):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'rival': 1}
        )

        rival_id = doc['rival']

        if not rival_id:
            raise GameException(ConfigErrorMessage.get_error_id("ARENA_MATCH_NO_RIVAL"))

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

        self.check_and_buy_times()

        club_one = Club(self.server_id, self.char_id)
        club_two = ArenaClub(self.server_id, rival_id)
        club_match = ClubMatch(club_one, club_two, 6, f.get_skill_sequence(), {})
        msg = club_match.start()
        msg.key = rival_id
        msg.map_name = GlobalConfig.value_string("MATCH_MAP_ARENA")
        return msg
Example #26
0
    def match(self, formation_slots=None):
        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}, {'rival': 1})

        rival_id = doc['rival']

        if not rival_id:
            raise GameException(
                ConfigErrorMessage.get_error_id("ARENA_MATCH_NO_RIVAL"))

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

        self.check_and_buy_times()

        club_one = Club(self.server_id, self.char_id)
        club_two = ArenaClub(self.server_id, rival_id)
        club_match = ClubMatch(club_one, club_two, 6, f.get_skill_sequence(),
                               {})
        msg = club_match.start()
        msg.key = rival_id
        msg.map_name = GlobalConfig.value_string("MATCH_MAP_ARENA")
        return msg
Example #27
0
        def _query(low, high):
            condition = [
                {
                    '_id': {
                        '$gte': low
                    }
                },
                {
                    '_id': {
                        '$lte': high
                    }
                },
            ]

            _docs = MongoArenaScore.db(self.server_id).find(
                {'$and': condition})

            _char_ids = []
            for _doc in _docs:
                _char_ids.extend(_doc['char_ids'])

            random.shuffle(_char_ids)

            amount = len(_char_ids)

            # 上面已经按照积分范围选除了 角色id
            # 下面用各种条件过滤
            npc = []
            real = []
            loop_times = 0
            for cid in _char_ids:
                if cid == str(self.char_id):
                    continue

                # 有cd的肯定的就不要了
                if ArenaMatchCD(self.server_id, self.char_id,
                                cid).get_cd_seconds():
                    continue

                if is_npc_club(cid):
                    npc.append(cid)
                else:
                    # 选出来的真实玩家,需要一次都没打过
                    _rival_doc = MongoArena.db(self.server_id).find_one(
                        {'_id': cid}, {'match_times': 1})
                    if _rival_doc.get('match_times', 0):
                        real.append(cid)

                # 第一次,优先给NPC
                if match_times == 0:
                    if npc:
                        return npc[0]
                else:
                    if loop_times >= amount / 2:
                        # 已经跑了一半了,还没玩家, 就返回NPC吧
                        if npc:
                            return npc[0]
                    else:
                        if real:
                            return real[0]

                loop_times += 1

            # 走到这儿,已经循环完了,原因
            # 1 如果是第一次, 那就没有Npc
            # 2 如果不是第一次,那就没有 符合条件的 real
            # 这时候有什么就给什么吧
            if real:
                return real[0]

            if npc:
                return npc[0]

            return None
Example #28
0
        def _query(low, high):
            condition = [
                {'_id': {'$gte': low}},
                {'_id': {'$lte': high}},
            ]

            _docs = MongoArenaScore.db(self.server_id).find({'$and': condition})

            _char_ids = []
            for _doc in _docs:
                _char_ids.extend(_doc['char_ids'])

            random.shuffle(_char_ids)

            amount = len(_char_ids)

            # 上面已经按照积分范围选除了 角色id
            # 下面用各种条件过滤
            npc = []
            real = []
            loop_times = 0
            for cid in _char_ids:
                if cid == str(self.char_id):
                    continue

                # 有cd的肯定的就不要了
                if ArenaMatchCD(self.server_id, self.char_id, cid).get_cd_seconds():
                    continue

                if is_npc_club(cid):
                    npc.append(cid)
                else:
                    # 选出来的真实玩家,需要一次都没打过
                    _rival_doc = MongoArena.db(self.server_id).find_one({'_id': cid}, {'match_times': 1})
                    if _rival_doc.get('match_times', 0):
                        real.append(cid)

                # 第一次,优先给NPC
                if match_times == 0:
                    if npc:
                        return npc[0]
                else:
                    if loop_times >= amount / 2:
                        # 已经跑了一半了,还没玩家, 就返回NPC吧
                        if npc:
                            return npc[0]
                    else:
                        if real:
                            return real[0]

                loop_times += 1

            # 走到这儿,已经循环完了,原因
            # 1 如果是第一次, 那就没有Npc
            # 2 如果不是第一次,那就没有 符合条件的 real
            # 这时候有什么就给什么吧
            if real:
                return real[0]

            if npc:
                return npc[0]

            return None
Example #29
0
    def search_rival(self):
        # 获取对手
        def _query(low, high):
            condition = [
                {
                    '_id': {
                        '$gte': low
                    }
                },
                {
                    '_id': {
                        '$lte': high
                    }
                },
            ]

            _docs = MongoArenaScore.db(self.server_id).find(
                {'$and': condition})

            _char_ids = []
            for _doc in _docs:
                _char_ids.extend(_doc['char_ids'])

            random.shuffle(_char_ids)

            amount = len(_char_ids)

            # 上面已经按照积分范围选除了 角色id
            # 下面用各种条件过滤
            npc = []
            real = []
            loop_times = 0
            for cid in _char_ids:
                if cid == str(self.char_id):
                    continue

                # 有cd的肯定的就不要了
                if ArenaMatchCD(self.server_id, self.char_id,
                                cid).get_cd_seconds():
                    continue

                if is_npc_club(cid):
                    npc.append(cid)
                else:
                    # 选出来的真实玩家,需要一次都没打过
                    _rival_doc = MongoArena.db(self.server_id).find_one(
                        {'_id': cid}, {'match_times': 1})
                    if _rival_doc.get('match_times', 0):
                        real.append(cid)

                # 第一次,优先给NPC
                if match_times == 0:
                    if npc:
                        return npc[0]
                else:
                    if loop_times >= amount / 2:
                        # 已经跑了一半了,还没玩家, 就返回NPC吧
                        if npc:
                            return npc[0]
                    else:
                        if real:
                            return real[0]

                loop_times += 1

            # 走到这儿,已经循环完了,原因
            # 1 如果是第一次, 那就没有Npc
            # 2 如果不是第一次,那就没有 符合条件的 real
            # 这时候有什么就给什么吧
            if real:
                return real[0]

            if npc:
                return npc[0]

            return None

        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}, {
                'search_index': 1,
                'match_times': 1
            })

        search_index = doc['search_index']
        match_times = doc.get('match_times', 0)

        my_score = ArenaScore(self.server_id, self.char_id).score

        rival_id = 0
        _search_times = 0
        while True:
            if _search_times > len(ConfigArenaSearchRange.LIST) * 2:
                break

            # 这里循环 search_index
            if search_index > ConfigArenaSearchRange.MAX_INDEX:
                search_index = ConfigArenaSearchRange.START_INDEX - 1
            elif search_index < 0:
                search_index = ConfigArenaSearchRange.START_INDEX

            search_config = ConfigArenaSearchRange.get(search_index)
            rival_id = _query(my_score * search_config.range_1,
                              my_score * search_config.range_2)
            if rival_id:
                break

            # 这里改变 search_index
            if search_index >= ConfigArenaSearchRange.START_INDEX:
                search_index += 1
            else:
                search_index -= 1

            _search_times += 1

        if not rival_id:
            # 找不到人的情况就是 第一名的, 积分太高, 实在找不到. 就随机选一个
            docs = MongoArena.db(self.server_id).find(
                {
                    '_id': {
                        '$ne': str(self.char_id)
                    }
                }, {
                    '_id': 1
                }).limit(200)

            char_ids = []
            for doc in docs:
                char_ids.append(doc['_id'])

            rival_id = random.choice(char_ids)

        return rival_id
Example #30
0
    def report(self, key, win):
        rival_id = key

        my_rank = self.get_current_rank()
        my_max_rank = self.get_max_rank()

        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)}, {
                'search_index': 1,
                'continue_win': 1,
            })

        ArenaRefreshCD(self.server_id, self.char_id).clean()
        ArenaMatchCD(self.server_id, self.char_id,
                     rival_id).set(GlobalConfig.value("ARENA_MATCH_CD"))

        config_search = ConfigArenaSearchRange.get(doc['search_index'])
        if win:
            score_changed = config_search.score_win
            new_search_index = doc['search_index'] + 1
            continue_win = doc.get('continue_win', 0) + 1
        else:
            score_changed = -config_search.score_lose
            new_search_index = doc['search_index'] - 1
            continue_win = 0

        if new_search_index > ConfigArenaSearchRange.MAX_INDEX:
            new_search_index = ConfigArenaSearchRange.MAX_INDEX
        if new_search_index < 0:
            new_search_index = 0

        MongoArena.db(self.server_id).update_one({'_id': str(self.char_id)}, {
            '$set': {
                'search_index': new_search_index,
                'rival': 0,
                'continue_win': continue_win,
            },
            '$inc': {
                'match_times': 1,
            }
        })

        ass = ArenaScore(self.server_id, self.char_id)
        score_changed = ass.add_score(score_changed)

        new_rank = ass.rank
        max_rank_changed = False

        if new_rank > my_max_rank:
            my_max_rank = new_rank

            MongoArena.db(self.server_id).update_one(
                {'_id': str(self.char_id)}, {'$set': {
                    'max_rank': new_rank
                }})

            max_rank_changed = True

        rank_changed = new_rank - my_rank

        rival_rank = Arena(self.server_id, rival_id).get_current_rank()

        if win:
            ValueLogArenaWinTimes(self.server_id, self.char_id).record()
            config_reward = ConfigArenaMatchReward.get(1)
        else:
            config_reward = ConfigArenaMatchReward.get(2)

        ValueLogArenaHonorPoints(
            self.server_id, self.char_id).record(value=config_reward.honor)
        ValueLogArenaMatchTimes(self.server_id, self.char_id).record()

        drop = config_reward.get_drop()
        resource_classified = ResourceClassification.classify(drop)
        resource_classified.add(self.server_id,
                                self.char_id,
                                message="Arena.report:{0}".format(win))

        self.send_honor_notify()
        self.send_notify()

        arena_match_signal.send(
            sender=None,
            server_id=self.server_id,
            char_id=self.char_id,
            target_id=rival_id,
            target_name=ArenaClub(self.server_id, rival_id).name,
            my_rank=new_rank,
            target_rank=rival_rank,
            win=win,
            continue_win=continue_win,
        )

        if max_rank_changed:
            task_condition_trig_signal.send(sender=None,
                                            server_id=self.server_id,
                                            char_id=self.char_id,
                                            condition_name='core.arena.Arena')

        WinningArena(self.server_id, self.char_id).set(win)

        return resource_classified, score_changed, -rank_changed, my_max_rank, new_rank, ass.score
Example #31
0
    def report(self, key, win):
        rival_id = key

        my_rank = self.get_current_rank()
        my_max_rank = self.get_max_rank()

        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {
                'search_index': 1,
                'continue_win': 1,
            }
        )

        ArenaRefreshCD(self.server_id, self.char_id).clean()
        ArenaMatchCD(self.server_id, self.char_id, rival_id).set(GlobalConfig.value("ARENA_MATCH_CD"))

        config_search = ConfigArenaSearchRange.get(doc['search_index'])
        if win:
            score_changed = config_search.score_win
            new_search_index = doc['search_index'] + 1
            continue_win = doc.get('continue_win', 0) + 1
        else:
            score_changed = -config_search.score_lose
            new_search_index = doc['search_index'] - 1
            continue_win = 0

        if new_search_index > ConfigArenaSearchRange.MAX_INDEX:
            new_search_index = ConfigArenaSearchRange.MAX_INDEX
        if new_search_index < 0:
            new_search_index = 0

        MongoArena.db(self.server_id).update_one(
            {'_id': str(self.char_id)},
            {
                '$set': {
                    'search_index': new_search_index,
                    'rival': 0,
                    'continue_win': continue_win,
                },
                '$inc': {
                    'match_times': 1,
                }
            }
        )

        ass = ArenaScore(self.server_id, self.char_id)
        score_changed = ass.add_score(score_changed)

        new_rank = ass.rank
        max_rank_changed = False

        if new_rank > my_max_rank:
            my_max_rank = new_rank

            MongoArena.db(self.server_id).update_one(
                {'_id': str(self.char_id)},
                {'$set': {'max_rank': new_rank}}
            )

            max_rank_changed = True

        rank_changed = new_rank - my_rank

        rival_rank = Arena(self.server_id, rival_id).get_current_rank()

        if win:
            ValueLogArenaWinTimes(self.server_id, self.char_id).record()
            config_reward = ConfigArenaMatchReward.get(1)
        else:
            config_reward = ConfigArenaMatchReward.get(2)

        ValueLogArenaHonorPoints(self.server_id, self.char_id).record(value=config_reward.honor)
        ValueLogArenaMatchTimes(self.server_id, self.char_id).record()

        drop = config_reward.get_drop()
        resource_classified = ResourceClassification.classify(drop)
        resource_classified.add(self.server_id, self.char_id, message="Arena.report:{0}".format(win))

        self.send_honor_notify()
        self.send_notify()

        arena_match_signal.send(
            sender=None,
            server_id=self.server_id,
            char_id=self.char_id,
            target_id=rival_id,
            target_name=ArenaClub(self.server_id, rival_id).name,
            my_rank=new_rank,
            target_rank=rival_rank,
            win=win,
            continue_win=continue_win,
        )

        if max_rank_changed:
            task_condition_trig_signal.send(
                sender=None,
                server_id=self.server_id,
                char_id=self.char_id,
                condition_name='core.arena.Arena'
            )

        WinningArena(self.server_id, self.char_id).set(win)

        return resource_classified, score_changed, -rank_changed, my_max_rank, new_rank, ass.score
Example #32
0
    def search_rival(self):
        # 获取对手
        def _query(low, high):
            condition = [
                {'_id': {'$gte': low}},
                {'_id': {'$lte': high}},
            ]

            _docs = MongoArenaScore.db(self.server_id).find({'$and': condition})

            _char_ids = []
            for _doc in _docs:
                _char_ids.extend(_doc['char_ids'])

            random.shuffle(_char_ids)

            amount = len(_char_ids)

            # 上面已经按照积分范围选除了 角色id
            # 下面用各种条件过滤
            npc = []
            real = []
            loop_times = 0
            for cid in _char_ids:
                if cid == str(self.char_id):
                    continue

                # 有cd的肯定的就不要了
                if ArenaMatchCD(self.server_id, self.char_id, cid).get_cd_seconds():
                    continue

                if is_npc_club(cid):
                    npc.append(cid)
                else:
                    # 选出来的真实玩家,需要一次都没打过
                    _rival_doc = MongoArena.db(self.server_id).find_one({'_id': cid}, {'match_times': 1})
                    if _rival_doc.get('match_times', 0):
                        real.append(cid)

                # 第一次,优先给NPC
                if match_times == 0:
                    if npc:
                        return npc[0]
                else:
                    if loop_times >= amount / 2:
                        # 已经跑了一半了,还没玩家, 就返回NPC吧
                        if npc:
                            return npc[0]
                    else:
                        if real:
                            return real[0]

                loop_times += 1

            # 走到这儿,已经循环完了,原因
            # 1 如果是第一次, 那就没有Npc
            # 2 如果不是第一次,那就没有 符合条件的 real
            # 这时候有什么就给什么吧
            if real:
                return real[0]

            if npc:
                return npc[0]

            return None

        doc = MongoArena.db(self.server_id).find_one(
            {'_id': str(self.char_id)},
            {'search_index': 1, 'match_times': 1}
        )

        search_index = doc['search_index']
        match_times = doc.get('match_times', 0)

        my_score = ArenaScore(self.server_id, self.char_id).score

        rival_id = 0
        _search_times = 0
        while True:
            if _search_times > len(ConfigArenaSearchRange.LIST) * 2:
                break

            # 这里循环 search_index
            if search_index > ConfigArenaSearchRange.MAX_INDEX:
                search_index = ConfigArenaSearchRange.START_INDEX - 1
            elif search_index < 0:
                search_index = ConfigArenaSearchRange.START_INDEX

            search_config = ConfigArenaSearchRange.get(search_index)
            rival_id = _query(my_score * search_config.range_1, my_score * search_config.range_2)
            if rival_id:
                break

            # 这里改变 search_index
            if search_index >= ConfigArenaSearchRange.START_INDEX:
                search_index += 1
            else:
                search_index -= 1

            _search_times += 1

        if not rival_id:
            # 找不到人的情况就是 第一名的, 积分太高, 实在找不到. 就随机选一个
            docs = MongoArena.db(self.server_id).find(
                {'_id': {'$ne': str(self.char_id)}},
                {'_id': 1}
            ).limit(200)

            char_ids = []
            for doc in docs:
                char_ids.append(doc['_id'])

            rival_id = random.choice(char_ids)

        return rival_id