Caso de uso
Um filtro de chat com IA para servidores de Minecraft
Os filtros de chat com listas de palavras bloqueiam palavras inocentes e deixam passar insultos sem palavrões. A VigiMod lê o sentido de cada mensagem, em 26 idiomas, e verifica as regras do seu servidor, como «Sem publicidade a outros servidores».
O que torna difícil
As listas de palavras falham nos dois sentidos
Bloqueiam palavras inocentes que contêm um palavrão e deixam passar «aqui ninguém te quer». Um modelo pontua o sentido, não palavras soltas.
Jogadores de todas as idades
Muitos jogadores são jovens. A categoria opcional child_safety (beta) assinala tentativas de aliciar um menor, como alerta para a staff.
Anúncios de servidores e vendas
Fazer publicidade a outros servidores ou vender contas é uma regra, não um palavrão. Escreva-a como regra e a VigiMod pontua-a.
Como funciona com a VigiMod
- 1
Um plugin escuta o chat (AsyncChatEvent no Paper), que corre fora da thread principal.
- 2
Envia à VigiMod a mensagem, o UUID do jogador e as suas regras, com um timeout curto.
- 3
Se for assinalada, cancela a mensagem e avisa o jogador; várias marcações podem ativar o seu comando de mute ou aviso.
Regras para copiar
Envie-as no campo rules: cada uma volta com a sua própria pontuação, como uma categoria integrada.
{
"rules": {
"no-server-ads": "Sem publicidade a outros servidores de Minecraft ou de Discord",
"no-selling": "Sem vender contas, itens ou ranks por dinheiro real",
"no-personal-info": "Não perguntar aos jogadores a idade, a morada ou o telefone",
"portuguese-only": "No chat global, só português"
}
}Exemplo
Um listener para um plugin Paper em Java: o evento do chat é assíncrono, por isso a chamada HTTP não abranda o tick do servidor.
Java (Paper plugin)
// A listener for a Paper plugin: register it in onEnable() with
// getServer().getPluginManager().registerEvents(new ChatFilter(), this);
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.papermc.paper.event.player.AsyncChatEvent;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public final class ChatFilter implements Listener {
private final HttpClient http = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(2)).build();
private final String key = System.getenv("VIGIMOD_KEY");
// AsyncChatEvent runs off the main thread: waiting for the answer does not slow the server
@EventHandler(ignoreCancelled = true)
public void onChat(AsyncChatEvent event) {
JsonObject rules = new JsonObject();
rules.addProperty("no-server-ads", "No advertising other Minecraft servers or Discord servers");
JsonObject body = new JsonObject();
body.addProperty("text", PlainTextComponentSerializer.plainText().serialize(event.message()));
body.addProperty("user_id", event.getPlayer().getUniqueId().toString());
body.addProperty("scope", "my-server");
body.add("rules", rules);
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.vigimod.com/moderate"))
.timeout(Duration.ofSeconds(2))
.header("X-API-Key", key)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body.toString()))
.build();
try {
HttpResponse<String> response = http.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) return;
JsonObject result = JsonParser.parseString(response.body()).getAsJsonObject();
if (result.get("flagged").getAsBoolean()) {
event.setCancelled(true);
event.getPlayer().sendMessage(Component.text("Your message was not sent: it breaks the server rules."));
}
} catch (Exception e) {
// slow or down: let the message through
}
}
}Dicas
- Use um timeout curto (cerca de dois segundos) e deixe passar a mensagem se a verificação falhar, para o chat nunca congelar.
- Adicione child_safety às categorias em servidores com jogadores jovens e envie essas marcações à staff em vez de agir sozinho.
- Envie o UUID do jogador como user_id: a mesma mensagem repetida sem parar aumenta a pontuação de spam.
Perguntas
- Funciona em Spigot, Paper e Velocity?
- O exemplo usa o AsyncChatEvent do Paper. O Spigot tem AsyncPlayerChatEvent e os proxies como o Velocity têm os seus próprios eventos de chat; a chamada HTTP à VigiMod é igual em todos.
- Vai causar lag no servidor?
- Não, se a chamar a partir do evento assíncrono do chat como no exemplo: a thread principal nunca fica bloqueada.
- Apanha truques de escrita como o l33t speak?
- Muitas vezes, porque o modelo lê frases inteiras, mas nem sempre. Para os piores casos, acrescente as suas palavras bloqueadas no plugin que já usa.
- Quantas mensagens consegue verificar?
- A beta gratuita permite 120 mensagens por minuto por chave API. Redes maiores podem pedir ao suporte um limite mais alto.
Continue a aprender
Todos os guias- Básico · 6 min de leituraO que é um classificador de texto e como decide?Um classificador de texto lê uma frase e devolve uma probabilidade para cada categoria. Como é construído, o que significa a pontuação e onde erra.
- Intermédio · 6 min de leituraComo escolher o limiar de moderaçãoUma pontuação de 0,7 não é uma decisão. Como funcionam os limiares, porque o valor predefinido é só um ponto de partida e como afiná-los.
- Intermédio · 6 min de leituraO enviesamento nos modelos de moderação: porque são assinaladas mensagens inocentes com nomes estrangeirosUm modelo pode assinalar «O Mohammed perdeu o comboio» como ódio. De onde vem este enviesamento, como medi-lo e como corrigi-lo.
Experimente na sua comunidade
Crie uma chave API gratuita em dois minutos. Sem cartão, sem período de teste.