diff src/plugins/plugin_misc_quiz.py @ 683:75e4f5e2cc65

plugins radiocol, card_game, quiz: code factorization
author souliane <souliane@mailoo.org>
date Wed, 23 Oct 2013 12:45:13 +0200
parents 2805fa3f4bdf
children f610864eb7a5
line wrap: on
line diff
--- a/src/plugins/plugin_misc_quiz.py	Fri Oct 18 11:58:42 2013 +0200
+++ b/src/plugins/plugin_misc_quiz.py	Wed Oct 23 12:45:13 2013 +0200
@@ -30,7 +30,7 @@
 from wokkel import disco, iwokkel, data_form
 from sat.tools.xml_tools import dataForm2XML
 from sat.tools.frontends.games import TarotCard
-
+from sat.tools.plugins.games import RoomGame
 from time import time
 
 try:
@@ -55,16 +55,15 @@
 }
 
 
-class Quiz(object):
+class Quiz(RoomGame):
 
     def __init__(self, host):
         info(_("Plugin Quiz initialization"))
-        self.host = host
-        self.games = {}
-        self.waiting_inv = {}  # Invitation waiting for people to join to launch a game
-        host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.quizGameLaunch)  # args: players, profile
-        host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.quizGameCreate)  # args: room_jid, players, profile
-        host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.newPlayerReady)  # args: player, referee, profile
+        RoomGame.__init__(self, host, PLUGIN_INFO, (NS_QG, QG_TAG), player_init_data={'score': 0},
+                          options={'stage': None})
+        host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.prepareRoom)  # args: players, profile
+        host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame)  # args: room_jid, players, profile
+        host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.playerReady)  # args: player, referee, profile
         host.bridge.addMethod("quizGameAnswer", ".plugin", in_sign='ssss', out_sign='', method=self.playerAnswer)
         host.bridge.addSignal("quizGameStarted", ".plugin", signature='ssass')  # args: room_jid, referee, players, profile
         host.bridge.addSignal("quizGameNew", ".plugin",
@@ -117,14 +116,6 @@
                                    'param_2': '%(doc_profile)s'})
         host.trigger.add("MUC user joined", self.userJoinedTrigger)
 
-    def createGameElt(self, to_jid, type="normal"):
-        type = "normal" if to_jid.resource else "groupchat"
-        elt = domish.Element((None, 'message'))
-        elt["to"] = to_jid.full()
-        elt["type"] = type
-        elt.addElement((NS_QG, QG_TAG))
-        return elt
-
     def __game_data_to_xml(self, game_data):
         """Convert a game data dict to domish element"""
         game_data_elt = domish.Element((None, 'game_data'))
@@ -172,18 +163,6 @@
 
         return answer_result_elt
 
-    def __create_started_elt(self, players):
-        """Create a game_started domish element"""
-        started_elt = domish.Element((None, 'started'))
-        idx = 0
-        for player in players:
-            player_elt = domish.Element((None, 'player'))
-            player_elt.addContent(player)
-            player_elt['index'] = str(idx)
-            idx += 1
-            started_elt.addChild(player_elt)
-        return started_elt
-
     def __ask_question(self, question_id, question, timer):
         """Create a element for asking a question"""
         question_elt = domish.Element((None, 'question'))
@@ -202,100 +181,6 @@
         yourturn_elt = mess.firstChildElement().addElement('your_turn')
         self.host.profiles[profile].xmlstream.send(mess)
 
-    def userJoinedTrigger(self, room, user, profile):
-        """This trigger is used to check if we are waiting people in this room,
-        and to create a game if everybody is here"""
-        _room_jid = room.occupantJID.userhostJID()
-        if _room_jid in self.waiting_inv and len(room.roster) == 4:
-            #When we have 4 people in the room, we create the game
-            #TODO: check people identity
-            players = room.roster.keys()
-            del self.waiting_inv[_room_jid]
-            self.quizGameCreate(_room_jid.userhost(), players, profile_key=profile)
-        return True
-
-    def quizGameLaunch(self, players, profile_key='@DEFAULT@'):
-        """Launch a game: helper method to create a room, invite players, and create the quiz game
-        @param players: list for players jid"""
-        debug(_('Launching quiz game'))
-        profile = self.host.memory.getProfileName(profile_key)
-        if not profile:
-            error(_("Unknown profile"))
-            return
-
-        def quizRoomJoined(room):
-            _room = room.occupantJID.userhostJID()
-            for player in players:
-                self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game": "Quiz"}, profile)
-            self.waiting_inv[_room] = (time(), players)  # TODO: remove invitation waiting for too long, using the time data
-
-        def after_init(ignore):
-            room_name = "sat_quiz_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
-            print "\n\n===> room_name:", room_name
-            muc_service = None
-            for service in self.host.memory.getServerServiceEntities("conference", "text", profile):
-                if not ".irc." in service.userhost():
-                    #FIXME:
-                    #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway
-                    #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way
-                    #to manage this, but this hack fill do it for test purpose
-                    muc_service = service
-                    break
-            if not muc_service:
-                error(_("Can't find a MUC service"))
-                return
-
-            _jid, xmlstream = self.host.getJidNStream(profile)
-            d = self.host.plugins["XEP-0045"].join(jid.JID("%s@%s" % (room_name, muc_service.userhost())), _jid.user, {}, profile).addCallback(quizRoomJoined)
-
-        client = self.host.getClient(profile)
-        if not client:
-            error(_('No client for this profile key: %s') % profile_key)
-            return
-        client.client_initialized.addCallback(after_init)
-
-    def quizGameCreate(self, room_jid_param, players, profile_key='@DEFAULT@'):
-        """Create a new game
-        @param room_jid_param: jid of the room
-        @param players: list of players nick (nick must exist in the room)
-        @param profile_key: %(doc_profile_key)s"""
-        debug(_("Creating Quiz game"))
-        room_jid = jid.JID(room_jid_param)
-        profile = self.host.memory.getProfileName(profile_key)
-        if not profile:
-            error(_("profile %s is unknown") % profile_key)
-            return
-        if room_jid in self.games:
-            warning(_("Quiz game already started in room %s") % room_jid.userhost())
-        else:
-            room_nick = self.host.plugins["XEP-0045"].getRoomNick(room_jid.userhost(), profile)
-            if not room_nick:
-                error('Internal error')
-                return
-            referee = room_jid.userhost() + '/' + room_nick
-            status = {}
-            players_data = {}
-            for player in players:
-                players_data[player] = {'score': 0}
-                status[player] = "init"
-            self.games[room_jid.userhost()] = {'referee': referee, 'players': players, 'status': status, 'players_data': players_data, 'stage': None}
-            for player in players:
-                mess = self.createGameElt(jid.JID(room_jid.userhost() + '/' + player))
-                mess.firstChildElement().addChild(self.__create_started_elt(players))
-                self.host.profiles[profile].xmlstream.send(mess)
-
-    def newPlayerReady(self, player, referee, profile_key='@DEFAULT@'):
-        """Must be called when player is ready to start a new game"""
-        profile = self.host.memory.getProfileName(profile_key)
-        if not profile:
-            error(_("profile %s is unknown") % profile_key)
-            return
-        debug('new player ready: %s' % profile)
-        mess = self.createGameElt(jid.JID(referee))
-        ready_elt = mess.firstChildElement().addElement('player_ready')
-        ready_elt['player'] = player
-        self.host.profiles[profile].xmlstream.send(mess)
-
     def playerAnswer(self, player, referee, answer, profile_key='@DEFAULT@'):
         """Called when a player give an answer"""
         profile = self.host.memory.getProfileName(profile_key)
@@ -371,22 +256,12 @@
 
     def newGame(self, room_jid, profile):
         """Launch a new round"""
-        debug(_('new Quiz game'))
-        game_data = self.games[room_jid.userhost()]
-        players = game_data['players']
-        players_data = game_data['players_data']
-        game_data['stage'] = "init"
-
-        for player in players:
-            players_data[player]['game_score'] = 0
-
+        common_data = {'game_score': 0}
         new_game_data = {"instructions": _(u"""Bienvenue dans cette partie rapide de quizz, le premier à atteindre le score de 9 remporte le jeu
 
 Attention, tu es prêt ?""")}
-
-        mess = self.createGameElt(room_jid)
-        mess.firstChildElement().addChild(self.__game_data_to_xml(new_game_data))
-        self.host.profiles[profile].xmlstream.send(mess)
+        msg_elts = self.__game_data_to_xml(new_game_data)
+        RoomGame.newRound(self, room_jid, (common_data, msg_elts), profile)
         reactor.callLater(10, self.askQuestion, room_jid, profile)
 
     def quiz_game_cmd(self, mess_elt, profile):