diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..de54500 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team in the discord at https://discord.com/invite/qbcore. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..369c61a --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,23 @@ +name: Lint +on: [push, pull_request_target] +jobs: + lint: + name: Lint Resource + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Lint + uses: iLLeniumStudios/fivem-lua-lint-action@v2 + with: + capture: "junit.xml" + args: "-t --formatter JUnit" + extra_libs: mysql + - name: Generate Lint Report + if: always() + uses: mikepenz/action-junit-report@v3 + with: + report_paths: "**/junit.xml" + check_name: Linting Report + fail_on_failure: false diff --git a/README.md b/README.md index b0e11be..89b0194 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,6 @@ # qb-core -### [Official QBCore Documentation](https://qbcore-framework.github.io/qb-docs/) - - -## QBCore is officially partnered with Sonoran Software! -Sonoran Software offers: -* [The most advanced, integrated CAD software](https://sonorancad.com/kakarot) -* [Complete community management software](https://sonorancms.com/kakarot) -* [In-depth radio communications simulator](https://sonoranradio.com/kakarot) -* [Premium server hosting](https://sonoranservers.com/kakarot) - -Use code `KAKAROT` for 20% off your first month at checkout! - -# Sonoran Software -![Sonoran Software Partnership](https://sonoransoftware.com/assets/images/promotional/partners/qb_banner_coupon.png) +### [Official QBCore Documentation](https://docs.qbcore.org) # License diff --git a/client/drawtext.lua b/client/drawtext.lua index ef669b2..2f3280b 100644 --- a/client/drawtext.lua +++ b/client/drawtext.lua @@ -5,7 +5,7 @@ local function hideText() end local function drawText(text, position) - if not type(position) == "string" then position = "left" end + if type(position) ~= "string" then position = "left" end SendNUIMessage({ action = 'DRAW_TEXT', @@ -17,7 +17,7 @@ local function drawText(text, position) end local function changeText(text, position) - if not type(position) == "string" then position = "left" end + if type(position) ~= "string" then position = "left" end SendNUIMessage({ action = 'CHANGE_TEXT', diff --git a/client/events.lua b/client/events.lua index ff48269..c0b2597 100644 --- a/client/events.lua +++ b/client/events.lua @@ -30,19 +30,89 @@ RegisterNetEvent('QBCore:Command:TeleportToCoords', function(x, y, z) end) RegisterNetEvent('QBCore:Command:GoToMarker', function() - local ped = PlayerPedId() - local blip = GetFirstBlipInfoId(8) - if not DoesBlipExist(blip) then return end - local blipCoords = GetBlipCoords(blip) - for height = 1, 1000 do - SetPedCoordsKeepVehicle(ped, blipCoords.x, blipCoords.y, height + 0.0) - local foundGround, zPos = GetGroundZFor_3dCoord(blipCoords.x, blipCoords.y, height + 0.0) - if foundGround then - SetPedCoordsKeepVehicle(ped, blipCoords.x, blipCoords.y, height + 0.0) + local PlayerPedId = PlayerPedId + local GetEntityCoords = GetEntityCoords + local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord + + local blipMarker = GetFirstBlipInfoId(8) + if not DoesBlipExist(blipMarker) then + QBCore.Functions.Notify('No Waypoint Set.', "error",5000) + return 'marker' + end + + -- Fade screen to hide how clients get teleported. + DoScreenFadeOut(650) + while not IsScreenFadedOut() do + Wait(0) + end + + local ped, coords = PlayerPedId(), GetBlipInfoIdCoord(blipMarker) + local vehicle = GetVehiclePedIsIn(ped, false) + local oldCoords = GetEntityCoords(ped) + + -- Unpack coords instead of having to unpack them while iterating. + -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. + local x, y, groundZ, Z_START = coords['x'], coords['y'], 850.0, 950.0 + local found = false + if vehicle > 0 then + FreezeEntityPosition(vehicle, true) + else + FreezeEntityPosition(ped, true) + end + + for i = Z_START, 0, -25.0 do + local z = i + if (i % 2) ~= 0 then + z = Z_START - i + end + + NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) + local curTime = GetGameTimer() + while IsNetworkLoadingScene() do + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + NewLoadSceneStop() + SetPedCoordsKeepVehicle(ped, x, y, z) + + while not HasCollisionLoadedAroundEntity(ped) do + RequestCollisionAtCoord(x, y, z) + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + + -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. + found, groundZ = GetGroundZFor_3dCoord(x, y, z, false); + if found then + Wait(0) + SetPedCoordsKeepVehicle(ped, x, y, groundZ) break end Wait(0) end + + -- Remove black screen once the loop has ended. + DoScreenFadeIn(650) + if vehicle > 0 then + FreezeEntityPosition(vehicle, false) + else + FreezeEntityPosition(ped, false) + end + + if not found then + -- If we can't find the coords, set the coords to the old ones. + -- We don't unpack them before since they aren't in a loop and only called once. + SetPedCoordsKeepVehicle(ped, oldCoords['x'], oldCoords['y'], oldCoords['z'] - 1.0) + QBCore.Functions.Notify('Error While Teleporting.', "error",5000) + end + + -- If Z coord was found, set coords in found coords. + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + QBCore.Functions.Notify('Teleported To Waypoint.', "success",5000) end) -- Vehicle Commands @@ -57,13 +127,14 @@ RegisterNetEvent('QBCore:Command:SpawnVehicle', function(vehName) Wait(0) end - if IsPedInAnyVehicle(ped) then + if IsPedInAnyVehicle(ped) then DeleteVehicle(veh) end local vehicle = CreateVehicle(hash, GetEntityCoords(ped), GetEntityHeading(ped), true, false) TaskWarpPedIntoVehicle(ped, vehicle, -1) SetVehicleFuelLevel(vehicle, 100.0) + SetVehicleDirtLevel(vehicle, 0.0) SetModelAsNoLongerNeeded(hash) TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(vehicle)) end) @@ -77,7 +148,7 @@ RegisterNetEvent('QBCore:Command:DeleteVehicle', function() else local pcoords = GetEntityCoords(ped) local vehicles = GetGamePool('CVehicle') - for k, v in pairs(vehicles) do + for _, v in pairs(vehicles) do if #(pcoords - GetEntityCoords(v)) <= 5.0 then SetEntityAsMissionEntity(v, true, true) DeleteVehicle(v) diff --git a/client/functions.lua b/client/functions.lua index c11c1ab..7e72c50 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -52,39 +52,6 @@ function QBCore.Functions.DrawText3D(x, y, z, text) ClearDrawOrigin() end -function QBCore.Functions.CreateBlip(coords, sprite, display, scale, colour, shortRange, title, alpha, friendly, bright, category, hiddenOnLegend, highDetail, rotation, cone, shrink, showHeight, showNumber, showOutline) - if not coords or (type(coords) ~= 'table' and type(coords) ~= 'vector3') then - print("Blip failed to create, the coords were not specified or was specified in the wrong format, coords must be a table or vector3, debug log: ") - print(("Coords: %s Sprite: %s Display: %s scale: %s shortRange: %s Title: %s Alpha: %s Friendly: %s Bright: %s Category: %s Hidden On Legend: %s High Detail: %s Rotation: %s Cone: %s Shrink: %s Show Heigt: %s Show Number: %s Show Outline: %s"):format(coords, sprite, display, scale, colour, shortRange, title, alpha, friendly, bright, category, hiddenOnLegend, highDetail, rotation, cone, shrink, showHeight, showNumber, showOutline)) - return - end - coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords - local blip = AddBlipForCoord(coords) - if sprite then SetBlipSprite(blip, sprite) end - if display then SetBlipDisplay(blip, display) end - if scale then SetBlipScale(blip, scale) end - if colour then SetBlipColour(blip, colour) end - if shortRange ~= nil then SetBlipAsShortRange(blip, shortRange) end - if title then - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(title) - EndTextCommandSetBlipName(blip) - end - if alpha then SetBlipAlpha(blip, alpha) end - if friendly ~= nil then SetBlipAsFriendly(blip, friendly) end - if bright ~= nil then SetBlipBright(blip, bright) end - if category then SetBlipCategory(blip, category) end -- categories can be found here: https://docs.fivem.net/natives/?_0x234CDD44D996FD9A - if hiddenOnLegend ~= nil then SetBlipHiddenOnLegend(blip, hiddenOnLegend) end - if highDetail ~= nil then SetBlipHighDetail(blip, highDetail) end - if rotation then SetBlipRotation(blip, rotation) end -- Required to be an integer - if cone ~= nil then SetBlipShowCone(blip, cone) end - if shrink ~= nil then SetBlipShrink(blip, shrink) end - if showHeight ~= nil then ShowHeightOnBlip(blip, showHeight) end - if showNumber then ShowNumberOnBlip(blip, showNumber) end - if showOutline ~= nil then ShowOutlineIndicatorOnBlip(blip, showOutline) end - return blip -end - function QBCore.Functions.RequestAnimDict(animDict) if HasAnimDictLoaded(animDict) then return end RequestAnimDict(animDict) @@ -109,6 +76,14 @@ function QBCore.Functions.LoadModel(model) end end +function QBCore.Functions.LoadAnimSet(animSet) + if HasAnimSetLoaded(animSet) then return end + RequestAnimSet(animSet) + while not HasAnimSetLoaded(animSet) do + Wait(0) + end +end + RegisterNUICallback('getNotifyConfig', function(_, cb) cb(QBCore.Config.Notify) end) @@ -211,7 +186,7 @@ function QBCore.Functions.GetClosestPed(coords, ignoreList) else coords = GetEntityCoords(ped) end - local ignoreList = ignoreList or {} + ignoreList = ignoreList or {} local peds = QBCore.Functions.GetPeds(ignoreList) local closestDistance = -1 local closestPed = -1 @@ -432,12 +407,12 @@ function QBCore.Functions.GetVehicleProperties(vehicle) local colorPrimary, colorSecondary = GetVehicleColours(vehicle) if GetIsVehiclePrimaryColourCustom(vehicle) then - r, g, b = GetVehicleCustomPrimaryColour(vehicle) + local r, g, b = GetVehicleCustomPrimaryColour(vehicle) colorPrimary = {r, g, b} end if GetIsVehicleSecondaryColourCustom(vehicle) then - r, g, b = GetVehicleCustomSecondaryColour(vehicle) + local r, g, b = GetVehicleCustomSecondaryColour(vehicle) colorSecondary = {r, g, b} end @@ -454,11 +429,6 @@ function QBCore.Functions.GetVehicleProperties(vehicle) modLivery = GetVehicleLivery(vehicle) end - local neons = {} - for i = 0, 3 do - neons[i] = IsVehicleNeonLightEnabled(vehicle, i) - end - local tireHealth = {} for i = 0, 3 do tireHealth[i] = GetVehicleWheelHealth(vehicle, i) @@ -509,7 +479,12 @@ function QBCore.Functions.GetVehicleProperties(vehicle) windowStatus = windowStatus, doorStatus = doorStatus, xenonColor = GetVehicleXenonLightsColour(vehicle), - neonEnabled = neons, + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + }, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), headlightColor = GetVehicleHeadlightsColour(vehicle), interiorColor = GetVehicleInteriorColour(vehicle), @@ -677,9 +652,10 @@ function QBCore.Functions.SetVehicleProperties(vehicle, props) end end if props.neonEnabled then - for neonIndex, enableNeons in pairs(props.neonEnabled) do - SetVehicleNeonLightEnabled(vehicle, neonIndex, enableNeons) - end + 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.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) diff --git a/client/loops.lua b/client/loops.lua index 62b0f5d..925e588 100644 --- a/client/loops.lua +++ b/client/loops.lua @@ -12,7 +12,7 @@ end) CreateThread(function() while true do if LocalPlayer.state.isLoggedIn then - if (QBCore.PlayerData.metadata['hunger'] <= 0 or QBCore.PlayerData.metadata['thirst'] <= 0) and not QBCore.PlayerData.metadata['isdead'] then + if (QBCore.PlayerData.metadata['hunger'] <= 0 or QBCore.PlayerData.metadata['thirst'] <= 0) and not QBCore.PlayerData.metadata['isdead'] then local ped = PlayerPedId() local currentHealth = GetEntityHealth(ped) local decreaseTreshold = math.random(5, 10) diff --git a/client/main.lua b/client/main.lua index efa365b..80f9157 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,4 +10,4 @@ end) -- To use this export in a script instead of manifest method -- Just put this line of code below at the very top of the script --- local QBCore = exports['qb-core']:GetCoreObject() \ No newline at end of file +-- local QBCore = exports['qb-core']:GetCoreObject() diff --git a/config.lua b/config.lua index 43de9d5..6941fe4 100644 --- a/config.lua +++ b/config.lua @@ -9,7 +9,7 @@ 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.PayCheckTimeOut = 10 -- The time in minutes that it will give the paycheck -QBConfig.Money.PayCheckSociety = false -- If true paycheck will come from the society account that the player is employed at, requires qb-bossmenu +QBConfig.Money.PayCheckSociety = false -- If true paycheck will come from the society account that the player is employed at, requires qb-management QBConfig.Player = {} QBConfig.Player.MaxWeight = 120000 -- Max weight a player can carry (currently 120kg, written in grams) diff --git a/html/css/drawtext.css b/html/css/drawtext.css index 489e967..d4769a6 100644 --- a/html/css/drawtext.css +++ b/html/css/drawtext.css @@ -25,6 +25,20 @@ box-shadow: 0rem 0rem 0.1rem 0.05rem #000000; } +@media (width: 3840px) and (height: 2160px) { + #drawtext-container { + display: none; + width: 100%; + height: 100%; + overflow: hidden; + padding: 0; + margin: 0; + font-family: "Poppins", sans-serif !important; + font-weight: 300; + font-size: 1.5vh; + } +} + .text.pressed { background: var(--active-bg); } diff --git a/html/css/style.css b/html/css/style.css index 4581314..5842d7a 100644 --- a/html/css/style.css +++ b/html/css/style.css @@ -2,6 +2,49 @@ html::-webkit-scrollbar { display: none; } +@media (width: 3840px) and (height: 2160px) { + .success { + background-color: rgba(23, 23, 23, 90%); + border-radius: 10px; + box-shadow: 0rem 0rem 0.1rem 0.05rem #000000; + border-left: 0.5rem solid #20bb44; + font-size: 1.5vh; + } + + .primary { + background-color: rgba(23, 23, 23, 90%); + border-radius: 10px; + box-shadow: 0rem 0rem 0.1rem 0.05rem #000000; + border-left: 5px solid #1c75d2; + font-size: 1.5vh; + } + + .error { + background-color: rgba(23, 23, 23, 90%); + border-radius: 10px; + box-shadow: 0rem 0rem 0.1rem 0.05rem #000000; + border-left: 5px solid #c10114; + font-size: 1.5vh; + } + + .police { + background-color: rgba(23, 23, 23, 90%); + border-radius: 10px; + box-shadow: 0rem 0rem 0.1rem 0.05rem #000000; + border-left: 5px solid #2197f2; + font-size: 1.5vh; + } + + .ambulance { + background-color: rgba(23, 23, 23, 90%); + border-radius: 10px; + box-shadow: 0rem 0rem 0.1rem 0.05rem #000000; + border-left: 5px solid #f44236; + font-size: 1.5vh; + } + +} + .success { background-color: rgba(23, 23, 23, 90%); border-radius: 10px; diff --git a/locale/bg.lua b/locale/bg.lua new file mode 100644 index 0000000..547139a --- /dev/null +++ b/locale/bg.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + not_online = 'Играчът не е онлайн', + wrong_format = 'Некоректен формат', + missing_args = 'Не всички аргументи са въведени (x, y, z)', + missing_args2 = 'Всички аргументи трябва да бъдат попълнени!', + no_access = 'Нямате достъп до тази команда', + company_too_poor = 'Работодателят ви е разорен', + item_not_exist = 'Артикулът не съществува', + too_heavy = 'Ивентарът е препълнен', + duplicate_license = 'Намерен е дубликат на Rockstar лиценза', + no_valid_license = 'Не е намерен валиден Rockstar лиценз', + not_whitelisted = 'Вие не сте включени в белия списък за този сървър' + }, + success = {}, + info = { + received_paycheck = 'Получихте заплата от $%{value}', + job_info = 'Работно място: %{value} | Чин: %{value2} | Служба: %{value3}', + gang_info = 'Банда: %{value} | Чин: %{value2}', + on_duty = 'Сега сте на служба!', + off_duty = 'Вече не сте на служба!', + checking_ban = 'Здравейте %s. Проверяваме дали сте баннат.', + join_server = 'Добре дошли %s в {Server Name}.', + checking_whitelisted = 'Здравейте %s. Проверяваме дали сте включени в белия списък.' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) \ No newline at end of file diff --git a/locale/cn.lua b/locale/cn.lua index 40ceb80..b0dd4bb 100644 --- a/locale/cn.lua +++ b/locale/cn.lua @@ -5,17 +5,23 @@ local Translations = { missing_args = '请输入必须参数 (x, y, z)', missing_args2 = '请输入所有参数!', no_access = '你没有权限', - company_too_poor = '你的老板破产了', - item_not_exist = '物品不存在', - too_heavy = '背包已满' + company_too_poor = '你所在的公司账户目前发不起工资', + item_not_exist = '该物品不存在', + too_heavy = '背包已满', + duplicate_license = '发现重复的 Rockstar 许可证', + no_valid_license = '未找到有效的 Rockstar 许可证', + not_whitelisted = '您没有被列入此服务器的白名单' }, success = {}, info = { received_paycheck = '你收到了你的工资 $%{value}', - job_info = '工作: %{value} | 级别: %{value2} | 责任: %{value3}', - gang_info = '团队: %{value} | 级别: %{value2}', - on_duty = '你开始工作了!', - off_duty = '你现在下班了!' + job_info = '工作: %{value} | 级别: %{value2} | 工作状态状态: %{value3}', + gang_info = '帮派: %{value} | 级别: %{value2}', + on_duty = '你开始上班了!', + off_duty = '你现在下班了!', + checking_ban = '你好 %s. 我们正在检查你是否被服务器封禁.', + join_server = '欢迎 %s 进入 {Server Name}.', + checking_whitelisted = '你好 %s. 我们正在检查您是否在白名单内.' } } diff --git a/locale/cs.lua b/locale/cs.lua new file mode 100644 index 0000000..616c13d --- /dev/null +++ b/locale/cs.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + not_online = 'Hráč není online', + wrong_format = 'Nesprávný formát', + missing_args = 'Né všechny argumenty byly vyplněny (x, y, z)', + missing_args2 = 'Všechny argumenty musí být vyplněný!', + no_access = 'Nemáte přístup k tomuto příkazu', + company_too_poor = 'Váš zaměstnavatel nemá dostatek peněz, aby vás vyplatil', + item_not_exist = 'Předmět neexistuje', + too_heavy = 'Inventář je plný', + duplicate_license = 'Stejná Rockstar licence je již na serveru', + no_valid_license = 'Nebyla nalezena žádná platná Rockstar licence', + not_whitelisted = 'Nejste na whitelistu' + }, + success = {}, + info = { + received_paycheck = 'Obdrželi jste výplatu v hodnotě $%{value}', + job_info = 'Práce: %{value} | Pozice: %{value2} | Ve službě: %{value3}', + gang_info = 'Gang: %{value} | Pozice: %{value2}', + on_duty = 'Vešli jste do služby', + off_duty = 'Odešli jste ze služby!', + checking_ban = 'Ahoj %s. Kontrolujeme zda nejste zabanováni.', + join_server = 'Vítejte %s na {Server Name}.', + checking_whitelisted = 'Ahoj %s. Kontrolujeme zda máte přístup.' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/locale/de.lua b/locale/de.lua index 0c4107c..c7cf6f4 100644 --- a/locale/de.lua +++ b/locale/de.lua @@ -6,16 +6,22 @@ local Translations = { missing_args2 = 'Alle Argumente müssen ausgefüllt werden!', no_access = 'Kein Zugriff auf diesen Befehl', company_too_poor = 'Dein Arbeitgeber ist pleite', - item_not_exist = 'Gegenstand existiert nicht', - too_heavy = 'Inventar ist zu voll!' + item_not_exist = 'Item existiert nicht', + too_heavy = 'Inventar zu voll', + duplicate_license = 'Doppelte Rockstar-Lizenz gefunden', + no_valid_license = 'Keine gültige Rockstar-Lizenz gefunden', + not_whitelisted = 'Du bist nicht gewhitelistet für diesen Server' }, success = {}, info = { received_paycheck = 'Du hast deinen Gehalt über $%{value} erhalten', - job_info = 'Beruf: %{value} | Position: %{value2} | im Dienst: %{value3}', - gang_info = 'Gang: %{value} | Position: %{value2}', + job_info = 'Beruf: %{value} | Dienstgrad: %{value2} | im Dienst: %{value3}', + gang_info = 'Gang: %{value} | Rang: %{value2}', on_duty = 'Du bist jetzt im Dienst!', - off_duty = 'Du bist jetzt außer Dienst!' + off_duty = 'Du bist jetzt außer Dienst!', + checking_ban = 'Hallo %s. Wir prüfen gerade, ob du gebannt bist.', + join_server = 'Willkommen %s bei {Server Name}.', + checking_whitelisted = 'Hallo %s. Wir überprüfen gerade deine Erlaubnis.' } } diff --git a/locale/ee.lua b/locale/ee.lua new file mode 100644 index 0000000..8bd5da0 --- /dev/null +++ b/locale/ee.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + not_online = 'Mängija pole serveris!', + wrong_format = 'Vale formaat.', + missing_args = 'Kõiki argumente pole sisestatud (x, y, z)', + missing_args2 = 'Kõik argumendid tuleb täita!', + no_access = 'Sellele käsule pole juurdepääsu!', + company_too_poor = 'Teie tööandja on pankrotis.', + item_not_exist = 'Sellist asja ei eksisteeri', + too_heavy = 'Inventuur on liiga täis', + duplicate_license = 'Leiti Rockstari litsentsi duplikaat', + no_valid_license = 'Kehtivat Rockstari litsentsi ei leitud', + not_whitelisted = 'Te\'pole serveri Allowlistis!' + }, + success = {}, + info = { + received_paycheck = 'Saite oma töötasu kätte $%{value}', + job_info = 'Töökoht: %{value} | Auaste: %{value2} | Tööl: %{value3}', + gang_info = 'Gang: %{value} | Auaste: %{value2}', + on_duty = 'Alustasite enda tööpäeva!', + off_duty = 'Lõpetasite enda tööpäeva!', + checking_ban = 'Tere %s. Me kontrollime, kas olete keelustatud.', + join_server = 'Tere tulemast %s serverisse {Server Name}.', + checking_whitelisted = 'Tere %s. Kontrollime teie Allowlisti olemasolu.' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/locale/en.lua b/locale/en.lua index b9d91ae..202d41b 100644 --- a/locale/en.lua +++ b/locale/en.lua @@ -7,7 +7,10 @@ local Translations = { no_access = 'No access to this command', company_too_poor = 'Your employer is broke', item_not_exist = 'Item does not exist', - too_heavy = 'Inventory too full' + too_heavy = 'Inventory too full', + duplicate_license = 'Duplicate Rockstar License Found', + no_valid_license = 'No Valid Rockstar License Found', + not_whitelisted = 'You\'re not whitelisted for this server' }, success = {}, info = { @@ -15,7 +18,10 @@ local Translations = { job_info = 'Job: %{value} | Grade: %{value2} | Duty: %{value3}', gang_info = 'Gang: %{value} | Grade: %{value2}', on_duty = 'You are now on duty!', - off_duty = 'You are now off duty!' + off_duty = 'You are now off duty!', + checking_ban = 'Hello %s. We are checking if you are banned.', + join_server = 'Welcome %s to {Server Name}.', + checking_whitelisted = 'Hello %s. We are checking your allowance.' } } diff --git a/locale/es.lua b/locale/es.lua index 7e3ffdb..183cacf 100644 --- a/locale/es.lua +++ b/locale/es.lua @@ -1,25 +1,31 @@ local Translations = { error = { - not_online = 'El jugador no está conectado!', - wrong_format = 'Formato incorrecto!', - missing_args = 'No todos los argumentos estan presente! (x, y, z)', - missing_args2 = 'Todos los argumentos tienen que estar presente!', - no_access = 'No tienes acceso a este comando!', - company_too_poor = 'Tu empresa está en bancarrota. No hay dinero suficiente.', - item_not_exist = 'El objeto no existe en el sistema.', - too_heavy = 'Tienes el inventario muy lleno.' + not_online = 'El jugador no está en línea', + wrong_format = 'Formato incorrecto', + missing_args = 'No se han ingresado todos los argumentos (x, y, z)', + missing_args2 = '¡Todos los argumentos deben estar presentes!', + no_access = 'No tienes acceso a este comando', + company_too_poor = 'Tu empleador está en bancarrota', + item_not_exist = 'El objeto no existe', + too_heavy = 'Inventario muy lleno', + duplicate_license = 'Tu licencia de Rockstar está duplicada', + no_valid_license = 'No tienes licencia de Rockstar válida', + not_whitelisted = 'No estás en la lista blanca de este servidor' }, success = {}, info = { - received_paycheck = 'Has recibido tu pago de $%{value}', - job_info = 'Trabajo: %{value} | Grado: %{value2} | Estado: %{value3}', - gang_info = 'Pandilla: %{value} | Grado: %{value2}', - on_duty = 'Ahora estás en servicio!', - off_duty = 'Ahora estás fuera de servicio!' + received_paycheck = 'Has recibido tu salario de $%{value}', + job_info = 'Trabajo: %{value} | Puesto: %{value2} | Estado: %{value3}', + gang_info = 'Pandilla: %{value} | Puesto: %{value2}', + on_duty = '¡Estás en servicio!', + off_duty = '¡Estás fuera de servicio!', + checking_ban = 'Hola %s. Estámos revisando si has sido baneado.', + join_server = 'Bienvenido %s a {Server Name}.', + checking_whitelisted = 'Hola %s. Estámos revisando si estás en nuestra lista blanca.' } } Lang = Locale:new({ phrases = Translations, warnOnMissing = true -}) \ No newline at end of file +}) diff --git a/locale/et.lua b/locale/et.lua new file mode 100644 index 0000000..98802c9 --- /dev/null +++ b/locale/et.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + not_online = 'Mängija pole serveris', + wrong_format = 'Vale vorming', + missing_args = 'Kõiki argumente pole sisestatud (x, y, z)', + missing_args2 = 'Kõik argumendid tuleb täita!', + no_access = 'Sellele käsule pole juurdepääsu', + company_too_poor = 'Teie tööandja on võlgades', + item_not_exist = 'Asi ei eksisteeri', + too_heavy = 'Inventuur on liiga täis', + duplicate_license = 'Leiti Rockstari litsentsi duplikaat', + no_valid_license = 'Kehtivat Rockstari litsentsi ei leitud', + not_whitelisted = 'Te ei ole selle serveri jaoks Allowlisted' + }, + success = {}, + info = { + received_paycheck = 'Saite oma palga $%{value}', + job_info = 'Töö: %{value} | Auaste: %{value2} | Tööpostil: %{value3}', + gang_info = 'Gang: %{value} | Auaste: %{value2}', + on_duty = 'Sa oled tööle kirjutatud!', + off_duty = 'Sa kirjutasid ennast töölt vabaks!', + checking_ban = 'Tere %s. Me kontrollime, kas olete keelustatud.', + join_server = 'Tere tulemast %s serverisse {Server Name}.', + checking_whitelisted = 'Tere %s. Kontrollime teie Allowlisti staatust.' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/locale/fr.lua b/locale/fr.lua index 2a838c7..f072789 100644 --- a/locale/fr.lua +++ b/locale/fr.lua @@ -2,12 +2,15 @@ local Translations = { error = { not_online = 'Le joueur n\'est pas connecté', wrong_format = 'Format incorrect', - missing_args = 'Arguments manquant (x, y, z)', + missing_args = 'Arguments manquants (x, y, z)', missing_args2 = 'Tous les arguments doivent être remplis!', no_access = 'Vous n\'avez pas accès à cette commande', company_too_poor = 'Votre entreprise n\'a pas suffisamment d\'argent', item_not_exist = 'L\'objet n\'existe pas', - too_heavy = 'L\'inventaire est plein' + too_heavy = 'L\'inventaire est plein', + duplicate_license = 'License Rockstar Dupliquée trouvée', + no_valid_license = 'Aucune License Rockstar trouvée', + not_whitelisted = 'Vous n\'êtes pas sur la "whitelist" de ce serveur' }, success = {}, info = { @@ -15,11 +18,15 @@ local Translations = { job_info = 'Emplois: %{value} | Grade: %{value2} | Service: %{value3}', gang_info = 'Gang: %{value} | Grade: %{value2}', on_duty = 'Vous êtes désormais en service!', - off_duty = 'Vous n\'êtes plus en service!' + off_duty = 'Vous n\'êtes plus en service!', + checking_ban = 'Bonjour %s. Nous verifions si vous êtes banni.', + validatin_license = 'Bonjour %s. Nous validons votre License Rockstar.', + join_server = 'Bienvenue %s sur {Server Name}.', + checking_whitelisted = 'Bonjour %s. Nous vérifions si vous êtes sur la "whitelist".' } } Lang = Locale:new({ phrases = Translations, warnOnMissing = true -}) +}) diff --git a/locale/nl.lua b/locale/nl.lua index c99d359..fd19d57 100644 --- a/locale/nl.lua +++ b/locale/nl.lua @@ -7,7 +7,10 @@ local Translations = { no_access = 'Geen toegang tot dit commando', company_too_poor = 'Je werkgever is arm', item_not_exist = 'Item bestaat niet', - too_heavy = 'Inventaris is te vol' + too_heavy = 'Inventaris is te vol', + duplicate_license = 'Dubbele Rockstar-licentie gevonden', + no_valid_license = 'Geen geldige Rockstar-licentie gevonden', + not_whitelisted = 'Je staat niet op de whitelist voor deze server' }, success = {}, info = { @@ -15,7 +18,10 @@ local Translations = { job_info = 'Baan: %{value} | Rang: %{value2} | In dienst: %{value3}', gang_info = 'Gang: %{value} | Rang: %{value2}', on_duty = 'Je bent nu in dienst!', - off_duty = 'Je bent nu uit dienst!' + off_duty = 'Je bent nu uit dienst!', + checking_ban = 'Hallo %s. We controleren of je verbannen bent.', + join_server = 'Welkom %s bij {Server Name}.', + checking_whitelisted = 'Hallo %s. We controleren of je op de whitelist staat.' } } diff --git a/locale/pl.lua b/locale/pl.lua new file mode 100644 index 0000000..5e1704c --- /dev/null +++ b/locale/pl.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + not_online = 'Gracz nie jest online', + wrong_format = 'Nieprawidłowy format', + missing_args = 'Nie każdy argument został wprowadzony (x, y, z)', + missing_args2 = 'Wszystkie argumenty muszą być wypełnione!', + no_access = 'Brak dostępu do tego polecenia', + company_too_poor = 'Twój pracodawca jest spłukany', + item_not_exist = 'Przedmiot nie istnieje', + too_heavy = 'Ekwipunek jest zbyt pełny', + duplicate_license = 'Znaleziono zduplikowaną licencję Rockstar', + no_valid_license = 'Nie znaleziono ważnej licencji Rockstar', + not_whitelisted = 'Nie jesteś na białej liście tego serwera' + }, + success = {}, + info = { + received_paycheck = 'Otrzymałeś czek w wysokości $%{value}', + job_info = 'Praca: %{value} | Stopień: %{value2} | Służba: %{value3}', + gang_info = 'Gang: %{value} | Stopień: %{value2}', + on_duty = 'Jesteś teraz na służbie!', + off_duty = 'Jesteś teraz po służbie!', + checking_ban = 'Witaj %s. Sprawdzamy, czy jesteś zbanowany.', + join_server = 'Witaj %s na {Server Name}.', + checking_whitelisted = 'Witaj %s. Sprawdzamy Twoje kieszonkowe.' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/locale/pt-br.lua b/locale/pt-br.lua new file mode 100644 index 0000000..9621437 --- /dev/null +++ b/locale/pt-br.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + not_online = 'O jogador não está online', + wrong_format = 'Formato inválido', + missing_args = 'Nem todos os argumentos foram inseridos (x, y, z)', + missing_args2 = 'Todos os argumentos devem ser preenchidos!', + no_access = 'Sem acesso a este comando', + company_too_poor = 'Sua compania está quebrada', + item_not_exist = 'O item não existe', + too_heavy = 'Inventário cheio', + duplicate_license = 'Licença duplicada da Rockstar encontrada', + no_valid_license = 'Nenhuma licença válida da Rockstar encontrada', + not_whitelisted = 'Você não tem whitelist neste servidor' + }, + success = {}, + info = { + received_paycheck = 'Você recebeu seu salário de %{value}€', + job_info = 'Emprego: %{value} | Grau: %{value2} | Serviço: %{value3}', + gang_info = 'Gang: %{value} | Grau: %{value2}', + on_duty = 'Você agora está de plantão!', + off_duty = 'Você agora está de folga!', + checking_ban = 'Olá %s. Estamos verificando se você foi banido.', + join_server = 'Bem-vindo %s a {Server Name}.', + checking_whitelisted = 'Olá %s. Estamos verificando sua whitelist.' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/locale/rs.lua b/locale/rs.lua new file mode 100644 index 0000000..bf20832 --- /dev/null +++ b/locale/rs.lua @@ -0,0 +1,25 @@ +local Translations = { + error = { + not_online = 'Igrac nije online', + wrong_format = 'Netacan format', + missing_args = 'Nije unet svaki argument (x, y, z)', + missing_args2 = 'Svi argumenti moraju biti popunjeni!', + no_access = 'Nemate pristup ovoj komandi', + company_too_poor = 'Vas poslodavac nema para', + item_not_exist = 'Stavka ne postoji', + too_heavy = 'Inventar je prepun' + }, + success = {}, + info = { + received_paycheck = 'Dobili ste platu u iznosu od $%{value}', + job_info = 'Posao: %{value} | Rank: %{value2} | Duznost: %{value3}', + gang_info = 'Banda: %{value} | Rank: %{value2}', + on_duty = 'Sada ste na duznosti!', + off_duty = 'Sada ste van duznosti!' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/locale/th.lua b/locale/th.lua new file mode 100644 index 0000000..c070c7a --- /dev/null +++ b/locale/th.lua @@ -0,0 +1,25 @@ +local Translations = { + error = { + not_online = 'ผู้เล่นไม่ออนไลน์', + wrong_format = 'รูปแบบไม่ถูกต้อง', + missing_args = 'ไม่ได้ป้อนทุกอาร์กิวเมนต์ (x, y, z)', + missing_args2 = 'จะต้องกรอกอาร์กิวเมนต์ทั้งหมด', + no_access = 'ไม่มีสิทธิ์เข้าถึงคำสั่งนี้', + company_too_poor = 'ผู้ว่าจ้างของคุณยากจนมาก', + item_not_exist = 'ไม่มีรายการนี้', + too_heavy = 'สินค้าในคลังเต็มแล้ว' + }, + success = {}, + info = { + received_paycheck = 'คุณได้รับเงินเดือนเป็นเงิน $%{value}', + job_info = 'อาชีพ: %{value} | ระดับ: %{value2} | อยู่ในหน้าที่: %{value3}', + gang_info = 'แก๊ง: %{value} | ระดับ: %{value2}', + on_duty = 'ตอนนี้คุณอยู่ในหน้าที่แล้ว', + off_duty = 'ตอนนี้คุณออกหน้าที่แล้ว' + } +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/qbcore.sql b/qbcore.sql index f0f6880..ee0d6d8 100644 --- a/qbcore.sql +++ b/qbcore.sql @@ -18,15 +18,6 @@ CREATE TABLE IF NOT EXISTS `players` ( KEY `license` (`license`) ) ENGINE=InnoDB AUTO_INCREMENT=1; -CREATE TABLE IF NOT EXISTS `permissions` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `license` varchar(255) NOT NULL, - `permission` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - KEY `license` (`license`) -) ENGINE=InnoDB AUTO_INCREMENT=1; - CREATE TABLE IF NOT EXISTS `bans` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, diff --git a/server/commands.lua b/server/commands.lua index 457277d..fdcf590 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -6,7 +6,7 @@ QBCore.Commands.IgnoreList = { -- Ignore old perm levels while keeping backwards } CreateThread(function() -- Add ace to node for perm checking - for k,v in pairs(QBConfig.Server.Permissions) do + for _, v in pairs(QBConfig.Server.Permissions) do ExecuteCommand(('add_ace qbcore.%s %s allow'):format(v, v)) end end) @@ -65,9 +65,9 @@ QBCore.Commands.Add('tp', 'TP To Player or Coords (Admin Only)', { { name = 'id/ end else if args[1] and args[2] and args[3] then - local x = tonumber(args[1]) - local y = tonumber(args[2]) - local z = tonumber(args[3]) + local x = tonumber((args[1]:gsub(",",""))) + .0 + local y = tonumber((args[2]:gsub(",",""))) + .0 + local z = tonumber((args[3]:gsub(",",""))) + .0 if x ~= 0 and y ~= 0 and z ~= 0 then TriggerClientEvent('QBCore:Command:TeleportToCoords', source, x, y, z) else @@ -208,7 +208,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) - local playerId = args[1] and args[1] ~= '' or source + local playerId = args[1] ~= '' and args[1] or source local Player = QBCore.Functions.GetPlayer(tonumber(playerId)) if Player then Player.Functions.ClearInventory() @@ -224,7 +224,7 @@ QBCore.Commands.Add('ooc', 'OOC Chat Message', {}, false, function(source, args) local Players = QBCore.Functions.GetPlayers() local Player = QBCore.Functions.GetPlayer(source) local playerCoords = GetEntityCoords(GetPlayerPed(source)) - for k, v in pairs(Players) do + for _, v in pairs(Players) do if v == source then TriggerClientEvent('chat:addMessage', v, { color = { 0, 0, 255}, @@ -253,16 +253,17 @@ end, 'user') -- Me command QBCore.Commands.Add('me', 'Show local message', {{name = 'message', help = 'Message to respond with'}}, false, function(source, args) + if #args < 1 then TriggerClientEvent('QBCore:Notify', source, Lang:t('error.missing_args2'), 'error') return end local ped = GetPlayerPed(source) local pCoords = GetEntityCoords(ped) - local msg = table.concat(args, ' ') - if msg == '' then return end - if string.match(msg, "<") then TriggerClientEvent('QBCore:Notify', source, Lang:t('error.wrong_format'), 'error') return end - for k,v in pairs(QBCore.Functions.GetPlayers()) do - local target = GetPlayerPed(v) + local msg = table.concat(args, ' '):gsub('[~<].-[>~]', '') + local Players = QBCore.Functions.GetPlayers() + for i=1, #Players do + local Player = Players[i] + local target = GetPlayerPed(Player) local tCoords = GetEntityCoords(target) - if #(pCoords - tCoords) < 20 then - TriggerClientEvent('QBCore:Command:ShowMe3D', v, source, msg) + if target == ped or #(pCoords - tCoords) < 20 then + TriggerClientEvent('QBCore:Command:ShowMe3D', Player, source, msg) end end end, 'user') diff --git a/server/debug.lua b/server/debug.lua index 7a8a9cf..9b4b3b2 100644 --- a/server/debug.lua +++ b/server/debug.lua @@ -42,4 +42,4 @@ end function QBCore.ShowSuccess(resource, msg) print('\x1b[32m['..resource..':LOG]\x1b[0m '..msg) -end \ No newline at end of file +end diff --git a/server/events.lua b/server/events.lua index c48160e..3b2ceab 100644 --- a/server/events.lua +++ b/server/events.lua @@ -1,10 +1,17 @@ -- Event Handler -AddEventHandler('playerDropped', function() +AddEventHandler('chatMessage', function(_, _, message) + if string.sub(message, 1, 1) == '/' then + CancelEvent() + return + end +end) + +AddEventHandler('playerDropped', function(reason) local src = source if not QBCore.Players[src] then return end local Player = QBCore.Players[src] - TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**' .. GetPlayerName(src) .. '** (' .. Player.PlayerData.license .. ') left..') + TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**' .. GetPlayerName(src) .. '** (' .. Player.PlayerData.license .. ') left..' ..'\n **Reason:** ' .. reason) Player.Functions.Save() QBCore.Player_Buckets[Player.PlayerData.license] = nil QBCore.Players[src] = nil @@ -27,7 +34,7 @@ local function onPlayerConnecting(name, setKickReason, deferrals) end end - deferrals.update(string.format('Hello %s. Validating Your Rockstar License', name)) + deferrals.update(string.format(Lang:t('info.checking_ban'), name)) for _, v in pairs(identifiers) do if string.find(v, 'license') then @@ -39,7 +46,7 @@ local function onPlayerConnecting(name, setKickReason, deferrals) -- Mandatory wait Wait(2500) - deferrals.update(string.format('Hello %s. We are checking your allowance.', name)) + deferrals.update(string.format(Lang:t('info.checking_whitelisted'), name)) local isBanned, Reason = QBCore.Functions.IsPlayerBanned(src) local isLicenseAlreadyInUse = QBCore.Functions.IsLicenseInUse(license) @@ -47,16 +54,16 @@ local function onPlayerConnecting(name, setKickReason, deferrals) Wait(2500) - deferrals.update(string.format('Welcome %s to {Server Name}.', name)) + deferrals.update(string.format(Lang:t('info.join_server'), name)) if not license then - deferrals.done('No Valid Rockstar License Found') + deferrals.done(Lang:t('error.no_valid_license')) elseif isBanned then deferrals.done(Reason) elseif isLicenseAlreadyInUse and QBCore.Config.Server.CheckDuplicateLicense then - deferrals.done('Duplicate Rockstar License Found') + deferrals.done(Lang:t('error.duplicate_license')) elseif isWhitelist and not whitelisted then - deferrals.done('You\'re not whitelisted for this server') + deferrals.done(Lang:t('error.not_whitelisted')) else deferrals.done() if QBCore.Config.Server.UseConnectQueue then @@ -128,14 +135,13 @@ end) RegisterNetEvent('QBCore:Server:SetMetaData', function(meta, data) local src = source local Player = QBCore.Functions.GetPlayer(src) + if not Player then return end if meta == 'hunger' or meta == 'thirst' then if data > 100 then data = 100 end end - if Player then - Player.Functions.SetMetaData(meta, data) - end + Player.Functions.SetMetaData(meta, data) TriggerClientEvent('hud:client:UpdateNeeds', src, Player.PlayerData.metadata['hunger'], Player.PlayerData.metadata['thirst']) end) @@ -182,7 +188,7 @@ RegisterNetEvent('QBCore:CallCommand', function(command, args) if not QBCore.Commands.List[command] then return end local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local hasPerm = QBCore.Functions.HasPermission(src, QBCore.Commands.List[command].permission) + local hasPerm = QBCore.Functions.HasPermission(src, "command."..QBCore.Commands.List[command].name) if hasPerm then if QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and not args[#QBCore.Commands.List[command].arguments] then TriggerClientEvent('QBCore:Notify', src, Lang:t('error.missing_args2'), 'error') @@ -200,52 +206,32 @@ QBCore.Functions.CreateCallback('QBCore:HasItem', function(source, cb, items, am local retval = false local Player = QBCore.Functions.GetPlayer(source) if not Player then return cb(false) end - 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 finalcount += 1 end - local item = Player.Functions.GetItemByName(k) - if item then - if item.amount >= v then - 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 += 1 - if count == finalcount then - retval = true - end - end - else - count += 1 - if count == finalcount then - retval = true - end - end - end + local isTable = type(items) == 'table' + local isArray = isTable and table.type(items) == 'array' or false + local totalItems = #items + local count = 0 + local kvIndex = 2 + if isTable and not isArray then + totalItems = 0 + for _ in pairs(items) do totalItems += 1 end + kvIndex = 1 + end + if isTable then + for k, v in pairs(items) do + local itemKV = {k, v} + local item = Player.Functions.GetItemByName(itemKV[kvIndex]) + if item and ((amount and item.amount >= amount) or (not amount and not isArray and item.amount >= v) or (not amount and isArray)) then + count += 1 end - end - else - local item = Player.Functions.GetItemByName(items) - if not item then return cb(false) end - if amount then - if item.amount >= amount then - retval = true - end - else + end + if count == totalItems then + retval = true + end + else -- Single item as string + local item = Player.Functions.GetItemByName(items) + if item and not amount or (amount and item.amount >= amount) then retval = true end - end + end cb(retval) end) diff --git a/server/exports.lua b/server/exports.lua index 2cfed5a..3b50fb1 100644 --- a/server/exports.lua +++ b/server/exports.lua @@ -65,6 +65,22 @@ end QBCore.Functions.AddItem = AddItem exports('AddItem', AddItem) +-- Single update item +local function UpdateItem(itemName, item) + if type(itemName) ~= "string" then + return false, "invalid_item_name" + end + if not QBCore.Shared.Items[itemName] then + return false, "item_not_exists" + end + QBCore.Shared.Items[itemName] = item + TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Items', itemName, item) + TriggerEvent('QBCore:Server:UpdateObject') + return true, "success" +end +QBCore.Functions.UpdateItem = UpdateItem +exports('UpdateItem', UpdateItem) + -- Multiple Add Items local function AddItems(items) local shouldContinue = true @@ -152,3 +168,19 @@ local function GetCoreVersion(InvokingResource) end QBCore.Functions.GetCoreVersion = GetCoreVersion exports('GetCoreVersion', GetCoreVersion) + +local function ExploitBan(playerId, origin) + local name = GetPlayerName(playerId) + MySQL.insert('INSERT INTO bans (name, license, discord, ip, reason, expire, bannedby) VALUES (?, ?, ?, ?, ?, ?, ?)', { + name, + QBCore.Functions.GetIdentifier(playerId, 'license'), + QBCore.Functions.GetIdentifier(playerId, 'discord'), + QBCore.Functions.GetIdentifier(playerId, 'ip'), + origin, + 2147483647, + 'Anti Cheat' + }) + DropPlayer(playerId, "You have been banned for cheating. Check our Discord for more information: " .. QBCore.Config.Server.Discord) + TriggerEvent("qb-log:server:CreateLog", "anticheat", "Anti-Cheat", "red", name.." has been banned for exploiting "..origin, true) +end +exports('ExploitBan', ExploitBan) diff --git a/server/functions.lua b/server/functions.lua index 95b302d..1b9b16f 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -63,7 +63,7 @@ end function QBCore.Functions.GetPlayers() local sources = {} - for k, v in pairs(QBCore.Players) do + for k, _ in pairs(QBCore.Players) do sources[#sources+1] = k end return sources @@ -137,7 +137,7 @@ end function QBCore.Functions.GetPlayersInBucket(bucket --[[ int ]]) local curr_bucket_pool = {} if QBCore.Player_Buckets and next(QBCore.Player_Buckets) then - for k, v in pairs(QBCore.Player_Buckets) do + for _, v in pairs(QBCore.Player_Buckets) do if v.bucket == bucket then curr_bucket_pool[#curr_bucket_pool + 1] = v.id end @@ -152,7 +152,7 @@ end function QBCore.Functions.GetEntitiesInBucket(bucket --[[ int ]]) local curr_bucket_pool = {} if QBCore.Entity_Buckets and next(QBCore.Entity_Buckets) then - for k, v in pairs(QBCore.Entity_Buckets) do + for _, v in pairs(QBCore.Entity_Buckets) do if v.bucket == bucket then curr_bucket_pool[#curr_bucket_pool + 1] = v.id end @@ -236,7 +236,7 @@ function QBCore.Functions.Kick(source, reason, setKickReason, deferrals) if source then DropPlayer(source, reason) end - for i = 0, 4 do + for _ = 0, 4 do while true do if source then if GetPlayerPing(source) >= 0 then @@ -279,7 +279,7 @@ function QBCore.Functions.RemovePermission(source, permission) QBCore.Commands.Refresh(src) end else - for k,v in pairs(QBCore.Config.Server.Permissions) do + for _, v in pairs(QBCore.Config.Server.Permissions) do if IsPlayerAceAllowed(src, v) then ExecuteCommand(('remove_principal identifier.%s qbcore.%s'):format(license, v)) QBCore.Commands.Refresh(src) @@ -299,7 +299,7 @@ end function QBCore.Functions.GetPermission(source) local src = source local perms = {} - for k,v in pairs (QBCore.Config.Server.Permissions) do + for _, v in pairs (QBCore.Config.Server.Permissions) do if IsPlayerAceAllowed(src, v) then perms[v] = true end @@ -328,13 +328,13 @@ end function QBCore.Functions.IsPlayerBanned(source) local plicense = QBCore.Functions.GetIdentifier(source, 'license') - local result = MySQL.Sync.fetchSingle('SELECT * FROM bans WHERE license = ?', { plicense }) + local result = MySQL.single.await('SELECT * FROM bans WHERE license = ?', { plicense }) if not result then return false end if os.time() < result.expire then local timeTable = os.date('*t', tonumber(result.expire)) return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n' else - MySQL.Async.execute('DELETE FROM bans WHERE id = ?', { result.id }) + MySQL.query('DELETE FROM bans WHERE id = ?', { result.id }) end return false end diff --git a/server/main.lua b/server/main.lua index 41c0c43..722e84b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -10,4 +10,4 @@ end) -- To use this export in a script instead of manifest method -- Just put this line of code below at the very top of the script --- local QBCore = exports['qb-core']:GetCoreObject() \ No newline at end of file +-- local QBCore = exports['qb-core']:GetCoreObject() diff --git a/server/player.lua b/server/player.lua index bbf0751..5fe4915 100644 --- a/server/player.lua +++ b/server/player.lua @@ -9,7 +9,7 @@ function QBCore.Player.Login(source, citizenid, newData) if source and source ~= '' then if citizenid then local license = QBCore.Functions.GetIdentifier(source, 'license') - local PlayerData = MySQL.Sync.prepare('SELECT * FROM players where citizenid = ?', { citizenid }) + local PlayerData = MySQL.prepare.await('SELECT * FROM players where citizenid = ?', { citizenid }) if PlayerData and license == PlayerData.license then PlayerData.money = json.decode(PlayerData.money) PlayerData.job = json.decode(PlayerData.job) @@ -56,7 +56,7 @@ function QBCore.Player.CheckPlayerData(source, PlayerData) 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 or QBCore.Functions.CreatePhoneNumber() + PlayerData.charinfo.phone = tonumber(PlayerData.charinfo.phone) or QBCore.Functions.CreatePhoneNumber() PlayerData.charinfo.account = PlayerData.charinfo.account or QBCore.Functions.CreateAccountNumber() -- Metadata PlayerData.metadata = PlayerData.metadata or {} @@ -240,9 +240,9 @@ function QBCore.Player.CreatePlayer(PlayerData) 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) + 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] .. ' reason: ' .. reason, 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]) + 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] .. ' reason: ' .. reason) end TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, false) return true @@ -264,9 +264,9 @@ function QBCore.Player.CreatePlayer(PlayerData) 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) + 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] .. ' reason: ' .. reason, 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]) + 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] .. ' reason: ' .. reason) end TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, true) if moneytype == 'bank' then @@ -283,7 +283,7 @@ function QBCore.Player.CreatePlayer(PlayerData) if not self.PlayerData.money[moneytype] then return false end 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]) + 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] .. ' reason: ' .. reason) return true end @@ -353,16 +353,16 @@ function QBCore.Player.CreatePlayer(PlayerData) 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 + 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) + 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 + 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') + 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 @@ -447,7 +447,7 @@ function QBCore.Player.Save(source) local pcoords = GetEntityCoords(ped) local PlayerData = QBCore.Players[source].PlayerData if PlayerData then - MySQL.Async.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', { + MySQL.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, @@ -476,7 +476,6 @@ local playertables = { -- Add tables as needed { table = 'phone_invoices' }, { table = 'phone_messages' }, { table = 'playerskins' }, - { table = 'player_boats' }, { table = 'player_contacts' }, { table = 'player_houses' }, { table = 'player_mails' }, @@ -486,7 +485,7 @@ local playertables = { -- Add tables as needed function QBCore.Player.DeleteCharacter(source, citizenid) local license = QBCore.Functions.GetIdentifier(source, 'license') - local result = MySQL.Sync.fetchScalar('SELECT license FROM players where citizenid = ?', { citizenid }) + local result = MySQL.scalar.await('SELECT license FROM players where citizenid = ?', { citizenid }) if license == result then local query = "DELETE FROM %s WHERE citizenid = ?" local tableCount = #playertables @@ -497,8 +496,8 @@ function QBCore.Player.DeleteCharacter(source, citizenid) queries[i] = {query = query:format(v.table), values = { citizenid }} end - MySQL.Async.transaction(queries, function(result) - if result then + MySQL.transaction(queries, function(result2) + if result2 then TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Character Deleted', 'red', '**' .. GetPlayerName(source) .. '** ' .. license .. ' deleted **' .. citizenid .. '**..') end end) @@ -512,7 +511,7 @@ end function QBCore.Player.LoadInventory(PlayerData) PlayerData.items = {} - local inventory = MySQL.Sync.prepare('SELECT inventory FROM players WHERE citizenid = ?', { PlayerData.citizenid }) + local inventory = MySQL.prepare.await('SELECT inventory FROM players WHERE citizenid = ?', { PlayerData.citizenid }) local missingItems = {} if inventory then inventory = json.decode(inventory) @@ -568,9 +567,9 @@ function QBCore.Player.SaveInventory(source) } end end - MySQL.Async.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid }) + MySQL.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid }) else - MySQL.Async.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid }) + MySQL.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid }) end end @@ -611,7 +610,7 @@ function QBCore.Player.CreateCitizenId() local CitizenId = nil while not UniqueFound do CitizenId = tostring(QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(5)):upper() - local result = MySQL.Sync.prepare('SELECT COUNT(*) as count FROM players WHERE citizenid = ?', { CitizenId }) + local result = MySQL.prepare.await('SELECT COUNT(*) as count FROM players WHERE citizenid = ?', { CitizenId }) if result == 0 then UniqueFound = true end @@ -625,7 +624,7 @@ function QBCore.Functions.CreateAccountNumber() while not UniqueFound do AccountNumber = 'US0' .. math.random(1, 9) .. 'QBCore' .. math.random(1111, 9999) .. math.random(1111, 9999) .. math.random(11, 99) local query = '%' .. AccountNumber .. '%' - local result = MySQL.Sync.prepare('SELECT COUNT(*) as count FROM players WHERE charinfo LIKE ?', { query }) + local result = MySQL.prepare.await('SELECT COUNT(*) as count FROM players WHERE charinfo LIKE ?', { query }) if result == 0 then UniqueFound = true end @@ -637,9 +636,9 @@ function QBCore.Functions.CreatePhoneNumber() local UniqueFound = false local PhoneNumber = nil while not UniqueFound do - PhoneNumber = math.random(100,999) .. math.random(1000000,9999999) + PhoneNumber = tonumber(math.random(100,999) .. math.random(1000000,9999999)) local query = '%' .. PhoneNumber .. '%' - local result = MySQL.Sync.prepare('SELECT COUNT(*) as count FROM players WHERE charinfo LIKE ?', { query }) + local result = MySQL.prepare.await('SELECT COUNT(*) as count FROM players WHERE charinfo LIKE ?', { query }) if result == 0 then UniqueFound = true end @@ -653,7 +652,7 @@ function QBCore.Player.CreateFingerId() 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 = MySQL.Sync.prepare('SELECT COUNT(*) as count FROM `players` WHERE `metadata` LIKE ?', { query }) + local result = MySQL.prepare.await('SELECT COUNT(*) as count FROM `players` WHERE `metadata` LIKE ?', { query }) if result == 0 then UniqueFound = true end @@ -667,7 +666,7 @@ function QBCore.Player.CreateWalletId() while not UniqueFound do WalletId = 'QB-' .. math.random(11111111, 99999999) local query = '%' .. WalletId .. '%' - local result = MySQL.Sync.prepare('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) + local result = MySQL.prepare.await('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) if result == 0 then UniqueFound = true end @@ -681,7 +680,7 @@ function QBCore.Player.CreateSerialNumber() while not UniqueFound do SerialNumber = math.random(11111111, 99999999) local query = '%' .. SerialNumber .. '%' - local result = MySQL.Sync.prepare('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) + local result = MySQL.prepare.await('SELECT COUNT(*) as count FROM players WHERE metadata LIKE ?', { query }) if result == 0 then UniqueFound = true end diff --git a/shared/items.lua b/shared/items.lua index 546a0c2..d58cd32 100644 --- a/shared/items.lua +++ b/shared/items.lua @@ -244,7 +244,7 @@ QBShared.Items = { ['shotgun_ammo'] = {['name'] = 'shotgun_ammo', ['label'] = 'Shotgun ammo', ['weight'] = 500, ['type'] = 'item', ['image'] = 'shotgun_ammo.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Ammo for Shotguns'}, ['mg_ammo'] = {['name'] = 'mg_ammo', ['label'] = 'MG ammo', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'mg_ammo.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Ammo for Machine Guns'}, ['snp_ammo'] = {['name'] = 'snp_ammo', ['label'] = 'Sniper ammo', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'rifle_ammo.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Ammo for Sniper Rifles'}, - ['emp_ammo'] = {['name'] = 'emp_ammo', ['label'] = 'EMP Ammo', ['weight'] = 200, ['type'] = 'item', ['image'] = 'emp_ammo.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Ammo for EMP Launcher'}, + ['emp_ammo'] = {['name'] = 'emp_ammo', ['label'] = 'EMP Ammo', ['weight'] = 200, ['type'] = 'item', ['image'] = 'emp_ammo.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Ammo for EMP Launcher'}, -- Card ITEMS ['id_card'] = {['name'] = 'id_card', ['label'] = 'ID Card', ['weight'] = 0, ['type'] = 'item', ['image'] = 'id_card.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'A card containing all your information to identify yourself'}, diff --git a/shared/locale.lua b/shared/locale.lua index eb7e462..6b9510b 100644 --- a/shared/locale.lua +++ b/shared/locale.lua @@ -31,7 +31,6 @@ end --- @param opts table - Constructor opts param --- @return Locale function Locale:new(opts) - local self = {} setmetatable(self, Locale) self.warnOnMissing = opts.warnOnMissing or true @@ -135,4 +134,4 @@ function Locale:delete(phraseTarget, prefix) end end end -end \ No newline at end of file +end diff --git a/shared/main.lua b/shared/main.lua index cace3c0..2319bc9 100644 --- a/shared/main.lua +++ b/shared/main.lua @@ -155,4 +155,4 @@ QBShared.FemaleNoGloves = { [157] = true, [161] = true, [165] = true -} \ No newline at end of file +} diff --git a/shared/vehicles.lua b/shared/vehicles.lua index 7c41559..79e9afc 100644 --- a/shared/vehicles.lua +++ b/shared/vehicles.lua @@ -1,4 +1,6 @@ QBShared = QBShared or {} +QBShared.VehicleHashes = {} + QBShared.Vehicles = { --- Compacts ['asbo'] = { @@ -4418,3 +4420,7 @@ QBShared.Vehicles = { ['shop'] = 'air', }, } + +for _, v in pairs(QBShared.Vehicles) do + QBShared.VehicleHashes[v.hash] = v +end diff --git a/shared/weapons.lua b/shared/weapons.lua index af0df12..148a40d 100644 --- a/shared/weapons.lua +++ b/shared/weapons.lua @@ -145,4 +145,4 @@ QBShared.Weapons = { -- Animals [`weapon_animal`] = {['name'] = 'weapon_animal', ['label'] = 'Animal', ['ammotype'] = nil, ['damagereason'] = 'Mauled'}, [`weapon_cougar`] = {['name'] = 'weapon_cougar', ['label'] = 'Cougar', ['ammotype'] = nil, ['damagereason'] = 'Mauled'}, -} \ No newline at end of file +}