NR_Harness
A professional vehicle modification script for QBX/QBCore that allows authorized mechanics to install and remove racing harnesses with persistent database storage.
Features
- Job-restricted access - Only specified mechanic jobs can install/remove harnesses
- Persistent storage - MySQL database tracks harness installations by vehicle plate
- ox_target integration - Clean third-eye interaction system for vehicle modifications
- Command alternative -
/harnesscommand for quick access - Progress animations - Realistic installation/removal animations with progress circles
- Item management - Requires harness item from ox_inventory
- Optional item return - Configurable to return harness item when removed
- Network synced - All players see harness status updates in real-time
- Export function - Other scripts can check if a vehicle has a harness
- Proximity detection - Automatic vehicle detection within configurable distance
Dependencies
| Resource | Description | Required |
|---|---|---|
| qbx_core | Core framework | Yes |
| ox_lib | UI library (context menus, progress bars, notifications) | Yes |
| ox_inventory | Inventory system | Yes |
| ox_target | Interaction system | Yes |
| oxmysql | Database connector | Yes |
Installation
Step 1: Database Setup
Execute the included SQL file to create the vehicle_harnesses table. This stores all harness installations persistently.
Step 2: Download
Download NR_Harness and extract it to your resources folder:
server/
└── resources/
└── [nightrider]/
└── NR_Harness/
Step 3: server.cfg
Add the resource to your server configuration:
ensure NR_Harness
Step 4: Add Inventory Item
Add a harness item to your ox_inventory:
['harness'] = {
label = 'Racing Harness',
weight = 2500,
stack = false,
close = true,
description = 'A racing harness for improved vehicle safety'
}
Step 5: Configure
Edit config.lua to set authorized jobs, harness item name, and installation/removal times.
Step 6: Restart
Restart your server to load the resource.
Make sure qbx_core, ox_lib, ox_inventory, ox_target, and oxmysql are all started before NR_Harness in your server.cfg.
How It Works
1. Obtaining Harnesses
Mechanics receive or purchase harness items. Items are stored in ox_inventory like normal.
2. Installation Process
Mechanic approaches a vehicle (within 3 meters default) and uses /harness or ox_target on the vehicle. Select "Install Racing Harness" from the menu. A 10-second progress bar plays with a repair animation. The harness item is consumed from inventory, the installation is saved to the database, and all clients are notified of the harness status.
3. Removal Process
Mechanic approaches a vehicle that has a harness and uses /harness or ox_target. Select "Remove Racing Harness". An 8-second progress bar plays with a repair animation. The harness is removed from the database, the item is returned to inventory (if configured), and all clients are notified of the status change.
Database Schema
vehicle_harnesses
├── id (INT) - Primary key
├── plate (VARCHAR) - Vehicle plate (unique)
└── installed_at (TIMESTAMP) - Installation date/time
Features a unique constraint on plate (one harness per vehicle), indexed plate column for fast lookups, timestamp tracking for installation history, and ON DUPLICATE KEY UPDATE for reinstallation handling.
Configuration
Job Permissions
Config.Jobs = {
'flywheel', -- Mechanic shop 1
'afterlife', -- Mechanic shop 2
'bennys', -- Add more as needed
}
Item Settings
Config.HarnessItem = 'harness' -- Item name in ox_inventory
Distance & Timing
Config.InstallDistance = 3.0 -- Meters from vehicle
Config.HarnessSettings = {
installTime = 10000, -- 10 seconds
removeTime = 8000, -- 8 seconds
returnItemOnRemove = true, -- Give item back when removing
}
Custom Notifications
Config.Notifications = {
installSuccess = 'Racing harness installed successfully!',
removeSuccess = 'Racing harness removed successfully!',
alreadyInstalled = 'This vehicle already has a harness installed!',
noHarness = 'This vehicle does not have a harness installed!',
noItem = 'You need a racing harness to install!',
wrongJob = 'You are not qualified to install/remove harnesses!',
cancelled = 'Installation cancelled!',
vehicleNotFound = 'No vehicle found nearby!',
}
Integration with Other Scripts
Export: Check Harness Status
Other scripts can check if a vehicle has a harness installed:
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
local hasHarness = exports['NR_Harness']:hasHarness(vehicle)
if hasHarness then
-- Apply harness benefits (reduced ejection, etc.)
else
-- Normal vehicle behavior
end
Example: Ejection Prevention
CreateThread(function()
while true do
Wait(100)
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
local hasHarness = exports['NR_Harness']:hasHarness(vehicle)
if hasHarness then
SetPedConfigFlag(ped, 32, false) -- Disable exit on impact
end
end
end
end)
Example: Racing Script Integration
AddEventHandler('baseevents:onPlayerWasted', function()
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
local hasHarness = exports['NR_Harness']:hasHarness(vehicle)
if hasHarness then
SetEntityHealth(ped, GetEntityHealth(ped) + 50)
end
end
end)
Common use cases:
- Crash/rollover scripts reducing ejection chance
- Racing scripts providing safety bonuses
- Injury systems reducing damage
- Insurance scripts affecting premiums
Security Features
Server-Side Validation
| Protection | Description |
|---|---|
| Job verification | Every action double-checks job permission, prevents client-side exploits |
| Item possession | Validates harness item via ox_inventory:Search() before installation |
| Database integrity | UNIQUE constraint on plate prevents duplicates, ON DUPLICATE KEY UPDATE handles edge cases |
| State validation | Checks if harness exists before install/remove, prevents impossible state transitions |
Client-Side Protection
- Job requirement - ox_target and command only work for authorized jobs
- Progress cancellation - Player can cancel, no item consumed, clean rollback
- Distance enforcement - Vehicle must be within configured range via
lib.getClosestVehicle()
Customization
Adding More Jobs
Config.Jobs = {
'mechanic',
'tuner',
'customs',
'garage',
}
Custom Animations
Modify the animation in progress circles:
anim = {
dict = 'anim@amb@clubhouse@tutorial@bkr_tut_ig3@',
clip = 'machinic_loop_mechandplayer'
}
Popular mechanic animations:
mini@repair / fixing_a_player(default)amb@prop_human_bum_bin@idle_a / idle_aanim@amb@clubhouse@tutorial@bkr_tut_ig3@ / machinic_loop_mechandplayer
Different Item Per Job
Modify the item check in server.lua:
local itemToUse = Config.HarnessItem
if player.PlayerData.job.name == 'premium_mechanic' then
itemToUse = 'premium_harness'
end
Commands
| Command | Description | Permission |
|---|---|---|
/harness |
Open harness installation menu for nearest vehicle | Configured jobs only |
Performance
| Metric | Value |
|---|---|
| Resmon impact | ~0.00ms (idle), ~0.01ms (in vehicle check) |
| Network traffic | Minimal (event on install/remove only) |
| Database queries | 1 on resource start (load all), 1 per install/remove |
| Memory usage | ~0.8 MB |
| Threads | 1 (vehicle entry detection) |
Database Maintenance
-- Check harness count
SELECT COUNT(*) FROM vehicle_harnesses;
-- List all harnessed vehicles
SELECT plate, installed_at FROM vehicle_harnesses ORDER BY installed_at DESC;
-- Remove harness from specific vehicle
DELETE FROM vehicle_harnesses WHERE plate = 'ABC123';
-- Clear old harnesses (vehicles likely deleted)
DELETE FROM vehicle_harnesses WHERE installed_at < DATE_SUB(NOW(), INTERVAL 90 DAY);
Troubleshooting
Harness not installing
- Verify player has an authorized job
- Check if harness item is in inventory
- Confirm item name matches
Config.HarnessItem - Check server console for SQL errors
Database errors
- Ensure oxmysql is running
- Verify SQL table was created correctly
- Check database connection in
server.cfg
ox_target not showing option
- Confirm ox_target is started before this resource
- Verify player has one of the configured jobs
- Check if within
Config.InstallDistance
Harness status not updating
- Verify all clients received the network event
- Check client console for errors
- Restart resource on all clients
Item not returning on removal
- Check
Config.HarnessSettings.returnItemOnRemoveis set totrue - Verify inventory isn't full
- Check server console for inventory errors
Wrong vehicle getting harness
- Plates are case-sensitive and space-sensitive
- Script auto-trims spaces, but custom plates may have issues
- Check database for duplicate plate entries
Support
Need help? Join our Discord server for community support and updates.