# Installation

## 🛠️ Step 1: Put in your resouces file

***

1. Download resouces `kc_garagev2`
2. Extract file and put `kc_garagev2` in your resource files

## 🛠️ Step 2: Insert SQL Query&#x20;

***

Enter the database query below into your database server.

### Premium Garage SQL

```sql
/* [[[ PREMIUM GARAGE ]]] */
CREATE TABLE IF NOT EXISTS `premium_garage` (
  `identifier` varchar(60) NOT NULL,
  `class` varchar(60) NOT NULL,
  `date_regist` timestamp NULL DEFAULT NULL,
  `expired` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

### Vehicle SQL

<details>

<summary>ESX</summary>

* If you don't have an `owned_vehicles` database you can add the query below to your database. If you already have one you can skip this step.<br>

  ```sql
  /* [[[ CREATE NEW DATABASE ]]] */
  /* [[[ this is the database of ESX ]]] */
  CREATE TABLE IF NOT EXISTS `owned_vehicles` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `owner` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
    `plate` varchar(12) COLLATE utf8mb4_unicode_ci NOT NULL,
    `vin` CHAR(17) NULL DEFAULT NULL,
    `type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'car',
    `job` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `model` VARCHAR(20) NULL DEFAULT NULL,
    `class` TINYINT NULL DEFAULT NULL,
    `stored` tinyint(1) NOT NULL DEFAULT 0,
    `vehicle` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
    `metadata` LONGTEXT NULL DEFAULT NULL,

    PRIMARY KEY (`id`),
    UNIQUE INDEX `plate` (`plate`),
    UNIQUE INDEX `vin` (`vin`),
    INDEX `FK_owned_vehicles_users` (`owner`),
    CONSTRAINT `FK_owned_vehicles_users` FOREIGN KEY (`owner`) REFERENCES `users` (`identifier`) ON UPDATE CASCADE ON DELETE CASCADE
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  ```

* These are the additional columns required for this script<br>

  ```sql
  /* [[[ ADD A DATABASE COLUMN ]]] */
  /* [[[ these are the additional columns required for this script ]]] */
  ALTER TABLE `owned_vehicles` ADD COLUMN `parking` varchar(60) DEFAULT NULL;
  ALTER TABLE `owned_vehicles` ADD COLUMN `odo` varchar(255) NOT NULL DEFAULT '0';
  ALTER TABLE `owned_vehicles` ADD COLUMN `deformation` LONGTEXT NULL;
  ALTER TABLE `owned_vehicles` ADD COLUMN `peopleWithKeys` LONGTEXT NULL;
  ALTER TABLE `owned_vehicles` ADD COLUMN `shared` tinyint(1) NOT NULL DEFAULT 0;
  ALTER TABLE `owned_vehicles` ADD COLUMN `favorit` tinyint(1) NOT NULL DEFAULT 0;
  ALTER TABLE `owned_vehicles` ADD COLUMN `date_in` timestamp NULL DEFAULT NULL;
  ALTER TABLE `owned_vehicles` ADD COLUMN `date_out` timestamp NULL DEFAULT NULL;
  ```

* if you are using `ox_inventory` this field is required<br>

  ```sql
  /* [[[ OPTIONAL DATABASE COLUMNS ]]] */
  /* [[[ if you are using ox_inventory this field is required ]]] */
  ALTER TABLE `owned_vehicles` ADD COLUMN `glovebox` LONGTEXT NULL;
  ALTER TABLE `owned_vehicles` ADD COLUMN `trunk` LONGTEXT NULL;
  ```

</details>

<details>

<summary>QB</summary>

* If you don't have a `player_vehicles` database you can add the query below to your database. If you already have one you can skip this step.<br>

  ```sql
  /* [[[ CREATE NEW DATABASE ]]] */
  /* [[[ this is the database of QB ]]] */
  CREATE TABLE IF NOT EXISTS `player_vehicles` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `license` varchar(50) DEFAULT NULL,
    `citizenid` varchar(50) DEFAULT NULL,
    `vehicle` varchar(50) DEFAULT NULL,
    `hash` varchar(50) DEFAULT NULL,
    `mods` longtext DEFAULT NULL,
    `plate` varchar(50) NOT NULL,
    `fakeplate` varchar(50) DEFAULT NULL,
    `garage` varchar(50) DEFAULT NULL,
    `fuel` int(11) DEFAULT 100,
    `engine` float DEFAULT 1000,
    `body` float DEFAULT 1000,
    `state` int(11) DEFAULT 1,
    `depotprice` int(11) NOT NULL DEFAULT 0,
    `drivingdistance` int(50) DEFAULT NULL,
    `status` text DEFAULT NULL,
    `balance` int(11) NOT NULL DEFAULT 0,
    `paymentamount` int(11) NOT NULL DEFAULT 0,
    `paymentsleft` int(11) NOT NULL DEFAULT 0,
    `financetime` int(11) NOT NULL DEFAULT 0,
    PRIMARY KEY (`id`),
    KEY `plate` (`plate`),
    KEY `citizenid` (`citizenid`),
    KEY `license` (`license`)
  ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  ```

* these are the additional columns required for this script<br>

  ```sql
  /* [[[ ADD A DATABASE COLUMN ]]] */
  /* [[[ these are the additional columns required for this script ]]] */
  ALTER TABLE `player_vehicles` ADD COLUMN `type` varchar(20) NOT NULL DEFAULT 'car';
  ALTER TABLE `player_vehicles` ADD COLUMN `odo` varchar(255) NOT NULL DEFAULT '0';
  ALTER TABLE `player_vehicles` ADD COLUMN `deformation` LONGTEXT NULL;
  ALTER TABLE `player_vehicles` ADD COLUMN `peopleWithKeys` LONGTEXT NULL;
  ALTER TABLE `player_vehicles` ADD COLUMN `shared` tinyint(1) NOT NULL DEFAULT 0;
  ALTER TABLE `player_vehicles` ADD COLUMN `favorit` tinyint(1) NOT NULL DEFAULT 0;
  ALTER TABLE `player_vehicles` ADD COLUMN `date_in` timestamp NULL DEFAULT NULL;
  ALTER TABLE `player_vehicles` ADD COLUMN `date_out` timestamp NULL DEFAULT NULL;
  ```

* if you are using `ox_inventory` this field is required<br>

  ```sql
  /* [[[ OPTIONAL DATABASE COLUMNS ]]] */
  /* [[[ if you are using ox_inventory this field is required ]]] */
  ALTER TABLE `owned_vehicles` ADD COLUMN `glovebox` LONGTEXT NULL;
  ALTER TABLE `owned_vehicles` ADD COLUMN `trunk` LONGTEXT NULL;
  ```

</details>

## 🛠️ Step 3: Configuration

***

You can edit the configuration in `shared/config.lua`

<details>

<summary>Default Config</summary>

This is the config that you get the first time. Please customize this config to your server.

```lua
Config = Config or {}

-- [[ FRAMEWORK ]] --
Config.Framework              = 'esx' -- Framework 
Config.FrameworkFolder        = 'es_extended' -- Framework folder
Config.NewESX                 = true -- if you not use new esx set false
Config.NewQb                  = true -- if you not use new qb set false
Config.DatabaseName           = 'owned_vehicles'

-- [[ INTEGRATION ]] --
Config.Notify                 = 'custom' -- 'esx', 'qb', 'lib', 'custom' you can custom notify in mainAPI.lua line 12
Config.TextUI                 = 'lib' -- use 'esx', 'lib', 'qb' or 'custom' you can custom textUI in mainAPI.lua line 70 and line 82
Config.RadialMenu             = 'lib' -- you can use 'qb', 'lib' or 'custom' radial menu. if you don't want to use the radial menu you can replace it with false
Config.Target			            = 'ox_target' -- value qb-target, ox_target, or false
Config.Mysql                  = 'mysql-async' -- mysql-async ,ghmattisql, oxmysql

-- [[ SYSTEM ]] --
Config.Locale                 = 'en' -- locale
Config.CheckForUpdates        = true -- check if a new update
Config.Debug                  = false -- print debug
Config.AccountType            = 'money' -- account type for default qb = 'cash'
Config.FeeSwapGarage          = 20000 -- The initial cost of moving a garage will be multiplied by the distance of the new garage
Config.UseAnim                = true -- use animation if open garages menu
Config.UseKMH                 = true -- set false if you not use KMH
Config.AutoTpToVeh            = false -- auto teleport player to vehicles if player spawn vehicle 
Config.AutoLockVeh            = false -- auto lock vehilce if vehilce has spawn
Config.AutoDelVeh             = true -- auto delete vehicle 
Config.DelVehTimer            = 5 -- auto delete vehicle timer to send notif
Config.DelVehInSafeZone       = true -- include auto delete vehicle in safe zone
Config.CmdDelAllVeh           = 'impound' -- command for delete vehicles in word
Config.ToggleParking          = true -- if you cannot use ox_target and radial menu we recomment set it true
Config.ToggleParkingKey       = 'E' -- if you canot use ox_target
Config.UseVehicleKeys         = true -- if you're using qb-vehiclekeys or similar, I recommend turning it off
Config.CmdLockVeh             = 'keys' -- command for lock vehicles
Config.ToggleLockVeh          = 'U' -- keybind for lock or unlock vehicles
Config.CmdGiveKey             = 'givekeys' -- command for give keys
Config.PremiumGarage          = true -- subcribe fiture
Config.CmdOpenPremiumMenu     = 'premiumgarage' -- for open premium menu if not use ox_target

Config.GroupAdminList= { -- Admin list for to use Config.CmdVehDelete
  'group.god',
  'group.dev',
  'group.moderator',
  'group.headadmin',
  'group.superadmin',
  'group.admin',
}

Config.DeleteVehiclesAt = { -- Automatic clock setting to delete or impound vehicles if there is no player inside. format 24h [[[ { ['h'] = hh, ['m'] = mm } ]]]
	{ ['h'] = 00, ['m'] = 00 },
	{ ['h'] = 03, ['m'] = 00 },
	{ ['h'] = 09, ['m'] = 00 },
	{ ['h'] = 15, ['m'] = 00 },
}

Config.SafeZones = { -- If the vehicle is within the safe zone, it will not be deleted.
	{ ['coords'] = vector3(-317.4510, -889.2014, 31.0735),  ['radius'] = 50.0},
	{ ['coords'] = vector3(-1846.3047, -1227.2388, 13.0172), ['radius'] = 50.0},
}

Config.DefaultImpound   = { -- default vehicles storage if vehicle out garages
  ['car'] = 'SandyShores',
  ['aircraft'] = 'SandyShoresAir'
}

Config.DefaultJobImpound   = { -- storage of the default vehicle if the vehicle is confiscated by officers 
  ['car'] = 'Samsat',
  ['aircraft'] = 'SandyShoresAir'
}

Config.Peds = { -- Peds List
  garage = 'CSB_TrafficWarden',  -- Garages
  impound = 's_m_y_construct_01', -- Impounds
  policeImpound = 'IG_ProlSec_02' -- PoliceImpounds
}

Config.Premium = {
  ['basic'] = {
    label           = 'MURAH', -- premium label
    icon            = 'bolt',
    price           = 175000, -- weekly subscription price
    parking         = 'free', -- value string for free or number for discount
    impound         = 50, -- value string for free or number for discount
    moveGarage      = 20, -- value string for free or number for discount
    vehParked       = 5, -- increase in the number of vehicles that can be parked value > 99 = unlimited
  },

  ['pro'] = {
    label           = 'SEDANG', -- premium label
    icon            = 'dragon',
    price           = 250000, -- weekly subscription price
    parking         = 'free', -- value string for free or number for discount
    impound         = 70, -- value string for free or number for discount
    moveGarage      = 50, -- value string for free or number for discount
    vehParked       = 15, -- increase in the number of vehicles that can be parked value > 99 = unlimited
  },

  ['vip'] = {
    label           = 'MAHAL ANJG', -- premium label
    icon            = 'star',
    price           = 450000, -- weekly subscription price
    parking         = 'free', -- value string for free or number for discount
    impound         = 'free', -- value string for free or number for discount
    moveGarage      = 'free', -- value string for free or number for discount
    vehParked       = 35, -- increase in the number of vehicles that can be parked value > 99 = unlimited
  },
}

Config.VehicleFee = { -- fees for removing vehicles in garages or impounds, if set to 0 the player does not pay
  garage = { -- Garage Fee
    [0] = 2000, -- Compacts
    [1] = 2000, -- Sedans
    [2] = 2000, -- SUVs
    [3] = 2000, -- Coupes
    [4] = 2000, -- Muscle
    [5] = 2000, -- Sports Classics
    [6] = 2000, -- Sports
    [7] = 2000, -- Super
    [8] = 2000, -- Motorcycles
    [9] = 2000, -- Off-road
    [10] = 2000, -- Industrial
    [11] = 2000, -- Utility
    [12] = 2000, -- Vans
    [13] = 2000, -- Cylces
    [14] = 2000, -- Boats
    [15] = 2000, -- Helicopters
    [16] = 2000, -- Planes
    [17] = 2000, -- Service
    [18] = 2000, -- Emergency
    [19] = 2000, -- Military
    [20] = 2000, -- Commercial
    [21] = 2000 -- Train 
  },

  impound = { -- Impound Fee
    [0] = 15000, -- Compacts
    [1] = 15000, -- Sedans
    [2] = 15000, -- SUVs
    [3] = 15000, -- Coupes
    [4] = 15000, -- Muscle
    [5] = 15000, -- Sports Classics
    [6] = 15000, -- Sports
    [7] = 15000, -- Super
    [8] = 10000, -- Motorcycles
    [9] = 15000, -- Off-road
    [10] = 15000, -- Industrial
    [11] = 15000, -- Utility
    [12] = 15000, -- Vans
    [13] = 0, -- Cylces
    [14] = 50000, -- Boats
    [15] = 50000, -- Helicopters
    [16] = 50000, -- Planes
    [17] = 15000, -- Service
    [18] = 0, -- Emergency
    [19] = 15000, -- Military
    [20] = 15000, -- Commercial
    [21] = 0 -- Train 
  }
}

Config.Blips = {
  ['Garages'] = { -- blips for garage
    car = {
      Sprite = 357,
      Colour = 3,
      Display = 2,
      Scale = 0.8
    },
    aircraft = {
      Sprite = 359,
      Colour = 3,
      Display = 2,
      Scale = 0.8
    },
    boat = {
      Sprite = 356,
      Colour = 3,
      Display = 2,
      Scale =  0.8
    }
  },

  ['Impounds'] = { -- blips for impound
    car = {
      Sprite = 477,
      Colour = 51,
      Display = 2,
      Scale = 0.7
    },
    aircraft = {
      Sprite = 359,
      Colour = 51,
      Display = 2,
      Scale = 0.8
    },
    boat = {
      Sprite = 356,
      Colour = 51,
      Display = 2,
      Scale =  0.8
    }
  }
}

-- [[ FRAMEWORK LOAD ]] --
Core = nil

pcall(function()
	while Core == nil do
    if GetResourceState(Config.FrameworkFolder) == 'missing' then
      print('[^3kc_garage^7] ^1Couldn\'t get resouce folder in [ '..Config.FrameworkFolder..' ].^0')
      break
    end
    
    if Config.Framework == 'esx' then
      if Config.NewESX then
        Core = exports[Config.FrameworkFolder]:getSharedObject()
      else
        TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
      end
    elseif Config.Framework == 'qb' then
      if Config.NewQb then
        Core = exports[Config.FrameworkFolder]:GetCoreObject()
      else
        TriggerEvent('QBCore:GetObject', function(obj) Core = obj end)
      end
    end
    Citizen.Wait(10)
	end 
end)
```

</details>

## 🛠️ Step 4: Setup Garages

***

You can make a garage according to the place you want. Or you can use the base of this script.

### Public Garages

Place the garage according to your wishes by following the format below.

```lua
['Legion'] = { -- Garage key name
    Label = 'Legion', -- Garage label name
    Type = 'car', -- Vehicle type
    MaxVehicle = 5, -- Max vehicle parking in this garage
    Blip = true, -- Show or hide blips
    Players = false, -- Only selected players can access || param: boolean or table
    Jobs = false, -- Only selected jobs can access || param: boolean or table
    Coords = vector4(-282.7397, -888.6456, 31.0806, 73.9637), -- Garage coords
    SpawnPoint = {-- Spawn vehicle points
      vector4(-285.6491, -888.0939, 31.0806, 166.4453), -- Spawn point 1 || param: vector4
      vector4(-289.2811, -887.3295, 31.0806, 169.8648), -- Spawn point 2 || param: vector4
      vector4(-292.9691, -886.3055, 31.0806, 168.2578), -- Spawn point 3 || param: vector4
      vector4(-296.4071, -885.5869, 31.0806, 167.0156), -- Spawn point 4 || param: vector4
      vector4(-300.0922, -884.8438, 31.0806, 167.7881), -- Spawn point 5 || param: vector4
      vector4(-303.7151, -883.9635, 31.0806, 165.1761), -- Spawn point 6 || param: vector4
    },
    DeletePoint = { -- Delete vehicle if inside zone
      Pos = vector3(-293.78, -886.32, 30.18),  -- Coords delete point zone
      Size = vector3(20, 6, 5), -- Size box zone
      Rotation = 348 -- Rotation zone
    }
  },
```

### Private Garages

You can use a private garage for players who own a house or other.

```lua
  ['HachiGarage'] = {
    Label = 'Hachi Garage',
    Type = 'car',
    Blip = false,
    Players = {
      'steam:xxxxxxxxxxxx',
    },
    Jobs = false,
    Coords = vector4(-100.3831, 819.2451, 235.7249, 7.1012),
    SpawnPoint = {
      vector4(-104.9789, 824.1717, 235.7252, 9.1065),
    },
    DeletePoint = {
      Pos = vector3(-104.98, 824.17, 235.73),
      Size = vector3(10, 10, 5),
      Rotation = 15
    }
  },
```

### Jobs Garages

Job Garages you can use for players who are on duty.

```lua
  ['PoliceOffice'] = {
    Label = 'Police Office',
    Type = 'aircraft',
    Blip = false,
    Players = false,
    Jobs = {
      'police',
    },
    Coords = vector4(-675.1924, 327.1154, 140.1467, 88.0828),
    SpawnPoint = {
      vector4(-686.8148, 326.8840, 140.1467, 179.3648),
    },
    DeletePoint = {
      Pos = vector3(-687.07, 323.44, 140.15),
      Size = vector3(15, 15, 5),
      Rotation = 0
    }
  },
```

### Parameter

* Label: `string`
  * &#x20;Garage Label.
* Type: `string`&#x20;
  * Vehicle type.
* MaxVehicle: `number`&#x20;
  * Max vehicle parking in this garage,
* Blips: `boolean`&#x20;
  * Show or hide blip garage.
* Players: `boolean` or `table`&#x20;
  * Boolean: you can set `false` if this garage not private.
  * Table: you can enter `identifier` or `citizenid` players.
* Jobs: `boolean` or `table`&#x20;
  * Boolean: you can set `false` if this garage not for jobs.
  * Table: you can enter `jobName` if this garage for jobs.
* Coords: `vector4`
  * &#x20;Coords for garage blips and spawn peds.
* SpawnPoint: `table`&#x20;
  * Spawn vehicles place. Use vector4.
* DeletePoint: `table`&#x20;
  * Pos: `vector3`&#x20;
    * &#x20;Coords for delete point.
  * Size: `vector3`&#x20;
    * Size for delete point.
  * Rotation: `number`&#x20;
    * Rotation for delete point

{% hint style="info" %}
To create `DeletePoint` you need to use `PolyZone` to make it easier.
{% endhint %}

{% hint style="info" %}
If you already have a garage script. customize the `garageName` with the existing one.
{% endhint %}

## 🛠️ Step 5: Setup Impounds

***

### Public Impound

Public Impound, this is usually used when the player loses their vehicle. They can take out their vehicle here.

```lua
['SandyShores'] = { -- Impound key name
  Label = 'Impound', -- Impound label name
  Type = 'car', -- Vehicle type
  Blip = true, -- Show or hide blips
  Jobs = false, -- Only selected jobs can access || param: boolean or table
  Coords = vector4(252.6120, 2595.9448, 44.8955, 15.9485), -- Impound coords
  SpawnPoint = { -- Spawn vehicle points
    vector4(258.2920, 2592.3401, 44.6332, 9.6964) -- Spawn point 1 || param: vector4
  }
},

['SandyShoresAir'] = {
  Label = 'Aircraft Impound',
  Type = 'aircraft',
  Blip = true,
  Jobs = false,
  Coords = vector4(1743.8893, 3296.8372, 41.1287, 193.3046),
  SpawnPoint = {
    vector4(1739.1770, 3281.5996, 41.0936, 11.3545)
  }
},
```

### Jobs Impound

Impound jobs are used to retrieve vehicles impounded by impound jobs.

```lua
['PoliceImpound'] = {
	Label = 'Police Impound',
	Type = 'car',
	Blip = true,
	Jobs = {'police'},
	Coords = vector4(409.1168, -1623.0258, 29.2919, 230.4279),
	SpawnPoint = {
		vector4(416.9999, -1627.8965, 29.0, 137.3000),
		vector4(419.6365, -1629.6110, 29.0, 135.3693),
	}
},
```

### Parameter

* Label: `string`
  * &#x20;Garage Label.
* Type: `string`&#x20;
  * Vehicle type.
* Blips: `boolean`&#x20;
  * Show or hide blip garage.
* Jobs: `boolean` or `table`&#x20;
  * Boolean: you can set `false` if this garage not for jobs.
  * Table: you can enter `jobName` if this garage for jobs.
* Coords: `vector4`
  * &#x20;Coords for garage blips and spawn peds.
* SpawnPoint: `table`&#x20;
  * Spawn vehicles place. Use vector4.

## 🛠️ Step 6: Start the resouce

***

If everything is set up according to your server. You can start this `kc_garagev2`

* Go to `server.cfg` and replace `ensure kc_garagev2`
* Restart your server


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kucluck.gitbook.io/docs/garage/kc-garage-v2/installation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
