├── .gitattributes ├── .gitignore ├── README.md ├── config.yml ├── licence.txt ├── plugin.yml ├── pom.xml └── src └── me └── confuser └── barapi ├── BarAPI.java ├── Util.java └── nms ├── FakeDragon.java ├── v1_6.java ├── v1_7.java ├── v1_8.java ├── v1_8Fake.java └── v1_9.java /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | .settings 3 | .classpath 4 | bin 5 | .project 6 | *.iml 7 | .idea/ 8 | 9 | # Package Files # 10 | *.jar 11 | *.war 12 | *.ear 13 | /target 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |

Server Owners

4 |

This plugin does nothing on its own. It is simply an API for other plugins to implement with.

5 |

Developers

6 |

Simply add BarAPI.jar to your project build path.

7 |

This plugin makes use of reflection and therefore "shouldn't" break on craftbukkit updates.

8 |

Limitations

9 |

The message can not be more than 64 characters. If it is more, BarAPI will automatically cut it to 64 characters to prevent the client from crashing.

10 |

This is a client limitation and cannot be changed.

11 |

Examples

12 |
BarAPI.setMessage(Player player, String message)
13 |

Set a message for the player. It will remain there until the player logs off or another plugin overrides it.

14 |
BarAPI.setMessage(Player player, String message, float percent)
15 |

Same as above except you can set the % of the health bar. 100 shows the entire health bar, 50 shows half the health bar and so on.

16 |
BarAPI.setMessage(final Player player, String message, int seconds)
17 |

Sets a timed message for the player. It will remain until the timer runs out. The health automatically reduces based on how long the timer is.

18 |
BarAPI.hasBar(Player player)
19 |

Pretty self explanatory, returns a boolean.

20 |
BarAPI.removeBar(Player player)
21 |

Also pretty self explanatory.

22 |
BarAPI.setHealth(Player player, float percent)
23 |

Allows you to modify the health of an existing bar. If the player has no bar, this does nothing.

24 |

Tutorials

25 |

German - DerFeliix

26 |

Source

27 |

GitHub

28 |

Maven

29 |
<repositories>
30 | 	<repository>
31 | 		<id>confuser-repo</id>
32 | 		<url>https://ci.frostcast.net/plugin/repository/everything</url>
33 | 	</repository>
34 | </repositories>
35 | 
36 | <dependencies>
37 | 	<dependency>
38 | 		<groupId>me.confuser</groupId>
39 | 		<artifactId>BarAPI</artifactId>
40 | 		<version>3.5</version>
41 | 	</dependency>
42 | </dependencies>
43 | 
44 |

Updater

45 |

This plugin contains an auto updater which is enabled by default. If you do not wish to automatically download new updates, edit BarAPI/config.yml and set autoUpdate to false.

46 |

To Dos

47 | 49 |

Plugins Using BarAPI

50 |

WelcomeBar

51 |

Parkour

52 |

QuickSupport

53 |

BossBroadcast

54 |

BossMessage

55 |

PvPGames Automated

56 |

BossEventScheduler

57 |

Infernal Mobs

58 |

MythicMobs

59 |

MultiKill

60 |

PlayerBoss

61 |

BossAds

62 |

Item Lore Stats

63 |

BossBarPro

64 |

VIPLobby

65 |

Battle Of Blocks

66 |

BossBroadcaster

67 |

SilkSpawners

68 |

BarJoin

69 |

JoinGlobalMessages

70 |

Metrics

71 |

To determine popularity and usage of BarAPI, plugin installs are automatically tracked by the Metrics plugin tracking system. Your Java version, OS, player count, server country location and plugin & server versions are collected. This is used to determine what environments are using the plugin to ensure full compatibility. This collection is anonymous. If you don't want this tracking, edit plugins/PluginMetrics/config.yml and set opt-out to true. 72 |

73 | -------------------------------------------------------------------------------- /config.yml: -------------------------------------------------------------------------------- 1 | # Set to false to disable the auto updater 2 | autoUpdate: true 3 | testMode: false 4 | # For the latest spigot fake protocol hacks 5 | useSpigotHack: false 6 | -------------------------------------------------------------------------------- /licence.txt: -------------------------------------------------------------------------------- 1 | Attribution - Non-Commercial - Share-Alike 2.0 England and Wales 2 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENCE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. 3 | 4 | Licence 5 | 6 | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENCE ("CCPL" OR "LICENCE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENCE OR COPYRIGHT LAW IS PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENCE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 7 | 8 | This Creative Commons England and Wales Public Licence enables You (all capitalised terms defined below) to view, edit, modify, translate and distribute Works worldwide, under the terms of this licence, provided that You credit the Original Author. 9 | 10 | 'The Licensor' [one or more legally recognised persons or entities offering the Work under the terms and conditions of this Licence] 11 | 12 | and 13 | 14 | 'You' 15 | 16 | agree as follows: 17 | 18 | 1. Definitions 19 | 20 | "Attribution" means acknowledging all the parties who have contributed to and have rights in the Work or Collective Work under this Licence. 21 | "Collective Work" means the Work in its entirety in unmodified form along with a number of other separate and independent works, assembled into a collective whole. 22 | "Derivative Work" means any work created by the editing, modification, adaptation or translation of the Work in any media (however a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this Licence). For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this Licence. 23 | "Licence" means this Creative Commons England and Wales Public Licence agreement. 24 | "Licence Elements" means the following high-level licence attributes indicated in the title of this Licence: Attribution, Non-Commercial, Share-Alike. 25 | "Non-Commercial" means "not primarily intended for or directed towards commercial advantage or private monetary compensation". The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed towards commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in connection with the exchange of copyrighted works. 26 | "Original Author" means the individual (or entity) who created the Work. 27 | "Work" means the work protected by copyright which is offered under the terms of this Licence. 28 | For the purpose of this Licence, when not inconsistent with the context, words in the singular number include the plural number. 29 | 30 | 2. Licence Terms 31 | 32 | 2.1 The Licensor hereby grants to You a worldwide, royalty-free, non-exclusive, Licence for Non-Commercial use and for the duration of copyright in the Work. 33 | 34 | You may: 35 | 36 | copy the Work; 37 | create one or more Derivative Works; 38 | incorporate the Work into one or more Collective Works; 39 | copy Derivative Works or the Work as incorporated in any Collective Work; and 40 | publish, distribute, archive, perform or otherwise disseminate the Work or the Work as incorporated in any Collective Work, to the public in any material form in any media whether now known or hereafter created. 41 | 42 | HOWEVER, 43 | 44 | You must not: 45 | 46 | impose any terms on the use to be made of the Work, the Derivative Work or the Work as incorporated in a Collective Work that alter or restrict the terms of this Licence or any rights granted under it or has the effect or intent of restricting the ability to exercise those rights; 47 | impose any digital rights management technology on the Work or the Work as incorporated in a Collective Work that alters or restricts the terms of this Licence or any rights granted under it or has the effect or intent of restricting the ability to exercise those rights; 48 | sublicense the Work; 49 | subject the Work to any derogatory treatment as defined in the Copyright, Designs and Patents Act 1988. 50 | 51 | FINALLY, 52 | 53 | You must: 54 | 55 | make reference to this Licence (by Uniform Resource Identifier (URI), spoken word or as appropriate to the media used) on all copies of the Work and Collective Works published, distributed, performed or otherwise disseminated or made available to the public by You; 56 | recognise the Licensor's / Original Author's right of attribution in any Work and Collective Work that You publish, distribute, perform or otherwise disseminate to the public and ensure that You credit the Licensor / Original Author as appropriate to the media used; and 57 | to the extent reasonably practicable, keep intact all notices that refer to this Licence, in particular the URI, if any, that the Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work. 58 | 59 | Additional Provisions for third parties making use of the Work 60 | 61 | 2.2. Further licence from the Licensor 62 | 63 | Each time You publish, distribute, perform or otherwise disseminate 64 | 65 | the Work; or 66 | any Derivative Work; or 67 | the Work as incorporated in a Collective Work 68 | 69 | the Licensor agrees to offer to the relevant third party making use of the Work (in any of the alternatives set out above) a licence to use the Work on the same terms and conditions as granted to You hereunder. 70 | 71 | 2.3. Further licence from You 72 | 73 | Each time You publish, distribute, perform or otherwise disseminate 74 | 75 | a Derivative Work; or 76 | a Derivative Work as incorporated in a Collective Work 77 | 78 | You agree to offer to the relevant third party making use of the Work (in either of the alternatives set out above) a licence to use the Derivative Work on any of the following premises: 79 | 80 | a licence on the same terms and conditions as the licence granted to You hereunder; or 81 | a later version of the licence granted to You hereunder; or 82 | any other Creative Commons licence with the same Licence Elements. 83 | 84 | 2.4. This Licence does not affect any rights that the User may have under any applicable law, including fair use, fair dealing or any other legally recognised limitation or exception to copyright infringement. 85 | 86 | 2.5. All rights not expressly granted by the Licensor are hereby reserved, including but not limited to, the exclusive right to collect, whether individually or via a licensing body, such as a collecting society, royalties for any use of the Work which results in commercial advantage or private monetary compensation. 87 | 88 | 3. Warranties and Disclaimer 89 | 90 | Except as required by law, the Work is licensed by the Licensor on an "as is" and "as available" basis and without any warranty of any kind, either express or implied. 91 | 92 | 4. Limit of Liability 93 | 94 | Subject to any liability which may not be excluded or limited by law the Licensor shall not be liable and hereby expressly excludes all liability for loss or damage howsoever and whenever caused to You. 95 | 96 | 5. Termination 97 | 98 | The rights granted to You under this Licence shall terminate automatically upon any breach by You of the terms of this Licence. Individuals or entities who have received Collective Works from You under this Licence, however, will not have their Licences terminated provided such individuals or entities remain in full compliance with those Licences. 99 | 100 | 6. General 101 | 102 | 6.1. The validity or enforceability of the remaining terms of this agreement is not affected by the holding of any provision of it to be invalid or unenforceable. 103 | 104 | 6.2. This Licence constitutes the entire Licence Agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. The Licensor shall not be bound by any additional provisions that may appear in any communication in any form. 105 | 106 | 6.3. A person who is not a party to this Licence shall have no rights under the Contracts (Rights of Third Parties) Act 1999 to enforce any of its terms. 107 | 108 | 6.4. This Licence shall be governed by the law of England and Wales and the parties irrevocably submit to the exclusive jurisdiction of the Courts of England and Wales. 109 | 110 | 7. On the role of Creative Commons 111 | 112 | 7.1. Neither the Licensor nor the User may use the Creative Commons logo except to indicate that the Work is licensed under a Creative Commons Licence. Any permitted use has to be in compliance with the Creative Commons trade mark usage guidelines at the time of use of the Creative Commons trade mark. These guidelines may be found on the Creative Commons website or be otherwise available upon request from time to time. 113 | 114 | 7.2. Creative Commons Corporation does not profit financially from its role in providing this Licence and will not investigate the claims of any Licensor or user of the Licence. 115 | 116 | 7.3. One of the conditions that Creative Commons Corporation requires of the Licensor and You is an acknowledgement of its limited role and agreement by all who use the Licence that the Corporation is not responsible to anyone for the statements and actions of You or the Licensor or anyone else attempting to use or using this Licence. 117 | 118 | 7.4. Creative Commons Corporation is not a party to this Licence, and makes no warranty whatsoever in connection to the Work or in connection to the Licence, and in all events is not liable for any loss or damage resulting from the Licensor's or Your reliance on this Licence or on its enforceability. 119 | 120 | 7.5. USE OF THIS LICENCE MEANS THAT YOU AND THE LICENSOR EACH ACCEPTS THESE CONDITIONS IN SECTION 7.1, 7.2, 7.3, 7.4 AND EACH ACKNOWLEDGES CREATIVE COMMONS CORPORATION'S VERY LIMITED ROLE AS A FACILITATOR OF THE LICENCE FROM THE LICENSOR TO YOU. 121 | 122 | Creative Commons is not a party to this Licence, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this licence. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. 123 | 124 | Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. 125 | 126 | Creative Commons may be contacted at http://creativecommons.org/. -------------------------------------------------------------------------------- /plugin.yml: -------------------------------------------------------------------------------- 1 | main: me.confuser.barapi.BarAPI 2 | name: ${project.name} 3 | version: ${project.version} 4 | description: ${project.description} -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | BarAPI 5 | Allows plugins to control the boss health bar message 6 | me.confuser 7 | BarAPI 8 | 3.5 9 | 10 | BarAPI 11 | 12 | 13 | . 14 | true 15 | ${basedir} 16 | 17 | *.yml 18 | 19 | 20 | 21 | src 22 | 23 | 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.6 28 | 1.6 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-shade-plugin 34 | 1.5 35 | 36 | 37 | package 38 | 39 | shade 40 | 41 | 42 | true 43 | 44 | 45 | net.gravitydevelopment.updater 46 | me.confuser.barapi.updater 47 | 48 | 49 | org.mcstats 50 | me.confuser.barapi.mcstats 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | spigot-repo 62 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 63 | 64 | 65 | gravity-repo 66 | http://repo.gravitydevelopment.net 67 | 68 | 69 | Plugin Metrics 70 | http://repo.mcstats.org/content/repositories/snapshots 71 | 72 | 73 | 74 | 75 | org.spigotmc 76 | spigot-api 77 | 1.9-R0.1-SNAPSHOT 78 | provided 79 | 80 | 81 | org.bukkit 82 | bukkit 83 | 1.9-R0.1-SNAPSHOT 84 | provided 85 | 86 | 87 | net.gravitydevelopment.updater 88 | updater 89 | 2.3 90 | 91 | 92 | org.mcstats.bukkit 93 | metrics-lite 94 | R8-SNAPSHOT 95 | compile 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/BarAPI.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi; 2 | 3 | import me.confuser.barapi.nms.FakeDragon; 4 | import me.confuser.barapi.nms.v1_8Fake; 5 | import me.confuser.barapi.nms.v1_9; 6 | import net.gravitydevelopment.updater.Updater; 7 | import org.apache.commons.lang.Validate; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.ChatColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.block.BlockFace; 12 | import org.bukkit.boss.BossBar; 13 | import org.bukkit.entity.Player; 14 | import org.bukkit.event.EventHandler; 15 | import org.bukkit.event.EventPriority; 16 | import org.bukkit.event.Listener; 17 | import org.bukkit.event.player.PlayerKickEvent; 18 | import org.bukkit.event.player.PlayerQuitEvent; 19 | import org.bukkit.event.player.PlayerRespawnEvent; 20 | import org.bukkit.event.player.PlayerTeleportEvent; 21 | import org.bukkit.plugin.java.JavaPlugin; 22 | import org.mcstats.MetricsLite; 23 | 24 | import java.io.IOException; 25 | import java.util.HashMap; 26 | import java.util.UUID; 27 | 28 | /** 29 | * Allows plugins to safely set a health bar message. 30 | * 31 | * @author James Mortemore 32 | */ 33 | 34 | public class BarAPI extends JavaPlugin implements Listener { 35 | 36 | private static HashMap players = new HashMap(); 37 | private static HashMap timers = new HashMap(); 38 | 39 | private static BarAPI plugin; 40 | 41 | private static boolean useSpigotHack = false; 42 | 43 | public static boolean useSpigotHack() { 44 | return useSpigotHack; 45 | } 46 | 47 | /** 48 | * Set a message for all players.
49 | * It will remain there until the player logs off or another plugin overrides it.
50 | * This method will show a full health bar and will cancel any running timers. 51 | * 52 | * @param message The message shown.
53 | * Due to limitations in Minecraft this message cannot be longer than 64 characters.
54 | * It will be cut to that size automatically. 55 | * 56 | * @see BarAPI#setMessage(player, message) 57 | */ 58 | @Deprecated 59 | public static void setMessage(String message) { 60 | for (Player player : Bukkit.getOnlinePlayers()) { 61 | setMessage(player, message); 62 | } 63 | } 64 | 65 | /** 66 | * Set a message for the given player.
67 | * It will remain there until the player logs off or another plugin overrides it.
68 | * This method will show a full health bar and will cancel any running timers. 69 | * 70 | * @param player The player who should see the given message. 71 | * @param message The message shown to the player.
72 | * Due to limitations in Minecraft this message cannot be longer than 64 characters.
73 | * It will be cut to that size automatically. 74 | */ 75 | @Deprecated 76 | public static void setMessage(Player player, String message) { 77 | if (hasBar(player)) 78 | removeBar(player); 79 | FakeDragon dragon = getDragon(player, message); 80 | 81 | dragon.name = cleanMessage(message); 82 | dragon.health = dragon.getMaxHealth(); 83 | 84 | cancelTimer(player); 85 | 86 | sendDragon(dragon, player); 87 | } 88 | 89 | /** 90 | * Set a message for all players.
91 | * It will remain there for each player until the player logs off or another plugin overrides it.
92 | * This method will show a health bar using the given percentage value and will cancel any running timers. 93 | * 94 | * @param message The message shown to the player.
95 | * Due to limitations in Minecraft this message cannot be longer than 64 characters.
96 | * It will be cut to that size automatically. 97 | * @param percent The percentage of the health bar filled.
98 | * This value must be between 0F (inclusive) and 100F (inclusive). 99 | * 100 | * @throws IllegalArgumentException If the percentage is not within valid bounds. 101 | * @see BarAPI#setMessage(player, message, percent) 102 | */ 103 | @Deprecated 104 | public static void setMessage(String message, float percent) { 105 | for (Player player : Bukkit.getOnlinePlayers()) { 106 | setMessage(player, message, percent); 107 | } 108 | } 109 | 110 | /** 111 | * Set a message for the given player.
112 | * It will remain there until the player logs off or another plugin overrides it.
113 | * This method will show a health bar using the given percentage value and will cancel any running timers. 114 | * 115 | * @param player The player who should see the given message. 116 | * @param message The message shown to the player.
117 | * Due to limitations in Minecraft this message cannot be longer than 64 characters.
118 | * It will be cut to that size automatically. 119 | * @param percent The percentage of the health bar filled.
120 | * This value must be between 0F (inclusive) and 100F (inclusive). 121 | * 122 | * @throws IllegalArgumentException If the percentage is not within valid bounds. 123 | */ 124 | @Deprecated 125 | public static void setMessage(Player player, String message, float percent) { 126 | Validate.isTrue(0F <= percent && percent <= 100F, "Percent must be between 0F and 100F, but was: ", percent); 127 | 128 | if (hasBar(player)) 129 | removeBar(player); 130 | 131 | FakeDragon dragon = getDragon(player, message); 132 | 133 | dragon.name = cleanMessage(message); 134 | dragon.health = (percent / 100f) * dragon.getMaxHealth(); 135 | 136 | cancelTimer(player); 137 | 138 | sendDragon(dragon, player); 139 | } 140 | 141 | /** 142 | * Set a message for all players.
143 | * It will remain there for each player until the player logs off or another plugin overrides it.
144 | * This method will use the health bar as a decreasing timer, all previously started timers will be cancelled.
145 | * The timer starts with a full bar.
146 | * The health bar will be removed automatically if it hits zero. 147 | * 148 | * @param message The message shown.
149 | * Due to limitations in Minecraft this message cannot be longer than 64 characters.
150 | * It will be cut to that size automatically. 151 | * @param seconds The amount of seconds displayed by the timer.
152 | * Supports values above 1 (inclusive). 153 | * 154 | * @throws IllegalArgumentException If seconds is zero or below. 155 | * @see BarAPI#setMessage(player, message, seconds) 156 | */ 157 | @Deprecated 158 | public static void setMessage(String message, int seconds) { 159 | for (Player player : Bukkit.getOnlinePlayers()) { 160 | setMessage(player, message, seconds); 161 | } 162 | } 163 | 164 | /** 165 | * Set a message for the given player.
166 | * It will remain there until the player logs off or another plugin overrides it.
167 | * This method will use the health bar as a decreasing timer, all previously started timers will be cancelled.
168 | * The timer starts with a full bar.
169 | * The health bar will be removed automatically if it hits zero. 170 | * 171 | * @param player The player who should see the given timer/message. 172 | * @param message The message shown to the player.
173 | * Due to limitations in Minecraft this message cannot be longer than 64 characters.
174 | * It will be cut to that size automatically. 175 | * @param seconds The amount of seconds displayed by the timer.
176 | * Supports values above 1 (inclusive). 177 | * 178 | * @throws IllegalArgumentException If seconds is zero or below. 179 | */ 180 | @Deprecated 181 | public static void setMessage(final Player player, String message, int seconds) { 182 | Validate.isTrue(seconds > 0, "Seconds must be above 1 but was: ", seconds); 183 | 184 | if (hasBar(player)) 185 | removeBar(player); 186 | 187 | FakeDragon dragon = getDragon(player, message); 188 | 189 | dragon.name = cleanMessage(message); 190 | dragon.health = dragon.getMaxHealth(); 191 | 192 | final float dragonHealthMinus = dragon.getMaxHealth() / seconds; 193 | 194 | cancelTimer(player); 195 | 196 | timers.put(player.getUniqueId(), Bukkit.getScheduler().runTaskTimer(plugin, new Runnable() { 197 | 198 | @Override 199 | public void run() { 200 | FakeDragon drag = getDragon(player, ""); 201 | drag.health -= dragonHealthMinus; 202 | 203 | if (drag.health <= 1) { 204 | removeBar(player); 205 | cancelTimer(player); 206 | } else { 207 | sendDragon(drag, player); 208 | } 209 | } 210 | 211 | }, 20L, 20L).getTaskId()); 212 | 213 | sendDragon(dragon, player); 214 | } 215 | 216 | /** 217 | * Checks whether the given player has a bar. 218 | * 219 | * @param player The player who should be checked. 220 | * 221 | * @return True, if the player has a bar, False otherwise. 222 | */ 223 | @Deprecated 224 | public static boolean hasBar(Player player) { 225 | return players.get(player.getUniqueId()) != null; 226 | } 227 | 228 | /** 229 | * Removes the bar from the given player.
230 | * If the player has no bar, this method does nothing. 231 | * 232 | * @param player The player whose bar should be removed. 233 | */ 234 | @Deprecated 235 | public static void removeBar(Player player) { 236 | if (!hasBar(player)) 237 | return; 238 | 239 | FakeDragon dragon = getDragon(player, ""); 240 | 241 | if (dragon instanceof v1_9) { 242 | ((v1_9) dragon).getBar().removePlayer(player); 243 | } else { 244 | Util.sendPacket(player, getDragon(player, "").getDestroyPacket()); 245 | } 246 | 247 | players.remove(player.getUniqueId()); 248 | 249 | cancelTimer(player); 250 | } 251 | 252 | /** 253 | * Modifies the health of an existing bar.
254 | * If the player has no bar, this method does nothing. 255 | * 256 | * @param player The player whose bar should be modified. 257 | * @param percent The percentage of the health bar filled.
258 | * This value must be between 0F and 100F (inclusive). 259 | */ 260 | @Deprecated 261 | public static void setHealth(Player player, float percent) { 262 | if (!hasBar(player)) 263 | return; 264 | 265 | FakeDragon dragon = getDragon(player, ""); 266 | dragon.health = (percent / 100f) * dragon.getMaxHealth(); 267 | 268 | cancelTimer(player); 269 | 270 | if (percent == 0) { 271 | removeBar(player); 272 | } else { 273 | sendDragon(dragon, player); 274 | } 275 | } 276 | 277 | /** 278 | * Get the health of an existing bar. 279 | * 280 | * @param player The player whose bar's health should be returned. 281 | * 282 | * @return The current absolute health of the bar.
283 | * If the player has no bar, this method returns -1. 284 | */ 285 | @Deprecated 286 | public static float getHealth(Player player) { 287 | if (!hasBar(player)) 288 | return -1; 289 | 290 | return getDragon(player, "").health; 291 | } 292 | 293 | /** 294 | * Get the message of an existing bar. 295 | * 296 | * @param player The player whose bar's message should be returned. 297 | * 298 | * @return The current message displayed to the player.
299 | * If the player has no bar, this method returns an empty string. 300 | */ 301 | @Deprecated 302 | public static String getMessage(Player player) { 303 | if (!hasBar(player)) 304 | return ""; 305 | 306 | return getDragon(player, "").name; 307 | } 308 | 309 | private static String cleanMessage(String message) { 310 | if (message.length() > 64) 311 | message = message.substring(0, 63); 312 | 313 | return message; 314 | } 315 | 316 | private static void cancelTimer(Player player) { 317 | Integer timerID = timers.remove(player.getUniqueId()); 318 | 319 | if (timerID != null) { 320 | Bukkit.getScheduler().cancelTask(timerID); 321 | } 322 | } 323 | 324 | private static void sendDragon(FakeDragon dragon, Player player) { 325 | if (dragon instanceof v1_9) { 326 | BossBar bar = ((v1_9) dragon).getBar(); 327 | 328 | bar.addPlayer(player); 329 | bar.setProgress(dragon.health / dragon.getMaxHealth()); 330 | } else { 331 | Util.sendPacket(player, dragon.getMetaPacket(dragon.getWatcher())); 332 | Util.sendPacket(player, dragon.getTeleportPacket(getDragonLocation(player.getLocation()))); 333 | } 334 | } 335 | 336 | private static FakeDragon getDragon(Player player, String message) { 337 | if (hasBar(player)) { 338 | return players.get(player.getUniqueId()); 339 | } else 340 | return addDragon(player, cleanMessage(message)); 341 | } 342 | 343 | private static FakeDragon addDragon(Player player, String message) { 344 | FakeDragon dragon = Util.newDragon(message, getDragonLocation(player.getLocation())); 345 | 346 | if (dragon instanceof v1_9) { 347 | BossBar bar = ((v1_9) dragon).getBar(); 348 | 349 | bar.addPlayer(player); 350 | } else { 351 | Util.sendPacket(player, dragon.getSpawnPacket()); 352 | } 353 | 354 | players.put(player.getUniqueId(), dragon); 355 | 356 | return dragon; 357 | } 358 | 359 | private static FakeDragon addDragon(Player player, Location loc, String message) { 360 | FakeDragon dragon = Util.newDragon(message, getDragonLocation(loc)); 361 | 362 | if (dragon instanceof v1_9) { 363 | BossBar bar = ((v1_9) dragon).getBar(); 364 | 365 | bar.addPlayer(player); 366 | } else { 367 | Util.sendPacket(player, dragon.getSpawnPacket()); 368 | } 369 | 370 | players.put(player.getUniqueId(), dragon); 371 | 372 | return dragon; 373 | } 374 | 375 | private static Location getDragonLocation(Location loc) { 376 | if (Util.isBelowGround) { 377 | loc.subtract(0, 300, 0); 378 | return loc; 379 | } 380 | 381 | float pitch = loc.getPitch(); 382 | 383 | if (pitch >= 55) { 384 | loc.add(0, -300, 0); 385 | } else if (pitch <= -55) { 386 | loc.add(0, 300, 0); 387 | } else { 388 | loc = loc.getBlock().getRelative(getDirection(loc), plugin.getServer().getViewDistance() * 16).getLocation(); 389 | } 390 | 391 | return loc; 392 | } 393 | 394 | private static BlockFace getDirection(Location loc) { 395 | float dir = Math.round(loc.getYaw() / 90); 396 | if (dir == -4 || dir == 0 || dir == 4) 397 | return BlockFace.SOUTH; 398 | if (dir == -1 || dir == 3) 399 | return BlockFace.EAST; 400 | if (dir == -2 || dir == 2) 401 | return BlockFace.NORTH; 402 | if (dir == -3 || dir == 1) 403 | return BlockFace.WEST; 404 | return null; 405 | } 406 | 407 | public void onEnable() { 408 | getConfig().options().copyDefaults(true); 409 | saveConfig(); 410 | 411 | if (getConfig().getBoolean("autoUpdate")) { 412 | new Updater(this, 64876, getFile(), Updater.UpdateType.DEFAULT, false); 413 | } 414 | 415 | try { 416 | MetricsLite metrics = new MetricsLite(this); 417 | metrics.start(); 418 | } catch (IOException e) { 419 | // Failed to submit the stats :-( 420 | } 421 | 422 | plugin = this; 423 | 424 | useSpigotHack = getConfig().getBoolean("useSpigotHack", false); 425 | 426 | if (!useSpigotHack) { 427 | if (v1_8Fake.isUsable()) { 428 | useSpigotHack = true; 429 | Util.detectVersion(); 430 | getLogger().info("Detected spigot hack, enabling fake 1.8"); 431 | } 432 | } 433 | 434 | getServer().getPluginManager().registerEvents(this, this); 435 | 436 | getLogger().info("Loaded"); 437 | 438 | if (useSpigotHack) { 439 | getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() { 440 | 441 | public void run() { 442 | for (UUID uuid : players.keySet()) { 443 | Player p = Bukkit.getPlayer(uuid); 444 | Util.sendPacket(p, players.get(uuid).getTeleportPacket(getDragonLocation(p.getLocation()))); 445 | } 446 | } 447 | }, 0L, 5L); 448 | } 449 | 450 | // TestMode 451 | if (getConfig().getBoolean("testMode")) { 452 | plugin.getServer().getScheduler().runTaskTimer(plugin, new Runnable() { 453 | 454 | @Override 455 | public void run() { 456 | for (Player player : plugin.getServer().getOnlinePlayers()) { 457 | BarAPI.setMessage(player, ChatColor.AQUA + "Testing BarAPI Testing BarAPI Testing BarAPI Testing BarAPI Testing BarAPI Testing BarAPI Testing BarAPI", 10); 458 | } 459 | } 460 | 461 | }, 30L, 300L); 462 | } 463 | } 464 | 465 | public void onDisable() { 466 | for (Player player : plugin.getServer().getOnlinePlayers()) { 467 | quit(player); 468 | } 469 | 470 | players.clear(); 471 | 472 | for (int timerID : timers.values()) { 473 | Bukkit.getScheduler().cancelTask(timerID); 474 | } 475 | 476 | timers.clear(); 477 | } 478 | 479 | @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) 480 | public void PlayerLoggout(PlayerQuitEvent event) { 481 | quit(event.getPlayer()); 482 | } 483 | 484 | @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) 485 | public void onPlayerKick(PlayerKickEvent event) { 486 | quit(event.getPlayer()); 487 | } 488 | 489 | @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) 490 | public void onPlayerTeleport(final PlayerTeleportEvent event) { 491 | handleTeleport(event.getPlayer(), event.getTo().clone()); 492 | } 493 | 494 | @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) 495 | public void onPlayerTeleport(final PlayerRespawnEvent event) { 496 | handleTeleport(event.getPlayer(), event.getRespawnLocation().clone()); 497 | } 498 | 499 | private void handleTeleport(final Player player, final Location loc) { 500 | 501 | if (!hasBar(player)) 502 | return; 503 | 504 | final FakeDragon oldDragon = getDragon(player, ""); 505 | 506 | if (oldDragon instanceof v1_9) return; 507 | 508 | Bukkit.getScheduler().runTaskLater(plugin, new Runnable() { 509 | 510 | @Override 511 | public void run() { 512 | // Check if the player still has a dragon after the two ticks! ;) 513 | if (!hasBar(player)) 514 | return; 515 | 516 | float health = oldDragon.health; 517 | String message = oldDragon.name; 518 | 519 | Util.sendPacket(player, getDragon(player, "").getDestroyPacket()); 520 | 521 | players.remove(player.getUniqueId()); 522 | 523 | FakeDragon dragon = addDragon(player, loc, message); 524 | dragon.health = health; 525 | 526 | sendDragon(dragon, player); 527 | } 528 | 529 | }, 2L); 530 | } 531 | 532 | private void quit(Player player) { 533 | removeBar(player); 534 | } 535 | } 536 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/Util.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi; 2 | 3 | import me.confuser.barapi.nms.*; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.Location; 6 | import org.bukkit.World; 7 | import org.bukkit.entity.Entity; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.lang.reflect.Field; 11 | import java.lang.reflect.InvocationTargetException; 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * This is a utility class for BarAPI. It is based on the code by SoThatsIt. 16 | *

17 | * http://forums.bukkit.org/threads/tutorial-utilizing-the-boss-health-bar 18 | * .158018/page-2#post-1760928 19 | * 20 | * @author James Mortemore 21 | */ 22 | public class Util { 23 | 24 | public static boolean newProtocol = false; 25 | public static String version; 26 | public static Class fakeDragonClass = v1_6.class; 27 | public static boolean isBelowGround = true; 28 | 29 | static { 30 | detectVersion(); 31 | } 32 | 33 | public static void detectVersion() { 34 | if (BarAPI.useSpigotHack()) { 35 | fakeDragonClass = v1_8Fake.class; 36 | version = "v1_7_R4."; 37 | isBelowGround = false; 38 | } else { 39 | String name = Bukkit.getServer().getClass().getPackage().getName(); 40 | String mcVersion = name.substring(name.lastIndexOf('.') + 1); 41 | String[] versions = mcVersion.split("_"); 42 | 43 | if (versions[0].equals("v1")) { 44 | int minor = Integer.parseInt(versions[1]); 45 | 46 | if (minor == 7) { 47 | newProtocol = true; 48 | fakeDragonClass = v1_7.class; 49 | } else if (minor == 8) { 50 | fakeDragonClass = v1_8.class; 51 | isBelowGround = false; 52 | } else if (minor >= 9) { 53 | fakeDragonClass = v1_9.class; 54 | } 55 | } 56 | 57 | version = mcVersion + "."; 58 | } 59 | } 60 | 61 | public static FakeDragon newDragon(String message, Location loc) { 62 | FakeDragon fakeDragon = null; 63 | 64 | try { 65 | fakeDragon = (FakeDragon) fakeDragonClass.getConstructor(String.class, Location.class).newInstance(message, loc); 66 | } catch (IllegalArgumentException e) { 67 | e.printStackTrace(); 68 | } catch (SecurityException e) { 69 | e.printStackTrace(); 70 | } catch (InstantiationException e) { 71 | e.printStackTrace(); 72 | } catch (IllegalAccessException e) { 73 | e.printStackTrace(); 74 | } catch (InvocationTargetException e) { 75 | e.printStackTrace(); 76 | } catch (NoSuchMethodException e) { 77 | e.printStackTrace(); 78 | } 79 | 80 | return fakeDragon; 81 | } 82 | 83 | // Reflection Util 84 | public static void sendPacket(Player p, Object packet) { 85 | try { 86 | Object nmsPlayer = getHandle(p); 87 | Field con_field = nmsPlayer.getClass().getField("playerConnection"); 88 | Object con = con_field.get(nmsPlayer); 89 | Method packet_method = getMethod(con.getClass(), "sendPacket"); 90 | packet_method.invoke(con, packet); 91 | } catch (SecurityException e) { 92 | e.printStackTrace(); 93 | } catch (IllegalArgumentException e) { 94 | e.printStackTrace(); 95 | } catch (IllegalAccessException e) { 96 | e.printStackTrace(); 97 | } catch (InvocationTargetException e) { 98 | e.printStackTrace(); 99 | } catch (NoSuchFieldException e) { 100 | e.printStackTrace(); 101 | } 102 | } 103 | 104 | public static Class getCraftClass(String ClassName) { 105 | String className = "net.minecraft.server." + version + ClassName; 106 | Class c = null; 107 | try { 108 | c = Class.forName(className); 109 | } catch (ClassNotFoundException e) { 110 | e.printStackTrace(); 111 | } 112 | return c; 113 | } 114 | 115 | public static Object getHandle(World world) { 116 | Object nms_entity = null; 117 | Method entity_getHandle = getMethod(world.getClass(), "getHandle"); 118 | try { 119 | nms_entity = entity_getHandle.invoke(world); 120 | } catch (IllegalArgumentException e) { 121 | e.printStackTrace(); 122 | } catch (IllegalAccessException e) { 123 | e.printStackTrace(); 124 | } catch (InvocationTargetException e) { 125 | e.printStackTrace(); 126 | } 127 | return nms_entity; 128 | } 129 | 130 | public static Object getHandle(Entity entity) { 131 | Object nms_entity = null; 132 | Method entity_getHandle = getMethod(entity.getClass(), "getHandle"); 133 | try { 134 | nms_entity = entity_getHandle.invoke(entity); 135 | } catch (IllegalArgumentException e) { 136 | e.printStackTrace(); 137 | } catch (IllegalAccessException e) { 138 | e.printStackTrace(); 139 | } catch (InvocationTargetException e) { 140 | e.printStackTrace(); 141 | } 142 | return nms_entity; 143 | } 144 | 145 | public static Field getField(Class cl, String field_name) { 146 | try { 147 | Field field = cl.getDeclaredField(field_name); 148 | return field; 149 | } catch (SecurityException e) { 150 | e.printStackTrace(); 151 | } catch (NoSuchFieldException e) { 152 | e.printStackTrace(); 153 | } 154 | return null; 155 | } 156 | 157 | public static Method getMethod(Class cl, String method, Class[] args) { 158 | for (Method m : cl.getMethods()) { 159 | if (m.getName().equals(method) && ClassListEqual(args, m.getParameterTypes())) { 160 | return m; 161 | } 162 | } 163 | return null; 164 | } 165 | 166 | public static Method getMethod(Class cl, String method, Integer args) { 167 | for (Method m : cl.getMethods()) { 168 | if (m.getName().equals(method) && args.equals(new Integer(m.getParameterTypes().length))) { 169 | return m; 170 | } 171 | } 172 | return null; 173 | } 174 | 175 | public static Method getMethod(Class cl, String method) { 176 | for (Method m : cl.getMethods()) { 177 | if (m.getName().equals(method)) { 178 | return m; 179 | } 180 | } 181 | return null; 182 | } 183 | 184 | public static boolean ClassListEqual(Class[] l1, Class[] l2) { 185 | boolean equal = true; 186 | 187 | if (l1.length != l2.length) 188 | return false; 189 | for (int i = 0; i < l1.length; i++) { 190 | if (l1[i] != l2[i]) { 191 | equal = false; 192 | break; 193 | } 194 | } 195 | 196 | return equal; 197 | } 198 | 199 | } -------------------------------------------------------------------------------- /src/me/confuser/barapi/nms/FakeDragon.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi.nms; 2 | 3 | import me.confuser.barapi.Util; 4 | 5 | import org.bukkit.Location; 6 | 7 | public abstract class FakeDragon { 8 | private float maxHealth = 200; 9 | private int x; 10 | private int y; 11 | private int z; 12 | 13 | private int pitch = 0; 14 | private int yaw = 0; 15 | private byte xvel = 0; 16 | private byte yvel = 0; 17 | private byte zvel = 0; 18 | public float health = 0; 19 | private boolean visible = false; 20 | public String name; 21 | private Object world; 22 | 23 | public FakeDragon(String name, Location loc, int percent) { 24 | this.name = name; 25 | this.x = loc.getBlockX(); 26 | this.y = loc.getBlockY(); 27 | this.z = loc.getBlockZ(); 28 | this.health = percent / 100F * maxHealth; 29 | this.world = Util.getHandle(loc.getWorld()); 30 | } 31 | 32 | public FakeDragon(String name, Location loc) { 33 | this.name = name; 34 | this.x = loc.getBlockX(); 35 | this.y = loc.getBlockY(); 36 | this.z = loc.getBlockZ(); 37 | this.world = Util.getHandle(loc.getWorld()); 38 | } 39 | 40 | public float getMaxHealth() { 41 | return maxHealth; 42 | } 43 | 44 | public void setHealth(int percent) { 45 | this.health = percent / 100F * maxHealth; 46 | } 47 | 48 | public void setName(String name) { 49 | this.name = name; 50 | } 51 | 52 | public int getX() { 53 | return x; 54 | } 55 | 56 | public void setX(int x) { 57 | this.x = x; 58 | } 59 | 60 | public int getY() { 61 | return y; 62 | } 63 | 64 | public void setY(int y) { 65 | this.y = y; 66 | } 67 | 68 | public int getZ() { 69 | return z; 70 | } 71 | 72 | public void setZ(int z) { 73 | this.z = z; 74 | } 75 | 76 | public int getPitch() { 77 | return pitch; 78 | } 79 | 80 | public void setPitch(int pitch) { 81 | this.pitch = pitch; 82 | } 83 | 84 | public int getYaw() { 85 | return yaw; 86 | } 87 | 88 | public void setYaw(int yaw) { 89 | this.yaw = yaw; 90 | } 91 | 92 | public byte getXvel() { 93 | return xvel; 94 | } 95 | 96 | public void setXvel(byte xvel) { 97 | this.xvel = xvel; 98 | } 99 | 100 | public byte getYvel() { 101 | return yvel; 102 | } 103 | 104 | public void setYvel(byte yvel) { 105 | this.yvel = yvel; 106 | } 107 | 108 | public byte getZvel() { 109 | return zvel; 110 | } 111 | 112 | public void setZvel(byte zvel) { 113 | this.zvel = zvel; 114 | } 115 | 116 | public boolean isVisible() { 117 | return visible; 118 | } 119 | 120 | public void setVisible(boolean visible) { 121 | this.visible = visible; 122 | } 123 | 124 | public Object getWorld() { 125 | return world; 126 | } 127 | 128 | public void setWorld(Object world) { 129 | this.world = world; 130 | } 131 | 132 | public void setMaxHealth(float max) { 133 | maxHealth = max; 134 | } 135 | 136 | public abstract Object getSpawnPacket(); 137 | 138 | public abstract Object getDestroyPacket(); 139 | 140 | public abstract Object getMetaPacket(Object watcher); 141 | 142 | public abstract Object getTeleportPacket(Location loc); 143 | 144 | public abstract Object getWatcher(); 145 | } 146 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/nms/v1_6.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi.nms; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | import me.confuser.barapi.Util; 8 | 9 | import org.bukkit.Location; 10 | import org.bukkit.entity.EntityType; 11 | 12 | /** 13 | * This is the FakeDragon class for BarAPI. 14 | * It is based on the code by SoThatsIt. 15 | * 16 | * http://forums.bukkit.org/threads/tutorial-utilizing-the-boss-health-bar.158018/page-2#post-1760928 17 | * 18 | * @author James Mortemore 19 | */ 20 | 21 | public class v1_6 extends FakeDragon { 22 | private static final Integer EntityID = 6000; 23 | 24 | public v1_6(String name, Location loc) { 25 | super(name, loc); 26 | } 27 | 28 | @SuppressWarnings("deprecation") 29 | @Override 30 | public Object getSpawnPacket() { 31 | Class mob_class = Util.getCraftClass("Packet24MobSpawn"); 32 | Object mobPacket = null; 33 | try { 34 | mobPacket = mob_class.newInstance(); 35 | 36 | Field a = Util.getField(mob_class, "a"); 37 | a.setAccessible(true); 38 | a.set(mobPacket, EntityID);// Entity ID 39 | Field b = Util.getField(mob_class, "b"); 40 | b.setAccessible(true); 41 | b.set(mobPacket, EntityType.ENDER_DRAGON.getTypeId());// Mob type 42 | // (ID: 64) 43 | Field c = Util.getField(mob_class, "c"); 44 | c.setAccessible(true); 45 | c.set(mobPacket, getX());// X position 46 | Field d = Util.getField(mob_class, "d"); 47 | d.setAccessible(true); 48 | d.set(mobPacket, getY());// Y position 49 | Field e = Util.getField(mob_class, "e"); 50 | e.setAccessible(true); 51 | e.set(mobPacket, getZ());// Z position 52 | Field f = Util.getField(mob_class, "f"); 53 | f.setAccessible(true); 54 | f.set(mobPacket, (byte) ((int) (getPitch() * 256.0F / 360.0F)));// Pitch 55 | Field g = Util.getField(mob_class, "g"); 56 | g.setAccessible(true); 57 | g.set(mobPacket, (byte) ((int) 0));// Head 58 | // Pitch 59 | Field h = Util.getField(mob_class, "h"); 60 | h.setAccessible(true); 61 | h.set(mobPacket, (byte) ((int) (getYaw() * 256.0F / 360.0F)));// Yaw 62 | Field i = Util.getField(mob_class, "i"); 63 | i.setAccessible(true); 64 | i.set(mobPacket, getXvel());// X velocity 65 | Field j = Util.getField(mob_class, "j"); 66 | j.setAccessible(true); 67 | j.set(mobPacket, getYvel());// Y velocity 68 | Field k = Util.getField(mob_class, "k"); 69 | k.setAccessible(true); 70 | k.set(mobPacket, getZvel());// Z velocity 71 | 72 | Object watcher = getWatcher(); 73 | Field t = Util.getField(mob_class, "t"); 74 | t.setAccessible(true); 75 | t.set(mobPacket, watcher); 76 | } catch (InstantiationException e1) { 77 | e1.printStackTrace(); 78 | } catch (IllegalAccessException e1) { 79 | e1.printStackTrace(); 80 | } 81 | 82 | return mobPacket; 83 | } 84 | 85 | @Override 86 | public Object getDestroyPacket() { 87 | Class packet_class = Util.getCraftClass("Packet29DestroyEntity"); 88 | Object packet = null; 89 | try { 90 | packet = packet_class.newInstance(); 91 | 92 | Field a = Util.getField(packet_class, "a"); 93 | a.setAccessible(true); 94 | a.set(packet, new int[] { EntityID }); 95 | } catch (InstantiationException e) { 96 | e.printStackTrace(); 97 | } catch (IllegalAccessException e) { 98 | e.printStackTrace(); 99 | } 100 | 101 | return packet; 102 | } 103 | 104 | @Override 105 | public Object getMetaPacket(Object watcher) { 106 | Class packet_class = Util.getCraftClass("Packet40EntityMetadata"); 107 | Object packet = null; 108 | try { 109 | packet = packet_class.newInstance(); 110 | 111 | Field a = Util.getField(packet_class, "a"); 112 | a.setAccessible(true); 113 | a.set(packet, EntityID); 114 | 115 | Method watcher_c = Util.getMethod(watcher.getClass(), "c"); 116 | Field b = Util.getField(packet_class, "b"); 117 | b.setAccessible(true); 118 | b.set(packet, watcher_c.invoke(watcher)); 119 | } catch (InstantiationException e) { 120 | e.printStackTrace(); 121 | } catch (IllegalAccessException e) { 122 | e.printStackTrace(); 123 | } catch (IllegalArgumentException e) { 124 | e.printStackTrace(); 125 | } catch (InvocationTargetException e) { 126 | e.printStackTrace(); 127 | } 128 | 129 | return packet; 130 | } 131 | 132 | @Override 133 | public Object getTeleportPacket(Location loc) { 134 | Class packet_class = Util.getCraftClass("Packet34EntityTeleport"); 135 | Object packet = null; 136 | try { 137 | packet = packet_class.newInstance(); 138 | 139 | Field a = Util.getField(packet_class, "a"); 140 | a.setAccessible(true); 141 | a.set(packet, EntityID); 142 | Field b = Util.getField(packet_class, "b"); 143 | b.setAccessible(true); 144 | b.set(packet, (int) Math.floor(loc.getX() * 32.0D)); 145 | Field c = Util.getField(packet_class, "c"); 146 | c.setAccessible(true); 147 | c.set(packet, (int) Math.floor(loc.getY() * 32.0D)); 148 | Field d = Util.getField(packet_class, "d"); 149 | d.setAccessible(true); 150 | d.set(packet, (int) Math.floor(loc.getZ() * 32.0D)); 151 | Field e = Util.getField(packet_class, "e"); 152 | e.setAccessible(true); 153 | e.set(packet, (byte) ((int) (loc.getYaw() * 256.0F / 360.0F))); 154 | Field f = Util.getField(packet_class, "f"); 155 | f.setAccessible(true); 156 | f.set(packet, (byte) ((int) (loc.getPitch() * 256.0F / 360.0F))); 157 | } catch (InstantiationException e) { 158 | e.printStackTrace(); 159 | } catch (IllegalAccessException e) { 160 | e.printStackTrace(); 161 | } 162 | return packet; 163 | } 164 | 165 | @Override 166 | public Object getWatcher() { 167 | Class watcher_class = Util.getCraftClass("DataWatcher"); 168 | Object watcher = null; 169 | try { 170 | watcher = watcher_class.newInstance(); 171 | 172 | Method a = Util.getMethod(watcher_class, "a", new Class[] { int.class, Object.class }); 173 | a.setAccessible(true); 174 | 175 | a.invoke(watcher, 0, isVisible() ? (byte) 0 : (byte) 0x20); 176 | a.invoke(watcher, 6, (Float) (float) health); 177 | a.invoke(watcher, 7, (Integer) (int) 0); 178 | a.invoke(watcher, 8, (Byte) (byte) 0); 179 | a.invoke(watcher, 10, (String) name); 180 | a.invoke(watcher, 11, (Byte) (byte) 1); 181 | } catch (InstantiationException e) { 182 | e.printStackTrace(); 183 | } catch (IllegalAccessException e) { 184 | e.printStackTrace(); 185 | } catch (IllegalArgumentException e) { 186 | e.printStackTrace(); 187 | } catch (InvocationTargetException e) { 188 | e.printStackTrace(); 189 | } 190 | 191 | return watcher; 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/nms/v1_7.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi.nms; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | import me.confuser.barapi.Util; 8 | 9 | import org.bukkit.Location; 10 | 11 | /** 12 | * This is the FakeDragon class for BarAPI. 13 | * It is based on the code by SoThatsIt. 14 | * 15 | * http://forums.bukkit.org/threads/tutorial-utilizing-the-boss-health-bar.158018/page-5#post-2053705 16 | * 17 | * @author James Mortemore 18 | */ 19 | 20 | public class v1_7 extends FakeDragon { 21 | private Object dragon; 22 | private int id; 23 | 24 | public v1_7(String name, Location loc) { 25 | super(name, loc); 26 | } 27 | 28 | @Override 29 | public Object getSpawnPacket() { 30 | Class Entity = Util.getCraftClass("Entity"); 31 | Class EntityLiving = Util.getCraftClass("EntityLiving"); 32 | Class EntityEnderDragon = Util.getCraftClass("EntityEnderDragon"); 33 | Object packet = null; 34 | try { 35 | dragon = EntityEnderDragon.getConstructor(Util.getCraftClass("World")).newInstance(getWorld()); 36 | 37 | Method setLocation = Util.getMethod(EntityEnderDragon, "setLocation", new Class[] { double.class, double.class, double.class, float.class, float.class }); 38 | setLocation.invoke(dragon, getX(), getY(), getZ(), getPitch(), getYaw()); 39 | 40 | Method setInvisible = Util.getMethod(EntityEnderDragon, "setInvisible", new Class[] { boolean.class }); 41 | setInvisible.invoke(dragon, isVisible()); 42 | 43 | Method setCustomName = Util.getMethod(EntityEnderDragon, "setCustomName", new Class[] { String.class }); 44 | setCustomName.invoke(dragon, name); 45 | 46 | Method setHealth = Util.getMethod(EntityEnderDragon, "setHealth", new Class[] { float.class }); 47 | setHealth.invoke(dragon, health); 48 | 49 | Field motX = Util.getField(Entity, "motX"); 50 | motX.set(dragon, getXvel()); 51 | 52 | Field motY = Util.getField(Entity, "motY"); 53 | motY.set(dragon, getYvel()); 54 | 55 | Field motZ = Util.getField(Entity, "motZ"); 56 | motZ.set(dragon, getZvel()); 57 | 58 | Method getId = Util.getMethod(EntityEnderDragon, "getId", new Class[] {}); 59 | this.id = (Integer) getId.invoke(dragon); 60 | 61 | Class PacketPlayOutSpawnEntityLiving = Util.getCraftClass("PacketPlayOutSpawnEntityLiving"); 62 | 63 | packet = PacketPlayOutSpawnEntityLiving.getConstructor(new Class[] { EntityLiving }).newInstance(dragon); 64 | } catch (IllegalArgumentException e) { 65 | e.printStackTrace(); 66 | } catch (SecurityException e) { 67 | e.printStackTrace(); 68 | } catch (InstantiationException e) { 69 | e.printStackTrace(); 70 | } catch (IllegalAccessException e) { 71 | e.printStackTrace(); 72 | } catch (InvocationTargetException e) { 73 | e.printStackTrace(); 74 | } catch (NoSuchMethodException e) { 75 | e.printStackTrace(); 76 | } 77 | 78 | return packet; 79 | } 80 | 81 | @Override 82 | public Object getDestroyPacket() { 83 | Class PacketPlayOutEntityDestroy = Util.getCraftClass("PacketPlayOutEntityDestroy"); 84 | 85 | Object packet = null; 86 | try { 87 | packet = PacketPlayOutEntityDestroy.newInstance(); 88 | Field a = PacketPlayOutEntityDestroy.getDeclaredField("a"); 89 | a.setAccessible(true); 90 | a.set(packet, new int[] { id }); 91 | } catch (SecurityException e) { 92 | e.printStackTrace(); 93 | } catch (NoSuchFieldException e) { 94 | e.printStackTrace(); 95 | } catch (InstantiationException e) { 96 | e.printStackTrace(); 97 | } catch (IllegalAccessException e) { 98 | e.printStackTrace(); 99 | } catch (IllegalArgumentException e) { 100 | e.printStackTrace(); 101 | } 102 | 103 | return packet; 104 | } 105 | 106 | @Override 107 | public Object getMetaPacket(Object watcher) { 108 | Class DataWatcher = Util.getCraftClass("DataWatcher"); 109 | 110 | Class PacketPlayOutEntityMetadata = Util.getCraftClass("PacketPlayOutEntityMetadata"); 111 | 112 | Object packet = null; 113 | try { 114 | packet = PacketPlayOutEntityMetadata.getConstructor(new Class[] { int.class, DataWatcher, boolean.class }).newInstance(id, watcher, true); 115 | } catch (IllegalArgumentException e) { 116 | e.printStackTrace(); 117 | } catch (SecurityException e) { 118 | e.printStackTrace(); 119 | } catch (InstantiationException e) { 120 | e.printStackTrace(); 121 | } catch (IllegalAccessException e) { 122 | e.printStackTrace(); 123 | } catch (InvocationTargetException e) { 124 | e.printStackTrace(); 125 | } catch (NoSuchMethodException e) { 126 | e.printStackTrace(); 127 | } 128 | 129 | return packet; 130 | } 131 | 132 | @Override 133 | public Object getTeleportPacket(Location loc) { 134 | Class PacketPlayOutEntityTeleport = Util.getCraftClass("PacketPlayOutEntityTeleport"); 135 | 136 | Object packet = null; 137 | 138 | try { 139 | packet = PacketPlayOutEntityTeleport.getConstructor(new Class[] { int.class, int.class, int.class, int.class, byte.class, byte.class }).newInstance(this.id, loc.getBlockX() * 32, loc.getBlockY() * 32, loc.getBlockZ() * 32, (byte) ((int) loc.getYaw() * 256 / 360), (byte) ((int) loc.getPitch() * 256 / 360)); 140 | } catch (IllegalArgumentException e) { 141 | e.printStackTrace(); 142 | } catch (SecurityException e) { 143 | e.printStackTrace(); 144 | } catch (InstantiationException e) { 145 | e.printStackTrace(); 146 | } catch (IllegalAccessException e) { 147 | e.printStackTrace(); 148 | } catch (InvocationTargetException e) { 149 | e.printStackTrace(); 150 | } catch (NoSuchMethodException e) { 151 | e.printStackTrace(); 152 | } 153 | 154 | return packet; 155 | } 156 | 157 | @Override 158 | public Object getWatcher() { 159 | Class Entity = Util.getCraftClass("Entity"); 160 | Class DataWatcher = Util.getCraftClass("DataWatcher"); 161 | 162 | Object watcher = null; 163 | try { 164 | watcher = DataWatcher.getConstructor(new Class[] { Entity }).newInstance(dragon); 165 | Method a = Util.getMethod(DataWatcher, "a", new Class[] { int.class, Object.class }); 166 | 167 | a.invoke(watcher, 0, isVisible() ? (byte) 0 : (byte) 0x20); 168 | a.invoke(watcher, 6, (Float) health); 169 | a.invoke(watcher, 7, (Integer) 0); 170 | a.invoke(watcher, 8, (Byte) (byte) 0); 171 | a.invoke(watcher, 10, name); 172 | a.invoke(watcher, 11, (Byte) (byte) 1); 173 | } catch (IllegalArgumentException e) { 174 | 175 | e.printStackTrace(); 176 | } catch (SecurityException e) { 177 | 178 | e.printStackTrace(); 179 | } catch (InstantiationException e) { 180 | 181 | e.printStackTrace(); 182 | } catch (IllegalAccessException e) { 183 | 184 | e.printStackTrace(); 185 | } catch (InvocationTargetException e) { 186 | 187 | e.printStackTrace(); 188 | } catch (NoSuchMethodException e) { 189 | 190 | e.printStackTrace(); 191 | } 192 | return watcher; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/nms/v1_8.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi.nms; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | import me.confuser.barapi.Util; 8 | 9 | import org.bukkit.Location; 10 | 11 | public class v1_8 extends FakeDragon { 12 | private Object dragon; 13 | private int id; 14 | 15 | public v1_8(String name, Location loc) { 16 | super(name, loc); 17 | } 18 | 19 | @Override 20 | public Object getSpawnPacket() { 21 | Class Entity = Util.getCraftClass("Entity"); 22 | Class EntityLiving = Util.getCraftClass("EntityLiving"); 23 | Class EntityEnderDragon = Util.getCraftClass("EntityEnderDragon"); 24 | Object packet = null; 25 | 26 | try { 27 | dragon = EntityEnderDragon.getConstructor(Util.getCraftClass("World")).newInstance(getWorld()); 28 | 29 | Method setLocation = Util.getMethod(EntityEnderDragon, "setLocation", new Class[] { double.class, double.class, double.class, float.class, float.class }); 30 | setLocation.invoke(dragon, getX(), getY(), getZ(), getPitch(), getYaw()); 31 | 32 | Method setInvisible = Util.getMethod(EntityEnderDragon, "setInvisible", new Class[] { boolean.class }); 33 | setInvisible.invoke(dragon, true); 34 | 35 | Method setCustomName = Util.getMethod(EntityEnderDragon, "setCustomName", new Class[] { String.class }); 36 | setCustomName.invoke(dragon, name); 37 | 38 | Method setHealth = Util.getMethod(EntityEnderDragon, "setHealth", new Class[] { float.class }); 39 | setHealth.invoke(dragon, health); 40 | 41 | Field motX = Util.getField(Entity, "motX"); 42 | motX.set(dragon, getXvel()); 43 | 44 | Field motY = Util.getField(Entity, "motY"); 45 | motY.set(dragon, getYvel()); 46 | 47 | Field motZ = Util.getField(Entity, "motZ"); 48 | motZ.set(dragon, getZvel()); 49 | 50 | Method getId = Util.getMethod(EntityEnderDragon, "getId", new Class[] {}); 51 | this.id = (Integer) getId.invoke(dragon); 52 | 53 | Class PacketPlayOutSpawnEntityLiving = Util.getCraftClass("PacketPlayOutSpawnEntityLiving"); 54 | 55 | packet = PacketPlayOutSpawnEntityLiving.getConstructor(new Class[] { EntityLiving }).newInstance(dragon); 56 | } catch (IllegalArgumentException e) { 57 | e.printStackTrace(); 58 | } catch (SecurityException e) { 59 | e.printStackTrace(); 60 | } catch (InstantiationException e) { 61 | e.printStackTrace(); 62 | } catch (IllegalAccessException e) { 63 | e.printStackTrace(); 64 | } catch (InvocationTargetException e) { 65 | e.printStackTrace(); 66 | } catch (NoSuchMethodException e) { 67 | e.printStackTrace(); 68 | } 69 | 70 | return packet; 71 | } 72 | 73 | @Override 74 | public Object getDestroyPacket() { 75 | Class PacketPlayOutEntityDestroy = Util.getCraftClass("PacketPlayOutEntityDestroy"); 76 | 77 | Object packet = null; 78 | try { 79 | packet = PacketPlayOutEntityDestroy.newInstance(); 80 | Field a = PacketPlayOutEntityDestroy.getDeclaredField("a"); 81 | a.setAccessible(true); 82 | a.set(packet, new int[] { id }); 83 | } catch (SecurityException e) { 84 | e.printStackTrace(); 85 | } catch (NoSuchFieldException e) { 86 | e.printStackTrace(); 87 | } catch (InstantiationException e) { 88 | e.printStackTrace(); 89 | } catch (IllegalAccessException e) { 90 | e.printStackTrace(); 91 | } catch (IllegalArgumentException e) { 92 | e.printStackTrace(); 93 | } 94 | 95 | return packet; 96 | } 97 | 98 | @Override 99 | public Object getMetaPacket(Object watcher) { 100 | Class DataWatcher = Util.getCraftClass("DataWatcher"); 101 | 102 | Class PacketPlayOutEntityMetadata = Util.getCraftClass("PacketPlayOutEntityMetadata"); 103 | 104 | Object packet = null; 105 | try { 106 | packet = PacketPlayOutEntityMetadata.getConstructor(new Class[] { int.class, DataWatcher, boolean.class }).newInstance(id, watcher, true); 107 | } catch (IllegalArgumentException e) { 108 | e.printStackTrace(); 109 | } catch (SecurityException e) { 110 | e.printStackTrace(); 111 | } catch (InstantiationException e) { 112 | e.printStackTrace(); 113 | } catch (IllegalAccessException e) { 114 | e.printStackTrace(); 115 | } catch (InvocationTargetException e) { 116 | e.printStackTrace(); 117 | } catch (NoSuchMethodException e) { 118 | e.printStackTrace(); 119 | } 120 | 121 | return packet; 122 | } 123 | 124 | @Override 125 | public Object getTeleportPacket(Location loc) { 126 | Class PacketPlayOutEntityTeleport = Util.getCraftClass("PacketPlayOutEntityTeleport"); 127 | Object packet = null; 128 | 129 | try { 130 | packet = PacketPlayOutEntityTeleport.getConstructor(new Class[] { int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class }).newInstance(this.id, loc.getBlockX() * 32, loc.getBlockY() * 32, loc.getBlockZ() * 32, (byte) ((int) loc.getYaw() * 256 / 360), (byte) ((int) loc.getPitch() * 256 / 360), false); 131 | } catch (IllegalArgumentException e) { 132 | e.printStackTrace(); 133 | } catch (SecurityException e) { 134 | e.printStackTrace(); 135 | } catch (InstantiationException e) { 136 | e.printStackTrace(); 137 | } catch (IllegalAccessException e) { 138 | e.printStackTrace(); 139 | } catch (InvocationTargetException e) { 140 | e.printStackTrace(); 141 | } catch (NoSuchMethodException e) { 142 | e.printStackTrace(); 143 | } 144 | 145 | return packet; 146 | } 147 | 148 | @Override 149 | public Object getWatcher() { 150 | Class Entity = Util.getCraftClass("Entity"); 151 | Class DataWatcher = Util.getCraftClass("DataWatcher"); 152 | 153 | Object watcher = null; 154 | try { 155 | watcher = DataWatcher.getConstructor(new Class[] { Entity }).newInstance(dragon); 156 | Method a = Util.getMethod(DataWatcher, "a", new Class[] { int.class, Object.class }); 157 | 158 | a.invoke(watcher, 5, isVisible() ? (byte) 0 : (byte) 0x20); 159 | a.invoke(watcher, 6, (Float) health); 160 | a.invoke(watcher, 7, (Integer) 0); 161 | a.invoke(watcher, 8, (Byte) (byte) 0); 162 | a.invoke(watcher, 10, name); 163 | a.invoke(watcher, 11, (Byte) (byte) 1); 164 | } catch (IllegalArgumentException e) { 165 | e.printStackTrace(); 166 | } catch (SecurityException e) { 167 | e.printStackTrace(); 168 | } catch (InstantiationException e) { 169 | e.printStackTrace(); 170 | } catch (IllegalAccessException e) { 171 | e.printStackTrace(); 172 | } catch (InvocationTargetException e) { 173 | e.printStackTrace(); 174 | } catch (NoSuchMethodException e) { 175 | e.printStackTrace(); 176 | } 177 | 178 | return watcher; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/nms/v1_8Fake.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi.nms; 2 | 3 | import me.confuser.barapi.Util; 4 | import org.bukkit.Location; 5 | 6 | import java.lang.reflect.Field; 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | 10 | /** 11 | * This is the FakeDragon class for BarAPI. 12 | * It is based on the code by SoThatsIt. 13 | *

14 | * http://forums.bukkit.org/threads/tutorial-utilizing-the-boss-health-bar.158018/page-5#post-2053705 15 | * 16 | * @author James Mortemore 17 | */ 18 | 19 | public class v1_8Fake extends FakeDragon { 20 | 21 | private Object dragon; 22 | private int id; 23 | 24 | public v1_8Fake(String name, Location loc) { 25 | super(name, loc); 26 | } 27 | 28 | public static boolean isUsable() { 29 | Class PacketPlayOutEntityTeleport = Util.getCraftClass("PacketPlayOutEntityTeleport"); 30 | 31 | try { 32 | PacketPlayOutEntityTeleport 33 | .getConstructor(new Class[] { int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class, boolean.class }); 34 | } catch (IllegalArgumentException e) { 35 | return false; 36 | } catch (SecurityException e) { 37 | return false; 38 | } catch (NoSuchMethodException e) { 39 | return false; 40 | } 41 | 42 | return true; 43 | } 44 | 45 | @Override 46 | public Object getSpawnPacket() { 47 | Class Entity = Util.getCraftClass("Entity"); 48 | Class EntityLiving = Util.getCraftClass("EntityLiving"); 49 | Class EntityEnderDragon = Util.getCraftClass("EntityEnderDragon"); 50 | Object packet = null; 51 | try { 52 | dragon = EntityEnderDragon.getConstructor(Util.getCraftClass("World")).newInstance(getWorld()); 53 | 54 | Method setLocation = Util 55 | .getMethod(EntityEnderDragon, "setLocation", new Class[] { double.class, double.class, double.class, float.class, float.class }); 56 | setLocation.invoke(dragon, getX(), getY(), getZ(), getPitch(), getYaw()); 57 | 58 | Method setInvisible = Util.getMethod(EntityEnderDragon, "setInvisible", new Class[] { boolean.class }); 59 | setInvisible.invoke(dragon, true); 60 | 61 | Method setCustomName = Util.getMethod(EntityEnderDragon, "setCustomName", new Class[] { String.class }); 62 | setCustomName.invoke(dragon, name); 63 | 64 | Method setHealth = Util.getMethod(EntityEnderDragon, "setHealth", new Class[] { float.class }); 65 | setHealth.invoke(dragon, health); 66 | 67 | Field motX = Util.getField(Entity, "motX"); 68 | motX.set(dragon, getXvel()); 69 | 70 | Field motY = Util.getField(Entity, "motY"); 71 | motY.set(dragon, getYvel()); 72 | 73 | Field motZ = Util.getField(Entity, "motZ"); 74 | motZ.set(dragon, getZvel()); 75 | 76 | Method getId = Util.getMethod(EntityEnderDragon, "getId", new Class[] {}); 77 | this.id = (Integer) getId.invoke(dragon); 78 | 79 | Class PacketPlayOutSpawnEntityLiving = Util.getCraftClass("PacketPlayOutSpawnEntityLiving"); 80 | 81 | packet = PacketPlayOutSpawnEntityLiving.getConstructor(new Class[] { EntityLiving }).newInstance(dragon); 82 | } catch (IllegalArgumentException e) { 83 | e.printStackTrace(); 84 | } catch (SecurityException e) { 85 | e.printStackTrace(); 86 | } catch (InstantiationException e) { 87 | e.printStackTrace(); 88 | } catch (IllegalAccessException e) { 89 | e.printStackTrace(); 90 | } catch (InvocationTargetException e) { 91 | e.printStackTrace(); 92 | } catch (NoSuchMethodException e) { 93 | e.printStackTrace(); 94 | } 95 | 96 | return packet; 97 | } 98 | 99 | @Override 100 | public Object getDestroyPacket() { 101 | Class PacketPlayOutEntityDestroy = Util.getCraftClass("PacketPlayOutEntityDestroy"); 102 | 103 | Object packet = null; 104 | try { 105 | packet = PacketPlayOutEntityDestroy.newInstance(); 106 | Field a = PacketPlayOutEntityDestroy.getDeclaredField("a"); 107 | a.setAccessible(true); 108 | a.set(packet, new int[] { id }); 109 | } catch (SecurityException e) { 110 | e.printStackTrace(); 111 | } catch (NoSuchFieldException e) { 112 | e.printStackTrace(); 113 | } catch (InstantiationException e) { 114 | e.printStackTrace(); 115 | } catch (IllegalAccessException e) { 116 | e.printStackTrace(); 117 | } catch (IllegalArgumentException e) { 118 | e.printStackTrace(); 119 | } 120 | 121 | return packet; 122 | } 123 | 124 | @Override 125 | public Object getMetaPacket(Object watcher) { 126 | Class DataWatcher = Util.getCraftClass("DataWatcher"); 127 | 128 | Class PacketPlayOutEntityMetadata = Util.getCraftClass("PacketPlayOutEntityMetadata"); 129 | 130 | Object packet = null; 131 | try { 132 | packet = PacketPlayOutEntityMetadata.getConstructor(new Class[] { int.class, DataWatcher, boolean.class }) 133 | .newInstance(id, watcher, true); 134 | } catch (IllegalArgumentException e) { 135 | e.printStackTrace(); 136 | } catch (SecurityException e) { 137 | e.printStackTrace(); 138 | } catch (InstantiationException e) { 139 | e.printStackTrace(); 140 | } catch (IllegalAccessException e) { 141 | e.printStackTrace(); 142 | } catch (InvocationTargetException e) { 143 | e.printStackTrace(); 144 | } catch (NoSuchMethodException e) { 145 | e.printStackTrace(); 146 | } 147 | 148 | return packet; 149 | } 150 | 151 | @Override 152 | public Object getTeleportPacket(Location loc) { 153 | Class PacketPlayOutEntityTeleport = Util.getCraftClass("PacketPlayOutEntityTeleport"); 154 | Object packet = null; 155 | 156 | try { 157 | packet = PacketPlayOutEntityTeleport 158 | .getConstructor(new Class[] { int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class, boolean.class }) 159 | .newInstance(this.id, loc.getBlockX() * 32, loc.getBlockY() * 32, loc.getBlockZ() * 32, (byte) ((int) loc 160 | .getYaw() * 256 / 360), (byte) ((int) loc.getPitch() * 256 / 360), false, false); 161 | } catch (IllegalArgumentException e) { 162 | e.printStackTrace(); 163 | } catch (SecurityException e) { 164 | e.printStackTrace(); 165 | } catch (InstantiationException e) { 166 | e.printStackTrace(); 167 | } catch (IllegalAccessException e) { 168 | e.printStackTrace(); 169 | } catch (InvocationTargetException e) { 170 | e.printStackTrace(); 171 | } catch (NoSuchMethodException e) { 172 | e.printStackTrace(); 173 | } 174 | 175 | return packet; 176 | } 177 | 178 | @Override 179 | public Object getWatcher() { 180 | Class Entity = Util.getCraftClass("Entity"); 181 | Class DataWatcher = Util.getCraftClass("DataWatcher"); 182 | 183 | Object watcher = null; 184 | try { 185 | watcher = DataWatcher.getConstructor(new Class[] { Entity }).newInstance(dragon); 186 | Method a = Util.getMethod(DataWatcher, "a", new Class[] { int.class, Object.class }); 187 | 188 | a.invoke(watcher, 5, isVisible() ? (byte) 0 : (byte) 0x20); 189 | a.invoke(watcher, 6, (Float) health); 190 | a.invoke(watcher, 7, (Integer) 0); 191 | a.invoke(watcher, 8, (Byte) (byte) 0); 192 | a.invoke(watcher, 10, name); 193 | a.invoke(watcher, 11, (Byte) (byte) 1); 194 | } catch (IllegalArgumentException e) { 195 | e.printStackTrace(); 196 | } catch (SecurityException e) { 197 | e.printStackTrace(); 198 | } catch (InstantiationException e) { 199 | e.printStackTrace(); 200 | } catch (IllegalAccessException e) { 201 | e.printStackTrace(); 202 | } catch (InvocationTargetException e) { 203 | e.printStackTrace(); 204 | } catch (NoSuchMethodException e) { 205 | e.printStackTrace(); 206 | } 207 | 208 | return watcher; 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/me/confuser/barapi/nms/v1_9.java: -------------------------------------------------------------------------------- 1 | package me.confuser.barapi.nms; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Location; 5 | import org.bukkit.boss.BarColor; 6 | import org.bukkit.boss.BarStyle; 7 | import org.bukkit.boss.BossBar; 8 | 9 | /** 10 | * This is the FakeDragon class for BarAPI. 11 | * It is based on the code by SoThatsIt. 12 | *

13 | * http://forums.bukkit.org/threads/tutorial-utilizing-the-boss-health-bar.158018/page-5#post-2053705 14 | * 15 | * @author James Mortemore 16 | */ 17 | 18 | public class v1_9 extends FakeDragon { 19 | 20 | private Object dragon; 21 | private int id; 22 | private BossBar bar; 23 | 24 | public v1_9(String name, Location loc) { 25 | super(name, loc); 26 | 27 | bar = Bukkit.createBossBar(name, BarColor.PINK, BarStyle.SOLID); 28 | } 29 | 30 | public BossBar getBar() { 31 | return bar; 32 | } 33 | 34 | @Override 35 | public Object getSpawnPacket() { 36 | return null; 37 | } 38 | 39 | @Override 40 | public Object getDestroyPacket() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public Object getMetaPacket(Object watcher) { 46 | return null; 47 | } 48 | 49 | @Override 50 | public Object getTeleportPacket(Location loc) { 51 | return null; 52 | } 53 | 54 | @Override 55 | public Object getWatcher() { 56 | return null; 57 | } 58 | } 59 | --------------------------------------------------------------------------------