diff --git a/etc/toon.dc b/etc/toon.dc index 29a554a..d681f40 100755 --- a/etc/toon.dc +++ b/etc/toon.dc @@ -2846,17 +2846,10 @@ dclass TTAvatarFriendsManager : AvatarFriendsManager { dclass TTPlayerFriendsManager : PlayerFriendsManager { }; -struct Friend { - uint32 doId; - string name; - blob dnaString; - uint32 petId; -}; - dclass ToontownFriendsManager : DistributedObject { getFriendsListRequest() clsend; - getFriendsListResponse(Friend[]); - friendOnline(uint32, uint8, uint8); + getFriendsListResponse(blob); + friendOnline(blob); getAvatarDetailsRequest(uint32) clsend; getAvatarDetailsResponse(blob); }; diff --git a/toontown/distributed/ToontownClientRepository.py b/toontown/distributed/ToontownClientRepository.py index f08e18b..6e06b28 100644 --- a/toontown/distributed/ToontownClientRepository.py +++ b/toontown/distributed/ToontownClientRepository.py @@ -910,15 +910,20 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): PetDetail.PetDetail(doId, petDetailsCallback) - if __astron__: - def handleGetFriendsList(self, friendsList): - for friend in friendsList: - doId = friend[0] - name = friend[1] - dnaString = friend[2] + def handleGetFriendsList(self, di): + error = di.getUint8() + if error: + self.notify.warning('Got error return from friends list.') + self.friendsListError = 1 + else: + count = di.getUint16() + for i in range(0, count): + doId = di.getUint32() + name = di.getString() + dnaString = di.getBlob() dna = ToonDNA.ToonDNA() dna.makeFromNetString(dnaString) - petId = friend[3] + petId = di.getUint32() handle = FriendHandle.FriendHandle(doId, name, dna, petId) self.friendsMap[doId] = handle if doId in self.friendsOnline: @@ -935,41 +940,8 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): self.addPetToFriendsMap(handleAddedPet) return - self.friendsMapPending = 0 - messenger.send('friendsMapComplete') - else: - def handleGetFriendsList(self, di): - error = di.getUint8() - if error: - self.notify.warning('Got error return from friends list.') - self.friendsListError = 1 - else: - count = di.getUint16() - for i in range(0, count): - doId = di.getUint32() - name = di.getString() - dnaString = di.getString() - dna = ToonDNA.ToonDNA() - dna.makeFromNetString(dnaString) - petId = di.getUint32() - handle = FriendHandle.FriendHandle(doId, name, dna, petId) - self.friendsMap[doId] = handle - if doId in self.friendsOnline: - self.friendsOnline[doId] = handle - if doId in self.friendPendingChatSettings: - self.notify.debug('calling setCommonAndWL %s' % str(self.friendPendingChatSettings[doId])) - handle.setCommonAndWhitelistChatFlags(*self.friendPendingChatSettings[doId]) - - if base.wantPets and base.localAvatar.hasPet(): - - def handleAddedPet(): - self.friendsMapPending = 0 - messenger.send('friendsMapComplete') - - self.addPetToFriendsMap(handleAddedPet) - return - self.friendsMapPending = 0 - messenger.send('friendsMapComplete') + self.friendsMapPending = 0 + messenger.send('friendsMapComplete') def handleGetFriendsListExtended(self, di): avatarHandleList = [] @@ -998,29 +970,20 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): if avatarHandleList: messenger.send('gotExtraFriendHandles', [avatarHandleList]) - if __astron__: - def handleFriendOnline(self, doId, commonChatFlags, whitelistChatFlags): - self.notify.debug('Friend %d now online. common=%d whitelist=%d' % (doId, commonChatFlags, whitelistChatFlags)) - if doId not in self.friendsOnline: - self.friendsOnline[doId] = self.identifyFriend(doId) - messenger.send('friendOnline', [doId, commonChatFlags, whitelistChatFlags]) - if not self.friendsOnline[doId]: - self.friendPendingChatSettings[doId] = (commonChatFlags, whitelistChatFlags) - else: - def handleFriendOnline(self, di): - doId = di.getUint32() - commonChatFlags = 0 - whitelistChatFlags = 0 - if di.getRemainingSize() > 0: - commonChatFlags = di.getUint8() - if di.getRemainingSize() > 0: - whitelistChatFlags = di.getUint8() - self.notify.debug('Friend %d now online. common=%d whitelist=%d' % (doId, commonChatFlags, whitelistChatFlags)) - if doId not in self.friendsOnline: - self.friendsOnline[doId] = self.identifyFriend(doId) - messenger.send('friendOnline', [doId, commonChatFlags, whitelistChatFlags]) - if not self.friendsOnline[doId]: - self.friendPendingChatSettings[doId] = (commonChatFlags, whitelistChatFlags) + def handleFriendOnline(self, di): + doId = di.getUint32() + commonChatFlags = 0 + whitelistChatFlags = 0 + if di.getRemainingSize() > 0: + commonChatFlags = di.getUint8() + if di.getRemainingSize() > 0: + whitelistChatFlags = di.getUint8() + self.notify.debug('Friend %d now online. common=%d whitelist=%d' % (doId, commonChatFlags, whitelistChatFlags)) + if doId not in self.friendsOnline: + self.friendsOnline[doId] = self.identifyFriend(doId) + messenger.send('friendOnline', [doId, commonChatFlags, whitelistChatFlags]) + if not self.friendsOnline[doId]: + self.friendPendingChatSettings[doId] = (commonChatFlags, whitelistChatFlags) def handleFriendOffline(self, di): doId = di.getUint32() diff --git a/toontown/friends/ToontownFriendsManager.py b/toontown/friends/ToontownFriendsManager.py index 7e5f58d..814cc7d 100644 --- a/toontown/friends/ToontownFriendsManager.py +++ b/toontown/friends/ToontownFriendsManager.py @@ -11,10 +11,14 @@ class ToontownFriendsManager(DistributedObjectGlobal): self.sendUpdate('getFriendsListRequest') def getFriendsListResponse(self, friendsList): - self.cr.handleGetFriendsList(friendsList) + datagram = PyDatagram(friendsList) + di = PyDatagramIterator(datagram) + self.cr.handleGetFriendsList(di) - def friendOnline(self, doId, commonChatFlags, whitelistChatFlags): - self.cr.handleFriendOnline(doId, commonChatFlags, whitelistChatFlags) + def friendOnline(self, friend): + datagram = PyDatagram(friend) + di = PyDatagramIterator(datagram) + self.cr.handleFriendOnline(di) def sendGetAvatarDetailsRequest(self, avId): self.sendUpdate('getAvatarDetailsRequest', [avId]) diff --git a/toontown/friends/ToontownFriendsManagerUD.py b/toontown/friends/ToontownFriendsManagerUD.py index bd74818..06345dc 100644 --- a/toontown/friends/ToontownFriendsManagerUD.py +++ b/toontown/friends/ToontownFriendsManagerUD.py @@ -18,65 +18,6 @@ class FriendsOperation: pass -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.__sendAvatarDetails(False) - self._handleError('Retrieved avatar is not a DistributedToonUD or DistributedPetAI!') - return - - self.dclass = dclass - self.fields = fields - self.fields['avId'] = self.avId - self.__sendAvatarDetails(True) - 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: - details = self.__packAvatarDetails(self.dclass, self.fields) - datagram.appendData(details) - - self.friendsManager.sendUpdateToAvatarId(self.sender, 'getAvatarDetailsResponse', [datagram.getMessage()]) - - class GetFriendsListOperation(FriendsOperation): def __init__(self, friendsManager, sender): @@ -101,7 +42,6 @@ class GetFriendsListOperation(FriendsOperation): self.tempFriendsList = fields['setFriendsList'][0] if len(self.tempFriendsList) <= 0: - self.__sendFriendsList() self._handleDone() return @@ -135,13 +75,100 @@ class GetFriendsListOperation(FriendsOperation): self.onlineFriends.append(avId) if self.currentFriendIdx >= len(self.friendsList): - self.__sendFriendsList() self._handleDone() - def __sendFriendsList(self): - self.friendsManager.sendUpdateToAvatarId(self.sender, 'getFriendsListResponse', [self.friendsList]) + 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: - self.friendsManager.sendUpdateToAvatarId(self.sender, 'friendOnline', [friendId, 0, 1]) + 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):