Este guia mostra exatamente quais funções do LB Phone foram adaptadas para funcionar com o framework vRP, onde cada função está localizada e como foi implementada.
📌 IMPORTANTE: O framework Creative Summzerz é baseado no vRP, por isso as adaptações mostradas aqui funcionam para ambos os frameworks. O Creative Summzerz mantém a mesma estrutura e funções do vRP, apenas com melhorias e otimizações.
| Framework | Config | Compatibilidade |
|---|---|---|
| Creative Summzerz | "vrp" |
✅ Total (baseado no vRP) |
| Standalone | "standalone" |
❌ Sem framework ( São todos) |
-- Arquivo: config/config.lua
Config.Framework = "standalone"
### **2. Reiniciar Recurso**
```lua
restart lbphoneFunção: GetIdentifier(source)
- Onde: Linha 212-214
- Adaptação:
vRP.users_by_source[source].cid - Retorna: ID único do jogador com prefixo "vrp_"
Função: GetCharacterName(source)
- Onde: Linha 216-220
- Adaptação:
vRP.EXT.Identity:getIdentity(user.cid) - Retorna: Nome e sobrenome do personagem
Função: GetBalance(source)
- Onde: Linha 236-238
- Adaptação:
user:getBank() - Retorna: Saldo bancário do jogador
Função: AddMoney(source, amount)
- Onde: Linha 240-242
- Adaptação:
user:giveBank(amount) - Retorna: Adiciona dinheiro ao banco
Função: RemoveMoney(source, amount)
- Onde: Linha 244-246
- Adaptação:
user:setBank(math.abs(bank - amount)) - Retorna: Remove dinheiro do banco
Função: HasItem(source, itemName)
- Onde: Linha 224-234
- Adaptação:
user:tryTakeItem(item, 1, true, true) - Retorna: Verifica se jogador tem o item
Função: registerItem(item, name, description)
- Onde: Linha 87-89
- Adaptação:
vRP.EXT.Inventory:defineItem(item, name, description, nil, 0.2) - Retorna: Registra item como usável
Função: IsAdmin(source)
- Onde: Linha 248-250
- Adaptação:
user:hasGroup("admin") - Retorna: Verifica se jogador é admin
Função: GetJob(source)
- Onde: Linha 252-254
- Adaptação:
user:getGroupByType("job") - Retorna: Job atual do jogador
Função: GetEmployees(job)
- Onde: Linha 256-258
- Adaptação: Loop através de
vRP.users_by_source - Retorna: Lista de funcionários do job
Função: GetPlayerVehicles(source)
- Onde: Linha 260-262
- Adaptação:
user:getVehicles()euser:getVehicleState(model) - Retorna: Lista de veículos do jogador
Função: GetVehicle(source, model)
- Onde: Linha 264-266
- Adaptação:
user:getVehicleState(model) - Retorna: Dados específicos do veículo
Função: ApplyVehicleMods(vehicle, vehicleData)
- Onde: Linha 109-111
- Adaptação:
vRP.EXT.Garage:setVehicleState(vehicle, vehicleData) - Retorna: Aplica modificações no veículo
Função: CreateFrameworkVehicle(vehicleData, coords)
- Onde: Linha 113-123
- Adaptação:
lbphone.spawnVehicle(vehicleData, coords) - Retorna: Cria veículo do framework
Função: HasItem(itemName)
- Onde: Linha 100-104
- Adaptação:
return true(verificação server-side) - Retorna: Verifica item no cliente
Função: playerSpawn()
- Onde: Linha 23-29
- Adaptação:
TriggerEvent("lb-phone:vrp:firstSpawn") - Retorna: Detecta quando jogador spawna
Função: FirstSpawn()
- Onde: Linha 17-21
- Adaptação:
hasSpawned = true - Retorna: Marca primeiro spawn
-- Arquivo: server/custom/frameworks/standalone.lua
-- Linha: 1-178
local lbphone = class("lbphone", vRP.Extension)
function lbphone:__construct()
vRP.Extension.__construct(self)
end
lbphone.event = {}
lbphone.tunnel = {}
lbphone.proxy = {}
-- Registra extensão
vRP:registerExtension(lbphone)-- Arquivo: client/custom/frameworks/standalone.lua
-- Linha: 5-63
local lbphone = class(name, vRP.Extension)
lbphone.user = class("User")
lbphone.proxy = {}
lbphone.event = {}
lbphone.tunnel = {}
-- Registra extensão
vRP:registerExtension(lbphone)| LB Phone | vRP Implementation | Arquivo | Linha |
|---|---|---|---|
GetIdentifier() |
vRP.users_by_source[source].cid |
server/standalone.lua | 212-214 |
GetCharacterName() |
vRP.EXT.Identity:getIdentity() |
server/standalone.lua | 216-220 |
GetBalance() |
user:getBank() |
server/standalone.lua | 236-238 |
AddMoney() |
user:giveBank() |
server/standalone.lua | 240-242 |
RemoveMoney() |
user:setBank() |
server/standalone.lua | 244-246 |
HasItem() |
user:tryTakeItem() |
server/standalone.lua | 224-234 |
IsAdmin() |
user:hasGroup("admin") |
server/standalone.lua | 248-250 |
GetJob() |
user:getGroupByType("job") |
server/standalone.lua | 252-254 |
GetEmployees() |
Loop vRP.users_by_source |
server/standalone.lua | 256-258 |
GetPlayerVehicles() |
user:getVehicles() |
server/standalone.lua | 260-262 |
GetVehicle() |
user:getVehicleState() |
server/standalone.lua | 264-266 |
ApplyVehicleMods() |
vRP.EXT.Garage:setVehicleState() |
client/standalone.lua | 109-111 |
CreateFrameworkVehicle() |
lbphone.spawnVehicle() |
client/standalone.lua | 113-123 |
if GetCurrentResourceName() == "vrp" then
---@diagnostic disable: undefined-global
local lbphone = class("lbphone", vRP.Extension)
function lbphone:__construct()
vRP.Extension.__construct(self)
end
lbphone.event = {}
lbphone.tunnel = {}
lbphone.proxy = {}
function lbphone.proxy:getIdentifier(source)
local user = vRP.users_by_source[source]
if user and user.cid then
return "vrp_" .. user.cid
end
end
function lbphone.proxy:getCharacterName(source)
local user = vRP.users_by_source[source]
local identity = user and user.cid and vRP.EXT.Identity:getIdentity(user.cid)
if identity then
return identity.firstname, identity.name
else
return GetPlayerName(source), ""
end
end
function lbphone.proxy:hasItem(source, item)
local user = vRP.users_by_source[source]
if user then
return user:tryTakeItem(item, 1, true, true)
else
return false
end
end
function lbphone.proxy:getBank(source)
local user = vRP.users_by_source[source]
if user then
return user:getBank()
end
end
function lbphone.proxy:giveBank(source, amount)
local user = vRP.users_by_source[source]
if user and amount > 0 then
user:giveBank(amount)
return true
end
return false
end
function lbphone.proxy:removeBank(source, amount)
local user = vRP.users_by_source[source]
local bank = user and user:getBank()
if user and bank and amount > 0 and bank >= amount then
user:setBank(math.abs(bank - amount))
return true
end
return false
end
function lbphone.proxy:isAdmin(source)
local user = vRP.users_by_source[source]
return user and user:hasGroup("admin")
end
function lbphone.proxy:getJob(source)
local user = vRP.users_by_source[source]
return user and user:getGroupByType("job") or "citizen"
end
function lbphone.proxy:registerItem(item, name, description)
vRP.EXT.Inventory:defineItem(item, name, description, nil, 0.2)
end
function lbphone.event:playerSpawn(user, firstSpawn)
print("PLAYER SPAWNED!", user, firstSpawn)
end
function lbphone.event:characterLoad(user)
print("character load", user)
end
function lbphone.event:characterUnload(user)
print("character unload", user)
end
function lbphone.proxy:getPlayerVehicles(source)
local user = vRP.users_by_source[source]
if not user then
return {}
end
---@type { [string]: number }[]
local vehicles = user:getVehicles()
local toSend = {}
for model, stored in pairs(vehicles) do
local vehicleState = user:getVehicleState(model)
if not vehicleState then
vehicleState = {
customization = {},
condition = {}
}
end
toSend[#toSend+1] = {
plate = model,
type = "car",
model = model,
location = stored == 1 and "Garage" or "out",
statistics = {
engine = vehicleState.condition.engine_health or 1000.0,
body = vehicleState.condition.body_health or 1000.0
}
}
end
return toSend
end
function lbphone.proxy:getVehicle(source, model)
local user = vRP.users_by_source[source]
if not user then
return
end
local vehicle = user:getVehicleState(model)
if not vehicle then
return
end
vehicle.plate = model
vehicle.model = GetHashKey(model)
vehicle.type = "car"
return vehicle
end
function lbphone.proxy:getEmployees(job)
local users = vRP.users_by_source
local employees = {}
for src, user in pairs(users) do
if user and user:getGroupByType("job") == job then
employees[#employees+1] = src
end
end
return employees
end
vRP:registerExtension(lbphone)
print("^6[LB Phone]: ^2[INFO]^7: Loaded LB Phone vRP extension.")
return
end---@diagnostic disable: deprecated
if Config.Framework ~= "vrp2" then
return
end
local utils = LoadResourceFile("vrp", "lib/utils.lua")
if not utils then
print("^6[LB Phone] ^1[ERROR]^7: Failed to load vrp (could not find vrp/lib/utils.lua)")
return
end
load(utils)()
local proxy = module("vrp", "lib/Proxy")
local tunnel = module("vrp", "lib/Tunnel")
if not proxy or not tunnel then
print("^6[LB Phone] ^1[ERROR]^7: Failed to load vrp (could not load proxy/tunnel module)")
return
end
local vRP = proxy.getInterface("vRP")
vRP.loadScript(GetCurrentResourceName(), "server/custom/frameworks/vrp2")
local lbphone = proxy.getInterface("vRP.EXT.lbphone")
lbphone.registerItem(Config.Item.Name, "Phone", "A phone")
---@param source number
---@return string | nil
function GetIdentifier(source)
return lbphone.getIdentifier(source)
end
---@param source number
---@return string firstname
---@return string lastname
function GetCharacterName(source)
return lbphone.getCharacterName(source)
end
---@param source number
---@param itemName string
function HasItem(source, itemName)
if GetResourceState("ox_inventory") == "started" then
return (exports.ox_inventory:Search(source, "count", itemName) or 0) > 0
end
return lbphone.hasItem(source, itemName)
end
---@param source number
---@return integer
function GetBalance(source)
return lbphone.getBank(source)
end
---@param source number
---@param amount integer
---@return boolean # Success
function AddMoney(source, amount)
return lbphone.giveBank(source, amount)
end
---@param source number
---@param amount integer
---@return boolean # Success
function RemoveMoney(source, amount)
return lbphone.removeBank(source, amount)
end
---@param source number
---@return boolean
function IsAdmin(source)
return lbphone.isAdmin(source)
end
---@param source number
---@return string
function GetJob(source)
return lbphone.getJob(source)
end
---Get an array of player sources with a specific job
---@param job string
---@return number[] employees
function GetEmployees(job)
return lbphone.getEmployees(job)
end
function RefreshCompanies()
for i = 1, #Config.Companies.Services do
local jobData = Config.Companies.Services[i]
jobData.open = #lbphone.getEmployees(jobData.job) > 0
end
end
function GetPlayerVehicles(source)
return lbphone.getPlayerVehicles(source)
end
function GetVehicle(source, model)
return lbphone.getVehicle(source, model)
end---@diagnostic disable: deprecated
local name = "lbphone" .. 1
if GetCurrentResourceName() == "vrp" then
print("loaded in vrp")
---@diagnostic disable: undefined-global
local lbphone = class(name, vRP.Extension)
lbphone.user = class("User")
lbphone.proxy = {}
lbphone.event = {}
lbphone.tunnel = {}
local hasSpawned = false
local function FirstSpawn()
hasSpawned = true
TriggerEvent("lb-phone:vrp:firstSpawn")
end
function lbphone.event:playerSpawn()
if hasSpawned then
return
end
FirstSpawn()
end
function lbphone.tunnel:setCharacterId(id)
print("got character id:", id)
end
if vRP.EXT.Base.cid then
FirstSpawn()
end
function lbphone.proxy:spawnVehicle(vehicleData, coords)
local model = vehicleData.model
RequestModel(model)
while not HasModelLoaded(model) do
Wait(0)
end
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, 0.0, true, false)
SetVehicleOnGroundProperly(vehicle)
SetModelAsNoLongerNeeded(model)
return vehicle
end
function lbphone.proxy:applyVehicleMods(vehicle, vehicleData)
vRP.EXT.Garage:setVehicleState(vehicle, vehicleData)
end
vRP:registerExtension(lbphone)
return
endWait(500)
if Config.Framework ~= "vrp" then
return
end
local utils = LoadResourceFile("vrp", "lib/utils.lua")
if not utils then
print("^6[LB Phone] ^1[ERROR]^7: Failed to load vrp (could not find vrp/lib/utils.lua)")
return
end
load(utils)()
local proxy = module("vrp", "lib/Proxy")
local tunnel = module("vrp", "lib/Tunnel")
if not proxy or not tunnel then
print("^6[LB Phone] ^1[ERROR]^7: Failed to load vrp (could not load proxy/tunnel module)")
return
end
local vRP = proxy.getInterface("vRP")
RegisterNetEvent("lb-phone:vrp:firstSpawn", function()
loaded = true
end)
vRP.loadScript(GetCurrentResourceName(), "client/custom/frameworks/vrp2")
local lbphone = proxy.getInterface("vRP.EXT." .. name)
-- TODO: check if has phone item
---@param itemName string
---@return boolean
function HasItem(itemName)
return true
end
---Apply vehicle mods
---@param vehicle number
---@param vehicleData table
function ApplyVehicleMods(vehicle, vehicleData)
lbphone.applyVehicleMods(vehicle, vehicleData)
end
---Create a vehicle and apply vehicle mods
---@param vehicleData table
---@param coords vector3
---@return number? vehicle
function CreateFrameworkVehicle(vehicleData, coords)
local vehicle = lbphone.spawnVehicle(vehicleData, coords)
ApplyVehicleMods(vehicle, vehicleData)
return vehicle
end-- Initialize crypto data
CreateThread(function()
while not FrameworkLoaded do
Wait(0)
end
-- Add timeout protection
local timeout = 0
local maxTimeout = 30000 -- 30 seconds
local coins = nil
local success = false
-- Try to get crypto data with timeout
CreateThread(function()
coins = AwaitCallback("crypto:get")
success = true
end)
-- Wait for callback or timeout
while not success and timeout < maxTimeout do
Wait(100)
timeout = timeout + 100
end
cryptoData = {}
if success and coins and type(coins) == "table" then
for _, coin in pairs(coins) do
if coin and type(coin) == "table" then
table.insert(cryptoData, coin)
end
end
debugprint("fetched coins successfully")
else
if not success then
debugprint("crypto:get timed out after", timeout, "ms")
else
debugprint("crypto:get returned invalid data:", type(coins))
end
-- Initialize with empty data to prevent errors
cryptoData = {}
end
end)-- Inicia a atualização das moedas periodicamente
CreateThread(function()
-- Initial fetch
UpdateCryptoCoins()
CryptoData.hasFetched = true
TriggerClientEvent("phone:crypto:updateCoins", -1, CryptoData.coins)
-- Periodic updates
while true do
Wait(Config.Refresh)
UpdateCryptoCoins()
TriggerClientEvent("phone:crypto:updateCoins", -1, CryptoData.coins)
end
end)
-- Callbacks
RegisterCallback("crypto:get", function(source)
local identifier = GetIdentifier(source)
if not identifier then
debugprint("crypto:get - No identifier found for source:", source)
return {}
end
-- Wait for initial data fetch with timeout
local timeout = 0
local maxTimeout = 10000 -- 10 seconds
while not CryptoData.hasFetched and timeout < maxTimeout do
Wait(100)
timeout = timeout + 100
end
if not CryptoData.hasFetched then
debugprint("crypto:get - Timeout waiting for crypto data")
return {}
end
-- Get player's crypto holdings
local holdings = {}
local success, result = pcall(function()
return MySQL.query.await(
"SELECT coin, amount, invested FROM phone_crypto WHERE id = ?",
{identifier}
)
end)
if success and result then
holdings = result
else
debugprint("crypto:get - Failed to get holdings for identifier:", identifier)
end
-- Create a copy of the coin data
local coinData = {}
if CryptoData.coins and type(CryptoData.coins) == "table" then
coinData = table.deep_clone(CryptoData.coins)
end
-- Add player's holdings to the data
for _, holding in ipairs(holdings) do
if holding and coinData[holding.coin] then
coinData[holding.coin].owned = holding.amount
coinData[holding.coin].invested = holding.invested
end
end
return coinData
end)Causa: vRP não está carregado
Solução: Verificar se Config.Framework = "standalone" está correto
Causa: Tentando usar vRP 1.0 com código vRP 2.0
Solução: Usar Config.Framework = "vrp" para vRP 1.0
Causa: Timeout no sistema de crypto Solução: ✅ Já corrigido - Adicionado timeout protection
- vRP framework instalado e funcionando
- Extensões vRP necessárias (Identity, Inventory, Garage)
- Banco de dados configurado
- LB Phone baixado
- Alterar
Config.Framework = "standalone"emconfig/config.lua - Reiniciar o recurso:
restart lbphone - Testar se o telefone abre
- Verificar se as funções básicas funcionam
- Abrir/fechar telefone
- Verificar saldo bancário
- Testar sistema de itens
- Verificar jobs e permissões
- Testar sistema de veículos
O que foi feito:
- ✅ 13 funções principais adaptadas para vRP
- ✅ Sistema de extensão nativo implementado
- ✅ Compatibilidade vRP 1.0 e 2.0 garantida
- ✅ Correção de bugs conhecidos
- ✅ Documentação completa de cada função
Para usar:
- Altere
Config.Framework = "standalone" - Reinicie o recurso
- Pronto!
Suporte: FIVE COMMUNITY