diff src/plugins/plugin_misc_room_game.py @ 791:23b0c949b86c

plugins room games, XEP-0045: small fixes, improved docstrings
author souliane <souliane@mailoo.org>
date Fri, 10 Jan 2014 18:07:36 +0100
parents 19262fb77230
children 1fe00f0c9a91
line wrap: on
line diff
--- a/src/plugins/plugin_misc_room_game.py	Thu Jan 09 10:28:25 2014 +0100
+++ b/src/plugins/plugin_misc_room_game.py	Fri Jan 10 18:07:36 2014 +0100
@@ -147,6 +147,7 @@
         referee = room_jid_s + '/' + referee_nick
         self.games[room_jid_s] = {'referee': referee, 'players': [], 'started': False}
         self.games[room_jid_s].update(copy.deepcopy(self.game_init))
+        self.invitations.setdefault(room_jid_s, [])
 
     def _gameExists(self, room_jid_s, started=False):
         """Return True if a game has been initialized/started.
@@ -172,6 +173,7 @@
         elif self.join_mode == self.ALL or self.isPlayer(room_jid_s, nick):
             auth = True
         elif self.join_mode == self.INVITED:
+            user_jid_s = JID(user_jid_s).userhost()
             # considering all the batches of invitations
             for invitations in self.invitations[room_jid_s]:
                 if user_jid_s is not None:
@@ -190,17 +192,27 @@
         return auth
 
     def _updatePlayers(self, room_jid_s, nicks, profile):
-        """Signal to the room that some players joined the game"""
+        """Update the list of players and signal to the room that some players joined the game.
+        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)
+        """
         if nicks == []:
             return
-        new_nicks = set(nicks).difference(self.games[room_jid_s]['players'])
+        # this is better than set(nicks).difference(...) as it keeps the order
+        new_nicks = [nick for nick in nicks if nick not in self.games[room_jid_s]['players']]
         if len(new_nicks) == 0:
             return
         self.games[room_jid_s]['players'].extend(new_nicks)
         self._signalPlayers(room_jid_s, [JID(room_jid_s)], profile)
 
     def _signalPlayers(self, room_jid_s, recipients, profile):
-        """Let these guys know that we are playing (they may not play themselves)."""
+        """Let these guys know that we are playing (they may not play themselves).
+        @param room_jid_s: room userhost
+        @recipients: list of JIDs, the recipients of the message could be:
+        - room JID
+        - room JID + "/" + user nick
+        """
         if self._gameExists(room_jid_s, started=True):
             element = self._createStartElement(self.games[room_jid_s]['players'])
         else:
@@ -224,17 +236,17 @@
         @param room: wokkel.muc.Room instance
         @param other_players: list of JID userhosts to invite
         @param nick: nick of the user who send the invitation
-        @return: list of the invited players who were already in the room
+        @return: list of room nicks for invited players who are already in the room
         """
         room_jid = room.occupantJID.userhostJID()
         room_jid_s = room.occupantJID.userhost()
         if not self._checkInviteAuth(room_jid_s, nick):
             return []
-        self.invitations.setdefault(room_jid_s, [])
         # TODO: remove invitation waiting for too long, using the time data
-        self.invitations[room_jid_s].append((time(), other_players))
-        nicks = [nick]
-        for player_jid in [JID(player) for player in other_players]:
+        players_jids = [JID(player) for player in other_players]
+        self.invitations[room_jid_s].append((time(), [player.userhost() for player in players_jids]))
+        nicks = []
+        for player_jid in [player.userhostJID() for player in players_jids]:
             # TODO: find a way to make it secure
             other_nick = self.host.plugins["XEP-0045"].getRoomNickOfUser(room, player_jid, secure=False)
             if other_nick is None:
@@ -254,7 +266,7 @@
         if self.invite_mode == self.FROM_ALL or not self._gameExists(room_jid_s):
             auth = True
         elif self.invite_mode == self.FROM_NONE:
-            auth = not self._gameExists(room_jid_s, started=True)
+            auth = not self._gameExists(room_jid_s, started=True) and self.isReferee(room_jid_s, nick)
         elif self.invite_mode == self.FROM_REFEREE:
             auth = self.isReferee(room_jid_s, nick)
         elif self.invite_mode == self.FROM_PLAYERS:
@@ -288,7 +300,7 @@
     def _checkWaitAuth(self, room, other_players, verbose=False):
         """Check if we must wait for other players before starting the game.
         @param room: wokkel.muc.Room instance
-        @param other_players: list of the players without the referee
+        @param other_players: list of players JID userhosts without the referee
         @param verbose: display debug message
         @return: (x, y, z) with:
         x: False if we must wait, True otherwise
@@ -297,7 +309,8 @@
         """
         if self.wait_mode == self.FOR_NONE or other_players == []:
             result = (True, [], other_players)
-        elif len(room.roster) < len(other_players) + 1:
+        elif len(room.roster) < len(other_players):
+            # do not check the players until we may actually have them all
             result = (False, [], other_players)
         else:
             # TODO: find a way to make it secure
@@ -330,7 +343,7 @@
 
         def roomJoined(room):
             """@param room: instance of wokkel.muc.Room"""
-            self._createOrInvite(room, other_players, profile)
+            self._createOrInvite(room, [JID(player).userhost() for player in other_players], profile)
 
         def afterClientInit(room_jid_s):
             """Create/join the given room, or a unique generated one if no room is specified.
@@ -365,7 +378,7 @@
         profile_nick = room.occupantJID.resource
         if not self.isReferee(room_jid_s, profile_nick):
             return True  # profile is not the referee
-        if not self._checkJoinAuth(room_jid_s, nick=user.nick):
+        if not self._checkJoinAuth(room_jid_s, user.entity.userhost() if user.entity else None, user.nick):
             # user not allowed but let him know that we are playing :p
             self._signalPlayers(room_jid_s, [JID(room_jid_s + '/' + user.nick)], profile)
             return True
@@ -403,13 +416,13 @@
                 pass
             if self.wait_mode == self.FOR_ALL:
                 # allow this user to join the game again
-                user_jid = user.entity.userhost()
+                user_jid_s = user.entity.userhost()
                 if len(self.invitations[room_jid_s]) == 0:
-                    self.invitations[room_jid_s].append((time(), [user_jid]))
+                    self.invitations[room_jid_s].append((time(), [user_jid_s]))
                 else:
                     batch = 0  # add to the first batch of invitations
-                    if user_jid not in self.invitations[room_jid_s][batch][1]:
-                        self.invitations[room_jid_s][batch][1].append(user_jid)
+                    if user_jid_s not in self.invitations[room_jid_s][batch][1]:
+                        self.invitations[room_jid_s][batch][1].append(user_jid_s)
         return True
 
     def _checkCreateGameAndInit(self, room_jid_s, profile):
@@ -442,7 +455,7 @@
         and skips all the checks and invitation system, but the game must
         not exist and all the players must be in the room already.
         @param room_jid: JID userhost of the room
-        @param nicks: list of players nicks in the room
+        @param nicks: list of players nicks in the room (referee included, in first position)
         @param profile_key: %(doc_profile_key)s"""
         debug(_("Creating %s game in room %s") % (self.name, room_jid_s))
         profile = self.host.memory.getProfileName(profile_key)