130 lines
4.8 KiB
Python
130 lines
4.8 KiB
Python
|
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)
|