[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/masterai-top/Snake-Game-JavaScript-Python-Unity/main/kingday.py [Back]  [Original]

#! -*- coding:utf-8 -*-
# Author:   qianyong
# Created:  2016.06.30 19.43

from freetime.util import log as ftlog
from poker.entity.dao import daobase

from cars.entity import const
from cars.entity import carsconf
from cars.entity.util import UtilFunc

import time


class KingDay(object):
    ''''''

    # 30, winchips, 
    #  {userId: 132, purl: "http://asdfsaf", name: "zhangsan", winChips: 1234}
    _dayRanks = []

    # dayRank
    _dateForDayRank = ''

    # redis
    _lastCheckedRanksAt = 0

    # 30redis
    CHECK_REDIS_RANKS_PERIOD = 30 * 60

    @classmethod
    def initialize(cls):
        ''', timer'''

        UtilFunc.callLater(cls.CHECK_REDIS_RANKS_PERIOD, cls._loopCheckRedisRanksPeriod)

    @classmethod
    def addWinChip(cls, userId, deltaChip, now):
        ''', , '''

        today = cls._todayDate(now)

        # , 
        dayData = UtilFunc.getDayData(userId, today)
        dayData['winChipsForKing'] += deltaChip
        UtilFunc.setDayData(userId, dayData, today)
        userDayWinChips = dayData['winChipsForKing']

        # , 
        dayRanks = cls._getLocalDayRanks(today)
        if len(dayRanks) >= cls._maxRanksCount() and dayRanks[-1]['winChips'] >= userDayWinChips:
            return

        # redis, redis
        daobase.executeRankCmd('ZADD', cls._dayKey(today), -userDayWinChips, userId)

        # 
        cls._updateLocalDayRanks(userId, userDayWinChips, today)

        return userDayWinChips

    @classmethod
    def getTodayGameRanks(cls, now):
        '''20'''

        today = cls._todayDate(now)
        ranks = cls._getLocalDayRanks(today)

        maxCount = carsconf.getKingConf().get('today', {}).get('game_count', 1)
        return ranks[:maxCount]

    @classmethod
    def getYesterdayRanks(cls, now, count=None):
        '''20. redis'''

        yesterday = cls._todayDate(now - const.ONE_DAY_SEC)

        if count is None:
            count = cls._maxRanksCount()

        dayRanks = []
        parts = daobase.executeRankCmd('ZRANGE', cls._dayKey(yesterday), 0, count - 1, 'WITHSCORES')
        if not parts:
            parts = []

        for i in xrange(len(parts) / 2):
            userId = int(parts[i * 2])
            winChips = -int(parts[i * 2 + 1])
            user = cls._buildUser(userId, winChips)
            dayRanks.append(user)

        return dayRanks

    @classmethod
    def getYesterdayTop(cls, now):
        ''', , None redis'''

        ranks = cls.getYesterdayRanks(now, 1)
        if len(ranks) > 0:
            return ranks[0]
        else:
            return None

    @classmethod
    def setExpireRemoteRank(cls, now):
        '''redisrank24'''

        today = cls._todayDate(now)
        daobase.executeRankCmd('EXPIRE', cls._dayKey(today), 24 * 3600)

    @classmethod
    def getUserTodayWinChips(cls, userId, now):
        '''rediswinchips'''

        today = cls._todayDate(now)
        data = UtilFunc.getDayData(userId, today)
        return data['winChipsForKing']

    @classmethod
    def _buildUser(cls, userId, winChips):
        '''user'''

        name, purl = UtilFunc.getUserNameAndPurl(userId)
        return {
            "userId": userId,
            "winChips": winChips,
            "name": name,
            "purl": purl
        }

    @classmethod
    def _dayKey(cls, date):
        '''key'''

        return 'kingrank:%s:%s' % (const.GAME_ID, date)

    @classmethod
    def _todayDate(cls, now=None):
        ''''''

        if now is None:
            now = time.time()
        return time.strftime("%Y%m%d", time.localtime(now))

    @classmethod
    def _getLocalDayRanks(cls, today):
        '''
        dayRank

        :param today: 
        :return: dayRank
        '''

        # , redis
        if today != cls._dateForDayRank:
            del cls._dayRanks[:]

            count = cls._maxRanksCount()

            parts = daobase.executeRankCmd('ZRANGE', cls._dayKey(today), 0, count - 1, 'WITHSCORES')
            if not parts:
                parts = []

            for i in xrange(len(parts) / 2):
                userId = int(parts[i * 2])
                winChips = -int(parts[i * 2 + 1])
                user = cls._buildUser(userId, winChips)
                cls._dayRanks.append(user)

            cls._dateForDayRank = today

        return cls._dayRanks

    @classmethod
    def _updateLocalDayRanks(cls, userId, winChips, today):
        '''dayrank'''

        count = cls._maxRanksCount()
        dayRanks = cls._getLocalDayRanks(today)

        # 
        index = cls._findUserInDayRanks(userId, dayRanks)
        if index >= 0:
            dayRanks[index]['winChips'] = winChips
        else:
            if len(dayRanks) < count:
                dayRanks.append(cls._buildUser(userId, winChips))
            else:
                dayRanks[-1] = cls._buildUser(userId, winChips)

        # 
        dayRanks.sort(cmp=lambda a, b: cmp(a['winChips'], b['winChips']), reverse=True)

    @classmethod
    def _findUserInDayRanks(cls, userId, dayRank):
        '''dayrank, -1'''

        for i in xrange(len(dayRank)):
            if dayRank[i]['userId'] == userId:
                return i

        return -1

    @classmethod
    def _maxRanksCount(cls):
        ''''''

        dayConf = carsconf.getKingConf().get('today', {})
        return max(dayConf.get('game_count', 1), dayConf.get('bi_count', 1))

    @classmethod
    def _loopCheckRedisRanksPeriod(cls):

        now = int(time.time())

        # 
        today = cls._todayDate(now)
        countInRedis = daobase.executeRankCmd('ZCOUNT', cls._dayKey(today), '-inf', '+inf')
        if not countInRedis:
            countInRedis = 0
        countInRedis = int(countInRedis)
        ftlog.info('_loopCheckRedisRanksPeriod king ranks total length', countInRedis)

        # , 
        maxCount = cls._maxRanksCount()
        if countInRedis > maxCount * 2:
            daobase.executeRankCmd('ZREMRANGEBYRANK', cls._dayKey(today), maxCount, -1)

        # check, , BI
        if UtilFunc.isAcrossTwoDays(now, cls._lastCheckedRanksAt):
            biCount = carsconf.getKingConf().get('today', {}).get('bi_count', 1)
            yesterday = cls._todayDate(now - const.ONE_DAY_SEC)
            parts = daobase.executeRankCmd('ZRANGE', cls._dayKey(yesterday), 0, biCount, 'WITHSCORES')
            if not parts:
                parts = []

            # BI
            ftlog.info('King.Ranks.Yesterday:', parts)

        # , 
        cls.setExpireRemoteRank(now)

        cls._lastCheckedRanksAt = now

        # , 
        UtilFunc.callLater(cls.CHECK_REDIS_RANKS_PERIOD, cls._loopCheckRedisRanksPeriod)

Web Proxy Viewer  |  New URL  |  Original Page