feat: Bedrock support — typed commands and ASCII labels

Geyser cannot deliver a chat clickEvent to Bedrock, and most emoji render
as tofu boxes there, so Bedrock players could see the reaction row but
neither read nor use it.

Messages carrying buttons are now built twice and sent per player rather
than via Bukkit.broadcast. Each reaction gains a per-platform label plus a
typed shortcut:

    uau: { java: "[😮]", texto: "[UAU]", comando: "wow" }

Typed fallbacks for every clickable interaction: /reagir, /legal, /wow,
/top, /f, /palpite and /votar, all acting on the most recent message so no
message id is needed.

Bedrock detection uses Floodgate's UUID scheme (high 64 bits zero) rather
than the Floodgate API, keeping it an optional runtime dependency.
/canalhandia plataformas lists who is online and on which platform.

Reaction config moves from a flat key->label map to a section per
reaction; the old flat form is still accepted and gets an ASCII fallback
derived from the key.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ActvLGJApdxEAd2yfKPwqv
This commit is contained in:
marcos
2026-08-04 21:31:24 +00:00
parent 18ac5a5d17
commit 987ee13d74
11 changed files with 431 additions and 72 deletions
+30 -1
View File
@@ -66,7 +66,36 @@ counting for `reacao-validade-minutos` (default 15) even after the boss bar is
gone, and the last 8 reaction sets stay in memory for that reason. Silently
dropping a late click looks like a bug to the player.
### 3. Names are translated by the client, not by us
### 3. Bedrock cannot click, and cannot show emoji
Geyser cannot deliver a chat `clickEvent` to a Bedrock client, and most emoji
render as tofu boxes there. So every clickable interaction has a typed
equivalent, and every reaction carries two labels:
```yaml
reacoes:
uau:
java: "[😮]" # Java clients
texto: "[UAU]" # Bedrock clients — ASCII only
comando: "wow" # what a Bedrock player types
```
Messages with buttons are therefore built twice and sent per player
(`broadcastPerPlatform`), not via `Bukkit.broadcast`. Typed fallbacks:
`/reagir <chave>`, `/legal`, `/wow`, `/top`, `/f`, `/palpite <nome>`,
`/votar <número>` — all of which act on the most recent message, so the player
never needs a message id.
Changing a `comando` to a new name also requires adding that command to
`plugin.yml` and restarting; Bukkit commands are static.
**Detecting Bedrock**: Floodgate mints UUIDs whose high 64 bits are zero
(`00000000-0000-0000-0009-…`), so `Platform.isBedrock` checks
`getUniqueId().getMostSignificantBits() == 0`. That keeps Floodgate an optional
runtime dependency rather than a compile-time one. `/canalhandia plataformas`
lists who is online and on which platform.
### 4. Names are translated by the client, not by us
Block, item and mob names are emitted as **translatable components**
(`Component.translatable(material.translationKey())`), so a pt-BR client renders