Profesjonalna infrastruktura cyfrowa · Citymoon Dynamics

Citymoon DynamicsCitymoon Dynamics
UsługiDeweloperzyCennikDocsForaKontakt
Zaloguj sięZarejestruj się

Dokumentacja

Citymoon Dynamics
Minecraft
Discord
Usługi WWW
Ulises Licenses
Słowniczek
Słowniczek

Dokumentacja Ulises Licenses

Integracja Wtyczki Minecraft

1. Załaduj Plik Konfiguracyjny

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. Walidacja Licencji z Logiką Ponawiania

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. Okresowe Kontrole Bezpieczeństwa

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

Pełny Przykład Wtyczki

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

Ulepszone Metody API

String getDiscordId(String productId, String licenseKey)

Pobiera ID Discord powiązane z licencją. Zwraca null, jeśli walidacja nie powiedzie się.

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

String getProductName(String productId, String licenseKey)

Pobiera nazwę produktu z licencji. Zwraca null, jeśli walidacja nie powiedzie się.

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

String getExpirationDate(String productId, String licenseKey)

Pobiera datę wygaśnięcia w formacie ISO. Zwraca null, jeśli walidacja nie powiedzie się.

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

String getLicenseStatus(String productId, String licenseKey)

Pobiera status licencji (aktywna/odwołana/wygasła). Zwraca null, jeśli walidacja nie powiedzie się.

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

String getSubType(String productId, String licenseKey)

Pobiera podtyp licencji (Enterprise, Advanced, itp.). Zwraca null, jeśli walidacja nie powiedzie się.

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

String getLastError()

Zwraca ostatni komunikat o błędzie. Przydatne do debugowania problemów z połączeniem.

Zarządzanie Połączeniem

Automatyczne Ponowne Połączenie

Biblioteka teraz automatycznie obsługuje problemy z połączeniem

  • Nieskończone Ponawianie: Gdy backend jest niedostępny, biblioteka ponawia co 30 sekund do sukcesu
  • Jasne Komunikaty: Konsola pokazuje "Nie można połączyć się z serwerem backend" z odliczaniem ponawiania
  • Eleganckie Obsługiwanie: Wyłącza wtyczkę tylko dla rzeczywistych problemów z licencją, nie problemów z połączeniem

Ważna Uwaga dla Deweloperów Wtyczek

Twoja wtyczka powinna działać normalnie podczas problemów z połączeniem. Wyłączaj wtyczkę tylko przy rzeczywistych błędach walidacji licencji (wygasła, odwołana, nieprawidłowa). Problemy z połączeniem powinny wyzwalać próby ponowienia, a nie natychmiastowe zamknięcie.

Integracja Automatycznej Aktualizacji

UlisesLib zawiera wbudowane metody do sprawdzania aktualizacji, pobierania najnowszego pliku jar i weryfikacji jego integralności. Wszystkie walidacje bezpieczeństwa (status licencji, wiązanie HWID, limity IP) są obsługowane automatycznie przez bibliotekę.

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

Sprawdza, czy dostępna jest nowsza wersja pliku jar produktu. Zwraca true, jeśli aktualizacja istnieje.

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)

Pobiera najnowszy plik jar. Automatycznie obsługuje wiązanie HWID przy pierwszym pobraniu. Zwraca pobrany plik lub null, jeśli pobieranie nie powiedzie się.

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)

Weryfikuje sumę kontrolną SHA-256 pobranego pliku jar, aby zapewnić integralność pliku.

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)

Zwraca najnowszy ciąg wersji pliku jar produktu dostępny na serwerze.

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

Walidacje Bezpieczeństwa

Wszystkie operacje aktualizacji automatycznie walidują:

  • Status Licencji: Tylko aktywne, niewygasłe licencje mogą pobierać aktualizacje
  • Wiązanie HWID: ID sprzętu jest weryfikowane i wiązane z licencją przy pierwszym pobraniu
  • Limit IP: Respektuje limit IP skonfigurowany dla każdej licencji

Pełny Przykład Automatycznej Aktualizacji

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

Najlepsze Praktyki

✓ Zrób To

  • Używaj nieskończonych pętli ponawiania dla problemów z połączeniem
  • Wyświetlaj szczegółowe informacje o licencji przy pomyślnej walidacji
  • Implementuj okresowe kontrole (co 10 minut)
  • Twórz plik konfiguracyjny z wartościami domyślnymi

✗ Unikaj Tego

  • Wyłączanie wtyczki przy timeout połączenia
  • Hardkodowanie poświadczeń w kodzie źródłowym
  • Ujawnianie szczegółów błędów użytkownikom końcowym
  • Uruchamianie walidacji w głównym wątku
Citymoon DynamicsCitymoon Dynamics

Zaawansowane rozwiązania dla infrastruktury cyfrowej. Specjaliści od Minecraft, Discord i tworzenia stron internetowych.

Powiązane usługi

  • Ulises Licenses
  • Freewings Discord Bot
  • ResistanceCore Plugin

More

  • Rymbo
  • Vulcan + Grim Prime AC Configuration

Nawigacja

  • Usługi
  • Wpływ
  • Kontakt

Prawne

  • Prywatność
  • Warunki
  • Pliki cookie
  • footer.refund

© (2026) 2025-2030 Citymoon Dynamics (citymoon.org). Wszelkie prawa zastrzeżone.

An international service, made in Uruguay