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