diff --git a/.gitignore b/.gitignore index 5fc5ec9..f944d01 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ *.pyo *.log resources/ +news/ +sign/ +whitelist/ *.so diff --git a/etc/otp.dc b/etc/otp.dc index f984a1c..f856f68 100755 --- a/etc/otp.dc +++ b/etc/otp.dc @@ -542,5 +542,6 @@ dclass AstronLoginManager : DistributedObject { nameTypedResponse(uint32, uint8); acknowledgeAvatarName(uint32) clsend; acknowledgeAvatarNameResponse(); + requestRemoveAvatar(uint32) clsend; + requestPlayAvatar(uint32) clsend; }; - diff --git a/etc/toon.dc b/etc/toon.dc index 2fbafad..df18e0b 100755 --- a/etc/toon.dc +++ b/etc/toon.dc @@ -442,72 +442,72 @@ typedef int16 pair16[2]; dclass DistributedToon : DistributedPlayer { setDNAString(blob) required broadcast ownrecv db; - setGM(uint8) required broadcast ownrecv db; - setMaxBankMoney(int16) required broadcast ownrecv db; - setBankMoney(int16) required broadcast ownrecv db; - setMaxMoney(int16) required broadcast ownrecv db; - setMoney(int16) required broadcast ownrecv db; - setMaxHp(int16) required broadcast ownrecv db; - setHp(int16) required broadcast ownrecv db; + setGM(uint8 = 0) required broadcast ownrecv db; + setMaxBankMoney(int16 = 12000) required broadcast ownrecv db; + setBankMoney(int16 = 0) required broadcast ownrecv db; + setMaxMoney(int16 = 40) required broadcast ownrecv db; + setMoney(int16 = 0) required broadcast ownrecv db; + setMaxHp(int16 = 15) required broadcast ownrecv db; + setHp(int16 = 15) required broadcast ownrecv db; toonUp(uint16) broadcast ownrecv; takeDamage(uint16) broadcast ownrecv; setBattleId(uint32) required broadcast ram; - setExperience(blob) required ownrecv db; - setMaxCarry(uint8) required ownrecv db; - setTrackAccess(uint16[]) required broadcast ownrecv db; - setTrackProgress(int8, uint32) required ownrecv db; - setTrackBonusLevel(int8[]) required broadcast ownrecv db; - setInventory(blob) required ownrecv db; - setMaxNPCFriends(uint16) required ownrecv db; + setExperience(blob = [0 * 14]) required ownrecv db; + setMaxCarry(uint8 = 20) required ownrecv db; + setTrackAccess(uint16[] = [0, 0, 0, 0, 1, 1, 0]) required broadcast ownrecv db; + setTrackProgress(int8 = -1, uint32 = 0) required ownrecv db; + setTrackBonusLevel(int8[] = [-1 * 7]) required broadcast ownrecv db; + setInventory(blob = [0 * 7, 0 * 7, 0 * 7, 0 * 7, 1, 0 * 6, 1, 0 * 6, 0 * 7]) required ownrecv db; + setMaxNPCFriends(uint16 = 16) required ownrecv db; setNPCFriendsDict(FriendEntry[]) required ownrecv db; - setDefaultShard(uint32) required ownrecv db; - setDefaultZone(uint32) required ownrecv db; - setShtickerBook(blob) required ownrecv db; - setZonesVisited(uint32[]) required ownrecv db; - setHoodsVisited(uint32[]) required ownrecv db; - setInterface(blob) required ownrecv db; - setLastHood(uint32) required ownrecv db; - setTutorialAck(uint8) required ownrecv db; - setMaxClothes(uint32) required ownrecv db; - setClothesTopsList(uint8[]) required ownrecv db; - setClothesBottomsList(uint8[]) required ownrecv db; - setMaxAccessories(uint32) required ownrecv db; - setHatList(uint8[]) required ownrecv db; - setGlassesList(uint8[]) required ownrecv db; - setBackpackList(uint8[]) required ownrecv db; - setShoesList(uint8[]) required ownrecv db; - setHat(uint8, uint8, uint8) required broadcast db ownrecv; - setGlasses(uint8, uint8, uint8) required broadcast db ownrecv; - setBackpack(uint8, uint8, uint8) required broadcast db ownrecv; - setShoes(uint8, uint8, uint8) required broadcast db ownrecv; - setGardenSpecials(gardenSpecial []) required ownrecv db airecv; + setDefaultShard(uint32 = 0) required ownrecv db; + setDefaultZone(uint32 = 0) required ownrecv db; + setShtickerBook(blob = []) required ownrecv db; + setZonesVisited(uint32[] = [2000]) required ownrecv db; + setHoodsVisited(uint32[] = [2000]) required ownrecv db; + setInterface(blob = []) required ownrecv db; + setLastHood(uint32 = 0) required ownrecv db; + setTutorialAck(uint8 = 0) required ownrecv db; + setMaxClothes(uint32 = 10) required ownrecv db; + setClothesTopsList(uint8[] = []) required ownrecv db; + setClothesBottomsList(uint8[] = []) required ownrecv db; + setMaxAccessories(uint32 = 0) required ownrecv db; + setHatList(uint8[] = []) required ownrecv db; + setGlassesList(uint8[] = []) required ownrecv db; + setBackpackList(uint8[] = []) required ownrecv db; + setShoesList(uint8[] = []) required ownrecv db; + setHat(uint8 = 0, uint8 = 0, uint8 = 0) required broadcast db ownrecv; + setGlasses(uint8 = 0, uint8 = 0, uint8 = 0) required broadcast db ownrecv; + setBackpack(uint8 = 0, uint8 = 0, uint8 = 0) required broadcast db ownrecv; + setShoes(uint8 = 0, uint8 = 0, uint8 = 0) required broadcast db ownrecv; + setGardenSpecials(gardenSpecial [] = []) required ownrecv db airecv; setEarnedExperience(uint16[]) ownrecv; setTunnelIn(int16, int16/10, int16/10, int16/10, int16/100, int32/100) ownsend broadcast; setTunnelOut(int16, int16/10, int16/10, int16/10, int16/10, int16/100, int32/100) ownsend broadcast; setAnimState(char [0-1024], int16/1000, int16) broadcast ram ownsend airecv; setEmoteState(int16, int16/1000, int16) broadcast ram ownsend; - setEmoteAccess(uint8[]) required ownrecv db; - setCustomMessages(uint16[]) required ownrecv db; + setEmoteAccess(uint8[] = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) required ownrecv db; + setCustomMessages(uint16[] = []) required ownrecv db; setSleepAutoReply(uint32) broadcast clsend ownrecv; - setResistanceMessages(pair16 []) required ownrecv db; - setPetTrickPhrases(uint8[]) required ownrecv db; - setCatalogSchedule(uint16, uint32) required ownrecv db; - setCatalog(blob, blob, blob) required ownrecv db; - setMailboxContents(blob) required ownrecv db; - setDeliverySchedule(blob) required ownrecv db airecv; - setGiftSchedule(blob) required ownrecv db airecv; - setAwardMailboxContents(blob) required ownrecv db; - setAwardSchedule(blob) required ownrecv db airecv; - setAwardNotify(uint8) required ownrecv db; - setCatalogNotify(uint8, uint8) required ownrecv db; + setResistanceMessages(pair16 [] = []) required ownrecv db; + setPetTrickPhrases(uint8[] = [0]) required ownrecv db; + setCatalogSchedule(uint16 = 0, uint32 = 0) required ownrecv db; + setCatalog(blob = [], blob = [], blob = []) required ownrecv db; + setMailboxContents(blob = []) required ownrecv db; + setDeliverySchedule(blob = []) required ownrecv db airecv; + setGiftSchedule(blob = []) required ownrecv db airecv; + setAwardMailboxContents(blob = []) required ownrecv db; + setAwardSchedule(blob = []) required ownrecv db airecv; + setAwardNotify(uint8 = 0) required ownrecv db; + setCatalogNotify(uint8 = 0, uint8 = 0) required ownrecv db; playSplashEffect(int16/10, int16/10, int16/10) broadcast ownsend; setWhisperSCToontaskFrom(uint32, uint32, uint32, uint32, uint8) ownrecv clsend; setSCToontask(uint32, uint32, uint32, uint8) broadcast ownsend; reqSCResistance(uint16, uint32 []) ownsend airecv; setSCResistance(uint16, uint32 []) broadcast ownrecv; - setSpeedChatStyleIndex(uint8) required ownsend broadcast db; + setSpeedChatStyleIndex(uint8 = 1) required ownsend broadcast db; setTrophyScore(uint16) broadcast ownrecv ram; - setTeleportAccess(uint32[]) required ownrecv db; + setTeleportAccess(uint32[] = []) required ownrecv db; checkTeleportAccess(uint16) airecv ownsend; battleSOS(uint32) ownrecv clsend; teleportQuery(uint32) ownrecv clsend; @@ -515,39 +515,39 @@ dclass DistributedToon : DistributedPlayer { teleportResponseToAI(uint32, int8, uint32, uint32, uint32, uint32) ownsend airecv; teleportGiveup(uint32) ownrecv clsend; teleportGreeting(uint32) broadcast ownsend; - setCogStatus(uint32[]) required ownrecv db; - setCogCount(uint32[]) required ownrecv db; - setCogRadar(uint8[]) required ownrecv db; - setBuildingRadar(uint8[]) required ownrecv db; - setCogLevels(uint8[]) required broadcast ownrecv db; - setCogTypes(uint8[]) required broadcast ownrecv db; - setCogParts(uint32[]) required broadcast ownrecv db; - setCogMerits(uint16[]) required ownrecv db; + setCogStatus(uint32[] = [1 * 32]) required ownrecv db; + setCogCount(uint32[] = [0 * 32]) required ownrecv db; + setCogRadar(uint8[] = [0 * 4]) required ownrecv db; + setBuildingRadar(uint8[] = [0 * 4]) required ownrecv db; + setCogLevels(uint8[] = [0 * 4]) required broadcast ownrecv db; + setCogTypes(uint8[] = [0 * 4]) required broadcast ownrecv db; + setCogParts(uint32[] = [0 * 4]) required broadcast ownrecv db; + setCogMerits(uint16[] = [0 * 4]) required ownrecv db; setCogIndex(int8) broadcast ram; setDisguisePageFlag(int8) ownrecv; setSosPageFlag(int8) ownrecv; - setHouseId(uint32) required ownrecv db; - setQuests(uint32[]) required broadcast ownrecv db; - setQuestHistory(uint16[]) required ownrecv db; - setRewardHistory(uint8, uint16[]) required ownrecv db; - setQuestCarryLimit(uint8) required ownrecv db; + setHouseId(uint32 = 0) required ownrecv db; + setQuests(uint32[] = []) required broadcast ownrecv db; + setQuestHistory(uint16[] = []) required ownrecv db; + setRewardHistory(uint8 = 0, uint16[] = []) required ownrecv db; + setQuestCarryLimit(uint8 = 1) required ownrecv db; requestDeleteQuest(uint32[]) ownsend airecv; - setCheesyEffect(int16, uint32, uint32) required broadcast ownrecv db; + setCheesyEffect(int16 = 0, uint32 = 0, uint32 = 0) required broadcast ownrecv db; setGhostMode(uint8) broadcast ownrecv ram; - setPosIndex(uint8) required ownrecv db; - setFishCollection(uint8[], uint8[], uint16[]) required ownrecv db; - setMaxFishTank(uint8) required ownrecv db; - setFishTank(uint8[], uint8[], uint16[]) required ownrecv db; - setFishingRod(uint8) required broadcast ownrecv db; - setFishingTrophies(uint8[]) required ownrecv db; - setFlowerCollection(uint8[], uint8[]) required ownrecv db; - setFlowerBasket(uint8[], uint8[]) required ownrecv db; - setMaxFlowerBasket(uint8) required ownrecv db; - setGardenTrophies(uint8[]) required ownrecv db; - setShovel(uint8) required broadcast ownrecv db; - setShovelSkill(uint32) required ownrecv db; - setWateringCan(uint8) required broadcast ownrecv db; - setWateringCanSkill(uint32) required ownrecv db; + setPosIndex(uint8 = 0) required ownrecv db; + setFishCollection(uint8[] = [], uint8[] = [], uint16[] = []) required ownrecv db; + setMaxFishTank(uint8 = 20) required ownrecv db; + setFishTank(uint8[] = [], uint8[] = [], uint16[] = []) required ownrecv db; + setFishingRod(uint8 = 0) required broadcast ownrecv db; + setFishingTrophies(uint8[] = []) required ownrecv db; + setFlowerCollection(uint8[] = [], uint8[] = []) required ownrecv db; + setFlowerBasket(uint8[] = [], uint8[] = []) required ownrecv db; + setMaxFlowerBasket(uint8 = 20) required ownrecv db; + setGardenTrophies(uint8[] = []) required ownrecv db; + setShovel(uint8 = 0) required broadcast ownrecv db; + setShovelSkill(uint32 = 0) required ownrecv db; + setWateringCan(uint8 = 0) required broadcast ownrecv db; + setWateringCanSkill(uint32 = 0) required ownrecv db; promoteShovel(uint8) ownrecv; promoteWateringCan(uint8) ownrecv; reactivateWater() ownrecv; @@ -558,51 +558,51 @@ dclass DistributedToon : DistributedPlayer { setNumPies(uint16) broadcast ownrecv ram; catalogGenClothes(uint32) broadcast ownrecv; catalogGenAccessories(uint32) broadcast ownrecv; - setPetId(uint32) required broadcast ownrecv db; + setPetId(uint32 = 0) required broadcast ownrecv db; setPetMovie(uint32, uint8) ownsend airecv; - setPetTutorialDone(uint8) required ownsend airecv db; - setFishBingoTutorialDone(uint8) required ownsend airecv db; - setFishBingoMarkTutorialDone(uint8) required ownsend airecv db; - setKartBodyType(int8) required broadcast ownrecv db; - setKartBodyColor(int8) required broadcast ownrecv db; - setKartAccessoryColor(int8) required broadcast ownrecv db; - setKartEngineBlockType(int8) required broadcast ownrecv db; - setKartSpoilerType(int8) required broadcast ownrecv db; - setKartFrontWheelWellType(int8) required broadcast ownrecv db; - setKartBackWheelWellType(int8) required broadcast ownrecv db; - setKartRimType(int8) required broadcast ownrecv db; - setKartDecalType(int8) required broadcast ownrecv db; + setPetTutorialDone(uint8 = 0) required ownsend airecv db; + setFishBingoTutorialDone(uint8 = 0) required ownsend airecv db; + setFishBingoMarkTutorialDone(uint8 = 0) required ownsend airecv db; + setKartBodyType(int8 = -1) required broadcast ownrecv db; + setKartBodyColor(int8 = -1) required broadcast ownrecv db; + setKartAccessoryColor(int8 = -1) required broadcast ownrecv db; + setKartEngineBlockType(int8 = -1) required broadcast ownrecv db; + setKartSpoilerType(int8 = -1) required broadcast ownrecv db; + setKartFrontWheelWellType(int8 = -1) required broadcast ownrecv db; + setKartBackWheelWellType(int8 = -1) required broadcast ownrecv db; + setKartRimType(int8 = -1) required broadcast ownrecv db; + setKartDecalType(int8 = -1) required broadcast ownrecv db; updateKartDNAField(int8, int8) ownsend airecv; addOwnedAccessory(int8) ownsend airecv; removeOwnedAccessory(int8) ownsend airecv; - setTickets(uint32) required broadcast ownrecv db; - setKartingHistory(uint8 [16]) required ownrecv db; - setKartingTrophies(uint8 [33]) required ownrecv db; - setKartingPersonalBest(uint32/1000 [6]) required ownrecv db; - setKartingPersonalBest2(uint32/1000 [12]) required ownrecv db; - setKartAccessoriesOwned(int8 [16]) required broadcast ownrecv db; + setTickets(uint32 = 200) required broadcast ownrecv db; + setKartingHistory(uint8 [16] = [0 * 16]) required ownrecv db; + setKartingTrophies(uint8 [33] = [0 * 33]) required ownrecv db; + setKartingPersonalBest(uint32/1000 [6] = [0 * 6]) required ownrecv db; + setKartingPersonalBest2(uint32/1000 [12] = [0 * 12]) required ownrecv db; + setKartAccessoriesOwned(int8 [16] = [-1 * 16]) required broadcast ownrecv db; setCurrentKart(uint32) broadcast ownrecv ram; squish(uint8) ownsend airecv; announceBingo() broadcast ownrecv; trickOrTreatTargetMet(uint32) ownrecv; trickOrTreatMilestoneMet() ownrecv; winterCarolingTargetMet(uint32) ownrecv; - setCogSummonsEarned(uint8[]) required ownrecv db; + setCogSummonsEarned(uint8[] = [0 * 32]) required ownrecv db; reqCogSummons(char [0-256], uint32) ownsend airecv; cogSummonsResponse(string, uint32, uint32) ownrecv; reqUseSpecial(int32) ownsend airecv; useSpecialResponse(string) ownrecv; - setGardenStarted(uint8) required ownrecv db; + setGardenStarted(uint8 = 0) required ownrecv db; sendToGolfCourse(uint32) ownrecv; - setGolfHistory(uint16 [18]) required ownrecv db; - setPackedGolfHoleBest(uint8 [18]) required ownrecv db; - setGolfCourseBest(uint8 [3]) required ownrecv db; + setGolfHistory(uint16 [18] = [0 * 18]) required ownrecv db; + setPackedGolfHoleBest(uint8 [18] = [0 * 18]) required ownrecv db; + setGolfCourseBest(uint8 [3] = [0 * 3]) required ownrecv db; setUnlimitedSwing(uint8) broadcast ownrecv ram; logSuspiciousEvent(char [0-1024]) ownsend airecv; logMessage(char [0-1024]) ownsend airecv; forceLogoutWithNotify() ownrecv; - setPinkSlips(uint8) required ownrecv db; - setNametagStyle(uint8) broadcast required ram db; + setPinkSlips(uint8 = 0) required ownrecv db; + setNametagStyle(uint8 = 0) broadcast required ram db; setMail(simpleMail []) ownrecv; setNumMailItems(uint32) airecv; setSimpleMailNotify(uint8) ownrecv airecv; @@ -3269,4 +3269,3 @@ dclass DistributedTrashcanZeroMgr : DistributedPhaseEventMgr { dclass DistributedSillyMeterMgr : DistributedPhaseEventMgr { }; - diff --git a/libotp/settings/Settings.py b/libotp/settings/Settings.py index 9764b1b..8edf12c 100644 --- a/libotp/settings/Settings.py +++ b/libotp/settings/Settings.py @@ -42,3 +42,11 @@ class Settings: @staticmethod def doSavedSettingsExist(): return 0 + + @staticmethod + def getAcceptingNewFriends(): + return 1 + + @staticmethod + def getAcceptingNonFriendWhispers(): + return 1 diff --git a/otp/distributed/OTPClientRepository.py b/otp/distributed/OTPClientRepository.py index 5e7001c..ad0295c 100644 --- a/otp/distributed/OTPClientRepository.py +++ b/otp/distributed/OTPClientRepository.py @@ -956,18 +956,18 @@ class OTPClientRepository(ClientRepositoryBase): @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def _requestAvatarList(self): - if not self.astronSupport: - self.sendGetAvatarsMsg() - else: - self.astronLoginManager.sendRequestAvatarList() + self.sendGetAvatarsMsg() self.waitForDatabaseTimeout(requestName='WaitForAvatarList') self.acceptOnce(OtpAvatarManager.OtpAvatarManager.OnlineEvent, self._requestAvatarList) @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def sendGetAvatarsMsg(self): - datagram = PyDatagram() - datagram.addUint16(CLIENT_GET_AVATARS) - self.send(datagram) + if self.astronSupport: + self.astronLoginManager.sendRequestAvatarList() + else: + datagram = PyDatagram() + datagram.addUint16(CLIENT_GET_AVATARS) + self.send(datagram) @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def exitWaitForAvatarList(self): @@ -1086,16 +1086,20 @@ class OTPClientRepository(ClientRepositoryBase): @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def enterWaitForDeleteAvatarResponse(self, potAv): - self.handler = self.handleWaitForDeleteAvatarResponse + if not self.astronSupport: + self.handler = self.handleWaitForDeleteAvatarResponse self.sendDeleteAvatarMsg(potAv.id) self.waitForDatabaseTimeout(requestName='WaitForDeleteAvatarResponse') @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def sendDeleteAvatarMsg(self, avId): - datagram = PyDatagram() - datagram.addUint16(CLIENT_DELETE_AVATAR) - datagram.addUint32(avId) - self.send(datagram) + if self.astronSupport: + self.astronLoginManager.sendRequestRemoveAvatar(avId) + else: + datagram = PyDatagram() + datagram.addUint16(CLIENT_DELETE_AVATAR) + datagram.addUint32(avId) + self.send(datagram) @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def exitWaitForDeleteAvatarResponse(self): @@ -1133,7 +1137,8 @@ class OTPClientRepository(ClientRepositoryBase): @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def enterWaitForSetAvatarResponse(self, potAv): - self.handler = self.handleWaitForSetAvatarResponse + if not self.astronSupport: + self.handler = self.handleWaitForSetAvatarResponse self.sendSetAvatarMsg(potAv) self.waitForDatabaseTimeout(requestName='WaitForSetAvatarResponse') @@ -1152,10 +1157,13 @@ class OTPClientRepository(ClientRepositoryBase): def sendSetAvatarIdMsg(self, avId): if avId != self.__currentAvId: self.__currentAvId = avId - datagram = PyDatagram() - datagram.addUint16(CLIENT_SET_AVATAR) - datagram.addUint32(avId) - self.send(datagram) + if self.astronSupport: + self.astronLoginManager.sendRequestPlayAvatar(avId) + else: + datagram = PyDatagram() + datagram.addUint16(CLIENT_SET_AVATAR) + datagram.addUint32(avId) + self.send(datagram) if avId == 0: self.stopPeriodTimer() else: @@ -1413,7 +1421,8 @@ class OTPClientRepository(ClientRepositoryBase): @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def enterWaitOnEnterResponses(self, shardId, hoodId, zoneId, avId): self.cleanGameExit = False - self.handler = self.handleWaitOnEnterResponses + if not self.astronSupport: + self.handler = self.handleWaitOnEnterResponses self.handlerArgs = {'hoodId': hoodId, 'zoneId': zoneId, 'avId': avId} @@ -1635,33 +1644,52 @@ class OTPClientRepository(ClientRepositoryBase): else: self.gameFSM.request('playGame', [hoodId, zoneId, avId]) - def handlePlayGame(self, msgType, di): - if self.notify.getDebug(): - self.notify.debug('handle play game got message type: ' + `msgType`) - if msgType == CLIENT_CREATE_OBJECT_REQUIRED: - self.handleGenerateWithRequired(di) - elif msgType == CLIENT_CREATE_OBJECT_REQUIRED_OTHER: - self.handleGenerateWithRequiredOther(di) - elif msgType == CLIENT_OBJECT_UPDATE_FIELD: - self.handleUpdateField(di) - elif msgType == CLIENT_OBJECT_DISABLE_RESP: - self.handleDisable(di) - elif msgType == CLIENT_OBJECT_DELETE_RESP: - self.handleDelete(di) - elif msgType == CLIENT_GET_FRIEND_LIST_RESP: - self.handleGetFriendsList(di) - elif msgType == CLIENT_GET_FRIEND_LIST_EXTENDED_RESP: - self.handleGetFriendsListExtended(di) - elif msgType == CLIENT_FRIEND_ONLINE: - self.handleFriendOnline(di) - elif msgType == CLIENT_FRIEND_OFFLINE: - self.handleFriendOffline(di) - elif msgType == CLIENT_GET_AVATAR_DETAILS_RESP: - self.handleGetAvatarDetailsResp(di) - elif msgType == CLIENT_GET_PET_DETAILS_RESP: - self.handleGetAvatarDetailsResp(di) - else: - self.handleMessageType(msgType, di) + if not config.GetBool('astron-support', True): + def handlePlayGame(self, msgType, di): + if self.notify.getDebug(): + self.notify.debug('handle play game got message type: ' + `msgType`) + if msgType == CLIENT_CREATE_OBJECT_REQUIRED: + self.handleGenerateWithRequired(di) + elif msgType == CLIENT_CREATE_OBJECT_REQUIRED_OTHER: + self.handleGenerateWithRequiredOther(di) + elif msgType == CLIENT_OBJECT_UPDATE_FIELD: + self.handleUpdateField(di) + elif msgType == CLIENT_OBJECT_DISABLE_RESP: + self.handleDisable(di) + elif msgType == CLIENT_OBJECT_DELETE_RESP: + self.handleDelete(di) + elif msgType == CLIENT_GET_FRIEND_LIST_RESP: + self.handleGetFriendsList(di) + elif msgType == CLIENT_GET_FRIEND_LIST_EXTENDED_RESP: + self.handleGetFriendsListExtended(di) + elif msgType == CLIENT_FRIEND_ONLINE: + self.handleFriendOnline(di) + elif msgType == CLIENT_FRIEND_OFFLINE: + self.handleFriendOffline(di) + elif msgType == CLIENT_GET_AVATAR_DETAILS_RESP: + self.handleGetAvatarDetailsResp(di) + elif msgType == CLIENT_GET_PET_DETAILS_RESP: + self.handleGetAvatarDetailsResp(di) + else: + self.handleMessageType(msgType, di) + else: + def handlePlayGame(self, msgType, di): + if self.notify.getDebug(): + self.notify.debug('handle play game got message type: ' + `msgType`) + if msgType == CLIENT_ENTER_OBJECT_REQUIRED: + self.handleGenerateWithRequired(di) + elif msgType == CLIENT_ENTER_OBJECT_REQUIRED_OTHER: + self.handleGenerateWithRequiredOther(di) + elif msgType == CLIENT_OBJECT_SET_FIELD: + self.handleUpdateField(di) + elif msgType == CLIENT_OBJECT_DISABLE: + self.handleDisable(di) + elif msgType == CLIENT_OBJECT_DISABLE_OWNER: + self.handleDisable(di, ownerView=True) + elif msgType == CLIENT_OBJECT_DELETE_RESP: + self.handleDelete(di) + else: + self.handleMessageType(msgType, di) @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def enterSwitchShards(self, shardId, hoodId, zoneId, avId): @@ -2226,6 +2254,36 @@ class OTPClientRepository(ClientRepositoryBase): self.doGenerate(parentId, zoneId, classId, doId, di) else: self.doGenerate(parentId, zoneId, classId, doId, di) + + def handleGenerateWithRequiredOtherOwner(self, di): + classId = di.getUint16() + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + dclass = self.dclassesByNumber[classId] + dclass.startGenerate() + distObj = self.generateWithRequiredOtherFieldsOwner(dclass, doId, di) + dclass.stopGenerate() + + def handleQuietZoneGenerateWithRequired(self, di): + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + doId = di.getUint32() + dclass = self.dclassesByNumber[classId] + dclass.startGenerate() + distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() + + def handleQuietZoneGenerateWithRequiredOther(self, di): + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + doId = di.getUint32() + dclass = self.dclassesByNumber[classId] + dclass.startGenerate() + distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() else: def handleGenerateWithRequired(self, di, other=False): doId = di.getUint32() @@ -2356,6 +2414,36 @@ class OTPClientRepository(ClientRepositoryBase): # We're done. dclass.stopGenerate() + def handleGenerateWithRequiredOtherOwner(self, di): + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + dclass = self.dclassesByNumber[classId] + dclass.startGenerate() + distObj = self.generateWithRequiredOtherFieldsOwner(dclass, doId, di) + dclass.stopGenerate() + + def handleQuietZoneGenerateWithRequired(self, di): + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + dclass = self.dclassesByNumber[classId] + dclass.startGenerate() + distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() + + def handleQuietZoneGenerateWithRequiredOther(self, di): + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + dclass = self.dclassesByNumber[classId] + dclass.startGenerate() + distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() + @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def handleAvatarListResponse(self, avatarList): avList = [] @@ -2379,36 +2467,6 @@ class OTPClientRepository(ClientRepositoryBase): self.avList = avList self.loginFSM.request('chooseAvatar', [self.avList]) - def handleGenerateWithRequiredOtherOwner(self, di): - classId = di.getUint16() - doId = di.getUint32() - parentId = di.getUint32() - zoneId = di.getUint32() - dclass = self.dclassesByNumber[classId] - dclass.startGenerate() - distObj = self.generateWithRequiredOtherFieldsOwner(dclass, doId, di) - dclass.stopGenerate() - - def handleQuietZoneGenerateWithRequired(self, di): - parentId = di.getUint32() - zoneId = di.getUint32() - classId = di.getUint16() - doId = di.getUint32() - dclass = self.dclassesByNumber[classId] - dclass.startGenerate() - distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) - dclass.stopGenerate() - - def handleQuietZoneGenerateWithRequiredOther(self, di): - parentId = di.getUint32() - zoneId = di.getUint32() - classId = di.getUint16() - doId = di.getUint32() - dclass = self.dclassesByNumber[classId] - dclass.startGenerate() - distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId) - dclass.stopGenerate() - def handleDisable(self, di, ownerView = False): doId = di.getUint32() if not self.isLocalId(doId): diff --git a/otp/distributed/OTPInternalRepository.py b/otp/distributed/OTPInternalRepository.py index 77972be..7be3a75 100644 --- a/otp/distributed/OTPInternalRepository.py +++ b/otp/distributed/OTPInternalRepository.py @@ -15,3 +15,6 @@ class OTPInternalRepository(AstronInternalRepository): def getAccountIdFromSender(self): return (self.getMsgSender() >> 32) & 0xFFFFFFFF + + def getAvatarIdFromSender(self): + return self.getMsgSender() & 0xFFFFFFFF diff --git a/otp/friends/FriendSecret.py b/otp/friends/FriendSecret.py index f812535..a2962c4 100644 --- a/otp/friends/FriendSecret.py +++ b/otp/friends/FriendSecret.py @@ -1,4 +1,5 @@ from pandac.PandaModules import * +from libotp import * from direct.gui.DirectGui import * from direct.directnotify import DirectNotifyGlobal from direct.fsm import StateData diff --git a/otp/login/AstronLoginManager.py b/otp/login/AstronLoginManager.py index 188b765..fb06589 100644 --- a/otp/login/AstronLoginManager.py +++ b/otp/login/AstronLoginManager.py @@ -149,3 +149,9 @@ class AstronLoginManager(DistributedObjectGlobal): def acknowledgeAvatarNameResponse(self): self._callback() + + def sendRequestRemoveAvatar(self, avId): + self.sendUpdate('requestRemoveAvatar', [avId]) + + def sendRequestPlayAvatar(self, avId): + self.sendUpdate('requestPlayAvatar', [avId]) diff --git a/otp/login/AstronLoginManagerUD.py b/otp/login/AstronLoginManagerUD.py index 9e867f6..202307a 100644 --- a/otp/login/AstronLoginManagerUD.py +++ b/otp/login/AstronLoginManagerUD.py @@ -191,6 +191,7 @@ class LoginOperation: class GetAvatarsOperation: + notify = DirectNotifyGlobal.directNotify.newCategory('GetAvatarsOperation') def __init__(self, loginManager, sender): self.loginManager = loginManager @@ -549,6 +550,181 @@ class AcknowledgeNameOperation: del self.loginManager.account2operation[self.sender] +class RemoveAvatarOperation: + notify = DirectNotifyGlobal.directNotify.newCategory('RemoveAvatarOperation') + + def __init__(self, loginManager, sender): + self.loginManager = loginManager + self.sender = sender + self.account = None + self.avList = [] + self.pendingAvatars = None + self.avatarFields = None + self.avId = None + + def start(self, avId): + self.avId = avId + self.loginManager.air.dbInterface.queryObject(self.loginManager.air.dbId, self.sender, self.__handleAccountRetrieved) + + def __handleAccountRetrieved(self, dclass, fields): + if dclass != self.loginManager.air.dclassesByName['AstronAccountUD']: + # no uwu + return + + self.account = fields + self.avList = self.account['ACCOUNT_AV_SET'] + self.avList = self.avList[:6] + self.avList += [0] * (6 - len(self.avList)) + self.__handleRemoveAvatar() + + def __handleRemoveAvatar(self): + if self.avId not in self.avList: + # avatar doesn't exist. + return + + index = self.avList.index(self.avId) + self.avList[index] = 0 + avatarsRemoved = list(self.account.get('ACCOUNT_AV_SET_DEL', [])) + avatarsRemoved.append([self.avId, int(time.time())]) + estateId = self.account.get('ESTATE_ID', 0) + if estateId != 0: + self.loginManager.air.dbInterface.updateObject(self.loginManager.air.dbId, estateId, + self.loginManager.air.dclassesByName['DistributedEstateAI'], + {'setSlot%sToonId' % index: [0], + 'setSlot%sItems' % index: [[]]}) + + self.loginManager.air.dbInterface.updateObject(self.loginManager.air.dbId, self.sender, self.loginManager.air.dclassesByName['AstronAccountUD'], + {'ACCOUNT_AV_SET': self.avList, + 'ACCOUNT_AV_SET_DEL': avatarsRemoved}, + {'ACCOUNT_AV_SET': self.account['ACCOUNT_AV_SET'], + 'ACCOUNT_AV_SET_DEL': self.account['ACCOUNT_AV_SET_DEL']}, + self.__handleAvatarRemoved) + + def __handleAvatarRemoved(self, fields): + if fields: + # failed to remove the avatar. + return + + self.__handleQueryAvatars() + + def __handleQueryAvatars(self): + self.pendingAvatars = set() + self.avatarFields = {} + for avId in self.avList: + if avId: + self.pendingAvatars.add(avId) + def response(dclass, fields, avId=avId): + if dclass != self.loginManager.air.dclassesByName['DistributedToonUD']: + # mayonnaise + return + + self.avatarFields[avId] = fields + self.pendingAvatars.remove(avId) + if not self.pendingAvatars: + self.__handleSendAvatars() + + self.loginManager.air.dbInterface.queryObject(self.loginManager.air.dbId, avId, response) + + if not self.pendingAvatars: + self.__handleSendAvatars() + + def __handleSendAvatars(self): + potentialAvatars = [] + for avId, fields in self.avatarFields.items(): + index = self.avList.index(avId) + wishNameState = fields.get('WishNameState', [''])[0] + name = fields['setName'][0] + nameState = 0 + if wishNameState == 'OPEN': + nameState = 1 + elif wishNameState == 'PENDING': + nameState = 2 + elif wishNameState == 'APPROVED': + nameState = 3 + name = fields['WishName'][0] + elif wishNameState == 'REJECTED': + nameState = 4 + elif wishNameState == 'LOCKED': + nameState = 0 + else: + # unknown name state. + nameState = 0 + + potentialAvatars.append([avId, name, fields['setDNAString'][0], index, nameState]) + + self.loginManager.sendUpdateToAccountId(self.sender, 'avatarListResponse', [potentialAvatars]) + del self.loginManager.account2operation[self.sender] + + +class LoadAvatarOperation: + notify = DirectNotifyGlobal.directNotify.newCategory('LoadAvatarOperation') + + def __init__(self, loginManager, sender): + self.loginManager = loginManager + self.sender = sender + self.avId = None + + def start(self, avId): + self.avId = avId + self.__handleRetrieveAccount() + + def __handleRetrieveAccount(self): + self.loginManager.air.dbInterface.queryObject(self.loginManager.air.dbId, self.sender, self.__handleAccountRetrieved) + + def __handleAccountRetrieved(self, dclass, fields): + if dclass != self.loginManager.air.dclassesByName['AstronAccountUD']: + # no uwu + return + + self.account = fields + self.avList = self.account['ACCOUNT_AV_SET'] + self.avList = self.avList[:6] + self.avList += [0] * (6 - len(self.avList)) + self.__handleGetTargetAvatar() + + def __handleGetTargetAvatar(self): + if self.avId not in self.avList: + return + + self.loginManager.air.dbInterface.queryObject(self.loginManager.air.dbId, self.avId, self.__handleAvatarRetrieved) + + def __handleAvatarRetrieved(self, dclass, fields): + if dclass != self.loginManager.air.dclassesByName['DistributedToonUD']: + return + + self.avatar = fields + self.__handleSetAvatar() + + def __handleSetAvatar(self): + channel = self.loginManager.GetAccountConnectionChannel(self.sender) + + cleanupDatagram = PyDatagram() + cleanupDatagram.addServerHeader(self.avId, channel, STATESERVER_OBJECT_DELETE_RAM) + cleanupDatagram.addUint32(self.avId) + datagram = PyDatagram() + datagram.addServerHeader(channel, self.loginManager.air.ourChannel, CLIENTAGENT_ADD_POST_REMOVE) + datagram.addString(cleanupDatagram.getMessage()) + self.loginManager.air.send(datagram) + + self.loginManager.air.sendActivate(self.avId, 0, 0, self.loginManager.air.dclassesByName['DistributedToonUD']) + + datagram = PyDatagram() + datagram.addServerHeader(channel, self.loginManager.air.ourChannel, CLIENTAGENT_OPEN_CHANNEL) + datagram.addChannel(self.loginManager.GetPuppetConnectionChannel(self.avId)) + self.loginManager.air.send(datagram) + + self.loginManager.air.clientAddSessionObject(channel, self.avId) + + datagram = PyDatagram() + datagram.addServerHeader(channel, self.loginManager.air.ourChannel, CLIENTAGENT_SET_CLIENT_ID) + datagram.addChannel(self.sender << 32 | self.avId) # accountId in high 32 bits, avatar in low. + self.loginManager.air.send(datagram) + + self.loginManager.air.setOwner(self.avId, channel) + + del self.loginManager.account2operation[self.sender] + + class AstronLoginManagerUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory('AstronLoginManagerUD') @@ -653,3 +829,45 @@ class AstronLoginManagerUD(DistributedObjectGlobalUD): newOperation = AcknowledgeNameOperation(self, sender) self.account2operation[sender] = newOperation newOperation.start(avId) + + def requestRemoveAvatar(self, avId): + sender = self.air.getAccountIdFromSender() + if not sender: + # TODO KILL CONNECTION + return + + if sender in self.account2operation: + # BAD!!!! + return + + newOperation = RemoveAvatarOperation(self, sender) + self.account2operation[sender] = newOperation + newOperation.start(avId) + + def requestPlayAvatar(self, avId): + currentAvId = self.air.getAvatarIdFromSender() + accId = self.air.getAccountIdFromSender() + if currentAvId and avId: + # todo: kill the connection + return + elif not currentAvId and not avId: + # I don't think we need to do anything extra here + return + + sender = self.air.getAccountIdFromSender() + if not sender: + # TODO KILL CONNECTION + return + + if sender in self.account2operation: + # BAD!!!! + return + + if avId: + newOperation = LoadAvatarOperation(self, sender) + self.account2operation[sender] = newOperation + newOperation.start(avId) + else: + newOperation = UnloadAvatarOperation(self, sender) + self.account2operation[sender] = newOperation + newOperation.start(currentAvId) diff --git a/otp/login/LoginAstronAccount.py b/otp/login/LoginAstronAccount.py index a9b5b04..e42441a 100644 --- a/otp/login/LoginAstronAccount.py +++ b/otp/login/LoginAstronAccount.py @@ -23,3 +23,6 @@ class LoginAstronAccount(LoginBase): if __debug__: return 1 return 0 + + def supportsAuthenticateDelete(self): + return 0 diff --git a/toontown/ai/HolidayManagerAI.py b/toontown/ai/HolidayManagerAI.py new file mode 100644 index 0000000..8f4d17f --- /dev/null +++ b/toontown/ai/HolidayManagerAI.py @@ -0,0 +1,4 @@ +class HolidayManagerAI: + def __init__(self, air): + self.air = air + self.currentHolidays = {} diff --git a/toontown/ai/ToontownAIRepository.py b/toontown/ai/ToontownAIRepository.py index 0fa236f..0551fb8 100644 --- a/toontown/ai/ToontownAIRepository.py +++ b/toontown/ai/ToontownAIRepository.py @@ -1,16 +1,25 @@ from direct.directnotify import DirectNotifyGlobal +from otp.ai.AIZoneData import AIZoneDataStore +from otp.distributed.OtpDoGlobals import * from toontown.distributed.ToontownInternalRepository import ToontownInternalRepository from toontown.distributed.ToontownDistrictAI import ToontownDistrictAI -from otp.distributed.OtpDoGlobals import * +from toontown.ai.HolidayManagerAI import HolidayManagerAI +from toontown.catalog.CatalogManagerAI import CatalogManagerAI +from toontown.uberdog.DistributedInGameNewsMgrAI import DistributedInGameNewsMgrAI class ToontownAIRepository(ToontownInternalRepository): notify = DirectNotifyGlobal.directNotify.newCategory('ToontownAIRepository') def __init__(self, baseChannel, serverId, districtName): ToontownInternalRepository.__init__(self, baseChannel, serverId, dcSuffix='AI') + self.doLiveUpdates = config.GetBool('want-live-updates', True) self.districtName = districtName self.districtId = None self.district = None + self.holidayManager = None + self.zoneDataStore = None + self.inGameNewsMgr = None + self.catalogManager = None def handleConnected(self): ToontownInternalRepository.handleConnected(self) @@ -24,6 +33,53 @@ class ToontownAIRepository(ToontownInternalRepository): # Claim ownership of that district... self.district.setAI(self.ourChannel) + # Create our local objects. + self.createLocals() + + # Create our global objects. + self.createGlobals() + # Make our district available, and we're done. self.district.b_setAvailable(True) self.notify.info('Done.') + + def createLocals(self): + """ + Creates "local" (non-distributed) objects. + """ + + # Create our holiday manager... + self.holidayManager = HolidayManagerAI(self) + + # Create our zone data store... + self.zoneDataStore = AIZoneDataStore() + + def createGlobals(self): + """ + Creates "global" (distributed) objects. + """ + + # Generate our in-game news manager... + self.inGameNewsMgr = DistributedInGameNewsMgrAI(self) + self.inGameNewsMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT) + + # Generate our catalog manager... + self.catalogManager = CatalogManagerAI(self) + + def getTrackClsends(self): + return False + + def getAvatarExitEvent(self, avId): + return 'distObjDelete-%d' % avId + + def getZoneDataStore(self): + return self.zoneDataStore + + def incrementPopulation(self): + print 'TODO districtStats' + + def decrementPopulation(self): + print 'TODO districtStats' + + def sendQueryToonMaxHp(self, avId, callback): + pass # TODO? diff --git a/toontown/catalog/CatalogManagerAI.py b/toontown/catalog/CatalogManagerAI.py index 47db795..e348b12 100644 --- a/toontown/catalog/CatalogManagerAI.py +++ b/toontown/catalog/CatalogManagerAI.py @@ -3,3 +3,9 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI class CatalogManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory('CatalogManagerAI') + + def startCatalog(self): + pass + + def deliverCatalogFor(self, _): + pass diff --git a/toontown/chat/TTWhiteList.py b/toontown/chat/TTWhiteList.py index 21d7085..8027172 100644 --- a/toontown/chat/TTWhiteList.py +++ b/toontown/chat/TTWhiteList.py @@ -3,7 +3,6 @@ import datetime from pandac.PandaModules import * from direct.directnotify import DirectNotifyGlobal from direct.distributed import DistributedObject -from direct.showbase import AppRunnerGlobal from otp.chat.WhiteList import WhiteList from toontown.toonbase import TTLocalizer @@ -23,14 +22,8 @@ class TTWhiteList(WhiteList, DistributedObject.DistributedObject): vfs = VirtualFileSystem.getGlobalPtr() filename = Filename('twhitelist.dat') searchPath = DSearchPath() - if AppRunnerGlobal.appRunner: - searchPath.appendDirectory(Filename.expandFrom('$TT_3_ROOT/phase_3/etc')) - else: - searchPath.appendDirectory(Filename('.')) - searchPath.appendDirectory(Filename('etc')) - searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('$TOONTOWN/src/chat'))) - searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('toontown/src/chat'))) - searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('toontown/chat'))) + if __debug__: + searchPath.appendDirectory(Filename('resources/phase_3/etc')) found = vfs.resolveFilename(filename, searchPath) if not found: self.notify.info("Couldn't find whitelist data file!") diff --git a/toontown/distributed/PlayGame.py b/toontown/distributed/PlayGame.py index 9d3a6bf..37a131f 100644 --- a/toontown/distributed/PlayGame.py +++ b/toontown/distributed/PlayGame.py @@ -1,4 +1,5 @@ from pandac.PandaModules import * +from libtoontown import * from toontown.toonbase.ToonBaseGlobal import * from direct.directnotify import DirectNotifyGlobal from direct.fsm import StateData diff --git a/toontown/distributed/ToontownClientRepository.py b/toontown/distributed/ToontownClientRepository.py index 6842917..b92ccfc 100644 --- a/toontown/distributed/ToontownClientRepository.py +++ b/toontown/distributed/ToontownClientRepository.py @@ -322,7 +322,8 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): self.avCreate = MakeAToon.MakeAToon(self.loginFSM, avList, 'makeAToonComplete', index, self.isPaid()) self.avCreate.load() self.avCreate.enter() - self.handler = self.handleCreateAvatar + if not self.astronSupport: + self.handler = self.handleCreateAvatar self.accept('makeAToonComplete', self.__handleMakeAToon, [avList, index]) self.accept('nameShopCreateAvatar', self.sendCreateAvatarMsg) self.accept('nameShopPost', self.relayMessage) @@ -332,13 +333,10 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): self.send(dg) def handleCreateAvatar(self, msgType, di): - if self.astronSupport: - self.handleMessageType(msgType, di) + if msgType == CLIENT_CREATE_AVATAR_RESP or msgType == CLIENT_SET_NAME_PATTERN_ANSWER or msgType == CLIENT_SET_WISHNAME_RESP: + self.avCreate.ns.nameShopHandler(msgType, di) else: - if msgType == CLIENT_CREATE_AVATAR_RESP or msgType == CLIENT_SET_NAME_PATTERN_ANSWER or msgType == CLIENT_SET_WISHNAME_RESP: - self.avCreate.ns.nameShopHandler(msgType, di) - else: - self.handleMessageType(msgType, di) + self.handleMessageType(msgType, di) def __handleMakeAToon(self, avList, avPosition): done = self.avCreate.getDoneStatus() @@ -372,11 +370,38 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): del self.newPotAv return - def handleAvatarResponseMsg(self, di): - self.cleanupWaitingForDatabase() - avatarId = di.getUint32() - returnCode = di.getUint8() - if returnCode == 0: + if not config.GetBool('astron-support', True): + def handleAvatarResponseMsg(self, di): + self.cleanupWaitingForDatabase() + avatarId = di.getUint32() + returnCode = di.getUint8() + if returnCode == 0: + dclass = self.dclassesByName['DistributedToon'] + NametagGlobals.setMasterArrowsOn(0) + loader.beginBulkLoad('localAvatarPlayGame', OTPLocalizer.CREnteringToontown, 400, 1, TTLocalizer.TIP_GENERAL) + localAvatar = LocalToon.LocalToon(self) + localAvatar.dclass = dclass + base.localAvatar = localAvatar + __builtins__['localAvatar'] = base.localAvatar + NametagGlobals.setToon(base.localAvatar) + localAvatar.doId = avatarId + self.localAvatarDoId = avatarId + parentId = None + zoneId = None + localAvatar.setLocation(parentId, zoneId) + localAvatar.generateInit() + localAvatar.generate() + localAvatar.updateAllRequiredFields(dclass, di) + self.doId2do[avatarId] = localAvatar + localAvatar.initInterface() + self.sendGetFriendsListRequest() + self.loginFSM.request('playingGame') + else: + self.notify.error('Bad avatar: return code %d' % returnCode) + return + else: + def handleAvatarResponseMsg(self, avatarId, di): + self.cleanupWaitingForDatabase() dclass = self.dclassesByName['DistributedToon'] NametagGlobals.setMasterArrowsOn(0) loader.beginBulkLoad('localAvatarPlayGame', OTPLocalizer.CREnteringToontown, 400, 1, TTLocalizer.TIP_GENERAL) @@ -392,14 +417,13 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): localAvatar.setLocation(parentId, zoneId) localAvatar.generateInit() localAvatar.generate() - localAvatar.updateAllRequiredFields(dclass, di) + dclass.receiveUpdateBroadcastRequiredOwner(localAvatar, di) + localAvatar.announceGenerate() + localAvatar.postGenerateMessage() self.doId2do[avatarId] = localAvatar localAvatar.initInterface() self.sendGetFriendsListRequest() self.loginFSM.request('playingGame') - else: - self.notify.error('Bad avatar: return code %d' % returnCode) - return def getAvatarDetails(self, avatar, func, *args): pad = ScratchPad() @@ -826,11 +850,14 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): self.friendsListError = 0 def sendGetFriendsListRequest(self): - self.friendsMapPending = 1 - self.friendsListError = 0 - datagram = PyDatagram() - datagram.addUint16(CLIENT_GET_FRIEND_LIST) - self.send(datagram) + if self.astronSupport: + print 'sendGetFriendsListRequest TODO' + else: + self.friendsMapPending = 1 + self.friendsListError = 0 + datagram = PyDatagram() + datagram.addUint16(CLIENT_GET_FRIEND_LIST) + self.send(datagram) def cleanPetsFromFriendsMap(self): for objId, obj in self.friendsMap.items(): @@ -1050,29 +1077,63 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): return True def sendQuietZoneRequest(self): - self.sendSetZoneMsg(OTPGlobals.QuietZone) + if self.astronSupport: + self.sendSetZoneMsg(OTPGlobals.QuietZone, []) + else: + self.sendSetZoneMsg(OTPGlobals.QuietZone) - def handleQuietZoneGenerateWithRequired(self, di): - parentId = di.getUint32() - zoneId = di.getUint32() - classId = di.getUint16() - doId = di.getUint32() - dclass = self.dclassesByNumber[classId] - if dclass.getClassDef().neverDisable: - dclass.startGenerate() - distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) - dclass.stopGenerate() + if not config.GetBool('astron-support', True): + def handleQuietZoneGenerateWithRequired(self, di): + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + doId = di.getUint32() + dclass = self.dclassesByNumber[classId] + if dclass.getClassDef().neverDisable: + dclass.startGenerate() + distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() - def handleQuietZoneGenerateWithRequiredOther(self, di): - parentId = di.getUint32() - zoneId = di.getUint32() - classId = di.getUint16() - doId = di.getUint32() - dclass = self.dclassesByNumber[classId] - if dclass.getClassDef().neverDisable: - dclass.startGenerate() - distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId) - dclass.stopGenerate() + def handleQuietZoneGenerateWithRequiredOther(self, di): + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + doId = di.getUint32() + dclass = self.dclassesByNumber[classId] + if dclass.getClassDef().neverDisable: + dclass.startGenerate() + distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() + else: + def handleQuietZoneGenerateWithRequired(self, di): + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + dclass = self.dclassesByNumber[classId] + if dclass.getClassDef().neverDisable: + dclass.startGenerate() + distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() + + def handleQuietZoneGenerateWithRequiredOther(self, di): + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + dclass = self.dclassesByNumber[classId] + if dclass.getClassDef().neverDisable: + dclass.startGenerate() + distObj = self.generateWithRequiredOtherFields(dclass, doId, di, parentId, zoneId) + dclass.stopGenerate() + + def handleGenerateWithRequiredOtherOwner(self, di): + if self.loginFSM.getCurrentState().getName() == 'waitForSetAvatarResponse': + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + classId = di.getUint16() + self.handleAvatarResponseMsg(doId, di) def handleQuietZoneUpdateField(self, di): di2 = DatagramIterator(di) diff --git a/toontown/distributed/ToontownInternalRepository.py b/toontown/distributed/ToontownInternalRepository.py index 80abfc1..b01334a 100644 --- a/toontown/distributed/ToontownInternalRepository.py +++ b/toontown/distributed/ToontownInternalRepository.py @@ -8,3 +8,9 @@ class ToontownInternalRepository(OTPInternalRepository): def __init__(self, baseChannel, serverId=None, dcFileNames=None, dcSuffix='AI', connectMethod=None, threadedNet=None): OTPInternalRepository.__init__(self, baseChannel, serverId, dcFileNames, dcSuffix, connectMethod, threadedNet) + + def _isValidPlayerLocation(self, parentId, zoneId): + if zoneId < 1000 and zoneId != -1: + return False + + return True diff --git a/toontown/friends/FriendsListManager.py b/toontown/friends/FriendsListManager.py index be5e2d1..eabeec7 100644 --- a/toontown/friends/FriendsListManager.py +++ b/toontown/friends/FriendsListManager.py @@ -1,4 +1,5 @@ from pandac.PandaModules import * +from libotp import * import FriendsListPanel import FriendInviter import FriendInvitee diff --git a/toontown/hood/Hood.py b/toontown/hood/Hood.py index fc64e07..8e8eb7b 100644 --- a/toontown/hood/Hood.py +++ b/toontown/hood/Hood.py @@ -12,6 +12,7 @@ import QuietZoneState import ZoneUtil from toontown.toonbase import TTLocalizer from toontown.toon.Toon import teleportDebug +from direct.interval.IntervalGlobal import * class Hood(StateData.StateData): notify = DirectNotifyGlobal.directNotify.newCategory('Hood') @@ -25,6 +26,7 @@ class Hood(StateData.StateData): self.id = None self.hoodId = hoodId self.titleText = None + self.titleTextSeq = None self.titleColor = (1, 1, 1, 1) self.holidayStorageDNADict = {} self.spookySkyFile = None @@ -56,19 +58,17 @@ class Hood(StateData.StateData): self.titleText.setColor(Vec4(*self.titleColor)) self.titleText.clearColorScale() self.titleText.setFg(self.titleColor) - seq = Task.sequence(Task.pause(0.1), Task.pause(6.0), self.titleText.lerpColorScale(Vec4(1.0, 1.0, 1.0, 1.0), Vec4(1.0, 1.0, 1.0, 0.0), 0.5), Task(self.hideTitleTextTask)) - taskMgr.add(seq, 'titleText') - - def hideTitleTextTask(self, task): - self.titleText.hide() - return Task.done + self.titleTextSeq = Sequence(Wait(0.1), Wait(6.0), self.titleText.colorScaleInterval(0.5, Vec4(1.0, 1.0, 1.0, 0.0), Vec4(1.0, 1.0, 1.0, 1.0)), Func(self.hideTitleText)) + self.titleTextSeq.start() def hideTitleText(self): if self.titleText: self.titleText.hide() def exit(self): - taskMgr.remove('titleText') + if self.titleTextSeq: + self.titleTextSeq.finish() + self.titleTextSeq = None if self.titleText: self.titleText.cleanup() self.titleText = None @@ -194,7 +194,9 @@ class Hood(StateData.StateData): self.spawnTitleText(requestStatus['zoneId']) def exitSafeZoneLoader(self): - taskMgr.remove('titleText') + if self.titleTextSeq: + self.titleTextSeq.finish() + self.titleTextSeq = None self.hideTitleText() self.ignore(self.loaderDoneEvent) self.loader.exit() diff --git a/toontown/hood/Place.py b/toontown/hood/Place.py index 55cb3ba..a7abcb0 100644 --- a/toontown/hood/Place.py +++ b/toontown/hood/Place.py @@ -111,7 +111,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager): def removeSetZoneCompleteCallback(self, token): if token is not None: - if token in self._setZoneCompleteLocalCallbacks: + if any(token == x[1] for x in self._setZoneCompleteLocalCallbacks._callbacks): self._setZoneCompleteLocalCallbacks.remove(token) qzsd = self._getQZState() if qzsd: diff --git a/toontown/hood/QuietZoneState.py b/toontown/hood/QuietZoneState.py index 3bb24f4..ef9ab71 100644 --- a/toontown/hood/QuietZoneState.py +++ b/toontown/hood/QuietZoneState.py @@ -138,18 +138,32 @@ class QuietZoneState(StateData.StateData): self._setZoneCompleteCallbacks.remove(token) return - def handleWaitForQuietZoneResponse(self, msgType, di): - self.notify.debug('handleWaitForQuietZoneResponse(' + 'msgType=' + str(msgType) + ', di=' + str(di) + ')') - if msgType == CLIENT_CREATE_OBJECT_REQUIRED: - base.cr.handleQuietZoneGenerateWithRequired(di) - elif msgType == CLIENT_CREATE_OBJECT_REQUIRED_OTHER: - base.cr.handleQuietZoneGenerateWithRequiredOther(di) - elif msgType == CLIENT_OBJECT_UPDATE_FIELD: - base.cr.handleQuietZoneUpdateField(di) - elif msgType in QUIET_ZONE_IGNORED_LIST: - self.notify.debug('ignoring unwanted message from previous zone') - else: - base.cr.handlePlayGame(msgType, di) + if not config.GetBool('astron-support', True): + def handleWaitForQuietZoneResponse(self, msgType, di): + self.notify.debug('handleWaitForQuietZoneResponse(' + 'msgType=' + str(msgType) + ', di=' + str(di) + ')') + if msgType == CLIENT_CREATE_OBJECT_REQUIRED: + base.cr.handleQuietZoneGenerateWithRequired(di) + elif msgType == CLIENT_CREATE_OBJECT_REQUIRED_OTHER: + base.cr.handleQuietZoneGenerateWithRequiredOther(di) + elif msgType == CLIENT_OBJECT_UPDATE_FIELD: + base.cr.handleQuietZoneUpdateField(di) + elif msgType in QUIET_ZONE_IGNORED_LIST: + self.notify.debug('ignoring unwanted message from previous zone') + else: + base.cr.handlePlayGame(msgType, di) + else: + def handleWaitForQuietZoneResponse(self, msgType, di): + self.notify.debug('handleWaitForQuietZoneResponse(' + 'msgType=' + str(msgType) + ', di=' + str(di) + ')') + if msgType == CLIENT_ENTER_OBJECT_REQUIRED: + base.cr.handleQuietZoneGenerateWithRequired(di) + elif msgType == CLIENT_ENTER_OBJECT_REQUIRED_OTHER: + base.cr.handleQuietZoneGenerateWithRequiredOther(di) + elif msgType == CLIENT_OBJECT_SET_FIELD: + base.cr.handleQuietZoneUpdateField(di) + elif msgType in QUIET_ZONE_IGNORED_LIST: + self.notify.debug('ignoring unwanted message from previous zone') + else: + base.cr.handlePlayGame(msgType, di) def handleWaitForZoneRedirect(self, msgType, di): self.notify.debug('handleWaitForZoneRedirect(' + 'msgType=' + str(msgType) + ', di=' + str(di) + ')') diff --git a/toontown/login/AvatarChoice.py b/toontown/login/AvatarChoice.py index 7eecb1d..3486ea6 100644 --- a/toontown/login/AvatarChoice.py +++ b/toontown/login/AvatarChoice.py @@ -219,7 +219,7 @@ class AvatarChoice(DirectButton): nameBalloon = loader.loadModel('phase_3/models/props/chatbox_input') okButtonImage = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr')) cancelButtonImage = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')) - self.deleteWithPasswordFrame = DirectFrame(pos=(0.0, 0.1, 0.2), parent=aspect2dp, relief=None, image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.4, 1.0, 1.0), text=deleteText, text_wordwrap=19, text_scale=TTLocalizer.ACdeleteWithPasswordFrame, text_pos=(0, 0.25), textMayChange=1, sortOrder=NO_FADE_SORT_INDEX) + self.deleteWithPasswordFrame = DirectFrame(pos=(0.0, 0.1, 0.2), parent=aspect2dp, relief=None, image=DGG.getDefaultDialogGeom(), image_color=ToontownGlobals.GlobalDialogColor, image_scale=(1.4, 1.0, 1.0), text=deleteText, text_wordwrap=19, text_scale=TTLocalizer.ACdeleteWithPasswordFrame, text_pos=(0, 0.25), textMayChange=1, sortOrder=DGG.NO_FADE_SORT_INDEX) self.deleteWithPasswordFrame.hide() if self.deleteWithPassword: self.passwordLabel = DirectLabel(parent=self.deleteWithPasswordFrame, relief=None, pos=(-0.07, 0.0, -0.2), text=TTLocalizer.AvatarChoicePassword, text_scale=0.08, text_align=TextNode.ARight, textMayChange=0) diff --git a/toontown/parties/CalendarGuiDay.py b/toontown/parties/CalendarGuiDay.py index 71d84ac..5c02b6b 100644 --- a/toontown/parties/CalendarGuiDay.py +++ b/toontown/parties/CalendarGuiDay.py @@ -202,7 +202,7 @@ class CalendarGuiDay(DirectFrame): except e: numItems = 0 - if numItems <= self.scrollList.numItemsVisible: + if numItems <= self.scrollList['numItemsVisible']: self.scrollList.incButton.hide() self.scrollList.decButton.hide() else: diff --git a/toontown/shtiker/OptionsPage.py b/toontown/shtiker/OptionsPage.py index a51d273..c4da4c3 100644 --- a/toontown/shtiker/OptionsPage.py +++ b/toontown/shtiker/OptionsPage.py @@ -128,14 +128,12 @@ class OptionsTabPage(DirectFrame): 'DirectX8': Settings.DX8} def __init__(self, parent = aspect2d): - self.parent = parent self.currentSizeIndex = None - DirectFrame.__init__(self, parent=self.parent, relief=None, pos=(0.0, 0.0, 0.0), scale=(1.0, 1.0, 1.0)) + DirectFrame.__init__(self, parent=parent, relief=None, pos=(0.0, 0.0, 0.0), scale=(1.0, 1.0, 1.0)) self.load() return def destroy(self): - self.parent = None DirectFrame.destroy(self) return @@ -473,13 +471,11 @@ class CodesTabPage(DirectFrame): notify = DirectNotifyGlobal.directNotify.newCategory('CodesTabPage') def __init__(self, parent = aspect2d): - self.parent = parent - DirectFrame.__init__(self, parent=self.parent, relief=None, pos=(0.0, 0.0, 0.0), scale=(1.0, 1.0, 1.0)) + DirectFrame.__init__(self, parent=parent, relief=None, pos=(0.0, 0.0, 0.0), scale=(1.0, 1.0, 1.0)) self.load() return def destroy(self): - self.parent = None DirectFrame.destroy(self) return diff --git a/toontown/shtiker/ShtikerBook.py b/toontown/shtiker/ShtikerBook.py index fc82e71..862c70a 100644 --- a/toontown/shtiker/ShtikerBook.py +++ b/toontown/shtiker/ShtikerBook.py @@ -1,4 +1,5 @@ from pandac.PandaModules import * +from libotp import * from toontown.toonbase import ToontownGlobals from direct.showbase import DirectObject from direct.fsm import StateData diff --git a/toontown/toon/DistributedToonAI.py b/toontown/toon/DistributedToonAI.py index bf78bee..215ac97 100644 --- a/toontown/toon/DistributedToonAI.py +++ b/toontown/toon/DistributedToonAI.py @@ -410,7 +410,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo def announceZoneChange(self, newZoneId, oldZoneId): from toontown.pets import PetObserve - self.air.welcomeValleyManager.toonSetZone(self.doId, newZoneId) + #self.air.welcomeValleyManager.toonSetZone(self.doId, newZoneId) # TODO broadcastZones = [oldZoneId, newZoneId] if self.isInEstate() or self.wasInEstate(): broadcastZones = union(broadcastZones, self.estateZones) diff --git a/toontown/toon/LocalToon.py b/toontown/toon/LocalToon.py index 3fc90f0..7f2faed 100644 --- a/toontown/toon/LocalToon.py +++ b/toontown/toon/LocalToon.py @@ -12,6 +12,7 @@ from direct.showbase import PythonUtil from direct.directnotify import DirectNotifyGlobal from direct.gui import DirectGuiGlobals from pandac.PandaModules import * +from libotp import * from otp.avatar import LocalAvatar from otp.login import LeaveToPayDialog from otp.avatar import PositionExaminer diff --git a/toontown/toonbase/ToontownLoader.py b/toontown/toonbase/ToontownLoader.py index b2970f7..dd9a91f 100644 --- a/toontown/toonbase/ToontownLoader.py +++ b/toontown/toonbase/ToontownLoader.py @@ -1,4 +1,5 @@ from pandac.PandaModules import * +from libtoontown import * from direct.directnotify.DirectNotifyGlobal import * from direct.showbase import Loader from toontown.toontowngui import ToontownLoadingScreen diff --git a/toontown/uberdog/DistributedInGameNewsMgrAI.py b/toontown/uberdog/DistributedInGameNewsMgrAI.py index 5f09b0b..ed199d1 100644 --- a/toontown/uberdog/DistributedInGameNewsMgrAI.py +++ b/toontown/uberdog/DistributedInGameNewsMgrAI.py @@ -3,3 +3,20 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI class DistributedInGameNewsMgrAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedInGameNewsMgrAI') + + def __init__(self, air): + DistributedObjectAI.__init__(self, air) + self.latestIssueStr = '' + + def setLatestIssueStr(self, latestIssueStr): + self.latestIssueStr = latestIssueStr + + def d_setLatestIssueStr(self, latestIssueStr): + self.sendUpdate('setLatestIssueStr', [latestIssueStr]) + + def b_setLatestIssueStr(self, latestIssueStr): + self.setLatestIssueStr(latestIssueStr) + self.d_setLatestIssueStr(latestIssueStr) + + def getLatestIssueStr(self): + return self.latestIssueStr