Pular para o conteúdo

O que é o Agent

O Agent é um pequeno programa que a Lootfy publica para você rodar na mesma máquina do seu servidor de jogo. A função dele é única e fácil de descrever: pegar um pedido do seu servidor, assiná-lo com a sua chave e entregá-lo à Lootfy — e, no sentido inverso, receber os avisos da plataforma, conferir se são autênticos e repassá-los ao seu servidor. Ele é o tradutor entre o seu jogo e o contrato criptográfico da Lootfy.

Pense nele como a caneta, não o autor. Quem decide o que assinar é sempre o seu servidor; o Agent só assina o que o seu código mandar assinar, do jeito que a Lootfy exige, e cuida do transporte. Ele não tem opinião sobre como você construiu o seu jogo, não conhece item nem personagem, e não sabe nada de preço, saldo ou estoque.

O contrato da Lootfy exige assinatura JWS RS256 em toda chamada, nos dois sentidos. Assinar assim envolve criptografia de chave pública, codificação base64url e uma requisição HTTP de saída. A maioria dos servidores da família TFS (a base de boa parte dos servidores Open Tibia) simplesmente não consegue fazer isso sozinha: o Lua embarcado nesses servidores expõe md5 e sha1, e nada além disso — não há RS256, não há base64url, não há cliente HTTP.

A consequência é direta: sem um componente fora do Lua, nenhum servidor dessa família integra com a Lootfy. Não é peculiaridade de um fork; é a família inteira. O Agent é esse componente. Para qualquer servidor que não consiga assinar em RS256 e falar HTTP por conta própria, ele é obrigatório — não é uma conveniência, é o que torna a integração possível.

O Agent faz

Guarda a sua chave privada e a sua API key; recebe um pedido de negócio em JSON simples; acrescenta jti e exp, assina em RS256 destacado e envia com a API key onde ela é exigida; repete com backoff quando a falha é transitória; verifica a assinatura dos webhooks da plataforma e os reentrega ao seu servidor; e, nas rotas transportadas pelo client, devolve o envelope assinado em vez de enviar.

O Agent não faz

Não lê o seu banco de dados nem abre conexão com nada do seu servidor; não valida posse de item, saldo, preço ou estoque; não tem tabela de negócio nem migration; não conhece item, personagem ou jogo. A autoridade de negócio é sempre o seu servidor.

A primeira dessas ausências é a mais importante e é um requisito, não um detalhe: o Agent nunca acessa o banco de dados do parceiro, sob nenhuma hipótese. É isso que o torna publicável — não há adapter por fork, não há credencial de banco alheio, não há responsabilidade da Lootfy sobre o seu dado. Uma versão anterior do desenho lia as tabelas do jogo para conferir posse de item; foi descartada justamente por violar essa premissa.

O Agent abre duas portas de rede, com papéis opostos, e a separação entre elas não é negociável.

Porta de controle — assina

Ouve só em loopback (127.0.0.1:8899 por padrão). É onde o seu servidor pede uma assinatura. Ela assina sob demanda: quem a alcança detém toda a autoridade da sua conta Lootfy. Por isso nunca pode ser exposta à internet — e o Agent se recusa a subir se você tentar publicá-la.

Porta de webhook — verifica

Ouve em 127.0.0.1:8898 por padrão. É onde a plataforma entrega os webhooks (transfer_order e transaction_terminal). Ela só verifica a assinatura da Lootfy e nunca assina nada. Por isso pode, com cuidado, ficar atrás de um proxy público com TLS.

A assimetria é intencional. Uma porta que assina qualquer coisa que recebe não pode ser alcançável pelo jogador; uma porta que apenas confere assinaturas da plataforma não tem nada a entregar a quem a alcança. É por isso, também, que o envelope das rotas transportadas pelo client nasce no lado do servidor e chega ao client pelo canal do jogo, nunca por uma chamada direta do client ao Agent.

No caminho de saída — o seu servidor iniciando uma ação na Lootfy — o Agent fica no meio, entre o seu código e a API:

  1. O seu servidor decide que precisa chamar a Lootfy (registrar um anúncio, criar uma transação, confirmar uma entrega) e monta um pedido em JSON simples.

  2. Ele entrega esse pedido ao Agent por uma das interfaces locais — HTTP em loopback ou um arquivo no spool.

  3. O Agent acrescenta jti e exp, assina o corpo em JWS RS256 com a sua chave, anexa a API key quando a rota exige, e envia à Lootfy (ou, nas rotas transportadas pelo client, devolve o envelope assinado sem enviar).

  4. A resposta da plataforma volta ao seu servidor pela mesma interface, como JSON simples — sem nenhuma criptografia aparecendo do seu lado.

seu servidor ──JSON──▶ Agent ──JWS RS256 + API key──▶ API Lootfy
▲ │ │
└────── JSON ────────┴──────────── resposta ───────────┘

No caminho de entrada — a Lootfy avisando o seu servidor de uma transferência ou de um estado terminal — o fluxo se inverte: a plataforma faz um POST na porta de webhook, o Agent verifica a assinatura da Lootfy e, sendo válida, entrega o evento ao seu servidor pelo spool.

API Lootfy ──JWS assinado pela plataforma──▶ Agent (verifica) ──evento──▶ seu servidor

O Agent é o pacote lootfy-agent, versão 0.1.0, escrito em TypeScript e distribuído como ESM. Ele roda em Node 22 ou superior, tem zero dependências de runtime (só a biblioteca padrão do Node) e é licenciado sob Apache-2.0. O binário se chama lootfy-agent.