Infrastructure numérique professionnelle · Citymoon Dynamics

Citymoon DynamicsCitymoon Dynamics
ServicesDéveloppeursTarifsDocsForumsContact
ConnexionInscription

Documentation

Citymoon Dynamics
Minecraft
Discord
Services Web
Ulises Licenses
Glossaire
Glossaire

Documentation Ulises Licenses

Intégration de Plugin Minecraft

1. Charger le Fichier de Configuration

private void loadAntileakConfig() {
    File krakenDir = getDataFolder();
    if (!krakenDir.exists()) {
        krakenDir.mkdirs();
    }

    File antileakFile = new File(krakenDir, "antileak.yml");
    if (!antileakFile.exists()) {
        try {
            antileakFile.createNewFile();
            this.antileakConfig = YamlConfiguration.loadConfiguration(antileakFile);
            this.antileakConfig.set("license.key", "your-license-key-here");
            this.antileakConfig.save(antileakFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        this.antileakConfig = YamlConfiguration.loadConfiguration(antileakFile);
    }
}

2. Validation de Licence avec Logique de Réessai

private void validateLicense() {
    UlisesLib ulib = new UlisesLib();
    String productId = "myproductid";
    String licenseKey = this.antileakConfig.getString("license.key", "");
   
    boolean licenseValid = false;
    while (!licenseValid) {
        if (ulib.isLicenseValid(productId, licenseKey)) {
            licenseValid = true;
            
            String discordId = ulib.getDiscordId(productId, licenseKey);
            String productName = ulib.getProductName(productId, licenseKey);
            String expiresAt = ulib.getExpirationDate(productId, licenseKey);
            String licenseStatus = ulib.getLicenseStatus(productId, licenseKey);
            
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                ChatColor.DARK_AQUA + "✓ Authentication successful. Powering up Kraken..."
            );
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                ChatColor.GRAY + " » Discord ID: " + ChatColor.AQUA + discordId
            );
            
            loadPlugin();
            
        } else {
            String lastError = ulib.getLastError();
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                ChatColor.RED + "✗ License authentication failed: " + lastError
            );
            
            if (lastError != null && lastError.contains("Unable to connect to the backend server")) {
                Bukkit.getConsoleSender().sendMessage(
                    ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                    ChatColor.YELLOW + "⚠ Retrying connection in 30 seconds..."
                );
                
                try {
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    Bukkit.getPluginManager().disablePlugin(this);
                    return;
                }
            } else {
                Bukkit.getPluginManager().disablePlugin(this);
                return;
            }
        }
    }
}

3. Vérifications de Sécurité Périodiques

private void startSecurityChecks() {
    ScheduledExecutorService licenseService = Executors.newSingleThreadScheduledExecutor();
    
    licenseService.scheduleAtFixedRate(() -> {
        UlisesLib ulib = new UlisesLib();
        String productId = antileakConfig.getString("license.product-id", "");
        String licenseKey = antileakConfig.getString("license.key", "");
        
        if (!ulib.isLicenseValid(productId, licenseKey)) {
            String lastError = ulib.getLastError();
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                ChatColor.RED + "✗ License validation failed during periodic check."
            );
            
            if (lastError != null && lastError.contains("Unable to connect to the backend server")) {
                Bukkit.getConsoleSender().sendMessage(
                    ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                    ChatColor.YELLOW + "⚠ Will retry in next check cycle..."
                );
            } else {
                Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().disablePlugin(this));
                licenseService.shutdown();
            }
        } else {
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Kraken" + ChatColor.GRAY + "] " +
                ChatColor.GREEN + "✓ License check passed. Status: " + 
                ulib.getLicenseStatus(productId, licenseKey)
            );
        }
    }, 10L, 10L, TimeUnit.MINUTES);
}

Exemple Complet de Plugin

public class KrakenAntiCheat extends JavaPlugin {
    private FileConfiguration antileakConfig;
    
    @Override
    public void onEnable() {
        loadAntileakConfig();
        
        String productId = antileakConfig.getString("license.product-id");
        String licenseKey = antileakConfig.getString("license.key");
        
        if (productId.equals("your-product-id-here") || licenseKey.equals("your-license-key-here")) {
            getLogger().severe("License details not configured. Please edit antileak.yml");
            Bukkit.getPluginManager().disablePlugin(this);
            return;
        }
        
        validateLicense(productId, licenseKey);
    }
    
    private void validateLicense(String productId, String licenseKey) {
        UlisesLib ulib = new UlisesLib();
        
        while (true) {
            if (ulib.isLicenseValid(productId, licenseKey)) {
                String discordId = ulib.getDiscordId(productId, licenseKey);
                String expiresAt = ulib.getExpirationDate(productId, licenseKey);
                
                getLogger().info("License validated for Discord ID: " + discordId);
                getLogger().info("License expires: " + expiresAt);
                
                loadFeatures();
                startPeriodicChecks();
                break;
                
            } else {
                String error = ulib.getLastError();
                getLogger().severe("License validation failed: " + error);
                
                if (error != null && error.contains("Unable to connect to the backend server")) {
                    getLogger().warning("Retrying connection in 30 seconds...");
                    try {
                        Thread.sleep(30000);
                    } catch (InterruptedException e) {
                        Bukkit.getPluginManager().disablePlugin(this);
                        break;
                    }
                } else {
                    Bukkit.getPluginManager().disablePlugin(this);
                    break;
                }
            }
        }
    }
    
    private void startPeriodicChecks() {
        Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
            UlisesLib ulib = new UlisesLib();
            String productId = antileakConfig.getString("license.product-id");
            String licenseKey = antileakConfig.getString("license.key");
            
            if (!ulib.isLicenseValid(productId, licenseKey)) {
                String error = ulib.getLastError();
                getLogger().severe("Periodic license check failed: " + error);
                
                if (!error.contains("Unable to connect to the backend server")) {
                    Bukkit.getScheduler().runTask(this, () -> 
                        Bukkit.getPluginManager().disablePlugin(this)
                    );
                }
            } else {
                getLogger().info("Periodic license check passed.");
            }
        }, 20L * 60 * 10, 20L * 60 * 10);
    }
}

Méthodes API Améliorées

String getDiscordId(String productId, String licenseKey)

Récupère l'ID Discord associé à la licence. Renvoie null si la validation échoue.

String discordId = ulib.getDiscordId(productId, licenseKey);
// Returns: "1216532655592439862"

String getProductName(String productId, String licenseKey)

Récupère le nom du produit de la licence. Renvoie null si la validation échoue.

String productName = ulib.getProductName(productId, licenseKey);
// Returns: "KrakenAnticheat"

String getExpirationDate(String productId, String licenseKey)

Récupère la date d'expiration au format ISO. Renvoie null si la validation échoue.

String expiresAt = ulib.getExpirationDate(productId, licenseKey);
// Returns: "2025-12-05T00:00:00.000Z"

String getLicenseStatus(String productId, String licenseKey)

Récupère le statut de la licence (active/révoquée/expirée). Renvoie null si la validation échoue.

String status = ulib.getLicenseStatus(productId, licenseKey);
// Returns: "active"

String getSubType(String productId, String licenseKey)

Récupère le sous-type de licence (Enterprise, Advanced, etc). Renvoie null si la validation échoue.

String subType = ulib.getSubType(productId, licenseKey);
// Returns: "Enterprise"

String getLastError()

Renvoie le dernier message d'erreur. Utile pour déboguer les problèmes de connexion.

Gestion de Connexion

Reconnexion Automatique

La bibliothèque gère maintenant automatiquement les problèmes de connexion

  • Réessai Infini: Lorsque le backend est inaccessible, la bibliothèque réessaie toutes les 30 secondes jusqu'au succès
  • Messages Clairs: La console affiche "Impossible de se connecter au serveur backend" avec compte à rebours de réessai
  • Gestion Gracieuse: Désactive uniquement le plugin pour les problèmes réels de licence, pas les problèmes de connexion

Note Importante pour les Développeurs de Plugins

Votre plugin devrait continuer à fonctionner normalement pendant les problèmes de connexion. Désactivez uniquement le plugin lorsqu'il y a des échecs réels de validation de licence (expirée, révoquée, invalide). Les problèmes de connexion devraient déclencher des tentatives de réessai, pas un arrêt immédiat.

Intégration de Mise à Jour Automatique

UlisesLib inclut des méthodes intégrées pour vérifier les mises à jour, télécharger le jar le plus récent et vérifier son intégrité. Toutes les validations de sécurité (statut de licence, liaison HWID, limites IP) sont gérées automatiquement par la bibliothèque.

boolean checkForUpdate(String productId, String licenseKey, String currentVersion)

Vérifie si une version plus récente du jar du produit est disponible. Renvoie true si une mise à jour existe.

String currentVersion = "1.0.0";
if (ulib.checkForUpdate(productId, licenseKey, currentVersion)) {
    getLogger().info("Update available! Downloading...");
    ulib.downloadUpdate(productId, licenseKey, hwid);
}

File downloadUpdate(String productId, String licenseKey, String hwid)

Télécharge le fichier jar le plus récent. Gère automatiquement la liaison HWID lors du premier téléchargement. Renvoie le fichier téléchargé, ou null si le téléchargement échoue.

String hwid = ulib._getHwid();
File updatedJar = ulib.downloadUpdate(productId, licenseKey, hwid);
if (updatedJar != null) {
    getLogger().info("Update downloaded: " + updatedJar.getName());
    if (ulib.verifyChecksum(productId, licenseKey, hwid, updatedJar)) {
        getLogger().info("Checksum verified!");
    }
}

boolean verifyChecksum(String productId, String licenseKey, String hwid, File jarFile)

Vérifie le checksum SHA-256 du fichier jar téléchargé pour assurer l'intégrité du fichier.

File jarFile = new File("plugins/MyPlugin.jar");
boolean valid = ulib.verifyChecksum(productId, licenseKey, hwid, jarFile);
if (!valid) {
    getLogger().warning("Checksum mismatch! File may be corrupted.");
}

String getCurrentVersion(String productId, String licenseKey)

Renvoie la chaîne de version la plus récente du jar du produit disponible sur le serveur.

String latestVersion = ulib.getCurrentVersion(productId, licenseKey);
getLogger().info("Latest version available: " + latestVersion);

Validations de Sécurité

Toutes les opérations de mise à jour valident automatiquement:

  • Statut de Licence: Seules les licences actives et non expirées peuvent télécharger des mises à jour
  • Liaison HWID: L'ID matériel est validé et lié à la licence lors du premier téléchargement
  • Limite IP: Respecte la limite IP configurée par licence

Exemple Complet de Mise à Jour Automatique

private void checkAndApplyUpdate(String productId, String licenseKey) {
    String currentVersion = this.getDescription().getVersion();
    String hwid = ulib.getHardwareId();

    if (ulib.checkForUpdate(productId, licenseKey, currentVersion)) {
        String latestVersion = ulib.getCurrentVersion(productId, licenseKey);
        getLogger().info("New version available: " + latestVersion + " (current: " + currentVersion + ")");

        File updatedJar = ulib.downloadUpdate(productId, licenseKey, hwid);
        if (updatedJar != null) {
            if (ulib.verifyChecksum(productId, licenseKey, hwid, updatedJar)) {
                getLogger().info("Update downloaded and verified successfully!");
                getLogger().info("Restart the server to apply the update.");
            } else {
                getLogger().warning("Checksum verification failed. Update may be corrupted.");
            }
        }
    } else {
        getLogger().info("Plugin is up to date.");
    }
}

Meilleures Pratiques

✓ Faire Cela

  • Utiliser des boucles de réessai infinies pour les problèmes de connexion
  • Afficher des informations détaillées de licence lors d'une validation réussie
  • Implémenter des vérifications périodiques (toutes les 10 minutes)
  • Créer un fichier de configuration avec des valeurs par défaut

✗ Éviter Cela

  • Désactiver le plugin lors d'un timeout de connexion
  • Coder les identifiants en dur dans le code source
  • Exposer les détails d'erreur aux utilisateurs finaux
  • Exécuter la validation sur le thread principal
Citymoon DynamicsCitymoon Dynamics

Solutions avancées pour l’infrastructure numérique. Spécialistes de Minecraft, Discord et développement web.

Services liés

  • Ulises Licenses
  • Freewings Discord Bot
  • ResistanceCore Plugin

More

  • Rymbo
  • Vulcan + Grim Prime AC Configuration

Navigation

  • Services
  • Impact
  • Contact

Juridique

  • Confidentialité
  • Conditions
  • Cookies
  • Remboursements

© (2026) 2025-2030 Citymoon Dynamics (citymoon.org). Tous droits réservés.

An international service, made in Uruguay