├── .gitignore ├── deploy.bat ├── CHANGELOG.md ├── src └── main │ └── java │ └── io │ └── github │ └── theluca98 │ └── textapi │ ├── ServerPackage.java │ ├── ActionBar.java │ └── Title.java ├── pom.xml ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | *.iml -------------------------------------------------------------------------------- /deploy.bat: -------------------------------------------------------------------------------- 1 | mvn clean javadoc:jar source:jar deploy -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### TextAPI Changelog 2 | The full changelog can be found in the 3 | [**Releases**](https://github.com/TheLuca98/TextAPI/releases) 4 | page on GitHub. -------------------------------------------------------------------------------- /src/main/java/io/github/theluca98/textapi/ServerPackage.java: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of TextAPI 2.0. 3 | Copyright (c) 2015 Luca P. 4 | 5 | TextAPI is free software: you can redistribute it and/or modify it under the 6 | terms of the GNU Lesser General Public License as published by the Free 7 | Software Foundation, either version 3 of the License, or (at your option) any 8 | later version. 9 | 10 | TextAPI is distributed in the hope that it will be useful, but WITHOUT ANY 11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 | A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License along 16 | with TextAPI. If not, see . 17 | */ 18 | package io.github.theluca98.textapi; 19 | 20 | import org.bukkit.Bukkit; 21 | 22 | enum ServerPackage { 23 | 24 | MINECRAFT("net.minecraft.server." + getServerVersion()), 25 | CRAFTBUKKIT("org.bukkit.craftbukkit." + getServerVersion()); 26 | 27 | private final String path; 28 | 29 | ServerPackage(String path) { 30 | this.path = path; 31 | } 32 | 33 | public static String getServerVersion() { 34 | return Bukkit.getServer().getClass().getPackage().getName().substring(23); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return path; 40 | } 41 | 42 | public Class getClass(String className) throws ClassNotFoundException { 43 | return Class.forName(this.toString() + "." + className); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | io.github.theluca98 6 | TextAPI 7 | 1.12.2-R2.2 8 | jar 9 | 10 | 1.7 11 | 1.7 12 | UTF-8 13 | 14 | 15 | 16 | org.bukkit 17 | bukkit 18 | 1.12.2-R0.1-SNAPSHOT 19 | 20 | 21 | 22 | 23 | spigot-repo 24 | https://hub.spigotmc.org/nexus/content/groups/public/ 25 | 26 | 27 | 28 | 29 | luca98-plugins 30 | https://api.bintray.com/maven/luca98/plugins/TextAPI/;publish=1 31 | 32 | 33 | 34 | clean install javadoc:javadoc 35 | TextAPI 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-javadoc-plugin 40 | 3.0.0-M1 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TextAPI ![JDK 1.7](https://img.shields.io/badge/JDK-1.7-orange.svg) ![Bukkit 1.12.2](https://img.shields.io/badge/Bukkit-1.12.2-yellow.svg) 2 | 3 | ### _Title and action bar APIs for Bukkit._ 4 | 5 | At the moment, Bukkit and Spigot API do not provide a way to use two important features that have been available since the 6 | release of Minecraft 1.8: titles and custom action bar messages. This extremely lightweight library aims to provide developers 7 | with an easy way to use those features, without having to mess with NMS or CraftBukkit internals. 8 | 9 | ## Use with Maven 10 | If you use Maven, we recommend adding TextAPI as a dependency in the `` section of your POM: 11 | ```xml 12 | 13 | io.github.theluca98 14 | TextAPI 15 | 1.12.2-R2.2 16 | 17 | ``` 18 | You can also allow Maven to automatically download TextAPI by adding our repository to the `` section: 19 | ```xml 20 | 21 | textapi-repo 22 | https://dl.bintray.com/luca98/plugins/ 23 | 24 | ``` 25 | **Use the [Maven Shade Plugin](https://maven.apache.org/plugins/maven-shade-plugin) to include TextAPI in your plugin JAR.** 26 | 27 | ## Download 28 | For those who wish to import the library manually via the IDE instead of using Maven, a pre-compiled JAR can be downloaded from 29 | the [Releases](https://github.com/TheLuca98/TextAPI/releases) page. 30 | 31 | ## Tutorial 32 | Creating a Title instance and sending it to a player is very simple: 33 | ```java 34 | Title title = new Title(title, subtitle, fadeIn, stay, fadeOut); 35 | title.send(player); 36 | ``` 37 | Action bar messages work similarly: 38 | ```java 39 | ActionBar bar = new ActionBar("Hello world"); 40 | bar.send(player); 41 | ``` 42 | The full JavaDocs are automatically generated when compiling the project. 43 | 44 | ## Compile 45 | If you have [Git](https://git-scm.com) and [Maven](https://maven.apache.org) installed, downloading and compiling TextAPI is 46 | fairly easy: 47 | ``` 48 | git clone https://github.com/TheLuca98/TextAPI.git 49 | cd TextAPI 50 | mvn 51 | ``` 52 | This will compile and install TextAPI into your local Maven repository as well as generating the JavaDocs, which you will find 53 | in the subdirectory `target/site/apidocs`. 54 | 55 | ## Notes 56 | Because this plugin doesn't directly depend on NMS classes thanks to reflection, except in the case of major changes, it should 57 | be compatible between Minecraft/Spigot updates. If it does break, I will try to update it as soon as possible (no promises 58 | though). 59 | 60 | ## License 61 | This library is published under the terms of the GNU Lesser General Public License, version 3. 62 | -------------------------------------------------------------------------------- /src/main/java/io/github/theluca98/textapi/ActionBar.java: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of TextAPI 2.0. 3 | Copyright (c) 2015 Luca P. 4 | 5 | TextAPI is free software: you can redistribute it and/or modify it under the 6 | terms of the GNU Lesser General Public License as published by the Free 7 | Software Foundation, either version 3 of the License, or (at your option) any 8 | later version. 9 | 10 | TextAPI is distributed in the hope that it will be useful, but WITHOUT ANY 11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 | A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License along 16 | with TextAPI. If not, see . 17 | */ 18 | package io.github.theluca98.textapi; 19 | 20 | import com.google.common.base.Preconditions; 21 | import org.bukkit.Bukkit; 22 | import org.bukkit.entity.Player; 23 | import org.json.simple.JSONObject; 24 | 25 | /** 26 | * Represents a message displayed above the hotbar. 27 | * 28 | * @author Luca 29 | */ 30 | public class ActionBar { 31 | 32 | /** 33 | * Used to toggle debug messages. Disabled by default. 34 | * 35 | * @deprecated No longer in use. 36 | */ 37 | @Deprecated 38 | public static boolean DEBUG; 39 | 40 | private JSONObject json; 41 | 42 | /** 43 | * Constructs an {@link ActionBar} object based on plain text. 44 | * 45 | * @param text Text to display. 46 | */ 47 | public ActionBar(String text) { 48 | Preconditions.checkNotNull(text); 49 | this.json = Title.convert(text); 50 | } 51 | 52 | /** 53 | * Constructs an {@link ActionBar} object based on JSON-formatted text. 54 | * 55 | * @param json Text to display Must be in /tellraw JSON format. 56 | */ 57 | public ActionBar(JSONObject json) { 58 | Preconditions.checkNotNull(json); 59 | Preconditions.checkArgument(!json.isEmpty()); 60 | this.json = json; 61 | } 62 | 63 | /** 64 | * This method has been kept just to ensure backwards compatibility with older versions of TextAPI. 65 | * It is not supported and will be removed in a future release. 66 | * 67 | * @param player The player to send the message to. 68 | * @param message The message to send. 69 | * @deprecated Please create a new {@link ActionBar} instance instead. 70 | */ 71 | @Deprecated 72 | public static void send(Player player, String message) { 73 | new ActionBar(message).send(player); 74 | } 75 | 76 | /** 77 | * This method has been kept just to ensure backwards compatibility with older versions of TextAPI. 78 | * It is not supported and will be removed in a future release. 79 | * 80 | * @param message The message to send. 81 | * @deprecated Please create a new {@link ActionBar} instance instead. 82 | */ 83 | @Deprecated 84 | public static void sendToAll(String message) { 85 | new ActionBar(message).sendToAll(); 86 | } 87 | 88 | /** 89 | * Sends an action bar message to a specific player. 90 | * 91 | * @param player The player to send the message to. 92 | */ 93 | public void send(Player player) { 94 | Preconditions.checkNotNull(player); 95 | try { 96 | Class clsIChatBaseComponent = ServerPackage.MINECRAFT.getClass("IChatBaseComponent"); 97 | Class clsChatMessageType = ServerPackage.MINECRAFT.getClass("ChatMessageType"); 98 | Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player); 99 | Object playerConnection = entityPlayer.getClass().getField("playerConnection").get(entityPlayer); 100 | Object chatBaseComponent = ServerPackage.MINECRAFT.getClass("IChatBaseComponent$ChatSerializer").getMethod("a", String.class).invoke(null, json.toString()); 101 | Object chatMessageType = clsChatMessageType.getMethod("valueOf", String.class).invoke(null, "GAME_INFO"); 102 | Object packetPlayOutChat = ServerPackage.MINECRAFT.getClass("PacketPlayOutChat").getConstructor(clsIChatBaseComponent, clsChatMessageType).newInstance(chatBaseComponent, chatMessageType); 103 | playerConnection.getClass().getMethod("sendPacket", ServerPackage.MINECRAFT.getClass("Packet")).invoke(playerConnection, packetPlayOutChat); 104 | } catch (Throwable e) { 105 | throw new RuntimeException(e); 106 | } 107 | } 108 | 109 | /** 110 | * Sends an action bar message to all online players. 111 | */ 112 | public void sendToAll() { 113 | for (Player player : Bukkit.getOnlinePlayers()) { 114 | send(player); 115 | } 116 | } 117 | 118 | /** 119 | * Changes the text to display. 120 | * 121 | * @param text Text to display. 122 | */ 123 | public void setText(String text) { 124 | Preconditions.checkNotNull(text); 125 | this.json = Title.convert(text); 126 | } 127 | 128 | /** 129 | * Changes the text to display. 130 | * 131 | * @param json Text to display. Must be in /tellraw JSON format. 132 | */ 133 | public void setJsonText(JSONObject json) { 134 | Preconditions.checkNotNull(json); 135 | Preconditions.checkArgument(!json.isEmpty()); 136 | this.json = json; 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /src/main/java/io/github/theluca98/textapi/Title.java: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of TextAPI 2.0. 3 | Copyright (c) 2015 Luca P. 4 | 5 | TextAPI is free software: you can redistribute it and/or modify it under the 6 | terms of the GNU Lesser General Public License as published by the Free 7 | Software Foundation, either version 3 of the License, or (at your option) any 8 | later version. 9 | 10 | TextAPI is distributed in the hope that it will be useful, but WITHOUT ANY 11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 | A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License along 16 | with TextAPI. If not, see . 17 | */ 18 | package io.github.theluca98.textapi; 19 | 20 | import com.google.common.base.Preconditions; 21 | import org.bukkit.Bukkit; 22 | import org.bukkit.entity.Player; 23 | import org.json.simple.JSONObject; 24 | 25 | /** 26 | * Represents a title that appears at the center of the screen. 27 | * 28 | * @author Luca 29 | */ 30 | public class Title { 31 | 32 | /** 33 | * Used to toggle debug messages. Disabled by default. 34 | * 35 | * @deprecated No longer in use. 36 | */ 37 | @Deprecated 38 | public static boolean DEBUG; 39 | private JSONObject title, subtitle; 40 | private int fadeIn, fadeOut, stay; 41 | 42 | /** 43 | * Constructs a {@link Title} object. 44 | * 45 | * @param title The text of the main title. 46 | * @param subtitle The text of the subtitle. 47 | * @param fadeIn The fade-in time of the title (in ticks). 48 | * @param stay The stay time of the title (in ticks). 49 | * @param fadeOut The fade-out time of the title (in ticks). 50 | */ 51 | public Title(String title, String subtitle, int fadeIn, int stay, int fadeOut) { 52 | this.title = convert(title); 53 | this.subtitle = convert(subtitle); 54 | this.fadeIn = fadeIn; 55 | this.fadeOut = fadeOut; 56 | this.stay = stay; 57 | } 58 | 59 | /** 60 | * Constructs a {@link Title} object. 61 | * 62 | * @param title The text of the main title. Must be in /tellraw JSON format. 63 | * @param subtitle The text of the subtitle. Must be in /tellraw JSON 64 | * format. 65 | * @param fadeIn The fade-in time of the title, in ticks. 66 | * @param stay The stay time of the title, in ticks. 67 | * @param fadeOut The fade-out time of the title, in ticks. 68 | */ 69 | public Title(JSONObject title, JSONObject subtitle, int fadeIn, int fadeOut, int stay) { 70 | this.title = title; 71 | this.subtitle = subtitle; 72 | this.fadeIn = fadeIn; 73 | this.fadeOut = fadeOut; 74 | this.stay = stay; 75 | } 76 | 77 | static JSONObject convert(String text) { 78 | JSONObject json = new JSONObject(); 79 | json.put("text", text); 80 | return json; 81 | } 82 | 83 | /** 84 | * Sends the title to a specific player. 85 | * 86 | * @param player The player to send the title to. 87 | */ 88 | public void send(Player player) { 89 | Preconditions.checkNotNull(player); 90 | try { 91 | Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player); 92 | Object playerConnection = entityPlayer.getClass().getField("playerConnection").get(entityPlayer); 93 | // NMS Classes 94 | Class clsPacketPlayOutTitle = ServerPackage.MINECRAFT.getClass("PacketPlayOutTitle"); 95 | Class clsPacket = ServerPackage.MINECRAFT.getClass("Packet"); 96 | Class clsIChatBaseComponent = ServerPackage.MINECRAFT.getClass("IChatBaseComponent"); 97 | Class clsChatSerializer = ServerPackage.MINECRAFT.getClass("IChatBaseComponent$ChatSerializer"); 98 | Class clsEnumTitleAction = ServerPackage.MINECRAFT.getClass("PacketPlayOutTitle$EnumTitleAction"); 99 | Object timesPacket = clsPacketPlayOutTitle.getConstructor(int.class, int.class, int.class).newInstance(fadeIn, stay, fadeOut); 100 | playerConnection.getClass().getMethod("sendPacket", clsPacket).invoke(playerConnection, timesPacket); 101 | // Play the title packet 102 | if (title != null && !title.isEmpty()) { 103 | Object titleComponent = clsChatSerializer.getMethod("a", String.class).invoke(null, title.toString()); 104 | Object titlePacket = clsPacketPlayOutTitle.getConstructor(clsEnumTitleAction, clsIChatBaseComponent).newInstance(clsEnumTitleAction.getField("TITLE").get(null), titleComponent); 105 | playerConnection.getClass().getMethod("sendPacket", clsPacket).invoke(playerConnection, titlePacket); 106 | } 107 | // Play the subtitle packet 108 | if (subtitle != null && !subtitle.isEmpty()) { 109 | Object subtitleComponent = clsChatSerializer.getMethod("a", String.class).invoke(null, subtitle.toString()); 110 | Object subtitlePacket = clsPacketPlayOutTitle.getConstructor(clsEnumTitleAction, clsIChatBaseComponent).newInstance(clsEnumTitleAction.getField("SUBTITLE").get(null), subtitleComponent); 111 | playerConnection.getClass().getMethod("sendPacket", clsPacket).invoke(playerConnection, subtitlePacket); 112 | } 113 | } catch (Throwable e) { 114 | throw new RuntimeException(e); 115 | } 116 | } 117 | 118 | /** 119 | * Sends the title to all online players. 120 | */ 121 | public void sendToAll() { 122 | for (Player player : Bukkit.getOnlinePlayers()) { 123 | send(player); 124 | } 125 | } 126 | 127 | /** 128 | * Getter for the text of the main title. 129 | * 130 | * @return Text of main title. 131 | */ 132 | public JSONObject getTitle() { 133 | return title; 134 | } 135 | 136 | /** 137 | * Setter for the text of the main title. 138 | * 139 | * @param title New main title text. 140 | */ 141 | public void setTitle(String title) { 142 | this.title = convert(title); 143 | } 144 | 145 | /** 146 | * Setter for the text of the main title. 147 | * 148 | * @param title New main title text. Must be in /tellraw JSON format. 149 | */ 150 | public void setTitle(JSONObject title) { 151 | this.title = title; 152 | } 153 | 154 | /** 155 | * Getter for the text of the subtitle. 156 | * 157 | * @return Text of subtitle. 158 | */ 159 | public JSONObject getSubtitle() { 160 | return subtitle; 161 | } 162 | 163 | /** 164 | * Setter for the text of the subtitle. 165 | * 166 | * @param subtitle New subtitle text. 167 | */ 168 | public void setSubtitle(String subtitle) { 169 | this.subtitle = convert(subtitle); 170 | } 171 | 172 | /** 173 | * Setter for the text of the subtitle. 174 | * 175 | * @param subtitle New subtitle text. Must be in /tellraw JSON format. 176 | */ 177 | public void setSubtitle(JSONObject subtitle) { 178 | this.subtitle = subtitle; 179 | } 180 | 181 | /** 182 | * Getter for the fade-in time, in ticks. 183 | * 184 | * @return Fade-in ticks. 185 | */ 186 | public int getFadeIn() { 187 | return fadeIn; 188 | } 189 | 190 | /** 191 | * Setter for the fade-in time, in ticks. 192 | * 193 | * @param fadeIn New fade-in ticks. 194 | */ 195 | public void setFadeIn(int fadeIn) { 196 | this.fadeIn = fadeIn; 197 | } 198 | 199 | /** 200 | * Getter for the fade-out time, in ticks. 201 | * 202 | * @return Fade-out ticks. 203 | */ 204 | public int getFadeOut() { 205 | return fadeOut; 206 | } 207 | 208 | /** 209 | * Setter for the fade-out time, in ticks. 210 | * 211 | * @param fadeOut New fade-out ticks. 212 | */ 213 | public void setFadeOut(int fadeOut) { 214 | this.fadeOut = fadeOut; 215 | } 216 | 217 | /** 218 | * Getter for the stay time, in ticks. 219 | * 220 | * @return Stay ticks. 221 | */ 222 | public int getStay() { 223 | return stay; 224 | } 225 | 226 | /** 227 | * Setter for the stay time, in ticks. 228 | * 229 | * @param stay New stay ticks. 230 | */ 231 | public void setStay(int stay) { 232 | this.stay = stay; 233 | } 234 | 235 | } 236 | --------------------------------------------------------------------------------