local required_services = { { name = "SkyPhoneApps", service = SkyPhoneApps }, { name = "SkyPhoneCalls", service = SkyPhoneCalls }, { name = "SkyPhoneCamera", service = SkyPhoneCamera }, { name = "SkyPhoneClient", service = SkyPhoneClient }, { name = "SkyPhoneFocus", service = SkyPhoneFocus }, { name = "SkyPhoneNavigation", service = SkyPhoneNavigation }, { name = "SkyPhonePublicApi", service = SkyPhonePublicApi }, } for index = 1, #required_services do local entry = required_services[index] if type(entry.service) ~= "table" then error(("[sky_phone] Client public API initialized before %s."):format(entry.name)) end end local CLIENT_CAPABILITIES = { apiVersion = SkyPhonePublicApi.Version, customAppProtocolVersion = SkyPhoneApps.ProtocolVersion, features = { calls = { audio = true, company = true, video = false, }, camera = true, customApps = { enabled = Config.CustomApps.Enabled == true, external = Config.CustomApps.Enabled == true and Config.CustomApps.ExternalApps == true, }, equippedPhoneNumber = true, navigation = true, notifications = { customApps = Config.CustomApps.Enabled == true and Config.CustomApps.ExternalApps == true, system = false, }, phoneGameInput = true, phoneState = true, }, ready = true, side = "client", } local function refresh_configured_capabilities() local enabled = Config.CustomApps.Enabled == true local external = enabled and Config.CustomApps.ExternalApps == true CLIENT_CAPABILITIES.features.customApps.enabled = enabled CLIENT_CAPABILITIES.features.customApps.external = external CLIENT_CAPABILITIES.features.notifications.customApps = external end refresh_configured_capabilities() AddEventHandler("sky_phone:configurator:updated", refresh_configured_capabilities) local custom_app_api = SkyPhoneApps.ClientPublicApi if type(custom_app_api) ~= "table" then error("[sky_phone] Client public API initialized before the custom app API.") end local camera_owner_resource local function get_calling_resource(error_code) local owner_resource = GetInvokingResource() if type(owner_resource) ~= "string" or owner_resource == "" then return nil, error_code or "resource_required" end return owner_resource end local function claim_camera() local owner_resource, owner_error = get_calling_resource() if not owner_resource then return nil, owner_error end if camera_owner_resource and camera_owner_resource ~= owner_resource then return nil, "camera_claimed" end if not camera_owner_resource and SkyPhoneCamera.GetState().active then return nil, "camera_in_use" end camera_owner_resource = owner_resource return owner_resource end local function verify_camera_owner() local owner_resource, owner_error = get_calling_resource() if not owner_resource then return nil, owner_error end if camera_owner_resource and camera_owner_resource ~= owner_resource then return nil, "camera_claimed" end return owner_resource end local function release_camera_state() SkyPhoneCamera.DisableWalkable() SkyPhoneCamera.SetFlashlight(false) SkyPhoneCamera.SetSelfie(false) camera_owner_resource = nil end local function get_api_capabilities() return SkyPhonePublicApi.Copy(CLIENT_CAPABILITIES) end local function is_api_ready() return true end local function set_phone_game_input_enabled(enabled) if type(enabled) ~= "boolean" then return false, "invalid_focus_claim" end local owner_resource = GetInvokingResource() if type(owner_resource) ~= "string" or owner_resource == "" then return false, "resource_required" end return SkyPhoneFocus.SetExternalGameInput(owner_resource, enabled) end local function set_flashlight(enabled) if type(enabled) ~= "boolean" then return false, "invalid_state" end local owner_resource, owner_error if enabled then owner_resource, owner_error = claim_camera() else owner_resource, owner_error = verify_camera_owner() end if not owner_resource then return false, owner_error end SkyPhoneCamera.SetFlashlight(enabled) return true end local function set_selfie_camera(enabled) if type(enabled) ~= "boolean" then return false, "invalid_state" end local owner_resource, owner_error if enabled then owner_resource, owner_error = claim_camera() else owner_resource, owner_error = verify_camera_owner() end if not owner_resource then return false, owner_error end SkyPhoneCamera.SetSelfie(enabled) return true end local function enable_walkable_camera(selfie) if selfie ~= nil and type(selfie) ~= "boolean" then return false, "invalid_state" end local owner_resource, owner_error = claim_camera() if not owner_resource then return false, owner_error end SkyPhoneCamera.EnableWalkable(selfie == true) return true end local function disable_walkable_camera() local owner_resource, owner_error = verify_camera_owner() if not owner_resource then return false, owner_error end if camera_owner_resource == owner_resource then release_camera_state() end return true end local function toggle_camera_frozen() if not SkyPhoneCamera.GetState().active then return false, "camera_not_active" end local owner_resource, owner_error = claim_camera() if not owner_resource then return false, owner_error end SkyPhoneCamera.ToggleFrozen() return true, SkyPhoneCamera.GetState() end local function set_camera_frozen(frozen) if type(frozen) ~= "boolean" then return false, "invalid_state" end local camera_state = SkyPhoneCamera.GetState() if not camera_state.active then return false, "camera_not_active" end local owner_resource, owner_error = claim_camera() if not owner_resource then return false, owner_error end if camera_state.frozen ~= frozen then SkyPhoneCamera.ToggleFrozen() camera_state = SkyPhoneCamera.GetState() end return true, camera_state end local function release_camera() local owner_resource, owner_error = verify_camera_owner() if not owner_resource then return false, owner_error end if camera_owner_resource == owner_resource then release_camera_state() end return true end exports("GetApiCapabilities", get_api_capabilities) exports("IsApiReady", is_api_ready) exports("TogglePhone", SkyPhoneClient.Toggle) exports("GetPhoneState", SkyPhoneClient.GetState) exports("GetEquippedPhoneNumber", SkyPhoneClient.GetEquippedPhoneNumber) exports("OpenApp", SkyPhoneNavigation.Open) exports("CloseApp", SkyPhoneNavigation.Close) exports("GetNavigationState", SkyPhoneNavigation.GetState) exports("GetCurrentApp", SkyPhoneNavigation.GetCurrent) exports("IsAppDataLoaded", SkyPhoneNavigation.IsDataLoaded) exports("IsAppInstalled", SkyPhoneNavigation.IsInstalled) exports("Dial", SkyPhoneCalls.Dial) exports("AnswerCall", SkyPhoneCalls.Answer) exports("DeclineCall", SkyPhoneCalls.Decline) exports("HangupCall", SkyPhoneCalls.Hangup) exports("TerminateCall", SkyPhoneCalls.Terminate) exports("GetActiveCall", SkyPhoneCalls.GetActive) exports("IsInCall", SkyPhoneCalls.IsActive) exports("GetCameraState", SkyPhoneCamera.GetState) exports("SetFlashlight", set_flashlight) exports("SetSelfieCamera", set_selfie_camera) exports("EnableWalkableCamera", enable_walkable_camera) exports("DisableWalkableCamera", disable_walkable_camera) exports("SetCameraFrozen", set_camera_frozen) exports("ToggleCameraFrozen", toggle_camera_frozen) exports("ReleaseCamera", release_camera) exports("SetPhoneGameInputEnabled", set_phone_game_input_enabled) exports("AddCustomApp", custom_app_api.AddCustomApp) exports("AddCustomAppFromAdapter", custom_app_api.AddCustomAppFromAdapter) exports("CloseActiveCustomAppFromAdapter", custom_app_api.CloseActiveCustomAppFromAdapter) exports("CloseCustomApp", custom_app_api.CloseCustomApp) exports("CloseCustomAppFromAdapter", custom_app_api.CloseCustomAppFromAdapter) exports("GetCustomAppCapabilities", custom_app_api.GetCustomAppCapabilities) exports("OpenCustomApp", custom_app_api.OpenCustomApp) exports("OpenCustomAppFromAdapter", custom_app_api.OpenCustomAppFromAdapter) exports("RemoveCustomApp", custom_app_api.RemoveCustomApp) exports("RemoveCustomAppFromAdapter", custom_app_api.RemoveCustomAppFromAdapter) exports("SendAppMessage", custom_app_api.SendAppMessage) exports("SendCustomAppMessage", custom_app_api.SendCustomAppMessage) exports("SendCustomAppMessageFromAdapter", custom_app_api.SendCustomAppMessageFromAdapter) exports("SendCustomAppNotification", custom_app_api.SendCustomAppNotification) exports( "SendCustomAppNotificationFromAdapter", custom_app_api.SendCustomAppNotificationFromAdapter ) exports("UpdateCustomApp", custom_app_api.UpdateCustomApp) exports("UpdateCustomAppFromAdapter", custom_app_api.UpdateCustomAppFromAdapter) AddEventHandler("onClientResourceStop", function(resource_name) if resource_name == camera_owner_resource then release_camera_state() end end) TriggerEvent("sky_phone:client:apiReady", SkyPhonePublicApi.Version)