Phone (núcleo)
Núcleo do celular: a tela, os aparelhos, a loja, os apps básicos e o banco de dados. Sozinho, ele não abre nenhum aparelho. Quem libera cada aparelho é o módulo dele.
Precisa de: oxmysql e o framework krs ou vRP. A escolha é automática: com o resource krs no servidor, usa krs; sem ele, usa vRP. A bridge do phone só traz esses dois.
O que depende do quê
| Resource | O que traz | Precisa de |
|---|---|---|
phone | Tela, loja, aparelhos e apps básicos | oxmysql, krs ou vRP |
phone_smartphone | Celular: ligações, mensagens, redes sociais, jogos | phone |
phone_tablet | Tablet e painel da staff | phone |
phone_watch | Relógio | phone, phone_smartphone |
kayfy | Música e o app Kayfy | ox_lib, krs_helper, API de música. O phone é opcional |
Sem um módulo, o aparelho dele sai da loja, o atalho de teclado não é criado e os apps dele não aparecem.
Toda a configuração dos módulos fica em phone/shared-side/config.lua, exceto o painel da staff.
Instalação
1. Banco de dados. Importe phone/sql/install.sql uma vez. Este passo é obrigatório: o phone não cria essas tabelas sozinho. As views phone_* que leem o framework são criadas ao iniciar.
2. server.cfg:
set midia_api "https://midia.SEUNOME.workers.dev"
set midia_host "midia.SEUNOME.workers.dev"
set midia_key "SUA_CHAVE"
ensure oxmysql
ensure phone
ensure phone_smartphone
ensure phone_tablet
ensure phone_watch
ensure kayfyTire a linha de quem você não usa. O framework sobe antes. Veja a ordem de instalação.
3. Itens. Cada aparelho é um item e o item precisa existir no inventário do servidor. Veja a lista em Aparelhos.
| Framework | Como o item vira aparelho |
|---|---|
| krs | Automático, com o resource inventory ligado |
| vRP | Chame exports.phone:UseItem(source, nomeDoItem) ao usar o item. O nome do item no vRP fica na tabela Items de bridge/server.lua |
Fotos, vídeos e áudios
O envio de mídia usa um serviço externo. Sem as três convars, o resto do celular funciona, mas nada de mídia é enviado.
| Convar | O que é |
|---|---|
midia_api | Endereço da API de envio |
midia_key | Chave da API. Use set, nunca setr |
midia_host | Host dos arquivos, sem https://. Link de outro host é recusado |
A pasta midia-worker publica esse serviço na sua conta Cloudflare, no plano gratuito do R2. Ela não é um resource: rode em qualquer PC com Windows e Node.js LTS.
- Ative o R2 no painel da Cloudflare.
- Rode
instalar.bate autorize no navegador. - Copie as três linhas de
COLE_NO_SERVER_CFG.txtpara oserver.cfg, antes doensure phone. - Reinicie o servidor.
Rodar instalar.bat de novo gera uma chave nova e invalida a antiga. O serviço aceita foto e áudio de até 5 MB e vídeo de até 25 MB.
Outro serviço serve se responder a GET <midia_api>/presigned-url?type=image|video|audio, com a chave no header Authorization, e devolver { data: { presignedUrl } }.
Cada personagem envia por dia até 50 fotos, 10 vídeos e 30 áudios, com 2 segundos entre um envio e outro.
Comandos e teclas
| Comando | Tecla | O que faz | Precisa de |
|---|---|---|---|
/celular | F1 | Abre o celular | phone_smartphone |
/tablet | F5 | Abre o tablet | phone_tablet |
/relogio | F3 | Abre o relógio | phone_watch |
/celulardobrar | sem tecla | Abre ou fecha o celular dobrável | |
/celularatender | Y | Atende a ligação | |
/celularrecusar | N | Recusa a ligação | |
/celularsoneca | Y | Adia o alarme | |
/celularpararalarme | N | Para o alarme |
Segure Alt com o aparelho aberto para mover a câmera do jogo. Morto, caído ou algemado, o jogador não abre o aparelho.
Aparelhos
| Item | Modelo | Preço na loja | Detalhe |
|---|---|---|---|
cellphone | normal | 725 | Dado no primeiro acesso |
cellphone_s26 | s26 | 1450 | |
cellphone_air | air | 1800 | |
cellphone_fold | fold | 5000 diamantes | Dobrável |
cellphone_fold_tall | fold_tall | 5000 diamantes | Dobrável |
cellphone_fold_max | fold_max | 6000 diamantes | Dobrável |
cellphone_flip | flip | 1200 | Dobrável com tela externa |
cellphone_boomer | boomer | 150 | Teclado físico: mensagens, contatos, chamadas, cobrinha, alarmes e ajustes. À prova d'água |
tablet | tablet | 900 | Veja Phone Tablet |
watch | watch | 1100 | À prova d'água |
watch_galax | watch_galax | 950 | À prova d'água |
watch_amber | watch_amber | 1400 | À prova d'água |
O aparelho fica no nome do personagem. Só o item na mochila não basta: sem o registro, o jogador vê "Este aparelho não está no seu nome". O registro nasce na compra, no aparelho inicial ou ao usar o item.
Número, contatos, mensagens e fotos pertencem ao personagem, não ao aparelho. Em Ajustes, o jogador escolhe qual celular é o principal, desde que esteja com ele.
Loja
A loja fica em Shop.Locations, com blip no mapa. O pagamento é em dinheiro ou no banco. Aparelhos com Gems = true são pagos só em diamantes, nunca quebram e são à prova d'água.
Na loja o jogador também troca a tela quebrada, por 15% do preço, e compra a proteção contra água, por 20%.
Tela quebrada
A tela tem 3 níveis de dano. Queda, atropelamento, explosão e ragdoll podem subir um nível. Entrar na água com o celular aberto pode levar direto ao nível 3, se ele não for à prova d'água. Desligue tudo com Damage.Enabled = false.
Apps
Instalação: Fixo não pode ser removido, Padrão já vem no personagem novo, Loja é instalado pelo app Loja.
Tela: o app só aparece no aparelho indicado.
| ID | Nome | Módulo | Tela | Instalação | O que faz |
|---|---|---|---|---|---|
bank | Banco | phone | Celular e tablet | Padrão | Saldo, extrato, transferência, faturas, taxas e multas |
browser | Navegador | phone | Celular e tablet | Loja | Abre os sites liberados em Browser |
calculator | Calculadora | phone | Celular e tablet | Padrão | Calculadora |
camera | Câmera | phone | Celular e tablet | Fixo | Fotos e vídeos para a galeria |
clock | Relógio | phone | Celular e tablet | Fixo | Horário, alarmes, cronômetro e timer |
garage | Garagem | phone | Celular e tablet | Padrão | Lista os veículos e localiza os que estão fora |
mail | phone | Celular e tablet | Padrão | Conta @krs.br criada para cada personagem | |
map | Mapas | phone | Celular e tablet | Padrão | Pins salvos, rota no GPS e localização ao vivo |
notes | Notas | phone | Celular e tablet | Padrão | Até 300 notas, com fixar |
photos | Fotos | phone | Celular e tablet | Fixo | Galeria com álbuns, até 500 arquivos |
settings | Ajustes | phone | Celular e tablet | Fixo | Tema, papel de parede, tela de bloqueio e código |
store | Loja | phone | Celular e tablet | Fixo | Instala e remove apps |
phone | Telefone | phone_smartphone | Celular | Fixo | Ligações, recentes e teclado |
messages | Mensagens | phone_smartphone | Celular | Fixo | Conversas e grupos com foto, áudio e localização |
contacts | Contatos | phone_smartphone | Celular | Fixo | Contatos, favoritos e bloqueio |
calendar | Calendário | phone_smartphone | Celular | Padrão | Compromissos com lembrete |
houses | Casa | phone_smartphone | Celular | Padrão | Casas e apartamentos do personagem |
services | Serviços | phone_smartphone | Celular | Padrão | Chamados para polícia, hospital, mecânica e empresas |
weather | Tempo | phone_smartphone | Celular | Padrão | Tempo agora e próximas horas |
news | Notícias | phone_smartphone | Celular | Padrão | Manchetes da cidade, com alerta de urgência |
recorder | Gravador | phone_smartphone | Celular | Padrão | Memos de voz de até 5 minutos |
ringtones | Toques | phone_smartphone | Celular | Padrão | Toque e aviso, inclusive próprios |
birdy | Birdy | phone_smartphone | Celular | Loja | Posts curtos e assuntos do momento |
instapic | Instapic | phone_smartphone | Celular | Loja | Fotos, seguidores e stories |
trendy | Trendy | phone_smartphone | Celular | Loja | Vídeos curtos |
flash | Flash | phone_smartphone | Celular | Loja | Fotos que somem depois de vistas |
match | Match | phone_smartphone | Celular | Loja | Perfis, curtidas e match |
darkchat | DarkChat | phone_smartphone | Celular | Loja | Salas anônimas |
pages | Páginas | phone_smartphone | Celular | Loja | Anúncios de negócios e serviços |
health | Saúde | phone_smartphone | Celular | Loja | Passos, distância, minutos ativos e sinais vitais |
crypto | Cripto | phone_smartphone | Celular | Loja | Compra e venda de cripto e ações com o saldo do banco |
radio | Rádio | phone_smartphone | Celular | Loja | Frequências de rádio, com o item radio |
spotfinder | Onde É? | phone_smartphone | Celular | Loja | Jogo de adivinhar onde a foto foi tirada |
cobrinha | Cobrinha | phone_smartphone | Celular | Loja | Jogo com placar |
blocos | Blocos | phone_smartphone | Celular | Loja | Jogo com placar |
voo | Voo | phone_smartphone | Celular | Loja | Jogo com placar |
tijolos | Tijolos | phone_smartphone | Celular | Loja | Jogo com placar |
stack | Torre | phone_smartphone | Celular | Loja | Jogo com placar |
memoria | Memória | phone_smartphone | Celular | Loja | Jogo com placar |
campo | Campo Minado | phone_smartphone | Celular | Loja | Jogo com placar |
admin | Admin | phone_smartphone | Celular | Automático para o grupo Admin | Painel de moderação do celular |
staff | Administração | phone_tablet | Tablet | Fixo, com permissão | Painel da staff |
watch | Relógio | phone_watch | Celular | Loja | Ajustes e dados do relógio no celular |
kayfy | Kayfy | kayfy | Celular e tablet | Padrão | Música |
Recursos opcionais de cada app
| App | Usa | Sem ele |
|---|---|---|
| Banco | Resource bank | Saldo e transferência funcionam. Extrato, faturas, taxas e multas ficam vazios |
| Garagem | Resource garages | Todo veículo aparece como guardado e não dá para localizar |
| Casa | Resource kay_housing | A lista fica vazia |
| Tempo | Resource time_system | "Clima indisponível no momento." |
| Rádio | Item radio, pma-voice e os eventos radio:Connect e radio:Disconnect | "Você precisa de um rádio." |
Permissão
Config.Permissions restringe um app por ID. Por padrão, só staff tem regra, para o grupo Admin.
Permissions = {
staff = "Admin",
darkchat = { "Policia","Paramedico" },
news = "export:meu_resource:PodeLerNoticias"
}Uma lista libera quem cumprir qualquer item. export:resource:nome chama a export com o passaporte e aceita somente true.
Grupos do vRP ficam em GroupMap, no bridge/server.lua. A posição na lista é o cargo: 1 é o mais alto.
Configuração
Tudo fica em shared-side/config.lua, aberto para edição.
Geral
| Opção | Padrão | O que muda |
|---|---|---|
Interaction | "target" | Como usar a loja e o orelhão. "target" usa o resource target; "E" usa a tecla E |
DefaultDevice | "normal" | Aparelho dado ao personagem no primeiro acesso, com o item. nil começa sem nenhum |
RealBrands | true | true mostra os nomes comerciais reais em alguns apps. false usa os nomes da tabela de apps acima |
Brands | 6 apps | Par de nomes de cada app para RealBrands |
Command, Key | "celular", "f1" | Comando e tecla do celular |
AnswerKey, DeclineKey | "Y", "N" | Teclas de atender e recusar. Também adiam e param o alarme |
Items | 12 itens | Item de cada aparelho |
Models | Modelo 3D de cada aparelho | |
Permissions | staff = "Admin" | Quem pode usar cada app |
Apps.Core | 9 apps | Apps fixos |
Apps.Defaults | 14 apps | Apps do personagem novo |
Apps.Store | 20 apps | Apps da Loja |
Quotas | Limite por minuto de cada ação. O que não está na lista não tem limite |
Loja
| Opção | Padrão | O que muda |
|---|---|---|
Shop.Locations | 1 ponto | Locais da loja. A compra só vale a até 4 m e no routing bucket 0 |
Shop.Blip | ícone 459, cor 3 | Blip de cada loja. false tira o blip |
Shop.MigrateUntil | "2026-10-31" | Até essa data, o personagem sem registro fica dono dos aparelhos que já carrega |
Shop.Devices | 12 aparelhos | Modelos à venda |
Campos de cada aparelho em Shop.Devices:
| Campo | O que faz |
|---|---|
Model | Modelo, igual ao de Items |
Price | Preço |
Gems | Paga em diamantes. Nunca quebra e é à prova d'água |
Waterproof | Já vem à prova d'água |
Repair | Preço fixo da troca de tela, no lugar de Damage.Repair |
Tablet, Watch | Marca o tipo do aparelho |
Dano
| Opção | Padrão | O que muda |
|---|---|---|
Damage.Enabled | true | false: a tela nunca quebra |
Damage.Cooldown | 120 | Segundos entre um dano e outro |
Damage.Repair | 0.15 | Troca de tela, em fração do preço |
Damage.Waterproof | 0.2 | Proteção contra água, em fração do preço |
Damage.Chances.FallHigh | 0.35 | Queda de 8 m ou mais |
Damage.Chances.Fall | 0.12 | Queda de 4 m ou mais |
Damage.Chances.Ragdoll | 0.10 | Personagem caído |
Damage.Chances.Vehicle | 0.30 | Atropelamento ou batida |
Damage.Chances.Explosion | 0.40 | Explosão a até 6 m |
Damage.Chances.Water | 0.50 | Na água com o celular aberto |
Navegador
| Opção | Padrão | O que muda |
|---|---|---|
Browser.Home | 3 links de exemplo | Atalhos da tela inicial, com Name e Url |
Browser.Allowed | { "*.*" } | Domínios liberados. Cada um libera também os subdomínios |
Troque os dois antes de abrir o servidor. O valor "*.*" não libera nenhum site: liste os domínios.
Browser = {
Home = { { Name = "Site", Url = "https://meuservidor.com.br" } },
Allowed = { "meuservidor.com.br" }
}Modelo na mão
| Opção | Padrão | O que muda |
|---|---|---|
PropColor | 0 | Variação de cor do celular |
PropOffset, PropRotation | 0, -0.005, 0 e 0, 0, 180 | Posição do celular na mão |
ScreenDistance | 6.0 | Distância máxima para desenhar a tela no modelo 3D |
ScreenStates, Screens | Estados e medidas da tela. Só mude ao trocar o modelo 3D |
Bridge
| Arquivo | O que ajustar |
|---|---|
bridge/server.lua | Grupos e itens do vRP e o webhook do canal Phone, usado só no vRP |
bridge/client.lua | Avisos na tela e chamadas do target. Para outro target, troque as chamadas em PhoneTarget |
Diferenças no vRP
| Recurso | No vRP |
|---|---|
| Diamantes | A bridge não paga em diamantes: a loja responde "Diamantes insuficientes.". Esses aparelhos entram pelo item, com UseItem |
| Casa | A view phone_houses volta vazia, então o app fica sem casas |
| Banimento | Veja Phone Tablet |
Para programadores
Exports do cliente:
exports.phone:IsOpen(tipo) -- tipo: "phone", "tablet", "watch" ou nil
exports.phone:ToggleOpen(estado, tipo)
exports.phone:ToggleDisabled(estado) -- true impede abrir e fecha o aparelho
exports.phone:OpenApp(id, tipo)
exports.phone:CloseApp(id)
exports.phone:CreateCall({ number = 123456 })
exports.phone:Notify({ App = "bank", Title = "Banco", Text = "Pagamento recebido." })
exports.phone:SendNotification({ app = "bank", title = "Banco", content = "Pagamento recebido." })
exports.phone:Activity(payload) -- payload.Id obrigatórioExports do servidor:
exports.phone:UseItem(source, item)
exports.phone:Notify(source, { App = "bank", Title = "Banco", Text = "Texto" })
exports.phone:NotifyCharId(passaporte, { App = "bank", Title = "Banco", Text = "Texto" })
exports.phone:Pins(passaporte)
exports.phone:PinSave(passaporte, dados)
exports.phone:PinDelete(passaporte, id)
exports.phone:CanUseApp(passaporte, id)
exports.phone:SetAppPermission(id, permissao)
exports.phone:RegisterApp(id) -- coloca o id no catálogo de apps da administraçãoA notificação enviada pelo servidor fica salva por 7 dias. App tem até 24 caracteres, Title até 60 e Text até 200.
Os exports do phone_smartphone e o StaffCan do phone_tablet também respondem em exports.phone, com o módulo ligado.
App próprio
No cliente do seu resource:
local ok, erro = exports.phone:AddCustomApp({
identifier = "meuapp",
name = "Meu App",
icon = "web/icone.png",
ui = "meu_resource/web/index.html",
color = "#3b82f6",
description = "O que o app faz.",
category = "Utilidades",
only = "both",
permissions = { "storage","notify" },
onOpen = function() end,
onClose = function() end
})| Campo | Regra |
|---|---|
identifier | Até 32 caracteres, letras, números e _. Não pode repetir um ID da tabela de apps |
name | Até 24 caracteres |
icon | <svg, http(s)://, nui:// ou caminho dentro do seu resource |
only | phone, tablet ou both |
defaultApp | true impede a remoção |
permissions | Só storage e notify |
O app sai sozinho quando o resource para. Use exports.phone:RemoveCustomApp(id) para tirar antes e exports.phone:SendCustomAppMessage(id, mensagem) para falar com a tela. Mensagens da tela chegam no evento de cliente phone:customApp:<id>.
Eventos
| Evento | Lado | Quando |
|---|---|---|
phone:Toggled | Cliente | Aparelho abriu ou fechou: estado, modelo |
phone:Activity | Cliente | Botão de uma atividade: id, acao |
krs:security:Flagged | Servidor | Jogador estourou a cota de uma ação 3 vezes em 5 minutos: source, passaporte, motivo |
Problemas comuns
| Mensagem | Causa |
|---|---|
Você precisa de um Celular. | O jogador está sem o item de nenhum aparelho |
Este aparelho não está no seu nome. Compre o seu numa loja de celulares. | O personagem carrega o item, mas não tem o registro |
O relógio precisa de um celular no seu nome para funcionar. | Relógio sem celular registrado |
Calma, muitas ações seguidas. | A ação passou do limite de Quotas |
App indisponível. | App desativado na administração ou sem permissão |
O envio de mídia não está configurado no servidor. | Falta midia_api ou midia_key, ou o servidor não reiniciou |
Não foi possível preparar o envio. | A midia_key não confere. O console mostra o serviço de mídia recusou a URL de envio |
Mídia inválida. | O midia_host é diferente do endereço dos arquivos |
... não está na lista de sites liberados do celular. | O domínio não está em Browser.Allowed |
[phone] Framework = "krs", mas o resource krs não foi encontrado. | O resource krs existe, mas não pôde ser lido |
[phone] bank não tem a export X; usando o padrão. | O resource opcional está ligado, mas sem a export. Vale para bank, garages e kay_housing |
