comparison src/plugins/plugin_misc_tarot.py @ 320:5fc5e6a7e5c3

plugin Tarot: added a launch method to automatically create a new room, invite players and create the game - xep-0249 (direct MUC invitation) is used with a custom attribute to invite other users - bridge: added tarotGameLaunch in frontend side
author Goffi <goffi@goffi.org>
date Fri, 06 May 2011 15:42:26 +0200
parents 7c79d4a8c9e6
children 809733b8d9be
comparison
equal deleted inserted replaced
319:5bb1cfc105d0 320:5fc5e6a7e5c3
23 from twisted.words.xish import domish 23 from twisted.words.xish import domish
24 from twisted.internet import protocol, defer, threads, reactor 24 from twisted.internet import protocol, defer, threads, reactor
25 from twisted.words.protocols.jabber import client, jid, xmlstream 25 from twisted.words.protocols.jabber import client, jid, xmlstream
26 from twisted.words.protocols.jabber import error as jab_error 26 from twisted.words.protocols.jabber import error as jab_error
27 from twisted.words.protocols.jabber.xmlstream import IQ 27 from twisted.words.protocols.jabber.xmlstream import IQ
28 import os.path
29 import pdb
30 import random 28 import random
31 29
32 from zope.interface import implements 30 from zope.interface import implements
33 31
34 from wokkel import disco, iwokkel, data_form 32 from wokkel import disco, iwokkel, data_form
35 from sat.tools.xml_tools import dataForm2xml 33 from sat.tools.xml_tools import dataForm2xml
36 from sat.tools.games import TarotCard 34 from sat.tools.games import TarotCard
35
36 from time import time
37 37
38 try: 38 try:
39 from twisted.words.protocols.xmlstream import XMPPHandler 39 from twisted.words.protocols.xmlstream import XMPPHandler
40 except ImportError: 40 except ImportError:
41 from wokkel.subprotocols import XMPPHandler 41 from wokkel.subprotocols import XMPPHandler
48 PLUGIN_INFO = { 48 PLUGIN_INFO = {
49 "name": "Tarot cards plugin", 49 "name": "Tarot cards plugin",
50 "import_name": "Tarot", 50 "import_name": "Tarot",
51 "type": "Misc", 51 "type": "Misc",
52 "protocols": [], 52 "protocols": [],
53 "dependencies": ["XEP-0045"], 53 "dependencies": ["XEP-0045", "XEP-0249"],
54 "main": "Tarot", 54 "main": "Tarot",
55 "handler": "yes", 55 "handler": "yes",
56 "description": _("""Implementation of Tarot card game""") 56 "description": _("""Implementation of Tarot card game""")
57 } 57 }
58 58
61 61
62 def __init__(self, host): 62 def __init__(self, host):
63 info(_("Plugin Tarot initialization")) 63 info(_("Plugin Tarot initialization"))
64 self.host = host 64 self.host = host
65 self.games={} 65 self.games={}
66 self.waiting_inv = {} #Invitation waiting for people to join to launch a game
66 self.contrats = [_('Passe'), _('Petite'), _('Garde'), _('Garde Sans'), _('Garde Contre')] 67 self.contrats = [_('Passe'), _('Petite'), _('Garde'), _('Garde Sans'), _('Garde Contre')]
68 host.bridge.addMethod("tarotGameLaunch", ".communication", in_sign='ass', out_sign='', method=self.launchGame) #args: room_jid, players, profile
67 host.bridge.addMethod("tarotGameCreate", ".communication", in_sign='sass', out_sign='', method=self.createGame) #args: room_jid, players, profile 69 host.bridge.addMethod("tarotGameCreate", ".communication", in_sign='sass', out_sign='', method=self.createGame) #args: room_jid, players, profile
68 host.bridge.addMethod("tarotGameReady", ".communication", in_sign='sss', out_sign='', method=self.newPlayerReady) #args: player, referee, profile 70 host.bridge.addMethod("tarotGameReady", ".communication", in_sign='sss', out_sign='', method=self.newPlayerReady) #args: player, referee, profile
69 host.bridge.addMethod("tarotGameContratChoosed", ".communication", in_sign='ssss', out_sign='', method=self.contratChoosed) #args: player, referee, contrat, profile 71 host.bridge.addMethod("tarotGameContratChoosed", ".communication", in_sign='ssss', out_sign='', method=self.contratChoosed) #args: player, referee, contrat, profile
70 host.bridge.addMethod("tarotGamePlayCards", ".communication", in_sign='ssa(ss)s', out_sign='', method=self.play_cards) #args: player, referee, cards, profile 72 host.bridge.addMethod("tarotGamePlayCards", ".communication", in_sign='ssa(ss)s', out_sign='', method=self.play_cards) #args: player, referee, cards, profile
71 host.bridge.addSignal("tarotGameStarted", ".communication", signature='ssass') #args: room_jid, referee, players, profile 73 host.bridge.addSignal("tarotGameStarted", ".communication", signature='ssass') #args: room_jid, referee, players, profile
74 host.bridge.addSignal("tarotGameShowCards", ".communication", signature='ssa(ss)a{ss}s') #args: room_jid, type ["chien", "poignée",...], cards, data[dict], profile 76 host.bridge.addSignal("tarotGameShowCards", ".communication", signature='ssa(ss)a{ss}s') #args: room_jid, type ["chien", "poignée",...], cards, data[dict], profile
75 host.bridge.addSignal("tarotGameCardsPlayed", ".communication", signature='ssa(ss)s') #args: room_jid, player, type ["chien", "poignée",...], cards, data[dict], profile 77 host.bridge.addSignal("tarotGameCardsPlayed", ".communication", signature='ssa(ss)s') #args: room_jid, player, type ["chien", "poignée",...], cards, data[dict], profile
76 host.bridge.addSignal("tarotGameYourTurn", ".communication", signature='ss') #args: room_jid, profile 78 host.bridge.addSignal("tarotGameYourTurn", ".communication", signature='ss') #args: room_jid, profile
77 host.bridge.addSignal("tarotGameScore", ".communication", signature='ssasass') #args: room_jid, xml_data, winners (list of nicks), loosers (list of nicks), profile 79 host.bridge.addSignal("tarotGameScore", ".communication", signature='ssasass') #args: room_jid, xml_data, winners (list of nicks), loosers (list of nicks), profile
78 host.bridge.addSignal("tarotGameInvalidCards", ".communication", signature='ssa(ss)a(ss)s') #args: room_jid, game phase, played_cards, invalid_cards, profile 80 host.bridge.addSignal("tarotGameInvalidCards", ".communication", signature='ssa(ss)a(ss)s') #args: room_jid, game phase, played_cards, invalid_cards, profile
81 host.trigger.add("MUC user joined", self.userJoinedTrigger)
79 self.deck_ordered = [] 82 self.deck_ordered = []
80 for value in ['excuse']+map(str,range(1,22)): 83 for value in ['excuse']+map(str,range(1,22)):
81 self.deck_ordered.append(TarotCard(("atout",value))) 84 self.deck_ordered.append(TarotCard(("atout",value)))
82 for suit in ["pique", "coeur", "carreau", "trefle"]: 85 for suit in ["pique", "coeur", "carreau", "trefle"]:
83 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]: 86 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]:
204 #TODO: manage the case where excuse is played on the last trick (and lost) 207 #TODO: manage the case where excuse is played on the last trick (and lost)
205 #TODO: gof: manage excuse (fool) 208 #TODO: gof: manage excuse (fool)
206 players_data = game_data['players_data'] 209 players_data = game_data['players_data']
207 excuse = TarotCard(("atout","excuse")) 210 excuse = TarotCard(("atout","excuse"))
208 211
209 #we first check if the Excuse was already player 212 #we first check if the Excuse was already played
210 #and if somebody is waiting for a card 213 #and if somebody is waiting for a card
211 for player in game_data['players']: 214 for player in game_data['players']:
212 if players_data[player]['wait_for_low']: 215 if players_data[player]['wait_for_low']:
213 #the excuse owner has to give a card to somebody 216 #the excuse owner has to give a card to somebody
214 if winner == player: 217 if winner == player:
395 mess = self.createGameElt(to_jid) 398 mess = self.createGameElt(to_jid)
396 yourturn_elt = mess.firstChildElement().addElement('your_turn') 399 yourturn_elt = mess.firstChildElement().addElement('your_turn')
397 self.host.profiles[profile].xmlstream.send(mess) 400 self.host.profiles[profile].xmlstream.send(mess)
398 401
399 402
403 def userJoinedTrigger(self, room, user, profile):
404 """This trigger is used to check if we are waiting people in this room,
405 and to create a game if everybody is here"""
406 _room_jid = room.occupantJID.userhostJID()
407 if _room_jid in self.waiting_inv and len(room.roster) == 4:
408 #When we have 4 people in the room, we create the game
409 #TODO: check people identity
410 players = room.roster.keys()
411 del self.waiting_inv[_room_jid]
412 self.createGame(_room_jid.userhost(), players, profile_key=profile)
413 return True
414
415 def launchGame(self, players, profile_key='@DEFAULT@'):
416 """Launch a game: helper method to create a room, invite players, and create the tarot game
417 @param players: list for players jid"""
418 debug(_('Launching tarot game'))
419 profile = self.host.memory.getProfileName(profile_key)
420 if not profile:
421 error(_("Unknown profile"))
422 return
423
424 def tarotRoomJoined(room):
425 _room = room.occupantJID.userhostJID()
426 for player in players:
427 self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game":"Tarot"}, profile)
428 self.waiting_inv[_room] = (time(), players) #TODO: remove invitation waiting for too long, using the time data
429
430 def after_init(ignore):
431 room_name = "sat_tarot_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
432 print "\n\n===> room_name:", room_name
433 #muc_service = self.host.memory.getServerServiceEntity("conference", "text", profile)
434 muc_service = None
435 for service in self.host.memory.getServerServiceEntities("conference", "text", profile):
436 if not ".irc." in service.userhost():
437 #FIXME:
438 #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway
439 #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way
440 #to manage this, but this hack fill do it for test purpose
441 muc_service = service
442 break
443 if not muc_service:
444 error(_("Can't find a MUC service"))
445 return
446
447 _jid, xmlstream = self.host.getJidNStream(profile)
448 d = self.host.plugins["XEP-0045"].join(muc_service.userhost(), room_name, _jid.user, profile).addCallback(tarotRoomJoined)
449
450 client = self.host.getClient(profile)
451 if not client:
452 error(_('No client for this profile key: %s') % profile_key)
453 return
454 client.client_initialized.addCallback(after_init)
455
456
457
458
400 def createGame(self, room_jid_param, players, profile_key='@DEFAULT@'): 459 def createGame(self, room_jid_param, players, profile_key='@DEFAULT@'):
401 """Create a new game""" 460 """Create a new game
461 @param room_jid_param: jid of the room
462 @param players: list of players nick (nick must exist in the room)
463 @param profile_key: %(doc_profile_key)s"""
402 debug (_("Creating Tarot game")) 464 debug (_("Creating Tarot game"))
403 room_jid = jid.JID(room_jid_param) 465 room_jid = jid.JID(room_jid_param)
404 profile = self.host.memory.getProfileName(profile_key) 466 profile = self.host.memory.getProfileName(profile_key)
405 if not profile: 467 if not profile:
406 error (_("profile %s is unknown") % profile_key) 468 error (_("profile %s is unknown") % profile_key)