Merge pull request #158 from StamBoom/bossbar

Implement 1.9 BossBarAPI for developers
This commit is contained in:
Myles 2016-03-06 18:35:55 +00:00
commit d8ce66ce29
7 changed files with 484 additions and 3 deletions

View File

@ -15,7 +15,11 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.ViaVersionAPI;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.armor.ArmorListener;
import us.myles.ViaVersion.boss.ViaBossBar;
import us.myles.ViaVersion.commands.ViaVersionCommand;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.listeners.CommandBlockListener;
@ -110,7 +114,12 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
@Override
public boolean isPorted(Player player) {
return portedPlayers.containsKey(player.getUniqueId());
return isPorted(player.getUniqueId());
}
@Override
public boolean isPorted(UUID playerUUID) {
return portedPlayers.containsKey(playerUUID);
}
@Override
@ -119,11 +128,26 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
}
public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException {
if (!isPorted(player)) throw new IllegalArgumentException("This player is not on 1.9");
ConnectionInfo ci = portedPlayers.get(player.getUniqueId());
sendRawPacket(player.getUniqueId(), packet);
}
@Override
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not on 1.9");
ConnectionInfo ci = portedPlayers.get(uuid);
ci.sendRawPacket(packet);
}
@Override
public BossBar createBossBar(String title, BossColor color, BossStyle style) {
return new ViaBossBar(title, 1F, color, style);
}
@Override
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
return new ViaBossBar(title, health, color, style);
}
@Override
public boolean isDebug() {
return this.debug;

View File

@ -0,0 +1,122 @@
package us.myles.ViaVersion.api.boss;
import org.bukkit.entity.Player;
import java.util.Set;
import java.util.UUID;
public interface BossBar {
/**
* Change the title
*
* @param title Title can be in either JSON or just text
*/
void setTitle(String title);
/**
* Get the current title
*
* @return the title
*/
String getTitle();
/**
* Change the health
*
* @param health this float has to be between 0F - 1F
*/
void setHealth(float health);
/**
* Get the health
*
* @return float between 0F - 1F
*/
float getHealth();
/**
* Yay colors!
*
* @param color Whatever color you want!
*/
void setColor(BossColor color);
/**
* Get the bossbar color
*
* @return
*/
BossColor getColor();
/**
* Change the bosbar style
*
* @param style BossStyle
*/
void setStyle(BossStyle style);
/**
* Get the bosbar style
*
* @return BossStyle
*/
BossStyle getStyle();
/**
* Show the bossbar to a player.
*
* @param player
*/
void addPlayer(Player player);
/**
* Remove the bossbar from a player
*
* @param player
*/
void removePlayer(Player player);
/**
* Add flags
*
* @param flag
*/
void addFlag(BossFlag flag);
/**
* Remove flags.
*
* @param flag
*/
void removeFlag(BossFlag flag);
/**
* @param flag
* @return
*/
boolean hasFlag(BossFlag flag);
/**
* Get players
*
* @return UUIDS from players (sorry I lied)
*/
Set<UUID> getPlayers();
/**
* Show the bossbar to everyone (In the getPlayer set)
*/
void show();
/**
* Hide the bossbar from everyone (In the getPlayer set)
*/
void hide();
/**
* Is it visible?
*
* @return visibility changable with show() and hide()
*/
boolean isVisible();
}

View File

@ -0,0 +1,21 @@
package us.myles.ViaVersion.api.boss;
public enum BossColor {
PINK(0),
BLUE(1),
RED(2),
GREEN(3),
YELLOW(4),
PURPLE(5),
WHITE(6);
private final int id;
BossColor(int id) {
this.id = id;
}
public int getId() {
return id;
}
}

View File

@ -0,0 +1,16 @@
package us.myles.ViaVersion.api.boss;
public enum BossFlag {
DARKEN_SKY(1),
PLAY_BOSS_MUSIC(2);
private final int id;
BossFlag(int id) {
this.id = id;
}
public int getId() {
return id;
}
}

View File

@ -0,0 +1,19 @@
package us.myles.ViaVersion.api.boss;
public enum BossStyle {
SOLID(0),
SEGMENTED_6(1),
SEGMENTED_10(2),
SEGMENTED_12(3),
SEGMENTED_20(4);
private final int id;
BossStyle(int id) {
this.id = id;
}
public int getId() {
return id;
}
}

View File

@ -2,37 +2,85 @@ package us.myles.ViaVersion.api;
import io.netty.buffer.ByteBuf;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import java.util.UUID;
public interface ViaVersionAPI {
/**
* Is player using 1.9?
*
* @param player
* @return True if the client is on 1.9
*/
boolean isPorted(Player player);
/**
* Is player using 1.9?
*
* @param playerUUID
* @return True if the client is on 1.9
*/
boolean isPorted(UUID playerUUID);
/**
* Get the version of the plugin
*
* @return Plugin version
*/
String getVersion();
/**
* Send a raw packet to the player (Use new IDs)
*
* @param player The player to send packet
* @param packet The packet, you need a VarInt ID then the packet contents.
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
*/
void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException;
/**
* Send a raw packet to the player (Use new IDs)
*
* @param uuid The uuid from the player to send packet
* @param packet The packet, you need a VarInt ID then the packet contents.
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
*/
void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
/**
* Create a new bossbar instance
*
* @param title The title
* @param color The color
* @param style The style
* @return Bossbar instance
*/
BossBar createBossBar(String title, BossColor color, BossStyle style);
/**
* Create a new bossbar instance
*
* @param title The title
* @param health Number between 0 and 1
* @param color The color
* @param style The style
* @return Bossbar instance
*/
BossBar createBossBar(String title, float health, BossColor color, BossStyle style);
/**
* Obtain if global debug is enabled
*
* @return true if debug is enabled
*/
boolean isDebug();
/**
* Obtains if syncing chunks is on
*
* @return true if it is
*/
boolean isSyncedChunks();

View File

@ -0,0 +1,231 @@
package us.myles.ViaVersion.boss;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossFlag;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class ViaBossBar implements BossBar {
private UUID uuid;
private String title;
private float health;
private BossColor color;
private BossStyle style;
private Set<UUID> players;
private boolean visible;
private Set<BossFlag> flags;
public ViaBossBar(String title, float health, BossColor color, BossStyle style) {
Validate.notNull(title, "Title cannot be null");
Validate.isTrue((health >= 0 && health <= 1), "Health must be between 0 and 1");
this.uuid = UUID.randomUUID();
this.title = title;
this.health = health;
this.color = color == null ? BossColor.PURPLE : color;
this.style = style == null ? BossStyle.SOLID : style;
this.players = new HashSet<>();
this.flags = new HashSet<>();
visible = true;
}
@Override
public void setTitle(String title) {
Validate.notNull(title, "Title cannot be null");
this.title = title;
sendPacket(UpdateAction.UPDATE_TITLE);
}
@Override
public String getTitle() {
return title;
}
@Override
public void setHealth(float health) {
Validate.isTrue((health >= 0 && health <= 1), "Health must be between 0 and 1");
this.health = health;
sendPacket(UpdateAction.UPDATE_HEALTH);
}
@Override
public float getHealth() {
return health;
}
@Override
public void setColor(BossColor color) {
Validate.notNull(color, "Color cannot be null");
this.color = color;
sendPacket(UpdateAction.UPDATE_STYLE);
}
@Override
public BossColor getColor() {
return color;
}
@Override
public void setStyle(BossStyle style) {
Validate.notNull(style, "Style cannot be null");
this.style = style;
sendPacket(UpdateAction.UPDATE_STYLE);
}
@Override
public BossStyle getStyle() {
return style;
}
@Override
public void addPlayer(Player player) {
if (player != null && !players.contains(player.getUniqueId())) {
players.add(player.getUniqueId());
if (visible)
sendPacket(player.getUniqueId(), getPacket(UpdateAction.ADD));
}
}
@Override
public void removePlayer(Player player) {
if (player != null && players.contains(player.getUniqueId())) {
players.remove(player.getUniqueId());
sendPacket(player.getUniqueId(), getPacket(UpdateAction.REMOVE));
}
}
@Override
public void addFlag(BossFlag flag) {
if (!hasFlag(flag))
flags.add(flag);
sendPacket(UpdateAction.UPDATE_FLAGS);
}
@Override
public void removeFlag(BossFlag flag) {
if (hasFlag(flag))
flags.remove(flag);
sendPacket(UpdateAction.UPDATE_FLAGS);
}
@Override
public boolean hasFlag(BossFlag flag) {
return flags.contains(flag);
}
@Override
public Set<UUID> getPlayers() {
return Collections.unmodifiableSet(players);
}
@Override
public void show() {
setVisible(true);
}
@Override
public void hide() {
setVisible(false);
}
@Override
public boolean isVisible() {
return visible;
}
private void setVisible(boolean value) {
if (visible != value) {
visible = value;
sendPacket(value ? UpdateAction.ADD : UpdateAction.REMOVE);
}
}
private void sendPacket(UpdateAction action) {
ByteBuf buf = getPacket(action);
for (UUID uuid : players)
sendPacket(uuid, buf);
}
private void sendPacket(UUID uuid, ByteBuf buf) {
if (!ViaVersion.getInstance().isPorted(uuid)) {
players.remove(uuid);
return;
}
ViaVersion.getInstance().sendRawPacket(uuid, buf);
}
private ByteBuf getPacket(UpdateAction action) {
ByteBuf buf = Unpooled.buffer();
PacketUtil.writeVarInt(PacketType.PLAY_BOSS_BAR.getNewPacketID(), buf);
PacketUtil.writeUUID(uuid, buf);
PacketUtil.writeVarInt(action.getId(), buf);
switch (action) {
case ADD:
PacketUtil.writeString(fixJson(title), buf);
buf.writeFloat(health);
PacketUtil.writeVarInt(color.getId(), buf);
PacketUtil.writeVarInt(style.getId(), buf);
buf.writeByte(flagToBytes());
break;
case REMOVE:
break;
case UPDATE_HEALTH:
buf.writeFloat(health);
break;
case UPDATE_TITLE:
PacketUtil.writeString(fixJson(title), buf);
break;
case UPDATE_STYLE:
PacketUtil.writeVarInt(color.getId(), buf);
PacketUtil.writeVarInt(style.getId(), buf);
break;
case UPDATE_FLAGS:
buf.writeByte(flagToBytes());
break;
}
return buf;
}
private int flagToBytes() {
int bitmask = 0;
for (BossFlag flag : flags)
bitmask |= flag.getId();
return bitmask;
}
private String fixJson(String text) {
return OutgoingTransformer.fixJson(text);
}
private enum UpdateAction {
ADD(0),
REMOVE(1),
UPDATE_HEALTH(2),
UPDATE_TITLE(3),
UPDATE_STYLE(4),
UPDATE_FLAGS(5);
private final int id;
UpdateAction(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
}