Fingerprint Cloner
Fingerprint Cloner runs on the client. Your script starts it, waits for the result and tells your server what happened. It uses the game’s own textures, sounds and videos, so it streams nothing.
Install
- Get the files. Owner: under Granted Assets in your Cfx.re Portal. Developer: the download link in the Tebex email.
- Put the
fsd-fingerprint-clonerfolder in your server resources. Keep that name: the export uses it. - Add this line to your
server.cfgand restart:
ensure fsd-fingerprint-cloner
It has no dependencies.
Start it
You can start it with the export or with the event. Both run in a client script.
Export
The export waits until the game ends and returns the result, so call it inside a thread:
CreateThread(function()
local result, reason = exports['fsd-fingerprint-cloner']:start(4, 300000)
end)
Event
The event returns right away and calls your function when the game ends:
TriggerEvent('fingerprint-cloner:start', 4, 300000, function(result, reason)
-- your code
end)
It isn’t a network event, so TriggerClientEvent from the server doesn’t reach it. To start it from the server, send your own event to the player and call the export or the event there. The example at the end does exactly that.
Options
Both are optional. Leave one out and its default applies.
| Option | What it is | Default |
|---|---|---|
rounds |
Fingerprints to solve, from 1 to 4 | 4 |
time |
Time for the whole hack, in milliseconds | 300000 (5 minutes) |
Results
result |
reason |
When |
|---|---|---|
1 |
success |
Every fingerprint matched |
2 |
timeout |
Time ran out |
0 |
quit |
The player left the hack |
-1 |
busy |
It was already running |
-1 |
load_failed |
The game assets didn’t load |
Give the reward on the server
A cheater can fire myheist:hackDone from a mod menu without playing, so the server only pays for a hack it started itself, that took a possible time, and only once:
-- client.lua
RegisterNetEvent('myheist:startHack', function(token)
CreateThread(function()
local result = exports['fsd-fingerprint-cloner']:start(4, 300000)
TriggerServerEvent('myheist:hackDone', token, result == 1)
end)
end)
-- server.lua
local MAX_TIME = 300 + 10 -- seconds: your time limit plus slack for loading and the network
local MIN_TIME = 5 -- seconds: time a fast run on your server and raise it
local hacks = {}
-- Call this from your heist when the player may hack (at the terminal, not on cooldown).
local function startHack(src)
local token = ('%08x%08x'):format(math.random(0, 0x7fffffff), math.random(0, 0x7fffffff))
hacks[src] = { token = token, startedAt = os.time() }
TriggerClientEvent('myheist:startHack', src, token)
end
RegisterNetEvent('myheist:hackDone', function(token, success)
local src = source
local hack = hacks[src]
hacks[src] = nil -- one use: a second report finds nothing
if not hack or hack.token ~= token or not success then return end
local took = os.time() - hack.startedAt
if took < MIN_TIME or took > MAX_TIME then return end
-- Give the reward here.
end)
AddEventHandler('playerDropped', function()
hacks[source] = nil
end)