# Aplicação de moderação personalizada

Normalmente, o Verité aplica silenciamentos, modo lento e congelamentos de chat automaticamente. No entanto, alguns plugins de chat intercetam o evento de chat normal do Minecraft e tratam do envio das mensagens por conta própria.

Se o seu plugin fizer isso, o Verité poderá nunca ver a mensagem, por isso as suas próprias verificações de silenciamento e modo lento nunca correm. Nesse caso, deverá perguntar ao Verité sobre o remetente antes de o seu plugin enviar a mensagem, e parar a mensagem por conta própria quando o Verité o indicar.

> **Só precisa deste guia se o seu plugin tratar ou substituir o chat normal do Minecraft.** Os servidores que utilizam o chat padrão não precisam de qualquer configuração adicional.

Esta é a contraparte de moderação do guia [Integração de chat personalizado](page:developers/wiring). O guia do filtro verifica o conteúdo das mensagens; este guia aplica silenciamentos, modo lento e congelamentos de chat.

## Integração com Java

A superfície de moderação reside em `teacommontea.api.VeriteModeration`. Cada método devolve um valor seguro quando o módulo de moderação está desativado, por isso quem o chama nunca tem de tratar esse caso especialmente.

### 1. Adicione o Verité como dependência opcional

Adicione o Verité ao seu `plugin.yml`:

```yaml
softdepend:
  - Verite
```

A utilização de uma dependência opcional garante que o Verité é carregado antes da sua integração quando estiver instalado, sem o tornar obrigatório para que o seu plugin possa iniciar.

### 2. Verifique se a API está disponível

Se o Verité for opcional, verifique se a API está disponível antes de a utilizar:

```java
private static final boolean VERITE_AVAILABLE;

static {
    boolean available;

    try {
        Class.forName("teacommontea.api.VeriteModeration");
        available = true;
    } catch (ClassNotFoundException ignored) {
        available = false;
    }

    VERITE_AVAILABLE = available;
}
```

Desta forma, a sua integração pode simplesmente não fazer nada quando o Verité não estiver instalado.

### 3. Aplique silenciamentos

Antes de o seu sistema de chat personalizado enviar uma mensagem, pergunte ao Verité se o remetente está silenciado:

```java
if (VERITE_AVAILABLE) {
    if (VeriteModeration.muteGate(player)) {
        return;
    }
}
```

`muteGate` devolve `true` quando o jogador está silenciado e, ao fazê-lo, envia-lhe o aviso de silenciamento por si. Quando devolve `true`, pare a mensagem.

Se preferir construir o aviso por conta própria, leia antes o silenciamento ativo:

```java
if (VeriteModeration.isMuted(player.getUniqueId())) {
    Punishment mute = VeriteModeration.activeMute(player.getUniqueId());

    String line = mute.permanent()
        ? "You are muted."
        : "You are muted for " + mute.remaining(System.currentTimeMillis()) + " more milliseconds.";

    player.sendMessage(line);
    return;
}
```

`isMuted` é uma verificação pura e não envia nada. `activeMute` devolve o silenciamento como um `Punishment`, a partir do qual pode ler `reason()`, `permanent()` e `remaining(now)`.

### 4. Aplique o modo lento e o congelamento de chat

O Verité tem dois travões de chat de âmbito servidor: um congelamento global de chat definido pelo pessoal e um modo lento por jogador. Aplique ambos da mesma forma que aplica os silenciamentos:

```java
if (VeriteModeration.chatMuteGate(player)) {
    return;
}

if (VeriteModeration.slowmodeGate(player)) {
    return;
}
```

Cada um devolve `true` quando o jogador deve ser parado e envia-lhe o motivo (o aviso de chat congelado ou a espera restante do modo lento) ao fazê-lo. Verifique ambos antes de enviar.

### Juntando tudo

Um manipulador de chat completo que reproduz a aplicação do Verité tem este aspeto:

```java
if (VERITE_AVAILABLE) {
    if (VeriteModeration.muteGate(player)) {
        return;
    }

    if (VeriteModeration.chatMuteGate(player)) {
        return;
    }

    if (VeriteModeration.slowmodeGate(player)) {
        return;
    }
}

sendMessage(player, message);
```

## Reagir a castigos

Se o seu plugin precisar de saber quando um castigo é emitido ou levantado (para registo, notificações ou sincronização de outro sistema), registe um ouvinte:

```java
VeriteModeration.registerListener(new ModerationListener() {
    @Override
    public void entryAdded(Punishment punishment) {
    }

    @Override
    public void entryRemoved(Punishment punishment) {
    }
});
```

`entryAdded` dispara quando um castigo é emitido, `entryRemoved` quando um é levantado. Cada `Punishment` carrega o alvo, o tipo, o motivo, a duração, o executor e se foi silencioso. Chame `unregisterListener` com o mesmo ouvinte para deixar de receber eventos.

## Bloqueio do servidor

O Verité pode selar o servidor por trás de um bloqueio. O seu plugin pode ler o estado de bloqueio ou controlá-lo através de `teacommontea.api.VeriteLockdown`:

```java
if (VeriteLockdown.active()) {
    String reason = VeriteLockdown.reason();
}

VeriteLockdown.begin("Maintenance");
VeriteLockdown.end();
```

`active()` reporta se um bloqueio está em vigor, `reason()` devolve o motivo atual, `begin(reason)` inicia um e `end()` limpa-o. Use `active()` para condicionar o seu próprio comportamento durante um bloqueio, ou `begin` e `end` para controlar o bloqueio a partir dos seus próprios comandos.

---

# Utilizar o Verité com Skript

Se o seu sistema de chat personalizado estiver escrito em Skript, não precisa de interagir com a API Java.

Com **Verité e Skript instalados**, a sintaxe de moderação do Verité fica automaticamente disponível.

## Aplicar silenciamentos, modo lento e congelamento

Se o seu script já tratar do envio das mensagens de chat, verifique o remetente antes de enviar. Use estas dentro do seu evento de chat:

```vb
if chat is frozen for player:
    stop

if player is on slowmode:
    stop
```

`chat is frozen` reporta o congelamento global do chat, e `player is on slowmode` reporta o tempo de espera do modo lento por jogador. Ambos enviam ao jogador o motivo como efeito secundário, por isso use-os onde pretende aplicar, não meramente para ler o estado.

Para verificar o silenciamento pessoal de um jogador:

```vb
if player is muted:
    stop
```

`player is muted` lê o estado de silenciamento ativo sem enviar nada, por isso combine-o com o seu próprio aviso.

## Controlar o bloqueio

Pode iniciar ou levantar um bloqueio de servidor a partir de um script:

```vb
begin message lockdown with reason "Maintenance"

end message lockdown
```

O motivo é opcional; omiti-lo utiliza um rótulo genérico.

## Referência da sintaxe do Skript

```vb
player is muted
player is not muted

chat is frozen [for %-player%]
player is rate limited
player is on slowmode

begin message lockdown [(with reason|for) %-string%]
end message lockdown
```

`chat is frozen`, `is rate limited` e `is on slowmode` enviam ao jogador um aviso quando correspondem, por isso use-os num manipulador de chat onde pretende parar a mensagem.

---

## Referência da API

A API pública encontra-se em:

```text
teacommontea.api
```

As classes principais para a aplicação de moderação são:

```java
VeriteModeration
VeriteLockdown
```

Os métodos úteis incluem:

```java
VeriteModeration.muteGate(Player player)
VeriteModeration.chatMuteGate(Player player)
VeriteModeration.slowmodeGate(Player player)

VeriteModeration.isMuted(UUID player)
VeriteModeration.activeMute(UUID player)

VeriteModeration.registerListener(ModerationListener listener)
VeriteModeration.unregisterListener(ModerationListener listener)

VeriteLockdown.active()
VeriteLockdown.reason()
VeriteLockdown.begin(String reason)
VeriteLockdown.end()
```

Os métodos de porta (`muteGate`, `chatMuteGate`, `slowmodeGate`) tanto decidem se devem parar o jogador como lhe enviam o motivo. Os métodos de consulta (`isMuted`, `activeMute`) apenas leem o estado e não enviam nada.

Para a maioria das integrações de chat personalizado, aplicar as três portas por ordem é tudo o que precisa:

```java
if (VeriteModeration.muteGate(player)
        || VeriteModeration.chatMuteGate(player)
        || VeriteModeration.slowmodeGate(player)) {
    return;
}
```

O Verité trata do resto.
