Tutorial: Bukkit Plugins Programmieren

Dieses Thema im Forum "Tutorials" wurde erstellt von Benni1000, 14. Juni 2012.

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    Eins vorweg: Sorry für den Doppelpost, aber der Post überschreitet die Maximallänge von 10.000 Zeichen also, musste ich 2 erstellen.

    === Vorwort ===
    da mich jetzt schon einige Leute per PN nach Hilfe beim Programmieren gefragt haben, dachte ich mir ich schreibe euch hier ein kleines Tutorial wie das eigentlich funktioniert. Ich werde hier auf die Programmierung unter Bukkit eingehen, nicht auf Java Programmierung im allgemeinen.

    === Vorraussetzungen ===
    (*) Grundlegende Java Kentnisse. (Was sind Klassen, Objekte, Schleifen usw.)
    (*) Das Java Development Kit
    (*) Ein aktueller bukkit build von www.bukkit.org
    (*) Netbeans oder eine andere IDE. (Ich gehe hier im speziellen auf Netbeans ein.)
    (*) Ein Bukkit Server
    (*) Interesse am selbständigen Lernen.

    === Vorbereitung ===
    Kopiert euch den runtergeladenen Bukkit-Build an einen Ort den ihr euch gut merken könnt, denn ihr werdet ihn bei jedem neuen Plugin neu einbinden müssen. In meinem Fall Lagere ich ihn in meinem NetbeansProjects Ordner. Vergesst nicht euren Build regelmäßig zu aktualisieren.
    Jetzt öffnet ihr Netbeans und erstellt ein neues Projekt, in diesem Fall nennen wir es “Tutorial”.
    Bei dem Punkt “generate main class” könnt ihr euren paketnamen eintragen, dieser kann willkürlich gewählt sein, sollte aber euer fqdn sein wenn ihr eine Domain besitzt. Z.b so: “eu.benni1000.tutorial.Tutorial” in diesem fall würde eure Main klasse Tutorial.java heißen.
    Ob ihr die generierte Klasse als Main Klasse benutzt bleibt euch überlassen, die oben genannte Methode ist nur sehr gut um schnell viele pakete zu generieren. Jetzt Solltet ihr ein Projekt angelegt haben. Herzlichen Glückwunsch, ihr seit fast mit der Einrichtung fertig. Jetzt müsst ihr nur noch den vorher runtergeladenen Bukkit-Build inkludieren. Macht einen Rechtsklick auf euer Projekt, und wählt den Menüpunkt Properties. Dort wählt ihr in der Linken Menüzeile den Punkt Libaries aus, und drückt auf den Button “Add Jar / Folder”. Hier wählt ihr den vorhin runtergeladenen Bukkit Build aus.
    Jetzt seit ihr mit dem einrichten eures Projektes fertig.
    === Ein kleines Testprojekt ===
    Öffnet jetzt eure Main-Klasse, ihr könnt fast alles aus der Klasse löschen, denn Bukkit hat eine eigene Struktur. Vorhanden bleiben muss nur die Deklaration der Klasse und die Information in welchem paket die klasse steckt. Habt ihr alles was oben steht 1 zu 1 nachgemacht schaut eure Klasse jetzt so aus:
    Code (Text):
    1.  
    2. package eu.benni1000.tutorial;
    3. public class Tutorial {
    4.  
    5. }
    6.  
    Jetzt müsst ihr Bukkit darauf hinweisen das es sich hier um die Main Klasse handelt. Erreichen könnt ihr das indem ihr die Klasse die Klasse JavaPlugin extendieren lasst. Also so:
    Code (Text):
    1.  
    2. package eu.benni1000.tutorial;
    3.  
    4. import org.bukkit.plugin.java.JavaPlugin;
    5.  
    6. public class Tutorial extends JavaPlugin {
    7.  
    8. }
    9.  
    Ihr werdet während diesem und einigen anderen Arbeitsschritten, teile eures Codes markiert bekommen, das passiert weil euch imports fehlen. Ihr könnt die Fehlenden Codes Importieren indem ihr auf die kleine rote Glühbirne neben eurem Code klickt und dort auf Importieren klickt.
    Ich werde ab hier nicht mehr darauf hinweisen wenn etwas importiert gehört, da es ziemlich offensichtlich dargestellt wird und das Tutorial in die Länge ziehen würde.
    Jetzt solltet ihr einen Logger erstellen. Logger werden dazu benutzt in der Konsole Fehler oder Informationen auszugeben. Fügt folgenden in eueren Code ein:
    Code (Text):
    1. static final Logger log = Bukkit.getLogger();
    Hier sehen wir auch schon einen Zugriff auf die Bukkit API mit Bukkit.getLogger(); .
    Nun müsst ihr die OnEnable und die OnDisable Methode einbauen.
    Ich füge die OnDisable Methode immer zuerst ein, aber das ist Geschmakssache.
    Code (Text):
    1.  
    2.    @Override
    3.     public void onDisable() {
    4.        
    5.     }
    6.  
    Mit diesem Code erstellt ihr die Disable Methode. Hier könnt ihr an @Override erkennen das euer plugin die OnDisable Methode der Klasse JavaPlugin überschreibt.
    Jetzt könnt ihr z.b eine Nachricht ausgeben lassen, die angezeigt wird wenn der Server heruntergefahren wird.
    Code (Text):
    1.  
    2.     @Override
    3.     public void onDisable() {
    4.         log.info("Tutorial v1.0 by Benni1000 disabled!");
    5.     }
    6.  
    Genau das gleiche könnt ihr mit der OnEnable Methode machen, mit dem Unterschied das die OnEnable Methode beim starten des Servers ausgeführt wird.
    Code (Text):
    1.  
    2.    @Override
    3.     public void onEnable() {
    4.         log.info("Tutorial v1.0 by Benni1000 enabled!");
    5.     }
    6.  
    Jetzt sind wir an der Stelle angelang an der Auf den Befehl eines Users reagiert werden soll.
    Befor das möglich ist müsst ihr eine neue Datei anlegen die sogenannte plugin.yml. Die plugin.yml enthält informationen die euer Plugin beschreiben wie z.b Name, wo die MainKlasse ist version euere homepage, und eben auch auf welche Befehle euer Plugin hören soll. Achtung: Ihr benötigt die plugin.yml IMMER nicht nur wenn ihr ein Plugin entwickelt welches Befehlt hat.
    Macht einen Rechtsklick auf den Ordner SourcePackages. Jetzt wählt ihr New aus, dann geht ihr auf other, dort geht ihr in der Linken menüleiste runter bis zum Menüpunkt other und wählt dort den Menüpunkt YamlFile. Als Name müsst ihr “plugin” angeben, die endung .yml wird automatisch hinzugefügt. Jetzt fügt ihr folgendes ein:
    Code (Text):
    1.  
    2. name: Tutorial
    3. version: 1.0
    4. main: eu.benni1000.tutorial.Tutorial
    5. commands:
    6.   heal:
    7.     description: Heals a Player.
    8.     usage: /<command> username
    9.  
    Ihr müsst euren Packetpfad anpassen!
    Der Letzte Punkt des Pfades ist eure Main-Klasse, ihr müsst aber die endung .java weglassen!
    Wenn ihr keine befehle wollt dann könnt ihr auf alles unter dem main: punkt verzichten.
    Neue Befehle werden im Gleichen Schema einfach unten angehängt.
    Wichtig: Ihr dürft nur Leerzeichen in YAML dateien verwenden und keine TABs, sonst funktioniert die Datei nicht, und euer Server wird euer Plugin nicht aktivieren können.
    Jetzt wo wir das haben könnt ihr schon unseren Befehl einfügen. In diesem Fall haben wir oben den Befehl “/heal” definiert, der Leute heilen soll. Um das zu erreichen müssen wir die OnCommand Methode überschreiben. Die Struktur schaut am Anfang etwas komplex aus, sie ist es aber nicht.
    Fügt in den Code das ein:
    Code (Text):
    1.  
    2. @Override
    3.     public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    4.         return false;
    5.     }
    6.  
    Für euch wichtig ist, das euch in dieser Methode die Objekte sender,cmd und das array args zur verfügung stehen. Das Objekt sender enthält Informationen über den Absender des Objekt, unter anderem auch ob der Absender ein Spieler ist oder nicht. Das Objekt cmd enthält den übergebenen Befehl, ihr könnt auf ihn mit cmd.getName zugreifen. Das array args enthält alle argumente die euch übergeben wurden. Würde ich z.b “/heal Benni1000_ JemandAnderes” eingeben würde in args[0] der Name Benni1000_ stecken und in args[1] der Name JemandAnderes stecken.
     
    #1
  2. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    Da wir jetzt auf das heal command reagieren wollen müsst ihr eure methode wie folgt erweitern:
    Code (Text):
    1.  
    2. //Wenn der Befehl heal ist dann tue das unten stehende.
    3.         //Das hier wäre nicht nötig, da wir nur einen Befehl haben, ich habe es trotzdem eingebaut damit ihr seht
    4.         //was ihr bei mehreren Befehlen braucht.
    5.         if(cmd.getName().equalsIgnoreCase("heal")) {
    6.             //Erzeuge einen neuen Spieler variablen-name = pl
    7.             Player pl = null;
    8.             //Wenn der Absender des befehls ein Spieler ist
    9.             if(sender instanceof Player) {
    10.                 //Setze ihn in die variable pl ein.
    11.                 pl = Bukkit.getServer().getPlayer(sender.getName());
    12.             }
    13.             //Sonst
    14.             else {
    15.                 //Hier steht fest: Der Absender ist kein Spieler.
    16.                 //Wenn keine Argumente übergeben wurden
    17.                 if (args.length < 1) {
    18.                     //Die Konsole hat keine Spielernamen angeben, sie kann sich aber nicht selber heilen. Fehler.
    19.                     log.info("Bitte gib einen Spielername an!");
    20.                     return true;
    21.                 }
    22.                 //Die Konsole hat einen Namen angeben!
    23.                 else {
    24.                     //Hier überprüfen wir ob der Spieler der angegeben wurde online ist.
    25.                     if(Bukkit.getServer().getPlayer(args[0])!=null) {
    26.                         //dann heilen wir den Spieler der übergeben wurde.
    27.                         //In den fall 20 Halbe Herzen also das Minecraft Maximum
    28.                         Bukkit.getServer().getPlayer(args[0]).setHealth(20);
    29.                         log.info(args[0]+" wurde geheilt!");
    30.                         //Sendet eine Nachricht an einen Spieler das"§"zeichen wird zum färben von Nachrichten benutzt.
    31.                         Bukkit.getServer().getPlayer(args[0]).sendMessage("§2Du wurdest geheilt!");
    32.                     }
    33.                     //Das Spielerobjekt enthält "null" daten.
    34.                     else {
    35.                         log.info("Spieler konnte nicht gefunden werden!");
    36.                     }
    37.                     return true;
    38.                 }
    39.             }
    40.             //Hier haben wir eine Spieler den wir heilen können und keinen invaliden sender.
    41.             //Wenn die anzahl der übergebenen argumente nicht null ist
    42.             if(args.length > 0) {
    43.                 //Hier überprüfen wir ob der Spieler der angegeben wurde online ist.
    44.                 if(Bukkit.getServer().getPlayer(args[0])!=null) {
    45.                     //dann heilen wir den Spieler der übergeben wurde.
    46.                     //In den fall 20 Halbe Herzen also das Minecraft Maximum
    47.                     Bukkit.getServer().getPlayer(args[0]).setHealth(20);
    48.                     //Sendet eine Nachricht an einen Spieler das"§"zeichen wird zum färben von Nachrichten benutzt.
    49.                     pl.sendMessage("§2"+args[0]+" wurde geheilt!");
    50.                     //Sendet eine Nachricht an einen Spieler das"§"zeichen wird zum färben von Nachrichten benutzt.
    51.                     Bukkit.getServer().getPlayer(args[0]).sendMessage("§2Du wurdest geheilt!");
    52.                 }
    53.                 //Das Spielerobjekt enthält "null" daten.
    54.                 else {
    55.                     //Sendet eine Nachricht an einen Spieler das"§"zeichen wird zum färben von Nachrichten benutzt.
    56.                     pl.sendMessage("§4Spieler konnte nicht gefunden werden!");
    57.                 }
    58.                 return true;
    59.             }
    60.             //ansonsten
    61.             else {
    62.                 //Heile den Spieler der den Befehl abgesendet hat.
    63.                 //In den fall 20 Halbe Herzen also das Minecraft Maximum
    64.                 pl.setHealth(20);
    65.                 //Sendet eine Nachricht an einen Spieler das"§"zeichen wird zum färben von Nachrichten benutzt.
    66.                 pl.sendMessage("§2Du wurdest geheilt!");
    67.                 return true;
    68.             }  
    69.         }
    70.        return false;
    71.  
    Das schaut jetzt sehr viel aus, ist es aber nicht. Alles was mit // beginnt ist ein Kommentar. Ihr könnt alle Kommentare löschen wenn ihr möchtet, allerdings solltet ihr sie vorher Lesen, da sie euch den Quellcode erklären werden ;). wenn wir nach oben blicken, was haben wir neues kennen gelernt? Nun das wichtigste ist sicher der Zugriff auf das Spielerobjekt. Daran könnt ihr sehen wie einfach die Bukkitprogrammierung ist. Wenn ihr in Netbeans ein Objekt erstellt und versucht auf eine Methode des Objektes zuzugreifen, listet euch Netbeans alle verfügbaren Methoden auf. Da könnt ihr euch schön anschauen was ihr alles mit dem Objekt anstellen könnt. Was durchaus auch eine erwähnung wert ist dass das Zeichen “§” von Minecraft als Sonderzeichen gewertet wird.Ihr kennt das wahrscheinlich von Plugins wie essentials, das ihr bunt schreiben könnt. Nun essentials macht nichts anderes als die “&” Zeichen zu “§”zu ändern, das bewirkt bunten oder sich drehenden Text in Minecraft. Das heisst wenn ihe folgendes macht: pl.sendMessage("§2Du wurdest geheilt!"); Dann wird der Text “Du wurdest geheilt” in grün im chat stehen.

    === Üben ===
    Versucht doch mal als Übung einen kill Befehl einzubauen, der den angegeben Spieler tötet.
    Wenn kein Spieler angegeben wurde soll er den Absender töten.
    Die Lösung zu der Aufgabe findet ihr weiter unten.

    === Wo bekomme ich Informationen ===
    Um An Informationen für die Pluginprogrammierung zu bekommen könnt ihr die JavaDocs von Bukkit benutzen, das ist eine Liste von verfügbaren Objekten, und deren Methoden. Meistens ist auch noch ein Beispiel wie die methode zu verwenden ist mit dabei. Die Javadocs könnt ihr hier finden: http://jd.bukkit.org/doxygen/annotated.html
    Hier ist beispielsweise die Klasse Player:
    http://jd.bukkit.org/doxygen/d5/d74/interfaceorg_1_1bukkit_1_1entity_1_1Player.html
    Wie ihr sehen könnt findet ihr hier alle Methoden die wir für unseren Player “pl” weiter oben verwendet haben.

    === Mehr Tutorials ===
    Da das Thema ziemlich umfangreich ist, werde ich nicht noch mehr Text-Tutorials erstellen,
    sondern YouTube Videos, die all das enthalten, was in diesem Tutorial erklärt wurde und noch mehr.
    Meinen YouTube Kanal findet ihr hier: http://www.youtube.com/user/Benni1000games

    === Links ===
    Hier findet ihr den vollständigen Quellcode für das Projekt:
    http://benni1000.eu/tutorial/Tutorial.zip
    Hier findet ihr den Quellcode für das Plugin + kill Befehl:
    http://benni1000.eu/tutorial/Tutorial_mit_kill.zip
    Hier findet ihr dieses Tutorial als PDF zum Download:
    http://benni1000.eu/tutorial/Tutorial_PDF.pdf
    NetBeans Download:
    http://www.netbeans.org

    === Schlusswort ===
    Wenn ihr noch Fragen habt, könnt ihr sie gerne stellen.
    Solltet ihr Rechtschreibfehler oder finden, oder andere Verbesserungsvorschläge haben schreibt einfach hier drunter :p.

    Mfg Benni1000
     
    #2
  3. Smuil
    Online

    Smuil

    Danke Benni :)
    Aber das habe ich mir schon selbst beigebracht :D Trotzdem toller Thread :)
     
    #3
  4. volibal23
    Offline

    volibal23

    Registriert seit:
    18. Februar 2012
    Beiträge:
    958
    Minecraft:
    volibal23
    Gute Arbeit ;)
     
    #4
  5. mplusxl
    Online

    mplusxl

    Nice, man merkt das du dir mühe gegeben hast :).

    Schade das man kein "thx" geben kann ^____^.

    ~
    lg
     
    #5
  6. daKingchen
    Offline

    daKingchen Gesperrt

    Registriert seit:
    10. Februar 2012
    Beiträge:
    306
    Hast du toll erklärt :thumbsup:
    Ich wär ja fuer einen "Gefällt mir" Button :D
     
    #6
    Jamana_ gefällt das.
  7. Smuil
    Online

    Smuil

    Kurze Frage: Kannst du ein gutes kurzes Tutorial über Executor machen? Ich krieg das irgendwie nicht hin.....
     
    #7
  8. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    Kannst du mir beschreiben was du mit Executor meinst?
    Meinst du das man Befehle in extra Klassen packen kann oder meinst du das ausführen lassen von Befehlen von Spielern?
     
    #8
  9. MrTieger12
    Offline

    MrTieger12

    Registriert seit:
    11. April 2012
    Beiträge:
    2
  10. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    Was soll das?
    Hier geht es um Plugin-Programmierung, nicht um das finden von plugins, also was willst du mit diesem Link?
    Ausserdem habe ich oben das geschrieben:
     
    #10
  11. Smuil
    Online

    Smuil

    Ich meine z.B. wenn ich mein eigenes "Essentials" erstelle, wie ich jeden der einzelnen Commands in verschiedenen Javaclass packe.....bei mir spuckt der immer da Fehlermeldungen aus und ich kriege es einfach nicht hin :D

    An alle die Java lernen wollen ---> http://www.java-tutorial.org/methoden.html <---- Das ist ein gutes Tutorial meiner Meinung nach auf Deutsch, nur leider finde ich nicht die Zeit es perfekt durchzuarbeiten...
     
    #11
  12. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    #12
  13. Smuil
    Online

    Smuil

    Dankeschön :)
     
    #13
  14. ApFeLkErN
    Offline

    ApFeLkErN

    Registriert seit:
    13. Mai 2012
    Beiträge:
    147
    Muss ich das erste Bukkit hier runterladen ? Also 1.2.5-R4.1

    [​IMG]



    Und wenn ich auch New Project gehe weis ich leider nicht was ich dort im Menu auswählen soll.


    [​IMG]

    Wäre nett wenn mir jemand helfen würder Ahnung hat!
     
    #14
  15. ApFeLkErN
    Offline

    ApFeLkErN

    Registriert seit:
    13. Mai 2012
    Beiträge:
    147
    Muss ich das erste Bukkit hier runterladen ? Also 1.2.5-R4.1

    [​IMG]



    Und wenn ich auch New Project gehe weis ich leider nicht was ich dort im Menu auswählen soll.


    [​IMG]

    Wäre nett wenn mir jemand helfen würder Ahnung hat!
     
    #15
  16. Crafter6432
    Offline

    Crafter6432

    Registriert seit:
    22. Dezember 2011
    Beiträge:
    686
    Java EE, der aktuelle Bukkit-Build, Also 1.2.5-R4.1
     
    #16
  17. Crafter6432
    Offline

    Crafter6432

    Registriert seit:
    22. Dezember 2011
    Beiträge:
    686
    Java EE, der aktuelle Bukkit-Build, Also 1.2.5-R4.1
     
    #17
  18. ApFeLkErN
    Offline

    ApFeLkErN

    Registriert seit:
    13. Mai 2012
    Beiträge:
    147
    Wo finde ich den die Main-Class. Ist das die MANIFEST.MF
     
    #18
  19. ApFeLkErN
    Offline

    ApFeLkErN

    Registriert seit:
    13. Mai 2012
    Beiträge:
    147
    Wo finde ich den die Main-Class. Ist das die MANIFEST.MF
     
    #19
  20. Benni1000
    Offline

    Benni1000 Ehem. Teammitglied

    Registriert seit:
    4. Mai 2012
    Beiträge:
    1.408
    Du musst in der linken Liste ganz oben auf Java drücken und dort Java Application auswählen.
    Die Main Class legst du selbst fest?
    Sie muss JavaPlugin extenden und in der plugin.yml angegeben sein.
     
    #20
Status des Themas:
Es sind keine weiteren Antworten möglich.