6 CONFIG
= 'game_config.xml'
8 WINDOW_SIZE
= (640, 480)
9 WINDOW_CAPTION
= "Testing stuff"
12 BROADCAST_BIND
= 50031
22 MULTICAST
= '234.0.0.1'
26 GUI_THEME
= 'theme_two.zip'
27 WIDGETS_FILE
= 'widgets.xml'
34 from protocol
import *
40 sys
.path
.insert(0, 'pygame_gui')
44 from xml
.dom
.minidom
import parse
, parseString
45 from threading
import Lock
49 from twisted
.internet
.protocol
import DatagramProtocol
50 from twisted
.internet
import reactor
51 from twisted
.internet
import task
58 from DerGUI
import GUISystem
62 from OpenGL
.GL
import *
64 from OpenGL
.GLU
import *
71 # parse command line stuff
76 print "main(): No configuration file specified, using default of", CONFIG
79 configuration
= parse_config(config
)
81 if configuration
.has_key('error') and configuration
['error']:
82 print "main(): Error parsing configuration"
85 event_queue
= ThreadQueue()
87 multicast
= Multicast()
90 engine
= Engine(configuration
, event_queue
, client
)
92 client
.init(configuration
, event_queue
, engine
, multicast
)
94 net_thread
= threading
.Thread(target
=net_thread_func
, args
=(), kwargs
={'dmulticast': multicast
, 'dclient':client
, 'configs':configuration
})
103 def net_thread_func(dmulticast
, dclient
, configs
):
105 reactor
.listenMulticast(configs
['broadcast_port'], dmulticast
)
106 reactor
.listenUDP(configs
['message_port'], dclient
)
108 echo_request
= task
.LoopingCall(dclient
.serverRequest
)
110 if configs
.has_key('echo_time') and configs
['echo_time'] != None:
111 echo_request
.start(configs
['echo_time'])
113 print "net_thread_func(): No ECHO_TIME specified, using default of", ECHO_TIME
114 echo_request
.start(ECHO_TIME
)
116 reactor
.run(installSignalHandlers
=0)
120 def parse_config(filename
):
121 results
= {'error': 1}
123 if (exists(filename
)):
124 dom
= parse(filename
)
126 print "parse_config():", filename
, "doesn't exist."
129 results
= {'window_title': None,
134 'message_port': None,
135 'broadcast_port': None,
136 'broadcast_bind': None,
138 'background_color': None,
145 if (dom
.childNodes
[0].nodeName
== 'config'):
146 for node
in dom
.childNodes
[0].childNodes
:
148 if (node
.nodeName
== 'window_title'):
149 results
['window_title'] = node
.childNodes
[0].nodeValue
151 if (node
.nodeName
== 'log'):
152 results
['log'] = node
.childNodes
[0].nodeValue
154 if (node
.nodeName
== 'name'):
155 results
['name'] = node
.childNodes
[0].nodeValue
157 if (node
.nodeName
== 'font'):
158 results
['font'] = node
.childNodes
[0].nodeValue
160 if (node
.nodeName
== 'init'):
161 results
['init'] = node
.childNodes
[0].nodeValue
163 if (node
.nodeName
== 'message_port'):
164 results
['message_port'] = int(node
.childNodes
[0].nodeValue
)
166 if (node
.nodeName
== 'broadcast_port'):
167 results
['broadcast_port'] = int(node
.childNodes
[0].nodeValue
)
169 if (node
.nodeName
== 'broadcast_bind'):
170 results
['broadcast_bind'] = int(node
.childNodes
[0].nodeValue
)
172 if (node
.nodeName
== 'fullscreen'):
173 results
['fullscreen'] = int(node
.childNodes
[0].nodeValue
)
175 if (node
.nodeName
== 'background_color'):
177 string_parts
= node
.childNodes
[0].nodeValue
.split()
178 results
['background_color'] = [float(string_parts
[0]), float(string_parts
[1])]
179 results
['background_color'].append(float(string_parts
[2]))
180 results
['background_color'].append(float(string_parts
[3]))
182 if (node
.nodeName
== 'window_size'):
184 string_parts
= node
.childNodes
[0].nodeValue
.split()
185 results
['window_size'] = ((int(string_parts
[0]), int(string_parts
[1])))
187 if (node
.nodeName
== 'gravity'):
189 string_parts
= node
.childNodes
[0].nodeValue
.split()
190 results
['gravity'] = [float(string_parts
[0]), float(string_parts
[1])]
191 results
['gravity'].append(float(string_parts
[2]))
193 if (node
.nodeName
== 'step_size'):
194 results
['step_size'] = float(node
.childNodes
[0].nodeValue
)
196 if (node
.nodeName
== 'pack_dir'):
197 results
['pack_dir'] = node
.childNodes
[0].nodeValue
199 if (node
.nodeName
== 'echo_time'):
200 results
['echo_time'] = int(node
.childNodes
[0].nodeValue
)
210 self
.items_lock
= Lock()
212 def append(self
, new_item
):
213 self
.items_lock
.acquire()
214 self
.items
.append(new_item
)
215 self
.items_lock
.release()
218 self
.items_lock
.acquire()
220 the_item
= self
.items
.pop(0)
223 self
.items_lock
.release()
228 return len(self
.items
)
230 class Multicast(DatagramProtocol
):
232 def startProtocol(self
):
233 self
.transport
.joinGroup(MULTICAST
)
235 def datagramReceived(self
, datagram
, address
):
236 self
.transport
.write(final
, address
)
241 def __init__(self
, config
, event_queue
, client
):
245 self
.event_queue
= event_queue
249 video_flags
= OPENGL|DOUBLEBUF
251 assert config
.has_key('window_size')
252 self
.display
= pygame
.display
.set_mode(config
['window_size'], video_flags
)
254 self
.resize((config
['window_size']))
258 if not self
.config
.has_key('background_color') or self
.config
['background_color'] == None:
259 self
.config
['background_color'] = (0, 0, 0, 0)
260 print "Engine.__init__(): No background color specified, using default of (0, 0, 0, 0)"
262 glShadeModel(GL_SMOOTH
)
263 glClearColor(self
.config
['background_color'][0],
264 self
.config
['background_color'][1],
265 self
.config
['background_color'][2],
266 self
.config
['background_color'][3])
268 glEnable(GL_DEPTH_TEST
)
269 glDepthFunc(GL_LEQUAL
)
270 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
)
274 if not self
.config
.has_key('window_title') or self
.config
.has_key('window_title') == None:
275 self
.config
['window_title'] = WINDOW_CAPTION
276 print "Engine.__init__(): No window title specified, using default of", WINDOW_CAPTION
278 pygame
.display
.set_caption(self
.config
['window_title'])
280 self
.lamina_screen
= lamina
.LaminaScreenSurface()
281 self
.gui_system
= GUISystem(WIDGETS_FILE
, GUI_THEME
)
290 if not self
.config
.has_key('pack_dir') or self
.config
['pack_dir'] == None:
291 self
.config
['pack_dir'] = PACK_DIR
292 print "Engine.__init__(): No pack dir specified, using default of", PACK_DIR
294 for file in listdir(self
.config
['pack_dir']):
295 if is_zipfile(os
.path
.join(self
.config
['pack_dir'], file)):
296 self
.zipfiles
.append(ZipFile(os
.path
.join(self
.config
['pack_dir'], file)))
298 if not self
.config
.has_key('init') or self
.config
['init'] == None:
299 self
.config
['init'] = INIT
300 print "Engine.__init__(): No initial file specified, using default of", INIT
302 self
.running
= self
.addFile(self
.config
['init'])
304 print "Engine.__init__(): Failed adding initial file"
310 self
.gui_system
.draw(self
.lamina_screen
.surf
)
311 self
.lamina_screen
.refresh()
315 self
.process_events()
317 pygame
.display
.flip()
321 def process_events(self
):
323 for e
in pygame
.event
.get():
326 print "Engine.process_events(): Should be quitting..."
330 self
.change
= self
.gui_system
.event(e
)
332 new_event
= self
.convertEvent(e
)
333 self
.event_queue
.append(new_event
)
338 if len(self
.event_queue
):
339 new_event
= self
.event_queue
.pop()
343 for file in self
.files
.keys():
344 for name
in self
.files
[file]['object_instances'].keys():
345 self
.files
[file]['object_instances'][name
].event(new_event
[0], new_event
[1])
351 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT
)
358 self
.gui_system
.draw(self
.lamina_screen
.surf
)
359 self
.lamina_screen
.refresh()
360 self
.lamina_screen
.display()
365 reactor
.callFromThread(self
.killThreadGame
)
369 def killThreadGame(self
):
373 def convertEvent(self
, e
):
380 if e
.type == ACTIVEEVENT
:
381 data
['gain'] = e
.gain
382 data
['state'] = e
.state
384 if e
.type == KEYDOWN
:
385 data
['unicode'] = e
.unicode
393 if e
.type == MOUSEMOTION
:
396 data
['buttons'] = e
.buttons
398 if e
.type == MOUSEBUTTONUP
:
400 data
['button'] = e
.button
402 if e
.type == MOUSEBUTTONDOWN
:
404 data
['button'] = e
.button
406 if e
.type == JOYAXISMOTION
:
408 data
['axis'] = e
.axis
409 data
['value'] = e
.value
411 if e
.type == JOYBALLMOTION
:
413 data
['ball'] = e
.ball
416 if e
.type == JOYHATMOTION
:
419 data
['value'] = e
.value
421 if e
.type == JOYBUTTONUP
:
423 data
['button'] = e
.button
425 if e
.type == JOYBUTTONDOWN
:
427 data
['button'] = e
.button
429 if e
.type == VIDEORESIZE
:
430 data
['size'] = e
.size
434 if e
.type == VIDEOEXPOSE
:
437 if e
.type == USEREVENT
:
438 data
['code'] = e
.code
442 if e
.type == QUIT
: type = "QUIT"
443 if e
.type == ACTIVEEVENT
: type = "ACTIVEEVENT"
444 if e
.type == KEYDOWN
: type = "KEYDOWN"
445 if e
.type == KEYUP
: type = "KEYUP"
446 if e
.type == MOUSEMOTION
: type = "MOUSEMOTION"
447 if e
.type == MOUSEBUTTONUP
: type = "MOUSEBUTTONUP"
448 if e
.type == MOUSEBUTTONDOWN
: type = "MOUSEBUTTONDOWN"
449 if e
.type == JOYAXISMOTION
: type = "JOYAXISMOTION"
450 if e
.type == JOYBALLMOTION
: type = "JOYBALLMOTION"
451 if e
.type == JOYHATMOTION
: type = "JOYHATMOTION"
452 if e
.type == JOYBUTTONUP
: type = "JOYBUTTONUP"
453 if e
.type == JOYBUTTONDOWN
: type = "JOYBUTTONDOWN"
454 if e
.type == VIDEORESIZE
: type = "VIDEORESIZE"
455 if e
.type == VIDEOEXPOSE
: type = "VIDEOEXPOSE"
456 if e
.type == USEREVENT
: type = "USEREVENT"
460 def resize(self
, (width
, height
)):
463 glViewport(0, 0, width
, height
)
464 glMatrixMode(GL_PROJECTION
)
466 gluPerspective(45, 1.0*width
/height
, 0.1, 100.0)
467 glMatrixMode(GL_MODELVIEW
)
472 def getVisisbleMenus(self
):
476 for file, contents
in self
.files
.iteritems():
477 for name
, menu
in contents
['menu_instances'].iteritems():
483 def hideAllMenus(self
):
485 for file, contents
in self
.files
.iteritems():
486 for name
, menu
in contents
['menu_instances'].iteritems():
491 def showMenu(self
, menu_name
):
493 for file, contents
in self
.files
.iteritems():
494 for name
, menu
in contents
['menu_instances'].iteritems():
495 if contents
['menu_instances'].has_key(menu_name
):
496 contents
['menu_instances'][menu_name
].show()
500 def hideMenu(self
, menu_name
):
502 for file, contents
in self
.files
:
503 for name
, menu
in contents
['menu_instances'].iteritems():
504 if contents
['menu_instances'].has_key(menu_name
):
505 contents
['menu_instances'][menu_name
].hide()
509 def setMenu(self
, menu_name
):
512 self
.showMenu(menu_name
)
516 def addFile(self
, filename
, parent
=''):
520 for zipfile
in self
.zipfiles
:
521 for file in zipfile
.namelist():
524 dom
= parseString(zipfile
.read(file))
528 if dom
.childNodes
[0].nodeName
== 'game':
529 self
.files
[filename
] = {
533 'object_instances': {},
534 'menu_instances': {},
537 object_instances_d
= []
540 for node
in dom
.childNodes
[0].childNodes
:
541 if node
.nodeName
== 'def':
542 for sub_node
in node
.childNodes
:
544 if sub_node
.nodeName
== 'object':
548 for suber_node
in sub_node
.childNodes
:
549 if suber_node
.nodeName
== 'name':
550 if len(suber_node
.childNodes
):
551 temp_object_def
['name'] = suber_node
.childNodes
[0].nodeValue
553 if suber_node
.nodeName
== 'script':
554 if len(suber_node
.childNodes
):
555 temp_object_def
['script'] = suber_node
.childNodes
[0].nodeValue
557 if suber_node
.nodeName
== 'tangible':
558 if len(suber_node
.childNodes
):
559 temp_object_def
['tangible'] = suber_node
.childNodes
[0].nodeValue
561 if suber_node
.nodeName
== 'type':
562 if len(suber_node
.childNodes
):
563 temp_object_def
['type'] = suber_node
.childNodes
[0].nodeValue
565 self
.files
[filename
]['object_defs'][temp_object_def
['name']] = copy
.copy(temp_object_def
)
568 if sub_node
.nodeName
== 'menu':
571 temp_menu_def
['elements'] = {}
573 temp_element_set
= {}
575 for suber_node
in sub_node
.childNodes
:
577 if suber_node
.nodeName
== 'name':
578 temp_menu_def
['name'] = suber_node
.childNodes
[0].nodeValue
580 if (suber_node
.nodeName
== 'elements'):
582 for suberer_node
in suber_node
.childNodes
:
584 if (suberer_node
.nodeType
!= 3 and suberer_node
.nodeType
!= 8):
585 if (suberer_node
.hasAttribute('name')):
586 temp_element_set
['name'] = suberer_node
.getAttribute('name')
588 if (suberer_node
.hasAttribute('x')):
589 temp_element_set
['x'] = int(suberer_node
.getAttribute('x'))
591 if (suberer_node
.hasAttribute('y')):
592 temp_element_set
['y'] = int(suberer_node
.getAttribute('y'))
594 if (suberer_node
.hasAttribute('width')):
595 temp_element_set
['width'] = int(suberer_node
.getAttribute('width'))
597 if (suberer_node
.hasAttribute('height')):
598 temp_element_set
['height'] = int(suberer_node
.getAttribute('height'))
600 if (suberer_node
.hasAttribute('parent')):
601 temp_element_set
['parent'] = suberer_node
.getAttribute('parent')
603 if (suberer_node
.hasAttribute('target')):
604 temp_element_set
['target'] = suberer_node
.getAttribute('target')
606 if (suberer_node
.hasAttribute('text')):
607 temp_element_set
['text'] = suberer_node
.getAttribute('text')
609 temp_element_set
['type'] = suberer_node
.nodeName
610 temp_menu_def
['elements'][temp_element_set
['name']] = copy
.copy(temp_element_set
)
611 temp_element_set
= {}
613 self
.files
[filename
]['menu_defs'][temp_menu_def
['name']] = temp_menu_def
615 temp_element_set
= {}
617 if node
.nodeName
== 'instance':
619 for sub_node
in node
.childNodes
:
621 if sub_node
.nodeName
== 'object':
622 object_instances_d
.append(sub_node
.childNodes
[0].nodeValue
)
624 if sub_node
.nodeName
== 'menu':
625 menu_instances
.append(sub_node
.childNodes
[0].nodeValue
)
628 self
.files
[parent
]['children'].append(filename
)
630 self
.files
[filename
]['parent'] = parent
634 print "Engine.addFile(): Instance creation isn't done quite yet."
636 for menuname
in menu_instances
:
641 if self
.files
[filename
]['menu_defs'].has_key(menuname
):
642 print "\tInstantiate menu:", menuname
643 the_def
= self
.files
[filename
]['menu_defs'][menuname
]
646 for file in self
.files
.keys():
648 if self
.files
[file]['menu_defs'].has_key(menuname
):
649 print "Instantiate menu:", menuname
650 the_def
= self
.files
[file]['menu_defs'][menuname
]
656 for file in self
.files
.keys():
657 if self
.files
[file]['menu_instances'].has_key(menuname
):
658 self
.files
[file]['menu_instances'][menuname
].show()
661 if not instance_found
:
662 self
.files
[filename
]['menu_instances'][menuname
] = Menu(menuname
, the_def
['elements'], self
)
663 self
.files
[filename
]['menu_instances'][menuname
].show()
665 for objectname
in object_instances_d
:
666 print "\tInstantiate object:", objectname
670 def removeFile(self
, filename
):
672 if self
.files
.has_key(filename
):
674 for child
in self
.files
[filename
]['children']:
675 self
.removeFile(child
)
677 del self
.files
[filename
]['children']
678 parent
= self
.files
[filename
]['parent']
680 if self
.files
[parent
].has_key(filename
):
681 self
.files
[parent
]['children'].pop(self
.files
[parent
]['children'].index(filename
))
683 del self
.files
[filename
]
689 def __init__(self
, name
, elements
, engine
):
691 # elements is a dictionary with name:{element info}
696 self
.widget_info
= elements
698 self
.gui_system
= engine
.gui_system
699 self
.event_queue
= engine
.event_queue
703 config
= engine
.config
705 for name
, element
in elements
.iteritems():
707 multiplier_x
= float(config
['window_size'][0]) / 100.00
708 multiplier_y
= float(config
['window_size'][1]) / 100.00
710 dx
= float(element
['x']) * multiplier_x
711 dy
= float(element
['y']) * multiplier_y
713 dwidth
= float(element
['width']) * multiplier_x
714 dheight
= float(element
['height']) * multiplier_y
716 params
= {'x': dx
, 'y': dy
, 'width': dwidth
, 'height': dheight
}
718 if element
['type'] == 'button':
719 params
['text'] = element
['text']
720 self
.widgets
[name
] = self
.gui_system
.makeWidget('button', params
)
721 self
.widgets
[name
].connect('BUTTON_CLICKED', self
.clicked
, {'name': name
})
723 if element
['type'] == 'image':
724 print "Menu.__init__(): 'image' widget type not implemented yet."
726 if element
['type'] == 'label':
727 params
['text'] = element
['text']
728 self
.widgets
[name
] = self
.gui_system
.makeWidget('label', params
)
730 if element
['type'] == 'listbox':
731 print "Menu.__init__(): 'listbox' widget type not implemented yet."
733 if element
['type'] == 'textbox':
734 params
['type'] == element
['text']
735 self
.widgets
[name
] = self
.gui_system
.makeWidget('textbox', params
)
736 self
.widgets
[name
].connect('KEYDOWN', self
.key_pressed
, {'name': name
})
740 def clicked(self
, params
, more_params
):
742 if self
.widgets
.has_key(params
['name']):
743 self
.event_queue
.append(['WIDGET_CLICKED', {'name':params
['name']}])
745 if self
.widget_info
[params
['name']].has_key('target') and self
.widget_info
[params
['name']]['target'] != '':
747 exec(self
.widget_info
[params
['name']]['target'])
750 # print "Menu.clicked(): Error executing widget click callback"
754 def key_pressed(self
, params
, more_params
):
756 if self
.widgets
.has_key(params
['name']):
757 self
.event_queue
.append(['WIDGET_KEYDOWN', more_params
])
763 for widget
in self
.widgets
:
764 self
.widgets
[widget
].show()
772 for widget
in self
.widgets
:
773 self
.widgets
[widget
].hide()
780 final
= ''.join([dog
[0], dog
[4], dog
[6], dog
[-3], ' ', dog
[7], dog
[0], dog
[0]])
782 # Below this point, nothing really changes.
783 # A 'here be dragons' wouldn't really be appropriate, but same kind of
784 # idea. Aka, don't mess with below.
786 class Client(DatagramProtocol
):
788 def init(self
, config
, event_queue
, engine
, multicast
):
791 self
.event_queue
= event_queue
792 self
.multicast
= multicast
796 self
.current_server
= ()
797 self
.requested_server
= ()
799 self
.server_request
= 0
803 def datagramReceived(self
, data
, (host
, port
)):
805 if data
[:len(YOUTHERE
)] == YOUTHERE
:
807 # print "Client.datagramReceived(): Recieved YOUTHERE, responding with IMHERE"
808 self
.transport
.write(IMHERE
, (host
, port
))
810 if data
[:len(SERVEROFFER
)] == SERVEROFFER
:
812 split_strings
= data
.split()
814 self
.servers
[split_strings
[2]] = (host
, int(split_strings
[1]))
816 event
= [SERVEROFFER
, {'server_name': split_strings
[2],
817 'server_address': self
.servers
[split_strings
[2]]}]
818 self
.event_queue
.append(event
)
820 print "Client.datagramReceived(): Received SERVEROFFER"
822 if data
[:len(YOUREIN
)] == YOUREIN
:
824 if (host
, port
) == self
.requested_server
:
825 self
.current_server
= (host
, port
)
826 self
.requested_server
= ()
829 data
= {'server': self
.current_server
}
832 self
.event_queue
.append(event
)
834 print "Client.datagramReceived(): Received YOUREIN, joined server"
838 if data
[:len(STILLIN
)] == STILLIN
:
840 if (host
, port
) == self
.current_server
:
841 # print "Client.datagramReceived(): Received STILLIN, responding with IMHERE"
842 self
.transport
.write(IMHERE
, (host
, port
))
846 if data
[:len(LIST
)] == LIST
:
848 print "Client.datagramReceived(): Received LIST"
850 split_strings
= data
.split()
854 for string
in split_strings
:
856 self
.members
.append(string
)
859 data
= {'names': self
.members
, 'server_address': (host
, port
)}
862 self
.event_queue
.append(event
)
866 if data
[:len(SOMEONEJOINED
)] == SOMEONEJOINED
:
868 if (host
, port
) == self
.current_server
:
870 print "Client.datagramReceived(): Received SOMEONEJOINED"
874 for member
in self
.members
:
875 if member
== data
[len(SOMEONEJOINED
) + 1:]:
878 if left_member
== '':
879 self
.members
.append(data
[len(SOMEONEJOINED
) + 1:])
881 event
= [SOMEONEJOINED
]
882 data
= {'name': data
[len(SOMEONEJOINED
) + 1:]}
886 self
.event_queue
.append(event
)
890 if data
[:len(SOMEONELEFT
)] == SOMEONELEFT
:
892 if (host
, port
) == self
.current_server
:
894 name
= data
[len(SOMEONELEFT
) + 1:]
896 if name
in self
.members
:
897 print "Client.datagramReceived(): Received SOMEONELEFT"
899 self
.members
.remove(name
)
901 event
= [SOMEONELEFT
]
902 data
= {'name': name
}
906 self
.event_queue
.append(event
)
909 print "Client.datagramReceived(): Received SOMEONELEFT, but", name
, "not present in roster"
913 if data
[:len(YOUROUT
)] == YOUROUT
:
915 if (host
, port
) == self
.current_server
:
917 print "Client.datagramReceived(): Recieved YOUROUT"
919 self
.current_server
= ()
925 self
.event_queue
.append(event
)
929 if data
[:len(LETTER
)] == LETTER
:
931 if (host
, port
) == self
.current_server
:
932 print "Client.datagramReceived(): Received LETTER"
934 split_strings
= data
.split(':')
936 message
= data
[data
.find(':', len(LETTER
) + 1) + 1:]
937 message_origin
= split_strings
[1]
940 data
= {'message': message
, 'origin': message_origin
}
943 self
.event_queue
.append(event
)
947 if data
[:len(IMHERE
)] == IMHERE
:
949 if (host
, port
) == self
.current_server
:
950 print "Client.datagramReceived(): Received IMHERE from server"
952 self
.server_request
= 0
956 def serverRequest(self
):
958 if self
.current_server
!= ():
960 if self
.server_request
> SERVER_TIMEOUT
:
961 self
.event_queue
.append([SERVER_GONE
, {}])
962 self
.current_server
= ()
965 self
.server_request
+= 1
966 self
.transport
.write(YOUTHERE
, self
.current_server
)
970 def executeCommand(self
, command
, data
):
972 reactor
.callFromThread(self
.executeThreadedCommand
, command
, data
)
976 def executeThreadedCommand(self
, command
, data
):
977 if command
== SERVERKILL
:
979 if self
.current_server
!= ():
981 message
= ''.join([SERVERKILL
, ' '])
983 if data
.has_key('password'):
984 message
= ''.join([message
, data
['password']])
986 self
.transport
.write(message
, self
.current_server
)
988 if command
== SERVERREQUEST
:
990 message
= ''.join([SERVERREQUEST
, ' ', str(self
.params
['message_port'])])
992 self
.multicast
.transport
.write(message
, (MULTICAST
, self
.params
['broadcast_port']))
993 #self.transport.write(message, ('255.255.255.255', self.params['broadcast_port']))
995 if command
== GETLIST
:
999 if data
.has_key('server'):
1001 if self
.servers
.has_key(data
['server']):
1002 self
.transport
.write(message
, self
.servers
[data
['server']])
1006 if self
.current_server
!= ():
1007 self
.transport
.write(message
, self
.current_server
)
1009 if command
== IMOUT
:
1011 if self
.current_server
!= ():
1015 self
.transport
.write(message
, self
.current_server
)
1017 self
.current_server
= ()
1019 if command
== LETTER
:
1021 if self
.current_server
!= ():
1023 message
= ''.join([LETTER
, ':'])
1025 for dest
in data
['destinations']:
1026 if dest
in self
.members
:
1027 message
= ''.join([message
, ' ' , dest
])
1029 message
= ''.join([message
, ':', data
['message']])
1031 self
.transport
.write(message
, self
.current_server
)
1033 if command
== WANTIN
:
1035 if data
.has_key('server'):
1036 if self
.servers
.has_key(data
['server']):
1038 self
.transport
.write(''.join([WANTIN
, ' ', self
.params
['name']]),
1039 self
.servers
[data
['server']])
1040 self
.current_server
= ()
1041 self
.requested_server
= self
.servers
[data
['server']]
1044 if __name__
== '__main__':