structura foldere
mutat kq- folders in un singur folder [kq]
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
if Config.Billing ~= 'RxBilling' then return end
|
||||
|
||||
---@param src number
|
||||
---@return Invoice[]
|
||||
function GetInvoices(src)
|
||||
local identifier = GetIdentifier(src)
|
||||
local invoices = exports.RxBilling:GetPlayerInvoices(identifier, 'incoming')
|
||||
local data = {}
|
||||
|
||||
for k, v in pairs(invoices) do
|
||||
if v.status ~= 'pending' then goto continue end
|
||||
|
||||
table.insert(data, {
|
||||
id = v.id,
|
||||
price = v.amount,
|
||||
label = v.reason or 'No reason',
|
||||
})
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
if Config.Billing ~= 'codemv2' then return end
|
||||
|
||||
---@param source number
|
||||
---@return Invoice[]
|
||||
function GetInvoices(source)
|
||||
local src = source
|
||||
local bills = exports['codem-billingv2']:GetPlayerUnpaidBillings(src)
|
||||
local data = {}
|
||||
|
||||
if bills then
|
||||
for _, v in pairs(bills) do
|
||||
table.insert(data, {
|
||||
id = v.invoiceid,
|
||||
price = v.amount,
|
||||
label = v.reason,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
RegisterNetEvent('codemBilling:PayInvoice', function(invoiceId)
|
||||
local src = source
|
||||
exports['codem-billingv2']:PayBilling(src, invoiceId)
|
||||
end)
|
||||
@@ -0,0 +1,19 @@
|
||||
if Config.Billing ~= 'esx_billing' then return end
|
||||
|
||||
---@param source number
|
||||
---@return Invoice[]
|
||||
function GetInvoices(source)
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
local invoices = MySQL.query.await('SELECT amount, id, label FROM billing WHERE identifier = ?', { xPlayer.identifier })
|
||||
local data = {}
|
||||
|
||||
for k, v in pairs(invoices) do
|
||||
table.insert(data, {
|
||||
id = v.id,
|
||||
price = v.amount,
|
||||
label = v.label or 'No reason',
|
||||
})
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
if Config.Billing ~= 'okok' then return end
|
||||
|
||||
|
||||
---@param source number
|
||||
---@return Invoice[]
|
||||
function GetInvoices(source)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
local invoices = MySQL.Sync.fetchAll('SELECT * FROM okokbilling WHERE receiver_identifier = ? ORDER BY CASE WHEN status = "unpaid" THEN 1 WHEN status = "autopaid" THEN 2 WHEN status = "paid" THEN 3 WHEN status = "cancelled" THEN 4 END ASC, id DESC', { identifier })
|
||||
local data = {}
|
||||
for k, v in pairs(invoices) do
|
||||
if v.status == 'paid' then goto continue end
|
||||
table.insert(data, {
|
||||
id = v.id,
|
||||
price = v.invoice_value,
|
||||
label = v.notes or 'No reason',
|
||||
})
|
||||
::continue::
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
if Config.Billing ~= 'qs' then return end
|
||||
|
||||
---@param source number
|
||||
---@return Invoice[]
|
||||
function GetInvoices(source)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
-- Consulta ajustada a la tabla qs_billing
|
||||
local invoices = MySQL.Sync.fetchAll('SELECT * FROM qs_billing WHERE receiver_identifier = ? ORDER BY CASE WHEN status = "unpaid" THEN 1 WHEN status = "autopaid" THEN 2 WHEN status = "paid" THEN 3 WHEN status = "cancelled" THEN 4 END ASC, id DESC', { identifier })
|
||||
local data = {}
|
||||
for k, v in pairs(invoices) do
|
||||
-- Ignora facturas no pagadas
|
||||
if v.status == 'unpaid' then goto continue end
|
||||
table.insert(data, {
|
||||
id = v.id,
|
||||
price = v.invoice_value, -- Mapeo directo de invoice_value
|
||||
label = v.notes or 'No reason', -- Mapeo directo de notes
|
||||
})
|
||||
::continue::
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
if Config.Billing ~= 'standalone' then return end
|
||||
|
||||
---@param source number
|
||||
---@return Invoice[]
|
||||
function GetInvoices(source)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
local invoices = MySQL.Sync.fetchAll('SELECT * FROM phone_bills WHERE `identifier` = ?', { identifier })
|
||||
return invoices
|
||||
end
|
||||
|
||||
RegisterCommand('sendbill', function(source, args)
|
||||
local job = GetJobName(source)
|
||||
local existJob = table.find(Config.BillJobs, function(v)
|
||||
return v == job
|
||||
end)
|
||||
if not existJob then
|
||||
return TriggerClientEvent('phone:client:sendTextMessage', source, Lang('PHONE_NOTIFICATION_BANK_BILL_WHITELIST'), 'error')
|
||||
end
|
||||
local target = tonumber(args[1])
|
||||
local price = tonumber(args[2])
|
||||
local reason = table.concat(args, ' ', 3)
|
||||
reason = reason == '' and Lang('PHONE_NOTIFICATION_BANK_INVOICE_NO_REASON') or reason
|
||||
if not target or not price then
|
||||
return TriggerClientEvent('phone:client:sendTextMessage', source, Lang('PHONE_NOTIFICATION_BANK_NO_PLAYER'), 'error')
|
||||
end
|
||||
local identifier = GetIdentifier(target)
|
||||
if not identifier then
|
||||
return TriggerClientEvent('phone:client:sendTextMessage', source, Lang('PHONE_NOTIFICATION_BANK_NO_PLAYER'), 'error')
|
||||
end
|
||||
MySQL.Sync.execute('INSERT INTO `phone_bills` (`identifier`, `sender`, `price`, `label`) VALUES (?, ?, ?, ?)', {
|
||||
identifier,
|
||||
GetIdentifier(source),
|
||||
price,
|
||||
reason
|
||||
})
|
||||
TriggerClientEvent('phone:client:sendTextMessage', source, Lang('PHONE_NOTIFICATION_BANK_BILL_SENT') .. ' ' .. GetPlayerName(target), 'success')
|
||||
TriggerClientEvent('phone:sendNotificationOld', target, {
|
||||
app = 'bank',
|
||||
title = Lang('PHONE_NOTIFICATION_BANK_TITLE'),
|
||||
text = Lang('PHONE_NOTIFICATION_BANK_BILL_RECEIVED') .. ' ' .. GetPlayerName(source)
|
||||
})
|
||||
end, false)
|
||||
@@ -0,0 +1,91 @@
|
||||
-- These are examples of how to use the custom functions in the server.
|
||||
|
||||
-- Example of how to use the sendNewMail export.
|
||||
RegisterCommand('mailTest', function(source)
|
||||
exports['qs-smartphone-pro']:sendNewMail(source, {
|
||||
sender = 'Quasar',
|
||||
subject = 'Es tu culpa',
|
||||
message = 'Es tu culpa que no haya un ejemplo de como usar esto...'
|
||||
})
|
||||
end, false)
|
||||
|
||||
-- You can get phone name by using this export. It returns all phone names.
|
||||
RegisterCommand('phoneNames', function(source)
|
||||
local phoneNames = exports['qs-smartphone-pro']:getPhoneNames()
|
||||
print(json.encode(phoneNames, { indent = true }))
|
||||
end, false)
|
||||
|
||||
-- This export returns player's phone number. If the user has used the phone. It prioritizes that phone. If the user has never used a phone, it returns the phone number of any phone from its inventory.
|
||||
RegisterCommand('getPhone', function(source, args)
|
||||
local identifier = GetIdentifier(source) -- This is a player identifier. Like ESX.GetPlayerFromId(source).identifier
|
||||
local mustBePhoneOwner = true -- If its true, checks phone owner is the identifier. So you can handle to a stolen phone.
|
||||
local number = exports['qs-smartphone-pro']:GetPhoneNumberFromIdentifier(identifier, mustBePhoneOwner)
|
||||
print(number) -- phone number or false
|
||||
end, false)
|
||||
|
||||
-- This export returns player's currently using or last used phone meta
|
||||
RegisterCommand('getMeta', function(source, args)
|
||||
local meta = exports['qs-smartphone-pro']:getMetaFromSource(source)
|
||||
print(json.encode(meta, { indent = true })) -- phone meta or false
|
||||
end, false)
|
||||
|
||||
-- This export sends a new message to a phone number.
|
||||
RegisterCommand('sendNewMessage', function(source, args)
|
||||
local identifier = GetIdentifier(source)
|
||||
local sender = exports['qs-smartphone-pro']:GetPhoneNumberFromIdentifier(identifier, false) -- Sender phone number
|
||||
local target = '293823' -- Target phone number
|
||||
local message = 'Hello world!'
|
||||
local type = 'message' -- message or location
|
||||
exports['qs-smartphone-pro']:sendNewMessage(sender, target, message, type)
|
||||
end, false)
|
||||
|
||||
-- This export sends a SOS message to a phone number.
|
||||
RegisterCommand('sendSOSMessage', function(source, args)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
local phoneNumber = exports['qs-smartphone-pro']:GetPhoneNumberFromIdentifier(identifier, false) -- Sender phone number
|
||||
local job = 'ambulance'
|
||||
local coords = GetEntityCoords(GetPlayerPed(src))
|
||||
exports['qs-smartphone-pro']:sendSOSMessage(phoneNumber, job, json.encode(coords), 'location')
|
||||
end, false)
|
||||
|
||||
-- This export sends a new message from a app. You can use this to send a message from a app.
|
||||
RegisterCommand('sendNewMessageFromApp', function(source, args)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
local phone = exports['qs-smartphone-pro']:GetPhoneNumberFromIdentifier(identifier, false) -- Sender phone number
|
||||
local message = 'Quasar: Hello from twitter!'
|
||||
local appName = 'twitter'
|
||||
exports['qs-smartphone-pro']:sendNewMessageFromApp(src, phone, message, appName)
|
||||
end, false)
|
||||
|
||||
-- This export sends a new notification to a phone number.
|
||||
RegisterCommand('sendNewNotification', function(source, args)
|
||||
local phone = exports['qs-smartphone-pro']:GetPhoneNumberFromIdentifier(GetIdentifier(source), false)
|
||||
local disableTempNotification = false -- Disables the temporary notification. (Pop up notification)
|
||||
exports['qs-smartphone-pro']:sendNotification(phone, {
|
||||
app = 'twitter',
|
||||
msg = 'Hello world!',
|
||||
head = 'Quasar'
|
||||
}, disableTempNotification)
|
||||
end, false)
|
||||
|
||||
-- Same as sendNewNotification
|
||||
RegisterCommand('sendNewNotification', function(source, args)
|
||||
local phone = exports['qs-smartphone-pro']:GetPhoneNumberFromIdentifier(GetIdentifier(source), false)
|
||||
local disableTempNotification = false -- Disables the temporary notification. (Pop up notification)
|
||||
exports['qs-smartphone-pro']:sendNotificationOld(phone, {
|
||||
app = 'twitter',
|
||||
msg = 'Hello world!',
|
||||
head = 'Quasar'
|
||||
}, disableTempNotification)
|
||||
end, false)
|
||||
|
||||
RegisterCommand('sendNewMessage', function(source, args)
|
||||
local phone = '323'
|
||||
local targetPhone = '123'
|
||||
local message = 'Hello'
|
||||
local type = 'message' -- message, location
|
||||
local success = exports['qs-smartphone-pro']:sendNewMessage(phone, targetPhone, message, type)
|
||||
print('Success: ', success)
|
||||
end, false)
|
||||
@@ -0,0 +1,197 @@
|
||||
--[[
|
||||
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
|
||||
|
||||
local legacyEsx = pcall(function()
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
end)
|
||||
if not legacyEsx then
|
||||
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
|
||||
end
|
||||
|
||||
identifierTable = 'identifier'
|
||||
userColumn = 'users'
|
||||
garageTable = 'owned_vehicles'
|
||||
garageIdentifierColumn = 'owner'
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded', function(id, data)
|
||||
Wait(2000)
|
||||
Debug('Loaded player:', id)
|
||||
CreateQuests(id)
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
for k, v in pairs(ESX.Players) do
|
||||
if v and v.source then
|
||||
Debug('Loaded player:', v.source)
|
||||
CreateQuests(v.source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function RegisterServerCallback(name, cb)
|
||||
ESX.RegisterServerCallback(name, cb)
|
||||
end
|
||||
|
||||
exports('RegisterServerCallback', RegisterServerCallback)
|
||||
|
||||
function RegisterUsableItem(name, cb)
|
||||
ESX.RegisterUsableItem(name, cb)
|
||||
end
|
||||
|
||||
function GetPlayerFromId(source)
|
||||
return ESX.GetPlayerFromId(source)
|
||||
end
|
||||
|
||||
function GetPlayerFromIdentifier(identifier)
|
||||
if not identifier then return nil end
|
||||
identifier = string.gsub(identifier, ' ', '')
|
||||
return ESX.GetPlayerFromIdentifier(identifier)
|
||||
end
|
||||
|
||||
function GetItem(player, item)
|
||||
return player.getInventoryItem(item)
|
||||
end
|
||||
|
||||
function GetCrypto(identifier)
|
||||
local str = ([[
|
||||
SELECT cryptocurrency FROM %s WHERE %s = ? LIMIT 1
|
||||
]]):format(userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] or not result[1].cryptocurrency then
|
||||
return 0
|
||||
end
|
||||
return result[1].cryptocurrency
|
||||
end
|
||||
|
||||
function AddItem(source, item, count, slot, metadata)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.addInventoryItem(item, count, metadata, slot)
|
||||
end
|
||||
|
||||
function AddWeapon(source, weapon, ammo)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.addWeapon(weapon, ammo)
|
||||
end
|
||||
|
||||
function RemoveItem(source, item, count, slot)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.removeInventoryItem(item, count, nil, slot)
|
||||
end
|
||||
|
||||
function GetBankMoney(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
return player.getAccount('bank').money
|
||||
end
|
||||
|
||||
function SetJob(source, job, grade)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.setJob(job, grade)
|
||||
end
|
||||
|
||||
function AddBankMoney(source, amount)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.addAccountMoney('bank', amount)
|
||||
end
|
||||
|
||||
function RemoveBankMoney(source, amount)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.removeAccountMoney('bank', amount)
|
||||
end
|
||||
|
||||
function GetJobName(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
if not player then return 'unemployed' end
|
||||
return player.getJob().name
|
||||
end
|
||||
|
||||
function IsAdmin(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
return player.getGroup() == 'admin'
|
||||
end
|
||||
|
||||
function GetIdentifier(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
if not player then
|
||||
print('ESX player not found. Source: ', source)
|
||||
return false
|
||||
end
|
||||
return player.identifier
|
||||
end
|
||||
|
||||
function GetItems(player)
|
||||
if not player then return end
|
||||
if Config.Inventory == 'codem-inventory' then
|
||||
local inventory = player.getInventory()
|
||||
for k, v in pairs(inventory) do
|
||||
if tonumber(v.amount) <= 0 then
|
||||
inventory[k] = nil
|
||||
elseif not Config.UniquePhone and not v.info then
|
||||
inventory[k].info = {}
|
||||
inventory[k].metadata = {}
|
||||
end
|
||||
end
|
||||
return inventory
|
||||
elseif Config.Inventory == 'tgiann-inventory' then
|
||||
local inventory = exports['tgiann-inventory']:GetPlayerItems(player.source)
|
||||
for k, v in pairs(inventory) do
|
||||
if tonumber(v.amount) <= 0 then
|
||||
inventory[k] = nil
|
||||
elseif not Config.UniquePhone and not v.info then
|
||||
inventory[k].info = {}
|
||||
inventory[k].metadata = {}
|
||||
end
|
||||
end
|
||||
return inventory
|
||||
else
|
||||
local inventory = player.getInventory()
|
||||
for k, v in pairs(inventory) do
|
||||
local count = v.count or v.amount or 0
|
||||
if count <= 0 then
|
||||
inventory[k] = nil
|
||||
elseif not Config.UniquePhone and not v.info then
|
||||
inventory[k].info = {}
|
||||
inventory[k].metadata = {}
|
||||
end
|
||||
end
|
||||
return inventory
|
||||
end
|
||||
end
|
||||
|
||||
function GetPlayerSource(player)
|
||||
return player.source
|
||||
end
|
||||
|
||||
function GetDataForWithOutMetaData(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
local identifier = GetIdentifier(source)
|
||||
local result = MySQL.Sync.fetchAll('SELECT * FROM phone_metadata WHERE owneridentifier = ?', {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if result then return json.decode(result.metadata) end
|
||||
local info
|
||||
local firstname, lastname, phone = GetUserData(identifier)
|
||||
info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
phone = phone
|
||||
})
|
||||
MySQL.Async.execute('INSERT INTO phone_metadata (owneridentifier, metadata, phoneNumber) VALUES (?, ?, ?)', {
|
||||
identifier,
|
||||
json.encode(info),
|
||||
info.phoneNumber
|
||||
})
|
||||
return info
|
||||
end
|
||||
@@ -0,0 +1,173 @@
|
||||
--[[
|
||||
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 = exports['qb-core']:GetCoreObject()
|
||||
|
||||
identifierTable = 'citizenid'
|
||||
userColumn = 'players'
|
||||
garageTable = 'player_vehicles'
|
||||
garageIdentifierColumn = 'citizenid'
|
||||
|
||||
function RegisterServerCallback(name, cb)
|
||||
ESX.Functions.CreateCallback(name, cb)
|
||||
end
|
||||
|
||||
exports('RegisterServerCallback', RegisterServerCallback)
|
||||
|
||||
function RegisterUsableItem(name, cb)
|
||||
ESX.Functions.CreateUseableItem(name, cb)
|
||||
end
|
||||
|
||||
RegisterNetEvent('QBCore:Server:OnPlayerLoaded', function()
|
||||
local src = source
|
||||
if CheckWalletId then
|
||||
CheckWalletId(src)
|
||||
end
|
||||
CreateQuests(src)
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
for k, v in pairs(ESX.Functions.GetPlayers()) do
|
||||
Debug('Loaded player:', v)
|
||||
if v then
|
||||
CreateQuests(v)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function GetPlayerFromId(source)
|
||||
source = tonumber(source)
|
||||
return ESX.Functions.GetPlayer(source)
|
||||
end
|
||||
|
||||
function GetPlayerFromIdentifier(identifier)
|
||||
identifier = string.gsub(identifier, ' ', '')
|
||||
return ESX.Functions.GetPlayerByCitizenId(identifier)
|
||||
end
|
||||
|
||||
function GetItem(player, item)
|
||||
local data = player.Functions.GetItemByName(item)
|
||||
data.count = data.amount
|
||||
return data
|
||||
end
|
||||
|
||||
function AddItem(source, item, count, slot, metadata)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.AddItem(item, count, slot, metadata)
|
||||
end
|
||||
|
||||
function GetCrypto(identifier)
|
||||
local str = ([[
|
||||
SELECT cryptocurrency FROM %s WHERE %s = ? LIMIT 1
|
||||
]]):format(userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] or not result[1].cryptocurrency then
|
||||
return 0
|
||||
end
|
||||
return result[1].cryptocurrency
|
||||
end
|
||||
|
||||
function RemoveItem(source, item, count, slot)
|
||||
local player = GetPlayerFromId(source, true)
|
||||
player.Functions.RemoveItem(item, count, slot)
|
||||
end
|
||||
|
||||
function GetBankMoney(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
return player.PlayerData.money.bank
|
||||
end
|
||||
|
||||
function SetJob(source, job, grade)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.SetJob(job, grade)
|
||||
end
|
||||
|
||||
function AddBankMoney(source, amount)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.AddMoney('bank', amount)
|
||||
end
|
||||
|
||||
function RemoveBankMoney(source, amount)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.RemoveMoney('bank', amount)
|
||||
end
|
||||
|
||||
function GetJobName(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
return player.PlayerData.job.name
|
||||
end
|
||||
|
||||
function IsAdmin(source)
|
||||
if source == 0 then
|
||||
return true
|
||||
end
|
||||
return ESX.Functions.HasPermission(source, 'god') or IsPlayerAceAllowed(source, 'command') or ESX.Functions.HasPermission(source, 'admin')
|
||||
end
|
||||
|
||||
function GetIdentifier(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
if not player then
|
||||
print('ESX player not found. Source: ', source)
|
||||
return false
|
||||
end
|
||||
return player.PlayerData.citizenid
|
||||
end
|
||||
|
||||
function GetItems(player)
|
||||
if not player then return false end
|
||||
if Config.Inventory == 'origen_inventory' then
|
||||
local userData = OrigenInventory:getInventory(player.PlayerData.source)
|
||||
if not userData then return end
|
||||
return userData.inventory
|
||||
end
|
||||
return player.PlayerData.items
|
||||
end
|
||||
|
||||
function GetPlayerSource(player)
|
||||
return player.PlayerData.source
|
||||
end
|
||||
|
||||
function GetDataForWithOutMetaData(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
local identifier = GetIdentifier(source)
|
||||
local result = MySQL.Sync.fetchAll('SELECT * FROM phone_metadata WHERE owneridentifier = ?', {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if result then return json.decode(result.metadata) end
|
||||
local info
|
||||
info = CreatePhoneMetaData({
|
||||
firstname = player.PlayerData.charinfo.firstname,
|
||||
lastname = player.PlayerData.charinfo.lastname,
|
||||
identifier = identifier,
|
||||
phone = player.PlayerData.charinfo.phone
|
||||
})
|
||||
MySQL.Async.execute('INSERT INTO phone_metadata (owneridentifier, metadata, phoneNumber) VALUES (?, ?, ?)', {
|
||||
identifier,
|
||||
json.encode(info),
|
||||
info.phoneNumber
|
||||
})
|
||||
return info
|
||||
end
|
||||
|
||||
RegisterServerCallback('phone:market:getPlayerData', function(_, cb, player)
|
||||
local identifier = GetIdentifier(player)
|
||||
local firstName, lastName, phoneNumber = GetUserData(identifier)
|
||||
cb({
|
||||
name = firstName .. ' ' .. lastName,
|
||||
id = identifier,
|
||||
})
|
||||
end)
|
||||
|
||||
RegisterServerCallback('phone:market:getAccountBalance', function(source, cb, account)
|
||||
cb(exports['qb-banking']:GetAccountBalance(account))
|
||||
end)
|
||||
@@ -0,0 +1,161 @@
|
||||
--[[
|
||||
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
|
||||
|
||||
ESX = exports['qb-core']:GetCoreObject()
|
||||
|
||||
identifierTable = 'citizenid'
|
||||
userColumn = 'players'
|
||||
|
||||
function RegisterServerCallback(name, cb)
|
||||
ESX.Functions.CreateCallback(name, cb)
|
||||
end
|
||||
|
||||
exports('RegisterServerCallback', RegisterServerCallback)
|
||||
|
||||
function RegisterUsableItem(name, cb)
|
||||
exports.qbx_core:CreateUseableItem(name, cb)
|
||||
end
|
||||
|
||||
RegisterNetEvent('QBCore:Server:OnPlayerLoaded', function()
|
||||
local src = source
|
||||
if CheckWalletId then
|
||||
CheckWalletId(src)
|
||||
end
|
||||
CreateQuests(src)
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
for k, v in pairs(QBCore.Functions.GetPlayers()) do
|
||||
if v and v.source then
|
||||
Debug('Loaded player:', v.source)
|
||||
CreateQuests(v.source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function GetPlayerFromId(source)
|
||||
source = tonumber(source)
|
||||
return exports.qbx_core:GetPlayer(source)
|
||||
end
|
||||
|
||||
function GetPlayerFromIdentifier(identifier)
|
||||
identifier = string.gsub(identifier, ' ', '')
|
||||
return exports.qbx_core:GetPlayerByCitizenId(identifier)
|
||||
end
|
||||
|
||||
function GetItem(player, item)
|
||||
local data = exports.ox_inventory:GetItem(player.PlayerData.source, item, nil, false)
|
||||
return data
|
||||
end
|
||||
|
||||
function AddItem(source, item, count, slot, metadata)
|
||||
exports.ox_inventory:AddItem(source, item, count, metadata, slot)
|
||||
end
|
||||
|
||||
function GetCrypto(identifier)
|
||||
local str = ([[
|
||||
SELECT cryptocurrency FROM %s WHERE %s = ? LIMIT 1
|
||||
]]):format(userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] or not result[1].cryptocurrency then
|
||||
return 0
|
||||
end
|
||||
return result[1].cryptocurrency
|
||||
end
|
||||
|
||||
function RemoveItem(source, item, count, slot)
|
||||
exports.ox_inventory:RemoveItem(source, item, count, metadata, slot)
|
||||
end
|
||||
|
||||
function GetBankMoney(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
return player.PlayerData.money.bank
|
||||
end
|
||||
|
||||
function SetJob(source, job, grade)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.SetJob(job, grade)
|
||||
end
|
||||
|
||||
function AddBankMoney(source, amount)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.AddMoney('bank', amount)
|
||||
end
|
||||
|
||||
function RemoveBankMoney(source, amount)
|
||||
local player = GetPlayerFromId(source)
|
||||
player.Functions.RemoveMoney('bank', amount)
|
||||
end
|
||||
|
||||
function GetJobName(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
return player.PlayerData.job.name
|
||||
end
|
||||
|
||||
function IsAdmin(source)
|
||||
if source == 0 then
|
||||
return true
|
||||
end
|
||||
return exports.qbx_core:HasPermission(source, 'god') or IsPlayerAceAllowed(source, 'command') or exports.qbx_core:HasPermission(source, 'admin')
|
||||
end
|
||||
|
||||
function GetIdentifier(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
if not player then
|
||||
print('ESX player not found. Source: ', source)
|
||||
return false
|
||||
end
|
||||
return player.PlayerData.citizenid
|
||||
end
|
||||
|
||||
function GetItems(player)
|
||||
if not player then return false end
|
||||
return exports.ox_inventory:GetInventoryItems(player.PlayerData.source)
|
||||
end
|
||||
|
||||
function GetPlayerSource(player)
|
||||
return player.PlayerData.source
|
||||
end
|
||||
|
||||
function GetDataForWithOutMetaData(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
local identifier = GetIdentifier(source)
|
||||
local result = MySQL.Sync.fetchAll('SELECT * FROM phone_metadata WHERE owneridentifier = ?', {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if result then return json.decode(result.metadata) end
|
||||
local info
|
||||
info = CreatePhoneMetaData({
|
||||
firstname = player.PlayerData.charinfo.firstname,
|
||||
lastname = player.PlayerData.charinfo.lastname,
|
||||
identifier = identifier,
|
||||
phone = player.PlayerData.charinfo.phone
|
||||
})
|
||||
MySQL.Async.execute('INSERT INTO phone_metadata (owneridentifier, metadata, phoneNumber) VALUES (?, ?, ?)', {
|
||||
identifier,
|
||||
json.encode(info),
|
||||
info.phoneNumber
|
||||
})
|
||||
return info
|
||||
end
|
||||
|
||||
RegisterServerCallback('phone:market:getPlayerData', function(_, cb, player)
|
||||
local identifier = GetIdentifier(player)
|
||||
local firstName, lastName, phoneNumber = GetUserData(identifier)
|
||||
cb({
|
||||
name = firstName .. ' ' .. lastName,
|
||||
id = identifier,
|
||||
})
|
||||
end)
|
||||
@@ -0,0 +1,202 @@
|
||||
--[[
|
||||
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
|
||||
|
||||
-- ESX Callbacks
|
||||
local serverCallbacks = {}
|
||||
|
||||
local clientRequests = {}
|
||||
local RequestId = 0
|
||||
|
||||
---@param eventName string
|
||||
---@param callback function
|
||||
RegisterServerCallback = function(eventName, callback)
|
||||
serverCallbacks[eventName] = callback
|
||||
end
|
||||
|
||||
exports('RegisterServerCallback', RegisterServerCallback)
|
||||
|
||||
RegisterNetEvent('qs-smartphone-pro:triggerServerCallback', function(eventName, requestId, invoker, ...)
|
||||
if not serverCallbacks[eventName] then
|
||||
return print(('[^1ERROR^7] Server Callback not registered, name: ^5%s^7, invoker resource: ^5%s^7'):format(eventName, invoker))
|
||||
end
|
||||
|
||||
local source = source
|
||||
|
||||
serverCallbacks[eventName](source, function(...)
|
||||
TriggerClientEvent('qs-smartphone-pro:serverCallback', source, requestId, invoker, ...)
|
||||
end, ...)
|
||||
end)
|
||||
|
||||
---@param player number playerId
|
||||
---@param eventName string
|
||||
---@param callback function
|
||||
---@param ... any
|
||||
TriggerClientCallback = function(player, eventName, callback, ...)
|
||||
clientRequests[RequestId] = callback
|
||||
|
||||
TriggerClientEvent('qs-smartphone-pro:triggerClientCallback', player, eventName, RequestId, GetInvokingResource() or 'unknown', ...)
|
||||
|
||||
RequestId = RequestId + 1
|
||||
end
|
||||
|
||||
RegisterNetEvent('qs-smartphone-pro:clientCallback', function(requestId, invoker, ...)
|
||||
if not clientRequests[requestId] then
|
||||
return print(('[^1ERROR^7] Client Callback with requestId ^5%s^7 Was Called by ^5%s^7 but does not exist.'):format(requestId, invoker))
|
||||
end
|
||||
|
||||
clientRequests[requestId](...)
|
||||
clientRequests[requestId] = nil
|
||||
end)
|
||||
|
||||
function GetCrypto(identifier)
|
||||
Debug('GetCrypto used with standalone')
|
||||
return 0
|
||||
end
|
||||
|
||||
RegisterServerCallback('qs-smartphone-pro:GetIdentifier', function(source, cb)
|
||||
local identifier = GetIdentifier(source)
|
||||
cb(identifier)
|
||||
end)
|
||||
|
||||
function RegisterUsableItem(name, cb)
|
||||
Debug('RegisterUsableItem is not supported with standalone')
|
||||
return false
|
||||
end
|
||||
|
||||
function GetPlayerFromId(source)
|
||||
return {
|
||||
source = source,
|
||||
identifier = GetIdentifier(source)
|
||||
}
|
||||
end
|
||||
|
||||
function GetPlayerFromIdentifier(identifier)
|
||||
if not identifier then
|
||||
return nil
|
||||
end
|
||||
identifier = string.gsub(identifier, ' ', '')
|
||||
local players = GetPlayers()
|
||||
for k, v in pairs(players) do
|
||||
if GetIdentifier(v) == identifier then
|
||||
return {
|
||||
source = v,
|
||||
identifier = identifier
|
||||
}
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function GetItem(player, item)
|
||||
Debug('GetItem used with standalone')
|
||||
return {
|
||||
name = item,
|
||||
count = 99,
|
||||
}
|
||||
end
|
||||
|
||||
function AddItem(source, item, count, slot, metadata)
|
||||
Debug('AddItem used with standalone')
|
||||
return true
|
||||
end
|
||||
|
||||
function AddWeapon(source, weapon, ammo)
|
||||
Debug('AddWeapon used with standalone')
|
||||
return true
|
||||
end
|
||||
|
||||
function RemoveItem(source, item, count, slot)
|
||||
Debug('RemoveItem used with standalone')
|
||||
return true
|
||||
end
|
||||
|
||||
function GetBankMoney(source)
|
||||
Debug('GetBankMoney used with standalone')
|
||||
return 0
|
||||
end
|
||||
|
||||
function SetJob(source, job, grade)
|
||||
Debug('SetJob used with standalone')
|
||||
return true
|
||||
end
|
||||
|
||||
function AddBankMoney(source, amount)
|
||||
Debug('AddBankMoney used with standalone')
|
||||
return false
|
||||
end
|
||||
|
||||
function RemoveBankMoney(source, amount)
|
||||
Debug('RemoveBankMoney used with standalone')
|
||||
return false
|
||||
end
|
||||
|
||||
function GetJobName(source)
|
||||
Debug('GetJobName used with standalone')
|
||||
return 'unemployed'
|
||||
end
|
||||
|
||||
function IsAdmin(source)
|
||||
return IsPlayerAceAllowed(source, 'command.qsphone_admin') == 1
|
||||
end
|
||||
|
||||
function GetIdentifier(source)
|
||||
for k, v in pairs(GetPlayerIdentifiers(source)) do
|
||||
if string.sub(v, 1, string.len('license:')) == 'license:' then
|
||||
return v:gsub('license:', '')
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function GetStandaloneUserData(identifier)
|
||||
local firstname = 'unknown'
|
||||
local lastname = 'unknown'
|
||||
local phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function GetItems(player)
|
||||
Debug('Get Items used with standalone')
|
||||
return {
|
||||
{
|
||||
name = 'phone'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function GetPlayerSource(player)
|
||||
return player.source
|
||||
end
|
||||
|
||||
function GetDataForWithOutMetaData(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
local identifier = GetIdentifier(source)
|
||||
local result = MySQL.Sync.fetchAll('SELECT * FROM phone_metadata WHERE owneridentifier = ?', {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if result then return json.decode(result.metadata) end
|
||||
local info
|
||||
local firstname, lastname, phone = GetUserData(identifier)
|
||||
info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
phone = phone
|
||||
})
|
||||
MySQL.Async.execute('INSERT INTO phone_metadata (owneridentifier, metadata, phoneNumber) VALUES (?, ?, ?)', {
|
||||
identifier,
|
||||
json.encode(info),
|
||||
info.phoneNumber
|
||||
})
|
||||
return info
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
if Config.Garage ~= 'RxGarages' then
|
||||
return
|
||||
end
|
||||
|
||||
local function getTableName()
|
||||
return Config.Framework == 'qb' and 'player_vehicles' or 'owned_vehicles'
|
||||
end
|
||||
|
||||
local function getOwnerField()
|
||||
return Config.Framework == 'qb' and 'citizenid' or 'owner'
|
||||
end
|
||||
|
||||
local function determineGarageName(vehicleData)
|
||||
local garageName = vehicleData.location or vehicleData.in_shared
|
||||
if not garageName then
|
||||
if vehicleData.parked_at == 'garage' then
|
||||
garageName = 'Garage'
|
||||
elseif vehicleData.parked_at == 'outside' then
|
||||
garageName = 'Outside'
|
||||
elseif vehicleData.parked_at == 'impound' then
|
||||
garageName = 'Impound'
|
||||
elseif vehicleData.parked_at == 'shared' then
|
||||
garageName = 'Shared Garage'
|
||||
else
|
||||
garageName = vehicleData.parked_at
|
||||
end
|
||||
end
|
||||
return garageName
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = ([[
|
||||
UPDATE %s
|
||||
SET parked_at = 'outside'
|
||||
WHERE plate = ?
|
||||
]]):format(getTableName())
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local tableName = getTableName()
|
||||
local ownerField = getOwnerField()
|
||||
|
||||
local str = ([[
|
||||
SELECT * FROM %s WHERE %s = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]):format(tableName, ownerField)
|
||||
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
|
||||
for k, v in pairs(result) do
|
||||
if Config.Framework ~= 'qb' then
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = v.parked_at == 'garage' or v.parked_at == 'shared',
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = vehicle,
|
||||
garage = determineGarageName(v),
|
||||
})
|
||||
else
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = v.parked_at == 'garage' or v.parked_at == 'shared',
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = determineGarageName(v),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,95 @@
|
||||
if Config.Garage ~= 'cd_garage' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET in_garage = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET state = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local inGarage = v.in_garage
|
||||
local garageId = v.garage_id
|
||||
local impound = v.impound
|
||||
|
||||
if not inGarage and impound == 0 then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
if impound == 1 then
|
||||
garageId = 'IMPOUND'
|
||||
inGarage = false
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
local inGarage = v.in_garage
|
||||
local garageId = v.garage_id
|
||||
local impound = v.impound
|
||||
|
||||
if not inGarage and impound == 0 then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
if impound == 1 then
|
||||
garageId = 'IMPOUND'
|
||||
inGarage = false
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,81 @@
|
||||
if Config.Garage ~= 'codem-garage' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET parking = '', stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET parking = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local garageId = v.parking
|
||||
local inGarage = v.stored == 1 or v.stored == 2
|
||||
|
||||
if v.stored == 0 then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = v.stored,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
local inGarage = v.stored
|
||||
local garageId = v.parking
|
||||
if not inGarage then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = v.stored,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
if Config.Garage ~= 'default' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET garage = 'OUT', stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET state = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local garageId = v.garage or v.parking
|
||||
local inGarage = v.state == 1 or v.state == 2
|
||||
|
||||
if v.state == 0 then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
local inGarage = v.stored == 1
|
||||
local garageId = v.garage or v.parking
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,95 @@
|
||||
if Config.Garage ~= 'jg-advancedgarages' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET in_garage = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET in_garage = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local inGarage = v.in_garage
|
||||
local garageId = v.garage_id
|
||||
local impound = v.impound
|
||||
|
||||
if not inGarage then
|
||||
garageId = v.impound == 1 and 'IMPOUND' or 'OUT'
|
||||
end
|
||||
|
||||
if impound == 1 then
|
||||
garageId = v.garage_id
|
||||
inGarage = false
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel * 10 or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
local inGarage = v.in_garage
|
||||
local garageId = v.garage_id
|
||||
local impound = v.impound
|
||||
|
||||
if not inGarage then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
if impound == 1 then
|
||||
garageId = v.impound == 1 and 'IMPOUND' or 'OUT'
|
||||
inGarage = false
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel * 10 or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
if Config.Garage ~= 'loaf_garage' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET garage = 'OUT', stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET state = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local garageId = v.garage or v.parking
|
||||
local inGarage = v.state == 1 or v.state == 2
|
||||
|
||||
if v.state == 0 then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
local inGarage = v.stored
|
||||
local garageId = v.garage or v.parking
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,84 @@
|
||||
if Config.Garage ~= 'lunar_garage' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND type = 'car' and job is NULL
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ? and (type = 'car' OR type = 'automobile') and job is NULL
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local garageId = 'OUT'
|
||||
local inGarage = v.stored == 1 or v.stored == true
|
||||
|
||||
if inGarage then
|
||||
garageId = 'IN'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
|
||||
local garageId = 'OUT'
|
||||
local inGarage = v.stored == 1 or v.stored == true
|
||||
|
||||
if inGarage then
|
||||
garageId = 'IN'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,93 @@
|
||||
if Config.Garage ~= 'okokGarage' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET parking = '', stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET state = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT *, cast(`stored` as signed) as `stored` FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT *, cast(`state` as signed) as `state` FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
if type(v.state) ~= 'number' then
|
||||
v.state = tonumber(v.state)
|
||||
end
|
||||
local garageId = v.garage or v.parking
|
||||
local inGarage = v.state == 1
|
||||
|
||||
if v.state == 0 then
|
||||
garageId = 'OUT'
|
||||
if tonumber(v.state) == 2 then
|
||||
garageId = 'IMPOUNDED'
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
if type(v.stored) ~= 'number' then
|
||||
v.stored = tonumber(v.stored)
|
||||
end
|
||||
local inGarage = v.stored == 1
|
||||
local garageId = v.garage or v.parking
|
||||
if not inGarage then
|
||||
garageId = 'OUT'
|
||||
if tonumber(v.stored) == 2 then
|
||||
garageId = 'IMPOUNDED'
|
||||
end
|
||||
end
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,120 @@
|
||||
if Config.Garage ~= 'qs-advancedgarages' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET garage = 'OUT', stored = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET garage = 'OUT', state = 0
|
||||
WHERE plate = ?
|
||||
]]
|
||||
end
|
||||
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car')
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ?
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then return false end
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
local impoundGarages = exports['qs-advancedgarages']:getImpoundGarages()
|
||||
for k, v in pairs(result) do
|
||||
local inImpound = false
|
||||
if impoundGarages and impoundGarages[v.garage] then
|
||||
inImpound = true
|
||||
end
|
||||
|
||||
local garageId = v.garage or v.parking
|
||||
local inGarage = (v.state == 1 or v.state == 2) and not inImpound
|
||||
|
||||
if v.state == 0 then
|
||||
garageId = 'OUT'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = v.vehicle,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = v.fuel or 1000,
|
||||
engine = v.engine or 1000,
|
||||
body = v.body or 1000,
|
||||
vehicle = json.decode(v.mods),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
local impoundGarages = exports['qs-advancedgarages']:getImpoundGarages()
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then return end
|
||||
|
||||
local inImpound = false
|
||||
if impoundGarages and impoundGarages[v.garage] then
|
||||
inImpound = true
|
||||
end
|
||||
|
||||
local inGarage = true
|
||||
local garageId = v.garage
|
||||
|
||||
print('garageId', garageId)
|
||||
print('inImpound', inImpound)
|
||||
|
||||
if v.garage == 'OUT' or inImpound then
|
||||
inGarage = false
|
||||
end
|
||||
|
||||
print('inGarage', inGarage)
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = json.decode(v.vehicle),
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
RegisterNetEvent('qs-smartphone-pro:addToPersistent', function(plate, netId)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
local str = ([[
|
||||
SELECT 1 FROM %s WHERE plate = ? AND %s = ? AND jobVehicle = ? LIMIT 1
|
||||
]]):format(garageTable, garageIdentifierColumn)
|
||||
local result = MySQL.Sync.fetchAll(str,
|
||||
{ plate, identifier, '' })
|
||||
if not result[1] then
|
||||
return Error(src, 'Tried to exploit qs-smartphone-pro:addToPersistent')
|
||||
end
|
||||
local response = exports['qs-advancedgarages']:setVehicleToPersistent(netId)
|
||||
if not response then
|
||||
Error(plate, 'Failed to add vehicle to persistent')
|
||||
return
|
||||
end
|
||||
Debug(plate, 'Added vehicle to persistent')
|
||||
end)
|
||||
@@ -0,0 +1,135 @@
|
||||
if Config.Garage ~= 'vms_garagesv2' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:setVehicleToOutSide', function(plate)
|
||||
local plate = plate
|
||||
|
||||
local queryVehicleData = 'SELECT garage, garageSpotID FROM owned_vehicles WHERE plate = ? AND impound_data IS NULL AND impound_date IS NULL'
|
||||
if Config.Framework == 'qb' then
|
||||
queryVehicleData = 'SELECT garage, garageSpotID FROM player_vehicles WHERE plate = ? AND impound_data IS NULL AND impound_date IS NULL'
|
||||
end
|
||||
local vehicleData = MySQL.query.await(queryVehicleData, { plate })
|
||||
|
||||
if vehicleData and vehicleData[1] then
|
||||
TriggerEvent('vms_garagesv2:vehicleTakenByPhone', vehicleData[1].garage, vehicleData[1].garageSpotID)
|
||||
end
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
Citizen.Wait(3000)
|
||||
local foundNetId = nil
|
||||
|
||||
local allVehicles = GetAllVehicles()
|
||||
for i = 1, #allVehicles do
|
||||
if DoesEntityExist(allVehicles[i]) then
|
||||
local vehPlate = GetVehicleNumberPlateText(allVehicles[i])
|
||||
local cleanedPlate = vehPlate:match('^%s*(.-)%s*$')
|
||||
if cleanedPlate == plate then
|
||||
foundNetId = NetworkGetNetworkIdFromEntity(allVehicles[i])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local str = [[
|
||||
UPDATE owned_vehicles
|
||||
SET garage = NULL, garageSpotID = NULL
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
UPDATE player_vehicles
|
||||
SET garage = NULL, garageSpotID = NULL
|
||||
]]
|
||||
end
|
||||
|
||||
if foundNetId then
|
||||
str = str .. ', netid = ? WHERE plate = ?'
|
||||
MySQL.Sync.execute(str, { foundNetId, plate })
|
||||
else
|
||||
str = str .. ' WHERE plate = ?'
|
||||
MySQL.Sync.execute(str, { plate })
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
function getGarageData(identifier, plate)
|
||||
local str = [[
|
||||
SELECT * FROM owned_vehicles WHERE owner = ? AND (type = 'vehicle' OR type = 'car') AND impound_data IS NULL AND impound_date IS NULL
|
||||
]]
|
||||
if Config.Framework == 'qb' then
|
||||
str = [[
|
||||
SELECT * FROM player_vehicles WHERE citizenid = ? AND (type = 'vehicle' OR type = 'car' OR type = 'automobile') AND impound_data IS NULL AND impound_date IS NULL
|
||||
]]
|
||||
end
|
||||
if plate then
|
||||
str = str .. ([[
|
||||
AND plate = "%s"
|
||||
]]):format(plate)
|
||||
end
|
||||
print(str)
|
||||
local result = MySQL.Sync.fetchAll(str, { identifier })
|
||||
if not result[1] then
|
||||
return false
|
||||
end
|
||||
|
||||
local data = {}
|
||||
if Config.Framework == 'qb' then
|
||||
for k, v in pairs(result) do
|
||||
local mods = json.decode(v.mods)
|
||||
if not mods then
|
||||
return
|
||||
end
|
||||
|
||||
local inGarage = false
|
||||
local garageId = 'OUT'
|
||||
if v.garage then
|
||||
local label, coords = exports['vms_garagesv2']:getGarageInfo(v.garage)
|
||||
inGarage = true
|
||||
garageId = label
|
||||
elseif v.impound then
|
||||
garageId = 'IMPOUND'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = mods.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = mods.fuel or 1000,
|
||||
engine = mods.engine or 1000,
|
||||
body = mods.body or 1000,
|
||||
vehicle = mods,
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
else
|
||||
for k, v in pairs(result) do
|
||||
local vehicle = json.decode(v.vehicle)
|
||||
if not vehicle then
|
||||
return
|
||||
end
|
||||
|
||||
local inGarage = false
|
||||
local garageId = 'OUT'
|
||||
print(v.garage)
|
||||
if v.garage then
|
||||
local label, coords = exports['vms_garagesv2']:getGarageInfo(v.garage)
|
||||
inGarage = true
|
||||
garageId = label
|
||||
elseif v.impound then
|
||||
garageId = 'IMPOUND'
|
||||
end
|
||||
|
||||
table.insert(data, {
|
||||
name = vehicle.model,
|
||||
plate = v.plate,
|
||||
inGarage = inGarage,
|
||||
fuel = vehicle.fuel or 1000,
|
||||
engine = vehicle.engine or 1000,
|
||||
body = vehicle.body or 1000,
|
||||
vehicle = vehicle,
|
||||
garage = garageId,
|
||||
})
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -0,0 +1,90 @@
|
||||
if Config.Inventory ~= 'ak47_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
ak47_inventory = exports['ak47_inventory']
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
local identifier = GetIdentifier(src)
|
||||
ak47_inventory:SetItemInfo(identifier, slot, data)
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local identifier = GetIdentifier(src)
|
||||
local items = ak47_inventory:GetInventoryItems(identifier)
|
||||
if not items then return end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
local itemToUpdate = nil
|
||||
for k, v in pairs(items) do
|
||||
if Config.Phones[v.name] then
|
||||
local meta = v.info
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
itemToUpdate = v
|
||||
break
|
||||
elseif v.category == 'uniqueItem' then
|
||||
itemToUpdate = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ak47_inventory:SetItemInfo(identifier, itemToUpdate.slot, MetaData[src])
|
||||
end
|
||||
|
||||
local usedPhone = {} -- This fix for the laggy phone
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item)
|
||||
local time = os.time()
|
||||
if usedPhone[source] and usedPhone[source] > time then return end
|
||||
usedPhone[source] = time + 2
|
||||
local player = GetPlayerFromId(source)
|
||||
if not item.info or not item.info?.phoneNumber then
|
||||
local identifier = GetIdentifier(source)
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.info = info
|
||||
InitPhoneMeta(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
Debug('loading with', item.info.phoneNumber)
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,90 @@
|
||||
if Config.Inventory ~= 'ak47_qb_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
ak47_qb_inventory = exports['ak47_qb_inventory']
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
local identifier = GetIdentifier(src)
|
||||
ak47_qb_inventory:SetItemInfo(identifier, slot, data)
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local identifier = GetIdentifier(src)
|
||||
local items = ak47_qb_inventory:GetInventoryItems(identifier)
|
||||
if not items then return end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
local itemToUpdate = nil
|
||||
for k, v in pairs(items) do
|
||||
if Config.Phones[v.name] then
|
||||
local meta = v.info
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
itemToUpdate = v
|
||||
break
|
||||
elseif v.category == 'uniqueItem' then
|
||||
itemToUpdate = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ak47_qb_inventory:SetItemInfo(identifier, itemToUpdate.slot, MetaData[src])
|
||||
end
|
||||
|
||||
local usedPhone = {} -- This fix for the laggy phone
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item)
|
||||
local time = os.time()
|
||||
if usedPhone[source] and usedPhone[source] > time then return end
|
||||
usedPhone[source] = time + 2
|
||||
local player = GetPlayerFromId(source)
|
||||
if not item.info or not item.info?.phoneNumber then
|
||||
local identifier = GetIdentifier(source)
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.info = info
|
||||
InitPhoneMeta(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
Debug('loading with', item.info.phoneNumber)
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
if Config.Inventory ~= 'codem-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
CodemInventory = exports['codem-inventory']
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
if Config.Framework == 'esx' then
|
||||
CodemInventory:SetItemMetadata(src, slot, data)
|
||||
else
|
||||
CodemInventory:SetItemMetadata(src, slot, data)
|
||||
-- local player = GetPlayerFromId(src)
|
||||
-- player.PlayerData.items[slot].info.metadata = data.metadata
|
||||
-- player.PlayerData.items[slot].info.charinfo = data.charinfo
|
||||
-- player.PlayerData.items[slot].info.phoneNumber = data.phoneNumber
|
||||
-- player.PlayerData.items[slot].info.owneridentifier = data.owneridentifier
|
||||
-- player.Functions.SetInventory(player.PlayerData.items)
|
||||
end
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local player = GetPlayerFromId(src)
|
||||
local items = GetItems(player)
|
||||
local slot = 0
|
||||
--local meta
|
||||
if not items then return Debug('Save metadata to inventory failed. items is nil', 'Player src:', src) end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
for k, v in pairs(items) do
|
||||
for phoneName, phoneData in pairs(Config.Phones) do
|
||||
if v.name == phoneName then
|
||||
local meta = v.info and v.info or v.metadata
|
||||
--print('Test1'..json.encode(meta))
|
||||
--print('Test2'..meta.phoneNumber)
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
slot = v.slot
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
CodemInventory:SetItemMetadata(src, slot, MetaData[src])
|
||||
end
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item, item)
|
||||
local player = GetPlayerFromId(source)
|
||||
if not item?.info or not item?.info?.phoneNumber then
|
||||
local result = MySQL.Sync.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = ?', {
|
||||
player.identifier
|
||||
})
|
||||
result = result[1]
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = result.firstname,
|
||||
lastname = result.lastname,
|
||||
identifier = player.identifier,
|
||||
})
|
||||
item.info = info
|
||||
print(json.encode(item))
|
||||
CodemInventory:SetItemMetadata(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
exports('handleDeleteItem', function(source, itemData)
|
||||
if itemData then
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local itemIsPhone = ItemIsPhone(itemData.name)
|
||||
if not itemIsPhone then return end
|
||||
local itemPhoneNumber = itemData.info.phoneNumber
|
||||
if metaPhone and itemPhoneNumber and itemPhoneNumber == metaPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
else
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local existPhone = FindUserExistPhone(source, metaPhone)
|
||||
if not existPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,96 @@
|
||||
if Config.Inventory ~= 'core_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
CoreInventory = exports['core_inventory']
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
local identifier = GetIdentifier(src)
|
||||
local inventory = 'content-' .. identifier:gsub(':', '')
|
||||
CoreInventory:updateMetadata(inventory, slot, data)
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local identifier = GetIdentifier(src)
|
||||
local inventory = 'content-' .. identifier:gsub(':', '')
|
||||
local items = CoreInventory:getInventory(inventory)
|
||||
if not items then return end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
local itemToUpdate = nil
|
||||
for k, v in pairs(items) do
|
||||
if Config.Phones[v.name] then
|
||||
local meta = v.info or v.metadata
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
itemToUpdate = v
|
||||
break
|
||||
elseif v.category == 'uniqueItem' then
|
||||
itemToUpdate = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
CoreInventory:updateMetadata(inventory, itemToUpdate.id, MetaData[src])
|
||||
end
|
||||
|
||||
local usedPhone = {} -- This fix for the laggy phone
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item, itemData)
|
||||
local time = os.time()
|
||||
if usedPhone[source] and usedPhone[source] > time then return end
|
||||
usedPhone[source] = time + 2
|
||||
local player = GetPlayerFromId(source)
|
||||
if not type(item) ~= 'table' and type(itemData) == 'table' then
|
||||
item = itemData
|
||||
end
|
||||
item.info = item.metadata
|
||||
if not item.info or not item.info?.phoneNumber then
|
||||
local identifier = GetIdentifier(source)
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.info = info
|
||||
InitPhoneMeta(source, item.id, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
Debug('loading with', item.info.phoneNumber)
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
if Config.Inventory ~= 'default' then
|
||||
return
|
||||
end
|
||||
|
||||
function GetUserData(identifier)
|
||||
if Config.Framework == 'standalone' then
|
||||
return GetStandaloneUserData(identifier)
|
||||
end
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
@@ -0,0 +1,104 @@
|
||||
if Config.Inventory ~= 'origen_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
OrigenInventory = exports['origen_inventory']
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
Debug('src', src, 'Slot', slot, 'Data', data)
|
||||
local metadata = {
|
||||
metadata = data.metadata,
|
||||
charinfo = data.charinfo,
|
||||
phoneNumber = data.phoneNumber,
|
||||
owneridentifier = data.owneridentifier
|
||||
}
|
||||
OrigenInventory:setMetadata(src, slot, metadata)
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local userData = OrigenInventory:getInventory(src)
|
||||
local items = userData.inventory
|
||||
if not items then return end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
for k, v in pairs(items) do
|
||||
local meta = v.metadata
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
OrigenInventory:setMetadata(src, k, MetaData[src])
|
||||
Debug('Saved metadata to inventory', src, k, MetaData[src])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item)
|
||||
if not item?.metadata or not item?.metadata?.phoneNumber then
|
||||
local identifier = GetIdentifier(source)
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.metadata = info
|
||||
InitPhoneMeta(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.metadata)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
exports('handleDeleteItem', function(source, itemData)
|
||||
if itemData then
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local itemIsPhone = ItemIsPhone(itemData.name)
|
||||
if not itemIsPhone then return end
|
||||
local itemPhoneNumber = itemData.metadata.phoneNumber
|
||||
if metaPhone and itemPhoneNumber and itemPhoneNumber == metaPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
else
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local existPhone = FindUserExistPhone(source, metaPhone)
|
||||
if not existPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,134 @@
|
||||
if Config.Inventory ~= 'ox_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
ox_inventory = exports['ox_inventory']
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
Error('You failed to adapt phone to ox_inventory properly! Please check the docs!')
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local player = GetPlayerFromId(src)
|
||||
local items = GetItems(player)
|
||||
local slot = 0
|
||||
if not items then return Debug('Save metadata to inventory failed. items is nil', 'Player src:', src) end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
for k, v in pairs(items) do
|
||||
local meta = v.info and v.info or v.metadata
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
slot = v.slot
|
||||
if v.info then
|
||||
v.info = MetaData[src]
|
||||
else
|
||||
v.metadata = MetaData[src]
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
MetaData[src].description = Lang('PHONE_NUI_INVENTORY_INFORMATION') .. ' ' .. MetaData[src].phoneNumber
|
||||
ox_inventory:SetMetadata(src, slot, MetaData[src])
|
||||
end
|
||||
|
||||
function RegisterItems() end
|
||||
|
||||
RegisterNetEvent('phone:usePhoneItem', function(itemData)
|
||||
local src = source
|
||||
local identifier = GetIdentifier(src)
|
||||
local itemName = itemData.name
|
||||
local colorData = Config.Phones[itemName]
|
||||
if not Config.UniquePhone then
|
||||
local meta = GetDataForWithOutMetaData(src)
|
||||
TriggerClientEvent('phone:openPhone', src, colorData, itemName, meta)
|
||||
return
|
||||
end
|
||||
if not itemData.metadata or not itemData.metadata.phoneNumber then return TriggerClientEvent('phone:client:sendTextMessage', src, Lang('PHONE_NOTIFICATION_PHONE_USE_OTHER'), 'error') end
|
||||
TriggerClientEvent('phone:openPhone', src, colorData, itemName, itemData.metadata)
|
||||
end)
|
||||
|
||||
exports('handleDeleteItem', function(source, itemData)
|
||||
if itemData then
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local itemIsPhone = ItemIsPhone(itemData.name)
|
||||
if not itemIsPhone then return end
|
||||
local itemPhoneNumber = itemData.info.phoneNumber
|
||||
if metaPhone and itemPhoneNumber and itemPhoneNumber == metaPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
else
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local existPhone = FindUserExistPhone(source, metaPhone)
|
||||
if not existPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
end
|
||||
TriggerClientEvent('phone:closePhone', source)
|
||||
end)
|
||||
|
||||
local function getPhoneWithNotPhoneNumber(source)
|
||||
local player = GetPlayerFromId(source)
|
||||
local items = GetItems(player)
|
||||
for a, x in pairs(Config.Phones) do
|
||||
for k, v in pairs(items) do
|
||||
local meta = v?.info or v?.metadata
|
||||
if v.name == a and not meta.phoneNumber then
|
||||
return v
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
RegisterNetEvent('phone:itemAdd', function()
|
||||
local src = source
|
||||
local item = getPhoneWithNotPhoneNumber(src)
|
||||
if not item then return print('OX Error: item is nil. You need to take a new phone. And we hope you did read the docs well.') end
|
||||
if not item?.metadata.phoneNumber then
|
||||
local identifier = GetIdentifier(src)
|
||||
local firstname, lastname, phone = GetUserData(identifier)
|
||||
if not firstname then return print('OX Error: firstname is nil') end
|
||||
local metadata = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.metadata = metadata
|
||||
metadata.description = Lang('PHONE_NUI_INVENTORY_INFORMATION') .. ' ' .. metadata.phoneNumber
|
||||
ox_inventory:SetMetadata(src, item.slot, metadata)
|
||||
return
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,88 @@
|
||||
if Config.Inventory ~= 'qb-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT charinfo FROM players WHERE citizenid = ?
|
||||
]])
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
if not result[1] then return false end
|
||||
local charinfo = json.decode(result[1].charinfo)
|
||||
Debug('GetUserData', identifier, 'firstname', charinfo.firstname, 'lastname', charinfo.lastname)
|
||||
return charinfo.firstname, charinfo.lastname, charinfo.phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
local player = GetPlayerFromId(src)
|
||||
player.PlayerData.items[slot].info.metadata = data.metadata
|
||||
player.PlayerData.items[slot].info.charinfo = data.charinfo
|
||||
player.PlayerData.items[slot].info.phoneNumber = data.phoneNumber
|
||||
player.PlayerData.items[slot].info.owneridentifier = data.owneridentifier
|
||||
player.Functions.SetInventory(player.PlayerData.items)
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local player = GetPlayerFromId(src)
|
||||
local items = GetItems(player)
|
||||
if not items then return end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
for k, v in pairs(items) do
|
||||
local meta = v.info and v.info or v.metadata
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
if v.info then
|
||||
v.info = MetaData[src]
|
||||
else
|
||||
v.metadata = MetaData[src]
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
player.Functions.SetInventory(items)
|
||||
end
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item)
|
||||
local player = GetPlayerFromId(source)
|
||||
if not item?.info or not item?.info?.phoneNumber then
|
||||
local identifier = GetIdentifier(source)
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.info = info
|
||||
InitPhoneMeta(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
exports('handleDeleteItem', function(source, itemData)
|
||||
if itemData then
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local itemIsPhone = ItemIsPhone(itemData.name)
|
||||
if not itemIsPhone then return end
|
||||
local itemPhoneNumber = itemData.info.phoneNumber
|
||||
if metaPhone and itemPhoneNumber and itemPhoneNumber == metaPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
else
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local existPhone = FindUserExistPhone(source, metaPhone)
|
||||
if not existPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,109 @@
|
||||
if Config.Inventory ~= 'qs-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
QSInventory = exports['qs-inventory']
|
||||
ItemList = exports['qs-inventory']:GetItemList()
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
Debug('GetUserData', identifier, 'firstname', firstname, 'lastname', lastname, 'phone', phone)
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, data)
|
||||
if Config.Framework == 'esx' then
|
||||
QSInventory:SetItemMetadata(src, slot, data)
|
||||
else
|
||||
local player = GetPlayerFromId(src)
|
||||
player.PlayerData.items[slot].info.metadata = data.metadata
|
||||
player.PlayerData.items[slot].info.charinfo = data.charinfo
|
||||
player.PlayerData.items[slot].info.phoneNumber = data.phoneNumber
|
||||
player.PlayerData.items[slot].info.owneridentifier = data.owneridentifier
|
||||
player.Functions.SetInventory(player.PlayerData.items)
|
||||
end
|
||||
Debug('Init phone meta', src, slot, data)
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local player = GetPlayerFromId(src)
|
||||
local items = GetItems(player)
|
||||
local slot = 0
|
||||
if not items then return Debug('Save metadata to inventory failed. items is nil', 'Player src:', src) end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
for k, v in pairs(items) do
|
||||
local meta = v.info and v.info or v.metadata
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
slot = v.slot
|
||||
break
|
||||
end
|
||||
end
|
||||
QSInventory:SetItemMetadata(src, slot, MetaData[src])
|
||||
end
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
RegisterUsableItem(k, function(source, item)
|
||||
local identifier = GetIdentifier(source)
|
||||
if not item?.info or not item?.info?.phoneNumber then
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.info = info
|
||||
InitPhoneMeta(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
end
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
exports('handleDeleteItem', function(source, itemData)
|
||||
if itemData then
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local itemIsPhone = ItemIsPhone(itemData.name)
|
||||
if not itemIsPhone then return end
|
||||
local itemPhoneNumber = itemData.info.phoneNumber
|
||||
if metaPhone and itemPhoneNumber and itemPhoneNumber == metaPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
else
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local existPhone = FindUserExistPhone(source, metaPhone)
|
||||
if not existPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,100 @@
|
||||
---@diagnostic disable
|
||||
if Config.Inventory ~= 'tgiann-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function GetUserData(identifier)
|
||||
local str = ([[
|
||||
SELECT %s FROM %s WHERE %s = ?
|
||||
]]):format(Config.Framework == 'esx' and 'firstname, lastname, phone_number' or 'charinfo', userColumn, identifierTable)
|
||||
local result = MySQL.Sync.fetchAll(str, {
|
||||
identifier
|
||||
})
|
||||
result = result[1]
|
||||
if not result then return false end
|
||||
local firstname, lastname, phone
|
||||
if Config.Framework == 'esx' then
|
||||
firstname = result.firstname
|
||||
lastname = result.lastname
|
||||
phone = result.phone_number
|
||||
elseif Config.Framework == 'qb' then
|
||||
local data = json.decode(result.charinfo)
|
||||
firstname = data.firstname
|
||||
lastname = data.lastname
|
||||
phone = data.phone
|
||||
end
|
||||
if not phone and Config.Framework == 'esx' then
|
||||
phone = Config.Prefix .. math.random(StartDigit, FinishDigit)
|
||||
MySQL.Sync.execute('UPDATE `users` SET `phone_number` = ? WHERE `identifier` = ?', {
|
||||
phone,
|
||||
identifier
|
||||
})
|
||||
end
|
||||
return firstname, lastname, phone
|
||||
end
|
||||
|
||||
function InitPhoneMeta(src, slot, info)
|
||||
local item = exports["tgiann-inventory"]:GetItemBySlot(src, slot)
|
||||
if not item then return end
|
||||
exports["tgiann-inventory"]:UpdateItemMetadata(src, item.name, item.slot, info)
|
||||
Debug('Init phone meta', src, json.encode(item))
|
||||
end
|
||||
|
||||
function SaveMetadataToInventory(src, customNumber)
|
||||
local items = exports["tgiann-inventory"]:GetPlayerItems(src)
|
||||
if not items then return end
|
||||
local phone = customNumber or MetaData[src].phoneNumber
|
||||
for _, v in pairs(items) do
|
||||
local meta = v.info
|
||||
if meta.phoneNumber == phone and PhoneIsUseable(meta.uniqueId) then
|
||||
exports["tgiann-inventory"]:UpdateItemMetadata(src, v.name, v.slot, MetaData[src])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RegisterItems()
|
||||
for k, v in pairs(Config.Phones) do
|
||||
print(k, "registired")
|
||||
RegisterUsableItem(k, function(source, item)
|
||||
if not item?.info or not item?.info?.phoneNumber then
|
||||
local identifier = GetIdentifier(source)
|
||||
local firstname, lastname = GetUserData(identifier)
|
||||
local info = CreatePhoneMetaData({
|
||||
firstname = firstname,
|
||||
lastname = lastname,
|
||||
identifier = identifier,
|
||||
})
|
||||
item.info = info
|
||||
InitPhoneMeta(source, item.slot, info)
|
||||
Debug('Created phone meta')
|
||||
print('Created phone meta')
|
||||
end
|
||||
print("open")
|
||||
print(json.encode(item))
|
||||
TriggerClientEvent('phone:openPhone', source, v, k, item.info)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
exports('handleDeleteItem', function(source, itemData)
|
||||
if itemData then
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local itemIsPhone = ItemIsPhone(itemData.name)
|
||||
if not itemIsPhone then return end
|
||||
local itemPhoneNumber = itemData.info.phoneNumber
|
||||
if metaPhone and itemPhoneNumber and itemPhoneNumber == metaPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
else
|
||||
local metaPhone = MetaData[source]?.phoneNumber
|
||||
local existPhone = FindUserExistPhone(source, metaPhone)
|
||||
if not existPhone then
|
||||
MetaData[source] = nil
|
||||
TriggerClientEvent('phone:UpdatedMeta', source, nil)
|
||||
Debug('Cleared metadata. for: ' .. source)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,35 @@
|
||||
local securedFileTypes = {
|
||||
'image',
|
||||
'audio',
|
||||
'video'
|
||||
}
|
||||
|
||||
---@param source number
|
||||
---@param fileType string
|
||||
---@return string
|
||||
lib.callback.register('phone:getPresignedUrl', function(source, fileType)
|
||||
if Config.Webhook == '' then
|
||||
Error('Webhook is empty, please set a webhook in the server/custom/webhooks/webhooks.lua file. Or you are not be able to use the voice recorder, camera, and video recorder.')
|
||||
return ''
|
||||
end
|
||||
if not table.includes(securedFileTypes, fileType) then
|
||||
Error('Invalid file type', fileType, 'source', source)
|
||||
return ''
|
||||
end
|
||||
local url = ('https://fmapi.net/api/v2/presigned-url?fileType=%s'):format(fileType)
|
||||
local promise = promise.new()
|
||||
PerformHttpRequest(url, function(err, text, headers)
|
||||
local data = json.decode(text)
|
||||
if not data then
|
||||
return promise:resolve('')
|
||||
end
|
||||
if data.status ~= 'ok' then
|
||||
Error('Failed to get presigned url', data)
|
||||
return promise:resolve('')
|
||||
end
|
||||
promise:resolve(data.data.presignedUrl)
|
||||
end, 'GET', nil, {
|
||||
Authorization = Config.Webhook
|
||||
})
|
||||
return Citizen.Await(promise)
|
||||
end)
|
||||
@@ -0,0 +1,31 @@
|
||||
RegisterServerCallback('phone:getBankData', function(source, cb)
|
||||
local src = source
|
||||
local bankMoney = GetBankMoney(src)
|
||||
local invoices = GetInvoices(src)
|
||||
cb({
|
||||
balance = bankMoney,
|
||||
invoices = invoices,
|
||||
})
|
||||
end)
|
||||
|
||||
RegisterServerCallback('phone:payInvoice', function(source, cb, invoiceId)
|
||||
local src = source
|
||||
local bill = MySQL.Sync.fetchAll('SELECT * FROM `phone_bills` WHERE `id` = ?', { invoiceId })
|
||||
if not bill[1] then
|
||||
TriggerClientEvent('phone:client:sendTextMessage', src, Lang('PHONE_NOTIFICATION_BANK_BILL_NO_DATA'), 'error')
|
||||
return cb(false)
|
||||
end
|
||||
bill = bill[1]
|
||||
local price = bill.price
|
||||
local sender = bill.sender
|
||||
local bankMoney = GetBankMoney(src)
|
||||
if bankMoney >= price then
|
||||
MySQL.Sync.execute('DELETE FROM `phone_bills` WHERE `id` = ?', { invoiceId })
|
||||
RemoveBankMoney(src, price)
|
||||
TriggerClientEvent('phone:client:sendTextMessage', src, Lang('PHONE_NOTIFICATION_BANK_BILL_PAID') .. price, 'success')
|
||||
cb(true)
|
||||
else
|
||||
TriggerClientEvent('phone:client:sendTextMessage', src, Lang('PHONE_NOTIFICATION_BANK_BILL_NO_MONEY'), 'error')
|
||||
cb(false)
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,153 @@
|
||||
function CreateQuests(source)
|
||||
if GetResourceState('qs-inventory') ~= 'started' then
|
||||
Debug('qs-inventory not started, skipping phone quest creation.')
|
||||
return
|
||||
end
|
||||
|
||||
local quest1 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'hack_catcord',
|
||||
title = 'Catcord Hacker',
|
||||
description = 'Hack your smartphone to unlock hidden Catcord rooms.',
|
||||
reward = 150,
|
||||
requiredLevel = 1
|
||||
})
|
||||
|
||||
local quest2 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'use_taxi_app',
|
||||
title = 'Call Me a Cab',
|
||||
description = 'Take a ride using the Taxi app.',
|
||||
reward = 100,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest3 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'download_apps',
|
||||
title = 'App Collector',
|
||||
description = 'Download 5 different apps on your phone.',
|
||||
reward = 200,
|
||||
requiredLevel = 1
|
||||
})
|
||||
|
||||
local quest4 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'create_tweet',
|
||||
title = 'First Tweet',
|
||||
description = 'Post your first tweet using the Twitter app on your phone.',
|
||||
reward = 150,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest5 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'buy_crypto',
|
||||
title = 'Crypto Curious',
|
||||
description = 'Buy your first cryptocurrency.',
|
||||
reward = 250,
|
||||
requiredLevel = 2
|
||||
})
|
||||
|
||||
local quest6 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'take_photo',
|
||||
title = 'Say Cheese!',
|
||||
description = 'Take a photo using your smartphone camera.',
|
||||
reward = 100,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest7 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'make_call',
|
||||
title = 'Can You Hear Me?',
|
||||
description = 'Make a phone call using your smartphone.',
|
||||
reward = 100,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest8 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'create_contact',
|
||||
title = 'Stay Connected',
|
||||
description = 'Add a new contact to your smartphone.',
|
||||
reward = 100,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest9 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'send_email',
|
||||
title = 'Inbox Outbox',
|
||||
description = 'Send an email using your smartphone.',
|
||||
reward = 150,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest10 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'send_money_bank_app',
|
||||
title = 'Mobile Transfer',
|
||||
description = 'Send money to another player using the banking app.',
|
||||
reward = 200,
|
||||
requiredLevel = 1
|
||||
})
|
||||
|
||||
local quest11 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'register_social_network',
|
||||
title = 'Social Starter',
|
||||
description = 'Register an account on a social media app.',
|
||||
reward = 150,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest12 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'post_instagraph',
|
||||
title = 'Insta Moment',
|
||||
description = 'Create a post and upload a photo using Instagraph.',
|
||||
reward = 200,
|
||||
requiredLevel = 1
|
||||
})
|
||||
|
||||
local quest13 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'post_ticktock',
|
||||
title = 'TickTock Star',
|
||||
description = 'Post a video on the TickTock app.',
|
||||
reward = 200,
|
||||
requiredLevel = 1
|
||||
})
|
||||
|
||||
local quest14 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'post_yellow_pages',
|
||||
title = 'Business Blast',
|
||||
description = 'Create a public post using Yellow Pages.',
|
||||
reward = 150,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest15 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'get_job_jobcenter',
|
||||
title = 'Career Kickstart',
|
||||
description = 'Get a job using the Job Center app on your smartphone.',
|
||||
reward = 200,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
local quest16 = exports['qs-inventory']:createQuest(source, {
|
||||
name = 'rent_vehicle_aventon',
|
||||
title = 'Ready to Ride',
|
||||
description = 'Rent a vehicle using the Aventon app on your smartphone.',
|
||||
reward = 200,
|
||||
requiredLevel = 0
|
||||
})
|
||||
|
||||
Debug('Phone quests assigned to player:', source, {
|
||||
hack_catcord = quest1,
|
||||
use_taxi_app = quest2,
|
||||
download_apps = quest3,
|
||||
create_tweet = quest4,
|
||||
buy_crypto = quest5,
|
||||
take_photo = quest6,
|
||||
make_call = quest7,
|
||||
create_contact = quest8,
|
||||
send_email = quest9,
|
||||
send_money_bank_app = quest10,
|
||||
register_social_network = quest11,
|
||||
post_instagraph = quest12,
|
||||
post_ticktock = quest13,
|
||||
post_yellow_pages = quest14,
|
||||
get_job_jobcenter = quest15,
|
||||
rent_vehicle_aventon = quest16
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
local salty = exports['saltychat']
|
||||
|
||||
RegisterNetEvent('phone:addToCall', function(callId)
|
||||
local src = source
|
||||
if Config.Voice == 'salty' then
|
||||
salty:AddPlayerToCall(tostring(callId), src)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('phone:removeFromCall', function(callId)
|
||||
local src = source
|
||||
if Config.Voice == 'salty' then
|
||||
salty:RemovePlayerFromCall(tostring(callId), src)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('phone:toggleSpeaker', function(enabled)
|
||||
local src = source
|
||||
if Config.Voice == 'salty' then
|
||||
salty:SetPhoneSpeaker(src, enabled == true)
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,20 @@
|
||||
--[[
|
||||
Discord webhook configuration, here you can configure the private webhook
|
||||
that will store all your images and below you can optionally make public
|
||||
webhooks for certain apps/social networks.
|
||||
|
||||
In case you don't know how to create a webhook, we recommend that you read
|
||||
the documentation or watch the following video: https://www.youtube.com/watch?v=fKksxz2Gdnc
|
||||
|
||||
If you will use public webhooks, create a new channel for each config,
|
||||
remember that the main Config.Webhook should be private.
|
||||
]]
|
||||
|
||||
-- Mandatory webhook or Fivemanage token [https://www.fivemanage.com] (full use)
|
||||
Config.Webhook = ''
|
||||
|
||||
-- Optional webhook (public use)
|
||||
Config.TikTokWebhook = ''
|
||||
Config.TwitterWebhook = ''
|
||||
Config.InstagramWebhook = ''
|
||||
Config.YellowPagesWebhook = ''
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user