--================================================================================================ --== -- XenKnighT -- https://discord.gg/XUck63E == --================================================================================================ local trackCooldown = {} -- Credits to txAdmin for the list. isCarSpawned = false VehClassNamesEnum = { [8] = "bike", [11] = "trailer", [13] = "bike", [14] = "boat", [15] = "heli", [16] = "plane", [21] = "train", } MismatchedTypes = { [`airtug`] = "automobile", -- trailer [`avisa`] = "submarine", -- boat [`blimp`] = "heli", -- plane [`blimp2`] = "heli", -- plane [`blimp3`] = "heli", -- plane [`caddy`] = "automobile", -- trailer [`caddy2`] = "automobile", -- trailer [`caddy3`] = "automobile", -- trailer [`chimera`] = "automobile", -- bike [`docktug`] = "automobile", -- trailer [`forklift`] = "automobile", -- trailer [`kosatka`] = "submarine", -- boat [`mower`] = "automobile", -- trailer [`policeb`] = "bike", -- automobile [`ripley`] = "automobile", -- trailer [`rrocket`] = "automobile", -- bike [`sadler`] = "automobile", -- trailer [`sadler2`] = "automobile", -- trailer [`scrap`] = "automobile", -- trailer [`slamtruck`] = "automobile", -- trailer [`Stryder`] = "automobile", -- bike [`submersible`] = "submarine", -- boat [`submersible2`] = "submarine", -- boat [`thruster`] = "heli", -- automobile [`towtruck`] = "automobile", -- trailer [`towtruck2`] = "automobile", -- trailer [`tractor`] = "automobile", -- trailer [`tractor2`] = "automobile", -- trailer [`tractor3`] = "automobile", -- trailer [`trailersmall2`] = "trailer", -- automobile [`utillitruck`] = "automobile", -- trailer [`utillitruck2`] = "automobile", -- trailer [`utillitruck3`] = "automobile", -- trailer } --- GKSPHONE VALET APP (client) --- -- Made by GKSHOP | https://discord.gg/XUck63E -- Version: 2.1.1 --- @return number|nil function LoadModel(model, timeoutMs) if type(model) == "string" and model ~= "" then model = joaat(model) end model = tonumber(model) if not model or model == 0 then print("^1[GKSPHONE] model is missing, skipping^7") return nil end if not IsModelValid(model) or not IsModelInCdimage(model) then print(("^1[GKSPHONE] model not available, skipping: %s^7"):format(model)) return nil end RequestModel(model) local deadline = GetGameTimer() + (tonumber(timeoutMs) or 10000) while not HasModelLoaded(model) and GetGameTimer() < deadline do Wait(0) end if not HasModelLoaded(model) then print(("^1[GKSPHONE] model did not load in time: %s^7"):format(model)) return nil end return model end --- Same contract for an animation dictionary. --- @return boolean loaded function LoadAnimDict(dict, timeoutMs) if type(dict) ~= "string" or dict == "" then return false end if not DoesAnimDictExist(dict) then print(("^1[GKSPHONE] anim dict does not exist, skipping: %s^7"):format(dict)) return false end RequestAnimDict(dict) local deadline = GetGameTimer() + (tonumber(timeoutMs) or 10000) while not HasAnimDictLoaded(dict) and GetGameTimer() < deadline do Wait(0) end if not HasAnimDictLoaded(dict) then print(("^1[GKSPHONE] anim dict did not load in time: %s^7"):format(dict)) return false end return true end function WaitForNetworkId(netId, timeoutTicks) if netId == nil or type(netId) ~= "number" or netId <= 0 then return nil end timeoutTicks = timeoutTicks or 450 while timeoutTicks > 0 do if NetworkDoesEntityExistWithNetworkId(netId) then return NetworkGetEntityFromNetworkId(netId) end Wait(10) timeoutTicks = timeoutTicks - 1 end return nil end function RequestNetworkControl(entity) local timeout = 500 if NetworkHasControlOfEntity(entity) then return true end while not NetworkHasControlOfEntity(entity) and timeout > 0 do NetworkRequestControlOfEntity(entity) timeout -= 1 Wait(10) end return NetworkHasControlOfEntity(entity) end -- Try Nth-closest vehicle nodes so dirt/small roads are found; filter by height so car spawns on same level (not bridge/upper road) --- @param pos vector3 --- @param clearance number|nil --- @return boolean local function IsNodeClear(pos, clearance) if not clearance or clearance <= 0 then return true end local pool = GetGamePool('CVehicle') for i = 1, #pool do local veh = pool[i] if DoesEntityExist(veh) and #(GetEntityCoords(veh) - pos) < clearance then return false end end return true end local function GetBestVehicleNodeWithHeading(coords, maxDist, maxNth, maxZDiff, minClearance) maxNth = maxNth or 12 maxZDiff = maxZDiff or 18.0 local cx, cy, cz = coords.x, coords.y, coords.z for n = 1, maxNth do local ok, found, roadPos, heading = pcall(function() return GetNthClosestVehicleNodeWithHeading(cx, cy, cz, n, 0, 0, 0) end) if not ok or not found or not roadPos then if n == 1 and not ok then return GetClosestVehicleNodeWithHeading(cx, cy, cz, 0, 0, 0) end else local posVec = type(roadPos) == "vector3" and roadPos or vector3(roadPos.x or 0, roadPos.y or 0, roadPos.z or 0) local zDiff = math.abs(posVec.z - cz) if zDiff > maxZDiff then -- Node on different level (bridge/upper road); try next else local dist = #(vector3(cx, cy, cz) - posVec) if (maxDist == nil or dist <= maxDist) and IsNodeClear(posVec, minClearance) then return true, roadPos, heading end end end end return false, nil, nil end --- @param entity number --- @return boolean local function IsLocalOwner(entity) return NetworkGetEntityOwner(entity) == PlayerId() end AddStateBagChangeHandler("gksphone:valetProps", "", function(bagName, key, value) if not value then return end local entity = 0 local tries = 0 while tries < 250 do entity = GetEntityFromStateBagName(bagName) if entity and entity > 0 then break end Wait(40) tries = tries + 1 end if not entity or entity == 0 or not DoesEntityExist(entity) then return end for _ = 1, 10 do if IsLocalOwner(entity) then ApplyVehicleMods(entity, value, true) SetVehicleOnGroundProperly(entity) Entity(entity).state:set(key, nil, true) return end Wait(400) if not DoesEntityExist(entity) or not Entity(entity).state[key] then return end end end) --- @param vehicle number --- @return boolean local function DeliverWithoutValet(vehicle) if not DoesEntityExist(vehicle) then return false end local found, roadPos, roadHeading = GetBestVehicleNodeWithHeading(GetEntityCoords(PlayerPedId()), Config.ValeMaxOffRoadDistance, nil, nil, Config.ValeSpawnClearance) if not found or not roadPos then return false end if not RequestNetworkControl(vehicle) then return false end local pos = type(roadPos) == "vector3" and roadPos or vector3(roadPos.x, roadPos.y, roadPos.z) SetEntityCoords(vehicle, pos.x, pos.y, pos.z, false, false, false, false) SetEntityHeading(vehicle, roadHeading or 0.0) SetVehicleOnGroundProperly(vehicle) return true end local function BringCar(netId, vehicleData, pos, plate) Debugprint('BringCar Test', {netId, vehicleData, pos}) local player = PlayerPedId() local playerCoords = GetEntityCoords(player) local createVeh local usedClientFallback = false if not Config.ServerSideSpawnVehicle then local model = LoadModel(tonumber(vehicleData.hash)) if not model then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_CARNOTFOUND")) isCarSpawned = false return end createVeh = VehicleCreate(model, pos, vehicleData) else if not vehicleData or vehicleData.vehNetId == nil or vehicleData.vehNetId == 0 then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_CARNOTFOUND")) isCarSpawned = false return end local vehNetId = vehicleData.vehNetId createVeh = WaitForNetworkId(vehNetId, 500) if not createVeh or not DoesEntityExist(createVeh) then TriggerServerEvent("gksphone:server:vale:replicationFailed", plate) Wait(200) local model = LoadModel(tonumber(vehicleData.hash)) createVeh = model and VehicleCreate(model, pos, vehicleData) or nil usedClientFallback = true end end if not createVeh or not DoesEntityExist(createVeh) then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_CARNOTFOUND")) isCarSpawned = false return end if Config.ServerSideSpawnVehicle and not usedClientFallback then GiveKeyCar(createVeh) end GarageVehicleDelivered(createVeh, plate) SetVehicleNeedsToBeHotwired(createVeh, false) SetVehRadioStation(createVeh, "OFF") SetVehicleEngineOn(createVeh, true, true, true) SetEntityAsMissionEntity(createVeh, true, true) local carBlip = AddBlipForEntity(createVeh) SetBlipSprite(carBlip, 225)--Blip Spawning. SetBlipFlashes(carBlip, true) SetBlipColour(carBlip, 0) SetBlipFlashes(carBlip, false) BeginTextCommandSetBlipName("STRING") AddTextComponentString("Valet") EndTextCommandSetBlipName(carBlip) if Config.ValeNPC then local ValePed if not Config.ServerSideSpawnVehicle or usedClientFallback then -- No valet ped is better than none of the car arriving. local valeNPCModel = LoadModel(Config.ValeNPCModel) ValePed = valeNPCModel and CreatePedInsideVehicle(createVeh, 4, valeNPCModel, -1, true, false) or nil if valeNPCModel then SetModelAsNoLongerNeeded(valeNPCModel) end else ValePed = vehicleData.pedNetId and WaitForNetworkId(vehicleData.pedNetId) or nil if not ValePed then TriggerServerEvent("gksphone:server:vale:pedFailed") end end Wait(1000) if ValePed and DoesEntityExist(ValePed) then SetDriverAbility(ValePed, 1.0) SetDriverAggressiveness(ValePed, 0.0) if RequestNetworkControl(ValePed) then TaskVehicleDriveToCoordLongrange(ValePed, createVeh, playerCoords.x, playerCoords.y, playerCoords.z, 15.0, 786603, 5.0) end SetPedKeepTask(ValePed, true) SetEntityAsMissionEntity(ValePed, true, true) SetBlockingOfNonTemporaryEvents(ValePed, true) SetPedCombatAttributes(ValePed, 17, true) SetPedAlertness(ValePed, 0) local lastVehPos = GetEntityCoords(createVeh) local stuckTicks = 0 local tickCount = 0 local deadline = GetGameTimer() + (math.max(tonumber(Config.ValeMaxDeliverySeconds) or 180, 30) * 1000) while true do if GetGameTimer() > deadline then if DoesEntityExist(ValePed) then TaskLeaveVehicle(ValePed, createVeh, 16) DeleteEntity(ValePed) end DeliverWithoutValet(createVeh) RemoveBlip(carBlip) break end local currentPlayerCoords = GetEntityCoords(PlayerPedId()) local pedCoords = GetEntityCoords(ValePed) local distance = #(currentPlayerCoords - pedCoords) tickCount = tickCount + 1 if distance > 400.0 then SetPedCoordsKeepVehicle(ValePed, currentPlayerCoords.x + 5.0, currentPlayerCoords.y + 5.0, currentPlayerCoords.z) stuckTicks = 0 elseif distance > 80.0 then if tickCount % 20 == 0 then local vehPos = GetEntityCoords(createVeh) local moved = #(vehPos - lastVehPos) lastVehPos = vehPos if moved < 2.5 then stuckTicks = stuckTicks + 1 if stuckTicks >= 3 then local found, roadPos, roadHeading = GetBestVehicleNodeWithHeading(currentPlayerCoords, 55.0, 8) if found and roadPos then local rp = type(roadPos) == "vector3" and roadPos or vector3(roadPos.x, roadPos.y, roadPos.z) SetEntityCoords(createVeh, rp.x, rp.y, rp.z, false, false, false, false) SetEntityHeading(createVeh, roadHeading or 0.0) Wait(500) if RequestNetworkControl(ValePed) and RequestNetworkControl(createVeh) then TaskVehicleDriveToCoordLongrange(ValePed, createVeh, currentPlayerCoords.x, currentPlayerCoords.y, currentPlayerCoords.z, 15.0, 786603, 5.0) end else SetPedCoordsKeepVehicle(ValePed, currentPlayerCoords.x + 35.0, currentPlayerCoords.y + 35.0, currentPlayerCoords.z) if RequestNetworkControl(ValePed) then TaskVehicleDriveToCoordLongrange(ValePed, createVeh, currentPlayerCoords.x, currentPlayerCoords.y, currentPlayerCoords.z, 15.0, 786603, 5.0) end end stuckTicks = 0 end else stuckTicks = 0 end end else stuckTicks = 0 end if GetScriptTaskStatus(ValePed, 567490903) == 7 then TaskLeaveVehicle(ValePed, createVeh, 0) Wait(1000) TaskWanderStandard(ValePed, 10.0, 10) Wait(10000) DeleteEntity(ValePed) RemoveBlip(carBlip) break end if GetPedInVehicleSeat(createVeh, -1) == 0 then DeleteEntity(ValePed) RemoveBlip(carBlip) break end Wait(250) end else if not DeliverWithoutValet(createVeh) then Wait(60000) else Wait(5000) end RemoveBlip(carBlip) end else Wait(5000) RemoveBlip(carBlip) end isCarSpawned = false end RegisterNUICallback('gksphone:vale:getVehicles', function(data, cb) Debugprint('gksphone:vale:getVehicles', data) CallBackServerTrigger('gksphone:server:vale:getVehicles', function(vehicles) Debugprint('gksphone:server:vale:getVehicles', vehicles) if vehicles then local pool, outside = GetGamePool('CVehicle'), {} for i = 1, #pool do outside[(GetVehicleNumberPlateText(pool[i]) or ""):gsub("%s", "")] = true end for i = 1, #vehicles do local hash = vehicles[i].hash vehicles[i].speed = math.floor(GetVehicleModelEstimatedMaxSpeed(hash) * 3.6) if outside[(vehicles[i].plate or ""):gsub("%s", "")] then vehicles[i].location = "out" end if vehicles[i].name == nil then local carModel = GetLabelText(GetDisplayNameFromVehicleModel(hash)) if carModel == "NULL" then carModel = string.upper(GetDisplayNameFromVehicleModel(hash)) end vehicles[i].name = carModel vehicles[i].model = string.lower(GetDisplayNameFromVehicleModel(hash)) end end end cb(vehicles) end, data.app) end) RegisterNUICallback('gksphone:vale:track', function(data, cb) local plate = data and data.plate if not plate then cb({ status = false }) return end local now = GetGameTimer() trackCooldown = trackCooldown or {} local lastAt = trackCooldown[plate] or 0 if (now - lastAt) < 1500 then cb({ status = false }) return end trackCooldown[plate] = now Debugprint('Car Point', data) CallBackServerTrigger('gksphone:server:vale:vehichlepoint', function(status, vehicleCoords) Debugprint('Car Point', {status, vehicleCoords}) if status then SetNewWaypoint(vehicleCoords.x, vehicleCoords.y) -- Trigger the notification using the gksphone exports exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_MARKED")) else -- Trigger the notification using the gksphone exports exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_TRACK_CARGARAGE")) end cb({ status = status, coords = json.encode(vehicleCoords)}) end, data.plate) end) RegisterNUICallback('gksphone:vale:getVehicleData', function(data, cb) CallBackServerTrigger('gksphone:server:vale:vehichlepoint', function(status, vehicleCoords, vehicle) Debugprint('Car Point', {status, vehicleCoords, vehicle}) local ent = 0 if status == true and type(vehicle) == "number" and vehicle > 0 and NetworkDoesEntityExistWithNetworkId(vehicle) then ent = NetworkGetEntityFromNetworkId(vehicle) end local vehicleCheck = ent ~= 0 and DoesEntityExist(ent) and IsEntityAVehicle(ent) local carDoorsLocked = 1 local engineStatus = 0 local alldoor = 0 local frontTrunk = 0 local hood = 0 local headLights = 0 if vehicleCheck then carDoorsLocked = GetVehicleDoorLockStatus(ent) engineStatus = GetIsVehicleEngineRunning(ent) for i = 0, 3 do local angle = GetVehicleDoorAngleRatio(ent, i) if angle > 0 then alldoor = 1 break end end frontTrunk = GetVehicleDoorAngleRatio(ent, 5) hood = GetVehicleDoorAngleRatio(ent, 4) local _, lightsOn, highbeamsOn = GetVehicleLightsState(ent) if lightsOn == 1 or highbeamsOn == 1 then headLights = 1 end end local carData = { unlock = carDoorsLocked == 2 and true or false, start = engineStatus == 1 and true or false, alldoor = alldoor > 0 and true or false, frontTrunk = frontTrunk > 0 and true or false, hood = hood > 0 and true or false, headlight = headLights > 0 and true or false, EntityId = vehicleCheck and ent or false } cb({ status = status, coords = json.encode(vehicleCoords), cardata = json.encode(carData)}) end, data.plate) end) local function vehicleActions(data) local info = {status = true} if data.action == 'unlock' then if data.change then SetVehicleDoorsLocked(data.entityId, 2) local lockstate = (GetVehicleDoorLockStatus(data.entityId) % 2) + 1 if lockstate ~= 2 then info.status = true end else SetVehicleDoorsLocked(data.entityId, 1) local lockstate = (GetVehicleDoorLockStatus(data.entityId) % 2) + 1 if lockstate == 2 then info.status = true end end elseif data.action == 'start' then SetVehicleEngineOn(data.entityId, data.change, true, true) local headLights = 0 local _, lightsOn, highbeamsOn = GetVehicleLightsState(data.entityId) if lightsOn == 1 or highbeamsOn == 1 then headLights = 1 end info.status = true info.light = headLights elseif data.action == 'alldoor' then if data.change then SetVehicleDoorOpen(data.entityId, 0, false, false) SetVehicleDoorOpen(data.entityId, 1, false, false) SetVehicleDoorOpen(data.entityId, 2, false, false) SetVehicleDoorOpen(data.entityId, 3, false, false) else SetVehicleDoorShut(data.entityId, 0, false) SetVehicleDoorShut(data.entityId, 1, false) SetVehicleDoorShut(data.entityId, 2, false) SetVehicleDoorShut(data.entityId, 3, false) end info.status = true elseif data.action == 'headlight' then if data.change then SetVehicleLights(data.entityId, 3) else SetVehicleLights(data.entityId, 4) end info.status = true elseif data.action == 'trunk' then if data.change then SetVehicleDoorOpen(data.entityId, 4, false, false) else SetVehicleDoorShut(data.entityId, 4, false) end info.status = true elseif data.action == 'frontTrunk' then if data.change then SetVehicleDoorOpen(data.entityId, 5, false, false) else SetVehicleDoorShut(data.entityId, 5, false) end info.status = true end return info.status end RegisterNetEvent('gksphone:vale:vehicleActions', function(netId, action, change) local data = { entityId = NetToVeh(netId), action = action, change = change } vehicleActions(data) end) RegisterNUICallback('gksphone:vale:action', function(data, cb) local info = {status = false} if data.entityId == nil then local vehiclePool = GetGamePool('CVehicle') for i = 1, #vehiclePool do if GetVehicleNumberPlateText(vehiclePool[i]) == data.plate then data.entityId = vehiclePool[i] end end end if data.entityId then local checkOwner = NetworkGetEntityOwner(data.entityId) if checkOwner == PlayerId() then local vehicleUpdate = vehicleActions(data) info.status = vehicleUpdate else local isOwnerCheck = AwaitCallback('gksphone:server:getOwnerEntity', VehToNet(data.entityId), data.action, data.change) info.status = isOwnerCheck end end cb(info) end) local BringErrorToasts = { nomoney = "GarageApp.APP_GARAGE_ERROR_BRING_NOMONEY", carnotfound = "GarageApp.APP_GARAGE_ERROR_BRING_CARNOTFOUND", carimpounded = "GarageApp.APP_GARAGE_ERROR_BRING_CARIMPOUNDED", carnotingarage = "GarageApp.APP_GARAGE_ERROR_BRING_NOTINGARAGE", carout = "GarageApp.APP_GARAGE_ERROR_BRING_CAROUTSIDE", carblacklist = "GarageApp.APP_GARAGE_ERROR_CARBLACKLIST", busy = "GarageApp.APP_GARAGE_ERROR_BRING_WAIT", invehicle = "GarageApp.APP_GARAGE_ERROR_BRING_INVEHICLE", } RegisterNUICallback('gksphone:vale:bring', function(data, cb) Debugprint('Car Spawn', data.plate, data.model, isCarSpawned) if isCarSpawned then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_WAIT")) cb({ status = false, error = "busy" }) return end if IsPedInAnyVehicle(PlayerPedId(), false) then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_INVEHICLE")) cb({ status = false, error = "invehicle" }) return end isCarSpawned = true local blacklistCheck = false local model = type(data.model) == "string" and joaat(data.model) or data.model local modelType if MismatchedTypes[model] then modelType = MismatchedTypes[model] else local modelClassNumber = GetVehicleClassFromName(model) modelType = VehClassNamesEnum[modelClassNumber] or "automobile" end if Config.ValeBlaclistCars then for k, v in pairs(Config.ValeBlaclistCars) do if v then local blacklistModel = type(v) == "string" and GetHashKey(v) or v if model == blacklistModel then blacklistCheck = true break end end end end if blacklistCheck then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_CARBLACKLIST")) isCarSpawned = false cb({ status = false, error = "carblacklist" }) return end local coords = GetEntityCoords(PlayerPedId()) local foundRoad, nearestRoadPos, _ = GetBestVehicleNodeWithHeading(coords, Config.ValeMaxOffRoadDistance) if not foundRoad or not nearestRoadPos then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_OFFROAD")) isCarSpawned = false cb({ status = false, error = "offroad" }) return end local spawnRadius = ValetSpawnRadius() local spawnCenter = coords if Config.ValeNPC then local offset = math.floor(spawnRadius) spawnCenter = vector3(coords.x + math.random(-offset, offset), coords.y + math.random(-offset, offset), coords.z) end local found, spawnPos, spawnHeading = GetBestVehicleNodeWithHeading(spawnCenter, nil, nil, nil, Config.ValeSpawnClearance) if found and spawnPos then local picked = type(spawnPos) == "vector3" and spawnPos or vector3(spawnPos.x, spawnPos.y, spawnPos.z) if #(picked - coords) > spawnRadius then found, spawnPos, spawnHeading = GetBestVehicleNodeWithHeading(coords, spawnRadius, nil, nil, Config.ValeSpawnClearance) end end if not found or not spawnPos then found, spawnPos, spawnHeading = GetClosestVehicleNodeWithHeading(coords.x, coords.y, coords.z, 0, 0, 0) end if not found or not spawnPos then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_ERROR_BRING_OFFROAD")) isCarSpawned = false cb({ status = false, error = "offroad" }) return end local pos = type(spawnPos) == "vector3" and spawnPos or vector3(spawnPos.x, spawnPos.y, spawnPos.z) local coordinates = {x = pos.x, y = pos.y, z = pos.z, h = spawnHeading or 0} CallBackServerTrigger('gksphone:server:vale:vehiclebring', function(status, vehicleData) Debugprint('Car Spawn2', {status, vehicleData}) if status == "spawned" then exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, "GarageApp.APP_GARAGE_SUCESS_BRING")) cb({ status = true }) BringCar(status, vehicleData, coordinates, data.plate) return end isCarSpawned = false local reason = type(status) == "string" and status or "carnotfound" exports["gksphone"]:ToastNotification(_T(LastItemData?.info?.phoneLang, BringErrorToasts[reason] or "GarageApp.APP_GARAGE_ERROR_BRING_CARNOTFOUND")) cb({ status = false, error = reason }) end, data.plate, coordinates, modelType) end)