Ejemplo n.º 1
0
 def nextHand(self, dummyResults):
     """next hand: maybe rotate"""
     if not self.running:
         return
     DeferredBlock.garbageCollection()
     for block in DeferredBlock.blocks:
         if block.table == self:
             logError('request left from previous hand: %s' %
                      block.outstandingStr())
     token = self.game.handId.prompt(
         withAI=False)  # we need to send the old token until the
     # clients started the new hand
     rotateWinds = self.game.maybeRotateWinds()
     if self.game.finished():
         self.server.removeTable(self, 'gameOver',
                                 i18nE('Game <numid>%1</numid> is over!'),
                                 self.game.seed)
         if Debug.process and os.name != 'nt':
             logDebug('MEM:%s' %
                      resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
         return
     self.game.sortPlayers()
     playerNames = list((x.wind, x.name) for x in self.game.players)
     self.tellAll(None,
                  Message.ReadyForHandStart,
                  self.startHand,
                  playerNames=playerNames,
                  rotateWinds=rotateWinds,
                  token=token)
Ejemplo n.º 2
0
 def _clientDiscarded4(self, dummyResults, msg, dangerousText,
                       mustPlayDangerous):
     """client told us he discarded a tile. Continue, check for dangerous game"""
     block = DeferredBlock(self)
     player = msg.player
     if dangerousText:
         if mustPlayDangerous and not player.lastSource.isDiscarded:
             if Debug.dangerousGame:
                 tile = Tile(msg.args[0])
                 logDebug(
                     '%s claims no choice. Discarded %s, keeping %s. %s' %
                     (player, tile, ''.join(
                         player.concealedTiles), ' / '.join(dangerousText)))
             player.claimedNoChoice = True
             block.tellAll(player,
                           Message.NoChoice,
                           tiles=TileList(player.concealedTiles))
         else:
             player.playedDangerous = True
             if Debug.dangerousGame:
                 tile = Tile(msg.args[0])
                 logDebug(
                     '%s played dangerous. Discarded %s, keeping %s. %s' %
                     (player, tile, ''.join(
                         player.concealedTiles), ' / '.join(dangerousText)))
             block.tellAll(player,
                           Message.DangerousGame,
                           tiles=TileList(player.concealedTiles))
     if msg.answer == Message.OriginalCall:
         player.isCalling = True
         block.callback(self.clientMadeOriginalCall, msg)
     else:
         block.callback(self._askForClaims, msg)
Ejemplo n.º 3
0
 def clientMadeOriginalCall(self, dummyResults, msg):
     """first tell everybody about original call
     and then treat the implicit discard"""
     msg.player.originalCall = True
     if Debug.originalCall:
         logDebug('server.clientMadeOriginalCall: %s' % msg.player)
     block = DeferredBlock(self)
     block.tellAll(msg.player, Message.OriginalCall)
     block.callback(self.askForClaims)
Ejemplo n.º 4
0
 def initGame(self):
     """ask clients if they are ready to start"""
     game = self.preparedGame
     game.saveNewGame()
     block = DeferredBlock(self)
     for player in game.players:
         block.tellPlayer(player, Message.ReadyForGameStart, tableid=self.tableid,
             gameid=game.gameid, shouldSave=player.shouldSave,
             wantedGame=game.wantedGame, source=list((x.wind, x.name) for x in game.players))
     block.callback(self.startGame)
Ejemplo n.º 5
0
 def claimMahJongg(self, msg):
     """a player claims mah jongg. Check this and
     if correct, tell all. Otherwise abort game, kajongg client is faulty"""
     if not self.running:
         return
     player = msg.player
     concealedMelds = MeldList(msg.args[0])
     withDiscard = Tile(msg.args[1]) if msg.args[1] else None
     lastMeld = Meld(msg.args[2])
     if self.game.ruleset.mustDeclareCallingHand:
         assert player.isCalling, '%s %s %s says MJ but never claimed: concmelds:%s withdiscard:%s lastmeld:%s' % (
             self.game.handId, player.hand, player, concealedMelds,
             withDiscard, lastMeld)
     discardingPlayer = self.game.activePlayer
     lastMove = next(self.game.lastMoves(withoutNotifications=True))
     robbedTheKong = lastMove.message == Message.DeclaredKong
     if robbedTheKong:
         player.robsTile()
         withDiscard = lastMove.meld[0].concealed
         lastMove.player.robTileFrom(withDiscard)
     msgArgs = player.showConcealedMelds(concealedMelds, withDiscard)
     if msgArgs:
         self.abort(*msgArgs)
         return
     player.declaredMahJongg(concealedMelds, withDiscard, player.lastTile,
                             lastMeld)
     if not player.hand.won:
         msg = i18nE('%1 claiming MahJongg: This is not a winning hand: %2')
         self.abort(msg, player.name, player.hand.string)
         return
     block = DeferredBlock(self)
     if robbedTheKong:
         block.tellAll(player, Message.RobbedTheKong, tile=withDiscard)
     if (player.lastSource is TileSource.LivingWallDiscard
             and self.game.dangerousFor(discardingPlayer, player.lastTile)
             and discardingPlayer.playedDangerous):
         player.usedDangerousFrom = discardingPlayer
         if Debug.dangerousGame:
             logDebug('%s wins with dangerous tile %s from %s' %
                      (player, self.game.lastDiscard, discardingPlayer))
         block.tellAll(player,
                       Message.UsedDangerousFrom,
                       source=discardingPlayer.name)
     block.tellAll(player,
                   Message.MahJongg,
                   melds=concealedMelds,
                   lastTile=player.lastTile,
                   lastMeld=lastMeld,
                   withDiscardTile=withDiscard)
     block.callback(self.endHand)
Ejemplo n.º 6
0
 def proposeGameId(self, gameid):
     """server proposes an id to the clients ands waits for answers"""
     while True:
         with Transaction():
             query = Query('insert into game(id,seed) values(?,?)',
                   list([gameid, 'proposed']), mayFail=True)
             if query.success:
                 break
             gameid += random.randrange(1, 100)
     block = DeferredBlock(self)
     for player in self.preparedGame.players:
         if player.shouldSave and isinstance(player.remote, User):
             # do not ask robot players, they use the server data base
             block.tellPlayer(player, Message.ProposeGameId, gameid=gameid)
     block.callback(self.collectGameIdAnswers, gameid)
Ejemplo n.º 7
0
 def endHand(self, dummyResults=None):
     """hand is over, show all concealed tiles to all players"""
     if not self.game:
         return
     if self.game.playOpen:
         self.saveHand()
     else:
         block = DeferredBlock(self)
         for player in self.game.players:
             # there might be no winner, winner.others() would be wrong
             if player != self.game.winner:
                 # the winner tiles are already shown in claimMahJongg
                 block.tellOthers(player, Message.ShowConcealedTiles, show=True,
                     source=player.concealedTileNames)
         block.callback(self.saveHand)
Ejemplo n.º 8
0
 def claimTile(self, player, claim, meldTiles, nextMessage):
     """a player claims a tile for pung, kong or chow.
     meldTiles contains the claimed tile, concealed"""
     if not self.running:
         return
     lastDiscard = self.game.lastDiscard
     # if we rob a tile, self.game.lastDiscard has already been set to the
     # robbed tile
     hasTiles = Meld(meldTiles[:])
     discardingPlayer = self.game.activePlayer
     hasTiles = hasTiles.without(lastDiscard)
     meld = Meld(meldTiles)
     if len(meld) != 4 and not (meld.isPair or meld.isPungKong
                                or meld.isChow):
         msg = i18nE('%1 wrongly said %2 for meld %3')
         self.abort(msg, player.name, claim.name, str(meld))
         return
     if not player.hasConcealedTiles(hasTiles):
         msg = i18nE(
             '%1 wrongly said %2: claims to have concealed tiles %3 but only has %4'
         )
         self.abort(msg, player.name, claim.name, ' '.join(hasTiles),
                    ''.join(player.concealedTiles))
         return
     # update our internal state before we listen to the clients again
     self.game.discardedTiles[lastDiscard.exposed] -= 1
     self.game.activePlayer = player
     if lastDiscard:
         player.lastTile = lastDiscard.exposed
         player.lastSource = TileSource.LivingWallDiscard
     player.exposeMeld(hasTiles, lastDiscard)
     self.game.lastDiscard = None
     block = DeferredBlock(self)
     if (nextMessage != Message.Kong
             and self.game.dangerousFor(discardingPlayer, lastDiscard)
             and discardingPlayer.playedDangerous):
         player.usedDangerousFrom = discardingPlayer
         if Debug.dangerousGame:
             logDebug('%s claims dangerous tile %s discarded by %s' %
                      (player, lastDiscard, discardingPlayer))
         block.tellAll(player,
                       Message.UsedDangerousFrom,
                       source=discardingPlayer.name)
     block.tellAll(player, nextMessage, meld=meld)
     if claim == Message.Kong:
         block.callback(self.pickKongReplacement)
     else:
         block.callback(self.moved)
Ejemplo n.º 9
0
 def divided(self, dummyResults=None):
     """the wall is now divided for all clients"""
     if not self.game:
         return
     block = DeferredBlock(self)
     for clientPlayer in self.game.players:
         allPlayerTiles = []
         for player in self.game.players:
             bonusTileNames = tuple(x.element for x in player.bonusTiles)
             if player == clientPlayer or self.game.playOpen:
                 playerTiles = player.concealedTileNames
             else:
                 playerTiles = ('Xy',) * 13
             allPlayerTiles.append((player.name, playerTiles + bonusTileNames))
         block.tellPlayer(clientPlayer, Message.SetConcealedTiles, source=allPlayerTiles)
     block.callback(self.dealt)
Ejemplo n.º 10
0
 def sendVoiceData(self, requests, voiceDataRequests):
     """sends voice sounds to other human players"""
     self.processAnswers(requests)
     block = DeferredBlock(self)
     for voiceDataRequester, voiceFor in voiceDataRequests:
         # this player requested sounds for voiceFor
         voice = voiceFor.voice
         content = voice.archiveContent
         if content:
             if Debug.sound:
                 logDebug('server got voice data %s for %s from client' % (voiceFor.voice, voiceFor.name))
             block.tell(voiceFor, voiceDataRequester, Message.VoiceData, md5sum=voice.md5sum, source=content)
         elif Debug.sound:
             logDebug('server got empty voice data %s for %s from client' % (
                 voice, voiceFor.name))
     block.callback(self.assignVoices)
Ejemplo n.º 11
0
 def sendVoiceIds(self):
     """tell each player what voice ids the others have. By now the client has a Game instance!"""
     humanPlayers = [x for x in self.game.players if isinstance(x.remote, User)]
     if len(humanPlayers) < 2 or not any(x.remote.voiceId for x in humanPlayers):
         # no need to pass around voice data
         self.assignVoices()
         return
     block = DeferredBlock(self)
     for player in humanPlayers:
         if player.remote.voiceId:
             # send it to other human players:
             others = [x for x in humanPlayers if x != player]
             if Debug.sound:
                 logDebug('telling other human players that %s has voiceId %s' % (
                     player.name, player.remote.voiceId))
             block.tell(player, others, Message.VoiceId, source=player.remote.voiceId)
     block.callback(self.collectVoiceData)
Ejemplo n.º 12
0
 def nextHand(self, dummyResults):
     """next hand: maybe rotate"""
     if not self.game:
         return
     DeferredBlock.garbageCollection()
     for block in DeferredBlock.blocks:
         if block.table == self:
             logError('request left from previous hand: %s' % block.outstandingStr())
     token = self.game.handId() # we need to send the old token until the
                                # clients started the new hand
     rotateWinds = self.game.maybeRotateWinds()
     if self.game.finished():
         self.close('gameOver', m18nE('The game is over!'))
         return
     self.game.sortPlayers()
     playerNames = list((x.wind, x.name) for x in self.game.players)
     self.tellAll(None, Message.ReadyForHandStart, self.startHand,
         source=playerNames, rotateWinds=rotateWinds, token=token)
Ejemplo n.º 13
0
 def collectVoiceData(self, requests):
     """collect voices of other players"""
     if not self.game:
         return
     block = DeferredBlock(self)
     voiceDataRequests = []
     for request in requests:
         if request.answer == Message.ClientWantsVoiceData:
             # another human player requests sounds for voiceId
             voiceId = request.args[0]
             voiceFor = [x for x in self.game.players if isinstance(x.remote, User) \
                 and x.remote.voiceId == voiceId][0]
             voiceFor.voice = Voice(voiceId)
             if Debug.sound:
                 logDebug('client %s wants voice data %s for %s' % (request.player.name, request.args[0], voiceFor))
             voiceDataRequests.append((request.player, voiceFor))
             if not voiceFor.voice.oggFiles():
                 # the server does not have it, ask the client with that voice
                 block.tell(voiceFor, voiceFor, Message.ServerWantsVoiceData)
     block.callback(self.sendVoiceData, voiceDataRequests)
Ejemplo n.º 14
0
 def sendVoiceIds(self):
     """tell each player what voice ids the others have. By now the client has a Game instance!"""
     humanPlayers = [
         x for x in self.game.players if isinstance(self.remotes[x], User)
     ]
     if len(humanPlayers) < 2 or not any(self.remotes[x].voiceId
                                         for x in humanPlayers):
         # no need to pass around voice data
         self.assignVoices()
         return
     block = DeferredBlock(self)
     for player in humanPlayers:
         remote = self.remotes[player]
         if remote.voiceId:
             # send it to other human players:
             others = [x for x in humanPlayers if x != player]
             if Debug.sound:
                 logDebug(
                     'telling other human players that %s has voiceId %s' %
                     (player.name, remote.voiceId))
             block.tell(player,
                        others,
                        Message.VoiceId,
                        source=remote.voiceId)
     block.callback(self.collectVoiceData)
Ejemplo n.º 15
0
 def collectVoiceData(self, requests):
     """collect voices of other players"""
     if not self.running:
         return
     block = DeferredBlock(self)
     voiceDataRequests = []
     for request in requests:
         if request.answer == Message.ClientWantsVoiceData:
             # another human player requests sounds for voiceId
             voiceId = request.args[0]
             voiceFor = [
                 x for x in self.game.players
                 if isinstance(self.remotes[x], User)
                 and self.remotes[x].voiceId == voiceId
             ][0]
             voiceFor.voice = Voice(voiceId)
             if Debug.sound:
                 logDebug('client %s wants voice data %s for %s' %
                          (request.user.name, request.args[0], voiceFor))
             voiceDataRequests.append((request.user, voiceFor))
             if not voiceFor.voice.oggFiles():
                 # the server does not have it, ask the client with that
                 # voice
                 block.tell(voiceFor, voiceFor,
                            Message.ServerWantsVoiceData)
     block.callback(self.sendVoiceData, voiceDataRequests)
Ejemplo n.º 16
0
 def assignVoices(self, dummyResults=None):
     """now all human players have all voice data needed"""
     humanPlayers = [
         x for x in self.game.players if isinstance(self.remotes[x], User)
     ]
     block = DeferredBlock(self)
     block.tell(None, humanPlayers, Message.AssignVoices)
     block.callback(self.startHand)
Ejemplo n.º 17
0
 def claimMahJongg(self, msg):
     """a player claims mah jongg. Check this and if correct, tell all."""
     # pylint: disable=R0912
     # too many branches
     if not self.game:
         return
     player = msg.player
     concealedMelds, withDiscard, lastMeld = msg.args
     if self.game.ruleset.mustDeclareCallingHand:
         assert player.isCalling, '%s: concmelds:%s withdiscard:%s lastmeld:%s' % (
             player, concealedMelds, withDiscard, lastMeld)
     discardingPlayer = self.game.activePlayer
     # pylint: disable=E1103
     # (pylint ticket 8774)
     lastMove = self.game.lastMoves(without=[Message.PopupMsg]).next()
     robbedTheKong = lastMove.message == Message.DeclaredKong
     if robbedTheKong:
         player.lastSource = 'k'
         withDiscard = lastMove.source[0].capitalize()
         lastMove.player.robTile(withDiscard)
     lastMeld = Meld(lastMeld)
     msgArgs = player.showConcealedMelds(concealedMelds, withDiscard)
     if msgArgs:
         self.abort(*msgArgs) # pylint: disable=W0142
     player.declaredMahJongg(concealedMelds, withDiscard, player.lastTile, lastMeld)
     if not player.hand.won:
         msg = m18nE('%1 claiming MahJongg: This is not a winning hand: %2')
         self.abort(msg, player.name, player.hand.string)
         return
     block = DeferredBlock(self)
     if robbedTheKong:
         block.tellAll(player, Message.RobbedTheKong, tile=withDiscard)
     if (player.lastSource == 'd'
             and self.game.dangerousFor(discardingPlayer, player.lastTile)
             and discardingPlayer.playedDangerous):
         player.usedDangerousFrom = discardingPlayer
         if Debug.dangerousGame:
             logDebug('%s wins with dangerous tile %s from %s' % \
                          (player, self.game.lastDiscard, discardingPlayer))
         block.tellAll(player, Message.UsedDangerousFrom, source=discardingPlayer.name)
     block.tellAll(player, Message.MahJongg, source=concealedMelds, lastTile=player.lastTile,
                  lastMeld=list(lastMeld.pairs), withDiscard=withDiscard)
     block.callback(self.endHand)
Ejemplo n.º 18
0
 def pickTile(self, dummyResults=None, deadEnd=False):
     """the active player gets a tile from wall. Tell all clients."""
     if not self.game:
         return
     player = self.game.activePlayer
     try:
         tile = player.pickedTile(deadEnd)
     except WallEmpty:
         self.endHand()
     else:
         tileName = tile.element
         self.game.lastDiscard = None
         block = DeferredBlock(self)
         block.tellPlayer(player, Message.PickedTile, source=tileName, deadEnd=deadEnd)
         if tileName[0] in 'fy' or self.game.playOpen:
             block.tellOthers(player, Message.PickedTile, source=tileName, deadEnd=deadEnd)
         else:
             block.tellOthers(player, Message.PickedTile, source= 'Xy', deadEnd=deadEnd)
         block.callback(self.moved)
Ejemplo n.º 19
0
 def clientMadeOriginalCall(self, dummyResults, msg):
     """first tell everybody about original call
     and then treat the implicit discard"""
     msg.player.originalCall = True
     if Debug.originalCall:
         logDebug('server.clientMadeOriginalCall: %s' % msg.player)
     block = DeferredBlock(self)
     block.tellAll(msg.player, Message.OriginalCall)
     block.callback(self._askForClaims, msg)
Ejemplo n.º 20
0
 def claimTile(self, player, claim, meldTiles, nextMessage):
     """a player claims a tile for pung, kong or chow.
     meldTiles contains the claimed tile, concealed"""
     if not self.game:
         return
     lastDiscard = self.game.lastDiscard
     claimedTile = lastDiscard.element
     hasTiles = meldTiles[:]
     discardingPlayer = self.game.activePlayer
     hasTiles.remove(claimedTile)
     meld = Meld(meldTiles)
     if len(meldTiles) != 4 and meld.meldType not in [PAIR, PUNG, KONG, CHOW]:
         msg = m18nE('%1 wrongly said %2 for meld %3') + 'x:' + str(meld.meldType) + meld.joined
         self.abort(msg, player.name, claim.name, str(meld))
         return
     if not player.hasConcealedTiles(hasTiles):
         msg = m18nE('%1 wrongly said %2: claims to have concealed tiles %3 but only has %4')
         self.abort(msg, player.name, claim.name, ' '.join(hasTiles), ''.join(player.concealedTileNames))
         return
     # update our internal state before we listen to the clients again
     self.game.discardedTiles[claimedTile.lower()] -= 1
     self.game.activePlayer = player
     if claimedTile:
         player.lastTile = claimedTile.lower()
         player.lastSource = 'd'
     player.exposeMeld(hasTiles, claimedTile)
     self.game.lastDiscard = None
     block = DeferredBlock(self)
     if (nextMessage != Message.Kong
             and self.game.dangerousFor(discardingPlayer, lastDiscard)
             and discardingPlayer.playedDangerous):
         player.usedDangerousFrom = discardingPlayer
         if Debug.dangerousGame:
             logDebug('%s claims dangerous tile %s discarded by %s' % \
                      (player, lastDiscard, discardingPlayer))
         block.tellAll(player, Message.UsedDangerousFrom, source=discardingPlayer.name)
     block.tellAll(player, nextMessage, source=meldTiles)
     if claim == Message.Kong:
         block.callback(self.pickKongReplacement)
     else:
         block.callback(self.moved)
Ejemplo n.º 21
0
 def _clientDiscarded3(self, dummyResults, msg, dangerousText,
                       mustPlayDangerous):
     """client told us he discarded a tile. Continue, check for calling"""
     block = DeferredBlock(self)
     player = msg.player
     if self.game.ruleset.mustDeclareCallingHand and not player.isCalling:
         if player.hand.callingHands:
             player.isCalling = True
             block.tellAll(player, Message.Calling)
     block.callback(self._clientDiscarded4, msg, dangerousText,
                    mustPlayDangerous)
Ejemplo n.º 22
0
 def _clientDiscarded2(self, dummyResults, msg, dangerousText,
                       mustPlayDangerous, violates):
     """client told us he discarded a tile. Continue, check for violating original call"""
     block = DeferredBlock(self)
     player = msg.player
     if violates:
         if Debug.originalCall:
             tile = Tile(msg.args[0])
             logDebug('%s just violated OC with %s' % (player, tile))
         player.mayWin = False
         block.tellAll(player, Message.ViolatesOriginalCall)
     block.callback(self._clientDiscarded3, msg, dangerousText,
                    mustPlayDangerous)
Ejemplo n.º 23
0
    def joinTable(self, user, tableid):
        """user joins table"""
        table = self._lookupTable(tableid)
        table.addUser(user)
        block = DeferredBlock(table)
        block.tell(None,
                   self.srvUsers,
                   Message.TableChanged,
                   source=table.asSimpleList())
        if len(table.users) == table.maxSeats():
            if Debug.table:
                logDebug('Table %s: All seats taken, starting' % table)

            def startTable(dummy):
                """now all players know about our join"""
                table.readyForGameStart(table.owner)

            block.callback(startTable)
        else:
            block.callback(False)
        return True
Ejemplo n.º 24
0
 def pickTile(self, dummyResults=None, deadEnd=False):
     """the active player gets a tile from wall. Tell all clients."""
     if not self.running:
         return
     player = self.game.activePlayer
     try:
         tile = player.pickedTile(deadEnd)
     except WallEmpty:
         self.endHand()
     else:
         self.game.lastDiscard = None
         block = DeferredBlock(self)
         block.tellPlayer(player,
                          Message.PickedTile,
                          tile=tile,
                          deadEnd=deadEnd)
         showTile = tile if tile.isBonus or self.game.playOpen else Tile.unknown
         block.tellOthers(player,
                          Message.PickedTile,
                          tile=showTile,
                          deadEnd=deadEnd)
         block.callback(self.moved)
Ejemplo n.º 25
0
 def initGame(self):
     """ask clients if they are ready to start"""
     game = self.game
     game.saveStartTime()
     block = DeferredBlock(self)
     for player in game.players:
         block.tellPlayer(player,
                          Message.ReadyForGameStart,
                          tableid=self.tableid,
                          gameid=game.gameid,
                          shouldSave=player.shouldSave,
                          wantedGame=game.wantedGame,
                          playerNames=list(
                              (x.wind, x.name) for x in game.players))
     block.callback(self.startGame)
Ejemplo n.º 26
0
 def proposeGameId(self, gameid):
     """server proposes an id to the clients ands waits for answers"""
     while True:
         query = Query('insert into game(id,seed) values(?,?)',
                       (gameid, 'proposed'),
                       mayFail=True,
                       failSilent=True)
         if not query.failure:
             break
         gameid += random.randrange(1, 100)
     block = DeferredBlock(self)
     for player in self.game.players:
         if player.shouldSave and isinstance(self.remotes[player], User):
             # do not ask robot players, they use the server data base
             block.tellPlayer(player, Message.ProposeGameId, gameid=gameid)
     block.callback(self.collectGameIdAnswers, gameid)
Ejemplo n.º 27
0
 def divided(self, dummyResults=None):
     """the wall is now divided for all clients"""
     if not self.running:
         return
     block = DeferredBlock(self)
     for clientPlayer in self.game.players:
         for player in self.game.players:
             if player == clientPlayer or self.game.playOpen:
                 tiles = player.concealedTiles
             else:
                 tiles = TileList(Tile.unknown * 13)
             block.tell(player,
                        clientPlayer,
                        Message.SetConcealedTiles,
                        tiles=TileList(chain(tiles, player.bonusTiles)))
     block.callback(self.dealt)
Ejemplo n.º 28
0
 def endHand(self, dummyResults=None):
     """hand is over, show all concealed tiles to all players"""
     if not self.running:
         return
     if self.game.playOpen:
         self.saveHand()
     else:
         block = DeferredBlock(self)
         for player in self.game.players:
             # there might be no winner, winner.others() would be wrong
             if player != self.game.winner:
                 # the winner tiles are already shown in claimMahJongg
                 block.tellOthers(player,
                                  Message.ShowConcealedTiles,
                                  show=True,
                                  tiles=TileList(player.concealedTiles))
         block.callback(self.saveHand)
Ejemplo n.º 29
0
 def leaveTable(self, user, tableid, message=None, *args):
     """user leaves table. If no human user is left on a new table, remove it"""
     if tableid in self.tables:
         table = self.tables[tableid]
         if user in table.users:
             if len(table.users) == 1 and not table.suspendedAt:
                 # silent: do not tell the user who left the table that he
                 # did
                 self.removeTable(table, 'silent', message, *args)
             else:
                 table.delUser(user)
                 if self.srvUsers:
                     block = DeferredBlock(table)
                     block.tell(None,
                                self.srvUsers,
                                Message.TableChanged,
                                source=table.asSimpleList())
                     block.callback(False)
     return True
Ejemplo n.º 30
0
 def clientDiscarded(self, msg):
     """client told us he discarded a tile. Check for consistency and tell others."""
     if not self.running:
         return
     player = msg.player
     assert player == self.game.activePlayer
     tile = Tile(msg.args[0])
     if tile not in player.concealedTiles:
         self.abort('player %s discarded %s but does not have it' %
                    (player, tile))
         return
     dangerousText = self.game.dangerousFor(player, tile)
     mustPlayDangerous = player.mustPlayDangerous()
     violates = player.violatesOriginalCall(tile)
     self.game.hasDiscarded(player, tile)
     block = DeferredBlock(self)
     block.tellAll(player, Message.Discard, tile=tile)
     block.callback(self._clientDiscarded2, msg, dangerousText,
                    mustPlayDangerous, violates)
Ejemplo n.º 31
0
 def sendVoiceData(self, requests, voiceDataRequests):
     """sends voice sounds to other human players"""
     self.processAnswers(requests)
     block = DeferredBlock(self)
     for voiceDataRequester, voiceFor in voiceDataRequests:
         # this player requested sounds for voiceFor
         voice = voiceFor.voice
         content = voice.archiveContent
         if content:
             if Debug.sound:
                 logDebug('server got voice data %s for %s from client' %
                          (voiceFor.voice, voiceFor.name))
             block.tell(voiceFor,
                        voiceDataRequester,
                        Message.VoiceData,
                        md5sum=voice.md5sum,
                        source=content)
         elif Debug.sound:
             logDebug('server got empty voice data %s for %s from client' %
                      (voice, voiceFor.name))
     block.callback(self.assignVoices)
Ejemplo n.º 32
0
 def tellOthers(self, player, command, callback=None, **kwargs):
     """tell something about player to all other players"""
     block = DeferredBlock(self)
     block.tellOthers(player, command, **kwargs)
     block.callback(callback)
     return block
Ejemplo n.º 33
0
 def assignVoices(self, dummyResults=None):
     """now all human players have all voice data needed"""
     humanPlayers = [x for x in self.game.players if isinstance(x.remote, User)]
     block = DeferredBlock(self)
     block.tell(None, humanPlayers, Message.AssignVoices)
     block.callback(self.startHand)
Ejemplo n.º 34
0
 def clientDiscarded(self, msg):
     """client told us he discarded a tile. Check for consistency and tell others."""
     # pylint: disable=R0912
     # too many branches
     player = msg.player
     game = self.game
     if not game:
         return
     assert player == game.activePlayer
     tile = msg.args[0]
     if tile not in player.concealedTileNames:
         self.abort('player %s discarded %s but does not have it' % (player, tile))
         return
     txt = game.dangerousFor(player, tile)
     mustPlayDangerous = player.mustPlayDangerous()
     block = DeferredBlock(self)
     game.hasDiscarded(player, tile)
     block.tellAll(player, Message.Discard, tile=tile)
     if player.violatesOriginalCall():
         if Debug.originalCall:
             logDebug('%s just violated OC with %s' % (player, player.discarded[-1]))
         player.mayWin = False
         block.tellAll(player, Message.ViolatedOriginalCall)
     if game.ruleset.mustDeclareCallingHand and not player.isCalling:
         if player.hand.callingHands(mustBeAvailable=True):
             player.isCalling = True
             block.tellAll(player, Message.Calling)
     if txt:
         if mustPlayDangerous and player.lastSource not in 'dZ':
             if Debug.dangerousGame:
                 logDebug('%s claims no choice. Discarded %s, keeping %s. %s' % \
                      (player, tile, ''.join(player.concealedTileNames), ' / '.join(txt)))
             player.claimedNoChoice = True
             block.tellAll(player, Message.HasNoChoice, tile=player.concealedTileNames)
         else:
             player.playedDangerous = True
             if Debug.dangerousGame:
                 logDebug('%s played dangerous. Discarded %s, keeping %s. %s' % \
                      (player, tile, ''.join(player.concealedTileNames), ' / '.join(txt)))
             block.tellAll(player, Message.PlayedDangerous, tile=player.concealedTileNames)
     if msg.answer == Message.OriginalCall:
         block.callback(self.clientMadeOriginalCall, msg)
     else:
         block.callback(self.askForClaims)
Ejemplo n.º 35
0
 def tellAll(self, player, command, callback=None, **kwargs):
     """tell something about player to all players"""
     block = DeferredBlock(self)
     block.tellAll(player, command, **kwargs)
     block.callback(callback)
     return block