fivem-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFiveM Development — vRP
FiveM 开发 — vRP
Arquitetura do Framework
框架架构
A vRP Creative Network é baseada em Lua 5.4 com comunicação via Proxy (server-to-server) e Tunnel (client-server).
vRP Creative Network 基于 Lua 5.4 构建,通过 Proxy(服务器到服务器)和 Tunnel(客户端到服务器)实现通信。
Natives FiveM — Fonte Oficial
FiveM 原生函数 — 官方来源
Fonte oficial de natives:
- Docs: https://docs.fivem.net/natives/
- Repositório oficial (espelho): https://github.com/proelias7/fivem-natives
官方原生函数来源:
Suporte Creative v5 e vRPEX (variações antigas)
支持Creative v5与vRPEX(旧版本变体)
As versões antigas mantêm a mesma lógica e boas práticas, mas mudam nomes de funções e arquivos.
- Creative v5: core em ,
camelCase, configs emmodules/group.lua.config/*.lua - vRPEX: core clássico (,
getUserId,getUserSource, etc.) e configs emgetUsers.cfg/*.lua
Veja o mapeamento completo em reference.md.
旧版本保留相同逻辑与最佳实践,但函数名和文件名有所变化。
- Creative v5:核心采用命名,模块文件为
camelCase,配置文件位于modules/group.lua。config/*.lua - vRPEX:经典核心(包含、
getUserId、getUserSource等函数),配置文件位于getUsers。cfg/*.lua
完整映射关系请查看reference.md。
Conceitos-chave
核心概念
| Conceito | Descrição |
|---|---|
| Passport | ID único do personagem (equivalente a |
| Source | ID da conexão do jogador no servidor (muda a cada reconexão) |
| Datatable | Tabela em memória com dados do personagem (inventário, posição, skin, etc.) |
| Characters | Tabela global server-side indexada por |
| Sources | Tabela global |
| 概念 | 描述 |
|---|---|
| Passport | 角色唯一ID(等同于其他vRP框架中的 |
| Source | 玩家在服务器中的连接ID(每次重连都会变化) |
| Datatable | 存储角色数据的内存表(包含库存、位置、外观等信息) |
| Characters | 服务器端全局表,通过 |
| Sources | 全局表 |
Fluxo de identificação
身份验证流程
lua
-- Server-side: obter Passport a partir do source
local Passport = vRP.Passport(source)
-- Server-side: obter source a partir do Passport
local source = vRP.Source(Passport)
-- Server-side: obter Datatable do personagem
local Datatable = vRP.Datatable(Passport)
-- Server-side: obter inventário
local Inventory = vRP.Inventory(Passport)lua
-- Server-side: 通过source获取Passport
local Passport = vRP.Passport(source)
-- Server-side: 通过Passport获取source
local source = vRP.Source(Passport)
-- Server-side: 获取角色的Datatable
local Datatable = vRP.Datatable(Passport)
-- Server-side: 获取角色库存
local Inventory = vRP.Inventory(Passport)Sistema Proxy/Tunnel
Proxy/Tunnel 系统
lua
-- Em qualquer resource SERVER-SIDE, obter acesso à vRP:
local Proxy = module("vrp", "lib/Proxy")
vRP = Proxy.getInterface("vRP")
-- Em qualquer resource CLIENT-SIDE:
local Tunnel = module("vrp", "lib/Tunnel")
local Proxy = module("vrp", "lib/Proxy")
vRPS = Tunnel.getInterface("vRP") -- chamar funções do server
-- Expor funções do seu resource (server):
myResource = {}
Proxy.addInterface("myResource", myResource)
Tunnel.bindInterface("myResource", myResource)lua
-- 在任意SERVER-SIDE资源中,获取vRP访问权限:
local Proxy = module("vrp", "lib/Proxy")
vRP = Proxy.getInterface("vRP")
-- 在任意CLIENT-SIDE资源中:
local Tunnel = module("vrp", "lib/Tunnel")
local Proxy = module("vrp", "lib/Proxy")
vRPS = Tunnel.getInterface("vRP") -- 调用服务器端函数
-- 暴露自定义资源的函数(服务器端):
myResource = {}
Proxy.addInterface("myResource", myResource)
Tunnel.bindInterface("myResource", myResource)Regra de fire-and-forget
即发即弃(fire-and-forget)规则
Prefixar chamada Tunnel com para não aguardar resposta:
_lua
-- Aguarda resposta (bloqueante)
local result = vRP.Generateitem(Passport,"water",1)
-- Fire-and-forget (não bloqueia)
vRP._Generateitem(Passport,"water",1)在Tunnel调用前添加前缀,无需等待响应:
_lua
-- 等待响应(阻塞式)
local result = vRP.Generateitem(Passport,"water",1)
-- 即发即弃(非阻塞)
vRP._Generateitem(Passport,"water",1)API Principal (Server-side)
核心API(服务器端)
Jogador/Identidade
玩家/身份管理
| Função | Parâmetros | Retorno | Descrição |
|---|---|---|---|
| source | Passport|false | Obtém Passport do jogador |
| Passport | source|nil | Obtém source do Passport |
| Passport | table|false | Dados em memória do personagem |
| Passport | table | Inventário do personagem |
| Passport | table|false | Dados do personagem (name, name2, bank, phone, etc.) |
| source | string|false | Nome completo do personagem |
| — | table | Retorna |
| source, string | — | Kicka o jogador |
| source, coords | — | Teleporta o jogador |
| source | vector3 | Coordenadas do jogador |
| source | string | Modelo do ped (mp_m/mp_f) |
| 函数 | 参数 | 返回值 | 描述 |
|---|---|---|---|
| source | Passport|false | 获取玩家的Passport |
| Passport | source|nil | 通过Passport获取source |
| Passport | table|false | 获取角色的内存数据 |
| Passport | table | 获取角色库存 |
| Passport | table|false | 获取角色身份数据(姓名、姓氏、银行余额、手机号等) |
| source | string|false | 获取角色全名 |
| — | table | 返回 |
| source, string | — | 踢出玩家 |
| source, 坐标 | — | 传送玩家 |
| source | vector3 | 获取玩家坐标 |
| source | string | 获取玩家模型(mp_m/mp_f) |
Dinheiro
货币管理
| Função | Parâmetros | Retorno | Descrição |
|---|---|---|---|
| source | number | Saldo bancário |
| Passport, number | — | Adiciona dinheiro ao banco |
| Passport, number | — | Remove dinheiro do banco |
| Passport, number | bool | Paga com banco (verifica saldo) |
| Passport, number | bool | Paga com dinheiro em espécie |
| Passport, number | bool | Tenta espécie, depois banco |
| Passport, number | bool | Paga com dinheiro sujo |
| Passport, number | bool | Saque bancário |
| Passport, number | bool | Paga com gemas |
| Passport | number | Obtém coins |
| Passport, number | bool | Adiciona coins |
| Passport, number | bool | Remove coins |
| 函数 | 参数 | 返回值 | 描述 |
|---|---|---|---|
| source | number | 获取银行余额 |
| Passport, number | — | 增加银行存款 |
| Passport, number | — | 扣除银行存款 |
| Passport, number | bool | 使用银行支付(会检查余额) |
| Passport, number | bool | 使用现金支付 |
| Passport, number | bool | 优先使用现金,不足则从银行扣除 |
| Passport, number | bool | 使用黑钱支付 |
| Passport, number | bool | 从银行取现 |
| Passport, number | bool | 使用宝石支付 |
| Passport | number | 获取硬币数量 |
| Passport, number | bool | 增加硬币数量 |
| Passport, number | bool | 扣除硬币数量 |
Inventário
库存管理
| Função | Parâmetros | Retorno | Descrição |
|---|---|---|---|
| ... | — | Dá item (sem durabilidade) |
| ... | — | Dá item (com durabilidade/charges) |
| ... | bool | Remove item (retorna sucesso) |
| ... | — | Remove item (sem retorno) |
| Passport, string | number | Quantidade do item |
| ... | bool | Verifica se tem a quantidade |
| Passport | number | Peso atual |
| Passport | number | Peso máximo |
| Passport, number | — | Adiciona ao peso máximo |
| ... | bool | Verifica limite máximo do item |
| Passport | — | Limpa inventário |
| 函数 | 参数 | 返回值 | 描述 |
|---|---|---|---|
| ... | — | 发放物品(无耐久度) |
| ... | — | 发放物品(带耐久度/使用次数) |
| ... | bool | 移除物品(返回操作是否成功) |
| ... | — | 移除物品(无返回值) |
| Passport, string | number | 获取物品数量 |
| ... | bool | 检查是否拥有指定数量的物品 |
| Passport | number | 获取当前库存重量 |
| Passport | number | 获取最大库存重量 |
| Passport, number | — | 增加最大库存重量 |
| ... | bool | 检查物品是否达到携带上限 |
| Passport | — | 清空库存 |
Grupos/Permissões
群组/权限管理
| Função | Parâmetros | Retorno | Descrição |
|---|---|---|---|
| ... | bool | Verifica permissão direta |
| ... | bool | Verifica grupo (inclui parents) |
| ... | bool | Verifica se está em serviço |
| ... | — | Define permissão |
| ... | — | Remove permissão |
| ... | — | Toggle serviço |
| ... | table, number | Players no serviço |
| ... | bool | Verifica grupo por tipo |
| Passport | bool | Verifica ação policial |
| ... | — | Define status de ação |
| 函数 | 参数 | 返回值 | 描述 |
|---|---|---|---|
| ... | bool | 检查是否拥有直接权限 |
| ... | bool | 检查是否拥有群组权限(包含父群组) |
| ... | bool | 检查是否处于服务状态 |
| ... | — | 设置权限 |
| ... | — | 移除权限 |
| ... | — | 切换服务状态 |
| ... | table, number | 获取处于该服务的玩家列表及数量 |
| ... | bool | 按类型检查群组 |
| Passport | bool | 检查是否处于警察行动状态 |
| ... | — | 设置行动状态 |
Sobrevivência
生存系统
| Função | Parâmetros | Descrição |
|---|---|---|
| ... | Aumenta fome |
| ... | Diminui fome |
| ... | Aumenta sede |
| ... | Diminui sede |
| ... | Aumenta infecção |
| ... | Diminui infecção |
| ... | Revive jogador |
| 函数 | 参数 | 描述 |
|---|---|---|
| ... | 增加饥饿值 |
| ... | 减少饥饿值 |
| ... | 增加口渴值 |
| ... | 减少口渴值 |
| ... | 增加感染值 |
| ... | 减少感染值 |
| ... | 复活玩家 |
Banco de Dados
数据库操作
lua
-- Registrar query preparada
vRP.Prepare("nome/query", "SELECT * FROM tabela WHERE id = @id")
-- Executar query
local result = vRP.Query("nome/query", { id = 123 })Usa oxmysql internamente. Parâmetros com .
@nomelua
-- 注册预编译查询
vRP.Prepare("nome/query", "SELECT * FROM tabela WHERE id = @id")
-- 执行查询
local result = vRP.Query("nome/query", { id = 123 })内部使用 oxmysql,参数使用格式。
@nomeDados Persistentes
持久化数据
lua
-- Server Data (entitydata — dados globais)
local data = vRP.GetSrvData("ChaveUnica")
vRP.SetSrvData("ChaveUnica", { campo = "valor" })
-- Player Data (playerdata — dados por jogador)
local data = vRP.UserData(Passport, "chave")
vRP.setUData(Passport, "chave", json.encode(dados))lua
-- 服务器数据(entitydata — 全局数据)
local data = vRP.GetSrvData("ChaveUnica")
vRP.SetSrvData("ChaveUnica", { campo = "valor" })
-- 玩家数据(playerdata — 按玩家存储)
local data = vRP.UserData(Passport, "chave")
vRP.setUData(Passport, "chave", json.encode(dados))Utilitários Globais
全局工具函数
| Função | Descrição |
|---|---|
| Converte para inteiro (mín. 0) |
| Formata número com separador de milhar |
| Divide string por separador |
| Primeiro elemento do split |
| Filtra caracteres |
| Formata tempo completo em HTML |
| Formata tempo resumido |
| Conta itens na tabela |
| Executa função assíncrona |
| 函数 | 描述 |
|---|---|
| 转换为整数(最小值为0) |
| 为数字添加千位分隔符 |
| 按分隔符分割字符串 |
| 获取分割后的第一个元素 |
| 过滤字符串中的指定字符 |
| 将秒数格式化为完整的HTML时间显示 |
| 将秒数格式化为简洁的时间显示 |
| 统计表中的元素数量 |
| 执行异步函数 |
Comunicação Client-Server
客户端-服务器通信
Eventos de Notificação
通知事件
lua
-- Server-side: notificação simples
TriggerClientEvent("Notify", source, "success", "Mensagem.", false, 5000)
-- Tipos: "success", "important", "negado"
-- Server-side: notificação de item
TriggerClientEvent("NotifyItens", source, { "+", "itemIndex", "quantidade", "Nome do Item" })
-- "+" para ganho, "-" para perdalua
-- Server-side: 简单通知
TriggerClientEvent("Notify", source, "success", "消息内容。", false, 5000)
-- 类型:"success"、"important"、"negado"
-- Server-side: 物品通知
TriggerClientEvent("NotifyItens", source, { "+", "itemIndex", "数量", "物品名称" })
-- "+"代表获得物品,"-"代表失去物品Eventos Importantes
重要事件
| Evento | Lado | Descrição |
|---|---|---|
| Server | Jogador escolheu personagem |
| Server | Jogador desconectou |
| Server | Personagem escolhido |
| Client | Jogador ativado |
| 事件 | 运行端 | 描述 |
|---|---|---|
| Server | 玩家选择角色时触发 |
| Server | 玩家断开连接时触发 |
| Server | 玩家选定角色时触发 |
| Client | 玩家激活时触发 |
Regras Críticas de Performance (Resumo)
关键性能优化规则(摘要)
Seguir SEMPRE estas regras ao escrever código:
- Tunnel vs Evento: Use /
TriggerServerEventquando NÃO precisa de retorno. Use Tunnel apenas quando PRECISA de retorno.TriggerClientEvent - Sleep dinâmico: NUNCA fixo. Ajuste baseado no estado (dist < 20 =
Wait(0), dist < 50 =0, senão =500+).1000 - Chamadas no mesmo ambiente: Chame funções diretamente. NUNCA use para chamar no mesmo side.
TriggerEvent() - Sem chamadas remotas em loops: Não use Tunnel/Eventos em loops < 5 segundos. Prefira batch ou delta.
- Payloads pequenos: Envie apenas a mudança, não dados completos. Limite de ~8KB por evento.
- Cache: Use para consultas repetidas ao banco. Nunca query no banco em loop.
exports.cacheaside:Get() - SafeEvent (server): Todo evento que dá dinheiro/item/vantagem DEVE passar por .
exports["cerberus"]:SafeEvent(source, "nomeEvento", { time = N }) - SetCooldown (client): Ações repetitivas no client (abrir menu, usar item) devem usar .
exports["cerberus"]:SetCooldown("nome", ms) - Tabelas > if/else: Para 3+ condições, use tabela de lookup (O(1)) ao invés de cadeias if/elseif.
- Proteger nil: Sempre verificar variáveis antes de concatenar. Usar como fallback.
or ""
编写代码时必须遵守以下规则:
- Tunnel与事件选择:无需返回值时使用/
TriggerServerEvent;仅当需要返回值时使用Tunnel。TriggerClientEvent - 动态Sleep:禁止固定使用,需根据状态调整(距离<20时用
Wait(0),距离<50时用0,否则用500+)。1000 - 同环境函数调用:直接调用函数,禁止在同一端使用调用函数。
TriggerEvent() - 循环中避免远程调用:禁止在间隔小于5秒的循环中使用Tunnel/事件,优先使用批量处理或增量更新。
- 小负载传输:仅发送变更数据,而非完整数据集,单次事件负载限制约8KB。
- 缓存使用:重复查询数据库时使用,禁止在循环中查询数据库。
exports.cacheaside:Get() - SafeEvent(服务器端):所有涉及货币/物品/优势的事件必须通过验证。
exports["cerberus"]:SafeEvent(source, "nomeEvento", { time = N }) - SetCooldown(客户端):客户端重复操作(如打开菜单、使用物品)需使用设置冷却。
exports["cerberus"]:SetCooldown("nome", ms) - 表查询替代if/else:当条件超过3个时,使用表查询(O(1)复杂度)替代if/elseif链式判断。
- 空值保护:拼接变量前必须检查是否为nil,使用作为 fallback。
or ""
Construção de UI (React + Vite)
UI构建(React + Vite)
Stack: React 18 + TypeScript + Vite + Tailwind CSS + Zustand.
Regras fundamentais:
- no vite.config.ts (OBRIGATÓRIO para FiveM)
base: "./" - Usar para TODOS os tamanhos — NUNCA
rempara layoutpx - Media queries no font-size para escalar com resolução do jogador
html - Tailwind v4 usa OKLCH e o CEF do FiveM não suporta. Use Tailwind v3.4.17.
- PROIBIDO: ,
backdrop-filter: blur(),filter: blur()— causam queda de FPSfilter: drop-shadow() - PROIBIDO: framer-motion, GSAP, react-spring — libs de animação pesadas
- Usar CSS transitions/keyframes puras para animações
- Módulos independentes (Notify, Progress) fora do VisibilityProvider
- Interface principal dentro do VisibilityProvider com NuiFocus
- e
overflow: hiddenglobaisuser-select: none - para mock de dados no dev
isEnvBrowser() - Comunicação: para ouvir NUI,
observe()para enviar callbacksPost.create()
Para guia completo de UI: ui-guide.md
技术栈:React 18 + TypeScript + Vite + Tailwind CSS + Zustand。
核心规则:
- vite.config.ts中必须设置(FiveM要求)
base: "./" - 所有布局尺寸使用,禁止使用
rempx - 通过字体大小的媒体查询适配玩家分辨率
html - Tailwind v4 使用OKLCH颜色模型,但FiveM的CEF不支持,必须使用Tailwind v3.4.17。
- 禁止使用:、
backdrop-filter: blur()、filter: blur()—— 会导致帧率下降filter: drop-shadow() - 禁止使用:framer-motion、GSAP、react-spring —— 这些动画库性能开销大
- 使用纯CSS transitions/keyframes实现动画
- 独立模块(Notify、Progress)需放在VisibilityProvider外部
- 主界面需放在带有NuiFocus的VisibilityProvider内部
- 全局设置和
overflow: hiddenuser-select: none - 使用在开发环境中模拟数据
isEnvBrowser() - 通信方式:使用监听NUI,使用
observe()发送回调Post.create()
完整UI开发指南请查看ui-guide.md
Referências Adicionais
附加参考
- Para guia de construção de UI (React + Vite + FiveM): ui-guide.md
- Para boas práticas detalhadas (performance, segurança, cache): best-practices.md
- Para API completa e detalhada: reference.md
- Para exemplos de código: examples.md
- Para templates de resources: templates.md
- Para padrões e convenções: patterns.md
- FiveM UI构建指南(React + Vite):ui-guide.md
- 详细最佳实践(性能、安全、缓存):best-practices.md
- 完整API文档:reference.md
- 代码示例:examples.md
- 资源模板:templates.md
- 模式与规范:patterns.md
Recursos Externos (Download)
外部资源(下载)
Use estes repositórios oficiais quando o projeto mencionar dependências:
- (cache em memória):
cacheasidegit@github.com:proelias7/cacheaside.git - (anti-exploit + cooldowns):
cerberusgit@github.com:proelias7/cerberus.git
当项目涉及依赖时,请使用以下官方仓库:
- (内存缓存):
cacheasidegit@github.com:proelias7/cacheaside.git - (反作弊 + 冷却系统):
cerberusgit@github.com:proelias7/cerberus.git
Compatibilidade vRPex
vRPex兼容性
A vRP Creative Network possui aliases de compatibilidade com a vRP clássica:
| vRPex (antigo) | Creative Network (atual) |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
SEMPRE use os nomes nativos da Creative Network (coluna direita), não os aliases.
vRP Creative Network 提供与经典vRPex的兼容别名:
| vRPex(旧版) | Creative Network(当前版) |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
必须使用Creative Network的原生函数名(右列),禁止使用兼容别名。