Skip to content

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

  1. Get the files. Owner: under Granted Assets in your Cfx.re Portal. Developer: the download link in the Tebex email.
  2. Put the fsd-fingerprint-cloner folder in your server resources. Keep that name: the export uses it.
  3. Add this line to your server.cfg and 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)