ChestCommands é um sistema de menus configuráveis (estilo "Chest Commands") projetado para Hytale. O projeto é dividido em core (engine‑agnóstico), API e adapter Hytale para abrir UIs reais no servidor. O objetivo é permitir criar menus via YAML/JSON sem editar código de outros plugins — inclusive integrouor com plugins de economia sem precisar alterar seus fontes.
Este README explica:
- visão geral da arquitetura
- como instalar/compilar
- como criar menus por
config.ymlemenus/*.yml - exemplos de placeholders e actions
- integração com plugins de economia (sem alterar o source deles)
- como funciona o CI (GitHub Actions) e como obter o JAR gerado
- troubleshooting rápido
- Arquitetura
- Instalação e build
- Configuração de menus (exemplos)
- Placeholders e actions suportadas
- Integração com plugins externos (economy)
- Adapter Hytale: como ligar ao servidor
- GitHub Actions e artefatos / releases
- Troubleshooting
O projeto é dividido conceitualmente em camadas:
api— interfaces públicas (ex.:ChestCommandsAPI,CommandDispatcher).core— lógica agnóstica de engine: parsing de menus, modelos, registries de ações/condições.hytale— adapter Hytale (integração com a API do servidor). Aqui vivem oHytaleMenuRenderer, o dispatcher reflexivo e oChestCommandsPluginque orquestra a inicialização.
Princípios importantes
- O core não conhece Hytale — o adapter faz a ponte.
- Integração com outros plugins é feita por duas estratégias:
ServiceLoader(interfaceEconomyService) — recomendado se o outro plugin puder expor um provider.CommandDispatcherreflexivo — chama comandos do servidor (ex.:/wallet) sem alterar o outro plugin.
Requisitos:
- Java 17
- Maven 3.6+
Passos:
- Certifique-se de ter uma cópia de
libs/HytaleServer.jardentro do diretóriolibs/(se necessário pelo build). O POM já referencialibs/HytaleServer.jarcomo dependência system-scope. - Na raiz do projeto execute:
cd "D:\Programação\ChestCommands"
mvn -B -DskipTests package- O JAR será gerado em
target/. Se usar o GitHub Actions, o workflow está configurado para instalarlibs/HytaleServer.jarno runner, compilar e subir o JAR como artefato e também criar uma release pré-lançamento e anexar o JAR.
O projeto suporta menus configurados em config.yml (o loader do PluginMenuConfig procura o arquivo na pasta de dados do plugin). Exemplo mínimo:
ChestCommands:
rows: 5
tables: 10
menus:
wallet:
command: /wallet
title: "Carteira de {player}"
rows: 5
items:
"13":
material: CHEST
name: "§aSaldo: {balance}"
lore:
- "§7Banco: {bank}"
- "§7Última: {last_transaction}"
action: command:wallet info {player}
"22":
material: EMERALD
name: "§eFazer transação"
lore:
- "Clique para iniciar"
action: command:wallet send {player} <target> <amount>Explicação:
menusé um mapa de menus nomeados. Cada menu temcommand,title,rowseitems.itemsusa a chave do slot (ex.: "13") e definematerial,name,loreeaction.actioné uma string interpretada peloActionExecutor/ConfigMenuAction. Prefixos comuns:command:,service:,wallet:send(custom).
Placeholders suportados (exemplos)
{player}— nome do jogador{balance}— saldo (seEconomyServicepresente){bank}— saldo em banco (seEconomyServicepresente){last_transaction}— última transação (seEconomyServicepresente)
Actions (comportamento padrão)
- command: — o adapter executará o comando usando
CommandDispatchercomo jogador ou console; útil para chamar comandos expostos por outros plugins (ex.:/wallet info {player}). - service:#method — experimental: o
ActionExecutorpode usar ServiceLoader/reflection para invocar serviços registrados. - wallet:send — exemplo de ação custom que seu adapter pode mapear para abrir prompts e chamar a
EconomyService.transfer.
Dois caminhos:
-
Sem tocar o plugin de economia (recomendado para seu caso):
- Use
action: command:...no menu para executar o comando público do plugin de economia (por exemplo/wallet info <player>). - O
CommandDispatcher(implementado reflexivamente emReflectiveCommandDispatcher) tentará executar o comando no servidor sem modificar o plugin de economia. - Exemplo:
action: command:/wallet info {player}no item do menu.
- Use
-
Integração mais robusta (opcional, requer pequena alteração no plugin de economia):
- Implementar a interface
org.konpekiestudios.chestcommands.hooks.EconomyServiceno plugin de economia e registrar como provider do JavaServiceLoader(arquivoMETA-INF/services/org.konpekiestudios.chestcommands.hooks.EconomyServicecontendo a FQN da implementação). - O ChestCommands carregará automaticamente a implementação via ServiceLoader e preencherá placeholders
{balance},{bank},{last_transaction}.
- Implementar a interface
O projeto inclui um adapter reflexivo para Hytale (ReflectiveCommandDispatcher, PlayerReflector) que:
- executa comandos no servidor por reflexão (evitando necessidade de alterar outros plugins);
- envia mensagens ao jogador via métodos reflexivos quando a UI não puder ser construída (fallback textual).
Para integrar ao servidor Hytale real, no onEnable do seu módulo adapter faça algo como:
// PSEUDO
CommandDispatcher dispatcher = new ReflectiveCommandDispatcher();
ChestCommandsPlugin cc = new ChestCommandsPlugin();
cc.onEnable(dataFolder, (cmdName, playerConsumer) -> {
// registra o comando no servidor; quando executado, chame playerConsumer.accept(hytalePlayerObject)
server.registerCommand(cmdName, hplayer -> playerConsumer.accept(hplayer));
}, dispatcher);O adapter pode também implementar HytaleMenuRenderer.open(EntityStore player, Menu menu) usando as APIs do JAR do servidor para abrir uma janela gráfica real.
O workflow .github/workflows/build.yml do repositório agora:
- instala
libs/HytaleServer.jarno repositório Maven local do runner (se existir emlibs/); - executa
mvn -B -DskipTests package; - cria uma Release (pré-release) com a tag fornecida via
workflow_dispatch(ou gera uma tagpre-release-<run_id>); - localiza o JAR em
target/e anexa o arquivo ao release com o nomeChestCommands-<tag>.jar; - faz upload também do artefato para acesso via Actions UI.
Como disparar uma release com tag customizada:
- Vá em Actions → selecione workflow → Run workflow → no campo
release_taginformev1.0.0-preou o nome desejado.
- Erro de compilação por Hytale API: confirme
libs/HytaleServer.jarestá presente ou que o POM aponta corretamente. O workflow instala esse JAR no runner, mas localmente você precisa tê-lo emlibs/. - Release step 403: se o passo criar release falhar com 403, verifique as permissões do GITHUB_TOKEN (em repositórios organizacionais pode haver restrições). Alternativa: configure um PAT com
reposcope e atualize o workflow para usar o secret. - Asset não encontrado (ENOENT): o workflow agora busca o primeiro
target/*.jare usa esse caminho; se o JAR tiver nome inesperado, verifique output dotarget/no log de build.
- Para ações customizadas (por exemplo,
wallet:send), implemente umActionHandlerno adapter que saiba tratarwallet:send(abrir prompt, coletar destino e valor, e chamarEconomyService.transfer(...)via ServiceLoader ou enviar/dispatch de comando). - Para condições (por exemplo
permission), registre condicionalmente no startup comConditionRegistry.register("permission", ctx -> new HasPermissionCondition(ctx.getValue()));.
- Abra um PR para features ou correções. O CI valida build e upload do JAR.
- Se você desenvolver um adapter específico (Hytale), mantenha o core engine-agnóstico e registre a lógica de UI no adapter.
- Config loader:
org.konpekiestudios.chestcommands.config.PluginMenuConfig - Adapter:
org.konpekiestudios.chestcommands.hytale(ReflectiveCommandDispatcher, HytaleMenuRenderer) - API:
org.konpekiestudios.chestcommands.hooks.EconomyService,org.konpekiestudios.chestcommands.api.CommandDispatcher
Escolha e adicione aqui a licença que preferir (MIT, Apache-2.0 etc.).
Se quiser, eu posso:
- gerar exemplos adicionais de
menus/*.ymlcom mais tipos de ações (abrir submenus, dar item, executar comando remoto), - implementar
HytaleMenuRenderer.open(...)usando classes reais do JAR (se quiser que eu incorpore a UI real ao adapter), ou - criar um pequeno guia em vídeo (passos textuais) para ligar o
ChestCommandsPluginao seu servidor Hytale local e testar/walletcom o plugin de economia.
Diga qual desses extras você quer que eu faça a seguir.