Pular para o conteúdo
Blog

Servir as imagens de itens do ox_inventory por uma CDN

Mova o web/images do ox_inventory para uma CDN com um zip e uma convar: resource mais leve, entrada mais rápida e imagens que você troca sem reiniciar.

Por Termi

8 min de leitura
  • ox_inventory
  • CDN
  • Performance
Nesta página

Cada item do ox_inventory tem um PNG em ox_inventory/web/images. Num servidor com algumas centenas de itens customizados, essa pasta chega fácil a dezenas de megabytes, e tudo isso faz parte de um resource que todo jogador baixa antes de poder jogar. Este guia move as imagens para uma CDN: um upload de zip, uma linha no server.cfg, e o inventário passa a carregar as imagens de cdn.fivedock.dev.

Por que tirar as imagens do resource

O fxmanifest.lua do ox_inventory lista web/images/*.png em files, o que transforma cada imagem em um arquivo do resource: o servidor manda para cada client, e o client guarda no cache do FiveM. Isso tem alguns custos:

  • Um jogador novo baixa a pasta inteira antes de spawnar, inclusive imagens de itens que nunca vai segurar, então entrar demora mais.
  • O FiveM faz cache dos arquivos do resource por hash, então uma imagem que não mudou não é baixada duas vezes. Mas toda imagem que você adiciona ou troca é mais um arquivo que todo jogador baixa na próxima entrada.
  • Um arquivo novo no resource só chega aos jogadores depois que o ox_inventory é reiniciado, e num servidor no ar esse é o resource que você menos quer reiniciar.

Com uma CDN, as imagens deixam de fazer parte do resource. A página de navegador do inventário só pede uma imagem quando precisa mostrar aquele item, e a mantém no cache HTTP para a próxima vez. Um jogador que nunca abre a loja de armas nunca baixa as imagens das armas.

Como o ox_inventory acha uma imagem

O ox_inventory lê a convar replicada inventory:imagepath e monta cada link de imagem como <imagepath>/<item name>.png. O padrão aponta para dentro do próprio resource:

image links
default  nui://ox_inventory/web/images/burger.png
CDN      https://cdn.fivedock.dev/o/<your-workspace>/items/burger.png

Então basta uma pasta na web em que cada imagem tenha exatamente o nome do seu item. Dois detalhes do código-fonte do ox_inventory:

  • A extensão é sempre .png. Mantenha as imagens como arquivos PNG com o nome do item: burger.png, não Burger.PNG nem burger.webp.
  • O client.image próprio de um item continua valendo mais. Uma URL completa ali é usada como está; um nome de arquivo solto, como burger_deluxe.png, é procurado sob o imagepath e vai para a CDN junto com o resto.

Envie as imagens

No FiveDock, um arquivo enviado com chave recebe um link que nunca muda: https://cdn.fivedock.dev/o/<your-workspace>/<key>. Envie as imagens de modo que burger.png fique com a chave items/burger.png e o imagepath seja …/items. O slug da sua organização é o nome curto exibido no painel, e também é o nome do seu bucket S3.

Pelo painel

  1. Compacte o conteúdo da pasta, não a pasta em si: no Windows, abra ox_inventory/web/images, selecione todos os arquivos com Ctrl+A, clique com o botão direito e escolha Enviar para → Pasta compactada, ou rode zip -r ../images.zip . dentro de ox_inventory/web/images.
  2. No painel, abra Arquivos, crie uma pasta chamada items e abra-a.
  3. Clique em Enviar um arquivo e solte o zip. Manter nomes dos arquivos vem ativado por padrão para arquivos compactados; deixe ativado.

O FiveDock descompacta o arquivo e guarda cada imagem como um arquivo próprio. As pastas dentro do arquivo compactado são mantidas, por isso você compacta as imagens e não a pasta images: burger.png vira items/burger.png, e não items/images/burger.png. Tudo que não for uma imagem aceita, como um readme.txt esquecido, é ignorado e listado no resultado.

Pela API

O mesmo em uma requisição, com um token de API (fd_live_…, criado na página Tokens) com o escopo files:write:

bash
cd ox_inventory/web/images
zip -r ../images.zip .

curl -X POST https://api.fivedock.dev/api/v3/file/archive \
  -H "Authorization: Bearer fd_live_…" \
  -F "file=@../images.zip" \
  -F "path=items"
response
{
  "status": "ok",
  "data": {
    "uploaded": [
      {
        "key": "items/burger.png",
        "url": "https://cdn.fivedock.dev/o/my-city/items/burger.png",
        "fileUrl": "https://cdn.fivedock.dev/f/…png",
        "filename": "burger.png",
        "path": "/items",
        "size": 18233,
        "mime_type": "image/png",
        "deduplicated": false
      }
    ],
    "skipped": [{ "name": "readme.txt", "reason": "unsupported_type" }]
  }
}

url é o link estável com chave; fileUrl é o link por upload que todo arquivo também recebe. Um arquivo compactado pode ter até 5.000 arquivos, o que cobre quase qualquer lista de itens. Se a sua for maior, envie em dois arquivos compactados ou use o rclone.

Com rclone (S3)

Se você mantém seu servidor no Git ou faz deploy com scripts, o endpoint S3 é o caminho mais confortável. Configure um remote do rclone chamado fivedock, como mostra a documentação de uploads, e depois:

rclone
# my-city = your workspace slug (it is also your S3 bucket name)
rclone sync ./ox_inventory/web/images fivedock:my-city/items --dry-run
rclone sync ./ox_inventory/web/images fivedock:my-city/items

rclone sync deixa o destino igual à origem, e isso inclui apagar em items os arquivos que não estão na sua pasta local. Rode primeiro com --dry-run, ou use rclone copy se você só adiciona e atualiza.

Objetos que você envia pelo S3 também são arquivos com chave, então ganham os mesmos links estáveis.

Aponte o ox_inventory para a CDN

Adicione a convar ao server.cfg, acima da linha que inicia o ox_inventory:

server.cfg
setr inventory:imagepath "https://cdn.fivedock.dev/o/<your-workspace>/items"

ensure ox_inventory
  • Use setr, não set: a UI do inventário roda no client, e só convars setr são replicadas para os clients.
  • Sem barra no final, o ox_inventory adiciona.
  • O ox_inventory lê a convar quando inicia, então reinicie-o (ou o servidor) uma vez.

Antes de reiniciar, abra uma imagem no navegador para conferir o link, por exemplo https://cdn.fivedock.dev/o/<your-workspace>/items/burger.png.

Tire as imagens do resource

Entre no servidor, abra seu inventário e uma ou duas lojas, e confira se as imagens carregam. Quando carregarem, tire os arquivos PNG de ox_inventory/web/images e guarde em outro lugar: aquela pasta agora é a fonte dos seus uploads, não parte do servidor.

Quando atualizar o ox_inventory depois, deixe web/images de fora da cópia, ou esvazie a pasta de novo em seguida.

Adicionando e trocando imagens depois

Para adicionar a imagem de um item novo, ou corrigir uma antiga, envie o PNG com a chave que ele deve ter: Enviar um arquivo na pasta items do painel com Manter nomes dos arquivos ativado, ou pela API:

bash
curl -X POST https://api.fivedock.dev/api/v3/file \
  -H "Authorization: Bearer fd_live_…" \
  -F "[email protected]" \
  -F "key=items/burger.png"

Se items/burger.png já existir, o upload o substitui atrás do mesmo link; a versão antiga fica guardada por 7 dias antes de ser apagada. Links com chave ficam em cache por 5 minutos e depois são revalidados, então os jogadores veem a imagem nova em cerca de cinco minutos, sem reiniciar nada e sem baixar nada novo ao entrar.

Se uma imagem não aparecer

  • Um item está com a imagem quebrada. O nome do arquivo precisa bater exatamente com o nome do item, inclusive maiúsculas e minúsculas: WEAPON_PISTOL.png para WEAPON_PISTOL. Chaves montadas a partir de nomes de arquivo trocam espaços por - e outros caracteres incomuns por _, então uma imagem chamada my item.png acaba como my-item.png.
  • Todas as imagens estão quebradas. Abra o imagepath mais /burger.png no navegador. Um 404 costuma indicar que a pasta está errada (items/images/burger.png em vez de items/burger.png) ou que o slug da organização está errado. Confira também se você usou setr.
  • A imagem antiga continua aparecendo depois da troca. Espere cinco minutos; os jogadores ficam com a cópia anterior até o cache expirar.
  • Um item ignora a CDN. Provavelmente ele define client.image com uma URL completa. Remova isso, ou aponte para a CDN.

Os mesmos links com chave servem para qualquer outra imagem que sua UI carregue, como miniaturas de veículos ou mugshots: envie uma vez e use o link onde precisar.

Perguntas frequentes

De onde o ox_inventory carrega as imagens dos itens?

Da convar replicada inventory:imagepath, que por padrão é nui://ox_inventory/web/images, a pasta web/images dentro do resource. Para cada item, o ox_inventory monta o link <imagepath>/<item name>.png. O client.image próprio do item sobrescreve isso: uma URL completa é usada como está, e um nome de arquivo solto é procurado sob o imagepath.

Como mudo o imagepath do ox_inventory?

Adicione setr inventory:imagepath "https://cdn.fivedock.dev/o/<your-workspace>/items" ao server.cfg acima de ensure ox_inventory, sem barra no final, e reinicie o ox_inventory uma vez. Precisa ser setr, porque a UI do inventário roda no client e só convars setr chegam aos clients. Cada imagem deve então estar nesse endereço, com o nome exato do seu item e a extensão .png.

Por que as imagens dos meus itens do ox_inventory não aparecem?

Em geral o nome do arquivo não bate exatamente com o nome do item, inclusive maiúsculas e minúsculas, ou o arquivo não é um .png. Se todas as imagens sumiram, abra o imagepath mais /burger.png no navegador: um 404 significa que a pasta ou o slug da organização no caminho está errado. Confira também se a convar foi definida com setr e não com set.

O ox_inventory aceita imagens de itens em WebP ou JPG?

Só item a item. A busca pelo imagepath sempre acrescenta .png ao nome do item, então um burger.webp ao lado nunca é pedido. Defina o client.image do item como burger.webp, que é procurado sob o imagepath, ou como uma URL completa, e a página NUI do inventário o carrega como qualquer navegador.

Preciso reiniciar o ox_inventory para trocar a imagem de um item?

Não, quando as imagens estão numa CDN. Envie o novo PNG para a mesma chave, como items/burger.png, e os jogadores o veem em cerca de cinco minutos, quando a cópia em cache expira. Imagens dentro de web/images só chegam aos jogadores depois que o ox_inventory é reiniciado.

Todos os artigos