feat(chunkloader): add native chunk loader module with LuckPerms limits and BlueMap support

This commit is contained in:
Marcos Paulo
2026-08-18 21:45:51 -03:00
parent 01e6c28fef
commit 01ada6d987
14 changed files with 1212 additions and 17 deletions
+37
View File
@@ -0,0 +1,37 @@
# Plan: Módulo Nativo de Chunk Loader
## Arquitetura
1. **`ChunkLoader.java` (Record puro)**
- `id`, `ownerUuid`, `ownerName`, `world`, `x`, `y`, `z`, `chunkX`, `chunkZ`, `createdAt`.
- Métodos utilitários: `chunkCoords()`, `blockCoords()`, etc.
2. **`ChunkLoaders.java` (Gerenciador e Persistência)**
- Gerencia lista em memória sincronizada `List<ChunkLoader>`.
- Persistência em `plugins/Canalhandia/chunks.yml` com salvamento assíncrono.
- Métodos: `add()`, `remove()`, `byChunk()`, `byOwner()`, `loadAll()`, `unloadAll()`, `playerLimit(Player)`.
- Executa `world.addPluginChunkTicket` e `world.removePluginChunkTicket`.
3. **`Module.java` & `Settings.java`**
- Adiciona `CHUNKLOADER("chunkloader", "Âncoras de carregamento contínuo de chunks")` no enum `Module`.
- Adiciona configurações em `Settings.java` (limite padrão, material do bloco, raio de partículas).
4. **`ChunkLoaderListener.java` (Eventos do Mundo)**
- `BlockPlaceEvent`: Detecta colocação da Âncora, verifica permissões/limites LuckPerms, registra loader e ticket.
- `BlockBreakEvent`: Protege quebra por não-donos, remove ticket e devolve o item customizado.
- `BlockExplodeEvent` / `EntityExplodeEvent`: Impede destruição por explosão.
- `BlockPistonExtendEvent` / `BlockPistonRetractEvent`: Impede movimentação por pistão.
5. **`CanalhandiaCommand.java` & `ChunkLoaderCommand.java`**
- Subcomandos de `/chunkloader` / `/ancora` e tab-completion completo.
6. **`BlueMapBridge.java`**
- Cria conjunto de marcadores para chunk loaders no mapa web.
7. **Testes Unitários (`ChunkLoaderTest.java`)**
- Validação de regras de permissão, cálculo de limite, serialização em YAML e exclusão de duplicatas na mesma chunk.
## Riscos & Mitigações
- **Risco:** Descarregamento incorreto no shutdown do servidor gerando tickets órfãos.
- **Mitigação:** `unloadAll()` limpo em `onDisable()`, e tickets do Paper (`PluginChunkTicket`) são re-validados no `onEnable()`.
- **Risco:** Jogador contornar limite colocando em mundos não permitidos ou múltiplas na mesma chunk.
- **Mitigação:** Validação estrita de unicidade de chunk (`byChunk(world, cx, cz) != null`) e verificação de limite antes de aceitar o evento.
+72
View File
@@ -0,0 +1,72 @@
# Spec: Módulo Nativo de Chunk Loader (Canalhandia)
## 1. Visão Geral
Adiciona ao plugin `Canalhandia` um módulo nativo, performático e equilibrado de **Chunk Loading** para o Paper 1.21.x.
Permite que jogadores mantenham áreas/chunks específicas carregadas para farms, redstone e sistemas automatizados usando a API nativa de tickets do Paper (`addPluginChunkTicket`), com permissões granulares e limites por cargo configuráveis via **LuckPerms**.
---
## 2. Requisitos e Mecânicas
### 2.1. Bloco e Item Customizado: "Âncora de Chunk" (Chunk Anchor)
- **Item Base:** `RESPAWN_ANCHOR` ou `LODESTONE` com nome formatado (`§b§lÂncora de Chunk`), lore explicativa e `PersistentDataContainer` identificando o item customizado.
- **Receita de Crafting:**
- Configurada em `config.yml` (ex: 4 Obsidianas Choronas, 4 Diamantes, 1 Estrela do Nether ou Olho do Fim).
- Desbloqueia automaticamente no livro de receitas ao obter os ingredientes.
### 2.2. Colocação e Restrições
- Ao colocar o bloco (`BlockPlaceEvent`):
- Verifica se o jogador possui permissão `canalhandia.chunkloader`.
- Verifica o limite de loaders do jogador no LuckPerms:
- Lê permissões numéricas: `canalhandia.chunkloader.limite.<N>` (ex: `limite.1`, `limite.2`, `limite.5`, `limite.10`).
- Pega o maior `<N>` encontrado nas permissões do jogador.
- Se não houver permissão numérica explícita, usa `chunkloader.limite-padrao` do `config.yml` (padrão: 1).
- Administradores com `canalhandia.admin` não têm limite.
- Verifica se já existe um loader ativo na mesma chunk (máximo 1 por chunk).
- Se aprovado:
- Ativa o ticket na chunk: `world.addPluginChunkTicket(chunkX, chunkZ, plugin)`.
- Salva em `chunks.yml`.
- Cria partícula/efeito sonoro de ativação.
- Registra marcador no BlueMap (opcional/configurável).
- Envia mensagem de confirmação informando quantas âncoras o jogador está usando (ex: `1/3 ativas`).
### 2.3. Remoção e Proteção
- **Proteção:** Apenas o dono da âncora ou administradores (`canalhandia.admin`) podem quebrar o bloco (`BlockBreakEvent`).
- **Explosões / Pistões:** Protegido contra destruição acidental por TNT/Creeper (`EntityExplodeEvent`, `BlockExplodeEvent`) e empurrão por pistão (`BlockPistonExtendEvent`).
- Ao quebrar:
- Remove o ticket de chunk do Paper: `world.removePluginChunkTicket(chunkX, chunkZ, plugin)`.
- Remove de `chunks.yml` e do BlueMap.
- Devolve o item "Âncora de Chunk" ao jogador.
### 2.4. Persistência e Ciclo de Vida
- Arquivo `plugins/Canalhandia/chunks.yml`:
- Armazena ID, UUID do dono, nome, mundo, coordenadas (x, y, z), chunk (cx, cz) e data de criação.
- **No `onEnable()` do plugin:** Carrega `chunks.yml` e registra `addPluginChunkTicket` em todas as chunks salvas.
- **No `onDisable()` do plugin:** Remove os tickets do plugin de forma limpa.
### 2.5. Comandos (`/chunkloader` ou `/ancora`)
- `/chunkloader` ou `/ancora`:
- `/chunkloader info` — Mostra o status da chunk atual (se está carregada por um loader e por quem) e seus limites de uso.
- `/chunkloader listar` — Lista todas as âncoras ativas do jogador com coordenadas e link para deletar/desativar.
- `/chunkloader remover <id>` — Desativa remotamente uma âncora do próprio jogador.
- `/chunkloader receita` — Mostra a receita de crafting.
- `/chunkloader admin listar [jogador]` — (Admin) Lista todos os chunk loaders do servidor.
- `/chunkloader admin remover <id>` — (Admin) Força a remoção de qualquer loader.
- `/chunkloader reload` — (Admin) Recarrega configurações e sincroniza tickets.
---
## 3. Integração com LuckPerms
Nós de permissão:
- `canalhandia.chunkloader` — Habilita o jogador a craftar, colocar e gerenciar âncoras.
- `canalhandia.chunkloader.limite.<N>` — Define o limite máximo de âncoras ativas para o cargo (ex: `canalhandia.chunkloader.limite.3` para VIP).
- `canalhandia.chunkloader.admin` — Acesso total aos comandos administrativos de chunk loading.
---
## 4. Critérios de Aceite
1. Módulo pode ser ativado/desativado via `config.yml` e `/canalhandia modulo chunkloader`.
2. Bloco colocado registra ticket via `world.addPluginChunkTicket` que sobrevive a reboots via `chunks.yml`.
3. Limites de permissão do LuckPerms são respeitados estritamente.
4. Blocos não podem ser roubados ou quebrados por terceiros.
5. Suíte de testes unitários (`ChunkLoaderTest.java`) com 100% de aprovação.
+28
View File
@@ -0,0 +1,28 @@
# Tasks: Módulo Nativo de Chunk Loader
- [x] **Task 1: Modelo de Dados e Gerenciador (`ChunkLoader.java`, `ChunkLoaders.java` e `ChunkLoaderTest.java`)**
- Implementar record `ChunkLoader` puro.
- Implementar `ChunkLoaders` com persistência em `chunks.yml`, `playerLimit(Player)` (LuckPerms `canalhandia.chunkloader.limite.<N>`), registro de tickets no Paper e busca por chunk/dono.
- Criar suíte de testes unitários `ChunkLoaderTest.java` validando regras de limites, unicidade e serialização.
- [x] **Task 2: Configuração e Item Customizado (`Module.java`, `Settings.java` e `ChunkAnchorItem.java`)**
- Adicionar `CHUNKLOADER` ao enum `Module`.
- Adicionar chaves de configuração em `config.yml` e `Settings.java`.
- Criar utilitário `ChunkAnchorItem` para gerar o ItemStack com nome, lore e `PersistentDataContainer`, e registrar receita de crafting.
- [x] **Task 3: Listeners de Proteção e Colocação (`ChunkLoaderListener.java`)**
- Tratar `BlockPlaceEvent` (validação de permissão, cálculo de limite LuckPerms, ativação de ticket).
- Tratar `BlockBreakEvent` (proteção de dono/admin, remoção de ticket, drop do item).
- Tratar explosões e pistões.
- [x] **Task 4: Comandos e Tab-Completion (`CanalhandiaCommand.java`)**
- Adicionar `/chunkloader` e alias `/ancora` (`listar`, `info`, `remover`, `receita`, `admin`).
- Implementar tab-completion completo com permissões.
- [x] **Task 5: Integração no Ciclo de Vida e BlueMap (`Canalhandia.java` & `BlueMapBridge.java`)**
- Inicializar `ChunkLoaders` no `onEnable` e descarregar tickets no `onDisable`.
- Adicionar marcadores no BlueMap.
- [x] **Task 6: Testes, PR e Deploy (`mvn test`, `mvn package`, PR no Gitea)**
- Executar suíte completa de testes.
- Criar branch `feat/chunk-loader-module`, abrir PR com labels `AI-REVIEW` e `AI-USAGE`.