Repository navigation
Expand file tree
/
Copy pathserver.lua
More file actions
316 lines (279 loc) · 10.9 KB
/
Copy pathserver.lua
File metadata and controls
316 lines (279 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
local QBCore = exports['qb-core']:GetCoreObject({ 'Functions' })
local sharedVehicles = exports['qb-core']:GetShared('Vehicles')
local OutsideVehicles = {}
-- Handler
AddEventHandler('onResourceStart', function(resource)
if resource == GetCurrentResourceName() then
Wait(100)
if Config['AutoRespawn'] then
MySQL.update('UPDATE player_vehicles SET state = 1 WHERE state = 0', {})
else
MySQL.update('UPDATE player_vehicles SET depotprice = 500 WHERE state = 0', {})
end
end
end)
-- Functions
local vehicleClasses = {
compacts = 0,
sedans = 1,
suvs = 2,
coupes = 3,
muscle = 4,
sportsclassics = 5,
sports = 6,
super = 7,
motorcycles = 8,
offroad = 9,
industrial = 10,
utility = 11,
vans = 12,
cycles = 13,
boats = 14,
helicopters = 15,
planes = 16,
service = 17,
emergency = 18,
military = 19,
commercial = 20,
trains = 21,
openwheel = 22,
}
local function arrayToSet(array)
local set = {}
for _, item in ipairs(array) do
set[item] = true
end
return set
end
local function filterVehiclesByCategory(vehicles, category)
local filtered = {}
local categorySet = arrayToSet(category)
for _, vehicle in pairs(vehicles) do
local vehicleData = sharedVehicles[vehicle.vehicle]
local vehicleCategoryString = vehicleData and vehicleData.category or 'compacts'
local vehicleCategoryNumber = vehicleClasses[vehicleCategoryString]
if vehicleCategoryNumber and categorySet[vehicleCategoryNumber] then
filtered[#filtered + 1] = vehicle
end
end
return filtered
end
-- Callbacks
QBCore.Functions.CreateCallback('qb-garages:server:getHouseGarage', function(_, cb, house)
local houseInfo = MySQL.single.await('SELECT * FROM houselocations WHERE name = ?', { house })
cb(houseInfo)
end)
QBCore.Functions.CreateCallback('qb-garages:server:GetGarageVehicles', function(source, cb, garage, type, category)
local Player = exports['qb-core']:GetPlayer(source)
if not Player then return end
local citizenId = Player.PlayerData.citizenid
local vehicles
if type == 'depot' then
vehicles = MySQL.rawExecute.await('SELECT * FROM player_vehicles WHERE citizenid = ? AND depotprice > 0', { citizenId })
elseif Config.SharedGarages then
vehicles = MySQL.rawExecute.await('SELECT * FROM player_vehicles WHERE citizenid = ?', { citizenId })
else
vehicles = MySQL.rawExecute.await('SELECT * FROM player_vehicles WHERE citizenid = ? AND garage = ?', { citizenId, garage })
end
if #vehicles == 0 then
cb(nil)
return
end
if Config.ClassSystem then
local filteredVehicles = filterVehiclesByCategory(vehicles, category)
cb(filteredVehicles)
else
cb(vehicles)
end
end)
-- Backwards Compat
local vehicleTypes = { -- https://docs.fivem.net/natives/?_0xA273060E
motorcycles = 'bike',
boats = 'boat',
helicopters = 'heli',
planes = 'plane',
submarines = 'submarine',
trailer = 'trailer',
train = 'train'
}
local function GetVehicleTypeByModel(model)
local vehicleData = sharedVehicles[model]
if not vehicleData then return 'automobile' end
local category = vehicleData.category
local vehicleType = vehicleTypes[category]
return vehicleType or 'automobile'
end
-- Backwards Compat
-- Spawns a vehicle and returns its network ID and properties.
QBCore.Functions.CreateCallback('qb-garages:server:spawnvehicle', function(source, cb, plate, _, coords)
local Player = exports['qb-core']:GetPlayer(source)
if not Player then
cb(nil, nil, nil)
return
end
local ownedVehicle = MySQL.single.await('SELECT vehicle, mods FROM player_vehicles WHERE plate = ? AND citizenid = ? LIMIT 1', { plate, Player.PlayerData.citizenid })
if not ownedVehicle then
cb(nil, nil, nil)
return
end
local vehType = sharedVehicles[ownedVehicle.vehicle] and sharedVehicles[ownedVehicle.vehicle].type or GetVehicleTypeByModel(ownedVehicle.vehicle)
local hash = type(ownedVehicle.vehicle) == 'number' and ownedVehicle.vehicle or type(ownedVehicle.vehicle) == 'string' and GetHashKey(ownedVehicle.vehicle) or nil
if not hash then
cb(nil, nil, nil)
return
end
local veh = CreateVehicleServerSetter(hash, vehType, coords.x, coords.y, coords.z, coords.w)
local netId = NetworkGetNetworkIdFromEntity(veh)
SetVehicleNumberPlateText(veh, plate)
local vehProps = {}
if ownedVehicle.mods then vehProps = json.decode(ownedVehicle.mods) end
OutsideVehicles[plate] = { netID = netId, entity = veh }
cb(netId, vehProps, plate)
end)
-- Checks if a vehicle can be spawned based on its type and location.
QBCore.Functions.CreateCallback('qb-garages:server:IsSpawnOk', function(_, cb, plate, type)
if OutsideVehicles[plate] and DoesEntityExist(OutsideVehicles[plate].entity) then
cb(false)
return
end
cb(true)
end)
QBCore.Functions.CreateCallback('qb-garages:server:canDeposit', function(source, cb, plate, type, garage, state)
local Player = exports['qb-core']:GetPlayer(source)
local isOwned = MySQL.scalar.await('SELECT citizenid FROM player_vehicles WHERE plate = ? LIMIT 1', { plate })
if isOwned ~= Player.PlayerData.citizenid then
cb(false)
return
end
if type == 'house' and not exports['qb-houses']:hasKey(Player.PlayerData.license, Player.PlayerData.citizenid, Config.Garages[garage].houseName) then
cb(false)
return
end
if state == 1 then
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ? WHERE plate = ?', { state, garage, plate })
cb(true)
else
cb(false)
end
end)
-- Events
RegisterNetEvent('qb-garages:server:updateVehicleStats', function(plate, fuel, engine, body)
local src = source
local Player = exports['qb-core']:GetPlayer(src)
if not Player then return end
MySQL.update('UPDATE player_vehicles SET fuel = ?, engine = ?, body = ? WHERE plate = ? AND citizenid = ?', { fuel, engine, body, plate, Player.PlayerData.citizenid })
end)
RegisterNetEvent('qb-garages:server:updateVehicleState', function(state, plate)
local src = source
local Player = exports['qb-core']:GetPlayer(src)
if not Player then return end
MySQL.update('UPDATE player_vehicles SET state = ?, depotprice = ? WHERE plate = ? AND citizenid = ?', { state, 0, plate, Player.PlayerData.citizenid })
end)
RegisterNetEvent('qb-garages:server:UpdateOutsideVehicle', function(plate, vehicleNetID)
OutsideVehicles[plate] = {
netID = vehicleNetID,
entity = NetworkGetEntityFromNetworkId(vehicleNetID)
}
end)
RegisterNetEvent('qb-garages:server:trackVehicle', function(plate)
local src = source
local vehicleData = OutsideVehicles[plate]
if vehicleData and DoesEntityExist(vehicleData.entity) then
TriggerClientEvent('qb-garages:client:trackVehicle', src, GetEntityCoords(vehicleData.entity))
TriggerClientEvent('QBCore:Notify', src, Lang:t('success.vehicle_tracked'), 'success')
else
TriggerClientEvent('QBCore:Notify', src, Lang:t('error.vehicle_not_tracked'), 'error')
end
end)
RegisterNetEvent('qb-garages:server:PayDepotPrice', function(data)
local src = source
local Player = exports['qb-core']:GetPlayer(src)
local cashBalance = Player.PlayerData.money['cash']
local bankBalance = Player.PlayerData.money['bank']
MySQL.scalar('SELECT depotprice FROM player_vehicles WHERE plate = ?', { data.plate }, function(result)
if result then
local depotPrice = result
if cashBalance >= depotPrice then
Player.RemoveMoney('cash', depotPrice, 'paid-depot')
TriggerClientEvent('qb-garages:client:takeOutGarage', src, data)
elseif bankBalance >= depotPrice then
Player.RemoveMoney('bank', depotPrice, 'paid-depot')
TriggerClientEvent('qb-garages:client:takeOutGarage', src, data)
else
TriggerClientEvent('QBCore:Notify', src, Lang:t('error.not_enough'), 'error')
end
end
end)
end)
-- House Garages
RegisterNetEvent('qb-garages:server:syncGarage', function(updatedGarages)
Config.Garages = updatedGarages
end)
--Call from qb-phone
QBCore.Functions.CreateCallback('qb-garages:server:GetPlayerVehicles', function(source, cb)
local Player = exports['qb-core']:GetPlayer(source)
local Vehicles = {}
MySQL.rawExecute('SELECT * FROM player_vehicles WHERE citizenid = ?', { Player.PlayerData.citizenid }, function(result)
if result[1] then
for _, v in pairs(result) do
local VehicleData = sharedVehicles[v.vehicle]
local VehicleGarage = Lang:t('error.no_garage')
if v.garage ~= nil then
if Config.Garages[v.garage] ~= nil then
VehicleGarage = Config.Garages[v.garage].label
else
VehicleGarage = Lang:t('info.house')
end
end
local stateTranslation
if v.state == 0 then
stateTranslation = Lang:t('status.out')
elseif v.state == 1 then
stateTranslation = Lang:t('status.garaged')
elseif v.state == 2 then
stateTranslation = Lang:t('status.impound')
end
local fullname
if VehicleData and VehicleData['brand'] then
fullname = VehicleData['brand'] .. ' ' .. VehicleData['name']
else
fullname = VehicleData and VehicleData['name'] or 'Unknown Vehicle'
end
Vehicles[#Vehicles + 1] = {
fullname = fullname,
brand = VehicleData and VehicleData['brand'] or '',
model = VehicleData and VehicleData['name'] or '',
plate = v.plate,
garage = VehicleGarage,
state = stateTranslation,
fuel = v.fuel,
engine = v.engine,
body = v.body
}
end
cb(Vehicles)
else
cb(nil)
end
end)
end)
local function getAllGarages()
local garages = {}
for k, v in pairs(Config.Garages) do
garages[#garages + 1] = {
name = k,
label = v.label,
type = v.type,
takeVehicle = v.takeVehicle,
putVehicle = v.putVehicle,
spawnPoint = v.spawnPoint,
showBlip = v.showBlip,
blipName = v.blipName,
blipNumber = v.blipNumber,
blipColor = v.blipColor,
vehicle = v.vehicle
}
end
return garages
end
exports('getAllGarages', getAllGarages)