mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-29 20:01:35 +00:00
dcf7b47113
Enable verbose tracing for custom apps and wire diagnostics through the stack. Sets Config.CustomApps.Debug = true, adds a debug_custom_app logger exposed as SkyPhoneApps.Debug, and instruments client and shared compatibility code (registration, normalization, provider exports, catalog sync, lifecycle hooks, resource stop, and app add/update/remove) with structured debug messages. Frontend sends a debug flag with the catalog and will call back to NUI (custom-app:catalog-debug) when debug is enabled. Tests updated to enable debug and assert fixBlur preservation and NUI catalog ACK handling. This provides detailed traces for exports, registration, catalog sync and lifecycle events.
748 lines
24 KiB
Lua
748 lines
24 KiB
Lua
local RESOURCE_NAME = GetCurrentResourceName()
|
|
local providers = SkyPhoneCompatibility.Providers
|
|
local core = SkyPhoneApps.CompatibilityCore
|
|
local debug_custom_app = SkyPhoneApps.Debug or function() end
|
|
local provider_apps = {}
|
|
local high_client_apps = {}
|
|
local high_server_apps = {}
|
|
|
|
local function get_calling_resource(export_name)
|
|
local owner_resource = GetInvokingResource()
|
|
if owner_resource then
|
|
return owner_resource
|
|
end
|
|
|
|
Bridge.Debug("warn", "[%s] %s rejected: the export must be called by another resource.",
|
|
RESOURCE_NAME,
|
|
export_name
|
|
)
|
|
return nil, "invalid_owner"
|
|
end
|
|
|
|
local function copy_record_data(value)
|
|
if type(value) ~= "table" then
|
|
return nil
|
|
end
|
|
|
|
local copied = {}
|
|
for key, nested_value in pairs(value) do
|
|
copied[key] = nested_value
|
|
end
|
|
return copied
|
|
end
|
|
|
|
local function register_provider_app(provider, owner_resource, definition, vendor_data)
|
|
local app_id = definition.id
|
|
local existing = provider_apps[app_id]
|
|
debug_custom_app(
|
|
"provider",
|
|
"registration requested provider=%s id=%s owner=%s operation=%s",
|
|
tostring(provider),
|
|
tostring(app_id),
|
|
tostring(owner_resource),
|
|
existing and "update" or "add"
|
|
)
|
|
if existing and (existing.owner_resource ~= owner_resource or existing.provider ~= provider) then
|
|
debug_custom_app(
|
|
"provider",
|
|
"registration rejected provider=%s id=%s owner=%s existing_provider=%s existing_owner=%s error=duplicate_app_id",
|
|
tostring(provider),
|
|
tostring(app_id),
|
|
tostring(owner_resource),
|
|
tostring(existing.provider),
|
|
tostring(existing.owner_resource)
|
|
)
|
|
return false, "duplicate_app_id"
|
|
end
|
|
|
|
local success, error_message
|
|
if existing then
|
|
success, error_message = core.Update(owner_resource, definition)
|
|
else
|
|
success, error_message = core.Add(owner_resource, definition)
|
|
end
|
|
if success then
|
|
provider_apps[app_id] = {
|
|
definition = definition,
|
|
owner_resource = owner_resource,
|
|
provider = provider,
|
|
vendor_data = vendor_data,
|
|
}
|
|
end
|
|
debug_custom_app(
|
|
"provider",
|
|
"registration result provider=%s id=%s owner=%s success=%s error=%s",
|
|
tostring(provider),
|
|
tostring(app_id),
|
|
tostring(owner_resource),
|
|
tostring(success),
|
|
tostring(error_message)
|
|
)
|
|
return success, error_message
|
|
end
|
|
|
|
local function get_provider_app(owner_resource, app_id, allowed_providers)
|
|
if type(app_id) ~= "string" then
|
|
return nil, "invalid_app_id"
|
|
end
|
|
|
|
local record = provider_apps[app_id]
|
|
if not record then
|
|
return nil, "app_not_found"
|
|
end
|
|
if record.owner_resource ~= owner_resource then
|
|
return nil, "app_owner_mismatch"
|
|
end
|
|
if allowed_providers and not allowed_providers[record.provider] then
|
|
return nil, "app_provider_mismatch"
|
|
end
|
|
return record
|
|
end
|
|
|
|
local function remove_provider_app(owner_resource, app_id, allowed_providers)
|
|
local record, record_error = get_provider_app(owner_resource, app_id, allowed_providers)
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
|
|
return core.Remove(owner_resource, app_id)
|
|
end
|
|
|
|
function SkyPhoneApps.RegisterCompatibilityExport(owner_resource, app_data)
|
|
debug_custom_app(
|
|
"provider",
|
|
"compatibility export received owner=%s identifier=%s key=%s data_type=%s",
|
|
tostring(owner_resource),
|
|
type(app_data) == "table" and tostring(app_data.identifier) or "nil",
|
|
type(app_data) == "table" and tostring(app_data.key) or "nil",
|
|
type(app_data)
|
|
)
|
|
local provider
|
|
local definition
|
|
local definition_error
|
|
if app_data.identifier ~= nil then
|
|
provider = providers.lb
|
|
definition, definition_error = SkyPhoneCompatibility.BuildLbDefinition(owner_resource, app_data)
|
|
elseif app_data.key ~= nil then
|
|
provider = providers.yseries
|
|
definition, definition_error = SkyPhoneCompatibility.BuildYSeriesDefinition(app_data)
|
|
else
|
|
debug_custom_app(
|
|
"provider",
|
|
"compatibility export rejected owner=%s error=unknown_app_provider",
|
|
tostring(owner_resource)
|
|
)
|
|
return false, "unknown_app_provider"
|
|
end
|
|
|
|
if not definition then
|
|
debug_custom_app(
|
|
"provider",
|
|
"definition rejected provider=%s owner=%s error=%s",
|
|
tostring(provider),
|
|
tostring(owner_resource),
|
|
tostring(definition_error)
|
|
)
|
|
Bridge.Debug("warn", "[%s] %s registration rejected for %s: %s.",
|
|
RESOURCE_NAME,
|
|
provider,
|
|
owner_resource,
|
|
definition_error
|
|
)
|
|
return false, definition_error
|
|
end
|
|
debug_custom_app(
|
|
"provider",
|
|
"definition built provider=%s id=%s owner=%s ui=%s icon=%s default_installed=%s fix_blur=%s",
|
|
tostring(provider),
|
|
tostring(definition.id),
|
|
tostring(owner_resource),
|
|
tostring(definition.ui),
|
|
tostring(definition.icon),
|
|
tostring(definition.defaultInstalled),
|
|
definition.compatibility and tostring(definition.compatibility.fixBlur) or "nil"
|
|
)
|
|
return register_provider_app(provider, owner_resource, definition, copy_record_data(app_data))
|
|
end
|
|
|
|
SkyPhoneApps.OnCompatibilityAppRemoved = function(owner_resource, app_id)
|
|
local record = provider_apps[app_id]
|
|
if record and record.owner_resource == owner_resource then
|
|
provider_apps[app_id] = nil
|
|
end
|
|
end
|
|
|
|
local function add_17mov_application(app_data)
|
|
local owner_resource, owner_error = get_calling_resource("AddApplication")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local definition, definition_error = SkyPhoneCompatibility.Build17MovDefinition(app_data)
|
|
if not definition then
|
|
Bridge.Debug("warn", "[%s] 17mov registration rejected for %s: %s.",
|
|
RESOURCE_NAME,
|
|
owner_resource,
|
|
definition_error
|
|
)
|
|
return false, definition_error
|
|
end
|
|
return register_provider_app(
|
|
providers.seventeen,
|
|
owner_resource,
|
|
definition,
|
|
copy_record_data(app_data)
|
|
)
|
|
end
|
|
|
|
local function remove_17mov_application(app_name, _resource_name)
|
|
local owner_resource, owner_error = get_calling_resource("RemoveApplication")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local app_id = type(app_name) == "table" and app_name.name or app_name
|
|
return remove_provider_app(owner_resource, app_id, {
|
|
[providers.seventeen] = true,
|
|
})
|
|
end
|
|
|
|
local function send_app_message(app_id, data)
|
|
local owner_resource, owner_error = get_calling_resource("SendAppMessage")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local record, record_error = get_provider_app(owner_resource, app_id, {
|
|
[providers.seventeen] = true,
|
|
[providers.yseries] = true,
|
|
})
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
return core.SendMessage(owner_resource, app_id, data)
|
|
end
|
|
|
|
local function add_high_application(app_name, data, locales)
|
|
local owner_resource, owner_error = get_calling_resource("addApplication")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local definition, definition_error = SkyPhoneCompatibility.BuildHighDefinition(
|
|
owner_resource,
|
|
app_name,
|
|
data,
|
|
locales
|
|
)
|
|
if not definition then
|
|
Bridge.Debug("warn", "[%s] High Phone registration rejected for %s: %s.",
|
|
RESOURCE_NAME,
|
|
owner_resource,
|
|
definition_error
|
|
)
|
|
return false, definition_error
|
|
end
|
|
|
|
high_client_apps[app_name] = {
|
|
definition = definition,
|
|
owner_resource = owner_resource,
|
|
}
|
|
local server_record = high_server_apps[app_name]
|
|
if server_record then
|
|
if server_record.owner_resource ~= owner_resource then
|
|
return false, "duplicate_app_id"
|
|
end
|
|
if server_record.registered then
|
|
return true
|
|
end
|
|
return false, "server_definition_not_registered"
|
|
end
|
|
|
|
return register_provider_app(
|
|
providers.high,
|
|
owner_resource,
|
|
definition,
|
|
copy_record_data(data)
|
|
)
|
|
end
|
|
|
|
local function send_high_app_nui(app_name, data)
|
|
local owner_resource, owner_error = get_calling_resource("sendAppNui")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local record, record_error = get_provider_app(owner_resource, app_name, {
|
|
[providers.high] = true,
|
|
})
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
return core.SendMessage(owner_resource, app_name, data)
|
|
end
|
|
|
|
local function add_quasar_app_for_owner(owner_resource, app_data)
|
|
local definition, definition_error = SkyPhoneCompatibility.BuildQuasarDefinition(app_data)
|
|
if not definition then
|
|
Bridge.Debug("warn", "[%s] Quasar registration rejected for %s: %s.",
|
|
RESOURCE_NAME,
|
|
owner_resource,
|
|
definition_error
|
|
)
|
|
return false, definition_error
|
|
end
|
|
|
|
return register_provider_app(
|
|
providers.quasar,
|
|
owner_resource,
|
|
definition,
|
|
SkyPhoneCompatibility.CopyQuasarData(app_data)
|
|
)
|
|
end
|
|
|
|
local function add_quasar_app(app_data)
|
|
local owner_resource, owner_error = get_calling_resource("addCustomApp")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
if type(app_data) ~= "table" then
|
|
return false, "invalid_app_data"
|
|
end
|
|
return add_quasar_app_for_owner(owner_resource, app_data)
|
|
end
|
|
|
|
local function add_quasar_apps_batch(apps)
|
|
local owner_resource, owner_error = get_calling_resource("addCustomAppsBatch")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
if type(apps) ~= "table" then
|
|
return false, "invalid_app_batch"
|
|
end
|
|
|
|
for index = 1, #apps do
|
|
local success, error_message = add_quasar_app_for_owner(owner_resource, apps[index])
|
|
if not success then
|
|
return false, error_message
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function update_quasar_app(app_id, patch)
|
|
local owner_resource, owner_error = get_calling_resource("updateCustomApp")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
if type(patch) ~= "table" then
|
|
return false, "invalid_patch"
|
|
end
|
|
|
|
local record, record_error = get_provider_app(owner_resource, app_id, {
|
|
[providers.quasar] = true,
|
|
})
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
|
|
local merged = SkyPhoneCompatibility.CopyQuasarData(record.vendor_data)
|
|
for key, value in pairs(patch) do
|
|
if key == "iframe" and type(value) == "table" then
|
|
merged.iframe = merged.iframe or {}
|
|
for iframe_key, iframe_value in pairs(value) do
|
|
merged.iframe[iframe_key] = iframe_value
|
|
end
|
|
elseif key ~= "id" then
|
|
merged[key] = value
|
|
end
|
|
end
|
|
merged.id = app_id
|
|
|
|
local definition, definition_error = SkyPhoneCompatibility.BuildQuasarDefinition(merged)
|
|
if not definition then
|
|
return false, definition_error
|
|
end
|
|
|
|
local success, error_message = core.Update(owner_resource, definition)
|
|
if success then
|
|
record.definition = definition
|
|
record.vendor_data = SkyPhoneCompatibility.CopyQuasarData(merged)
|
|
end
|
|
return success, error_message
|
|
end
|
|
|
|
local function remove_quasar_app(app_id)
|
|
local owner_resource, owner_error = get_calling_resource("removeCustomApp")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
return remove_provider_app(owner_resource, app_id, {
|
|
[providers.quasar] = true,
|
|
})
|
|
end
|
|
|
|
local function get_quasar_apps()
|
|
local ids = {}
|
|
for app_id, record in pairs(provider_apps) do
|
|
if record.provider == providers.quasar then
|
|
ids[#ids + 1] = app_id
|
|
end
|
|
end
|
|
table.sort(ids)
|
|
|
|
local apps = {}
|
|
for index = 1, #ids do
|
|
apps[index] = SkyPhoneCompatibility.CopyQuasarData(provider_apps[ids[index]].vendor_data)
|
|
end
|
|
return apps
|
|
end
|
|
|
|
local function open_quasar_app(app_id)
|
|
local owner_resource, owner_error = get_calling_resource("OpenPhoneApp")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local record, record_error = get_provider_app(owner_resource, app_id, {
|
|
[providers.quasar] = true,
|
|
})
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
return core.Open(owner_resource, app_id)
|
|
end
|
|
|
|
local function open_phone_app(app_id, data)
|
|
local owner_resource, owner_error = get_calling_resource("OpenApp")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local record, record_error = get_provider_app(owner_resource, app_id)
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
return core.Open(owner_resource, app_id, data)
|
|
end
|
|
|
|
local function close_phone_app(options)
|
|
local owner_resource, owner_error = get_calling_resource("CloseApp")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
|
|
local app_id = type(options) == "table" and options.app or nil
|
|
if app_id then
|
|
local record, record_error = get_provider_app(owner_resource, app_id, {
|
|
[providers.lb] = true,
|
|
[providers.yseries] = true,
|
|
})
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
return core.Close(owner_resource, app_id)
|
|
end
|
|
return core.CloseActive(owner_resource)
|
|
end
|
|
|
|
local function normalize_lb_notification_text(value, maximum_length, error_code)
|
|
if type(value) ~= "string" then
|
|
return nil, error_code
|
|
end
|
|
|
|
local normalized = value:match("^%s*(.-)%s*$")
|
|
if normalized == "" or #normalized > maximum_length then
|
|
return nil, error_code
|
|
end
|
|
return normalized
|
|
end
|
|
|
|
local function send_lb_notification(data)
|
|
local owner_resource, owner_error = get_calling_resource("SendNotification")
|
|
if not owner_resource then
|
|
return false, owner_error
|
|
end
|
|
if type(data) ~= "table" then
|
|
return false, "invalid_notification"
|
|
end
|
|
|
|
local app_id = data.app or data.identifier
|
|
local valid_app_id, app_id_error = SkyPhoneApps.ValidateAppId(app_id)
|
|
if not valid_app_id then
|
|
return false, app_id_error
|
|
end
|
|
|
|
local registered_record = provider_apps[app_id]
|
|
if registered_record then
|
|
local record, record_error = get_provider_app(owner_resource, app_id, {
|
|
[providers.lb] = true,
|
|
})
|
|
if not record then
|
|
return false, record_error
|
|
end
|
|
elseif not SkyPhoneApps.ReservedAppIds[app_id] then
|
|
return false, "app_not_found"
|
|
end
|
|
|
|
local title, title_error = normalize_lb_notification_text(
|
|
data.title,
|
|
128,
|
|
"invalid_notification_title"
|
|
)
|
|
if not title then
|
|
return false, title_error
|
|
end
|
|
|
|
local content, content_error = normalize_lb_notification_text(
|
|
data.content or data.message or data.text,
|
|
512,
|
|
"invalid_notification_text"
|
|
)
|
|
if not content then
|
|
return false, content_error
|
|
end
|
|
|
|
SendNUIMessage({
|
|
type = "notification:show",
|
|
data = {
|
|
appId = app_id,
|
|
route = "/apps/" .. app_id,
|
|
text = content,
|
|
title = title,
|
|
},
|
|
})
|
|
return true
|
|
end
|
|
|
|
local function register_high_server_app(owner_resource, definition, revision)
|
|
if type(owner_resource) ~= "string"
|
|
or type(definition) ~= "table"
|
|
or type(definition.id) ~= "string"
|
|
or type(revision) ~= "number"
|
|
or revision ~= math.floor(revision)
|
|
or revision < 1
|
|
then
|
|
Bridge.Debug("warn", "[%s] Rejected invalid High Phone server application snapshot.", RESOURCE_NAME)
|
|
return nil
|
|
end
|
|
|
|
local app_id = definition.id
|
|
local existing = high_server_apps[app_id]
|
|
if existing and revision <= existing.revision then
|
|
if revision < existing.revision or existing.registered then
|
|
return app_id
|
|
end
|
|
if existing.owner_resource ~= owner_resource then
|
|
Bridge.Debug("warn", "[%s] Rejected conflicting High Phone owner for %s.",
|
|
RESOURCE_NAME,
|
|
app_id
|
|
)
|
|
return app_id
|
|
end
|
|
end
|
|
|
|
local provider_record = provider_apps[app_id]
|
|
local success, error_message
|
|
local retained_registration = false
|
|
if provider_record then
|
|
if provider_record.owner_resource ~= owner_resource or provider_record.provider ~= providers.high then
|
|
success, error_message = false, "duplicate_app_id"
|
|
else
|
|
retained_registration = true
|
|
success, error_message = core.Update(owner_resource, definition)
|
|
end
|
|
else
|
|
success, error_message = core.Add(owner_resource, definition)
|
|
end
|
|
|
|
high_server_apps[app_id] = {
|
|
definition = definition,
|
|
last_error = success and nil or error_message,
|
|
owner_resource = owner_resource,
|
|
registered = success or retained_registration,
|
|
revision = revision,
|
|
}
|
|
if success then
|
|
provider_apps[app_id] = {
|
|
definition = definition,
|
|
owner_resource = owner_resource,
|
|
provider = providers.high,
|
|
}
|
|
elseif not existing or existing.revision ~= revision or existing.last_error ~= error_message then
|
|
Bridge.Debug("error", "[%s] Could not register High Phone server application %s revision %s: %s.",
|
|
RESOURCE_NAME,
|
|
app_id,
|
|
revision,
|
|
error_message or "unknown_error"
|
|
)
|
|
end
|
|
return app_id
|
|
end
|
|
|
|
local function remove_high_server_app(owner_resource, app_id)
|
|
local record = high_server_apps[app_id]
|
|
if not record or record.owner_resource ~= owner_resource then
|
|
return
|
|
end
|
|
|
|
high_server_apps[app_id] = nil
|
|
if record.registered then
|
|
core.Remove(owner_resource, app_id)
|
|
end
|
|
|
|
local client_record = high_client_apps[app_id]
|
|
if client_record then
|
|
local success, error_message = register_provider_app(
|
|
providers.high,
|
|
client_record.owner_resource,
|
|
client_record.definition,
|
|
nil
|
|
)
|
|
if not success then
|
|
Bridge.Debug("error", "[%s] Could not restore High Phone client application %s: %s.",
|
|
RESOURCE_NAME,
|
|
app_id,
|
|
error_message or "unknown_error"
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
RegisterNetEvent("sky_phone:compat:high:client:syncApplication", function(owner_resource, definition, revision)
|
|
if source ~= 65535 then
|
|
Bridge.Debug("warn", "[%s] Rejected locally invoked High Phone application sync.", RESOURCE_NAME)
|
|
return
|
|
end
|
|
register_high_server_app(owner_resource, definition, revision)
|
|
end)
|
|
|
|
RegisterNetEvent("sky_phone:compat:high:client:removeApplication", function(owner_resource, app_id)
|
|
if source ~= 65535 then
|
|
Bridge.Debug("warn", "[%s] Rejected locally invoked High Phone application removal.", RESOURCE_NAME)
|
|
return
|
|
end
|
|
if type(owner_resource) ~= "string" or type(app_id) ~= "string" then
|
|
Bridge.Debug("warn", "[%s] Rejected invalid High Phone application removal.", RESOURCE_NAME)
|
|
return
|
|
end
|
|
remove_high_server_app(owner_resource, app_id)
|
|
end)
|
|
|
|
RegisterNetEvent("sky_phone:compat:high:client:replaceSnapshot", function(snapshot)
|
|
if source ~= 65535 then
|
|
Bridge.Debug("warn", "[%s] Rejected locally invoked High Phone application snapshot.", RESOURCE_NAME)
|
|
return
|
|
end
|
|
if type(snapshot) ~= "table" then
|
|
Bridge.Debug("warn", "[%s] Rejected invalid High Phone application snapshot.", RESOURCE_NAME)
|
|
return
|
|
end
|
|
|
|
local seen = {}
|
|
for index = 1, #snapshot do
|
|
local record = snapshot[index]
|
|
if type(record) == "table" then
|
|
local app_id = register_high_server_app(
|
|
record.owner_resource,
|
|
record.definition,
|
|
record.revision
|
|
)
|
|
if app_id then
|
|
seen[app_id] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
local removed = {}
|
|
for app_id, record in pairs(high_server_apps) do
|
|
if not seen[app_id] then
|
|
removed[#removed + 1] = {
|
|
app_id = app_id,
|
|
owner_resource = record.owner_resource,
|
|
}
|
|
end
|
|
end
|
|
for index = 1, #removed do
|
|
remove_high_server_app(removed[index].owner_resource, removed[index].app_id)
|
|
end
|
|
end)
|
|
|
|
AddEventHandler("onClientResourceStart", function(resource_name)
|
|
for _, record in pairs(high_server_apps) do
|
|
if record.owner_resource == resource_name and not record.registered then
|
|
register_high_server_app(record.owner_resource, record.definition, record.revision)
|
|
end
|
|
end
|
|
end)
|
|
|
|
AddEventHandler("onClientResourceStop", function(resource_name)
|
|
for app_id, record in pairs(high_client_apps) do
|
|
if record.owner_resource == resource_name then
|
|
high_client_apps[app_id] = nil
|
|
end
|
|
end
|
|
end)
|
|
|
|
exports("AddApplication", add_17mov_application)
|
|
exports("RemoveApplication", remove_17mov_application)
|
|
exports("SendAppMessage", send_app_message)
|
|
exports("addApplication", add_high_application)
|
|
exports("sendAppNui", send_high_app_nui)
|
|
exports("addCustomApp", add_quasar_app)
|
|
exports("addCustomAppsBatch", add_quasar_apps_batch)
|
|
exports("updateCustomApp", update_quasar_app)
|
|
exports("removeCustomApp", remove_quasar_app)
|
|
exports("getCustomApps", get_quasar_apps)
|
|
exports("OpenPhoneApp", open_quasar_app)
|
|
exports("OpenApp", open_phone_app)
|
|
exports("CloseApp", close_phone_app)
|
|
exports("SendNotification", send_lb_notification)
|
|
|
|
SkyPhoneCompatibility.RegisterExportAlias("lb-phone", "OpenApp", open_phone_app)
|
|
SkyPhoneCompatibility.RegisterExportAlias("lb-phone", "CloseApp", close_phone_app)
|
|
SkyPhoneCompatibility.RegisterExportAlias("lb-phone", "SendNotification", send_lb_notification)
|
|
|
|
SkyPhoneCompatibility.RegisterExportAlias("17mov_Phone", "AddApplication", add_17mov_application)
|
|
SkyPhoneCompatibility.RegisterExportAlias("17mov_Phone", "RemoveApplication", remove_17mov_application)
|
|
SkyPhoneCompatibility.RegisterExportAlias("17mov_Phone", "SendAppMessage", send_app_message)
|
|
|
|
SkyPhoneCompatibility.RegisterExportAlias("high-phone", "addApplication", add_high_application)
|
|
SkyPhoneCompatibility.RegisterExportAlias("high-phone", "sendAppNui", send_high_app_nui)
|
|
|
|
SkyPhoneCompatibility.RegisterExportAlias("qs-smartphone", "addCustomApp", add_quasar_app)
|
|
SkyPhoneCompatibility.RegisterExportAlias("qs-smartphone", "addCustomAppsBatch", add_quasar_apps_batch)
|
|
SkyPhoneCompatibility.RegisterExportAlias("qs-smartphone", "updateCustomApp", update_quasar_app)
|
|
SkyPhoneCompatibility.RegisterExportAlias("qs-smartphone", "removeCustomApp", remove_quasar_app)
|
|
SkyPhoneCompatibility.RegisterExportAlias("qs-smartphone", "getCustomApps", get_quasar_apps)
|
|
SkyPhoneCompatibility.RegisterExportAlias("qs-smartphone", "OpenPhoneApp", open_quasar_app)
|
|
|
|
SkyPhoneCompatibility.RegisterExportAlias("yseries", "SendAppMessage", send_app_message)
|
|
SkyPhoneCompatibility.RegisterExportAlias("yseries", "CloseApp", close_phone_app)
|
|
SkyPhoneCompatibility.RegisterExportAlias("yseries", "GetDataLoaded", function()
|
|
return true
|
|
end)
|
|
|
|
CreateThread(function()
|
|
debug_custom_app("provider", "requesting provider snapshots and emitting compatibility ready signals")
|
|
TriggerServerEvent("sky_phone:compat:high:server:requestSnapshot")
|
|
TriggerEvent("17mov_Phone:Client:Ready")
|
|
|
|
local provider_resources = {
|
|
"lb-phone",
|
|
"17mov_Phone",
|
|
"high-phone",
|
|
"qs-smartphone",
|
|
"yseries",
|
|
}
|
|
for index = 1, #provider_resources do
|
|
debug_custom_app(
|
|
"provider",
|
|
"emitting onResourceStart compatibility signal for %s (state=%s)",
|
|
provider_resources[index],
|
|
tostring(GetResourceState(provider_resources[index]))
|
|
)
|
|
TriggerEvent("onResourceStart", provider_resources[index])
|
|
end
|
|
end)
|