Changeset 9465

Show
Ignore:
Timestamp:
04/15/08 07:32:45 (6 months ago)
Author:
bct
Message:

check tic-tac-toe win conditions, slimmed down _messageCB some more

Location:
branches/session_centric/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • branches/session_centric/src/common/connection_handlers.py

    r9459 r9465  
    15941594 
    15951595                msgtxt = msg.getBody() 
    1596                 msghtml = msg.getXHTML() 
    15971596                subject = msg.getSubject() # if not there, it's None 
    15981597 
     
    16131612                                jid = gajim.get_jid_without_resource(frm) 
    16141613 
    1615                 encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED) 
    16161614                # invitations 
    16171615                invite = None 
     1616                encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED) 
    16181617 
    16191618                if not encTag: 
     
    16211620                        if invite and not invite.getTag('invite'): 
    16221621                                invite = None 
    1623  
    1624                 delayed = msg.getTag('x', namespace = common.xmpp.NS_DELAY) != None 
    1625                 msg_id = None 
    1626                 composing_xep = None 
    16271622 
    16281623                # FIXME: Msn transport (CMSN1.2.1 and PyMSN0.10) do NOT RECOMMENDED 
     
    16401635                                return 
    16411636 
    1642                 form_node = None 
    1643                 for xtag in xtags: 
    1644                         if xtag.getNamespace() == common.xmpp.NS_DATA: 
    1645                                 form_node = xtag 
    1646                                 break 
    1647  
    1648                 chatstate = None 
    1649  
    1650                 # chatstates - look for chatstate tags in a message if not delayed 
    1651                 if not delayed: 
    1652                         composing_xep = False 
    1653                         children = msg.getChildren() 
    1654                         for child in children: 
    1655                                 if child.getNamespace() == 'http://jabber.org/protocol/chatstates': 
    1656                                         chatstate = child.getName() 
    1657                                         composing_xep = 'XEP-0085' 
    1658                                         break 
    1659                         # No XEP-0085 support, fallback to XEP-0022 
    1660                         if not chatstate: 
    1661                                 chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT) 
    1662                                 if chatstate_child: 
    1663                                         chatstate = 'active' 
    1664                                         composing_xep = 'XEP-0022' 
    1665                                         if not msgtxt and chatstate_child.getTag('composing'): 
    1666                                                 chatstate = 'composing' 
    1667  
    1668                 # XEP-0172 User Nickname 
    1669                 user_nick = msg.getTagData('nick') 
    1670                 if not user_nick: 
    1671                         user_nick = '' 
    1672  
    16731637                if encTag and self.USE_GPG: 
    16741638                        encmsg = encTag.getData() 
     
    16841648                if mtype == 'error': 
    16851649                        self.dispatch_error_message(msg, msgtxt, session, frm, tim, subject) 
    1686  
    1687                         return 
    16881650                elif mtype == 'groupchat': 
    1689                         self.dispatch_gc_message(msg, subject, frm, msgtxt, jid, tim, msghtml) 
    1690  
    1691                         return 
     1651                        self.dispatch_gc_message(msg, subject, frm, msgtxt, jid, tim) 
    16921652                elif invite is not None: 
    16931653                        self.dispatch_invite_message(invite, frm) 
    1694  
    1695                         return 
    1696                 elif mtype == 'chat': 
    1697                         if not msg.getTag('body') and chatstate is None: # no <body> 
    1698                                 return 
    1699  
    1700                         log_type = 'chat_msg_recv' 
    1701                 else: # it's a single message 
    1702                         log_type = 'single_msg_recv' 
    1703  
    1704                         mtype = 'normal' 
    1705  
    1706                 if session.is_loggable() and msgtxt: 
    1707                         try: 
    1708                                 msg_id = gajim.logger.write(log_type, frm, msgtxt, 
    1709                                         tim = tim, subject = subject) 
    1710                         except exceptions.PysqliteOperationalError, e: 
    1711                                 self.dispatch('ERROR', (_('Disk Write Error'), str(e))) 
    1712  
    1713                 treat_as = gajim.config.get('treat_incoming_messages') 
    1714  
    1715                 if treat_as: 
    1716                         mtype = treat_as 
    1717  
    1718                 # XXX horrible hack 
    1719                 if isinstance(session, ChatControlSession): 
    1720                         session.received(frm, msgtxt, tim, encrypted, mtype, subject, chatstate, 
    1721                                 msg_id, composing_xep, user_nick, msghtml, form_node) 
    17221654                else: 
    1723                         session.received(msg) 
     1655                        # XXX horrible hack 
     1656                        if isinstance(session, ChatControlSession): 
     1657                                session.received(frm, msgtxt, tim, encrypted, subject, msg) 
     1658                        else: 
     1659                                session.received(msg) 
    17241660        # END messageCB 
    17251661 
     
    17421678 
    17431679        # process and dispatch a groupchat message 
    1744         def dispatch_gc_message(self, msg, subject, frm, msgtxt, jid, tim, msghtml): 
     1680        def dispatch_gc_message(self, msg, subject, frm, msgtxt, jid, tim): 
    17451681                has_timestamp = bool(msg.timestamp) 
    17461682 
     
    17621698                                return 
    17631699 
    1764                         self.dispatch('GC_MSG', (frm, msgtxt, tim, has_timestamp, msghtml, 
     1700                        self.dispatch('GC_MSG', (frm, msgtxt, tim, has_timestamp, msg.getXHTML(), 
    17651701                                statusCode)) 
    17661702 
  • branches/session_centric/src/session.py

    r9459 r9465  
    11from common import helpers 
    22 
     3from common import exceptions 
    34from common import gajim 
    45from common import stanza_session 
    56from common import contacts 
    67 
     8import common.xmpp 
     9 
    710import dialogs 
    811 
     
    1720                self.control = None 
    1821 
     22        # extracts chatstate from a <message/> stanza 
     23        def get_chatstate(self, msg, msgtxt): 
     24                composing_xep = None 
     25                chatstate = None 
     26 
     27                # chatstates - look for chatstate tags in a message if not delayed 
     28                delayed = msg.getTag('x', namespace=common.xmpp.NS_DELAY) != None 
     29                if not delayed: 
     30                        composing_xep = False 
     31                        children = msg.getChildren() 
     32                        for child in children: 
     33                                if child.getNamespace() == 'http://jabber.org/protocol/chatstates': 
     34                                        chatstate = child.getName() 
     35                                        composing_xep = 'XEP-0085' 
     36                                        break 
     37                        # No XEP-0085 support, fallback to XEP-0022 
     38                        if not chatstate: 
     39                                chatstate_child = msg.getTag('x', namespace = common.xmpp.NS_EVENT) 
     40                                if chatstate_child: 
     41                                        chatstate = 'active' 
     42                                        composing_xep = 'XEP-0022' 
     43                                        if not msgtxt and chatstate_child.getTag('composing'): 
     44                                                chatstate = 'composing' 
     45 
     46                return (composing_xep, chatstate) 
     47 
    1948        # dispatch a received <message> stanza 
    20         def received(self, full_jid_with_resource, message, tim, encrypted, msg_type, subject, chatstate, msg_id, composing_xep, user_nick, xhtml, form_node): 
     49        def received(self, full_jid_with_resource, msgtxt, tim, encrypted, subject, msg): 
     50                msg_type = msg.getType() 
     51                msg_id = None 
     52 
     53                # XEP-0172 User Nickname 
     54                user_nick = msg.getTagData('nick') 
     55                if not user_nick: 
     56                        user_nick ='' 
     57 
     58                form_node = None 
     59                for xtag in msg.getTags('x'): 
     60                        if xtag.getNamespace() == common.xmpp.NS_DATA: 
     61                                form_node = xtag 
     62                                break 
     63 
     64                composing_xep, chatstate = self.get_chatstate(msg, msgtxt) 
     65 
     66                xhtml = msg.getXHTML() 
     67 
     68                if msg_type == 'chat': 
     69                        if not msg.getTag('body') and chatstate is None: 
     70                                return 
     71 
     72                        log_type = 'chat_msg_recv' 
     73                else: 
     74                        log_type = 'single_msg_recv' 
     75 
     76                if self.is_loggable() and msgtxt: 
     77                        try: 
     78                                msg_id = gajim.logger.write(log_type, full_jid_with_resource, msgtxt, 
     79                                                tim=tim, subject=subject) 
     80                        except exceptions.PysqliteOperationalError, e: 
     81                                gajim.dispatch('ERROR', (_('Disk WriteError'), str(e))) 
     82 
     83                treat_as = gajim.config.get('treat_incoming_messages') 
     84                if treat_as: 
     85                        msg_type = treat_as 
    2186 
    2287                jid = gajim.get_jid_without_resource(full_jid_with_resource) 
     
    66131                # THIS MUST BE AFTER chatstates handling 
    67132                # AND BEFORE playsound (else we ear sounding on chatstates!) 
    68                 if not message: # empty message text 
     133                if not msgtxt: # empty message text 
    69134                        return 
    70135 
     
    87152                if pm: 
    88153                        nickname = resource 
    89                         groupchat_control.on_private_message(nickname, message, array[2], 
     154                        groupchat_control.on_private_message(nickname, msgtxt, array[2], 
    90155                                xhtml, session, msg_id) 
    91156                else: 
    92                         self.roster_message(jid, message, tim, encrypted, msg_type, 
     157                        self.roster_message(jid, msgtxt, tim, encrypted, msg_type, 
    93158                                subject, resource, msg_id, user_nick, advanced_notif_num, 
    94159                                xhtml=xhtml, form_node=form_node) 
     
    96161                        nickname = gajim.get_name_from_jid(self.conn.name, jid) 
    97162                # Check and do wanted notifications 
    98                 msg = message 
     163                msg = msgtxt 
    99164                if subject: 
    100165                        msg = _('Subject: %s') % subject + '\n' + msg 
     
    112177                if gajim.interface.remote_ctrl: 
    113178                        gajim.interface.remote_ctrl.raise_signal('NewMessage', 
    114                                         (self.conn.name, [full_jid_with_resource, message, tim, 
     179                                        (self.conn.name, [full_jid_with_resource, msgtxt, tim, 
    115180                                                encrypted, msg_type, subject, chatstate, msg_id, 
    116181                                                composing_xep, user_nick, xhtml, form_node])) 
  • branches/session_centric/src/tictactoe.py

    r9459 r9465  
    1010# implements <http://pidgin-games.sourceforge.net/xep/tictactoe.html#invite> 
    1111 
     12games_ns = 'http://jabber.org/protocol/games' 
     13 
    1214class InvalidMove(Exception): 
    1315        pass 
     
    2527                        self.role_o = 'x' 
    2628 
     29                self.send_invitation() 
     30 
     31                self.next_move_id = 1 
     32                self.received = self.wait_for_invite_response 
     33 
     34        def send_invitation(self): 
    2735                msg = xmpp.Message() 
    2836 
    2937                invite = msg.NT.invite 
    30                 invite.setNamespace('http://jabber.org/protocol/games') 
     38                invite.setNamespace(games_ns) 
    3139 
    3240                game = invite.NT.game 
    33                 game.setAttr('var', 'http://jabber.org/protocol/games/tictactoe') 
     41                game.setAttr('var', games_ns + '/tictactoe') 
    3442 
    3543                x = xmpp.DataForm(typ='submit') 
     
    3947                self.send(msg) 
    4048 
    41                 self.next_move_id = 1 
    42                 self.state = 'sent_invite' 
     49        def read_invitation(self, msg): 
     50                invite = msg.getTag('invite', namespace=games_ns) 
     51                game = invite.getTag('game') 
     52                x = game.getTag('x', namespace='jabber:x:data') 
     53 
     54                form = xmpp.DataForm(node=x) 
     55 
     56                if form.getField('role'): 
     57                        self.role_o = form.getField('role').getValues()[0] 
     58                else: 
     59                        self.role_o = 'x' 
     60 
     61                if form.getField('rows'): 
     62                        self.rows = int(form.getField('rows').getValues()[0]) 
     63                else: 
     64                        self.rows = 3 
     65 
     66                if form.getField('cols'): 
     67                        self.cols = int(form.getField('cols').getValues()[0]) 
     68                else: 
     69                        self.cols = 3 
     70 
     71                if form.getField('strike'): 
     72                        self.strike = int(form.getField('strike').getValues()[0]) 
     73                else: 
     74                        self.strike = 3 
    4375 
    4476        # received an invitation 
    4577        def invited(self, msg): 
    46                 invite = msg.getTag('invite', namespace='http://jabber.org/protocol/games') 
    47                 game = invite.getTag('game') 
    48                 x = game.getTag('x', namespace='jabber:x:data') 
    49  
    50                 form = xmpp.DataForm(node=x) 
    51  
    52                 if form.getField('role'): 
    53                         self.role_o = form.getField('role').getValues()[0] 
    54  
    55                 if form.getField('rows'): 
    56                         self.rows = int(form.getField('rows').getValues()[0]) 
    57  
    58                 if form.getField('cols'): 
    59                         self.cols = int(form.getField('cols').getValues()[0]) 
    60  
    61                 # XXX 'strike' 
    62  
    63                 if not hasattr(self, 'rows'): 
    64                         self.rows = 3 
    65  
    66                 if not hasattr(self, 'cols'): 
    67                         self.cols = 3 
     78                self.read_invitation(msg) 
     79 
     80                # XXX prompt user 
     81                #   "accept, reject, ignore" 
    6882 
    6983                # the number of the move about to be made 
    7084                self.next_move_id = 1 
    7185 
     86                # display the board 
    7287                self.board = TicTacToeBoard(self, self.rows, self.cols) 
    7388 
     
    7691 
    7792                join = response.NT.join 
    78                 join.setNamespace('http://jabber.org/protocol/games') 
     93                join.setNamespace(games_ns) 
    7994 
    8095                self.send(response) 
    8196 
    82                 if not hasattr(self, 'role_o') or self.role_o == 'x': 
     97                if self.role_o == 'x': 
    8398                        self.role_s = 'o' 
    84                         self.role_o = 'x' 
    8599 
    86100                        self.their_turn() 
     
    92106 
    93107        def is_my_turn(self): 
    94                 return self.state == 'get_input' 
    95  
    96         def received(self, msg): 
    97                 # just sent an invitation, expecting a reply 
    98                 if self.state == 'sent_invite': 
    99                         if msg.getTag('join', namespace='http://jabber.org/protocol/games'): 
    100                                 self.board = TicTacToeBoard(self, self.rows, self.cols) 
    101  
    102                                 if self.role_s == 'x': 
    103                                         self.our_turn() 
    104                                 else: 
    105                                         self.their_turn() 
    106  
    107                         return 
    108  
    109                 # ignore messages unless we're expecting a move 
    110                 if self.state != 'waiting': 
    111                         return 
    112  
    113                 turn = msg.getTag('turn', namespace='http://jabber.org/protocol/games') 
    114  
     108                # XXX not great semantics 
     109                return self.received == self.ignore 
     110 
     111        # just sent an invitation, expecting a reply 
     112        def wait_for_invite_response(self, msg): 
     113                if msg.getTag('join', namespace=games_ns): 
     114                        self.board = TicTacToeBoard(self, self.rows, self.cols) 
     115 
     116                        if self.role_s == 'x': 
     117                                self.our_turn() 
     118                        else: 
     119                                self.their_turn() 
     120 
     121                elif msg.getTag('decline', namespace=games_ns): 
     122                        self.XXX() 
     123 
     124        # silently ignores any received messages 
     125        def ignore(self, msg): 
     126                pass 
     127 
     128        def wait_for_move(self, msg): 
     129                turn = msg.getTag('turn', namespace=games_ns) 
    115130                move = turn.getTag('move', namespace='http://jabber.org/protocol/games/tictactoe') 
    116131 
     
    129144                        return 
    130145 
    131                 # XXX check win conditions 
    132  
    133                 self.next_move_id += 1 
    134  
    135                 self.our_turn() 
     146                # check win conditions 
     147                if self.board.check_for_strike(self.role_o, row, col, self.strike): 
     148                        self.lost() 
     149                elif self.board.full(): 
     150                        self.drawn() 
     151                else: 
     152                        self.next_move_id += 1 
     153 
     154                        self.our_turn() 
    136155 
    137156        def our_turn(self): 
    138                 self.state = 'get_input' 
     157                # ignore messages until we've made our move 
     158                self.received = self.ignore 
    139159                self.board.win.set_title(self.board.title + ': your turn') 
    140160 
    141161        def their_turn(self): 
    142                 self.state = 'waiting' 
     162                self.received = self.wait_for_move 
    143163                self.board.win.set_title(self.board.title + ': their turn') 
    144164 
    145165        # called when the board receives input 
    146         def move(self, row, column): 
     166        def move(self, row, col): 
    147167                try: 
    148                         self.board.mark(row, column, self.role_s) 
     168                        self.board.mark(row, col, self.role_s) 
    149169                except InvalidMove, e: 
    150                         print 'invalid move' 
     170                        print 'you made an invalid move' 
    151171                        return 
    152172 
    153                 self.send_move(row, column) 
    154  
    155                 # XXX check win conditions 
     173                self.send_move(row, col) 
     174 
     175                # check win conditions 
     176                if self.board.check_for_strike(self.role_s, row, col,self.strike): 
     177                        self.won() 
     178                elif self.board.full(): 
     179                        self.drawn() 
     180                else: 
     181                        self.next_move_id += 1 
     182 
     183                        self.their_turn() 
    156184 
    157185        def send_move(self, row, column): 
    158186                msg = xmpp.Message() 
     187                msg.setType('chat') 
    159188 
    160189                turn = msg.NT.turn 
    161                 turn.setNamespace('http://jabber.org/protocol/games') 
     190                turn.setNamespace(games_ns) 
    162191 
    163192                move = turn.NT.move 
    164                 move.setNamespace('http://jabber.org/protocol/games/tictactoe') 
     193                move.setNamespace(games_ns+'/tictactoe') 
    165194 
    166195                move.setAttr('row', str(row)) 
     
    170199                self.send(msg) 
    171200 
    172                 self.next_move_id += 1 
    173  
    174                 self.their_turn() 
    175  
    176201class TicTacToeBoard: 
     202        def check_for_strike(self, p, r, c, strike): 
     203                # up and down, left and right 
     204                tallyI = 0 
     205                tally_ = 0 
     206 
     207                # right triangles: L\ , F/ 
     208                tallyL = 0 
     209                tallyF = 0 
     210 
     211                # convert real columns to internal columns 
     212                r -= 1 
     213                c -= 1 
     214 
     215                for d in xrange(-strike, strike): 
     216                        # vertical check 
     217                        try: 
     218                                tallyI = tallyI + 1 if self.board[r+d][c] == p else 0 
     219                        except IndexError: 
     220                                pass 
     221 
     222                        # horizontal check 
     223                        try: 
     224                                tally_ = tally_ + 1 if self.board[r][c+d] == p else 0 
     225                        except IndexError: 
     226                                pass 
     227 
     228                        # diagonal checks 
     229                        try: 
     230                                tallyL = tallyL + 1 if self.board[r+d][c+d] == p else 0 
     231                        except IndexError: 
     232                                pass 
     233 
     234                        try: 
     235                                tallyF = tallyF + 1 if self.board[r+d][c-d] == p else 0 
     236                        except IndexError: 
     237                                pass 
     238 
     239                        if any([t == strike for t in (tallyL, tallyF, tallyI, tally_)]): 
     240                                return True 
     241 
     242                return False 
     243 
    177244        def __init__(self, session, rows, cols): 
    178245                self.session = session 
     
    184251 
    185252                self.setup_window() 
     253 
     254        # is the board full? 
     255        def full(self): 
     256                for r in xrange(self.rows): 
     257                        for c in xrange(self.cols): 
     258                                if self.board[r][c] == None: 
     259                                        return False 
     260 
     261                return True 
    186262 
    187263        def setup_window(self): 
     
    215291                self.session.move(row, column) 
    216292 
     293        # this actually draws the board 
    217294        def expose(self, widget, event): 
    218295                win = widget.window