Citymoon Dynamics logo - digital infrastructure and web solutionsCitymoon Dynamics
Servizi
Casi di Studio
La Nostra Storia
Sviluppatori
Prezzi
Docs
Forum
Contatti
AccediRegistrati

Documentazione

Citymoon Dynamics

Citymoon Dynamics

Minecraft

DisBan6
authentication.ymlconfig.ymldiscord.ymllang.ymlantileak.ymlPermessi

Discord

Rymbo

Servizi Web

Ulises Licenses

Glossario

Glossario

Documentazione Ulises Licenses

Documentazione ufficiale

Riferimento completo per sviluppatori sul sito Ulises Licenses.

Apri documentazione ufficiale↗

Integrazione Plugin Minecraft

1. Carica File di Configurazione

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

    File antileakFile = new File(myBestPluginDir, "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. Validazione Licenza con Retry Logic

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 + "MyBestPlugin" + ChatColor.GRAY + "] " +
                ChatColor.DARK_AQUA + "✓ Authentication successful. Powering up MyBestPlugin..."
            );
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "MyBestPlugin" + ChatColor.GRAY + "] " +
                ChatColor.GRAY + " » Discord ID: " + ChatColor.AQUA + discordId
            );
            
            loadPlugin();
            
        } else {
            String lastError = ulib.getLastError();
            Bukkit.getConsoleSender().sendMessage(
                ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "MyBestPlugin" + 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 + "MyBestPlugin" + 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. Controlli di Sicurezza Periodici

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 + "MyBestPlugin" + 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 + "MyBestPlugin" + 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 + "MyBestPlugin" + ChatColor.GRAY + "] " +
                ChatColor.GREEN + "✓ License check passed. Status: " + 
                ulib.getLicenseStatus(productId, licenseKey)
            );
        }
    }, 10L, 10L, TimeUnit.MINUTES);
}

Esempio Completo di Plugin

public class MyBestPlugin 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);
    }
}

Metodi API Avanzati

String getDiscordId(String productId, String licenseKey)

Recupera il Discord ID associato alla licenza. Ritorna null se la validazione fallisce.

String discordId = ulib.getDiscordId(productId, licenseKey);
// Returns: <span className="text-primary">"1216532655592439862"</span>

String getProductName(String productId, String licenseKey)

Recupera il nome prodotto della licenza. Ritorna null se la validazione fallisce.

String productName = ulib.getProductName(productId, licenseKey);
// Returns: <span className="text-primary">"MyBestPlugin"</span>

String getExpirationDate(String productId, String licenseKey)

Recupera la data di scadenza in formato ISO. Ritorna null se la validazione fallisce.

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

String getLicenseStatus(String productId, String licenseKey)

Recupera lo stato licenza (attiva/revocata/scaduta). Ritorna null se la validazione fallisce.

String status = ulib.getLicenseStatus(productId, licenseKey);
// Returns: <span className="text-primary">"active"</span>

String getSubType(String productId, String licenseKey)

Recupera il sottotipo licenza (Enterprise, Advanced, ecc). Ritorna null se la validazione fallisce.

String subType = ulib.getSubType(productId, licenseKey);
// Returns: <span className="text-primary">"Enterprise"</span>

String getLastError()

Ritorna l’ultimo messaggio di errore. Utile per debug di connessione.

Gestione Connessione

Riconnessione Automatica

La libreria gestisce i problemi di connessione in automatico

  • Retry Infinito: se il backend non risponde, la libreria riprova ogni 30 secondi fino al successo
  • Messaggi Chiari: la console mostra "Unable to connect to the backend server" con countdown
  • Gestione Elegante: disattiva il plugin solo per problemi reali di licenza, non di connessione

Nota Importante per Plugin Developer

Il tuo plugin deve continuare a girare durante problemi di connessione. Disattivalo solo per fallimenti reali di licenza (scaduta, revocata, invalida). I problemi di connessione richiedono retry, non shutdown immediato.

Integrazione Auto-Update

UlisesLib include metodi per check update, download ultimo jar e verifica integrità. Tutte le validazioni (stato, HWID, limiti IP) sono automatiche.

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

Verifica se esiste una versione più recente del jar. Ritorna true se c’è un update.

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)

Scarica l’ultimo jar. Gestisce HWID binding al primo download. Ritorna il File o null se fallisce.

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)

Verifica lo SHA-256 del jar scaricato per garantirne l’integrità.

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)

Ritorna l’ultima versione del jar disponibile sul server.

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

Validazioni di Sicurezza

Tutte le operazioni di update validano automaticamente:

  • Stato Licenza: solo licenze attive non scadute possono scaricare update
  • HWID Binding: Hardware ID validato e legato alla licenza al primo download
  • Limite IP: rispetta il limite IP configurato per licenza

Esempio Completo Auto-Update

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.");
    }
}

Best Practice

✓ Da Fare

  • Usa retry loop infiniti per problemi di connessione
  • Mostra info licenza dettagliate a validazione riuscita
  • Implementa controlli periodici (ogni 10 minuti)
  • Crea file di configurazione con valori default

✗ Da Evitare

  • Disattivare il plugin a timeout di connessione
  • Hardcodare credenziali nel sorgente
  • Esporre dettagli errore agli utenti finali
  • Eseguire validazione sul main thread
←Rymbo
→Glossario
Citymoon Dynamics logo - digital infrastructure and web solutionsCitymoon Dynamics

Soluzioni avanzate per infrastruttura digitale. Specialisti in Minecraft, Discord e Sviluppo Web.

Servizi correlati

  • Ulises Licenses
  • Freewings Discord Bot
  • ResistanceCore Plugin
  • Synth | Enterprise Serverside Anticheat

More

  • Rymbo
  • Vulcan + Grim | Prime AC Configuration
  • DisBan | Sync and appeals made easier

Navigazione

  • La Nostra Storia
  • Servizi
  • Casi di Studio
  • Impatto
  • Contatti

Legale

  • Privacy
  • Termini
  • Cookie
  • Rimborsi

© (2026) 2025-2030 Citymoon Dynamics S.R.L. (citymoon.org). Tutti i diritti riservati. | Registered by Eric Martinez, Director.

An international service, made in Uruguay