Agency-Phone Armazenamento de Mídia
Agora com o AgencyOS27: uma atualização grátis para quem já tem o telefone.

Onde fotos, vídeos e mensagens de voz são armazenados
Toda foto, clipe de vídeo, gravação de tela e mensagem de voz do Agency Phone é salva pelo próprio script, a partir da versão 27.1.1. Você escolhe onde:
| Armazenamento | Configuração | Indicado para |
|---|---|---|
| Local (padrão) | Nenhuma. Funciona logo após a instalação. | Todos os servidores. Os arquivos ficam no seu próprio servidor, no seu banco de dados. |
| Cloudflare R2 | Cerca de 10 minutos, uma única vez. Grátis até 10 GB. | Servidores com muitos vídeos ou com muitos jogadores. |
Fivemanage e Discord não são mais usados como armazenamento. Os webhooks do Discord continuam disponíveis para logs.
Armazenamento local (padrão)
Não há nada para configurar. O script cria duas tabelas no seu banco de dados na primeira inicialização (agency_media e agency_media_parts) e guarda os arquivos nelas. Você só precisa do oxmysql, que o script já exige de qualquer forma.
O que isso significa para você:
- Sem conta, sem chave de API, sem resource extra. Nada roda fora do seu servidor.
- Atualizações são seguras. Os arquivos ficam no banco de dados, não na pasta do resource, então substituir a pasta em uma atualização mantém todas as fotos.
- Os backups do seu banco de dados incluem a mídia. O banco cresce cerca de um terço a mais do que os próprios arquivos. Uma foto ocupa cerca de 150 KB.
- Agency Phone e Agency Pad compartilham o armazenamento. Uma foto tirada com um deles aparece no outro, inclusive fotos sincronizadas com o Agency Cloud.
- O app Agency Companion também mostra tudo, no iOS, no Android e no app web. Também não há nada para configurar nesse caso.
Velocidade
Os arquivos viajam pela própria conexão do FiveM, sem travar o jogo. O FiveM limita a velocidade com que um jogador pode enviar dados ao servidor (cerca de 165 KB por segundo), então:
| O quê | O salvamento leva cerca de |
|---|---|
| Foto | 1 segundo |
| Mensagem de voz | menos de 1 segundo |
| Clipe de vídeo de 15 segundos | 20 segundos (a câmera mostra o progresso em porcentagem) |
Mostrar um arquivo para outros jogadores é rápido, um clipe inteiro chega em poucos segundos. Se o seu servidor grava muitos vídeos, o Cloudflare R2 salva os clipes quase instantaneamente.
Configurações no config.lua
AgencyConfig.MediaStorage = {
Provider = 'local', -- 'local' or 'cloudflare'
MaxFileMegabytes = 10, -- largest single file (clips, recordings)
TransferKilobytesPerSecond = 1000, -- 'local': how fast files are sent to players
Local = {
RetentionDays = 30, -- delete files older than this (0 = keep forever)
MaxStorageGigabytes = 10, -- delete the oldest files above this (0 = no limit)
},
}
| Configuração | O que faz |
|---|---|
RetentionDays | Arquivos mais antigos que isso são apagados automaticamente uma vez por hora. Uma foto apagada mostra um pequeno marcador na galeria. Defina 0 para manter tudo. |
MaxStorageGigabytes | Quando todos os arquivos juntos ultrapassam esse valor, os mais antigos são apagados primeiro. Defina 0 para não ter limite. |
MaxFileMegabytes | Arquivos maiores são recusados. Também limita clipes de vídeo e gravações de tela. |
TransferKilobytesPerSecond | Velocidade por jogador no envio de arquivos aos jogadores. O jogo sempre tem prioridade. |
Cloudflare R2, passo a passo
O Cloudflare R2 é gratuito até 10 GB de armazenamento, 1 milhão de uploads e 10 milhões de downloads por mês, e os downloads nunca geram custo. A Cloudflare pede uma forma de pagamento quando você ativa o R2, mesmo no plano gratuito. Você só paga se ultrapassar os limites gratuitos.
1. Ativar o R2
- Faça login em dash.cloudflare.com (uma conta gratuita é suficiente).
- No menu à esquerda, abra Storage & databases e depois R2 Object Storage.
- Adicione a assinatura do R2. A visão geral mostra $0.00 a pagar agora. Aceite os termos e clique em Activate.
2. Criar um bucket
- Clique em Create bucket.
- Dê um nome, por exemplo
myserver-media. O nome não pode ser alterado depois. - Deixe a localização em Automatic e a classe de armazenamento em Standard.
- Clique em Create bucket.
3. Tornar os arquivos visíveis
- Abra o seu bucket e vá em Settings.
- Em Public Development URL, clique em Enable, digite
allowe confirme. - Copie o endereço que aparece, parecido com
https://pub-1a2b3c….r2.dev. Esse é o seu PublicUrl.
A Cloudflare limita o endereço r2.dev para servidores muito movimentados. Se você tem um domínio próprio na Cloudflare, pode adicioná-lo em Custom Domains, no mesmo lugar, e usar esse endereço como PublicUrl.
4. Permitir uploads a partir do jogo
- Ainda em Settings, encontre CORS Policy e clique em Add.
- Apague tudo no campo de texto, cole o conteúdo abaixo e clique em Save:
[
{
"AllowedOrigins": ["https://cfx-nui-agency-phone", "https://cfx-nui-agency-pad"],
"AllowedMethods": ["PUT", "GET"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]
Sem esta etapa, o jogo não consegue fazer upload e as fotos não são salvas. Se você renomeou a pasta do resource, coloque o nome da sua pasta depois de cfx-nui-.
5. Criar uma chave
- Volte para R2 Object Storage e clique em Manage API tokens.
- Clique em Create API token (um token de conta serve).
- Permissões: Object Read & Write.
- Na escolha do bucket, selecione somente o seu bucket.
- Clique em Create. A Cloudflare mostra o Access Key ID e o Secret Access Key apenas uma vez, copie os dois agora.
- O seu Account ID aparece na visão geral do R2 e também é a primeira parte do endereço S3 (
https://<Account ID>.r2.cloudflarestorage.com).
6. Informar no script
As chaves vão no config_server.lua. Esse arquivo é lido apenas pelo servidor e nunca é enviado aos jogadores. Não coloque as chaves no config.lua: esse arquivo é enviado a todos os jogadores.
-- config_server.lua
AgencyServerConfig.Cloudflare = {
AccountId = 'your account id',
Bucket = 'myserver-media',
AccessKeyId = 'your access key id',
SecretAccessKey = 'your secret access key',
PublicUrl = 'https://pub-1a2b3c....r2.dev',
}
Depois defina o provedor no config.lua e reinicie o resource:
AgencyConfig.MediaStorage = {
Provider = 'cloudflare',
...
}
O console do servidor agora mostra Media: storage: Cloudflare R2, bucket myserver-media. Se algo estiver faltando, o console diz o que é, e o script continua salvando localmente até que seja corrigido, então a câmera nunca para de funcionar.
Usa Agency Phone e Agency Pad juntos? Os dois podem usar o mesmo bucket e a mesma chave, cada um guarda seus arquivos na sua própria pasta.
Verifique se funciona
Execute isto no console do servidor (ou como admin no jogo), com o ID de um jogador que esteja online:
phonemediatest 1
O Agency Phone do jogador salva uma pequena imagem de teste, carrega-a de volta como qualquer outro jogador faria, exibe-a e reproduz uma curta mensagem de voz. O console responde:
Media test passed for player 1 in 1361 ms: upload ok, download ok, shown as picture ok, app markup and backgrounds ok, voice message plays ok
Adicione big para testar também um clipe de vídeo de 6 MB: phonemediatest 1 big.
Problemas e soluções
| O que você vê | Solução |
|---|---|
could not create the media tables no console | O oxmysql não está rodando ou não consegue acessar o banco de dados. Inicie o oxmysql antes do agency-phone. |
Provider is 'cloudflare', but config_server.lua is missing ... | Um dos cinco valores está vazio, ou o PublicUrl não começa com https://. Confira a etapa 6. |
Fotos falham com Cloudflare HTTP 403 | A chave não tem permissão de escrita neste bucket, ou o nome do bucket está errado. Confira a etapa 5. |
Fotos falham com Failed to fetch no Cloudflare | A política de CORS da etapa 4 está ausente ou tem um nome de resource diferente. |
| Fotos salvas não aparecem no Cloudflare | A Public Development URL da etapa 3 está desativada, ou o PublicUrl aponta para outro bucket. |
| Um vídeo demora para salvar | É normal com armazenamento local, veja Velocidade acima. Use o Cloudflare R2 para clipes instantâneos. |
| Fotos antigas sumiram | O RetentionDays as apagou. Aumente o valor ou defina 0. |
Vindo do Fivemanage ou do Discord
Não há nada para migrar. Fotos salvas antes mantêm seus links antigos e continuam visíveis enquanto esse serviço ainda as entregar. Tudo o que for novo vai para o armazenamento que você escolheu. As configurações antigas MediaStorageProvider, FiveManageApiUrl, FiveManageApiKey e ScreenshotWebhook são ignoradas e podem ser apagadas da sua config.
Segurança
- Apenas jogadores conectados ao seu servidor podem fazer upload. Cada upload é anunciado antes e verificado quanto ao tipo e ao tamanho.
- O conteúdo é verificado pelos primeiros bytes. Uma página web ou um script nunca pode ser armazenado disfarçado de foto.
- Os nomes de arquivo são aleatórios de 128 bits, não podem ser adivinhados nem listados.
- Uploads e downloads são limitados por jogador.
- Com o Cloudflare, cada upload recebe seu próprio link, válido por 5 minutos, para exatamente um arquivo de um tipo e um tamanho. A chave secreta nunca sai do seu servidor.