Mercurial > libervia-backend
comparison 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 |
comparison
equal
deleted
inserted
replaced
790:19262fb77230 | 791:23b0c949b86c |
---|---|
145 it is necessary to not modify 'players' outside of _updatePlayers. | 145 it is necessary to not modify 'players' outside of _updatePlayers. |
146 """ | 146 """ |
147 referee = room_jid_s + '/' + referee_nick | 147 referee = room_jid_s + '/' + referee_nick |
148 self.games[room_jid_s] = {'referee': referee, 'players': [], 'started': False} | 148 self.games[room_jid_s] = {'referee': referee, 'players': [], 'started': False} |
149 self.games[room_jid_s].update(copy.deepcopy(self.game_init)) | 149 self.games[room_jid_s].update(copy.deepcopy(self.game_init)) |
150 self.invitations.setdefault(room_jid_s, []) | |
150 | 151 |
151 def _gameExists(self, room_jid_s, started=False): | 152 def _gameExists(self, room_jid_s, started=False): |
152 """Return True if a game has been initialized/started. | 153 """Return True if a game has been initialized/started. |
153 @param started: if False, the game must be initialized to return True, | 154 @param started: if False, the game must be initialized to return True, |
154 otherwise it must be initialized and started with createGame. | 155 otherwise it must be initialized and started with createGame. |
170 if not self._gameExists(room_jid_s): | 171 if not self._gameExists(room_jid_s): |
171 auth = False | 172 auth = False |
172 elif self.join_mode == self.ALL or self.isPlayer(room_jid_s, nick): | 173 elif self.join_mode == self.ALL or self.isPlayer(room_jid_s, nick): |
173 auth = True | 174 auth = True |
174 elif self.join_mode == self.INVITED: | 175 elif self.join_mode == self.INVITED: |
176 user_jid_s = JID(user_jid_s).userhost() | |
175 # considering all the batches of invitations | 177 # considering all the batches of invitations |
176 for invitations in self.invitations[room_jid_s]: | 178 for invitations in self.invitations[room_jid_s]: |
177 if user_jid_s is not None: | 179 if user_jid_s is not None: |
178 if user_jid_s in invitations[1]: | 180 if user_jid_s in invitations[1]: |
179 auth = True | 181 auth = True |
188 if not auth and (verbose or _DEBUG): | 190 if not auth and (verbose or _DEBUG): |
189 debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s)) | 191 debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s)) |
190 return auth | 192 return auth |
191 | 193 |
192 def _updatePlayers(self, room_jid_s, nicks, profile): | 194 def _updatePlayers(self, room_jid_s, nicks, profile): |
193 """Signal to the room that some players joined the game""" | 195 """Update the list of players and signal to the room that some players joined the game. |
196 Remark: self.games[room_jid_s]['players'] should not be modified outside this method. | |
197 @param room_jid_s: room userhost | |
198 @param nicks: list of players nicks in the room (referee included, in first position) | |
199 """ | |
194 if nicks == []: | 200 if nicks == []: |
195 return | 201 return |
196 new_nicks = set(nicks).difference(self.games[room_jid_s]['players']) | 202 # this is better than set(nicks).difference(...) as it keeps the order |
203 new_nicks = [nick for nick in nicks if nick not in self.games[room_jid_s]['players']] | |
197 if len(new_nicks) == 0: | 204 if len(new_nicks) == 0: |
198 return | 205 return |
199 self.games[room_jid_s]['players'].extend(new_nicks) | 206 self.games[room_jid_s]['players'].extend(new_nicks) |
200 self._signalPlayers(room_jid_s, [JID(room_jid_s)], profile) | 207 self._signalPlayers(room_jid_s, [JID(room_jid_s)], profile) |
201 | 208 |
202 def _signalPlayers(self, room_jid_s, recipients, profile): | 209 def _signalPlayers(self, room_jid_s, recipients, profile): |
203 """Let these guys know that we are playing (they may not play themselves).""" | 210 """Let these guys know that we are playing (they may not play themselves). |
211 @param room_jid_s: room userhost | |
212 @recipients: list of JIDs, the recipients of the message could be: | |
213 - room JID | |
214 - room JID + "/" + user nick | |
215 """ | |
204 if self._gameExists(room_jid_s, started=True): | 216 if self._gameExists(room_jid_s, started=True): |
205 element = self._createStartElement(self.games[room_jid_s]['players']) | 217 element = self._createStartElement(self.games[room_jid_s]['players']) |
206 else: | 218 else: |
207 element = self._createStartElement(self.games[room_jid_s]['players'], name="players") | 219 element = self._createStartElement(self.games[room_jid_s]['players'], name="players") |
208 elements = [(element, None, None)] | 220 elements = [(element, None, None)] |
222 def _invitePlayers(self, room, other_players, nick, profile): | 234 def _invitePlayers(self, room, other_players, nick, profile): |
223 """Invite players to a room, associated game may exist or not. | 235 """Invite players to a room, associated game may exist or not. |
224 @param room: wokkel.muc.Room instance | 236 @param room: wokkel.muc.Room instance |
225 @param other_players: list of JID userhosts to invite | 237 @param other_players: list of JID userhosts to invite |
226 @param nick: nick of the user who send the invitation | 238 @param nick: nick of the user who send the invitation |
227 @return: list of the invited players who were already in the room | 239 @return: list of room nicks for invited players who are already in the room |
228 """ | 240 """ |
229 room_jid = room.occupantJID.userhostJID() | 241 room_jid = room.occupantJID.userhostJID() |
230 room_jid_s = room.occupantJID.userhost() | 242 room_jid_s = room.occupantJID.userhost() |
231 if not self._checkInviteAuth(room_jid_s, nick): | 243 if not self._checkInviteAuth(room_jid_s, nick): |
232 return [] | 244 return [] |
233 self.invitations.setdefault(room_jid_s, []) | |
234 # TODO: remove invitation waiting for too long, using the time data | 245 # TODO: remove invitation waiting for too long, using the time data |
235 self.invitations[room_jid_s].append((time(), other_players)) | 246 players_jids = [JID(player) for player in other_players] |
236 nicks = [nick] | 247 self.invitations[room_jid_s].append((time(), [player.userhost() for player in players_jids])) |
237 for player_jid in [JID(player) for player in other_players]: | 248 nicks = [] |
249 for player_jid in [player.userhostJID() for player in players_jids]: | |
238 # TODO: find a way to make it secure | 250 # TODO: find a way to make it secure |
239 other_nick = self.host.plugins["XEP-0045"].getRoomNickOfUser(room, player_jid, secure=False) | 251 other_nick = self.host.plugins["XEP-0045"].getRoomNickOfUser(room, player_jid, secure=False) |
240 if other_nick is None: | 252 if other_nick is None: |
241 self.host.plugins["XEP-0249"].invite(player_jid, room_jid, {"game": self.name}, profile) | 253 self.host.plugins["XEP-0249"].invite(player_jid, room_jid, {"game": self.name}, profile) |
242 else: | 254 else: |
252 """ | 264 """ |
253 auth = False | 265 auth = False |
254 if self.invite_mode == self.FROM_ALL or not self._gameExists(room_jid_s): | 266 if self.invite_mode == self.FROM_ALL or not self._gameExists(room_jid_s): |
255 auth = True | 267 auth = True |
256 elif self.invite_mode == self.FROM_NONE: | 268 elif self.invite_mode == self.FROM_NONE: |
257 auth = not self._gameExists(room_jid_s, started=True) | 269 auth = not self._gameExists(room_jid_s, started=True) and self.isReferee(room_jid_s, nick) |
258 elif self.invite_mode == self.FROM_REFEREE: | 270 elif self.invite_mode == self.FROM_REFEREE: |
259 auth = self.isReferee(room_jid_s, nick) | 271 auth = self.isReferee(room_jid_s, nick) |
260 elif self.invite_mode == self.FROM_PLAYERS: | 272 elif self.invite_mode == self.FROM_PLAYERS: |
261 auth = self.isPlayer(room_jid_s, nick) | 273 auth = self.isPlayer(room_jid_s, nick) |
262 if not auth and (verbose or _DEBUG): | 274 if not auth and (verbose or _DEBUG): |
286 return nick in self.games[room_jid_s]['players'] or self.isReferee(room_jid_s, nick) | 298 return nick in self.games[room_jid_s]['players'] or self.isReferee(room_jid_s, nick) |
287 | 299 |
288 def _checkWaitAuth(self, room, other_players, verbose=False): | 300 def _checkWaitAuth(self, room, other_players, verbose=False): |
289 """Check if we must wait for other players before starting the game. | 301 """Check if we must wait for other players before starting the game. |
290 @param room: wokkel.muc.Room instance | 302 @param room: wokkel.muc.Room instance |
291 @param other_players: list of the players without the referee | 303 @param other_players: list of players JID userhosts without the referee |
292 @param verbose: display debug message | 304 @param verbose: display debug message |
293 @return: (x, y, z) with: | 305 @return: (x, y, z) with: |
294 x: False if we must wait, True otherwise | 306 x: False if we must wait, True otherwise |
295 y: the nicks of the players that have been checked and confirmed | 307 y: the nicks of the players that have been checked and confirmed |
296 z: the players that have not been checked or that are missing | 308 z: the players that have not been checked or that are missing |
297 """ | 309 """ |
298 if self.wait_mode == self.FOR_NONE or other_players == []: | 310 if self.wait_mode == self.FOR_NONE or other_players == []: |
299 result = (True, [], other_players) | 311 result = (True, [], other_players) |
300 elif len(room.roster) < len(other_players) + 1: | 312 elif len(room.roster) < len(other_players): |
313 # do not check the players until we may actually have them all | |
301 result = (False, [], other_players) | 314 result = (False, [], other_players) |
302 else: | 315 else: |
303 # TODO: find a way to make it secure | 316 # TODO: find a way to make it secure |
304 (nicks, missing) = self.host.plugins["XEP-0045"].getRoomNicksOfUsers(room, other_players, secure=False) | 317 (nicks, missing) = self.host.plugins["XEP-0045"].getRoomNicksOfUsers(room, other_players, secure=False) |
305 result = (len(nicks) == len(other_players), nicks, missing) | 318 result = (len(nicks) == len(other_players), nicks, missing) |
328 error(_("Unknown profile")) | 341 error(_("Unknown profile")) |
329 return | 342 return |
330 | 343 |
331 def roomJoined(room): | 344 def roomJoined(room): |
332 """@param room: instance of wokkel.muc.Room""" | 345 """@param room: instance of wokkel.muc.Room""" |
333 self._createOrInvite(room, other_players, profile) | 346 self._createOrInvite(room, [JID(player).userhost() for player in other_players], profile) |
334 | 347 |
335 def afterClientInit(room_jid_s): | 348 def afterClientInit(room_jid_s): |
336 """Create/join the given room, or a unique generated one if no room is specified. | 349 """Create/join the given room, or a unique generated one if no room is specified. |
337 @param room_jids: userhost of the room to join | 350 @param room_jids: userhost of the room to join |
338 """ | 351 """ |
363 """ | 376 """ |
364 room_jid_s = room.occupantJID.userhost() | 377 room_jid_s = room.occupantJID.userhost() |
365 profile_nick = room.occupantJID.resource | 378 profile_nick = room.occupantJID.resource |
366 if not self.isReferee(room_jid_s, profile_nick): | 379 if not self.isReferee(room_jid_s, profile_nick): |
367 return True # profile is not the referee | 380 return True # profile is not the referee |
368 if not self._checkJoinAuth(room_jid_s, nick=user.nick): | 381 if not self._checkJoinAuth(room_jid_s, user.entity.userhost() if user.entity else None, user.nick): |
369 # user not allowed but let him know that we are playing :p | 382 # user not allowed but let him know that we are playing :p |
370 self._signalPlayers(room_jid_s, [JID(room_jid_s + '/' + user.nick)], profile) | 383 self._signalPlayers(room_jid_s, [JID(room_jid_s + '/' + user.nick)], profile) |
371 return True | 384 return True |
372 if self.wait_mode == self.FOR_ALL: | 385 if self.wait_mode == self.FOR_ALL: |
373 # considering the last batch of invitations | 386 # considering the last batch of invitations |
401 self.games[room_jid_s]['players'].remove(user.nick) | 414 self.games[room_jid_s]['players'].remove(user.nick) |
402 except ValueError: | 415 except ValueError: |
403 pass | 416 pass |
404 if self.wait_mode == self.FOR_ALL: | 417 if self.wait_mode == self.FOR_ALL: |
405 # allow this user to join the game again | 418 # allow this user to join the game again |
406 user_jid = user.entity.userhost() | 419 user_jid_s = user.entity.userhost() |
407 if len(self.invitations[room_jid_s]) == 0: | 420 if len(self.invitations[room_jid_s]) == 0: |
408 self.invitations[room_jid_s].append((time(), [user_jid])) | 421 self.invitations[room_jid_s].append((time(), [user_jid_s])) |
409 else: | 422 else: |
410 batch = 0 # add to the first batch of invitations | 423 batch = 0 # add to the first batch of invitations |
411 if user_jid not in self.invitations[room_jid_s][batch][1]: | 424 if user_jid_s not in self.invitations[room_jid_s][batch][1]: |
412 self.invitations[room_jid_s][batch][1].append(user_jid) | 425 self.invitations[room_jid_s][batch][1].append(user_jid_s) |
413 return True | 426 return True |
414 | 427 |
415 def _checkCreateGameAndInit(self, room_jid_s, profile): | 428 def _checkCreateGameAndInit(self, room_jid_s, profile): |
416 """Check if that profile can create the game. If the game can be created | 429 """Check if that profile can create the game. If the game can be created |
417 but is not initialized yet, this method will also do the initialization. | 430 but is not initialized yet, this method will also do the initialization. |
440 def createGame(self, room_jid_s, nicks=[], profile_key='@NONE@'): | 453 def createGame(self, room_jid_s, nicks=[], profile_key='@NONE@'): |
441 """Create a new game - this can be called directly from a frontend | 454 """Create a new game - this can be called directly from a frontend |
442 and skips all the checks and invitation system, but the game must | 455 and skips all the checks and invitation system, but the game must |
443 not exist and all the players must be in the room already. | 456 not exist and all the players must be in the room already. |
444 @param room_jid: JID userhost of the room | 457 @param room_jid: JID userhost of the room |
445 @param nicks: list of players nicks in the room | 458 @param nicks: list of players nicks in the room (referee included, in first position) |
446 @param profile_key: %(doc_profile_key)s""" | 459 @param profile_key: %(doc_profile_key)s""" |
447 debug(_("Creating %s game in room %s") % (self.name, room_jid_s)) | 460 debug(_("Creating %s game in room %s") % (self.name, room_jid_s)) |
448 profile = self.host.memory.getProfileName(profile_key) | 461 profile = self.host.memory.getProfileName(profile_key) |
449 if not profile: | 462 if not profile: |
450 error(_("profile %s is unknown") % profile_key) | 463 error(_("profile %s is unknown") % profile_key) |