From b75d7c278aee73c532a45eb6cb5012b8312f2c95 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Wed, 15 Mar 2023 18:09:13 +0100 Subject: [PATCH] Finalize Killchecker and include BauSystem Bossbar API for better Bossbar usage Signed-off-by: yoyosource --- BauSystem_Main/src/BauSystem.properties | 1 + BauSystem_Main/src/BauSystem_de.properties | 1 + .../killchecker/KillcheckerCommand.java | 7 +- .../killchecker/KillcheckerVisualizer.java | 43 +++--- .../utils/bossbar/BauSystemBossbar.java | 51 ++++++ .../utils/bossbar/BossBarService.java | 90 +++++++++++ .../utils/bossbar/GlobalBossbar.java | 112 ++++++++++++++ .../utils/bossbar/RegionedBossbar.java | 146 ++++++++++++++++++ 8 files changed, 429 insertions(+), 22 deletions(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BauSystemBossbar.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BossBarService.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/GlobalBossbar.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/RegionedBossbar.java diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 8d03d0ca..4ad71e2f 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -657,6 +657,7 @@ KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Disables Killcheck KILLCHECKER_INFO = §7Shows the overlaps of cannon kills in your build area. KILLCHECKER_ENABLE = §aKillchecker activated KILLCHECKER_DISABLE = §cKillchecker deactivated +KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 cannons # BlockCounter BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Toggle on/off diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties index f49f1fc6..89c05696 100644 --- a/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem_Main/src/BauSystem_de.properties @@ -630,6 +630,7 @@ KILLCHECKER_HELP_DISABLE = §8/§ekillchecker disable §8- §7Deaktiviert Killch KILLCHECKER_INFO = §7Zeigt Überlappungen der Kanonen Kills im Baubereich an. KILLCHECKER_ENABLE = §aKillchecker aktiviert KILLCHECKER_DISABLE = §cKillchecker deaktiviert +KILLCHECKER_BOSSBAR = §e§l{0} §7(§e{1}%§7) §e§l{2}§7 Kanonnen # BlockCounter BLOCK_COUNTER_HELP_TOGGLE = §8/§eblockcounter §8- §7Wechsel zwischen an und aus diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java index 6a0fe5b9..7148b0f9 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java @@ -21,8 +21,10 @@ package de.steamwar.bausystem.features.killchecker; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.utils.bossbar.BossBarService; import de.steamwar.command.SWCommand; import de.steamwar.linkage.Linked; +import de.steamwar.linkage.LinkedInstance; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -42,6 +44,9 @@ public class KillcheckerCommand extends SWCommand implements Listener { private Map visualizers = new HashMap<>(); + @LinkedInstance + public BossBarService bossBarService; + public KillcheckerCommand() { super("killchecker"); addDefaultHelpMessage("KILLCHECKER_INFO"); @@ -50,7 +55,7 @@ public class KillcheckerCommand extends SWCommand implements Listener { @Register(value = "enable", description = "KILLCHECKER_HELP_ENABLE") public void genericCommand(Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) { Region region = Region.getRegion(player.getLocation()); - KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, KillcheckerVisualizer::new); + KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, region1 -> new KillcheckerVisualizer(region1, bossBarService)); killcheckerVisualizer.recalc(); killcheckerVisualizer.show(player, onlyOutline); BauSystem.MESSAGE.send("KILLCHECKER_ENABLE", player); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java index 2d876ebe..161a44b2 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java @@ -19,11 +19,13 @@ package de.steamwar.bausystem.features.killchecker; -import de.steamwar.bausystem.features.killchecker.Cuboid; +import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.utils.RegionExtensionType; import de.steamwar.bausystem.region.utils.RegionType; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; +import de.steamwar.bausystem.utils.bossbar.BossBarService; import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; @@ -58,13 +60,19 @@ public class KillcheckerVisualizer { private final Set players = new HashSet<>(); private final Set areaPlayers = new HashSet<>(); - public KillcheckerVisualizer(Region region) { + private final Region region; + private final BossBarService bossBarService; + + public KillcheckerVisualizer(Region region, BossBarService bossBarService) { + this.region = region; this.minPoint = region.getMinPoint(RegionType.BUILD, RegionExtensionType.NORMAL); this.maxPoint = region.getMaxPoint(RegionType.BUILD, RegionExtensionType.NORMAL); yArea = (maxPoint.getX() - minPoint.getX()) * (maxPoint.getZ() - minPoint.getZ()); zArea = (maxPoint.getX() - minPoint.getX()) * (maxPoint.getY() - minPoint.getY()); xArea = (maxPoint.getY() - minPoint.getY()) * (maxPoint.getZ() - minPoint.getZ()); + + this.bossBarService = bossBarService; } private final REntityServer outline = new REntityServer(); @@ -73,7 +81,6 @@ public class KillcheckerVisualizer { private final Map killCount = new HashMap<>(); private final Set outlinePointsCache = new HashSet<>(); private final Map rEntities = new HashMap<>(); - private final Map bossBars = new HashMap<>(); private double percent = 0; private int kills = 0; @@ -253,9 +260,7 @@ public class KillcheckerVisualizer { double zPercent = xCount / (double) zArea; percent = (xPercent + yPercent + zPercent) / 3; kills = zKills + yKills + xKills; - for (Map.Entry entry : bossBars.entrySet()) { - updateBossBar(entry.getKey(), entry.getValue()); - } + players.forEach(this::updateBossBar); Set pointSet = new HashSet<>(killCount.keySet()); Set outlinePointsCacheLast = new HashSet<>(outlinePointsCache); @@ -284,17 +289,19 @@ public class KillcheckerVisualizer { return kills * (kills - 1) / 2; } - private void updateBossBar(Player player, BossBar bossBar) { - bossBar.setTitle("§e§l" + kills + " §7(§e" + ((int) (percent * 1000) / 10.0) + "%§7) §e§l" + cannonCount + "§7 Kanonen"); - bossBar.setProgress(percent); + private void updateBossBar(Player player) { + BauSystemBossbar bossbar = bossBarService.get(player, region, "killchecker"); + bossbar.setTitle(BauSystem.MESSAGE.parse("KILLCHECKER_BOSSBAR", player, kills, ((int) (percent * 1000) / 10.0), cannonCount)); + bossbar.setProgress(percent); + if (percent >= 0.35) { - bossBar.setColor(BarColor.RED); + bossbar.setColor(BarColor.RED); } else if (percent >= 0.25) { - bossBar.setColor(BarColor.PURPLE); + bossbar.setColor(BarColor.PURPLE); } else if (percent >= 0.15) { - bossBar.setColor(BarColor.YELLOW); + bossbar.setColor(BarColor.YELLOW); } else { - bossBar.setColor(BarColor.GREEN); + bossbar.setColor(BarColor.GREEN); } } @@ -357,13 +364,7 @@ public class KillcheckerVisualizer { inner.removePlayer(player); areaPlayers.remove(player); } - bossBars.computeIfAbsent(player, player1 -> { - BossBar bossBar = Bukkit.createBossBar("", BarColor.GREEN, BarStyle.SOLID); - updateBossBar(player1, bossBar); - bossBar.addPlayer(player1); - bossBar.setVisible(true); - return bossBar; - }); + updateBossBar(player); return players.add(player); } @@ -374,7 +375,7 @@ public class KillcheckerVisualizer { } players.remove(player); areaPlayers.remove(player); - bossBars.remove(player).removePlayer(player); + bossBarService.remove(player, region, "killchecker"); if (players.isEmpty()) { outline.close(); return true; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BauSystemBossbar.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BauSystemBossbar.java new file mode 100644 index 00000000..e72e0b53 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BauSystemBossbar.java @@ -0,0 +1,51 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.utils.bossbar; + +import de.steamwar.bausystem.region.Region; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarFlag; +import org.bukkit.boss.BarStyle; + +public interface BauSystemBossbar { + + String getTitle(); + void setTitle(String title); + + double getProgress(); + void setProgress(double progress); + + BarColor getColor(); + void setColor(BarColor color); + + BarStyle getStyle(); + void setStyle(BarStyle style); + + boolean hasFlag(BarFlag flag); + void addFlag(BarFlag flag); + void removeFlag(BarFlag flag); + + boolean isVisible(); + void setVisible(boolean visible); + + Region getRegion(); + + void cleanup(); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BossBarService.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BossBarService.java new file mode 100644 index 00000000..6c7d636d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/BossBarService.java @@ -0,0 +1,90 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.utils.bossbar; + +import de.steamwar.bausystem.region.Region; +import de.steamwar.linkage.Linked; +import org.bukkit.Bukkit; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.HashMap; +import java.util.Map; + +@Linked +public class BossBarService implements Listener { + + private final Map>> playerBossBars = new HashMap<>(); + + public synchronized BauSystemBossbar get(Player player, Region region, String key) { + return playerBossBars.computeIfAbsent(player, p -> new HashMap<>()) + .computeIfAbsent(region, r -> new HashMap<>()) + .computeIfAbsent(key, k -> { + BossBar bossBar = Bukkit.createBossBar("", BarColor.WHITE, BarStyle.SOLID); + bossBar.addPlayer(player); + if (region.isGlobal()) { + return new GlobalBossbar(bossBar); + } else { + return new RegionedBossbar(bossBar, region, player); + } + }); + } + + public synchronized void removeAll(Player player, String key) { + Map> regionMap = playerBossBars.get(player); + if (regionMap == null) return; + for (Map bossBarMap : regionMap.values()) { + BauSystemBossbar bossBar = bossBarMap.remove(key); + if (bossBar == null) continue; + bossBar.cleanup(); + } + } + + public synchronized void removeAll(Player player) { + Map> regionMap = playerBossBars.remove(player); + if (regionMap == null) return; + for (Map bossBarMap : regionMap.values()) { + for (BauSystemBossbar bossBar : bossBarMap.values()) { + bossBar.cleanup(); + } + } + } + + public synchronized void remove(Player player, Region region, String key) { + Map> regionMap = playerBossBars.get(player); + if (regionMap == null) return; + Map bossBarMap = regionMap.get(region); + if (bossBarMap == null) return; + BauSystemBossbar bossBar = bossBarMap.remove(key); + if (bossBar == null) return; + bossBar.cleanup(); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + removeAll(event.getPlayer()); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/GlobalBossbar.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/GlobalBossbar.java new file mode 100644 index 00000000..a5aaf9fe --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/GlobalBossbar.java @@ -0,0 +1,112 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.utils.bossbar; + +import de.steamwar.bausystem.region.GlobalRegion; +import de.steamwar.bausystem.region.Region; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarFlag; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; + +public class GlobalBossbar implements BauSystemBossbar { + + private BossBar bossBar; + + public GlobalBossbar(BossBar bossBar) { + this.bossBar = bossBar; + } + + @Override + public String getTitle() { + return bossBar.getTitle(); + } + + @Override + public void setTitle(String title) { + bossBar.setTitle(title); + } + + @Override + public double getProgress() { + return bossBar.getProgress(); + } + + @Override + public void setProgress(double progress) { + bossBar.setProgress(progress); + } + + @Override + public BarColor getColor() { + return bossBar.getColor(); + } + + @Override + public void setColor(BarColor color) { + bossBar.setColor(color); + } + + @Override + public BarStyle getStyle() { + return bossBar.getStyle(); + } + + @Override + public void setStyle(BarStyle style) { + bossBar.setStyle(style); + } + + @Override + public boolean hasFlag(BarFlag flag) { + return bossBar.hasFlag(flag); + } + + @Override + public void addFlag(BarFlag flag) { + bossBar.addFlag(flag); + } + + @Override + public void removeFlag(BarFlag flag) { + bossBar.removeFlag(flag); + } + + @Override + public boolean isVisible() { + return bossBar.isVisible(); + } + + @Override + public void setVisible(boolean visible) { + bossBar.setVisible(visible); + } + + @Override + public Region getRegion() { + return GlobalRegion.getInstance(); + } + + @Override + public void cleanup() { + bossBar.removeAll(); + bossBar = null; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/RegionedBossbar.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/RegionedBossbar.java new file mode 100644 index 00000000..4d922143 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/bossbar/RegionedBossbar.java @@ -0,0 +1,146 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.utils.bossbar; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.utils.RegionExtensionType; +import de.steamwar.bausystem.region.utils.RegionType; +import org.bukkit.Bukkit; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarFlag; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class RegionedBossbar implements BauSystemBossbar, Listener { + + private BossBar bossBar; + private Region region; + private Player player; + + public RegionedBossbar(BossBar bossBar, Region region, Player player) { + this.bossBar = bossBar; + this.region = region; + this.player = player; + Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); + } + + @Override + public String getTitle() { + return bossBar.getTitle(); + } + + @Override + public void setTitle(String title) { + bossBar.setTitle(title); + } + + @Override + public double getProgress() { + return bossBar.getProgress(); + } + + @Override + public void setProgress(double progress) { + bossBar.setProgress(progress); + } + + @Override + public BarColor getColor() { + return bossBar.getColor(); + } + + @Override + public void setColor(BarColor color) { + bossBar.setColor(color); + } + + @Override + public BarStyle getStyle() { + return bossBar.getStyle(); + } + + @Override + public void setStyle(BarStyle style) { + bossBar.setStyle(style); + } + + @Override + public boolean hasFlag(BarFlag flag) { + return bossBar.hasFlag(flag); + } + + @Override + public void addFlag(BarFlag flag) { + bossBar.addFlag(flag); + } + + @Override + public void removeFlag(BarFlag flag) { + bossBar.removeFlag(flag); + } + + @Override + public boolean isVisible() { + return bossBar.isVisible(); + } + + @Override + public void setVisible(boolean visible) { + bossBar.setVisible(visible); + } + + @Override + public Region getRegion() { + return region; + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if (event.getPlayer() != player) return; + if (region.inRegion(event.getTo(), RegionType.NORMAL, RegionExtensionType.NORMAL)) { + bossBar.addPlayer(player); + } else { + bossBar.removePlayer(player); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (event.getPlayer() != player) return; + cleanup(); + } + + @Override + public void cleanup() { + bossBar.removeAll(); + bossBar = null; + region = null; + player = null; + + PlayerMoveEvent.getHandlerList().unregister(this); + PlayerQuitEvent.getHandlerList().unregister(this); + } +}