FIX - harden inventory contracts and resolve phone interaction issues (#20)

* FIX - repair inventory metadata and ESX contracts

Use the stable core_inventory metadata setter and validate the complete inventory adapter contract after provider bridges load. Preserve the real ESX configuration error instead of cascading into a missing RegisterUsableItem failure.

* FIX - clarify phone opening without SIM

* FIX - harden inventory and device contracts

Validate SIM number configuration before item handling, preserve QB metadata mutation contracts, and propagate phone-open failures to callers. Extend regression coverage for inventory bridges and device bootstrap errors.

* FIX - resolve reported phone interaction issues

Stop game-input passthrough while NUI text fields are focused and add an independent hold-to-look option. Propagate SIM number formatting to the frontend, migrate configured currency symbols to utf8mb4, and clarify SkyRide, VaultX, and DarkChat behavior with focused contract coverage.

* FIX - detect missing packaged phone UI

Validate the generated NUI entrypoint, its referenced assets, and required static media when the resource starts. Print an actionable server-console warning for incomplete source archives, package phone sounds through the manifest, and cover the detection contract with Lua regressions.
This commit is contained in:
DerEchteAlec
2026-08-21 17:19:27 +02:00
committed by GitHub
parent 698420584d
commit 97db163cd0
34 changed files with 912 additions and 79 deletions
+124
View File
@@ -0,0 +1,124 @@
local resource_name = GetCurrentResourceName()
local index_path = "source/html/index.html"
local required_static_files = {
"source/html/img/custom-app.svg",
"source/html/sounds/button.mp3",
}
local function load_non_empty_file(path)
local content = LoadResourceFile(resource_name, path)
if type(content) ~= "string" or content == "" then
return nil
end
return content
end
local function add_missing_path(missing_paths, seen_paths, path)
if seen_paths[path] then
return
end
seen_paths[path] = true
missing_paths[#missing_paths + 1] = path
end
local function normalize_entry_asset_path(url)
if type(url) ~= "string" then
return nil
end
local path = url:gsub("[?#].*$", "")
while path:sub(1, 2) == "./" do
path = path:sub(3)
end
if path:sub(1, 7) ~= "assets/" then
return nil
end
return "source/html/" .. path
end
local function collect_entry_asset_paths(index_html)
local paths = {}
local seen_paths = {}
for url in index_html:gmatch("src%s*=%s*[\"']([^\"']+)[\"']") do
local path = normalize_entry_asset_path(url)
if path and not seen_paths[path] then
seen_paths[path] = true
paths[#paths + 1] = path
end
end
for url in index_html:gmatch("href%s*=%s*[\"']([^\"']+)[\"']") do
local path = normalize_entry_asset_path(url)
if path and not seen_paths[path] then
seen_paths[path] = true
paths[#paths + 1] = path
end
end
return paths
end
local function find_missing_nui_files()
local missing_paths = {}
local seen_paths = {}
local index_html = load_non_empty_file(index_path)
if not index_html then
add_missing_path(missing_paths, seen_paths, index_path)
add_missing_path(missing_paths, seen_paths, "source/html/assets/* (generated entry assets)")
else
local entry_asset_paths = collect_entry_asset_paths(index_html)
if #entry_asset_paths == 0 then
add_missing_path(missing_paths, seen_paths, "source/html/assets/* (no entry asset referenced by index.html)")
else
for index = 1, #entry_asset_paths do
local path = entry_asset_paths[index]
if not load_non_empty_file(path) then
add_missing_path(missing_paths, seen_paths, path)
end
end
end
end
for index = 1, #required_static_files do
local path = required_static_files[index]
if not load_non_empty_file(path) then
add_missing_path(missing_paths, seen_paths, path)
end
end
return missing_paths
end
local function print_missing_nui_notice(missing_paths)
local border = "======================================================================"
local lines = {
("^1%s^0"):format(border),
"^1 SKY PHONE UI BUILD IS MISSING OR INCOMPLETE ^0",
("^1%s^0"):format(border),
"^3 The resource started, but the packaged phone UI cannot load.^0",
"",
"^3 Missing or invalid files:^0",
}
for index = 1, #missing_paths do
lines[#lines + 1] = ("^1 - %s^0"):format(missing_paths[index])
end
lines[#lines + 1] = ""
lines[#lines + 1] = "^3 Install the latest published release package, not GitHub's automatic source archive.^0"
lines[#lines + 1] = "^5 Release: https://github.com/sky-systems/sky_phone/releases/latest^0"
lines[#lines + 1] = "^3 Developers working from source must run build_frontend.bat before starting sky_phone.^0"
lines[#lines + 1] = ("^1%s^0"):format(border)
print(table.concat(lines, "\n"))
end
local missing_paths = find_missing_nui_files()
if #missing_paths > 0 then
print_missing_nui_notice(missing_paths)
end