ATY Scripts Logo
ATY Scripts/Docs/Doorlock/Doorlock

Doorlock

🔐 aty_doorlock

A powerful, fully-featured door lock system for FiveM (ESX & QBCore)
Built by atiysu — part of the [aty] resource suite


🔍 Overview

aty_doorlock is a comprehensive, database-driven door management system for FiveM servers. It supports both ESX and QBCore frameworks and provides server administrators with a fully interactive NUI panel to create, configure, and manage door locks entirely in-game — no file editing required after initial setup.

The system is designed around multi-layered security:

  1. Gate Authorization — Job, Citizen ID, or item-based access control
  2. Secondary Verification — PIN code, biometric scanner (fingerprint / face ID), or keycard
  3. Illegal Bypass — Lockpicking or terminal hacking minigames for criminals

Doors sync to all connected players in real time and their state is managed server-side.


✨ Features

Feature Description
🖥️ NUI Admin Panel Full in-game UI to create, edit, delete, and manage doors
🚪 Single & Double Doors Supports individual doors and synchronized double-door pairs
🔑 Layered Access Control Job, CitizenID, item-based, or public access
🔢 PIN Code Locks Number pad prompt for authorized users
👆 Fingerprint Scanner Physical prop spawned at door; blocks gloved players
👤 Face ID Scanner Physical prop spawned at door; blocks masked players
💳 Keycard Reader Uses keycard animation to unlock
🛠️ Lockpick Bypass Minigame bypass for lockpick-enabled doors
💻 Terminal Hacking ox_lib skill check for hackable doors
🧬 Biometric Hacking Word-search minigame to bypass scanners
📡 Remote Controller Item-based remote toggling within a configurable range
⏱️ Auto-Lock Doors can be configured to re-lock after a set interval
🔊 Custom Sounds Custom lock/unlock audio via NUI or GTA native sounds
📂 Category System Organize doors into categories (Police, Hospital, etc.)
🌐 Real-time Sync All door states sync across players instantly
📥 ox_doorlock Import One-command migration from ox_doorlock
🎯 Scanner Prop Streaming Physical scanner props spawn/despawn based on proximity
🗺️ Teleport to Door Admin can teleport to any door from the management UI

📦 Dependencies

The following resources must be installed and started before aty_doorlock:

Dependency Required Notes
aty_lib ✅ Yes Core utility library (framework bridge)
oxmysql ✅ Yes MySQL/MariaDB interface
ox_lib ✅ Yes Used for skillCheck minigames
es_extended or qb-core ✅ One of them Supported frameworks

Note: ox_inventory is optional but recommended for item-metadata features (remote controller).


🚀 Installation

Step 1 — Copy the Resource

Place the aty_doorlock folder into your server's resources directory:

resources/
  [aty]/
    aty_doorlock/    ← here

Step 2 — Import the Database

Run the SQL file against your database using phpMyAdmin, HeidiSQL, or the MySQL CLI:

-- Run this file:
aty_doorlock/doorlocks.sql

The server will also attempt to auto-create the table on startup via oxmysql, so this step is a safety net.

Step 3 — Add to server.cfg

Add the resource to your server.cfg and make sure it starts after its dependencies:

ensure oxmysql
ensure aty_lib
ensure ox_lib
ensure aty_doorlock

Step 4 — Configure

Open shared/config.lua and adjust the settings to match your server's setup. See the Configuration Reference section for full details.

Step 5 — Restart Server

Start or restart your FiveM server. You should see this in the console on a successful load:

[ATY-DOORLOCK] X doors loaded successfully.

🗄️ Database

The resource uses a single table: aty_doorlocks

Column Type Description
id INT Auto-increment primary key
doorId VARCHAR(50) Unique string identifier for the door
doorLabel VARCHAR(100) Human-readable name of the door
doorType VARCHAR(20) single or double
category VARCHAR(50) Category label (e.g. police, hospital)
dist FLOAT Interaction radius in meters
lockInterval INT Auto-lock timer in seconds (0 = disabled)
doorHash VARCHAR(255) GTA model hash of the door entity
coords LONGTEXT JSON coordinates of the door(s)
users LONGTEXT JSON array of authorized CitizenIDs
jobs LONGTEXT JSON array of authorized job names
items LONGTEXT JSON array of authorized item names
pinCode VARCHAR(20) PIN code for secondary verification
canLockpick TINYINT 1 = lockpicking allowed
lpItem VARCHAR(50) Item name required to lockpick
lpDiff VARCHAR(20) Lockpick difficulty (easy, medium, hard)
canHack TINYINT 1 = terminal hacking allowed
hackItem VARCHAR(50) Item name required to hack
hackDiff VARCHAR(20) Hack difficulty (easy, medium, hard)
hasFingerprint TINYINT 1 = fingerprint scanner enabled
hasFaceId TINYINT 1 = face ID scanner enabled
hasKeycard TINYINT 1 = keycard reader enabled
pinCodeCoords LONGTEXT JSON coordinates of PIN pad prop
fingerprintCoords LONGTEXT JSON coordinates of fingerprint prop
faceIdCoords LONGTEXT JSON coordinates of face ID panel prop
keycardCoords LONGTEXT JSON coordinates of keycard reader prop
isLockedByDefault TINYINT 1 = locked on server start
createRemoteController TINYINT 1 = give creator a remote controller item

⚙️ Configuration Reference

All configuration is located in shared/config.lua.

Core Settings

Config = {
    Debug = true,           -- Enable debug prints in server console
    OldESX = false,         -- Set true only if using ESX legacy (< 1.2)
    LicenseType = "steam",  -- Player identifier: steam, license, license2, discord, xbox
    LocalTimeout = 500,     -- ms cooldown per-player between toggles
    GlobalTimeout = 1000,   -- ms cooldown for a door to be toggled by anyone
}

Admin Command

DoorlockCommand = {
    Name = 'doorlock',           -- Chat command to open the admin panel
    Suggestion = 'Door Lock',    -- Description shown in command suggestions
    Permissions = {
        'admin',                 -- ESX group / QBCore permission required
        -- 'god'                 -- Uncomment if using QBCore 'god' permission
    }
}

Minigame Settings

Minigames = {
    Lockpick = {
        BreakChance = 30,       -- % chance item breaks on minigame failure (if RemoveOnFail = false)
        RemoveOnSuccess = true, -- Remove the lockpick item on success
        RemoveOnFail = true,    -- Remove the lockpick item on failure
        Anim = { dict = "...", anim = "...", duration = -1 } -- Animation during lockpicking
    },
    Hack = {
        BreakChance = 10,       -- % chance terminal breaks on failure
        RemoveOnSuccess = false,
        RemoveOnFail = true,
    },
    Biometric = {
        faceid = {
            item = "hacking_kit",   -- Item required to attempt face ID bypass
            difficulty = "hard",    -- Minigame difficulty
            time = 15,              -- Seconds to complete
            lives = 3,              -- Allowed mistakes
            gridSize = 10,          -- Grid size (10x10)
            targetCount = 5         -- Letters to find
        },
        fingerprint = {
            item = "lockpick",
            difficulty = "medium",
            time = 25,
            lives = 5,
            gridSize = 10,
            targetCount = 4
        }
    }
}

Access Control

AdminBypass = false,              -- Admins bypass all door locks entirely
MasterJobs = { "police", "sheriff" }, -- These jobs bypass all access checks

Scanner Props

These are the GTA prop models that are physically placed at scanner locations:

ScannerProps = {
    faceid      = "hei_prop_hei_securitypanel",
    fingerprint = "ch_prop_fingerprint_scanner_01d",
    keycard     = "prop_cs_swipe_card",
    pincode     = "prop_ld_keypad_01",
}

Scanner Animations

Animations played when interacting with a scanner:

ScannerAnimations = {
    faceid      = { dict = "mp_common_miss",             anim = "put_away_sub", duration = 2000 },
    fingerprint = { dict = "mp_fbi_heist",               anim = "loop",         duration = 2000 },
    keycard     = { dict = "anim@heists@keycard@",       anim = "exit",         duration = 2000 },
    pincode     = { dict = "anim@mp_player_intmenu@key_fob@", anim = "fob_click", duration = 1500 },
}

Door Categories

Used for organizing doors in the admin UI:

Categories = {
    { label = "Police Department", value = "police"   },
    { label = "Hospital",          value = "hospital"  },
    { label = "Cafes",             value = "cafes"     },
    { label = "General",           value = "general"   },
}

To add a new category: Simply add a new { label = "...", value = "..." } entry.

Sounds

Sounds = {
    enabled = true,
    lock    = { file = "lock.mp3",   volume = 0.3 },
    unlock  = { file = "unlock.mp3", volume = 0.3 }
}

Sound files must be placed in the web/dist/ folder or referenced as GTA native audio sets.

Remote Controller

RemoteDistance = 15.0,              -- Maximum range (meters) to use the remote
RemoteItem     = "remote_controller", -- Inventory item name for the remote
RemoteAnimation = { dict = "anim@mp_player_intmenu@key_fob@", anim = "fob_click", duration = 1000 }

🎮 In-Game Usage Guide

Admin Panel (Door Manager)

The door manager is an admin-only NUI interface for creating and managing all doors.

Opening the panel:

/doorlock

Requires the admin permission (or as configured in Config.DoorlockCommand.Permissions).

The panel displays all registered doors in a table/list, filterable by category. From here you can:

  • Create a new door
  • ✏️ Edit an existing door's settings
  • 🗑️ Delete a door
  • 🔓 Toggle a door's state directly from the UI
  • 📍 Teleport to a door's location (with 5-second stealth mode)

Creating a Single Door

  1. Open the panel with /doorlock
  2. Click "Add Door" / "Create"
  3. Fill in the required fields:
    • Door ID — unique identifier (e.g. pd_front_door)
    • Door Label — display name (e.g. Police Department Front Door)
    • Door Type — select Single
    • Category — select from the dropdown
    • Interaction Distance — how close a player must be to interact (default: 5.0 meters)
  4. Click "Select Door" — the UI will hide and you'll enter door selection mode
  5. In the world, look at the door entity you want to register:
    • A green outline will highlight the door you're aiming at
    • Left Click to select it
  6. The door's hash and coordinates are automatically captured
  7. Configure access settings (jobs, users, items, scanners, PIN, etc.)
  8. Click Save to register the door

Creating a Double Door

For double doors (e.g. saloon-style swinging doors):

  1. Follow steps 1–3 above, but set Door Type to Double
  2. Click "Select Door"
  3. You must select 2 door entities one at a time:
    • Select the first door panel (green outline appears → Left Click)
    • The system awaits the second selection
    • Select the second door panel
  4. Both entities are captured with their individual hashes and coordinates
  5. Continue with access configuration and save

Placing Scanner Props

If you enable a scanner (fingerprint, face ID, keycard, or PIN pad), a physical prop must be placed in the world.

  1. In the door creation/edit form, enable a scanner type (e.g. toggle Fingerprint Scanner)
  2. Click "Place Scanner" next to the scanner type
  3. The UI hides and a ghost prop appears, following your cursor:
    • Point your camera at a wall or surface within 5 meters
    • Use Scroll Wheel / Q / E / Arrow Keys to rotate the prop
    • Left Click to place it at that position
    • Right Click to cancel
  4. The prop's world position is saved to the door configuration

The prop will automatically appear/disappear based on the player's proximity (within 50 meters).


Editing & Deleting Doors

In the door manager panel:

  • Edit: Click the edit/pencil icon on a door row. The form re-populates with current settings. Change any field and save.
  • Delete: Click the delete/trash icon. The door is immediately removed from the database and all clients are synced.

Toggling Doors as a Player

Players can interact with nearby doors using the E key:

  1. Walk within the configured interaction distance (default: 5.0 meters) of a door
  2. A HUD indicator appears on-screen showing the door label and its current status (🔒 Locked / 🔓 Unlocked)
  3. Press E to attempt to toggle the door

What happens next depends on the door's configuration:

Door State Player Has Access Secondary Verification Result
Locked ✅ Yes None Unlocks immediately
Locked ✅ Yes PIN Code PIN pad UI appears
Locked ✅ Yes Fingerprint Fingerprint scanner UI appears
Locked ✅ Yes Face ID Face ID scanner UI appears
Locked ✅ Yes Keycard Keycard animation plays, unlocks
Locked ❌ No Any Error notification
Unlocked ✅ Yes N/A Locks immediately

🔐 Access Control System

Access is evaluated in this priority order on both client and server:

1. Admin Bypass (Optional)

If Config.AdminBypass = true, admins skip all checks.

2. Master Jobs

Jobs listed in Config.MasterJobs (default: police, sheriff) bypass all per-door access checks.

3. Per-Door Access Rules

If a door has no authorized users, jobs, or items configured → it is treated as public (anyone can toggle it).

If a door has any restriction set, the player must match at least one:

Type What's Checked
Users Player's CitizenID / identifier must be in the door's user list
Jobs Player's active job must be in the door's job list
Items Player must have at least one of the door's required items in inventory

🔒 Security & Verification Methods

These are the secondary lock layers that apply after gate authorization. They are only triggered when a player is unlocking (locking never requires secondary verification).

PIN Code

A number pad prompt appears in-game. The player must enter the correct PIN.

  • Configuration (per door): Set a numeric PIN code in the door creation form
  • Player action: Press E near the door → PIN pad UI appears → type the code → submit

Fingerprint Scanner

A physical prop (ch_prop_fingerprint_scanner_01d by default) is placed at a configured location. When the player interacts, their character performs a scanning animation.

Security checks:

  • If the player is wearing gloves, the scan is rejected automatically
  • The scanner verifies the player's CitizenID against the door's authorized users list

Player action: Press E near the door → fingerprint scanner UI appears → animation plays → result shown

Face ID Scanner

A physical security panel prop (hei_prop_hei_securitypanel) is placed at a configured location.

Security checks:

  • If the player is wearing a mask or head covering, the scan is rejected automatically
  • The scanner verifies the player's CitizenID against the door's authorized users list

Player action: Press E near the door → face ID scanner UI appears → animation plays → result shown

Keycard Reader

A swipe card prop (prop_cs_swipe_card) is physically placed at the door. No player inventory item is required — the player simply interacts and the animation plays.

Player action: Press E near the door → swipe animation plays → door unlocks if authorized


🦹 Illegal Bypass Methods

These systems allow unauthorized players (criminals) to attempt to bypass locked doors using minigames — at the risk of losing their tools.

Lockpicking

Requirements:

  • Door must have canLockpick = true
  • Door must have a lockpick item configured (default: lockpick)
  • Player must have the required item in inventory

How to use:

  1. Have the configured lockpick item in your inventory
  2. Use the item from your inventory while standing near a locked door
  3. A skill check minigame (ox_lib:skillCheck) launches — press the correct keys in sequence
  4. Success → Door unlocks; item may be removed (based on RemoveOnSuccess)
  5. Failure → Item may break/be removed (based on RemoveOnFail and BreakChance)

Difficulty levels:

Level Pattern
easy easy, easy
medium easy, medium, easy
hard medium, hard, hard

Hacking

Requirements:

  • Door must have canHack = true
  • Door must have a hack item configured (default: terminal)
  • Player must have the required item in inventory

How to use:

  1. Have the configured hacking item in your inventory
  2. Use the item near a locked door
  3. The same ox_lib:skillCheck minigame launches with configured difficulty
  4. Same success/fail logic as lockpicking

Biometric Hacking

Requirements:

  • Door must have a fingerprint or face ID scanner AND canHack = true
  • Player must have the configured biometric hacking item:
    • Face ID bypass: hacking_kit (by default)
    • Fingerprint bypass: lockpick (by default)

How to use:

  1. Have the required item in your inventory
  2. Use the item near the door
  3. A word-search grid minigame appears in the NUI:
    • Find the hidden letters within the time limit
    • You have a limited number of mistakes allowed
  4. Success → Door unlocks; item handled per config
  5. Failure → Item loss based on config

📡 Remote Controller

Certain doors can be assigned a remote controller — an inventory item that lets an authorized holder toggle the door from a distance.

Setup (Admin)

In the door creation/edit form:

  1. Enable "Create Remote Controller"
  2. Set a Remote ID — a unique string that links the remote to this door (e.g. pd_garage_remote)
  3. Save the door — a remote_controller item is automatically added to the admin's inventory with the Remote ID embedded as metadata

Using the Remote (Player)

  1. Have the remote_controller item in your inventory
  2. Use the item
  3. A key-fob animation plays on the character
  4. If you are within Config.RemoteDistance meters (default: 15m), the linked door toggles
  5. If you are too far, you'll receive an error notification

Note: The remote bypasses the normal gate authorization check — whoever holds the item can toggle the door regardless of their job.


⏱️ Auto-Lock System

Doors can be configured to automatically re-lock after being unlocked.

Setting it up: In the door form, set the "Lock Interval" field to a number of seconds (e.g. 30 = re-locks after 30 seconds).

Behavior:

  • When a door is unlocked, a server-side timer starts
  • After the interval, the door state is set back to locked
  • All players receive a real-time state update
  • Setting the interval to 0 disables auto-lock

🔊 Sound System

When a door is toggled, lock/unlock sounds are played for nearby players (within 15 meters).

Configuration:

Sounds = {
    enabled = true,
    lock    = { file = "lock.mp3",   volume = 0.3 },
    unlock  = { file = "unlock.mp3", volume = 0.3 }
}
  • file — Audio file served via NUI (place in web/dist/)
  • volume — Float from 0.0 to 1.0
  • Alternatively, use name + set for GTA native audio (omit file to use native sounds)

📥 Importing from ox_doorlock

If you're migrating from ox_doorlock, the script includes a built-in import command.

Requirements:

  • ox_doorlock table must exist in the database
  • You must have admin permissions

How to import:

In the F8 console or via server console:

import_ox

Or from the game as an admin:

/import_ox

What gets imported:

  • Door name → doorLabel
  • Door model hash → doorHash
  • Coordinates (single or double)
  • Job groups → jobs
  • Items → items
  • Lock state → isLockedByDefault
  • PIN code → pinCode
  • Lockpick permission → canLockpick

After import, the console will report how many doors were successfully migrated. Restart the resource to apply:

restart aty_doorlock

📤 Export API

The import.lua file is not escrow-locked, allowing developers to extend or integrate with aty_doorlock. Key server events:

Event Direction Description
aty_doorlock:server:RequestDoors Client → Server Request full door sync
aty_doorlock:server:ToggleDoor Client → Server Attempt to toggle a door
aty_doorlock:server:CreateDoor Client → Server Create a new door (admin)
aty_doorlock:server:UpdateDoor Client → Server Update door settings (admin)
aty_doorlock:server:DeleteDoor Client → Server Delete a door (admin)
aty_doorlock:server:MinigameFail Client → Server Report minigame failure
aty_doorlock:client:SyncDoors Server → Client Push full door table to client
aty_doorlock:client:UpdateDoorState Server → Client Update a single door's lock state
aty_doorlock:client:OpenUI Server → Client Open the admin panel

🛠️ Troubleshooting

"Doors not loading" / "0 doors loaded"

  • Ensure oxmysql is started before aty_doorlock
  • Run the doorlocks.sql file manually to confirm the table exists
  • Check the server console for SQL errors

"You do not have permission to interact with this door"

  • The door is restricted — check the door's users, jobs, or items configuration
  • Verify the player's CitizenID or job name matches exactly
  • Make sure Config.MasterJobs includes the relevant job if you want blanket access

Door won't unlock even with correct PIN

  • Ensure the pin is stored as a string (not 0 or empty)
  • Check Config.Debug = true and review server console output for toggle details

Scanner prop not appearing in-game

  • The prop only spawns within 50 meters of the player
  • Ensure a valid GTA prop model is set in Config.ScannerProps
  • The coordinates must be set during door creation via the "Place Scanner" flow

Lockpick/hack minigame not launching

  • Confirm canLockpick = true or canHack = true on the door
  • Confirm the player has the correct item (lockpick, terminal, or hacking_kit)
  • Ensure ox_lib is started and the skillCheck export works

Import command not found

  • Wait ~2 seconds after server start (the command registers on a short delay)
  • Confirm server/import.lua is included in fxmanifest.lua ✓ (it is by default)

📁 File Structure

aty_doorlock/
├── client/
│   └── client.lua          # Client-side logic: HUD, interaction, NUI callbacks, animations
├── server/
│   ├── server.lua          # Server-side logic: DB operations, authorization, sync
│   └── import.lua          # ox_doorlock migration utility (not escrow-locked)
├── shared/
│   ├── config.lua          # All configurable settings + Notify function
│   └── locale.lua          # Locale strings (en/fr, extendable)
├── web/
│   └── dist/               # Compiled NUI (HTML/CSS/JS admin panel + sounds)
├── doorlocks.sql           # Database table schema
└── fxmanifest.lua          # Resource manifest

📝 Notes & Best Practices

  • Door IDs must be unique. Use descriptive names like pd_front_door, hospital_pharmacy_gate.
  • Always test your access configuration after saving by swapping to a test character.
  • Keep Config.Debug = true during setup; switch to false in production to reduce console noise.
  • The GlobalTimeout prevents rapid door-spamming by any player. Increase it if you experience abuse.
  • If using ox_inventory, remote controller metadata is automatically read from slot metadata.
  • Doors loaded on server start default to their isLockedByDefault state — plan accordingly for shops, public areas, etc.

Made with ❤️ by atiysu — part of the [aty] FiveM resource collection.

ATY Scripts LogoATY SCRIPTS

Des scripts FiveM hautement optimisés pour QBCore & ESX. Performance maximale, code précis, zéro lag.

Rejoindre la communauté

Partenaire

Partenaire officiel de Tebex. Paiement sécurisé et intégration Cfx.re Keymaster.

Mentions légales

Non affilié à Rockstar Games, Cfx.re, FiveM ou Take-Two Interactive. Les achats sont soumis aux CGU de Tebex.

© 2026 ATY SCRIPTS. Tous droits réservés.