text: import json
  import os
  import time
  from datetime import datetime
  from pandac.PandaModules import *
  from direct.distributed.MsgTypes import *
  from direct.gui.DirectGui import *
  from direct.fsm import StateData
  from direct.fsm import ClassicFSM
  from direct.fsm import State
  from direct.directnotify import DirectNotifyGlobal
  from direct.task import Task
  from otp.otpgui import OTPDialog
  from otp.otpbase import OTPLocalizer
  from otp.otpbase import OTPGlobals
  from otp.uberdog.AccountDetailRecord import AccountDetailRecord, SubDetailRecord
  import TTAccount
  import GuiScreen
  
  class LoginScreen(StateData.StateData, GuiScreen.GuiScreen):
      AutoLoginName = base.config.GetString('%s-auto-login%s' % (game.name, os.getenv('otp_client', '')), '')
      AutoLoginPassword = base.config.GetString('%s-auto-password%s' % (game.name, os.getenv('otp_client', '')), '')
      notify = DirectNotifyGlobal.directNotify.newCategory('LoginScreen')
      ActiveEntryColor = Vec4(1, 1, 1, 1)
      InactiveEntryColor = Vec4(0.8, 0.8, 0.8, 1)
  
      def __init__(self, cr, doneEvent):
          self.notify.debug('__init__')
          StateData.StateData.__init__(self, doneEvent)
          GuiScreen.GuiScreen.__init__(self)
          self.cr = cr
          self.loginInterface = self.cr.loginInterface
          self.userName = ''
          self.password = ''
          self.fsm = ClassicFSM.ClassicFSM('LoginScreen', [State.State('off', self.enterOff, self.exitOff, ['login', 'waitForLoginResponse']),
           State.State('login', self.enterLogin, self.exitLogin, ['waitForLoginResponse', 'login', 'showLoginFailDialog']),
           State.State('showLoginFailDialog', self.enterShowLoginFailDialog, self.exitShowLoginFailDialog, ['login', 'showLoginFailDialog']),
           State.State('waitForLoginResponse', self.enterWaitForLoginResponse, self.exitWaitForLoginResponse, ['login', 'showLoginFailDialog', 'showConnectionProblemDialog']),
           State.State('showConnectionProblemDialog', self.enterShowConnectionProblemDialog, self.exitShowConnectionProblemDialog, ['login'])], 'off', 'off')
          self.fsm.enterInitialState()
  
      def load(self):
          self.notify.debug('load')
          masterScale = 0.8
          textScale = 0.1 * masterScale
          entryScale = 0.08 * masterScale
          lineHeight = 0.21 * masterScale
          buttonScale = 1.15 * masterScale
          buttonLineHeight = 0.14 * masterScale
          self.frame = DirectFrame(parent=aspect2d, relief=None, sortOrder=20)
          self.frame.hide()
          linePos = -0.26
          self.nameLabel = DirectLabel(parent=self.frame, relief=None, pos=(-0.21, 0, linePos), text=OTPLocalizer.LoginScreenUserName, text_scale=textScale, text_align=TextNode.ARight)
          self.nameEntry = DirectEntry(parent=self.frame, relief=DGG.SUNKEN, borderWidth=(0.1, 0.1), scale=entryScale, pos=(-0.125, 0.0, linePos), width=OTPGlobals.maxLoginWidth, numLines=1, focus=0, cursorKeys=1)
          linePos -= lineHeight
          self.passwordLabel = DirectLabel(parent=self.frame, relief=None, pos=(-0.21, 0, linePos), text=OTPLocalizer.LoginScreenPassword, text_scale=textScale, text_align=TextNode.ARight)
          self.passwordEntry = DirectEntry(parent=self.frame, relief=DGG.SUNKEN, borderWidth=(0.1, 0.1), scale=entryScale, pos=(-0.125, 0.0, linePos), width=OTPGlobals.maxLoginWidth, numLines=1, focus=0, cursorKeys=1, obscured=1, command=self.__handleLoginPassword)
          linePos -= lineHeight
          buttonImageScale = (1.7, 1.1, 1.1)
          self.loginButton = DirectButton(parent=self.frame, relief=DGG.RAISED, borderWidth=(0.01, 0.01), pos=(0, 0, linePos), scale=buttonScale, text=OTPLocalizer.LoginScreenLogin, text_scale=0.06, text_pos=(0, -0.02), command=self.__handleLoginButton)
          linePos -= buttonLineHeight
          self.createAccountButton = DirectButton(parent=self.frame, relief=DGG.RAISED, borderWidth=(0.01, 0.01), pos=(0, 0, linePos), scale=buttonScale, text=OTPLocalizer.LoginScreenCreateAccount, text_scale=0.06, text_pos=(0, -0.02), command=self.__handleCreateAccount)
          linePos -= buttonLineHeight
          self.quitButton = DirectButton(parent=self.frame, relief=DGG.RAISED, borderWidth=(0.01, 0.01), pos=(0, 0, linePos), scale=buttonScale, text=OTPLocalizer.LoginScreenQuit, text_scale=0.06, text_pos=(0, -0.02), command=self.__handleQuit)
          linePos -= buttonLineHeight
          self.dialogDoneEvent = 'loginDialogAck'
          dialogClass = OTPGlobals.getGlobalDialogClass()
          self.dialog = dialogClass(dialogName='loginDialog', doneEvent=self.dialogDoneEvent, message='', style=OTPDialog.Acknowledge, sortOrder=DGG.NO_FADE_SORT_INDEX + 100)
          self.dialog.hide()
          self.failDialog = DirectFrame(parent=aspect2dp, relief=DGG.RAISED, borderWidth=(0.01, 0.01), pos=(0, 0.1, 0), text='', text_scale=0.08, text_pos=(0.0, 0.3), text_wordwrap=15, sortOrder=DGG.NO_FADE_SORT_INDEX)
          linePos = -.05
          self.failTryAgainButton = DirectButton(parent=self.failDialog, relief=DGG.RAISED, borderWidth=(0.01, 0.01), pos=(0, 0, linePos), scale=0.9, text=OTPLocalizer.LoginScreenTryAgain, text_scale=0.06, text_pos=(0, -.02), command=self.__handleFailTryAgain)
          linePos -= buttonLineHeight
          self.failCreateAccountButton = DirectButton(parent=self.failDialog, relief=DGG.RAISED, borderWidth=(0.01, 0.01), pos=(0, 0, linePos), scale=0.9, text=OTPLocalizer.LoginScreenCreateAccount, text_scale=0.06, text_pos=(0, -.02), command=self.__handleFailCreateAccount)
          linePos -= buttonLineHeight
          self.failDialog.hide()
          self.connectionProblemDialogDoneEvent = 'loginConnectionProblemDlgAck'
          dialogClass = OTPGlobals.getGlobalDialogClass()
          self.connectionProblemDialog = dialogClass(dialogName='connectionProblemDialog', doneEvent=self.connectionProblemDialogDoneEvent, message='', style=OTPDialog.Acknowledge, sortOrder=DGG.NO_FADE_SORT_INDEX + 100)
          self.connectionProblemDialog.hide()
          return
  
      def unload(self):
          self.notify.debug('unload')
          self.nameEntry.destroy()
          self.passwordEntry.destroy()
          self.failTryAgainButton.destroy()
          self.failCreateAccountButton.destroy()
          self.createAccountButton.destroy()
          self.loginButton.destroy()
          self.quitButton.destroy()
          self.dialog.cleanup()
          del self.dialog
          self.failDialog.destroy()
          del self.failDialog
          self.connectionProblemDialog.cleanup()
          del self.connectionProblemDialog
          self.frame.destroy()
          del self.fsm
          del self.loginInterface
          del self.cr
  
      def enter(self):
          if self.cr.blue:
              self.userName = 'blue'
              self.password = self.cr.blue
              self.fsm.request('waitForLoginResponse')
          elif self.cr.playToken:
              self.userName = '*'
              self.password = self.cr.playToken
              self.fsm.request('waitForLoginResponse')
          elif hasattr(self.cr, 'DISLToken') and self.cr.DISLToken:
              self.userName = '*'
              self.password = self.cr.DISLToken
              self.fsm.request('waitForLoginResponse')
          elif self.AutoLoginName:
              self.userName = self.AutoLoginName
              self.password = self.AutoLoginPassword
              self.fsm.request('waitForLoginResponse')
          else:
              self.fsm.request('login')
  
      def exit(self):
          self.frame.hide()
          self.ignore(self.dialogDoneEvent)
          self.fsm.requestFinalState()
  
      def enterOff(self):
          pass
  
      def exitOff(self):
          pass
  
      def enterLogin(self):
          self.cr.resetPeriodTimer(None)
          self.userName = ''
          self.password = ''
          self.userName = launcher.getLastLogin()
          if self.userName and self.nameEntry.get():
              if self.userName != self.nameEntry.get():
                  self.userName = ''
          self.frame.show()
          self.nameEntry.enterText(self.userName)
          self.passwordEntry.enterText(self.password)
          self.focusList = [self.nameEntry, self.passwordEntry]
          focusIndex = 0
          if self.userName:
              focusIndex = 1
          self.startFocusMgmt(startFocus=focusIndex)
          return
  
      def exitLogin(self):
          self.stopFocusMgmt()
  
      def enterShowLoginFailDialog(self, msg):
          base.transitions.fadeScreen(0.5)
          self.failDialog['text'] = msg
          self.failDialog.show()
  
      def __handleFailTryAgain(self):
          self.fsm.request('login')
  
      def __handleFailCreateAccount(self):
          messenger.send(self.doneEvent, [{'mode': 'createAccount'}])
  
      def __handleFailNoNewAccountsAck(self):
          self.dialog.hide()
          self.fsm.request('showLoginFailDialog', [self.failDialog['text']])
  
      def exitShowLoginFailDialog(self):
          base.transitions.noTransitions()
          self.failDialog.hide()
  
      def __handleLoginPassword(self, password):
          if password != '':
              if self.nameEntry.get() != '':
                  self.__handleLoginButton()
  
      def __handleLoginButton(self):
          self.removeFocus()
          self.userName = self.nameEntry.get()
          self.password = self.passwordEntry.get()
          if self.userName == '':
              self.dialog.setMessage(OTPLocalizer.LoginScreenLoginPrompt)
              self.dialog.show()
              self.acceptOnce(self.dialogDoneEvent, self.__handleEnterLoginAck)
          else:
              self.fsm.request('waitForLoginResponse')
  
      def __handleQuit(self):
          self.removeFocus()
          messenger.send(self.doneEvent, [{'mode': 'quit'}])
  
      def __handleCreateAccount(self):
          self.removeFocus()
          messenger.send(self.doneEvent, [{'mode': 'createAccount'}])
  
      def enterWaitForLoginResponse(self):
          self.cr.handler = self.handleWaitForLoginResponse
          self.cr.userName = self.userName
          self.cr.password = self.password
          try:
              error = self.loginInterface.authorize(self.userName, self.password)
          except TTAccount.TTAccountException, e:
              self.fsm.request('showConnectionProblemDialog', [str(e)])
              return
  
          if error:
              self.notify.info(error)
              freeTimeExpired = self.loginInterface.getErrorCode() == 10
              if freeTimeExpired:
                  self.cr.logAccountInfo()
                  messenger.send(self.doneEvent, [{'mode': 'freeTimeExpired'}])
              else:
                  self.fsm.request('showLoginFailDialog', [error])
          else:
              self.loginInterface.sendLoginMsg()
              self.waitForDatabaseTimeout(requestName='WaitForLoginResponse')
  
      def exitWaitForLoginResponse(self):
          self.cleanupWaitingForDatabase()
          self.cr.handler = None
          return
  
      def enterShowConnectionProblemDialog(self, msg):
          self.connectionProblemDialog.setMessage(msg)
          self.connectionProblemDialog.show()
          self.acceptOnce(self.connectionProblemDialogDoneEvent, self.__handleConnectionProblemAck)
  
      def __handleConnectionProblemAck(self):
          self.connectionProblemDialog.hide()
          self.fsm.request('login')
  
      def exitShowConnectionProblemDialog(self):
          pass
  
      if not config.GetBool('astron-support', True):
          def handleWaitForLoginResponse(self, msgType, di):
              if msgType == CLIENT_LOGIN_2_RESP:
                  self.handleLoginResponseMsg2(di)
              elif msgType == CLIENT_LOGIN_RESP:
                  self.handleLoginResponseMsg(di)
              elif msgType == CLIENT_LOGIN_3_RESP:
                  self.handleLoginResponseMsg3(di)
              elif msgType == CLIENT_LOGIN_TOONTOWN_RESP:
                  self.handleLoginToontownResponse(di)
              else:
                  self.cr.handleMessageType(msgType, di)
      else:
          def handleWaitForLoginResponse(self, msgType, di):
              if msgType == CLIENT_HELLO_RESP:
                  self.handleHelloResp()
              else:
                  self.cr.handleMessageType(msgType, di)
  
          def handleHelloResp(self):
              self.cr.startHeartbeat()
              self.cr.astronLoginManager.handleRequestLogin()
  
      def getExtendedErrorMsg(self, errorString):
          prefix = 'Bad DC Version Compare'
          if len(errorString) < len(prefix):
              return errorString
          if errorString[:len(prefix)] == prefix:
              return '%s%s' % (errorString, ', address=%s' % base.cr.getServerAddress())
          return errorString
  
      def handleLoginResponseMsg3(self, di):
          now = time.time()
          returnCode = di.getInt8()
          errorString = self.getExtendedErrorMsg(di.getString())
          self.notify.info('Login response return code %s' % returnCode)
          if returnCode != 0:
              self.notify.info('Login failed: %s' % errorString)
              messenger.send(self.doneEvent, [{'mode': 'reject'}])
              return
          accountDetailRecord = AccountDetailRecord()
          accountDetailRecord.openChatEnabled = di.getString() == 'YES'
          accountDetailRecord.createFriendsWithChat = di.getString() == 'YES'
          chatCodeCreation = di.getString()
          accountDetailRecord.chatCodeCreation = chatCodeCreation == 'YES'
          parentControlledChat = chatCodeCreation == 'PARENT'
          access = di.getString()
          if access == 'VELVET':
              access = OTPGlobals.AccessVelvetRope
          elif access == 'FULL':
              access = OTPGlobals.AccessFull
          else:
              self.notify.warning('Unknown access: %s' % access)
              access = OTPGlobals.AccessUnknown
          accountDetailRecord.piratesAccess = access
          accountDetailRecord.familyAccountId = di.getInt32()
          accountDetailRecord.playerAccountId = di.getInt32()
          accountDetailRecord.playerName = di.getString()
          accountDetailRecord.playerNameApproved = di.getInt8()
          accountDetailRecord.maxAvatars = di.getInt32()
          self.cr.openChatAllowed = accountDetailRecord.openChatEnabled
          self.cr.secretChatAllowed = accountDetailRecord.chatCodeCreation or parentControlledChat
          self.cr.setIsPaid(accountDetailRecord.piratesAccess)
          self.userName = accountDetailRecord.playerName
          self.cr.userName = accountDetailRecord.playerName
          accountDetailRecord.numSubs = di.getUint16()
          for i in range(accountDetailRecord.numSubs):
              subDetailRecord = SubDetailRecord()
              subDetailRecord.subId = di.getUint32()
              subDetailRecord.subOwnerId = di.getUint32()
              subDetailRecord.subName = di.getString()
              subDetailRecord.subActive = di.getString()
              access = di.getString()
              if access == 'VELVET':
                  access = OTPGlobals.AccessVelvetRope
              elif access == 'FULL':
                  access = OTPGlobals.AccessFull
              else:
                  access = OTPGlobals.AccessUnknown
              subDetailRecord.subAccess = access
              subDetailRecord.subLevel = di.getUint8()
              subDetailRecord.subNumAvatars = di.getUint8()
              subDetailRecord.subNumConcur = di.getUint8()
              subDetailRecord.subFounder = di.getString() == 'YES'
              accountDetailRecord.subDetails[subDetailRecord.subId] = subDetailRecord
  
          accountDetailRecord.WLChatEnabled = di.getString() == 'YES'
          if accountDetailRecord.WLChatEnabled:
              self.cr.whiteListChatEnabled = 1
          else:
              self.cr.whiteListChatEnabled = 0
          self.notify.info('End of DISL token parse')
          if base.logPrivateInfo:
              self.notify.info('accountDetailRecord: %s' % accountDetailRecord)
          self.cr.accountDetailRecord = accountDetailRecord
          self.__handleLoginSuccess()
  
      def handleLoginResponseMsg2(self, di):
          self.notify.debug('handleLoginResponseMsg2')
          if base.logPrivateInfo:
              if self.notify.getDebug():
                  dgram = di.getDatagram()
                  dgram.dumpHex(ostream)
          now = time.time()
          returnCode = di.getUint8()
          errorString = self.getExtendedErrorMsg(di.getString())
          self.userName = di.getString()
          self.cr.userName = self.userName
          accountDetailRecord = AccountDetailRecord()
          self.cr.accountDetailRecord = accountDetailRecord
          canChat = di.getUint8()
          self.cr.secretChatAllowed = canChat
          if base.logPrivateInfo:
              self.notify.info('Chat from game server login: %s' % canChat)
          sec = di.getUint32()
          usec = di.getUint32()
          serverTime = sec + usec / 1000000.0
          self.cr.serverTimeUponLogin = serverTime
          self.cr.clientTimeUponLogin = now
          self.cr.globalClockRealTimeUponLogin = globalClock.getRealTime()
          if hasattr(self.cr, 'toontownTimeManager'):
              self.cr.toontownTimeManager.updateLoginTimes(serverTime, now, self.cr.globalClockRealTimeUponLogin)
          serverDelta = serverTime - now
          self.cr.setServerDelta(serverDelta)
          self.notify.setServerDelta(serverDelta, 28800)
          self.isPaid = di.getUint8()
          self.cr.setIsPaid(self.isPaid)
          if self.isPaid:
              launcher.setPaidUserLoggedIn()
          if base.logPrivateInfo:
              self.notify.info('Paid from game server login: %s' % self.isPaid)
          self.cr.resetPeriodTimer(None)
          if di.getRemainingSize() >= 4:
              minutesRemaining = di.getInt32()
              if base.logPrivateInfo:
                  self.notify.info('Minutes remaining from server %s' % minutesRemaining)
              if base.logPrivateInfo:
                  if minutesRemaining >= 0:
                      self.notify.info('Spawning period timer')
                      self.cr.resetPeriodTimer(minutesRemaining * 60)
                  elif self.isPaid:
                      self.notify.warning('Negative minutes remaining for paid user (?)')
                  else:
                      self.notify.warning('Not paid, but also negative minutes remaining (?)')
          elif base.logPrivateInfo:
              self.notify.info('Minutes remaining not returned from server; not spawning period timer')
          familyStr = di.getString()
          WhiteListResponse = di.getString()
          if WhiteListResponse == 'YES':
              self.cr.whiteListChatEnabled = 1
          else:
              self.cr.whiteListChatEnabled = 0
          if di.getRemainingSize() > 0:
              self.cr.accountDays = self.parseAccountDays(di.getInt32())
          else:
              self.cr.accountDays = 100000
          if di.getRemainingSize() > 0:
              self.lastLoggedInStr = di.getString()
              self.notify.info('last logged in = %s' % self.lastLoggedInStr)
          else:
              self.lastLoggedInStr = ''
          self.cr.lastLoggedIn = datetime.now()
          if hasattr(self.cr, 'toontownTimeManager'):
              self.cr.lastLoggedIn = self.cr.toontownTimeManager.convertStrToToontownTime(self.lastLoggedInStr)
          self.cr.withParentAccount = False
          self.notify.info('Login response return code %s' % returnCode)
          if returnCode == 0:
              self.__handleLoginSuccess()
          elif returnCode == -13:
              self.notify.info('Period Time Expired')
              self.fsm.request('showLoginFailDialog', [OTPLocalizer.LoginScreenPeriodTimeExpired])
          else:
              self.notify.info('Login failed: %s' % errorString)
              messenger.send(self.doneEvent, [{'mode': 'reject'}])
          return
  
      def handleLoginResponseMsg(self, di):
          self.notify.debug('handleLoginResponseMsg1')
          if base.logPrivateInfo:
              if self.notify.getDebug():
                  dgram = di.getDatagram()
                  dgram.dumpHex(ostream)
          now = time.time()
          accountDetailRecord = AccountDetailRecord()
          self.cr.accountDetailRecord = accountDetailRecord
          returnCode = di.getUint8()
          accountCode = di.getUint32()
          errorString = self.getExtendedErrorMsg(di.getString())
          sec = di.getUint32()
          usec = di.getUint32()
          serverTime = sec + usec / 1000000.0
          serverDelta = serverTime - now
          self.cr.serverTimeUponLogin = serverTime
          self.cr.clientTimeUponLogin = now
          self.cr.globalClockRealTimeUponLogin = globalClock.getRealTime()
          if hasattr(self.cr, 'toontownTimeManager'):
              self.cr.toontownTimeManager.updateLoginTimes(serverTime, now, self.cr.globalClockRealTimeUponLogin)
          self.cr.setServerDelta(serverDelta)
          self.notify.setServerDelta(serverDelta, 28800)
          if di.getRemainingSize() > 0:
              self.cr.accountDays = self.parseAccountDays(di.getInt32())
          else:
              self.cr.accountDays = 100000
          if di.getRemainingSize() > 0:
              WhiteListResponse = di.getString()
          else:
              WhiteListResponse = 'NO'
          if WhiteListResponse == 'YES':
              self.cr.whiteListChatEnabled = 1
          else:
              self.cr.whiteListChatEnabled = 0
          self.lastLoggedInStr = base.config.GetString('last-logged-in', '')
          self.cr.lastLoggedIn = datetime.now()
          if hasattr(self.cr, 'toontownTimeManager'):
              self.cr.lastLoggedIn = self.cr.toontownTimeManager.convertStrToToontownTime(self.lastLoggedInStr)
          self.cr.withParentAccount = base.config.GetBool('dev-with-parent-account', 0)
          self.notify.info('Login response return code %s' % returnCode)
          if returnCode == 0:
              self.__handleLoginSuccess()
          elif returnCode == 12:
              self.notify.info('Bad password')
              self.fsm.request('showLoginFailDialog', [OTPLocalizer.LoginScreenBadPassword])
          elif returnCode == 14:
              self.notify.info('Bad word in user name')
              self.fsm.request('showLoginFailDialog', [OTPLocalizer.LoginScreenInvalidUserName])
          elif returnCode == 129:
              self.notify.info('Username not found')
              self.fsm.request('showLoginFailDialog', [OTPLocalizer.LoginScreenUserNameNotFound])
          else:
              self.notify.info('Login failed: %s' % errorString)
              messenger.send(self.doneEvent, [{'mode': 'reject'}])
  
      def __handleLoginSuccess(self):
          self.cr.logAccountInfo()
          launcher.setGoUserName(self.userName)
          launcher.setLastLogin(self.userName)
          launcher.setUserLoggedIn()
          if self.loginInterface.freeTimeExpires == -1:
              launcher.setPaidUserLoggedIn()
          if self.loginInterface.needToSetParentPassword():
              messenger.send(self.doneEvent, [{'mode': 'getChatPassword'}])
          else:
              messenger.send(self.doneEvent, [{'mode': 'success'}])
  
      def __handleEnterLoginAck(self):
          self.dialog.hide()
          self.fsm.request('login')
  
      def __handleNoNewAccountsAck(self):
          self.dialog.hide()
          self.fsm.request('login')
  
      def parseAccountDays(self, accountDays):
          result = 100000
          if accountDays >= 0:
              result = accountDays
          else:
              self.notify.warning('account days is negative %s' % accountDays)
          self.notify.debug('result=%s' % result)
          return result
  
      if not config.GetBool('astron-support', True):
          def handleLoginToontownResponse(self, di):
              self.notify.debug("handleLoginToontownResponse")
              if 1:
                  if base.logPrivateInfo:
                      dgram = di.getDatagram()
                      dgram.dumpHex(ostream)
              now = time.time()
              returnCode = di.getUint8()
              respString = di.getString()
              errorString = self.getExtendedErrorMsg(respString)
              self.accountNumber = di.getUint32()
              self.cr.DISLIdFromLogin = self.accountNumber
              self.accountName = di.getString()
              self.accountNameApproved = di.getUint8()
              accountDetailRecord = AccountDetailRecord()
              self.cr.accountDetailRecord = accountDetailRecord
              self.openChatEnabled = di.getString() == "YES"
              createFriendsWithChat = di.getString()
              canChat = createFriendsWithChat == "YES" or createFriendsWithChat == "CODE"
              self.cr.secretChatAllowed = canChat
              if base.logPrivateInfo:
                  self.notify.info("CREATE_FRIENDS_WITH_CHAT from game server login: %s %s" % (createFriendsWithChat, canChat))
              self.chatCodeCreationRule = di.getString()
              self.cr.chatChatCodeCreationRule = self.chatCodeCreationRule
              if base.logPrivateInfo:
                  self.notify.info("Chat code creation rule = %s" % self.chatCodeCreationRule)
              self.cr.secretChatNeedsParentPassword = self.chatCodeCreationRule == "PARENT"
              sec = di.getUint32()
              usec = di.getUint32()
              serverTime = sec + (usec/1000000.0)
              self.cr.serverTimeUponLogin = serverTime
              self.cr.clientTimeUponLogin = now
              self.cr.globalClockRealTimeUponLogin = globalClock.getRealTime()
              if hasattr(self.cr, "toontownTimeManager"):
                  self.cr.toontownTimeManager.updateLoginTimes(serverTime, now, self.cr.globalClockRealTimeUponLogin)
              serverDelta = serverTime - now
              self.cr.setServerDelta(serverDelta)
              self.notify.setServerDelta(serverDelta, 28800)
              access = di.getString()
              self.isPaid = access == "FULL"
              self.cr.parentPasswordSet = self.isPaid
              self.cr.setIsPaid(self.isPaid)
              if self.isPaid:
                  launcher.setPaidUserLoggedIn()
              if base.logPrivateInfo:
                  self.notify.info("Paid from game server login: %s" % self.isPaid)
              WhiteListResponse = di.getString()
              if WhiteListResponse == "YES":
                  self.cr.whiteListChatEnabled = 1
              else:
                  self.cr.whiteListChatEnabled = 0
              self.lastLoggedInStr = di.getString()
              self.cr.lastLoggedIn = datetime.now()
              if hasattr(self.cr, "toontownTimeManager"):
                  self.cr.lastLoggedIn = self.cr.toontownTimeManager.convertStrToToontownTime(self.lastLoggedInStr)
              if di.getRemainingSize() > 0:
                  self.cr.accountDays = self.parseAccountDays(di.getInt32())
              else:
                  self.cr.accountDays = 100000
              self.toonAccountType = di.getString()
              if self.toonAccountType == "WITH_PARENT_ACCOUNT":
                  self.cr.withParentAccount = True
              elif self.toonAccountType == "NO_PARENT_ACCOUNT":
                  self.cr.withParentAccount = False
              else:
                  self.notify.error("unknown toon account type %s" % self.toonAccountType)
              if base.logPrivateInfo:
                  self.notify.info("toonAccountType=%s" % self.toonAccountType)
              self.userName = di.getString()
              self.cr.userName = self.userName
              self.notify.info("Login response return code %s" % returnCode)
              if returnCode == 0:
                  self.__handleLoginSuccess()
              elif returnCode == -13:
                  self.notify.info("Period Time Expired")
                  self.fsm.request("showLoginFailDialog", [OTPLocalizer.LoginScreenPeriodTimeExpired])
              else:
                  self.notify.info("Login failed: %s" % errorString)
                  messenger.send(self.doneEvent, [{'mode': 'reject'}])
      else:
          def handleLoginToontownResponse(self, responseBlob):
              self.notify.debug("handleLoginToontownResponse")
              responseData = json.loads(responseBlob)
              now = time.time()
              returnCode = responseData.get('returnCode')
              respString = responseData.get('respString')
              errorString = self.getExtendedErrorMsg(respString)
              self.accountNumber = responseData.get('accountNumber')
              self.cr.DISLIdFromLogin = self.accountNumber
              accountDetailRecord = AccountDetailRecord()
              self.cr.accountDetailRecord = accountDetailRecord
              createFriendsWithChat = responseData.get('createFriendsWithChat')
              canChat = createFriendsWithChat == "YES" or createFriendsWithChat == "CODE"
              self.cr.secretChatAllowed = canChat
              if base.logPrivateInfo:
                  self.notify.info("CREATE_FRIENDS_WITH_CHAT from game server login: %s %s" % (createFriendsWithChat, canChat))
              self.chatCodeCreationRule = responseData.get('chatCodeCreationRule')
              self.cr.chatChatCodeCreationRule = self.chatCodeCreationRule
              if base.logPrivateInfo:
                  self.notify.info("Chat code creation rule = %s" % self.chatCodeCreationRule)
              self.cr.secretChatNeedsParentPassword = self.chatCodeCreationRule == "PARENT"
              serverTime = responseData.get('serverTime')
              self.cr.serverTimeUponLogin = serverTime
              self.cr.clientTimeUponLogin = now
              self.cr.globalClockRealTimeUponLogin = globalClock.getRealTime()
              if hasattr(self.cr, "toontownTimeManager"):
                  self.cr.toontownTimeManager.updateLoginTimes(serverTime, now, self.cr.globalClockRealTimeUponLogin)
              serverDelta = serverTime - now
              self.cr.setServerDelta(serverDelta)
              self.notify.setServerDelta(serverDelta, 28800)
              access = responseData.get('access')
              self.isPaid = access == "FULL"
              self.cr.parentPasswordSet = self.isPaid
              self.cr.setIsPaid(self.isPaid)
              if self.isPaid:
                  launcher.setPaidUserLoggedIn()
              if base.logPrivateInfo:
                  self.notify.info("Paid from game server login: %s" % self.isPaid)
              WhiteListResponse = responseData.get('WhiteListResponse')
              if WhiteListResponse == "YES":
                  self.cr.whiteListChatEnabled = 1
              else:
                  self.cr.whiteListChatEnabled = 0
              self.lastLoggedInStr = responseData.get('lastLoggedInStr')
              self.cr.lastLoggedIn = datetime.now()
              if hasattr(self.cr, "toontownTimeManager"):
                  self.cr.lastLoggedIn = self.cr.toontownTimeManager.convertStrToToontownTime(self.lastLoggedInStr)
              accountDaysFromServer = responseData.get('accountDays')
              if accountDaysFromServer is not None:
                  self.cr.accountDays = self.parseAccountDays(accountDaysFromServer)
              else:
                  self.cr.accountDays = 100000
              self.toonAccountType = responseData.get('toonAccountType')
              if self.toonAccountType == "WITH_PARENT_ACCOUNT":
                  self.cr.withParentAccount = True
              elif self.toonAccountType == "NO_PARENT_ACCOUNT":
                  self.cr.withParentAccount = False
              else:
                  self.notify.error("unknown toon account type %s" % self.toonAccountType)
              if base.logPrivateInfo:
                  self.notify.info("toonAccountType=%s" % self.toonAccountType)
              self.userName = responseData.get('userName')
              self.cr.userName = self.userName
              self.notify.info("Login response return code %s" % returnCode)
              if returnCode == 0:
                  self.__handleLoginSuccess()
              elif returnCode == -13:
                  self.notify.info("Period Time Expired")
                  self.fsm.request("showLoginFailDialog", [OTPLocalizer.LoginScreenPeriodTimeExpired])
              else:
                  self.notify.info("Login failed: %s" % errorString)
                  messenger.send(self.doneEvent, [{'mode': 'reject'}])
  