From 0f976d2316e312e4c4e8d402ce896728e31ec73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Sun, 10 Nov 2024 17:28:02 +0100 Subject: [PATCH] added infobars --- .../spawn/appliances/infoBars/Bar.java | 67 ++++++++++++++ .../appliances/infoBars/InfoBarCommand.java | 32 +++++++ .../spawn/appliances/infoBars/InfoBars.java | 91 +++++++++++++++++++ .../infoBars/ShowPreviousBarsListener.java | 12 +++ .../appliances/infoBars/bars/MsptBar.java | 50 ++++++++++ .../infoBars/bars/PlayerCounterBar.java | 44 +++++++++ .../appliances/infoBars/bars/TpsBar.java | 48 ++++++++++ src/main/resources/plugin.yml | 1 + 8 files changed, 345 insertions(+) create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/Bar.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBarCommand.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBars.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/ShowPreviousBarsListener.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/MsptBar.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/PlayerCounterBar.java create mode 100644 src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/TpsBar.java diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/Bar.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/Bar.java new file mode 100644 index 0000000..503a674 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/Bar.java @@ -0,0 +1,67 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars; + +import eu.mhsl.craftattack.spawn.Main; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.util.Ticks; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +public abstract class Bar { + private BossBar bossBar; + private final BukkitTask updateTask; + + public Bar() { + long refreshRateInTicks = this.refresh().get(ChronoUnit.SECONDS) * Ticks.TICKS_PER_SECOND; + this.updateTask = Bukkit.getScheduler().runTaskTimerAsynchronously( + Main.instance(), + this::update, + refreshRateInTicks, + refreshRateInTicks + ); + } + + public BossBar getBossBar() { + if(this.bossBar == null) this.bossBar = this.createBar(); + return this.bossBar; + } + + private BossBar createBar() { + return BossBar.bossBar( + this.title(), + this.correctedProgress(), + this.color(), + this.overlay() + ); + } + + private void update() { + if(this.bossBar == null) return; + + this.beforeRefresh(); + this.bossBar.name(this.title()); + this.bossBar.progress(this.correctedProgress()); + this.bossBar.color(this.color()); + this.bossBar.overlay(this.overlay()); + } + + public void stopUpdate() { + this.updateTask.cancel(); + } + + private float correctedProgress() { + return Math.clamp(this.progress(), 0, 1); + } + + protected void beforeRefresh() {} + protected abstract Duration refresh(); + protected abstract String name(); + + protected abstract Component title(); + protected abstract float progress(); + protected abstract BossBar.Color color(); + protected abstract BossBar.Overlay overlay(); +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBarCommand.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBarCommand.java new file mode 100644 index 0000000..d3aa097 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBarCommand.java @@ -0,0 +1,32 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class InfoBarCommand extends ApplianceCommand.PlayerChecked { + public InfoBarCommand() { + super("infobar"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + if(args.length == 0) throw new Error(" [bar name]"); + switch(args[0]) { + case "hideAll" -> getAppliance().hideAll(getPlayer()); + case "show" -> getAppliance().show(getPlayer(), args[1]); + case "hide" -> getAppliance().hide(getPlayer(), args[1]); + default -> throw new Error("Erlaubte Optionen sind 'show', 'hide', 'hideAll'!"); + } + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if(args.length == 1) return List.of("show", "hide", "hideAll"); + return getAppliance().getInfoBars().stream().map(Bar::name).toList(); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBars.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBars.java new file mode 100644 index 0000000..5e08c60 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/InfoBars.java @@ -0,0 +1,91 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars; + +import eu.mhsl.craftattack.spawn.Main; +import eu.mhsl.craftattack.spawn.appliance.Appliance; +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.infoBars.bars.MsptBar; +import eu.mhsl.craftattack.spawn.appliances.infoBars.bars.PlayerCounterBar; +import eu.mhsl.craftattack.spawn.appliances.infoBars.bars.TpsBar; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class InfoBars extends Appliance { + private final NamespacedKey infoBarKey = new NamespacedKey(Main.instance(), "infobars"); + private final List infoBars = List.of( + new TpsBar(), + new MsptBar(), + new PlayerCounterBar() + ); + + public void showAll(Player player) { + this.getStoredBars(player).forEach(bar -> this.show(player, bar)); + } + + public void hideAll(Player player) { + this.getStoredBars(player).forEach(bar -> this.hide(player, bar)); + this.setStoredBars(player, List.of()); + } + + public void show(Player player, String bar) { + this.validateBarName(bar); + List existingBars = new ArrayList<>(this.getStoredBars(player)); + existingBars.add(bar); + player.showBossBar(this.getBarByName(bar).getBossBar()); + this.setStoredBars(player, existingBars); + } + + public void hide(Player player, String bar) { + this.validateBarName(bar); + List existingBars = new ArrayList<>(this.getStoredBars(player)); + existingBars.remove(bar); + player.hideBossBar(this.getBarByName(bar).getBossBar()); + this.setStoredBars(player, existingBars); + } + + private List getStoredBars(Player player) { + PersistentDataContainer container = player.getPersistentDataContainer(); + if(!container.has(infoBarKey)) return List.of(); + return container.get(infoBarKey, PersistentDataType.LIST.strings()); + } + + private void setStoredBars(Player player, List bars) { + player.getPersistentDataContainer().set(infoBarKey, PersistentDataType.LIST.strings(), bars); + } + + private Bar getBarByName(String name) { + return infoBars.stream() + .filter(bar -> bar.name().equalsIgnoreCase(name)) + .findFirst() + .orElse(null); + } + + private void validateBarName(String name) { + if(getBarByName(name) == null) throw new ApplianceCommand.Error(String.format("Ungültiger infobar name '%s'", name)); + } + + public List getInfoBars() { + return infoBars; + } + + @Override + public void onDisable() { + infoBars.forEach(Bar::stopUpdate); + } + + @Override + protected @NotNull List listeners() { + return List.of(new ShowPreviousBarsListener()); + } + + @Override + protected @NotNull List> commands() { + return List.of(new InfoBarCommand()); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/ShowPreviousBarsListener.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/ShowPreviousBarsListener.java new file mode 100644 index 0000000..fa5006a --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/ShowPreviousBarsListener.java @@ -0,0 +1,12 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +public class ShowPreviousBarsListener extends ApplianceListener { + @EventHandler + public void onJoin(PlayerJoinEvent event) { + getAppliance().showAll(event.getPlayer()); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/MsptBar.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/MsptBar.java new file mode 100644 index 0000000..abdc4e0 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/MsptBar.java @@ -0,0 +1,50 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars.bars; + +import eu.mhsl.craftattack.spawn.appliances.infoBars.Bar; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; + +import java.time.Duration; + +public class MsptBar extends Bar { + @Override + protected Duration refresh() { + return Duration.ofSeconds(1); + } + + @Override + protected String name() { + return "mspt"; + } + + @Override + protected Component title() { + return Component.text() + .append(Component.text("M")) + .append(Component.text("illi", NamedTextColor.GRAY)) + .append(Component.text("S")) + .append(Component.text("econds ", NamedTextColor.GRAY)) + .append(Component.text("P")) + .append(Component.text("er ", NamedTextColor.GRAY)) + .append(Component.text("T")) + .append(Component.text("ick", NamedTextColor.GRAY)) + .build(); + } + + @Override + protected float progress() { + return Bukkit.getServer().getTickTimes()[0] / 50f; + } + + @Override + protected BossBar.Color color() { + return BossBar.Color.YELLOW; + } + + @Override + protected BossBar.Overlay overlay() { + return BossBar.Overlay.NOTCHED_10; + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/PlayerCounterBar.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/PlayerCounterBar.java new file mode 100644 index 0000000..eabc4bb --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/PlayerCounterBar.java @@ -0,0 +1,44 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars.bars; + +import eu.mhsl.craftattack.spawn.Main; +import eu.mhsl.craftattack.spawn.appliances.infoBars.Bar; +import eu.mhsl.craftattack.spawn.appliances.playerlimit.PlayerLimit; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; + +import java.time.Duration; + +public class PlayerCounterBar extends Bar { + @Override + protected Duration refresh() { + return Duration.ofSeconds(3); + } + + @Override + protected String name() { + return "playerCounter"; + } + + @Override + protected Component title() { + return Component.text("Spieler online"); + } + + @Override + protected float progress() { + int maxPlayers = Main.instance().getAppliance(PlayerLimit.class).getLimit(); + int currentPlayers = Bukkit.getOnlinePlayers().size(); + return (float) currentPlayers / maxPlayers; + } + + @Override + protected BossBar.Color color() { + return BossBar.Color.BLUE; + } + + @Override + protected BossBar.Overlay overlay() { + return BossBar.Overlay.NOTCHED_10; + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/TpsBar.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/TpsBar.java new file mode 100644 index 0000000..0e48657 --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/infoBars/bars/TpsBar.java @@ -0,0 +1,48 @@ +package eu.mhsl.craftattack.spawn.appliances.infoBars.bars; + +import eu.mhsl.craftattack.spawn.appliances.infoBars.Bar; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; + +import java.time.Duration; + +public class TpsBar extends Bar { + @Override + protected Duration refresh() { + return Duration.ofSeconds(3); + } + + @Override + protected String name() { + return "tps"; + } + + @Override + protected Component title() { + return Component.text() + .append(Component.text("T")) + .append(Component.text("icks ", NamedTextColor.GRAY)) + .append(Component.text("P")) + .append(Component.text("er ", NamedTextColor.GRAY)) + .append(Component.text("S")) + .append(Component.text("econds", NamedTextColor.GRAY)) + .build(); + } + + @Override + protected float progress() { + return (float) (Bukkit.getTPS()[0] / 20); + } + + @Override + protected BossBar.Color color() { + return BossBar.Color.YELLOW; + } + + @Override + protected BossBar.Overlay overlay() { + return BossBar.Overlay.NOTCHED_20; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f7108d5..dd31f27 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -46,3 +46,4 @@ commands: adminchat: aliases: [ "sc" ] acInform: + infobar: