Back to Home

ESO Lua File v101041

pregame/accountlogin/keyboard/zo_loginmanager.lua

[◄ back to folders ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
local LoginManager_Keyboard = ZO_Object:Subclass()
function LoginManager_Keyboard:New(...)
    local object = ZO_Object.New(self)
    object:Initialize(...)
    return object
end
function LoginManager_Keyboard:Initialize()
    self.showCreateLinkAccountFragment = false  -- Always assume we show the regular login screen first
    local function FilterMethodCallback(method)
        return function(_, ...)
            if self:IsLoginSceneShowing() or ZO_Dialogs_IsShowing("LOGIN_QUEUED") then
                -- calling self.method(self) is the same as calling self:method()
                return method(self, ...)
            end
        end
    end
    if IsUsingLinkedLogin() then
        EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_CREATE_LINK_LOADING_ERROR, FilterMethodCallback(self.OnCreateLinkLoadingError))
        EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_ACCOUNT_LINK_SUCCESSFUL, FilterMethodCallback(self.OnCreateLinkAccountSuccessful))
        EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_PROFILE_NOT_LINKED, FilterMethodCallback(self.OnProfileNotLinked))
    end
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_LOGIN_FAILED_INVALID_CREDENTIALS, FilterMethodCallback(self.OnBadLogin))
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_LOGIN_SUCCESSFUL, FilterMethodCallback(self.OnLoginSuccessful))
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_LOGIN_QUEUED, FilterMethodCallback(self.OnLoginQueued))
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_LOGIN_OVERFLOW_MODE_PROMPT, FilterMethodCallback(self.OnOverflowModeWaiting))
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_LOGIN_REQUESTED, FilterMethodCallback(self.OnLoginRequested))
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_LOGIN_OTP_PENDING, FilterMethodCallback(self.OnOTPPending))
    EVENT_MANAGER:RegisterForEvent("LoginManager", EVENT_BAD_CLIENT_VERSION, FilterMethodCallback(self.OnBadClientVersion))
end
function LoginManager_Keyboard:GetRelevantLoginFragment()
    -- Show the create/link account fragment if the following conditions are met:
    -- 1. If we require a linked login for the current client version
    -- 2. If we have not yet established a link between accounts
    -- 3. If we didn't encounter an error trying to establish the link (or the Login button was pressed again after that)
    if IsUsingLinkedLogin() and self.showCreateLinkAccountFragment then
        self.currentFragment = CREATE_LINK_ACCOUNT_FRAGMENT
    else
        self.currentFragment = LOGIN_FRAGMENT
    end
    return self.currentFragment
end
function LoginManager_Keyboard:HideShowingLoginFragment()
    if self.currentFragment then
        SCENE_MANAGER:RemoveFragment(self.currentFragment)
    end
end
function LoginManager_Keyboard:IsShowingCreateLinkAccountFragment()
    return self.showCreateLinkAccountFragment
end
function LoginManager_Keyboard:IsLoginSceneShowing()
    return GAME_MENU_PREGAME_KEYBOARD:IsLoginSceneShowing()
end
function LoginManager_Keyboard:SwitchToLoginFragment()
    if self.showCreateLinkAccountFragment then
        self.currentFragment = LOGIN_FRAGMENT
        GAME_MENU_PREGAME_KEYBOARD:GetScene():RemoveFragment(CREATE_LINK_ACCOUNT_FRAGMENT)
        GAME_MENU_PREGAME_KEYBOARD:GetScene():AddFragment(LOGIN_FRAGMENT)
        self.showCreateLinkAccountFragment = false
        LOGIN_KEYBOARD:SetLoginControlsHidden(false)
    end
end
function LoginManager_Keyboard:SwitchToCreateLinkAccountFragment()
    if not self.showCreateLinkAccountFragment then
        self.currentFragment = CREATE_LINK_ACCOUNT_FRAGMENT
        GAME_MENU_PREGAME_KEYBOARD:GetScene():RemoveFragment(LOGIN_FRAGMENT)
        GAME_MENU_PREGAME_KEYBOARD:GetScene():AddFragment(CREATE_LINK_ACCOUNT_FRAGMENT)
        self.showCreateLinkAccountFragment = true
        LOGIN_KEYBOARD:SetLoginControlsHidden(true)
    end
end
function LoginManager_Keyboard:IsLoginPossible()
    return not IsUsingLinkedLogin() or not self.mustRelaunch
end
function LoginManager_Keyboard:AttemptLinkedLogin()
    -- Attempts to log in with credentials supplied to the client by the launcher.
    ZO_Dialogs_ShowDialog("LINKED_LOGIN_KEYBOARD")
end
function LoginManager_Keyboard:AttemptCreateAccount(email, emailSignup, country, requestedAccountName)
    self.isLinking = nil
    ZO_Dialogs_ShowDialog("CREATING_ACCOUNT_KEYBOARD")
    PregameSetAccountCreationInfo(email, emailSignup, country, requestedAccountName)
end
function LoginManager_Keyboard:AttemptAccountLink(username, password)
    self.isLinking = true
    ZO_Dialogs_ShowDialog("LINKING_ACCOUNTS_KEYBOARD")
    PregameLinkAccount(username, password)
end
function LoginManager_Keyboard:RequestAccountActivationCode()
    self.isLinking = true
end
function LoginManager_Keyboard:OnCreateLinkAccountSuccessful()
    ZO_Dialogs_ReleaseDialog(self.isLinking and "LINKING_ACCOUNTS_KEYBOARD" or "CREATING_ACCOUNT_KEYBOARD")
    local textParams
    if not self.isLinking then
        local note3 = GetPlatformServiceType() == PLATFORM_SERVICE_TYPE_DMM and SI_CREATEACCOUNT_SUCCESS_NOTE_3_DMM or SI_CREATEACCOUNT_SUCCESS_NOTE_3
        textParams = { mainTextParams = {
                                            GetString(SI_CREATEACCOUNT_SUCCESS_HEADER),
                                            GetString(SI_CREATEACCOUNT_SUCCESS_NOTE_1),
                                            GetString(SI_CREATEACCOUNT_SUCCESS_NOTE_2),
                                            GetString(note3),
                                        }
                     }
    end
    ZO_Dialogs_ShowDialog(self.isLinking and "LINKING_ACCOUNTS_SUCCESS_KEYBOARD" or "CREATE_ACCOUNT_SUCCESS_KEYBOARD", nil, textParams)
    self.isLinking = nil
end
function LoginManager_Keyboard:OnCreateLinkLoadingError(loginError, linkingError, debugInfo)
    ZO_Dialogs_ReleaseDialog("LINKED_LOGIN_KEYBOARD")
    local dialogName
    local errorString
    local formattedErrorString
    local dialogData = nil
    if loginError ~= LOGIN_AUTH_ERROR_NO_ERROR then
        if loginError == LOGIN_AUTH_ERROR_ACCOUNT_NOT_LINKED then
            -- User needs to create a link.
            self:OnProfileNotLinked()
        else
            dialogName = "LINKED_LOGIN_ERROR_KEYBOARD"
            errorString = GetString("SI_LOGINAUTHERROR", loginError)
            if loginError == LOGIN_AUTH_ERROR_MISSING_DMM_TOKEN or loginError == LOGIN_AUTH_ERROR_BAD_DMM_TOKEN then
                -- If the issue was with the token, kinda have to restart, since that's supplied from the launcher
                self.mustRelaunch = true
                LOGIN_KEYBOARD:ShowRelaunchGameLabel()
            elseif loginError == LOGIN_AUTH_ERROR_ACCOUNT_NOT_VERIFIED or loginError == LOGIN_AUTH_ERROR_GAME_ACCOUNT_NOT_VERIFIED then
                dialogData =
                {
                    showResendVerificationEmail = true,
                }
            elseif loginError == LOGIN_AUTH_ERROR_ACCOUNT_BANNED or loginError == LOGIN_AUTH_ERROR_GAME_ACCOUNT_BANNED then
                dialogData =
                {
                    titleStringId = SI_LOGIN_DIALOG_TITLE_ACCOUNT_BANNED,
                }
            elseif loginError == LOGIN_AUTH_ERROR_ACCOUNT_SUSPENDED or loginError == LOGIN_AUTH_ERROR_GAME_ACCOUNT_SUSPENDED then
                dialogData =
                {
                    titleStringId = SI_LOGIN_DIALOG_TITLE_ACCOUNT_SUSPENDED,
                }
            end
            -- In any case, show the normal login fragment so that the user can attempt to manually login again if a
            -- relaunch isn't necessary.
            self:SwitchToLoginFragment()
        end
    elseif linkingError ~= ACCOUNT_CREATE_LINK_ERROR_NO_ERROR then
        ZO_Dialogs_ReleaseDialog(self.isLinking and "LINKING_ACCOUNTS_KEYBOARD" or "CREATING_ACCOUNT_KEYBOARD")
        dialogName = self.isLinking and "LINKING_ACCOUNTS_ERROR_KEYBOARD" or "CREATE_ACCOUNT_ERROR_KEYBOARD"
        if linkingError == ACCOUNT_CREATE_LINK_ERROR_EXTERNAL_REFERENCE_ALREADY_USED or linkingError == ACCOUNT_CREATE_LINK_ERROR_USER_ALREADY_LINKED then
            local serviceType = GetPlatformServiceType()
            local accountTypeName = GetString("SI_PLATFORMSERVICETYPE", serviceType)
            errorString = GetString(SI_LINKACCOUNT_ALREADY_LINKED_ERROR_FORMAT)
            formattedErrorString = zo_strformat(errorString, accountTypeName)
        else
            errorString = GetString("SI_ACCOUNTCREATELINKERROR", linkingError)
        end
        CREATE_LINK_ACCOUNT_KEYBOARD:GetPasswordEdit():Clear()
        -- We need to switch back to the login fragment to refresh session ID, or else the player won't be able to finish
        -- creating or linking an account
        self:SwitchToLoginFragment()
    end
    if dialogName then
        if errorString == nil or errorString == "" then
            errorString = GetString(SI_UNEXPECTED_ERROR)
        end
        if formattedErrorString == nil then
            formattedErrorString = zo_strformat(errorString, GetURLTextByType(APPROVED_URL_ESO_HELP))
        end
        local textParams = { mainTextParams = { formattedErrorString .. debugInfo }}
        ZO_Dialogs_ShowDialog(dialogName, dialogData, textParams)
    end
    self.isLinking = nil
end
function LoginManager_Keyboard:OnProfileNotLinked()
    ZO_Dialogs_ReleaseDialog("LINKED_LOGIN_KEYBOARD")
end
function LoginManager_Keyboard:OnLoginSuccessful()
    if IsUsingLinkedLogin() then
        self:SwitchToLoginFragment()
    end
    if PregameStateManager_GetCurrentState() == "AccountLogin" then
        PregameStateManager_SetState("WorldSelect_Requested")
    end
end
local loginQueuedScene
local currentLoginQueueWaitTime
local lastQueuePosition
local function GetLoginQueueApproximateWaitTime(waitTime, queuePosition)
    -- if our position increases, the ETA we have "locked" is no longer valid
    if not currentLoginQueueWaitTime or queuePosition > lastQueuePosition then
        currentLoginQueueWaitTime = zo_max(waitTime * 1000, 1000) -- minimum wait time is that last second...
    else
        currentLoginQueueWaitTime = zo_min(currentLoginQueueWaitTime, zo_max(waitTime * 1000, 1000))
    end
    lastQueuePosition = queuePosition
    return currentLoginQueueWaitTime
end
function LoginManager_Keyboard:OnLoginQueued(waitTime, queuePosition)
    if not loginQueuedScene then
        loginQueuedScene = ZO_Scene:New("loginQueuedScene", SCENE_MANAGER)
        loginQueuedScene:AddFragment(PREGAME_BACKGROUND_FRAGMENT)
    end
    SCENE_MANAGER:Show("loginQueuedScene")
    waitTime = GetLoginQueueApproximateWaitTime(waitTime, queuePosition)
    if ZO_Dialogs_IsShowing("LOGIN_QUEUED") then
        ZO_Dialogs_UpdateDialogMainText(ZO_Dialogs_FindDialog("LOGIN_QUEUED"), nil, { waitTime, queuePosition })
    else
        ZO_Dialogs_ReleaseAllDialogs(true)
        ZO_Dialogs_ShowDialog("LOGIN_QUEUED", nil, { mainTextParams = { waitTime, queuePosition } })
    end
end
function LoginManager_Keyboard:OnOverflowModeWaiting(mainServerETASeconds, queuePosition)
    local waitTime = GetLoginQueueApproximateWaitTime(mainServerETASeconds, queuePosition)
    ZO_Dialogs_ShowDialog("PROVIDE_OVERFLOW_RESPONSE", {waitTime = waitTime})
end
function LoginManager_Keyboard:OnBadClientVersion()
    ZO_Dialogs_ShowDialog("BAD_CLIENT_VERSION")
end
function LoginManager_Keyboard:OnLoginRequested()
end
function LoginManager_Keyboard:OnBadLogin(errorCode, accountPageURL)
    ZO_Dialogs_ReleaseDialog("LOGIN_REQUESTED")
    if errorCode == AUTHENTICATION_ERROR_PAYMENT_EXPIRED then
        ZO_Dialogs_ShowDialog("BAD_LOGIN_PAYMENT_EXPIRED", { accountPageURL = accountPageURL })
    elseif errorCode == AUTHENTICATION_ERROR_ACCOUNT_BANNED then
        ZO_Dialogs_ShowDialog("BAD_LOGIN_ACCOUNT_BANNED")
    elseif errorCode == AUTHENTICATION_ERROR_ACCOUNT_SUSPENDED then
        ZO_Dialogs_ShowDialog("BAD_LOGIN_ACCOUNT_SUSPENDED")
    else
        ZO_Dialogs_ShowDialog("BAD_LOGIN", { accountPageURL = accountPageURL })
    end
end
function LoginManager_Keyboard:OnOTPPending(otpReason, otpType, otpDurationInSeconds)
    local otpDurationMs = otpDurationInSeconds * 1000
    local otpExpirationMs = GetFrameTimeMilliseconds() + otpDurationMs
    local dialogName, textParams
    if otpReason == LOGIN_STATUS_OTP_PENDING then
        dialogName = "PROVIDE_OTP_INITIAL"
        textParams = { GetString(SI_OTP_DIALOG_SUBMIT), otpDurationMs }
    elseif otpReason == LOGIN_STATUS_OTP_FAILED then
        dialogName = "PROVIDE_OTP_SUBSEQUENT"
        textParams = { otpDurationMs }
    end
    ZO_Dialogs_ShowDialog(dialogName, { otpExpirationMs = otpExpirationMs, otpReason = otpReason }, {mainTextParams = textParams})
end
LOGIN_MANAGER_KEYBOARD = LoginManager_Keyboard:New()