diff -Naur MoopO/bootstrap.txt Moop/bootstrap.txt
--- MoopO/bootstrap.txt 2001-03-08 19:04:55.000000000 -0800
+++ Moop/bootstrap.txt  2002-11-08 15:21:28.000000000 -0800
@@ -1,8 +1,8 @@
%# (c) 1999 - AccesSoft - See license.txt for details
-%$Id: bootstrap.txt,v 1.5 2001/03/09 03:04:55 jmacy Exp $
+%#$Id: bootstrap.txt,v 1.5 2001/03/09 03:04:55 jmacy Exp $

%# prepare our creative powers
-%transfer(None,me,10000)
+%transfer(None,me,1000000)
%me.accept = 1
%thing = getObj(1)
%thing.f = 1
@@ -564,7 +564,7 @@
# then add a list of room contents
for item in self.contents():
       if item!=looker:
-               desc = "%s\n    " % (desc, item.name)
+               desc = "%s\n    %s" % (desc, item.name)
return desc
.x
@set $dir.description.desc = "List name, desc, and contents"
diff -Naur MoopO/moop.py Moop/moop.py
--- MoopO/moop.py       2001-03-10 09:21:16.000000000 -0800
+++ Moop/moop.py        2002-11-08 23:38:40.000000000 -0800
@@ -13,10 +13,12 @@
import types
from types import StringType, InstanceType, ListType, TupleType, ModuleType, IntType
from tostr import tostr
-from time import time
+import time
import copy
import marksub
import msg
+import traceback
+import math
#from moopparse import HandleCommand, CmdDef
import moopparse

@@ -33,7 +35,7 @@
gUser = None        # object who invoked the current command
gCallers = [None]   # sort of a traceback list of calling objects
gUnpickling = 0     # set to 1 when unpickling
-gLastSave = time()  # time database was last saved
+gLastSave = time.time()  # time database was last saved
gFilePath = os.path.join(os.curdir, 'moopfiles') # path for user-accessible files
gTreasury = 100000  # credits for use by wizards

@@ -806,7 +808,7 @@
        elif type(parents) == InstanceType:
            parents = (parents,)
        elif type(parents) != TupleType:
-            raise "ParamError", "parents must be an object, list, or tuple"
+            raise "ParamError", "parents must be an object, list, or tuple -- parents were %s, type %s" % (str(parents), str(type(parents)))
        for p in parents:
            if type(p) != InstanceType or \
              (p.__class__ != Obj and p.__class__ != User and
@@ -885,7 +887,7 @@
            # the owner of the object owns the overridden property
            if prop.c: owner = self.owner
            else: owner = prop.owner
-            if gOwner != owner and not prop.w and not gOwner.wizard:
+            if gOwner and gOwner != owner and not prop.w and not gOwner.wizard:
                raise "PermError", "Can't modify "+propname
            np = Prop(owner,value)
            for k in ['r','w','c']:
@@ -968,7 +970,7 @@
            except:
                self.owner.tell("Error calling " + str(self) + ".update():")
                self.owner.handleErr(sys.exc_type, sys.exc_value, sys.exc_traceback)
-                if (time()%10 < 1):
+                if (time.time()%10 < 1):
                    self.__dict__['wantsUpdates'] = 0
                    self.owner.tell(str(self) + ".wantsUpdates has been set to 0")
                self.CheckUpdate()
@@ -1267,7 +1269,7 @@
        gLocals[self] = {'self':self, 'this':self, 'player':self,
                'caller':self, 'me':self, 'user':self, '__builtins__':None }
        self.__dict__['__outstream'] = stream
-        self.activeTime = self.loginTime = time()
+        self.activeTime = self.loginTime = time.time()
        self.CheckUpdate()
        prevOwner = gOwner
        try:
@@ -1322,7 +1324,7 @@
        #lines = map(lambda x:string.rstrip(x), lines)
        #self._inbuf = self._inbuf + lines
        self._inbuf = self._inbuf + [msg]
-        self.activeTime = time()
+        self.activeTime = time.time()

    #------------------------------------------------------------------
    # User METHOD: CheckUpdate
@@ -1398,6 +1400,10 @@
            self.__dict__['_editObj'] = object
            self.__dict__['_editProp'] = propname
            copyList(prop, self._editBuf)
+        elif type(prop) == StringType:
+            self.__dict__['_editObj'] = object
+            self.__dict__['_editProp'] = propname
+            self.__dict__['_editBuf'] = string.split(prop, '\n')
        else:
            try:
                raise "TypeError", "Can't edit "+ str(type(prop.val)) +" objects"
@@ -1425,6 +1431,43 @@
            except:
                pass
        gOwner = prevOwner
+
+    #------------------------------------------------------------------
+    # User METHOD: startInput
+    #------------------------------------------------------------------
+    def startInput(self, object, propname, prompt, postEdit=None):
+        """User METHOD: startInput(self, object, propname, prompt,
+                                   postEdit=None):
+        get a line from the user to replace the named object
+        property.  If present, postEdit should be a function which
+        will receive the object reference, property name, and a
+        'saved' parameter which will be 0 if the user aborted, 1
+        if user saved changes.  propname should refer to a string
+        property.  promp is a string for the prompt.
+        """
+
+        global gOwner
+        if gOwner and not gOwner.wizard and self.owner != gOwner:
+            raise "PermError", "Must be wizard or owner to startInput"
+        # check permissions...
+        # but don't apply C flag, since we're modifying it in place.
+        if not object.canWriteProp(propname, 0):
+            raise "PermError", "Can't modify property"
+        self.__dict__['_editBuf'] = []
+        prop = getattr(object, propname)
+        if prop is None:
+            raise "NotFoundError", "No property named " + propname
+        if type(prop) == StringType:
+            self.__dict__['_editObj'] = object
+            self.__dict__['_editProp'] = propname
+        else:
+            raise "TypeError", "Can't edit " + str(type(prop)) + "objects"
+        self.__dict__['_postEditFunc'] = postEdit
+        # set editor prompt
+        self.__dict__['_oldprompt'] = self._prompt
+        self.__dict__['_prompt'] = prompt
+        # Now, skip invoking the editor...
+        self.__dict__['_editState'] = 'SINGLE'

    #------------------------------------------------------------------
    # User METHOD: doEdit
@@ -1433,6 +1476,15 @@
        if gOwner and gOwner != self:
            raise "UseError", "doEdit() must only be called on oneself"

+        # Handle single-line edits:
+        if self._editState == 'SINGLE':
+            self._editBuf = msg
+            if msg == '':
+                self.endEdit(0)
+            else:
+                self.endEdit(1)
+            return
+
        # invoke the built-in editor, or the user's preferred one
        try:
            state = self.editor( self._editBuf, msg, self._editState )
@@ -1462,18 +1514,33 @@
        if not self._editObj:
            raise "Error", "endEdit() called while not editing!"
        if save:
-            setattr( self._editObj, self._editProp, tuple(self._editBuf) )
-        if self._postEditFunc:
-            try:
-                self._postEditFunc( self, self._editObj, self._editProp, save )
-            except:
-                self.tell( "Error calling post-edit function " \
-                        + str(self._postEditFunc) )
+            prop = getattr(self._editObj, self._editProp)
+            if type(prop) == StringType:
+                if type(self._editBuf) == StringType:
+                    setattr(self._editObj, self._editProp, self._editBuf)
+                else:
+                    setattr(self._editObj, self._editProp,
+                            string.join(self._editBuf, '\n'))
+            else:
+                setattr(self._editObj, self._editProp, tuple(self._editBuf))
+        # Needs to be this way so that _postEditFunc can reset
+        # _editObj if it wants to.  - DA
+        editObj = self._editObj
+        editProp = self._editProp
+        postEdit = self._postEditFunc
+
        self.__dict__['_editObj'] = None
        self.__dict__['_editProp'] = ''
        self.__dict__['_editBuf'] = []
        self.__dict__['_postEditFunc'] = None

+        if postEdit:
+            try:
+                postEdit(self, editObj, editProp, save)
+            except:
+                self.tell("Error calling post-edit function " + str(postEdit))
+                traceback.print_exc()
+
    #------------------------------------------------------------------
    # User METHOD: enterFunc
    #------------------------------------------------------------------
@@ -1920,9 +1987,12 @@
            del gObjlist[k]

    # remove from gUpdateList
-    for i in range(0,len(gUpdateList)):
+    i = 0
+    while i < len(gUpdateList):
        if gUpdateList[i] == object:
            del gUpdateList[i]
+        else:
+            i = i + 1

#----------------------------------------------------------------------
# FUNCTION: show
@@ -2011,7 +2081,7 @@
    file = open(filename, 'w')
    MoopPickler(file).dump((gObjlist,gProps,gContents,gCmdDefs,gTreasury))
    file.close()
-    gLastSave = time()
+    gLastSave = time.time()

#----------------------------------------------------------------------
# FUNCTION: gLoad
@@ -2057,7 +2127,7 @@
    for ob in gUpdateList:
        ob.DoUpdate()
    # consider saving the database
-    t = time() - gLastSave
+    t = time.time() - gLastSave
    if t > maxSaveTime:            # later: do more sophisticated checks here!
        gSave()

@@ -2114,7 +2184,6 @@

    import md5
    import imp
-    import time
    from qsplit import qsplit
    from whrandom import randint
    import moophelp
@@ -2141,17 +2210,19 @@
        'help':moophelp.help,
        'globalkeys':globalkeys,
        'marksub':marksub,
+        'math':math,
        'md5':md5,
        'move':move,
        'msg':msg,
        'Obj':Obj,
        'open':MOOPopen,
        'Prop':Prop,
+        'print_exc':traceback.print_exc,
        'randint':randint,
        'show':show,
        'string':string,
        'split':qsplit,
-        'time':time,
+        'time':time.time,
        'tostr':tostr,
        'treasury':treasury,
        'transfer':transfer,
diff -Naur MoopO/moopparse.py Moop/moopparse.py
--- MoopO/moopparse.py  2001-03-12 20:08:12.000000000 -0800
+++ Moop/moopparse.py   2002-11-09 00:21:28.000000000 -0800
@@ -115,6 +115,8 @@
            return 1
        if s[0] == '$':
            return 1
+        if s[0] == '[':
+            return 0
        if '.' in s:
            return 1
        if self.__findname(s) != None:
@@ -137,6 +139,8 @@
        if s[0] == '#' or s[0] == '$':
            ob = moop.getObj(s)
            return moop.getObj(s)
+        if s[0] == '[':
+            return None
        if '.' in s:
            parts = string.split(s,'.')
            regx = re.compile (s, re.IGNORECASE)
@@ -184,7 +188,6 @@
        return 1        # ANYTHING will work as a <val>

    def value(self,s,caller):
-
        # try it as a number
        try:
            return string.atoi(s)
@@ -213,7 +216,7 @@
            return map(lambda x,me=self,c=caller:me.value(x,c), listparts )

        # see if it's a quoted string
-        if s[0] == '"' or s[0] == "'":
+        if len(s) and (s[0] == '"' or s[0] == "'"):
            return QUALS['str'].value(s,caller)
        # none of the above?  pass it as a string (for now!)
        return s
@@ -449,7 +452,9 @@
def GatherObjNames(caller):
    global gObjNames

-    objlists = [caller.contents(), caller.location.contents()]
+    loccontents = caller.location.contents()[:]
+    loccontents.sort(lambda x, y: cmp(y.dead, x.dead))
+    objlists = [[caller.location], loccontents, caller.contents()]

    # first, stuff special words
    gObjNames = {
diff -Naur MoopO/moopsock.py Moop/moopsock.py
--- MoopO/moopsock.py   2001-03-12 19:33:57.000000000 -0800
+++ Moop/moopsock.py    2002-11-08 16:14:12.000000000 -0800
@@ -89,38 +89,38 @@
#    Returns 1 if host is banned, 0 if allowed
#
def CheckDomain(addr):
-        out = 0
-        # See if they are allowed
-        ad = string.splitfields(addr[0],'.')
-        for dh in Allowed:
-                print "Checking "+dh[0]+"."+dh[1]+"."+dh[2]+"."+dh[3]+"."
-                if dh[0] == '*': ad[0] = '*'
-                if dh[1] == '*': ad[1] = '*'
-                if dh[2] == '*': ad[2] = '*'
-                if dh[3] == '*': ad[3] = '*'
-                if ad == dh and out == 0:
-                        out = 0
-                        print " Allowed",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
-                elif not ad == dh:
-                        out = 1
-                        print "Not Allowed",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
-
-        # See if they are banned
-        ad = string.splitfields(addr[0],'.')
-        for dh in Banned:
-                print "Checking "+dh[0]+"."+dh[1]+"."+dh[2]+"."+dh[3]+"."
-                if dh[0] == '*': ad[0] = '*'
-                if dh[1] == '*': ad[1] = '*'
-                if dh[2] == '*': ad[2] = '*'
-                if dh[3] == '*': ad[3] = '*'
-                if not ad == dh and out == 0:
-                        out = 0
-                        print "Not Banned",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
-                elif ad == dh:
-                        out = 1
-                        print "Banned",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
-
-        return out
+    out = 0
+    # See if they are allowed
+    ad = string.splitfields(addr[0],'.')
+    for dh in Allowed:
+        print "Checking "+dh[0]+"."+dh[1]+"."+dh[2]+"."+dh[3]+"."
+        if dh[0] == '*': ad[0] = '*'
+        if dh[1] == '*': ad[1] = '*'
+        if dh[2] == '*': ad[2] = '*'
+        if dh[3] == '*': ad[3] = '*'
+        if ad == dh and out == 0:
+            out = 0
+            print " Allowed",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
+        elif not ad == dh:
+            out = 1
+            print "Not Allowed",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
+
+    # See if they are banned
+    ad = string.splitfields(addr[0],'.')
+    for dh in Banned:
+        print "Checking "+dh[0]+"."+dh[1]+"."+dh[2]+"."+dh[3]+"."
+        if dh[0] == '*': ad[0] = '*'
+        if dh[1] == '*': ad[1] = '*'
+        if dh[2] == '*': ad[2] = '*'
+        if dh[3] == '*': ad[3] = '*'
+        if not ad == dh and out == 0:
+            out = 0
+            print "Not Banned",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
+        elif ad == dh:
+            out = 1
+            print "Banned",ad[0]+"."+ad[1]+"."+ad[2]+"."+ad[3]+"."
+
+    return out

#----------------------------------------------------------------------
# function to start the server
@@ -324,8 +324,13 @@
                self.HandleLoginLine('guest')    # auto-password
            else:
                self.send('Password: ')
+                ATT = chr(27) + '['
+                self.send(ATT+'30m')
+                self.send(ATT+'40m')
            return
        if self.password == '':
+            ATT = chr(27) + '['
+            self.send(ATT+'0m')
            self.password = md5.new(msg).digest()
            # check to see if this matches some player
            mtch = filter(self.Matches, moop.gObjlist.values())