root/adventure/adventuremuc.py

Revision 156, 7.7 kB (checked in by thib, 6 months ago)

Quelques modifs ( World, Place et Thing héritent d'object )

Line 
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 from sys import argv
5 from world import World
6 from xmpp import (Component, JID, NS_COMPONENT_ACCEPT, NS_DATA, NS_VCARD, Node,
7                   NodeProcessed)
8 from xmpp_error import Error
9
10 class AdventureMUC(Component):
11     def __init__(self, jid, password, server, port=5347):
12         self.Namespace = NS_COMPONENT_ACCEPT
13         self.DBG = 'component'
14         self.jid = JID(jid)
15         Component.__init__(self, server=server, port=port, debug=[])
16         self.worlds = {}
17    
18         if not self.connect():
19             raise Exception, 'Unable to connect to %s:%s' % (server, port)
20         if not self.auth(jid, password):
21             raise Exception, 'Unable to autenticate as %s' % jid
22
23         self.RegisterHandler('iq', self.handle_iq)
24         self.RegisterHandler('presence', self.handle_presence)
25         self.RegisterHandler('message', self.handle_message)
26         print 'Adventure component up and running'
27
28
29     def add_world(self, filename):
30         """
31         Adding new world in mud instance
32         """
33         print 'Adding world from "%s"...' % filename
34         world = World(self, filename)
35         self.worlds[world.node] = world
36         print ' ' + world.name
37
38     def snd(self, worldnode, worldresource, stanza):
39         """
40         Send stanza 'stanza' to 'worldresource' in world 'worldnode'
41         """
42         stanza.setFrom(JID(node=worldnode, domain=self.jid.getDomain(),
43                            resource=worldresource))
44         self.send(stanza)
45
46     def handle_iq(self, _, iq):
47         """
48         Handle iq stanza
49         """
50         if not iq.getQueryNS():
51             # If not a query, is it a vCard?
52             vcard = iq.getTag('vCard')
53
54             if vcard:
55                 # Resolve world and player involved
56                 world_name = iq.getTo().getNode()
57                 player_name = iq.getTo().getResource()
58                 world = self.worlds[world_name]
59                 player = None
60                 for thing in (world.players + world.npcs):
61                     if thing.name == player_name:
62                         player = thing
63                 if player_name == 'Bag':
64                     player = world.bag
65                 # Reply
66                 answer = iq.buildReply('result')
67                 if iq.getType() == 'get' and player is not None:
68                     if player.vcard is not None:
69                         answer.addChild(node=player.vcard)
70                     else:
71                         answer.setTag(NS_VCARD + ' vCard')
72                 self.send(answer)
73                 raise NodeProcessed
74                    
75         elif (iq.getQueryNS().endswith('#info') or
76               iq.getQueryNS().endswith('#items')):
77             self.handle_disco_info(iq)
78             raise NodeProcessed
79
80     def handle_disco_info(self, iq):
81         if iq.getType() != 'get' :
82             #answer = iq.buildReply('error')
83             answer = Error(iq, 'bad-request')
84             self.send(answer)
85             return
86         answer = iq.buildReply('result')
87         if not iq.getTo().getNode():
88             query = answer.getTag('query')
89             if not query:
90                 query = answer.setTag('query')
91             query.setTag('identity', attrs = {'category': 'conference',
92                                               'type': 'text',
93                                               'name': 'MUD-MUC'})
94             query.setTag('feature',
95                          attrs = {'var': 'http://jabber.org/protocol/muc' })
96         elif self.worlds.has_key(iq.getTo().getNode()):
97             world_name = iq.getTo().getNode()
98             query = answer.getTag('query')
99             if not query:
100                 query = answer.setTag('query')
101             query.setTag('identity', attrs = {'category': 'conference',
102                                               'type': 'text',
103                                               'name': world_name})
104             query.setTag('feature', attrs =
105                          {'var': 'http://jabber.org/protocol/muc' })
106             query.setTag('feature', attrs = {'var': 'muc_public' })
107             query.setTag('feature', attrs = {'var': 'muc_persistent' })
108             query.setTag('feature', attrs = {'var': 'muc_open' })
109             query.setTag('feature', attrs = {'var': 'muc_semianonymous' })
110             query.setTag('feature', attrs = {'var': 'muc_unmoderated' })
111             query.setTag('feature', attrs = {'var': 'muc_unsecured' })
112             data = query.setTag(NS_DATA + ' x', attrs = {'type': 'result'})
113             field = data.setTag('field', attrs = {'type': 'hidden',
114                                                   'var': 'FORM_TYPE'})
115             field.addChild(node=Node('value', {},
116                                      'http://jabber.org/protocol/muc#roominfo'))
117            
118             field = data.setTag('field',
119                                 attrs = {'label': 'Description',
120                                          'var': 'muc#roominfo_description'})
121             field.addChild(node=Node('value', {}, self.worlds[world_name].name))
122            
123             field = data.setTag('field',
124                                 attrs = {'label': 'Number of occupants',
125                                          'var': 'muc#roominfo_occupants'})
126             field.addChild(node=Node('value', {},
127                                      str(len(self.worlds[world_name].players))))
128         self.send(answer)
129  
130     def handle_disco_items(self, iq):
131         if iq.getType() != 'get':
132             self.send(answer)
133             return
134         answer = iq.buildReply('result')
135         if not iq.getTo().getNode():
136             query = answer.getTag('query')
137             if not query:
138                 query = answer.setTag('query')
139             for name, i in self.worlds.items():
140                 query.setTag('item',
141                              attrs = {'jid': JID(node=i.node,
142                                                  domain=self.jid.getDomain()),
143                                       'name': name})
144         self.send(answer)
145
146     def handle_presence(self, _, pres):
147         """
148         Handle presence stanza
149         """
150         print 'presence: from %s type %s to %s' % (unicode(pres.getFrom()),
151                                                    unicode(pres.getType()),
152                                                    unicode(pres.getTo()))
153
154         world = pres.getTo().getNode()
155         if self.worlds.has_key(world):
156             self.worlds[world].handle_presence(pres)
157         else:
158             answer = Error(pres, 'item-not-found',
159                            'The world you are trying to reach is currently '
160                            'unavailable.')
161             self.send(answer)
162         return True
163
164     def handle_message(self, _, msg):
165         """
166         Handle message stanza
167         """
168         print 'message: from %s type %s to %s: %s' % (msg.getFrom(),
169                                                       msg.getType(),
170                                                       msg.getTo(),
171                                                       repr(msg.getBody()))
172
173         world = msg.getTo().getNode()
174         if self.worlds.has_key(world):
175             self.worlds[world].handle_message(msg)
176         else:
177             answer = Error(msg, 'item-not-found',
178                            'The world you are trying to reach is currently '
179                            'unavailable.')
180             self.send(answer)
181         return True
182
183
184
185 if __name__ == '__main__':
186     if len(argv) != 5:
187         print 'Syntax: ./adventuremuc.py <JID> <Password> <Host> <Port>'
188         print 'See README for further help'
189     else:
190         MUD = AdventureMUC(argv[1], argv[2], argv[3], int(argv[4]))
191         MUD.add_world('cave.xml')
192         MUD.add_world('tower/tower.xml')
193         while 1:
194             MUD.Process(10)
195
Note: See TracBrowser for help on using the browser.