package org.bukkit.craftbukkit.boss; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; import net.minecraft.server.BossBattle; import net.minecraft.server.BossBattleServer; import net.minecraft.server.EntityPlayer; import net.minecraft.server.PacketPlayOutBoss; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarFlag; import org.bukkit.boss.BarStyle; import org.bukkit.boss.BossBar; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.Player; public class CraftBossBar implements BossBar { private final BossBattleServer handle; private Map flags; public CraftBossBar(String title, BarColor color, BarStyle style, BarFlag... flags) { handle = new BossBattleServer( CraftChatMessage.fromString(title, true)[0], convertColor(color), convertStyle(style) ); this.initialize(); for (BarFlag flag : flags) { this.addFlag(flag); } this.setColor(color); this.setStyle(style); } public CraftBossBar(BossBattleServer bossBattleServer) { this.handle = bossBattleServer; this.initialize(); } private void initialize() { this.flags = new HashMap<>(); this.flags.put(BarFlag.DARKEN_SKY, new FlagContainer(handle::isDarkenSky, handle::setDarkenSky)); this.flags.put(BarFlag.PLAY_BOSS_MUSIC, new FlagContainer(handle::isPlayMusic, handle::setPlayMusic)); this.flags.put(BarFlag.CREATE_FOG, new FlagContainer(handle::isCreateFog, handle::setCreateFog)); } private BarColor convertColor(BossBattle.BarColor color) { BarColor bukkitColor = BarColor.valueOf(color.name()); return (bukkitColor == null) ? BarColor.WHITE : bukkitColor; } private BossBattle.BarColor convertColor(BarColor color) { BossBattle.BarColor nmsColor = BossBattle.BarColor.valueOf(color.name()); return (nmsColor == null) ? BossBattle.BarColor.WHITE : nmsColor; } private BossBattle.BarStyle convertStyle(BarStyle style) { switch (style) { default: case SOLID: return BossBattle.BarStyle.PROGRESS; case SEGMENTED_6: return BossBattle.BarStyle.NOTCHED_6; case SEGMENTED_10: return BossBattle.BarStyle.NOTCHED_10; case SEGMENTED_12: return BossBattle.BarStyle.NOTCHED_12; case SEGMENTED_20: return BossBattle.BarStyle.NOTCHED_20; } } private BarStyle convertStyle(BossBattle.BarStyle style) { switch (style) { default: case PROGRESS: return BarStyle.SOLID; case NOTCHED_6: return BarStyle.SEGMENTED_6; case NOTCHED_10: return BarStyle.SEGMENTED_10; case NOTCHED_12: return BarStyle.SEGMENTED_12; case NOTCHED_20: return BarStyle.SEGMENTED_20; } } @Override public String getTitle() { return CraftChatMessage.fromComponent(handle.title); } @Override public void setTitle(String title) { handle.title = CraftChatMessage.fromString(title, true)[0]; handle.sendUpdate(PacketPlayOutBoss.Action.UPDATE_NAME); } @Override public BarColor getColor() { return convertColor(handle.color); } @Override public void setColor(BarColor color) { handle.color = convertColor(color); handle.sendUpdate(PacketPlayOutBoss.Action.UPDATE_STYLE); } @Override public BarStyle getStyle() { return convertStyle(handle.style); } @Override public void setStyle(BarStyle style) { handle.style = convertStyle(style); handle.sendUpdate(PacketPlayOutBoss.Action.UPDATE_STYLE); } @Override public void addFlag(BarFlag flag) { FlagContainer flagContainer = flags.get(flag); if (flagContainer != null) { flagContainer.set.accept(true); } } @Override public void removeFlag(BarFlag flag) { FlagContainer flagContainer = flags.get(flag); if (flagContainer != null) { flagContainer.set.accept(false); } } @Override public boolean hasFlag(BarFlag flag) { FlagContainer flagContainer = flags.get(flag); if (flagContainer != null) { return flagContainer.get.get(); } return false; } @Override public void setProgress(double progress) { Preconditions.checkArgument(progress >= 0.0 && progress <= 1.0, "Progress must be between 0.0 and 1.0 (%s)", progress); handle.setProgress((float) progress); } @Override public double getProgress() { return handle.getProgress(); } @Override public void addPlayer(Player player) { Preconditions.checkArgument(player != null, "player == null"); Preconditions.checkArgument(((CraftPlayer) player).getHandle().playerConnection != null, "player is not fully connected (wait for PlayerJoinEvent)"); handle.addPlayer(((CraftPlayer) player).getHandle()); } @Override public void removePlayer(Player player) { Preconditions.checkArgument(player != null, "player == null"); handle.removePlayer(((CraftPlayer) player).getHandle()); } @Override public List getPlayers() { ImmutableList.Builder players = ImmutableList.builder(); for (EntityPlayer p : handle.getPlayers()) { players.add(p.getBukkitEntity()); } return players.build(); } @Override public void setVisible(boolean visible) { handle.setVisible(visible); } @Override public boolean isVisible() { return handle.visible; } @Override public void show() { handle.setVisible(true); } @Override public void hide() { handle.setVisible(false); } @Override public void removeAll() { for (Player player : getPlayers()) { removePlayer(player); } } private final class FlagContainer { private Supplier get; private Consumer set; private FlagContainer(Supplier get, Consumer set) { this.get = get; this.set = set; } } public BossBattleServer getHandle() { return handle; } }