mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-29 01:08:59 +00:00
FIX - complete LB custom app compatibility (#11)
* FIX - preserve LB custom app lifecycle * FIX - reset LB export aliases before startup * FIX - report competing custom app providers * FIX - identify LB app frames as live NUI * FIX - complete LB custom app compatibility * FIX - provide LB PicChat runtime exports * FIX - route LB PicChat through Sky Phone * FIX - return cached LB equipped phone number * FIX - harden PicChat compatibility migration * ENH - complete modular phone provider and Creator APIs * DOC - document the Sky Phone Creator API --------- Co-authored-by: DerEchteAlec <bycraky@gmail.com> Co-authored-by: DerEchteAlec <alec.schitzkat@luwan.io>
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
local invoking_resource = "creator_resource"
|
||||
local client_events = {}
|
||||
local encoded_value
|
||||
local notification_requests = {}
|
||||
|
||||
Config = {
|
||||
CustomApps = {
|
||||
BundledApps = false,
|
||||
Enabled = true,
|
||||
ExternalApps = true,
|
||||
MaximumMessageBytes = 64,
|
||||
TrustedAdapters = {},
|
||||
},
|
||||
}
|
||||
|
||||
json = {
|
||||
decode = function(encoded)
|
||||
if encoded:sub(1, 1) == '"' then
|
||||
return encoded:sub(2, -2)
|
||||
end
|
||||
return encoded_value
|
||||
end,
|
||||
encode = function(value)
|
||||
if type(value) == "function" then
|
||||
error("unsupported")
|
||||
end
|
||||
if type(value) == "string" then
|
||||
return '"' .. value .. '"'
|
||||
end
|
||||
encoded_value = value
|
||||
return "{}"
|
||||
end,
|
||||
}
|
||||
|
||||
SkyPhoneNotifications = {
|
||||
Send = function(target, notification)
|
||||
notification_requests[#notification_requests + 1] = {
|
||||
notification = notification,
|
||||
target = target,
|
||||
}
|
||||
return { delivered = target.value == 10 and 1 or 0 }
|
||||
end,
|
||||
}
|
||||
|
||||
Bridge = {
|
||||
Debug = function() end,
|
||||
Framework = {
|
||||
GetIdentifier = function(source)
|
||||
return source == 10 and "license:online" or nil
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
function AddEventHandler() end
|
||||
function GetCurrentResourceName() return "sky_phone" end
|
||||
function GetInvokingResource() return invoking_resource end
|
||||
function GetResourceState() return "started" end
|
||||
function TriggerClientEvent(name, target, ...)
|
||||
client_events[#client_events + 1] = {
|
||||
arguments = { ... },
|
||||
name = name,
|
||||
target = target,
|
||||
}
|
||||
end
|
||||
|
||||
assert(loadfile("sky_phone/source/shared/custom_apps.lua"))()
|
||||
assert(loadfile("sky_phone/source/server/custom_apps.lua"))()
|
||||
|
||||
local api = assert(SkyPhoneApps.ServerPublicApi)
|
||||
local capabilities = api.GetCustomAppCapabilities()
|
||||
assert(capabilities.enabled and capabilities.externalApps)
|
||||
assert(capabilities.messageDispatch and capabilities.notificationDispatch)
|
||||
assert(api.AddCustomAppPolicy({
|
||||
id = "creator-app",
|
||||
permissions = { "app.open", "notifications" },
|
||||
}))
|
||||
|
||||
assert(api.SendAppMessage(10, "creator-app", {
|
||||
action = "refresh",
|
||||
revision = 2,
|
||||
}))
|
||||
assert(#client_events == 1, "valid server app messages must emit exactly one client event")
|
||||
assert(client_events[1].name == "sky_phone:custom-app:message")
|
||||
assert(client_events[1].target == 10)
|
||||
assert(client_events[1].arguments[1] == "creator_resource",
|
||||
"the server must bind messages to the invoking owner resource")
|
||||
assert(client_events[1].arguments[2] == "creator-app")
|
||||
assert(client_events[1].arguments[3].action == "refresh")
|
||||
|
||||
local notification_success, notification_result = api.SendCustomAppNotification(
|
||||
10,
|
||||
"creator-app",
|
||||
{
|
||||
title = "Creator",
|
||||
content = "Updated",
|
||||
}
|
||||
)
|
||||
assert(notification_success and notification_result.delivered == 1)
|
||||
assert(#notification_requests == 1)
|
||||
assert(notification_requests[1].target.kind == "source")
|
||||
assert(notification_requests[1].target.value == 10)
|
||||
assert(notification_requests[1].notification.appId == "creator-app")
|
||||
assert(notification_requests[1].notification.text == "Updated")
|
||||
|
||||
notification_success, notification_result = api.SendCustomAppNotification(
|
||||
20,
|
||||
"creator-app",
|
||||
{
|
||||
title = "Creator",
|
||||
text = "Offline",
|
||||
}
|
||||
)
|
||||
assert(not notification_success and notification_result == "device_not_equipped")
|
||||
|
||||
notification_success, notification_result = api.SendCustomAppNotification(
|
||||
10,
|
||||
"creator-app",
|
||||
{
|
||||
appId = "other-app",
|
||||
title = "Creator",
|
||||
text = "Spoofed",
|
||||
}
|
||||
)
|
||||
assert(not notification_success and notification_result == "invalid_app_id")
|
||||
|
||||
local success, error_code = api.SendCustomAppMessage("10", "creator-app", {})
|
||||
assert(not success and error_code == "invalid_source", "message targets must remain strictly typed")
|
||||
|
||||
success, error_code = api.SendCustomAppMessage(20, "creator-app", {})
|
||||
assert(not success and error_code == "player_unavailable", "offline message targets must fail visibly")
|
||||
|
||||
success, error_code = api.SendCustomAppMessage(10, "creator-app", string.rep("x", 65))
|
||||
assert(not success and error_code == "payload_too_large", "message payload limits must be server enforced")
|
||||
|
||||
success, error_code = api.SendCustomAppMessage(10, "creator-app", function() end)
|
||||
assert(not success and error_code == "invalid_payload", "non-JSON message payloads must be rejected")
|
||||
|
||||
invoking_resource = "other_resource"
|
||||
success, error_code = api.SendCustomAppMessage(10, "creator-app", {})
|
||||
assert(not success and error_code == "app_owner_mismatch",
|
||||
"a different resource must not message another owner's app")
|
||||
assert(#client_events == 1, "rejected messages must not reach a client")
|
||||
|
||||
notification_success, notification_result = api.SendCustomAppNotification(
|
||||
10,
|
||||
"creator-app",
|
||||
{ title = "Creator", text = "Spoofed" }
|
||||
)
|
||||
assert(not notification_success and notification_result == "app_owner_mismatch")
|
||||
|
||||
print("Custom app server messaging tests passed")
|
||||
Reference in New Issue
Block a user