Plugin-Erstellung/Java/Plugin Klasse

Aus Rising World Wiki


Plugin Klasse ist die Basisklasse für alle Rising World Plugins. Ein Plugin muss von dieser Klasse erben und die Methoden onEnable() und onDisable() überschreiben. Die Klasse Plugin stellt Methoden zur Verfügung, um auf Spielereignisse zu reagieren, Datenbankverbindungen herzustellen, HTTP-Requests zu senden und Aufgaben zeitverzögert auszuführen.
Die Klasse Plugin erbt von java.lang.Object und muss von jedem Plugin als Hauptklasse erweitert werden.
Dieser Artikel dokumentiert einige wichtige Methoden der Plugin Klasse und zeigt anhand ausgewählter Java-Beispiele, wie diese zu verwenden sind. Hier sind nicht alle Methoden aufgeführt. Die vollständige API-Dokumentation mit allen Methoden, Feldern und Konstruktoren ist im JavaDoc zu finden.


Dokumentation

Die Klasse Plugin ist unter JavaDoc: Class Plugin zu finden. Die vollständige API-Dokumentation mit allen Paketen, Klassen, Methoden, Feldern und Konstruktoren ist im JavaDoc zu finden.

Java Paket

In der Java Plugin-API bezeichnet der Begriff "Package" (Paket) eine Gruppierung von zusammengehörigen Klassen, Interfaces und anderen Paketen. Die Plugin Klasse befindet sich im Package net.risingworld.api.

Methoden der Oberklasse

Die Klasse Plugin erbt von java.lang.Object. Alle Methoden der Oberklasse sind verfügbar, werden aber in der Regel nicht direkt in Plugins verwendet.

Wichtige Plugin-Methoden

  • Plugin.onEnable() – wird aufgerufen, wenn das Plugin aktiviert wird. Alle anderen Plugins sind zu diesem Zeitpunkt bereits geladen.
  • Plugin.onDisable() – wird aufgerufen, wenn das Plugin deaktiviert und entladen wird.
  • Plugin.onLoad() – wird aufgerufen, wenn das Plugin geladen wird (bevor onEnable() aufgerufen wird). Andere Plugins sind zu diesem Zeitpunkt möglicherweise noch nicht geladen.

Beispiel Plugin erstellen

Zeigt ein sehr einfaches Plugin, das die Plugin-Klasse erweitert und das Listener-Interface implementiert, um auf Events zu reagieren. Das Plugin registriert sich selbst als Event-Listener und reagiert auf Chat-Nachrichten.

//Eine Klasse erstellen, die die Plugin-Klasse erweitert und das Listener-Interface implementiert
//(um auf Events zu hören)
public class MyPlugin extends Plugin implements Listener 
{

    @Override
    public void onEnable() {
        //Diese Methode wird aufgerufen, wenn das Plugin initial geladen wird.
        
        //Wir möchten, dass unser Plugin auf Events hört (es implementiert das "Listener"-Interface),
        //also registrieren wir es als Event-Listener
        registerEventListener(this);
    }

    @Override
    public void onDisable() {
        //Dies wird aufgerufen, wenn das Plugin entladen/deaktiviert wird
    }

    //Um auf Events zu hören, müssen "EventMethods" zu dieser Klasse hinzugefügt werden.
    //Jede Event-Methode erfordert eine "@EventMethod"-Annotation.
    //Beispiel: PlayerChatEvent (wird aufgerufen, wenn der Spieler eine Textnachricht im Chat sendet)

    @EventMethod
    public void onChatEvent(PlayerChatEvent event) {
        //Event abbrechen, damit es nicht mehr im Chat angezeigt wird (weil wir
        //stattdessen eine benutzerdefinierte Nachricht senden wollen)
        event.setCancelled(true); 
       
        //Eine geänderte Nachricht an den Chat senden
        Server.broadcastTextMessage("Player " + event.getPlayerChatName() + " send a text message: " + event.getChatMessage());
    }
}

Dieses Beispiel ist unter JavaDoc: Class Plugin - Example: Very basic example plugin zu finden.

Beispiel onEnable

Überschreibt die onEnable()-Methode, um beim Plugin-Start eine Nachricht in die Konsole zu schreiben.

public class MyPlugin extends Plugin
{
    @Override
    public void onEnable(){
        System.out.println("MyPlugin enabled!");
    }

    @Override
    public void onDisable(){
        System.out.println("MyPlugin disabled!");
    }
}

Die Methode onEnable() mit Codeschnipsel ist unter javadoc RW: Class Plugin - onEnable() zu finden. Die Methode onDisable() wird aufgerufen, wenn das Plugin deaktiviert und entladen wird.

Beispiel enqueue

Reiht eine Aufgabe (Runnable) in die Warteschlange ein, die im nächsten Tick verarbeitet wird. Die Methode enqueue() ist nützlich, um Thread-Sicherheit zu gewährleisten, da alle eingereihten Aufgaben vom selben Thread verarbeitet werden.

//Aufgabe mit Lambda-Ausdruck einreihen
enqueue(() -> {
    //Etwas tun
});

Die Methode enqueue() mit Codeschnipsel ist unter javadoc RW: Class Plugin - enqueue(Runnable) zu finden.

Runnable-Schnittstelle

Die Schnittstelle java.lang.Runnable ist eine funktionale Schnittstelle in Java, die eine Aufgabe definiert, die von einem Thread ausgeführt werden kann. Sie enthält eine einzige Methode run(), die den Code enthält, der ausgeführt werden soll.

//Gleiches wie Beispiel #1, aber ohne Lambda-Ausdrücke,
//stattdessen wird die anonyme Klasse als Parameter übergeben (alter Stil)
enqueue(new Runnable(){
    @Override
    public void run(){
        //Etwas tun
    }
});

Beispiel für eine Klasse, die Runnable implementiert

//Beispiel mit einer separaten Klasse, die Runnable implementiert
public class MyRunnableTask implements Runnable 
{
    @Override
    public void run() {
        //Aufgabe hier ausführen
        System.out.println("Aufgabe wird ausgeführt");
    }
}

//Aufgabe einreihen
MyRunnableTask task = new MyRunnableTask();
enqueue(task);

Runnable vs Thread

  • Runnable ist eine Schnittstelle, die eine Aufgabe beschreibt. Sie kann von verschiedenen Threads ausgeführt werden.
  • Thread ist eine Klasse, die einen eigenen Ausführungs-Thread darstellt. Ein Thread kann eine Runnable-Aufgabe ausführen.

In Rising World Plugins ist es in der Regel nicht notwendig, eigene Threads zu erstellen. Stattdessen werden Aufgaben über enqueue() oder executeDelayed() an den Haupt-Server-Thread übergeben, was Thread-Sicherheit gewährleistet.

Beispiel executeDelayed

Führt eine Aufgabe nach einer Verzögerung aus. Die Methode executeDelayed() führt die Aufgabe vom Haupt-Server-Thread aus (ähnlich wie enqueue()).

//In der Plugin-Klasse: Aufgabe nach 5 Sekunden ausführen (mit Lambda-Ausdruck)
executeDelayed(5.0f, () -> {
    //Etwas tun
});

Die Methode executeDelayed() mit Codeschnipsel ist unter javadoc RW: Class Plugin - executeDelayed(float, Runnable) zu finden.

Beispiel mit Runnable-Implementierung

//Class mit Runnable-Implementierung
public class DelayedTask implements Runnable 
{
    @Override
    public void run() {
        System.out.println("Verzögerte Aufgabe ausgeführt");
    }
}

//Aufgabe nach 10 Sekunden ausführen
executeDelayed(10.0f, new DelayedTask());

Unterschied zwischen enqueue und executeDelayed

  • enqueue() – Die Aufgabe wird im nächsten Tick verarbeitet (sofort, aber im nächsten Game-Loop-Durchlauf).
  • executeDelayed() – Die Aufgabe wird nach einer angegebenen Verzögerung in Sekunden verarbeitet.

Beide Methoden führen die Aufgabe vom selben Thread aus (Haupt-Server-Thread), was Thread-Sicherheit gewährleistet.

Lambda-Ausdruck

Ein Lambda-Ausdruck ist eine kurze Schreibweise für anonyme Klassen, die funktionale Schnittstellen implementieren. In Java 8+ können Lambda-Ausdrücke verwendet werden, um Code prägnanter zu schreiben.

Beispiel: () -> { /* Code */ } ist äquivalent zu einer anonymen Klasse, die die run()-Methode von Runnable implementiert.

Beispiel getMySQLConnection

Erstellt eine Verbindung zu einer MySQL-Datenbank. Die Methode getMySQLConnection() benötigt Datenbankname, IP-Adresse, Port, Benutzernamen und Passwort.

//Verbindung zur Datenbank "rwdb" auf lokalem Server erstellen
Database database = getMySQLConnection("rwdb", "127.0.0.1", 3306, "root", "1234");
if(database != null){
    //Verbindung war erfolgreich
}

Die Methode getMySQLConnection() mit Codeschnipsel ist unter javadoc RW: Class Plugin - getMySQLConnection zu finden.

Beispiel getPath

Ruft den Pfad zum Plugin-Ordner Folder-icon.png RisingWorld\Plugins\ ab. Die Methode getPath() gibt den Pfad zurück (zum Beispiel: "C:/Server/plugins/MyPlugin"), ohne Slash am Ende.

//Neues Dateiobjekt erstellen
File config = new File(getPath() + "/config.txt");

//Prüfen, ob Datei existiert
if	config.exists()){
    //Inhalt aus Datei lesen
    String content = Utils.FileUtils.readStringFromFile(file);
}

Die Methode getPath() mit Codeschnipsel ist unter javadoc RW: Class Plugin - getPath() zu finden.

Beispiel getPluginByName

Findet ein anderes Plugin anhand seines Namens. Die Methode getPluginByName() gibt die Plugin-Instanz zurück oder null, wenn das Plugin nicht gefunden wurde.

//Anderes Plugin mit dem Namen "PluginB" abrufen
Plugin otherPlugin = getPluginByName("PluginB");

//Prüfen, ob Plugin wirklich existiert
if(otherPlugin != null){
    //Datei aus anderem Plugin-Ordner lesen
    String path = otherPlugin.getPath() + "/database.db";
    File file = new File(path);
    if(file.exists(){
        //...
    }
}

Die Methode getPluginByName() mit Codeschnipsel ist unter javadoc RW: Class Plugin - getPluginByName(String) zu finden.

Beispiel getSQLiteConnection

Erstellt eine Verbindung zu einer SQLite-Datenbank. Die Methode getSQLiteConnection() kann eine Datenbank im Plugin-Ordner erstellen oder eine temporäre Speicherdatenbank erstellen.

//Verbindung zur Datenbank "MyDatabase.db" im Plugin-Ordner erstellen
//Um den Plugin-Ordner zu erhalten, wird "getPath()" aufgerufen
Database database = getSQLiteConnection(getPath() + "/" + "MyDatabase.db");

//CREATE SQL-Anweisung ausführen
database.execute("CREATE TABLE IF NOT EXISTS `Players` (`ID` INTEGER PRIMARY KEY NOT NULL, `Name` VARCHAR(64), `Level` INTEGER)");

//Datenbankverbindung nur schließen, wenn sie nicht mehr benötigt wird
database.close();

Die Methode getSQLiteConnection() mit Codeschnipsel ist unter javadoc RW: Class Plugin - getSQLiteConnection(String) zu finden.

//Verbindung zur Datenbank im Plugin-Ordner/config erstellen
//Um den Plugin-Ordner zu erhalten, kann "getPath()" aufgerufen werden
Database database = getSQLiteConnection(getPath() + "/config/MyDatabase.db");

//Etwas tun
//...

//Verbindung schließen, sobald sie nicht mehr benötigt wird
database.close();
//Verbindung mit null-Parameter erstellen (Speicherdatenbank)
Database database = getSQLiteConnection(null);

//Etwas tun
//...

//Verbindung schließen, sobald sie nicht mehr benötigt wird
database.close();

Beispiel registerEventListener

Registriert einen Event-Listener. Die Methode registerEventListener() registriert eine Klasse, die das Listener-Interface implementiert und mit @EventMethod annotierte Methoden enthält.

//Beispielklasse für einen Event-Listener
public class MyListener implements Listener{

    //Referenz auf unsere Plugin-Hauptklasse, um von diesem Listener darauf zuzugreifen
    private Plugin plugin;

    //Konstruktor, in diesem Fall übergeben wir eine Referenz auf unsere Plugin-Hauptklasse
    public MyListener(Plugin plugin){
        this.plugin = plugin;
    }

    @EventMethod
    public void onPlayerHit(PlayerHitEvent event){
        //Diese Methode wird aufgerufen, wenn ein PlayerHitEvent ausgelöst wird
    }

    @EventMethod
    public void onPlayerCommand(PlayerCommandEvent event){
        //Diese Methode wird aufgerufen, wenn ein PlayerCommandEvent ausgelöst wird
    }
}

Die Methode registerEventListener() mit Codeschnipsel ist unter javadoc RW: Class Plugin - registerEventListener(Listener) zu finden.

//Da die "MyListener"-Klasse nur die Methoden "onPlayerHit()" und
//"onPlayerCommand()" hat (Hinweis: Der Name ist nicht wichtig, nur der
//Parametertyp ist relevant), wird sie nur auf "PlayerHitEvent"
//und "PlayerCommandEvent" hören
MyListener listener = new MyListener();
registerEventListener(listener);

Beispiel triggerEvent

Löst ein benutzerdefiniertes Event aus. Die Methode triggerEvent() ist nützlich, wenn eigene Events erstellt und durch die Event-Pipeline aufgerufen werden sollen.

//Benutzerdefinierte Event-Klasse
public class CustomEvent extends Event
{
    private String message;
    
    public CustomEvent(String message){
        this.message = message;
    }
    
    public String getMessage(){
        return message;
    }
}

//Event-Listener, der auf das benutzerdefinierte Event hört
public class MyCustomEventListener implements Listener
{
    @EventMethod
    public void customMethod(CustomEvent event){
        System.out.println(event.getMessage());
    }
}

Die Methode triggerEvent() mit Codeschnipsel ist unter javadoc RW: Class Plugin - triggerEvent(Event) zu finden.

//Das "CustomEvent" auslösen
CustomEvent evt = new CustomEvent("Hello World!");
triggerEvent(evt);

Spieler Events

Das Package net.risingworld.api.events.player enthält zahlreiche Events, die auf Spieleraktionen reagieren. Beispiele sind PlayerCommandEvent (wenn ein Spieler einen Befehl eingibt), PlayerHitEvent (wenn ein Spieler etwas trifft) oder PlayerChatEvent (wenn ein Spieler eine Chatnachricht sendet). Durch Implementierung des Listener-Interfaces und Verwendung der @EventMethod-Annotation können Plugins auf diese Events reagieren.

Beispiel onPlayerCommand

    @EventMethod
    public void onPlayerCommand(PlayerCommandEvent event) 
    {
        //diese Methode wird aufgerufen, wenn das "PlayerCommandEvent" ausgelöst wird
        //d.h. wenn ein Spieler einen Befehl in den Chat eingibt

		//Befehl durch Leerzeichen Teilen
		String[] cmd = event.getCommand().split(" ");

		//Spieler, der den Befehl ausgeführt hat
		Player player = event.getPlayer();
    }

Java Override Annotation

Mit der Java @Override Annotation kann dem Compiler mitgeteilt werden, dass absichtlich eine Methode der Plugin-Oberklasse überschrieben wird (in diesem Fall onEnable() und onDisable()).

Siehe auch

API Dokumentation

Forum

Kategorien

Tutorial Kategorien
Plugin-API(1 K, 10 S)
Tutorial(3 S)
Plugin-Erstellung
Java(2 K, 6 S)
Unity(5 S)