mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 13:17:49 +00:00
278 lines
8.9 KiB
Lua
278 lines
8.9 KiB
Lua
--[[
|
|
// SetAccountCredentialsScreen.lua
|
|
]]
|
|
local CoreGui = game:GetService("CoreGui")
|
|
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
|
|
local Modules = GuiRoot:FindFirstChild("Modules")
|
|
|
|
local ContextActionService = game:GetService('ContextActionService')
|
|
local GuiService = game:GetService('GuiService')
|
|
|
|
local AccountManager = require(Modules:FindFirstChild('AccountManager'))
|
|
local AssetManager = require(Modules:FindFirstChild('AssetManager'))
|
|
local BaseSignInScreen = require(Modules:FindFirstChild('BaseSignInScreen'))
|
|
local Errors = require(Modules:FindFirstChild('Errors'))
|
|
local ErrorOverlay = require(Modules:FindFirstChild('ErrorOverlay'))
|
|
local EventHub = require(Modules:FindFirstChild('EventHub'))
|
|
local GlobalSettings = require(Modules:FindFirstChild('GlobalSettings'))
|
|
local LoadingWidget = require(Modules:FindFirstChild('LoadingWidget'))
|
|
local ScreenManager = require(Modules:FindFirstChild('ScreenManager'))
|
|
local SoundManager = require(Modules:FindFirstChild('SoundManager'))
|
|
local Strings = require(Modules:FindFirstChild('LocalizedStrings'))
|
|
local TextBox = require(Modules:FindFirstChild('TextBox'))
|
|
local Utility = require(Modules:FindFirstChild('Utility'))
|
|
local UserData = require(Modules:FindFirstChild('UserData'))
|
|
|
|
local function createSetAccountCredentialsScreen(title, description, buttonText)
|
|
local this = BaseSignInScreen()
|
|
|
|
this:SetTitle(string.upper(title or ""))
|
|
this:SetDescriptionText(description or "")
|
|
this:SetButtonText(buttonText or "")
|
|
|
|
local ModalOverlay = Utility.Create'Frame'
|
|
{
|
|
Name = "ModalOverlay";
|
|
Size = UDim2.new(1, 0, 1, 0);
|
|
BackgroundTransparency = GlobalSettings.ModalBackgroundTransparency;
|
|
BackgroundColor3 = GlobalSettings.ModalBackgroundColor;
|
|
BorderSizePixel = 0;
|
|
ZIndex = 4;
|
|
}
|
|
|
|
local myUsername = nil
|
|
local myPassword = nil
|
|
|
|
local isUsernameValid = false
|
|
local isPasswordValid = false
|
|
|
|
local UserNameProcessingCount = 0
|
|
local PasswordProcessingCount = 0
|
|
|
|
this.UsernameObject:SetDefaultText(Strings:LocalizedString("UsernameWord").." ("..
|
|
Strings:LocalizedString("UsernameRulePhrase")..")")
|
|
this.UsernameObject:SetKeyboardTitle(Strings:LocalizedString("UsernameWord"))
|
|
this.UsernameObject:SetKeyboardDescription(Strings:LocalizedString("UsernameRulePhrase"))
|
|
local usernameChangedCn = nil
|
|
|
|
this.PasswordObject:SetDefaultText(Strings:LocalizedString("PasswordWord").." ("..
|
|
Strings:LocalizedString("PasswordRulePhrase")..")")
|
|
this.PasswordObject:SetKeyboardTitle(Strings:LocalizedString("PasswordWord"))
|
|
this.PasswordObject:SetKeyboardDescription(Strings:LocalizedString("PasswordRulePhrase"))
|
|
this.PasswordObject:SetKeyboardType(Enum.XboxKeyBoardType.Password)
|
|
local passwordChangedCn = nil
|
|
|
|
local function createAndSetCredentialsAsync()
|
|
local result = nil
|
|
|
|
local function signInAsync()
|
|
-- check linked account status
|
|
result = AccountManager:HasLinkedAccountAsync()
|
|
|
|
-- linked, set credentials
|
|
if result == AccountManager.AuthResults.Success then
|
|
result = AccountManager:SetRobloxCredentialsAsync(myUsername, myPassword)
|
|
-- unlinked, create new account and set credentials
|
|
elseif result == AccountManager.AuthResults.AccountUnlinked then
|
|
result = AccountManager:GenerateAccountAsync(myUsername, myPassword)
|
|
end
|
|
end
|
|
|
|
local loader = LoadingWidget(
|
|
{ Parent = ModalOverlay }, { signInAsync } )
|
|
|
|
-- set up full screen loader
|
|
ModalOverlay.Parent = GuiRoot
|
|
ContextActionService:BindCoreAction("BlockB", function() end, false, Enum.KeyCode.ButtonB)
|
|
local selectedObject = GuiService.SelectedCoreObject
|
|
GuiService.SelectedCoreObject = nil
|
|
|
|
-- call loader
|
|
loader:AwaitFinished()
|
|
|
|
-- clean up
|
|
loader:Cleanup()
|
|
loader = nil
|
|
GuiService.SelectedCoreObject = selectedObject
|
|
ContextActionService:UnbindCoreAction("BlockB")
|
|
ModalOverlay.Parent = nil
|
|
|
|
if result == AccountManager.AuthResults.Success then
|
|
EventHub:dispatchEvent(EventHub.Notifications["AuthenticationSuccess"])
|
|
else
|
|
local err = result and Errors.Authentication[result] or Errors.Default
|
|
ScreenManager:OpenScreen(ErrorOverlay(err), false)
|
|
end
|
|
end
|
|
|
|
local function validatePassword(silent)
|
|
PasswordProcessingCount = PasswordProcessingCount + 1
|
|
|
|
local reason = nil
|
|
isPasswordValid, reason = AccountManager:IsValidPasswordAsync(myUsername or "", myPassword)
|
|
if isPasswordValid then
|
|
if myUsername and #myUsername > 0 then
|
|
GuiService.SelectedCoreObject = this.SignInButton
|
|
else
|
|
GuiService.SelectedCoreObject = this.UsernameSelection
|
|
end
|
|
elseif isPasswordValid == false then
|
|
if not silent then
|
|
-- web returns long strings on password error. Lets create our own error type
|
|
GuiService.SelectedCoreObject = this.PasswordSelection
|
|
local err = Errors.Default;
|
|
if reason then
|
|
err = Errors.SignIn.InvalidPassword
|
|
err.Msg = reason
|
|
end
|
|
ScreenManager:OpenScreen(ErrorOverlay(err), false)
|
|
end
|
|
else -- Http failure
|
|
|
|
end
|
|
|
|
PasswordProcessingCount = PasswordProcessingCount - 1
|
|
end
|
|
|
|
local function validateUsername(silent)
|
|
UserNameProcessingCount = UserNameProcessingCount + 1
|
|
|
|
-- 1. Check if valid user name
|
|
local reason = nil
|
|
isUsernameValid, reason = AccountManager:IsValidUsernameAsync(myUsername)
|
|
if isUsernameValid then
|
|
-- 2. if password set, need to recheck password rules
|
|
if myPassword and #myPassword > 0 then
|
|
validatePassword()
|
|
else
|
|
GuiService.SelectedCoreObject = this.PasswordSelection
|
|
end
|
|
elseif isUsernameValid == false then
|
|
if not silent then
|
|
GuiService.SelectedCoreObject = this.UsernameSelection
|
|
-- NOTE: Web has changed username rules and the result of the ErrorMessage in the endpoint call.
|
|
-- We key check reason vs. our current error table, if we don't find a key, we create an error out
|
|
-- of the reason returned. If there is no reason, use default. This covers both old and new behavior
|
|
local err = nil
|
|
if Errors.SignIn[reason] then
|
|
err = Errors.SignIn[reason]
|
|
elseif reason then
|
|
err = { Title = Strings:LocalizedString("InvalidUsernameTitle"), Msg = reason }
|
|
else
|
|
err = Errors.Default
|
|
end
|
|
ScreenManager:OpenScreen(ErrorOverlay(err), false)
|
|
end
|
|
else -- Http Request failed
|
|
|
|
end
|
|
|
|
UserNameProcessingCount = UserNameProcessingCount - 1
|
|
end
|
|
|
|
local function onUsernameChanged(text)
|
|
myUsername = text
|
|
if #myUsername > 0 then
|
|
validateUsername()
|
|
else
|
|
GuiService.SelectedCoreObject = this.UsernameSelection
|
|
isUsernameValid = false
|
|
end
|
|
end
|
|
|
|
local function onPasswordChanged(text)
|
|
myPassword = text
|
|
if #myPassword > 0 then
|
|
validatePassword()
|
|
else
|
|
GuiService.SelectedCoreObject = this.PasswordSelection
|
|
isPasswordValid = false
|
|
end
|
|
end
|
|
|
|
|
|
local isSettingCredentials = false
|
|
this.SignInButton.MouseButton1Click:connect(function()
|
|
if isSettingCredentials then return end
|
|
isSettingCredentials = true
|
|
|
|
local function stillValidatingUserInfo()
|
|
return UserNameProcessingCount > 0 or PasswordProcessingCount > 0
|
|
end
|
|
local function awaitValidatingUserInfo()
|
|
while stillValidatingUserInfo() do wait() end
|
|
end
|
|
|
|
SoundManager:Play('ButtonPress')
|
|
|
|
|
|
local processingFunctions = nil
|
|
-- Wait for current validation to finish
|
|
if stillValidatingUserInfo() then
|
|
|
|
processingFunctions = { awaitValidatingUserInfo }
|
|
|
|
-- Retry our username and password validation
|
|
elseif isUsernameValid == nil or isPasswordValid == nil then
|
|
|
|
processingFunctions = {}
|
|
if isUsernameValid == nil then
|
|
table.insert(processingFunctions, function() validateUsername(true) awaitValidatingUserInfo() end)
|
|
end
|
|
if isPasswordValid == nil then
|
|
table.insert(processingFunctions, function() validatePassword(true) awaitValidatingUserInfo() end)
|
|
end
|
|
|
|
end
|
|
|
|
if processingFunctions then
|
|
local processingLoader = LoadingWidget(
|
|
{ Parent = ModalOverlay },
|
|
processingFunctions)
|
|
|
|
-- NOTE: may need to get a separate overlay for this spinner
|
|
-- Also should we disable input while overlay is active?
|
|
ModalOverlay.Parent = GuiRoot
|
|
|
|
processingLoader:AwaitFinished()
|
|
processingLoader:Cleanup()
|
|
processingLoader = nil
|
|
|
|
ModalOverlay.Parent = nil
|
|
end
|
|
|
|
if isUsernameValid and isPasswordValid then
|
|
createAndSetCredentialsAsync()
|
|
elseif isUsernameValid == false or isPasswordValid == false then
|
|
local err = Errors.SignIn.NoUsernameOrPasswordEntered
|
|
ScreenManager:OpenScreen(ErrorOverlay(err), false)
|
|
else -- Http failed to validate your password or username
|
|
local err = Errors.SignIn.ConnectionFailed
|
|
ScreenManager:OpenScreen(ErrorOverlay(err), false)
|
|
end
|
|
isSettingCredentials = false
|
|
end)
|
|
|
|
|
|
--[[ Public API ]]--
|
|
-- override
|
|
local baseFocus = this.Focus
|
|
function this:Focus()
|
|
baseFocus(self)
|
|
usernameChangedCn = this.UsernameObject.OnTextChanged:connect(onUsernameChanged)
|
|
passwordChangedCn = this.PasswordObject.OnTextChanged:connect(onPasswordChanged)
|
|
end
|
|
|
|
-- override
|
|
local baseRemoveFocus = this.RemoveFocus
|
|
function this:RemoveFocus()
|
|
baseRemoveFocus(self)
|
|
Utility.DisconnectEvent(usernameChangedCn)
|
|
Utility.DisconnectEvent(passwordChangedCn)
|
|
end
|
|
|
|
return this
|
|
end
|
|
|
|
return createSetAccountCredentialsScreen
|