Ulises Licenses Dokumentation
Minecraft-Plugin-Integration
1. Konfigurationsdatei Laden
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. Lizenzvalidierung mit Wiederholungslogik
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. Periodische Sicherheitsprüfungen
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);
}Vollständiges Plugin-Beispiel
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);
}
}Erweiterte API-Methoden
String getDiscordId(String productId, String licenseKey)
Ruft die mit der Lizenz verknüpfte Discord-ID ab. Gibt null zurück, wenn die Validierung fehlschlägt.
String discordId = ulib.getDiscordId(productId, licenseKey);
// Returns: "1216532655592439862"String getProductName(String productId, String licenseKey)
Ruft den Produktnamen aus der Lizenz ab. Gibt null zurück, wenn die Validierung fehlschlägt.
String productName = ulib.getProductName(productId, licenseKey);
// Returns: "KrakenAnticheat"String getExpirationDate(String productId, String licenseKey)
Ruft das Ablaufdatum im ISO-Format ab. Gibt null zurück, wenn die Validierung fehlschlägt.
String expiresAt = ulib.getExpirationDate(productId, licenseKey);
// Returns: "2025-12-05T00:00:00.000Z"String getLicenseStatus(String productId, String licenseKey)
Ruft den Lizenzstatus (aktiv/widerrufen/abgelaufen) ab. Gibt null zurück, wenn die Validierung fehlschlägt.
String status = ulib.getLicenseStatus(productId, licenseKey);
// Returns: "active"String getSubType(String productId, String licenseKey)
Ruft den Lizenzuntertyp (Enterprise, Advanced, usw.) ab. Gibt null zurück, wenn die Validierung fehlschlägt.
String subType = ulib.getSubType(productId, licenseKey);
// Returns: "Enterprise"String getLastError()
Gibt die letzte Fehlermeldung zurück. Nützlich zum Debuggen von Verbindungsproblemen.
Verbindungsverwaltung
Automatische Neuverbindung
Die Bibliothek verarbeitet Verbindungsprobleme jetzt automatisch
- Unendlicher Wiederholungsversuch: Wenn das Backend nicht erreichbar ist, wiederholt die Bibliothek alle 30 Sekunden bis zum Erfolg
- Klare Nachrichten: Die Konsole zeigt "Verbindung zum Backend-Server nicht möglich" mit Wiederholungs-Countdown
- Elegante Behandlung: Deaktiviert nur das Plugin für tatsächliche Lizenzprobleme, nicht für Verbindungsprobleme
Wichtiger Hinweis für Plugin-Entwickler
Ihr Plugin sollte während Verbindungsproblemen normal weiterlaufen. Deaktivieren Sie das Plugin nur bei tatsächlichen Lizenzvalidierungsfehlern (abgelaufen, widerrufen, ungültig). Verbindungsprobleme sollten Wiederholungsversuche auslösen, kein sofortiges Herunterfahren.
Auto-Update-Integration
UlisesLib enthält integrierte Methoden zum Überprüfen von Updates, Herunterladen der neuesten jar-Datei und Überprüfung ihrer Integrität. Alle Sicherheitsvalidierungen (Lizenzstatus, HWID-Bindung, IP-Limits) werden automatisch von der Bibliothek verarbeitet.
boolean checkForUpdate(String productId, String licenseKey, String currentVersion)
Überprüft, ob eine neuere Version der Produkt-jar-Datei verfügbar ist. Gibt true zurück, wenn ein Update existiert.
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)
Lädt die neueste jar-Datei herunter. Verarbeitet die HWID-Bindung beim ersten Download automatisch. Gibt die heruntergeladene Datei zurück oder null, wenn der Download fehlschlägt.
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)
Überprüft die SHA-256-Prüfsumme der heruntergeladenen jar-Datei, um die Dateiintegrität sicherzustellen.
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)
Gibt die neueste Versionszeichenfolge der auf dem Server verfügbaren Produkt-jar-Datei zurück.
String latestVersion = ulib.getCurrentVersion(productId, licenseKey);
getLogger().info("Latest version available: " + latestVersion);Sicherheitsvalidierungen
Alle Update-Operationen validieren automatisch:
- Lizenzstatus: Nur aktive, nicht abgelaufene Lizenzen können Updates herunterladen
- HWID-Bindung: Die Hardware-ID wird beim ersten Download validiert und an die Lizenz gebunden
- IP-Limit: Respektiert das pro Lizenz konfigurierte IP-Limit
Vollständiges Auto-Update-Beispiel
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 Practices
✓ Machen Sie Das
- Verwenden Sie unendliche Wiederholungsschleifen für Verbindungsprobleme
- Zeigen Sie detaillierte Lizenzinformationen bei erfolgreicher Validierung an
- Implementieren Sie periodische Prüfungen (alle 10 Minuten)
- Erstellen Sie eine Konfigurationsdatei mit Standardwerten
✗ Vermeiden Sie Das
- Plugin bei Verbindungs-Timeout deaktivieren
- Anmeldeinformationen im Quellcode hartcodieren
- Fehlerdetails Endbenutzern aussetzen
- Validierung auf Hauptthread ausführen