From a5ebf4b9cea874f5d3206991e9dec67969683990 Mon Sep 17 00:00:00 2001 From: Taso Date: Wed, 13 Oct 2021 21:54:25 -0400 Subject: [PATCH] chore(styling): ensure consistent indentation & define editorconfig --- .editorconfig | 14 + client/events.lua | 10 +- client/functions.lua | 670 +++++++++++++++---------- client/loops.lua | 2 +- client/main.lua | 2 +- config.lua | 10 +- server/commands.lua | 24 +- server/debug.lua | 10 +- server/events.lua | 314 ++++++------ server/functions.lua | 340 ++++++------- server/main.lua | 22 +- server/player.lua | 1107 +++++++++++++++++++++--------------------- shared.lua | 106 ++-- 13 files changed, 1406 insertions(+), 1225 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1e1daab --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = false +indent_style = space +charset = utf-8 +trim_trailing_whitespace = true + +[*.lua] +indent_size = 4 + +[*.js] +indent_size = 2 diff --git a/client/events.lua b/client/events.lua index f9a27a0..9bfed48 100644 --- a/client/events.lua +++ b/client/events.lua @@ -46,13 +46,17 @@ end) RegisterNetEvent('QBCore:Command:SpawnVehicle', function(vehName) local ped = PlayerPedId() local hash = GetHashKey(vehName) - if not IsModelInCdimage(hash) then return end + if not IsModelInCdimage(hash) then + return + end RequestModel(hash) - while not HasModelLoaded(hash) do Wait(10) end + while not HasModelLoaded(hash) do + Wait(10) + end local vehicle = CreateVehicle(hash, GetEntityCoords(ped), GetEntityHeading(ped), true, false) TaskWarpPedIntoVehicle(ped, vehicle, -1) SetModelAsNoLongerNeeded(vehicle) - TriggerEvent("vehiclekeys:client:SetOwner", GetVehicleNumberPlateText(vehicle)) + TriggerEvent("vehiclekeys:client:SetOwner", GetVehicleNumberPlateText(vehicle)) end) RegisterNetEvent('QBCore:Command:DeleteVehicle', function() diff --git a/client/functions.lua b/client/functions.lua index 3e93d1d..447059f 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -14,81 +14,83 @@ end function QBCore.Functions.GetCoords(entity) local coords = GetEntityCoords(entity, false) local heading = GetEntityHeading(entity) - return vector4(coords.x, coords.y, coords.z, heading) + return vector4(coords.x, coords.y, coords.z, heading) end function QBCore.Functions.HasItem(item) - QBCore.Functions.TriggerCallback('QBCore:HasItem', function(result) - if result then - return true - end - return false - end, item) - return false + QBCore.Functions.TriggerCallback('QBCore:HasItem', function(result) + if result then + return true + end + return false + end, item) + return false end -- Utility -function QBCore.Functions.DrawText(x, y, width, height, scale, r, g, b, a, text) -- Use local function instead - SetTextFont(4) +function QBCore.Functions.DrawText(x, y, width, height, scale, r, g, b, a, text) + -- Use local function instead + SetTextFont(4) SetTextProportional(0) SetTextScale(scale, scale) SetTextColour(r, g, b, a) - SetTextDropShadow(0, 0, 0, 0,255) + SetTextDropShadow(0, 0, 0, 0, 255) SetTextEdge(2, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() SetTextEntry('STRING') AddTextComponentString(text) - DrawText(x - width/2, y - height/2 + 0.005) + DrawText(x - width / 2, y - height / 2 + 0.005) end -function QBCore.Functions.DrawText3D(x, y, z, text) -- Use local function instead - SetTextScale(0.35, 0.35) +function QBCore.Functions.DrawText3D(x, y, z, text) + -- Use local function instead + SetTextScale(0.35, 0.35) SetTextFont(4) SetTextProportional(1) SetTextColour(255, 255, 255, 215) SetTextEntry('STRING') SetTextCentre(true) AddTextComponentString(text) - SetDrawOrigin(x,y,z, 0) + SetDrawOrigin(x, y, z, 0) DrawText(0.0, 0.0) local factor = (string.len(text)) / 370 - DrawRect(0.0, 0.0+0.0125, 0.017+ factor, 0.03, 0, 0, 0, 75) + DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75) ClearDrawOrigin() end RegisterNUICallback('getNotifyConfig', function(_, cb) - cb(QBCore.Config.Notify) + cb(QBCore.Config.Notify) end) function QBCore.Functions.Notify(text, textype, length) - if type(text) == "table" then - local ttext = text.text or 'Placeholder' - local caption = text.caption or 'Placeholder' - local ttype = textype or 'primary' - local length = length or 5000 - SendNUIMessage({ - action = 'notify', - type = ttype, - length = length, - text = ttext, - caption = caption - }) - else - local ttype = textype or 'primary' - local length = length or 5000 - SendNUIMessage({ - action = 'notify', - type = ttype, - length = length, - text = text - }) - end + if type(text) == "table" then + local ttext = text.text or 'Placeholder' + local caption = text.caption or 'Placeholder' + local ttype = textype or 'primary' + local length = length or 5000 + SendNUIMessage({ + action = 'notify', + type = ttype, + length = length, + text = ttext, + caption = caption + }) + else + local ttype = textype or 'primary' + local length = length or 5000 + SendNUIMessage({ + action = 'notify', + type = ttype, + length = length, + text = text + }) + end end function QBCore.Debug(resource, obj, depth) - TriggerServerEvent('QBCore:DebugSomething', resource, obj, depth) + TriggerServerEvent('QBCore:DebugSomething', resource, obj, depth) end function QBCore.Functions.TriggerCallback(name, cb, ...) @@ -122,26 +124,32 @@ end -- Getters -function QBCore.Functions.GetVehicles() return GetGamePool('CVehicle') end -function QBCore.Functions.GetObjects() return GetGamePool('CObject') end -function QBCore.Functions.GetPlayers() return GetActivePlayers() end +function QBCore.Functions.GetVehicles() + return GetGamePool('CVehicle') +end +function QBCore.Functions.GetObjects() + return GetGamePool('CObject') +end +function QBCore.Functions.GetPlayers() + return GetActivePlayers() +end function QBCore.Functions.GetPeds(ignoreList) local pedPool = GetGamePool('CPed') local ignoreList = ignoreList or {} local peds = {} for i = 1, #pedPool, 1 do - local found = false - for j=1, #ignoreList, 1 do - if ignoreList[j] == pedPool[i] then - found = true - end - end - if not found then - peds[#peds+1] = pedPool[i] - end + local found = false + for j = 1, #ignoreList, 1 do + if ignoreList[j] == pedPool[i] then + found = true + end + end + if not found then + peds[#peds + 1] = pedPool[i] + end end - return peds + return peds end function QBCore.Functions.GetClosestPed(coords, ignoreList) @@ -169,18 +177,18 @@ function QBCore.Functions.GetClosestPlayer(coords) local closestPlayers = QBCore.Functions.GetPlayersFromCoords(coords) local closestDistance = -1 local closestPlayer = -1 - for i=1, #closestPlayers, 1 do + for i = 1, #closestPlayers, 1 do if closestPlayers[i] ~= PlayerId() and closestPlayers[i] ~= -1 then local pos = GetEntityCoords(GetPlayerPed(closestPlayers[i])) - local distance = #(pos - coords) + local distance = #(pos - coords) if closestDistance == -1 or closestDistance > distance then closestPlayer = closestPlayers[i] closestDistance = distance end end - end - return closestPlayer, closestDistance + end + return closestPlayer, closestDistance end function QBCore.Functions.GetPlayersFromCoords(coords, distance) @@ -189,32 +197,32 @@ function QBCore.Functions.GetPlayersFromCoords(coords, distance) local distance = distance or 5 local closePlayers = {} for _, player in pairs(players) do - local target = GetPlayerPed(player) - local targetCoords = GetEntityCoords(target) - local targetdistance = #(targetCoords - coords) - if targetdistance <= distance then - closePlayers[#closePlayers+1] = player - end + local target = GetPlayerPed(player) + local targetCoords = GetEntityCoords(target) + local targetdistance = #(targetCoords - coords) + if targetdistance <= distance then + closePlayers[#closePlayers + 1] = player + end end return closePlayers end function QBCore.Functions.GetClosestVehicle(coords) - local ped = PlayerPedId() - local vehicles = GetGamePool('CVehicle') - local closestDistance = -1 - local closestVehicle = -1 - local coords = coords or GetEntityCoords(ped) - for i=1, #vehicles, 1 do - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = #(vehicleCoords - coords) + local ped = PlayerPedId() + local vehicles = GetGamePool('CVehicle') + local closestDistance = -1 + local closestVehicle = -1 + local coords = coords or GetEntityCoords(ped) + for i = 1, #vehicles, 1 do + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = #(vehicleCoords - coords) - if closestDistance == -1 or closestDistance > distance then - closestVehicle = vehicles[i] - closestDistance = distance - end - end - return closestVehicle, closestDistance + if closestDistance == -1 or closestDistance > distance then + closestVehicle = vehicles[i] + closestDistance = distance + end + end + return closestVehicle, closestDistance end function QBCore.Functions.GetClosestObject(coords) @@ -237,29 +245,33 @@ end -- Vehicle local function Round(value, numDecimalPlaces) - if numDecimalPlaces then - local power = 10^numDecimalPlaces - return math.floor((value * power) + 0.5) / (power) - else - return math.floor(value + 0.5) - end + if numDecimalPlaces then + local power = 10 ^ numDecimalPlaces + return math.floor((value * power) + 0.5) / (power) + else + return math.floor(value + 0.5) + end end local function Trim(value) - if value then - return (string.gsub(value, '^%s*(.-)%s*$', '%1')) - else - return nil - end + if value then + return (string.gsub(value, '^%s*(.-)%s*$', '%1')) + else + return nil + end end function QBCore.Functions.SpawnVehicle(model, cb, coords, isnetworked) local model = GetHashKey(model) local coords = coords or QBCore.Functions.GetCoords(PlayerPedId()) local isnetworked = isnetworked or true - if not IsModelInCdimage(model) then return end + if not IsModelInCdimage(model) then + return + end RequestModel(model) - while not HasModelLoaded(model) do Citizen.Wait(10) end + while not HasModelLoaded(model) do + Citizen.Wait(10) + end local veh = CreateVehicle(model, coords.x, coords.y, coords.z, coords.w, isnetworked, false) local netid = NetworkGetNetworkIdFromEntity(veh) SetVehicleHasBeenOwnedByPlayer(veh, true) @@ -267,7 +279,9 @@ function QBCore.Functions.SpawnVehicle(model, cb, coords, isnetworked) SetVehicleNeedsToBeHotwired(veh, false) SetVehRadioStation(veh, 'OFF') SetModelAsNoLongerNeeded(model) - if cb then cb(veh) end + if cb then + cb(veh) + end end function QBCore.Functions.DeleteVehicle(vehicle) @@ -276,184 +290,310 @@ function QBCore.Functions.DeleteVehicle(vehicle) end function QBCore.Functions.GetVehicleProperties(vehicle) - if DoesEntityExist(vehicle) then - local colorPrimary, colorSecondary = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - local extras = {} + if DoesEntityExist(vehicle) then + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + local extras = {} - for extraId=0, 12 do - if DoesExtraExist(vehicle, extraId) then - local state = IsVehicleExtraTurnedOn(vehicle, extraId) == 1 - extras[tostring(extraId)] = state - end - end + for extraId = 0, 12 do + if DoesExtraExist(vehicle, extraId) then + local state = IsVehicleExtraTurnedOn(vehicle, extraId) == 1 + extras[tostring(extraId)] = state + end + end - return { - model = GetEntityModel(vehicle), - plate = Trim(GetVehicleNumberPlateText(vehicle)), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - bodyHealth = Round(GetVehicleBodyHealth(vehicle), 1), - engineHealth = Round(GetVehicleEngineHealth(vehicle), 1), - tankHealth = Round(GetVehiclePetrolTankHealth(vehicle), 1), - fuelLevel = Round(GetVehicleFuelLevel(vehicle), 1), - dirtLevel = Round(GetVehicleDirtLevel(vehicle), 1), - color1 = colorPrimary, - color2 = colorSecondary, - pearlescentColor = pearlescentColor, - interiorColor = GetVehicleInteriorColor(vehicle), - dashboardColor = GetVehicleDashboardColour(vehicle), - wheelColor = wheelColor, - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), - xenonColor = GetVehicleXenonLightsColour(vehicle), - neonEnabled = { - IsVehicleNeonLightEnabled(vehicle, 0), - IsVehicleNeonLightEnabled(vehicle, 1), - IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3) - }, - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - extras = extras, - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), - modSpoilers = GetVehicleMod(vehicle, 0), - modFrontBumper = GetVehicleMod(vehicle, 1), - modRearBumper = GetVehicleMod(vehicle, 2), - modSideSkirt = GetVehicleMod(vehicle, 3), - modExhaust = GetVehicleMod(vehicle, 4), - modFrame = GetVehicleMod(vehicle, 5), - modGrille = GetVehicleMod(vehicle, 6), - modHood = GetVehicleMod(vehicle, 7), - modFender = GetVehicleMod(vehicle, 8), - modRightFender = GetVehicleMod(vehicle, 9), - modRoof = GetVehicleMod(vehicle, 10), - modEngine = GetVehicleMod(vehicle, 11), - modBrakes = GetVehicleMod(vehicle, 12), - modTransmission = GetVehicleMod(vehicle, 13), - modHorns = GetVehicleMod(vehicle, 14), - modSuspension = GetVehicleMod(vehicle, 15), - modArmor = GetVehicleMod(vehicle, 16), - modTurbo = IsToggleModOn(vehicle, 18), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), - modCustomTiresF = GetVehicleModVariation(vehicle, 23), - modCustomTiresR = GetVehicleModVariation(vehicle, 24), - modPlateHolder = GetVehicleMod(vehicle, 25), - modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), - modOrnaments = GetVehicleMod(vehicle, 28), - modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), - modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), - modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), - modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), - modArchCover = GetVehicleMod(vehicle, 42), - modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), - modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleMod(vehicle, 48), - } - else - return - end + return { + model = GetEntityModel(vehicle), + plate = Trim(GetVehicleNumberPlateText(vehicle)), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + bodyHealth = Round(GetVehicleBodyHealth(vehicle), 1), + engineHealth = Round(GetVehicleEngineHealth(vehicle), 1), + tankHealth = Round(GetVehiclePetrolTankHealth(vehicle), 1), + fuelLevel = Round(GetVehicleFuelLevel(vehicle), 1), + dirtLevel = Round(GetVehicleDirtLevel(vehicle), 1), + color1 = colorPrimary, + color2 = colorSecondary, + pearlescentColor = pearlescentColor, + interiorColor = GetVehicleInteriorColor(vehicle), + dashboardColor = GetVehicleDashboardColour(vehicle), + wheelColor = wheelColor, + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), + xenonColor = GetVehicleXenonLightsColour(vehicle), + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + }, + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + extras = extras, + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), + modSpoilers = GetVehicleMod(vehicle, 0), + modFrontBumper = GetVehicleMod(vehicle, 1), + modRearBumper = GetVehicleMod(vehicle, 2), + modSideSkirt = GetVehicleMod(vehicle, 3), + modExhaust = GetVehicleMod(vehicle, 4), + modFrame = GetVehicleMod(vehicle, 5), + modGrille = GetVehicleMod(vehicle, 6), + modHood = GetVehicleMod(vehicle, 7), + modFender = GetVehicleMod(vehicle, 8), + modRightFender = GetVehicleMod(vehicle, 9), + modRoof = GetVehicleMod(vehicle, 10), + modEngine = GetVehicleMod(vehicle, 11), + modBrakes = GetVehicleMod(vehicle, 12), + modTransmission = GetVehicleMod(vehicle, 13), + modHorns = GetVehicleMod(vehicle, 14), + modSuspension = GetVehicleMod(vehicle, 15), + modArmor = GetVehicleMod(vehicle, 16), + modTurbo = IsToggleModOn(vehicle, 18), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), + modCustomTiresF = GetVehicleModVariation(vehicle, 23), + modCustomTiresR = GetVehicleModVariation(vehicle, 24), + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleMod(vehicle, 48), + } + else + return + end end function QBCore.Functions.SetVehicleProperties(vehicle, props) if DoesEntityExist(vehicle) then - local colorPrimary, colorSecondary = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleModKit(vehicle, 0) - if props.plate then SetVehicleNumberPlateText(vehicle, props.plate) end - if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end - if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end - if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end - if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end - if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end - if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end - if props.color2 then SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end - if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end - if props.interiorColor then SetVehicleInteriorColor(vehicle, props.interiorColor) end - if props.dashboardColor then SetVehicleDashboardColour(vehicle, props.dashboardColor) end - if props.wheelColor then SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor) end - if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end - if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end - if props.neonEnabled then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) - SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) - end - if props.extras then - for id,enabled in pairs(props.extras) do - if enabled then - SetVehicleExtra(vehicle, tonumber(id), 0) - else - SetVehicleExtra(vehicle, tonumber(id), 1) - end - end - end - if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end - if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end - if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end - if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end - if props.modFrontBumper then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end - if props.modRearBumper then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end - if props.modSideSkirt then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end - if props.modExhaust then SetVehicleMod(vehicle, 4, props.modExhaust, false) end - if props.modFrame then SetVehicleMod(vehicle, 5, props.modFrame, false) end - if props.modGrille then SetVehicleMod(vehicle, 6, props.modGrille, false) end - if props.modHood then SetVehicleMod(vehicle, 7, props.modHood, false) end - if props.modFender then SetVehicleMod(vehicle, 8, props.modFender, false) end - if props.modRightFender then SetVehicleMod(vehicle, 9, props.modRightFender, false) end - if props.modRoof then SetVehicleMod(vehicle, 10, props.modRoof, false) end - if props.modEngine then SetVehicleMod(vehicle, 11, props.modEngine, false) end - if props.modBrakes then SetVehicleMod(vehicle, 12, props.modBrakes, false) end - if props.modTransmission then SetVehicleMod(vehicle, 13, props.modTransmission, false) end - if props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end - if props.modSuspension then SetVehicleMod(vehicle, 15, props.modSuspension, false) end - if props.modArmor then SetVehicleMod(vehicle, 16, props.modArmor, false) end - if props.modTurbo then ToggleVehicleMod(vehicle, 18, props.modTurbo) end - if props.modXenon then ToggleVehicleMod(vehicle, 22, props.modXenon) end - if props.xenonColor then SetVehicleXenonLightsColor(vehicle, props.xenonColor) end - if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, false) end - if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, false) end - if props.modCustomTiresF then SetVehicleMod(vehicle, 23, props.modFrontWheels, props.modCustomTiresF) end - if props.modCustomTiresR then SetVehicleMod(vehicle, 24, props.modBackWheels, props.modCustomTiresR) end - if props.modPlateHolder then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end - if props.modVanityPlate then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end - if props.modTrimA then SetVehicleMod(vehicle, 27, props.modTrimA, false) end - if props.modOrnaments then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end - if props.modDashboard then SetVehicleMod(vehicle, 29, props.modDashboard, false) end - if props.modDial then SetVehicleMod(vehicle, 30, props.modDial, false) end - if props.modDoorSpeaker then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end - if props.modSeats then SetVehicleMod(vehicle, 32, props.modSeats, false) end - if props.modSteeringWheel then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end - if props.modShifterLeavers then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end - if props.modAPlate then SetVehicleMod(vehicle, 35, props.modAPlate, false) end - if props.modSpeakers then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end - if props.modTrunk then SetVehicleMod(vehicle, 37, props.modTrunk, false) end - if props.modHydrolic then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end - if props.modEngineBlock then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end - if props.modAirFilter then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end - if props.modStruts then SetVehicleMod(vehicle, 41, props.modStruts, false) end - if props.modArchCover then SetVehicleMod(vehicle, 42, props.modArchCover, false) end - if props.modAerials then SetVehicleMod(vehicle, 43, props.modAerials, false) end - if props.modTrimB then SetVehicleMod(vehicle, 44, props.modTrimB, false) end - if props.modTank then SetVehicleMod(vehicle, 45, props.modTank, false) end - if props.modWindows then SetVehicleMod(vehicle, 46, props.modWindows, false) end - if props.modLivery then - SetVehicleMod(vehicle, 48, props.modLivery, false) - SetVehicleLivery(vehicle, props.modLivery) - end - end + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleModKit(vehicle, 0) + if props.plate then + SetVehicleNumberPlateText(vehicle, props.plate) + end + if props.plateIndex then + SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) + end + if props.bodyHealth then + SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) + end + if props.engineHealth then + SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) + end + if props.fuelLevel then + SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) + end + if props.dirtLevel then + SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) + end + if props.color1 then + SetVehicleColours(vehicle, props.color1, colorSecondary) + end + if props.color2 then + SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) + end + if props.pearlescentColor then + SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) + end + if props.interiorColor then + SetVehicleInteriorColor(vehicle, props.interiorColor) + end + if props.dashboardColor then + SetVehicleDashboardColour(vehicle, props.dashboardColor) + end + if props.wheelColor then + SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor) + end + if props.wheels then + SetVehicleWheelType(vehicle, props.wheels) + end + if props.windowTint then + SetVehicleWindowTint(vehicle, props.windowTint) + end + if props.neonEnabled then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end + if props.extras then + for id, enabled in pairs(props.extras) do + if enabled then + SetVehicleExtra(vehicle, tonumber(id), 0) + else + SetVehicleExtra(vehicle, tonumber(id), 1) + end + end + end + if props.neonColor then + SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) + end + if props.modSmokeEnabled then + ToggleVehicleMod(vehicle, 20, true) + end + if props.tyreSmokeColor then + SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) + end + if props.modSpoilers then + SetVehicleMod(vehicle, 0, props.modSpoilers, false) + end + if props.modFrontBumper then + SetVehicleMod(vehicle, 1, props.modFrontBumper, false) + end + if props.modRearBumper then + SetVehicleMod(vehicle, 2, props.modRearBumper, false) + end + if props.modSideSkirt then + SetVehicleMod(vehicle, 3, props.modSideSkirt, false) + end + if props.modExhaust then + SetVehicleMod(vehicle, 4, props.modExhaust, false) + end + if props.modFrame then + SetVehicleMod(vehicle, 5, props.modFrame, false) + end + if props.modGrille then + SetVehicleMod(vehicle, 6, props.modGrille, false) + end + if props.modHood then + SetVehicleMod(vehicle, 7, props.modHood, false) + end + if props.modFender then + SetVehicleMod(vehicle, 8, props.modFender, false) + end + if props.modRightFender then + SetVehicleMod(vehicle, 9, props.modRightFender, false) + end + if props.modRoof then + SetVehicleMod(vehicle, 10, props.modRoof, false) + end + if props.modEngine then + SetVehicleMod(vehicle, 11, props.modEngine, false) + end + if props.modBrakes then + SetVehicleMod(vehicle, 12, props.modBrakes, false) + end + if props.modTransmission then + SetVehicleMod(vehicle, 13, props.modTransmission, false) + end + if props.modHorns then + SetVehicleMod(vehicle, 14, props.modHorns, false) + end + if props.modSuspension then + SetVehicleMod(vehicle, 15, props.modSuspension, false) + end + if props.modArmor then + SetVehicleMod(vehicle, 16, props.modArmor, false) + end + if props.modTurbo then + ToggleVehicleMod(vehicle, 18, props.modTurbo) + end + if props.modXenon then + ToggleVehicleMod(vehicle, 22, props.modXenon) + end + if props.xenonColor then + SetVehicleXenonLightsColor(vehicle, props.xenonColor) + end + if props.modFrontWheels then + SetVehicleMod(vehicle, 23, props.modFrontWheels, false) + end + if props.modBackWheels then + SetVehicleMod(vehicle, 24, props.modBackWheels, false) + end + if props.modCustomTiresF then + SetVehicleMod(vehicle, 23, props.modFrontWheels, props.modCustomTiresF) + end + if props.modCustomTiresR then + SetVehicleMod(vehicle, 24, props.modBackWheels, props.modCustomTiresR) + end + if props.modPlateHolder then + SetVehicleMod(vehicle, 25, props.modPlateHolder, false) + end + if props.modVanityPlate then + SetVehicleMod(vehicle, 26, props.modVanityPlate, false) + end + if props.modTrimA then + SetVehicleMod(vehicle, 27, props.modTrimA, false) + end + if props.modOrnaments then + SetVehicleMod(vehicle, 28, props.modOrnaments, false) + end + if props.modDashboard then + SetVehicleMod(vehicle, 29, props.modDashboard, false) + end + if props.modDial then + SetVehicleMod(vehicle, 30, props.modDial, false) + end + if props.modDoorSpeaker then + SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) + end + if props.modSeats then + SetVehicleMod(vehicle, 32, props.modSeats, false) + end + if props.modSteeringWheel then + SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) + end + if props.modShifterLeavers then + SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) + end + if props.modAPlate then + SetVehicleMod(vehicle, 35, props.modAPlate, false) + end + if props.modSpeakers then + SetVehicleMod(vehicle, 36, props.modSpeakers, false) + end + if props.modTrunk then + SetVehicleMod(vehicle, 37, props.modTrunk, false) + end + if props.modHydrolic then + SetVehicleMod(vehicle, 38, props.modHydrolic, false) + end + if props.modEngineBlock then + SetVehicleMod(vehicle, 39, props.modEngineBlock, false) + end + if props.modAirFilter then + SetVehicleMod(vehicle, 40, props.modAirFilter, false) + end + if props.modStruts then + SetVehicleMod(vehicle, 41, props.modStruts, false) + end + if props.modArchCover then + SetVehicleMod(vehicle, 42, props.modArchCover, false) + end + if props.modAerials then + SetVehicleMod(vehicle, 43, props.modAerials, false) + end + if props.modTrimB then + SetVehicleMod(vehicle, 44, props.modTrimB, false) + end + if props.modTank then + SetVehicleMod(vehicle, 45, props.modTank, false) + end + if props.modWindows then + SetVehicleMod(vehicle, 46, props.modWindows, false) + end + if props.modLivery then + SetVehicleMod(vehicle, 48, props.modLivery, false) + SetVehicleLivery(vehicle, props.modLivery) + end + end end diff --git a/client/loops.lua b/client/loops.lua index 7a3e97d..94bf46a 100644 --- a/client/loops.lua +++ b/client/loops.lua @@ -13,7 +13,7 @@ CreateThread(function() Wait(QBCore.Config.StatusInterval) if LocalPlayer.state['isLoggedIn'] then if QBCore.Functions.GetPlayerData().metadata['hunger'] <= 0 or - QBCore.Functions.GetPlayerData().metadata['thirst'] <= 0 then + QBCore.Functions.GetPlayerData().metadata['thirst'] <= 0 then local ped = PlayerPedId() local currentHealth = GetEntityHealth(ped) SetEntityHealth(ped, currentHealth - math.random(5, 10)) diff --git a/client/main.lua b/client/main.lua index 095d962..efa365b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -5,7 +5,7 @@ QBCore.Shared = QBShared QBCore.ServerCallbacks = {} exports('GetCoreObject', function() - return QBCore + return QBCore end) -- To use this export in a script instead of manifest method diff --git a/config.lua b/config.lua index 9855b3e..a10eedf 100644 --- a/config.lua +++ b/config.lua @@ -6,8 +6,8 @@ QBConfig.UpdateInterval = 5 -- how often to update player data in minutes QBConfig.StatusInterval = 5000 -- how often to check hunger/thirst status in ms QBConfig.Money = {} -QBConfig.Money.MoneyTypes = {['cash'] = 500, ['bank'] = 5000, ['crypto'] = 0 } -- ['type']=startamount - Add or remove money types for your server (for ex. ['blackmoney']=0), remember once added it will not be removed from the database! -QBConfig.Money.DontAllowMinus = {'cash', 'crypto'} -- Money that is not allowed going in minus +QBConfig.Money.MoneyTypes = { ['cash'] = 500, ['bank'] = 5000, ['crypto'] = 0 } -- ['type']=startamount - Add or remove money types for your server (for ex. ['blackmoney']=0), remember once added it will not be removed from the database! +QBConfig.Money.DontAllowMinus = { 'cash', 'crypto' } -- Money that is not allowed going in minus QBConfig.Money.PayCheckTimeOut = 10 -- The time in minutes that it will give the paycheck QBConfig.Player = {} @@ -37,9 +37,9 @@ QBConfig.Server.PermissionList = {} -- permission list QBConfig.Notify = {} QBConfig.Notify.NotificationStyling = { - group = false, -- Allow notifications to stack with a badge instead of repeating - position = "right", -- top-left | top-right | bottom-left | bottom-right | top | bottom | left | right | center - progress = true -- Display Progress Bar + group = false, -- Allow notifications to stack with a badge instead of repeating + position = "right", -- top-left | top-right | bottom-left | bottom-right | top | bottom | left | right | center + progress = true -- Display Progress Bar } -- These are how you define different notification variants diff --git a/server/commands.lua b/server/commands.lua index ac974a7..4454484 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -29,7 +29,7 @@ function QBCore.Commands.Refresh(source) local hasPerm = QBCore.Functions.HasPermission(src, QBCore.Commands.List[command].permission) local isPrincipal = IsPlayerAceAllowed(src, 'command') if isGod or hasPerm or isPrincipal then - suggestions[#suggestions+1] = { + suggestions[#suggestions + 1] = { name = '/' .. command, help = info.help, params = info.arguments @@ -42,7 +42,7 @@ end -- Teleport -QBCore.Commands.Add('tp', 'TP To Player or Coords (Admin Only)', {{name = 'id/x', help = 'ID of player or X position'},{name = 'y', help = 'Y position'}, {name = 'z', help = 'Z position'}}, false, function(source, args) +QBCore.Commands.Add('tp', 'TP To Player or Coords (Admin Only)', { { name = 'id/x', help = 'ID of player or X position' }, { name = 'y', help = 'Y position' }, { name = 'z', help = 'Z position' } }, false, function(source, args) local src = source if args[1] and not args[2] and not args[3] then local target = GetPlayerPed(tonumber(args[1])) @@ -75,7 +75,7 @@ end, 'admin') -- Permissions -QBCore.Commands.Add('addpermission', 'Give Player Permissions (God Only)', {{name = 'id', help = 'ID of player'},{name = 'permission', help = 'Permission level'}}, true, function(source, args) +QBCore.Commands.Add('addpermission', 'Give Player Permissions (God Only)', { { name = 'id', help = 'ID of player' }, { name = 'permission', help = 'Permission level' } }, true, function(source, args) local src = source local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) local permission = tostring(args[2]):lower() @@ -86,7 +86,7 @@ QBCore.Commands.Add('addpermission', 'Give Player Permissions (God Only)', {{nam end end, 'god') -QBCore.Commands.Add('removepermission', 'Remove Players Permissions (God Only)', {{name = 'id', help = 'ID of player'}}, true, function(source, args) +QBCore.Commands.Add('removepermission', 'Remove Players Permissions (God Only)', { { name = 'id', help = 'ID of player' } }, true, function(source, args) local src = source local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) if Player then @@ -98,7 +98,7 @@ end, 'god') -- Vehicle -QBCore.Commands.Add('car', 'Spawn Vehicle (Admin Only)',{{name = 'model', help = 'Model name of the vehicle'}}, true, function(source, args) +QBCore.Commands.Add('car', 'Spawn Vehicle (Admin Only)', { { name = 'model', help = 'Model name of the vehicle' } }, true, function(source, args) local src = source TriggerClientEvent('QBCore:Command:SpawnVehicle', src, args[1]) end, 'admin') @@ -110,7 +110,7 @@ end, 'admin') -- Money -QBCore.Commands.Add('givemoney', 'Give A Player Money (Admin Only)', {{name = 'id', help = 'Player ID'},{name = 'moneytype', help = 'Type of money (cash, bank, crypto)'},{name = 'amount', help = 'Amount of money'}}, true, function(source, args) +QBCore.Commands.Add('givemoney', 'Give A Player Money (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'moneytype', help = 'Type of money (cash, bank, crypto)' }, { name = 'amount', help = 'Amount of money' } }, true, function(source, args) local src = source local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) if Player then @@ -120,7 +120,7 @@ QBCore.Commands.Add('givemoney', 'Give A Player Money (Admin Only)', {{name = 'i end end, 'admin') -QBCore.Commands.Add('setmoney', 'Set Players Money Amount (Admin Only)', {{name = 'id', help = 'Player ID'},{name = 'moneytype', help = 'Type of money (cash, bank, crypto)'},{name = 'amount', help = 'Amount of money'}}, true, function(source, args) +QBCore.Commands.Add('setmoney', 'Set Players Money Amount (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'moneytype', help = 'Type of money (cash, bank, crypto)' }, { name = 'amount', help = 'Amount of money' } }, true, function(source, args) local src = source local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) if Player then @@ -138,7 +138,7 @@ QBCore.Commands.Add('job', 'Check Your Job', {}, false, function(source) TriggerClientEvent('QBCore:Notify', src, string.format('[Job]: %s [Grade]: %s [On Duty]: %s', PlayerJob.label, PlayerJob.grade.name, PlayerJob.onduty)) end, 'user') -QBCore.Commands.Add('setjob', 'Set A Players Job (Admin Only)', {{name = 'id', help = 'Player ID'}, {name = 'job', help = 'Job name'},{name = 'grade', help = 'Grade'}}, true, function(source, args) +QBCore.Commands.Add('setjob', 'Set A Players Job (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'job', help = 'Job name' }, { name = 'grade', help = 'Grade' } }, true, function(source, args) local src = source local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) if Player then @@ -156,7 +156,7 @@ QBCore.Commands.Add('gang', 'Check Your Gang', {}, false, function(source) TriggerClientEvent('QBCore:Notify', src, string.format('[Gang]: %s [Grade]: %s', PlayerGang.label, PlayerGang.grade.name)) end, 'user') -QBCore.Commands.Add('setgang', 'Set A Players Gang (Admin Only)', {{name = 'id', help = 'Player ID'}, {name = 'gang', help = 'Name of a gang'},{name = 'grade', help = 'Grade'}}, true, function(source, args) +QBCore.Commands.Add('setgang', 'Set A Players Gang (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'gang', help = 'Name of a gang' }, { name = 'grade', help = 'Grade' } }, true, function(source, args) local src = source local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) if Player then @@ -168,7 +168,7 @@ end, 'admin') -- Inventory (should be in qb-inventory?) -QBCore.Commands.Add('clearinv', 'Clear Players Inventory (Admin Only)',{{name = 'id', help = 'Player ID'}}, false, function(source, args) +QBCore.Commands.Add('clearinv', 'Clear Players Inventory (Admin Only)', { { name = 'id', help = 'Player ID' } }, false, function(source, args) local src = source local playerId = args[1] or src local Player = QBCore.Functions.GetPlayer(tonumber(playerId)) @@ -190,12 +190,12 @@ QBCore.Commands.Add('ooc', 'OOC Chat Message', {}, false, function(source, args) if v == src then TriggerClientEvent('chat:addMessage', v, 'OOC ' .. GetPlayerName(src), 'normal', message) elseif #(GetEntityCoords(GetPlayerPed(src)) - - GetEntityCoords(GetPlayerPed(v))) < 20.0 then + GetEntityCoords(GetPlayerPed(v))) < 20.0 then TriggerClientEvent('chat:addMessage', v, 'OOC ' .. GetPlayerName(src), 'normal', message) elseif QBCore.Functions.HasPermission(v, 'admin') then if QBCore.Functions.IsOptin(v) then TriggerClientEvent('chat:addMessage', v, 'Proximity OOC ' .. GetPlayerName(src), 'normal', message) - TriggerEvent('qb-log:server:CreateLog', 'ooc', 'OOC', 'white', '**' .. GetPlayerName(src) .. '** (CitizenID: ' ..Player.PlayerData.citizenid .. ' | ID: ' .. src ..') **Message:** ' .. message, false) + TriggerEvent('qb-log:server:CreateLog', 'ooc', 'OOC', 'white', '**' .. GetPlayerName(src) .. '** (CitizenID: ' .. Player.PlayerData.citizenid .. ' | ID: ' .. src .. ') **Message:** ' .. message, false) end end end diff --git a/server/debug.lua b/server/debug.lua index d41b55b..4bb900b 100644 --- a/server/debug.lua +++ b/server/debug.lua @@ -8,15 +8,15 @@ local function tPrint(tbl, indent) print(formatting) tPrint(v, indent + 1) elseif tblType == 'boolean' then - print(("%s^1 %s ^0"):format(formatting,v)) + print(("%s^1 %s ^0"):format(formatting, v)) elseif tblType == "function" then - print(("%s^9 %s ^0"):format(formatting,v)) + print(("%s^9 %s ^0"):format(formatting, v)) elseif tblType == 'number' then - print(("%s^5 %s ^0"):format(formatting,v)) + print(("%s^5 %s ^0"):format(formatting, v)) elseif tblType == 'string' then - print(("%s ^2'%s' ^0"):format(formatting,v)) + print(("%s ^2'%s' ^0"):format(formatting, v)) else - print(("%s^2 %s ^0"):format(formatting,v)) + print(("%s^2 %s ^0"):format(formatting, v)) end end end diff --git a/server/events.lua b/server/events.lua index ca16198..d4b15d4 100644 --- a/server/events.lua +++ b/server/events.lua @@ -1,40 +1,40 @@ -- Event Handler AddEventHandler('playerDropped', function() - local src = source - if QBCore.Players[src] then - local Player = QBCore.Players[src] - TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**'.. GetPlayerName(src) .. '** ('..Player.PlayerData.license..') left..') - Player.Functions.Save() - QBCore.Players[src] = nil - end + local src = source + if QBCore.Players[src] then + local Player = QBCore.Players[src] + TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**' .. GetPlayerName(src) .. '** (' .. Player.PlayerData.license .. ') left..') + Player.Functions.Save() + QBCore.Players[src] = nil + end end) AddEventHandler('chatMessage', function(source, n, message) - local src = source - if string.sub(message, 1, 1) == '/' then - local args = QBCore.Shared.SplitStr(message, ' ') - local command = string.gsub(args[1]:lower(), '/', '') - CancelEvent() - if QBCore.Commands.List[command] then - local Player = QBCore.Functions.GetPlayer(src) - if Player then - local isGod = QBCore.Functions.HasPermission(src, 'god') - local hasPerm = QBCore.Functions.HasPermission(src, QBCore.Commands.List[command].permission) - local isPrincipal = IsPlayerAceAllowed(src, 'command') - table.remove(args, 1) - if isGod or hasPerm or isPrincipal then - if (QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and args[#QBCore.Commands.List[command].arguments] == nil) then - TriggerClientEvent('QBCore:Notify', src, 'All arguments must be filled out!', 'error') - else - QBCore.Commands.List[command].callback(src, args) - end - else - TriggerClientEvent('QBCore:Notify', src, 'No Access To This Command', 'error') - end - end - end - end + local src = source + if string.sub(message, 1, 1) == '/' then + local args = QBCore.Shared.SplitStr(message, ' ') + local command = string.gsub(args[1]:lower(), '/', '') + CancelEvent() + if QBCore.Commands.List[command] then + local Player = QBCore.Functions.GetPlayer(src) + if Player then + local isGod = QBCore.Functions.HasPermission(src, 'god') + local hasPerm = QBCore.Functions.HasPermission(src, QBCore.Commands.List[command].permission) + local isPrincipal = IsPlayerAceAllowed(src, 'command') + table.remove(args, 1) + if isGod or hasPerm or isPrincipal then + if (QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and args[#QBCore.Commands.List[command].arguments] == nil) then + TriggerClientEvent('QBCore:Notify', src, 'All arguments must be filled out!', 'error') + else + QBCore.Commands.List[command].callback(src, args) + end + else + TriggerClientEvent('QBCore:Notify', src, 'No Access To This Command', 'error') + end + end + end + end end) -- Player Connecting @@ -72,7 +72,7 @@ local function OnPlayerConnecting(name, setKickReason, deferrals) if not license then deferrals.done('No Valid Rockstar License Found') elseif isBanned then - deferrals.done(Reason) + deferrals.done(Reason) elseif isLicenseAlreadyInUse then deferrals.done('Duplicate Rockstar License Found') else @@ -88,19 +88,19 @@ AddEventHandler('playerConnecting', OnPlayerConnecting) -- Open & Close Server (prevents players from joining) RegisterNetEvent('QBCore:server:CloseServer', function(reason) - local src = source + local src = source if QBCore.Functions.HasPermission(src, 'admin') or QBCore.Functions.HasPermission(src, 'god') then local reason = reason or 'No reason specified' QBCore.Config.Server.closed = true QBCore.Config.Server.closedReason = reason TriggerClientEvent('qbadmin:client:SetServerStatus', -1, true) - else - QBCore.Functions.Kick(src, 'You don\'t have permissions for this..', nil, nil) + else + QBCore.Functions.Kick(src, 'You don\'t have permissions for this..', nil, nil) end end) RegisterNetEvent('QBCore:server:OpenServer', function() - local src = source + local src = source if QBCore.Functions.HasPermission(src, 'admin') or QBCore.Functions.HasPermission(src, 'god') then QBCore.Config.Server.closed = false TriggerClientEvent('qbadmin:client:SetServerStatus', -1, false) @@ -112,159 +112,165 @@ end) -- Callbacks RegisterNetEvent('QBCore:Server:TriggerCallback', function(name, ...) - local src = source - QBCore.Functions.TriggerCallback(name, src, function(...) - TriggerClientEvent('QBCore:Client:TriggerCallback', src, name, ...) - end, ...) + local src = source + QBCore.Functions.TriggerCallback(name, src, function(...) + TriggerClientEvent('QBCore:Client:TriggerCallback', src, name, ...) + end, ...) end) -- Player RegisterNetEvent('QBCore:UpdatePlayer', function() - local src = source - local Player = QBCore.Functions.GetPlayer(src) - if Player then - local newHunger = Player.PlayerData.metadata['hunger'] - QBCore.Config.Player.HungerRate - local newThirst = Player.PlayerData.metadata['thirst'] - QBCore.Config.Player.ThirstRate - if newHunger <= 0 then newHunger = 0 end - if newThirst <= 0 then newThirst = 0 end - Player.Functions.SetMetaData('thirst', newThirst) - Player.Functions.SetMetaData('hunger', newHunger) - TriggerClientEvent('hud:client:UpdateNeeds', src, newHunger, newThirst) - Player.Functions.Save() - end + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if Player then + local newHunger = Player.PlayerData.metadata['hunger'] - QBCore.Config.Player.HungerRate + local newThirst = Player.PlayerData.metadata['thirst'] - QBCore.Config.Player.ThirstRate + if newHunger <= 0 then + newHunger = 0 + end + if newThirst <= 0 then + newThirst = 0 + end + Player.Functions.SetMetaData('thirst', newThirst) + Player.Functions.SetMetaData('hunger', newHunger) + TriggerClientEvent('hud:client:UpdateNeeds', src, newHunger, newThirst) + Player.Functions.Save() + end end) RegisterNetEvent('QBCore:Server:SetMetaData', function(meta, data) local src = source - local Player = QBCore.Functions.GetPlayer(src) - if meta == 'hunger' or meta == 'thirst' then - if data > 100 then - data = 100 - end - end - if Player then - Player.Functions.SetMetaData(meta, data) - end - TriggerClientEvent('hud:client:UpdateNeeds', src, Player.PlayerData.metadata['hunger'], Player.PlayerData.metadata['thirst']) + local Player = QBCore.Functions.GetPlayer(src) + if meta == 'hunger' or meta == 'thirst' then + if data > 100 then + data = 100 + end + end + if Player then + Player.Functions.SetMetaData(meta, data) + end + TriggerClientEvent('hud:client:UpdateNeeds', src, Player.PlayerData.metadata['hunger'], Player.PlayerData.metadata['thirst']) end) RegisterNetEvent('QBCore:ToggleDuty', function() - local src = source - local Player = QBCore.Functions.GetPlayer(src) - if Player.PlayerData.job.onduty then - Player.Functions.SetJobDuty(false) - TriggerClientEvent('QBCore:Notify', src, 'You are now off duty!') - else - Player.Functions.SetJobDuty(true) - TriggerClientEvent('QBCore:Notify', src, 'You are now on duty!') - end - TriggerClientEvent('QBCore:Client:SetDuty', src, Player.PlayerData.job.onduty) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if Player.PlayerData.job.onduty then + Player.Functions.SetJobDuty(false) + TriggerClientEvent('QBCore:Notify', src, 'You are now off duty!') + else + Player.Functions.SetJobDuty(true) + TriggerClientEvent('QBCore:Notify', src, 'You are now on duty!') + end + TriggerClientEvent('QBCore:Client:SetDuty', src, Player.PlayerData.job.onduty) end) -- Items RegisterNetEvent('QBCore:Server:UseItem', function(item) - local src = source - if item and item.amount > 0 then - if QBCore.Functions.CanUseItem(item.name) then - QBCore.Functions.UseItem(src, item) - end - end + local src = source + if item and item.amount > 0 then + if QBCore.Functions.CanUseItem(item.name) then + QBCore.Functions.UseItem(src, item) + end + end end) RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount, slot) - local src = source - local Player = QBCore.Functions.GetPlayer(src) - Player.Functions.RemoveItem(itemName, amount, slot) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + Player.Functions.RemoveItem(itemName, amount, slot) end) RegisterNetEvent('QBCore:Server:AddItem', function(itemName, amount, slot, info) - local src = source - local Player = QBCore.Functions.GetPlayer(src) - Player.Functions.AddItem(itemName, amount, slot, info) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + Player.Functions.AddItem(itemName, amount, slot, info) end) -- Non-Chat Command Calling (ex: qb-adminmenu) RegisterNetEvent('QBCore:CallCommand', function(command, args) - local src = source - if QBCore.Commands.List[command] then - local Player = QBCore.Functions.GetPlayer(src) - if Player then - local isGod = QBCore.Functions.HasPermission(src, 'god') + local src = source + if QBCore.Commands.List[command] then + local Player = QBCore.Functions.GetPlayer(src) + if Player then + local isGod = QBCore.Functions.HasPermission(src, 'god') local hasPerm = QBCore.Functions.HasPermission(src, QBCore.Commands.List[command].permission) local isPrincipal = IsPlayerAceAllowed(src, 'command') - if (QBCore.Commands.List[command].permission == Player.PlayerData.job.name) or isGod or hasPerm or isPrincipal then - if (QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and args[#QBCore.Commands.List[command].arguments] == nil) then - TriggerClientEvent('QBCore:Notify', src, 'All arguments must be filled out!', 'error') - else - QBCore.Commands.List[command].callback(src, args) - end - else - TriggerClientEvent('QBCore:Notify', src, 'No Access To This Command', 'error') - end - end - end + if (QBCore.Commands.List[command].permission == Player.PlayerData.job.name) or isGod or hasPerm or isPrincipal then + if (QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and args[#QBCore.Commands.List[command].arguments] == nil) then + TriggerClientEvent('QBCore:Notify', src, 'All arguments must be filled out!', 'error') + else + QBCore.Commands.List[command].callback(src, args) + end + else + TriggerClientEvent('QBCore:Notify', src, 'No Access To This Command', 'error') + end + end + end end) -- Has Item Callback (can also use client function - QBCore.Functions.HasItem(item)) QBCore.Functions.CreateCallback('QBCore:HasItem', function(source, cb, items, amount) - local src = source - local retval = false - local Player = QBCore.Functions.GetPlayer(src) - if Player then - if type(items) == 'table' then - local count = 0 + local src = source + local retval = false + local Player = QBCore.Functions.GetPlayer(src) + if Player then + if type(items) == 'table' then + local count = 0 local finalcount = 0 - for k, v in pairs(items) do - if type(k) == 'string' then - finalcount = 0 - for i, _ in pairs(items) do - if i then finalcount = finalcount + 1 end - end - local item = Player.Functions.GetItemByName(k) - if item then - if item.amount >= v then - count = count + 1 - if count == finalcount then - retval = true - end - end - end - else + for k, v in pairs(items) do + if type(k) == 'string' then + finalcount = 0 + for i, _ in pairs(items) do + if i then + finalcount = finalcount + 1 + end + end + local item = Player.Functions.GetItemByName(k) + if item then + if item.amount >= v then + count = count + 1 + if count == finalcount then + retval = true + end + end + end + else finalcount = #items - local item = Player.Functions.GetItemByName(v) - if item then - if amount then - if item.amount >= amount then - count = count + 1 - if count == finalcount then - retval = true - end - end - else - count = count + 1 - if count == finalcount then - retval = true - end - end - end - end - end - else - local item = Player.Functions.GetItemByName(items) - if item then - if amount then - if item.amount >= amount then - retval = true - end - else - retval = true - end - end - end - end - cb(retval) + local item = Player.Functions.GetItemByName(v) + if item then + if amount then + if item.amount >= amount then + count = count + 1 + if count == finalcount then + retval = true + end + end + else + count = count + 1 + if count == finalcount then + retval = true + end + end + end + end + end + else + local item = Player.Functions.GetItemByName(items) + if item then + if amount then + if item.amount >= amount then + retval = true + end + else + retval = true + end + end + end + end + cb(retval) end) \ No newline at end of file diff --git a/server/functions.lua b/server/functions.lua index 16a052b..2ea06c6 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -8,83 +8,83 @@ QBCore.Functions = {} function QBCore.Functions.GetCoords(entity) local coords = GetEntityCoords(entity, false) local heading = GetEntityHeading(entity) - return vector4(coords.x, coords.y, coords.z, heading) + return vector4(coords.x, coords.y, coords.z, heading) end function QBCore.Functions.GetIdentifier(source, idtype) - local src = source - local idtype = idtype or QBConfig.IdentifierType - for _, identifier in pairs(GetPlayerIdentifiers(src)) do - if string.find(identifier, idtype) then - return identifier - end - end - return nil + local src = source + local idtype = idtype or QBConfig.IdentifierType + for _, identifier in pairs(GetPlayerIdentifiers(src)) do + if string.find(identifier, idtype) then + return identifier + end + end + return nil end function QBCore.Functions.GetSource(identifier) - for src, player in pairs(QBCore.Players) do - local idens = GetPlayerIdentifiers(src) - for _, id in pairs(idens) do - if identifier == id then - return src - end - end - end - return 0 + for src, player in pairs(QBCore.Players) do + local idens = GetPlayerIdentifiers(src) + for _, id in pairs(idens) do + if identifier == id then + return src + end + end + end + return 0 end function QBCore.Functions.GetPlayer(source) local src = source - if type(src) == 'number' then - return QBCore.Players[src] - else - return QBCore.Players[QBCore.Functions.GetSource(src)] - end + if type(src) == 'number' then + return QBCore.Players[src] + else + return QBCore.Players[QBCore.Functions.GetSource(src)] + end end function QBCore.Functions.GetPlayerByCitizenId(citizenid) - for src, player in pairs(QBCore.Players) do - local cid = citizenid - if QBCore.Players[src].PlayerData.citizenid == cid then - return QBCore.Players[src] - end - end - return nil + for src, player in pairs(QBCore.Players) do + local cid = citizenid + if QBCore.Players[src].PlayerData.citizenid == cid then + return QBCore.Players[src] + end + end + return nil end function QBCore.Functions.GetPlayerByPhone(number) - for src, player in pairs(QBCore.Players) do - local cid = citizenid - if QBCore.Players[src].PlayerData.charinfo.phone == number then - return QBCore.Players[src] - end - end - return nil + for src, player in pairs(QBCore.Players) do + local cid = citizenid + if QBCore.Players[src].PlayerData.charinfo.phone == number then + return QBCore.Players[src] + end + end + return nil end function QBCore.Functions.GetPlayers() - local sources = {} - for k, v in pairs(QBCore.Players) do - table.insert(sources, k) - end - return sources + local sources = {} + for k, v in pairs(QBCore.Players) do + table.insert(sources, k) + end + return sources end -- Will return an array of QB Player class instances -- unlike the GetPlayers() wrapper which only returns IDs function QBCore.Functions.GetQBPlayers() - return QBCore.Players + return QBCore.Players end -- Paychecks (standalone - don't touch) function PaycheckLoop() local Players = QBCore.Functions.GetPlayers() - for i=1, #Players, 1 do + for i = 1, #Players, 1 do local Player = QBCore.Functions.GetPlayer(Players[i]) if Player.PlayerData.job and Player.PlayerData.job.payment > 0 then Player.Functions.AddMoney('bank', Player.PlayerData.job.payment) - TriggerClientEvent('QBCore:Notify', Players[i], 'You received your paycheck of $'..Player.PlayerData.job.payment) + TriggerClientEvent('QBCore:Notify', Players[i], 'You received your paycheck of $' .. Player.PlayerData.job.payment) end end SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckLoop) @@ -93,193 +93,193 @@ end -- Callbacks function QBCore.Functions.CreateCallback(name, cb) - QBCore.ServerCallbacks[name] = cb + QBCore.ServerCallbacks[name] = cb end function QBCore.Functions.TriggerCallback(name, source, cb, ...) - local src = source - if QBCore.ServerCallbacks[name] then - QBCore.ServerCallbacks[name](src, cb, ...) - end + local src = source + if QBCore.ServerCallbacks[name] then + QBCore.ServerCallbacks[name](src, cb, ...) + end end -- Items function QBCore.Functions.CreateUseableItem(item, cb) - QBCore.UseableItems[item] = cb + QBCore.UseableItems[item] = cb end function QBCore.Functions.CanUseItem(item) - return QBCore.UseableItems[item] + return QBCore.UseableItems[item] end function QBCore.Functions.UseItem(source, item) - local src = source - QBCore.UseableItems[item.name](src, item) + local src = source + QBCore.UseableItems[item.name](src, item) end -- Kick Player function QBCore.Functions.Kick(source, reason, setKickReason, deferrals) - local src = source - reason = '\n'..reason..'\n🔸 Check our Discord for further information: '..QBCore.Config.Server.discord - if setKickReason then - setKickReason(reason) - end - CreateThread(function() - if deferrals then - deferrals.update(reason) - Wait(2500) - end - if src then - DropPlayer(src, reason) - end - local i = 0 - while (i <= 4) do - i = i + 1 - while true do - if src then - if(GetPlayerPing(src) >= 0) then - break - end - Wait(100) - CreateThread(function() - DropPlayer(src, reason) - end) - end - end - Wait(5000) - end - end) + local src = source + reason = '\n' .. reason .. '\n🔸 Check our Discord for further information: ' .. QBCore.Config.Server.discord + if setKickReason then + setKickReason(reason) + end + CreateThread(function() + if deferrals then + deferrals.update(reason) + Wait(2500) + end + if src then + DropPlayer(src, reason) + end + local i = 0 + while (i <= 4) do + i = i + 1 + while true do + if src then + if (GetPlayerPing(src) >= 0) then + break + end + Wait(100) + CreateThread(function() + DropPlayer(src, reason) + end) + end + end + Wait(5000) + end + end) end -- Check if player is whitelisted (not used anywhere) function QBCore.Functions.IsWhitelisted(source) - local src = source - local plicense = QBCore.Functions.GetIdentifier(src, 'license') - local identifiers = GetPlayerIdentifiers(src) - if QBCore.Config.Server.whitelist then - local result = exports.oxmysql:fetchSync('SELECT * FROM whitelist WHERE license = ?', {plicense}) - if result[1] then - for _, id in pairs(identifiers) do - if result[1].license == id then - return true - end - end - end - else - return true - end - return false + local src = source + local plicense = QBCore.Functions.GetIdentifier(src, 'license') + local identifiers = GetPlayerIdentifiers(src) + if QBCore.Config.Server.whitelist then + local result = exports.oxmysql:fetchSync('SELECT * FROM whitelist WHERE license = ?', { plicense }) + if result[1] then + for _, id in pairs(identifiers) do + if result[1].license == id then + return true + end + end + end + else + return true + end + return false end -- Setting & Removing Permissions function QBCore.Functions.AddPermission(source, permission) - local src = source - local Player = QBCore.Functions.GetPlayer(src) - local plicense = Player.PlayerData.license - if Player then - QBCore.Config.Server.PermissionList[plicense] = { - license = plicense, - permission = permission:lower(), - } - exports.oxmysql:execute('DELETE FROM permissions WHERE license = ?', {plicense}) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + local plicense = Player.PlayerData.license + if Player then + QBCore.Config.Server.PermissionList[plicense] = { + license = plicense, + permission = permission:lower(), + } + exports.oxmysql:execute('DELETE FROM permissions WHERE license = ?', { plicense }) - exports.oxmysql:insert('INSERT INTO permissions (name, license, permission) VALUES (?, ?, ?)', { - GetPlayerName(src), - plicense, - permission:lower() - }) + exports.oxmysql:insert('INSERT INTO permissions (name, license, permission) VALUES (?, ?, ?)', { + GetPlayerName(src), + plicense, + permission:lower() + }) - Player.Functions.UpdatePlayerData() - TriggerClientEvent('QBCore:Client:OnPermissionUpdate', src, permission) - end + Player.Functions.UpdatePlayerData() + TriggerClientEvent('QBCore:Client:OnPermissionUpdate', src, permission) + end end function QBCore.Functions.RemovePermission(source) - local src = source - local Player = QBCore.Functions.GetPlayer(src) - local license = Player.PlayerData.license - if Player then - QBCore.Config.Server.PermissionList[license] = nil - exports.oxmysql:execute('DELETE FROM permissions WHERE license = ?', {license}) - Player.Functions.UpdatePlayerData() - end + local src = source + local Player = QBCore.Functions.GetPlayer(src) + local license = Player.PlayerData.license + if Player then + QBCore.Config.Server.PermissionList[license] = nil + exports.oxmysql:execute('DELETE FROM permissions WHERE license = ?', { license }) + Player.Functions.UpdatePlayerData() + end end -- Checking for Permission Level function QBCore.Functions.HasPermission(source, permission) - local src = source - local license = QBCore.Functions.GetIdentifier(src, 'license') - local permission = tostring(permission:lower()) - if permission == 'user' then - return true - else - if QBCore.Config.Server.PermissionList[license] then - if QBCore.Config.Server.PermissionList[license].license == license then - if QBCore.Config.Server.PermissionList[license].permission == permission or QBCore.Config.Server.PermissionList[license].permission == 'god' then - return true - end - end - end - end - return false + local src = source + local license = QBCore.Functions.GetIdentifier(src, 'license') + local permission = tostring(permission:lower()) + if permission == 'user' then + return true + else + if QBCore.Config.Server.PermissionList[license] then + if QBCore.Config.Server.PermissionList[license].license == license then + if QBCore.Config.Server.PermissionList[license].permission == permission or QBCore.Config.Server.PermissionList[license].permission == 'god' then + return true + end + end + end + end + return false end function QBCore.Functions.GetPermission(source) - local src = source - local license = QBCore.Functions.GetIdentifier(src, 'license') - if license then - if QBCore.Config.Server.PermissionList[license] then - if QBCore.Config.Server.PermissionList[license].license == license then - return QBCore.Config.Server.PermissionList[license].permission - end - end - end - return 'user' + local src = source + local license = QBCore.Functions.GetIdentifier(src, 'license') + if license then + if QBCore.Config.Server.PermissionList[license] then + if QBCore.Config.Server.PermissionList[license].license == license then + return QBCore.Config.Server.PermissionList[license].permission + end + end + end + return 'user' end -- Opt in or out of admin reports function QBCore.Functions.IsOptin(source) - local src = source - local license = QBCore.Functions.GetIdentifier(src, 'license') - if QBCore.Functions.HasPermission(src, 'admin') then - retval = QBCore.Config.Server.PermissionList[license].optin - return true - end - return false + local src = source + local license = QBCore.Functions.GetIdentifier(src, 'license') + if QBCore.Functions.HasPermission(src, 'admin') then + retval = QBCore.Config.Server.PermissionList[license].optin + return true + end + return false end function QBCore.Functions.ToggleOptin(source) - local src = source - local license = QBCore.Functions.GetIdentifier(src, 'license') - if QBCore.Functions.HasPermission(src, 'admin') then - QBCore.Config.Server.PermissionList[license].optin = not QBCore.Config.Server.PermissionList[license].optin - end + local src = source + local license = QBCore.Functions.GetIdentifier(src, 'license') + if QBCore.Functions.HasPermission(src, 'admin') then + QBCore.Config.Server.PermissionList[license].optin = not QBCore.Config.Server.PermissionList[license].optin + end end -- Check if player is banned function QBCore.Functions.IsPlayerBanned(source) - local src = source - local retval = false - local message = '' - local plicense = QBCore.Functions.GetIdentifier(src, 'license') - local result = exports.oxmysql:fetchSync('SELECT * FROM bans WHERE license = ?', {plicense}) + local src = source + local retval = false + local message = '' + local plicense = QBCore.Functions.GetIdentifier(src, 'license') + local result = exports.oxmysql:fetchSync('SELECT * FROM bans WHERE license = ?', { plicense }) if result[1] then if os.time() < result[1].expire then retval = true local timeTable = os.date('*t', tonumber(result.expire)) - message = 'You have been banned from the server:\n'..result[1].reason..'\nYour ban expires '..timeTable.day.. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour.. ':' .. timeTable.min .. '\n' + message = 'You have been banned from the server:\n' .. result[1].reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n' else - exports.oxmysql:execute('DELETE FROM bans WHERE id = ?', {result[1].id}) + exports.oxmysql:execute('DELETE FROM bans WHERE id = ?', { result[1].id }) end end - return retval, message + return retval, message end -- Check for duplicate license diff --git a/server/main.lua b/server/main.lua index 03ec598..32da6d5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -5,7 +5,7 @@ QBCore.ServerCallbacks = {} QBCore.UseableItems = {} exports('GetCoreObject', function() - return QBCore + return QBCore end) -- To use this export in a script instead of manifest method @@ -15,14 +15,14 @@ end) -- Get permissions on server start CreateThread(function() - local result = exports.oxmysql:fetchSync('SELECT * FROM permissions', {}) - if result[1] then - for k, v in pairs(result) do - QBCore.Config.Server.PermissionList[v.license] = { - license = v.license, - permission = v.permission, - optin = true, - } - end - end + local result = exports.oxmysql:fetchSync('SELECT * FROM permissions', {}) + if result[1] then + for k, v in pairs(result) do + QBCore.Config.Server.PermissionList[v.license] = { + license = v.license, + permission = v.permission, + optin = true, + } + end + end end) \ No newline at end of file diff --git a/server/player.lua b/server/player.lua index 1d934f2..d380257 100644 --- a/server/player.lua +++ b/server/player.lua @@ -6,139 +6,139 @@ QBCore.Player = {} -- Will cause major issues! function QBCore.Player.Login(source, citizenid, newData) - local src = source - if src then - if citizenid then - local result = exports.oxmysql:fetchSync('SELECT * FROM players WHERE citizenid = ?', { citizenid }) - local PlayerData = result[1] - if PlayerData then - PlayerData.money = json.decode(PlayerData.money) - PlayerData.job = json.decode(PlayerData.job) - PlayerData.position = json.decode(PlayerData.position) - PlayerData.metadata = json.decode(PlayerData.metadata) - PlayerData.charinfo = json.decode(PlayerData.charinfo) - if PlayerData.gang then - PlayerData.gang = json.decode(PlayerData.gang) - else - PlayerData.gang = {} - end - end - QBCore.Player.CheckPlayerData(src, PlayerData) - else - QBCore.Player.CheckPlayerData(src, newData) - end - return true - else - QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.LOGIN - NO SOURCE GIVEN!') - return false - end + local src = source + if src then + if citizenid then + local result = exports.oxmysql:fetchSync('SELECT * FROM players WHERE citizenid = ?', { citizenid }) + local PlayerData = result[1] + if PlayerData then + PlayerData.money = json.decode(PlayerData.money) + PlayerData.job = json.decode(PlayerData.job) + PlayerData.position = json.decode(PlayerData.position) + PlayerData.metadata = json.decode(PlayerData.metadata) + PlayerData.charinfo = json.decode(PlayerData.charinfo) + if PlayerData.gang then + PlayerData.gang = json.decode(PlayerData.gang) + else + PlayerData.gang = {} + end + end + QBCore.Player.CheckPlayerData(src, PlayerData) + else + QBCore.Player.CheckPlayerData(src, newData) + end + return true + else + QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.LOGIN - NO SOURCE GIVEN!') + return false + end end function QBCore.Player.CheckPlayerData(source, PlayerData) - local src = source - PlayerData = PlayerData or {} - PlayerData.source = src - PlayerData.citizenid = PlayerData.citizenid or QBCore.Player.CreateCitizenId() - PlayerData.license = PlayerData.license or QBCore.Functions.GetIdentifier(src, 'license') - PlayerData.name = GetPlayerName(src) - PlayerData.cid = PlayerData.cid or 1 - PlayerData.money = PlayerData.money or {} - for moneytype, startamount in pairs(QBCore.Config.Money.MoneyTypes) do - PlayerData.money[moneytype] = PlayerData.money[moneytype] or startamount - end - -- Charinfo - PlayerData.charinfo = PlayerData.charinfo or {} - PlayerData.charinfo.firstname = PlayerData.charinfo.firstname or 'Firstname' - PlayerData.charinfo.lastname = PlayerData.charinfo.lastname or 'Lastname' - PlayerData.charinfo.birthdate = PlayerData.charinfo.birthdate or '00-00-0000' - PlayerData.charinfo.gender = PlayerData.charinfo.gender or 0 - PlayerData.charinfo.backstory = PlayerData.charinfo.backstory or 'placeholder backstory' - PlayerData.charinfo.nationality = PlayerData.charinfo.nationality or 'USA' - PlayerData.charinfo.phone = PlayerData.charinfo.phone ~= nil and PlayerData.charinfo.phone or '1'..math.random(111111111, 999999999) - PlayerData.charinfo.account = PlayerData.charinfo.account ~= nil and PlayerData.charinfo.account or 'US0'..math.random(1,9)..'QBCore'..math.random(1111,9999)..math.random(1111,9999)..math.random(11,99) - -- Metadata - PlayerData.metadata = PlayerData.metadata or {} - PlayerData.metadata['hunger'] = PlayerData.metadata['hunger'] or 100 - PlayerData.metadata['thirst'] = PlayerData.metadata['thirst'] or 100 - PlayerData.metadata['stress'] = PlayerData.metadata['stress'] or 0 - PlayerData.metadata['isdead'] = PlayerData.metadata['isdead'] or false - PlayerData.metadata['inlaststand'] = PlayerData.metadata['inlaststand'] or false - PlayerData.metadata['armor'] = PlayerData.metadata['armor'] or 0 - PlayerData.metadata['ishandcuffed'] = PlayerData.metadata['ishandcuffed'] or false - PlayerData.metadata['tracker'] = PlayerData.metadata['tracker'] or false - PlayerData.metadata['injail'] = PlayerData.metadata['injail'] or 0 - PlayerData.metadata['jailitems'] = PlayerData.metadata['jailitems'] or {} - PlayerData.metadata['status'] = PlayerData.metadata['status'] or {} - PlayerData.metadata['phone'] = PlayerData.metadata['phone'] or {} - PlayerData.metadata['fitbit'] = PlayerData.metadata['fitbit'] or {} - PlayerData.metadata['commandbinds'] = PlayerData.metadata['commandbinds'] or {} - PlayerData.metadata['bloodtype'] = PlayerData.metadata['bloodtype'] or QBCore.Config.Player.Bloodtypes[math.random(1, #QBCore.Config.Player.Bloodtypes)] - PlayerData.metadata['dealerrep'] = PlayerData.metadata['dealerrep'] or 0 - PlayerData.metadata['craftingrep'] = PlayerData.metadata['craftingrep'] or 0 - PlayerData.metadata['attachmentcraftingrep'] = PlayerData.metadata['attachmentcraftingrep'] or 0 - PlayerData.metadata['currentapartment'] = PlayerData.metadata['currentapartment'] or nil - PlayerData.metadata['jobrep'] = PlayerData.metadata['jobrep'] or { - ['tow'] = 0, - ['trucker'] = 0, - ['taxi'] = 0, - ['hotdog'] = 0, - } - PlayerData.metadata['callsign'] = PlayerData.metadata['callsign'] or 'NO CALLSIGN' - PlayerData.metadata['fingerprint'] = PlayerData.metadata['fingerprint'] or QBCore.Player.CreateFingerId() - PlayerData.metadata['walletid'] = PlayerData.metadata['walletid'] or QBCore.Player.CreateWalletId() - PlayerData.metadata['criminalrecord'] = PlayerData.metadata['criminalrecord'] or { - ['hasRecord'] = false, - ['date'] = nil - } - PlayerData.metadata['licences'] = PlayerData.metadata['licences'] or { - ['driver'] = true, - ['business'] = false, - ['weapon'] = false - } - PlayerData.metadata['inside'] = PlayerData.metadata['inside'] or { - house = nil, - apartment = { - apartmentType = nil, - apartmentId = nil, - } - } - PlayerData.metadata['phonedata'] = PlayerData.metadata['phonedata'] or { + local src = source + PlayerData = PlayerData or {} + PlayerData.source = src + PlayerData.citizenid = PlayerData.citizenid or QBCore.Player.CreateCitizenId() + PlayerData.license = PlayerData.license or QBCore.Functions.GetIdentifier(src, 'license') + PlayerData.name = GetPlayerName(src) + PlayerData.cid = PlayerData.cid or 1 + PlayerData.money = PlayerData.money or {} + for moneytype, startamount in pairs(QBCore.Config.Money.MoneyTypes) do + PlayerData.money[moneytype] = PlayerData.money[moneytype] or startamount + end + -- Charinfo + PlayerData.charinfo = PlayerData.charinfo or {} + PlayerData.charinfo.firstname = PlayerData.charinfo.firstname or 'Firstname' + PlayerData.charinfo.lastname = PlayerData.charinfo.lastname or 'Lastname' + PlayerData.charinfo.birthdate = PlayerData.charinfo.birthdate or '00-00-0000' + PlayerData.charinfo.gender = PlayerData.charinfo.gender or 0 + PlayerData.charinfo.backstory = PlayerData.charinfo.backstory or 'placeholder backstory' + PlayerData.charinfo.nationality = PlayerData.charinfo.nationality or 'USA' + PlayerData.charinfo.phone = PlayerData.charinfo.phone ~= nil and PlayerData.charinfo.phone or '1' .. math.random(111111111, 999999999) + PlayerData.charinfo.account = PlayerData.charinfo.account ~= nil and PlayerData.charinfo.account or 'US0' .. math.random(1, 9) .. 'QBCore' .. math.random(1111, 9999) .. math.random(1111, 9999) .. math.random(11, 99) + -- Metadata + PlayerData.metadata = PlayerData.metadata or {} + PlayerData.metadata['hunger'] = PlayerData.metadata['hunger'] or 100 + PlayerData.metadata['thirst'] = PlayerData.metadata['thirst'] or 100 + PlayerData.metadata['stress'] = PlayerData.metadata['stress'] or 0 + PlayerData.metadata['isdead'] = PlayerData.metadata['isdead'] or false + PlayerData.metadata['inlaststand'] = PlayerData.metadata['inlaststand'] or false + PlayerData.metadata['armor'] = PlayerData.metadata['armor'] or 0 + PlayerData.metadata['ishandcuffed'] = PlayerData.metadata['ishandcuffed'] or false + PlayerData.metadata['tracker'] = PlayerData.metadata['tracker'] or false + PlayerData.metadata['injail'] = PlayerData.metadata['injail'] or 0 + PlayerData.metadata['jailitems'] = PlayerData.metadata['jailitems'] or {} + PlayerData.metadata['status'] = PlayerData.metadata['status'] or {} + PlayerData.metadata['phone'] = PlayerData.metadata['phone'] or {} + PlayerData.metadata['fitbit'] = PlayerData.metadata['fitbit'] or {} + PlayerData.metadata['commandbinds'] = PlayerData.metadata['commandbinds'] or {} + PlayerData.metadata['bloodtype'] = PlayerData.metadata['bloodtype'] or QBCore.Config.Player.Bloodtypes[math.random(1, #QBCore.Config.Player.Bloodtypes)] + PlayerData.metadata['dealerrep'] = PlayerData.metadata['dealerrep'] or 0 + PlayerData.metadata['craftingrep'] = PlayerData.metadata['craftingrep'] or 0 + PlayerData.metadata['attachmentcraftingrep'] = PlayerData.metadata['attachmentcraftingrep'] or 0 + PlayerData.metadata['currentapartment'] = PlayerData.metadata['currentapartment'] or nil + PlayerData.metadata['jobrep'] = PlayerData.metadata['jobrep'] or { + ['tow'] = 0, + ['trucker'] = 0, + ['taxi'] = 0, + ['hotdog'] = 0, + } + PlayerData.metadata['callsign'] = PlayerData.metadata['callsign'] or 'NO CALLSIGN' + PlayerData.metadata['fingerprint'] = PlayerData.metadata['fingerprint'] or QBCore.Player.CreateFingerId() + PlayerData.metadata['walletid'] = PlayerData.metadata['walletid'] or QBCore.Player.CreateWalletId() + PlayerData.metadata['criminalrecord'] = PlayerData.metadata['criminalrecord'] or { + ['hasRecord'] = false, + ['date'] = nil + } + PlayerData.metadata['licences'] = PlayerData.metadata['licences'] or { + ['driver'] = true, + ['business'] = false, + ['weapon'] = false + } + PlayerData.metadata['inside'] = PlayerData.metadata['inside'] or { + house = nil, + apartment = { + apartmentType = nil, + apartmentId = nil, + } + } + PlayerData.metadata['phonedata'] = PlayerData.metadata['phonedata'] or { SerialNumber = QBCore.Player.CreateSerialNumber(), InstalledApps = {}, } - -- Job - PlayerData.job = PlayerData.job or {} - PlayerData.job.name = PlayerData.job.name or 'unemployed' - PlayerData.job.label = PlayerData.job.label or 'Civilian' - PlayerData.job.payment = PlayerData.job.payment or 10 - PlayerData.job.onduty = PlayerData.job.onduty or true - PlayerData.job.isboss = PlayerData.job.isboss or false - PlayerData.job.grade = PlayerData.job.grade or {} - PlayerData.job.grade.name = PlayerData.job.grade.name or 'Freelancer' - PlayerData.job.grade.level = PlayerData.job.grade.level or 0 - -- Gang - PlayerData.gang = PlayerData.gang or {} - PlayerData.gang.name = PlayerData.gang.name or 'none' - PlayerData.gang.label = PlayerData.gang.label or 'No Gang Affiliaton' - PlayerData.gang.isboss = PlayerData.gang.isboss or false - PlayerData.gang.grade = PlayerData.gang.grade or {} - PlayerData.gang.grade.name = PlayerData.gang.grade.name or 'none' - PlayerData.gang.grade.level = PlayerData.gang.grade.level or 0 - -- Other - PlayerData.position = PlayerData.position or QBConfig.DefaultSpawn - PlayerData.LoggedIn = true - PlayerData = QBCore.Player.LoadInventory(PlayerData) - QBCore.Player.CreatePlayer(PlayerData) + -- Job + PlayerData.job = PlayerData.job or {} + PlayerData.job.name = PlayerData.job.name or 'unemployed' + PlayerData.job.label = PlayerData.job.label or 'Civilian' + PlayerData.job.payment = PlayerData.job.payment or 10 + PlayerData.job.onduty = PlayerData.job.onduty or true + PlayerData.job.isboss = PlayerData.job.isboss or false + PlayerData.job.grade = PlayerData.job.grade or {} + PlayerData.job.grade.name = PlayerData.job.grade.name or 'Freelancer' + PlayerData.job.grade.level = PlayerData.job.grade.level or 0 + -- Gang + PlayerData.gang = PlayerData.gang or {} + PlayerData.gang.name = PlayerData.gang.name or 'none' + PlayerData.gang.label = PlayerData.gang.label or 'No Gang Affiliaton' + PlayerData.gang.isboss = PlayerData.gang.isboss or false + PlayerData.gang.grade = PlayerData.gang.grade or {} + PlayerData.gang.grade.name = PlayerData.gang.grade.name or 'none' + PlayerData.gang.grade.level = PlayerData.gang.grade.level or 0 + -- Other + PlayerData.position = PlayerData.position or QBConfig.DefaultSpawn + PlayerData.LoggedIn = true + PlayerData = QBCore.Player.LoadInventory(PlayerData) + QBCore.Player.CreatePlayer(PlayerData) end -- On player logout function QBCore.Player.Logout(source) - local src = source - TriggerClientEvent('QBCore:Client:OnPlayerUnload', src) - TriggerClientEvent('QBCore:Player:UpdatePlayerData', src) - Citizen.Wait(200) - QBCore.Players[src] = nil + local src = source + TriggerClientEvent('QBCore:Client:OnPlayerUnload', src) + TriggerClientEvent('QBCore:Player:UpdatePlayerData', src) + Citizen.Wait(200) + QBCore.Players[src] = nil end -- Create a new character @@ -146,283 +146,294 @@ end -- Will cause major issues! function QBCore.Player.CreatePlayer(PlayerData) - local self = {} - self.Functions = {} - self.PlayerData = PlayerData + local self = {} + self.Functions = {} + self.PlayerData = PlayerData - self.Functions.UpdatePlayerData = function(dontUpdateChat) - TriggerClientEvent('QBCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData) - if dontUpdateChat == nil then - QBCore.Commands.Refresh(self.PlayerData.source) - end - end + self.Functions.UpdatePlayerData = function(dontUpdateChat) + TriggerClientEvent('QBCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData) + if dontUpdateChat == nil then + QBCore.Commands.Refresh(self.PlayerData.source) + end + end - self.Functions.SetJob = function(job, grade) - local job = job:lower() - local grade = tostring(grade) or '0' + self.Functions.SetJob = function(job, grade) + local job = job:lower() + local grade = tostring(grade) or '0' - if QBCore.Shared.Jobs[job] then - self.PlayerData.job.name = job - self.PlayerData.job.label = QBCore.Shared.Jobs[job].label - self.PlayerData.job.onduty = QBCore.Shared.Jobs[job].defaultDuty + if QBCore.Shared.Jobs[job] then + self.PlayerData.job.name = job + self.PlayerData.job.label = QBCore.Shared.Jobs[job].label + self.PlayerData.job.onduty = QBCore.Shared.Jobs[job].defaultDuty - if QBCore.Shared.Jobs[job].grades[grade] then - local jobgrade = QBCore.Shared.Jobs[job].grades[grade] - self.PlayerData.job.grade = {} - self.PlayerData.job.grade.name = jobgrade.name - self.PlayerData.job.grade.level = tonumber(grade) - self.PlayerData.job.payment = jobgrade.payment or 30 - self.PlayerData.job.isboss = jobgrade.isboss or false - else - self.PlayerData.job.grade = {} - self.PlayerData.job.grade.name = 'No Grades' - self.PlayerData.job.grade.level = 0 - self.PlayerData.job.payment = 30 - self.PlayerData.job.isboss = false - end + if QBCore.Shared.Jobs[job].grades[grade] then + local jobgrade = QBCore.Shared.Jobs[job].grades[grade] + self.PlayerData.job.grade = {} + self.PlayerData.job.grade.name = jobgrade.name + self.PlayerData.job.grade.level = tonumber(grade) + self.PlayerData.job.payment = jobgrade.payment or 30 + self.PlayerData.job.isboss = jobgrade.isboss or false + else + self.PlayerData.job.grade = {} + self.PlayerData.job.grade.name = 'No Grades' + self.PlayerData.job.grade.level = 0 + self.PlayerData.job.payment = 30 + self.PlayerData.job.isboss = false + end - self.Functions.UpdatePlayerData() - TriggerClientEvent('QBCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job) - return true - end + self.Functions.UpdatePlayerData() + TriggerClientEvent('QBCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job) + return true + end - return false - end + return false + end - self.Functions.SetGang = function(gang, grade) - local gang = gang:lower() - local grade = tostring(grade) or '0' + self.Functions.SetGang = function(gang, grade) + local gang = gang:lower() + local grade = tostring(grade) or '0' - if QBCore.Shared.Gangs[gang] then - self.PlayerData.gang.name = gang - self.PlayerData.gang.label = QBCore.Shared.Gangs[gang].label - if QBCore.Shared.Gangs[gang].grades[grade] then - local ganggrade = QBCore.Shared.Gangs[gang].grades[grade] - self.PlayerData.gang.grade = {} - self.PlayerData.gang.grade.name = ganggrade.name - self.PlayerData.gang.grade.level = tonumber(grade) - self.PlayerData.gang.isboss = ganggrade.isboss or false - else - self.PlayerData.gang.grade = {} - self.PlayerData.gang.grade.name = 'No Grades' - self.PlayerData.gang.grade.level = 0 - self.PlayerData.gang.isboss = false - end + if QBCore.Shared.Gangs[gang] then + self.PlayerData.gang.name = gang + self.PlayerData.gang.label = QBCore.Shared.Gangs[gang].label + if QBCore.Shared.Gangs[gang].grades[grade] then + local ganggrade = QBCore.Shared.Gangs[gang].grades[grade] + self.PlayerData.gang.grade = {} + self.PlayerData.gang.grade.name = ganggrade.name + self.PlayerData.gang.grade.level = tonumber(grade) + self.PlayerData.gang.isboss = ganggrade.isboss or false + else + self.PlayerData.gang.grade = {} + self.PlayerData.gang.grade.name = 'No Grades' + self.PlayerData.gang.grade.level = 0 + self.PlayerData.gang.isboss = false + end - self.Functions.UpdatePlayerData() - TriggerClientEvent('QBCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang) - return true - end - return false - end + self.Functions.UpdatePlayerData() + TriggerClientEvent('QBCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang) + return true + end + return false + end - self.Functions.SetJobDuty = function(onDuty) - self.PlayerData.job.onduty = onDuty - self.Functions.UpdatePlayerData() - end + self.Functions.SetJobDuty = function(onDuty) + self.PlayerData.job.onduty = onDuty + self.Functions.UpdatePlayerData() + end - self.Functions.SetMetaData = function(meta, val) - local meta = meta:lower() - if val ~= nil then - self.PlayerData.metadata[meta] = val - self.Functions.UpdatePlayerData() - end - end + self.Functions.SetMetaData = function(meta, val) + local meta = meta:lower() + if val ~= nil then + self.PlayerData.metadata[meta] = val + self.Functions.UpdatePlayerData() + end + end - self.Functions.AddJobReputation = function(amount) - local amount = tonumber(amount) - self.PlayerData.metadata['jobrep'][self.PlayerData.job.name] = self.PlayerData.metadata['jobrep'][self.PlayerData.job.name] + amount - self.Functions.UpdatePlayerData() - end + self.Functions.AddJobReputation = function(amount) + local amount = tonumber(amount) + self.PlayerData.metadata['jobrep'][self.PlayerData.job.name] = self.PlayerData.metadata['jobrep'][self.PlayerData.job.name] + amount + self.Functions.UpdatePlayerData() + end - self.Functions.AddMoney = function(moneytype, amount, reason) - reason = reason or 'unknown' - local moneytype = moneytype:lower() - local amount = tonumber(amount) - if amount < 0 then return end - if self.PlayerData.money[moneytype] then - self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype]+amount - self.Functions.UpdatePlayerData() - if amount > 100000 then - TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** $'..amount .. ' ('..moneytype..') added, new '..moneytype..' balance: '..self.PlayerData.money[moneytype], true) - else - TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** $'..amount .. ' ('..moneytype..') added, new '..moneytype..' balance: '..self.PlayerData.money[moneytype]) - end - TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, false) - return true - end - return false - end + self.Functions.AddMoney = function(moneytype, amount, reason) + reason = reason or 'unknown' + local moneytype = moneytype:lower() + local amount = tonumber(amount) + if amount < 0 then + return + end + if self.PlayerData.money[moneytype] then + self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] + amount + self.Functions.UpdatePlayerData() + if amount > 100000 then + TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') added, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype], true) + else + TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') added, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype]) + end + TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, false) + return true + end + return false + end - self.Functions.RemoveMoney = function(moneytype, amount, reason) - reason = reason or 'unknown' - local moneytype = moneytype:lower() - local amount = tonumber(amount) - if amount < 0 then return end - if self.PlayerData.money[moneytype] then - for _, mtype in pairs(QBCore.Config.Money.DontAllowMinus) do - if mtype == moneytype then - if self.PlayerData.money[moneytype] - amount < 0 then return false end - end - end - self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] - amount - self.Functions.UpdatePlayerData() - if amount > 100000 then - TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** $'..amount .. ' ('..moneytype..') removed, new '..moneytype..' balance: '..self.PlayerData.money[moneytype], true) - else - TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** $'..amount .. ' ('..moneytype..') removed, new '..moneytype..' balance: '..self.PlayerData.money[moneytype]) - end - TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, true) - if moneytype == 'bank' then - TriggerClientEvent('qb-phone:client:RemoveBankMoney', self.PlayerData.source, amount) - end - return true - end - return false - end + self.Functions.RemoveMoney = function(moneytype, amount, reason) + reason = reason or 'unknown' + local moneytype = moneytype:lower() + local amount = tonumber(amount) + if amount < 0 then + return + end + if self.PlayerData.money[moneytype] then + for _, mtype in pairs(QBCore.Config.Money.DontAllowMinus) do + if mtype == moneytype then + if self.PlayerData.money[moneytype] - amount < 0 then + return false + end + end + end + self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] - amount + self.Functions.UpdatePlayerData() + if amount > 100000 then + TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') removed, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype], true) + else + TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') removed, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype]) + end + TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, true) + if moneytype == 'bank' then + TriggerClientEvent('qb-phone:client:RemoveBankMoney', self.PlayerData.source, amount) + end + return true + end + return false + end - self.Functions.SetMoney = function(moneytype, amount, reason) - reason = reason or 'unknown' - local moneytype = moneytype:lower() - local amount = tonumber(amount) - if amount < 0 then return end - if self.PlayerData.money[moneytype] then - self.PlayerData.money[moneytype] = amount - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'SetMoney', 'green', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** $'..amount .. ' ('..moneytype..') set, new '..moneytype..' balance: '..self.PlayerData.money[moneytype]) - return true - end - return false - end + self.Functions.SetMoney = function(moneytype, amount, reason) + reason = reason or 'unknown' + local moneytype = moneytype:lower() + local amount = tonumber(amount) + if amount < 0 then + return + end + if self.PlayerData.money[moneytype] then + self.PlayerData.money[moneytype] = amount + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'SetMoney', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') set, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype]) + return true + end + return false + end - self.Functions.GetMoney = function(moneytype) - if moneytype then - local moneytype = moneytype:lower() - return self.PlayerData.money[moneytype] - end - return false - end + self.Functions.GetMoney = function(moneytype) + if moneytype then + local moneytype = moneytype:lower() + return self.PlayerData.money[moneytype] + end + return false + end - self.Functions.AddItem = function(item, amount, slot, info) - local totalWeight = QBCore.Player.GetTotalWeight(self.PlayerData.items) - local itemInfo = QBCore.Shared.Items[item:lower()] - if itemInfo == nil then TriggerClientEvent('QBCore:Notify', source, 'Item Does Not Exist', 'error') return end - local amount = tonumber(amount) - local slot = tonumber(slot) or QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item) - if itemInfo['type'] == 'weapon' and info == nil then - info = { - serie = tostring(QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(1) .. QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(4)), - } - end - if (totalWeight + (itemInfo['weight'] * amount)) <= QBCore.Config.Player.MaxWeight then - if (slot and self.PlayerData.items[slot]) and (self.PlayerData.items[slot].name:lower() == item:lower()) and (itemInfo['type'] == 'item' and not itemInfo['unique']) then - self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount + amount - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** got item: [slot:' ..slot..'], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount ..', new total amount: '.. self.PlayerData.items[slot].amount) - return true - elseif (not itemInfo['unique'] and slot or slot and self.PlayerData.items[slot] == nil) then - self.PlayerData.items[slot] = {name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = slot, combinable = itemInfo['combinable']} - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** got item: [slot:' ..slot..'], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount ..', new total amount: '.. self.PlayerData.items[slot].amount) - return true - elseif (itemInfo['unique']) or (not slot or slot == nil) or (itemInfo['type'] == 'weapon') then - for i = 1, QBConfig.Player.MaxInvSlots, 1 do - if self.PlayerData.items[i] == nil then - self.PlayerData.items[i] = {name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = i, combinable = itemInfo['combinable']} - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** got item: [slot:' ..i..'], itemname: ' .. self.PlayerData.items[i].name .. ', added amount: ' .. amount ..', new total amount: '.. self.PlayerData.items[i].amount) - --TriggerClientEvent('QBCore:Notify', self.PlayerData.source, itemInfo['label'].. ' toegevoegd!', 'success') - return true - end - end - end - else - TriggerClientEvent('QBCore:Notify', self.PlayerData.source, 'Your inventory is too heavy!', 'error') - end - return false - end + self.Functions.AddItem = function(item, amount, slot, info) + local totalWeight = QBCore.Player.GetTotalWeight(self.PlayerData.items) + local itemInfo = QBCore.Shared.Items[item:lower()] + if itemInfo == nil then + TriggerClientEvent('QBCore:Notify', source, 'Item Does Not Exist', 'error') + return + end + local amount = tonumber(amount) + local slot = tonumber(slot) or QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item) + if itemInfo['type'] == 'weapon' and info == nil then + info = { + serie = tostring(QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(1) .. QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(4)), + } + end + if (totalWeight + (itemInfo['weight'] * amount)) <= QBCore.Config.Player.MaxWeight then + if (slot and self.PlayerData.items[slot]) and (self.PlayerData.items[slot].name:lower() == item:lower()) and (itemInfo['type'] == 'item' and not itemInfo['unique']) then + self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount + amount + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount) + return true + elseif (not itemInfo['unique'] and slot or slot and self.PlayerData.items[slot] == nil) then + self.PlayerData.items[slot] = { name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = slot, combinable = itemInfo['combinable'] } + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount) + return true + elseif (itemInfo['unique']) or (not slot or slot == nil) or (itemInfo['type'] == 'weapon') then + for i = 1, QBConfig.Player.MaxInvSlots, 1 do + if self.PlayerData.items[i] == nil then + self.PlayerData.items[i] = { name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = i, combinable = itemInfo['combinable'] } + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. i .. '], itemname: ' .. self.PlayerData.items[i].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[i].amount) + --TriggerClientEvent('QBCore:Notify', self.PlayerData.source, itemInfo['label'].. ' toegevoegd!', 'success') + return true + end + end + end + else + TriggerClientEvent('QBCore:Notify', self.PlayerData.source, 'Your inventory is too heavy!', 'error') + end + return false + end - self.Functions.RemoveItem = function(item, amount, slot) - local amount = tonumber(amount) - local slot = tonumber(slot) - if slot then - if self.PlayerData.items[slot].amount > amount then - self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount - amount - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** lost item: [slot:' ..slot..'], itemname: ' .. self.PlayerData.items[slot].name .. ', removed amount: ' .. amount ..', new total amount: '.. self.PlayerData.items[slot].amount) - return true - else - self.PlayerData.items[slot] = nil - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** lost item: [slot:' ..slot..'], itemname: ' .. item .. ', removed amount: ' .. amount ..', item removed') - return true - end - else - local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item) - local amountToRemove = amount - if slots then - for _, slot in pairs(slots) do - if self.PlayerData.items[slot].amount > amountToRemove then - self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount - amountToRemove - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** lost item: [slot:' ..slot..'], itemname: ' .. self.PlayerData.items[slot].name .. ', removed amount: ' .. amount ..', new total amount: '.. self.PlayerData.items[slot].amount) - return true - elseif self.PlayerData.items[slot].amount == amountToRemove then - self.PlayerData.items[slot] = nil - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** lost item: [slot:' ..slot..'], itemname: ' .. item .. ', removed amount: ' .. amount ..', item removed') - return true - end - end - end - end - return false - end + self.Functions.RemoveItem = function(item, amount, slot) + local amount = tonumber(amount) + local slot = tonumber(slot) + if slot then + if self.PlayerData.items[slot].amount > amount then + self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount - amount + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', removed amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount) + return true + else + self.PlayerData.items[slot] = nil + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. item .. ', removed amount: ' .. amount .. ', item removed') + return true + end + else + local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item) + local amountToRemove = amount + if slots then + for _, slot in pairs(slots) do + if self.PlayerData.items[slot].amount > amountToRemove then + self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount - amountToRemove + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', removed amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount) + return true + elseif self.PlayerData.items[slot].amount == amountToRemove then + self.PlayerData.items[slot] = nil + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. item .. ', removed amount: ' .. amount .. ', item removed') + return true + end + end + end + end + return false + end - self.Functions.SetInventory = function(items, dontUpdateChat) - self.PlayerData.items = items - self.Functions.UpdatePlayerData(dontUpdateChat) - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'SetInventory', 'blue', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** items set: ' .. json.encode(items)) - end + self.Functions.SetInventory = function(items, dontUpdateChat) + self.PlayerData.items = items + self.Functions.UpdatePlayerData(dontUpdateChat) + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'SetInventory', 'blue', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** items set: ' .. json.encode(items)) + end - self.Functions.ClearInventory = function() - self.PlayerData.items = {} - self.Functions.UpdatePlayerData() - TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'ClearInventory', 'red', '**'..GetPlayerName(self.PlayerData.source) .. ' (citizenid: '..self.PlayerData.citizenid..' | id: '..self.PlayerData.source..')** inventory cleared') - end + self.Functions.ClearInventory = function() + self.PlayerData.items = {} + self.Functions.UpdatePlayerData() + TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'ClearInventory', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** inventory cleared') + end - self.Functions.GetItemByName = function(item) - local item = tostring(item):lower() - local slot = QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item) - if slot then - return self.PlayerData.items[slot] - end - return nil - end + self.Functions.GetItemByName = function(item) + local item = tostring(item):lower() + local slot = QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item) + if slot then + return self.PlayerData.items[slot] + end + return nil + end - self.Functions.GetItemsByName = function(item) - local item = tostring(item):lower() - local items = {} - local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item) - for _, slot in pairs(slots) do - if slot then - table.insert(items, self.PlayerData.items[slot]) - end - end - return items - end + self.Functions.GetItemsByName = function(item) + local item = tostring(item):lower() + local items = {} + local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item) + for _, slot in pairs(slots) do + if slot then + table.insert(items, self.PlayerData.items[slot]) + end + end + return items + end - self.Functions.SetCreditCard = function(cardNumber) - self.PlayerData.charinfo.card = cardNumber - self.Functions.UpdatePlayerData() - end + self.Functions.SetCreditCard = function(cardNumber) + self.PlayerData.charinfo.card = cardNumber + self.Functions.UpdatePlayerData() + end - self.Functions.GetCardSlot = function(cardNumber, cardType) + self.Functions.GetCardSlot = function(cardNumber, cardType) local item = tostring(cardType):lower() local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item) for _, slot in pairs(slots) do if slot then - if self.PlayerData.items[slot].info.cardNumber == cardNumber then + if self.PlayerData.items[slot].info.cardNumber == cardNumber then return slot end end @@ -430,222 +441,222 @@ function QBCore.Player.CreatePlayer(PlayerData) return nil end - self.Functions.GetItemBySlot = function(slot) - local slot = tonumber(slot) - if self.PlayerData.items[slot] then - return self.PlayerData.items[slot] - end - return nil - end + self.Functions.GetItemBySlot = function(slot) + local slot = tonumber(slot) + if self.PlayerData.items[slot] then + return self.PlayerData.items[slot] + end + return nil + end - self.Functions.Save = function() - QBCore.Player.Save(self.PlayerData.source) - end + self.Functions.Save = function() + QBCore.Player.Save(self.PlayerData.source) + end - QBCore.Players[self.PlayerData.source] = self - QBCore.Player.Save(self.PlayerData.source) + QBCore.Players[self.PlayerData.source] = self + QBCore.Player.Save(self.PlayerData.source) - -- At this point we are safe to emit new instance to third party resource for load handling - TriggerEvent('QBCore:Server:PlayerLoaded', self) - self.Functions.UpdatePlayerData() + -- At this point we are safe to emit new instance to third party resource for load handling + TriggerEvent('QBCore:Server:PlayerLoaded', self) + self.Functions.UpdatePlayerData() end -- Save player info to database (make sure citizenid is the primary key in your database) function QBCore.Player.Save(source) - local src = source - local ped = GetPlayerPed(src) - local pcoords = GetEntityCoords(ped) - local PlayerData = QBCore.Players[src].PlayerData - if PlayerData then - exports.oxmysql:insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', { - citizenid = PlayerData.citizenid, - cid = tonumber(PlayerData.cid), - license = PlayerData.license, - name = PlayerData.name, - money = json.encode(PlayerData.money), - charinfo = json.encode(PlayerData.charinfo), - job = json.encode(PlayerData.job), - gang = json.encode(PlayerData.gang), - position = json.encode(pcoords), - metadata = json.encode(PlayerData.metadata) - }) - QBCore.Player.SaveInventory(src) - QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name ..' PLAYER SAVED!') - else - QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!') - end + local src = source + local ped = GetPlayerPed(src) + local pcoords = GetEntityCoords(ped) + local PlayerData = QBCore.Players[src].PlayerData + if PlayerData then + exports.oxmysql:insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', { + citizenid = PlayerData.citizenid, + cid = tonumber(PlayerData.cid), + license = PlayerData.license, + name = PlayerData.name, + money = json.encode(PlayerData.money), + charinfo = json.encode(PlayerData.charinfo), + job = json.encode(PlayerData.job), + gang = json.encode(PlayerData.gang), + position = json.encode(pcoords), + metadata = json.encode(PlayerData.metadata) + }) + QBCore.Player.SaveInventory(src) + QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' PLAYER SAVED!') + else + QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!') + end end -- Delete character local playertables = { -- Add tables as needed - {table = 'players'}, - {table = 'apartments'}, - {table = 'bank_accounts'}, - {table = 'crypto_transactions'}, - {table = 'phone_invoices'}, - {table = 'phone_messages'}, - {table = 'playerskins'}, - {table = 'player_boats'}, - {table = 'player_contacts'}, - {table = 'player_houses'}, - {table = 'player_mails'}, - {table = 'player_outfits'}, - {table = 'player_vehicles'} + { table = 'players' }, + { table = 'apartments' }, + { table = 'bank_accounts' }, + { table = 'crypto_transactions' }, + { table = 'phone_invoices' }, + { table = 'phone_messages' }, + { table = 'playerskins' }, + { table = 'player_boats' }, + { table = 'player_contacts' }, + { table = 'player_houses' }, + { table = 'player_mails' }, + { table = 'player_outfits' }, + { table = 'player_vehicles' } } function QBCore.Player.DeleteCharacter(source, citizenid) - local src = source - local license = QBCore.Functions.GetIdentifier(src, 'license') - local result = exports.oxmysql:scalarSync('SELECT license FROM players where citizenid = ?', { citizenid }) - if license == result then - for k,v in pairs(playertables) do - exports.oxmysql:execute('DELETE FROM '..v.table..' WHERE citizenid = ?', { citizenid }) - end - TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Character Deleted', 'red', '**'.. GetPlayerName(src) .. '** '..license..' deleted **'..citizenid..'**..') - else - DropPlayer(src, 'You Have Been Kicked For Exploitation') - TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(src)..' Has Been Dropped For Character Deletion Exploit', false) - end + local src = source + local license = QBCore.Functions.GetIdentifier(src, 'license') + local result = exports.oxmysql:scalarSync('SELECT license FROM players where citizenid = ?', { citizenid }) + if license == result then + for k, v in pairs(playertables) do + exports.oxmysql:execute('DELETE FROM ' .. v.table .. ' WHERE citizenid = ?', { citizenid }) + end + TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Character Deleted', 'red', '**' .. GetPlayerName(src) .. '** ' .. license .. ' deleted **' .. citizenid .. '**..') + else + DropPlayer(src, 'You Have Been Kicked For Exploitation') + TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(src) .. ' Has Been Dropped For Character Deletion Exploit', false) + end end -- Inventory QBCore.Player.LoadInventory = function(PlayerData) - PlayerData.items = {} - local result = exports.oxmysql:fetchSync('SELECT * FROM players WHERE citizenid = ?', {PlayerData.citizenid}) - if result[1] then - if result[1].inventory then - plyInventory = json.decode(result[1].inventory) - if next(plyInventory) then - for _, item in pairs(plyInventory) do - if item then - local itemInfo = QBCore.Shared.Items[item.name:lower()] - if itemInfo then - PlayerData.items[item.slot] = { - name = itemInfo['name'], - amount = item.amount, - info = item.info or '', - label = itemInfo['label'], - description = itemInfo['description'] or '', - weight = itemInfo['weight'], - type = itemInfo['type'], - unique = itemInfo['unique'], - useable = itemInfo['useable'], - image = itemInfo['image'], - shouldClose = itemInfo['shouldClose'], - slot = item.slot, - combinable = itemInfo['combinable'] - } - end - end - end - end - end - end - return PlayerData + PlayerData.items = {} + local result = exports.oxmysql:fetchSync('SELECT * FROM players WHERE citizenid = ?', { PlayerData.citizenid }) + if result[1] then + if result[1].inventory then + plyInventory = json.decode(result[1].inventory) + if next(plyInventory) then + for _, item in pairs(plyInventory) do + if item then + local itemInfo = QBCore.Shared.Items[item.name:lower()] + if itemInfo then + PlayerData.items[item.slot] = { + name = itemInfo['name'], + amount = item.amount, + info = item.info or '', + label = itemInfo['label'], + description = itemInfo['description'] or '', + weight = itemInfo['weight'], + type = itemInfo['type'], + unique = itemInfo['unique'], + useable = itemInfo['useable'], + image = itemInfo['image'], + shouldClose = itemInfo['shouldClose'], + slot = item.slot, + combinable = itemInfo['combinable'] + } + end + end + end + end + end + end + return PlayerData end QBCore.Player.SaveInventory = function(source) - local src = source - if QBCore.Players[src] then - local PlayerData = QBCore.Players[src].PlayerData - local items = PlayerData.items - local ItemsJson = {} - if items and next(items) then - for slot, item in pairs(items) do - if items[slot] then - table.insert(ItemsJson, { - name = item.name, - amount = item.amount, - info = item.info, - type = item.type, - slot = slot, - }) - end - end - exports.oxmysql:execute('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid }) - else - exports.oxmysql:execute('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid }) - end - end + local src = source + if QBCore.Players[src] then + local PlayerData = QBCore.Players[src].PlayerData + local items = PlayerData.items + local ItemsJson = {} + if items and next(items) then + for slot, item in pairs(items) do + if items[slot] then + table.insert(ItemsJson, { + name = item.name, + amount = item.amount, + info = item.info, + type = item.type, + slot = slot, + }) + end + end + exports.oxmysql:execute('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid }) + else + exports.oxmysql:execute('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid }) + end + end end -- Util Functions function QBCore.Player.GetTotalWeight(items) - local weight = 0 - if items then - for slot, item in pairs(items) do - weight = weight + (item.weight * item.amount) - end - end - return tonumber(weight) + local weight = 0 + if items then + for slot, item in pairs(items) do + weight = weight + (item.weight * item.amount) + end + end + return tonumber(weight) end function QBCore.Player.GetSlotsByItem(items, itemName) - local slotsFound = {} - if items then - for slot, item in pairs(items) do - if item.name:lower() == itemName:lower() then - table.insert(slotsFound, slot) - end - end - end - return slotsFound + local slotsFound = {} + if items then + for slot, item in pairs(items) do + if item.name:lower() == itemName:lower() then + table.insert(slotsFound, slot) + end + end + end + return slotsFound end function QBCore.Player.GetFirstSlotByItem(items, itemName) - if items then - for slot, item in pairs(items) do - if item.name:lower() == itemName:lower() then - return tonumber(slot) - end - end - end - return nil + if items then + for slot, item in pairs(items) do + if item.name:lower() == itemName:lower() then + return tonumber(slot) + end + end + end + return nil end function QBCore.Player.CreateCitizenId() - local UniqueFound = false - local CitizenId = nil - while not UniqueFound do - CitizenId = tostring(QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(5)):upper() - local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM players WHERE citizenid = ?', { CitizenId }) - if result[1].count == 0 then - UniqueFound = true - end - end - return CitizenId + local UniqueFound = false + local CitizenId = nil + while not UniqueFound do + CitizenId = tostring(QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(5)):upper() + local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM players WHERE citizenid = ?', { CitizenId }) + if result[1].count == 0 then + UniqueFound = true + end + end + return CitizenId end function QBCore.Player.CreateFingerId() - local UniqueFound = false - local FingerId = nil - while not UniqueFound do - FingerId = tostring(QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(1) .. QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(4)) - local query = '%'..FingerId..'%' - local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM `players` WHERE `metadata` LIKE ?', { query }) - if result[1].count == 0 then - UniqueFound = true - end - end - return FingerId + local UniqueFound = false + local FingerId = nil + while not UniqueFound do + FingerId = tostring(QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(1) .. QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(4)) + local query = '%' .. FingerId .. '%' + local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM `players` WHERE `metadata` LIKE ?', { query }) + if result[1].count == 0 then + UniqueFound = true + end + end + return FingerId end function QBCore.Player.CreateWalletId() - local UniqueFound = false - local WalletId = nil - while not UniqueFound do - WalletId = 'QB-'..math.random(11111111, 99999999) - local query = '%'..WalletId..'%' - local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) - if result[1].count == 0 then - UniqueFound = true - end - end - return WalletId + local UniqueFound = false + local WalletId = nil + while not UniqueFound do + WalletId = 'QB-' .. math.random(11111111, 99999999) + local query = '%' .. WalletId .. '%' + local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) + if result[1].count == 0 then + UniqueFound = true + end + end + return WalletId end function QBCore.Player.CreateSerialNumber() @@ -653,11 +664,11 @@ function QBCore.Player.CreateSerialNumber() local SerialNumber = nil while not UniqueFound do SerialNumber = math.random(11111111, 99999999) - local query = '%'..SerialNumber..'%' - local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) - if result[1].count == 0 then - UniqueFound = true - end + local query = '%' .. SerialNumber .. '%' + local result = exports.oxmysql:fetchSync('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) + if result[1].count == 0 then + UniqueFound = true + end end return SerialNumber end diff --git a/shared.lua b/shared.lua index c1db673..4ef43d8 100644 --- a/shared.lua +++ b/shared.lua @@ -3,43 +3,49 @@ QBShared = {} local StringCharset = {} local NumberCharset = {} -for i = 48, 57 do table.insert(NumberCharset, string.char(i)) end -for i = 65, 90 do table.insert(StringCharset, string.char(i)) end -for i = 97, 122 do table.insert(StringCharset, string.char(i)) end +for i = 48, 57 do + table.insert(NumberCharset, string.char(i)) +end +for i = 65, 90 do + table.insert(StringCharset, string.char(i)) +end +for i = 97, 122 do + table.insert(StringCharset, string.char(i)) +end QBShared.RandomStr = function(length) - if length > 0 then - return QBShared.RandomStr(length-1) .. StringCharset[math.random(1, #StringCharset)] - else - return '' - end + if length > 0 then + return QBShared.RandomStr(length - 1) .. StringCharset[math.random(1, #StringCharset)] + else + return '' + end end QBShared.RandomInt = function(length) - if length > 0 then - return QBShared.RandomInt(length-1) .. NumberCharset[math.random(1, #NumberCharset)] - else - return '' - end + if length > 0 then + return QBShared.RandomInt(length - 1) .. NumberCharset[math.random(1, #NumberCharset)] + else + return '' + end end QBShared.SplitStr = function(str, delimiter) - local result = { } - local from = 1 - local delim_from, delim_to = string.find( str, delimiter, from ) - while delim_from do - table.insert( result, string.sub( str, from , delim_from-1 ) ) - from = delim_to + 1 - delim_from, delim_to = string.find( str, delimiter, from ) - end - table.insert( result, string.sub( str, from ) ) - return result + local result = { } + local from = 1 + local delim_from, delim_to = string.find(str, delimiter, from) + while delim_from do + table.insert(result, string.sub(str, from, delim_from - 1)) + from = delim_to + 1 + delim_from, delim_to = string.find(str, delimiter, from) + end + table.insert(result, string.sub(str, from)) + return result end QBShared.StarterItems = { - ['phone'] = {amount = 1, item = 'phone'}, - ['id_card'] = {amount = 1, item = 'id_card'}, - ['driver_license'] = {amount = 1, item = 'driver_license'}, + ['phone'] = { amount = 1, item = 'phone' }, + ['id_card'] = { amount = 1, item = 'id_card' }, + ['driver_license'] = { amount = 1, item = 'driver_license' }, } QBShared.Items = { @@ -130,7 +136,7 @@ QBShared.Items = { ['weapon_carbinerifle_mk2'] = {['name'] = 'weapon_carbinerifle_mk2', ['label'] = 'PD 762', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_RIFLE', ['image'] = 'carbineriflemk2.png', ['unique'] = true, ['useable'] = true, ['description'] = 'Carbine Rifle MK2'}, ['weapon_revolver_mk2'] = {['name'] = 'weapon_revolver_mk2', ['label'] = 'Violence', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_PISTOL', ['image'] = 'revolvermk2.png', ['unique'] = true, ['useable'] = true, ['description'] = 'da Violence'}, ['weapon_doubleaction'] = {['name'] = 'weapon_doubleaction', ['label'] = 'Double Action Revolver', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_PISTOL', ['image'] = 'doubleaction.png', ['unique'] = true, ['useable'] = true, ['description'] = 'Double Action Revolver'}, - + -- PISTOL ATTACHMENTS ['pistol_defaultclip'] = {['name'] = 'pistol_defaultclip', ['label'] = 'Pistol Clip', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'pistol_extendedclip.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Pistol Default Clip'}, ['pistol_extendedclip'] = {['name'] = 'pistol_extendedclip', ['label'] = 'Pistol EXT Clip', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'pistol_extendedclip.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Pistol Extended Clip'}, @@ -384,7 +390,7 @@ QBShared.Items = { ['redfish'] = {['name'] = 'redfish', ['label'] = 'Redfish', ['weight'] = 1111, ['type'] = 'item', ['image'] = 'redfish.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'One fish two fish...'}, ['bluefish'] = {['name'] = 'bluefish', ['label'] = 'Bluefish', ['weight'] = 1111, ['type'] = 'item', ['image'] = 'bluefish.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'One fish two fish redfish...'}, ['stripedbass'] = {['name'] = 'stripedbass', ['label'] = 'Striped Bass', ['weight'] = 1111, ['type'] = 'item', ['image'] = 'stripedbass.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A Striped Bass'}, - ['fishingrod'] = {['name'] = 'fishingrod', ['label'] = 'Fishing Rod', ['weight'] = 5000, ['type'] = 'item', ['image'] = 'fishingrod.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A fishing rod for adventures with friends!!'}, + ['fishingrod'] = {['name'] = 'fishingrod', ['label'] = 'Fishing Rod', ['weight'] = 5000, ['type'] = 'item', ['image'] = 'fishingrod.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A fishing rod for adventures with friends!!'}, ['fishingbait'] = {['name'] = 'fishingbait', ['label'] = 'Fish Bait', ['weight'] = 400, ['type'] = 'item', ['image'] = 'fishbait.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A fish bait'}, } @@ -477,7 +483,7 @@ QBShared.Weapons = { [`weapon_assaultrifle_mk2`] = {['name'] = 'weapon_assaultrifle_mk2', ['label'] = 'AK-47 MK2', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_RIFLE', ['image'] = 'assaultriflemk2.png', ['unique'] = true, ['useable'] = true, ['description'] = 'Assault Rifle MK2'}, [`weapon_carbinerifle_mk2`] = {['name'] = 'weapon_carbinerifle_mk2', ['label'] = 'PD 762', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_RIFLE', ['image'] = 'carbineriflemk2.png', ['unique'] = true, ['useable'] = true, ['description'] = 'Carbine Rifle MK2'}, [`weapon_revolver_mk2`] = {['name'] = 'weapon_revolver_mk2', ['label'] = 'Violence', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_PISTOL', ['image'] = 'revolvermk2.png', ['unique'] = true, ['useable'] = true, ['description'] = 'da Violence'}, - [`weapon_doubleaction`] = {['name'] = 'weapon_doubleaction', ['label'] = 'Double Action Revolver', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_PISTOL', ['image'] = 'doubleaction.png', ['unique'] = true, ['useable'] = true, ['description'] = 'Double Action Revolver'}, + [`weapon_doubleaction`] = {['name'] = 'weapon_doubleaction', ['label'] = 'Double Action Revolver', ['weight'] = 1000, ['type'] = 'weapon', ['ammotype'] = 'AMMO_PISTOL', ['image'] = 'doubleaction.png', ['unique'] = true, ['useable'] = true, ['description'] = 'Double Action Revolver'}, } -- Gangs @@ -976,7 +982,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['bfinjection'] = { - ['name'] = 'Bf Injection', + ['name'] = 'Bf Injection', ['brand'] = 'Annis', ['price'] = 9000, ['category'] = 'offroad', @@ -985,7 +991,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['bifta'] = { - ['name'] = 'Bifta', + ['name'] = 'Bifta', ['brand'] = 'Annis', ['price'] = 15500, ['category'] = 'offroad', @@ -1021,7 +1027,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['blazer'] = { - ['name'] = 'Blazer', + ['name'] = 'Blazer', ['price'] = 7500, ['category'] = 'offroad', ['model'] = 'blazer', @@ -1065,7 +1071,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['brawler'] = { - ['name'] = 'Brawler', + ['name'] = 'Brawler', ['brand'] = 'Annis', ['price'] = 40000, ['category'] = 'offroad', @@ -1082,7 +1088,7 @@ QBShared.Vehicles = { ['hash'] = `brioso`, ['shop'] = 'pdm', }, - ['btype'] = { --meme car that goes pretty fast + ['btype'] = { --meme car that goes pretty fast ['name'] = 'Roosevelt', ['brand'] = 'Albany', ['model'] = 'btype', @@ -1325,7 +1331,7 @@ QBShared.Vehicles = { ['hash'] = `coquette3`, ['shop'] = 'pdm', }, - ['cyclone'] = { --might be too overpowered + ['cyclone'] = { --might be too overpowered ['name'] = 'Cyclone', ['brand'] = 'Coil', ['model'] = 'cyclone', @@ -1380,7 +1386,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['dubsta3'] = { - ['name'] = 'Dubsta 6x6', + ['name'] = 'Dubsta 6x6', ['brand'] = 'Annis', ['price'] = 34000, ['category'] = 'offroad', @@ -1398,7 +1404,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['dune'] = { - ['name'] = 'Dune Buggy', + ['name'] = 'Dune Buggy', ['brand'] = 'Annis', ['price'] = 14000, ['category'] = 'offroad', @@ -1677,7 +1683,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['guardian'] = { - ['name'] = 'Guardian', + ['name'] = 'Guardian', ['brand'] = 'Annis', ['price'] = 21000, ['category'] = 'offroad', @@ -1739,7 +1745,7 @@ QBShared.Vehicles = { ['hash'] = `infernus`, ['shop'] = 'pdm', }, - ['infernus2'] = { + ['infernus2'] = { ['name'] = 'Infernus Classic', ['brand'] = 'Pegassi', ['model'] = 'infernus2', @@ -2145,7 +2151,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['rebel2'] = { - ['name'] = 'Rebel', + ['name'] = 'Rebel', ['brand'] = 'Annis', ['model'] = 'rebel2', ['price'] = 20000, @@ -2235,7 +2241,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['sandking'] = { - ['name'] = 'Sandking', + ['name'] = 'Sandking', ['brand'] = 'Annis', ['price'] = 25000, ['category'] = 'offroad', @@ -2505,7 +2511,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['trophytruck'] = { - ['name'] = 'Trophy Truck', + ['name'] = 'Trophy Truck', ['brand'] = 'Annis', ['price'] = 60000, ['category'] = 'offroad', @@ -3068,7 +3074,7 @@ QBShared.Vehicles = { ['hash'] = `double`, ['shop'] = 'pdm', }, - ['drafter'] = { + ['drafter'] = { ['name'] = '8F Drafter', ['brand'] = 'Obey', ['model'] = 'drafter', @@ -3634,7 +3640,7 @@ QBShared.Vehicles = { ['hash'] = `nero2`, ['shop'] = 'pdm', }, - ['novak'] = { + ['novak'] = { ['name'] = 'Novak', ['brand'] = 'Lampadati', ['model'] = 'novak', @@ -3869,7 +3875,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['sandking2'] = { - ['name'] = 'Sandking SWB', + ['name'] = 'Sandking SWB', ['brand'] = 'Annis', ['price'] = 38000, ['category'] = 'offroad', @@ -4234,7 +4240,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['vagrant'] = { - ['name'] = 'Vagrant', + ['name'] = 'Vagrant', ['brand'] = 'Maxwell', ['price'] = 50000, ['category'] = 'offroad', @@ -4252,7 +4258,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['verus'] = { - ['name'] = 'Verus', + ['name'] = 'Verus', ['brand'] = 'Dinka', ['price'] = 20000, ['category'] = 'offroad', @@ -4333,7 +4339,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['winky'] = { - ['name'] = 'Winky', + ['name'] = 'Winky', ['brand'] = 'Vapid', ['price'] = 10000, ['category'] = 'offroad', @@ -4360,7 +4366,7 @@ QBShared.Vehicles = { ['shop'] = 'pdm', }, ['yosemite3'] = { - ['name'] = 'Yosemite Rancher', + ['name'] = 'Yosemite Rancher', ['brand'] = 'Declasse', ['price'] = 425000, ['category'] = 'offroad', @@ -4422,7 +4428,7 @@ QBShared.Vehicles = { ['hash'] = `zorrusso`, ['shop'] = 'pdm', }, - + ----------MUST BE ENABLED FOR THE BELOW VEHICLES-------------+set sv_enforceGameBuild 2372------------------------------- ----------MUST BE ENABLED FOR THE BELOW VEHICLES-------------+set sv_enforceGameBuild 2372------------------------------- ----------MUST BE ENABLED FOR THE BELOW VEHICLES-------------+set sv_enforceGameBuild 2372-------------------------------