105 lines
2.9 KiB
Lua
105 lines
2.9 KiB
Lua
-- server/atm_access.lua
|
|
print("^2[turfwar]^7 atm_access.lua loaded (server-side gatekeeper)")
|
|
|
|
Config = Config or {}
|
|
Config.Finance = Config.Finance or {}
|
|
|
|
local USE_RADIUS = tonumber(Config.Finance.ATM_USE_RADIUS) or 1.8
|
|
local TTL_MS = tonumber(Config.Finance.ATM_SESSION_TTL_MS) or 15000
|
|
|
|
local sessions = {}
|
|
|
|
local function dist3(a, b)
|
|
local dx = (a.x - b.x)
|
|
local dy = (a.y - b.y)
|
|
local dz = (a.z - b.z)
|
|
return math.sqrt(dx*dx + dy*dy + dz*dz)
|
|
end
|
|
|
|
local function newToken()
|
|
return ("%08x%08x"):format(math.random(0, 0xffffffff), math.random(0, 0xffffffff))
|
|
end
|
|
|
|
local function getPlayerCoords(src)
|
|
local ped = GetPlayerPed(src)
|
|
if not ped or ped == 0 then return nil end
|
|
local c = GetEntityCoords(ped)
|
|
return { x = c.x, y = c.y, z = c.z }
|
|
end
|
|
|
|
RegisterNetEvent("turfwar:atm:open", function(payload)
|
|
local src = source
|
|
if type(payload) ~= "table" then
|
|
TriggerClientEvent("turfwar:atm:openDenied", src, "bad_payload")
|
|
return
|
|
end
|
|
|
|
local x, y, z = tonumber(payload.x), tonumber(payload.y), tonumber(payload.z)
|
|
local model = payload.model
|
|
|
|
if not x or not y or not z then
|
|
TriggerClientEvent("turfwar:atm:openDenied", src, "bad_coords")
|
|
return
|
|
end
|
|
|
|
local okModel = false
|
|
for _, m in ipairs(Config.Finance.ATM_MODELS or {}) do
|
|
if m == model then okModel = true break end
|
|
end
|
|
if not okModel then
|
|
TriggerClientEvent("turfwar:atm:openDenied", src, "bad_model")
|
|
return
|
|
end
|
|
|
|
local pc = getPlayerCoords(src)
|
|
if not pc then
|
|
TriggerClientEvent("turfwar:atm:openDenied", src, "no_ped")
|
|
return
|
|
end
|
|
|
|
local atmC = { x = x, y = y, z = z }
|
|
if dist3(pc, atmC) > (USE_RADIUS + 0.75) then
|
|
TriggerClientEvent("turfwar:atm:openDenied", src, "too_far")
|
|
return
|
|
end
|
|
|
|
local token = newToken()
|
|
sessions[src] = {
|
|
token = token,
|
|
expires = GetGameTimer() + TTL_MS,
|
|
atm = { x = x, y = y, z = z, model = model }
|
|
}
|
|
|
|
TriggerClientEvent("turfwar:atm:openGranted", src, token)
|
|
end)
|
|
|
|
local function RequireATM(src, token, verbose)
|
|
local s = sessions[src]
|
|
if not s then return false, "no_session" end
|
|
if token ~= s.token then return false, "bad_token" end
|
|
if GetGameTimer() > (s.expires or 0) then
|
|
sessions[src] = nil
|
|
return false, "expired"
|
|
end
|
|
|
|
local pc = getPlayerCoords(src)
|
|
if not pc then return false, "no_ped" end
|
|
|
|
local atmC = { x = s.atm.x, y = s.atm.y, z = s.atm.z }
|
|
if dist3(pc, atmC) > (USE_RADIUS + 0.75) then
|
|
if verbose then
|
|
print(("^1[ATM BLOCK]^7 src=%d moved away from ATM"):format(src))
|
|
end
|
|
sessions[src] = nil
|
|
return false, "moved_away"
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
exports("RequireATM", RequireATM)
|
|
|
|
AddEventHandler("playerDropped", function()
|
|
sessions[source] = nil
|
|
end)
|