diff --git a/etc/otp.dc b/etc/otp.dc index 1151600..6f32aa4 100755 --- a/etc/otp.dc +++ b/etc/otp.dc @@ -534,4 +534,6 @@ dclass AstronLoginManager : DistributedObject { loginResponse(blob); requestAvatarList() clsend; avatarListResponse(PotentialAvatar[]); + createAvatar(blob, uint8) clsend; + createAvatarResponse(uint32); }; diff --git a/otp/avatar/Avatar.py b/otp/avatar/Avatar.py index e82c2c3..4834033 100644 --- a/otp/avatar/Avatar.py +++ b/otp/avatar/Avatar.py @@ -26,7 +26,7 @@ class Avatar(Actor, ShadowCaster): ManagesNametagAmbientLightChanged = False def __init__(self, other = None): - self.name = '' + self._name = '' try: self.Avatar_initialized return @@ -222,7 +222,7 @@ class Avatar(Actor, ShadowCaster): return OTPGlobals.AvatarDefaultRadius def getName(self): - return self.name + return self._name def getType(self): return self.avatarType @@ -231,7 +231,7 @@ class Avatar(Actor, ShadowCaster): if hasattr(self, 'isDisguised'): if self.isDisguised: return - self.name = name + self._name = name if hasattr(self, 'nametag'): self.nametag.setName(name) diff --git a/otp/distributed/OTPClientRepository.py b/otp/distributed/OTPClientRepository.py index 945e401..f651db2 100644 --- a/otp/distributed/OTPClientRepository.py +++ b/otp/distributed/OTPClientRepository.py @@ -1057,15 +1057,18 @@ class OTPClientRepository(ClientRepositoryBase): @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def sendCreateAvatarMsg(self, avDNA, avName, avPosition): - datagram = PyDatagram() - datagram.addUint16(CLIENT_CREATE_AVATAR) - datagram.addUint16(0) - datagram.addString(avDNA.makeNetString()) - datagram.addUint8(avPosition) - self.newName = avName - self.newDNA = avDNA - self.newPosition = avPosition - self.send(datagram) + if self.astronSupport: + self.astronLoginManager.sendCreateAvatar(avDNA, avName, avPosition) + else: + datagram = PyDatagram() + datagram.addUint16(CLIENT_CREATE_AVATAR) + datagram.addUint16(0) + datagram.addString(avDNA.makeNetString()) + datagram.addUint8(avPosition) + self.newName = avName + self.newDNA = avDNA + self.newPosition = avPosition + self.send(datagram) @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def sendCreateAvatar2Msg(self, avClass, avDNA, avName, avPosition): diff --git a/otp/login/AstronLoginManager.py b/otp/login/AstronLoginManager.py index f8c465b..c8aa2f4 100644 --- a/otp/login/AstronLoginManager.py +++ b/otp/login/AstronLoginManager.py @@ -120,3 +120,10 @@ class AstronLoginManager(DistributedObjectGlobal): def avatarListResponse(self, avatarList): self.cr.handleAvatarListResponse(avatarList) + + def sendCreateAvatar(self, avDNA, avName, avPosition): + # avName isn't used. Sad! + self.sendUpdate('createAvatar', [avDNA.makeNetString(), avPosition]) + + def createAvatarResponse(self, avId): + messenger.send('nameShopCreateAvatarDone', [avId]) diff --git a/otp/login/AstronLoginManagerUD.py b/otp/login/AstronLoginManagerUD.py index 384b513..2f99a1c 100644 --- a/otp/login/AstronLoginManagerUD.py +++ b/otp/login/AstronLoginManagerUD.py @@ -8,6 +8,8 @@ import time from direct.directnotify import DirectNotifyGlobal from direct.distributed.DistributedObjectGlobalUD import DistributedObjectGlobalUD from direct.distributed.PyDatagram import * +from toontown.toon.ToonDNA import ToonDNA +from toontown.toonbase import TTLocalizer class AccountDB: """ @@ -260,6 +262,89 @@ class GetAvatarsOperation: del self.loginManager.account2operation[self.sender] +class CreateAvatarOperation: + notify = DirectNotifyGlobal.directNotify.newCategory('CreateAvatarOperation') + + def __init__(self, loginManager, sender): + self.loginManager = loginManager + self.sender = sender + self.avPosition = None + self.avDNA = None + + def start(self, avDNA, avPosition): + if avPosition >= 6: + # NO!!!!!!! + return + + valid = ToonDNA().isValidNetString(avDNA) + if not valid: + # time to eat paste + return + + self.avPosition = avPosition + self.avDNA = avDNA + + 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)) + if self.avList[self.avPosition]: + # my leg + return + + self.__handleCreateAvatar() + + def __handleCreateAvatar(self): + dna = ToonDNA() + dna.makeFromNetString(self.avDNA) + colorString = TTLocalizer.NumToColor[dna.headColor] + animalType = TTLocalizer.AnimalToSpecies[dna.getAnimal()] + name = ' '.join((colorString, animalType)) + toonFields = {'setName': (name,), + 'WishNameState': ('OPEN',), + 'WishName': ('',), + 'setDNAString': (self.avDNA,), + 'setDISLid': (self.sender,)} + + self.loginManager.air.dbInterface.createObject(self.loginManager.air.dbId, self.loginManager.air.dclassesByName['DistributedToonUD'], toonFields, self.__handleToonCreated) + + def __handleToonCreated(self, avId): + if not avId: + # WHAT! + return + + self.avId = avId + self.__handleStoreAvatar() + + def __handleStoreAvatar(self): + self.avList[self.avPosition] = self.avId + self.loginManager.air.dbInterface.updateObject(self.loginManager.air.dbId, self.sender, self.loginManager.air.dclassesByName['AstronAccountUD'], + {'ACCOUNT_AV_SET': self.avList}, + {'ACCOUNT_AV_SET': self.account['ACCOUNT_AV_SET']}, + self.__handleAvatarStored) + + def __handleAvatarStored(self, fields): + if fields: + # What happen! + # Someone set up us the bomb. + # We get signal. + # What! + return + + self.loginManager.sendUpdateToAccountId(self.sender, 'createAvatarResponse', [self.avId]) + del self.loginManager.account2operation[self.sender] + + class AstronLoginManagerUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory('AstronLoginManagerUD') @@ -288,6 +373,8 @@ class AstronLoginManagerUD(DistributedObjectGlobalUD): self.sender2loginOperation[sender] = newLoginOperation newLoginOperation.start(playToken) + # TODO: CLEAN UP ALL THIS CODE!!!!!!!! + def requestAvatarList(self): sender = self.air.getAccountIdFromSender() if not sender: @@ -301,3 +388,17 @@ class AstronLoginManagerUD(DistributedObjectGlobalUD): newOperation = GetAvatarsOperation(self, sender) self.account2operation[sender] = newOperation newOperation.start() + + def createAvatar(self, avDNA, avPosition): + sender = self.air.getAccountIdFromSender() + if not sender: + # TODO KILL CONNECTION + return + + if sender in self.account2operation: + # BAD!!!! + return + + newOperation = CreateAvatarOperation(self, sender) + self.account2operation[sender] = newOperation + newOperation.start(avDNA, avPosition) diff --git a/toontown/distributed/ToontownClientRepository.py b/toontown/distributed/ToontownClientRepository.py index 6992d44..3d2429f 100644 --- a/toontown/distributed/ToontownClientRepository.py +++ b/toontown/distributed/ToontownClientRepository.py @@ -324,10 +324,13 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): self.send(dg) def handleCreateAvatar(self, 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 self.astronSupport: self.handleMessageType(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) def __handleMakeAToon(self, avList, avPosition): done = self.avCreate.getDoneStatus() diff --git a/toontown/makeatoon/NameShop.py b/toontown/makeatoon/NameShop.py index 54c0341..1496825 100644 --- a/toontown/makeatoon/NameShop.py +++ b/toontown/makeatoon/NameShop.py @@ -1004,18 +1004,46 @@ class NameShop(StateData.StateData): self.requestingSkipTutorial = False if not self.avExists or self.avExists and self.avId == 'deleteMe': messenger.send('nameShopCreateAvatar', [style, '', self.index]) + if base.cr.astronSupport: + self.accept('nameShopCreateAvatarDone', self.handleCreateAvatarResponseMsg) else: self.checkNameTyped() self.notify.debug('Ending Make A Toon: %s' % self.toon.style) base.cr.centralLogger.writeClientEvent('MAT - endingMakeAToon: %s' % self.toon.style) - def handleCreateAvatarResponseMsg(self, di): - self.notify.debug('handleCreateAvatarResponseMsg') - echoContext = di.getUint16() - returnCode = di.getUint8() - if returnCode == 0: + if not config.GetBool('astron-support', True): + def handleCreateAvatarResponseMsg(self, di): + self.notify.debug('handleCreateAvatarResponseMsg') + echoContext = di.getUint16() + returnCode = di.getUint8() + if returnCode == 0: + self.notify.debug('avatar with default name accepted') + self.avId = di.getUint32() + self.avExists = 1 + self.logAvatarCreation() + if self.nameAction == 0: + self.toon.setName(self.names[0]) + newPotAv = PotentialAvatar.PotentialAvatar(self.avId, self.names, self.newDNA, self.index, 1) + self.avList.append(newPotAv) + self.doneStatus = 'done' + self.storeSkipTutorialRequest() + messenger.send(self.doneEvent) + elif self.nameAction == 1: + self.checkNamePattern() + elif self.nameAction == 2: + self.checkNameTyped() + else: + self.notify.debug('avatar invalid nameAction') + self.rejectName(TTLocalizer.NameError) + else: + self.notify.debug('avatar rejected') + self.rejectName(TTLocalizer.NameError) + return None + else: + def handleCreateAvatarResponseMsg(self, avId): + self.notify.debug('handleCreateAvatarResponseMsg') self.notify.debug('avatar with default name accepted') - self.avId = di.getUint32() + self.avId = avId self.avExists = 1 self.logAvatarCreation() if self.nameAction == 0: @@ -1032,10 +1060,6 @@ class NameShop(StateData.StateData): else: self.notify.debug('avatar invalid nameAction') self.rejectName(TTLocalizer.NameError) - else: - self.notify.debug('avatar rejected') - self.rejectName(TTLocalizer.NameError) - return None def waitForServer(self): self.waitForServerDialog = TTDialog.TTDialog(text=TTLocalizer.WaitingForNameSubmission, style=TTDialog.NoButtons) @@ -1068,7 +1092,7 @@ class NameShop(StateData.StateData): self.promptTutorial() def promptTutorial(self): - self.promptTutorialDialog = TTDialog.TTDialog(parent=aspect2dp, text=TTLocalizer.PromptTutorial, text_scale=0.06, text_align=TextNode.ACenter, text_wordwrap=22, command=self.__openTutorialDialog, fadeScreen=0.5, style=TTDialog.TwoChoice, buttonTextList=[TTLocalizer.MakeAToonEnterTutorial, TTLocalizer.MakeAToonSkipTutorial], button_text_scale=0.06, buttonPadSF=5.5, sortOrder=NO_FADE_SORT_INDEX) + self.promptTutorialDialog = TTDialog.TTDialog(parent=aspect2dp, text=TTLocalizer.PromptTutorial, text_scale=0.06, text_align=TextNode.ACenter, text_wordwrap=22, command=self.__openTutorialDialog, fadeScreen=0.5, style=TTDialog.TwoChoice, buttonTextList=[TTLocalizer.MakeAToonEnterTutorial, TTLocalizer.MakeAToonSkipTutorial], button_text_scale=0.06, buttonPadSF=5.5, sortOrder=DGG.NO_FADE_SORT_INDEX) self.promptTutorialDialog.show() def __openTutorialDialog(self, choice = 0):