Merge branch 'main' into patch-1

This commit is contained in:
Kakarot
2022-06-15 17:43:04 -07:00
committed by GitHub
27 changed files with 349 additions and 176 deletions
+74
View File
@@ -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
+23
View File
@@ -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
+1 -14
View File
@@ -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
+2 -2
View File
@@ -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',
+3 -2
View File
@@ -127,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)
@@ -147,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)
+3 -36
View File
@@ -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)
@@ -219,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
@@ -440,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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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()
-- local QBCore = exports['qb-core']:GetCoreObject()
+31
View File
@@ -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
})
+13 -7
View File
@@ -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. 我们正在检查您是否在白名单内.'
}
}
+20 -14
View File
@@ -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
})
})
+31
View File
@@ -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
})
+1 -1
View File
@@ -29,4 +29,4 @@ local Translations = {
Lang = Locale:new({
phrases = Translations,
warnOnMissing = true
})
})
+8 -2
View File
@@ -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.'
}
}
+31
View File
@@ -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
})
+2 -2
View File
@@ -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)
@@ -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},
+1 -1
View File
@@ -42,4 +42,4 @@ end
function QBCore.ShowSuccess(resource, msg)
print('\x1b[32m['..resource..':LOG]\x1b[0m '..msg)
end
end
+31 -52
View File
@@ -1,17 +1,17 @@
-- Event Handler
AddEventHandler('chatMessage', function(source, _, message)
AddEventHandler('chatMessage', function(_, _, message)
if string.sub(message, 1, 1) == '/' then
CancelEvent()
return
end
end)
AddEventHandler('playerDropped', function()
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
@@ -57,13 +57,13 @@ local function onPlayerConnecting(name, setKickReason, deferrals)
deferrals.update(string.format(Lang:t('info.join_server'), name))
if not license then
deferrals.done(Lang:t('error.no_valid_license'))
deferrals.done(Lang:t('error.no_valid_license'))
elseif isBanned then
deferrals.done(Reason)
elseif isLicenseAlreadyInUse and QBCore.Config.Server.CheckDuplicateLicense then
deferrals.done(Lang:t('error.duplicate_license'))
elseif isWhitelist and not whitelisted then
deferrals.done(Lang:t('error.not_whitelisted'))
deferrals.done(Lang:t('error.not_whitelisted'))
else
deferrals.done()
if QBCore.Config.Server.UseConnectQueue then
@@ -135,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)
@@ -207,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)
+32
View File
@@ -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)
+8 -8
View File
@@ -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
+1 -1
View File
@@ -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()
-- local QBCore = exports['qb-core']:GetCoreObject()
+26 -26
View File
@@ -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)
@@ -238,9 +238,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
@@ -262,9 +262,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
@@ -281,7 +281,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
@@ -351,16 +351,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
@@ -445,7 +445,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,
@@ -483,7 +483,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
@@ -494,8 +494,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)
@@ -509,7 +509,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)
@@ -565,9 +565,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
@@ -608,7 +608,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
@@ -622,7 +622,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
@@ -636,7 +636,7 @@ function QBCore.Functions.CreatePhoneNumber()
while not UniqueFound do
PhoneNumber = 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
@@ -650,7 +650,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
@@ -664,7 +664,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
@@ -678,7 +678,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
+1 -1
View File
@@ -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'},
+1 -2
View File
@@ -31,7 +31,6 @@ end
--- @param opts table<string, any> - 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
end
+1 -1
View File
@@ -155,4 +155,4 @@ QBShared.FemaleNoGloves = {
[157] = true,
[161] = true,
[165] = true
}
}
+1 -1
View File
@@ -4421,6 +4421,6 @@ QBShared.Vehicles = {
},
}
for k,v in pairs(QBShared.Vehicles) do
for _, v in pairs(QBShared.Vehicles) do
QBShared.VehicleHashes[v.hash] = v
end
+1 -1
View File
@@ -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'},
}
}