Files

359 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🖼️ betterMcGuis
[![Java](https://img.shields.io/badge/Java-17%2B%20%2F%2021-orange.svg)](https://www.oracle.com/java/)
[![Paper](https://img.shields.io/badge/Paper-1.20.4%2B-blue.svg)](https://papermc.io/)
[![Kyori Adventure](https://img.shields.io/badge/Adventure-MiniMessage-purple.svg)](https://docs.advntr.dev/)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](#)
Une bibliothèque Java moderne, fluide et événementielle permettant de créer, animer et gérer des interfaces graphiques (GUIs / Menus interactifs / Inventaires) sur serveurs Minecraft Paper et Spigot (1.20.4+).
---
## 📑 Sommaire
- [📚 Guides Détaillés (Dossier `/docs`)](#-guides-détaillés-dossier-docs)
- [🌟 Fonctionnalités](#-fonctionnalités)
- [🏗️ Architecture & Flux d'Interactions](#-architecture--flux-dinteractions)
- [📦 Installation & Configuration](#-installation--configuration)
- [🚀 Guide de Démarrage Rapide](#-guide-de-démarrage-rapide)
- [💡 Exemples de Menus](#-exemples-de-menus)
- [1. Menu Principal Standard (`GuiBuilder`)](#1-menu-principal-standard-guibuilder)
- [2. Menu Paginé Dynamique (`PaginatedGui`)](#2-menu-paginé-dynamique-paginatedgui)
- [3. Motifs ASCII & Grilles de Disposition (`GuiPattern`)](#3-motifs-ascii--grilles-de-disposition-guipattern)
- [4. Menus à Onglets sans Réouverture (`TabbedGui`)](#4-menus-à-onglets-sans-réouverture-tabbedgui)
- [5. Zones de Dépôt / Poubelle (`StorageGui`)](#5-zones-de-dépôt--poubelle-storagegui)
- [💎 Construction d'Items (`ItemBuilder`)](#-construction-ditems-itembuilder)
- [🎯 Système d'Événements & Écouteurs Annotés](#-système-dévénements--écouteurs-annotés)
- [📂 Organisation des Packages](#-organisation-des-packages)
---
## 📚 Guides Détaillés (Dossier `/docs`)
Pour une exploration approfondie de chaque composant, consultez la documentation modulaire :
* 📘 [**01. Guide de Démarrage Rapide**](docs/01_GETTING_STARTED.md) : Installation Gradle/Maven, initialisation dans `JavaPlugin` et cycle de vie.
* 🏗️ [**02. Fluent GUI Builder DSL**](docs/02_GUI_BUILDER_DSL.md) : Méthodes de placement de slots, dimensions, bordures, remplissages et propriétés dynamiques.
* 💎 [**03. ItemBuilder & GuiItem**](docs/03_ITEM_BUILDER_AND_ITEMS.md) : Formatage MiniMessage, têtes personnalisées, armures teintées, sons, cooldowns et `GuiClickContext`.
* 🎨 [**04. Motifs & Masques ASCII**](docs/04_PATTERNS_AND_MASKS.md) : Conception visuelle de grilles par matrices textuelles (`GuiPattern`, `GuiMask`).
* 📚 [**05. Menus Paginés, Onglets & Animations**](docs/05_PAGINATED_AND_ADVANCED_GUIS.md) : Pagination automatique, onglets commutables sans réouverture et frames animées.
* 🎯 [**06. Cycle de Vie & Événements**](docs/06_LIFECYCLE_AND_EVENTS.md) : Hooks locaux (`.onClick()`, `.onClose()`) et écouteurs globaux annotés `@GuiEventHandler`.
* 📦 [**07. Zones de Stockage & Slots Éditables**](docs/07_STORAGE_AND_EDITABLE_SLOTS.md) : Menus de dépôts, restitution d'items et sécurités anti-glitch.
---
## 🌟 Fonctionnalités
- **DSL Fluide & Déclaratif** : Construction rapide et lisible (`BetterMcGuis.builder("Titre", 3)`).
- **Formatage Moderne MiniMessage & Adventure** : Prise en charge native des gradients HEX, balises de style et composants texte.
- **Grilles & Motifs ASCII (`GuiPattern`)** : Dessinez vos interfaces directement en texte sous forme de matrice avec associations de caractères.
- **Pagination Intelligente (`PaginatedGui`)** : Calcul automatique des pages, boutons de navigation dynamiques et indicateurs de progression.
- **Onglets Commutables (`TabbedGui`)** : Basculez entre plusieurs vues de menu instantanément sans fermer la fenêtre du joueur.
- **Animations Cadencées (`AnimatedGui`)** : Lecture de séquences de frames temporelles (titres animés, coffres mystères, carrousels).
- **Protection Anti-Duplication & Sécurité** : Blocage natif et sécurisé des vols d'items, glisser-déposer illégaux, shift-clics et raccourcis de hotbar.
- **Moteur d'Événements Riches** : Bus d'événements global avec priorités et annotations `@GuiEventHandler`.
---
## 🏗️ Architecture & Flux d'Interactions
```mermaid
flowchart TD
Player["Joueur en Jeu"] -->|Effectue un Clic / Drag / Fermeture| BukkitEvt["BukkitGuiEventListener (Sécurité & Interception)"]
BukkitEvt --> HolderCheck{"Inventaire lié à BetterGuiHolder ?"}
HolderCheck -- Non --> Ignore["Ignore l'interaction"]
HolderCheck -- Oui --> SlotTypeCheck{"Localisation du Clic"}
SlotTypeCheck -- Extérieur (-999) --> OutsideHook["gui.handleOutsideClick() & GuiClickEvent"]
SlotTypeCheck -- Inventaire Joueur --> BottomCheck{"Shift-Clic ou Hotbar Swap vers slot protégé ?"}
BottomCheck -- Oui --> BlockShift["event.setCancelled(true) & Blocage"]
BottomCheck -- Non --> BottomHook["gui.handleBottomClick()"]
SlotTypeCheck -- Inventaire Supérieur (GUI) --> EditCheck{"Le Slot est-il Editable ?"}
EditCheck -- Non (Défaut) --> CancelDef["event.setCancelled(true) (Empêche le vol)"]
EditCheck -- Oui --> AllowEdit["event.setCancelled(false) (Autorise le dépôt)"]
CancelDef --> CoolCheck{"Cooldown Actif sur l'Item ?"}
AllowEdit --> CoolCheck
CoolCheck -- Oui --> CoolBlock["Interruption silencieuse"]
CoolCheck -- Non --> SoundTrigger["Déclenchement du Son configuré"]
SoundTrigger --> ItemAction["Exécution de l'Action Métier (item.handleClick)"]
ItemAction --> GuiHook["Exécution du Hook Local (gui.handleClick)"]
GuiHook --> EventBus["Diffusion sur le Bus Global (GuiClickEvent)"]
```
---
## 📦 Installation & Configuration
### Gradle (Kotlin DSL)
```kotlin
repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/")
}
dependencies {
implementation("fr.luc:betterMcGuis:1.0.0-SNAPSHOT")
}
```
---
## 🚀 Guide de Démarrage Rapide
### 1. Initialisation dans votre `JavaPlugin`
```java
package fr.luc.monplugin;
import fr.luc.bettermcguis.BetterMcGuis;
import org.bukkit.plugin.java.JavaPlugin;
public class MonPlugin extends JavaPlugin {
private BetterMcGuis guiManager;
@Override
public void onEnable() {
// Initialisation de betterMcGuis (enregistre automatiquement les écouteurs Bukkit)
this.guiManager = BetterMcGuis.create(this);
// Enregistrement d'écouteurs annotés globaux (optionnel)
this.guiManager.registerListeners(new MonEcouteurDeGui());
}
@Override
public void onDisable() {
// Nettoyage complet
if (guiManager != null) {
guiManager.unregisterAll();
}
}
}
```
---
## 💡 Exemples de Menus
### 1. Menu Principal Standard (`GuiBuilder`)
```java
BetterMcGuis.builder()
.title("<gradient:#ff5e62:#ff9966><bold>Menu Principal</bold></gradient>")
.rows(3)
.fillBorder(Material.BLACK_STAINED_GLASS_PANE)
// Bouton central interactif
.item(13, BetterMcGuis.item(Material.NETHER_STAR)
.name("<gold><bold>Récompense Quotidienne</bold></gold>")
.lore(
"<gray>Récupérez votre bonus de connexion !</gray>",
"",
"<yellow>▶ Cliquez pour réclamer</yellow>"
)
.glowing(true)
.asGuiItem(ctx -> {
ctx.playSound(Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.2f);
ctx.replySuccess("Bonus réclamé avec succès !");
ctx.close();
})
)
.build()
.open(player);
```
---
### 2. Menu Paginé Dynamique (`PaginatedGui`)
```java
var shop = BetterMcGuis.paginated()
.title("<gradient:#00c6ff:#0072ff><bold>Boutique du Serveur</bold></gradient>")
.rows(5)
.fillBorder(Material.GRAY_STAINED_GLASS_PANE);
// Ajout de 50 articles dans le catalogue paginé
for (int i = 1; i <= 50; i++) {
int id = i;
shop.addPageItem(BetterMcGuis.item(Material.DIAMOND)
.name("<aqua>Article #" + id + "</aqua>")
.lore("<gray>Prix : <gold>100 $</gold></gray>")
.asGuiItem(ctx -> {
ctx.replySuccess("Achat de l'article #" + id + " validé !");
})
);
}
shop.build().open(player);
```
---
### 3. Motifs ASCII & Grilles de Disposition (`GuiPattern`)
```java
BetterMcGuis.builder("Menu Quêtes", 5)
.pattern(p -> p
.lines(
"#########",
"# 1 2 3 #",
"# #",
"# C #",
"#########"
)
.bindFiller('#', Material.BLACK_STAINED_GLASS_PANE)
.bind('1', BetterMcGuis.item(Material.BOOK).name("<green>Quête Facile</green>").asGuiItem())
.bind('2', BetterMcGuis.item(Material.WRITABLE_BOOK).name("<yellow>Quête Moyenne</yellow>").asGuiItem())
.bind('3', BetterMcGuis.item(Material.ENCHANTED_BOOK).name("<red>Quête Difficile</red>").asGuiItem())
.bind('C', BetterMcGuis.item(Material.BARRIER).name("<red>Fermer</red>").asGuiItem(GuiClickContext::close))
)
.build()
.open(player);
```
---
### 4. Menus à Onglets sans Réouverture (`TabbedGui`)
```java
BetterMcGuis.tabbed("Menu Profil", 4)
// Onglet 1 : Statistiques
.tab("stats", 11, BetterMcGuis.item(Material.PAPER).name("<yellow>Statistiques</yellow>").asGuiItem(), tab -> {
tab.setTabItem("stats", 22, BetterMcGuis.item(Material.EXPERIENCE_BOTTLE).name("<green>Niveau 42</green>").asGuiItem());
})
// Onglet 2 : Récompenses
.tab("rewards", 15, BetterMcGuis.item(Material.CHEST).name("<gold>Récompenses</gold>").asGuiItem(), tab -> {
tab.setTabItem("rewards", 22, BetterMcGuis.item(Material.GOLD_INGOT).name("<gold>Bonus Débloqué</gold>").asGuiItem());
})
.build()
.open(player);
```
---
### 5. Zones de Dépôt / Poubelle (`StorageGui`)
```java
StorageGui trash = new StorageGui("<red><bold>Poubelle Publique</bold></red>", GuiType.CHEST_4_ROWS);
trash.fillBorder(Material.RED_STAINED_GLASS_PANE);
trash.setStorageSlots(SlotRange.interior(4, 9));
trash.returnItemsOnClose(false); // Détruit définitivement les objets déposés
trash.open(player);
```
---
## 💎 Construction d'Items (`ItemBuilder`)
```java
ItemStack item = BetterMcGuis.item(Material.DIAMOND_HELMET)
.name("<gradient:#4facfe:#00f2fe><bold>Casque de Diamant Divin</bold></gradient>")
.lore(
"<gray>Forgé par les anciens dieux.</gray>",
"",
"<yellow>Protection : <aqua>IV</aqua></yellow>"
)
.enchant(Enchantment.PROTECTION_ENVIRONMENTAL, 4)
.unbreakable(true)
.customModelData(2005)
.glowing(true)
.build();
```
---
## 🎯 Système d'Événements & Écouteurs Annotés
```java
package fr.luc.monplugin.listener;
import fr.luc.bettermcguis.event.*;
import fr.luc.bettermcguis.event.annotation.GuiEventHandler;
public class MonEcouteurGlobalGui {
@GuiEventHandler(priority = 10)
public void onGuiClick(GuiClickEvent event) {
var ctx = event.getContext();
System.out.println("[GUI] Clic de " + ctx.getPlayer().getName() + " sur le slot #" + ctx.getSlot());
}
@GuiEventHandler
public void onGuiClose(GuiCloseEvent event) {
System.out.println("[GUI] Fermeture du menu : " + event.getGui().getTitle());
}
}
```
---
## 📂 Organisation des Packages
```
fr.luc.bettermcguis/
├── BetterMcGuis.java (Façade principale & Enregistrement)
├── api/ (Contrats et modèles publics)
│ ├── Gui.java (Interface de base de tout GUI)
│ ├── GuiType.java (Types de coffres 1-6 et types Bukkit)
│ ├── GuiItem.java (Items interactifs, cooldowns, sons, visibilité)
│ ├── GuiClickAction.java (Callback fonctionnel de clic)
│ ├── GuiClickContext.java (Contexte complet de clic)
│ ├── GuiOpenContext.java (Contexte d'ouverture)
│ ├── GuiCloseContext.java (Contexte de fermeture)
│ └── slot/
│ ├── SlotPos.java (Position ligne, colonne)
│ └── SlotRange.java (Bordures, intérieurs, plages)
├── builder/ (Constructeurs fluides)
│ ├── ItemBuilder.java (Création d'ItemStacks riches avec Adventure)
│ ├── GuiBuilder.java (Constructeur de menus standards)
│ ├── PaginatedGuiBuilder.java (Constructeur de menus paginés)
│ ├── TabbedGuiBuilder.java (Constructeur de menus à onglets)
│ ├── AnimatedGuiBuilder.java (Constructeur de menus animés)
│ └── PatternBuilder.java (Constructeur de motifs ASCII)
├── pattern/ (Moteur de disposition par grilles ASCII)
│ ├── GuiPattern.java
│ └── GuiMask.java
├── type/ (Implémentations de GUIs)
│ ├── SimpleGui.java
│ ├── PaginatedGui.java
│ ├── TabbedGui.java
│ ├── AnimatedGui.java
│ └── StorageGui.java
├── animation/ (Moteur d'animation)
│ └── Frame.java
├── event/ (Bus d'événements & Lifecycle)
│ ├── GuiEvent.java
│ ├── CancellableGuiEvent.java
│ ├── GuiOpenEvent.java
│ ├── GuiCloseEvent.java
│ ├── GuiClickEvent.java
│ ├── GuiPageChangeEvent.java
│ ├── GuiRefreshEvent.java
│ ├── GuiEventManager.java
│ ├── GuiEventListener.java
│ └── annotation/
│ └── GuiEventHandler.java
├── holder/ (Liaison avec InventoryHolder de Bukkit)
│ └── BetterGuiHolder.java
├── listener/ (Interception Bukkit & Sécurités anti-glitch)
│ └── BukkitGuiEventListener.java
└── demo/ (Démonstrations et plugin de test)
├── DemoGuiPlugin.java
├── guis/
│ ├── DemoMainMenuGui.java
│ ├── DemoPaginatedShopGui.java
│ └── DemoStorageTrashGui.java
└── listeners/
└── DemoGuiListener.java
```
---
## 📄 Licence
Ce projet est sous licence [MIT](LICENSE).