def loadSuspendedTables(self, user): """loads all yet unloaded suspended tables where this user is participating. We do not unload them if the user logs out, there are filters anyway returning only the suspended games for a certain user. Never load old autoplay games.""" query = Query("select distinct g.id, g.starttime, " \ "g.seed, " \ "ruleset, s.scoretime " \ "from game g, player p0, score s," \ "player p1, player p2, player p3 " \ "where autoplay=0 " \ " and p0.id=g.p0 and p1.id=g.p1 " \ " and p2.id=g.p2 and p3.id=g.p3 " \ " and (p0.name=? or p1.name=? or p2.name=? or p3.name=?) " \ " and s.game=g.id" \ " and g.endtime is null" \ " and exists(select 1 from score where game=g.id)" \ " and s.scoretime = (select max(scoretime) from score where game=g.id) limit 10", list([user.name, user.name, user.name, user.name])) for gameid, starttime, seed, ruleset, suspendTime in query.records: playOpen = False # do not continue playing resumed games with open tiles, # playOpen is for testing purposes only anyway if gameid not in self.suspendedTables and starttime: # why do we get a record with empty fields when the query should return nothing? if gameid not in (x.game.gameid if x.game else None for x in self.tables.values()): table = Table(self, None, Ruleset.cached(ruleset, used=True), playOpen, autoPlay=False, wantedGame=str(seed)) table.tableid = 1000 + gameid table.status = m18ncE('table status', 'Suspended') + suspendTime table.preparedGame = RemoteGame.loadFromDB(gameid, None, cacheRuleset=True) self.suspendedTables[gameid] = table
def __init__(self, tableid, ruleset, suspendedAt, running, playOpen, autoPlay, wantedGame): self.tableid = tableid if isinstance(ruleset, Ruleset): self.ruleset = ruleset else: self.ruleset = Ruleset.cached(ruleset) self.suspendedAt = suspendedAt self.running = running self.playOpen = playOpen self.autoPlay = autoPlay self.wantedGame = wantedGame
def loadFromDB(cls, gameid, client=None): """load game by game id and return a new Game instance""" Internal.logPrefix = 'S' if Internal.isServer else 'C' qGame = Query("select p0,p1,p2,p3,ruleset,seed from game where id = %d" % gameid) if not qGame.records: return None rulesetId = qGame.records[0][4] or 1 ruleset = Ruleset.cached(rulesetId) Players.load() # we want to make sure we have the current definitions game = cls(Game.__getNames(qGame.records[0]), ruleset, gameid=gameid, client=client, wantedGame=qGame.records[0][5]) qLastHand = Query("select hand,rotated from score where game=%d and hand=" "(select max(hand) from score where game=%d)" % (gameid, gameid)) if qLastHand.records: (game.handctr, game.rotated) = qLastHand.records[0] qScores = Query("select player, wind, balance, won, prevailing from score " "where game=%d and hand=%d" % (gameid, game.handctr)) # default value. If the server saved a score entry but our client did not, # we get no record here. Should we try to fix this or exclude such a game from # the list of resumable games? prevailing = 'E' for record in qScores.records: playerid = record[0] wind = str(record[1]) player = game.players.byId(playerid) if not player: logError( 'game %d inconsistent: player %d missing in game table' % \ (gameid, playerid)) else: player.getsPayment(record[2]) player.wind = wind if record[3]: game.winner = player prevailing = record[4] game.roundsFinished = WINDS.index(prevailing) game.handctr += 1 game.notRotated += 1 game.maybeRotateWinds() game.sortPlayers() game.wall.decorate() return game
def loadFromDB(cls, gameid, client=None): """load game by game id and return a new Game instance""" Internal.logPrefix = 'S' if Internal.isServer else 'C' records = Query( "select p0,p1,p2,p3,ruleset,seed from game where id = ?", (gameid, )).records if not records: return None qGameRecord = records[0] rulesetId = qGameRecord[4] or 1 ruleset = Ruleset.cached(rulesetId) Players.load() # we want to make sure we have the current definitions records = Query( "select hand,rotated from score where game=? and hand=" "(select max(hand) from score where game=?)", (gameid, gameid)).records if records: qLastHandRecord = records[0] else: qLastHandRecord = tuple([0, 0]) qScoreRecords = Query( "select player, wind, balance, won, prevailing from score " "where game=? and hand=?", (gameid, qLastHandRecord[0])).records if not qScoreRecords: # this should normally not happen qScoreRecords = list([ tuple([qGameRecord[wind], wind.char, 0, False, East.char]) for wind in Wind.all4 ]) if len(qScoreRecords) != 4: logError('game %d inconsistent: There should be exactly ' '4 score records for the last hand' % gameid) # after loading SQL, prepare values. # default value. If the server saved a score entry but our client # did not, we get no record here. Should we try to fix this or # exclude such a game from the list of resumable games? if len(set(x[4] for x in qScoreRecords)) != 1: logError('game %d inconsistent: All score records for the same ' 'hand must have the same prevailing wind' % gameid) players = list( tuple([Wind(x[1]), Game.__getName(x[0])]) for x in qScoreRecords) # create the game instance. game = cls(players, ruleset, gameid=gameid, client=client, wantedGame=qGameRecord[5]) game.handctr, game.rotated = qLastHandRecord for record in qScoreRecords: playerid = record[0] player = game.players.byId(playerid) if not player: logError( 'game %d inconsistent: player %d missing in game table' % (gameid, playerid)) else: player.getsPayment(record[2]) if record[3]: game.winner = player game.roundsFinished = Wind(qScoreRecords[0][4]).__index__() game.handctr += 1 game.notRotated += 1 game.maybeRotateWinds() game.sortPlayers() with AnimationSpeed(Speeds.windMarker): animateAndDo(game.wall.decorate4) return game
def remote_needRuleset(ruleset): """server only knows hash, needs full definition""" result = Ruleset.cached(ruleset) assert result and result.hash == ruleset return result.toList()
def gotRulesets(result): """the server sent us the wanted ruleset definitions""" for ruleset in result: Ruleset.cached(ruleset).save(copy=True) # make it known to the cache and save in db return tables
def gotRulesets(result): """the server sent us the wanted ruleset definitions""" for ruleset in result: Ruleset.cached(ruleset).save() # make it known to the cache and save in db return tables
def loadFromDB(cls, gameid, client=None): """load game by game id and return a new Game instance""" Internal.logPrefix = 'S' if Internal.isServer else 'C' records = Query( "select p0,p1,p2,p3,ruleset,seed from game where id = ?", (gameid,)).records if not records: return None qGameRecord = records[0] rulesetId = qGameRecord[4] or 1 ruleset = Ruleset.cached(rulesetId) Players.load() # we want to make sure we have the current definitions records = Query( "select hand,rotated from score where game=? and hand=" "(select max(hand) from score where game=?)", (gameid, gameid)).records if records: qLastHandRecord = records[0] else: qLastHandRecord = tuple([0, 0]) qScoreRecords = Query( "select player, wind, balance, won, prevailing from score " "where game=? and hand=?", (gameid, qLastHandRecord[0])).records if not qScoreRecords: # this should normally not happen qScoreRecords = list([ tuple([qGameRecord[wind], wind.char, 0, False, East.char]) for wind in Wind.all4]) if len(qScoreRecords) != 4: logError(u'game %d inconsistent: There should be exactly ' '4 score records for the last hand' % gameid) # after loading SQL, prepare values. # default value. If the server saved a score entry but our client # did not, we get no record here. Should we try to fix this or # exclude such a game from the list of resumable games? if len(set(x[4] for x in qScoreRecords)) != 1: logError(u'game %d inconsistent: All score records for the same ' 'hand must have the same prevailing wind' % gameid) players = list(tuple([Wind(x[1]), Game.__getName(x[0])]) for x in qScoreRecords) # create the game instance. game = cls(players, ruleset, gameid=gameid, client=client, wantedGame=qGameRecord[5]) game.handctr, game.rotated = qLastHandRecord for record in qScoreRecords: playerid = record[0] player = game.players.byId(playerid) if not player: logError( u'game %d inconsistent: player %d missing in game table' % (gameid, playerid)) else: player.getsPayment(record[2]) if record[3]: game.winner = player game.roundsFinished = Wind(qScoreRecords[0][4]).__index__() game.handctr += 1 game.notRotated += 1 game.maybeRotateWinds() game.sortPlayers() game.wall.decorate() return game
def gotRuleset(ruleset): """now we have the full ruleset definition from the client""" Ruleset.cached( ruleset).save() # make it known to the cache and save in db