mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
OTPServer: client gets zone changes
This commit is contained in:
parent
ec6fab321c
commit
506fe267ba
@ -22,8 +22,12 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
self.setClientDatagram(1)
|
||||
|
||||
self.recorder = base.recorder
|
||||
|
||||
self.doId2do={}
|
||||
|
||||
# Dict of {DistributedObject ids : DistributedObjects}
|
||||
self.doId2do = {}
|
||||
if wantOtpServer:
|
||||
# Dict of {parent DistributedObject id : {zoneIds : [child DistributedObject ids]}}
|
||||
self.__doHierarchy = {}
|
||||
self.readDCFile()
|
||||
self.cache=CRCache.CRCache()
|
||||
self.serverDelta = 0
|
||||
@ -138,52 +142,132 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
it should be accurate plus or minus a couple of seconds.
|
||||
"""
|
||||
return time.time() + self.serverDelta
|
||||
|
||||
def handleObjectLocation(self, di):
|
||||
# CLEINT_OBJECT_LOCATION
|
||||
ThedoId = di.getUint32()
|
||||
TheParent = di.getUint32()
|
||||
TheZone = di.getUint32()
|
||||
print "Object Location->Id=%s Parent=%s Zone=%s"%(ThedoId,TheParent, TheZone)
|
||||
|
||||
|
||||
if wantOtpServer:
|
||||
def handleObjectLocation(self, di):
|
||||
# CLIENT_OBJECT_LOCATION
|
||||
doId = di.getUint32()
|
||||
parentId = di.getUint32()
|
||||
zoneId = di.getUint32()
|
||||
obj = self.doId2do.get(doId)
|
||||
if (obj != None):
|
||||
self.notify.info("handleObjectLocation: doId: %s parentId: %s zoneId: %s" %
|
||||
(doId, parentId, zoneId))
|
||||
# Let the object finish the job
|
||||
obj.setLocation(parentId, zoneId)
|
||||
else:
|
||||
ClientRepository.notify.warning(
|
||||
"handleObjectLocation: Asked to update non-existent obj: %s" % (doId))
|
||||
|
||||
def storeObjectLocation(self, objId, parentId, zoneId):
|
||||
# Do not store null values
|
||||
if ((parentId is None) or (zoneId is None)):
|
||||
return
|
||||
|
||||
# TODO: check current location
|
||||
obj = self.doId2do.get(objId)
|
||||
oldParentId, oldZoneId = obj.getLocation()
|
||||
|
||||
# Case 1: Same parent, new zone
|
||||
if (oldParentId == parentId):
|
||||
parentZoneDict = self.__doHierarchy.get(parentId)
|
||||
# Remove this objId from the old zone list
|
||||
oldObjList = parentZoneDict.get(oldZoneId)
|
||||
oldObjList.remove(objId)
|
||||
# Add it to the new zone list
|
||||
objList = parentZoneDict.get(zoneId)
|
||||
if objList is None:
|
||||
# No existing objList for this zone, let's make a new one
|
||||
parentZoneDict[zoneId] = [objId]
|
||||
return
|
||||
else:
|
||||
# Just add this objId to the existing list
|
||||
assert(objId not in objList)
|
||||
objList.append(objId)
|
||||
return
|
||||
|
||||
# Case 2: New parent, valid old parent
|
||||
# First delete the old location
|
||||
if ((oldParentId is not None) and (oldZoneId is not None)):
|
||||
self.deleteObjectLocation(objId, oldParentId, oldZoneId)
|
||||
# Do not return because we still need to add to the new location
|
||||
|
||||
# Case 2: continued, already deleted from old location
|
||||
# Case 3: New parent - no old parent
|
||||
parentZoneDict = self.__doHierarchy.get(parentId)
|
||||
if parentZoneDict is None:
|
||||
# This parent is not here, just fill the whole entry in
|
||||
self.__doHierarchy[parentId] = {zoneId : [objId]}
|
||||
else:
|
||||
objList = parentZoneDict.get(zoneId)
|
||||
if objList is None:
|
||||
# This parent has no objects in this zone before
|
||||
# create a new entry for this zone and list this objId
|
||||
parentZoneDict[zoneId] = [objId]
|
||||
else:
|
||||
# Just add this objId to the existing list
|
||||
objList.append(objId)
|
||||
|
||||
def deleteObjectLocation(self, objId, parentId, zoneId):
|
||||
# Do not worry about null values
|
||||
if ((parentId is None) or (zoneId is None)):
|
||||
return
|
||||
parentZoneDict = self.__doHierarchy.get(parentId)
|
||||
assert(parentZoneDict is not None, "deleteObjectLocation: parentId: %s not found" % (parentId))
|
||||
objList = parentZoneDict.get(zoneId)
|
||||
assert(objList is not None, "deleteObjectLocation: zoneId: %s not found" % (zoneId))
|
||||
assert(objId in objList, "deleteObjectLocation: objId: %s not found" % (objId))
|
||||
if len(objList) == 1:
|
||||
# If this is the last obj in this zone, delete the entire entry
|
||||
del parentZoneDict[zoneId]
|
||||
else:
|
||||
# Just remove the object
|
||||
objList.remove(objId)
|
||||
|
||||
|
||||
def handleGenerateWithRequired(self, di):
|
||||
if wantOtpServer:
|
||||
TheParent = di.getUint32()
|
||||
TheZone = di.getUint32()
|
||||
if wantOtpServer:
|
||||
parentId = di.getUint32()
|
||||
zoneId = di.getUint32()
|
||||
# Get the class Id
|
||||
classId = di.getUint16();
|
||||
classId = di.getUint16()
|
||||
# Get the DO Id
|
||||
doId = di.getUint32()
|
||||
# Look up the dclass
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
dclass.startGenerate()
|
||||
# Create a new distributed object, and put it in the dictionary
|
||||
distObj = self.generateWithRequiredFields(dclass, doId, di)
|
||||
if wantOtpServer:
|
||||
distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId)
|
||||
else:
|
||||
distObj = self.generateWithRequiredFields(dclass, doId, di)
|
||||
dclass.stopGenerate()
|
||||
|
||||
def handleGenerateWithRequiredOther(self, di):
|
||||
if wantOtpServer:
|
||||
TheParent = di.getUint32()
|
||||
TheZone = di.getUint32()
|
||||
parentId = di.getUint32()
|
||||
zoneId = di.getUint32()
|
||||
# Get the class Id
|
||||
classId = di.getUint16();
|
||||
classId = di.getUint16()
|
||||
# Get the DO Id
|
||||
doId = di.getUint32()
|
||||
# Look up the dclass
|
||||
dclass = self.dclassesByNumber[classId]
|
||||
dclass.startGenerate()
|
||||
# Create a new distributed object, and put it in the dictionary
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di)
|
||||
if wantOtpServer:
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId)
|
||||
else:
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di)
|
||||
dclass.stopGenerate()
|
||||
|
||||
def handleQuietZoneGenerateWithRequired(self, di):
|
||||
# Special handler for quiet zone generates -- we need to filter
|
||||
if wantOtpServer:
|
||||
TheParent = di.getUint32()
|
||||
TheZone = di.getUint32()
|
||||
parentId = di.getUint32()
|
||||
zoneId = di.getUint32()
|
||||
# Get the class Id
|
||||
classId = di.getUint16();
|
||||
classId = di.getUint16()
|
||||
# Get the DO Id
|
||||
doId = di.getUint32()
|
||||
# Look up the dclass
|
||||
@ -196,16 +280,16 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# Create a new distributed object, and put it in the dictionary
|
||||
distObj = self.generateWithRequiredFields(dclass, doId, di)
|
||||
else:
|
||||
distObj = self.generateWithRequiredFields(dclass, doId, di)
|
||||
distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId)
|
||||
dclass.stopGenerate()
|
||||
|
||||
def handleQuietZoneGenerateWithRequiredOther(self, di):
|
||||
# Special handler for quiet zone generates -- we need to filter
|
||||
if wantOtpServer:
|
||||
TheParent = di.getUint32()
|
||||
TheZone = di.getUint32()
|
||||
parentId = di.getUint32()
|
||||
zoneId = di.getUint32()
|
||||
# Get the class Id
|
||||
classId = di.getUint16();
|
||||
classId = di.getUint16()
|
||||
# Get the DO Id
|
||||
doId = di.getUint32()
|
||||
# Look up the dclass
|
||||
@ -218,15 +302,18 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# Create a new distributed object, and put it in the dictionary
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di)
|
||||
else:
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di)
|
||||
distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId)
|
||||
dclass.stopGenerate()
|
||||
|
||||
def generateWithRequiredFields(self, dclass, doId, di):
|
||||
# wantOtpServer: remove the None defaults when we remove this config variable
|
||||
def generateWithRequiredFields(self, dclass, doId, di, parentId = None, zoneId = None):
|
||||
if self.doId2do.has_key(doId):
|
||||
# ...it is in our dictionary.
|
||||
# Just update it.
|
||||
distObj = self.doId2do[doId]
|
||||
assert(distObj.dclass == dclass)
|
||||
if wantOtpServer:
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generate()
|
||||
distObj.updateRequiredFields(dclass, di)
|
||||
# updateRequiredFields calls announceGenerate
|
||||
@ -238,6 +325,8 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# put it in the dictionary:
|
||||
self.doId2do[doId] = distObj
|
||||
# and update it.
|
||||
if wantOtpServer:
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generate()
|
||||
distObj.updateRequiredFields(dclass, di)
|
||||
# updateRequiredFields calls announceGenerate
|
||||
@ -254,6 +343,8 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# Put the new do in the dictionary
|
||||
self.doId2do[doId] = distObj
|
||||
# Update the required fields
|
||||
if wantOtpServer:
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generateInit() # Only called when constructed
|
||||
distObj.generate()
|
||||
distObj.updateRequiredFields(dclass, di)
|
||||
@ -279,17 +370,24 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# Put the new do in the dictionary
|
||||
self.doId2do[doId] = distObj
|
||||
# Update the required fields
|
||||
if wantOtpServer:
|
||||
# TODO: ROGER: where should we get parentId and zoneId?
|
||||
parentId = None
|
||||
zoneId = None
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generateInit() # Only called when constructed
|
||||
distObj.generate()
|
||||
# updateRequiredFields calls announceGenerate
|
||||
return distObj
|
||||
|
||||
def generateWithRequiredOtherFields(self, dclass, doId, di):
|
||||
def generateWithRequiredOtherFields(self, dclass, doId, di, parentId = None, zoneId = None):
|
||||
if self.doId2do.has_key(doId):
|
||||
# ...it is in our dictionary.
|
||||
# Just update it.
|
||||
distObj = self.doId2do[doId]
|
||||
assert(distObj.dclass == dclass)
|
||||
if wantOtpServer:
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generate()
|
||||
distObj.updateRequiredOtherFields(dclass, di)
|
||||
# updateRequiredOtherFields calls announceGenerate
|
||||
@ -301,6 +399,8 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# put it in the dictionary:
|
||||
self.doId2do[doId] = distObj
|
||||
# and update it.
|
||||
if wantOtpServer:
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generate()
|
||||
distObj.updateRequiredOtherFields(dclass, di)
|
||||
# updateRequiredOtherFields calls announceGenerate
|
||||
@ -317,6 +417,8 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
# Put the new do in the dictionary
|
||||
self.doId2do[doId] = distObj
|
||||
# Update the required fields
|
||||
if wantOtpServer:
|
||||
distObj.setLocation(parentId, zoneId)
|
||||
distObj.generateInit() # Only called when constructed
|
||||
distObj.generate()
|
||||
distObj.updateRequiredOtherFields(dclass, di)
|
||||
@ -467,7 +569,7 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
self.handleGenerateWithRequiredOther(di)
|
||||
elif wantOtpServer and msgType == CLIENT_DONE_SET_ZONE_RESP:
|
||||
self.handleSetZoneDone()
|
||||
elif wantOtpServer and msgType == CLEINT_OBJECT_LOCATION:
|
||||
elif wantOtpServer and msgType == CLIENT_OBJECT_LOCATION:
|
||||
self.handleObjectLocation(di)
|
||||
else:
|
||||
currentLoginState = self.loginFSM.getCurrentState()
|
||||
@ -541,22 +643,22 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
|
||||
## interest managment
|
||||
##
|
||||
##
|
||||
def InterestAdd(self, parentId, zoneId, Description):
|
||||
def InterestAdd(self, parentId, zoneId, Description):
|
||||
"""
|
||||
Part of the new otp-server code.
|
||||
"""
|
||||
self.__interest_id_assign += 1
|
||||
self.__interesthash[self.__interest_id_assign] = Description
|
||||
contextId = self.__interest_id_assign;
|
||||
contextId = self.__interest_id_assign
|
||||
self.__sendAddInterest(contextId, parentId, zoneId)
|
||||
self.DumpInterests()
|
||||
return contextId;
|
||||
return contextId
|
||||
|
||||
def InterestRemove(self, contextId):
|
||||
"""
|
||||
Part of the new otp-server code.
|
||||
"""
|
||||
answer = 0;
|
||||
answer = 0
|
||||
if self.__interesthash.has_key(contextId):
|
||||
self.__sendRemoveInterest(contextId)
|
||||
del self.__interesthash[contextId]
|
||||
|
@ -31,6 +31,9 @@ class DistributedObject(PandaObject):
|
||||
except:
|
||||
self.DistributedObject_initialized = 1
|
||||
self.cr = cr
|
||||
if wantOtpServer:
|
||||
# Location stores the parentId, zoneId of this object
|
||||
self.__location = (None, None)
|
||||
|
||||
# Most DistributedObjects are simple and require no real
|
||||
# effort to load. Some, particularly actors, may take
|
||||
@ -150,6 +153,10 @@ class DistributedObject(PandaObject):
|
||||
assert(self.notify.debug('disable(): %s' % (self.doId)))
|
||||
self.activeState = ESDisabled
|
||||
self.__callbacks = {}
|
||||
if wantOtpServer:
|
||||
self.cr.deleteObjectLocation(self.doId, self.__location[0], self.__location[1])
|
||||
self.__location = (None, None)
|
||||
# TODO: disable my children
|
||||
|
||||
def isDisabled(self):
|
||||
"""
|
||||
@ -325,5 +332,13 @@ class DistributedObject(PandaObject):
|
||||
if self.__barrierContext != None:
|
||||
self.sendUpdate("setBarrierReady", [self.__barrierContext])
|
||||
self.__barrierContext = None
|
||||
|
||||
|
||||
|
||||
if wantOtpServer:
|
||||
def setLocation(self, parentId, zoneId):
|
||||
# The store must run first so we know the old location
|
||||
self.cr.storeObjectLocation(self.doId, parentId, zoneId)
|
||||
self.__location = (parentId, zoneId)
|
||||
|
||||
def getLocation(self):
|
||||
return self.__location
|
||||
|
||||
|
@ -72,12 +72,11 @@ CLIENT_GET_PET_DETAILS = 81
|
||||
CLIENT_GET_PET_DETAILS_RESP = 82
|
||||
|
||||
# (Proposed new message): CLIENT_SET_WORLD_POS = 83
|
||||
|
||||
CLIENT_ADD_INTEREST = 97
|
||||
CLEINT_ALTER_INTEREST = 98
|
||||
CLEINT_REMOVE_INTEREST = 99
|
||||
if wantOtpServer:
|
||||
CLEINT_OBJECT_LOCATION = 102
|
||||
CLIENT_ADD_INTEREST = 97
|
||||
CLIENT_ALTER_INTEREST = 98
|
||||
CLIENT_REMOVE_INTEREST = 99
|
||||
CLIENT_OBJECT_LOCATION = 102
|
||||
|
||||
# These messages are ignored when the client is headed to the quiet zone
|
||||
QUIET_ZONE_IGNORED_LIST = [
|
||||
|
Loading…
x
Reference in New Issue
Block a user