diff --git a/client.lua b/client.lua index 15a7369..5eb8e94 100644 --- a/client.lua +++ b/client.lua @@ -12,9 +12,15 @@ local inJobStation = {} local hasHouseKey = false local HouseKeys = {} local Blips = {} - +local PlayerIdentifier = nil +local OutsideVehiclesData = {} +local GlobalVehicles = {} +local SpawnedVehicles = false +local DeletingEntities = false +local UpdateVeh = false -- Functions + local function GetVehicleModifications(vehicle) --Get all vehicle information if DoesEntityExist(vehicle) then local colorPrimary, colorSecondary = GetVehicleColours(vehicle) @@ -824,6 +830,29 @@ function GetAllVehicles() -- Returns all loaded vehicles on client side return QBCore.Functions.GetVehicles() end +function updateOusiteVehicle() + QBCore.Functions.TriggerCallback('MojiaGarages:server:getOusiteVehicle', function(result) + if result then + for k, v in pairs(result) do + local vehspawned = true + if not isVehicleExistInRealLife(v.plate) then + vehspawned = false + else + vehspawned = true + end + OutsideVehiclesData[v.plate] = { + model = v.vehicle, + vehicle = nil, + position = vector3(v.posX, v.posY, v.posZ), + rotation = vector3(v.rotX, v.rotY, v.rotZ), + mods = json.decode(v.mods), + spawned = vehspawned + } + end + end + end) +end + -- Events RegisterNetEvent('MojiaGarages:client:spawnOutsiteVehicle', function(properties) if properties then @@ -877,8 +906,11 @@ RegisterNetEvent('MojiaGarages:client:setVehicleMods', function(netId, plate, mo TriggerServerEvent('MojiaGarages:server:setVehicleModsFailed', plate) end end) +RegisterNetEvent('MojiaVehicles:client:UpdateVehicleData', function(data, plate) + OutsideVehiclesData[plate] = data +end) -RegisterNetEvent('MojiaGarages:client:updateVehicle', function(netId) +RegisterNetEvent('MojiaGarages:client:updateVehicle', function(netId) local vehicle = NetworkGetEntityFromNetworkId(netId) if (vehicle == nil) then return @@ -902,12 +934,18 @@ RegisterNetEvent('MojiaGarages:client:updateVehicle', function(netId) or math.abs(modifications.engineHealth - oldmodifications.engineHealth) > 5.0 or math.abs(modifications.tankHealth - oldmodifications.tankHealth) > 5.0 ) then + UpdateVeh = true local networkId = NetworkGetNetworkIdFromEntity(vehicle) TriggerServerEvent('MojiaGarages:server:updateVehicle', networkId, plate, modifications) + Wait(100) + UpdateVeh = false end else + UpdateVeh = true local networkId = NetworkGetNetworkIdFromEntity(vehicle) TriggerServerEvent('MojiaGarages:server:updateVehicle', networkId, plate, modifications) + Wait(100) + UpdateVeh = false end end end @@ -1471,11 +1509,16 @@ end) CreateThread(function() --Save vehicle data on real times while (true) do + local veh = nil local ped = PlayerPedId() local pos = GetEntityCoords(ped) - local veh = QBCore.Functions.GetClosestVehicle(pos) + local vehout, distance = QBCore.Functions.GetClosestVehicle(pos) if IsPedInAnyVehicle(ped) then veh = GetVehiclePedIsIn(ped) + else + if NetworkGetEntityIsLocal(vehout) and distance < 2 then + veh = vehout + end end local vehpos = GetEntityCoords(veh) local class = GetVehicleClass(veh) @@ -1540,6 +1583,125 @@ CreateThread(function() -- Check if the player is in the garage area or not end end) + + + + + +local function GetNearOusiteVehicle() + local near = nil + local distance = 10000 + PlayerData = QBCore.Functions.GetPlayerData() + for k, v in pairs(OutsideVehiclesData) do + local ped = PlayerPedId() + local pos = GetEntityCoords(ped) + local cur_distance = #(pos - vector3(v.posX, v.posY, v.posZ)) + if cur_distance < distance then + distance = cur_distance + near = k + end + end + return near +end + +function RemoveVehicles(vehdata) + DeletingEntities = true + local tmpLoc = vehdata.position + local veh, distance = QBCore.Functions.GetClosestVehicle(tmpLoc) + if NetworkGetEntityIsLocal(veh) and distance < 1 then + local driver = GetPedInVehicleSeat(veh, -1) + if not DoesEntityExist(driver) or not IsPedAPlayer(driver) then + local tmpModel = GetEntityModel(veh) + SetModelAsNoLongerNeeded(tmpModel) + DeleteEntity(veh) + Wait(300) + end + end + -- Clean memory + tmpLoc, veh, distance, driver, tmpModel = nil + DeletingEntities = false +end + +function SpawnVehicles(vehdata) + CreateThread(function() + while DeletingEntities do + Wait(100) + end + if vehdata then + QBCore.Functions.SpawnVehicle(vehdata.model, function(veh) + SetVehicleModifications(veh, vehdata.mods) + SetEntityRotation(veh, vehdata.rotation) + exports['LegacyFuel']:SetFuel(veh, vehdata.mods.fuelLevel) + end, vehdata.position, true) + end + end) +end + + +function TrySpawnVehicles() + + Wait(500) + local Ped = PlayerPedId() + local PedCoord = GetEntityCoords(Ped) + if OutsideVehiclesData and next(OutsideVehiclesData) ~= nil then + for k, v in pairs(OutsideVehiclesData) do + if v then + if #(PedCoord - v.position) < 20 then + if not v.spawned then + if not IsSpawnPointClear(v.position, 2.5) then + local veh, distance = QBCore.Functions.GetClosestVehicle(v.position) + if NetworkGetEntityIsLocal(veh) and distance < 1 then + local plate = QBCore.Functions.GetPlate(veh) + QBCore.Functions.TriggerCallback('MojiaGarages:server:checkHasVehicleOwner', function(hasowned) + if not hasowned then + RemoveVehicles(v) + while DeletingEntities do + Wait(100) + end + end + end, plate) + end + else + SpawnVehicles(v) + OutsideVehiclesData[k].spawned = true + end + Wait(2000) + else + if not isVehicleExistInRealLife(k) then + OutsideVehiclesData[k].spawned = false + end + end + end + end + end + end +end + + +CreateThread(function() + while PlayerIdentifier == nil do + QBCore.Functions.TriggerCallback("MojiaGarages:server:getPlayerIdentifier", function(callback) + PlayerIdentifier = callback + Wait(500) + end) + Wait(500) + end + while UpdateVeh do + Wait(500) + end + while true do + TriggerServerEvent('MojiaGarages:server:refreshVehicles') + Wait(500) + TrySpawnVehicles() + Wait(1000) + end +end) + +RegisterNetEvent("MojiaGarages:client:refreshVehicles", function(vehicles) + OutsideVehiclesData = vehicles +end) + + -- export exports('IsInGarage', IsInGarage) diff --git a/server.lua b/server.lua index 008730d..6708bca 100644 --- a/server.lua +++ b/server.lua @@ -4,7 +4,7 @@ local OutsideVehicles = {} local activePlayerPositions = {} local dataLoaded = false local AllGarages = {} - +OutsideVehiclesData = {} -- Functions local function GetClosestPlayerId(position) -- return the ID of the closest player local closestDistance = 1000000.0 @@ -87,6 +87,17 @@ local function TryGetLoadedVehicle(plate, loadedVehicles) -- returns a loaded ve return nil end +local function isVehicleExistInRealLife(plate) -- returns a loaded vehicled with a given number plate + local loadedVehicles = GetAllVehicles() + local check = false + for k, v in pairs(loadedVehicles) do + if plate == GetPlate(v) and DoesEntityExist(v) then + check = true + end + end + return check +end + local function TrySpawnVehicles() -- checks if vehicles have to be spawned and spawns them if necessary local playerVehiclePlates = {} @@ -327,6 +338,38 @@ RegisterNetEvent('MojiaGarages:server:renderScorched', function(vehicleNetId, sc end end) +local VehicleData = {} + +RegisterNetEvent('MojiaVehicles:server:UpdateVehicleData', function(data, plate) + local currentTime = os.time() + VehicleData[plate] = data + if isVehicleExistInRealLife(plate) then + VehicleData[plate].spawned = true + else + VehicleData[plate].spawned = false + end + TriggerClientEvent('MojiaVehicles:client:UpdateVehicleData', -1, VehicleData[plate], plate) + MySQL.Async.fetchAll('SELECT plate FROM player_vehicles WHERE plate = @plate', + { + ['@plate'] = plate, + }, function(results) + if results then + MySQL.Async.execute('UPDATE player_vehicles SET posX = @posX, posY = @posY, posZ = @posZ, rotX = @rotX, rotY = @rotY, rotZ = @rotZ, mods = @mods, lastUpdate = @lastUpdate WHERE plate = @plate', + { + ['@plate'] = plate, + ['@posX'] = data.position.x, + ['@posY'] = data.position.y, + ['@posZ'] = data.position.z, + ['@rotX'] = data.rotation.x, + ['@rotY'] = data.rotation.y, + ['@rotZ'] = data.rotation.z, + ['@mods'] = json.encode(data.mods), + ['@lastUpdate'] = currentTime + }) + end + end) +end) + RegisterNetEvent('MojiaGarages:server:updateVehicle', function(networkId, plate, modifications) local vehicle = NetworkGetEntityFromNetworkId(networkId) if (DoesEntityExist(vehicle)) then @@ -359,6 +402,7 @@ RegisterNetEvent('MojiaGarages:server:updateVehicle', function(networkId, plate, ['@modifications'] = json.encode(OutsideVehicles[plate].modifications), ['@lastUpdate'] = OutsideVehicles[plate].lastUpdate }) + RefreshVehicles() else -- insert in db OutsideVehicles[plate] = { @@ -382,6 +426,7 @@ RegisterNetEvent('MojiaGarages:server:updateVehicle', function(networkId, plate, ['@modifications'] = json.encode(OutsideVehicles[plate].modifications), ['@lastUpdate'] = OutsideVehicles[plate].lastUpdate }) + RefreshVehicles() end end end) @@ -588,6 +633,7 @@ CreateThread(function() -- Update data end end) +--[[ CreateThread(function() -- loop to spawn vehicles near players while (true) do if (GetActivePlayerCount() > 0) then @@ -596,3 +642,60 @@ CreateThread(function() -- loop to spawn vehicles near players Wait(1000) end end) +]]-- + +QBCore.Functions.CreateCallback('MojiaGarages:server:getOusiteVehicle', function(source, cb) + MySQL.Async.fetchAll('SELECT * FROM player_vehicles WHERE state = ? AND depotprice = ?', + { + 0, + 0 + }, function(result) + if result then + cb(result) + else + cb(false) + end + end) +end) + +QBCore.Functions.CreateCallback("MojiaGarages:server:getPlayerIdentifier", function(source, cb) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if Player then + local playerId = Player.PlayerData.citizenid + if type(playerId) ~= 'nil' then + cb(playerId) + end + end +end) + +function RefreshVehicles() + local vehicles = {} + local result = MySQL.Sync.fetchAll('SELECT * FROM player_vehicles WHERE state = ? AND depotprice = ?', {0, 0}) + if result then + for k, v in pairs(result) do + local vehspawned = true + local loadedVehicles = GetAllVehicles() + local loadedVehicle = TryGetLoadedVehicle(plate, loadedVehicles) + if loadedVehicle ~= nil then -- vehicle found + vehspawned = true + else + vehspawned = false + end + vehicles[v.plate] = { + model = v.vehicle, + position = vector3(v.posX, v.posY, v.posZ), + rotation = vector3(v.rotX, v.rotY, v.rotZ), + mods = json.decode(v.mods), + spawned = vehspawned + } + end + TriggerClientEvent("MojiaGarages:client:refreshVehicles", -1, vehicles) + end +end + +RegisterNetEvent('MojiaGarages:server:refreshVehicles', function() + RefreshVehicles() +end) + +