ESX / QB / QBX supported
A remote vehicle sabotage toolkit delivered as an lb-phone app (C.A.R — Compromise And Reroute). Targets nearby vehicles through your camera crosshair and performs one of several sabotage actions. Actions are paid for with a custom currency called HackCoin — fully isolated from the player's bank, driven by exports you can hook into any earning loop you want.
-
Drop the resource into your server and
ensure randol_vehhackafterlb-phone. -
Build the UI (one-time, and again whenever you edit
ui/src/):cd randol_vehhack/ui npm install npm run build -
Restart the resource. The
randol_hackcoinMySQL table is created automatically on first start. -
Open your phone → App Store → search for C.A.R → Install.
The app is listed as a non-default store app (
Config.App.defaultApp = false). Flip that totrueif you want it preinstalled on every phone.
HackCoin is a per-player balance stored in the randol_hackcoin table, keyed by framework identifier (citizenid for qb/qbx, ESX identifier for ESX). The phone UI shows the current balance in the header and updates live whenever it changes.
Call these from any other resource to wire HackCoin into your economy (shops, missions, admin commands, heist rewards, darkweb purchases, etc.).
-- Read the player's current balance
local balance = exports.randol_vehhack:GetHackCoin(source)
-- Award HackCoin (returns ok, newBalance)
local ok, newBalance = exports.randol_vehhack:AddHackCoin(source, 2500, 'heist:payout')
-- Deduct HackCoin (returns false, 'insufficient funds' if short)
local ok, err = exports.randol_vehhack:RemoveHackCoin(source, 1000, 'shop:upgrade')
if not ok then
print('Could not charge player:', err)
endAll three exports accept an optional reason string which is logged server-side for easy auditing.
| Command | Who | What |
|---|---|---|
/givehackcoin <id> <amount> |
admin | Add HackCoin to a player. |
/removehackcoin <id> <amount> |
admin | Deduct HackCoin from a player. |
/checkhackcoin <id> |
admin | Look up a player's balance. |
/hackcoin |
anyone | Show your own balance. |
Admin commands are gated by group.admin via ox_lib. If you use custom ACE groups, grant access with:
add_ace group.admin command.givehackcoin allow
add_ace group.admin command.removehackcoin allow
add_ace group.admin command.checkhackcoin allowAll commands also work from the server console (no target restrictions). Example:
givehackcoin 1 10000
Everything lives in config.lua:
| Key | Purpose |
|---|---|
App |
lb-phone app metadata (identifier, name, developer, store pricing, default install) |
Currency |
HackCoin id / label / display name / starting balance / maxAmount / logTransactions (false = no console prints; sabotage fees never print either way) |
OutlineColor |
{r, g, b, a} color of the in-world vehicle outline when targeting |
MaxDistance |
Raycast distance when targeting a vehicle |
TimeBetweenVehicleActions |
Per-vehicle cooldown (ms) between sabotage attempts |
TimeBetweenActions |
Per-player cooldown (ms) between any sabotage attempts. Primary defense against mass-sabotage spam from forged events. |
AllowNpcTargets |
true = sabotage NPC-driven vehicles for npcFee. false = players-only; AI vehicles cannot be outlined or targeted. |
RequireLineOfSight |
Server-enforced line-of-sight check. The target vehicle's network owner raycasts from the attacker's position to the target; if a wall or prop is in the way, the action is denied before any fee is charged. Blocks wallhack-style sabotage through geometry. |
LineOfSightTimeoutMs |
Callback timeout for the LOS check (default 750). On timeout the check is skipped (fail-open) so network hiccups don't reject legitimate actions. |
BlacklistedModels |
Vehicles that cannot be sabotaged (trailers, etc.) |
VehicleActions |
All sabotage actions with label, description, icon, playerFee, npcFee, and task parameters |
playerFee is charged when the target's driver is a player; npcFee is charged for AI-driven vehicles. Set either to 0 to make an action free in that context.
UI colors and the in-world outline color are configured in two separate places:
1. Phone UI accent colors — ui/src/index.css, top of the file inside the :root { ... } block:
:root {
--accent: #ff1a4d; /* primary accent - logo, borders, hover glow */
--accent-rgb: 255, 26, 77; /* same color as rgb triplet for transparent variants */
--accent-dark: #8a0022; /* dark end of the logo gradient */
--accent-bright: #ff6d8a; /* lift color for highlights */
...
}Change the four --accent* values, then rebuild:
cd ui && npm run buildKeep --accent and --accent-rgb in sync (same color, one in hex form, one as r, g, b bytes) — anything using transparency uses rgba(var(--accent-rgb), X).
Action card icons — Font Awesome 6 (solid) through react-icons, mapped in ui/src/components/ActionCard.tsx. If you add a new icon string under VehicleActions, add the same key there and point it at an Fa* icon (or rebuild the UI after changing dependencies).
2. In-world vehicle outline — config.lua:
OutlineColor = { 223, 149, 12, 255 }, -- r, g, b, a (0-255)No rebuild needed for this one; just restart the resource.
The ui/public/icon.svg (phone store icon) is a static SVG — if you change the UI theme, swap the colors in that file too, or replace it with your own art.
- Player opens C.A.R on their phone.
- They tap an action card (e.g. Swerve Left, Explode Vehicle).
- The phone closes and a text prompt instructs them to aim at a vehicle.
- Aiming at a moving vehicle with a driver within
MaxDistancedraws a marker around it; ENTER confirms, BACKSPACE cancels. - On confirm, the server charges the HackCoin fee and fires the sabotage on the vehicle's network owner.
randol_vehhack/
├── config.lua app + currency + actions config
├── client.lua targeting / raycast / sabotage execution
├── server.lua server-side action handler + fee charge
├── server/currency.lua HackCoin storage + AddHackCoin/RemoveHackCoin/GetHackCoin exports
├── phone/client.lua lb-phone registration + NUI callbacks
├── phone/server.lua balance push to UI
├── bridge/{client,server}/* qb / qbx / esx framework shims
├── fxmanifest.lua
└── ui/ Vite + React + TypeScript phone UI
├── src/
└── dist/ built output (produced by npm run build)
- The previous
carhackdeviceinventory item has been removed — the phone app replaces it entirely. If you still want item gating, wrap theexecuteActionNUI callback in phone/client.lua with ahasItem()check. - Swap
ui/public/icon.svgandui/public/store/screenshot-*.svgfor your own art before shipping.
You have permission to use this in your server and edit for your personal needs but are not allowed to redistribute.