changeset 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 0f720618a8bd
children 43ad912b7c17
files orpg/chat/commands.py orpg/networking/gsclient.py orpg/networking/mplay_client.py orpg/networking/mplay_server.py orpg/networking/mplay_server_gui.py orpg/orpg_version.py orpg/tools/orpg_log.py
diffstat 7 files changed, 127 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/orpg/chat/commands.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/chat/commands.py	Tue Nov 03 00:52:47 2009 -0600
@@ -711,10 +711,7 @@
                 self.session.outbox.put(msg)
 
             else: self.chat.InfoPost("Unknown administrator command"  )
-            command_function = {
-            'banip': self.admin.r_admin_banip,
-            'createroom': self.r_admin_createroom,
-                                }
+            #command_function = {'banip': self.admin.r_admin_banip, 'createroom': self.r_admin_createroom,}
         except:
             self.chat.InfoPost("An error has occured while processing a Remote Administrator command!")
             traceback.print_exc()
--- a/orpg/networking/gsclient.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/networking/gsclient.py	Tue Nov 03 00:52:47 2009 -0600
@@ -84,7 +84,6 @@
     return 0
 
 class game_server_panel(wx.Panel):
-    ##debug()
     def __init__(self,parent):
         wx.Panel.__init__(self, parent, -1)
         self.parent = parent
--- a/orpg/networking/mplay_client.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/networking/mplay_client.py	Tue Nov 03 00:52:47 2009 -0600
@@ -194,7 +194,6 @@
     def sendMsg( self, sock, msg ):
         """Very simple function that will properly encode and send a message to te
         remote on the specified socket."""
-        #debug(log=False)
         if self.useCompression and self.compressionType != None:
             mpacket = self.compressionType.compress(msg)
             lpacket = pack('!i', len(mpacket))
@@ -218,7 +217,6 @@
         return sentm
 
     def recvData( self, sock, readSize ):
-        #debug(log=False)
         """Simple socket receive method.  This method will only return when the exact
         byte count has been read from the connection, if remote terminates our
         connection or we get some other socket exception."""
@@ -242,7 +240,6 @@
         return data
 
     def recvMsg(self, sock):
-        #debug()
         """This method now expects to receive a message having a 4-byte prefix length.  It will ONLY read completed messages.  In the event that the remote's connection is terminated, it will throw an exception which should allow for the caller to more gracefully handle this exception event.
 
         Because we use strictly reading ONLY based on the length that is told to use, we no longer have to worry about partially adjusting for fragmented buffers starting somewhere within a buffer that we've read.  Rather, it will get ONLY a whole message and nothing more.  Everything else will remain buffered with the OS until we attempt to read the next complete message."""
@@ -260,7 +257,6 @@
         return msgData
 
     def initialize_threads(self):
-        #debug()
         "Starts up our threads (2) and waits for them to make sure they are running!"
         self.status = MPLAY_CONNECTED
         self.sock.setblocking(1)
@@ -270,7 +266,7 @@
         self.startedEvent.set()
 
     def disconnect(self):
-        #debug()
+        debug()
         self.set_status(MPLAY_DISCONNECTING)
         self.log_msg("client stub " + self.ip +" disconnecting...")
         self.log_msg("closing sockets...")
@@ -282,18 +278,15 @@
         self.set_status(MPLAY_DISCONNECTED)
 
     def reset(self,sock):
-        #debug()
         self.disconnect()
         self.sock = sock
         self.initialize_threads()
 
     def update_role(self,role):
-        #debug()
         self.useroles = 1
         self.role = role
 
     def use_roles(self):
-        #debug()
         if self.useroles: return 1
         else: return 0
     def update_self_from_player(self, player):
@@ -307,7 +300,6 @@
      client provided IP address to have much value.  As such, we now label it as deprecated.
     """
     def toxml(self, action):
-        #debug((myescape(self.name), self.name, self.role))
         el = Element('player')
         el.set('name', self.name)
         el.set('action', action)
@@ -329,22 +321,19 @@
         return tostring(el)
 
     def log_msg(self,msg):
-        #debug(msg, log=False)
+        debug(msg, log=False)
         if self.log_console: self.log_console(msg)
 
     def get_status(self):
-        #debug(log=False)
         self.statLock.acquire()
         status = self.status
         self.statLock.release()
         return status
 
     def my_role(self):
-        #debug(self.role, log=False)
         return self.role
 
     def set_status(self,status):
-        #debug(status, log=False)
         self.statLock.acquire()
         self.status = status
         self.statLock.release()
@@ -398,10 +387,8 @@
 #
 #========================================================================
 class mplay_client(client_base):
-    #debug()
     "mplay client"
     def __init__(self,name,callbacks):
-        #debug(name)
         client_base.__init__(self)
         component.add('mp_client', self)
         self.xml = component.get('xml')
@@ -431,16 +418,13 @@
         return 0
 
     def get_chat(self):
-        #debug()
         return self.orpgFrame_callback.chat
 
     def set_name(self,name):
-        #debug(name)
         self.name =  name
         self.update()
 
     def set_text_status(self, status):
-        #debug()
         if self.text_status != status:
             self.text_status = status
             self.update()
@@ -584,8 +568,8 @@
                 oldloc = loc+1
         el = Element('alter')
         el.set('key', 'pwd')
-        el.set('val', npwd)
-        el.set('bpw', pwd)
+        #el.set('val', npwd)
+        el.set('bpw', str(pwd))
         el.set('plr', self.id)
         el.set('gid', self.group_id)
         self.outbox.put(tostring(el))
@@ -603,7 +587,6 @@
         self.outbox.put(tostring(el))
 
     def get_role(self):
-        #debug((self.group_id, self.id, self.role))
         el = Element('role')
         el.set('action', 'get')
         el.set('player', self.id)
@@ -611,7 +594,6 @@
         self.outbox.put(tostring(el))
 
     def set_role(self, player, role, pwd=""):
-        #debug(role)
         el = Element('role')
         el.set('action', 'set')
         el.set('player', player)
@@ -698,7 +680,13 @@
             end = data.find(">")
             head = data[:end+1]
             msg = data[end+1:]
-            el = fromstring(head)
+            ### Alpha ###
+            if head[end:] != '/':
+                if head[end:] != '>': head = head[:end] + '/>' 
+            ### This if statement should help close invalid messages.  Since it needs fixing, use the try except message for now.
+            try: el = fromstring(head)
+            except: el = fromstring(head[:end] +'/>')
+
             try:
                 el1 = fromstring(msg)
                 el.append(el1)
--- a/orpg/networking/mplay_server.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/networking/mplay_server.py	Tue Nov 03 00:52:47 2009 -0600
@@ -103,7 +103,6 @@
         self.game_map.init_from_xml(fromstring(tree))
 
     def save_map(self):
-        #debug(log=False)
         if self.mapFile is not None and self.persistant == 1 and self.mapFile.find("default_map.xml") == -1:
             f = open(self.mapFile, "w")
             f.write(self.game_map.get_all_xml())
@@ -156,7 +155,7 @@
         return tostring(el)
 
 class client_stub(client_base):
-    def __init__(self,inbox,sock,props,log):
+    def __init__(self, inbox, sock, props, log):
         client_base.__init__(self)
         self.ip = props['ip']
         self.role = props['role']
@@ -225,7 +224,6 @@
 """
 
 class mplay_server:
-    #debug(log=False)
     def __init__(self, log_console=None, name=None):
         logger._set_log_level = 16
         logger._set_log_to_console(True)
@@ -264,7 +262,6 @@
         self.lobbySound = 'http://www.digitalxero.net/music/mus_tavern1.bmu' ##used?
 
     def initServer(self, **kwargs):
-        #debug(log=False)
         for atter, value in kwargs.iteritems(): setattr(self, atter, value)
         validate.config_file( self.lobbyMapFile, "default_Lobby_map.xml" )
         validate.config_file( self.lobbyMessageFile, "default_LobbyMessage.html" )
@@ -358,7 +355,7 @@
     # as needed, over-riding any default values as requested.
 
     def initServerConfig(self):
-        #debug(log=False)
+        debug(log=False)
         self.log_msg("Processing Server Configuration File... " + self.userPath)
         # make sure the server_ini.xml exists!
         validate.config_file( "server_ini.xml", "default_server_ini.xml" )
@@ -657,23 +654,19 @@
         return name
 
     def registerRooms(self, args=None):
-        #debug()
         rooms = ''
         id = '0'
         time.sleep(500)
-        #debug(self.groups)
         for rnum in self.groups.keys():
             rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][name]":self.groups[rnum].name,
                                         "room_data[rooms][" + str(rnum) + "][pwd]":str(self.groups[rnum].pwd != "")})+'&'
             for pid in self.groups[rnum].players:
                 rooms += urllib.urlencode( {"room_data[rooms][" + str(rnum) + "][players]["+str(pid)+"]":self.players[pid].name,})+'&'
-        #debug(rooms)
         for meta in self.metas.keys():
             while id == '0':
                 id, cookie = self.metas[meta].getIdAndCookie()
                 data = urllib.urlencode( {"room_data[server_id]":id,
                                         "act":'registerrooms'})
-            #debug((data, rooms))
             get_server_dom(data+'&'+rooms, self.metas[meta].path, string=True)
 
     def register(self,name_given=None):
@@ -867,6 +860,7 @@
         self.log_msg("Server stopped!")
 
     def log_msg(self,msg):
+        debug(parents=True)
         if self.log_to_console:
             if self.log_console: self.log_console(msg)
             else: print str(msg)
@@ -1256,7 +1250,6 @@
         return 1
 
     def SendLobbyMessage(self, socket, player_id):
-        #debug(log=False)
         """
         #  Display the lobby message
         #  prepend this server's version string to the the lobby message
@@ -1328,7 +1321,6 @@
         self.listen_event.set()
 
     def acceptedNewConnectionThread( self, newsock, addr ):
-        #debug(log=False)
         """Once a new connection comes in and is accepted, this thread starts up to handle it."""
         # Initialize xml_dom
         xml_dom = None
@@ -1409,7 +1401,6 @@
     """
 
     def message_handler(self, arg):
-        #debug(log=False)
         xml_dom = None
         self.log_msg( "message handler thread running..." )
         while self.alive:
@@ -1434,7 +1425,8 @@
         self.log_msg("message handler thread exiting...")
         self.incoming_event.set()
 
-    def parse_incoming_dom(self,data):
+    def parse_incoming_dom(self, data):
+        #debug((data, tostring(data) if iselement(data) else 'None element'))  Sometimes I catch an error.
         end = data.find(">") #locate end of first element of message
         head = data[:end+1]
         #self.log_msg(head)
@@ -1457,11 +1449,11 @@
         return
 
     def do_alter(self, xml_dom, data):
-        target = xml_dom.get("key")
-        value = xml_dom.get("val")
-        player = xml_dom.get("plr")
-        group_id = xml_dom.get("gid")
-        boot_pwd = xml_dom.get("bpw")
+        target = xml_dom.get("key") or 'None'
+        value = xml_dom.get("val") or 'None'
+        player = xml_dom.get("plr") or 'None'
+        group_id = xml_dom.get("gid") or 'None'
+        boot_pwd = xml_dom.get("bpw") or 'None'
         actual_boot_pwd = self.groups[group_id].boot_pwd
 
         if self.allow_room_passwords == 0:
@@ -1480,7 +1472,7 @@
             elif target == "name":
                 # Check for & in name.  We want to allow this because of its common
                 # use in d&d games
-                result = self.change_group_name(group_id,value,player)
+                result = self.change_group_name(group_id, value, player)
                 msg ="<msg to='" + player + "' from='0' group_id='0' />" + result
                 self.players[player].outbox.put(msg)
         else:
@@ -1573,7 +1565,6 @@
 
             if not self.groups[group_id].check_pwd(pwd):
                 allowed = 0
-
                 #tell the clients password manager the password failed -- SD 8/03
                 pm = "<password signal='fail' type='room' id='" +  group_id  + "' data=''/>"
                 self.players[from_id].outbox.put(pm)
@@ -1611,9 +1602,9 @@
                 print "exception in move_player() "
                 traceback.print_exc()
 
-            old_group_id = self.players[from_id].change_group(group_id,self.groups)
-            self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del'))
-            self.send_to_group(from_id,group_id,self.players[from_id].toxml('new'))
+            old_group_id = self.players[from_id].change_group(group_id, self.groups)
+            self.send_to_group(from_id, old_group_id, self.players[from_id].toxml('del'))
+            self.send_to_group(from_id, group_id, self.players[from_id].toxml('new'))
             self.check_group(from_id, old_group_id)
 
             """
@@ -1669,7 +1660,7 @@
     # conditions written all over them.  Ack! Ack!
     """
     def new_group( self, name, pwd, boot, minVersion, mapFile, messageFile, persist = 0, moderated=0 ):
-        group_id = str( self.next_group_id )
+        group_id = str(self.next_group_id)
         self.next_group_id += 1
         self.groups[group_id] = game_group( group_id, name, pwd, "", boot, minVersion, mapFile, messageFile, persist )
         self.groups[group_id].moderated = moderated
@@ -1677,9 +1668,9 @@
         if persist !=0: ins="Persistant "
         lmsg = "Creating " + ins + "Group... (" + str(group_id) + ") " + str(name)
         self.log_msg( lmsg )
-        self.log_msg(("create_group", (str(name), int(group_id), 0) )) ##-99 works, could be better.
+        self.log_msg(("create_group", (str(name), int(group_id), pwd, 0) ))
 
-    def change_group_name(self,gid,name,pid):
+    def change_group_name(self, gid, name, pid):
         "Change the name of a group"
         # Check for & in name.  We want to allow this because of its common
         # use in d&d games.
@@ -1715,6 +1706,8 @@
             self.groups[gid].name = str(name)
             lmessage = "Room name changed to from \"" + oldroomname + "\" to \"" + name + "\""
             self.log_msg(lmessage  + " by " + str(pid) )
+            self.log_msg(("update_group", (str(name), group_id, False)))
+
             self.send_to_all('0',self.groups[gid].toxml('update'))
             return lmessage
         except: return "An error occured during rename of room!"
@@ -1765,20 +1758,21 @@
                 oldloc = loc+1
         group_id = str(self.next_group_id)
         self.next_group_id += 1
+
         self.groups[group_id] = game_group(group_id, name, pwd, "", boot_pwd, minVersion, None, messageFile)
         self.groups[group_id].voice[from_id]=1
         self.players[from_id].outbox.put(self.groups[group_id].toxml('new'))
-        old_group_id = self.players[from_id].change_group(group_id,self.groups)
-        self.send_to_group(from_id,old_group_id,self.players[from_id].toxml('del'))
+        old_group_id = self.players[from_id].change_group(group_id, self.groups)
+        self.send_to_group(from_id, old_group_id, self.players[from_id].toxml('del'))
         self.check_group(from_id, old_group_id)
         self.send_to_all(from_id,self.groups[group_id].toxml('new'))
         self.send_to_all('0',self.groups[group_id].toxml('update'))
-        self.handle_role("set",from_id,"GM",boot_pwd, group_id)
+        self.handle_role("set",from_id,"GM", boot_pwd, group_id)
         lmsg = "Creating Group... (" + str(group_id) + ") " + str(name)
         self.log_msg( lmsg )
         jmsg = "moving to room " + str(group_id) + "."
         self.log_msg( jmsg )
-        self.log_msg(("create_group", (str(name), group_id, from_id)))
+        self.log_msg(("create_group", (str(name), group_id, from_id, 'No' if pwd == '' else 'Yes')))
         #even creators of the room should see the HTML --akoman
         #edit: jan10/03 - was placed in the except statement. Silly me.
         if self.defaultMessageFile != None:
@@ -1805,10 +1799,8 @@
                 del self.groups[group_id]
                 self.log_msg(("delete_group", (group_id, from_id)))
             else: self.send_to_all("0",self.groups[group_id].toxml('update'))
-
             #The register Rooms thread
             thread.start_new_thread(self.registerRooms,(0,))
-
         except Exception, e: self.log_msg(str(e))
 
     def del_player(self, id, group_id):
@@ -2546,30 +2538,32 @@
     #  in chat window on remote client
     """
     def player_list_remote(self):
-        COLOR1 = "\"#004080\""  #header/footer background color
-        COLOR2 = "\"#DDDDDD\""  #group line background color
-        COLOR3 = "\"#FFFFFF\""  #player line background color
-        COLOR4 = "\"#FFFFFF\""  #header/footer text color
-        PCOLOR = "\"#000000\""  #Player text color
-        LCOLOR = "\"#404040\""  #Lurker text color
-        GCOLOR = "\"#FF0000\""  #GM text color
-        SIZE   = "size=\"-1\""  #player info text size
+        """Does not work!!!""" # TaS.
+        COLOR1 = "'#004080'"  #header/footer background color
+        COLOR2 = "'#DDDDDD'"  #group line background color
+        COLOR3 = "'#FFFFFF'"  #player line background color
+        COLOR4 = "'#FFFFFF'"  #header/footer text color
+        PCOLOR = "'#000000'"  #Player text color
+        LCOLOR = "'#404040'"  #Lurker text color
+        GCOLOR = "'#FF0000'"  #GM text color
+        SIZE   = "size='-1'"  #player info text size
         FG = PCOLOR
 
         "display a condensed list of players on the server"
         self.p_lock.acquire()
-        pl = "<br /><table border=\"0\" cellpadding=\"1\" cellspacing=\"2\">"
-        pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color=" + COLOR4 + ">"
-        pl += "<b>GROUP &amp; PLAYER LIST</b></font></td></tr>"
+        pl = "<br /><table border='0' cellpadding='1' cellspacing='2'>"
+        pl += "<tr><td colspan='4' bgcolor=" + COLOR1 + "><font color='" + COLOR4 + "'>"
+        pl += "<b>GROUP &amp; '' PLAYER LIST</b></font></td></tr>"
         try:
             keys = self.groups.keys()
             keys.sort(id_compare)
             for k in keys:
-                groupstring = "<tr><td bgcolor=" + COLOR2 + " colspan='2'>"
+                debug((self.groups, self.groups[k], self.groups[k].name))
+                groupstring = "<tr><td bgcolor='" + COLOR2 + "' colspan='2'>"
                 groutstring += "<b>Group " + str(k)  + ": " +  self.groups[k].name  + "</b>"
-                groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: \"" + self.groups[k].pwd + "\"</td>"
-                groupstring += "<td bgcolor=" + COLOR2 + " > Boot: \"" + self.groups[k].boot_pwd + "\"</i></td></tr>"
-                pl += groupstring
+                groupstring += "</td><td bgcolor=" + COLOR2 + " > <i>Password: " + self.groups[k].pwd + "</td>"
+                groupstring += "<td bgcolor=" + COLOR2 + " > Boot: " + self.groups[k].boot_pwd + "</i></td></tr>"
+                pl += groupstring; debug(groupstring)
                 ids = self.groups[k].get_player_ids()
                 ids.sort(id_compare)
                 for id in ids:
--- a/orpg/networking/mplay_server_gui.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/networking/mplay_server_gui.py	Tue Nov 03 00:52:47 2009 -0600
@@ -12,13 +12,15 @@
 import os, sys, time, types
 
 from orpg.dirpath import dir_struct
-#import orpg.systempath looks old
 from orpg.tools.validate import validate
 from orpg.orpg_wx import *
+from threading import Thread
+
 import webbrowser
-from threading import Thread
+
 from meta_server_lib import post_server_data, remove_server
 from mplay_server import mplay_server, server
+
 from xml.dom import minidom
 from orpg.orpgCore import component
 from orpg.tools.orpg_log import debug
@@ -95,7 +97,7 @@
 
 # ServerConfig Object ############################
 class ServerConfig:
-    debug(log=False)
+    #debug(log=False)
     """ This class contains configuration
         setting used to control the server."""
 
@@ -103,7 +105,7 @@
         """ Loads default configuration settings."""
         validate.config_file("server_ini.xml", "default_server_ini.xml")
         config_xml = parse(dir_struct['user'] + 'server_ini.xml')
-        debug(config_xml, log=False)
+        #debug(config_xml, log=False)
         configDom = minidom.parse(dir_struct["user"] + 'server_ini.xml') 
         port = configDom.childNodes[0].childNodes[1].getAttribute('port')
         OPENRPG_PORT = 6774 if port == '' else int(port) #Pretty ugly, but I couldn't find the tag any other way.
@@ -122,7 +124,6 @@
 # Server Monitor #################################
 
 class ServerMonitor(Thread):
-    debug(log=False)
     """ Monitor thread for GameServer. """
     def __init__(self, cb, conf, name, pwd):
         """ Setup the server. """
@@ -133,7 +134,7 @@
         self.bootPwd = pwd
 
     def log(self, mesg):
-        debug(log=False)
+        #debug(log=False)
         if type(mesg) == types.TupleType:
             func, msg = mesg
             event = MessageFunctionEvent( func, msg )
@@ -142,7 +143,7 @@
         del event
 
     def run(self):
-        debug(log=False)
+        #debug(log=False)
         """ Start the server. """
         self.server = mplay_server(self.log, self.serverName )
         self.server.initServer(bootPassword=self.bootPwd, reg="No")
@@ -150,7 +151,7 @@
         while self.alive: time.sleep(3)
 
     def stop(self):
-        debug(log=False)
+        #debug(log=False)
         """ Stop the server. """
         self.server.kill_server()
         self.alive = 0
@@ -158,6 +159,45 @@
 # GUI Server #####################################
 # Parent = notebook
 # Main = GUI
+class Groups(wx.ListCtrl):
+    def __init__(self, parent, main):
+        wx.ListCtrl.__init__(self, parent, -1, wx.DefaultPosition,
+                            wx.DefaultSize, wx.LC_REPORT|wx.SUNKEN_BORDER|wx.EXPAND|wx.LC_HRULES)
+        self.main = main
+
+        """Not completed.  Creates room, delets rooms.  Does not track players.  Nor does gsclient, ftm."""
+
+        ### Alpha ### Get Lobby Name # Moving to etree.
+        validate.config_file("server_ini.xml", "default_server_ini.xml" ) 
+        configDom = minidom.parse(dir_struct["user"] + 'server_ini.xml') 
+        lobbyname = configDom.childNodes[0].getAttribute('lobbyname')
+        #############
+        self.roomList = { 0 : lobbyname }
+
+        self.InsertColumn(0, 'Group ID')
+        self.InsertColumn(1, 'Game')
+        self.InsertColumn(2, 'Players')
+        self.InsertColumn(3, 'Passworded')
+        self.AddGroup((self.roomList[0], '0', 'Need to Find', 'No'))
+
+    def AddGroup(self, data):
+        (room, room_id, players, passworded) = data
+        i = self.InsertStringItem(0, str(room_id))
+        self.SetStringItem(i, 1, room)
+        self.SetStringItem(i, 2, players)
+        self.SetStringItem(i, 3, str(passworded))
+
+    def DeleteGroup(self, data):
+        i = self.FindItem(-1, str(data))
+        self.DeleteItem(i)        
+
+    def UpdateRoom(self, data):
+        (room, room_id, players) = data
+        i = self.FindItem( -1, str(room_id))
+        self.SetStringItem( i, 1, room )
+        if players: self.SetStringItem(i, 2, players)
+        ### Need to add room for Password Updates ###
+
 class Connections(wx.ListCtrl):
     def __init__( self, parent, main ):
         wx.ListCtrl.__init__( self, parent, -1, wx.DefaultPosition, 
@@ -241,16 +281,13 @@
         self.Refresh()
 
     def colorize_player_list(self, player):
-        debug(player, log=False)
         if player == 0: return
         for m in player.keys():
             id = player['id']
             item_list_location = self.FindItemData(-1, int(id))
             if item_list_location == -1: continue
             item = self.GetItem(item_list_location)
-            debug(item_list_location, log=False)
             role = player['role']
-            debug(role, log=False)
             try: #Players that turn up Blue are not passing the correct arguments.
                 try: 
                     if player['group_id'] != "0": item.SetTextColour(settings.get_setting(role + "RoleColor"))
@@ -261,7 +298,6 @@
             self.SetItem(item)
 
     def update(self, player):
-        debug(player, log=False)
         #try: int(player); i = self.FindItemData( -1, int(player) )
         i = self.FindItemData( -1, int(player["id"]) )
         if i > -1:
@@ -396,6 +432,7 @@
         cb["create_group"] = self.OnCreateGroup
         cb["delete_group"] = self.OnDeleteGroup
         cb["join_group"] = self.OnJoinGroup
+        cb['update_group'] = self.OnUpdateGroup
         cb["role"] = self.OnSetRole
         self.callbacks = cb
 
@@ -458,8 +495,10 @@
         """ Create the ViewNotebook and logger. """
         splitter = wx.SplitterWindow(self, -1, style=wx.NO_3D | wx.SP_3D)
         nb = wx.Notebook( splitter, -1 )
-        self.conns = Connections( nb, self )
-        nb.AddPage( self.conns, "Players" )
+        self.conns = Connections(nb, self)
+        self.groups = Groups(nb, self)
+        nb.AddPage(self.conns, "Players")
+        nb.AddPage(self.groups, 'Rooms')
 
         #Not sure why this is Remarked TaS - Sirebral
         #nb.AddPage( self.conns, "Rooms" )
@@ -501,7 +540,6 @@
 
     # Event handler for out logging event
     def OnFunctionMessage(self, event):
-        debug(log=False)
         self.callbacks[event.func]( event.message )
 
     ### Server Callbacks #####################################
@@ -528,22 +566,28 @@
         self.sb.SetStatusText("Recv: %s (%d)" % (format_bytes(self.total_data_received), self.total_messages_received), 2)
 
     def OnCreateGroup( self, data ):
-        room_id = data[1]
-        name = data[0]
+        (room, room_id, player, pwd) = data
+        self.groups.AddGroup(data)
         self.conns.roomList[room_id] = name
-        (room, room_id, player) = data
+        data = (room, room_id, player)
         self.conns.updateRoom(data)
 
     def OnDeleteGroup(self, data):
         (room_id, player) = data
+        self.groups.DeleteGroup(room_id)
         del self.conns.roomList[room_id]
 
     def OnJoinGroup(self, data):
-        self.conns.updateRoom(data )
+        #debug(data)
+        self.conns.updateRoom(data)
+
+    def OnUpdateGroup(self, data):
+        (room, room_id, players) = data
+        self.groups.UpdateGroup(data)
 
     def OnSetRole( self, data ):
         (id, role) = data
-        self.conns.setPlayerRole( id, role )
+        self.conns.setPlayerRole(id, role)
 
     ### Misc. ################################################
     def OnStart(self, event = None):
@@ -651,7 +695,13 @@
     def ConfigPingInterval( self, event = None ):
         "Configure the player ping interval.  Note that all players are pinged on a single timer."
 
-    def OnExit(self, event = None):
+    def OnExit(self, event):
+        dlg = wx.MessageDialog(self, "Exit the Server?", "OpenRPG- Server", wx.YES_NO)
+        if dlg.ShowModal() == wx.ID_YES:
+            dlg.Destroy()
+            self.ExitConfirmed()
+
+    def ExitConfirmed(self, event=None):
         """ Quit the program. """
         self.OnStop()
         self.BanListDialog.Destroy() ### Alpha ###
--- a/orpg/orpg_version.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/orpg_version.py	Tue Nov 03 00:52:47 2009 -0600
@@ -4,7 +4,7 @@
 #BUILD NUMBER FORMAT: "YYMMDD-##" where ## is the incremental daily build index (if needed)
 DISTRO = "Traipse Alpha"
 DIS_VER = "Ornery Orc"
-BUILD = "091002-01"
+BUILD = "091003-00"
 
 # This version is for network capability.
 PROTOCOL_VERSION = "1.2"
--- a/orpg/tools/orpg_log.py	Mon Nov 02 19:20:46 2009 -0600
+++ b/orpg/tools/orpg_log.py	Tue Nov 03 00:52:47 2009 -0600
@@ -81,7 +81,7 @@
         #if locale == 'all': print inspect.getouterframes(current)[4]; return
         if objects != None: debug_string += ' Objects: ' + str(objects)
         if locale: debug_string += ' File: ' + str(inspect.getouterframes(current)[1][1])
-        logger.debug(debug_string)
+        logger.debug(debug_string, True)
         return
 
     def get_parents(self, current):
@@ -89,7 +89,7 @@
         family = list(inspect.getouterframes(current))
         for parent in family:
             debug_string += ' ' + str(parent[4])
-        logger(debug_string)
+        logger.debug(debug_string, True)
         return
     
 class DebugConsole(wx.Frame):