Exemple #1
0
class DizhuPlayerErdayiMatch(DizhuPlayer):
    def __init__(self, room, userId, isAI, matchUserInfo):
        super(DizhuPlayerErdayiMatch, self).__init__(room, userId)
        self.matchUserInfo = matchUserInfo
        self.rank = 0
        self.isAI = isAI
        self.waitReason = WaitReason.UNKNOWN
        self.ai = None
        self._timer = None
        if self.isAI:
            self.ai = AIPlayer(self)
    
    def startTimer(self, delay, func, *args, **kw):
        assert(self.isAI)
        self.cancelTimer()
        self._timer = FTTimer(delay, functools.partial(func, *args, **kw))
    
    def cancelTimer(self):
        if self._timer:
            self._timer.cancel()
            self._timer = None
    
    def doActiveOutCard(self):
        assert(self.isAI)
        return self.ai.doActiveOutCard()
        
    def doPassiveOutCard(self):
        assert(self.isAI)
        return self.ai.doPassiveOutCard()
Exemple #2
0
class SeatBase(object):
    def __init__(self, table, seatIndex, seatId):
        # 属于哪个桌子
        self._table = table
        # 座位index
        self._seatIndex = seatIndex
        # seatId
        self._seatId = seatId
        # 该座位的玩家
        self._player = None
        # 下一个座位
        self._next = None
        # 该座位定时器
        self._timer = None

    @property
    def table(self):
        return self._table

    @property
    def tableId(self):
        return self._table.tableId

    @property
    def seatId(self):
        return self._seatId

    @property
    def seatIndex(self):
        return self._seatIndex

    @property
    def state(self):
        return self._state

    @property
    def player(self):
        return self._player

    @property
    def next(self):
        return self._next

    @property
    def userId(self):
        return self._player.userId if self._player else 0

    def startTimer(self, delay, func, *args, **kw):
        self.cancelTimer()
        self._timer = FTTimer(delay, functools.partial(func, *args, **kw))

    def cancelTimer(self):
        if self._timer:
            self._timer.cancel()
            self._timer = None
Exemple #3
0
class RoomTimer(object): 
    def __init__(self, room):
        self._fttimer = None  # 计时器对象
        self._interval = 0  # 倒计时时间,单位: 秒
        self._room = room

    def _onTimeOut(self):
        msg = stackless.getcurrent()._fttask.run_argl[0]
        self._room.on_match_event(msg)

    def setup(self, interval, msg, cancelLastTimer=True):
        if self._fttimer and cancelLastTimer:
            self._fttimer.cancel()
        self._interval = interval
        self._fttimer = FTTimer(interval, self._onTimeOut, msg)

    def cancel(self):
        '''
        取消当前的计时器
        '''
        if self._fttimer :
            self._fttimer.cancel()
            self._fttimer = None
            self._interval = 0  
            
    def reset(self, interval):
        '''
        重置当前的计时器
        '''
        
        if self._fttimer:
            self._fttimer.reset(interval)
            self._interval = interval
    
    def getInterval(self):
        '''
        取得当前计时器的倒计时时间
        '''
        if self._fttimer:
            return self._interval
        else:
            return 0
    
    
    def getTimeOut(self):
        '''
        取得当前计时器的剩余的倒计时时间, 若没有开始倒计时, 那么返回0
        '''
        if self._fttimer :
            self._fttimer.getTimeOut()
        return 0.0
Exemple #4
0
class Notify(object):
    '''
    一条通知
    '''
    def __init__(self, argd):
        self.argd = argd
        self._alive = False

        if self.argd['ntimeId'] == NOTIFY_TIME_ATONCE_ID:
            self.startTimer = FTTimer(0, self.start)
            ftlog.hinfo('Notify.__init__ atonce', self.argd)
        else:
            ntime = [0, 1]
            if self.argd['ntimeId'] == NOTIFY_TIME_TIMER_ID:
                try:
                    dtList = self.argd['ntime'].split('|')
                    ntime = map(int, dtList[1].split(':'))
                except:
                    ftlog.warn('Notify.__init__.NOTIFY_TIME_TIMER_ID error')
                    ntime = map(int, '00:01'.split(':'))
            else:
                ntime = map(int, self.argd['ntime'].split(':'))
            hm = map(int, getNowTimeStr().split(':'))

            interval = (ntime[0] * 60 * 60 +
                        ntime[1] * 60) - (hm[0] * 60 * 60 + hm[1] * 60)
            ftlog.hinfo('Notify.__init__ begin:', ntime, hm, interval,
                        (ntime[0] * 60 * 60 + ntime[1] * 60),
                        (hm[0] * 60 * 60 + hm[1] * 60))
            if interval > 0:
                self.startTimer = FTTimer(interval, self.start)

            ftlog.hinfo('Notify.__init__ end:', interval, self.argd)

    def start(self):
        self.startTimer.cancel()

        if self.argd['rmTag'] == 1:
            ftlog.hinfo('Notify.start error because be removed',
                        self.argd['uuid'])
            return

        self._alive = True
        self.endTimer = FTTimer(NOTIFY_TIMER_LIFE, self.end)

        ftlog.hinfo('Notify.start', NOTIFY_TIMER_LIFE, self.argd['uuid'])

    def end(self):
        self.endTimer.cancel()
        self._alive = False

        if self.argd['ntimeId'] == NOTIFY_TIME_TIMER_ID:
            daobase.executeRankCmd('HDEL',
                                   notify_timer_key % self.argd['hall'],
                                   self.uuid)
            ftlog.hinfo('HDEL.notify timer', self.argd)

        ftlog.hinfo('Notify.end', self.argd['uuid'])

    def pushNotify(self, userId, gameId, clientId, clientSys):
        try:

            if ftlog.is_debug():
                ftlog.hinfo('Notify.pushNotify enter argd=', userId, gameId,
                            clientId, clientSys, self.typeId,
                            self.typeId == NOTIFY_TYPEID_ANNOUNCE, self.argd)
            if self.argd['rmTag'] == 1:
                ftlog.hinfo('Notify.pushNotify notify be removed', userId,
                            gameId, clientId, clientSys)
                return
            if len(self.argd['userId']) >= len('10000') and str(
                    userId) not in self.argd['userId'].split('|'):
                ftlog.hinfo('Notify.pushNotify userId not match', userId,
                            gameId, clientId, clientSys)
                return
            package = self.argd['package']
            if len(package) > 0:
                if clientId not in package.split('|'):
                    ftlog.hinfo('Notify.pushNotify clientId not in package',
                                userId, gameId, clientId, clientSys)
                    return

            platform = self.argd['platform']
            if platform == '1':
                if clientSys != CLIENT_SYS_IOS:
                    ftlog.hinfo('Notify.pushNotify clientSys not is ios',
                                userId, gameId, clientId, clientSys)
                    return
            elif platform == '2':
                if clientSys != CLIENT_SYS_ANDROID:
                    ftlog.hinfo('Notify.pushNotify clientSys not is android',
                                userId, gameId, clientId, clientSys)
                    return
            elif platform == '3':
                pass  #任意平台都可以
            else:
                ftlog.warn('Notify.pushNotify clientSys error platform')
                return

            if clientId.count(self.argd['hall']) == 0:
                ftlog.hinfo('Notify.pushNotify hall not match', userId, gameId,
                            self.argd['hall'], clientId, clientSys)
                return
            else:
                plugin_gameid = self.argd['gameId']
                if len(plugin_gameid) > 0:
                    if plugin_gameid != str(gameId):
                        ftlog.hinfo(
                            'Notify.pushNotify plugin_gameid not match',
                            userId, gameId, self.argd['gameId'], clientId,
                            clientSys)
                        return

            if self.typeId == NOTIFY_TYPEID_ANNOUNCE:
                sendNotify_announce(gameId, userId, self.argd)
            elif self.typeId == NOTIFY_TYPEID_MESSAGE:
                sendNotify_message(gameId, userId, self.argd)
        except:
            ftlog.error('Notify.pushNotify before11', userId, gameId, clientId,
                        clientSys, self.argd)

    def rmTag(self):
        self.argd['rmTag'] = 1
        ftlog.hinfo('Notify.rmTag is 1', self.uuid)

    @property
    def alive(self):
        return self._alive

    @property
    def typeId(self):
        return self.argd['typeId']

    @property
    def uuid(self):
        return self.argd['uuid']

    def __str__(self):
        return dict(self.argd).__repr__()

    def __repr__(self):
        return self.__str__()
Exemple #5
0
class TYTableTimer(object):
    '''
    桌子使用的专用的计时器, 当计时器触发时, 触发桌子的同步方法:doTableCall
    '''
    def __init__(self, table):
        self._table = table  # 桌子对象
        self._fttimer = None  # 计时器对象
        self._interval = 0  # 倒计时时间,单位: 秒

    def _onTimeOut(self):
        '''
        计时器到时, 触发table的doTableCall方法
        '''
        msg = stackless.getcurrent()._fttask.run_argl[0]
        seatId = msg.getParam('seatId')
        if seatId == None:
            seatId = 0
        userId = msg.getParam('userId')
        if userId == None:
            userId = 0
        assert (isinstance(userId, int))
        assert (isinstance(seatId, int))
        action = msg.getParam('action')
        clientId = runcmd.getClientId(msg)
        self._table.doTableCall(msg, userId, seatId, action, clientId)

    def setup(self, interval, action, msgPackParams, cancelLastTimer=True):
        '''
        启动计时器
        interval 倒计时的时间, 单位: 秒
        action table_call命令下(params中)的action值
        msgPackParams 传递的其他的参数数据集合dict, 可以在doTableCall中的msg中使用msg.getParam(key)来取得其中的参数
        '''
        if self._fttimer and cancelLastTimer:
            self._fttimer.cancel()
        self._interval = interval
        userId = msgPackParams.get('userId', 0)
        clientId = msgPackParams.get('clientId', None)
        assert (isinstance(userId, int))
        assert (isinstance(action, (unicode, str)))
        if clientId != None:
            assert (isinstance(clientId, (unicode, str)))
        msg = MsgPack()
        msg.updateParam(msgPackParams)
        msg.setCmdAction('table_call', action)
        msg.setParam('gameId', self._table.gameId)
        msg.setParam('roomId', self._table.roomId)
        msg.setParam('tableId', self._table.tableId)
        msg.setParam('userId', userId)
        msg.setParam('clientId', clientId)
        self._fttimer = FTTimer(interval, self._onTimeOut, msg)

    def cancel(self):
        '''
        取消当前的计时器
        '''
        if self._fttimer:
            self._fttimer.cancel()
            self._fttimer = None

    def reset(self, interval):
        '''
        重置当前的计时器
        '''
        self._interval = interval
        self._fttimer.reset(interval)

    def getInterval(self):
        '''
        取得当前计时器的倒计时时间
        '''
        return self._interval

    def getTimeOut(self):
        '''
        取得当前计时器的剩余的倒计时时间, 若没有开始倒计时, 那么返回0
        '''
        if self._fttimer:
            time = self._fttimer.getTimeOut()
            if time < 0 or time > 3600:
                time = 0
            return time
        return 0
Exemple #6
0
class Heartbeat(object):
    ST_IDLE = 0
    ST_START = 1
    ST_STOP = 2

    def __init__(self, target, interval):
        self._target = target
        self._state = Heartbeat.ST_IDLE
        self._count = 0
        self._postTaskList = []
        self._timer = None
        self._interval = interval
        self._logger = Logger()
        self._init = False

    def start(self):
        assert (self._state == Heartbeat.ST_IDLE)
        self._state = Heartbeat.ST_START
        self._timer = FTTimer(0, self._onInit)

    def stop(self):
        if self._state != Heartbeat.ST_STOP:
            self._state = Heartbeat.ST_STOP
            if self._timer:
                self._timer.cancel()
            self._timer = None

    @property
    def count(self):
        return self._count

    def postCall(self, func, *args, **kwargs):
        self.postTask(functools.partial(func, *args, **kwargs))

    def postTask(self, task):
        if self._state != Heartbeat.ST_STOP:
            self._postTaskList.append(task)
            if self._init and self._timer:
                self._timer.cancel()
                self._timer = FTTimer(0, self._onTimeout)

    def _onInit(self):
        try:
            self._timer = None
            interval = self._target.onInit()
            if interval:
                self._interval = interval
            self._scheduleTimer()
        except:
            self._logger.error('Heartbeat._onInit')

    def _onTimeout(self):
        try:
            self._timer = None
            self._count += 1
            self._processPostTaskList()
            interval = self._target.onHeartbeat()
            if interval is not None:
                self._interval = interval
        except:
            self._interval = 1
            self._logger.error('Heartbeat._onTimeout')
        self._scheduleTimer()

    def _scheduleTimer(self):
        if self._state == Heartbeat.ST_START:
            interval = 0 if self._postTaskList else self._interval
            self._timer = FTTimer(interval, self._onTimeout)

    def _processPostTaskList(self):
        taskList = self._postTaskList
        self._postTaskList = []
        for task in taskList:
            try:
                task()
            except:
                self._logger.error('task=', task)
Exemple #7
0
class TableBase(Observable):
    def __init__(self, room, tableId, dealer):
        super(TableBase, self).__init__()
        # 房间
        self._room = room
        # 当前状态
        self._state = dealer.sm.findStateByName('idle')
        # 桌子ID
        self._tableId = tableId
        # 玩法
        self._dealer = dealer
        # 桌子定时器
        self._timer = None
        # 所有座位
        self._seats = []
        # 锁
        self.locker = FTLock(self.__class__.__name__ + "_%d" % id(self))

    @property
    def sm(self):
        return self._dealer.sm

    @property
    def playMode(self):
        return self._dealer.playMode

    @property
    def state(self):
        return self._state

    @property
    def gameId(self):
        return self.room.gameId

    @property
    def room(self):
        return self._room

    @property
    def roomId(self):
        return self.room.roomId

    @property
    def bigRoomId(self):
        return self.room.bigRoomId

    @property
    def tableId(self):
        return self._tableId

    @property
    def dealer(self):
        return self._dealer

    @property
    def seats(self):
        return self._seats

    @property
    def seatCount(self):
        return len(self._seats)

    @property
    def idleSeatCount(self):
        count = 0
        for seat in self._seats:
            if not seat.player:
                count += 1
        return count

    @locked
    def processCommand(self, cmd):
        self._processCommand(cmd)

    def getSeat(self, seatId):
        if seatId > 0 and seatId <= len(self._seats):
            return self._seats[seatId - 1]
        return None

    def getSeatByUserId(self, userId):
        for seat in self._seats:
            if seat.userId == userId:
                return seat
        return None

    def getPlayers(self):
        ret = []
        for seat in self._seats:
            if seat.player:
                ret.append(seat.player)
        return ret

    def getSeatUserIds(self):
        ret = []
        for seat in self._seats:
            ret.append(seat.userId)
        return ret

    def findIdleSeat(self):
        for seat in self._seats:
            if seat.player is None:
                return seat
        return None

    def init(self):
        self._makeSeats(self.playMode.seatCount)
        self._initImpl()
        return self

    def fire(self, event):
        event.table = self
        super(TableBase, self).fire(event)

    def startTimer(self, delay, func, *args, **kw):
        self.cancelTimer()
        self._timer = FTTimer(delay, functools.partial(func, *args, **kw))

    def cancelTimer(self):
        if self._timer:
            self._timer.cancel()
            self._timer = None

    def _processCommand(self, cmd):
        assert (isinstance(cmd, TableCommand))
        cmd.table = self
        cmd.timestamp = time.time()
        self.state.processCommand(cmd)

    def _makeSeats(self, seatCount):
        for i in xrange(seatCount):
            seat = self._newSeat(i, i + 1)
            assert (seat.table == self)
            assert (seat.seatId == i + 1)
            self._seats.append(seat)

    def _newSeat(self, seatIndex, seatId):
        raise NotImplementedError

    def _initImpl(self):
        pass
Exemple #8
0
class TYTableTimer(object):
    '''
    桌子使用的专用的计时器, 当计时器触发时, 触发桌子的同步方法:doTableCall
    '''

    def __init__(self, table):
        self._table = table  # 桌子对象
        self._fttimer = None  # 计时器对象
        self._interval = 0  # 倒计时时间,单位: 秒

    def _onTimeOut(self):
        '''
        计时器到时, 触发table的doTableCall方法
        '''
        msg = stackless.getcurrent()._fttask.run_argl[0]
        seatId = msg.getParam('seatId')
        if seatId == None:
            seatId = 0
        userId = msg.getParam('userId')
        if userId == None:
            userId = 0
        assert (isinstance(userId, int))
        assert (isinstance(seatId, int))
        action = msg.getParam('action')
        clientId = runcmd.getClientId(msg)
        self._table.doTableCall(msg, userId, seatId, action, clientId)

    def setup(self, interval, action, msgPackParams, cancelLastTimer=True):
        '''
        启动计时器
        interval 倒计时的时间, 单位: 秒
        action table_call命令下(params中)的action值
        msgPackParams 传递的其他的参数数据集合dict, 可以在doTableCall中的msg中使用msg.getParam(key)来取得其中的参数
        '''
        if self._fttimer and cancelLastTimer:
            self._fttimer.cancel()
        self._interval = interval
        userId = msgPackParams.get('userId', 0)
        clientId = msgPackParams.get('clientId', None)
        assert (isinstance(userId, int))
        assert (isinstance(action, (unicode, str)))
        if clientId != None:
            assert (isinstance(clientId, (unicode, str)))
        msg = MsgPack()
        msg.updateParam(msgPackParams)
        msg.setCmdAction('table_call', action)
        msg.setParam('gameId', self._table.gameId)
        msg.setParam('roomId', self._table.roomId)
        msg.setParam('tableId', self._table.tableId)
        msg.setParam('userId', userId)
        msg.setParam('clientId', clientId)
        self._fttimer = FTTimer(interval, self._onTimeOut, msg)

    def cancel(self):
        '''
        取消当前的计时器
        '''
        if self._fttimer:
            self._fttimer.cancel()
            self._fttimer = None

    def reset(self, interval):
        '''
        重置当前的计时器
        '''
        self._interval = interval
        self._fttimer.reset(interval)

    def getInterval(self):
        '''
        取得当前计时器的倒计时时间
        '''
        return self._interval

    def getTimeOut(self):
        '''
        取得当前计时器的剩余的倒计时时间, 若没有开始倒计时, 那么返回0
        '''
        if self._fttimer:
            time = self._fttimer.getTimeOut()
            if time < 0 or time > 3600:
                time = 0
            return time
        return 0