Beispiel #1
0
    def overPVP(self):
        ''' 战斗结算 '''
        for _uid in self.__users.iterkeys():
            yield redis.zadd(SET_RANK_ROOM_EAT%self.__id, _uid, -self.__eat_num.get(_uid, 0))
            yield redis.zadd(SET_RANK_ROOM_EATED%self.__id, _uid, -self.__be_eated_num.get(_uid, 0))
            _user_mgr = g_UserMgr.getUserByUid(_uid)
            _user_mgr.attrib.paly_num += 1
            _volume = yield redis.zscore(SET_RANK_ROOM_VOLUME%self.__id, _uid)
            _weight = int(_volume) * 10 if _volume else 0
            if _user_mgr.attrib.max_weight < _weight:
                _user_mgr.attrib.max_weight = _weight
                yield redis.zadd(SET_RANK_PVP_WEIGHT, _uid, -_weight)

        yield redis.hset(HASH_PVP_ROOM_USER_NUM, self.__id, self.count)
Beispiel #2
0
    def __migrate_accounts_registered(self):
        try:
            yield redis.delete(HASH_NICKNAME_REGISTERED, HASH_MACHINE_CODE_REGISTERED, HASH_UID_MACHINE_CODE, SET_RANK_PVP_WEIGHT)

            db_conf = {'host': setting.DB_CONF['host'],
                'port'       : setting.DB_CONF['port'],
                'user'       : setting.DB_CONF['user'],
                'passwd'     : setting.DB_CONF['pass'],
                'db'         : setting.DB_CONF['userdb'],
                'charset'    : 'utf8'
                }

            conn = MySQLdb.connect(**db_conf)
            cu   = conn.cursor()

            cu.execute('SELECT `id`,`machine_code`,`nickname`,`max_weight` FROM tb_character')
            _dataset = cu.fetchall()
            for _id, _machine_code, _nickname, _max_weight in _dataset:
                yield redis.hset(HASH_NICKNAME_REGISTERED, _nickname, _id)
                yield redis.hset(HASH_MACHINE_CODE_REGISTERED, _machine_code, _id)
                yield redis.hset(HASH_UID_MACHINE_CODE, _id, _machine_code)
                yield redis.zadd(SET_RANK_PVP_WEIGHT, _id, -_max_weight)

            cu.close()
            conn.close()

            conn = None
            cu   = None
        except Exception, e:
            reactor.callLater(1, self.__migrate_accounts_registered)
            print 'ERROR:', e
            print 'WARNING. Redis connection fail, callLater 1 second. redis:', redis
Beispiel #3
0
    def rank(self):
        _rank = yield redis.zrank(RANK_WORLDBOSS_DAMAGE, self._cid)

        if not _rank:
            yield redis.zadd(RANK_WORLDBOSS_DAMAGE, self._cid, -self._damage_total)
            _rank = yield redis.zrank(RANK_WORLDBOSS_DAMAGE, self._cid)

        defer.returnValue(_rank)
Beispiel #4
0
    def rank(self):
        _rank = yield redis.zrank(RANK_WORLDBOSS_DAMAGE, self._cid)

        if not _rank:
            yield redis.zadd(RANK_WORLDBOSS_DAMAGE, self._cid,
                             -self._damage_total)
            _rank = yield redis.zrank(RANK_WORLDBOSS_DAMAGE, self._cid)

        defer.returnValue(_rank)
Beispiel #5
0
    def get_char_score(self, cid, redis_key=SET_JOUST_CID_SCORE):
        ''' 获取玩家的积分 '''
        _score = yield redis.zscore(redis_key, cid)
        if _score is None:
            _score = JOUST_BASIC_SCORE
            yield redis.zadd(redis_key, cid, -JOUST_BASIC_SCORE)
        else:
            _score = -int(_score)

        defer.returnValue(_score)
Beispiel #6
0
    def get_battle_score(self, cid, other_cid, redis_key=SET_JOUST_CID_SCORE):
        ''' 挑战胜利后计算积分 '''
        _score = yield self.get_char_score(cid)
        # 机器人
        _score_reduce = 0
        if other_cid < JOUST_ROBOT_CID:
            _other_score = JOUST_BASIC_SCORE
            if _score > _other_score:
                _score += SCORE_BASIC_2
            elif _score < _other_score:
                _score += SCORE_BASIC_4
            else:
                _score += SCORE_BASIC_3

            yield redis.zadd(redis_key, cid, -_score)
            defer.returnValue((_score, _score_reduce))

        # 玩家
        _other_score = yield self.get_char_score(other_cid)
        if _score > _other_score:
            _score_add = (_other_score * SCORE_RATE_2 + SCORE_PERCENT -
                          1) / SCORE_PERCENT
            _score_reduce = _score / SCORE_PERCENT
        elif _score < _other_score:
            _score_add = (_other_score * SCORE_RATE_4 + SCORE_PERCENT -
                          1) / SCORE_PERCENT + SCORE_BASIC_4
            _score_reduce = _score * SCORE_RATE_4 / SCORE_PERCENT
        else:
            _score_add = (_other_score * SCORE_RATE_3 + SCORE_PERCENT -
                          1) / SCORE_PERCENT + SCORE_BASIC_3
            _score_reduce = _score * SCORE_RATE_2 / SCORE_PERCENT

        #log.info('For Test. cid<{0}> score: {1} add<{2}>, other_cid<{3}> score: {4} reduce<{5}>.'.format( cid, _score, _score_add, other_cid, _other_score, _score_reduce ))
        _score += _score_add
        yield redis.zadd(redis_key, cid, -_score)
        _other_score = (_other_score -
                        _score_reduce) if _other_score > _score_reduce else 0
        yield redis.zadd(redis_key, other_cid, -_other_score)

        defer.returnValue((_score, _score_reduce))
Beispiel #7
0
    def reward_to_award_center(self, total_count, interval):
        try:
            timestamp = int(time())
            start_rank = total_count - interval + 1 if total_count > interval else 0
            all_cids = yield redis.zrange(SET_JOUST_LAST_CID_SCORE, start_rank,
                                          total_count)
            for _idx, _cid in enumerate(all_cids):
                _rank = (_idx + start_rank + 1)
                yield g_AwardCenterMgr.new_award(_cid, AWARD_TYPE_JOUSTRANK,
                                                 [timestamp, _rank])
                # Reset score
                yield redis.zadd(SET_JOUST_CID_SCORE, _cid, -JOUST_BASIC_SCORE)
        except Exception as e:
            log.exception()

        if total_count > interval:
            total_count -= interval
            reactor.callLater(1, self.reward_to_award_center, total_count,
                              interval)
Beispiel #8
0
    def __migrate_accounts_registered(self):
        try:
            yield redis.delete(HASH_NICKNAME_REGISTERED,
                               HASH_MACHINE_CODE_REGISTERED,
                               HASH_UID_MACHINE_CODE, SET_RANK_PVP_WEIGHT)

            db_conf = {
                'host': setting.DB_CONF['host'],
                'port': setting.DB_CONF['port'],
                'user': setting.DB_CONF['user'],
                'passwd': setting.DB_CONF['pass'],
                'db': setting.DB_CONF['userdb'],
                'charset': 'utf8'
            }

            conn = MySQLdb.connect(**db_conf)
            cu = conn.cursor()

            cu.execute(
                'SELECT `id`,`machine_code`,`nickname`,`max_weight` FROM tb_character'
            )
            _dataset = cu.fetchall()
            for _id, _machine_code, _nickname, _max_weight in _dataset:
                yield redis.hset(HASH_NICKNAME_REGISTERED, _nickname, _id)
                yield redis.hset(HASH_MACHINE_CODE_REGISTERED, _machine_code,
                                 _id)
                yield redis.hset(HASH_UID_MACHINE_CODE, _id, _machine_code)
                yield redis.zadd(SET_RANK_PVP_WEIGHT, _id, -_max_weight)

            cu.close()
            conn.close()

            conn = None
            cu = None
        except Exception, e:
            reactor.callLater(1, self.__migrate_accounts_registered)
            print 'ERROR:', e
            print 'WARNING. Redis connection fail, callLater 1 second. redis:', redis
Beispiel #9
0
    def attack(self, user, damage):
        _now = time()

        if self._attack_time:
            if (_now - self._attack_time) < ATTACK_CD:
                log.warn('[ attack ]CD time. last attack time:{0}, now:{1}.',
                         self._attack_time, _now)
                defer.returnValue((WORLDBOSS_CD, None))

        _current_life = worldBoss.life
        if _current_life <= 0:
            defer.returnValue((WORLDBOSS_DEAD_ALREADY, None))

        self._attack_count += 1
        '''
        转到客户端算
        _attack_extra = self._attack_extra_level * 5
        damage = int(int(damage) * (100 + _attack_extra) / 100)
        '''
        self._damage_total += damage

        _farm = 10
        user.base_att.prestige += _farm

        worldBoss.on_attack(self._cid, user.nick_name, damage)

        self._attack_time = _now

        self.sync()

        yield redis.zadd(RANK_WORLDBOSS_DAMAGE, self._cid, -self._damage_total)
        yield redis.hset(DICT_WORLDBOSS_RANKER_DATA, self._cid,
                         dumps((user.nick_name, user.level, user.alliance_id)))

        #log.debug('attack come here...', self, self.__dict__)
        _current_rank = yield self.rank
        defer.returnValue((NO_ERROR, (self._damage_total, _farm,
                                      worldBoss.life, _current_rank + 1)))
Beispiel #10
0
    def attack(self, user, damage):
        _now = time()

        if self._attack_time:
            if (_now - self._attack_time) < ATTACK_CD:
                log.warn('[ attack ]CD time. last attack time:{0}, now:{1}.', self._attack_time, _now)
                defer.returnValue((WORLDBOSS_CD, None))

        _current_life = worldBoss.life
        if _current_life <= 0:
            defer.returnValue((WORLDBOSS_DEAD_ALREADY, None))

        self._attack_count += 1

        '''
        转到客户端算
        _attack_extra = self._attack_extra_level * 5
        damage = int(int(damage) * (100 + _attack_extra) / 100)
        '''
        self._damage_total += damage

        _farm = 10
        user.base_att.prestige += _farm

        worldBoss.on_attack(self._cid, user.nick_name, damage)

        self._attack_time  = _now

        self.sync()

        yield redis.zadd(RANK_WORLDBOSS_DAMAGE, self._cid, -self._damage_total)
        yield redis.hset(DICT_WORLDBOSS_RANKER_DATA, self._cid, dumps((user.nick_name, user.level, user.alliance_id)))

        #log.debug('attack come here...', self, self.__dict__)
        _current_rank = yield self.rank
        defer.returnValue((NO_ERROR, (self._damage_total, _farm, worldBoss.life, _current_rank+1)))
Beispiel #11
0
    def newUser(self, uid):
        if not self.__users:
            # common foodball and spineball
            self.__foodball = get_all_foodball()
            self.__spineball = get_all_spineball()
            foodball_conf = self.__foodball.values()
            spineball_conf = self.__spineball.values()
            self.__end_time = int((time() + PVP_SECONDS)*1000)
            #reactor.callLater(PVP_SECONDS, self._broadcastFoodball)
        else:
            foodball_conf = self.__foodball.values()
            spineball_conf = self.__spineball.values()

        self.__eat_num.setdefault(uid, 0)
        self.__be_eated_num.setdefault(uid, 0)

        userball_obj = Userball(uid)
        self.__users[uid] = userball_obj
        all_userball = userball_obj.initBall(self.count)
        for _ub in self.__users.itervalues():
            if _ub.uid == uid:
                continue
            all_userball.extend(_ub.getAllBall())
        yield redis.zadd(SET_RANK_ROOM_VOLUME%self.__id, uid, -INIT_USERBALL_VOLUME)
        rank = yield redis.zrank(SET_RANK_ROOM_VOLUME%self.__id, uid)
        rank = 0 if rank is None else int(rank) + 1

        data = {'userball': all_userball, \
                'foodball': foodball_conf, \
                'spineball': spineball_conf, \
                'end_time': self.__end_time, \
                'total': self.count, 
                'rank': rank, \
                'room_id': self.__id,
                }
        defer.returnValue(data)
Beispiel #12
0
    def syncUserball(self, character, ball_info, status):
        uid = character.attrib_id
        if not (ball_info and isinstance(ball_info[0], list)):
            log.error("args error. uid:{0}, ball_info:{1}.".format(uid, ball_info))
            defer.returnValue((ARGS_ERROR, None))

        if uid not in self.__users:
            log.error("user not in room error. uid:{0}, room_id:{1}.".format(uid, self.__id))
            defer.returnValue((PVPROOM_LOSE, None))

        _hide_fb_ids = list()
        userball_obj = self.__users[uid]
        if userball_obj.isDead:
            log.warn("room uids:{0}, __eat_num:{1}, __be_eated_num:{2}, uid:{3}, isDead:{4}, status:{5}.".format(self.__users.keys(), self.__eat_num, self.__be_eated_num, uid, userball_obj.isDead, status))
            if status:
                userball_obj.revive()
            else:
                log.error("user is dead. uid:{0}, isDead:{1}, status:{2}.".format(uid, userball_obj.isDead, status))
                defer.returnValue((USER_IS_DEAD, None))
        _hide_ub_ids, _delta_volume, ball_info = userball_obj.checkHideBall(ball_info)

        #_delta_br =  int(FOODBALL_RADIUS * MULTIPLE_ENLARGE_FOODBALL * 0.01)
        _max_hide = 1
        for _bid, _bx, _by, _bz in self.__foodball.itervalues():
            for _, ball_id, ball_x, ball_y, ball_z, ball_r, ball_v, ball_s, pow_r in ball_info:
                # 和食物球 其它玩家球比较半径大小 计算直线距离
                # 玩家球 分裂后的半径也会比食物球大吗?
                _distance = pow(ball_x-_bx, 2) + pow(ball_y-_by, 2) + pow(ball_z-_bz, 2)
                if _distance < pow_r:
                    log.warn('--------------- eated foodball uid:{0}, pow_r:{1}, _distance:{2}, source:{3}, target:{4}, _delta_volume:{5}.'.format(uid, pow_r, _distance, (ball_id, ball_x, ball_y, ball_z, ball_r), (_bid, _bx, _by, _bz), _delta_volume))
                    # 自身体积增长
                    _delta_volume[ball_id] = _delta_volume.setdefault(ball_id, ball_v) + INIT_FOODBALL_VOLUME
                    _hide_fb_ids.append(_bid)
                if len(_hide_fb_ids) > 2:
                    break
        for _bid in _hide_fb_ids:
            self.__hide_foodball_ids[_bid] = 0
            if _bid in self.__foodball:
                del self.__foodball[_bid]
        # uid and ballid
        for _ub in self.__users.itervalues():
            if _ub.isDead:
                log.error('----------------- user is dead. room_id:{0}, uid:{1}, isDead:{2}'.format(self.__id, _ub.uid, _ub.isDead))
            if _ub.uid == uid or _ub.isDead:
                continue
            _all_ball = _ub.getAllBall()
            for _uid, _bid, _bx, _by, _bz, _br, _bv, _bs in iter(_all_ball):
                _be_eated_user = g_UserMgr.getUserByUid(_uid)
                for _, ball_id, ball_x, ball_y, ball_z, ball_r, ball_v, ball_s, pow_r in ball_info:
                    if MULTIPLE_HIDE_USERBALL*_bv > ball_v:
                        continue
                    _distance = pow(ball_x-_bx, 2) + pow(ball_y-_by, 2) + pow(ball_z-_bz, 2)
                    if _distance < pow_r:
                        log.warn('---------------- eated userball uid:{0}, pow_r:{1}, _distance:{2}, source:{3}, target:{4}.'.format(uid, pow_r, _distance, (_uid, _bid, _bx, _by, _bz, _br), (ball_id, ball_x, ball_y, ball_z, ball_r)))
                        # 记录吞噬/被吞噬 玩家球的个数
                        character.eat_num += 1
                        self.__eat_num[uid] += 1
                        if _be_eated_user and _be_eated_user.attrib:
                            _be_eated_user.attrib.be_eated_num += 1
                            self.__be_eated_num[_uid] = self.__be_eated_num.setdefault(_uid, 0) + 1

                        # 自身体积增长
                        _delta_volume[ball_id] = _delta_volume.setdefault(ball_id, ball_v) + _bv
                        _ub.setHideBall(_bid)
                        _hide_ub_ids.append((_uid, _bid))
                        yield redis.zincrby(SET_RANK_ROOM_VOLUME%self.__id, _uid, _bv)

        data = list()
        _delta_ub_data = list()
        _delta_ub_volume = 0
        for _, ball_id, ball_x, ball_y, ball_z, ball_r, ball_v, ball_s, pow_r in ball_info:
            ball_v = _delta_volume[ball_id] if ball_id in _delta_volume else ball_v
            _delta_ub_data.append((uid, ball_id, ball_x, ball_y, ball_z, ball_r, ball_v, ball_s))
            _delta_ub_volume += ball_v
        # 更新自己的球体积排行榜
        yield redis.zadd(SET_RANK_ROOM_VOLUME%self.__id, uid, -_delta_ub_volume)
        # 更新自己的球体积信息
        userball_obj.updateVolume(_delta_volume)
        if (_hide_ub_ids or _hide_fb_ids or _delta_ub_data):
            data = [_hide_ub_ids, _hide_fb_ids, _delta_ub_data]
            #TODO broadcast
            uids = self.__users.keys()
            uids.remove(uid)
            if uids:
                send2client(uids, 'broadcastUserball', data)
        if _hide_ub_ids or _hide_fb_ids:
            log.error("-------------- final hide info. room_id:{0}, uid:{1}, _hide_ub_ids:{2}, _hide_fb_ids:{3}".format(self.__id, uid, _hide_ub_ids, _hide_fb_ids))

        _rank = yield redis.zrank(SET_RANK_ROOM_VOLUME%self.__id, uid)
        _rank = 0 if _rank is None else int(_rank) + 1 
        _total = len(self.__users)
        data.append((_rank, _total))
        defer.returnValue((NO_ERROR, data))
    def climbing_reward(self, fight_layer, status):
        '''
        @summary: 单次通关失败扣挑战次数, 更新玩家当前所在塔层及最大塔层, 给通关后的奖励
        '''
        self.system_daily_reset()
        # 可挑战的塔层数据不同步
        if fight_layer != self.climbing.cur_layer:
            log.error(
                'User request fight_layer error. cid: {0}, fight_layer: {1}, cur_layer: {2}.'
                .format(self.cid, fight_layer, self.climbing.cur_layer))
            defer.returnValue(REQUEST_LIMIT_ERROR)
        # 没有挑战次数不能挑战
        climbing_data = self.get_vip_conf_of_climbing()
        if (climbing_data[0] + self.climbing.buyed_fight < 1):
            log.error(
                'User no fight count. cid: {0}, had_free_fight: {1}, buyed_fight: {2}.'
                .format(self.cid, self.climbing.free_fight,
                        self.climbing.buyed_fight))
            defer.returnValue(REQUEST_LIMIT_ERROR)
        # 已经到了最大塔层 不能继续挑战
        if self.climbing.cur_layer >= self.MAX_LAYER:
            log.error(
                'Had been the max layer. cur_layer: {0}, climbing_tower MAX_LAYER: {1}.'
                .format(self.climbing.cur_layer, self.MAX_LAYER))
            defer.returnValue(IN_CLIMBING_MAX_LAYER)
        # 每日任务计数
        yield self.user.daily_quest_mgr.update_daily_quest(DAILY_QUEST_ID_9, 1)
        yield self.user.open_server_mgr.update_open_server_activity_quest(
            OPEN_SERVER_QUEST_ID_10, self.climbing.cur_layer)
        #成就
        yield self.user.achievement_mgr.update_achievement_status(
            ACHIEVEMENT_QUEST_ID_10, self.climbing.cur_layer)
        if not status:  # 通关失败
            if self.climbing.buyed_fight > 0:
                self.climbing.buyed_fight -= 1
            elif climbing_data[0] > 0:
                climbing_data[0] -= 1
                self.climbing.free_fight += 1
            defer.returnValue(
                (status, self.climbing.cur_layer, self.climbing.max_layer,
                 climbing_data[0] + self.climbing.buyed_fight, [], 0, 0, 0,
                 self.user.base_att.energy))

        # 获取塔层通过的奖励
        conf = get_climbing_conf(self.climbing.cur_layer)
        if not conf:
            log.error('No conf. cid: {0}, cur_layer: {0}.'.format(
                cid, self.climbing.cur_layer))
            defer.returnValue(NOT_FOUND_CONF)

        #self.user.base_att.golds += conf['RewardGold']
        self.user.get_golds(conf['RewardGold'], WAY_CLIMBING_AWARD)
        self.user.base_att.soul += conf['RewardSoul']
        items_return = []
        #log.info('For Test. cur_layer: {0}, BonusList: {1}.'.format( self.climbing.cur_layer, conf['BonusList'] ))
        for _type, _id, _num in conf['BonusList']:
            model = ITEM_MODELs.get(_type, None)
            if not model:
                log.error('Unknown item type. item: {0}.'.format(
                    (_type, _id, _num)))
                continue
            res_err, value = yield model(self.user,
                                         ItemID=_id,
                                         ItemNum=_num,
                                         AddType=WAY_CLIMBING_AWARD,
                                         CapacityFlag=False)
            if not res_err and value:
                #log.info('For Test. value: {0}.'.format( value ))
                for _v in value:
                    items_return = total_new_items(_v, items_return)
        #log.info('For Test. after BonusList: {0}.'.format( conf['BonusList'] ))

        if self.climbing.cur_layer >= self.MAX_LAYER:
            self.climbing.cur_layer = self.MAX_LAYER
        else:
            self.climbing.cur_layer += 1

        # 挑战更高的塔层
        if (self.climbing.cur_layer <= self.MAX_LAYER) and (
                self.climbing.cur_layer > self.climbing.max_layer):
            self.climbing.max_layer += 1
        if self.climbing.max_layer > self.MAX_LAYER:
            self.climbing.max_layer = self.MAX_LAYER

        # 更新天外天排行榜
        yield redis.zadd(SET_CLIMBING_CID_LAYER, self.cid,
                         -self.climbing.max_layer)

        defer.returnValue(
            (status, self.climbing.cur_layer, self.climbing.max_layer,
             climbing_data[0] + self.climbing.buyed_fight, items_return,
             conf['RewardGold'], conf['RewardSoul'], 0,
             self.user.base_att.energy))
Beispiel #14
0
    def get_battle_reward(self, status, scene_id, dungeon_id, dungeon_star):
        '''
        @summary: 战斗结束领取奖励
        @param  : 战斗结果 status 0:lose, 1:win
        '''
        yield self._load()
        if scene_id != self.cur_scene_id or dungeon_id != self.cur_dungeon_id or dungeon_star != self.cur_dungeon_star:
            log.error('Player battle info not match. old_scene_id: {0}, old_dungeon_id: {1}, old_dungeon_star: {2}.'.format( self.cur_scene_id, self.cur_dungeon_id, self.cur_dungeon_star ))
            #defer.returnValue( REQUEST_LIMIT_ERROR )
 
        dungeon = yield self.get_dungeon( scene_id, dungeon_id )
        if not dungeon:
            log.error('Unknown dungeon id. scene_id: {0}, dungeon_id: {1}.'.format( scene_id, dungeon_id ))
            defer.returnValue( REQUEST_LIMIT_ERROR )

        self.cur_scene_id, self.cur_dungeon_id, self.cur_dungeon_star = 0, 0, 0

        # 战斗失败
        if not status:
            syslogger(LOG_SCENE_BATTLE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, 1, status, dungeon_id, dungeon_star, 0, 0, 0, '')
            defer.returnValue( (1, status, dungeon_id, dungeon.dungeon_star, dungeon.dungeon_today_count, [], 0, 0, 0, self.user.base_att.energy) )

        # monster奖励金币、仙魂、经验
        exp_reward, golds_reward, soul_reward = 0, 0, 0
        monster_conf = get_monster_conf(dungeon_id, dungeon_star)
        no_energy = False
        if monster_conf:
            # 策划修改-副本的精力消耗改为5点
            if self.user.base_att.energy >= 5:
                self.user.base_att.energy -= 5
                exp_reward = self.user.base_att.level * BATTLE_MONSTER_EXP_RATIO
            else:
                no_energy = True
                exp_reward = self.user.base_att.level
            soul_reward  = monster_conf['Soul']
            golds_reward = monster_conf['Money']
        else:
            log.error('Can not find monster.')
        # 获取怪物组掉落
        drop_items = yield self.dungeon_star_drop( dungeon_id, dungeon_star, no_energy )
        # 判断是否是第一次挑战更高星级难度
        if dungeon_star > dungeon.dungeon_star:
            dungeon.dungeon_star = dungeon_star
            # 新增混沌星数
            self.user.base_att.scene_star += 1
            # 新增副本总星数
            self.total_star += 1
            yield redis.zadd(SET_SCENE_CID_STAR, self.cid, -self.total_star)
            # 更新最大副本ID
            if scene_id > self.max_scene_id:
                self.max_scene_id = scene_id
            syslogger(LOG_SCENESTAR_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, 1, self.user.base_att.scene_star, dungeon_id, dungeon_star)
        dungeon.dungeon_today_count += 1
        dungeon.dungeon_last_time    = datetime.now()

        # 新增掉落
        way_others = str((FIGHT_TYPE_NORMAL, dungeon_id, dungeon_star))
        dungeon_drop_items = yield self.get_dungeon_drop( drop_items, way_others )

        # 发放奖励
        yield self.user.update_battle_attr( soul_reward, golds_reward, exp_reward )

        # 每日任务计数
        yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_3, 1 )
        # 开服七天
        yield self.user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_3, dungeon_id)
        #成就
        yield self.user.achievement_mgr.update_achievement_status(ACHIEVEMENT_QUEST_ID_3, dungeon_id)
        yield self.user.achievement_mgr.update_alliance_level()
        # add syslog
        str_drop_items = str(dungeon_drop_items).replace('[', '(')
        str_drop_items = str_drop_items.replace(']', ')')
        syslogger(LOG_SCENE_BATTLE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, FIGHT_TYPE_NORMAL, status, dungeon_id, dungeon_star, exp_reward, soul_reward, golds_reward, str_drop_items)

        defer.returnValue( (1, status, dungeon_id, dungeon.dungeon_star, dungeon.dungeon_today_count, dungeon_drop_items, golds_reward, soul_reward, exp_reward, self.user.base_att.energy) )
Beispiel #15
0
    def randcard(self, rand_type):
        ''' 免费抽卡、钻石抽卡 '''
        _status, _data = yield self.status()
        if _status < 0:
            defer.returnValue( LIMIT_FELLOW_NO_ERROR )
        _need_time = self.left_free_timestamp( _data[3], LIMIT_FELLOW_FREE_TIME )
        _last_time = _data[3]
        # 检查抽卡条件是否满足
        _score = yield redis.zscore( SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name )
        _score = int(_score) if _score else 0
        _cost_flag = True # 扣钻石的标识位
        if rand_type == RANDCARD_TYPE_FREE:
            if _need_time > 0:
                defer.returnValue( LIMIT_FELLOW_FREE_ERROR )
            else:
                _last_time = int(time())
                _cost_flag = False
                _need_time = LIMIT_FELLOW_FREE_TIME
        else:
            # 某积分的整数倍时免费钻石抽卡
            if not _score or _score%RAND_COST_FREE_SCORE != 0:
                if self.user.credits < LIMIT_FELLOW_RAND_COST:
                    defer.returnValue( CHAR_CREDIT_NOT_ENOUGH )
            else:
                _cost_flag = False
        # 卡池升级
        res_err, shrine_data = self.update_shrine(_data[1], _data[2])
        if res_err:
            defer.returnValue( res_err )
        #log.info('For Test. shrine_data: {0}, redis_data: {1}.'.format( shrine_data, _data ))
        # 获取抽卡池并抽卡
        card_conf = self.get_randcard_frompool(_data[1], shrine_data[3]-_data[2])
        if not card_conf:
            defer.returnValue( NOT_FOUND_CONF )

        # 更新免费时间或扣钻石
        yield redis.hset( HASH_LIMIT_FELLOW_SHRINE, self.cid, dumps([_data[0], shrine_data[0], shrine_data[1], _last_time]) )
        if _cost_flag:
            yield self.user.consume_credits( LIMIT_FELLOW_RAND_COST, WAY_LIMIT_FELLOW_RANDCARD )
        _score += RANDCARD_ONCE_SCORE
        yield redis.zadd( SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name, _score )
        # 新增fellow
        try:
            # args: fellow_id, is_major, camp_id, on_troop
            new_fellow = []
            fellow_id  = card_conf['ItemId']
            res_err, attrib = yield self.user.fellow_mgr.create_table_data( fellow_id, 0, 0, 0 )
            if not res_err:
                new_fellow = [attrib.attrib_id, fellow_id]
                conf = get_fellow_by_fid( fellow_id )
                if conf and conf['Quality'] == QUALITY_PURPLE:
                    syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, \
                            attrib.attrib_id, fellow_id, conf['QualityLevel'], conf['Star'], RANDCARD_TYPE_CREDITS, '')
                    message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_LIMIT_FELLOW, [self.user.nick_name, fellow_id]]]
                    gw_broadcast('sync_broadcast', [message])
        except Exception as e:
            log.warn('Create fellow fail! e:', e)
            defer.returnValue(res_err)

        _rank  = yield redis.zrevrank( SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name )
        _rank  = int(_rank) + 1 if _rank >= 0 else 0
        _ranklist = yield self.ranklist()
        defer.returnValue( [self.user.credits, _rank, _score, _need_time, shrine_data[2], _ranklist, new_fellow] )
Beispiel #16
0
    def lottery_items(self, user, client_my_rank, enemy_rank, battle_status):
        '''
        @summary: 挑战胜利后,替换双方的排名,并返回可供翻牌的道具列表。长度为3。
        '''
        items_list = []
        # 判断是否处于结算时间 22:00-22:15
        _dt_now    = datetime.now()
        if _dt_now.hour == ARENA_RANK_REWARD_HOUR and _dt_now.minute < 15:
            defer.returnValue( ARENA_IN_REWARD_TIME )

        # 扣斗战点 2点
        if user.base_att.douzhan < PVP_NEED_DOUZHAN:
            log.error('user douzhan is 0. cid: {0}.'.format( user.cid ))
            defer.returnValue( CHAR_DOUZHAN_NOT_ENOUGH )
        user.base_att.douzhan -= PVP_NEED_DOUZHAN

        # 获取我的排名
        my_rank = yield self.get_char_rank( user.cid )
        if my_rank != client_my_rank:
            log.error('Client arena rank info need update. cid: {0}, client_my_rank: {1}, my_rank: {2}.'.format( user.cid, client_my_rank, my_rank ))
        # 每日任务计数
        yield user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_6, 1 )

        if not battle_status:
            # 失败获得10声望值
            user.get_prestige( 10, WAY_ARENA_BATTLE )
            enemy_detail = yield self.get_rank_detail( enemy_rank, flag=False )
            if not enemy_detail:
                log.error('No enemy rank data. cid: {0}, enemy_rank: {1}.'.format( user.cid, enemy_rank ))
                defer.returnValue( (items_list, user.base_att.douzhan) )

            ms_send('write_mail', (enemy_detail[0], MAIL_PAGE_BATTLE, MAIL_BATTLE_1, [user.base_att.lead_id, user.base_att.nick_name]))
            defer.returnValue( (items_list, user.base_att.douzhan) )

        # 胜利获得20声望值
        user.get_prestige( 20, WAY_ARENA_BATTLE )
        items_list = yield random_lottery_items( user.cid, user.base_att.level, user.base_att.vip_level )
        # 名次越靠前, 数字越小; 没有排名时也直接替换
        enemy_detail = yield self.get_rank_detail( enemy_rank, flag=False )
        if not enemy_detail:
            log.error('No enemy rank data. cid: {0}, enemy_rank: {1}.'.format( user.cid, enemy_rank ))
            defer.returnValue( (items_list, user.base_att.douzhan) )
        if my_rank == 0 or enemy_rank < my_rank:
            # 对方是玩家时 互换玩家信息
            if enemy_detail[0] > 0:
                old_enemy_rank = yield self.get_char_rank( enemy_detail[0] )
                if my_rank == 0: # 在排名5000(机器人总数)之外
                    yield redis.zrem( SET_ARENA_CID_RANK, enemy_detail[0] )
                    alli_send('sync_char_data', (enemy_detail[0], SYNC_ARENA_RANK, 0))
                else:
                    if old_enemy_rank == enemy_rank:
                        ms_send('write_mail', (enemy_detail[0], MAIL_PAGE_BATTLE, MAIL_BATTLE_2, [user.base_att.lead_id, user.base_att.nick_name, my_rank]))
                        yield redis.zadd( SET_ARENA_CID_RANK, enemy_detail[0], my_rank )
                        alli_send('sync_char_data', (enemy_detail[0], SYNC_ARENA_RANK, my_rank))
                        old_rank_detail = dumps( [enemy_detail[0], enemy_detail[1], enemy_detail[2], my_rank, 0, 0, [], enemy_detail[7]] )
                        yield redis.hset( HASH_ARENA_RANK, my_rank, old_rank_detail )
            elif my_rank > 0: # 对手是机器人, 恢复当前排名机器人数据
                old_rank_detail = dumps( [0, 0, '', my_rank, 0, 0, [], 0] )
                yield redis.hset( HASH_ARENA_RANK, my_rank, old_rank_detail )

            # 更新自己的rank数据
            yield redis.zadd( SET_ARENA_CID_RANK, user.cid, enemy_rank )
            alli_send('sync_char_data', (user.cid, SYNC_ARENA_RANK, enemy_rank))
            # 保存当前的camp
            #yield user.sync_camp_to_redis(update=True)
            new_rank_detail = dumps( [user.cid, user.level, user.nick_name, enemy_rank, 0, 0, [], user.lead_id] )
            yield redis.hset( HASH_ARENA_RANK, enemy_rank, new_rank_detail )
            # 夺得竞技场前十名, 全服广播
            if enemy_rank < 11:
                message = [RORATE_MESSAGE_ACHIEVE, [ACHIEVE_TYPE_ARENA, [user.base_att.nick_name, enemy_rank]]]
                gw_broadcast('sync_broadcast', [message])
        elif enemy_rank > my_rank:
            ms_send('write_mail', (enemy_detail[0], MAIL_PAGE_BATTLE, MAIL_BATTLE_3, [user.base_att.lead_id, user.base_att.nick_name]))
        #开服狂欢
        enemy_rank = enemy_rank if enemy_rank < my_rank else my_rank
        yield user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_7, enemy_rank)
        yield user.achievement_mgr.update_achievement_status( ACHIEVEMENT_QUEST_ID_7, enemy_rank)
        defer.returnValue( (items_list, user.base_att.douzhan) )
    def climbing_reward(self, fight_layer, status):
        '''
        @summary: 单次通关失败扣挑战次数, 更新玩家当前所在塔层及最大塔层, 给通关后的奖励
        '''
        self.system_daily_reset()
        # 可挑战的塔层数据不同步
        if fight_layer != self.climbing.cur_layer:
            log.error('User request fight_layer error. cid: {0}, fight_layer: {1}, cur_layer: {2}.'.format( self.cid, fight_layer, self.climbing.cur_layer ))
            defer.returnValue( REQUEST_LIMIT_ERROR )
        # 没有挑战次数不能挑战
        climbing_data = self.get_vip_conf_of_climbing()
        if (climbing_data[0] + self.climbing.buyed_fight < 1):
            log.error('User no fight count. cid: {0}, had_free_fight: {1}, buyed_fight: {2}.'.format( self.cid, self.climbing.free_fight, self.climbing.buyed_fight ))
            defer.returnValue( REQUEST_LIMIT_ERROR )
        # 已经到了最大塔层 不能继续挑战
        if self.climbing.cur_layer >= self.MAX_LAYER:
            log.error('Had been the max layer. cur_layer: {0}, climbing_tower MAX_LAYER: {1}.'.format( self.climbing.cur_layer, self.MAX_LAYER ))
            defer.returnValue( IN_CLIMBING_MAX_LAYER )
        # 每日任务计数
        yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_9, 1 )
        yield self.user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_10, self.climbing.cur_layer)
        #成就
        yield self.user.achievement_mgr.update_achievement_status( ACHIEVEMENT_QUEST_ID_10, self.climbing.cur_layer)
        if not status: # 通关失败
            if self.climbing.buyed_fight > 0:
                self.climbing.buyed_fight -= 1
            elif climbing_data[0] > 0:
                climbing_data[0] -= 1
                self.climbing.free_fight += 1
            defer.returnValue( (status, self.climbing.cur_layer, self.climbing.max_layer, climbing_data[0]+self.climbing.buyed_fight, [], 0, 0, 0, self.user.base_att.energy) )
 
        # 获取塔层通过的奖励
        conf = get_climbing_conf( self.climbing.cur_layer )
        if not conf:
            log.error('No conf. cid: {0}, cur_layer: {0}.'.format( cid, self.climbing.cur_layer ))
            defer.returnValue( NOT_FOUND_CONF )

        #self.user.base_att.golds += conf['RewardGold']
        self.user.get_golds( conf['RewardGold'], WAY_CLIMBING_AWARD )
        self.user.base_att.soul  += conf['RewardSoul']
        items_return = []
        #log.info('For Test. cur_layer: {0}, BonusList: {1}.'.format( self.climbing.cur_layer, conf['BonusList'] ))
        for _type, _id, _num in conf['BonusList']:
            model = ITEM_MODELs.get( _type, None )
            if not model:
                log.error('Unknown item type. item: {0}.'.format( (_type, _id, _num) ))
                continue
            res_err, value = yield model(self.user, ItemID=_id, ItemNum=_num, AddType=WAY_CLIMBING_AWARD, CapacityFlag=False)
            if not res_err and value:
                #log.info('For Test. value: {0}.'.format( value ))
                for _v in value:
                    items_return = total_new_items( _v, items_return )
        #log.info('For Test. after BonusList: {0}.'.format( conf['BonusList'] ))

        if self.climbing.cur_layer >= self.MAX_LAYER:
            self.climbing.cur_layer = self.MAX_LAYER
        else:
            self.climbing.cur_layer += 1

        # 挑战更高的塔层
        if (self.climbing.cur_layer <= self.MAX_LAYER) and (self.climbing.cur_layer > self.climbing.max_layer):
            self.climbing.max_layer += 1
        if self.climbing.max_layer > self.MAX_LAYER:
            self.climbing.max_layer = self.MAX_LAYER

        # 更新天外天排行榜
        yield redis.zadd(SET_CLIMBING_CID_LAYER, self.cid, -self.climbing.max_layer)

        defer.returnValue( (status, self.climbing.cur_layer, self.climbing.max_layer, climbing_data[0]+self.climbing.buyed_fight, items_return, conf['RewardGold'], conf['RewardSoul'], 0, self.user.base_att.energy) )
Beispiel #18
0
    def randcard(self, rand_type):
        ''' 免费抽卡、钻石抽卡 '''
        _status, _data = yield self.status()
        if _status < 0:
            defer.returnValue(LIMIT_FELLOW_NO_ERROR)
        _need_time = self.left_free_timestamp(_data[3], LIMIT_FELLOW_FREE_TIME)
        _last_time = _data[3]
        # 检查抽卡条件是否满足
        _score = yield redis.zscore(SET_LIMIT_FELLOW_NAME_SCORE,
                                    self.user.nick_name)
        _score = int(_score) if _score else 0
        _cost_flag = True  # 扣钻石的标识位
        if rand_type == RANDCARD_TYPE_FREE:
            if _need_time > 0:
                defer.returnValue(LIMIT_FELLOW_FREE_ERROR)
            else:
                _last_time = int(time())
                _cost_flag = False
                _need_time = LIMIT_FELLOW_FREE_TIME
        else:
            # 某积分的整数倍时免费钻石抽卡
            if not _score or _score % RAND_COST_FREE_SCORE != 0:
                if self.user.credits < LIMIT_FELLOW_RAND_COST:
                    defer.returnValue(CHAR_CREDIT_NOT_ENOUGH)
            else:
                _cost_flag = False
        # 卡池升级
        res_err, shrine_data = self.update_shrine(_data[1], _data[2])
        if res_err:
            defer.returnValue(res_err)
        #log.info('For Test. shrine_data: {0}, redis_data: {1}.'.format( shrine_data, _data ))
        # 获取抽卡池并抽卡
        card_conf = self.get_randcard_frompool(_data[1],
                                               shrine_data[3] - _data[2])
        if not card_conf:
            defer.returnValue(NOT_FOUND_CONF)

        # 更新免费时间或扣钻石
        yield redis.hset(
            HASH_LIMIT_FELLOW_SHRINE, self.cid,
            dumps([_data[0], shrine_data[0], shrine_data[1], _last_time]))
        if _cost_flag:
            yield self.user.consume_credits(LIMIT_FELLOW_RAND_COST,
                                            WAY_LIMIT_FELLOW_RANDCARD)
        _score += RANDCARD_ONCE_SCORE
        yield redis.zadd(SET_LIMIT_FELLOW_NAME_SCORE, self.user.nick_name,
                         _score)
        # 新增fellow
        try:
            # args: fellow_id, is_major, camp_id, on_troop
            new_fellow = []
            fellow_id = card_conf['ItemId']
            res_err, attrib = yield self.user.fellow_mgr.create_table_data(
                fellow_id, 0, 0, 0)
            if not res_err:
                new_fellow = [attrib.attrib_id, fellow_id]
                conf = get_fellow_by_fid(fellow_id)
                if conf and conf['Quality'] == QUALITY_PURPLE:
                    syslogger(LOG_FELLOW_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, \
                            attrib.attrib_id, fellow_id, conf['QualityLevel'], conf['Star'], RANDCARD_TYPE_CREDITS, '')
                    message = [
                        RORATE_MESSAGE_ACHIEVE,
                        [
                            ACHIEVE_TYPE_LIMIT_FELLOW,
                            [self.user.nick_name, fellow_id]
                        ]
                    ]
                    gw_broadcast('sync_broadcast', [message])
        except Exception as e:
            log.warn('Create fellow fail! e:', e)
            defer.returnValue(res_err)

        _rank = yield redis.zrevrank(SET_LIMIT_FELLOW_NAME_SCORE,
                                     self.user.nick_name)
        _rank = int(_rank) + 1 if _rank >= 0 else 0
        _ranklist = yield self.ranklist()
        defer.returnValue([
            self.user.credits, _rank, _score, _need_time, shrine_data[2],
            _ranklist, new_fellow
        ])
Beispiel #19
0
    def get_battle_reward(self, status, scene_id, dungeon_id, dungeon_star):
        '''
        @summary: 战斗结束领取奖励
        @param  : 战斗结果 status 0:lose, 1:win
        '''
        yield self._load()
        if scene_id != self.cur_scene_id or dungeon_id != self.cur_dungeon_id or dungeon_star != self.cur_dungeon_star:
            log.error(
                'Player battle info not match. old_scene_id: {0}, old_dungeon_id: {1}, old_dungeon_star: {2}.'
                .format(self.cur_scene_id, self.cur_dungeon_id,
                        self.cur_dungeon_star))
            #defer.returnValue( REQUEST_LIMIT_ERROR )

        dungeon = yield self.get_dungeon(scene_id, dungeon_id)
        if not dungeon:
            log.error(
                'Unknown dungeon id. scene_id: {0}, dungeon_id: {1}.'.format(
                    scene_id, dungeon_id))
            defer.returnValue(REQUEST_LIMIT_ERROR)

        self.cur_scene_id, self.cur_dungeon_id, self.cur_dungeon_star = 0, 0, 0

        # 战斗失败
        if not status:
            syslogger(LOG_SCENE_BATTLE, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, 1, status,
                      dungeon_id, dungeon_star, 0, 0, 0, '')
            defer.returnValue((1, status, dungeon_id, dungeon.dungeon_star,
                               dungeon.dungeon_today_count, [], 0, 0, 0,
                               self.user.base_att.energy))

        # monster奖励金币、仙魂、经验
        exp_reward, golds_reward, soul_reward = 0, 0, 0
        monster_conf = get_monster_conf(dungeon_id, dungeon_star)
        no_energy = False
        if monster_conf:
            # 策划修改-副本的精力消耗改为5点
            if self.user.base_att.energy >= 5:
                self.user.base_att.energy -= 5
                exp_reward = self.user.base_att.level * BATTLE_MONSTER_EXP_RATIO
            else:
                no_energy = True
                exp_reward = self.user.base_att.level
            soul_reward = monster_conf['Soul']
            golds_reward = monster_conf['Money']
        else:
            log.error('Can not find monster.')
        # 获取怪物组掉落
        drop_items = yield self.dungeon_star_drop(dungeon_id, dungeon_star,
                                                  no_energy)
        # 判断是否是第一次挑战更高星级难度
        if dungeon_star > dungeon.dungeon_star:
            dungeon.dungeon_star = dungeon_star
            # 新增混沌星数
            self.user.base_att.scene_star += 1
            # 新增副本总星数
            self.total_star += 1
            yield redis.zadd(SET_SCENE_CID_STAR, self.cid, -self.total_star)
            # 更新最大副本ID
            if scene_id > self.max_scene_id:
                self.max_scene_id = scene_id
            syslogger(LOG_SCENESTAR_GET, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, 1,
                      self.user.base_att.scene_star, dungeon_id, dungeon_star)
        dungeon.dungeon_today_count += 1
        dungeon.dungeon_last_time = datetime.now()

        # 新增掉落
        way_others = str((FIGHT_TYPE_NORMAL, dungeon_id, dungeon_star))
        dungeon_drop_items = yield self.get_dungeon_drop(
            drop_items, way_others)

        # 发放奖励
        yield self.user.update_battle_attr(soul_reward, golds_reward,
                                           exp_reward)

        # 每日任务计数
        yield self.user.daily_quest_mgr.update_daily_quest(DAILY_QUEST_ID_3, 1)
        # 开服七天
        yield self.user.open_server_mgr.update_open_server_activity_quest(
            OPEN_SERVER_QUEST_ID_3, dungeon_id)
        #成就
        yield self.user.achievement_mgr.update_achievement_status(
            ACHIEVEMENT_QUEST_ID_3, dungeon_id)
        yield self.user.achievement_mgr.update_alliance_level()
        # add syslog
        str_drop_items = str(dungeon_drop_items).replace('[', '(')
        str_drop_items = str_drop_items.replace(']', ')')
        syslogger(LOG_SCENE_BATTLE, self.cid, self.user.level,
                  self.user.vip_level, self.user.alliance_id,
                  FIGHT_TYPE_NORMAL, status, dungeon_id, dungeon_star,
                  exp_reward, soul_reward, golds_reward, str_drop_items)

        defer.returnValue(
            (1, status, dungeon_id, dungeon.dungeon_star,
             dungeon.dungeon_today_count, dungeon_drop_items, golds_reward,
             soul_reward, exp_reward, self.user.base_att.energy))