181 lines
5.3 KiB
Lua
181 lines
5.3 KiB
Lua
--[[
|
|
// ControllerStateManager.lua
|
|
|
|
// Handles controller state changes
|
|
]]
|
|
local CoreGui = game:GetService("CoreGui")
|
|
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
|
|
local Modules = GuiRoot:FindFirstChild("Modules")
|
|
local ShellModules = Modules:FindFirstChild("Shell")
|
|
local PlatformService = nil
|
|
pcall(function() PlatformService = game:GetService('PlatformService') end)
|
|
local ThirdPartyUserService = nil
|
|
pcall(function() ThirdPartyUserService = game:GetService('ThirdPartyUserService') end)
|
|
local UserInputService = game:GetService('UserInputService')
|
|
local GuiService = game:GetService('GuiService')
|
|
|
|
local Http = require(ShellModules:FindFirstChild('Http'))
|
|
local NoActionOverlay = require(ShellModules:FindFirstChild('NoActionOverlay'))
|
|
local ScreenManager = require(ShellModules:FindFirstChild('ScreenManager'))
|
|
local Alerts = require(ShellModules:FindFirstChild('Alerts'))
|
|
local Utility = require(ShellModules:FindFirstChild('Utility'))
|
|
local EventHub = require(ShellModules:FindFirstChild('EventHub'))
|
|
local XboxAppState = require(ShellModules:FindFirstChild('AppState'))
|
|
|
|
local ControllerStateManager = {}
|
|
|
|
local LostUserGamepadCn = nil
|
|
local GainedUserGamepadCn = nil
|
|
|
|
local noActionOverlay = nil
|
|
|
|
local DATAMODEL_TYPE = {
|
|
APP_SHELL = 0;
|
|
GAME = 1;
|
|
}
|
|
|
|
|
|
local PRESENCE_POLL_INTERVAL = Utility.GetFastVariable("XboxPresencePolling")
|
|
|
|
local AnyButtonBeganConnection = nil
|
|
local SelectionChangedConnection = nil
|
|
local ViewChangedConnection = nil
|
|
local AnyActionDone = false
|
|
local LastTimerInfo = {flag = true};
|
|
|
|
local function restartPresenceUpdateTimer()
|
|
LastTimerInfo.flag = false;
|
|
|
|
local info = { flag = true }
|
|
|
|
spawn(function()
|
|
AnyActionDone = true
|
|
while info.flag do
|
|
if AnyActionDone then
|
|
Http:RegisterAppPresence()
|
|
end
|
|
AnyActionDone = false
|
|
wait(PRESENCE_POLL_INTERVAL)
|
|
end
|
|
end)
|
|
|
|
Utility.DisconnectEvent(AnyButtonBeganConnection)
|
|
AnyButtonBeganConnection = UserInputService.InputBegan:connect(function(inputObject)
|
|
AnyActionDone = true
|
|
end)
|
|
|
|
Utility.DisconnectEvent(SelectionChangedConnection)
|
|
SelectionChangedConnection = GuiService:GetPropertyChangedSignal('SelectedCoreObject'):connect(function()
|
|
AnyActionDone = true
|
|
end)
|
|
|
|
LastTimerInfo = info
|
|
end
|
|
|
|
local function stopPresenceUpdateTimer()
|
|
LastTimerInfo.flag = false;
|
|
Utility.DisconnectEvent(AnyButtonBeganConnection)
|
|
Utility.DisconnectEvent(SelectionChangedConnection)
|
|
end
|
|
|
|
local function closeOverlay(dataModelType)
|
|
if not noActionOverlay then return end
|
|
if dataModelType == DATAMODEL_TYPE.GAME then
|
|
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.None
|
|
--Close overlay, don't focus on below screen
|
|
noActionOverlay:Hide()
|
|
else
|
|
ScreenManager:CloseCurrent()
|
|
end
|
|
noActionOverlay = nil
|
|
end
|
|
|
|
local function showErrorOverlay(alert, dataModelType)
|
|
if noActionOverlay then return end
|
|
noActionOverlay = NoActionOverlay(alert)
|
|
if dataModelType == DATAMODEL_TYPE.GAME then
|
|
UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.ForceHide
|
|
noActionOverlay:Show()
|
|
else
|
|
ScreenManager:OpenScreen(noActionOverlay, false)
|
|
end
|
|
end
|
|
|
|
local function onLostUserGamepad(dataModelType)
|
|
local userDisplayName = ""
|
|
if dataModelType == DATAMODEL_TYPE.APP_SHELL then
|
|
userDisplayName = XboxAppState.store:getState().XboxUser.gamertag
|
|
else
|
|
if ThirdPartyUserService then
|
|
userDisplayName = ThirdPartyUserService:GetUserDisplayName()
|
|
end
|
|
end
|
|
|
|
-- create alert
|
|
local alert = Alerts.LostConnection["Controller"]
|
|
alert.Msg = string.format(alert.Msg, userDisplayName)
|
|
showErrorOverlay(alert, dataModelType)
|
|
end
|
|
|
|
local function onGainedUserGamepad(dataModelType)
|
|
closeOverlay(dataModelType)
|
|
end
|
|
|
|
local function disconnectEvents()
|
|
LostUserGamepadCn = Utility.DisconnectEvent(LostUserGamepadCn)
|
|
GainedUserGamepadCn = Utility.DisconnectEvent(GainedUserGamepadCn)
|
|
end
|
|
|
|
local function initAppPresenceReporting()
|
|
restartPresenceUpdateTimer()
|
|
|
|
Utility.DisconnectEvent(ViewChangedConnection)
|
|
ViewChangedConnection = PlatformService.ViewChanged:connect(
|
|
function(value)
|
|
if value == DATAMODEL_TYPE.APP_SHELL then
|
|
restartPresenceUpdateTimer()
|
|
else
|
|
stopPresenceUpdateTimer()
|
|
end
|
|
end
|
|
)
|
|
end
|
|
|
|
--ControllerStateManager initialized from AppHome.lua(when in app shell)/NotificationScript2.lua(when in game)
|
|
--Note: The ControllerStateManager module scirpt is required on different DMs (app shell & game).
|
|
--Thus, whenever we enter a new game, this module will run once as it's required on a new game DM.
|
|
function ControllerStateManager:Initialize()
|
|
if not PlatformService then return end
|
|
|
|
local dataModelType = PlatformService.DatamodelType
|
|
|
|
disconnectEvents()
|
|
if ThirdPartyUserService then
|
|
LostUserGamepadCn = ThirdPartyUserService.ActiveGamepadRemoved:connect(function()
|
|
onLostUserGamepad(dataModelType)
|
|
end)
|
|
GainedUserGamepadCn = ThirdPartyUserService.ActiveGamepadAdded:connect(function()
|
|
onGainedUserGamepad(dataModelType)
|
|
end)
|
|
end
|
|
|
|
if dataModelType == DATAMODEL_TYPE.APP_SHELL then
|
|
EventHub:addEventListener(EventHub.Notifications["AuthenticationSuccess"], "AchievementManager",
|
|
function()
|
|
initAppPresenceReporting();
|
|
end
|
|
)
|
|
end
|
|
end
|
|
|
|
function ControllerStateManager:CheckUserConnected()
|
|
if not PlatformService then return end
|
|
|
|
local isGamepadConnected = UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1)
|
|
if not isGamepadConnected then
|
|
onLostUserGamepad(PlatformService.DatamodelType)
|
|
end
|
|
end
|
|
|
|
return ControllerStateManager
|