294 lines
9.7 KiB
Lua
294 lines
9.7 KiB
Lua
local PLATE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
local PLATE_LENGTH = 8
|
|
|
|
local function GenerateUniquePlate()
|
|
-- On génère une plaque basée sur le temps actuel pour être sûr qu'elle est unique rapidement
|
|
local plate = string.upper("QS" .. math.random(10, 99) .. os.time() % 10000)
|
|
print("[GARAGES] Plaque generee par securite: " .. plate)
|
|
return plate
|
|
end
|
|
|
|
local function GetVehicleTypeFilter(garageType)
|
|
if garageType == "vehicle" then
|
|
return "AND type IN(\"vehicles\", \"car\", \"pdm\", \"vehicle\", \"automobile\")"
|
|
elseif garageType == "plane" then
|
|
return "AND type IN(\"airplane\", \"air\", \"helicopter\")"
|
|
elseif garageType == "boat" then
|
|
return "AND type IN(\"water\")"
|
|
end
|
|
return ""
|
|
end
|
|
|
|
RegisterNetEvent("advancedgarages:giveVehicle")
|
|
AddEventHandler("advancedgarages:giveVehicle", function(vehicleModel, garageId, targetSource)
|
|
print("[GARAGES] Debug: Evenement giveVehicle RECU avec Succes dans le script !")
|
|
local playerSource = source
|
|
local isConsole = (playerSource == 0)
|
|
|
|
if isConsole then
|
|
-- On saute la vérification de permissions pour la console
|
|
else
|
|
local playerIdentifier = GetPlayerIdentifier(playerSource)
|
|
local jobName = GetJobName(playerSource)
|
|
local isAllowed = IsJobAllowed(jobName, "givecar")
|
|
|
|
if not isAllowed and not PlayerIsAdmin(playerSource) then
|
|
return Notification(playerSource, i18n.t("givecar.no_permission"), "error")
|
|
end
|
|
end
|
|
|
|
if not vehicleModel or vehicleModel == "" then
|
|
return Notification(playerSource, i18n.t("givecar.invalid_model"), "error")
|
|
end
|
|
if not garageId then
|
|
return Notification(playerSource, i18n.t("givecar.invalid_garage"), "error")
|
|
end
|
|
|
|
local garage = Config.Garages[garageId]
|
|
|
|
local targetSource = tonumber(targetSource) or playerSource
|
|
print("[GARAGES] Debug: Recherche de l'identifiant pour l'ID: " .. tostring(targetSource))
|
|
local targetIdent = GetPlayerIdentifier(targetSource)
|
|
print("[GARAGES] Debug: Identifiant trouve = " .. tostring(targetIdent))
|
|
|
|
if not targetIdent then
|
|
print("[GARAGES] Erreur: Cible introuvable !")
|
|
return Notification(playerSource, i18n.t("givecar.target_not_found"), "error")
|
|
end
|
|
|
|
local plate = GenerateUniquePlate()
|
|
local vehicleType = "car"
|
|
|
|
local vehicleData = {
|
|
model = joaat(vehicleModel),
|
|
plate = plate,
|
|
bodyHealth = 1000.0,
|
|
engineHealth = 1000.0,
|
|
fuelLevel = 100.0,
|
|
dirtLevel = 0.0,
|
|
color1 = 0,
|
|
color2 = 0,
|
|
pearlescentColor = 0,
|
|
wheelColor = 0,
|
|
wheels = 0,
|
|
windowTint = -1,
|
|
xenonColor = -1,
|
|
neonEnabled = {false, false, false, false},
|
|
neonColor = {255, 255, 255},
|
|
tyreSmokeColor = {255, 255, 255},
|
|
modTrunk = -1,
|
|
modHood = -1,
|
|
modGrille = -1,
|
|
modFrontBumper = -1,
|
|
modRearBumper = -1,
|
|
modExhaust = -1,
|
|
modFrame = -1,
|
|
modArchWheel = -1,
|
|
modFenders = -1,
|
|
modRightFender = -1,
|
|
modRoof = -1,
|
|
modEngine = -1,
|
|
modBrakes = -1,
|
|
modTransmission = -1,
|
|
modHorns = -1,
|
|
modSuspension = -1,
|
|
modArmor = -1,
|
|
modTurbo = false,
|
|
modXenon = false,
|
|
modFrontWheels = -1,
|
|
modBackWheels = -1,
|
|
modPlateHolder = -1,
|
|
modVanityPlate = -1,
|
|
modTrimA = -1,
|
|
modOrnaments = -1,
|
|
modDashboard = -1,
|
|
modDial = -1,
|
|
modDoorSpeaker = -1,
|
|
modSeats = -1,
|
|
modSteeringWheel = -1,
|
|
modShifterLeaver = -1,
|
|
modAPlate = -1,
|
|
modSpeakers = -1,
|
|
modTrunk = -1,
|
|
modHydrolic = -1,
|
|
modEngineBlock = -1,
|
|
modAirFilter = -1,
|
|
modStruts = -1,
|
|
modArchCover = -1,
|
|
modAerials = -1,
|
|
modTrimB = -1,
|
|
modTank = -1,
|
|
modWindows = -1,
|
|
modLivery = -1,
|
|
}
|
|
|
|
print("[GARAGES] Plaque generee: " .. plate)
|
|
print("[GARAGES] Insertion SQL dans " .. garageTable .. " pour " .. tostring(targetIdent))
|
|
|
|
local query = string.format(
|
|
"INSERT INTO %s (plate, `%s`, type, vehicle, garage, `%s`) VALUES (?, ?, ?, ?, ?, ?)",
|
|
garageTable, garageIdentifierColumn, storedColumn
|
|
)
|
|
|
|
local success = MySQL.Sync.execute(query, { plate, targetIdent, vehicleType, json.encode(vehicleData), garageId, State.stored })
|
|
|
|
if success then
|
|
print("[GARAGES] !!! VICTOIRE !!! Vehicule enregistre avec succes !")
|
|
Notification(playerSource, i18n.t("givecar.given", { plate = plate }), "success")
|
|
Notification(targetSource, i18n.t("givecar.received", { plate = plate }), "success")
|
|
else
|
|
print("[GARAGES] !!! ECHEC !!! L'insertion a échoué. Vérifiez vos colonnes SQL.")
|
|
Notification(playerSource, "Echec SQL: Verifiez votre console !", "error")
|
|
end
|
|
|
|
SendWebhook(
|
|
Webhooks.GiveCar,
|
|
"Give Car",
|
|
Config.WebhookColors.GiveCar,
|
|
"Player: " .. GetPlayerName(playerSource) .. " gave vehicle: " .. vehicleModel .. " to player: " .. GetPlayerName(targetSource) .. " with plate: " .. plate
|
|
)
|
|
end)
|
|
|
|
lib.callback.register("advancedgarages:getJobVehicles", function(sourcePlayer, garageId, jobName)
|
|
if not garageId then return false end
|
|
|
|
local query = string.format(
|
|
"SELECT * FROM %s WHERE garage = ? AND jobVehicle = ?",
|
|
garageTable
|
|
)
|
|
|
|
local results = MySQL.Sync.fetchAll(query, { garageId, jobName })
|
|
|
|
for _, vehicle in pairs(results) do
|
|
if Config.Framework == "qb" then
|
|
vehicle.vehicle = vehicle.mods
|
|
vehicle.owner = vehicle.citizenid
|
|
end
|
|
vehicle.vehicle = json.decode(vehicle.vehicle)
|
|
end
|
|
|
|
return results
|
|
end)
|
|
|
|
-- ============================================================
|
|
-- COMMANDE : /givecar [id] [model] [garageId]
|
|
-- ============================================================
|
|
|
|
RegisterCommand("givecar", function(source, args, rawCommand)
|
|
local playerSource = source
|
|
|
|
-- Sécurité Admin
|
|
if playerSource ~= 0 and not PlayerIsAdmin(playerSource) then
|
|
return Notification(playerSource, "Pas de permission !", "error")
|
|
end
|
|
|
|
local targetId = tonumber(args[1])
|
|
local model = args[2]
|
|
local garageId = args[3]
|
|
|
|
if not targetId or not model then
|
|
return Notification(playerSource, "Usage: /givecar [id] [model]", "error")
|
|
end
|
|
|
|
-- Garage par défaut
|
|
local firstGarage, _ = next(Config.Garages)
|
|
local finalGarageId = garageId or firstGarage or "Hayes Autos"
|
|
|
|
print("[GARAGES] >>> ATTENTION : Vehicule envoye au garage : " .. tostring(finalGarageId))
|
|
|
|
print("[GARAGES] Tentative directe pour ID: " .. tostring(targetId))
|
|
|
|
local xPlayer = GetPlayerFromId(targetId)
|
|
local targetIdent = xPlayer and xPlayer.identifier
|
|
print("[GARAGES] Identifiant EXACT ESX: " .. tostring(targetIdent))
|
|
|
|
if not targetIdent then
|
|
return Notification(playerSource, "Joueur introuvable !", "error")
|
|
end
|
|
|
|
local plate = GenerateUniquePlate()
|
|
|
|
-- Création d'un objet vehicle complet pour que le NUI ne le grise pas
|
|
local vehicleData = {
|
|
model = joaat(model),
|
|
plate = plate,
|
|
bodyHealth = 1000.0,
|
|
engineHealth = 1000.0,
|
|
fuelLevel = 100.0,
|
|
dirtLevel = 0.0,
|
|
color1 = 0,
|
|
color2 = 0,
|
|
pearlescentColor = 0,
|
|
wheelColor = 0,
|
|
wheels = 0,
|
|
windowTint = -1,
|
|
xenonColor = -1,
|
|
neonEnabled = {false, false, false, false},
|
|
neonColor = {255, 255, 255},
|
|
tyreSmokeColor = {255, 255, 255},
|
|
modTrunk = -1,
|
|
modHood = -1,
|
|
modGrille = -1,
|
|
modFrontBumper = -1,
|
|
modRearBumper = -1,
|
|
modExhaust = -1,
|
|
modFrame = -1,
|
|
modArchWheel = -1,
|
|
modFenders = -1,
|
|
modRightFender = -1,
|
|
modRoof = -1,
|
|
modEngine = -1,
|
|
modBrakes = -1,
|
|
modTransmission = -1,
|
|
modHorns = -1,
|
|
modSuspension = -1,
|
|
modArmor = -1,
|
|
modTurbo = false,
|
|
modXenon = false,
|
|
modFrontWheels = -1,
|
|
modBackWheels = -1,
|
|
modPlateHolder = -1,
|
|
modVanityPlate = -1,
|
|
modTrimA = -1,
|
|
modOrnaments = -1,
|
|
modDashboard = -1,
|
|
modDial = -1,
|
|
modDoorSpeaker = -1,
|
|
modSeats = -1,
|
|
modSteeringWheel = -1,
|
|
modShifterLeaver = -1,
|
|
modAPlate = -1,
|
|
modSpeakers = -1,
|
|
modTrunk = -1,
|
|
modHydrolic = -1,
|
|
modEngineBlock = -1,
|
|
modAirFilter = -1,
|
|
modStruts = -1,
|
|
modArchCover = -1,
|
|
modAerials = -1,
|
|
modTrimB = -1,
|
|
modTank = -1,
|
|
modWindows = -1,
|
|
modLivery = -1,
|
|
}
|
|
|
|
print("[GARAGES] Insertion SQL d'un vehicule COMPLET: " .. plate .. " pour " .. targetIdent)
|
|
|
|
local query = string.format(
|
|
"INSERT INTO %s (plate, `%s`, type, vehicle, garage, `%s`) VALUES (?, ?, ?, ?, ?, ?)",
|
|
garageTable, garageIdentifierColumn, storedColumn
|
|
)
|
|
|
|
local success = MySQL.Sync.execute(query, { plate, targetIdent, "vehicle", json.encode(vehicleData), finalGarageId, State.stored })
|
|
|
|
if success then
|
|
print("[GARAGES] !!! VICTOIRE !!! Vehicule pret et fonctionnel !")
|
|
Notification(playerSource, "Véhicule donné avec succès ! Boutons actifs. Plaque: " .. plate, "success")
|
|
Notification(targetId, "Vous avez reçu un véhicule complet ! Plaque: " .. plate, "success")
|
|
else
|
|
print("[GARAGES] !!! ECHEC SQL !!!")
|
|
Notification(playerSource, "Erreur SQL lors de l'insertion !", "error")
|
|
end
|
|
end, false)
|
|
-- Changé en false pour utiliser notre propre système d'admin
|