Beiträge von Floppy012

    Hey,


    also vorab muss ich dir höchstwahrscheinlich den Spaß verderben und dir mitteilen, dass du aus dem Addon keine Requests an einen nicht-LabyMod Server senden darfst (Addons MUST NOT communicate with external servers which are unknown to us.)


    Wenn du ein Addon für deinen Server Programmieren willst und an den Rang des Spielers gelangen möchtest, wenn der Spieler auf deinem Server spielt, dann kannst du das über das Plugin Channels machen. Damit schickst du entweder ganz rudimentär einfach die Spieler-Infos vom Server an den Client oder du baust dir damit ein eigenes Protokoll auf welches du in einen Plugin Channel einkapselst.


    Und um deine eigentliche Frage zu beantworten:


    Du kannst in Java einfach Verbindungen zu deiner Schnittstelle aufbauen. Entweder "vanilla" über die URL-Klasse. Da müsstest du die Response dann selber aus dem InputStream lesen oder du nimmst dir eine Library (in Forge/Minecraft wirds sicherlich bereits was geben).


    Was das Design der Schnittstelle angeht, könntest du noch eine query möglichkeit einfügen (z.B. https://minescope.net/api/test…98-4ad4-a3bc-d95bf90f46e8). Daraus würde dann eine Query generiert die so aussieht: SELECT * FROM users WHERE uuid='5998c899-1198-4ad4-a3bc-d95bf90f46e8'


    Damit würde dein Endpoint dann nur die Informationen des Users returnen, der angefragt wurde. Beachte aber bitte hier, dass du keinesfalls den String von $_GET['uuid'] in deine Query packen solltest (stichwort SQL-Injection). Nutze hierfür einen Query Builder oder Prepared Statements.


    Und Clientseitige Datenbank-Verbindungen solltest du schleunigst wieder vergessen. Für Immer.

    Da soll es ja. Wenn ich Du bist ein hs schreibe, kommt das Wort hs vor. Ich habe statt contains mal startsWith genommen. Jetzt wird das Wort nicht blockiert wenn der Spieler Du bist ein hs schreibt.


    Trotz allem wird das Wort Versuchs immer noch blockiert. Da am Ende ein hs steht

    Willkommen in der Welt der Filterlisten. RegEx ist hier definitiv dein Freund. Compile die Expressions aber vorher (evtl. onEnable) und nicht bei jeder Chatnachricht.


    Dann kommts nur noch darauf an wie gut du in RegEx bist.


    Die Frage, die dann noch bleibt ist wie erkennst du ob mit hs nun "Hurensohn" gemeint ist oder ob das hs zu einem anderen Wort gehört. Leerzeichen allein bringts nicht (du .hs würde das umgehen). Du musst also nen guten mittelwert finden. Idealerweise würde ich lieber ne Beleidigung (durch den Filter) durchgehen lassen als den Chat unbrauchbar zu machen.

    1. Die onCommand Methode muss mit return true; abgeschlossen werden.

    2. Ich empfehle dir deine Classnames ohne Grossbuchstaben zu gestalten, da es sonst zu verwechslungen kommen kann. (Außer natürlich die Main Klasse.)

    3. Eine permission muss ein Punkt beinhalten, also


    LG GrafDev


    Zu 1.: Die onCommand Methode muss nicht mit return true; abgeschlossen werden. Was man dort zurückgibt entscheidet ob vom Server der in der plugin.yml festgelegte usage-string an den Spieler gesendet wird oder nicht. Die meisten Plugins machen das selber und deswegen wird dort in den meisten Fällen true zurückgegeben (was dem Server signalisiert, dass der Befehl erfolgreich ausgeführt wurde)


    Zu 2.: Den Java Code Conventions zufolge

    Zitat

    Class names should be nouns, in mixed case with the first letter of each internal word capitalized.

    sind Klassen- und Interfacenamen in MixedCase/CamelCase zu schreiben und mit einem Großbuchstaben zu beginnen. Mir würde auch auf anhieb nichts einfallen wo es zu Verwechselungen kommt, da Variablennamen (außer static final) mit kleingeschriebenen Buchstaben anfangen.


    Zu 3.: Permission-Nodes müssen afaik nicht zwangsweise einen Punkt beinhalten, es ist jedoch best practice seine Permission-Nodes so zu gestalten, dass keine Verwechselung mit Nodes eines anderen Plugins oder des Servers auftreten können. Außerdm bietet sich in diesem Zuge an die Nodes direkt zu namespacen. Wenn dann ein Admin einem Spieler vollzugriff auf dein Plugin gewähren will, dann muss er nicht jede einzelne Node zuweisen sondern kann dem Spieler eine Wildcard-Node (deinPlugin.*) zuweisen.


    Und als kleine Sidenote: Die Frage ist mittlerweile älter als drei Jahre. Ich gehe stark davon aus, dass das Problem bereits gelöst wurde :)

    Die Lösung ist:



    Du solltest deine Prepared Statements nur einmal "preparen" (nach Verbindungsaufbau) und nicht jedes Mal wenn du eine Abfrage machen willst. So wie du es jetzt hast verschenkst du mit dem preparen eines Statements nur Leistung.

    Du hast einen positive lookahead verwendet. Das ist quasi nen operator der matched aber ohne dass das gematchte zum finalen match dazugehört.


    foo(?=bar)



    Das matched bei foobar aber nicht bei foobaz. Es ist allerdings im match string nur foo vorhanden, da wir hier das positive lookahead verwendet haben.


    Das Äquivalent hierzu ohne positive lookahead wäre das:



    Dein Pattern macht das Positive Lookahead praktisch nutzlos, weil es sagt, dass entweder ein oder mehrere a kommen können oder kein a kommen kann:



    Effektiv hast du ein .*


    Es gibt zwei Wege wie du das vermutlich haben möchtest:


    .*(?=a)



    Hier wird alles gematched bis zum letzten a. Das letzte a wird allerdings nicht mit ins match genommen.


    .*a



    So wird alles bis zum letzten a inklusive des letzten a gematched.


    Regex kann manchmal ein bisschen verwirrend sein. Hoffe, dass die Antwort ein bisschen hilft.


    Grüße

    Naja. Idealerweise machst du Backwardscompatibility. Das ist wesentlich weniger aufwand, da du hier im gegensatz zur Forwardscompatibility nicht unmengen an game content nachrüsten musst. Allerdings hat Backwardscompatibility auch seine nachteile. Du musst dir was einfallen lassen was du mit Blöcken, Items, usw. machst die die älteren Versionen nicht implementiert haben. Wenn es dir jedoch nur um kompatibilität geht dann würde ich eher zu einer älteren Version tendieren und Forwardscompatibility bauen, dann ist es bei vielen Versionen wirklich nur protokoll.


    Von welchem Ende du letztlich anfängst hängt also davon ab was du genau erreichen willst.


    Sidenote: 1.8.9 <-> 1.9 ist der absolute clusterfck. Mojang hat da geändert wie Chunks vom Server an den Client übermittelt werden. Alles danach ist im Gegensatz dazu einfach.


    Wie du bereits sagtest, benötigst du in jedem Fall NMS. Und da würde ich definitiv auf decompiled gehen und auf keinen Fall irgendwas mit Reflections anfangen.


    Und damit wären wir auch schon beim ersten Punkt auf den du achten solltest: Performance. Bei bestimmten Dingen musst du aufpassen wie du Programmierst. Du kannst da recht schnell unbemerkt performance "verschenken". Manche Probleme bemerkt man dann erst unter Last, deswegen ist hier definitiv Wissen über die Eigenheiten vom MC Protokoll erforderlich (ein kleines Beispiel ist, dass 1.8er clients jeden client-Tick ein Movement packet schicken ab 1.9 wurde das rausgenommen).


    Das nächste ist: Sicherheit. Machst du Fehler kannst du dir unter Umständen Sicherheitslücken reinhauen, die es Angreifern in den Meisten Fällen erlauben den Server zu überlasten.


    Abschließend bleibt noch ein Verweis auf DIE Informationsquelle wenns ums MC-Protokoll geht: https://wiki.vg/ Dort findest du (zumindest für Java) eine komplette Spezifikation des Protokolls von allen Versionen und allem drumherum.


    Eine wichtige Seite wird die Liste der Protokollversionen sein. Dort siehst du die Protokollversion von jedem einzelnen Snapshot/Release. Von dort aus kommst du auf die Diffs in der Protokollspezifikation zwischen den Versionen. Hier z.B. die Protokolländerungen zwischen 1.8.9 und 1.9-pre4.


    Und damit einem nicht langweilig wird, ändert Mojang auch gerne mal Packet IDs. Sieht man schön im Beispiel von 1.8.9 -> 1.9. Ein weiteres Beispiel hier.

    Sieht verdammt stark danach aus als wäre con in MySQL null. Eine Ursache könnte sein, dass du connect() nicht aufrufst oder, dass connect() nicht verbinden kann, einen Fehler schmeißt und der Programmablauf dadurch nicht unterbrochen wird, weil du die exception abfängst und lediglich den stacktrace ausgibst.


    Am besten, du stellst sicher, dass überhaupt eine DB verbindung aufgebaut ist, bevor du den Server weiter starten lässt:


    Java
      public static void connect() throws SQLException {
            if (!isConnected()) {
                con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Waterfight?autoReconnect=true", "admin", "********");
                System.out.println("MySQL Verbunden!");
            }
          }


    Der Fehler sagt nicht zwangsweise aus, dass das Passwort selber das Problem ist. Eher, dass die Authentifizierung am Server mittels Passwort fehlgeschlagen ist. Das kann unter Anderem eine IP-Restriction als Ursache haben. Je nach dem wie Adminer auf den PG-Container zugreift, lässt er das durch (z.B. via Socket). Schau mal mit Adminer ob admin auf irgend eine IP begrenzt ist (127.0.0.1?). Falls ja, musst du dort die IP von der Bridge die deinen Host mit den Docker containern verbindet eintragen (ist standardmäßig irgendwas im 172er subnetz).

    ImageIO.read kann null zurückgeben (Docs). Dies passiert, da ImageIO nicht weiß, wie es den Datenstream dekodieren soll, da ImageIO sich den MIME Type anscheinend über die URL holt und nicht über Header o.Ä..


    Versuchs mal so im JoinMeCommand:

    Java
    imageToSend = ImageIO.read(new URL("http://cravatar.eu/avatar/" + p.getName() + "/8.png"));


    Zusätzlich solltest du einen null check einbauen, damit solche Exceptions nicht mehr vorkommen.


    Edit:

    Ich bin mir gerade nicht sicher ob BungeeCord commands async ausführt. Falls das nicht der Fall sein sollte, solltest du den Abruf des Bildes asynchron machen, da es ansonsten zu BungeeCord-Seitigen lags kommen könnte (nur BungeeCord kram betreffend).

    Sind denn die Koordinaten richtig? Pack ein paar debug nachrichten rein und schau was er genau macht. Guck in der Client log ob nicht eventuell ein Fehler beim Laden der Skins für die Skulls auftritt.


    Wir können dir schlecht helfen ohne, dass wir Informationen haben was genau passiert und was nicht.

    zuerst die Vm's runterfahren (qm shutdown <vmid>)

    Die VMs und Container brauchst nicht einzeln runterzufahren. Sobald der Host herunterfährt und der Daemon gestoppt wird, bekommen alle VMs und CTs ein shutdown signal. Der Daemon blockiert hierbei so lange das herunterfahren des Hosts, bis die VMs und CTs entweder alle von alleine gestoppt sind oder, falls konfiguriert, die maximale Shutdown-Time überschritten wurde, in diesem Fall würde der Daemon dann die VM killen was zu Datenverlust führen könnte.


    Mein PVE hängt an einer USV und bei einem Stromausfall wird einfach nur ein Shutdown aufm Host ausgeführt und alle Maschinen (Windows und Linux) fahren ordentlich herunter.


    Der Timeout lässt sich über *VM auswählen* -> Options -> Start/Shutdown Order -> Shutdown Timeout konfigurieren

    Ich finde die Idee eigentlich recht gut, jedoch für den Anfang zu groß aufgezogen. Du suchst in vielen Bereichen Leute, die zertifizierte Abschlüsse vorweisen können. Solche Leute findest Du nicht so einfach und erst recht nicht ehrenamtlich. Zusätzlich müssen diese Leute gut mit den Problemen anderer umgehen können. Das heißt z.B., dass man nicht genervt auf eine dumme Frage reagiert, etc.


    Zusätzlich muss so etwas beworben werden, dazu reicht es nicht die ganze Geschichte in ein paar Internetforen bekannt zu machen. An dieser Stelle würde ich versuchen Kooperationen mit Ausbildungsstätten und Berufsschulen einzugehen. Quasi an den Stellen an denen sich viele Einsteiger befinden.


    Das ganze muss jedoch professionell durchgeführt werden mit greifbaren Personen und idealerweise einem Verein oder einer gemeinnützigen Organisation, mit Regeln an die sich gehalten werden muss (auch seitens der Administration/Vereinsleitung). Dein Ziel sind überwiegend minderjährige, die auch gerne mal in einer Beratung Informationen preisgeben, die vielleicht nicht so direkt für fremde Ohren/Augen gedacht sind. In dem Fall sind dinge wie Schweigepflicht erforderlich. Und das ist erst die oberste Spitze des Eisberges.


    Ich habe mal ein bisschen durchs Forum geschaut und mir sind dort und auch hier in Deinen Beiträten so einige Rechtschreib- und Grammatikfehler aufgefallen (Bsp.: an einer Stelle schreibst du "Netiquette" an der anderen Stelle "Netikette" [ersteres ist korrekt] oder "... dem orangen Bereich" [so geschrieben würde sich das auf die Frucht beziehen] -> "... dem orangenen Bereich" [jetzt ist's die Farbe]).


    Wenn Du selber Probleme mit Rechtschreibung und Grammatik hast (LRS o.Ä.), dann solltest Du auf jeden Fall vorher jemanden drüber schauen lassen, bevor Du Dinge veröffentlichst.


    Also ich würde in Deinem Fall erst mal das Angebot verkleinern. Dann mit einer Vereinsgründung beschäftigen (was braucht ein Verein, was kostet es einen Verein zu Gründen, was sind die Pflichten, usw.), dann Verträge wie z.B. eine NDA anwaltlich aufsetzen lassen (die Templates aus'm Internet taugen für Deinen Fall nichts).


    Grüße

    Liegt vermutlich daran, dass unterschiedliche Cassandra Libs verwendet werden, die beide geshaded werden.


    Wenn ein Plugin eine Klasse importiert, dann sucht die Bukkit-API nach dieser Klasse. Hat es die Klasse gefunden, wird sie gecached. Wenn man jetzt zwei unterschiedliche Versionen in zwei unterschiedlichen Plugins nutzt und beide ihre Version shaden, dann kann es zu einem solchen Fehler kommen.


    An dieser Stelle wäre es gut, wenn man in beiden Plugins die gleiche Version der lib shaded.