comparison src/plugins/plugin_misc_quiz.py @ 717:358018c5c398

plugins (games): more factorization and flexibility for launching and joining games: - "MUC user joined", "MUC user left" and class XMPPHandler are managed directly in RoomGame - renamed __init__ parameters 'player_init_data' to 'player_init' and 'options' to 'game_init' - pass the players list in radiocol method 'createGame' and signal 'radiocolStarted' (needed for invitation system and for UI players identification) - added some parameters to manage who can invite, who can join, who to wait for... managed with check***Auth methods - joining a game that is already launched may be possible, regarding these parameters and the invitation list - leave and join a game again is partly managed: new tarot round is launched, we should keep playing the same round instead
author souliane <souliane@mailoo.org>
date Thu, 21 Nov 2013 15:49:53 +0100
parents f610864eb7a5
children 074970227bc0
comparison
equal deleted inserted replaced
716:30eb49e4e05d 717:358018c5c398
23 from twisted.words.protocols.jabber import client, jid, xmlstream 23 from twisted.words.protocols.jabber import client, jid, xmlstream
24 from twisted.words.protocols.jabber import error as jab_error 24 from twisted.words.protocols.jabber import error as jab_error
25 from twisted.words.protocols.jabber.xmlstream import IQ 25 from twisted.words.protocols.jabber.xmlstream import IQ
26 import random 26 import random
27 27
28 from zope.interface import implements 28 from wokkel import data_form
29
30 from wokkel import disco, iwokkel, data_form
31 from sat.tools.xml_tools import dataForm2XML 29 from sat.tools.xml_tools import dataForm2XML
32 from sat.tools.frontends.games import TarotCard 30 from sat.tools.frontends.games import TarotCard
33 from sat.tools.plugins.games import RoomGame 31 from sat.tools.plugins.games import RoomGame
34 from time import time 32 from time import time
35 33
36 try: 34
37 from twisted.words.protocols.xmlstream import XMPPHandler
38 except ImportError:
39 from wokkel.subprotocols import XMPPHandler
40
41 MESSAGE = '/message'
42 NS_QG = 'http://www.goffi.org/protocol/quiz' 35 NS_QG = 'http://www.goffi.org/protocol/quiz'
43 QG_TAG = 'quiz' 36 QG_TAG = 'quiz'
44 QG_REQUEST = MESSAGE + '/' + QG_TAG + '[@xmlns="' + NS_QG + '"]'
45 37
46 PLUGIN_INFO = { 38 PLUGIN_INFO = {
47 "name": "Quiz game plugin", 39 "name": "Quiz game plugin",
48 "import_name": "Quiz", 40 "import_name": "Quiz",
49 "type": "Game", 41 "type": "Game",
57 49
58 class Quiz(RoomGame): 50 class Quiz(RoomGame):
59 51
60 def __init__(self, host): 52 def __init__(self, host):
61 info(_("Plugin Quiz initialization")) 53 info(_("Plugin Quiz initialization"))
62 RoomGame.__init__(self, host, PLUGIN_INFO, (NS_QG, QG_TAG), player_init_data={'score': 0}, 54 RoomGame.__init__(self, host, PLUGIN_INFO, (NS_QG, QG_TAG), game_init={'stage': None}, player_init={'score': 0})
63 options={'stage': None})
64 host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom) # args: players, room_jid, profile 55 host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom) # args: players, room_jid, profile
65 host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame) # args: room_jid, players, profile 56 host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame) # args: room_jid, players, profile
66 host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.playerReady) # args: player, referee, profile 57 host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.playerReady) # args: player, referee, profile
67 host.bridge.addMethod("quizGameAnswer", ".plugin", in_sign='ssss', out_sign='', method=self.playerAnswer) 58 host.bridge.addMethod("quizGameAnswer", ".plugin", in_sign='ssss', out_sign='', method=self.playerAnswer)
68 host.bridge.addSignal("quizGameStarted", ".plugin", signature='ssass') # args: room_jid, referee, players, profile 59 host.bridge.addSignal("quizGameStarted", ".plugin", signature='ssass') # args: room_jid, referee, players, profile
112 signature='sis', 103 signature='sis',
113 doc={'summary': "Nobody answered the question in time", 104 doc={'summary': "Nobody answered the question in time",
114 'param_0': "room_jid: jid of game's room", 105 'param_0': "room_jid: jid of game's room",
115 'param_1': "time_left: time left before timer expiration", 106 'param_1': "time_left: time left before timer expiration",
116 'param_2': '%(doc_profile)s'}) 107 'param_2': '%(doc_profile)s'})
117 host.trigger.add("MUC user joined", self.userJoinedTrigger)
118 108
119 def __game_data_to_xml(self, game_data): 109 def __game_data_to_xml(self, game_data):
120 """Convert a game data dict to domish element""" 110 """Convert a game data dict to domish element"""
121 game_data_elt = domish.Element((None, 'game_data')) 111 game_data_elt = domish.Element((None, 'game_data'))
122 for data in game_data: 112 for data in game_data:
262 Attention, tu es prĂȘt ?""")} 252 Attention, tu es prĂȘt ?""")}
263 msg_elts = self.__game_data_to_xml(new_game_data) 253 msg_elts = self.__game_data_to_xml(new_game_data)
264 RoomGame.newRound(self, room_jid, (common_data, msg_elts), profile) 254 RoomGame.newRound(self, room_jid, (common_data, msg_elts), profile)
265 reactor.callLater(10, self.askQuestion, room_jid, profile) 255 reactor.callLater(10, self.askQuestion, room_jid, profile)
266 256
267 def quiz_game_cmd(self, mess_elt, profile): 257 def room_game_cmd(self, mess_elt, profile):
268 from_jid = jid.JID(mess_elt['from']) 258 from_jid = jid.JID(mess_elt['from'])
269 room_jid = jid.JID(from_jid.userhost()) 259 room_jid = jid.JID(from_jid.userhost())
270 game_elt = mess_elt.firstChildElement() 260 game_elt = mess_elt.firstChildElement()
271 game_data = self.games[room_jid.userhost()] 261 game_data = self.games[room_jid.userhost()]
272 players_data = game_data['players_data'] 262 if 'players_data' in game_data:
263 players_data = game_data['players_data']
273 264
274 for elt in game_elt.elements(): 265 for elt in game_elt.elements():
275 266
276 if elt.name == 'started': # new game created 267 if elt.name == 'started': # new game created
277 players = [] 268 players = []
331 elif elt.name == 'timer_restarted': 322 elif elt.name == 'timer_restarted':
332 self.host.bridge.quizGameTimerRestarted(room_jid.userhost(), int(elt['time_left']), profile) 323 self.host.bridge.quizGameTimerRestarted(room_jid.userhost(), int(elt['time_left']), profile)
333 324
334 else: 325 else:
335 error(_('Unmanaged game element: %s') % elt.name) 326 error(_('Unmanaged game element: %s') % elt.name)
336
337 def getHandler(self, profile):
338 return QuizGameHandler(self)
339
340
341 class QuizGameHandler (XMPPHandler):
342 implements(iwokkel.IDisco)
343
344 def __init__(self, plugin_parent):
345 self.plugin_parent = plugin_parent
346 self.host = plugin_parent.host
347
348 def connectionInitialized(self):
349 self.xmlstream.addObserver(QG_REQUEST, self.plugin_parent.quiz_game_cmd, profile=self.parent.profile)
350
351 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
352 return [disco.DiscoFeature(NS_QG)]
353
354 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
355 return []