Skip to content

Commit

Permalink
Added bossbar for messages (#1088)
Browse files Browse the repository at this point in the history
* Added bossbar implementations

* Added bossbar component to the messages file

* Added limit to the amount of active bossbars at a time for players

* Added bossbar service to the API

* Moved bossbar utility classes under the bossbar service package

* Merge branch 'dev' into feature/player-roles-display-name

# Conflicts:
#	src/main/java/com/bgsoftware/superiorskyblock/service/placeholders/PlaceholdersServiceImpl.java
  • Loading branch information
OmerBenGera committed Apr 30, 2022
1 parent 0a424be commit afdc7b7
Show file tree
Hide file tree
Showing 20 changed files with 521 additions and 1 deletion.
Expand Up @@ -569,6 +569,11 @@ public interface SettingsManager {
*/
TopIslandMembersSorting getTopIslandMembersSorting();

/**
* Limit of the amount of bossbar tasks each player can have at the same time.
*/
int getBossbarLimit();

interface Database {

/**
Expand Down
@@ -0,0 +1,43 @@
package com.bgsoftware.superiorskyblock.api.service.bossbar;

import org.bukkit.entity.Player;

public interface BossBar {

/**
* Display this boss-bar to a player.
*
* @param player The player to display the boss-bar to.
*/
void addPlayer(Player player);

/**
* Stop displaying this boss-bar to all the players.
*/
void removeAll();

/**
* Set the progress bar of this boss-bar.
*
* @param progress The progress to set.
*/
void setProgress(double progress);

/**
* Get the progress bar of this boss-bar.
*/
double getProgress();

enum Color {

PINK,
BLUE,
RED,
GREEN,
YELLOW,
PURPLE,
WHITE

}

}
@@ -0,0 +1,18 @@
package com.bgsoftware.superiorskyblock.api.service.bossbar;

import org.bukkit.entity.Player;

public interface BossBarsService {

/**
* Create a new boss-bar.
*
* @param player The player to create the boss-bar for.
* @param message The message to display in the boss-bar.
* @param color The color of the boss-bar.
* @param ticksToRun The time to run the boss-bar.
* If set to 0 or below, it will stay forever.
*/
BossBar createBossBar(Player player, String message, BossBar.Color color, double ticksToRun);

}
Expand Up @@ -56,6 +56,7 @@
import com.bgsoftware.superiorskyblock.schematic.container.DefaultSchematicsContainer;
import com.bgsoftware.superiorskyblock.service.ServicesHandler;
import com.bgsoftware.superiorskyblock.service.dragon.DragonBattleServiceImpl;
import com.bgsoftware.superiorskyblock.service.bossbar.BossBarsServiceImpl;
import com.bgsoftware.superiorskyblock.service.hologram.HologramsServiceImpl;
import com.bgsoftware.superiorskyblock.service.placeholders.PlaceholdersServiceImpl;
import com.bgsoftware.superiorskyblock.tasks.CalcTask;
Expand Down Expand Up @@ -206,6 +207,7 @@ public void onLoad() {
this.servicesHandler.registerPlaceholdersService(new PlaceholdersServiceImpl());
this.servicesHandler.registerHologramsService(new HologramsServiceImpl(this));
this.servicesHandler.registerEnderDragonService(new DragonBattleServiceImpl(this));
this.servicesHandler.registerBossBarsService(new BossBarsServiceImpl(this));
}

@Override
Expand Down
Expand Up @@ -201,6 +201,7 @@ public final class SettingsContainer {
public final boolean autoLanguageDetection;
public final boolean autoUncoopWhenAlone;
public final TopIslandMembersSorting islandTopMembersSorting;
public final int bossBarLimit;

public SettingsContainer(SuperiorSkyblockPlugin plugin, YamlConfiguration config) throws HandlerLoadException {
databaseType = config.getString("database.type").toUpperCase(Locale.ENGLISH);
Expand Down Expand Up @@ -512,6 +513,7 @@ else if (sections.length == 3)
islandTopMembersSorting = TopIslandMembersSorting.NAMES;
}
this.islandTopMembersSorting = islandTopMembersSorting;
bossBarLimit = config.getInt("bossbar-limit", 1);
}

private List<String> loadInteractables(SuperiorSkyblockPlugin plugin) {
Expand Down
Expand Up @@ -535,6 +535,11 @@ public TopIslandMembersSorting getTopIslandMembersSorting() {
return this.container.islandTopMembersSorting;
}

@Override
public int getBossbarLimit() {
return this.container.bossBarLimit;
}

public void updateValue(String path, Object value) throws IOException {
SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin();
File file = new File(plugin.getDataFolder(), "config.yml");
Expand Down
@@ -1,10 +1,13 @@
package com.bgsoftware.superiorskyblock.lang.component;

import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBar;
import com.bgsoftware.superiorskyblock.formatting.Formatters;
import com.bgsoftware.superiorskyblock.lang.component.impl.ActionBarComponent;
import com.bgsoftware.superiorskyblock.lang.component.impl.BossBarComponent;
import com.bgsoftware.superiorskyblock.lang.component.impl.ComplexMessageComponent;
import com.bgsoftware.superiorskyblock.lang.component.impl.SoundComponent;
import com.bgsoftware.superiorskyblock.lang.component.impl.TitleComponent;
import com.bgsoftware.superiorskyblock.serialization.Serializers;
import com.bgsoftware.superiorskyblock.utils.FileUtils;
import com.bgsoftware.superiorskyblock.utils.StringUtils;
import net.md_5.bungee.api.chat.BaseComponent;
Expand Down Expand Up @@ -37,6 +40,18 @@ public static IMessageComponent parseSection(ConfigurationSection section) {
));
} else if (key.equals("sound")) {
messageComponents.add(SoundComponent.of(FileUtils.getSound(section.getConfigurationSection("sound"))));
} else if (key.equals("bossbar")) {
BossBar.Color color;

try {
color = BossBar.Color.valueOf(section.getString(key + ".color").toUpperCase());
} catch (Exception error) {
color = BossBar.Color.PINK;
}

messageComponents.add(BossBarComponent.of(
Formatters.COLOR_FORMATTER.format(section.getString(key + ".message")),
color, section.getInt(key + ".ticks")));
} else {
TextComponent textComponent = new TextComponent(Formatters.COLOR_FORMATTER.format(section.getString(key + ".text")));

Expand Down
@@ -0,0 +1,46 @@

package com.bgsoftware.superiorskyblock.lang.component.impl;

import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin;
import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBar;
import com.bgsoftware.superiorskyblock.lang.component.EmptyMessageComponent;
import com.bgsoftware.superiorskyblock.lang.component.IMessageComponent;
import org.apache.logging.log4j.util.Strings;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import javax.annotation.Nullable;

public final class BossBarComponent implements IMessageComponent {

private static final SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin();

private final String message;
private final BossBar.Color color;
private final int ticksToRun;

public static IMessageComponent of(@Nullable String message, BossBar.Color color, int ticks) {
return ticks <= 0 || Strings.isBlank(message) ? EmptyMessageComponent.getInstance() : new BossBarComponent(message, color, ticks);
}

private BossBarComponent(String message, BossBar.Color color, int ticks) {
this.message = message;
this.color = color;
this.ticksToRun = ticks;
}

@Override
public String getMessage() {
return this.message;
}

@Override
public void sendMessage(CommandSender sender, Object... objects) {
if (sender instanceof Player) {
IMessageComponent.replaceArgs(this.message, objects).ifPresent(message -> {
plugin.getServices().getBossBarsService().createBossBar((Player) sender, message, this.color, this.ticksToRun);
});
}
}

}
@@ -1,6 +1,7 @@
package com.bgsoftware.superiorskyblock.nms;

import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer;
import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBar;
import com.mojang.authlib.properties.Property;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Item;
Expand All @@ -19,6 +20,8 @@ public interface NMSPlayers {

void sendActionBar(Player player, String message);

BossBar createBossBar(Player player, String message, BossBar.Color color, double ticksToRun);

void sendTitle(Player player, String title, String subtitle, int fadeIn, int duration, int fadeOut);

boolean wasThrownByPlayer(Item item, Player player);
Expand Down
Expand Up @@ -2,6 +2,7 @@

import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin;
import com.bgsoftware.superiorskyblock.api.service.dragon.DragonBattleService;
import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBarsService;
import com.bgsoftware.superiorskyblock.api.service.hologram.HologramsService;
import com.bgsoftware.superiorskyblock.api.service.placeholders.PlaceholdersService;
import org.bukkit.Bukkit;
Expand All @@ -14,6 +15,7 @@ public final class ServicesHandler {
private PlaceholdersService placeholdersService;
private HologramsService hologramsService;
private DragonBattleService dragonBattleService;
private BossBarsService bossBarsService;

public ServicesHandler(SuperiorSkyblockPlugin plugin) {
this.plugin = plugin;
Expand All @@ -34,6 +36,11 @@ public void registerEnderDragonService(DragonBattleService dragonBattleService)
Bukkit.getServicesManager().register(DragonBattleService.class, dragonBattleService, plugin, ServicePriority.Normal);
}

public void registerBossBarsService(BossBarsService bossBarsService) {
this.bossBarsService = bossBarsService;
Bukkit.getServicesManager().register(BossBarsService.class, bossBarsService, plugin, ServicePriority.Normal);
}

public PlaceholdersService getPlaceholdersService() {
return placeholdersService;
}
Expand All @@ -46,4 +53,8 @@ public DragonBattleService getDragonBattleService() {
return dragonBattleService;
}

public BossBarsService getBossBarsService() {
return bossBarsService;
}

}
@@ -0,0 +1,75 @@
package com.bgsoftware.superiorskyblock.service.bossbar;

import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin;
import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBar;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.UUID;

public final class BossBarTask extends BukkitRunnable {

private static final SuperiorSkyblockPlugin plugin = SuperiorSkyblockPlugin.getPlugin();

private static final BossBarTask EMPTY_TASK = new BossBarTask(EmptyBossBar.getInstance(), 0);

private static final Map<UUID, Queue<BossBarTask>> PLAYERS_RUNNING_TASKS = new HashMap<>();

private final BossBar bossBar;
private final double progressToRemovePerTick;
private boolean reachedEndTask = false;

public static BossBarTask create(BossBar bossBar, double ticksToRun) {
return ticksToRun <= 0 ? EMPTY_TASK : new BossBarTask(bossBar, ticksToRun);
}

private BossBarTask(BossBar bossBar, double ticksToRun) {
this.bossBar = bossBar;
this.progressToRemovePerTick = this.bossBar.getProgress() / ticksToRun;
if (progressToRemovePerTick > 0) {
runTaskTimer(plugin, 1L, 1L);
}
}

@Override
public void run() {
if (reachedEndTask) {
cancel();
} else {
this.bossBar.setProgress(Math.max(0D, this.bossBar.getProgress() - progressToRemovePerTick));
reachedEndTask = this.bossBar.getProgress() == 0D;
}
}

@Override
public synchronized void cancel() throws IllegalStateException {
this.bossBar.removeAll();
super.cancel();
}

public void registerTask(Player player) {
Queue<BossBarTask> bossBarTasks = PLAYERS_RUNNING_TASKS.computeIfAbsent(player.getUniqueId(), s -> new LinkedList<>());

if (bossBarTasks.size() >= plugin.getSettings().getBossbarLimit()) {
BossBarTask lastRunningTask = bossBarTasks.poll();
if (lastRunningTask != null)
lastRunningTask.cancel();
}

bossBarTasks.add(this);
}

public void unregisterTask(Player player) {
Queue<BossBarTask> bossBarTasks = PLAYERS_RUNNING_TASKS.get(player.getUniqueId());

if (bossBarTasks == null)
return;

bossBarTasks.remove(this);
}

}
@@ -0,0 +1,21 @@
package com.bgsoftware.superiorskyblock.service.bossbar;

import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin;
import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBar;
import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBarsService;
import org.bukkit.entity.Player;

public final class BossBarsServiceImpl implements BossBarsService {

private final SuperiorSkyblockPlugin plugin;

public BossBarsServiceImpl(SuperiorSkyblockPlugin plugin) {
this.plugin = plugin;
}

@Override
public BossBar createBossBar(Player player, String message, BossBar.Color color, double ticksToRun) {
return plugin.getNMSPlayers().createBossBar(player, message, color, ticksToRun);
}

}
@@ -0,0 +1,38 @@
package com.bgsoftware.superiorskyblock.service.bossbar;

import com.bgsoftware.superiorskyblock.api.service.bossbar.BossBar;
import org.bukkit.entity.Player;

public final class EmptyBossBar implements BossBar {

private static final EmptyBossBar INSTANCE = new EmptyBossBar();

public static EmptyBossBar getInstance() {
return INSTANCE;
}

private EmptyBossBar() {

}

@Override
public void addPlayer(Player player) {

}

@Override
public void removeAll() {

}

@Override
public void setProgress(double progress) {

}

@Override
public double getProgress() {
return 0;
}

}

0 comments on commit afdc7b7

Please sign in to comment.