Documentation

# 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

moderationmodule.zip
moderationmodule.zip

# ⚒️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

src.zip
src.zip

# 🌍 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 .yml sont extraits automatiquement dans plugins/Horizons/modules/<votre-module>/languages/.
  • Synchronisation : Votre module utilise automatiquement la langue définie dans la config globale de Horizons.
  • Reload : La commande /hz reload recharge aussi vos langues instantanément.

# ModuleLanguageManager

En arrière-plan, chaque module se voit attribuer une instance de ModuleLanguageManager.

Fonctionnalités clés :

  1. Isolation : Charge les ressources depuis le ClassLoader du module (isolation du JAR).
  2. Synchronisation : La méthode reload() lit la configuration globale du serveur (language.default dans config.yml) pour s'assurer que tous les modules parlent la même langue que le coeur du plugin.
  3. 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

Retour Méthode Description
boolean teamExists(String teamName) Vérifie si une équipe existe.
boolean isPlayerInTeam(Player player, String teamName) Vérifie si le joueur est dans l'équipe donnée.
String getTeamPrefix(String teamName) Retourne le préfixe (couleur/tag).
String getTeamDisplayName(String teamName) Retourne le nom d'affichage.
int getTeamScore(String teamName) Retourne le score actuel.
String getPlayerTeam(Player player) Retourne le nom de l'équipe du joueur.
List<String> getAllTeams() Retourne tous les noms d'équipes.
List<Player> getTeamPlayers(String teamName) Retourne les joueurs en ligne.
List<UUID> getTeamPlayerUUIDs(String teamName) Retourne tous les joueurs (offline inclus).
Map<String, Integer> getAllTeamScores() Retourne une map Equipe -> Score.
List<String> getTeamsSortedByScore() Retourne les équipes triées par score.

# Modification (Écriture)

Retour Méthode Description
void createTeam(String name, String prefix, String display) Crée une nouvelle équipe.
void removeTeam(String teamName) Supprime une équipe.
void addPlayerToTeam(Player player, String teamName) Ajoute un joueur.
boolean removePlayerFromTeam(String playerName) Retire un joueur.
void setTeamPrefix(String teamName, String prefix) Change le préfixe.
void setTeamDisplayName(String teamName, String name) Change le nom d'affichage.
void setTeamScore(String teamName, int score) Définit le score.
void addTeamScore(String teamName, int points) Ajoute des points.
void removeTeamScore(String teamName, int points) Retire des points.

# ShopAPI Référence

Package : org.metaloul.horizons.api
Accès : Horizons.getShopAPI()

# Ouverture de Shop

Retour Méthode Description
boolean openShop(Player player, String shopId) Ouvre un shop pour un joueur. Retourne true si succès.
Set<String> getAllShopIds() Retourne tous les IDs de shops disponibles.

# Lecture des Prix & Items

Retour Méthode Description
boolean shopExists(String shopId) Vérifie l'existence d'un shop.
List<Material> getShopItems(String shopId) Liste des matériaux vendus.
double getItemPrice(String shopId, Material material) Prix global actuel.
double getItemPrice(String shopId, Material mat, String team) Prix pour une équipe spécifique.
double getCustomItemPrice(String shopId, String itemKey) Prix d'un item custom.
PriceTrend getPriceTrend(String shopId, Material material) Tendance (UP, DOWN, STABLE).

# Marché Noir

Retour Méthode Description
boolean blackMarketExists(String marketId) Vérifie l'existence.
List<Material> getBlackMarketItems(String marketId) Items disponibles.
int getBlackMarketItemPrice(String id, Material mat) Prix actuel (entier).

# Configuration des Scopes (Global vs Per-Team)

Retour Méthode Description
String getPriceScope(String shopId, String itemKey) Scope effectif (GLOBAL/PER_TEAM).
String getShopPriceScope(String shopId) Scope configuré pour le shop.
String getGlobalPriceScope() Scope par défaut du serveur.
void setItemPriceScope(String shopId, String key, String scope) Configure le scope d'un item.
void setShopPriceScope(String shopId, String scope) Configure le scope d'un shop.

# Infos Économie Avancée

Retour Méthode Description
String getPricingType(shopId, itemKey) Type de pricing (STATIC, TIERED, etc).
long getTotalSales(shopId, itemKey, team) Ventes totales (lifetime).
int getPeriodSales(shopId, itemKey, team) Ventes sur la période actuelle.
long getNextTierThreshold(shopId, itemKey, team) Seuil de ventes pour le prochain palier.
double getNextTierPrice(shopId, itemKey, team) Prix au prochain palier.
int getCurrentTierIndex(shopId, itemKey, team) Index du palier actuel (base 1).
long getTimeUntilNextPriceReset() Temps restant avant reset auto (secondes).
double getMinPrice(shopId, itemKey) Prix minimum configuré.
double getMaxPrice(shopId, itemKey) Prix maximum configuré.
double getBasePrice(shopId, itemKey) Prix de base configuré.
double getPreviousPrice(shopId, itemKey, team) Prix avant mise à jour.
int getSupplyThreshold(shopId, itemKey) Seuil de ventes pour baisse de prix.

# 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

  1. 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 }
      ]
    }
  ]
}
  1. 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
    }
  ]
}
  1. 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
        }
      ]
    }
  ]
}