125 lines
5.1 KiB
Lua
125 lines
5.1 KiB
Lua
|
|
-- ─────────────────────────────────────────────────────────────────────────────
|
|||
|
|
-- Store handlers – install / uninstall / list
|
|||
|
|
-- ─────────────────────────────────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
-- ── List store ───────────────────────────────────────────────────────────────
|
|||
|
|
RegisterNetEvent('pc-live:server:getStore', function()
|
|||
|
|
local src = source
|
|||
|
|
local user = ActiveSessions[src]
|
|||
|
|
if not user then return end
|
|||
|
|
|
|||
|
|
local installs = DB.GetInstalls(user.dbId)
|
|||
|
|
local storeList = AppRegistry.BuildStoreList(installs)
|
|||
|
|
TriggerClientEvent('pc-live:client:storeData', src, storeList)
|
|||
|
|
end)
|
|||
|
|
|
|||
|
|
-- ── Install app ──────────────────────────────────────────────────────────────
|
|||
|
|
RegisterNetEvent('pc-live:server:installApp', function(appId)
|
|||
|
|
local src = source
|
|||
|
|
local user = ActiveSessions[src]
|
|||
|
|
if not user then return end
|
|||
|
|
|
|||
|
|
if type(appId) ~= "string" then return end
|
|||
|
|
appId = appId:sub(1, 64)
|
|||
|
|
|
|||
|
|
local manifest = AppRegistry.Get(appId)
|
|||
|
|
if not manifest then
|
|||
|
|
Bridge.Notify(src, "App not found.", "error")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- Fetch installs once – used for all checks below
|
|||
|
|
local installs = DB.GetInstalls(user.dbId)
|
|||
|
|
|
|||
|
|
-- Already installed and up to date?
|
|||
|
|
local installedVersion = nil
|
|||
|
|
for _, row in ipairs(installs) do
|
|||
|
|
if row.app_id == appId then
|
|||
|
|
installedVersion = row.version
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
if installedVersion and installedVersion == manifest.version then
|
|||
|
|
Bridge.Notify(src, "Already installed.", "primary")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- Job permission check (single job OR list of jobs)
|
|||
|
|
local perms = manifest.permissions or {}
|
|||
|
|
if perms.job or perms.jobs then
|
|||
|
|
local playerJob = Bridge.GetJob and Bridge.GetJob(src) or nil
|
|||
|
|
local allowed = false
|
|||
|
|
if perms.jobs and type(perms.jobs) == "table" then
|
|||
|
|
for _, j in ipairs(perms.jobs) do
|
|||
|
|
if j == playerJob then allowed = true; break end
|
|||
|
|
end
|
|||
|
|
elseif perms.job then
|
|||
|
|
allowed = (playerJob == perms.job)
|
|||
|
|
end
|
|||
|
|
if not allowed then
|
|||
|
|
local jobList = perms.jobs and table.concat(perms.jobs, ", ") or perms.job
|
|||
|
|
Bridge.Notify(src, ("Zugriff verweigert. Benötigt: %s"):format(jobList), "error")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- Dependency check
|
|||
|
|
if manifest.dependencies and #manifest.dependencies > 0 then
|
|||
|
|
local installedMap = {}
|
|||
|
|
for _, row in ipairs(installs) do
|
|||
|
|
installedMap[row.app_id] = true
|
|||
|
|
end
|
|||
|
|
for _, depId in ipairs(manifest.dependencies) do
|
|||
|
|
if not installedMap[depId] then
|
|||
|
|
local dep = AppRegistry.Get(depId)
|
|||
|
|
Bridge.Notify(src, ("Missing dependency: %s"):format(dep and dep.name or depId), "error")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- Price check
|
|||
|
|
local price = manifest.price or 0
|
|||
|
|
if price > 0 then
|
|||
|
|
local balance = Bridge.GetMoney(src, "bank")
|
|||
|
|
if balance < price then
|
|||
|
|
Bridge.Notify(src, ("Insufficient funds. Required: $%d"):format(price), "error")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
Bridge.RemoveMoney(src, "bank", price)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
DB.InstallApp(user.dbId, appId, manifest.version)
|
|||
|
|
|
|||
|
|
-- Refresh desktop icons AND store view
|
|||
|
|
local updated = DB.GetInstalls(user.dbId)
|
|||
|
|
TriggerClientEvent('pc-live:client:installedApps', src, AppRegistry.BuildInstalledList(updated))
|
|||
|
|
TriggerClientEvent('pc-live:client:storeData', src, AppRegistry.BuildStoreList(updated))
|
|||
|
|
Bridge.Notify(src, ("%s installed."):format(manifest.name), "success")
|
|||
|
|
end)
|
|||
|
|
|
|||
|
|
-- ── Uninstall app ────────────────────────────────────────────────────────────
|
|||
|
|
RegisterNetEvent('pc-live:server:uninstallApp', function(appId)
|
|||
|
|
local src = source
|
|||
|
|
local user = ActiveSessions[src]
|
|||
|
|
if not user then return end
|
|||
|
|
|
|||
|
|
if type(appId) ~= "string" then return end
|
|||
|
|
appId = appId:sub(1, 64)
|
|||
|
|
|
|||
|
|
-- Cannot uninstall default system apps
|
|||
|
|
local manifest = AppRegistry.Get(appId)
|
|||
|
|
if manifest and manifest.default then
|
|||
|
|
Bridge.Notify(src, "System apps cannot be uninstalled.", "error")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
DB.UninstallApp(user.dbId, appId)
|
|||
|
|
|
|||
|
|
-- Refresh desktop icons AND store view
|
|||
|
|
local updated = DB.GetInstalls(user.dbId)
|
|||
|
|
TriggerClientEvent('pc-live:client:installedApps', src, AppRegistry.BuildInstalledList(updated))
|
|||
|
|
TriggerClientEvent('pc-live:client:storeData', src, AppRegistry.BuildStoreList(updated))
|
|||
|
|
Bridge.Notify(src, "App uninstalled.", "primary")
|
|||
|
|
end)
|