Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
dd60b20
feat: add auto-migrations on startup
Kenshiin13 Aug 24, 2025
5cb6f35
feat: add "restart required" print
Kenshiin13 Aug 24, 2025
22ab3dc
refactor: store migrations in core table
Kenshiin13 Aug 24, 2025
45308f5
refactor: only store migrations if not ran
Kenshiin13 Aug 24, 2025
ff8798a
Revert "refactor: only store migrations if not ran"
Kenshiin13 Aug 24, 2025
8fad1f9
refactor: only store migrations if not already ran
Kenshiin13 Aug 24, 2025
15d9c07
New ESX MENU DEFAULT DESIGN
Kr3mu Aug 26, 2025
0b8637b
Added auto scroll and maximum height, logo to right corner of title
Kr3mu Aug 26, 2025
7b36d7a
Adds options to the slider component
Kr3mu Aug 27, 2025
8aca701
Adds usable, unselectable, disableRightArrow
Kr3mu Aug 30, 2025
bbd0a57
fix(es_extended/client/functions): add export default values
Kenshiin13 Aug 31, 2025
f78beaf
fix(es_extended/server/migration): only require restart if actually n…
Kenshiin13 Aug 31, 2025
6d73946
Merge pull request #1711 from esx-framework/migration
Kenshiin13 Aug 31, 2025
8dc6f8d
Fixes the issue with less forgiving Typescript
Kr3mu Aug 31, 2025
63b76ad
fix(esx_identity/server/main): fix error when creating char
Kenshiin13 Aug 31, 2025
5382f50
refactor(esx_identity): fix formatting
Kenshiin13 Aug 31, 2025
12c0c9a
refactor(esx_identity): use static player methods
Kenshiin13 Aug 31, 2025
6ef25f1
Merge branch 'dev' into feature/argument-isValid-on-register-command
Kenshiin13 Aug 31, 2025
52eab10
refactor(es_extended/server/functions): Refactor command argument val…
Kenshiin13 Aug 31, 2025
bc1a7e2
Merge pull request #1715 from esx-framework/feature/argument-isValid-…
Kenshiin13 Aug 31, 2025
7a3a1e1
Merge pull request #1712 from Kr3mu/esx_default_menu
Kenshiin13 Aug 31, 2025
b8d0fa6
Deletes console.log from openMenu
Kr3mu Aug 31, 2025
faf1b40
fix(esx_inventory): fix return arrow
Kenshiin13 Aug 31, 2025
5e5b559
fix(es_extended/locales): add missing locales for inv
Kenshiin13 Aug 31, 2025
7c3b3c8
Merge pull request #1716 from Kr3mu/esx_default_menu
Kenshiin13 Aug 31, 2025
78ed0c6
Merge branch 'dev' of https://github.com/esx-framework/esx_core into dev
Kenshiin13 Aug 31, 2025
d95daf1
chore: bump manifest version to 1.13.4
github-actions[bot] Aug 31, 2025
54f4a2a
Updates the UI of esx_menu_dialog to match esx_menu_default, replace …
Kr3mu Aug 31, 2025
e214dd5
Merge pull request #1717 from Kr3mu/esx_menu_dialog
Kr3mu Aug 31, 2025
d10b85c
feat(es_extended): add comprehensive Vehicle Identification Number (V…
Nonanti Sep 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions VIN_FEATURE_DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
# Vehicle Identification Number (VIN) System

## Overview
This feature adds a comprehensive Vehicle Identification Number (VIN) system to the ESX Framework, providing unique identifiers for all vehicles. The VIN system follows real-world standards while being adapted for FiveM/GTA V use.

## Features

### 1. VIN Generation
- **17-character VIN format** following modified ISO 3779 standard
- **Unique identifiers** for every vehicle
- **Check digit validation** to prevent tampering
- **Model-specific encoding** when vehicle model is provided

### 2. VIN Structure
```
1ES XXXXX X Y ZZZZZZ
│││ │││││ │ │ ││││││
│││ │││││ │ │ └─────── Serial Number (6 chars)
│││ │││││ │ └───────── Plant Code (1 char)
│││ │││││ └─────────── Model Year (1 char)
│││ ││││└───────────── Check Digit (1 char)
│││ └───────────────── Vehicle Descriptor (5 chars)
└───────────────────── World Manufacturer ID (ESX)
```

### 3. Database Changes
- Added `vin` column to `owned_vehicles` table
- Added index for faster VIN lookups
- Optional VIN history tracking table
- Database triggers for audit trail

## API Reference

### Server Functions

#### ESX.GenerateVehicleVIN(modelHash?, owner?)
Generates a unique VIN for a vehicle.
```lua
local vin = ESX.GenerateVehicleVIN(GetHashKey("adder"), "char1:identifier")
print(vin) -- Output: 1ES2X3Y45S1X123456
```

#### ESX.ValidateVehicleVIN(vin)
Validates a VIN's format and check digit.
```lua
local isValid = ESX.ValidateVehicleVIN("1ES2X3Y45S1X123456")
if isValid then
print("VIN is valid")
end
```

#### ESX.DecodeVehicleVIN(vin)
Decodes a VIN to extract information.
```lua
local info = ESX.DecodeVehicleVIN("1ES2X3Y45S1X123456")
print(info.modelYear) -- 2025
print(info.serial) -- 123456
```

#### ESX.GetExtendedVehicleFromVIN(vin)
Gets an extended vehicle object by its VIN.
```lua
local xVehicle = ESX.GetExtendedVehicleFromVIN("1ES2X3Y45S1X123456")
if xVehicle then
print(xVehicle:getPlate())
end
```

### Vehicle Class Methods

#### xVehicle:getVIN()
Gets the VIN of a vehicle.
```lua
local xVehicle = ESX.GetExtendedVehicleFromPlate("ABC 123")
local vin = xVehicle:getVIN()
print(vin) -- Vehicle's VIN
```

## Installation

### 1. Database Migration
Run the SQL migration script to add VIN support:
```sql
mysql -u root -p esx_legacy < [SQL]/add_vin_support.sql
```

### 2. Generate VINs for Existing Vehicles (Optional)
After installation, you can generate VINs for existing vehicles:
```sql
CALL GenerateVINsForExistingVehicles();
```

### 3. Testing
Run the test suite to verify installation:
```
testvin
```

## Usage Examples

### Creating a Vehicle with VIN
```lua
-- When creating a new owned vehicle
local xPlayer = ESX.GetPlayerFromId(source)
local vehicleProps = {model = "adder", plate = "NEW CAR"}

-- Generate VIN before inserting
local vin = ESX.GenerateVehicleVIN(GetHashKey("adder"), xPlayer.identifier)

MySQL.insert("INSERT INTO owned_vehicles (owner, plate, vehicle, vin) VALUES (?, ?, ?, ?)",
{xPlayer.identifier, vehicleProps.plate, json.encode(vehicleProps), vin})
```

### Searching by VIN
```lua
-- Find a vehicle by VIN
local vin = "1ES2X3Y45S1X123456"
local xVehicle = ESX.GetExtendedVehicleFromVIN(vin)

if xVehicle then
print("Found vehicle with plate: " .. xVehicle:getPlate())
print("Owner: " .. xVehicle:getOwner())
end
```

### VIN Validation in Commands
```lua
RegisterCommand("checkvin", function(source, args)
local vin = args[1]

if not vin then
TriggerClientEvent("esx:showNotification", source, "Usage: /checkvin [VIN]")
return
end

if ESX.ValidateVehicleVIN(vin) then
local info = ESX.DecodeVehicleVIN(vin)
TriggerClientEvent("esx:showNotification", source,
("Valid VIN - Year: %d, Serial: %s"):format(info.modelYear, info.serial))
else
TriggerClientEvent("esx:showNotification", source, "Invalid VIN format")
end
end)
```

## Migration Guide

### For Existing Resources
Resources that create vehicles should be updated to include VIN generation:

**Before:**
```lua
MySQL.insert("INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)",
{owner, plate, vehicleData})
```

**After:**
```lua
local vin = ESX.GenerateVehicleVIN(vehicleModel, owner)
MySQL.insert("INSERT INTO owned_vehicles (owner, plate, vehicle, vin) VALUES (?, ?, ?, ?)",
{owner, plate, vehicleData, vin})
```

## Performance Considerations

- VIN generation is optimized with caching
- Database indexes ensure fast lookups
- Check digit validation is lightweight
- Batch operations supported for multiple vehicles

## Security Features

- **Check digit** prevents VIN tampering
- **Unique constraint** prevents duplicates
- **Audit trail** tracks VIN history
- **Validation** ensures data integrity

## Troubleshooting

### Common Issues

1. **Duplicate VIN Error**
- The system will retry generation up to 10 times
- If persistent, check database constraints

2. **Invalid VIN Format**
- Ensure VIN is exactly 17 characters
- Check for invalid characters (I, O, Q are not allowed)

3. **Migration Fails**
- Ensure MySQL user has ALTER TABLE permissions
- Check for existing `vin` column

## Future Enhancements

- [ ] Client-side VIN display UI
- [ ] VIN barcode generation
- [ ] Export/Import VIN registry
- [ ] VIN-based insurance system
- [ ] Vehicle history tracking

## Contributing

Please follow the ESX contribution guidelines when submitting improvements to the VIN system.

## License

This feature is part of the ESX Framework and follows the same license terms.
103 changes: 103 additions & 0 deletions [SQL]/add_vin_support.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
-- Vehicle VIN System Migration
-- This script adds VIN (Vehicle Identification Number) support to ESX Framework
-- Author: ESX Framework Contributors
-- Date: 2025

-- Add VIN column to owned_vehicles table
ALTER TABLE `owned_vehicles`
ADD COLUMN `vin` VARCHAR(17) DEFAULT NULL AFTER `plate`;

-- Add index for VIN column for faster lookups
ALTER TABLE `owned_vehicles`
ADD INDEX `idx_vin` (`vin`);

-- Add unique constraint to ensure VIN uniqueness
-- Note: This is commented out initially to allow NULL values for existing vehicles
-- Uncomment after populating VINs for all vehicles
-- ALTER TABLE `owned_vehicles`
-- ADD UNIQUE KEY `unique_vin` (`vin`);

-- Optional: Create a stored procedure to generate VINs for existing vehicles
-- This can be run manually after deployment
DELIMITER $$

CREATE PROCEDURE IF NOT EXISTS `GenerateVINsForExistingVehicles`()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE v_plate VARCHAR(12);
DECLARE v_owner VARCHAR(60);
DECLARE v_vin VARCHAR(17);
DECLARE cur CURSOR FOR
SELECT plate, owner
FROM owned_vehicles
WHERE vin IS NULL OR vin = '';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cur;

read_loop: LOOP
FETCH cur INTO v_plate, v_owner;
IF done THEN
LEAVE read_loop;
END IF;

-- Note: This generates a simple placeholder VIN
-- The actual VIN generation should be done by the Lua script
-- This is just for demonstration purposes
SET v_vin = CONCAT('1ES', UPPER(LEFT(MD5(CONCAT(v_plate, v_owner, NOW())), 14)));

UPDATE owned_vehicles
SET vin = v_vin
WHERE plate = v_plate AND owner = v_owner;
END LOOP;

CLOSE cur;
END$$

DELIMITER ;

-- Create a table to track VIN history (optional, for audit purposes)
CREATE TABLE IF NOT EXISTS `vehicle_vin_history` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`vin` VARCHAR(17) NOT NULL,
`plate` VARCHAR(12) NOT NULL,
`owner` VARCHAR(60) NOT NULL,
`action` ENUM('created', 'transferred', 'deleted') NOT NULL,
`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`details` JSON DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_vin_history` (`vin`),
INDEX `idx_plate_history` (`plate`),
INDEX `idx_owner_history` (`owner`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Add trigger to log VIN changes (optional)
DELIMITER $$

CREATE TRIGGER IF NOT EXISTS `log_vin_creation`
AFTER INSERT ON `owned_vehicles`
FOR EACH ROW
BEGIN
IF NEW.vin IS NOT NULL THEN
INSERT INTO `vehicle_vin_history` (`vin`, `plate`, `owner`, `action`, `details`)
VALUES (NEW.vin, NEW.plate, NEW.owner, 'created', JSON_OBJECT('type', NEW.type, 'stored', NEW.stored));
END IF;
END$$

CREATE TRIGGER IF NOT EXISTS `log_vin_transfer`
AFTER UPDATE ON `owned_vehicles`
FOR EACH ROW
BEGIN
IF OLD.owner != NEW.owner AND NEW.vin IS NOT NULL THEN
INSERT INTO `vehicle_vin_history` (`vin`, `plate`, `owner`, `action`, `details`)
VALUES (NEW.vin, NEW.plate, NEW.owner, 'transferred', JSON_OBJECT('previous_owner', OLD.owner, 'new_owner', NEW.owner));
END IF;
END$$

DELIMITER ;

-- Migration notes:
-- 1. Run this script to add VIN support to your database
-- 2. Restart your server to load the new VIN module
-- 3. Optionally run CALL GenerateVINsForExistingVehicles(); to generate VINs for existing vehicles
-- 4. After all vehicles have VINs, you can add the unique constraint
2 changes: 1 addition & 1 deletion [core]/cron/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ game 'gta5'
author 'ESX-Framework'
description 'Allows resources to Run tasks at specific intervals.'
lua54 'yes'
version '1.13.3'
version '1.13.4'

server_script 'server/main.lua'
2 changes: 1 addition & 1 deletion [core]/es_extended/client/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ end
---@param position? string The position of the notification
---@return nil
function ESX.ShowNotification(message, notifyType, length, title, position)
return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType, length, message, title, position)
return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType or "info", length or 5000, message, title, position)
end

function ESX.TextUI(...)
Expand Down
7 changes: 5 additions & 2 deletions [core]/es_extended/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fx_version 'cerulean'
game 'gta5'
description 'The Core resource that provides the functionalities for all other resources.'
lua54 'yes'
version '1.13.3'
version '1.13.4'

shared_scripts {
'locale.lua',
Expand All @@ -23,6 +23,7 @@ server_scripts {

'server/common.lua',
'server/modules/callback.lua',
'server/modules/vin.lua',
'server/classes/player.lua',
'server/classes/vehicle.lua',
'server/classes/overrides/*.lua',
Expand All @@ -35,7 +36,9 @@ server_scripts {

'server/bridge/**/*.lua',
'server/modules/npwd.lua',
'server/modules/createJob.lua'
'server/modules/createJob.lua',
'server/migration/**/main.lua',
'server/migration/main.lua',
}

client_scripts {
Expand Down
Loading
Loading