Servidores de Jogos

Discord Bot para monitorar servidor Minecraft: guia Python (mcstatus) e Java (JDA)

Por que um bot Discord?

Servidor MC + Discord + bot = engajamento e alertas em tempo real.

Cenários de uso:

  • Canal #status mostrando "18/50 players online" atualizado a cada minuto
  • Alerta no @equipe quando servidor cair
  • Comando /players que lista quem está online
  • Ponte chat MC ↔ Discord (mensagens vão nos dois lados)
  • /whois Steve123 pra ver rank, tempo jogado, saldo

2 abordagens

Abordagem A: Bot Python + mcstatus (o mais rápido)

Ideal para bots simples de status/monitoramento.

Tempo pra fazer: 20 minutos
Dificuldade: fácil
Você precisa: VPS/PC 24/7 com Python 3.10+

Abordagem B: Plugin DiscordSRV (o padrão da comunidade)

Já pronto, só instalar. Faz ponte de chat automática.

Tempo: 10 minutos
Dificuldade: trivial
Você precisa: apenas o servidor MC

Abordagem B primeiro — DiscordSRV (recomendado para maioria)

O que faz

  • Chat MC → aparece no canal Discord
  • Chat Discord → aparece no MC (com prefixo)
  • Comandos: /list, /link (vincula conta Discord ao player)
  • Alerta de join/leave no Discord
  • Cargos Discord ↔ ranks MC (sincroniza LuckPerms)

Setup

  1. Baixe o plugin em discordsrv.com
  2. Solte em /plugins/
  3. Reinicie o servidor MC
  4. Crie um bot Discord em discord.com/developers/applications
  5. Copie o Bot Token
  6. Convide o bot pro seu servidor Discord (URL geradora no dev portal, permissões: Send Messages, Manage Roles)
  7. Edite plugins/DiscordSRV/config.yml:
BotToken: "seu.token.aqui"
Channels:
  global: "1234567890"    # ID do canal Discord (habilitar Modo Desenvolvedor)
  staff:  "1234567891"
  1. Reinicie o MC. Chat funciona bidirecionalmente.

Zero código escrito! Pronto pra uso.

Abordagem A — bot Python custom (mcstatus)

Se você quer canal dedicado só de status ou bot custom próprio:

Setup do ambiente

apt install -y python3 python3-pip
pip3 install mcstatus discord.py

Bot completo (status.py)

import discord
from discord.ext import tasks
from mcstatus import JavaServer

# ─── CONFIG ────────────────────────────────────────
TOKEN = "SEU.BOT.TOKEN"
MC_HOST = "meuservidor.com.br"
MC_PORT = 25565
STATUS_CHANNEL_ID = 1234567890
UPDATE_INTERVAL_SECONDS = 60

# ─── BOT ──────────────────────────────────────────
intents = discord.Intents.default()
client = discord.Client(intents=intents)
last_status = None

@client.event
async def on_ready():
    print(f"Bot online: {client.user}")
    update_status.start()

@tasks.loop(seconds=UPDATE_INTERVAL_SECONDS)
async def update_status():
    global last_status
    try:
        server = JavaServer.lookup(f"{MC_HOST}:{MC_PORT}")
        status = server.status()
        online = status.players.online
        maxp = status.players.max
        motd = status.description if isinstance(status.description, str) else status.description.get("text", "")
        ping_ms = int(status.latency)

        # Atualiza status do bot
        activity = discord.Activity(
            type=discord.ActivityType.playing,
            name=f"{online}/{maxp} online | {ping_ms}ms"
        )
        await client.change_presence(activity=activity)

        # Notifica no canal se mudou (up/down)
        current = "up"
        if current != last_status:
            channel = client.get_channel(STATUS_CHANNEL_ID)
            if channel:
                await channel.send(f"🟢 Servidor ONLINE: **{online}/{maxp}** players | ping {ping_ms}ms")
            last_status = current

    except Exception as e:
        # Server offline ou erro
        activity = discord.Activity(type=discord.ActivityType.watching, name="Servidor offline")
        await client.change_presence(status=discord.Status.dnd, activity=activity)

        if last_status != "down":
            channel = client.get_channel(STATUS_CHANNEL_ID)
            if channel:
                await channel.send(f"🔴 Servidor OFFLINE! Erro: `{e}`")
            last_status = "down"

# ─── COMANDOS SLASH ────────────────────────────────
tree = discord.app_commands.CommandTree(client)

@tree.command(name="players", description="Lista quem está online no servidor")
async def players(interaction: discord.Interaction):
    try:
        server = JavaServer.lookup(f"{MC_HOST}:{MC_PORT}")
        query = server.query()
        players = query.players.names
        if not players:
            await interaction.response.send_message("Ninguém online agora 😢")
        else:
            lista = "\n".join(f"• {p}" for p in players)
            await interaction.response.send_message(f"**{len(players)} online:**\n{lista}")
    except Exception as e:
        await interaction.response.send_message(f"Erro ao consultar: `{e}`")

@client.event
async def setup_hook():
    await tree.sync()

client.run(TOKEN)

IMPORTANTE: para /players funcionar, habilite query em server.properties:

enable-query=true
query.port=25565

Rodar como serviço

systemd unit /etc/systemd/system/mc-discord-bot.service:

[Unit]
Description=MC Discord Bot
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/mc-bot
ExecStart=/usr/bin/python3 /opt/mc-bot/status.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
systemctl enable --now mc-discord-bot

Docker (alternativa)

Dockerfile:

FROM python:3.11-slim
WORKDIR /app
RUN pip install mcstatus discord.py
COPY status.py .
CMD ["python", "status.py"]

Abordagem C — Java (JDA)

Se você quer bot Java integrado ao plugin do MC:

<dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId>
    <version>5.0.0</version>
</dependency>
JDA jda = JDABuilder.createDefault("TOKEN")
    .setActivity(Activity.playing("MC Server"))
    .build();

TextChannel channel = jda.getTextChannelById("ID");
channel.sendMessage("Servidor iniciado ✅").queue();

Menos recomendado pra bot só de status — Python + mcstatus é mais rápido.

Recursos avançados

Notificar quando alguém morre

Use plugin bridge (DiscordSRV) OU custom com Bukkit listener + REST call pro Discord webhook.

Comandos in-game que respondem no Discord

/discord staff Server ficou instável → envia msg no canal staff.

Bot que aceita comandos no Discord e executa RCON

Combine mcstatus + RCON:

from mcrcon import MCRcon
with MCRcon("mc-server", "rcon_password") as mcr:
    resp = mcr.command("say Servidor será reiniciado em 5min!")

Cuidado: proteja com verificação de role Discord (só admin pode).

Alertar quando player VIP entra

Hook no PlayerJoinEvent (Bukkit) + webhook Discord:

@EventHandler
public void onJoin(PlayerJoinEvent e) {
    if (e.getPlayer().hasPermission("group.vip")) {
        DiscordSRV.getPlugin().getMainTextChannel()
            .sendMessage("👑 VIP " + e.getPlayer().getName() + " entrou!").queue();
    }
}

Segurança

  • Nunca commite o BOT_TOKEN em git público
  • Use variáveis de ambiente
  • Bot com permissões mínimas (Send Messages só)
  • Restrinja canais que aceitam comandos admin

Perguntas frequentes

"Meu servidor está atrás de proxy/tunnel, mcstatus funciona?"
Sim, aponte pro endereço público. Latência será a do tunnel.

"E se o bot cair?"
systemd Restart=always reinicia automaticamente. Ou use Docker + --restart unless-stopped.

"Consigo mostrar TPS do servidor no bot?"
TPS não vem via mcstatus (protocolo padrão). Você precisa de plugin custom + endpoint HTTP OU DiscordSRV que já expõe.

"Bot consome muita RAM?"
Não. Python + mcstatus rodam com < 50 MB.

Conclusão

Se você só quer status + chat bridge: use DiscordSRV. Zero código.

Se quer customização total (comandos custom, integração de loja, alertas específicos): faça bot Python.

Nossos VPS-BR rodam bot Discord + servidor MC juntos sem problema (memória sobra).

Links

Compartilhar:

Pronto para hospedar seu próximo projeto?

VPS com painel pré-instalado em 1 clique. Ativação imediata.

Ver planos VPS
⏰ 20% OFF em VPS-BR --:--:-- Ver oferta →