from direct.directnotify import DirectNotifyGlobal from direct.distributed.AstronInternalRepository import AstronInternalRepository from direct.distributed.PyDatagram import PyDatagram from otp.distributed.OtpDoGlobals import * class ToontownInternalRepository(AstronInternalRepository): notify = DirectNotifyGlobal.directNotify.newCategory('ToontownInternalRepository') GameGlobalsId = OTP_DO_ID_TOONTOWN dbId = 4003 def __init__(self, baseChannel, serverId=None, dcFileNames=None, dcSuffix='AI', connectMethod=None, threadedNet=None): AstronInternalRepository.__init__(self, baseChannel, serverId, dcFileNames, dcSuffix, connectMethod, threadedNet) def getAvatarIdFromSender(self): return self.getMsgSender() & 0xFFFFFFFF def getAccountIdFromSender(self): return (self.getMsgSender() >> 32) & 0xFFFFFFFF def _isValidPlayerLocation(self, parentId, zoneId): if zoneId < 1000 and zoneId != 1: return False return True def setAllowClientSend(self, avId, distObj, fieldNameList=[]): """ Allow an AI to temporarily give a client 'clsend' privileges on a particular fields on a particular object. This should be used on fields that are 'ownsend' by default. When you want to revoke these privileges, use clearAllowClientSend() to end these privileges. """ dg = PyDatagram() dg.addServerHeader(distObj.GetPuppetConnectionChannel(avId), self.ourChannel, CLIENTAGENT_SET_FIELDS_SENDABLE) fieldIds = [] for fieldName in fieldNameList: field = distObj.dclass.getFieldByName(fieldName) if field: fieldIds.append(field.getNumber()) dg.addUint32(distObj.getDoId()) dg.addUint16(len(fieldIds)) for fieldId in fieldIds: dg.addUint16(fieldId) self.send(dg) def createDgUpdateToDoId(self, dclassName, fieldName, doId, args, channelId=None): """ channelId can be used as a recipient if you want to bypass the normal airecv, ownrecv, broadcast, etc. If you don't include a channelId or if channelId == doId, then the normal broadcast options will be used. This is just like sendUpdateToDoId, but just returns the datagram instead of immediately sending it. """ result = None dclass = self.dclassesByName.get(dclassName+self.dcSuffix) assert dclass is not None if channelId is None: channelId = doId if dclass is not None: dg = dclass.aiFormatUpdate(fieldName, doId, channelId, self.ourChannel, args) result = dg return result def sendUpdateToDoId(self, dclassName, fieldName, doId, args, channelId=None): """ channelId can be used as a recipient if you want to bypass the normal airecv, ownrecv, broadcast, etc. If you don't include a channelId or if channelId == doId, then the normal broadcast options will be used. See Also: def queryObjectField """ dclass = self.dclassesByName.get(dclassName+self.dcSuffix) assert dclass is not None if channelId is None: channelId = doId if dclass is not None: dg = dclass.aiFormatUpdate(fieldName, doId, channelId, self.ourChannel, args) self.send(dg) def sendUpdateToGlobalDoId(self, dclassName, fieldName, doId, args): """ Used for sending messages from an AI directly to an uber object. """ dclass = self.dclassesByName.get(dclassName) assert dclass, 'dclass %s not found in DC files' % dclassName dg = dclass.aiFormatUpdate(fieldName, doId, doId, self.ourChannel, args) self.send(dg) def dispatchUpdateToDoId(self, dclassName, fieldName, doId, args, channelId=None): # dispatch immediately to local object if it's local, otherwise send # it over the wire obj = self.doId2do.get(doId) if obj is not None: assert obj.__class__.__name__ == (dclassName + self.dcSuffix) method = getattr(obj, fieldName) method(*args) else: self.sendUpdateToDoId(dclassName, fieldName, doId, args, channelId) def dispatchUpdateToGlobalDoId(self, dclassName, fieldName, doId, args): # dispatch immediately to local object if it's local, otherwise send # it over the wire obj = self.doId2do.get(doId) if obj is not None: assert obj.__class__.__name__ == dclassName method = getattr(obj, fieldName) method(*args) else: self.sendUpdateToGlobalDoId(dclassName, fieldName, doId, args)