comparison orpg/networking/mplay_server.py @ 128:fba298d65cf8 alpha

Traipse Alpha 'OpenRPG' {091003-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Cleaning up for Beta) Added Bookmarks Fix to Remote Admin Commands Minor fix to text based Server Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager default_manifest.xml renamed to default_upmana.xml Cleaner clode for saved repositories New TrueDebug Class in orpg_log (See documentation for usage) Mercurial's hgweb folder is ported to upmana Happy Halloween!
author sirebral
date Tue, 03 Nov 2009 00:52:47 -0600
parents 8827271fbe1b
children 8e07c1a2c69b
comparison
equal deleted inserted replaced
127:0f720618a8bd 128:fba298d65cf8
101 tree = f.read() 101 tree = f.read()
102 f.close() 102 f.close()
103 self.game_map.init_from_xml(fromstring(tree)) 103 self.game_map.init_from_xml(fromstring(tree))
104 104
105 def save_map(self): 105 def save_map(self):
106 #debug(log=False)
107 if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1: 106 if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1:
108 f = open(self.mapFile, "w") 107 f = open(self.mapFile, "w")
109 f.write(self.game_map.get_all_xml()) 108 f.write(self.game_map.get_all_xml())
110 f.close() 109 f.close()
111 110
154 el.set('players', str(self.get_num_players())) 153 el.set('players', str(self.get_num_players()))
155 el.set('action', act) 154 el.set('action', act)
156 return tostring(el) 155 return tostring(el)
157 156
158 class client_stub(client_base): 157 class client_stub(client_base):
159 def __init__(self,inbox,sock,props,log): 158 def __init__(self, inbox, sock, props, log):
160 client_base.__init__(self) 159 client_base.__init__(self)
161 self.ip = props['ip'] 160 self.ip = props['ip']
162 self.role = props['role'] 161 self.role = props['role']
163 self.id = props['id'] 162 self.id = props['id']
164 self.group_id = props['group_id'] 163 self.group_id = props['group_id']
223 ###################################################################### 222 ######################################################################
224 ###################################################################### 223 ######################################################################
225 """ 224 """
226 225
227 class mplay_server: 226 class mplay_server:
228 #debug(log=False)
229 def __init__(self, log_console=None, name=None): 227 def __init__(self, log_console=None, name=None):
230 logger._set_log_level = 16 228 logger._set_log_level = 16
231 logger._set_log_to_console(True) 229 logger._set_log_to_console(True)
232 self.log_to_console = 1 230 self.log_to_console = 1
233 self.log_console = log_console 231 self.log_console = log_console
262 self.allowRemoteAdmin = True 260 self.allowRemoteAdmin = True
263 self.sendLobbySound = False 261 self.sendLobbySound = False
264 self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used? 262 self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used?
265 263
266 def initServer(self, **kwargs): 264 def initServer(self, **kwargs):
267 #debug(log=False)
268 for atter, value in kwargs.iteritems(): setattr(self, atter, value) 265 for atter, value in kwargs.iteritems(): setattr(self, atter, value)
269 validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" ) 266 validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" )
270 validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" ) 267 validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" )
271 self.server_start_time = time.time() 268 self.server_start_time = time.time()
272 269
356 353
357 # This method reads in the server's configuration file and reconfigs the server 354 # This method reads in the server's configuration file and reconfigs the server
358 # as needed, over-riding any default values as requested. 355 # as needed, over-riding any default values as requested.
359 356
360 def initServerConfig(self): 357 def initServerConfig(self):
361 #debug(log=False) 358 debug(log=False)
362 self.log_msg("Processing Server Configuration File... " + self.userPath) 359 self.log_msg("Processing Server Configuration File... " + self.userPath)
363 # make sure the server_ini.xml exists! 360 # make sure the server_ini.xml exists!
364 validate.config_file( "server_ini.xml", "default_server_ini.xml" ) 361 validate.config_file( "server_ini.xml", "default_server_ini.xml" )
365 # try to use it. 362 # try to use it.
366 try: 363 try:
655 badchars = "\"\\`><" 652 badchars = "\"\\`><"
656 for c in badchars: name = name.replace(c,"") 653 for c in badchars: name = name.replace(c,"")
657 return name 654 return name
658 655
659 def registerRooms(self, args=None): 656 def registerRooms(self, args=None):
660 #debug()
661 rooms = '' 657 rooms = ''
662 id = '0' 658 id = '0'
663 time.sleep(500) 659 time.sleep(500)
664 #debug(self.groups)
665 for rnum in self.groups.keys(): 660 for rnum in self.groups.keys():
666 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][name]":self.groups[rnum].name, 661 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][name]":self.groups[rnum].name,
667 "room_data[rooms][" + str(rnum) + "][pwd]":str(self.groups[rnum].pwd != "")})+'&' 662 "room_data[rooms][" + str(rnum) + "][pwd]":str(self.groups[rnum].pwd != "")})+'&'
668 for pid in self.groups[rnum].players: 663 for pid in self.groups[rnum].players:
669 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][players]["+str(pid)+"]":self.players[pid].name,})+'&' 664 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][players]["+str(pid)+"]":self.players[pid].name,})+'&'
670 #debug(rooms)
671 for meta in self.metas.keys(): 665 for meta in self.metas.keys():
672 while id == '0': 666 while id == '0':
673 id, cookie = self.metas[meta].getIdAndCookie() 667 id, cookie = self.metas[meta].getIdAndCookie()
674 data = urllib.urlencode( {"room_data[server_id]":id, 668 data = urllib.urlencode( {"room_data[server_id]":id,
675 "act":'registerrooms'}) 669 "act":'registerrooms'})
676 #debug((data, rooms))
677 get_server_dom(data+'&'+rooms, self.metas[meta].path, string=True) 670 get_server_dom(data+'&'+rooms, self.metas[meta].path, string=True)
678 671
679 def register(self,name_given=None): 672 def register(self,name_given=None):
680 if name_given == None: name = self.name 673 if name_given == None: name = self.name
681 else: self.name = name = name_given 674 else: self.name = name = name_given
865 self.listen_event.wait(10) 858 self.listen_event.wait(10)
866 self.incoming_event.wait(10) 859 self.incoming_event.wait(10)
867 self.log_msg("Server stopped!") 860 self.log_msg("Server stopped!")
868 861
869 def log_msg(self,msg): 862 def log_msg(self,msg):
863 debug(parents=True)
870 if self.log_to_console: 864 if self.log_to_console:
871 if self.log_console: self.log_console(msg) 865 if self.log_console: self.log_console(msg)
872 else: print str(msg) 866 else: print str(msg)
873 867
874 def print_help(self): 868 def print_help(self):
1254 if v1>v2: return 0 1248 if v1>v2: return 0
1255 if len(minv)>len(cver): return 0 1249 if len(minv)>len(cver): return 0
1256 return 1 1250 return 1
1257 1251
1258 def SendLobbyMessage(self, socket, player_id): 1252 def SendLobbyMessage(self, socket, player_id):
1259 #debug(log=False)
1260 """ 1253 """
1261 # Display the lobby message 1254 # Display the lobby message
1262 # prepend this server's version string to the the lobby message 1255 # prepend this server's version string to the the lobby message
1263 """ 1256 """
1264 try: 1257 try:
1326 # At this point, we're done and cleaning up. 1319 # At this point, we're done and cleaning up.
1327 self.log_msg("server socket listening thread exiting...") 1320 self.log_msg("server socket listening thread exiting...")
1328 self.listen_event.set() 1321 self.listen_event.set()
1329 1322
1330 def acceptedNewConnectionThread( self, newsock, addr ): 1323 def acceptedNewConnectionThread( self, newsock, addr ):
1331 #debug(log=False)
1332 """Once a new connection comes in and is accepted, this thread starts up to handle it.""" 1324 """Once a new connection comes in and is accepted, this thread starts up to handle it."""
1333 # Initialize xml_dom 1325 # Initialize xml_dom
1334 xml_dom = None 1326 xml_dom = None
1335 data = None 1327 data = None
1336 1328
1407 # to multiple expiring parsing/handling threads to improve server performance 1399 # to multiple expiring parsing/handling threads to improve server performance
1408 # and player load capacity -- Snowdog 3/04 1400 # and player load capacity -- Snowdog 3/04
1409 """ 1401 """
1410 1402
1411 def message_handler(self, arg): 1403 def message_handler(self, arg):
1412 #debug(log=False)
1413 xml_dom = None 1404 xml_dom = None
1414 self.log_msg( "message handler thread running..." ) 1405 self.log_msg( "message handler thread running..." )
1415 while self.alive: 1406 while self.alive:
1416 data = None 1407 data = None
1417 try: data=self.incoming.get(0) 1408 try: data=self.incoming.get(0)
1432 #if xml_dom: xml_dom.unlink() 1423 #if xml_dom: xml_dom.unlink()
1433 #if xml_dom: xml_dom.unlink() 1424 #if xml_dom: xml_dom.unlink()
1434 self.log_msg("message handler thread exiting...") 1425 self.log_msg("message handler thread exiting...")
1435 self.incoming_event.set() 1426 self.incoming_event.set()
1436 1427
1437 def parse_incoming_dom(self,data): 1428 def parse_incoming_dom(self, data):
1429 #debug((data, tostring(data) if iselement(data) else 'None element')) Sometimes I catch an error.
1438 end = data.find(">") #locate end of first element of message 1430 end = data.find(">") #locate end of first element of message
1439 head = data[:end+1] 1431 head = data[:end+1]
1440 #self.log_msg(head) 1432 #self.log_msg(head)
1441 xml_dom = None 1433 xml_dom = None
1442 try: 1434 try:
1455 else: raise Exception, "Not a valid header!" 1447 else: raise Exception, "Not a valid header!"
1456 #Message Action thread expires and closes here. 1448 #Message Action thread expires and closes here.
1457 return 1449 return
1458 1450
1459 def do_alter(self, xml_dom, data): 1451 def do_alter(self, xml_dom, data):
1460 target = xml_dom.get("key") 1452 target = xml_dom.get("key") or 'None'
1461 value = xml_dom.get("val") 1453 value = xml_dom.get("val") or 'None'
1462 player = xml_dom.get("plr") 1454 player = xml_dom.get("plr") or 'None'
1463 group_id = xml_dom.get("gid") 1455 group_id = xml_dom.get("gid") or 'None'
1464 boot_pwd = xml_dom.get("bpw") 1456 boot_pwd = xml_dom.get("bpw") or 'None'
1465 actual_boot_pwd = self.groups[group_id].boot_pwd 1457 actual_boot_pwd = self.groups[group_id].boot_pwd
1466 1458
1467 if self.allow_room_passwords == 0: 1459 if self.allow_room_passwords == 0:
1468 msg ="<msg to='" + player + "' from='0' group_id='0' /> " 1460 msg ="<msg to='" + player + "' from='0' group_id='0' /> "
1469 msg += "Room passwords have been disabled by the server administrator." 1461 msg += "Room passwords have been disabled by the server administrator."
1478 self.log_msg(lmessage) 1470 self.log_msg(lmessage)
1479 self.send_to_all('0',self.groups[group_id].toxml('update')) 1471 self.send_to_all('0',self.groups[group_id].toxml('update'))
1480 elif target == "name": 1472 elif target == "name":
1481 # Check for & in name. We want to allow this because of its common 1473 # Check for & in name. We want to allow this because of its common
1482 # use in d&d games 1474 # use in d&d games
1483 result = self.change_group_name(group_id,value,player) 1475 result = self.change_group_name(group_id, value, player)
1484 msg ="<msg to='" + player + "' from='0' group_id='0' />" + result 1476 msg ="<msg to='" + player + "' from='0' group_id='0' />" + result
1485 self.players[player].outbox.put(msg) 1477 self.players[player].outbox.put(msg)
1486 else: 1478 else:
1487 msg ="<msg to='" + player + "' from='0' group_id='0'>Invalid Administrator Password." 1479 msg ="<msg to='" + player + "' from='0' group_id='0'>Invalid Administrator Password."
1488 self.players[player].outbox.put(msg) 1480 self.players[player].outbox.put(msg)
1571 allowed = 0 1563 allowed = 0
1572 msg = 'failed - invalid client version ('+self.groups[group_id].minVersion+' or later required)' 1564 msg = 'failed - invalid client version ('+self.groups[group_id].minVersion+' or later required)'
1573 1565
1574 if not self.groups[group_id].check_pwd(pwd): 1566 if not self.groups[group_id].check_pwd(pwd):
1575 allowed = 0 1567 allowed = 0
1576
1577 #tell the clients password manager the password failed -- SD 8/03 1568 #tell the clients password manager the password failed -- SD 8/03
1578 pm = "<password signal='fail' type='room' id='" + group_id + "' data=''/>" 1569 pm = "<password signal='fail' type='room' id='" + group_id + "' data=''/>"
1579 self.players[from_id].outbox.put(pm) 1570 self.players[from_id].outbox.put(pm)
1580 msg = 'failed - incorrect room password' 1571 msg = 'failed - incorrect room password'
1581 1572
1609 else: self.players[from_id].role = "Lurker" 1600 else: self.players[from_id].role = "Lurker"
1610 except Exception, e: 1601 except Exception, e:
1611 print "exception in move_player() " 1602 print "exception in move_player() "
1612 traceback.print_exc() 1603 traceback.print_exc()
1613 1604
1614 old_group_id = self.players[from_id].change_group(group_id,self.groups) 1605 old_group_id = self.players[from_id].change_group(group_id, self.groups)
1615 self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del')) 1606 self.send_to_group(from_id, old_group_id, self.players[from_id].toxml('del'))
1616 self.send_to_group(from_id,group_id,self.players[from_id].toxml('new')) 1607 self.send_to_group(from_id, group_id, self.players[from_id].toxml('new'))
1617 self.check_group(from_id, old_group_id) 1608 self.check_group(from_id, old_group_id)
1618 1609
1619 """ 1610 """
1620 # Here, if we have a group specific lobby message to send, push it on 1611 # Here, if we have a group specific lobby message to send, push it on
1621 # out the door! Make it put the message then announce the player...just 1612 # out the door! Make it put the message then announce the player...just
1667 # xml message. Ack! This version simply creates the groups, it does not 1658 # xml message. Ack! This version simply creates the groups, it does not
1668 # send them to players. Also note, both these methods have race 1659 # send them to players. Also note, both these methods have race
1669 # conditions written all over them. Ack! Ack! 1660 # conditions written all over them. Ack! Ack!
1670 """ 1661 """
1671 def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ): 1662 def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ):
1672 group_id = str( self.next_group_id ) 1663 group_id = str(self.next_group_id)
1673 self.next_group_id += 1 1664 self.next_group_id += 1
1674 self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist ) 1665 self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist )
1675 self.groups[group_id].moderated = moderated 1666 self.groups[group_id].moderated = moderated
1676 ins = "" 1667 ins = ""
1677 if persist !=0: ins="Persistant " 1668 if persist !=0: ins="Persistant "
1678 lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name) 1669 lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name)
1679 self.log_msg( lmsg ) 1670 self.log_msg( lmsg )
1680 self.log_msg(("create_group", (str(name), int(group_id), 0) )) ##-99 works, could be better. 1671 self.log_msg(("create_group", (str(name), int(group_id), pwd, 0) ))
1681 1672
1682 def change_group_name(self,gid,name,pid): 1673 def change_group_name(self, gid, name, pid):
1683 "Change the name of a group" 1674 "Change the name of a group"
1684 # Check for & in name. We want to allow this because of its common 1675 # Check for & in name. We want to allow this because of its common
1685 # use in d&d games. 1676 # use in d&d games.
1686 try: 1677 try:
1687 loc = name.find("&") 1678 loc = name.find("&")
1713 oldloc = loc+1 1704 oldloc = loc+1
1714 oldroomname = self.groups[gid].name 1705 oldroomname = self.groups[gid].name
1715 self.groups[gid].name = str(name) 1706 self.groups[gid].name = str(name)
1716 lmessage = "Room name changed to from \"" + oldroomname + "\" to \"" + name + "\"" 1707 lmessage = "Room name changed to from \"" + oldroomname + "\" to \"" + name + "\""
1717 self.log_msg(lmessage + " by " + str(pid) ) 1708 self.log_msg(lmessage + " by " + str(pid) )
1709 self.log_msg(("update_group", (str(name), group_id, False)))
1710
1718 self.send_to_all('0',self.groups[gid].toxml('update')) 1711 self.send_to_all('0',self.groups[gid].toxml('update'))
1719 return lmessage 1712 return lmessage
1720 except: return "An error occured during rename of room!" 1713 except: return "An error occured during rename of room!"
1721 thread.start_new_thread(self.registerRooms,(0,)) 1714 thread.start_new_thread(self.registerRooms,(0,))
1722 1715
1763 e = name[loc+1:] 1756 e = name[loc+1:]
1764 name = b + "&quot;" + e 1757 name = b + "&quot;" + e
1765 oldloc = loc+1 1758 oldloc = loc+1
1766 group_id = str(self.next_group_id) 1759 group_id = str(self.next_group_id)
1767 self.next_group_id += 1 1760 self.next_group_id += 1
1761
1768 self.groups[group_id] = game_group(group_id, name, pwd, "", boot_pwd, minVersion, None, messageFile) 1762 self.groups[group_id] = game_group(group_id, name, pwd, "", boot_pwd, minVersion, None, messageFile)
1769 self.groups[group_id].voice[from_id]=1 1763 self.groups[group_id].voice[from_id]=1
1770 self.players[from_id].outbox.put(self.groups[group_id].toxml('new')) 1764 self.players[from_id].outbox.put(self.groups[group_id].toxml('new'))
1771 old_group_id = self.players[from_id].change_group(group_id,self.groups) 1765 old_group_id = self.players[from_id].change_group(group_id, self.groups)
1772 self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del')) 1766 self.send_to_group(from_id, old_group_id, self.players[from_id].toxml('del'))
1773 self.check_group(from_id, old_group_id) 1767 self.check_group(from_id, old_group_id)
1774 self.send_to_all(from_id,self.groups[group_id].toxml('new')) 1768 self.send_to_all(from_id,self.groups[group_id].toxml('new'))
1775 self.send_to_all('0',self.groups[group_id].toxml('update')) 1769 self.send_to_all('0',self.groups[group_id].toxml('update'))
1776 self.handle_role("set",from_id,"GM",boot_pwd, group_id) 1770 self.handle_role("set",from_id,"GM", boot_pwd, group_id)
1777 lmsg = "Creating Group... (" + str(group_id) + ") " + str(name) 1771 lmsg = "Creating Group... (" + str(group_id) + ") " + str(name)
1778 self.log_msg( lmsg ) 1772 self.log_msg( lmsg )
1779 jmsg = "moving to room " + str(group_id) + "." 1773 jmsg = "moving to room " + str(group_id) + "."
1780 self.log_msg( jmsg ) 1774 self.log_msg( jmsg )
1781 self.log_msg(("create_group", (str(name), group_id, from_id))) 1775 self.log_msg(("create_group", (str(name), group_id, from_id, 'No' if pwd == '' else 'Yes')))
1782 #even creators of the room should see the HTML --akoman 1776 #even creators of the room should see the HTML --akoman
1783 #edit: jan10/03 - was placed in the except statement. Silly me. 1777 #edit: jan10/03 - was placed in the except statement. Silly me.
1784 if self.defaultMessageFile != None: 1778 if self.defaultMessageFile != None:
1785 if self.defaultMessageFile[:4] == 'http': 1779 if self.defaultMessageFile[:4] == 'http':
1786 data = urllib.urlretrieve(self.defaultMessageFile) 1780 data = urllib.urlretrieve(self.defaultMessageFile)
1803 if not self.isPersistentRoom(group_id) and self.groups[group_id].get_num_players() == 0: 1797 if not self.isPersistentRoom(group_id) and self.groups[group_id].get_num_players() == 0:
1804 self.send_to_all("0",self.groups[group_id].toxml('del')) 1798 self.send_to_all("0",self.groups[group_id].toxml('del'))
1805 del self.groups[group_id] 1799 del self.groups[group_id]
1806 self.log_msg(("delete_group", (group_id, from_id))) 1800 self.log_msg(("delete_group", (group_id, from_id)))
1807 else: self.send_to_all("0",self.groups[group_id].toxml('update')) 1801 else: self.send_to_all("0",self.groups[group_id].toxml('update'))
1808
1809 #The register Rooms thread 1802 #The register Rooms thread
1810 thread.start_new_thread(self.registerRooms,(0,)) 1803 thread.start_new_thread(self.registerRooms,(0,))
1811
1812 except Exception, e: self.log_msg(str(e)) 1804 except Exception, e: self.log_msg(str(e))
1813 1805
1814 def del_player(self, id, group_id): 1806 def del_player(self, id, group_id):
1815 try: 1807 try:
1816 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name) 1808 dmsg = "Client Disconnect: (" + str(id) + ") " + str(self.players[id].name)
2544 # 2536 #
2545 # Similar to console listing except formated for web display 2537 # Similar to console listing except formated for web display
2546 # in chat window on remote client 2538 # in chat window on remote client
2547 """ 2539 """
2548 def player_list_remote(self): 2540 def player_list_remote(self):
2549 COLOR1 = "\"#004080\"" #header/footer background color 2541 """Does not work!!!""" # TaS.
2550 COLOR2 = "\"#DDDDDD\"" #group line background color 2542 COLOR1 = "'#004080'" #header/footer background color
2551 COLOR3 = "\"#FFFFFF\"" #player line background color 2543 COLOR2 = "'#DDDDDD'" #group line background color
2552 COLOR4 = "\"#FFFFFF\"" #header/footer text color 2544 COLOR3 = "'#FFFFFF'" #player line background color
2553 PCOLOR = "\"#000000\"" #Player text color 2545 COLOR4 = "'#FFFFFF'" #header/footer text color
2554 LCOLOR = "\"#404040\"" #Lurker text color 2546 PCOLOR = "'#000000'" #Player text color
2555 GCOLOR = "\"#FF0000\"" #GM text color 2547 LCOLOR = "'#404040'" #Lurker text color
2556 SIZE = "size=\"-1\"" #player info text size 2548 GCOLOR = "'#FF0000'" #GM text color
2549 SIZE = "size='-1'" #player info text size
2557 FG = PCOLOR 2550 FG = PCOLOR
2558 2551
2559 "display a condensed list of players on the server" 2552 "display a condensed list of players on the server"
2560 self.p_lock.acquire() 2553 self.p_lock.acquire()
2561 pl = "<br /><table border=\"0\" cellpadding=\"1\" cellspacing=\"2\">" 2554 pl = "<br /><table border='0' cellpadding='1' cellspacing='2'>"
2562 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color=" + COLOR4 + ">" 2555 pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color='" + COLOR4 + "'>"
2563 pl += "<b>GROUP &amp; PLAYER LIST</b></font></td></tr>" 2556 pl += "<b>GROUP &amp; '' PLAYER LIST</b></font></td></tr>"
2564 try: 2557 try:
2565 keys = self.groups.keys() 2558 keys = self.groups.keys()
2566 keys.sort(id_compare) 2559 keys.sort(id_compare)
2567 for k in keys: 2560 for k in keys:
2568 groupstring = "<tr><td bgcolor=" + COLOR2 + " colspan='2'>" 2561 debug((self.groups, self.groups[k], self.groups[k].name))
2562 groupstring = "<tr><td bgcolor='" + COLOR2 + "' colspan='2'>"
2569 groutstring += "<b>Group " + str(k) + ": " + self.groups[k].name + "</b>" 2563 groutstring += "<b>Group " + str(k) + ": " + self.groups[k].name + "</b>"
2570 groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: \"" + self.groups[k].pwd + "\"</td>" 2564 groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: " + self.groups[k].pwd + "</td>"
2571 groupstring += "<td bgcolor=" + COLOR2 + " > Boot: \"" + self.groups[k].boot_pwd + "\"</i></td></tr>" 2565 groupstring += "<td bgcolor=" + COLOR2 + " > Boot: " + self.groups[k].boot_pwd + "</i></td></tr>"
2572 pl += groupstring 2566 pl += groupstring; debug(groupstring)
2573 ids = self.groups[k].get_player_ids() 2567 ids = self.groups[k].get_player_ids()
2574 ids.sort(id_compare) 2568 ids.sort(id_compare)
2575 for id in ids: 2569 for id in ids:
2576 if self.players.has_key(id): 2570 if self.players.has_key(id):
2577 if k != "0": 2571 if k != "0":