structura foldere

mutat kq- folders in un singur folder [kq]
This commit is contained in:
2026-03-30 01:55:03 +03:00
parent af1286d583
commit c291b81f26
2319 changed files with 0 additions and 14 deletions

View File

@@ -0,0 +1,142 @@
RegisterNUICallback('GetCryptoData', function(data, cb)
TriggerServerCallback('qb-crypto:server:GetCryptoData', function(CryptoData)
cb(CryptoData)
end, data.crypto)
end)
RegisterNUICallback('BuyCrypto', function(data, cb)
TriggerServerCallback('qb-crypto:server:BuyCrypto', function(CryptoData)
cb(CryptoData)
end, data)
end)
RegisterNUICallback('SellCrypto', function(data, cb)
TriggerServerCallback('qb-crypto:server:SellCrypto', function(CryptoData)
cb(CryptoData)
end, data)
end)
RegisterNUICallback('TransferCrypto', function(data, cb)
TriggerServerCallback('qb-crypto:server:TransferCrypto', function(CryptoData)
cb(CryptoData)
end, data)
end)
RegisterNUICallback('GetCryptoTransactions', function(data, cb)
local Data = {
CryptoTransactions = PhoneData.CryptoTransactions
}
cb(Data)
end)
RegisterNetEvent('phone:client:AddTransaction', function(_, _, Message, Title)
local Data = {
TransactionTitle = Title,
TransactionMessage = Message,
}
PhoneData.CryptoTransactions[#PhoneData.CryptoTransactions + 1] = Data
SendNUIMessage({
action = 'UpdateTransactions',
CryptoTransactions = PhoneData.CryptoTransactions
})
SendTempNotificationOld({
title = Lang('PHONE_NOTIFICATION_STOCK_TITLE'),
app = 'stock',
text = Message,
timeout = 3500,
})
TriggerServerEvent('phone:server:AddTransaction', Data)
end)
local function ExchangeSuccess()
TriggerServerEvent('qb-crypto:server:ExchangeSuccess', math.random(1, 10))
end
local function ExchangeFail()
local Odd = 5
local RemoveChance = math.random(1, Odd)
local LosingNumber = math.random(1, Odd)
if RemoveChance == LosingNumber then
TriggerServerEvent('qb-crypto:server:ExchangeFail')
TriggerServerEvent('qb-crypto:server:SyncReboot')
end
end
local function SystemCrashCooldown()
Citizen.CreateThread(function()
while Crypto.Exchange.RebootInfo.state do
if (Crypto.Exchange.RebootInfo.percentage + 1) <= 100 then
Crypto.Exchange.RebootInfo.percentage = Crypto.Exchange.RebootInfo.percentage + 1
TriggerServerEvent('qb-crypto:server:Rebooting', true, Crypto.Exchange.RebootInfo.percentage)
else
Crypto.Exchange.RebootInfo.percentage = 0
Crypto.Exchange.RebootInfo.state = false
TriggerServerEvent('qb-crypto:server:Rebooting', false, 0)
end
Citizen.Wait(1200)
end
end)
end
function HackingSuccess(success)
if success then
TriggerEvent('mhacking:hide')
ExchangeSuccess()
else
TriggerEvent('mhacking:hide')
ExchangeFail()
end
end
Citizen.CreateThread(function()
while true do
local sleep = 5000
local ped = PlayerPedId()
local pos = GetEntityCoords(ped)
local dist = #(pos - Crypto.Exchange.coords)
if Config.UseTarget then return end
if dist < 15 then
sleep = 1
if dist < 1.5 then
if not Crypto.Exchange.RebootInfo.state then
DrawText3D(Crypto.Exchange.coords.x, Crypto.Exchange.coords.y, Crypto.Exchange.coords.z, Lang('PHONE_DRAWTEXT_STOCK_ENTER_USB'), 'stock_enter_usb', 'E')
if IsControlJustPressed(0, 38) then
TriggerServerCallback('qb-crypto:server:HasSticky', function(HasItem)
if HasItem then
TriggerEvent('mhacking:show')
TriggerEvent('mhacking:start', math.random(4, 6), 45, HackingSuccess)
else
SendTextMessage(Lang('PHONE_NOTIFICATION_STOCK_MISSING_CRYPTOSTICK'), 'error')
end
end)
end
else
DrawText3Ds(Crypto.Exchange.coords.x, Crypto.Exchange.coords.y, Crypto.Exchange.coords.z, Lang('PHONE_DRAWTEXT_STOCK_REBOOTING') .. ' ' .. Crypto.Exchange.RebootInfo.percentage .. '%')
end
end
end
Citizen.Wait(sleep)
end
end)
RegisterNetEvent('qb-crypto:client:SyncReboot', function()
Crypto.Exchange.RebootInfo.state = true
SystemCrashCooldown()
end)
RegisterNetEvent('qb-crypto:client:UpdateCryptoWorth', function(crypto, amount, history)
Crypto.Worth[crypto] = amount
if history ~= nil then
Crypto.History[crypto] = history
end
end)
RegisterNetEvent('qb-crypto:client:GetRebootState', function(RebootInfo)
if RebootInfo.state then
Crypto.Exchange.RebootInfo.state = RebootInfo.state
Crypto.Exchange.RebootInfo.percentage = RebootInfo.percentage
SystemCrashCooldown()
end
end)

View File

@@ -0,0 +1,8 @@
if Config.Billing ~= 'RxBilling' then return end
---@param id number
---@return boolean
function PayInvoice(id)
local invoice, msg = exports.RxBilling:PayInvoice(id)
if invoice then return true end
end

View File

@@ -0,0 +1,9 @@
if Config.Billing ~= 'codemv2' then return end
---@param id number
---@return boolean
function PayInvoice(id)
TriggerServerEvent('codemBilling:PayInvoice', id)
Wait(250) -- Wait until the server has processed the request (this is a bad way to do it. Use callbacks instead)
return true
end

View File

@@ -0,0 +1,21 @@
if Config.Billing ~= 'esx_billing' then return end
---@param id number
---@return boolean
function PayInvoice(id)
local co = coroutine.running()
if not co then
return false
end
local result = false
ESX.TriggerServerCallback('esx_billing:payBill', function(resp)
if resp then
TriggerEvent('esx_billing:paidBill', id)
result = true
end
coroutine.resume(co, result)
end, id)
return coroutine.yield()
end

View File

@@ -0,0 +1,9 @@
if Config.Billing ~= 'okok' then return end
---@param id number
---@return boolean
function PayInvoice(id)
TriggerServerEvent('okokBilling:PayInvoice', id)
Wait(250) -- Wait until the server has processed the request (this is a bad way to do it. Use callbacks instead)
return true
end

View File

@@ -0,0 +1,8 @@
if Config.Billing ~= 'qs' then return end
---@param id number
---@return boolean
function PayInvoice(id)
TriggerEvent('qs-billing:client:Notify', 'You must go to pay it presentialy or in your invoice tablet', 'info')
return true
end

View File

@@ -0,0 +1,7 @@
if Config.Billing ~= 'standalone' then return end
---@param id number
---@return boolean
function PayInvoice(id)
return TriggerServerCallbackSync('phone:payInvoice', id)
end

View File

@@ -0,0 +1,55 @@
-- These are examples of how to use the custom functions in the client.
-- Example of how to use the notification function.
RegisterCommand('notifi', function(source)
exports['qs-smartphone-pro']:SendTempNotification({
title = 'Test',
text = 'This is a test notification.',
app = 'settings',
timeout = 5000,
disableBadge = true, -- Disables the badge on the app icon.
})
end, false)
-- Its same as the old one
RegisterCommand('notifiOld', function(source)
exports['qs-smartphone-pro']:SendTempNotificationOld({
title = 'Test',
text = 'This is a test notification.',
app = 'settings',
timeout = 5000,
disableBadge = true, -- Disables the badge on the app icon.
})
end, false)
-- Example of how to use the sendNewMail event.
RegisterCommand('mailTest', function(source)
TriggerServerEvent('phone:sendNewMail', {
sender = 'Movistar Plus',
subject = 'Family telephone balance promotion',
message = 'Enjoy the family balance at only $8.50 per month, what are you waiting for?'
})
end, false)
-- Example of how to use the sendNewMail event for the old smartphone.
RegisterCommand('mailTestOld', function(source)
TriggerServerEvent('qs-smartphone:server:sendNewMail', {
sender = 'Movistar Plus',
subject = 'Family telephone balance promotion',
message = 'Enjoy the family balance at only $8.50 per month, what are you waiting for?'
})
end, false)
-- You can check if user is using phone.
RegisterCommand('phoneCheck', function(source)
local isUsingPhone = exports['qs-smartphone-pro']:InPhone()
if isUsingPhone then
print('User is using phone.')
else
print('User is not using phone.')
end
end, false)
-- RegisterCommand('toggleCanOpenPhone', function()
-- exports['qs-smartphone-pro']:SetCanOpenPhone(false)
-- end, false)

View File

@@ -0,0 +1,409 @@
--[[
Hi dear customer or developer, here you can fully configure your server's
framework or you could even duplicate this file to create your own framework.
If you do not have much experience, we recommend you download the base version
of the framework that you use in its latest version and it will work perfectly.
]]
if Config.Framework ~= 'esx' then
return
end
ESX = nil
Citizen.CreateThread(function()
local legacyEsx = pcall(function()
ESX = exports['es_extended']:getSharedObject()
end)
Citizen.Wait(0)
if legacyEsx then return end
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(0)
end
end)
function TriggerServerCallback(name, cb, ...)
local startTime = GetGameTimer()
ESX.TriggerServerCallback(name, function(...)
local endTime = GetGameTimer()
local duration = endTime - startTime
Debug('TriggerServerCallback ::: ' .. name .. ' took ' .. duration .. 'ms')
cb(...)
end, ...)
end
exports('TriggerServerCallback', TriggerServerCallback)
RegisterNetEvent('esx:playerLoaded', function()
TriggerServerEvent('qb-crypto:server:FetchWorth')
TriggerServerEvent('qb-crypto:server:GetRebootState')
end)
RegisterNetEvent('esx:onPlayerLogout', function()
Logout()
end)
RegisterNetEvent('esx:setJob')
AddEventHandler('esx:setJob', function(JobInfo)
SendNUIMessage({
action = 'UpdateApplications',
jobName = JobInfo.name,
applications = PhoneApplications
})
end)
local brutalDead = GetResourceState('brutal_ambulancejob') == 'started'
function isDead()
if brutalDead then
return exports.brutal_ambulancejob:IsDead()
end
return IsPedDeadOrDying(PlayerPedId(), false) or IsEntityDead(PlayerPedId()) or IsPauseMenuActive() or LocalPlayer.state.dead
end
function GetHungry()
local promise = promise.new()
TriggerEvent('esx_status:getStatus', 'hunger', function(status)
promise:resolve(status.getPercent())
end)
return Citizen.Await(promise)
end
function GetThirsty()
local promise = promise:new()
TriggerEvent('esx_status:getStatus', 'thirst', function(status)
promise:resolve(status.getPercent())
end)
return Citizen.Await(promise)
end
function GetPlayerData()
return ESX.GetPlayerData()
end
function GetInventory()
return GetPlayerData().inventory
end
function GetJobName()
return GetPlayerData().job.name
end
function GetMoney()
for k, v in pairs(GetPlayerData().accounts) do
if v.name == 'bank' then return v.money end
end
return 0
end
function FrameworkGetClosestVehicle()
return ESX.Game.GetClosestVehicle()
end
function FrameworkSpawnVehicle(model, coords, heading, cb)
ESX.Game.SpawnVehicle(model, coords, heading, cb)
end
function FrameworkSetVehicleProperties(vehicle, props)
ESX.Game.SetVehicleProperties(vehicle, props)
end
function FrameworkGetVehicles(cb)
return ESX.Game.GetVehicles()
end
function GetIdentifier()
return GetPlayerData().identifier
end
function GetPlayerMoney()
local playerData = GetPlayerData()
for i = 1, #playerData.accounts, 1 do
if playerData.accounts[i].name == 'money' then
return playerData.accounts[i].money
end
end
end
function SendTextMessage(msg, type)
if GetResourceState('qs-interface') == 'started' then
if type == 'inform' then
exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas fa-file')
elseif type == 'error' then
exports['qs-interface']:AddNotify(msg, 'Error', 2500, 'fas fa-bug')
elseif type == 'success' then
exports['qs-interface']:AddNotify(msg, 'Success', 2500, 'fas fa-thumbs-up')
end
return
end
if type == 'inform' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'inform'
})
elseif type == 'error' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'error'
})
elseif type == 'success' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'success'
})
end
end
local texts = {}
if GetResourceState('qs-textui') == 'started' then
function DrawText3D(x, y, z, text, id, key)
local _id = id
if not texts[_id] then
CreateThread(function()
texts[_id] = 5
while texts[_id] > 0 do
texts[_id] = texts[_id] - 1
Wait(0)
end
texts[_id] = nil
exports['qs-textui']:DeleteDrawText3D(id)
Debug('Deleted text', id)
end)
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
end
texts[_id] = 5
end
else
function DrawText3D(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
end
function DrawText3Ds(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
function DrawGenericText(text)
SetTextFont(4)
SetTextProportional(0)
SetTextScale(0.65, 0.65)
SetTextDropShadow(0, 0, 0, 0, 255)
SetTextEdge(1, 0, 0, 0, 255)
SetTextEntry('STRING')
AddTextComponentString(text)
DrawText(0.825, 0.90)
end
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
if GetResourceState('qs-interface') == 'started' then
local success = exports['qs-interface']:ProgressBar({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
})
if success then
onFinish()
else
onCancel()
end
return
end
if lib.progressCircle({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
}) then
onFinish()
else
onCancel()
end
end
function DepositMoney(amount, cb)
Debug('Society Deposit', amount)
TriggerServerEvent('esx_society:depositMoney', GetJobName(), amount)
SetTimeout(500, function()
TriggerServerCallback('esx_society:getSocietyMoney', cb, GetJobName())
end)
end
function WithdrawMoney(amount, cb)
Debug('society withdraw money', amount)
TriggerServerEvent('esx_society:withdrawMoney', GetJobName(), amount)
SetTimeout(500, function()
TriggerServerCallback('esx_society:getSocietyMoney', cb, GetJobName())
end)
end
function HireEmployee(source, cb)
TriggerServerCallback('esx_society:getOnlinePlayers', function(players)
for i = 1, #players do
local player = players[i]
if player.source == source then
TriggerServerCallback('esx_society:setJob', function()
cb({
name = player.name,
id = player.identifier
})
end, player.identifier, GetJobName(), 0, 'hire')
return
end
end
end)
end
function FireEmployee(identifier, cb)
Debug('Fire Employee', identifier)
TriggerServerCallback('esx_society:setJob', function()
cb(true)
end, identifier, 'unemployed', 0, 'fire')
end
function SetGrade(identifier, newGrade, cb)
TriggerServerCallback('esx_society:getJob', function(job)
if newGrade > #job.grades - 1 then
return cb(false)
end
TriggerServerCallback('esx_society:setJob', function()
cb(true)
end, identifier, GetJobName(), newGrade, 'promote')
end, GetJobName())
end
RegisterNUICallback('getMarketData', function(data, cb)
local playerData = GetPlayerData()
local jobData = {
job = playerData.job.name,
jobLabel = playerData.job.label,
isBoss = playerData.job.grade_name == 'boss'
}
if not jobData.isBoss then
for cId = 1, #Config.Markets do
local market = Config.Markets[cId]
if table.includes(market.job, jobData.job) then
if not market.bossRanks then
break
end
jobData.bossRanks = market.bossRanks
for i = 1, #market.bossRanks do
if market.bossRanks[i] == playerData.job.grade_name then
jobData.isBoss = true
break
end
end
break
end
end
end
if jobData.isBoss then
local moneyPromise = promise.new()
TriggerServerCallback('esx_society:getSocietyMoney', function(money)
jobData.balance = money
moneyPromise:resolve()
end, jobData.job)
Citizen.Await(moneyPromise)
local employeesPromise = promise.new()
TriggerServerCallback('esx_society:getEmployees', function(employees)
jobData.employees = employees
for i = 1, #employees do
local employee = employees[i]
employees[i] = {
name = employee.name,
id = employee.identifier,
gradeLabel = employee.job.grade_label,
grade = employee.job.grade,
canInteract = employee.job.grade_name ~= 'boss'
}
end
employeesPromise:resolve()
end, jobData.job)
Citizen.Await(employeesPromise)
local gradesPromise = promise.new()
TriggerServerCallback('esx_society:getJob', function(job)
local grades = {}
for i = 1, #job.grades do
local grade = job.grades[i]
grades[i] = {
key = grade.grade,
value = grade.label
}
end
jobData.grades = grades
gradesPromise:resolve()
end, jobData.job)
Citizen.Await(gradesPromise)
end
Debug('Market Data', jobData)
cb(jobData)
end)
function ToggleHud(bool)
if bool then
Debug('Event to show the hud [client/custom/framework/esx.lua line 389]')
DisplayRadar(false) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(false)
end
else
Debug('Event to hide the hud [client/custom/framework/esx.lua line 389]')
DisplayRadar(true) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(true)
end
end
end

View File

@@ -0,0 +1,363 @@
--[[
Hi dear customer or developer, here you can fully configure your server's
framework or you could even duplicate this file to create your own framework.
If you do not have much experience, we recommend you download the base version
of the framework that you use in its latest version and it will work perfectly.
]]
if Config.Framework ~= 'qb' then
return
end
ESX = nil
Citizen.CreateThread(function()
ESX = exports['qb-core']:GetCoreObject()
end)
function TriggerServerCallback(name, cb, ...)
local startTime = GetGameTimer()
ESX.Functions.TriggerCallback(name, function(...)
local endTime = GetGameTimer()
local duration = endTime - startTime
Debug('TriggerServerCallback ::: ' .. name .. ' took ' .. duration .. 'ms')
cb(...)
end, ...)
end
exports('TriggerServerCallback', TriggerServerCallback)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
TriggerServerEvent('qb-crypto:server:FetchWorth')
TriggerServerEvent('qb-crypto:server:GetRebootState')
end)
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo)
SendNUIMessage({
action = 'UpdateApplications',
jobName = JobInfo.name,
applications = PhoneApplications
})
end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
Logout()
end)
function GetPlayerData()
return ESX.Functions.GetPlayerData()
end
local brutalDead = GetResourceState('brutal_ambulancejob') == 'started'
function isDead()
if brutalDead then
return exports.brutal_ambulancejob:IsDead()
end
return GetPlayerData().metadata['ishandcuffed'] or GetPlayerData().metadata['inlaststand'] or GetPlayerData().metadata['isdead'] or IsPauseMenuActive() or LocalPlayer.state.dead
end
function GetIdentifier()
return GetPlayerData().citizenid
end
function GetHungry()
return GetPlayerData().metadata.hunger
end
function GetThirsty()
return GetPlayerData().metadata.thirst
end
function GetInventory()
return GetPlayerData().items
end
function GetJobName()
return GetPlayerData().job.name
end
function GetMoney()
return GetPlayerData().money.bank or 0
end
function FrameworkGetClosestVehicle()
return ESX.Functions.GetClosestVehicle()
end
function FrameworkSpawnVehicle(model, coords, heading, cb)
ESX.Functions.SpawnVehicle(model, cb, coords, true)
end
function FrameworkSetVehicleProperties(vehicle, props)
ESX.Functions.SetVehicleProperties(vehicle, props)
end
function FrameworkGetVehicles(cb)
return ESX.Functions.GetVehicles(cb)
end
function GetPlayerMoney()
return GetPlayerData().money['cash']
end
function SendTextMessage(msg, type)
if GetResourceState('qs-interface') == 'started' then
if type == 'inform' then
exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas fa-file')
elseif type == 'error' then
exports['qs-interface']:AddNotify(msg, 'Error', 2500, 'fas fa-bug')
elseif type == 'success' then
exports['qs-interface']:AddNotify(msg, 'Success', 2500, 'fas fa-thumbs-up')
end
return
end
if type == 'inform' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'inform'
})
elseif type == 'error' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'error'
})
elseif type == 'success' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'success'
})
end
end
local texts = {}
if GetResourceState('qs-textui') == 'started' then
function DrawText3D(x, y, z, text, id, key)
local _id = id
if not texts[_id] then
CreateThread(function()
texts[_id] = 5
while texts[_id] > 0 do
texts[_id] = texts[_id] - 1
Wait(0)
end
texts[_id] = nil
exports['qs-textui']:DeleteDrawText3D(id)
Debug('Deleted text', id)
end)
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
end
texts[_id] = 5
end
else
function DrawText3D(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
end
function DrawText3Ds(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
function DrawGenericText(text)
SetTextFont(4)
SetTextProportional(0)
SetTextScale(0.65, 0.65)
SetTextDropShadow(0, 0, 0, 0, 255)
SetTextEdge(1, 0, 0, 0, 255)
SetTextEntry('STRING')
AddTextComponentString(text)
DrawText(0.825, 0.90)
end
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
if GetResourceState('qs-interface') == 'started' then
local success = exports['qs-interface']:ProgressBar({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
})
if success then
onFinish()
else
onCancel()
end
return
end
if lib.progressCircle({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
}) then
onFinish()
else
onCancel()
end
end
function GetCompanyData(cb)
local playerJob = GetPlayerData().job
local jobData = {
job = playerJob.name,
jobLabel = playerJob.label,
isBoss = playerJob.isboss,
}
if jobData.isBoss then
local moneyPromise = promise.new()
TriggerServerCallback('phone:market:getAccountBalance', function(money)
moneyPromise:resolve(money)
end, jobData.job)
jobData.balance = Citizen.Await(moneyPromise)
local employeesPromise = promise.new()
TriggerServerCallback('qb-bossmenu:server:GetEmployees', function(employees)
for i = 1, #employees do
local employee = employees[i]
employees[i] = {
name = employee.name,
id = employee.empSource,
gradeLabel = employee.grade.name,
grade = employee.grade.level,
canInteract = not employee.isboss
}
end
employeesPromise:resolve(employees)
end, jobData.job)
jobData.employees = Citizen.Await(employeesPromise)
jobData.grades = {}
for k, v in pairs(ESX.Shared.Jobs[jobData.job].grades) do
jobData.grades[#jobData.grades + 1] = {
key = tonumber(k),
value = v.name,
}
end
table.sort(jobData.grades, function(a, b)
return a.key < b.key
end)
end
cb(jobData)
end
RegisterNUICallback('getMarketData', function(data, cb)
return GetCompanyData(function(companyData)
cb(companyData)
end)
end)
function DepositMoney(amount, cb)
TriggerServerCallbackSync('qb-banking:server:deposit', {
amount = amount,
accountName = GetJobName()
})
TriggerServerCallback('phone:market:getAccountBalance', cb, GetPlayerData().job.name)
end
function WithdrawMoney(amount, cb)
TriggerServerCallbackSync('qb-banking:server:withdraw', {
amount = amount,
accountName = GetJobName()
})
TriggerServerCallback('phone:market:getAccountBalance', cb, GetJobName())
end
function HireEmployee(source, cb)
TriggerServerEvent('qb-bossmenu:server:HireEmployee', source)
TriggerServerCallback('phone:market:getPlayerData', function(playerData)
cb({
name = playerData.name,
id = playerData.id
})
end, source)
end
function FireEmployee(source, cb)
TriggerServerEvent('qb-bossmenu:server:FireEmployee', source)
cb(GetPlayerData().job.isboss)
end
function SetGrade(identifier, newGrade, cb)
local maxGrade = 0
for grade, _ in pairs(ESX.Shared.Jobs[GetPlayerData().job.name].grades) do
grade = tonumber(grade)
if grade and grade > maxGrade then
maxGrade = grade
end
end
if newGrade > maxGrade then
return cb(false)
end
TriggerServerEvent('qb-bossmenu:server:GradeUpdate', {
cid = identifier,
grade = newGrade,
gradename = ESX.Shared.Jobs[GetPlayerData().job.name].grades[tostring(newGrade)].name
})
cb(true)
end
function ToggleHud(bool)
if bool then
Debug('Event to show the hud [client/custom/framework/esx.lua line 335]')
DisplayRadar(false) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(false)
end
else
Debug('Event to hide the hud [client/custom/framework/esx.lua line 335]')
DisplayRadar(true) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(true)
end
end
end

View File

@@ -0,0 +1,331 @@
--[[
Hi dear customer or developer, here you can fully configure your server's
framework or you could even duplicate this file to create your own framework.
If you do not have much experience, we recommend you download the base version
of the framework that you use in its latest version and it will work perfectly.
]]
if Config.Framework ~= 'qbx' then
return
end
ESX = nil
Citizen.CreateThread(function()
ESX = exports['qb-core']:GetCoreObject()
end)
function TriggerServerCallback(name, cb, ...)
ESX.Functions.TriggerCallback(name, cb, ...)
end
exports('TriggerServerCallback', TriggerServerCallback)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
TriggerServerEvent('qb-crypto:server:FetchWorth')
TriggerServerEvent('qb-crypto:server:GetRebootState')
end)
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo)
SendNUIMessage({
action = 'UpdateApplications',
jobName = JobInfo.name,
applications = PhoneApplications
})
end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
Logout()
end)
function GetPlayerData()
return exports.qbx_core:GetPlayerData()
end
local brutalDead = GetResourceState('brutal_ambulancejob') == 'started'
function isDead()
if brutalDead then
return exports.brutal_ambulancejob:IsDead()
end
return GetPlayerData().metadata['ishandcuffed'] or GetPlayerData().metadata['inlaststand'] or GetPlayerData().metadata['isdead'] or IsPauseMenuActive() or LocalPlayer.state.dead
end
function GetIdentifier()
return GetPlayerData().citizenid
end
function GetHungry()
return GetPlayerData().metadata.hunger
end
function GetThirsty()
return GetPlayerData().metadata.thirst
end
function GetInventory()
return GetPlayerData().items
end
function GetJobName()
return GetPlayerData().job.name
end
function GetMoney()
return GetPlayerData().money.bank or 0
end
function FrameworkGetClosestVehicle()
return lib.getClosestVehicle(GetEntityCoords(cache.ped), 2.0, true)
end
function FrameworkSpawnVehicle(model, coords, heading, cb)
ESX.Functions.SpawnVehicle(model, cb, coords, true)
end
function FrameworkSetVehicleProperties(vehicle, props)
lib.setVehicleProperties(vehicle, props)
end
function FrameworkGetVehicles(cb)
return GetGamePool('CVehicle', cb)
end
function GetPlayerMoney()
return GetPlayerData().money['cash']
end
function SendTextMessage(msg, type)
if GetResourceState('qs-interface') == 'started' then
if type == 'inform' then
exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas fa-file')
elseif type == 'error' then
exports['qs-interface']:AddNotify(msg, 'Error', 2500, 'fas fa-bug')
elseif type == 'success' then
exports['qs-interface']:AddNotify(msg, 'Success', 2500, 'fas fa-thumbs-up')
end
return
end
exports.qbx_core:Notify(message, type, 5000)
end
local texts = {}
if GetResourceState('qs-textui') == 'started' then
function DrawText3D(x, y, z, text, id, key)
local _id = id
if not texts[_id] then
CreateThread(function()
texts[_id] = 5
while texts[_id] > 0 do
texts[_id] = texts[_id] - 1
Wait(0)
end
texts[_id] = nil
exports['qs-textui']:DeleteDrawText3D(id)
Debug('Deleted text', id)
end)
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
end
texts[_id] = 5
end
else
function DrawText3D(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
end
function DrawText3Ds(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
function DrawGenericText(text)
SetTextFont(4)
SetTextProportional(0)
SetTextScale(0.65, 0.65)
SetTextDropShadow(0, 0, 0, 0, 255)
SetTextEdge(1, 0, 0, 0, 255)
SetTextEntry('STRING')
AddTextComponentString(text)
DrawText(0.825, 0.90)
end
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
if GetResourceState('qs-interface') == 'started' then
local success = exports['qs-interface']:ProgressBar({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
})
if success then
onFinish()
else
onCancel()
end
return
end
if lib.progressCircle({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
}) then
onFinish()
else
onCancel()
end
end
function GetCompanyData(cb)
local playerJob = GetPlayerData().job
local jobData = {
job = playerJob.name,
jobLabel = playerJob.label,
isBoss = playerJob.isboss,
}
if jobData.isBoss then
local moneyPromise = promise.new()
TriggerServerCallback('qb-bossmenu:server:GetAccount', function(money)
moneyPromise:resolve(money)
end, jobData.job)
jobData.balance = Citizen.Await(moneyPromise)
local employeesPromise = promise.new()
TriggerServerCallback('qb-bossmenu:server:GetEmployees', function(employees)
for i = 1, #employees do
local employee = employees[i]
employees[i] = {
name = employee.name,
id = employee.empSource,
gradeLabel = employee.grade.name,
grade = employee.grade.level,
canInteract = not employee.isboss
}
end
employeesPromise:resolve(employees)
end, jobData.job)
jobData.employees = Citizen.Await(employeesPromise)
jobData.grades = {}
for k, v in pairs(exports.qbx_core:GetJobs()[jobData.job].grades) do
jobData.grades[#jobData.grades + 1] = {
key = tonumber(k),
value = v.name,
}
end
table.sort(jobData.grades, function(a, b)
return a.grade < b.grade
end)
end
cb(jobData)
end
function DepositMoney(amount, cb)
TriggerServerEvent('qb-bossmenu:server:depositMoney', amount)
SetTimeout(1500, function()
TriggerServerCallback('qb-bossmenu:server:GetAccount', cb, GetPlayerData().job.name)
end)
end
function WithdrawMoney(amount, cb)
TriggerServerEvent('qb-bossmenu:server:withdrawMoney', amount)
SetTimeout(1500, function()
TriggerServerCallback('qb-bossmenu:server:GetAccount', cb, GetPlayerData().job.name)
end)
end
function HireEmployee(source, cb)
TriggerServerEvent('qb-bossmenu:server:HireEmployee', source)
TriggerServerCallback('phone:market:getPlayerData', function(playerData)
cb({
name = playerData.name,
id = playerData.id
})
end, source)
end
function FireEmployee(source, cb)
TriggerServerEvent('qb-bossmenu:server:FireEmployee', source)
cb(GetPlayerData().job.isboss)
end
function SetGrade(identifier, newGrade, cb)
local maxGrade = 0
for grade, _ in pairs(exports.qbx_core:GetJobs()[GetPlayerData().job.name].grades) do
grade = tonumber(grade)
if grade and grade > maxGrade then
maxGrade = grade
end
end
if newGrade > maxGrade then
return cb(false)
end
TriggerServerEvent('qb-bossmenu:server:GradeUpdate', {
cid = identifier,
grade = newGrade,
gradename = exports.qbx_core:GetJobs()[GetPlayerData().job.name].grades[tostring(newGrade)].name
})
cb(true)
end
function ToggleHud(bool)
if bool then
Debug('Event to show the hud [client/custom/framework/esx.lua line 317]')
DisplayRadar(false) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(false)
end
else
Debug('Event to hide the hud [client/custom/framework/esx.lua line 317]')
DisplayRadar(true) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(true)
end
end
end

View File

@@ -0,0 +1,334 @@
--[[
Hi dear customer or developer, here you can fully configure your server's
framework or you could even duplicate this file to create your own framework.
If you do not have much experience, we recommend you download the base version
of the framework that you use in its latest version and it will work perfectly.
]]
if Config.Framework ~= 'standalone' then
return
end
local RequestId = 0
local serverRequests = {}
local clientCallbacks = {}
---@param eventName string
---@param callback function
---@param ... any
TriggerServerCallback = function(eventName, callback, ...)
serverRequests[RequestId] = callback
TriggerServerEvent('qs-smartphone-pro:triggerServerCallback', eventName, RequestId, GetInvokingResource() or 'unknown', ...)
RequestId = RequestId + 1
end
exports('TriggerServerCallback', TriggerServerCallback)
RegisterNetEvent('qs-smartphone-pro:serverCallback', function(requestId, invoker, ...)
if not serverRequests[requestId] then
return print(('[^1ERROR^7] Server Callback with requestId ^5%s^7 Was Called by ^5%s^7 but does not exist.'):format(requestId, invoker))
end
serverRequests[requestId](...)
serverRequests[requestId] = nil
end)
---@param eventName string
---@param callback function
_RegisterClientCallback = function(eventName, callback)
clientCallbacks[eventName] = callback
end
RegisterNetEvent('qs-smartphone-pro:triggerClientCallback', function(eventName, requestId, invoker, ...)
if not clientCallbacks[eventName] then
return print(('[^1ERROR^7] Client Callback not registered, name: ^5%s^7, invoker resource: ^5%s^7'):format(eventName, invoker))
end
clientCallbacks[eventName](function(...)
TriggerServerEvent('qs-smartphone-pro:clientCallback', requestId, invoker, ...)
end, ...)
end)
function isDead()
return IsPedDeadOrDying(PlayerPedId(), false) or IsEntityDead(PlayerPedId()) or IsPauseMenuActive() or LocalPlayer.state.dead
end
function GetHungry()
Debug('GetHungry is used with standalone')
return 100
end
function GetThirsty()
Debug('GetThirsty is used with standalone')
return 100
end
function GetPlayerData()
return {}
end
function GetJobName()
Debug('GetJobName is used with standalone')
return 'unemployed'
end
function GetMoney()
Debug('GetMoney is used with standalone')
return 0
end
function GetVehicles() -- Leave the function for compatibility
return GetGamePool('CVehicle')
end
function GetClosestEntity(entities, isPlayerEntities, coords, modelFilter)
local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil
if coords then
coords = vector3(coords.x, coords.y, coords.z)
else
local playerPed = PlayerPedId()
coords = GetEntityCoords(playerPed)
end
if modelFilter then
filteredEntities = {}
for k, entity in pairs(entities) do
if modelFilter[GetEntityModel(entity)] then
filteredEntities[#filteredEntities + 1] = entity
end
end
end
for k, entity in pairs(filteredEntities or entities) do
local distance = #(coords - GetEntityCoords(entity))
if closestEntityDistance == -1 or distance < closestEntityDistance then
closestEntity, closestEntityDistance = isPlayerEntities and k or entity, distance
end
end
return closestEntity, closestEntityDistance
end
function FrameworkGetClosestVehicle()
return GetClosestEntity(GetVehicles(), false, coords, modelFilter)
end
function _RequestModel(modelHash, cb)
modelHash = (type(modelHash) == 'number' and modelHash or joaat(modelHash))
if not HasModelLoaded(modelHash) and IsModelInCdimage(modelHash) then
RequestModel(modelHash)
while not HasModelLoaded(modelHash) do
Wait(0)
end
end
if cb ~= nil then
cb()
end
end
function FrameworkSpawnVehicle(vehicle, coords, heading, cb)
local model = type(vehicle) == 'number' and vehicle or joaat(vehicle)
local vector = type(coords) == 'vector3' and coords or vec(coords.x, coords.y, coords.z)
networked = networked == nil and true or networked
local playerCoords = GetEntityCoords(PlayerPedId())
if not vector or not playerCoords then
return
end
local dist = #(playerCoords - vector)
if dist > 424 then -- Onesync infinity Range (https://docs.fivem.net/docs/scripting-reference/onesync/)
local executingResource = GetInvokingResource() or 'Unknown'
return print(('[^1ERROR^7] Resource ^5%s^7 Tried to spawn vehicle on the client but the position is too far away (Out of onesync range).'):format(executing_resource))
end
CreateThread(function()
_RequestModel(model)
local vehicle = CreateVehicle(model, vector.xyz, heading, networked, true)
if networked and NetworkGetEntityIsNetworked(vehicle) then
local id = NetworkGetNetworkIdFromEntity(vehicle)
SetNetworkIdCanMigrate(id, true)
SetEntityAsMissionEntity(vehicle, true, true)
end
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
SetVehicleNeedsToBeHotwired(vehicle, false)
SetModelAsNoLongerNeeded(model)
SetVehRadioStation(vehicle, 'OFF')
RequestCollisionAtCoord(vector.xyz)
while not HasCollisionLoadedAroundEntity(vehicle) do
Wait(0)
end
if cb then
cb(vehicle)
end
end)
end
function FrameworkSetVehicleProperties(vehicle, props)
Debug('FrameworkSetVehicleProperties is used with standalone')
return true
end
function FrameworkGetVehicles(cb)
return GetVehicles()
end
function GetIdentifier()
return TriggerServerCallbackSync('qs-smartphone-pro:GetIdentifier')
end
function GetPlayerMoney()
Debug('GetPlayerMoney is used with standalone')
return 100
end
function SendTextMessage(msg, type)
if GetResourceState('qs-interface') == 'started' then
if type == 'inform' then
exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas fa-file')
elseif type == 'error' then
exports['qs-interface']:AddNotify(msg, 'Error', 2500, 'fas fa-bug')
elseif type == 'success' then
exports['qs-interface']:AddNotify(msg, 'Success', 2500, 'fas fa-thumbs-up')
end
return
end
if type == 'inform' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'inform'
})
elseif type == 'error' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'error'
})
elseif type == 'success' then
lib.notify({
title = 'Smartphone',
description = msg,
type = 'success'
})
end
end
local texts = {}
if GetResourceState('qs-textui') == 'started' then
function DrawText3D(x, y, z, text, id, key)
local _id = id
if not texts[_id] then
CreateThread(function()
texts[_id] = 5
while texts[_id] > 0 do
texts[_id] = texts[_id] - 1
Wait(0)
end
texts[_id] = nil
exports['qs-textui']:DeleteDrawText3D(id)
Debug('Deleted text', id)
end)
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
end
texts[_id] = 5
end
else
function DrawText3D(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry('STRING')
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x, y, z, 0)
DrawText(0.0, 0.0)
local factor = text:len() / 370
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end
end
function DrawGenericText(text)
SetTextFont(4)
SetTextProportional(0)
SetTextScale(0.65, 0.65)
SetTextDropShadow(0, 0, 0, 0, 255)
SetTextEdge(1, 0, 0, 0, 255)
SetTextEntry('STRING')
AddTextComponentString(text)
DrawText(0.825, 0.90)
end
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
if GetResourceState('qs-interface') == 'started' then
local success = exports['qs-interface']:ProgressBar({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
})
if success then
onFinish()
else
onCancel()
end
return
end
if lib.progressCircle({
duration = duration,
label = label,
position = 'bottom',
useWhileDead = useWhileDead,
canCancel = canCancel,
disable = disableControls,
anim = {
dict = animation.animDict,
clip = animation.anim,
flag = animation?.flags
},
prop = prop
}) then
onFinish()
else
onCancel()
end
end
function ToggleHud(bool)
if bool then
Debug('Event to show the hud [client/custom/framework/esx.lua line 320]')
DisplayRadar(false) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(false)
end
else
Debug('Event to hide the hud [client/custom/framework/esx.lua line 320]')
DisplayRadar(true) -- You can enable or disable mini-map here
if GetResourceState('qs-interface') == 'started' then
exports['qs-interface']:ToggleHud(true)
end
end
end

View File

@@ -0,0 +1,235 @@
if Config.Menu ~= 'nh-context' then
return
end
function openRecipeMenu()
TriggerServerCallback('phone:CheckExistRecipe', function(exist)
local method = exist?.method or ''
local moment_header = ([[
Moment %s
]]):format(method == 'moment' and '<span style="color:green; margin-left: 4px"> - ' .. Lang('PHONE_MENU_RECIPES_OPTION_CURRENTLY') .. exist?.amount .. '</span>' or '')
local daily_header = ([[
Daily %s
]]):format(method == 'daily' and ' - ' .. Lang('PHONE_MENU_RECIPES_OPTION_CURRENTLY') or '')
local data = {
{
header = Lang('PHONE_MENU_RECIPES_TITLE'),
},
{
header = daily_header,
context = Lang('PHONE_MENU_RECIPES_UPDATED'),
event = 'phone:recipeSelectMethod',
args = { 'daily' }
},
{
header = moment_header,
context = Lang('PHONE_MENU_RECIPES_CONTOUR'),
event = 'phone:recipeSelectMethod',
args = { 'moment' }
},
}
if exist then
table.insert(data, {
header = "<span style='color: gray'>" .. Lang('PHONE_MENU_RECIPES_OPTION_CANCEL') .. '</span>',
context = Lang('PHONE_MENU_RECIPES_CANCEL'),
event = 'phone:CancelRecipe',
server = true,
args = {}
})
end
TriggerEvent('nh-context:createMenu', data)
end)
end
function openPhoneBoothMenu(isNearPB)
local data = {
{
header = Lang('PHONE_MENU_BOOTH_CALL_TITLE'),
},
{
header = Lang('PHONE_MENU_BOOTH_CALL_POLICE'),
context = 'police',
event = 'phone:boothCall',
args = { 'police' }
},
{
header = Lang('PHONE_MENU_BOOTH_CALL_AMBULANCE'),
context = 'ambulance',
event = 'phone:boothCall',
args = { 'ambulance' }
},
{
header = Lang('PHONE_MENU_BOOTH_CALL_MECHANIC'),
context = 'mechanic',
event = 'phone:boothCall',
args = { 'mechanic' }
},
{
header = Lang('PHONE_MENU_BOOTH_CALL_NUMBER'),
context = 'othercall',
event = 'phone:boothCall',
args = { 'othercall' }
}
}
TriggerEvent('nh-context:createMenu', data)
end
function openRentalMenu(key)
local data = {
{
header = Lang('PHONE_MENU_RENTEL_TITLE')
}
}
local coords = { x = Config.RentelLocations[key]['coords'].x, y = Config.RentelLocations[key]['coords'].y, z = Config.RentelLocations[key]['coords'].z, h = Config.RentelLocations[key]['coords'].w }
for model, v in pairs(Config.RentelVehicles) do
if v.stored then
table.insert(data, {
header = v.label .. ' - ' .. Lang('PHONE_MENU_RENTEL_STORED'),
context = 'Rentel',
event = 'phone:server:spawnVehicle',
server = true,
args = { {
model = model, price = 0, coords = coords
} }
})
else
table.insert(data, {
header = v.label .. ' - ' .. Lang('PHONE_MENU_RENTEL_MONEY') .. v.price,
context = 'Rentel',
event = 'phone:server:spawnVehicle',
server = true,
args = { {
model = model, price = v.price, coords = coords
} }
})
end
end
TriggerEvent('nh-context:createMenu', data)
end
function resetPasswordMenu()
local data = {
{
header = Lang('PHONE_MENU_PHONE_TITLE')
},
{
header = Lang('PHONE_MENU_PHONE_RESET_PASSWORD') .. Config.ResetPassword.money,
context = 'Reset Password',
event = 'phone:ResetPassword'
}
}
TriggerEvent('nh-context:createMenu', data)
end
RegisterNetEvent('phone:openPhoneMenu', function(event, ...)
local items = GetInventory()
local data = {
{
header = Lang('PHONE_MENU_BATTERY_TITLE')
}
}
if not Config.UniquePhone then
local userData = TriggerServerCallbackSync('phone:getUserData')
if not userData then
Debug('phone', 'userData is nil')
return
end
table.insert(data, {
header = Lang('PHONE_MENU_BATTERY_PHONE_NUMBER') .. ' ' .. userData.phoneNumber,
context = 'Phone',
event = 'phone:selectPhone',
args = { { name = 'phone', info = { phoneNumber = userData.phoneNumber } }, event, ... }
})
end
if Config.UniquePhone then
for phoneName in pairs(Config.Phones) do
for k, v in pairs(items) do
local meta = v.info or v.metadata
if v.name == phoneName and meta?.phoneNumber then
table.insert(data, {
header = Lang('PHONE_MENU_BATTERY_PHONE_NUMBER') .. ' ' .. meta.phoneNumber,
context = 'Phone',
event = 'phone:selectPhone',
args = { v, event, ... }
})
end
end
end
end
if #data < 2 then return SendTextMessage(Lang('PHONE_NOTIFICATION_PHONE_NO_PHONE'), 'error') end
TriggerEvent('nh-context:createMenu', data)
end)
RegisterNetEvent('phone:client:openChannelMenu', function()
if not MetaData then return SendTextMessage(Lang('PHONE_NOTIFICATION_RECIPES_USE_PHONE_FIRST'), 'inform') end
local input = lib.inputDialog(Lang('PHONE_MENU_DISCORD_CHANNEL_TITLE'), {
Lang('PHONE_MENU_DISCORD_SELECT_NAME'),
Lang('PHONE_MENU_DISCORD_SELECT_PASSWORD')
})
if not input then return end
local channelName = input[1]
local passcode = input[2]
Debug('phone', 'channelName', channelName, 'passcode', passcode)
local roomData = {
room_owner_name = MetaData.charinfo.firstname .. ' ' .. MetaData.charinfo.lastname
}
local allGood = false
if channelName then
roomData.room_name = channelName
allGood = true
end
if passcode then
roomData.room_pin = passcode
end
if allGood then
TriggerServerCallback('phone:server:PurchaseRoom', function(status)
if status then
local source = GetPlayerServerId(PlayerId())
TriggerServerEvent('phone:server:CreateRoom', source, roomData)
end
end, 250)
end
end)
RegisterNetEvent('phone:client:openChannelHackedMenu', function()
if not MetaData then return SendTextMessage(Lang('PHONE_NOTIFICATION_RECIPES_USE_PHONE_FIRST'), 'inform') end
local keyboard, channelName, passcode = exports['nh-keyboard']:Keyboard({
header = Lang('PHONE_MENU_DISCORD_SECURE_TITLE'),
rows = { Lang('PHONE_MENU_DISCORD_SELECT_NAME'), Lang('PHONE_MENU_DISCORD_SELECT_PASSWORD') }
})
if keyboard then
local roomData = {
room_owner_name = MetaData.charinfo.firstname .. ' ' .. MetaData.charinfo.lastname
}
local allGood = false
if channelName then
roomData.room_name = channelName
allGood = true
end
if passcode then
roomData.room_pin = passcode
end
if allGood then
TriggerServerCallback('phone:server:PurchaseRoom', function(status)
if status then
local source = GetPlayerServerId(PlayerId())
TriggerServerEvent('phone:server:CreateRoom', source, roomData, true)
end
end, 5000)
end
end
end)

View File

@@ -0,0 +1,239 @@
if Config.Menu ~= 'ox_lib' then
return
end
function openRecipeMenu()
TriggerServerCallback('phone:CheckExistRecipe', function(recipe)
print(json.encode(recipe))
local method = recipe and recipe.method or ''
local isMoment = method == 'moment'
local isDaily = method == 'daily'
local momentHeader = isMoment and (' - ' .. Lang('PHONE_MENU_RECIPES_OPTION_CURRENTLY') .. " " .. recipe.amount) or ''
local dailyHeader = isDaily and (' - ' .. Lang('PHONE_MENU_RECIPES_OPTION_CURRENTLY') .. " " .. recipe.amount) or ''
local options = {
{
title = ("%s $%s"):format(Lang('PHONE_MENU_RECIPES_UPDATED'), Config.BuyRecipe.prices["daily"]),
description = dailyHeader,
onSelect = function()
TriggerEvent('phone:recipeSelectMethod', 'daily')
end
},
{
title = ("%s $%s"):format(Lang('PHONE_MENU_RECIPES_CONTOUR'), Config.BuyRecipe.prices["moment"]),
description = momentHeader,
onSelect = function()
TriggerEvent('phone:recipeSelectMethod', 'moment')
end
}
}
if recipe then
table.insert(options, {
title = Lang('PHONE_MENU_RECIPES_CANCEL'),
onSelect = function()
TriggerServerEvent('phone:CancelRecipe')
end
})
end
lib.registerContext({
id = 'recipe_spot',
title = Lang('PHONE_MENU_RECIPES_TITLE'),
options = options
})
lib.showContext('recipe_spot')
end)
end
function openPhoneBoothMenu(isNearPB)
local data = {
{
title = Lang('PHONE_MENU_BOOTH_CALL_POLICE'),
onSelect = function(args)
TriggerEvent('phone:boothCall', 'police')
end
},
{
title = Lang('PHONE_MENU_BOOTH_CALL_AMBULANCE'),
onSelect = function(args)
TriggerEvent('phone:boothCall', 'police')
end
},
{
title = Lang('PHONE_MENU_BOOTH_CALL_MECHANIC'),
onSelect = function(args)
TriggerEvent('phone:boothCall', 'police')
end
},
{
title = Lang('PHONE_MENU_BOOTH_CALL_NUMBER'),
onSelect = function(args)
TriggerEvent('phone:boothCall', 'othercall')
end
},
}
lib.registerContext({
id = 'phone_booth',
title = Lang('PHONE_MENU_BOOTH_CALL_TITLE'),
options = data
})
lib.showContext('phone_booth')
end
function openRentalMenu(key)
local coords = { x = Config.RentelLocations[key]['coords'].x, y = Config.RentelLocations[key]['coords'].y, z = Config.RentelLocations[key]['coords'].z, h = Config.RentelLocations[key]['coords'].w }
local data = {}
for model, v in pairs(Config.RentelVehicles) do
if v.stored then
table.insert(data, {
title = v.label .. ' - ' .. Lang('PHONE_MENU_RENTEL_STORED'),
onSelect = function(args)
TriggerServerEvent('phone:server:spawnVehicle', { model = model, price = 0, coords = coords })
end
})
else
table.insert(data, {
title = v.label .. ' - ' .. Lang('PHONE_MENU_RENTEL_MONEY') .. v.price,
onSelect = function(args)
TriggerServerEvent('phone:server:spawnVehicle', { model = model, price = v.price, coords = coords })
end
})
end
end
lib.registerContext({
id = 'rentel_spot',
title = Lang('PHONE_MENU_RENTEL_TITLE'),
options = data
})
lib.showContext('rentel_spot')
end
function resetPasswordMenu()
local data = {
{
title = Lang('PHONE_MENU_PHONE_RESET_PASSWORD') .. Config.ResetPassword.money,
onSelect = function(args)
TriggerEvent('phone:ResetPassword')
end
}
}
lib.registerContext({
id = 'reset_password',
title = Lang('PHONE_MENU_PHONE_TITLE'),
options = data
})
lib.showContext('reset_password')
end
RegisterNetEvent('phone:openPhoneMenu', function(event, ...)
local items = GetInventory()
local data = {}
local varargs = { ... }
if not Config.UniquePhone then
local userData = TriggerServerCallbackSync('phone:getUserData')
if userData then
table.insert(data, {
title = Lang('PHONE_MENU_BATTERY_PHONE_NUMBER') .. ' ' .. userData.phoneNumber,
onSelect = function(args)
TriggerServerEvent(event, {
name = 'phone',
info = { phoneNumber = userData.phoneNumber }
}, table.unpack(varargs))
end,
})
end
else
for phoneName in pairs(Config.Phones) do
for k, v in pairs(items) do
local meta = v.info or v.metadata
if v.name == phoneName and meta?.phoneNumber then
table.insert(data, {
title = Lang('PHONE_MENU_BATTERY_PHONE_NUMBER') .. ' ' .. meta.phoneNumber,
onSelect = function(args)
TriggerServerEvent(event, v, table.unpack(varargs))
end,
})
end
end
end
end
if #data < 1 then return SendTextMessage(Lang('PHONE_NOTIFICATION_PHONE_NO_PHONE'), 'error') end
lib.registerContext({
id = 'charger_spot',
title = Lang('PHONE_MENU_BATTERY_TITLE'),
options = data
})
lib.showContext('charger_spot')
end)
RegisterNetEvent('phone:client:openChannelMenu', function()
if not MetaData then return SendTextMessage(Lang('PHONE_NOTIFICATION_RECIPES_USE_PHONE_FIRST'), 'inform') end
local input = lib.inputDialog(Lang('PHONE_MENU_DISCORD_CHANNEL_TITLE'), {
{ type = 'input', label = Lang('PHONE_MENU_DISCORD_SELECT_NAME'), description = Lang('PHONE_MENU_DISCORD_SELECT_NAME_INFO'), required = true },
{ type = 'number', label = Lang('PHONE_MENU_DISCORD_SELECT_PASSWORD'), description = Lang('PHONE_MENU_DISCORD_SELECT_PASSWORD_INFO'), required = false },
})
if input and input[1] then
local roomData = {
room_owner_name = MetaData.charinfo.firstname .. ' ' .. MetaData.charinfo.lastname
}
local allGood = false
if input[1] then
roomData.room_name = input[1]
allGood = true
end
if input[2] then
roomData.room_pin = input[2]
end
if allGood then
TriggerServerCallback('phone:server:PurchaseRoom', function(status)
if status then
local source = GetPlayerServerId(PlayerId())
TriggerServerEvent('phone:server:CreateRoom', source, roomData)
end
end, 250)
end
end
end)
RegisterNetEvent('phone:client:openChannelHackedMenu', function()
if not MetaData then return SendTextMessage(Lang('PHONE_NOTIFICATION_RECIPES_USE_PHONE_FIRST'), 'inform') end
local input = lib.inputDialog(Lang('PHONE_MENU_DISCORD_SECURE_TITLE'), {
{ type = 'input', label = Lang('PHONE_MENU_DISCORD_SELECT_NAME'), description = Lang('PHONE_MENU_DISCORD_SELECT_NAME_INFO'), required = true },
{ type = 'number', label = Lang('PHONE_MENU_DISCORD_SELECT_PASSWORD'), description = Lang('PHONE_MENU_DISCORD_SELECT_PASSWORD_INFO'), required = false },
})
if input and input[1] then
local roomData = {
room_owner_name = MetaData.charinfo.firstname .. ' ' .. MetaData.charinfo.lastname
}
local allGood = false
if input[1] then
roomData.room_name = input[1]
allGood = true
end
if input[2] then
roomData.room_pin = input[2]
end
if allGood then
TriggerServerCallback('phone:server:PurchaseRoom', function(status)
if status then
local source = GetPlayerServerId(PlayerId())
TriggerServerEvent('phone:server:CreateRoom', source, roomData, true)
end
end, 250)
end
end
end)

View File

@@ -0,0 +1,76 @@
function DisableControlActions()
-- Disables mouse actions
DisableControlAction(0, 18, true) -- Disable mouse
DisableControlAction(0, 69, true) -- Disable mouse
DisableControlAction(0, 92, true) -- Disable mouse
DisableControlAction(0, 106, true) -- Disable mouse
DisableControlAction(0, 122, true) -- Disable mouse
-- Disables mouse look actions
if not KeepInput then
DisableControlAction(0, 12, true) -- Disable mouse look
DisableControlAction(0, 13, true) -- Disable mouse look
DisableControlAction(0, 1, true) -- Disable mouse look
DisableControlAction(0, 2, true) -- Disable mouse look
DisableControlAction(0, 3, true) -- Disable mouse look
DisableControlAction(0, 4, true) -- Disable mouse look
DisableControlAction(0, 5, true) -- Disable mouse look
DisableControlAction(0, 6, true) -- Disable mouse look
end
-- Disables melee combat actions
DisableControlAction(0, 263, true) -- Disable melee
DisableControlAction(0, 264, true) -- Disable melee
DisableControlAction(0, 257, true) -- Disable melee
DisableControlAction(0, 140, true) -- Disable melee
DisableControlAction(0, 141, true) -- Disable melee
DisableControlAction(0, 142, true) -- Disable melee
DisableControlAction(0, 143, true) -- Disable melee
-- Disables escape and chat actions
DisableControlAction(0, 177, true) -- Disable escape
DisableControlAction(0, 200, true) -- Disable escape
DisableControlAction(0, 202, true) -- Disable escape
DisableControlAction(0, 322, true) -- Disable escape
DisableControlAction(0, 245, true) -- Disable chat
DisableControlAction(0, 199, true) -- Disable chat
-- Disables aiming and shooting actions
DisableControlAction(0, 25, true) -- Disable aim
DisableControlAction(0, 24, true) -- Disable shoot
-- Disables other specific actions
DisableControlAction(0, 45, true) -- Disable Reload (R)
DisableControlAction(0, 44, true) -- Disable Cover (Q)
DisableControlAction(0, 0, true) -- Disable Camera (V)
DisableControlAction(0, 26, true) -- Disable Camera Back (C)
DisableControlAction(0, 20, true) -- Disable Z
DisableControlAction(0, 236, true) -- Disable V
-- Disables numerical actions
DisableControlAction(0, 157, true) -- Disable 1
DisableControlAction(0, 158, true) -- Disable 2
DisableControlAction(0, 160, true) -- Disable 3
DisableControlAction(0, 164, true) -- Disable 4
DisableControlAction(0, 165, true) -- Disable 5
DisableControlAction(0, 159, true) -- Disable 6
DisableControlAction(0, 161, true) -- Disable 7
DisableControlAction(0, 162, true) -- Disable 8
DisableControlAction(0, 163, true) -- Disable 9
-- Other specific disablements
DisableControlAction(0, 73, true) -- Disable X
DisableControlAction(0, 47, true) -- Disable G
DisableControlAction(0, 58, true) -- Disable G
DisableControlAction(0, 74, true) -- Disable H
-- Disables control action for second player
DisableControlAction(1, 18, true) -- Enter / Exit vehicle
DisableControlAction(1, 24, true) -- Change weapon
DisableControlAction(1, 69, true) -- Fire
DisableControlAction(1, 92, true) -- Aim
DisableControlAction(1, 106, true) -- Jump
DisableControlAction(1, 122, true) -- Sprint
DisableControlAction(1, 135, true) -- Duck / Cover
-- ... (continues the list for the second player)
end

View File

@@ -0,0 +1,39 @@
---@param emergency? boolean
---@return boolean
function TogglePhone(emergency)
if not emergency and (isDead() or not canOpenPhone) then return false end
if not Config.UniquePhone then
local hasData = lib.callback.await('phone:server:HasPhone', 0)
if not hasData.phone then
SendTextMessage(Lang('PHONE_NOTIFICATION_PHONE_NO_PHONE'), 'error')
return false
end
local meta = TriggerServerCallbackSync('phone:GetPhoneDataForWithoutMeta')
OpenPhone(hasData.phone, Config.PhonesProps[hasData.name], meta)
return true
end
if not MetaData then
TriggerServerEvent('phone:server:openRandomItemPhone')
return true
end
local phoneData, name = TriggerServerCallbackSync('phone:server:checkHasPhoneWithUniqueId', MetaData.uniqueId)
if not phoneData then
if MetaData then
MetaData = nil
TriggerServerEvent('phone:server:openRandomItemPhone')
-- SendTextMessage('Your phone is fucked up', 'inform')
return true
end
SendTextMessage(Lang('PHONE_NOTIFICATION_PHONE_NO_PHONE'), 'error')
return false
end
OpenPhone(CurrentPhoneData.type, CurrentPhoneData.phoneColor, MetaData)
return true
end
if not Config.OpenPhoneByPress and Config.UniquePhone then return end
RegisterKeyMapping('TooglePhone', 'Open phone', 'keyboard', Config.OpenPhone)
RegisterCommand('TooglePhone', function()
TogglePhone()
end, false)

View File

@@ -0,0 +1,256 @@
if not Config.UseTarget then
return
end
TargetName = GetResourceState('ox_target'):find('started') and 'qtarget' or 'qb-target'
local hasHackedPhone = false
function UberEatsDoors(uberChoosenAdress)
exports[TargetName]:AddBoxZone('uber_eats_zone', vec3(Config.UberDelivery[uberChoosenAdress]['x'], Config.UberDelivery[uberChoosenAdress]['y'], Config.UberDelivery[uberChoosenAdress]['z'] - 1), 2.5, 2.5, {
name = 'uber_eats_zone',
heading = 90.0,
debugPoly = Config.ZoneDebug,
minZ = Config.UberDelivery[uberChoosenAdress]['z'] - 1,
maxZ = Config.UberDelivery[uberChoosenAdress]['z'] + 1,
}, {
options = {
{
icon = 'fa-solid fa-door-open',
label = Lang('PHONE_TARGET_UBEREATS_DELIVER_DELIVERY'),
action = function()
TriggerServerCallback('phone:checkItem', function(qtty)
if qtty > 0 then
TriggerServerEvent('phone:removeItem', Config.UberItems[uberChoosenItem]['item'])
doorKnocked = true
npcHome = math.random(1, 2)
PlayAnimation(PlayerPedId(), 'timetable@jimmy@doorknock@', 'knockdoor_idle')
Citizen.Wait(3000)
if npcHome == 1 then
Citizen.Wait(2000)
packagePoint = false
UberReward()
else
Citizen.Wait(2000)
UberReward()
end
-- Después de la acción, eliminar el target
RemoveUberTarget()
uberTargeted = false
else
SendTextMessage(Lang('PHONE_NOTIFICATION_UBEREATS_NO_ITEM') .. ' ' .. Config.UberItems[uberChoosenItem]['name'], 'error')
end
end, Config.UberItems[uberChoosenItem]['item'])
end,
},
},
distance = 2.5
})
end
function RemoveUberTarget()
exports[TargetName]:RemoveZone('uber_eats_zone')
end
CreateThread(function()
exports[TargetName]:AddTargetModel(Config.ChatSeller, {
options = {
{
type = 'client',
event = 'phone:client:openChannelMenu',
icon = 'fas fa-comment-dots',
label = Lang('PHONE_TARGET_DISCORD_PURCHASE_CHAT_CHANNEL'),
targeticon = 'fas fa-comments',
},
{
type = 'client',
event = 'phone:client:openChannelHackedMenu',
icon = 'fas fa-user-secret',
label = Lang('PHONE_TARGET_DISCORD_PURCHASE_SECURE_CHANNEL'),
targeticon = 'fas fa-comments',
canInteract = function()
TriggerServerCallback('phone:server:hasHackedPhone', function(result)
hasHackedPhone = result
end)
Citizen.Wait(500)
return hasHackedPhone
end
}
},
distance = 5.0
})
exports[TargetName]:AddBoxZone('crypto_spot', vec3(Crypto.Exchange.coords.x, Crypto.Exchange.coords.y, Crypto.Exchange.coords.z), 1.5, 1.5, {
name = 'crypto_spot',
heading = 90.0,
debugPoly = Config.ZoneDebug,
minZ = Crypto.Exchange.coords.z - 1,
maxZ = Crypto.Exchange.coords.z + 1,
}, {
options = {
{
icon = 'fa-solid fa-coins',
label = Lang('PHONE_TARGET_STOCK_ENTER_USB'),
canInteract = function()
HasItem = TriggerServerCallbackSync('qb-crypto:server:HasSticky')
return HasItem
end,
action = function()
TriggerEvent('mhacking:show')
TriggerEvent('mhacking:start', math.random(4, 6), 45, HackingSuccess)
end,
},
},
distance = 2.5
})
exports[TargetName]:AddTargetModel('a_m_m_afriamer_01', {
options = {
{
icon = 'fa-solid fa-gun',
label = Lang('PHONE_TARGET_DARKWEB_TAKE_ORDER'),
canInteract = function()
return waitingDarkWebData
end,
action = function()
TriggerServerCallbackSync('phone:darkweb:buyItem', waitingDarkWebData.item, waitingDarkWebData.amount)
SendTempNotificationOld({
app = 'darkweb',
title = Lang('PHONE_NOTIFICATION_DARKWEB_TITLE'),
text = Lang('PHONE_NOTIFICATION_DARKWEB_SUCCESS'),
timeout = 2500,
})
darkWebSuccess = true
waitingDarkWebData = nil
end,
},
},
distance = 5.0
})
for k, v in pairs(Config.RentelLocations) do
exports[TargetName]:AddBoxZone('rentel', vec3(v['coords'][1], v['coords'][2], v['coords'][3] - 1), 2.5, 2.5, {
name = 'rentel',
heading = 90.0,
debugPoly = Config.ZoneDebug,
minZ = v['coords'][3] - 1,
maxZ = v['coords'][3] + 1,
}, {
options = {
{
icon = 'fa-solid fa-bicycle',
label = Lang('PHONE_DRAWTEXT_RENTEL_TARGET_RENTAL'),
action = function()
if not IsPedInAnyVehicle(PlayerPedId(), false) then
openRentalMenu(k)
else
local veh = GetVehiclePedIsIn(PlayerPedId(), false)
local model = GetDisplayNameFromVehicleModel(GetEntityModel(veh))
model = string.lower(model)
if Config.RentelVehicles[model] then
local keysQs = GetResourceState('qs-vehiclekeys') == 'started'
if keysQs then
local plate = GetVehicleNumberPlateText(veh)
exports['qs-vehiclekeys']:RemoveKeys(plate, model)
end
TaskLeaveVehicle(PlayerPedId(), veh, 256)
DeleteVehicle(veh)
SendTempNotificationOld({
app = 'rentel',
title = Lang('PHONE_NOTIFICATION_RENTEL_TITLE'),
text = Lang('PHONE_NOTIFICATION_RENTEL_RETURN_VEHICLE_POST'),
timeout = 2500,
disableBadge = true,
})
else
SendTextMessage(Lang('PHONE_NOTIFICATION_RENTEL_VEHICLE_INVALID'), 'error')
end
end
end,
},
},
distance = 2.5
})
end
InitChargeTarget()
exports[TargetName]:AddTargetModel(Config.ResetPassword.ped.model, {
options = {
{
type = 'client',
event = 'phone:client:openChannelMenu',
icon = 'fas fa-comment-dots',
label = Lang('PHONE_TARGET_PHONE_RESET_PASSWORD'),
action = function()
resetPasswordMenu()
end,
},
},
distance = 5.0
})
InitBoothTarget()
if Config.EnableRecipe then
for _, recipeShop in ipairs(Config.BuyRecipe.coords) do
exports[TargetName]:AddBoxZone('booth_zone', vec3(recipeShop.x, recipeShop.y, recipeShop.z - 1), 1.5, 1.5, {
name = 'booth_zone',
heading = recipeShop.w or 0.0,
debugPoly = Config.ZoneDebug,
minZ = recipeShop.z - 1,
maxZ = recipeShop.z + 1,
}, {
options = {
{
icon = 'fa-solid fa-phone',
label = Lang('PHONE_TARGET_RECIPES_BUY'),
action = function()
if MetaData then
openRecipeMenu()
else
SendTextMessage(Lang('PHONE_NOTIFICATION_RECIPES_USE_PHONE_FIRST'), 'inform')
end
end,
},
},
distance = 2.5
})
end
end
end)
function InitChargeTarget()
exports[TargetName]:RemoveZone('charger_spots')
for k, v in pairs(Config.ChargeCoords) do
local coords = v.coords
exports[TargetName]:AddBoxZone('charger_spots', vec3(coords.x, coords.y, coords.z - 1), 2.5, 2.5, {
name = 'charger_spots',
heading = 90.0,
debugPoly = Config.ZoneDebug,
minZ = v['coords'][3] - 1,
maxZ = v['coords'][3] + 1,
}, {
options = {
{
icon = 'fa-solid fa-battery-full',
label = Lang('PHONE_TARGET_BATTERY_CHARGE_PHONE'),
action = function()
if Config.ChargeCoords[k].isAvailable then
TriggerEvent('phone:openPhoneMenu', 'phone:ChargePhone', k)
else
if Config.ChargeCoords[k].takeable ~= GetIdentifier() then
SendTextMessage(Lang('PHONE_NOTIFICATION_BATTERY_NOT_OWNER'), 'error')
else
TriggerServerEvent('phone:TakeBackPhoneFromCharging', k)
end
end
end,
},
},
distance = 2.5
})
end
end

View File

@@ -0,0 +1,7 @@
if Config.Vehiclekeys ~= 'mk_vehiclekeys' then
return
end
function AddVehiclekeys(vehicle)
exports['mk_vehiclekeys']:AddKey(vehicle)
end

View File

@@ -0,0 +1,8 @@
if Config.Vehiclekeys ~= 'mono_carkeys' then
return
end
function AddVehiclekeys(vehicle)
local plate = GetVehicleNumberPlateText(vehicle)
TriggerServerEvent('mono_carkeys:CreateKey', plate)
end

View File

@@ -0,0 +1,7 @@
if Config.Vehiclekeys ~= 'none' then
return
end
function AddVehiclekeys(vehicle)
return Debug('Vehiclekeys', 'AddVehiclekeys', 'Vehiclekeys is set to none')
end

View File

@@ -0,0 +1,8 @@
if Config.Vehiclekeys ~= 'okokGarage' then
return
end
function AddVehiclekeys(vehicle)
local plate = GetVehicleNumberPlateText(vehicle)
TriggerServerEvent('okokGarage:GiveKeys', plate)
end

View File

@@ -0,0 +1,7 @@
if Config.Vehiclekeys ~= 'qb-vehiclekeys' then
return
end
function AddVehiclekeys(vehicle)
TriggerEvent('vehiclekeys:client:SetOwner', ESX.Functions.GetPlate(vehicle))
end

View File

@@ -0,0 +1,9 @@
if Config.Vehiclekeys ~= 'qs-vehiclekeys' then
return
end
function AddVehiclekeys(vehicle)
local plate = GetVehicleNumberPlateText(vehicle)
local model = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))
exports['qs-vehiclekeys']:GiveKeys(plate, model)
end

View File

@@ -0,0 +1,8 @@
if Config.Vehiclekeys ~= 'vehicles_keys' then
return
end
function AddVehiclekeys(vehicle)
local plate = GetVehicleNumberPlateText(vehicle)
TriggerServerEvent('vehicles_keys:selfGiveVehicleKeys', plate)
end

View File

@@ -0,0 +1,8 @@
if Config.Vehiclekeys ~= 'wasabi_carlock' then
return
end
function AddVehiclekeys(vehicle)
local plate = GetVehicleNumberPlateText(vehicle)
exports.wasabi_carlock:GiveKey(plate)
end

View File

@@ -0,0 +1,28 @@
local pma = exports['pma-voice']
local mumble = exports['mumble-voip']
local toko = exports['tokovoip_script']
function AddToCall(callId)
if Config.Voice == 'pma' then
Debug('callId', callId)
pma:addPlayerToCall(callId)
elseif Config.Voice == 'mumble' then
mumble:addPlayerToCall(callId)
elseif Config.Voice == 'salty' then
TriggerServerEvent('phone:addToCall', callId)
elseif Config.Voice == 'toko' then
toko:addPlayerToRadio(callId)
end
end
function RemoveFromCall(callId)
if Config.Voice == 'pma' then
pma:removePlayerFromCall()
elseif Config.Voice == 'mumble' then
mumble:removePlayerFromCall()
elseif Config.Voice == 'salty' then
TriggerServerEvent('phone:removeFromCall', callId)
elseif Config.Voice == 'toko' then
toko:removePlayerFromRadio(callId)
end
end