#
☕ API Java & Modules
#
📝 Introduction
Horizons expose une API Java complète via le package org.metaloul.horizons.api.
Pour utiliser l'API, ajoutez le jar de Horizons à votre projet (scope provided).
#
Point d'entrée
import org.metaloul.horizons.api.Horizons;
if (Horizons.isEnabled()) {
// Accès statique aux managers
TeamManagerAPI teams = Horizons.getTeamAPI();
ShopAPI shops = Horizons.getShopAPI();
}
#
🧩 Système de Modules
Le système de modules permet de créer des extensions qui tournent à l'intérieur de Horizons. Contrairement aux plugins Bukkit classiques, les modules bénéficient de :
- Partage de ressources : Connexion BDD partagée, système de configuration unifié.
- Intégration profonde : Accès direct aux managers internes.
- Isolation : ClassLoader dédié pour éviter les conflits de dépendances.
- Hot-Reload : Possibilité de recharger la configuration des modules sans redémarrer.
#
Créer un module
Un module est un simple JAR contenant un fichier module.yml et une classe étendant HorizonsModule.
#
Le descriptor (module.yml)
À placer à la racine du JAR :
name: MonModule
version: 1.0.0
main: com.monpackage.MonModule
author: VotreNom
description: Un module exemple
dependencies: [] # Modules requis
#
La classe principale
import org.metaloul.horizons.api.module.HorizonsModule;
public class MonModule extends HorizonsModule {
public MonModule() {
super("MonModule", "1.0.0", "Auteur");
}
@Override
public void onEnable() {
getLogger().info("Mon module démarre !");
// Enregistrement automatique (nettoyé au disable)
registerCommand(new MaCommande());
registerListener(new MonListener());
// Configurable GUI item
setConfigMetadata("options.welcome", Material.PAPER, "Welcome Msg", "Description");
}
@Override
public void onDisable() {
// Nettoyage automatique
}
}
#
🎨 Personnalisation du GUI de Configuration (Optionnel)
Les modules peuvent personnaliser l'apparence de leurs options dans le menu de configuration admin (/horizons config). Ceci est purement optionnel ; par défaut, Horizons affichera des items génériques.
Utilisez setConfigMetadata dans onEnable :
// 1. Icône du module dans la liste principale
setConfigMetadata("", Material.DIAMOND_SWORD, "&bMon Module", "&7Description du module");
// 2. Icône pour une section de config spécifique
setConfigMetadata("database", Material.CHEST, "&eBase de données", "&7Configuration MySQL");
// 3. Icône pour une valeur spécifique
setConfigMetadata("database.host", Material.PAPER, "&fHôte Connexion", "&7IP du serveur");
Syntaxe : setConfigMetadata(String path, Material icon, String name, String description)
path: Chemin dans le config.yml (ex:category.setting). Chaine vide""pour le module lui-même.icon: Material Bukkit à afficher.name&description: Supportent les codes couleurs (&a,&l, etc.).
#
😎Exemple de module
#
⚒️Custom Item Providers
Horizons offre deux façons d'ajouter des items custom :
- Méthode Simplifiée (
SimpleCustomItemProvider) : Pour ajouter rapidement vos propres items créés via code. - Méthode Avancée (
CustomItemProvider) : Pour intégrer un plugin d'items externe (comme MMOItems, ExecutableItems, etc).
Option A : Créer vos propres items (Simple)
// 1. Initialiser le provider pour votre module
SimpleCustomItemProvider myProvider = new SimpleCustomItemProvider("mon_module");
// 2. Créer vos ItemStacks (Exemple avec ItemBuilder mais marche avec n'importe quel ItemStack)
ItemStack superEpée = new ItemStack(Material.DIAMOND_SWORD);
ItemMeta meta = superEpée.getItemMeta();
meta.setDisplayName("§cExcalibur");
superEpée.setItemMeta(meta);
// 3. Enregistrer les items dans votre provider
// Soit un par un :
myProvider.registerItem("excalibur", superEpée);
myProvider.registerItem("bouclier_magique", magicShield);
// Soit automatiquement depuis une classe (champs 'public static ItemStack') :
// L'ID sera le nom du champ en minuscule (ex: "EXCALIBUR" -> "excalibur")
myProvider.registerItemsFromClass(MyItems.class);
// 4. Enregistrer le provider dans Horizons
registerCustomItemProvider(myProvider);
Option B : Support d'un Plugin Externe (Avancé)
public class MonPluginProvider implements CustomItemProvider {
@Override
public String getProviderId() { return "mon_plugin_externe"; }
@Override
public Optional<ItemStack> getItemStack(String id, int amount) {
// Logique pour récupérer l'item depuis l'API externe
return ExternalApi.getItem(id);
}
// ... implémenter les autres méthodes (isCustomItem, etc)
}
// Enregistrement
registerCustomItemProvider(new MonPluginProvider());
Utilisation dans les configs (Shop, Kits, etc) : Une fois enregistrés, vos items sont accessibles partout dans Horizons via le format : provider_id:item_id.
Exemple : mon_module:excalibur ou oraxen:hyper_sword.
#
😎Exemple d'item custom simple
#
🌍 Système de Traduction (I18n)
Horizons fournit un système de langue natif et automatisé pour vos modules.
1. Structure des Fichiers Dans votre projet (JAR), placez vos fichiers YAML de langue dans src/main/resources/languages/ :
fr_FR.yml(Français)en_US.yml(Anglais - Fallback par défaut)
Exemple de contenu fr_FR.yml :
mon-module:
welcome: "&aBienvenue sur mon module, {player} !"
error: "&cUne erreur est survenue."
2. Utilisation dans le Code Votre classe principale (HorizonsModule) possède la méthode msg() pour récupérer les messages traduits.
// String msg(String key, String... placeholders)
// Simple
player.sendMessage(msg("mon-module.error"));
// Avec placeholders ({player} -> "Bob")
player.sendMessage(msg("mon-module.welcome", "{player}", player.getName()));
3. Automatisation
- Installation : Au premier lancement, vos fichiers
.ymlsont extraits automatiquement dansplugins/Horizons/modules/<votre-module>/languages/. - Synchronisation : Votre module utilise automatiquement la langue définie dans la config globale de Horizons.
- Reload : La commande
/hz reloadrecharge aussi vos langues instantanément.
#
ModuleLanguageManager
En arrière-plan, chaque module se voit attribuer une instance de ModuleLanguageManager.
Fonctionnalités clés :
- Isolation : Charge les ressources depuis le ClassLoader du module (isolation du JAR).
- Synchronisation : La méthode
reload()lit la configuration globale du serveur (language.defaultdansconfig.yml) pour s'assurer que tous les modules parlent la même langue que le coeur du plugin. - Fallback : Si une clé de traduction manque dans la langue cible, le manager peut (selon implémentation) se replier sur la langue par défaut du module.
#
🛠 APIs Principales
Cette section présente les concepts. Pour la liste complète des méthodes, voir la section Référence Syntaxique Complète ci-dessous.
#
TeamManagerAPI
Gère les équipes, scores et joueurs.
TeamManagerAPI api = Horizons.getTeamAPI();
api.addTeamScore("Red", 100);
#
ShopAPI
Gère l'économie, les shops et le marché noir.
ShopAPI api = Horizons.getShopAPI();
double price = api.getItemPrice("minerals::miner", Material.DIAMOND);
#
WebAPIManager
Permet d'interroger les données du serveur via HTTP/JSON.
#
📚 Référence Syntaxique Complète
Voici la liste exhaustive des méthodes disponibles pour chaque API.
#
TeamManagerAPI Référence
Package : org.metaloul.horizons.api
Accès : Horizons.getTeamAPI()
#
Vérifications & Lecture
#
Modification (Écriture)
#
ShopAPI Référence
Package : org.metaloul.horizons.api
Accès : Horizons.getShopAPI()
#
Ouverture de Shop
#
Lecture des Prix & Items
#
Marché Noir
#
Configuration des Scopes (Global vs Per-Team)
#
Infos Économie Avancée
#
WebAPIManager (HTTP API)
Authentification : Toutes les requêtes HTTP nécessitent le paramètre ?secret=VOTRE_SECRET_API.
Port par défaut : 8080 (Configurable dans config.yml).
Format : Réponse JSON UTF-8.
#
Endpoints HTTP
- Liste des Équipes
GET /api/teams?secret=...
Retourne la liste complète des équipes, scores et joueurs.
{
"teams": [
{
"name": "red",
"displayName": "&cRouge",
"displayNameClean": "Rouge",
"prefix": "&c[R]",
"score": 150,
"players": [
{ "uuid": "...", "name": "Player1", "online": true },
{ "uuid": "...", "name": "Player2", "online": false }
]
}
]
}
- Liste des Joueurs
GET /api/players?secret=...
Retourne tous les joueurs connus avec leur équipe et score personnel.
{
"players": [
{
"uuid": "...",
"name": "Player1",
"score": 10,
"team": "red",
"online": true
}
]
}
- Données des Shops
GET /api/shops?secret=...
Retourne la configuration et les prix actuels de tous les shops.
{
"shops": [
{
"id": "minerals::miner",
"name": "Miner Shop",
"items": [
{
"material": "DIAMOND",
"currentPrice": 45.5,
"pricingType": "DYNAMIC",
"basePrice": 50.0
}
]
}
]
}