[Frage] PlayerCommandEvent & Main-Class Problem

  • Hi,
    ich versuche in mein Plugin (Rising City Plugin - Kurz: rcp) ein Commandos zu erstellen! Aussehn: /rc [Kategorie] [Befehl] . Beispiele:


    Kategorie 1: info
    /rcp info playerinfo [Spielername]
    /rcp info worldinfo


    Kategorie 2: admin
    /rcp admin setadmin [Spielername]
    /rcp admin removeadmin [Spielername]
    /rcp admin ban [Playername]
    usw.


    Ich verstehe aber leider den Aufbaue nicht von dem cmd[]. Muss ich vielleicht sogar String[][] cmd = command.split(" ") machen, damit ich eins für /rcp und ein für die Kategorie hab? Und geht das überhaupt mit zweifachen Arrays? ?(

  • Du brauchst nur einmal den String Spliten.
    Dann teilt er die Eingabe aus dem Chat auf, Trennung ist dann immer das Leerzeichen


    Beispiel:
    /rcp info playerinfo [Spielername]


    /rcp = cmd[0]
    info = cmd[1]
    playerinfo = cmd[2]
    [Spielername] = cmd[3]


    Nun könntest du zb mit einer If Abfrage den Wert von cmd[1] auslesen und gucken ob der Spieler info oder admin geschrieben hat.

  • Bei mir sieht er etwa so aus:



    Ist das so richtig?

  • Soweit schon richtig nur solltest Du beachte, was passiert wenn der Spieler/admin beispielsweise


    folgenden Chatbefehl eingibt: "/rcp info"
    hier könntest Du unter umständen in der Zeile deines Quellcodes...

    Java
    if(cmd[2].equals("playerinfo")){ //Befehl 1
    //Code.........


    hier eine IndexOutOfBound-Exception riskieren, daher solltest Du immer die länge des cmdArrays prüfen.
    Nur rein vorsorglich solltest du bei administrativen Befehlen wie hier "setadmin", "removeadmin", "ban" usw... immer darauf
    achten, das der entsprechende Spieler auch die erforderlichen Rechte hat ergo -> event.getplayer().isAdmin()


    Ich habe Dir mal im folgenden dies als Quelltext zusammengestellt, wie ich es machen würde...


    viel Spass damit und ich hoffe gehofen zu haben ;)


    cu Blacky1004

    Programmierer machen nie Fehler! Sie bauen nur neue Features ein....

  • Danke für den Code,
    hat mir sehr weitergeholfen.


    Das einzige, was gefehlt hat zwischen den einzelnen case ist der break-Befehl! Aber sonst, ist er gut.



    if(cmd[0].equals("/rcp"){

    if(cmd[2].equals("worldinfo"){

    if(cmd[2].equals("playerinfo")

    if(cmd[2].equals("removeadmin")

    if(cmd[2].equals("ban")


    Über da fehlt übrigens am ende eine 2. Kammer ")"

  • Nun habe ich ein weiteres Problem.


    Mein Singelplayer will das Plugin nicht annehmen.
    Es sagt, dass es die Main-Class nicht findet.


    Inhalt plugin.yml


    Code
    name: RCPlugin
    main: de.pbplugins.RCPlugin
    version: 0.0.1
    author: PatrickBronke
    team: Rising-City-Team
    description: "Verwalten des Rising City Servers"
    license: N/A
    website: http://risingcityserver.de/
  • Vielleicht kurz vorweg zur string.split() Funktion: Damit wird ein String entsprechend eines bestimmten Trennzeichens aufgeteilt. Das PlayerCommandEvent bietet mit event.getCommand() ja Zugriff auf den vollständigen Command, den der Spieler eingegeben hat (zum Beispiel: "/ban player 60 griefing"). Nun würde, wenn man auf diesen String "split()" anwendet, und als Trennzeichen das Leerzeichen angibt, ein String-Array zurückgegeben, welches die einzelnen Wörter enthält, nämlich "/ban", "player", "60" und "griefing". Das Array hätte eine Länge von 4 (wie bei Programmiersprachen üblich fängt man beim Zugriff darauf aber bei 0 an zu zählen [Lua stellte eine Ausnahme dar, denn hier war der erste Index tatsächlich die 1]) ;)


    Beispiel:


    Wichtig ist immer, wie @Blacky1004 betont hat, vorher die Länge der Eingabe zu prüfen. Zumindestens dann, wenn mehrere Parameter erwartet werden, wie in unserem "/ban" Beispiel. Denn: Man muss auf alles vorbereitet sein, was ein Spieler eingibt. Denn auch wenn hier noch 3 zusätzliche Arugmente erwartet werden (player, 60 und griefing), kann es ja durchaus sein, dass der Spieler lediglich "/ban" eingibt, ohne irgendwelche Zusätze. Darauf muss man also vorbereitet sein, sonst wird eine ArrayIndexOutOfBoundsException geworfen. Momentan wird das zwar alles abgefangen, das heißt das Spiel läuft weiter, allerdings haben Exceptions einen sehr negativen Einfluss auf die Performance.
    Ab dem nächsten Update wird das Spiel beendet, sobald in einem Plugin zu viele Exceptions aufgetreten sind (was man zum Experimentieren natürlich ausschalten kann).


    Es sagt, dass es die Main-Class nicht findet.

    Du versuchst, das Plugin vom Spiel kompilieren zu lassen? Hast du in der config.properties Datei bei "plugins_jdk_path" den Pfad zum JDK angegeben? Hier müssen Escape-Character für Doppelpunkt und Backslashes angegeben werden, also zB plugins_jdk_path=C\:\\Program Files\\Java\\jdk1.8.0_91

  • Ich weis es jetzt, Nach dem Log, sucht das Plugin nach der RisingWorldAPI! Wir brauchen also nicht den Pfad von JDK, sondern von der Rising World API! (Hab herausgefunden, dass des dann auch nicht geht.) Weil die Imports bereits fehl schlagen!

  • Danke für den Log! Der war sehr hilfreich, das Problem ist tatsächlich, dass die API dem Classpath fehlt (zumindestens beim Client). Der Eintrag in der "config.properties" ist allerdings schon korrekt, dort muss das JDK angegeben werden.
    Ich habe eine Nightly in Steam hochgeladen, bitte probiere es damit nocheinmal aus. Um sie zu aktivieren, gehe via Rechtsklick auf RW in deiner Steam-Bibliothek -> Eigenschaften -> Betas -> wähle "testbranch - technical" (kein Code benötigt) und schließe das Fenster. Nach dem Download führe RW aus, und versuche erneut, eine Welt zu laden (aber wie gesagt, der Eintrag in der config.properties muss weiterhin den JDK Pfad beinhalten)

  • Danke für das Feedback! Ich bin nicht ganz sicher, ob diese Version auch 100%ig kompatibel mit den Servern ist (sollte sie aber eigentlich), und ein Serverupdate möchte ich deswegen nur ungerne forcieren, darum wird die Änderung sicherheitshalber wohl erst in das nächste Update einfließen (das aber vmtl. nicht lange auf sich warten lässt)^^

  • Hört sich super an.


    Jetzt habe ich noch eine Frage: Wie bekommt man die Playerinfos (z.B. Hunger usw.).



    JavaScript
    if(cmd[2].equals("playerinfo")){
    if(cmd.length == 4){
    String spielername = cmd[4];
    //...
    }
    }

    Bei den ... bleibe ich stehen, ich finde es einfach nicht heraus. Wo muss ich jetzt den String spielername hinzufügen und wie kann ich ihn abfragen?
    Am ende soll der Befehl so aussehen: /rcp info playerinfo <player>! /rcp, info und playerinfo habe ich bereits oben schon erledigt und es funktioniert. Mir fehlt nur noch <player>

  • hallo Patrick,


    Ich habe grad noch ein Fehler in meiner Hilfe gesehen was mir eigentlich selbst beruflich als Anwendungsentwickler peinlich sein sollte...
    Der Index eines Arrays/List beginnt immer bei 0! die Abfrage eines Counts(in C#) Length(JavaArray) , size(Java.ArrayList) Liefert nicht den letzten Index sondern die Anzahl der Elemente im Array.
    somit muss ich meine Hilfestellung etwas verbessern...

    Java
    if(cmd.length == 4){
    String spielername = cmd[3];
    //...
    }
    }

    Das war mein Fehler... sowas kommt davon wenn man schnell helfen will und im Hinterkopf andere Gedanken hat.
    Ich stehe Dir aber gerne auch per PN zur Verfügung!

    Programmierer machen nie Fehler! Sie bauen nur neue Features ein....

    Edited once, last by Blacky1004 ().

  • Habe wiedermal eine Frage zu dem PlayerCommandEvent:


    Ich möchte z.B. folgenden Befehl ausführen:


    /at yell <Nachricht> z.B. /at yell Das ist ein Test


    Folgendes erkennt mein Server:


    cmd[0] cmd[1] cmd[2] cmd[3] cmd[4] cmd[5]
    /at yell Das ist ein Test


    Ich möchte es aber so haben:


    cmd[0] cmd[1] cmd[2]
    /at yell Das ist ein Test


    Wie sage ich dem Befehl, das das letzte cmd (cmd[2]) ein Satz ist? Sonst kann ich keine Leerzeichen in Sätze schreiben!

Participate now!

Don’t have an account yet? Create a new account now and be part of our community!