Beiträge von Rincewind34

    So weit ich weiß wird das von Spigot ohne hin getracked. Ich weiß jetzt nicht, was du genau vor hast, aber vielleicht wäre das ja eine Überlegung wert. Da musst du mal googeln und dich in den Docs um sehen. Der Client hat ja aber auf jeden Fall diese Statistik und der Server kann sie auf jeden Fall verwenden, um Advancements umzusetzen etc.
    Das wäre dann auf jeden Fall eine performante und bereits implementierte Lösung.


    ~ Rincewind

    Das 'Ä' an sich ist kein Problem. Mach einfach Anführungszeichen um die Description, dann funktioniert das mit Umlauten. Wie ich sehe benutzt du Eclipse, da gibt es ein Plugin YAMLEdit oder so, damit passiert dir das dann nicht nochmal ;)


    ~ Rincewind

    Scoreboardplugins haben eine große Schwachstelle: Die Methode player#setScoreboard(...). Jeder Spieler kann nur "Mitglied" in einem Scoreboard sein. In den meisten Fällen soll jeder Spieler ein individuelles Scoreboard sehen, was bedeutet, dass jedem Spieler ein individuelles Scoreboard erstellt wird.

    Wenn das jetzt mehrere Plugins machen (bspw. Scoreboard und Tablist) machen die sich beide gegenseitig kaputt.

    Glücklicherweise gibt es ein einfaches Workaround. Irgendwo in deinem Code wirst du Bukkit#getNewScoreboard(..) machen. Das ersetzt du durch:

    Code
    Player player; // Den Spieler musst du gegeben haben
    Scoreboard scoreboard; // Das möchtest du bekommen
    if (player.getScoreboard() == Bukkit.getMainScoreboard()) {
    scoreboard = Bukkit.getNewScoreboard(...);
    player.setScoreboard(scoreboard);
    } else {
    scoreboard = player.getScoreboard();
    }


    Das sollte es schon gewesenen sein. Dieser Codeschnippsel ist mit den meisten anderen Plugins, die nicht darauf achten, kompatibel. Wenn es immer noch nicht geht, achte mal darauf, dass dein Plugin als letztes Enabled wird, und die Eventpriorities auf HIGHEST gesetzt sind.

    ~ Rincewind

    Wir wirklich das BlockExplodeEvent gefeuert? Da würde ich einmal einen Debug machen.
    Schick uns mal die klasse, in der die Methode #getResetBlocks ist, eventuell bringst du da ein paar Referenzen durcheinander.

    Ich weiß nicht, ob SMS der richtige Weg ist. Spätestens beim Video wars das dann (oder kann man Videos per SMS versenden; frage in die Runde?!).

    Wie genau sieht denn die Infrastruktur bei deinen Bienen aus? Gibt es da Netz, dann könnte man was mit einem Telekomstick basteln und natürlich Stromversorgung. Wärst du dort auf Batterie / Akku angewiesen?

    Solche Sachen müssen auf jeden Fall erst geklärt werden, bevor du dir über die konkrete Umsetzung Gedanken machst. Nochmal ein kleiner Denkanstoß: Das ganze klingt für mich nach eine Art Smarthome. Vielleicht findest du ja Komponenten, mit denen du dir was zusammen basteln kannst.

    Mit freundlichen Grüßen,

    ~ Rincewind

    Ich bin mir nicht mehr 100% sicher, aber ich glaube das "Flackern" wurde primär durch das Aufrufen von Player#setScoreboard(...) mit immer neuen Scoreboard-Instanzen erzeugt. Da musst du mal in die Protokollspezifikation gucken, welches Packet oder Packetkonfiguration dann nur einmal senden darfst, damit es nicht flackert.


    ~ Rincewind

    Hierzu wollte ich doch auch noch eine Kleinigkeit sagen, das ist etwas das Anfänger häufig vergessen: *Resourcen aufräumen*
    In diesem Fall also nicht das PlayerQuitEvent vergessen und den Eintrag aus der HashMap wegräumen.

    Alternativ wäre auch eine WeakHashMap und Player als Key möglich. Das ist aber grade in diesem Fall warscheinlich nicht die beste Lösung, da man sich darauf verlassen müsste, dass auch alle anderen Plugins (und der Server selbst) alle Referenzen zum Player aufräumen, aber ist für den einen oder anderen in einem anderen Kontext ja eventuell ein Denkanstoß ;)

    Mit freundlichen Grüßen,

    Rincewind

    Hier mal noch ein Code Beispiel wie man das in etwa machen würde.

    Dazu noch die etwas fortgeschrittenere Version mit Lambda / Java 11


    Ich würde anstatt der "DEFAULT"-Variante die Methode String#join(...) empfehlen. Die macht genau das, was du möchtest.

    ~ Rincewind

    Soo, Halleluja, wenn irgendwer sonst das Problem mal haben sollte:

    Um das Szenario einmal zusammen zufassen:
    - Eine Util-Klasse soll den ganzen Kram mit den Statements regeln (gerne, weil es deutlich weniger Programmieraufwand erfordert, auch unter der Prämisse, dass die Statements immer neu angelegt werden, und nicht mehrmals benutzt werden, so wie von mir vorgeschlagen).
    - Bei einem Update kein Problem: Die Methode bekommt alle Parameter, Statement wird erzeugt, ausgeführt, geschlossen.
    - Bei Selects gibt es das Problem mit dem Freigeben ( Aquaatic hat das angesprochen): Die Methode bekommen eventuelle Suchparameter, Statement wird erzeugt, ausgeführt, ResultSet wird returned und das Statement gammelt auch wenn das ResultSet geschlossen wird noch in der ConnectionPipeline.

    ABER: Es gibt eine Methode Statement#closeOnCompletion(), die bei den Selects alle Probleme löst. Sie setzt eine Flag in einem Statement, wodurch das Statement automatisch geschlossen wird, wenn alle aus ihr erzeugten ResultSets geschlossen werden. Das heißt in der Nutzung von der Util-Klasse muss nur noch auf das Schließen des ResultSets geachtet werden.

    Ich glaube nach wie vor nicht, dass das Software-Architektonisch die beste Lösung ist, aber allen Anfängern würde ich das auf jeden Fall empfehlen.

    ~ Rincewind

    Die Lösung dafür ist aber nicht, einfach das Statement nicht zu schließen, wie Rincewind empfiehlt

    es ist nämlich mindestens good practice alles zu schließen, was geht, um Memory Leaks zu vermeiden.

    Das habe ich wohl nicht ganz eindeutig kommuniziert, weil ich geschrieben habe, es sei das einzige, was er ändern müsste. Meine Lösung wäre nach wie vor das PrepraredStatement mehrmals zu benutzen.

    Ich kann an der pom jetzt so spontan keinen Fehler finden, würde dir aber empfehlen, einmal die JAR zu unzipen, und mir mal anzugucken, was (und ob überhaupt) an Libraries in die JAR kopiert wird.
    Meines Wissens legt das Shade-Plugin eine Version ohne die Shades an. Bist du dir sicher, dass du die richtige JAR verwendest?

    EDIT:
    Was mir doch aufgefallen ist, ist dass du den "finalName" auf "project.name" setzt. Diese Property finde ich deiner pom aber gar nicht. Was mich zu meinem nächsten Lösungsansatz führt: Streich die pom mal so gut es geht zusammen, und probiere erstmal an einem Minimalbeispiel das Shadeplugin zum laufen zu kriegen (wenn es denn daran liegt).

    Ein kleiner Verbesserungsvorschlag für die Datenbankstruktur:
    Ich würde das Feld "leader" in der Tabelle für Clans weglassen, und eher ein neues Feld "role" in der Tabelle für die Spielerzuordnung hinzufügen. Auf diese Weise vermeidest du die Konfusion, ob der Leader noch zusätzlich in der Spielerzuordnung steht (was programmiertechnisch deutlich angenehmer wäre, aber dafür redundant), oder nicht, wodurch die Abfrage, ob ein Spieler sich in einem Clan befindet, deutlich aufwendiger werden würde.

    Das wäre darüber hinaus eine nachhaltigere Lösung, wenn du mal verschiedene Ränge in dem Clan implementieren willst.


    ~ Rincewind

    Eine SQL Injection ist in deinem Fall ohne hin eher schwierig. Du darfst nicht vergessen, dass der Spieler auch die Möglichkeit haben muss, eine String irgendwo einzugeben. Also wenn du jetzt nicht grade irgendwas total abgefahrenes mit StringInputs via ChatBox implementiert hast, sondern der Spieler nur hin und wieder Geld von einem Konto abbucht, kann dir da quasi nichts passieren.
    Du musst halt bei dem Validieren des Userinputs ein bisschen mehr aufpassen.

    Aber auch mein Ratschlag: Verwende einfach PreparedStatements. Die sind darüber hinaus, wenn man es richtig anstellt, nicht nur sicherer, sondern auch performanter (hier dazu ein kleiner Beitrag https://stackoverflow.com/ques…dstatement-multiple-times). Dein Code wird dadurch sicherer und Nachhaltiger.

    Das einzige, was du an deinem Code oben ändern musst, ist halt dein PreparedStatement in der "query" Methode nicht zu schließen, sondern nur das ResultSet nach der Auswertung.

    Das ist nicht irgendeine "Third Party Libary", sondern eine "Default Libary" in Java seit Java 7, ich kann dir versichern es liegt nicht daran xD

    https://docs.oracle.com/javase…/api/java/util/Timer.html


    Direkt der erste Satz. Ich habe nicht gemeint, dass die Lib eventuell nicht funktioniert. (Das kann man ohne Zweifel ausschließen, da nach eine reconnect der richtige block angezeigt wird.) Meine These ist, dass das Problem durch den neuen Thread entsteht. Die #getBlock Methode sollte man ohne hin nur im Mainthread aufrufen. Unterumständen lädt die Methode nämlich einen ganzen Chuck nach. Spätestens dann fliegt dir das ganze um die Ohren.


    XCraft_MC Ich denke jedoch das du einen Fehler in deinem Timer hast. Den wenn ich das richtig gelesen habe führst du den Task einmal nach 5000 ms aus und dann startet er eine Schleife die ernuet alle 5000 ms ausgeführt wird! Ist das so gewollt? Ich denke du willst nur einen Block wieder in seinen Ursprungs Zustand zurücksetzten?

    Das, was XCraft_MC mit den Timern macht, ergibt zwar keinen Sinn, aber wenn das passiert, was du beschreibst, sollte der Code trotzdem funktionieren.


    Mit freundlichen Grüßen,

    Rincewind