Portal SAMP
[Utilitário] SA-MP Query Node - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Lançamentos (https://portalsamp.com/forumdisplay.php?fid=26)
+---- Fórum: Utilitários (https://portalsamp.com/forumdisplay.php?fid=28)
+---- Tópico: [Utilitário] SA-MP Query Node (/showthread.php?tid=4911)



SA-MP Query Node - Calasans - 02/11/2024

SA-MP Query Node
Introdução:
  • Uma API completa para ambientes Node.js, projetada para consultas a servidores SA-MP (San Andreas Multiplayer) e compatível com o OPEN.MP (Open Multiplayer). Oferece recursos avançados de monitoramento e coleta de informações em tempo real.


Sobre a API:
  • O SA-MP Query Node é uma API desenvolvida especificamente para interagir com servidores SA-MP, permitindo a coleta de informações detalhadas sobre o servidor em tempo real. A API utiliza o protocolo de consulta nativo do SA-MP e implementa várias camadas de otimização para garantir consultas eficientes e confiáveis.
A API foi projetada com foco em:
  1. Confiabilidade nas consultas
  2. Eficiência no processamento
  3. Facilidade de uso
  4. Tratamento robusto de erros
  5. Suporte completo a todas as funcionalidades do protocolo SA-MP

Funcionalidades
Sistema de Consulta Principal:
  • A API oferece um sistema de consulta completo que permite obter:
1 - Informações Básicas do Servidor:
  • Nome do servidor
  • Modo de jogo atual
  • Idioma configurado
  • Status de proteção por senha
  • Número máximo de jogadores
  • Número atual de jogadores online
2 - Lista Detalhada de Jogadores:
  • ID do jogador
  • Nome do jogador
  • Pontuação atual
  • Latência (ping) do jogador
3 - Regras do Servidor:
  • Configurações de lag compensation
  • Clima atual
  • Outras regras personalizadas definidas pelo servidor
4 - Medições de Desempenho:
  • Latência do servidor (ping)
  • Tempo de resposta das consultas
  • Estatísticas de conexão

Estrutura da API

1 - DNS_Cache

Código:
class DNS_Cache {
    constructor() {
        this.cache = new Map();
        this.Resolve_DNS = promisify(dns.resolve4);
    }
}

A classe DNS_Cache é responsável por:
  • Armazenar temporariamente resoluções DNS
  • Otimizar consultas repetidas
  • Reduzir a latência de conexão
  • Gerenciar o tempo de vida do cache
Métodos principais:
  • Get_IP_Address(host_name): Resolve e cache endereços IP
  • Cache automático com duração configurável (padrão: 5 minutos)
  • Fallback para hostname em caso de falha na resolução
2 - Query_Manager

Código:
class Query_Manager extends EventEmitter {
    constructor() {
        super();
        this.Active_Queries = new Map();
    }
}

O Query_Manager controla:
  • Gerenciamento de consultas ativas
  • Timeouts e retentativas
  • Eventos de conclusão de consulta
  • Limpeza de consultas expiradas
Funcionalidades:
  • Sistema de retry automático
  • Controle de tempo limite
  • Gerenciamento de múltiplas consultas simultâneas
  • Emissão de eventos de conclusão
3 - SAMP_Strings

Código:
class SAMP_Strings {
    static charset = [/* conjunto de caracteres SA-MP */];
    static Decode_String(buffer_data) { /* ... */ }
}

Responsável por:
  • Decodificação de strings do SA-MP
  • Suporte a caracteres especiais
  • Limpeza e sanitização de strings
  • Conversão de buffers para texto

Exemplos de Uso
1 - Consulta Básica

Código:
const query = require('samp-query-node');

query('127.0.0.1:7777', (erro, resposta) => {
    if (erro) {
        console.error('Erro na consulta:', erro);
        return;
    }
   
    console.log('Informações do servidor:', resposta);
});

2 - Consulta com Opções Personalizadas

Código:
const opcoes = {
    host: '127.0.0.1',
    port: 7777,
    timeout: 1500  // timeout de 1.5 segundos
};

query(opcoes, (erro, resposta) => {
    if (erro) {
        console.error('Erro:', erro);
        return;
    }
   
    console.log('Nome do servidor:', resposta.hostname);
    console.log('Jogadores:', resposta.onlinePlayers);
    console.log('Modo de jogo:', resposta.gamemode);
   
    // Processando lista de jogadores
    resposta.players.forEach(jogador => {
        console.log(`${jogador.name}: ${jogador.score} pontos`);
    });
});

3 - Utilizando Promises

Código:
const util = require('util');
const Query_Async = util.promisify(query);

async function Requisitar_Servidor() {
    try {
        const info = await Query_Async('127.0.0.1:7777');
       
        console.log('Servidor:', info.hostname);
        console.log('Jogadores:', info.onlinePlayers);
        console.log('Ping:', info.ping, 'ms');
       
        // Processando regras do servidor
        if (info.rules.lagcomp === 'On') {
            console.log('Servidor com lag compensation ativado');
        }
       
        // Listando top jogadores
        const topJogadores = info.players
            .sort((a, b) => b.score - a.score)
            .slice(0, 5);
           
        console.log('\nTop 5 Jogadores:');
        topJogadores.forEach((jogador, index) => {
            console.log(`${index + 1}. ${jogador.name}: ${jogador.score} pontos`);
        });
       
    } catch (erro) {
        console.error('Erro ao consultar servidor:', erro);
    }
}

4 - Monitoramento Contínuo

Código:
async function Monitorar_Servidor(endereco, intervalo = 60000) {
    const Query_Async = util.promisify(query);
   
    console.log(`Iniciando monitoramento de ${endereco}`);
   
    setInterval(async () => {
        try {
            const info = await Query_Async(endereco);
           
            console.log('\n=== Status do Servidor ===');
            console.log(`Tempo: ${new Date().toLocaleString()}`);
            console.log(`Jogadores: ${info.onlinePlayers}/${info.maxPlayers}`);
            console.log(`Ping: ${info.ping}ms`);
            console.log(`Modo: ${info.gamemode}`);
           
            if (info.onlinePlayers > 0) {
                console.log('\nJogadores Online:');
                info.players.forEach(jogador => {
                    console.log(`- ${jogador.name} (Ping: ${jogador.ping}ms)`);
                });
            }
           
        } catch (erro) {
            console.error('Erro no monitoramento:', erro);
        }
    }, intervalo);
}


Estrutura de Resposta

A API retorna um objeto detalhado com todas as informações do servidor:
Código:
{
    // Informações básicas
    address: "127.0.0.1", // Endereço do servidor
    port: 7777, // Porta do servidor
    hostname: "Server", // Nome do servidor
    gamemode: "RolePlay", // Modo de jogo
    language: "Português - Brasil", // Idioma
   
    // Status do servidor
    password: false, // Proteção por senha
    maxPlayers: 100, // Máximo de jogadores
    onlinePlayers: 45, // Jogadores online
    ping: 58, // Latência em ms
    queryTime: 1635789012345, // Timestamp da consulta
   
    // Lista de jogadores
    players: [
        {
            id: 0, // ID do jogador
            name: "Calasans", // Nome
            score: 63, // Pontuação
            ping: 117 // Ping do jogador
        },
    ],
   
    // Regras do servidor
    rules: {
        allowed_clients: "0.3.7, 0.3.DL", // Versões permitidas de clientes
        artwork: 1, // Habilitação de artwork
        lagcomp: "On", // Status do lag comp
        mapname: "San Andreas", // Nome do mapa
        version: "0.3.7", // Versão do servidor
        weather: 10, // ID do clima
        weburl: "website.com", // URL do site do servidor
        worldtime: "12:00" // Hora do mundo no servidor
    }
}


Leia o repositório disponibilizado no GitHub para saber mais!


RE: SA-MP Query Node - BitSain - 03/11/2024

Ótima contribuição, funciona perfeitamente seu código.
O tempo de resposta é bem rápida inclusive.