add gs
This commit is contained in:
@@ -0,0 +1,998 @@
|
||||
-- Creates the generic "ROBLOX" loading screen on startup
|
||||
-- Written by ArceusInator & Ben Tkacheff, 2014
|
||||
-- Updates by 0xBAADF00D, 2017
|
||||
local AssetService = game:GetService("AssetService")
|
||||
local MarketplaceService = game:GetService("MarketplaceService")
|
||||
local UserInputService = game:GetService("UserInputService")
|
||||
local VRService = game:GetService("VRService")
|
||||
local GuiService = game:GetService("GuiService")
|
||||
local ContextActionService = game:GetService("ContextActionService")
|
||||
local RunService = game:GetService("RunService")
|
||||
local Players = game:GetService("Players")
|
||||
local ContentProvider = game:GetService("ContentProvider")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local ReplicatedFirst = game:GetService("ReplicatedFirst")
|
||||
local ScriptContext = game:GetService("ScriptContext")
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local create = require(RobloxGui:WaitForChild("Modules"):WaitForChild("Common"):WaitForChild("Create"))
|
||||
local PolicyService = require(RobloxGui.Modules.Common:WaitForChild("PolicyService"))
|
||||
|
||||
--FFlags
|
||||
local FFlagLoadTheLoadingScreenFasterSuccess, FFlagLoadTheLoadingScreenFasterValue = pcall(function() return settings():GetFFlag("LoadTheLoadingScreenFaster") end)
|
||||
local FFlagLoadTheLoadingScreenFaster = FFlagLoadTheLoadingScreenFasterSuccess and FFlagLoadTheLoadingScreenFasterValue
|
||||
local FFlagLoadTheLoadingScreenEvenFaster = game:DefineFastFlag("LoadTheLoadingScreenEvenFaster", false)
|
||||
local FFlagLoadingScreenDontBlockOnPolicyService = game:DefineFastFlag("LoadingScreenDontBlockOnPolicyService", false)
|
||||
local FFlagBackButtonWhileLoadingGoesBackToApp = game:DefineFastFlag("BackButtonWhileLoadingGoesBackToApp", false)
|
||||
local FFlagLoadingScreenShowBlankUntilPolicyServiceReturns = game:DefineFastFlag("LoadingScreenShowBlankUntilPolicyServiceReturns", false)
|
||||
|
||||
local FFlagShowConnectionErrorCode = settings():GetFFlag("ShowConnectionErrorCode")
|
||||
local FFlagConnectionScriptEnabled = settings():GetFFlag("ConnectionScriptEnabled")
|
||||
|
||||
local antiAddictionNoticeStringEn = "Boycott bad games, refuse pirated games. Be aware of self-defense and being deceived. Playing games is good for your brain, but too much game play can harm your health. Manage your time well and enjoy a healthy lifestyle."
|
||||
local FFlagConnectErrorHandlerInLoadingScript = require(RobloxGui.Modules.Flags.FFlagConnectErrorHandlerInLoadingScript)
|
||||
local loadErrorHandlerFromEngine = game:GetEngineFeature("LoadErrorHandlerFromEngine")
|
||||
|
||||
local debugMode = false
|
||||
|
||||
local startTime = tick()
|
||||
local loadingImageInputBeganConn = nil
|
||||
local waitForGameIdConnection
|
||||
|
||||
local GAME_THUMBNAIL_URL = "rbxthumb://type=GameIcon&id=%d&w=256&h=256"
|
||||
local MAX_ICON_SIZE = Vector2.new(256, 256)
|
||||
local ICON_ASPECT_RATIO = 1
|
||||
|
||||
local COLORS = {
|
||||
BACKGROUND_COLOR = Color3.fromRGB(45, 45, 45),
|
||||
TEXT_COLOR = Color3.fromRGB(255, 255, 255),
|
||||
ERROR = Color3.fromRGB(253, 68, 72)
|
||||
}
|
||||
local spinnerImageId = "rbxasset://textures/loading/robloxTilt.png"
|
||||
|
||||
-- Variables
|
||||
local GameAssetInfo -- loaded by InfoProvider:LoadAssets()
|
||||
local currScreenGui
|
||||
local renderSteppedConnection
|
||||
local backButtonConnection
|
||||
local destroyingBackground, destroyedLoadingGui = false, false
|
||||
local isTenFootInterface = GuiService:IsTenFootInterface()
|
||||
|
||||
local placeLabel, creatorLabel = nil, nil
|
||||
local backgroundFadeStarted = false
|
||||
local tweenPlaceIcon = nil
|
||||
local layoutIsReady = false
|
||||
|
||||
local connectionHealthShown = false
|
||||
local connectionHealthCon
|
||||
|
||||
local InfoProvider = {}
|
||||
|
||||
local function WaitForPlaceId()
|
||||
local placeId = game.PlaceId
|
||||
if placeId == 0 then
|
||||
game:GetPropertyChangedSignal("PlaceId"):wait()
|
||||
placeId = game.PlaceId
|
||||
end
|
||||
return placeId
|
||||
end
|
||||
|
||||
function InfoProvider:GetGameName()
|
||||
if GameAssetInfo ~= nil then
|
||||
return GameAssetInfo.Name
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
function InfoProvider:GetCreatorName()
|
||||
if GameAssetInfo ~= nil then
|
||||
return GameAssetInfo.Creator.Name
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
function InfoProvider:LoadAssets()
|
||||
if FFlagLoadTheLoadingScreenFaster then
|
||||
coroutine.wrap(function()
|
||||
local placeId = WaitForPlaceId()
|
||||
local success, result = pcall(function()
|
||||
GameAssetInfo = MarketplaceService:GetProductInfo(placeId)
|
||||
end)
|
||||
if not success then
|
||||
print("LoadingScript->InfoProvider:LoadAssets:", result)
|
||||
end
|
||||
end)()
|
||||
else
|
||||
--spawn() == slowpoke.jpg
|
||||
spawn(function()
|
||||
local PLACEID = game.PlaceId
|
||||
if PLACEID <= 0 then
|
||||
while game.PlaceId <= 0 do
|
||||
wait()
|
||||
end
|
||||
PLACEID = game.PlaceId
|
||||
end
|
||||
|
||||
-- load game asset info
|
||||
coroutine.resume(coroutine.create(function()
|
||||
local success, result = pcall(function()
|
||||
GameAssetInfo = MarketplaceService:GetProductInfo(PLACEID)
|
||||
end)
|
||||
if not success then
|
||||
print("LoadingScript->InfoProvider:LoadAssets:", result)
|
||||
end
|
||||
end))
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- create a cancel binding for console to be able to cancel anytime while loading
|
||||
local function createTenfootCancelGui()
|
||||
local cancelLabel = create'ImageLabel'
|
||||
{
|
||||
Name = "CancelLabel",
|
||||
Size = UDim2.new(0, 83, 0, 83),
|
||||
Position = UDim2.new(1, -32 - 83, 0, 32),
|
||||
BackgroundTransparency = 1,
|
||||
Image = 'rbxasset://textures/ui/Shell/ButtonIcons/BButton.png'
|
||||
}
|
||||
local cancelText = create'TextLabel'
|
||||
{
|
||||
Name = "CancelText",
|
||||
Size = UDim2.new(0, 400, 0, 83),
|
||||
Position = UDim2.new(1, -131, 0, 32),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
BackgroundTransparency = 1,
|
||||
Font = Enum.Font.SourceSans,
|
||||
TextSize = 48,
|
||||
TextXAlignment = Enum.TextXAlignment.Right,
|
||||
TextColor3 = COLORS.TEXT_COLOR,
|
||||
Text = "Cancel"
|
||||
}
|
||||
|
||||
if not ReplicatedFirst:IsFinishedReplicating() then
|
||||
local seenBButtonBegin = false
|
||||
ContextActionService:BindCoreAction("CancelGameLoad",
|
||||
function(actionName, inputState, inputObject)
|
||||
if inputState == Enum.UserInputState.Begin then
|
||||
seenBButtonBegin = true
|
||||
elseif inputState == Enum.UserInputState.End and seenBButtonBegin then
|
||||
cancelLabel:Destroy()
|
||||
cancelText.Text = "Canceling..."
|
||||
cancelText.Position = UDim2.new(1, -32, 0, 32)
|
||||
ContextActionService:UnbindCoreAction('CancelGameLoad')
|
||||
game:Shutdown()
|
||||
end
|
||||
end,
|
||||
false,
|
||||
Enum.KeyCode.ButtonB)
|
||||
end
|
||||
|
||||
while cancelLabel.Parent == nil do
|
||||
if currScreenGui then
|
||||
local blackFrame = currScreenGui:FindFirstChild('BlackFrame')
|
||||
if blackFrame then
|
||||
cancelLabel.Parent = blackFrame
|
||||
cancelText.Parent = blackFrame
|
||||
break
|
||||
end
|
||||
end
|
||||
wait()
|
||||
end
|
||||
end
|
||||
|
||||
local function GenerateGui()
|
||||
local screenGui = create 'ScreenGui' {
|
||||
Name = 'RobloxLoadingGui',
|
||||
DisplayOrder = 8,
|
||||
}
|
||||
|
||||
--
|
||||
-- create descendant frames
|
||||
local mainBackgroundContainer
|
||||
|
||||
local inGameGlobalGuiInset = settings():GetFVariable("InGameGlobalGuiInset")
|
||||
mainBackgroundContainer = create 'Frame' {
|
||||
Name = 'BlackFrame',
|
||||
BackgroundColor3 = COLORS.BACKGROUND_COLOR,
|
||||
BackgroundTransparency = 0,
|
||||
Size = UDim2.new(1, 0, 1, inGameGlobalGuiInset),
|
||||
Position = UDim2.new(0, 0, 0, -inGameGlobalGuiInset),
|
||||
Active = true,
|
||||
Parent = screenGui
|
||||
}
|
||||
|
||||
local closeButton = create 'ImageButton' {
|
||||
Name = 'CloseButton',
|
||||
Image = 'rbxasset://textures/loading/cancelButton.png',
|
||||
ImageTransparency = 1,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(1, -37, 0, 5),
|
||||
Size = UDim2.new(0, 32, 0, 32),
|
||||
Active = false,
|
||||
ZIndex = 10,
|
||||
Parent = mainBackgroundContainer
|
||||
}
|
||||
|
||||
closeButton.MouseButton1Click:connect(function()
|
||||
game:Shutdown()
|
||||
end)
|
||||
|
||||
local graphicsFrame = create 'Frame' {
|
||||
Name = 'GraphicsFrame',
|
||||
BorderSizePixel = 0,
|
||||
BackgroundTransparency = 1,
|
||||
AnchorPoint = Vector2.new(1, 1),
|
||||
Position = UDim2.new(0.95, 0, 0.95, 0),
|
||||
Size = UDim2.new(0.15, 0, 0.15, 0),
|
||||
ZIndex = 2,
|
||||
Parent = mainBackgroundContainer,
|
||||
|
||||
create("UIAspectRatioConstraint") {
|
||||
AspectRatio = 1
|
||||
},
|
||||
create("UISizeConstraint") {
|
||||
MaxSize = Vector2.new(100, 100)
|
||||
}
|
||||
}
|
||||
|
||||
local loadingImage = create 'ImageLabel' {
|
||||
Name = 'LoadingImage',
|
||||
BackgroundTransparency = 1,
|
||||
Image = spinnerImageId,
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
ZIndex = 2,
|
||||
Parent = graphicsFrame,
|
||||
}
|
||||
|
||||
local numberOfTaps = 0
|
||||
local lastTapTime = math.huge
|
||||
local doubleTapTimeThreshold = 0.5
|
||||
|
||||
loadingImageInputBeganConn = loadingImage.InputBegan:connect(function()
|
||||
if PolicyService:IsSubjectToChinaPolicies() then
|
||||
return
|
||||
end
|
||||
|
||||
if numberOfTaps == 0 then
|
||||
numberOfTaps = 1
|
||||
lastTapTime = tick()
|
||||
return
|
||||
end
|
||||
|
||||
if UserInputService.TouchEnabled == true and UserInputService.MouseEnabled == false then
|
||||
if tick() - lastTapTime <= doubleTapTimeThreshold then
|
||||
GuiService:ShowStatsBasedOnInputString("ConnectionHealth")
|
||||
connectionHealthShown = not connectionHealthShown
|
||||
end
|
||||
end
|
||||
|
||||
numberOfTaps = 0
|
||||
lastTapTime = math.huge
|
||||
end)
|
||||
|
||||
local infoFrame = create 'Frame' {
|
||||
Name = 'InfoFrame',
|
||||
BackgroundTransparency = 1,
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
Size = UDim2.new(0.75, 0, 1, 0),
|
||||
ZIndex = 2,
|
||||
Parent = mainBackgroundContainer,
|
||||
create 'UIPadding' {
|
||||
Name = 'UiMessagePadding',
|
||||
PaddingBottom = UDim.new(0, 25),
|
||||
} or nil
|
||||
}
|
||||
|
||||
|
||||
local uiMessageFrame = create 'Frame' {
|
||||
Name = 'UiMessageFrame',
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0.25, 0, 1, -120),
|
||||
Size = UDim2.new(1, 0, 0, 35),
|
||||
ZIndex = 2,
|
||||
LayoutOrder = 5,
|
||||
Parent = infoFrame,
|
||||
|
||||
create 'TextLabel' {
|
||||
Name = 'UiMessage',
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, 5),
|
||||
Size = UDim2.new(1, 0, 0, 25),
|
||||
Font = Enum.Font.SourceSansLight,
|
||||
TextSize = 18,
|
||||
TextScaled = true,
|
||||
TextWrapped = true,
|
||||
TextColor3 = COLORS.TEXT_COLOR,
|
||||
Text = "",
|
||||
TextTransparency = 1,
|
||||
ZIndex = 2,
|
||||
}
|
||||
}
|
||||
|
||||
local infoFrameAspect = create("UIAspectRatioConstraint") {
|
||||
AspectRatio = 3 / 2,
|
||||
Parent = infoFrame
|
||||
}
|
||||
local infoFrameList = create("UIListLayout") {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
FillDirection = Enum.FillDirection.Vertical,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
Padding = UDim.new(0.05, 0),
|
||||
Parent = infoFrame
|
||||
}
|
||||
|
||||
local textContainer = create("Frame") {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(2/3, 0, 1, 0),
|
||||
LayoutOrder = 2,
|
||||
Parent = nil,
|
||||
|
||||
create("UIListLayout") {
|
||||
FillDirection = Enum.FillDirection.Vertical,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder
|
||||
}
|
||||
}
|
||||
local placeIcon = create("ImageLabel") {
|
||||
Name = "PlaceIcon",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
Position = UDim2.new(0.5, 0, 0, 0),
|
||||
AnchorPoint = Vector2.new(0.5, 0),
|
||||
LayoutOrder = 1,
|
||||
Parent = infoFrame,
|
||||
|
||||
ImageTransparency = 1,
|
||||
Image = "",
|
||||
|
||||
create("UIAspectRatioConstraint") {
|
||||
AspectRatio = FFlagLoadTheLoadingScreenEvenFaster and ICON_ASPECT_RATIO or 576 / 324,
|
||||
AspectType = Enum.AspectType.ScaleWithParentSize,
|
||||
DominantAxis = Enum.DominantAxis.Width
|
||||
},
|
||||
create("UISizeConstraint") {
|
||||
MaxSize = FFlagLoadTheLoadingScreenEvenFaster and MAX_ICON_SIZE or Vector2.new(400, 400)
|
||||
}
|
||||
}
|
||||
|
||||
if FFlagLoadTheLoadingScreenEvenFaster then
|
||||
local function onGameId()
|
||||
local gameId = game.GameId
|
||||
local imageUrl = GAME_THUMBNAIL_URL:format(gameId)
|
||||
placeIcon.Image = imageUrl
|
||||
ContentProvider:PreloadAsync({ placeIcon })
|
||||
if not backgroundFadeStarted then
|
||||
placeIcon.ImageTransparency = 0
|
||||
end
|
||||
end
|
||||
if game.GameId > 0 then
|
||||
coroutine.wrap(onGameId)()
|
||||
else
|
||||
waitForGameIdConnection = game:GetPropertyChangedSignal("GameId"):Connect(function ()
|
||||
waitForGameIdConnection:Disconnect()
|
||||
onGameId()
|
||||
end)
|
||||
end
|
||||
else
|
||||
--Start trying to load the place icon image
|
||||
--Web might not have this icon size generated, so we can poll asset-thumbnail/json and check
|
||||
--the JSON result for thumbnailFinal/Final to see when it's done being generated so we never
|
||||
--show a N/A image. This is how the console AppShell does it!
|
||||
coroutine.wrap(function()
|
||||
local placeId = WaitForPlaceId()
|
||||
|
||||
local function tryGetFinalAsync()
|
||||
local imageUrl = nil
|
||||
local isGenerated = false
|
||||
local success, msg = pcall(function()
|
||||
imageUrl, isGenerated = AssetService:GetAssetThumbnailAsync(placeId, Vector2.new(576, 324), 1)
|
||||
end)
|
||||
|
||||
if success and isGenerated == true and imageUrl then
|
||||
ContentProvider:PreloadAsync { imageUrl }
|
||||
placeIcon.Image = imageUrl
|
||||
|
||||
if not backgroundFadeStarted then
|
||||
placeIcon.ImageTransparency = 0
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
while not tryGetFinalAsync() do end
|
||||
end)()
|
||||
end
|
||||
|
||||
placeLabel = create 'TextLabel' {
|
||||
Name = 'PlaceLabel',
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, 80),
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Font = Enum.Font.SourceSans,
|
||||
TextSize = isTenFootInterface and 48 or 24,
|
||||
TextWrapped = true,
|
||||
TextScaled = true,
|
||||
TextColor3 = COLORS.TEXT_COLOR,
|
||||
TextStrokeTransparency = 1,
|
||||
TextTransparency = 1,
|
||||
Text = "",
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
TextYAlignment = Enum.TextYAlignment.Bottom,
|
||||
ZIndex = 2,
|
||||
LayoutOrder = 2,
|
||||
Parent = infoFrame
|
||||
}
|
||||
|
||||
local creatorContainer = create 'Frame' {
|
||||
Name = "Creator",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, 48),
|
||||
LayoutOrder = 3,
|
||||
|
||||
create 'UIListLayout' {
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 5)
|
||||
}
|
||||
}
|
||||
|
||||
local byLabel, creatorIcon = nil, nil
|
||||
if isTenFootInterface then
|
||||
byLabel = create'TextLabel' {
|
||||
Name = "ByLabel",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, 36, 0, 30),
|
||||
Position = UDim2.new(0, 0, 0, 80),
|
||||
Font = Enum.Font.SourceSansLight,
|
||||
TextSize = 36,
|
||||
TextScaled = true,
|
||||
TextColor3 = COLORS.TEXT_COLOR,
|
||||
TextStrokeTransparency = 1,
|
||||
Text = "By",
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
ZIndex = 2,
|
||||
Visible = true,
|
||||
Parent = infoFrame,
|
||||
LayoutOrder = 1
|
||||
}
|
||||
creatorIcon = create'ImageLabel' {
|
||||
Name = "CreatorIcon",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, 30, 0, 30),
|
||||
Position = UDim2.new(0, 38, 0, 80),
|
||||
ImageTransparency = 0,
|
||||
Image = 'rbxasset://textures/ui/Shell/Icons/RobloxIcon24.png',
|
||||
ZIndex = 2,
|
||||
Visible = true,
|
||||
Parent = infoFrame,
|
||||
LayoutOrder = 2
|
||||
}
|
||||
end
|
||||
|
||||
creatorLabel = create 'TextLabel' {
|
||||
Name = 'CreatorLabel',
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, 30),
|
||||
Position = UDim2.new(0, 0, 0, 80),
|
||||
Font = Enum.Font.SourceSansLight,
|
||||
TextSize = isTenFootInterface and 36 or 18,
|
||||
TextWrapped = true,
|
||||
TextScaled = true,
|
||||
TextColor3 = COLORS.TEXT_COLOR,
|
||||
TextStrokeTransparency = 1,
|
||||
Text = "",
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
TextYAlignment = Enum.TextYAlignment.Center,
|
||||
ZIndex = 2,
|
||||
LayoutOrder = 4,
|
||||
Parent = infoFrame
|
||||
}
|
||||
|
||||
if isTenFootInterface then
|
||||
creatorContainer.Parent = infoFrame
|
||||
|
||||
byLabel.TextScaled = false
|
||||
byLabel.Parent = creatorContainer
|
||||
byLabel.TextXAlignment = Enum.TextXAlignment.Center
|
||||
byLabel.TextYAlignment = Enum.TextYAlignment.Center
|
||||
|
||||
creatorIcon.Parent = creatorContainer
|
||||
|
||||
creatorLabel.Parent = creatorContainer
|
||||
creatorLabel.TextScaled = false
|
||||
creatorLabel.TextWrapped = false
|
||||
creatorLabel.Position = UDim2.new(0, 72, 0, 80)
|
||||
creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0)
|
||||
end
|
||||
|
||||
coroutine.wrap(function()
|
||||
RunService.RenderStepped:wait()
|
||||
RunService.RenderStepped:wait()
|
||||
layoutIsReady = true
|
||||
|
||||
placeLabel.TextTransparency = 0
|
||||
|
||||
local uiMessage = uiMessageFrame.UiMessage
|
||||
if uiMessage.Text ~= "" then
|
||||
uiMessage.TextTransparency = 0
|
||||
end
|
||||
end)()
|
||||
|
||||
if not FFlagConnectionScriptEnabled or isTenFootInterface then
|
||||
local errorFrame = create 'Frame' {
|
||||
Name = 'ErrorFrame',
|
||||
BackgroundColor3 = COLORS.ERROR,
|
||||
BorderSizePixel = 0,
|
||||
Position = UDim2.new(0.25,0,0,0),
|
||||
Size = UDim2.new(0.5, 0, 0, 80),
|
||||
ZIndex = 8,
|
||||
Visible = false,
|
||||
Parent = screenGui,
|
||||
|
||||
create 'TextLabel' {
|
||||
Name = "ErrorText",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
Font = Enum.Font.SourceSansBold,
|
||||
TextSize = 14,
|
||||
TextWrapped = true,
|
||||
TextColor3 = COLORS.TEXT_COLOR,
|
||||
Text = "",
|
||||
ZIndex = 8
|
||||
}
|
||||
}
|
||||
else
|
||||
if not loadErrorHandlerFromEngine and FFlagConnectErrorHandlerInLoadingScript then
|
||||
ScriptContext:AddCoreScriptLocal("Connection", RobloxGui)
|
||||
end
|
||||
end
|
||||
|
||||
while not game:GetService("CoreGui") do
|
||||
if FFlagLoadTheLoadingScreenFaster then
|
||||
RunService.RenderStepped:wait()
|
||||
else
|
||||
wait()
|
||||
end
|
||||
end
|
||||
|
||||
screenGui.Parent = CoreGui
|
||||
|
||||
infoFrame.RootLocalizationTable = CoreGui:FindFirstChild("CoreScriptLocalization")
|
||||
|
||||
currScreenGui = screenGui
|
||||
|
||||
local function onResized()
|
||||
local isPortrait = screenGui.AbsoluteSize.X < screenGui.AbsoluteSize.Y
|
||||
|
||||
infoFrame.Position = UDim2.new(0.5, 0, 0.5, 0)
|
||||
infoFrame.AnchorPoint = Vector2.new(0.5, 0.5)
|
||||
infoFrame.Size = UDim2.new(0.75, 0, 1, 0)
|
||||
infoFrameAspect.AspectRatio = isPortrait and 2/3 or 3/2
|
||||
|
||||
placeLabel.Size = UDim2.new(1, 0, 0, isTenFootInterface and 120 or 80)
|
||||
|
||||
if isTenFootInterface then
|
||||
creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0)
|
||||
else
|
||||
creatorLabel.Size = UDim2.new(1, 0, 0, 30)
|
||||
end
|
||||
|
||||
infoFrameList.FillDirection = Enum.FillDirection.Vertical
|
||||
infoFrameList.HorizontalAlignment = Enum.HorizontalAlignment.Center
|
||||
infoFrameList.Padding = UDim.new(0, 0)
|
||||
textContainer.Parent = nil
|
||||
infoFrameList:ApplyLayout()
|
||||
|
||||
placeLabel.TextXAlignment = Enum.TextXAlignment.Center
|
||||
placeLabel.AutoLocalize = false
|
||||
end
|
||||
onResized()
|
||||
screenGui:GetPropertyChangedSignal("AbsoluteSize"):connect(onResized)
|
||||
end
|
||||
|
||||
---------------------------------------------------------
|
||||
-- Main Script (show something now + setup connections)
|
||||
|
||||
-- start loading assets asap
|
||||
InfoProvider:LoadAssets()
|
||||
GenerateGui()
|
||||
if isTenFootInterface then
|
||||
createTenfootCancelGui()
|
||||
end
|
||||
|
||||
local fadeCycleTime = 1.7
|
||||
local turnCycleTime = 2
|
||||
|
||||
local function spinnerEasingFunc(a, b, t)
|
||||
t = t * 2
|
||||
if t < 1 then
|
||||
return b / 2 * t*t*t + a
|
||||
else
|
||||
t = t - 2
|
||||
return b / 2 * (t * t * t + 2) + b
|
||||
end
|
||||
end
|
||||
|
||||
if FFlagLoadingScreenDontBlockOnPolicyService then
|
||||
local showAntiAddictionNoticeStringEn = false
|
||||
if FFlagLoadingScreenShowBlankUntilPolicyServiceReturns then
|
||||
showAntiAddictionNoticeStringEn = "waiting"
|
||||
end
|
||||
-- PolicyService requires LocalPlayer to exist, which doesn't happen until
|
||||
-- after we connect to the server. If the server is full, this can take a
|
||||
-- very long time (like several minutes) to return a value. As a result, we
|
||||
-- call it asynchronously and default to false.
|
||||
coroutine.wrap(function()
|
||||
showAntiAddictionNoticeStringEn = PolicyService:IsSubjectToChinaPolicies()
|
||||
end)()
|
||||
|
||||
renderSteppedConnection = RunService.RenderStepped:connect(function(dt)
|
||||
if not currScreenGui then return end
|
||||
if not currScreenGui:FindFirstChild("BlackFrame") then return end
|
||||
|
||||
local infoFrame = currScreenGui.BlackFrame:FindFirstChild('InfoFrame')
|
||||
if infoFrame then
|
||||
-- set place name
|
||||
if placeLabel and placeLabel.Text == "" then
|
||||
placeLabel.Text = InfoProvider:GetGameName()
|
||||
end
|
||||
|
||||
-- set creator name
|
||||
if creatorLabel and creatorLabel.Text == "" then
|
||||
if FFlagLoadingScreenShowBlankUntilPolicyServiceReturns and showAntiAddictionNoticeStringEn == "waiting" then
|
||||
creatorLabel.Text = ""
|
||||
elseif showAntiAddictionNoticeStringEn then
|
||||
creatorLabel.Text = antiAddictionNoticeStringEn
|
||||
else
|
||||
local creatorName = InfoProvider:GetCreatorName()
|
||||
if creatorName ~= "" then
|
||||
if isTenFootInterface then
|
||||
creatorLabel.Text = creatorName
|
||||
creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0)
|
||||
else
|
||||
creatorLabel.Text = "By ".. creatorName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local currentTime = tick()
|
||||
local fadeAmount = dt * fadeCycleTime
|
||||
|
||||
local spinnerImage = currScreenGui.BlackFrame.GraphicsFrame.LoadingImage
|
||||
local timeInCycle = currentTime % turnCycleTime
|
||||
local cycleAlpha = spinnerEasingFunc(0, 1, timeInCycle / turnCycleTime)
|
||||
spinnerImage.Rotation = cycleAlpha * 360
|
||||
|
||||
|
||||
if not isTenFootInterface then
|
||||
if currentTime - startTime > 5 and currScreenGui.BlackFrame.CloseButton.ImageTransparency > 0 then
|
||||
currScreenGui.BlackFrame.CloseButton.ImageTransparency = currScreenGui.BlackFrame.CloseButton.ImageTransparency - fadeAmount
|
||||
|
||||
if currScreenGui.BlackFrame.CloseButton.ImageTransparency <= 0 then
|
||||
currScreenGui.BlackFrame.CloseButton.Active = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
coroutine.wrap(function()
|
||||
local showAntiAddictionNoticeStringEn = PolicyService:IsSubjectToChinaPolicies()
|
||||
|
||||
renderSteppedConnection = RunService.RenderStepped:connect(function(dt)
|
||||
if not currScreenGui then return end
|
||||
if not currScreenGui:FindFirstChild("BlackFrame") then return end
|
||||
|
||||
local infoFrame = currScreenGui.BlackFrame:FindFirstChild('InfoFrame')
|
||||
if infoFrame then
|
||||
-- set place name
|
||||
if placeLabel and placeLabel.Text == "" then
|
||||
placeLabel.Text = InfoProvider:GetGameName()
|
||||
end
|
||||
|
||||
-- set creator name
|
||||
if creatorLabel and creatorLabel.Text == "" then
|
||||
if showAntiAddictionNoticeStringEn then
|
||||
creatorLabel.Text = antiAddictionNoticeStringEn
|
||||
else
|
||||
local creatorName = InfoProvider:GetCreatorName()
|
||||
if creatorName ~= "" then
|
||||
if isTenFootInterface then
|
||||
creatorLabel.Text = creatorName
|
||||
creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0)
|
||||
else
|
||||
creatorLabel.Text = "By ".. creatorName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local currentTime = tick()
|
||||
local fadeAmount = dt * fadeCycleTime
|
||||
|
||||
local spinnerImage = currScreenGui.BlackFrame.GraphicsFrame.LoadingImage
|
||||
local timeInCycle = currentTime % turnCycleTime
|
||||
local cycleAlpha = spinnerEasingFunc(0, 1, timeInCycle / turnCycleTime)
|
||||
spinnerImage.Rotation = cycleAlpha * 360
|
||||
|
||||
|
||||
if not isTenFootInterface then
|
||||
if currentTime - startTime > 5 and currScreenGui.BlackFrame.CloseButton.ImageTransparency > 0 then
|
||||
currScreenGui.BlackFrame.CloseButton.ImageTransparency = currScreenGui.BlackFrame.CloseButton.ImageTransparency - fadeAmount
|
||||
|
||||
if currScreenGui.BlackFrame.CloseButton.ImageTransparency <= 0 then
|
||||
currScreenGui.BlackFrame.CloseButton.Active = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)()
|
||||
end
|
||||
|
||||
-- use the old error frame when on XBox
|
||||
if not FFlagConnectionScriptEnabled or isTenFootInterface then
|
||||
local errorImage
|
||||
|
||||
GuiService.ErrorMessageChanged:connect(function()
|
||||
if GuiService:GetErrorMessage() ~= '' then
|
||||
--TODO: Remove this reference to Utility
|
||||
local utility = require(RobloxGui.Modules.Settings.Utility)
|
||||
if isTenFootInterface then
|
||||
currScreenGui.ErrorFrame.Size = UDim2.new(1, 0, 0, 144)
|
||||
currScreenGui.ErrorFrame.Position = UDim2.new(0, 0, 0, 0)
|
||||
currScreenGui.ErrorFrame.BackgroundColor3 = COLORS.BACKGROUND_COLOR
|
||||
currScreenGui.ErrorFrame.BackgroundTransparency = 0.5
|
||||
currScreenGui.ErrorFrame.ErrorText.TextSize = 36
|
||||
currScreenGui.ErrorFrame.ErrorText.Position = UDim2.new(.3, 0, 0, 0)
|
||||
currScreenGui.ErrorFrame.ErrorText.Size = UDim2.new(.4, 0, 0, 144)
|
||||
if errorImage == nil then
|
||||
errorImage = Instance.new("ImageLabel")
|
||||
errorImage.Image = "rbxasset://textures/ui/ErrorIconSmall.png"
|
||||
errorImage.Size = UDim2.new(0, 96, 0, 79)
|
||||
errorImage.Position = UDim2.new(0.228125, 0, 0, 32)
|
||||
errorImage.ZIndex = 9
|
||||
errorImage.BackgroundTransparency = 1
|
||||
errorImage.Parent = currScreenGui.ErrorFrame
|
||||
end
|
||||
elseif utility:IsSmallTouchScreen() then
|
||||
currScreenGui.ErrorFrame.Size = UDim2.new(0.5, 0, 0, 40)
|
||||
end
|
||||
|
||||
local errorCode = GuiService:GetErrorCode()
|
||||
local errorMessage = GuiService:GetErrorMessage()
|
||||
if not FFlagShowConnectionErrorCode then
|
||||
currScreenGui.ErrorFrame.ErrorText.Text = errorMessage
|
||||
else
|
||||
if not errorCode then
|
||||
currScreenGui.ErrorFrame.ErrorText.Text = ("%s (Error Code: -1)"):format(errorMessage)
|
||||
else
|
||||
currScreenGui.ErrorFrame.ErrorText.Text = ("%s (Error Code: %d)"):format(errorMessage, errorCode.Value)
|
||||
end
|
||||
end
|
||||
|
||||
currScreenGui.ErrorFrame.Visible = true
|
||||
local blackFrame = currScreenGui:FindFirstChild('BlackFrame')
|
||||
if blackFrame then
|
||||
blackFrame.CloseButton.ImageTransparency = 0
|
||||
blackFrame.CloseButton.Active = true
|
||||
end
|
||||
else
|
||||
currScreenGui.ErrorFrame.Visible = false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if FFlagBackButtonWhileLoadingGoesBackToApp then
|
||||
backButtonConnection = GuiService.ShowLeaveConfirmation:Connect(function()
|
||||
-- When OS back button is pressed during loading screen, exit
|
||||
-- immediately. Behaves the same as the close button.
|
||||
game:Shutdown()
|
||||
end)
|
||||
end
|
||||
|
||||
GuiService.UiMessageChanged:connect(function(type, newMessage)
|
||||
if type == Enum.UiMessageType.UiMessageInfo then
|
||||
local blackFrame = currScreenGui and currScreenGui:FindFirstChild('BlackFrame')
|
||||
if blackFrame then
|
||||
local infoFrame = blackFrame:FindFirstChild("InfoFrame")
|
||||
if infoFrame then
|
||||
local uiMessage = infoFrame.UiMessageFrame.UiMessage
|
||||
uiMessage.Text = newMessage
|
||||
if newMessage ~= '' and layoutIsReady then
|
||||
uiMessage.TextTransparency = 0
|
||||
else
|
||||
uiMessage.TextTransparency = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if not FFlagConnectionScriptEnabled and GuiService:GetErrorMessage() ~= '' then
|
||||
currScreenGui.ErrorFrame.ErrorText.Text = GuiService:GetErrorMessage()
|
||||
currScreenGui.ErrorFrame.Visible = true
|
||||
end
|
||||
|
||||
|
||||
local function stopListeningToRenderingStep()
|
||||
if renderSteppedConnection then
|
||||
renderSteppedConnection:disconnect()
|
||||
renderSteppedConnection = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function disconnectAndCloseHealthStat()
|
||||
if connectionHealthCon then
|
||||
connectionHealthCon:disconnect()
|
||||
connectionHealthCon = nil
|
||||
GuiService:CloseStatsBasedOnInputString("ConnectionHealth")
|
||||
end
|
||||
end
|
||||
|
||||
local function fadeAndDestroyBlackFrame(blackFrame)
|
||||
if destroyingBackground then return end
|
||||
destroyingBackground = true
|
||||
spawn(function()
|
||||
local infoFrame = blackFrame:FindFirstChild("InfoFrame")
|
||||
local graphicsFrame = blackFrame:FindFirstChild("GraphicsFrame")
|
||||
|
||||
local infoFrameDescendants = infoFrame:GetDescendants()
|
||||
local transparency = 0
|
||||
local rateChange = 1.8
|
||||
local lastUpdateTime = nil
|
||||
|
||||
--Notify everything else to stop messing with transparency to avoid ugly fighting effects
|
||||
backgroundFadeStarted = true
|
||||
if tweenPlaceIcon then
|
||||
tweenPlaceIcon:Cancel()
|
||||
tweenPlaceIcon = nil
|
||||
end
|
||||
|
||||
while transparency < 1 do
|
||||
RunService.RenderStepped:wait()
|
||||
if not lastUpdateTime then
|
||||
lastUpdateTime = tick()
|
||||
else
|
||||
local newTime = tick()
|
||||
transparency = transparency + rateChange * (newTime - lastUpdateTime)
|
||||
for i = 1, #infoFrameDescendants do
|
||||
local child = infoFrameDescendants[i]
|
||||
if child:IsA('TextLabel') then
|
||||
child.TextTransparency = transparency
|
||||
elseif child:IsA('ImageLabel') then
|
||||
child.ImageTransparency = transparency
|
||||
end
|
||||
end
|
||||
graphicsFrame.LoadingImage.ImageTransparency = transparency
|
||||
blackFrame.BackgroundTransparency = transparency
|
||||
|
||||
lastUpdateTime = newTime
|
||||
end
|
||||
end
|
||||
if blackFrame ~= nil then
|
||||
stopListeningToRenderingStep()
|
||||
blackFrame:Destroy()
|
||||
end
|
||||
|
||||
if waitForGameIdConnection then
|
||||
waitForGameIdConnection:Disconnect()
|
||||
end
|
||||
|
||||
if loadingImageInputBeganConn then
|
||||
loadingImageInputBeganConn:disconnect()
|
||||
end
|
||||
|
||||
if backButtonConnection then
|
||||
backButtonConnection:Disconnect()
|
||||
end
|
||||
|
||||
if connectionHealthShown then
|
||||
if UserInputService.TouchEnabled == true and UserInputService.MouseEnabled == false then
|
||||
connectionHealthCon = game:GetService("UserInputService").InputBegan:connect(function()
|
||||
disconnectAndCloseHealthStat()
|
||||
end)
|
||||
else
|
||||
GuiService:CloseStatsBasedOnInputString("ConnectionHealth")
|
||||
end
|
||||
else
|
||||
GuiService:CloseStatsBasedOnInputString("ConnectionHealth")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function destroyLoadingElements(instant)
|
||||
if not currScreenGui then return end
|
||||
if destroyedLoadingGui then return end
|
||||
destroyedLoadingGui = true
|
||||
|
||||
local guiChildren = currScreenGui:GetChildren()
|
||||
for i=1, #guiChildren do
|
||||
-- need to keep this around in case we get a connection error later
|
||||
if guiChildren[i].Name ~= "ErrorFrame" then
|
||||
if guiChildren[i].Name == "BlackFrame" and not instant then
|
||||
fadeAndDestroyBlackFrame(guiChildren[i])
|
||||
else
|
||||
guiChildren[i]:Destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function waitForCharacterLoaded()
|
||||
if Players.CharacterAutoLoads then
|
||||
local localPlayer = Players.LocalPlayer
|
||||
if not localPlayer then
|
||||
Players:GetPropertyChangedSignal("LocalPlayer"):wait()
|
||||
localPlayer = Players.LocalPlayer
|
||||
end
|
||||
if not localPlayer.Character then
|
||||
localPlayer.CharacterAdded:wait()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handleRemoveDefaultLoadingGui(instant)
|
||||
if isTenFootInterface then
|
||||
ContextActionService:UnbindCoreAction('CancelGameLoad')
|
||||
end
|
||||
destroyLoadingElements(instant)
|
||||
ReplicatedFirst:SetDefaultLoadingGuiRemoved()
|
||||
end
|
||||
|
||||
local function handleFinishedReplicating()
|
||||
if #ReplicatedFirst:GetChildren() == 0 then
|
||||
if game:IsLoaded() then
|
||||
waitForCharacterLoaded()
|
||||
handleRemoveDefaultLoadingGui()
|
||||
else
|
||||
local gameLoadedCon = nil
|
||||
gameLoadedCon = game.Loaded:connect(function()
|
||||
gameLoadedCon:disconnect()
|
||||
gameLoadedCon = nil
|
||||
waitForCharacterLoaded()
|
||||
handleRemoveDefaultLoadingGui()
|
||||
end)
|
||||
end
|
||||
else
|
||||
wait(5) -- make sure after 5 seconds we remove the default gui, even if the user doesn't
|
||||
handleRemoveDefaultLoadingGui()
|
||||
end
|
||||
end
|
||||
|
||||
if debugMode then
|
||||
warn("Not destroying loading screen because debugMode is true")
|
||||
return
|
||||
end
|
||||
ReplicatedFirst.FinishedReplicating:connect(handleFinishedReplicating)
|
||||
if ReplicatedFirst:IsFinishedReplicating() then
|
||||
handleFinishedReplicating()
|
||||
end
|
||||
|
||||
ReplicatedFirst.RemoveDefaultLoadingGuiSignal:connect(handleRemoveDefaultLoadingGui)
|
||||
if ReplicatedFirst:IsDefaultLoadingGuiRemoved() then
|
||||
handleRemoveDefaultLoadingGui()
|
||||
end
|
||||
|
||||
coroutine.wrap(function()
|
||||
if not VRService.VREnabled then
|
||||
VRService:GetPropertyChangedSignal("VREnabled"):Wait()
|
||||
end
|
||||
handleRemoveDefaultLoadingGui(true)
|
||||
require(RobloxGui.Modules.LoadingScreen3D)
|
||||
end)()
|
||||
Reference in New Issue
Block a user