Mercurial > libervia-backend
diff src/plugins/plugin_misc_room_game.py @ 828:8f335c03eebb
plugins room_games, radiocol, libervia: small changes like refactorization to ease the maintenance
author | souliane <souliane@mailoo.org> |
---|---|
date | Fri, 17 Jan 2014 15:02:46 +0100 |
parents | e3f4d80f987d |
children | f3513c8cc2e6 |
line wrap: on
line diff
--- a/src/plugins/plugin_misc_room_game.py Thu Jan 16 11:44:14 2014 +0100 +++ b/src/plugins/plugin_misc_room_game.py Fri Jan 17 15:02:46 2014 +0100 @@ -108,14 +108,19 @@ self.join_mode = self.INVITED self.ready_mode = self.FORCE # TODO: asking for confirmation is not implemented + # this has been added for testing purpose. It is sometimes needed to remove a dependence + # while building the synchronization data, for example to replace a call to time.time() + # by an arbitrary value. If needed, this attribute would be set to True from the testcase. + self.testing = False + host.trigger.add("MUC user joined", self.userJoinedTrigger) host.trigger.add("MUC user left", self.userLeftTrigger) def _createOrInvite(self, room, other_players, profile): """ This is called only when someone explicitly wants to play. - The game must not be created if one already exists in the room, - and its creation could be postponed until all the expected players + The game will not be created if one already exists in the room, + also its creation could be postponed until all the expected players join the room (in that case it will be created from userJoinedTrigger). @param room: instance of wokkel.muc.Room @param other_players: list for other players JID userhosts @@ -128,7 +133,7 @@ if not self._checkJoinAuth(room_jid_s, user_jid.userhost(), nick): return nicks.extend(self._invitePlayers(room, other_players, nick, profile)) - self._updatePlayers(room_jid_s, nicks, profile) + self._updatePlayers(room_jid_s, nicks, True, profile) else: self._initGame(room_jid_s, nick) (auth, waiting, missing) = self._checkWaitAuth(room, other_players) @@ -137,7 +142,7 @@ if auth: self.createGame(room_jid_s, nicks, profile) else: - self._updatePlayers(room_jid_s, nicks, profile) + self._updatePlayers(room_jid_s, nicks, False, profile) def _initGame(self, room_jid_s, referee_nick): """Important: do not add the referee to 'players' yet. For a @@ -191,11 +196,14 @@ debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s)) return auth - def _updatePlayers(self, room_jid_s, nicks, profile): + def _updatePlayers(self, room_jid_s, nicks, sync, profile): """Update the list of players and signal to the room that some players joined the game. + If sync is True, the news players are synchronized with the game data they have missed. Remark: self.games[room_jid_s]['players'] should not be modified outside this method. @param room_jid_s: room userhost @param nicks: list of players nicks in the room (referee included, in first position) + @param sync: set to True to send synchronization data to the new players + @param profile """ if nicks == []: return @@ -203,12 +211,12 @@ new_nicks = [nick for nick in nicks if nick not in self.games[room_jid_s]['players']] if len(new_nicks) == 0: return - sync = self._gameExists(room_jid_s, True) and len(self.games[room_jid_s]['players']) > 0 def setStatus(status): for nick in new_nicks: self.games[room_jid_s]['status'][nick] = status + sync = sync and self._gameExists(room_jid_s, True) and len(self.games[room_jid_s]['players']) > 0 setStatus('desync' if sync else 'init') self.games[room_jid_s]['players'].extend(new_nicks) self._synchronizeRoom(room_jid_s, [JID(room_jid_s)], profile) @@ -231,7 +239,7 @@ elements = [(element, None, None)] sync_args = [] - sync_data = self.getSyncData(room_jid_s) + sync_data = self._getSyncData(room_jid_s) for nick in sync_data: user_jid = JID(room_jid_s + '/' + nick) if user_jid in recipients: @@ -248,16 +256,35 @@ for args, kwargs in sync_args: self._sendElements(*args, **kwargs) - def getSyncData(self, room_jid_s, force_nicks=[]): - """This method may (and should probably) be overwritten by a child class. - The synchronization data are returned for each player who has the state - 'desync' or if he's been contained by force_nicks. + def _getSyncData(self, room_jid_s, force_nicks=[]): + """The synchronization data are returned for each player who + has the state 'desync' or if he's been contained by force_nicks. @param room_jid_s: room userhost @param force_nicks: force the synchronization for this list of the nicks - @return: a mapping between player nicks and a list of child elements - to be sent by self._synchronizeRoom for the game to be synchronized. + @return: a mapping between player nicks and a list of elements to + be sent by self._synchronizeRoom for the game to be synchronized. """ - return {} + if not self._gameExists(room_jid_s): + return {} + data = {} + status = self.games[room_jid_s]['status'] + nicks = [nick for nick in status if status[nick] == 'desync'] + for nick in force_nicks: + if nick not in nicks: + nicks.append(nick) + for nick in nicks: + elements = self.getSyncDataForPlayer(room_jid_s, nick) + if elements: + data[nick] = elements + return data + + def getSyncDataForPlayer(self, room_jid_s, nick): + """This method may (and should probably) be overwritten by a child class. + @param room_jid_s: room userhost + @param nick: the nick of the player to be synchronized + @return: a list of elements to synchronize this player with the game. + """ + return [] def _invitePlayers(self, room, other_players, nick, profile): """Invite players to a room, associated game may exist or not. @@ -424,7 +451,7 @@ self.createGame(room_jid_s, nicks, profile_key=profile) return True # let the room know that a new player joined - self._updatePlayers(room_jid_s, [user.nick], profile) + self._updatePlayers(room_jid_s, [user.nick], True, profile) return True def userLeftTrigger(self, room, user, profile): @@ -442,6 +469,9 @@ self.games[room_jid_s]['players'].remove(user.nick) except ValueError: pass + if len(self.games[room_jid_s]['players']) == 0: + del self.games[room_jid_s] # finish the game + return True if self.wait_mode == self.FOR_ALL: # allow this user to join the game again user_jid_s = user.entity.userhost() @@ -493,11 +523,10 @@ (create, sync) = self._checkCreateGameAndInit(room_jid_s, profile) if not create: if sync: - debug(_('Synchronize game %s in %s for %s') % (self.name, room_jid_s, ', '.join(nicks))) - self._updatePlayers(room_jid_s, nicks, profile) + self._updatePlayers(room_jid_s, nicks, True, profile) return self.games[room_jid_s]['started'] = True - self._updatePlayers(room_jid_s, nicks, profile) + self._updatePlayers(room_jid_s, nicks, False, profile) if self.player_init: # specific data to each player (score, private data) self.games[room_jid_s].setdefault('players_data', {})