diff src/plugins/plugin_misc_tarot.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_tarot.py	Fri Oct 18 11:58:42 2013 +0200
+++ b/src/plugins/plugin_misc_tarot.py	Wed Oct 23 12:45:13 2013 +0200
@@ -28,6 +28,7 @@
 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:
@@ -52,17 +53,16 @@
 }
 
 
-class Tarot(object):
+class Tarot(RoomGame):
 
     def __init__(self, host):
         info(_("Plugin Tarot initialization"))
-        self.host = host
-        self.games = {}
-        self.waiting_inv = {}  # Invitation waiting for people to join to launch a game
+        RoomGame.__init__(self, host, PLUGIN_INFO, (NS_CG, CG_TAG), player_init_data={'score': 0},
+                          options={'hand_size': 18, 'init_player': 0, 'current_player': None, 'contrat': None, 'stage': None})
         self.contrats = [_('Passe'), _('Petite'), _('Garde'), _('Garde Sans'), _('Garde Contre')]
-        host.bridge.addMethod("tarotGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.launchGame)  # args: room_jid, players, profile
+        host.bridge.addMethod("tarotGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.prepareRoom)  # args: room_jid, players, profile
         host.bridge.addMethod("tarotGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame)  # args: room_jid, players, profile
-        host.bridge.addMethod("tarotGameReady", ".plugin", in_sign='sss', out_sign='', method=self.newPlayerReady)  # args: player, referee, profile
+        host.bridge.addMethod("tarotGameReady", ".plugin", in_sign='sss', out_sign='', method=self.playerReady)  # args: player, referee, profile
         host.bridge.addMethod("tarotGameContratChoosed", ".plugin", in_sign='ssss', out_sign='', method=self.contratChoosed)  # args: player, referee, contrat, profile
         host.bridge.addMethod("tarotGamePlayCards", ".plugin", in_sign='ssa(ss)s', out_sign='', method=self.play_cards)  # args: player, referee, cards, profile
         host.bridge.addSignal("tarotGameStarted", ".plugin", signature='ssass')  # args: room_jid, referee, players, profile
@@ -81,14 +81,6 @@
             for value in map(str, range(1, 11)) + ["valet", "cavalier", "dame", "roi"]:
                 self.deck_ordered.append(TarotCard((suit, value)))
 
-    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_CG, CG_TAG))
-        return elt
-
     def __card_list_to_xml(self, cards_list, elt_name):
         """Convert a card list to domish element"""
         cards_list_elt = domish.Element((None, elt_name))
@@ -106,18 +98,6 @@
             cards_list.append((card['suit'], card['value']))
         return cards_list
 
-    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_contrat(self):
         """Create a element for asking contrat"""
         contrat_elt = domish.Element((None, 'contrat'))
@@ -404,101 +384,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.createGame(_room_jid.userhost(), players, profile_key=profile)
-        return True
-
-    def launchGame(self, players, profile_key='@NONE@'):
-        """Launch a game: helper method to create a room, invite players, and create the tarot game
-        @param players: list for players jid"""
-        debug(_('Launching tarot game'))
-        profile = self.host.memory.getProfileName(profile_key)
-        if not profile:
-            error(_("Unknown profile"))
-            return
-
-        def tarotRoomJoined(room):
-            _room = room.occupantJID.userhostJID()
-            for player in players:
-                self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game": "Tarot"}, 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_tarot_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
-            print "\n\n===> room_name:", room_name
-            #muc_service = self.host.memory.getServerServiceEntity("conference", "text", profile)
-            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(tarotRoomJoined)
-
-        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 createGame(self, room_jid_param, players, profile_key='@NONE@'):
-        """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 Tarot 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(_("Tarot 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, 'hand_size': 18, 'init_player': 0, 'current_player': None, 'contrat': None, '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='@NONE@'):
-        """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 contratChoosed(self, player, referee, contrat, profile_key='@NONE@'):
         """Must be call by player when the contrat is selected
         @param player: player's name
@@ -533,36 +418,32 @@
         playcard_elt['player'] = player
         self.host.profiles[profile].xmlstream.send(mess)
 
-    def newGame(self, room_jid, profile):
-        """Launch a new round"""
-        debug(_('new Tarot game'))
-        deck = self.deck_ordered[:]
-        random.shuffle(deck)
+    def newRound(self, room_jid, profile):
         game_data = self.games[room_jid.userhost()]
         players = game_data['players']
-        players_data = game_data['players_data']
-        current_player = game_data['current_player']
-        game_data['stage'] = "init"
         game_data['first_player'] = None  # first player for the current trick
         game_data['contrat'] = None
+        common_data = {'contrat': None,
+                       'levees': [],  # cards won
+                       'played': None,  # card on the table
+                       'wait_for_low': None  # Used when a player wait for a low card because of excuse
+                       }
+
         hand = game_data['hand'] = {}
         hand_size = game_data['hand_size']
         chien = game_data['chien'] = []
+        deck = self.deck_ordered[:]
+        random.shuffle(deck)
         for i in range(4):
             hand[players[i]] = deck[0:hand_size]
             del deck[0:hand_size]
         chien.extend(deck)
         del(deck[:])
-
+        msg_elts = {}
         for player in players:
-            to_jid = jid.JID(room_jid.userhost() + "/" + player)  # FIXME: gof:
-            mess = self.createGameElt(to_jid)
-            mess.firstChildElement().addChild(self.__card_list_to_xml(hand[player], 'hand'))
-            self.host.profiles[profile].xmlstream.send(mess)
-            players_data[player]['contrat'] = None
-            players_data[player]['levees'] = []  # cards won
-            players_data[player]['played'] = None  # card on the table
-            players_data[player]['wait_for_low'] = None  # Used when a player wait for a low card because of excuse
+            msg_elts[player] = self.__card_list_to_xml(hand[player], 'hand')
+
+        RoomGame.newRound(self, room_jid, (common_data, msg_elts), profile)
 
         pl_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(players)  # the player after the dealer start
         player = players[pl_idx]
@@ -572,6 +453,9 @@
         self.host.profiles[profile].xmlstream.send(mess)
 
     def card_game_cmd(self, mess_elt, profile):
+        """
+        @param mess_elt: instance of twisted.words.xish.domish.Element
+        """
         from_jid = jid.JID(mess_elt['from'])
         room_jid = jid.JID(from_jid.userhost())
         game_elt = mess_elt.firstChildElement()
@@ -593,7 +477,7 @@
                 status[player] = 'ready'
                 debug(_('Player %(player)s is ready to start [status: %(status)s]') % {'player': player, 'status': status})
                 if status.values().count('ready') == nb_players:  # everybody is ready, we can start the game
-                    self.newGame(room_jid, profile)
+                    self.newRound(room_jid, profile)
 
             elif elt.name == 'hand':  # a new hand has been received
                 self.host.bridge.tarotGameNew(room_jid.userhost(), self.__xml_to_list(elt), profile)