• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

PlugIn Integer richtig aus einer Config auslesen für if abfrage

Status
Für weitere Antworten geschlossen.

AconTM

Schafhirte
Registriert
15 Juni 2015
Beiträge
118
Alter
29
Diamanten
260
Minecraft
AconTM
Guten morgen,

ich habe aktuell folgendes Problem.. Ich sitze gerade an einem kleinen Projekt zum Abspeichern
von Homes in einer Config. Damit die User mehrere Homes erstellen können (und ich nicht schon
wieder mit Permission's alles einstellen muss ^^) verwende ich einen Integer in der Config der
die maximale Anzahl an Homes wiederspiegelt, die ein User setzen darf. Hier ist meine Abfrage:

Code:
if(cfg.getInt("Player." + uuid + ".max") >= 1)

als "cfg" definiere ich die Config & "uuid" ist die UUID des Spielers (das klappt alles auch) jedoch
will diese Abfrage nicht funktionieren ^^ Kennt jemand das Problem bzw vlt sogar eine bessere
Lösung? Ich würde ungerne auf Permission's wechseln, da es so etwas angenehmer ist für mein
System ^^


Lg. AconTM
 

Taminoful

Schafhirte
Registriert
3 August 2012
Beiträge
137
Diamanten
390
Minecraft
Taminoful
Code:
Player:
  cffb9abe-ef53-45cd-8a10-d31feb47704d:
    max: '1'

Das is mein Path bzw die Config, ich sehe da direkt keinen Fehler

Vielleicht schaust du dir deinen Code doch noch mal genauer an. Ich sehe da direkt den Fehler.
In .yml Dateien werden Integer ohne Anführungszeichen definiert, du benutzt hier allerdings einfache Anführungszeichen und somit keinen Integer.
 

BlackHole

Workaholic
Registriert
1 Juli 2012
Beiträge
752
Diamanten
0
Minecraft
BlackHole
Du musst die UUID als String definieren. Ansonsten kann es zu Errors kommen.

Wenn man weiß wie Typen in Java funktionieren, dann kann man ganz gut mit UUIDs arbeiten und diese mittels String-Verkettung "+" bei Bedarf automatisch in Strings umwandeln lassen. Wie oben dargestellt handelt es hier eher um Problem mit den Datentypen von YAML.
 

UnityGaming

Workaholic
Registriert
25 Oktober 2015
Beiträge
527
Alter
26
Diamanten
312
Minecraft
FastFelix771
Dein Path ist vermutlich einfach nicht korrekt und die Methode getInt() gibt 0 als return value zurück, da du keinen zweiten Parameter übergeben hast. Somit würde deine if-Abfrage als if(0 >= 1) evaluiert.
10 Punkte für Gryffindor! :dia:

@AconTM

Laut deinem Code müsste deine YAML Struktur so aussehen, damit das funktioniert wie du es willst:
Code:
Player.cffb9abe-ef53-45cd-8a10-d31feb47704d.max = 1

Um allerdings deine oben von dir beschriebene YAML Struktur abzufragen, müsste dein Code in etwa so aussehen:
Code:
int maxHomes = cfg.getConfigurationSection("Player").getConfigurationSection(uuid.toString()).getInt("max");

Du musst die UUID als String definieren. Ansonsten kann es zu Errors kommen.
In diesem Fall, Quark.
@BlackHole hat ganz recht;

Bei einer Verkettung von Strings (+) wird intern automatisch die toString() Methode aufgerufen, wenn das Objekt kein String ist.
Und da die UUID.toString() Methode einen validen String ausgibt, funktioniert das in diesem Fall einwandfrei.

Ich sehe da direkt den Fehler.
In .yml Dateien werden Integer ohne Anführungszeichen definiert, du benutzt hier allerdings einfache Anführungszeichen und somit keinen Integer.
Bin mir nicht mehr 100% sicher wie SnakeYAML das handhabt, aber wenn ich mich recht entsinne, dann rafft der Parser das von selbst und parsed einen Integer aus dem String.
 

Taminoful

Schafhirte
Registriert
3 August 2012
Beiträge
137
Diamanten
390
Minecraft
Taminoful
Bin mir nicht mehr 100% sicher wie SnakeYAML das handhabt, aber wenn ich mich recht entsinne, dann rafft der Parser das von selbst und parsed einen Integer aus dem String.
SnakeYAML benutzt folgendes Pattern um Integer zu resolven. In Kombination mit folgender Zeile, schließe ich daraus - ohne mich jetzt großartig mit dem Code auseinandergesetzt zu haben - dass dies nicht der Fall ist. Auch die Spezifikation zum von SnakeYAML verwendeten YAML processor (1.1), lässt nicht darauf schließen, dass eine automatische Konvertierung stattfindet. Aber man möge mich korrigieren, falls ich damit falsch liegen sollte. :)


10 Punkte für Gryffindor! :dia:
Wo kann ich denn hier meinen Kontostand einsehen, welche Prämien gibt es und wie kann ich diese "Punkte" nun für die Prämien einlösen? :3
 

TobiasLP

Minecrafter
Registriert
26 März 2016
Beiträge
17
Alter
25
Diamanten
300
Minecraft
TobiasLP
Guten Tag,

ist denn der Fehler eine NullpointerException? Ich würde dir empfehlen einen "try and catch"-Block zu verwenden.

Als Beispiel:
Code:
int homes;
try{
  homes = cfg.getInt("Player." + uuid + ".max");
} catch(Exception e) {
  homes = 0;
if(homes >= 1) {
...

Wenn du noch kein Home gesetzt hast, steht in der Config nicht dein Name. Wenn du dann versuchst, den Wert aus deiner Config zu laden, gibt es einen Fehler, da er versucht einen Wert rauszulesen, den es nicht gibt. Daher musst du einen Try(versuche) Block zu verwenden. Wenn es dort einen Fehler gibt (Also wenn er keinen Wert auslesen kann), dann soll er den Integer "homes" auf 0 setzen, da er noch keine Homes gesetzt hat!:)

Ich habe diesen Code nicht ausprobiert, er sollte aber eigentlich funktionieren!:)
Ich wünsche euch noch ein schönes Wochenende.
Tobias

PS.: Du solltest auch beim Speichern des Wertes einen Integer abspeichern!:) Wie oben gesagt musst du das so machen:
Code:
cgf.set(Path, newhomes);
//speichern

//Und nicht sowas als Beispiel:
cgf.set(Path, Integer.toString(newhomes);
 

UnityGaming

Workaholic
Registriert
25 Oktober 2015
Beiträge
527
Alter
26
Diamanten
312
Minecraft
FastFelix771
Wo kann ich denn hier meinen Kontostand einsehen, welche Prämien gibt es und wie kann ich diese "Punkte" nun für die Prämien einlösen?
Dazu bitte im Offtopic Forum den Thread "Larry der Woche" aufsuchen.
Die Prämien belaufen sich meist auf Kekse und Kekskrümel.
Eine Auszahlung ist allerdings erst ab 1.000.000 Punkten möglich - doch wenn es erstmal soweit ist, bekommst du die brandneue XY-Marke Kaffeemaschine (fast) gratis!

Daher musst du einen Try(versuche) Block zu verwenden. Wenn es dort einen Fehler gibt (Also wenn er keinen Wert auslesen kann), dann soll er den Integer "homes" auf 0 setzen, da er noch keine Homes gesetzt hat!:)
Das ist aber eine ziemliche Berserkertaktik.
Bin mir ziemlich sicher, dass es auch eine vorhandene has() Methode oder sowas in der Richtung gibt um das direkt prüfen zu können.
 

JOO200

Braumeister
Registriert
18 Dezember 2016
Beiträge
442
Diamanten
228
Wenn man im Quellcode von der ConfigurationSection nachschaut, dann findet man relativ rasch folgendes:
Code:
    public int getInt(String path) {
        Object def = this.getDefault(path);
        return this.getInt(path, def instanceof Number ? NumberConversions.toInt(def) : 0);
    }

    public int getInt(String path, int def) {
        Object val = this.get(path, def);
        return val instanceof Number ? NumberConversions.toInt(val) : def;
    }

Sollte der "Defaultwert" von dem Int nicht angegeben sein (=null), dann wird die Kontrolle, ob "def instanceof Number" ein false zurückliefern und man erhält eine "0" bei dem Versuch, mit "config.getPath(...)" die Variable auszulesen.

Demnach ist das try-catch Konstrukt nicht von Nöten. (Auch bei einem einfachen "section.get(...)" würde höchstens "null" rauskommen und kein NPE)

Zu dem Beitrag von @UnityGaming :
Bist du dir sicher, dass dein Konstrukt:
Code:
config.getConfigurationSection(...).getConfigurationSection(...).getInt(...);
wirklich notwendig ist? Ich habe in einigen meiner Projekte den Pfad einfach mit Punkten aneinander gekettet und was soll ich sagen - bei mir funktioniert es einwandfrei.
Nachdem ich eine MInute im Source-Code gewühlt hab, hab ich auch die Erklärung, warum meine Variante funktioniert. Im Code der MemorySection wird das gemacht, was du manuell machen wolltest:
Code:
public Object get(String path, Object def) {
        Validate.notNull(path, "Path cannot be null");
        if (path.length() == 0) {
            return this;
        } else {
            Configuration root = this.getRoot();
            if (root == null) {
                throw new IllegalStateException("Cannot access section without a root");
            } else {
                char separator = root.options().pathSeparator();
                int i1 = -1;
                Object section = this;

                int i2;
                while((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
                    section = ((ConfigurationSection)section).getConfigurationSection(path.substring(i2, i1));
                    if (section == null) {
                        return def;
                    }
                }

                String key = path.substring(i2);
                if (section == this) {
                    Object result = this.map.get(key);
                    return result == null ? def : result;
                } else {
                    return ((ConfigurationSection)section).get(key, def);
                }
            }
        }
    }

Ich vermute den Fehler von @AconTM evtl. darin, dass die Configuration nicht geladen wurde oder anderes nicht passt, an seiner Abfrage erkenn ich keinen Fehler.
 

UnityGaming

Workaholic
Registriert
25 Oktober 2015
Beiträge
527
Alter
26
Diamanten
312
Minecraft
FastFelix771
Ich habe in einigen meiner Projekte den Pfad einfach mit Punkten aneinander gekettet und was soll ich sagen - bei mir funktioniert es einwandfrei.
Nachdem ich eine MInute im Source-Code gewühlt hab, hab ich auch die Erklärung, warum meine Variante funktioniert. Im Code der MemorySection wird das gemacht, was du manuell machen wolltest:
Hmm interessant.... das kannte ich bisher immer anders. Ist zugegeben aber schon lange her, dass ich das überhaupt benutzt habe... bin mittlerweile auf XML (JAXB) umgestiegen.

Gut zu wissen, dass sowas geht.
Damals kam mir das ganze immer so unhandlich vor.
 
Status
Für weitere Antworten geschlossen.
Oben