diff --git a/etc/otp.dc b/etc/otp.dc index 535fc9c..78b0c84 100755 --- a/etc/otp.dc +++ b/etc/otp.dc @@ -538,4 +538,8 @@ dclass AstronLoginManager : DistributedObject { createAvatarResponse(uint32); setNamePattern(uint32, int16, uint8, int16, uint8, int16, uint8, int16, uint8) clsend; namePatternAnswer(uint32, uint8); + setNameTyped(uint32, string) clsend; + nameTypedResponse(uint32, uint8); + acknowledgeAvatarName(uint32) clsend; + acknowledgeAvatarNameResponse(); }; diff --git a/otp/login/AstronLoginManager.py b/otp/login/AstronLoginManager.py index 139e130..b783828 100644 --- a/otp/login/AstronLoginManager.py +++ b/otp/login/AstronLoginManager.py @@ -135,3 +135,17 @@ class AstronLoginManager(DistributedObjectGlobal): def namePatternAnswer(self, avId, status): self._callback(avId, status) + + def sendSetNameTyped(self, avId, name, callback): + self._callback = callback + self.sendUpdate('setNameTyped', [avId, name]) + + def nameTypedResponse(self, avId, status): + self._callback(avId, status) + + def sendAcknowledgeAvatarName(self, avId, callback): + self._callback = callback + self.sendUpdate('acknowledgeAvatarName', [avId]) + + def acknowledgeAvatarNameResponse(self): + self._callback() diff --git a/otp/login/AstronLoginManagerUD.py b/otp/login/AstronLoginManagerUD.py index 98f0e59..9e867f6 100644 --- a/otp/login/AstronLoginManagerUD.py +++ b/otp/login/AstronLoginManagerUD.py @@ -421,6 +421,134 @@ class SetNamePatternOperation: del self.loginManager.account2operation[self.sender] +class SetNameTypedOperation: + notify = DirectNotifyGlobal.directNotify.newCategory('SetNameTypedOperation') + + def __init__(self, loginManager, sender): + self.loginManager = loginManager + self.sender = sender + self.avId = None + self.name = None + + def start(self, avId, name): + self.avId = avId + self.name = name + if self.avId: + self.__handleRetrieveAccount() + return + + self.__handleJudgeName() + + 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.__handleRetrieveAvatar() + + def __handleRetrieveAvatar(self): + if self.avId and self.avId not in self.avList: + # You have no chance to survive make your time + # Hahaha + 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']: + # How are you gentlemen? + # All your base are belong to us + return + + if fields['WishNameState'][0] != 'OPEN': + # You are on your way to destruction + # What you say? + return + + self.__handleJudgeName() + + def __handleJudgeName(self): + status = 1 # TODO Make this useful + if self.avId and status: + self.loginManager.air.dbInterface.updateObject(self.loginManager.air.dbId, self.avId, + self.loginManager.air.dclassesByName['DistributedToonUD'], + {'WishNameState': ('PENDING',), + 'WishName': (self.name,)}) + + self.loginManager.sendUpdateToAccountId(self.sender, 'nameTypedResponse', [self.avId, status]) + del self.loginManager.account2operation[self.sender] + + +class AcknowledgeNameOperation: + notify = DirectNotifyGlobal.directNotify.newCategory('AcknowledgeNameOperation') + + 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: + # welp + 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 + + wishNameState = fields['WishNameState'][0] + wishName = fields['WishName'][0] + name = fields['setName'][0] + if wishNameState == 'APPROVED': + wishNameState = 'LOCKED' + name = wishName + wishName = '' + elif wishNameState == 'REJECTED': + wishNameState = 'OPEN' + wishName = '' + else: + return + + self.loginManager.air.dbInterface.updateObject(self.loginManager.air.dbId, self.avId, + self.loginManager.air.dclassesByName['DistributedToonUD'], + {'WishNameState': (wishNameState,), + 'WishName': (wishName,), + 'setName': (name,)}, + {'WishNameState': fields['WishNameState'], + 'WishName': fields['WishName'], + 'setName': fields['setName']}) + + self.loginManager.sendUpdateToAccountId(self.sender, 'acknowledgeAvatarNameResponse', []) + del self.loginManager.account2operation[self.sender] + + class AstronLoginManagerUD(DistributedObjectGlobalUD): notify = DirectNotifyGlobal.directNotify.newCategory('AstronLoginManagerUD') @@ -497,3 +625,31 @@ class AstronLoginManagerUD(DistributedObjectGlobalUD): self.account2operation[sender] = newOperation newOperation.start(avId, [(p1, f1), (p2, f2), (p3, f3), (p4, f4)]) + + def setNameTyped(self, avId, name): + sender = self.air.getAccountIdFromSender() + if not sender: + # TODO KILL CONNECTION + return + + if sender in self.account2operation: + # BAD!!!! + return + + newOperation = SetNameTypedOperation(self, sender) + self.account2operation[sender] = newOperation + newOperation.start(avId, name) + + def acknowledgeAvatarName(self, avId): + sender = self.air.getAccountIdFromSender() + if not sender: + # TODO KILL CONNECTION + return + + if sender in self.account2operation: + # BAD!!!! + return + + newOperation = AcknowledgeNameOperation(self, sender) + self.account2operation[sender] = newOperation + newOperation.start(avId) diff --git a/otp/namepanel/NameCheck.py b/otp/namepanel/NameCheck.py index f360d58..31ac334 100644 --- a/otp/namepanel/NameCheck.py +++ b/otp/namepanel/NameCheck.py @@ -87,7 +87,7 @@ def checkName(name, otherCheckFuncs = [], font = None): tn = TextNode('NameCheck') tn.setFont(font) for c in name: - if not tn.hasCharacter(ord(c)): + if not tn.hasCharacter(unicode(c)): notify.info('name contains bad char: %s' % TextEncoder().encodeWtext(c)) return OTPLocalizer.NCBadCharacter % TextEncoder().encodeWtext(c) diff --git a/toontown/distributed/ToontownClientRepository.py b/toontown/distributed/ToontownClientRepository.py index 3d2429f..6842917 100644 --- a/toontown/distributed/ToontownClientRepository.py +++ b/toontown/distributed/ToontownClientRepository.py @@ -179,12 +179,16 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): del self.okButton del self.acceptedText del self.acceptedBanner - datagram = PyDatagram() - datagram.addUint16(CLIENT_SET_WISHNAME_CLEAR) - datagram.addUint32(avatarChoice.id) - datagram.addUint8(1) - self.send(datagram) - self.loginFSM.request('waitForSetAvatarResponse', [avatarChoice]) + if not self.astronSupport: + datagram = PyDatagram() + datagram.addUint16(CLIENT_SET_WISHNAME_CLEAR) + datagram.addUint32(avatarChoice.id) + datagram.addUint8(1) + self.send(datagram) + self.loginFSM.request('waitForSetAvatarResponse', [avatarChoice]) + else: + self.astronLoginManager.sendAcknowledgeAvatarName(avatarChoice.id, + lambda: self.loginFSM.request('waitForSetAvatarResponse', [avatarChoice])) def betterlucknexttime(self, avList, index): self.rejectDoneEvent = 'rejectDone' @@ -195,8 +199,9 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): def __handleReject(self, avList, index): self.rejectDialog.cleanup() - datagram = PyDatagram() - datagram.addUint16(CLIENT_SET_WISHNAME_CLEAR) + if not self.astronSupport: + datagram = PyDatagram() + datagram.addUint16(CLIENT_SET_WISHNAME_CLEAR) avid = 0 for k in avList: if k.position == index: @@ -204,10 +209,13 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): if avid == 0: self.notify.error('Avatar rejected not found in avList. Index is: ' + str(index)) - datagram.addUint32(avid) - datagram.addUint8(0) - self.send(datagram) - self.loginFSM.request('waitForAvatarList') + if not self.astronSupport: + datagram.addUint32(avid) + datagram.addUint8(0) + self.send(datagram) + self.loginFSM.request('waitForAvatarList') + else: + self.astronLoginManager.sendAcknowledgeAvatarName(avId, lambda: self.loginFSM.request('waitForAvatarList')) def enterChooseAvatar(self, avList): ModelPool.garbageCollect() diff --git a/toontown/makeatoon/NameShop.py b/toontown/makeatoon/NameShop.py index 4c52350..625d6ad 100644 --- a/toontown/makeatoon/NameShop.py +++ b/toontown/makeatoon/NameShop.py @@ -954,74 +954,124 @@ class NameShop(StateData.StateData): self.notify.debug('checkNameTyped') if self._submitTypeANameAsPickAName(): return - datagram = PyDatagram() - datagram.addUint16(CLIENT_SET_WISHNAME) + if not base.cr.astronSupport: + datagram = PyDatagram() + datagram.addUint16(CLIENT_SET_WISHNAME) if justCheck: avId = 0 else: avId = self.avId - datagram.addUint32(avId) - datagram.addString(self.nameEntry.get()) - messenger.send('nameShopPost', [datagram]) + if not base.cr.astronSupport: + datagram.addUint32(avId) + datagram.addString(self.nameEntry.get()) + messenger.send('nameShopPost', [datagram]) + else: + base.cr.astronLoginManager.sendSetNameTyped(avId, self.nameEntry.get(), self.handleSetNameTypedAnswerMsg) self.waitForServer() - def handleSetNameTypedAnswerMsg(self, di): - self.notify.debug('handleSetNameTypedAnswerMsg') - self.cleanupWaitForServer() - newavId = di.getUint32() - if newavId and newavId != self.avId: - self.notify.debug("doid's don't match up!") - self.rejectName(TTLocalizer.NameError) - returnCode = di.getUint16() - if newavId == 0: - if returnCode == 0: - pendingname = di.getString() + if not config.GetBool('astron-support', True): + def handleSetNameTypedAnswerMsg(self, di): + self.notify.debug('handleSetNameTypedAnswerMsg') + self.cleanupWaitForServer() + newavId = di.getUint32() + if newavId and newavId != self.avId: + self.notify.debug("doid's don't match up!") + self.rejectName(TTLocalizer.NameError) + returnCode = di.getUint16() + if newavId == 0: + if returnCode == 0: + pendingname = di.getString() + approvedname = di.getString() + rejectedname = di.getString() + if pendingname != '': + self.notify.debug('name check pending') + self.fsm.request('Approval') + elif approvedname != '': + self.notify.debug('name check accepted') + self.nameAction = 2 + self.serverCreateAvatar() + elif rejectedname != '': + self.notify.debug('name check rejected') + self.fsm.request('TypeAName') + self.rejectName(TTLocalizer.NameError) + else: + self.notify.debug('typed name response did not contain any return fields') + self.rejectName(TTLocalizer.NameError) + elif returnCode == 0: + wishname = di.getString() approvedname = di.getString() rejectedname = di.getString() - if pendingname != '': + if approvedname != '': + style = self.toon.getStyle() + avDNA = style.makeNetString() + self.names[0] = self.nameEntry.get() + self.notify.debug('typed name accepted') + newPotAv = PotentialAvatar.PotentialAvatar(newavId, self.names, avDNA, self.index, 0) + self.avList.append(newPotAv) + self.fsm.request('Accepted') + elif wishname != '': + style = self.toon.getStyle() + avDNA = style.makeNetString() + self.names[1] = self.nameEntry.get() + self.notify.debug('typed name needs approval') + newPotAv = PotentialAvatar.PotentialAvatar(newavId, self.names, avDNA, self.index, 1) + if not self.newwarp: + self.avList.append(newPotAv) + self.fsm.request('ApprovalAccepted') + elif rejectedname != '': + self.fsm.request('Rejected') + else: + self.notify.debug("name typed accepted but didn't fill any return fields") + self.rejectName(TTLocalizer.NameError) + else: + self.notify.debug('name typed rejected') + self.rejectName(TTLocalizer.NameError) + return None + else: + def handleSetNameTypedAnswerMsg(self, newavId, returnCode): + self.notify.debug('handleSetNameTypedAnswerMsg') + self.cleanupWaitForServer() + if newavId and newavId != self.avId: + self.notify.debug("doid's don't match up!") + self.rejectName(TTLocalizer.NameError) + if newavId == 0: + if returnCode == 1: self.notify.debug('name check pending') self.fsm.request('Approval') - elif approvedname != '': + elif returnCode == 2: self.notify.debug('name check accepted') self.nameAction = 2 self.serverCreateAvatar() - elif rejectedname != '': + elif returnCode == 0: self.notify.debug('name check rejected') self.fsm.request('TypeAName') self.rejectName(TTLocalizer.NameError) else: self.notify.debug('typed name response did not contain any return fields') self.rejectName(TTLocalizer.NameError) - elif returnCode == 0: - wishname = di.getString() - approvedname = di.getString() - rejectedname = di.getString() - if approvedname != '': - style = self.toon.getStyle() - avDNA = style.makeNetString() - self.names[0] = self.nameEntry.get() - self.notify.debug('typed name accepted') - newPotAv = PotentialAvatar.PotentialAvatar(newavId, self.names, avDNA, self.index, 0) - self.avList.append(newPotAv) - self.fsm.request('Accepted') - elif wishname != '': - style = self.toon.getStyle() - avDNA = style.makeNetString() - self.names[1] = self.nameEntry.get() - self.notify.debug('typed name needs approval') - newPotAv = PotentialAvatar.PotentialAvatar(newavId, self.names, avDNA, self.index, 1) - if not self.newwarp: - self.avList.append(newPotAv) - self.fsm.request('ApprovalAccepted') - elif rejectedname != '': - self.fsm.request('Rejected') else: - self.notify.debug("name typed accepted but didn't fill any return fields") - self.rejectName(TTLocalizer.NameError) - else: - self.notify.debug('name typed rejected') - self.rejectName(TTLocalizer.NameError) - return None + if returnCode == 2: + style = self.toon.getStyle() + avDNA = style.makeNetString() + self.names[0] = self.nameEntry.get() + self.notify.debug('typed name accepted') + newPotAv = PotentialAvatar.PotentialAvatar(newavId, self.names, avDNA, self.index, 0) + self.avList.append(newPotAv) + self.fsm.request('Accepted') + elif returnCode == 1: + style = self.toon.getStyle() + avDNA = style.makeNetString() + self.names[1] = self.nameEntry.get() + self.notify.debug('typed name needs approval') + newPotAv = PotentialAvatar.PotentialAvatar(newavId, self.names, avDNA, self.index, 1) + if not self.newwarp: + self.avList.append(newPotAv) + self.fsm.request('ApprovalAccepted') + elif returnCode == 0: + self.fsm.request('Rejected') + else: + self.notify.debug("name typed accepted but didn't fill any return fields") + self.rejectName(TTLocalizer.NameError) def serverCreateAvatar(self, skipTutorial = False): self.notify.debug('serverCreateAvatar')