Mercurial > libervia-backend
comparison src/plugins/plugin_misc_room_game.py @ 746:539f278bc265
plugin room_games, radiocol: send the current queue to new players
author | souliane <souliane@mailoo.org> |
---|---|
date | Thu, 28 Nov 2013 19:23:59 +0100 |
parents | 074970227bc0 |
children | bfabeedbf32e |
comparison
equal
deleted
inserted
replaced
745:812dc38c0094 | 746:539f278bc265 |
---|---|
21 from twisted.words.protocols.jabber.jid import JID | 21 from twisted.words.protocols.jabber.jid import JID |
22 from twisted.words.xish import domish | 22 from twisted.words.xish import domish |
23 from time import time | 23 from time import time |
24 from wokkel import disco, iwokkel | 24 from wokkel import disco, iwokkel |
25 from zope.interface import implements | 25 from zope.interface import implements |
26 import copy | |
26 try: | 27 try: |
27 from twisted.words.protocols.xmlstream import XMPPHandler | 28 from twisted.words.protocols.xmlstream import XMPPHandler |
28 except ImportError: | 29 except ImportError: |
29 from wokkel.subprotocols import XMPPHandler | 30 from wokkel.subprotocols import XMPPHandler |
30 | 31 |
31 # Don't forget to set it to False before you commit | 32 # Don't forget to set it to False before you commit |
32 _DEBUG = False | 33 _DEBUG = False |
33 _DEBUG_FILE = False | |
34 | 34 |
35 PLUGIN_INFO = { | 35 PLUGIN_INFO = { |
36 "name": "Room game", | 36 "name": "Room game", |
37 "import_name": "ROOM-GAME", | 37 "import_name": "ROOM-GAME", |
38 "type": "MISC", | 38 "type": "MISC", |
121 <players /> message to be emitted whenever a new player is joining, | 121 <players /> message to be emitted whenever a new player is joining, |
122 it is necessary to not modify 'players' outside of updatePlayers. | 122 it is necessary to not modify 'players' outside of updatePlayers. |
123 """ | 123 """ |
124 referee = room_jid_s + '/' + referee_nick | 124 referee = room_jid_s + '/' + referee_nick |
125 self.games[room_jid_s] = {'referee': referee, 'players': [], 'started': False} | 125 self.games[room_jid_s] = {'referee': referee, 'players': [], 'started': False} |
126 self.games[room_jid_s].update(self.game_init) | 126 self.games[room_jid_s].update(copy.deepcopy(self.game_init)) |
127 | 127 |
128 def gameExists(self, room_jid_s, started=False): | 128 def gameExists(self, room_jid_s, started=False): |
129 """Return True if a game has been initialized/started. | 129 """Return True if a game has been initialized/started. |
130 @param started: if False, the game must be initialized only, | 130 @param started: if False, the game must be initialized only, |
131 otherwise it must be initialized and started with createGame. | 131 otherwise it must be initialized and started with createGame. |
164 if not auth and (verbose or _DEBUG): | 164 if not auth and (verbose or _DEBUG): |
165 debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s)) | 165 debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s)) |
166 return auth | 166 return auth |
167 | 167 |
168 def updatePlayers(self, room_jid_s, nicks, profile): | 168 def updatePlayers(self, room_jid_s, nicks, profile): |
169 """Signal to the room or to each player that some players joined the game""" | 169 """Signal to the room that some players joined the game""" |
170 if nicks == []: | 170 if nicks == []: |
171 return | 171 return |
172 new_nicks = set(nicks).difference(self.games[room_jid_s]['players']) | 172 new_nicks = set(nicks).difference(self.games[room_jid_s]['players']) |
173 if len(new_nicks) == 0: | 173 if len(new_nicks) == 0: |
174 return | 174 return |
179 """Let these guys know that we are playing (they may not play themselves).""" | 179 """Let these guys know that we are playing (they may not play themselves).""" |
180 if self.gameExists(room_jid_s, started=True): | 180 if self.gameExists(room_jid_s, started=True): |
181 element = self.createStartElement(self.games[room_jid_s]['players']) | 181 element = self.createStartElement(self.games[room_jid_s]['players']) |
182 else: | 182 else: |
183 element = self.createStartElement(self.games[room_jid_s]['players'], name="players") | 183 element = self.createStartElement(self.games[room_jid_s]['players'], name="players") |
184 elements = [(element, None, None)] | |
185 for child in self.getSyncData(room_jid_s): | |
186 # TODO: sync data may be different and private to each player, | |
187 # in that case send a separate message to the new players | |
188 elements.append((child, None, None)) | |
184 for recipient in recipients: | 189 for recipient in recipients: |
185 self.send(recipient, element, profile=profile) | 190 self.sendElements(recipient, elements, profile=profile) |
191 | |
192 def getSyncData(self, room_jid_s): | |
193 """This method may be overwritten by any child class. | |
194 @return: a list of child elements to be added for the game to be synchronized. | |
195 """ | |
196 return [] | |
186 | 197 |
187 def invitePlayers(self, room, other_players, nick, profile): | 198 def invitePlayers(self, room, other_players, nick, profile): |
188 """Invite players to a room, associated game may exist or not. | 199 """Invite players to a room, associated game may exist or not. |
189 @param room: wokkel.muc.Room instance | 200 @param room: wokkel.muc.Room instance |
190 @param other_players: list of JID userhosts to invite | 201 @param other_players: list of JID userhosts to invite |
406 # specific data to each player | 417 # specific data to each player |
407 status = {} | 418 status = {} |
408 players_data = {} | 419 players_data = {} |
409 for nick in nicks: | 420 for nick in nicks: |
410 # The dict must be COPIED otherwise it is shared between all users | 421 # The dict must be COPIED otherwise it is shared between all users |
411 players_data[nick] = self.player_init.copy() | 422 players_data[nick] = copy.deepcopy(self.player_init) |
412 status[nick] = "init" | 423 status[nick] = "init" |
413 self.games[room_jid_s].update({'status': status, 'players_data': players_data}) | 424 self.games[room_jid_s].update({'status': status, 'players_data': players_data}) |
414 | 425 |
415 def playerReady(self, player, referee, profile_key='@NONE@'): | 426 def playerReady(self, player, referee, profile_key='@NONE@'): |
416 """Must be called when player is ready to start a new game""" | 427 """Must be called when player is ready to start a new game""" |
427 game_data = self.games[room_jid.userhost()] | 438 game_data = self.games[room_jid.userhost()] |
428 players = game_data['players'] | 439 players = game_data['players'] |
429 players_data = game_data['players_data'] | 440 players_data = game_data['players_data'] |
430 game_data['stage'] = "init" | 441 game_data['stage'] = "init" |
431 | 442 |
432 common_data, msg_elts = data if data is not None else (None, None) | 443 common_data, msg_elts = copy.deepcopy(data) if data is not None else (None, None) |
433 | 444 |
434 if isinstance(msg_elts, dict): | 445 if isinstance(msg_elts, dict): |
435 for player in players: | 446 for player in players: |
436 to_jid = JID(room_jid.userhost() + "/" + player) # FIXME: gof: | 447 to_jid = JID(room_jid.userhost() + "/" + player) # FIXME: gof: |
437 elem = msg_elts[player] if isinstance(msg_elts[player], domish.Element) else None | 448 elem = msg_elts[player] if isinstance(msg_elts[player], domish.Element) else None |
465 player_elt['index'] = str(idx) | 476 player_elt['index'] = str(idx) |
466 idx += 1 | 477 idx += 1 |
467 started_elt.addChild(player_elt) | 478 started_elt.addChild(player_elt) |
468 return started_elt | 479 return started_elt |
469 | 480 |
481 def sendElements(self, to_jid, data, profile=None): | |
482 """ | |
483 @param to_jid: recipient JID | |
484 @param data: list of (elem, attr, content) with: | |
485 - elem: domish.Element, unicode or a couple: | |
486 - domish.Element to be directly added as a child to the message | |
487 - unicode name or couple (uri, name) to create a new domish.Element | |
488 and add it as a child to the message (see domish.Element.addElement) | |
489 - attrs: dictionary of attributes for the new child | |
490 - content: unicode that is appended to the child content | |
491 @param profile: the profile from which the message is sent | |
492 """ | |
493 if profile is None: | |
494 error(_("Message can not be sent without a sender profile")) | |
495 return | |
496 msg = self.createGameElt(to_jid) | |
497 for elem, attrs, content in data: | |
498 if elem is not None: | |
499 if isinstance(elem, domish.Element): | |
500 msg.firstChildElement().addChild(elem) | |
501 else: | |
502 elem = msg.firstChildElement().addElement(elem) | |
503 if attrs is not None: | |
504 elem.attributes.update(attrs) | |
505 if content is not None: | |
506 elem.addContent(content) | |
507 self.host.profiles[profile].xmlstream.send(msg) | |
508 | |
509 | |
470 def send(self, to_jid, elem=None, attrs=None, content=None, profile=None): | 510 def send(self, to_jid, elem=None, attrs=None, content=None, profile=None): |
471 """ | 511 """ |
472 @param to_jid: recipient JID | 512 @param to_jid: recipient JID |
473 @param elem: domish.Element, unicode or a couple: | 513 @param elem: domish.Element, unicode or a couple: |
474 - domish.Element to be directly added as a child to the message | 514 - domish.Element to be directly added as a child to the message |
476 and add it as a child to the message (see domish.Element.addElement) | 516 and add it as a child to the message (see domish.Element.addElement) |
477 @param attrs: dictionary of attributes for the new child | 517 @param attrs: dictionary of attributes for the new child |
478 @param content: unicode that is appended to the child content | 518 @param content: unicode that is appended to the child content |
479 @param profile: the profile from which the message is sent | 519 @param profile: the profile from which the message is sent |
480 """ | 520 """ |
481 if profile is None: | 521 self.sendElements(to_jid, [(elem, attrs, content)], profile) |
482 error(_("Message can not be sent without a sender profile")) | |
483 return | |
484 msg = self.createGameElt(to_jid) | |
485 if elem is not None: | |
486 if isinstance(elem, domish.Element): | |
487 msg.firstChildElement().addChild(elem) | |
488 else: | |
489 elem = msg.firstChildElement().addElement(elem) | |
490 if attrs is not None: | |
491 elem.attributes.update(attrs) | |
492 if content is not None: | |
493 elem.addContent(content) | |
494 self.host.profiles[profile].xmlstream.send(msg) | |
495 | |
496 if _DEBUG_FILE: | |
497 # From here you will see all the game messages | |
498 file_ = open("/tmp/game_messages", "a") | |
499 file_.write("%s from %s to %s: %s\n" % (self.name, profile, "room" if to_jid.resource is None else to_jid.resource, elem.toXml())) | |
500 file_.close() | |
501 | 522 |
502 def getHandler(self, profile): | 523 def getHandler(self, profile): |
503 return RoomGameHandler(self) | 524 return RoomGameHandler(self) |
504 | 525 |
505 | 526 |