Mercurial > libervia-backend
annotate src/plugins/plugin_misc_tarot.py @ 353:cc2afb92ab93 0.2.0 SàT v0.2.0
updated version number
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 01 Jun 2011 12:09:09 +0200 |
parents | 809733b8d9be |
children | 141eeb7cd9e6 |
rev | line source |
---|---|
88 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 SAT plugin for managing xep-0045 | |
228 | 6 Copyright (C) 2009, 2010, 2011 Jérôme Poisson (goffi@goffi.org) |
88 | 7 |
8 This program is free software: you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation, either version 3 of the License, or | |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 """ | |
21 | |
22 from logging import debug, info, warning, error | |
23 from twisted.words.xish import domish | |
24 from twisted.internet import protocol, defer, threads, reactor | |
25 from twisted.words.protocols.jabber import client, jid, xmlstream | |
26 from twisted.words.protocols.jabber import error as jab_error | |
27 from twisted.words.protocols.jabber.xmlstream import IQ | |
28 import random | |
29 | |
30 from zope.interface import implements | |
31 | |
91 | 32 from wokkel import disco, iwokkel, data_form |
223 | 33 from sat.tools.xml_tools import dataForm2xml |
34 from sat.tools.games import TarotCard | |
88 | 35 |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
36 from time import time |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
37 |
88 | 38 try: |
39 from twisted.words.protocols.xmlstream import XMPPHandler | |
40 except ImportError: | |
41 from wokkel.subprotocols import XMPPHandler | |
42 | |
90 | 43 MESSAGE = '/message' |
44 NS_CG = 'http://www.goffi.org/protocol/card_game' | |
45 CG_TAG = 'card_game' | |
46 CG_REQUEST = MESSAGE + '/' + CG_TAG + '[@xmlns="' + NS_CG + '"]' | |
88 | 47 |
48 PLUGIN_INFO = { | |
49 "name": "Tarot cards plugin", | |
50 "import_name": "Tarot", | |
51 "type": "Misc", | |
52 "protocols": [], | |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
53 "dependencies": ["XEP-0045", "XEP-0249"], |
88 | 54 "main": "Tarot", |
90 | 55 "handler": "yes", |
88 | 56 "description": _("""Implementation of Tarot card game""") |
57 } | |
58 | |
94 | 59 |
88 | 60 class Tarot(): |
61 | |
62 def __init__(self, host): | |
63 info(_("Plugin Tarot initialization")) | |
64 self.host = host | |
65 self.games={} | |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
66 self.waiting_inv = {} #Invitation waiting for people to join to launch a game |
91 | 67 self.contrats = [_('Passe'), _('Petite'), _('Garde'), _('Garde Sans'), _('Garde Contre')] |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
68 host.bridge.addMethod("tarotGameLaunch", ".communication", in_sign='ass', out_sign='', method=self.launchGame) #args: room_jid, players, profile |
90 | 69 host.bridge.addMethod("tarotGameCreate", ".communication", in_sign='sass', out_sign='', method=self.createGame) #args: room_jid, players, profile |
92 | 70 host.bridge.addMethod("tarotGameReady", ".communication", in_sign='sss', out_sign='', method=self.newPlayerReady) #args: player, referee, profile |
71 host.bridge.addMethod("tarotGameContratChoosed", ".communication", in_sign='ssss', out_sign='', method=self.contratChoosed) #args: player, referee, contrat, profile | |
72 host.bridge.addMethod("tarotGamePlayCards", ".communication", in_sign='ssa(ss)s', out_sign='', method=self.play_cards) #args: player, referee, cards, profile | |
90 | 73 host.bridge.addSignal("tarotGameStarted", ".communication", signature='ssass') #args: room_jid, referee, players, profile |
74 host.bridge.addSignal("tarotGameNew", ".communication", signature='sa(ss)s') #args: room_jid, hand, profile | |
92 | 75 host.bridge.addSignal("tarotGameChooseContrat", ".communication", signature='sss') #args: room_jid, xml_data, profile |
76 host.bridge.addSignal("tarotGameShowCards", ".communication", signature='ssa(ss)a{ss}s') #args: room_jid, type ["chien", "poignée",...], cards, data[dict], profile | |
93 | 77 host.bridge.addSignal("tarotGameCardsPlayed", ".communication", signature='ssa(ss)s') #args: room_jid, player, type ["chien", "poignée",...], cards, data[dict], profile |
92 | 78 host.bridge.addSignal("tarotGameYourTurn", ".communication", signature='ss') #args: room_jid, profile |
95 | 79 host.bridge.addSignal("tarotGameScore", ".communication", signature='ssasass') #args: room_jid, xml_data, winners (list of nicks), loosers (list of nicks), profile |
99
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
80 host.bridge.addSignal("tarotGameInvalidCards", ".communication", signature='ssa(ss)a(ss)s') #args: room_jid, game phase, played_cards, invalid_cards, profile |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
81 host.trigger.add("MUC user joined", self.userJoinedTrigger) |
88 | 82 self.deck_ordered = [] |
92 | 83 for value in ['excuse']+map(str,range(1,22)): |
141
8c80d4dec7a8
mover Card class to tools/games and renamed it in TarotCard
Goffi <goffi@goffi.org>
parents:
134
diff
changeset
|
84 self.deck_ordered.append(TarotCard(("atout",value))) |
92 | 85 for suit in ["pique", "coeur", "carreau", "trefle"]: |
88 | 86 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]: |
141
8c80d4dec7a8
mover Card class to tools/games and renamed it in TarotCard
Goffi <goffi@goffi.org>
parents:
134
diff
changeset
|
87 self.deck_ordered.append(TarotCard((suit, value))) |
88 | 88 |
92 | 89 def createGameElt(self, to_jid, type="normal"): |
90 type = "normal" if to_jid.resource else "groupchat" | |
90 | 91 elt = domish.Element(('jabber:client','message')) |
92 elt["to"] = to_jid.full() | |
92 | 93 elt["type"] = type |
90 | 94 elt.addElement((NS_CG, CG_TAG)) |
95 return elt | |
96 | |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
97 def __card_list_to_xml(self, cards_list, elt_name): |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
98 """Convert a card list to domish element""" |
92 | 99 cards_list_elt = domish.Element(('',elt_name)) |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
100 for card in cards_list: |
90 | 101 card_elt = domish.Element(('','card')) |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
102 card_elt['suit'] = card.suit |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
103 card_elt['value'] = card.value |
92 | 104 cards_list_elt.addChild(card_elt) |
105 return cards_list_elt | |
90 | 106 |
92 | 107 def __xml_to_list(self, cards_list_elt): |
108 """Convert a domish element with cards to a list of tuples""" | |
109 cards_list = [] | |
110 for card in cards_list_elt.elements(): | |
111 cards_list.append((card['suit'], card['value'])) | |
112 return cards_list | |
90 | 113 |
114 def __create_started_elt(self, players): | |
115 """Create a game_started domish element""" | |
116 started_elt = domish.Element(('','started')) | |
117 idx = 0 | |
118 for player in players: | |
119 player_elt = domish.Element(('','player')) | |
120 player_elt.addContent(player) | |
121 player_elt['index'] = str(idx) | |
122 idx+=1 | |
123 started_elt.addChild(player_elt) | |
124 return started_elt | |
125 | |
91 | 126 def __ask_contrat(self): |
127 """Create a element for asking contrat""" | |
128 contrat_elt = domish.Element(('','contrat')) | |
129 form = data_form.Form('form', title=_('contrat selection')) | |
130 field = data_form.Field('list-single', 'contrat', options=map(data_form.Option, self.contrats), required=True) | |
131 form.addField(field) | |
132 contrat_elt.addChild(form.toElement()) | |
133 return contrat_elt | |
134 | |
95 | 135 def __give_scores(self, scores, winners, loosers): |
136 """Create an element to give scores | |
137 @param scores: unicode (can contain line feed) | |
138 @param winners: list of unicode nicks of winners | |
139 @param loosers: list of unicode nicks of loosers""" | |
140 | |
141 score_elt = domish.Element(('','score')) | |
142 form = data_form.Form('form', title=_('scores')) | |
143 for line in scores.split('\n'): | |
144 field = data_form.Field('fixed', value = line) | |
145 form.addField(field) | |
146 score_elt.addChild(form.toElement()) | |
147 for winner in winners: | |
148 winner_elt = domish.Element(('','winner')) | |
149 winner_elt.addContent(winner) | |
150 score_elt.addChild(winner_elt) | |
151 for looser in loosers: | |
152 looser_elt = domish.Element(('','looser')) | |
153 looser_elt.addContent(looser) | |
154 score_elt.addChild(looser_elt) | |
155 return score_elt | |
156 | |
99
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
157 def __invalid_cards_elt(self, played_cards, invalid_cards, game_phase): |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
158 """Create a element for invalid_cards error |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
159 @param list_cards: list of Card |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
160 @param game_phase: phase of the game ['ecart', 'play']""" |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
161 error_elt = domish.Element(('','error')) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
162 played_elt = self.__card_list_to_xml(played_cards, 'played') |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
163 invalid_elt = self.__card_list_to_xml(invalid_cards, 'invalid') |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
164 error_elt['type'] = 'invalid_cards' |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
165 error_elt['phase'] = game_phase |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
166 error_elt.addChild(played_elt) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
167 error_elt.addChild(invalid_elt) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
168 return error_elt |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
169 |
94 | 170 def __next_player(self, game_data, next_pl = None): |
171 """Increment player number & return player name | |
172 @param next_pl: if given, then next_player is forced to this one | |
173 """ | |
174 if next_pl: | |
175 game_data['current_player'] = game_data['players'].index(next_pl) | |
176 return next_pl | |
177 else: | |
178 pl_idx = game_data['current_player'] = (game_data['current_player'] + 1) % len(game_data['players']) | |
179 return game_data['players'][pl_idx] | |
180 | |
181 def __winner(self, game_data): | |
182 """give the nick of the player who win this trick""" | |
183 players_data = game_data['players_data'] | |
184 first = game_data['first_player'] | |
185 first_idx = game_data['players'].index(first) | |
186 suit_asked = None | |
187 strongest = None | |
188 winner = None | |
189 for idx in [(first_idx + i) % 4 for i in range(4)]: | |
190 player = game_data['players'][idx] | |
191 card = players_data[player]['played'] | |
192 if card.value == "excuse": | |
193 continue | |
194 if suit_asked == None: | |
195 suit_asked = card.suit | |
196 if (card.suit == suit_asked or card.suit == "atout") and card > strongest: | |
197 strongest = card | |
198 winner = player | |
95 | 199 assert winner |
94 | 200 return winner |
201 | |
202 def __excuse_hack(self, game_data, played, winner): | |
95 | 203 """give a low card to other team and keep excuse if trick is lost |
204 @param game_data: data of the game | |
205 @param played: cards currently on the table | |
206 @param winner: nick of the trick winner""" | |
94 | 207 #TODO: manage the case where excuse is played on the last trick (and lost) |
208 players_data = game_data['players_data'] | |
141
8c80d4dec7a8
mover Card class to tools/games and renamed it in TarotCard
Goffi <goffi@goffi.org>
parents:
134
diff
changeset
|
209 excuse = TarotCard(("atout","excuse")) |
95 | 210 |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
211 #we first check if the Excuse was already played |
95 | 212 #and if somebody is waiting for a card |
94 | 213 for player in game_data['players']: |
214 if players_data[player]['wait_for_low']: | |
215 #the excuse owner has to give a card to somebody | |
216 if winner == player: | |
217 #the excuse owner win the trick, we check if we have something to give | |
218 for card in played: | |
219 if card.points == 0.5: | |
220 pl_waiting = players_data[player]['wait_for_low'] | |
221 played.remove(card) | |
222 players_data[pl_waiting]['levees'].append(card) | |
223 debug (_('Player %(excuse_owner)s give %(card_waited)s to %(player_waiting)s for Excuse compensation') % {"excuse_owner":player, "card_waited": card, "player_waiting":pl_waiting}) | |
95 | 224 return |
94 | 225 return |
226 | |
227 if not excuse in played: | |
95 | 228 #the Excuse is not on the table, nothing to do |
94 | 229 return |
230 | |
95 | 231 excuse_player = None #Who has played the Excuse ? |
94 | 232 for player in game_data['players']: |
233 if players_data[player]['played'] == excuse: | |
234 excuse_player = player | |
235 break | |
236 | |
237 if excuse_player == winner: | |
238 return #the excuse player win the trick, nothing to do | |
239 | |
240 #first we remove the excuse from played cards | |
241 played.remove(excuse) | |
242 #then we give it back to the original owner | |
243 owner_levees = players_data[excuse_player]['levees'] | |
244 owner_levees.append(excuse) | |
245 #finally we give a low card to the trick winner | |
246 low_card = None | |
95 | 247 #We look backward in cards won by the Excuse owner to |
248 #find a low value card | |
94 | 249 for card_idx in range(len(owner_levees)-1, -1, -1): |
250 if owner_levees[card_idx].points == 0.5: | |
251 low_card = owner_levees[card_idx] | |
252 del owner_levees[card_idx] | |
253 players_data[winner]['levees'].append(low_card) | |
254 debug (_('Player %(excuse_owner)s give %(card_waited)s to %(player_waiting)s for Excuse compensation') % {"excuse_owner":excuse_player, "card_waited": low_card, "player_waiting":winner}) | |
255 break | |
256 if not low_card: #The player has no low card yet | |
257 #TODO: manage case when player never win a trick with low card | |
258 players_data[excuse_player]['wait_for_low'] = winner | |
259 debug(_("%(excuse_owner)s keep the Excuse but has not card to give, %(winner)s is waiting for one") % {'excuse_owner':excuse_player, 'winner':winner}) | |
260 | |
261 | |
328 | 262 def __draw_game(self, game_data): |
263 """The game is draw, no score change | |
264 @param game_data: data of the game | |
265 @return: tuple with (string victory message, list of winners, list of loosers)""" | |
266 players_data = game_data['players_data'] | |
267 scores_str = _('Draw game') | |
268 scores_str+='\n' | |
269 for player in game_data['players']: | |
270 scores_str+=_("\n--\n%(player)s:\nscore for this game ==> %(score_game)i\ntotal score ==> %(total_score)i") % {'player':player, 'score_game':0, 'total_score': players_data[player]['score']} | |
271 debug(scores_str) | |
272 | |
273 return (scores_str, [], []) | |
274 | |
275 | |
94 | 276 def __calculate_scores(self, game_data): |
95 | 277 """The game is finished, time to know who won :) |
278 @param game_data: data of the game | |
279 @return: tuple with (string victory message, list of winners, list of loosers)""" | |
94 | 280 players_data = game_data['players_data'] |
281 levees = players_data[game_data['attaquant']]['levees'] | |
282 score = 0 | |
283 nb_bouts = 0 | |
95 | 284 bouts = [] |
94 | 285 for card in levees: |
286 if card.bout: | |
287 nb_bouts +=1 | |
95 | 288 bouts.append(card.value) |
94 | 289 score += card.points |
95 | 290 |
161
c37826d80f2a
plugin tarot: fixed bad score calculation
Goffi <goffi@goffi.org>
parents:
147
diff
changeset
|
291 #We we do a basic check on score calculation |
95 | 292 check_score = 0 |
293 defenseurs = game_data['players'][:] | |
294 defenseurs.remove(game_data['attaquant']) | |
295 for defenseur in defenseurs: | |
296 for card in players_data[defenseur]['levees']: | |
297 check_score+=card.points | |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
298 if game_data['contrat'] == "Garde Contre": |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
299 for card in game_data['chien']: |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
300 check_score+=card.points |
95 | 301 assert (score + check_score == 91) |
302 | |
94 | 303 point_limit = None |
304 if nb_bouts == 3: | |
305 point_limit = 36 | |
306 elif nb_bouts == 2: | |
307 point_limit = 41 | |
308 elif nb_bouts == 1: | |
309 point_limit = 51 | |
310 else: | |
311 point_limit = 56 | |
95 | 312 if game_data['contrat'] == 'Petite': |
313 contrat_mult = 1 | |
314 elif game_data['contrat'] == 'Garde': | |
315 contrat_mult = 2 | |
316 elif game_data['contrat'] == 'Garde Sans': | |
317 contrat_mult = 4 | |
318 elif game_data['contrat'] == 'Garde Contre': | |
319 contrat_mult = 6 | |
320 else: | |
161
c37826d80f2a
plugin tarot: fixed bad score calculation
Goffi <goffi@goffi.org>
parents:
147
diff
changeset
|
321 error(_('INTERNAL ERROR: contrat not managed (mispelled ?)')) |
c37826d80f2a
plugin tarot: fixed bad score calculation
Goffi <goffi@goffi.org>
parents:
147
diff
changeset
|
322 assert(False) |
95 | 323 |
94 | 324 victory = (score >= point_limit) |
161
c37826d80f2a
plugin tarot: fixed bad score calculation
Goffi <goffi@goffi.org>
parents:
147
diff
changeset
|
325 margin = abs(score - point_limit) |
c37826d80f2a
plugin tarot: fixed bad score calculation
Goffi <goffi@goffi.org>
parents:
147
diff
changeset
|
326 points_defenseur = (margin + 25) * contrat_mult * (-1 if victory else 1) |
95 | 327 winners = [] |
328 loosers = [] | |
329 player_score = {} | |
330 for player in game_data['players']: | |
331 #TODO: adjust this for 3 and 5 players variants | |
332 #TODO: manage bonuses (petit au bout, poignée, chelem) | |
333 player_score[player] = points_defenseur if player != game_data['attaquant'] else points_defenseur * -3 | |
334 players_data[player]['score'] += player_score[player] #we add score of this game to the global score | |
335 if player_score[player] > 0: | |
336 winners.append(player) | |
337 else: | |
338 loosers.append(player) | |
94 | 339 |
147
dc692acde155
plugin Tarot: separator doen't appear anymore when attacked has no bout in scores
Goffi <goffi@goffi.org>
parents:
141
diff
changeset
|
340 scores_str = _('The attacker (%(attaquant)s) makes %(points)i and needs to make %(point_limit)i (%(nb_bouts)s oulder%(plural)s%(separator)s%(bouts)s): he %(victory)s') % {'attaquant':game_data['attaquant'], 'points':score, 'point_limit':point_limit, 'nb_bouts': nb_bouts, 'plural': 's' if nb_bouts>1 else '', 'separator':': ' if nb_bouts != 0 else '', 'bouts':','.join(map(str,bouts)), 'victory': 'win' if victory else 'loose'} |
95 | 341 scores_str+='\n' |
342 for player in game_data['players']: | |
343 scores_str+=_("\n--\n%(player)s:\nscore for this game ==> %(score_game)i\ntotal score ==> %(total_score)i") % {'player':player, 'score_game':player_score[player], 'total_score': players_data[player]['score']} | |
344 debug(scores_str) | |
345 | |
346 return (scores_str, winners, loosers) | |
94 | 347 |
99
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
348 def __invalid_cards(self, game_data, cards): |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
349 """Checks that the player has the right to play what he wants to |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
350 @param game_data: Game data |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
351 @param cards: cards the player want to play |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
352 @return forbidden_cards cards or empty list if cards are ok""" |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
353 forbidden_cards = [] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
354 if game_data['stage'] == 'ecart': |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
355 for card in cards: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
356 if card.bout or card.value=="roi": |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
357 forbidden_cards.append(card) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
358 #TODO: manage case where atouts (trumps) are in the dog |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
359 elif game_data['stage'] == 'play': |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
360 biggest_atout = None |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
361 suit_asked = None |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
362 players = game_data['players'] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
363 players_data = game_data['players_data'] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
364 idx = players.index(game_data['first_player']) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
365 current_idx = game_data['current_player'] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
366 current_player = players[current_idx] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
367 if idx == current_idx: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
368 #the player is the first to play, he can play what he wants |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
369 return forbidden_cards |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
370 while (idx != current_idx): |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
371 player = players[idx] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
372 played_card = players_data[player]['played'] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
373 if not suit_asked and played_card.value != "excuse": |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
374 suit_asked = played_card.suit |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
375 if played_card.suit == "atout" and played_card > biggest_atout: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
376 biggest_atout = played_card |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
377 idx = (idx + 1) % len(players) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
378 has_suit = False #True if there is one card of the asked suit in the hand of the player |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
379 has_atout = False |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
380 biggest_hand_atout = None |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
381 |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
382 for hand_card in game_data['hand'][current_player]: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
383 if hand_card.suit == suit_asked: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
384 has_suit = True |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
385 if hand_card.suit == "atout": |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
386 has_atout = True |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
387 if hand_card.suit == "atout" and hand_card > biggest_hand_atout: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
388 biggest_hand_atout = hand_card |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
389 |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
390 assert len(cards) == 1 |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
391 card = cards[0] |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
392 if card.suit != suit_asked and has_suit and card.value != "excuse": |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
393 forbidden_cards.append(card) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
394 return forbidden_cards |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
395 if card.suit != suit_asked and card.suit != "atout" and has_atout: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
396 forbidden_cards.append(card) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
397 return forbidden_cards |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
398 if card.suit == "atout" and card < biggest_atout and biggest_hand_atout > biggest_atout and card.value != "excuse": |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
399 forbidden_cards.append(card) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
400 else: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
401 error(_('Internal error: unmanaged game stage')) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
402 return forbidden_cards |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
403 |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
404 |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
405 def __start_play(self, room_jid, game_data, profile): |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
406 """Start the game (tell to the first player after dealer to play""" |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
407 game_data['stage'] = "play" |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
408 next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #the player after the dealer start |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
409 game_data['first_player'] = next_player = game_data['players'][next_player_idx] |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
410 to_jid = jid.JID(room_jid.userhost()+"/"+next_player) #FIXME: gof: |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
411 mess = self.createGameElt(to_jid) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
412 yourturn_elt = mess.firstChildElement().addElement('your_turn') |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
413 self.host.profiles[profile].xmlstream.send(mess) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
414 |
91 | 415 |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
416 def userJoinedTrigger(self, room, user, profile): |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
417 """This trigger is used to check if we are waiting people in this room, |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
418 and to create a game if everybody is here""" |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
419 _room_jid = room.occupantJID.userhostJID() |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
420 if _room_jid in self.waiting_inv and len(room.roster) == 4: |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
421 #When we have 4 people in the room, we create the game |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
422 #TODO: check people identity |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
423 players = room.roster.keys() |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
424 del self.waiting_inv[_room_jid] |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
425 self.createGame(_room_jid.userhost(), players, profile_key=profile) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
426 return True |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
427 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
428 def launchGame(self, players, profile_key='@DEFAULT@'): |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
429 """Launch a game: helper method to create a room, invite players, and create the tarot game |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
430 @param players: list for players jid""" |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
431 debug(_('Launching tarot game')) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
432 profile = self.host.memory.getProfileName(profile_key) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
433 if not profile: |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
434 error(_("Unknown profile")) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
435 return |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
436 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
437 def tarotRoomJoined(room): |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
438 _room = room.occupantJID.userhostJID() |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
439 for player in players: |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
440 self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game":"Tarot"}, profile) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
441 self.waiting_inv[_room] = (time(), players) #TODO: remove invitation waiting for too long, using the time data |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
442 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
443 def after_init(ignore): |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
444 room_name = "sat_tarot_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
445 print "\n\n===> room_name:", room_name |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
446 #muc_service = self.host.memory.getServerServiceEntity("conference", "text", profile) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
447 muc_service = None |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
448 for service in self.host.memory.getServerServiceEntities("conference", "text", profile): |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
449 if not ".irc." in service.userhost(): |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
450 #FIXME: |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
451 #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
452 #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
453 #to manage this, but this hack fill do it for test purpose |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
454 muc_service = service |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
455 break |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
456 if not muc_service: |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
457 error(_("Can't find a MUC service")) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
458 return |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
459 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
460 _jid, xmlstream = self.host.getJidNStream(profile) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
461 d = self.host.plugins["XEP-0045"].join(muc_service.userhost(), room_name, _jid.user, profile).addCallback(tarotRoomJoined) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
462 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
463 client = self.host.getClient(profile) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
464 if not client: |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
465 error(_('No client for this profile key: %s') % profile_key) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
466 return |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
467 client.client_initialized.addCallback(after_init) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
468 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
469 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
470 |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
471 |
90 | 472 def createGame(self, room_jid_param, players, profile_key='@DEFAULT@'): |
320
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
473 """Create a new game |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
474 @param room_jid_param: jid of the room |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
475 @param players: list of players nick (nick must exist in the room) |
5fc5e6a7e5c3
plugin Tarot: added a launch method to automatically create a new room, invite players and create the game
Goffi <goffi@goffi.org>
parents:
291
diff
changeset
|
476 @param profile_key: %(doc_profile_key)s""" |
88 | 477 debug (_("Creating Tarot game")) |
90 | 478 room_jid = jid.JID(room_jid_param) |
88 | 479 profile = self.host.memory.getProfileName(profile_key) |
480 if not profile: | |
481 error (_("profile %s is unknown") % profile_key) | |
482 return | |
194 | 483 if self.games.has_key(room_jid): |
90 | 484 warning (_("Tarot game already started in room %s") % room_jid.userhost()) |
88 | 485 else: |
291 | 486 room_nick = self.host.plugins["XEP-0045"].getRoomNick(room_jid.userhost(), profile) |
93 | 487 if not room_nick: |
488 error ('Internal error') | |
489 return | |
490 referee = room_jid.userhost() + '/' + room_nick | |
90 | 491 status = {} |
91 | 492 players_data = {} |
90 | 493 for player in players: |
95 | 494 players_data[player] = {'score':0} |
90 | 495 status[player] = "init" |
95 | 496 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} |
90 | 497 for player in players: |
498 mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+player)) | |
499 mess.firstChildElement().addChild(self.__create_started_elt(players)) | |
500 self.host.profiles[profile].xmlstream.send(mess) | |
501 | |
92 | 502 def newPlayerReady(self, player, referee, profile_key='@DEFAULT@'): |
90 | 503 """Must be called when player is ready to start a new game""" |
504 profile = self.host.memory.getProfileName(profile_key) | |
505 if not profile: | |
506 error (_("profile %s is unknown") % profile_key) | |
507 return | |
508 debug ('new player ready: %s' % profile) | |
509 mess = self.createGameElt(jid.JID(referee)) | |
91 | 510 ready_elt = mess.firstChildElement().addElement('player_ready') |
92 | 511 ready_elt['player'] = player |
91 | 512 self.host.profiles[profile].xmlstream.send(mess) |
513 | |
92 | 514 def contratChoosed(self, player, referee, contrat, profile_key='@DEFAULT@'): |
91 | 515 """Must be call by player when the contrat is selected |
92 | 516 @param player: player's name |
91 | 517 @param referee: arbiter jid |
518 @contrat: contrat choosed (must be the exact same string than in the give list options) | |
519 @profile_key: profile | |
520 """ | |
521 profile = self.host.memory.getProfileName(profile_key) | |
522 if not profile: | |
523 error (_("profile %s is unknown") % profile_key) | |
524 return | |
525 debug (_('contrat [%(contrat)s] choosed by %(profile)s') % {'contrat':contrat, 'profile':profile}) | |
526 mess = self.createGameElt(jid.JID(referee)) | |
527 contrat_elt = mess.firstChildElement().addElement(('','contrat_choosed'), content=contrat) | |
92 | 528 contrat_elt['player'] = player |
90 | 529 self.host.profiles[profile].xmlstream.send(mess) |
88 | 530 |
92 | 531 def play_cards(self, player, referee, cards, profile_key='@DEFAULT@'): |
532 """Must be call by player when the contrat is selected | |
533 @param player: player's name | |
534 @param referee: arbiter jid | |
535 @cards: cards played (list of tuples) | |
536 @profile_key: profile | |
537 """ | |
538 profile = self.host.memory.getProfileName(profile_key) | |
539 if not profile: | |
540 error (_("profile %s is unknown") % profile_key) | |
541 return | |
542 debug (_('Cards played by %(profile)s: [%(cards)s]') % {'profile':profile,'cards':cards}) | |
543 mess = self.createGameElt(jid.JID(referee)) | |
141
8c80d4dec7a8
mover Card class to tools/games and renamed it in TarotCard
Goffi <goffi@goffi.org>
parents:
134
diff
changeset
|
544 playcard_elt = mess.firstChildElement().addChild(self.__card_list_to_xml(TarotCard.from_tuples(cards), 'cards_played')) |
92 | 545 playcard_elt['player'] = player |
546 self.host.profiles[profile].xmlstream.send(mess) | |
88 | 547 |
92 | 548 def newGame(self, room_jid, profile): |
88 | 549 """Launch a new round""" |
550 debug (_('new Tarot game')) | |
551 deck = self.deck_ordered[:] | |
552 random.shuffle(deck) | |
91 | 553 game_data = self.games[room_jid.userhost()] |
554 players = game_data['players'] | |
555 players_data = game_data['players_data'] | |
556 current_player = game_data['current_player'] | |
92 | 557 game_data['stage'] = "init" |
94 | 558 game_data['first_player'] = None #first player for the current trick |
95 | 559 game_data['contrat'] = None |
91 | 560 hand = game_data['hand'] = {} |
561 hand_size = game_data['hand_size'] | |
562 chien = game_data['chien'] = [] | |
328 | 563 for i in range(4): |
88 | 564 hand[players[i]] = deck[0:hand_size] |
565 del deck[0:hand_size] | |
92 | 566 chien.extend(deck) |
88 | 567 del(deck[:]) |
568 | |
569 for player in players: | |
90 | 570 to_jid = jid.JID(room_jid.userhost()+"/"+player) #FIXME: gof: |
571 mess = self.createGameElt(to_jid) | |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
572 mess.firstChildElement().addChild(self.__card_list_to_xml(hand[player], 'hand')) |
92 | 573 self.host.profiles[profile].xmlstream.send(mess) |
91 | 574 players_data[player]['contrat'] = None |
92 | 575 players_data[player]['levees'] = [] #cards won |
94 | 576 players_data[player]['played'] = None #card on the table |
577 players_data[player]['wait_for_low'] = None #Used when a player wait for a low card because of excuse | |
91 | 578 |
579 pl_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(players) #the player after the dealer start | |
580 player = players[pl_idx] | |
581 to_jid = jid.JID(room_jid.userhost()+"/"+player) #FIXME: gof: | |
582 mess = self.createGameElt(to_jid) | |
583 mess.firstChildElement().addChild(self.__ask_contrat()) | |
92 | 584 self.host.profiles[profile].xmlstream.send(mess) |
90 | 585 |
586 | |
587 def card_game_cmd(self, mess_elt, profile): | |
93 | 588 from_jid = jid.JID(mess_elt['from']) |
589 room_jid = jid.JID(from_jid.userhost()) | |
90 | 590 game_elt = mess_elt.firstChildElement() |
92 | 591 game_data = self.games[room_jid.userhost()] |
592 players_data = game_data['players_data'] | |
593 | |
594 for elt in game_elt.elements(): | |
91 | 595 |
92 | 596 if elt.name == 'started': #new game created |
90 | 597 players = [] |
598 for player in elt.elements(): | |
599 players.append(unicode(player)) | |
93 | 600 self.host.bridge.tarotGameStarted(room_jid.userhost(), from_jid.full(), players, profile) |
91 | 601 |
92 | 602 elif elt.name == 'player_ready': #ready to play |
603 player = elt['player'] | |
90 | 604 status = self.games[room_jid.userhost()]['status'] |
605 nb_players = len(self.games[room_jid.userhost()]['players']) | |
606 status[player] = 'ready' | |
607 debug (_('Player %(player)s is ready to start [status: %(status)s]') % {'player':player, 'status':status}) | |
91 | 608 if status.values().count('ready') == nb_players: #everybody is ready, we can start the game |
92 | 609 self.newGame(room_jid, profile) |
88 | 610 |
90 | 611 elif elt.name == 'hand': #a new hand has been received |
92 | 612 self.host.bridge.tarotGameNew(room_jid.userhost(), self.__xml_to_list(elt), profile) |
91 | 613 |
614 elif elt.name == 'contrat': #it's time to choose contrat | |
615 form = data_form.Form.fromElement(elt.firstChildElement()) | |
102 | 616 xml_data = dataForm2xml(form) |
92 | 617 self.host.bridge.tarotGameChooseContrat(room_jid.userhost(), xml_data, profile) |
91 | 618 |
92 | 619 elif elt.name == 'contrat_choosed': |
91 | 620 #TODO: check we receive the contrat from the right person |
92 | 621 #TODO: use proper XEP-0004 way for answering form |
622 player = elt['player'] | |
623 players_data[player]['contrat'] = unicode(elt) | |
91 | 624 contrats = [players_data[player]['contrat'] for player in game_data['players']] |
625 if contrats.count(None): | |
626 #not everybody has choosed his contrat, it's next one turn | |
627 player = self.__next_player(game_data) | |
628 to_jid = jid.JID(room_jid.userhost()+"/"+player) #FIXME: gof: | |
629 mess = self.createGameElt(to_jid) | |
630 mess.firstChildElement().addChild(self.__ask_contrat()) | |
92 | 631 self.host.profiles[profile].xmlstream.send(mess) |
91 | 632 else: |
633 best_contrat = [None, "Passe"] | |
634 for player in game_data['players']: | |
635 contrat = players_data[player]['contrat'] | |
636 idx_best = self.contrats.index(best_contrat[1]) | |
637 idx_pl = self.contrats.index(contrat) | |
638 if idx_pl > idx_best: | |
639 best_contrat[0] = player | |
640 best_contrat[1] = contrat | |
328 | 641 if best_contrat[1] == "Passe": |
642 debug(_("Everybody is passing, round ended")) | |
643 to_jid = jid.JID(room_jid.userhost()) | |
644 mess = self.createGameElt(to_jid) | |
645 mess.firstChildElement().addChild(self.__give_scores(*self.__draw_game(game_data))) | |
646 self.host.profiles[profile].xmlstream.send(mess) | |
647 game_data['init_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #we change the dealer | |
648 for player in game_data['players']: | |
649 game_data['status'][player] = "init" | |
650 return | |
91 | 651 debug (_("%(player)s win the bid with %(contrat)s") % {'player':best_contrat[0],'contrat':best_contrat[1]}) |
95 | 652 game_data['contrat'] = best_contrat[1] |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
653 |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
654 if game_data['contrat'] == "Garde Sans" or game_data['contrat'] == "Garde Contre": |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
655 self.__start_play(room_jid, game_data, profile) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
656 game_data['attaquant'] = best_contrat[0] |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
657 else: |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
658 #Time to show the chien to everybody |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
659 to_jid = jid.JID(room_jid.userhost()) #FIXME: gof: |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
660 mess = self.createGameElt(to_jid) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
661 chien_elt = mess.firstChildElement().addChild(self.__card_list_to_xml(game_data['chien'], 'chien')) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
662 chien_elt['attaquant'] = best_contrat[0] |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
663 self.host.profiles[profile].xmlstream.send(mess) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
664 #the attacker (attaquant) get the chien |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
665 game_data['hand'][best_contrat[0]].extend(game_data['chien']) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
666 del game_data['chien'][:] |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
667 |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
668 if game_data['contrat'] == "Garde Sans": |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
669 #The chien go into attaquant's (attacker) levees |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
670 players_data[best_contrat[0]]['levees'].extend(game_data['chien']) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
671 del game_data['chien'][:] |
91 | 672 |
92 | 673 |
674 elif elt.name == 'chien': #we have received the chien | |
675 debug (_("tarot: chien received")) | |
676 data = {"attaquant":elt['attaquant']} | |
677 game_data['stage'] = "ecart" | |
678 game_data['attaquant'] = elt['attaquant'] | |
679 self.host.bridge.tarotGameShowCards(room_jid.userhost(), "chien", self.__xml_to_list(elt), data, profile) | |
680 | |
681 elif elt.name == 'cards_played': | |
682 if game_data['stage'] == "ecart": | |
683 #TODO: show atouts (trumps) if player put some in écart | |
684 assert (game_data['attaquant'] == elt['player']) #TODO: throw an xml error here | |
141
8c80d4dec7a8
mover Card class to tools/games and renamed it in TarotCard
Goffi <goffi@goffi.org>
parents:
134
diff
changeset
|
685 list_cards = TarotCard.from_tuples(self.__xml_to_list(elt)) |
99
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
686 #we now check validity of card |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
687 invalid_cards = self.__invalid_cards(game_data, list_cards) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
688 if invalid_cards: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
689 mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+elt['player'])) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
690 mess.firstChildElement().addChild(self.__invalid_cards_elt(list_cards, invalid_cards, game_data['stage'])) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
691 self.host.profiles[profile].xmlstream.send(mess) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
692 return |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
693 |
95 | 694 #FIXME: gof: manage Garde Sans & Garde Contre cases |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
695 players_data[elt['player']]['levees'].extend(list_cards) #we add the chien to attaquant's levées |
95 | 696 for card in list_cards: |
697 game_data['hand'][elt['player']].remove(card) | |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
698 |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
699 self.__start_play(room_jid, game_data, profile) |
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
700 |
93 | 701 elif game_data['stage'] == "play": |
702 current_player = game_data['players'][game_data['current_player']] | |
141
8c80d4dec7a8
mover Card class to tools/games and renamed it in TarotCard
Goffi <goffi@goffi.org>
parents:
134
diff
changeset
|
703 cards = TarotCard.from_tuples(self.__xml_to_list(elt)) |
94 | 704 |
705 if mess_elt['type'] == 'groupchat': | |
706 self.host.bridge.tarotGameCardsPlayed(room_jid.userhost(), elt['player'], self.__xml_to_list(elt), profile) | |
707 else: | |
99
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
708 #we first check validity of card |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
709 invalid_cards = self.__invalid_cards(game_data, cards) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
710 if invalid_cards: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
711 mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+current_player)) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
712 mess.firstChildElement().addChild(self.__invalid_cards_elt(cards, invalid_cards, game_data['stage'])) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
713 self.host.profiles[profile].xmlstream.send(mess) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
714 return |
93 | 715 #the card played is ok, we forward it to everybody |
94 | 716 #first we remove it from the hand and put in on the table |
93 | 717 game_data['hand'][current_player].remove(cards[0]) |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
718 players_data[current_player]['played'] = cards[0] |
93 | 719 |
720 #then we forward the message | |
721 mess = self.createGameElt(room_jid) | |
722 playcard_elt = mess.firstChildElement().addChild(elt) | |
723 self.host.profiles[profile].xmlstream.send(mess) | |
724 | |
94 | 725 #Did everybody played ? |
726 played = [players_data[player]['played'] for player in game_data['players']] | |
95 | 727 if all(played): |
728 #everybody has played | |
94 | 729 winner = self.__winner(game_data) |
730 debug (_('The winner of this trick is %s') % winner) | |
731 #the winner win the trick | |
732 self.__excuse_hack(game_data, played, winner) | |
733 players_data[elt['player']]['levees'].extend(played) | |
734 #nothing left on the table | |
735 for player in game_data['players']: | |
736 players_data[player]['played'] = None | |
737 if len(game_data['hand'][current_player]) == 0: | |
738 #no card lef: the game is finished | |
95 | 739 to_jid = jid.JID(room_jid.userhost()) #FIXME: gof: |
740 mess = self.createGameElt(to_jid) | |
741 chien_elt = mess.firstChildElement().addChild(self.__give_scores(*self.__calculate_scores(game_data))) | |
742 self.host.profiles[profile].xmlstream.send(mess) | |
328 | 743 game_data['init_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #we change the dealer |
744 for player in game_data['players']: | |
745 game_data['status'][player] = "init" | |
94 | 746 return |
747 #next player is the winner | |
748 next_player = game_data['first_player'] = self.__next_player(game_data, winner) | |
749 else: | |
750 next_player = self.__next_player(game_data) | |
751 | |
93 | 752 #finally, we tell to the next player to play |
753 to_jid = jid.JID(room_jid.userhost()+"/"+next_player) #FIXME: gof: | |
754 mess = self.createGameElt(to_jid) | |
755 yourturn_elt = mess.firstChildElement().addElement('your_turn') | |
756 self.host.profiles[profile].xmlstream.send(mess) | |
757 | |
92 | 758 elif elt.name == 'your_turn': |
759 self.host.bridge.tarotGameYourTurn(room_jid.userhost(), profile) | |
91 | 760 |
95 | 761 elif elt.name == 'score': |
762 form_elt = elt.elements(name='x',uri='jabber:x:data').next() | |
763 winners = [] | |
764 loosers = [] | |
765 for winner in elt.elements(name='winner', uri=''): | |
766 winners.append(unicode(winner)) | |
767 for looser in elt.elements(name='looser', uri=''): | |
768 loosers.append(unicode(looser)) | |
769 form = data_form.Form.fromElement(form_elt) | |
102 | 770 xml_data = dataForm2xml(form) |
95 | 771 self.host.bridge.tarotGameScore(room_jid.userhost(), xml_data, winners, loosers, profile) |
99
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
772 elif elt.name == 'error': |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
773 if elt['type'] == 'invalid_cards': |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
774 played_cards = self.__xml_to_list(elt.elements(name='played',uri='').next()) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
775 invalid_cards = self.__xml_to_list(elt.elements(name='invalid',uri='').next()) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
776 self.host.bridge.tarotGameInvalidCards(room_jid.userhost(), elt['phase'], played_cards, invalid_cards, profile) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
777 else: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
778 error (_('Unmanaged error type: %s') % elt['type']) |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
779 else: |
63c9067a1499
Tarot game: invalid cards management
Goffi <goffi@goffi.org>
parents:
98
diff
changeset
|
780 error (_('Unmanaged card game element: %s') % elt.name) |
95 | 781 |
90 | 782 def getHandler(self, profile): |
783 return CardGameHandler(self) | |
88 | 784 |
90 | 785 class CardGameHandler (XMPPHandler): |
786 implements(iwokkel.IDisco) | |
787 | |
788 def __init__(self, plugin_parent): | |
789 self.plugin_parent = plugin_parent | |
790 self.host = plugin_parent.host | |
791 | |
792 def connectionInitialized(self): | |
793 self.xmlstream.addObserver(CG_REQUEST, self.plugin_parent.card_game_cmd, profile = self.parent.profile) | |
794 | |
795 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): | |
98
dd556233a1b1
Tarot Plugin: Garde Sans and Garde Contre are now managed
Goffi <goffi@goffi.org>
parents:
96
diff
changeset
|
796 return [disco.DiscoFeature(NS_CG)] |
90 | 797 |
798 def getDiscoItems(self, requestor, target, nodeIdentifier=''): | |
799 return [] | |
800 |