local QBCore = exports['qb-core']:GetCoreObject() local activeTrackings = {} local trackingBlips = {} local inTrackingZone = false local currentLocation = nil -- Safety check for Config if not Config then Config = {} Config.TrackingLocations = { { coords = vector3(369.79, -1588.01, 29.43), radius = 2.0, job = {"police"}, label = "Polizei Tracking System" } } Config.EnableCommand = true Config.Command = "tracking" Config.InteractKey = 38 print("^1Warning: Config not loaded properly, using default values^7") end -- Command to open tracking menu (if enabled in config) if Config.EnableCommand then RegisterCommand(Config.Command, function() local PlayerData = QBCore.Functions.GetPlayerData() local job = PlayerData.job.name -- Überprüfe ob Job berechtigt ist local allowedJobs = {'police', 'ambulance', 'mechanic'} -- Füge hier weitere Jobs hinzu local hasPermission = false for _, allowedJob in pairs(allowedJobs) do if job == allowedJob then hasPermission = true break end end if not hasPermission then QBCore.Functions.Notify('Du hast keine Berechtigung für das Tracking-System!', 'error') return end OpenTrackingMenu() end) end -- Rest of your client.lua code... -- Check if player is near a tracking location CreateThread(function() while true do local playerPed = PlayerPedId() local playerCoords = GetEntityCoords(playerPed) local sleep = 1000 local isInZone = false local currentLocationData = nil for _, location in pairs(Config.TrackingLocations) do local distance = #(playerCoords - location.coords) if distance < location.radius then sleep = 0 isInZone = true currentLocationData = location break end end if isInZone and not inTrackingZone then inTrackingZone = true currentLocation = currentLocationData -- Check if player has the required job for this location local PlayerData = QBCore.Functions.GetPlayerData() local hasRequiredJob = false for _, jobName in pairs(currentLocation.job) do if PlayerData.job.name == jobName then hasRequiredJob = true break end end if hasRequiredJob then -- Show DrawText UI exports['qb-core']:DrawText(currentLocation.label, 'left') end elseif not isInZone and inTrackingZone then inTrackingZone = false currentLocation = nil exports['qb-core']:HideText() end Wait(sleep) end end) -- Key press detection for tracking locations CreateThread(function() while true do local sleep = 1000 if inTrackingZone and currentLocation then sleep = 0 -- Check if player has the required job for this location local PlayerData = QBCore.Functions.GetPlayerData() local hasRequiredJob = false for _, jobName in pairs(currentLocation.job) do if PlayerData.job.name == jobName then hasRequiredJob = true break end end if hasRequiredJob and IsControlJustPressed(0, Config.InteractKey) then exports['qb-core']:HideText() OpenTrackingMenu() end end Wait(sleep) end end) function OpenTrackingMenu() local options = { { title = 'Fahrzeug orten', description = 'Fahrzeug über Kennzeichen orten', icon = 'fas fa-search', onSelect = function() TrackVehicle() end }, { title = 'Aktive Trackings', description = 'Zeige alle aktiven Trackings', icon = 'fas fa-list', onSelect = function() ShowActiveTrackings() end }, { title = 'Tracking beenden', description = 'Beende ein aktives Tracking', icon = 'fas fa-times', onSelect = function() StopTracking() end } } lib.registerContext({ id = 'tracking_menu', title = 'Fahrzeug Tracking System', options = options }) lib.showContext('tracking_menu') end function TrackVehicle() local input = lib.inputDialog('Fahrzeug Tracking', { { type = 'input', label = 'Kennzeichen', description = 'Gib das Kennzeichen des Fahrzeugs ein', required = true, max = 8 } }) if not input then return end local plate = string.upper(input[1]) QBCore.Functions.TriggerCallback('tracking:server:trackVehicle', function(success, message, vehicleData) if success then QBCore.Functions.Notify('Fahrzeug wird getrackt!', 'success') StartTracking(plate, vehicleData) else QBCore.Functions.Notify(message, 'error') end end, plate) end function StartTracking(plate, vehicleData) if activeTrackings[plate] then QBCore.Functions.Notify('Fahrzeug wird bereits getrackt!', 'error') return end activeTrackings[plate] = { vehicle = vehicleData.vehicle, coords = vehicleData.coords, lastUpdate = GetGameTimer(), owner = vehicleData.owner or "Unbekannt" } -- Erstelle Blip local blip = AddBlipForCoord(vehicleData.coords.x, vehicleData.coords.y, vehicleData.coords.z) SetBlipSprite(blip, 225) SetBlipDisplay(blip, 4) SetBlipScale(blip, 0.8) SetBlipColour(blip, 1) SetBlipAsShortRange(blip, false) BeginTextCommandSetBlipName("STRING") AddTextComponentString("Tracking: " .. plate) EndTextCommandSetBlipName(blip) trackingBlips[plate] = blip -- Zeige Besitzerinformation an QBCore.Functions.Notify('Fahrzeug gehört: ' .. activeTrackings[plate].owner, 'info', 5000) -- Starte Update Loop CreateThread(function() while activeTrackings[plate] do TriggerServerEvent('tracking:server:updateVehicleLocation', plate) Wait(5000) -- Update alle 5 Sekunden end end) end function ShowActiveTrackings() local options = {} if next(activeTrackings) == nil then options[#options + 1] = { title = 'Keine aktiven Trackings', description = 'Derzeit werden keine Fahrzeuge getrackt', icon = 'fas fa-info-circle' } else for plate, data in pairs(activeTrackings) do local distance = #(GetEntityCoords(PlayerPedId()) - vector3(data.coords.x, data.coords.y, data.coords.z)) options[#options + 1] = { title = 'Kennzeichen: ' .. plate, description = 'Besitzer: ' .. data.owner .. ' | Entfernung: ' .. math.floor(distance) .. 'm | Letztes Update: ' .. math.floor((GetGameTimer() - data.lastUpdate) / 1000) .. 's', icon = 'fas fa-car', onSelect = function() SetNewWaypoint(data.coords.x, data.coords.y) QBCore.Functions.Notify('Wegpunkt zum Fahrzeug gesetzt!', 'success') end } end end lib.registerContext({ id = 'active_trackings', title = 'Aktive Trackings', menu = 'tracking_menu', options = options }) lib.showContext('active_trackings') end function StopTracking() local options = {} if next(activeTrackings) == nil then options[#options + 1] = { title = 'Keine aktiven Trackings', description = 'Derzeit werden keine Fahrzeuge getrackt', icon = 'fas fa-info-circle' } else for plate, data in pairs(activeTrackings) do options[#options + 1] = { title = 'Stoppe: ' .. plate, description = 'Tracking für dieses Fahrzeug beenden', icon = 'fas fa-stop', onSelect = function() StopVehicleTracking(plate) end } end end lib.registerContext({ id = 'stop_tracking', title = 'Tracking beenden', menu = 'tracking_menu', options = options }) lib.showContext('stop_tracking') end function StopVehicleTracking(plate) if activeTrackings[plate] then activeTrackings[plate] = nil if trackingBlips[plate] then RemoveBlip(trackingBlips[plate]) trackingBlips[plate] = nil end TriggerServerEvent('tracking:server:stopTracking', plate) QBCore.Functions.Notify('Tracking für ' .. plate .. ' beendet!', 'success') end end -- Update Tracking Position RegisterNetEvent('tracking:client:updatePosition', function(plate, coords) if activeTrackings[plate] then activeTrackings[plate].coords = coords activeTrackings[plate].lastUpdate = GetGameTimer() if trackingBlips[plate] then SetBlipCoords(trackingBlips[plate], coords.x, coords.y, coords.z) end end end) -- Cleanup beim Disconnect AddEventHandler('onResourceStop', function(resourceName) if GetCurrentResourceName() == resourceName then for plate, blip in pairs(trackingBlips) do RemoveBlip(blip) end -- Hide DrawText if active when resource stops if inTrackingZone then exports['qb-core']:HideText() end end end)