Seite 1 von 2

Titles und TabList

BeitragVerfasst: So 28. Sep 2014, 01:41
von ilouHD
Die meiner Meinung nach mit der besten Änderungen (neben WorldBoarder) in Minecraft 1.8 -> Der Titel.

Nach langem suchen, bin ich auf diese Seite hier gestoßen, und möchte euch - für die, die wenig Englisch können, unter anderem - diese Seite mal mehr oder weniger auf Deutsch Übersetzen. Bitte lasst euch durch die Texte, Nachrichten, Titles, was auch immer nicht ablenken - Der Text kommt aus meinem SurvivalGames-Plugin.

Also fangen wir an:
Zu aller erst benötigen wir einen Spigot-Build AB Version #1628 und müssen diesen in unseren workspace einbinden. Ausserdem benötigen wir einen CraftBukkit 1.8-Build oder einen Spigot-Build ab Version #1628, für den Server. Da es aber keine CraftBukkit für die 1.8 gibt, ist ein Spigot-Build unvermeidlich.

1. Thema Haben wir die Spigot.jar eingebunden, können wir ans 1. Thema gehen. Wir modifizieren die TabList. Seit der 1.8 kann man der TabList einen so genannten "Header" und "Footer" geben. Die jenigen, die sich ein wenig mit HTML auskennen, wissen was gemeint ist. Für die, die es nicht wissen:
Footer: Der Footer ist ein bereich unten auf einer Webseite. Meistens sind dort Links zu AGB, FAQ, Slogans, oder Ähnliches aufzufinden.
Header: Als Header bezeichnet man den "Kopf" einer Seite. Dieser ist - wie beim Menschen auch - am oberen Teil einer Webseite aufzufinden. Es befindet sich meist ein Navigationsmenü, ein "Banner", oder Ähnliches an dieser Stelle.

Wie wir den setzen, ist ziemlich leicht. Zuerst müssen wir jedoch die Clientversion überprüfen, damit es zu keinen Fehlern kommt. Das machen wir in Spigot folgendermaßen:
Code: Alles auswählen
  1. if(((CraftPlayer) e.getPlayer()).getHandle().playerConnection.networkManager.getVersion() >= 47)

Wie man auf die 47 kommt, ist hier mehr oder weniger beschrieben. Ich werde dieses jetzt hier nicht erläutern.
Wenn der Spieler nun aber die ProtocolVersion 47 hat - sprich auf der Minecraft 1.8 spielt - können wir zum Beispiel Im PlayerJoinEvent den Header und Footer so setzen:
Code: Alles auswählen
  1.          IChatBaseComponent tabTitle = ChatSerializer.a("{\"text\": \"§4SurvivalGames §8Halloween-Special\"}");
  2.          IChatBaseComponent tabFooter = ChatSerializer.a("{\"text\": \"§4ClashCraft §8Dein ClashOfMinecraft\"}");
  3.          
  4.          PacketTabHeader tabHeader= new PacketTabHeader(tabTitle, tabFooter);
  5.          
  6.          ((CraftPlayer) e.getPlayer()).getHandle().playerConnection.sendPacket(tabHeader);

Ich erläutere:
Mit den so genannten IChatBaseComponents können wir einen neuen 'JSON String' - unseren Text - erstellen. Damit Minecraft weis, dass es ein Text ist, müssen wir in der Methode a des ChatSerializers in geschweiften Klammern sagen, dass es ein text, mit den und den 'Inhalten' ist. dafür sorgt bei uns das
Code: Alles auswählen
  1. "{\"text\": \"§4SurvivalGames §8Halloween-Special\"}"

Die '\' sorgen dafür, dass die ' " ' nicht in Java 'erkannt' werden, und das Ende eines 'Strings' angeben.

Haben wir das geschafft, sagen wir, dass die beiden IChatBaseComponents dem PacketTabHeader zugewiesen werden, und sendem dem Spieler das Packet. Ziemlich einfach, nicht?

2. Thema Nun will ich euch zeigen, wie ihr Titles senden könnt. Da diese erst in der Minecraft 1.8 hinzugefügt wurden, müssen wir - wer hätt's gedacht - die Version abfragen. Das machen wir wie oben bereits beschrieben.

2.1: Um einen Titel zu erstellen, brauchen wir erneut Packets. Damit ein Titel komplett funktioniert, muss er so aussehen:
Code: Alles auswählen
  1.                            IChatBaseComponent chatTitle = ChatSerializer.a("{\"text\": \"§4Map: " + " §8HalloweenSG\"}");
  2.                            PacketTitle Title = new PacketTitle(Action.TITLE, chatTitle);
  3.                            ((CraftPlayer) all.getPlayer()).getHandle().playerConnection.sendPacket(Title);


Wie man sieht, ist alles ziemlich Ähnlich. Auch hier benötigen wir die IChatBaseComponent und den ChatSerializer.
Der Unterscheid ist, dass das Packet 'PacketTitle' heißt. Dabei müssen wir eine Aktion angeben. Hier ist es die Action.TITLE. Damit sagen wir, dass es sich um einen Title, und nicht um einen Subtitle handelt. Dann übergeben wir noch unseren Text als 2. Argument und senden dem Spieler das Packet.
Um dem Spieler nun einen Subtitle zu senden, ändern wir ggf. den Text und ändern
Code: Alles auswählen
  1. PacketTitle Title = new PacketTitle(Action.TITLE, chatTitle);

in
Code: Alles auswählen
  1. PacketTitle Title = new PacketTitle(Action.SUBTITLE, chatTitle);


Wenn man nun aber einstellen möchte, dass es eingeblendet wird, kurz da bleibt, und wieder ausgeblendet wird, kann das folgendermaßen eingestellt werden:
Code: Alles auswählen
  1.                            PacketTitle length = new PacketTitle(Action.TIMES, 1*20, 3*20, 1*20);
  2.                            ((CraftPlayer) all.getPlayer()).getHandle().playerConnection.sendPacket(length);

Das PacketTitle besteht aus:
Argument 1: Action
Argument 2: Zeit in Ticks, zum Einblenden
Argument 3: Zeit in Ticks, wie lange es da ist
Argument 4: Zeit in Ticks, zum Ausblenden

Dabei ist zu beachten, dass Action.TIMES VOR Action.TITLE oder Action.SUBTITLE gesendet wird. Also, bevor der Spieler den Title oder den Subtitle gesendet bekommt.

Außerdem sind die Imports zu beachten:
'Action'(.TIMES / .TITLE / .SUBTITLE) ist ein Spigot-Import: org.spigotmc.ProtocolInjector.PacketTitle.Action

Ich hoffe ich konnte euch etwas helfen.
Mit freundlichen Grüßen,
ilouHD

Re: Titles und TabList

BeitragVerfasst: So 28. Sep 2014, 08:11
von Sep2703
Finde ich richtig nice von dir!

Wobei ich noch eine kleine Ergänzung habe:
Diese Strings:
ilouhd hat geschrieben:"{\"text\": \"§4SurvivalGames §8Halloween-Special\"}"

Das sind JSON-Strings.

(Für die, die es interessiert)

Re: Titles und TabList

BeitragVerfasst: So 28. Sep 2014, 09:16
von ilouHD
Sep2703 hat geschrieben:Finde ich richtig nice von dir!

Wobei ich noch eine kleine Ergänzung habe:
Diese Strings:
ilouhd hat geschrieben:"{\"text\": \"§4SurvivalGames §8Halloween-Special\"}"

Das sind JSON-Strings.

(Für die, die es interessiert)


Noch was dazu gelernt ;D
Werde es abändern.

//EDIT: Ich glaube ich habe es geändert.

Re: Titles und TabList

BeitragVerfasst: Do 25. Dez 2014, 22:48
von StealWonders
PacketTabHeader gibt e sbei mir nicht :(

Re: Titles und TabList

BeitragVerfasst: Do 25. Dez 2014, 22:51
von Sep2703
PacketPlayOutTitle wurde hinzugefügt.
Musst aber auf den Footer per Reflection zugreifen.

Für Tabliste gibt es auch neue NMS Klassen.

Re: Titles und TabList

BeitragVerfasst: Do 25. Dez 2014, 23:27
von Jofkos
ilouhd hat geschrieben:"{\"text\": \"§4SurvivalGames §8Halloween-Special\"}"
Gibt da so 'ne nette Klasse, die CraftChatMessage heißt. Die macht dir aus einem normalen String ein IChatBaseComponent (mit anklickbaren links, falls enthalten, wobei das hier egal ist):
- CraftChatMessage.fromString(String message, boolean keepNewLine) gibt ein IChatBaseComponent zurück
Finde Json hardcoded nicht wirklich schön, besonders, da man immer Anführungszeichen escapen muss.

Re: Titles und TabList

BeitragVerfasst: Fr 26. Dez 2014, 01:28
von ilouHD
Hä?
eclipse hat geschrieben:Type mismatch: cannot convert from IChatBaseComponent[] to IChatBaseComponent

in
Code: Alles auswählen
  1. CraftChatMessage.fromString("Hallo", false);

bei
Code: Alles auswählen
  1. IChatBaseComponent text = CraftChatMessage.fromString("Hallo", false);


Kannst du mir da helfen?

Re: Titles und TabList

BeitragVerfasst: Fr 26. Dez 2014, 03:43
von Summerfeeling
Wie wärs damit, mal n [0] dahinter zu klatschen um den 1. Eintrag des Arrays zu bekommen..?

Re: Titles und TabList

BeitragVerfasst: Fr 26. Dez 2014, 03:47
von ilouHD
Summerfeeling hat geschrieben:Wie wärs damit, mal n [0] dahinter zu klatschen um den 1. Eintrag des Arrays zu bekommen..?


OK - Das würde gehen. Teste es später, habe gerade alles aus gemacht :(

Re: Titles und TabList

BeitragVerfasst: Fr 26. Dez 2014, 16:44
von Jofkos
ilouHD hat geschrieben:
Summerfeeling hat geschrieben:Wie wärs damit, mal n [0] dahinter zu klatschen um den 1. Eintrag des Arrays zu bekommen..?


OK - Das würde gehen. Teste es später, habe gerade alles aus gemacht :(

Ich weiss nicht genau, warum es ein Array zurückgibt. Es ist in jedem fall nur ein IChatBaseComponent.