Advertisement
Guest User

kkrai

a guest
Sep 4th, 2015
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.12 KB | None | 0 0
  1. package me.kartagedlç.title;
  2.  
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.Method;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. import org.bukkit.Bukkit;
  9. import org.bukkit.ChatColor;
  10. import org.bukkit.entity.Player;
  11.  
  12. /**
  13. * Minecraft 1.8 Title
  14. *
  15. * @version 1.0.4
  16. * @author Maxim Van de Wynckel
  17. */
  18. public class Title {
  19. /* Title packet */
  20. private Class<?> packetTitle;
  21. /* Title packet actions ENUM */
  22. private Class<?> packetActions;
  23. /* Chat serializer */
  24. private Class<?> nmsChatSerializer;
  25. private Class<?> chatBaseComponent;
  26. /* Title text and color */
  27. private String title = "";
  28. private ChatColor titleColor = ChatColor.WHITE;
  29. /* Subtitle text and color */
  30. private String subtitle = "";
  31. private ChatColor subtitleColor = ChatColor.WHITE;
  32. /* Title timings */
  33. private int fadeInTime = -1;
  34. private int stayTime = -1;
  35. private int fadeOutTime = -1;
  36. private boolean ticks = false;
  37.  
  38. private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
  39.  
  40. /**
  41. * Create a new 1.8 title
  42. *
  43. * @param title
  44. * Title
  45. */
  46. public Title(String title) {
  47. this.title = title;
  48. loadClasses();
  49. }
  50.  
  51. /**
  52. * Create a new 1.8 title
  53. *
  54. * @param title
  55. * Title text
  56. * @param subtitle
  57. * Subtitle text
  58. */
  59. public Title(String title, String subtitle) {
  60. this.title = title;
  61. this.subtitle = subtitle;
  62. loadClasses();
  63. }
  64.  
  65. /**
  66. * Copy 1.8 title
  67. *
  68. * @param title
  69. * Title
  70. */
  71. public Title(Title title) {
  72. // Copy title
  73. this.title = title.title;
  74. this.subtitle = title.subtitle;
  75. this.titleColor = title.titleColor;
  76. this.subtitleColor = title.subtitleColor;
  77. this.fadeInTime = title.fadeInTime;
  78. this.fadeOutTime = title.fadeOutTime;
  79. this.stayTime = title.stayTime;
  80. this.ticks = title.ticks;
  81. loadClasses();
  82. }
  83.  
  84. /**
  85. * Create a new 1.8 title
  86. *
  87. * @param title
  88. * Title text
  89. * @param subtitle
  90. * Subtitle text
  91. * @param fadeInTime
  92. * Fade in time
  93. * @param stayTime
  94. * Stay on screen time
  95. * @param fadeOutTime
  96. * Fade out time
  97. */
  98. public Title(String title, String subtitle, int fadeInTime, int stayTime,
  99. int fadeOutTime) {
  100. this.title = title;
  101. this.subtitle = subtitle;
  102. this.fadeInTime = fadeInTime;
  103. this.stayTime = stayTime;
  104. this.fadeOutTime = fadeOutTime;
  105. loadClasses();
  106. }
  107.  
  108. /**
  109. * Load spigot and NMS classes
  110. */
  111. private void loadClasses() {
  112. packetTitle = getNMSClass("PacketPlayOutTitle");
  113. packetActions = getNMSClass("PacketPlayOutTitle$EnumTitleAction");
  114. chatBaseComponent = getNMSClass("IChatBaseComponent");
  115. nmsChatSerializer = getNMSClass("IChatBaseComponent$ChatSerializer");
  116. }
  117.  
  118. /**
  119. * Set title text
  120. *
  121. * @param title
  122. * Title
  123. */
  124. public void setTitle(String title) {
  125. this.title = title;
  126. }
  127.  
  128. /**
  129. * Get title text
  130. *
  131. * @return Title text
  132. */
  133. public String getTitle() {
  134. return this.title;
  135. }
  136.  
  137. /**
  138. * Set subtitle text
  139. *
  140. * @param subtitle
  141. * Subtitle text
  142. */
  143. public void setSubtitle(String subtitle) {
  144. this.subtitle = subtitle;
  145. }
  146.  
  147. /**
  148. * Get subtitle text
  149. *
  150. * @return Subtitle text
  151. */
  152. public String getSubtitle() {
  153. return this.subtitle;
  154. }
  155.  
  156. /**
  157. * Set the title color
  158. *
  159. * @param color
  160. * Chat color
  161. */
  162. public void setTitleColor(ChatColor color) {
  163. this.titleColor = color;
  164. }
  165.  
  166. /**
  167. * Set the subtitle color
  168. *
  169. * @param color
  170. * Chat color
  171. */
  172. public void setSubtitleColor(ChatColor color) {
  173. this.subtitleColor = color;
  174. }
  175.  
  176. /**
  177. * Set title fade in time
  178. *
  179. * @param time
  180. * Time
  181. */
  182. public void setFadeInTime(int time) {
  183. this.fadeInTime = time;
  184. }
  185.  
  186. /**
  187. * Set title fade out time
  188. *
  189. * @param time
  190. * Time
  191. */
  192. public void setFadeOutTime(int time) {
  193. this.fadeOutTime = time;
  194. }
  195.  
  196. /**
  197. * Set title stay time
  198. *
  199. * @param time
  200. * Time
  201. */
  202. public void setStayTime(int time) {
  203. this.stayTime = time;
  204. }
  205.  
  206. /**
  207. * Set timings to ticks
  208. */
  209. public void setTimingsToTicks() {
  210. ticks = true;
  211. }
  212.  
  213. /**
  214. * Set timings to seconds
  215. */
  216. public void setTimingsToSeconds() {
  217. ticks = false;
  218. }
  219.  
  220. /**
  221. * Send the title to a player
  222. *
  223. * @param player
  224. * Player
  225. */
  226. public void send(Player player) {
  227. if (packetTitle != null) {
  228. // First reset previous settings
  229. resetTitle(player);
  230. try {
  231. // Send timings first
  232. Object handle = getHandle(player);
  233. Object connection = getField(handle.getClass(),
  234. "playerConnection").get(handle);
  235. Object[] actions = packetActions.getEnumConstants();
  236. Method sendPacket = getMethod(connection.getClass(),
  237. "sendPacket");
  238. Object packet = packetTitle.getConstructor(packetActions,
  239. chatBaseComponent, Integer.TYPE, Integer.TYPE,
  240. Integer.TYPE).newInstance(actions[2], null,
  241. fadeInTime * (ticks ? 1 : 20),
  242. stayTime * (ticks ? 1 : 20),
  243. fadeOutTime * (ticks ? 1 : 20));
  244. // Send if set
  245. if (fadeInTime != -1 && fadeOutTime != -1 && stayTime != -1)
  246. sendPacket.invoke(connection, packet);
  247.  
  248. // Send title
  249. Object serialized = getMethod(nmsChatSerializer, "a",
  250. String.class).invoke(
  251. null,
  252. "{text:\""
  253. + ChatColor.translateAlternateColorCodes('&',
  254. title) + "\",color:"
  255. + titleColor.name().toLowerCase() + "}");
  256. packet = packetTitle.getConstructor(packetActions,
  257. chatBaseComponent).newInstance(actions[0], serialized);
  258. sendPacket.invoke(connection, packet);
  259. if (subtitle != "") {
  260. // Send subtitle if present
  261. serialized = getMethod(nmsChatSerializer, "a", String.class)
  262. .invoke(null,
  263. "{text:\""
  264. + ChatColor
  265. .translateAlternateColorCodes(
  266. '&', subtitle)
  267. + "\",color:"
  268. + subtitleColor.name()
  269. .toLowerCase() + "}");
  270. packet = packetTitle.getConstructor(packetActions,
  271. chatBaseComponent).newInstance(actions[1],
  272. serialized);
  273. sendPacket.invoke(connection, packet);
  274. }
  275. } catch (Exception e) {
  276. e.printStackTrace();
  277. }
  278. }
  279. }
  280.  
  281. /**
  282. * Broadcast the title to all players
  283. */
  284. public void broadcast() {
  285. for (Player p : Bukkit.getOnlinePlayers()) {
  286. send(p);
  287. }
  288. }
  289.  
  290. /**
  291. * Clear the title
  292. *
  293. * @param player
  294. * Player
  295. */
  296. public void clearTitle(Player player) {
  297. try {
  298. // Send timings first
  299. Object handle = getHandle(player);
  300. Object connection = getField(handle.getClass(), "playerConnection")
  301. .get(handle);
  302. Object[] actions = packetActions.getEnumConstants();
  303. Method sendPacket = getMethod(connection.getClass(), "sendPacket");
  304. Object packet = packetTitle.getConstructor(packetActions,
  305. chatBaseComponent).newInstance(actions[3], null);
  306. sendPacket.invoke(connection, packet);
  307. } catch (Exception e) {
  308. e.printStackTrace();
  309. }
  310. }
  311.  
  312. /**
  313. * Reset the title settings
  314. *
  315. * @param player
  316. * Player
  317. */
  318. public void resetTitle(Player player) {
  319. try {
  320. // Send timings first
  321. Object handle = getHandle(player);
  322. Object connection = getField(handle.getClass(), "playerConnection")
  323. .get(handle);
  324. Object[] actions = packetActions.getEnumConstants();
  325. Method sendPacket = getMethod(connection.getClass(), "sendPacket");
  326. Object packet = packetTitle.getConstructor(packetActions,
  327. chatBaseComponent).newInstance(actions[4], null);
  328. sendPacket.invoke(connection, packet);
  329. } catch (Exception e) {
  330. e.printStackTrace();
  331. }
  332. }
  333.  
  334. private Class<?> getPrimitiveType(Class<?> clazz) {
  335. return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES
  336. .get(clazz) : clazz;
  337. }
  338.  
  339. private Class<?>[] toPrimitiveTypeArray(Class<?>[] classes) {
  340. int a = classes != null ? classes.length : 0;
  341. Class<?>[] types = new Class<?>[a];
  342. for (int i = 0; i < a; i++)
  343. types[i] = getPrimitiveType(classes[i]);
  344. return types;
  345. }
  346.  
  347. private static boolean equalsTypeArray(Class<?>[] a, Class<?>[] o) {
  348. if (a.length != o.length)
  349. return false;
  350. for (int i = 0; i < a.length; i++)
  351. if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i]))
  352. return false;
  353. return true;
  354. }
  355.  
  356. private Object getHandle(Object obj) {
  357. try {
  358. return getMethod("getHandle", obj.getClass()).invoke(obj);
  359. } catch (Exception e) {
  360. e.printStackTrace();
  361. return null;
  362. }
  363. }
  364.  
  365. private Method getMethod(String name, Class<?> clazz,
  366. Class<?>... paramTypes) {
  367. Class<?>[] t = toPrimitiveTypeArray(paramTypes);
  368. for (Method m : clazz.getMethods()) {
  369. Class<?>[] types = toPrimitiveTypeArray(m.getParameterTypes());
  370. if (m.getName().equals(name) && equalsTypeArray(types, t))
  371. return m;
  372. }
  373. return null;
  374. }
  375.  
  376. private String getVersion() {
  377. String name = Bukkit.getServer().getClass().getPackage().getName();
  378. String version = name.substring(name.lastIndexOf('.') + 1) + ".";
  379. return version;
  380. }
  381.  
  382. private Class<?> getNMSClass(String className) {
  383. String fullName = "net.minecraft.server." + getVersion() + className;
  384. Class<?> clazz = null;
  385. try {
  386. clazz = Class.forName(fullName);
  387. } catch (Exception e) {
  388. e.printStackTrace();
  389. }
  390. return clazz;
  391. }
  392.  
  393. private Field getField(Class<?> clazz, String name) {
  394. try {
  395. Field field = clazz.getDeclaredField(name);
  396. field.setAccessible(true);
  397. return field;
  398. } catch (Exception e) {
  399. e.printStackTrace();
  400. return null;
  401. }
  402. }
  403.  
  404. private Method getMethod(Class<?> clazz, String name, Class<?>... args) {
  405. for (Method m : clazz.getMethods())
  406. if (m.getName().equals(name)
  407. && (args.length == 0 || ClassListEqual(args,
  408. m.getParameterTypes()))) {
  409. m.setAccessible(true);
  410. return m;
  411. }
  412. return null;
  413. }
  414.  
  415. private boolean ClassListEqual(Class<?>[] l1, Class<?>[] l2) {
  416. boolean equal = true;
  417. if (l1.length != l2.length)
  418. return false;
  419. for (int i = 0; i < l1.length; i++)
  420. if (l1[i] != l2[i]) {
  421. equal = false;
  422. break;
  423. }
  424. return equal;
  425. }
  426. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement