set location for quests

This commit is contained in:
Dave Schuyler 2005-06-09 04:00:28 +00:00
parent 383cfb4704
commit ddef13c674

View File

@ -1,357 +1,368 @@
#hack: #hack:
BAD_DO_ID = BAD_ZONE_ID = -1 BAD_DO_ID = BAD_ZONE_ID = -1
class DoCollectionManager: class DoCollectionManager:
def __init__(self): def __init__(self):
# Dict of {DistributedObject ids : DistributedObjects} # Dict of {DistributedObject ids : DistributedObjects}
self.doId2do = {} self.doId2do = {}
if wantOtpServer: if wantOtpServer:
# Dict of { # Dict of {
# parent DistributedObject id: # parent DistributedObject id:
# { zoneIds : [child DistributedObject ids] }} # { zoneIds : [child DistributedObject ids] }}
self.__doHierarchy = {} self.__doHierarchy = {}
def doFind(self, str): def doFind(self, str):
""" """
Returns list of distributed objects with matching str in value. Returns list of distributed objects with matching str in value.
""" """
for value in self.doId2do.values(): for value in self.doId2do.values():
if `value`.find(str) >= 0: if `value`.find(str) >= 0:
return value return value
def doFindAll(self, str): def doFindAll(self, str):
""" """
Returns list of distributed objects with matching str in value. Returns list of distributed objects with matching str in value.
""" """
matches = [] matches = []
for value in self.doId2do.values(): for value in self.doId2do.values():
if `value`.find(str) >= 0: if `value`.find(str) >= 0:
matches.append(value) matches.append(value)
return matches return matches
def getDoHierarchy(self): def getDoHierarchy(self):
return self.__doHierarchy return self.__doHierarchy
if __debug__: if __debug__:
def printObjects(self): def printObjects(self):
format="%10s %10s %10s %30s %20s" format="%10s %10s %10s %30s %20s"
title=format%("parentId", "zoneId", "doId", "dclass", "name") title=format%("parentId", "zoneId", "doId", "dclass", "name")
print title print title
print '-'*len(title) print '-'*len(title)
for distObj in self.doId2do.values(): for distObj in self.doId2do.values():
print format%( print format%(
distObj.__dict__.get("parentId"), distObj.__dict__.get("parentId"),
distObj.__dict__.get("zoneId"), distObj.__dict__.get("zoneId"),
distObj.__dict__.get("doId"), distObj.__dict__.get("doId"),
distObj.dclass.getName(), distObj.dclass.getName(),
distObj.__dict__.get("name")) distObj.__dict__.get("name"))
def getDoList(self, parentId, zoneId=None, classType=None): def getDoList(self, parentId, zoneId=None, classType=None):
""" """
parentId is any distributed object id. parentId is any distributed object id.
zoneId is a uint32, defaults to None (all zones). Try zone 2 if zoneId is a uint32, defaults to None (all zones). Try zone 2 if
you're not sure which zone to use (0 is a bad/null zone and you're not sure which zone to use (0 is a bad/null zone and
1 has had reserved use in the past as a no messages zone, while 1 has had reserved use in the past as a no messages zone, while
2 has traditionally been a global, uber, misc stuff zone). 2 has traditionally been a global, uber, misc stuff zone).
dclassType is a distributed class type filter, defaults dclassType is a distributed class type filter, defaults
to None (no filter). to None (no filter).
If dclassName is None then all objects in the zone are returned; If dclassName is None then all objects in the zone are returned;
otherwise the list is filtered to only include objects of that type. otherwise the list is filtered to only include objects of that type.
""" """
parent=self.__doHierarchy.get(parentId) parent=self.__doHierarchy.get(parentId)
if parent is None: if parent is None:
return [] return []
if zoneId is None: if zoneId is None:
r = [] r = []
for zone in parent.values(): for zone in parent.values():
for obj in zone: for obj in zone:
r.append(obj) r.append(obj)
else: else:
r = parent.get(zoneId, []) r = parent.get(zoneId, [])
if classType is not None: if classType is not None:
a = [] a = []
for obj in r: for obj in r:
if isinstance(obj, classType): if isinstance(obj, classType):
a.append(obj) a.append(obj)
r = a r = a
return r return r
def countObjects(self, classType): def countObjects(self, classType):
""" """
Counts the number of objects of the given type in the Counts the number of objects of the given type in the
repository (for testing purposes) repository (for testing purposes)
""" """
count = 0; count = 0;
for dobj in self.doId2do.values(): for dobj in self.doId2do.values():
if isinstance(dobj, classType): if isinstance(dobj, classType):
count += 1 count += 1
return count return count
def getAllOfType(self, type): def getAllOfType(self, type):
# Returns a list of all DistributedObjects in the repository # Returns a list of all DistributedObjects in the repository
# of a particular type. # of a particular type.
result = [] result = []
for obj in self.doId2do.values(): for obj in self.doId2do.values():
if isinstance(obj, type): if isinstance(obj, type):
result.append(obj) result.append(obj)
return result return result
def findAnyOfType(self, type): def findAnyOfType(self, type):
# Searches the repository for any object of the given type. # Searches the repository for any object of the given type.
for obj in self.doId2do.values(): for obj in self.doId2do.values():
if isinstance(obj, type): if isinstance(obj, type):
return obj return obj
return None return None
#---------------------------------- #----------------------------------
def deleteDistributedObjects(self): def deleteDistributedObjects(self):
# Get rid of all the distributed objects # Get rid of all the distributed objects
for doId in self.doId2do.keys(): for doId in self.doId2do.keys():
# Look up the object # Look up the object
do = self.doId2do[doId] do = self.doId2do[doId]
self.deleteDistObject(do) self.deleteDistObject(do)
# Get rid of everything that manages distributed objects # Get rid of everything that manages distributed objects
self.deleteObjects() self.deleteObjects()
# the zoneId2doIds table should be empty now # the zoneId2doIds table should be empty now
if len(self.zoneId2doIds) > 0: if len(self.zoneId2doIds) > 0:
AIRepository.notify.warning( AIRepository.notify.warning(
'zoneId2doIds table not empty: %s' % self.zoneId2doIds) 'zoneId2doIds table not empty: %s' % self.zoneId2doIds)
self.zoneId2doIds = {} self.zoneId2doIds = {}
if wantOtpServer: if wantOtpServer:
def handleObjectLocation(self, di): def handleObjectLocation(self, di):
# CLIENT_OBJECT_LOCATION # CLIENT_OBJECT_LOCATION
doId = di.getUint32() doId = di.getUint32()
parentId = di.getUint32() parentId = di.getUint32()
zoneId = di.getUint32() zoneId = di.getUint32()
obj = self.doId2do.get(doId) obj = self.doId2do.get(doId)
if obj is not None: if obj is not None:
self.notify.info( self.notify.info(
"handleObjectLocation: doId: %s parentId: %s zoneId: %s"% "handleObjectLocation: doId: %s parentId: %s zoneId: %s"%
(doId, parentId, zoneId)) (doId, parentId, zoneId))
# Let the object finish the job # Let the object finish the job
obj.setLocation(parentId, zoneId) obj.setLocation(parentId, zoneId)
self.storeObjectLocation(doId, parentId, zoneId) self.storeObjectLocation(doId, parentId, zoneId)
else: else:
self.notify.warning( self.notify.warning(
"handleObjectLocation: Asked to update non-existent obj: %s" % (doId)) "handleObjectLocation: Asked to update non-existent obj: %s" % (doId))
def storeObjectLocation(self, doId, parentId, zoneId): def handleSetLocation(self, di):
if (parentId is None) or (zoneId is None): # This was initially added because creating a distributed quest
# Do not store null values # object would cause a message like this to be generated.
return assert self.notify.debugStateCall(self)
# TODO: check current location parentId = di.getUint32()
obj = self.doId2do.get(doId) zoneId = di.getUint32()
oldParentId = obj.parentId distObj = self.doId2do.get(self.getMsgChannel())
oldZoneId = obj.zoneId if distObj is not None:
distObj.setLocation(parentId, zoneId)
if oldParentId != parentId:
# Remove old location def storeObjectLocation(self, doId, parentId, zoneId):
parentZoneDict = self.__doHierarchy.get(oldParentId) if (parentId is None) or (zoneId is None):
if parentZoneDict is not None: # Do not store null values
zoneDoSet = parentZoneDict.get(oldZoneId) return
if zoneDoSet is not None and doId in zoneDoSet: # TODO: check current location
zoneDoSet.remove(doId) obj = self.doId2do.get(doId)
if len(zoneDoSet) == 0: if obj is not None:
del parentZoneDict[oldZoneId] oldParentId = obj.parentId
# Add to new location oldZoneId = obj.zoneId
parentZoneDict = self.__doHierarchy.setdefault(parentId, {})
zoneDoSet = parentZoneDict.setdefault(zoneId, set()) if oldParentId != parentId:
zoneDoSet.add(doId) # Remove old location
parentZoneDict = self.__doHierarchy.get(oldParentId)
## if oldParentId == parentId: if parentZoneDict is not None:
## # Case 1: Same parent, new zone zoneDoSet = parentZoneDict.get(oldZoneId)
## parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) if zoneDoSet is not None and doId in zoneDoSet:
## # Remove this doId from the old zone list zoneDoSet.remove(doId)
## zoneDoSet = parentZoneDict.setdefault(oldZoneId, set()) if len(zoneDoSet) == 0:
## if doId in zoneDoSet: del parentZoneDict[oldZoneId]
## zoneDoSet.remove(doId) # Add to new location
## # Add it to the new zone list parentZoneDict = self.__doHierarchy.setdefault(parentId, {})
## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) zoneDoSet = parentZoneDict.setdefault(zoneId, set())
## zoneDoSet[doId] = None zoneDoSet.add(doId)
## ## if zoneDoSet is None:
## ## # No existing objList for this zone, let's make a new one ## if oldParentId == parentId:
## ## parentZoneDict[zoneId] = [doId] ## # Case 1: Same parent, new zone
## ## else: ## parentZoneDict = self.__doHierarchy.setdefault(parentId, {})
## ## # Just add this doId to the existing list ## # Remove this doId from the old zone list
## ## assert(doId not in objList) ## zoneDoSet = parentZoneDict.setdefault(oldZoneId, set())
## ## zoneDoSet.append(doId) ## if doId in zoneDoSet:
## else: ## zoneDoSet.remove(doId)
## # Case 2: New parent, valid old parent ## # Add it to the new zone list
## if (oldParentId is not None) and (oldZoneId is not None): ## zoneDoSet = parentZoneDict.setdefault(zoneId, {})
## # First delete the old location ## zoneDoSet[doId] = None
## self.deleteObjectLocation(doId, oldParentId, oldZoneId) ## ## if zoneDoSet is None:
## # Case 2: continued, already deleted from old location ## ## # No existing objList for this zone, let's make a new one
## # Case 3: New parent - no old parent ## ## parentZoneDict[zoneId] = [doId]
## parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) ## ## else:
## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) ## ## # Just add this doId to the existing list
## zoneDoSet[doId] = None ## ## assert(doId not in objList)
## ## if parentZoneDict is None: ## ## zoneDoSet.append(doId)
## ## # This parent is not here, just fill the whole entry in ## else:
## ## self.__doHierarchy[parentId] = {zoneId : {doId: None}} ## # Case 2: New parent, valid old parent
## ## else: ## if (oldParentId is not None) and (oldZoneId is not None):
## ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) ## # First delete the old location
## ## zoneDoSet[doId] = None ## self.deleteObjectLocation(doId, oldParentId, oldZoneId)
## ## objList = parentZoneDict.get(zoneId) ## # Case 2: continued, already deleted from old location
## ## if objList is None: ## # Case 3: New parent - no old parent
## ## # This parent has no objects in this zone before ## parentZoneDict = self.__doHierarchy.setdefault(parentId, {})
## ## # create a new entry for this zone and list this doId ## zoneDoSet = parentZoneDict.setdefault(zoneId, {})
## ## parentZoneDict[zoneId] = {doId: None} ## zoneDoSet[doId] = None
## ## else: ## ## if parentZoneDict is None:
## ## assert doId not in objList ## ## # This parent is not here, just fill the whole entry in
## ## # Just add this doId to the existing list ## ## self.__doHierarchy[parentId] = {zoneId : {doId: None}}
## ## objList[doId] = None ## ## else:
## ## zoneDoSet = parentZoneDict.setdefault(zoneId, {})
def deleteObjectLocation(self, objId, parentId, zoneId): ## ## zoneDoSet[doId] = None
# Do not worry about null values ## ## objList = parentZoneDict.get(zoneId)
if ((parentId is None) or (zoneId is None)): ## ## if objList is None:
return ## ## # This parent has no objects in this zone before
parentZoneDict = self.__doHierarchy.get(parentId) ## ## # create a new entry for this zone and list this doId
assert(parentZoneDict is not None, "deleteObjectLocation: parentId: %s not found" % (parentId)) ## ## parentZoneDict[zoneId] = {doId: None}
objList = parentZoneDict.get(zoneId) ## ## else:
assert(objList is not None, "deleteObjectLocation: zoneId: %s not found" % (zoneId)) ## ## assert doId not in objList
assert(objId in objList, "deleteObjectLocation: objId: %s not found" % (objId)) ## ## # Just add this doId to the existing list
if len(objList) == 1: ## ## objList[doId] = None
# If this is the last obj in this zone, delete the entire entry
del parentZoneDict[zoneId] def deleteObjectLocation(self, objId, parentId, zoneId):
else: # Do not worry about null values
# Just remove the object if ((parentId is None) or (zoneId is None)):
objList.remove(objId) return
parentZoneDict = self.__doHierarchy.get(parentId)
if wantOtpServer: assert(parentZoneDict is not None, "deleteObjectLocation: parentId: %s not found" % (parentId))
def addDOToTables(self, do, location=None): objList = parentZoneDict.get(zoneId)
assert self.notify.debugStateCall(self) assert(objList is not None, "deleteObjectLocation: zoneId: %s not found" % (zoneId))
if location is None: assert(objId in objList, "deleteObjectLocation: objId: %s not found" % (objId))
location = (do.parentId, do.zoneId) if len(objList) == 1:
# If this is the last obj in this zone, delete the entire entry
assert do.doId not in self.doId2do del parentZoneDict[zoneId]
self.doId2do[do.doId]=do else:
# Just remove the object
if location is not None: objList.remove(objId)
assert do.doId not in self.zoneId2doIds.get(location,{})
self.zoneId2doIds.setdefault(location, {}) if wantOtpServer:
self.zoneId2doIds[location][do.doId]=do def addDOToTables(self, do, location=None):
else: assert self.notify.debugStateCall(self)
# NON OTP if location is None:
def addDOToTables(self, do, zoneId=None): location = (do.parentId, do.zoneId)
assert self.notify.debugStateCall(self)
if zoneId is None: assert do.doId not in self.doId2do
zoneId = do.zoneId self.doId2do[do.doId]=do
assert do.doId not in self.doId2do if location is not None:
self.doId2do[do.doId]=do assert do.doId not in self.zoneId2doIds.get(location,{})
self.zoneId2doIds.setdefault(location, {})
if zoneId is not None: self.zoneId2doIds[location][do.doId]=do
assert do.doId not in self.zoneId2doIds.get(zoneId,{}) else:
self.zoneId2doIds.setdefault(zoneId, {}) # NON OTP
self.zoneId2doIds[zoneId][do.doId]=do def addDOToTables(self, do, zoneId=None):
assert self.notify.debugStateCall(self)
if wantOtpServer: if zoneId is None:
def removeDOFromTables(self, do): zoneId = do.zoneId
assert self.notify.debugStateCall(self)
assert do.doId in self.doId2do assert do.doId not in self.doId2do
location = do.getLocation() self.doId2do[do.doId]=do
if location is not None:
if location not in self.zoneId2doIds: if zoneId is not None:
AIRepository.notify.warning( assert do.doId not in self.zoneId2doIds.get(zoneId,{})
'dobj %s (%s) has invalid location: %s' % self.zoneId2doIds.setdefault(zoneId, {})
(do, do.doId, location)) self.zoneId2doIds[zoneId][do.doId]=do
else:
assert do.doId in self.zoneId2doIds[location] if wantOtpServer:
del(self.zoneId2doIds[location][do.doId]) def removeDOFromTables(self, do):
if len(self.zoneId2doIds[location]) == 0: assert self.notify.debugStateCall(self)
del self.zoneId2doIds[location] assert do.doId in self.doId2do
location = do.getLocation()
del(self.doId2do[do.doId]) if location is not None:
else: if location not in self.zoneId2doIds:
def removeDOFromTables(self, do): AIRepository.notify.warning(
assert self.notify.debugStateCall(self) 'dobj %s (%s) has invalid location: %s' %
assert do.doId in self.doId2do (do, do.doId, location))
if do.zoneId is not None: else:
if do.zoneId not in self.zoneId2doIds: assert do.doId in self.zoneId2doIds[location]
AIRepository.notify.warning( del(self.zoneId2doIds[location][do.doId])
'dobj %s (%s) has invalid zoneId: %s' % if len(self.zoneId2doIds[location]) == 0:
(do, do.doId, do.zoneId)) del self.zoneId2doIds[location]
else:
assert do.doId in self.zoneId2doIds[do.zoneId] del(self.doId2do[do.doId])
del(self.zoneId2doIds[do.zoneId][do.doId]) else:
if len(self.zoneId2doIds[do.zoneId]) == 0: def removeDOFromTables(self, do):
del self.zoneId2doIds[do.zoneId] assert self.notify.debugStateCall(self)
assert do.doId in self.doId2do
del(self.doId2do[do.doId]) if do.zoneId is not None:
if do.zoneId not in self.zoneId2doIds:
if wantOtpServer: AIRepository.notify.warning(
def changeDOZoneInTables(self, do, newParentId, newZoneId, oldParentId, oldZoneId): 'dobj %s (%s) has invalid zoneId: %s' %
oldLocation = (oldParentId, oldZoneId) (do, do.doId, do.zoneId))
newLocation = (newParentId, newZoneId) else:
# HACK: DistributedGuildMemberUD starts in -1,-1, which isnt ever put in the assert do.doId in self.zoneId2doIds[do.zoneId]
# zoneId2doIds table del(self.zoneId2doIds[do.zoneId][do.doId])
if oldLocation != (BAD_DO_ID, BAD_ZONE_ID): if len(self.zoneId2doIds[do.zoneId]) == 0:
assert self.notify.debugStateCall(self) del self.zoneId2doIds[do.zoneId]
assert oldLocation in self.zoneId2doIds
assert do.doId in self.zoneId2doIds[oldLocation] del(self.doId2do[do.doId])
assert do.doId not in self.zoneId2doIds.get(newLocation,{})
# remove from old zone if wantOtpServer:
del(self.zoneId2doIds[oldLocation][do.doId]) def changeDOZoneInTables(self, do, newParentId, newZoneId, oldParentId, oldZoneId):
if len(self.zoneId2doIds[oldLocation]) == 0: oldLocation = (oldParentId, oldZoneId)
del self.zoneId2doIds[oldLocation] newLocation = (newParentId, newZoneId)
# add to new zone # HACK: DistributedGuildMemberUD starts in -1,-1, which isnt ever put in the
self.zoneId2doIds.setdefault(newLocation, {}) # zoneId2doIds table
self.zoneId2doIds[newLocation][do.doId]=do if oldLocation != (BAD_DO_ID, BAD_ZONE_ID):
assert self.notify.debugStateCall(self)
def getObjectsInZone(self, location): assert oldLocation in self.zoneId2doIds
""" call this to get a dict of doId:distObj for a zone. assert do.doId in self.zoneId2doIds[oldLocation]
Creates a shallow copy, so you can do whatever you want with the assert do.doId not in self.zoneId2doIds.get(newLocation,{})
dict. """ # remove from old zone
assert self.notify.debugStateCall(self) del(self.zoneId2doIds[oldLocation][do.doId])
return copy.copy(self.zoneId2doIds.get(location, {})) if len(self.zoneId2doIds[oldLocation]) == 0:
del self.zoneId2doIds[oldLocation]
def getObjectsOfClassInZone(self, location, objClass): # add to new zone
""" returns dict of doId:object for a zone, containing all objects self.zoneId2doIds.setdefault(newLocation, {})
that inherit from 'class'. returned dict is safely mutable. """ self.zoneId2doIds[newLocation][do.doId]=do
assert self.notify.debugStateCall(self)
doDict = {} def getObjectsInZone(self, location):
for doId, do in self.zoneId2doIds.get(location, {}).items(): """ call this to get a dict of doId:distObj for a zone.
if isinstance(do, objClass): Creates a shallow copy, so you can do whatever you want with the
doDict[doId] = do dict. """
return doDict assert self.notify.debugStateCall(self)
return copy.copy(self.zoneId2doIds.get(location, {}))
else:
# NON OTP def getObjectsOfClassInZone(self, location, objClass):
""" returns dict of doId:object for a zone, containing all objects
def changeDOZoneInTables(self, do, newZoneId, oldZoneId): that inherit from 'class'. returned dict is safely mutable. """
##print "changeDOZoneInTables:%s, dclass:%s, newZoneId:%s OldZoneId:%s"%(do.doId, do.dclass.getName(), newZoneId,oldZoneId); assert self.notify.debugStateCall(self)
doDict = {}
assert self.notify.debugStateCall(self) for doId, do in self.zoneId2doIds.get(location, {}).items():
assert oldZoneId in self.zoneId2doIds if isinstance(do, objClass):
assert do.doId in self.zoneId2doIds[oldZoneId] doDict[doId] = do
assert do.doId not in self.zoneId2doIds.get(newZoneId,{}) return doDict
# remove from old zone
del(self.zoneId2doIds[oldZoneId][do.doId]) else:
if len(self.zoneId2doIds[oldZoneId]) == 0: # NON OTP
del self.zoneId2doIds[oldZoneId]
# add to new zone def changeDOZoneInTables(self, do, newZoneId, oldZoneId):
self.zoneId2doIds.setdefault(newZoneId, {}) ##print "changeDOZoneInTables:%s, dclass:%s, newZoneId:%s OldZoneId:%s"%(do.doId, do.dclass.getName(), newZoneId,oldZoneId);
self.zoneId2doIds[newZoneId][do.doId]=do
assert self.notify.debugStateCall(self)
def getObjectsInZone(self, zoneId): assert oldZoneId in self.zoneId2doIds
""" call this to get a dict of doId:distObj for a zone. assert do.doId in self.zoneId2doIds[oldZoneId]
Creates a shallow copy, so you can do whatever you want with the assert do.doId not in self.zoneId2doIds.get(newZoneId,{})
dict. """ # remove from old zone
assert self.notify.debugStateCall(self) del(self.zoneId2doIds[oldZoneId][do.doId])
return copy.copy(self.zoneId2doIds.get(zoneId, {})) if len(self.zoneId2doIds[oldZoneId]) == 0:
del self.zoneId2doIds[oldZoneId]
def getObjectsOfClassInZone(self, zoneId, objClass): # add to new zone
""" returns dict of doId:object for a zone, containing all objects self.zoneId2doIds.setdefault(newZoneId, {})
that inherit from 'class'. returned dict is safely mutable. """ self.zoneId2doIds[newZoneId][do.doId]=do
assert self.notify.debugStateCall(self)
doDict = {} def getObjectsInZone(self, zoneId):
for doId, do in self.zoneId2doIds.get(zoneId, {}).items(): """ call this to get a dict of doId:distObj for a zone.
if isinstance(do, objClass): Creates a shallow copy, so you can do whatever you want with the
doDict[doId] = do dict. """
return doDict assert self.notify.debugStateCall(self)
return copy.copy(self.zoneId2doIds.get(zoneId, {}))
def getObjectsOfClassInZone(self, zoneId, objClass):
""" returns dict of doId:object for a zone, containing all objects
that inherit from 'class'. returned dict is safely mutable. """
assert self.notify.debugStateCall(self)
doDict = {}
for doId, do in self.zoneId2doIds.get(zoneId, {}).items():
if isinstance(do, objClass):
doDict[doId] = do
return doDict