195 lines
7.1 KiB
Python
195 lines
7.1 KiB
Python
from direct.directnotify import DirectNotifyGlobal
|
|
from direct.distributed.DistributedObjectGlobalUD import DistributedObjectGlobalUD
|
|
from direct.distributed.PyDatagram import *
|
|
|
|
|
|
class FriendsOperation:
|
|
|
|
def __init__(self, friendsManager, sender):
|
|
self.friendsManager = friendsManager
|
|
self.sender = sender
|
|
|
|
def _handleDone(self):
|
|
# TODO
|
|
pass
|
|
|
|
def _handleError(self, error):
|
|
# TODO
|
|
pass
|
|
|
|
|
|
class GetFriendsListOperation(FriendsOperation):
|
|
|
|
def __init__(self, friendsManager, sender):
|
|
FriendsOperation.__init__(self, friendsManager, sender)
|
|
self.friendsList = None
|
|
self.tempFriendsList = None
|
|
self.onlineFriends = None
|
|
self.currentFriendIdx = None
|
|
|
|
def start(self):
|
|
self.friendsList = []
|
|
self.tempFriendsList = []
|
|
self.onlineFriends = []
|
|
self.currentFriendIdx = 0
|
|
self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, self.sender,
|
|
self.__handleSenderRetrieved)
|
|
|
|
def __handleSenderRetrieved(self, dclass, fields):
|
|
if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']:
|
|
self._handleError('Retrieved sender is not a DistributedToonUD!')
|
|
return
|
|
|
|
self.tempFriendsList = fields['setFriendsList'][0]
|
|
if len(self.tempFriendsList) <= 0:
|
|
self._handleDone()
|
|
return
|
|
|
|
self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, self.tempFriendsList[0][0],
|
|
self.__handleFriendRetrieved)
|
|
|
|
def __handleFriendRetrieved(self, dclass, fields):
|
|
if dclass != self.friendsManager.air.dclassesByName['DistributedToonUD']:
|
|
self._handleError('Retrieved friend is not a DistributedToonUD!')
|
|
return
|
|
|
|
friendId = self.tempFriendsList[self.currentFriendIdx][0]
|
|
self.friendsList.append([friendId, fields['setName'][0], fields['setDNAString'][0], fields['setPetId'][0]])
|
|
if len(self.friendsList) >= len(self.tempFriendsList):
|
|
self.__checkFriendsOnline()
|
|
return
|
|
|
|
self.currentFriendIdx += 1
|
|
self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId,
|
|
self.tempFriendsList[self.currentFriendIdx][0],
|
|
self.__handleFriendRetrieved)
|
|
|
|
def __checkFriendsOnline(self):
|
|
self.currentFriendIdx = 0
|
|
for friendDetails in self.friendsList:
|
|
self.friendsManager.air.getActivated(friendDetails[0], self.__gotActivatedResp)
|
|
|
|
def __gotActivatedResp(self, avId, activated):
|
|
self.currentFriendIdx += 1
|
|
if activated:
|
|
self.onlineFriends.append(avId)
|
|
|
|
if self.currentFriendIdx >= len(self.friendsList):
|
|
self._handleDone()
|
|
|
|
def __sendFriendsList(self, success):
|
|
datagram = PyDatagram()
|
|
datagram.addUint8(0 if success else 1) # error
|
|
if success:
|
|
count = len(self.friendsList)
|
|
datagram.addUint16(count) # count
|
|
for i in range(count):
|
|
datagram.addUint32(self.friendsList[i][0]) # doId
|
|
datagram.addString(self.friendsList[i][1]) # name
|
|
datagram.addBlob(self.friendsList[i][2]) # dnaString
|
|
datagram.addUint32(self.friendsList[i][3]) # petId
|
|
|
|
self.friendsManager.sendUpdateToAvatarId(self.sender, 'getFriendsListResponse', [datagram.getMessage()])
|
|
for friendId in self.onlineFriends:
|
|
datagram = PyDatagram()
|
|
datagram.addUint32(friendId) # doId
|
|
datagram.addUint8(0) # commonChatFlags
|
|
datagram.addUint8(1) # whitelistChatFlags
|
|
self.friendsManager.sendUpdateToAvatarId(self.sender, 'friendOnline', [datagram.getMessage()])
|
|
|
|
def _handleDone(self):
|
|
self.__sendFriendsList(True)
|
|
FriendsOperation._handleDone(self)
|
|
|
|
def _handleError(self, error):
|
|
self.__sendFriendsList(False)
|
|
FriendsOperation._handleError(self, error)
|
|
|
|
|
|
class GetAvatarDetailsOperation(FriendsOperation):
|
|
|
|
def __init__(self, friendsManager, sender):
|
|
FriendsOperation.__init__(self, friendsManager, sender)
|
|
self.avId = None
|
|
self.dclass = None
|
|
self.fields = None
|
|
|
|
def start(self, avId):
|
|
self.avId = avId
|
|
self.fields = {}
|
|
self.friendsManager.air.dbInterface.queryObject(self.friendsManager.air.dbId, avId,
|
|
self.__handleAvatarRetrieved)
|
|
|
|
def __handleAvatarRetrieved(self, dclass, fields):
|
|
if dclass not in (self.friendsManager.air.dclassesByName['DistributedToonUD'],
|
|
self.friendsManager.air.dclassesByName['DistributedPetAI']):
|
|
self._handleError('Retrieved avatar is not a DistributedToonUD or DistributedPetAI!')
|
|
return
|
|
|
|
self.dclass = dclass
|
|
self.fields = fields
|
|
self.fields['avId'] = self.avId
|
|
self._handleDone()
|
|
|
|
def __packAvatarDetails(self, dclass, fields):
|
|
# Pack required fields.
|
|
fieldPacker = DCPacker()
|
|
for i in range(dclass.getNumInheritedFields()):
|
|
field = dclass.getInheritedField(i)
|
|
if not field.isRequired() or field.asMolecularField():
|
|
continue
|
|
|
|
k = field.getName()
|
|
v = fields.get(k, None)
|
|
|
|
fieldPacker.beginPack(field)
|
|
if not v:
|
|
fieldPacker.packDefaultValue()
|
|
else:
|
|
field.packArgs(fieldPacker, v)
|
|
|
|
fieldPacker.endPack()
|
|
|
|
return fieldPacker.getBytes()
|
|
|
|
def __sendAvatarDetails(self, success):
|
|
datagram = PyDatagram()
|
|
datagram.addUint32(self.fields['avId'])
|
|
datagram.addUint8(0 if success else 1)
|
|
if success:
|
|
avatarDetails = self.__packAvatarDetails(self.dclass, self.fields)
|
|
datagram.appendData(avatarDetails)
|
|
|
|
self.friendsManager.sendUpdateToAvatarId(self.sender, 'getAvatarDetailsResponse', [datagram.getMessage()])
|
|
|
|
def _handleDone(self):
|
|
self.__sendAvatarDetails(True)
|
|
FriendsOperation._handleDone(self)
|
|
|
|
def _handleError(self, error):
|
|
self.__sendAvatarDetails(False)
|
|
FriendsOperation._handleError(self, error)
|
|
|
|
|
|
class ToontownFriendsManagerUD(DistributedObjectGlobalUD):
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('ToontownFriendsManagerUD')
|
|
|
|
def __init__(self, air):
|
|
DistributedObjectGlobalUD.__init__(self, air)
|
|
self.operations = []
|
|
|
|
def runOperation(self, operationType, *args):
|
|
sender = self.air.getAvatarIdFromSender()
|
|
if not sender:
|
|
return
|
|
|
|
newOperation = operationType(self, sender)
|
|
self.operations.append(newOperation)
|
|
newOperation.start(*args)
|
|
|
|
def getFriendsListRequest(self):
|
|
self.runOperation(GetFriendsListOperation)
|
|
|
|
def getAvatarDetailsRequest(self, avId):
|
|
self.runOperation(GetAvatarDetailsOperation, avId)
|