From a80d02888741a33619bca35e2671b847febe33a2 Mon Sep 17 00:00:00 2001 From: pxav Date: Sun, 24 Jan 2021 14:11:19 +0100 Subject: [PATCH 01/68] Fix bug that milliseconds were not converted correctly to ticks --- .../main/java/de/pxav/kelp/core/scheduler/TimeConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/de/pxav/kelp/core/scheduler/TimeConverter.java b/core/src/main/java/de/pxav/kelp/core/scheduler/TimeConverter.java index ad42cdfe..0dd872c2 100644 --- a/core/src/main/java/de/pxav/kelp/core/scheduler/TimeConverter.java +++ b/core/src/main/java/de/pxav/kelp/core/scheduler/TimeConverter.java @@ -49,7 +49,7 @@ public static int secondsToTicks(int seconds) { public static int getTicks(int value, TimeUnit timeUnit) { switch (timeUnit) { case MILLISECONDS: - return secondsToTicks(value * 1000); + return value / 50; case SECONDS: return secondsToTicks(value); case MINUTES: From 7b42f808e5117746de1149b138d6078f5fe1dfc8 Mon Sep 17 00:00:00 2001 From: pxav Date: Sun, 24 Jan 2021 20:14:51 +0100 Subject: [PATCH 02/68] Bump version in plugin information to 0.1.0 --- core/src/main/java/de/pxav/kelp/core/KelpPlugin.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java index f31f2fe0..09728f9e 100644 --- a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java +++ b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java @@ -35,7 +35,7 @@ * * @author pxav */ -@Plugin(name = "Kelp", version = "0.0.4") +@Plugin(name = "Kelp", version = "0.1.0") @Author("pxav") @Description("A cross version spigot framework.") @Singleton @@ -100,8 +100,8 @@ public void onEnable() { injector.getInstance(EventHandlerRegistration.class).initialize(this.getClass().getPackage().getName()); injector.getInstance(KelpEventRepository.class).detectSubscriptions(this.getClass().getPackage().getName()); - injector.getInstance(SidebarRepository.class).loadSidebars(this.getClass().getPackage().getName()); - injector.getInstance(SidebarRepository.class).schedule(); +// injector.getInstance(SidebarRepository.class).loadSidebars(this.getClass().getPackage().getName()); +// injector.getInstance(SidebarRepository.class).schedule(); injector.getInstance(KelpCommandRepository.class).loadCommands(this.getClass().getPackage().getName()); @@ -130,7 +130,7 @@ public void onDisable() { injector.getInstance(KelpApplicationRepository.class).disableApplications(); injector.getInstance(KelpNpcRepository.class).stopScheduler(); - injector.getInstance(SidebarRepository.class).interruptAnimations(); + //injector.getInstance(SidebarRepository.class).interruptAnimations(); injector.getInstance(ParticleEffectRepository.class).stopAllTimers(); injector.getInstance(KelpSchedulerRepository.class).interruptAll(); From 4d59910bfbc20b8f490605327177988bfc1ee36b Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:44:18 +0100 Subject: [PATCH 03/68] Add new updating and render methods to scoreboard version template --- .../version/SidebarVersionTemplate.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java old mode 100644 new mode 100755 index f38ef309..587a488a --- a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java @@ -1,20 +1,15 @@ package de.pxav.kelp.core.sidebar.version; import de.pxav.kelp.core.application.KelpVersionTemplate; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.component.SidebarComponent; +import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; +import de.pxav.kelp.core.sidebar.type.KelpSidebar; import org.bukkit.entity.Player; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; /** - * This basically is a template for version-specific implementations. - * If you want to create a version specific implementation of scoreboards - * you need to make your class inherit from this abstract class - * and type the content of the given methods. - * - * Kelp always detects if there is an implementation installed and - * automatically binds it to this class so that it can be injected - * in your constructor. So you can always depend on this class if - * you need version specific sidebar code. * * @author pxav */ @@ -54,4 +49,10 @@ public abstract Objective createObjective(Scoreboard parent, */ public abstract void closeScoreboard(Player player); + public abstract void renderSidebar(KelpSidebar sidebar, KelpPlayer player); + + public abstract void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer); + + public abstract void updateSidebar(KelpSidebar sidebar, KelpPlayer player); + } From 415a446e5619b092fc25b41492b7c0ac063af58e Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:44:53 +0100 Subject: [PATCH 04/68] Remove methods that are not needed anymore from sidebar version template --- .../version/SidebarVersionTemplate.java | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java index 587a488a..26b14c43 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java @@ -16,39 +16,6 @@ @KelpVersionTemplate public abstract class SidebarVersionTemplate { - /** - * @return A new, empty scoreboard. - */ - public abstract Scoreboard createScoreboard(); - - /** - * Creates a scoreboard objective. - * - * @param parent The scoreboard in which the objective should be wrapped. - * @param identifier The name/identifier of the objective. - * @param title The display name/title of the objective. - * @return The final scoreboard objective. - */ - public abstract Objective createObjective(Scoreboard parent, - String identifier, - String title); - - /** - * Open the screboard for a player. - * - * @param scoreboard The actual scoreboard you want to open. - * @param player The player who should see the scoreboard. - */ - public abstract void openScoreboard(Scoreboard scoreboard, Player player); - - /** - * Close / hide the scoreboard for the player again. - * - * @param player The player whose scoreboard - * should become invisible. - */ - public abstract void closeScoreboard(Player player); - public abstract void renderSidebar(KelpSidebar sidebar, KelpPlayer player); public abstract void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer); From a00cc0632d33a09a28f8db01ed63ebc9a33aff4f Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:45:32 +0100 Subject: [PATCH 05/68] Remove old 1.8 sidebar implementation --- .../sidebar/SidebarVersion.java | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/SidebarVersion.java diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/SidebarVersion.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/SidebarVersion.java deleted file mode 100644 index 0a75a307..00000000 --- a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/SidebarVersion.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.pxav.kelp.implementation1_8.sidebar; - -import com.google.common.base.Preconditions; -import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; -import de.pxav.kelp.core.version.Versioned; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.ScoreboardManager; - -/** - * A class description goes here. - * - * @author pxav - */ -@Versioned -public class SidebarVersion extends SidebarVersionTemplate { - - @Override - public Scoreboard createScoreboard() { - return Bukkit.getScoreboardManager().getNewScoreboard(); - } - - @Override - public Objective createObjective(Scoreboard parent, - String identifier, - String title) { - Objective objective = parent.registerNewObjective(identifier, "dummy"); - objective.setDisplayName(title); - objective.setDisplaySlot(DisplaySlot.SIDEBAR); - return objective; - } - - @Override - public void openScoreboard(Scoreboard scoreboard, Player player) { - player.setScoreboard(scoreboard); - } - - @Override - public void closeScoreboard(Player player) { - ScoreboardManager manager = Bukkit.getScoreboardManager(); - Preconditions.checkNotNull(manager); - Scoreboard emptyScoreboard = manager.getNewScoreboard(); - player.setScoreboard(emptyScoreboard); - } - -} From 58683ae24e2b486bf8f8a0354ad3732128146363 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:46:41 +0100 Subject: [PATCH 06/68] Write new version implementation for new sidebar methods --- .../sidebar/VersionedSidebar.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100755 v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java new file mode 100755 index 00000000..34987473 --- /dev/null +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java @@ -0,0 +1,141 @@ +package de.pxav.kelp.implementation1_8.sidebar; + +import com.google.common.base.Preconditions; +import de.pxav.kelp.core.logger.KelpLogger; +import de.pxav.kelp.core.logger.LogLevel; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.SidebarRepository; +import de.pxav.kelp.core.sidebar.SidebarUtils; +import de.pxav.kelp.core.sidebar.component.SidebarComponent; +import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; +import de.pxav.kelp.core.sidebar.type.KelpSidebar; +import de.pxav.kelp.core.sidebar.type.SimpleSidebar; +import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; +import de.pxav.kelp.core.version.Versioned; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.*; + +import javax.inject.Inject; + +/** + * A class description goes here. + * + * @author pxav + */ +@Versioned +public class VersionedSidebar extends SidebarVersionTemplate { + + private SidebarUtils sidebarUtils; + private KelpLogger logger; + private SidebarRepository sidebarRepository; + + @Inject + public VersionedSidebar(SidebarUtils sidebarUtils, KelpLogger logger, SidebarRepository sidebarRepository) { + this.sidebarUtils = sidebarUtils; + this.logger = logger; + this.sidebarRepository = sidebarRepository; + } + + @Override + public void renderSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { + Player player = kelpPlayer.getBukkitPlayer(); + Scoreboard scoreboard; + Objective objective; + + if (kelpPlayer.hasScoreboard()) { + scoreboard = player.getScoreboard(); + } else { + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + } + + if (scoreboard.getObjective(DisplaySlot.SIDEBAR) == null) { + objective = scoreboard.registerNewObjective("kelpObj", "dummy"); + } else { + objective = scoreboard.getObjective(DisplaySlot.SIDEBAR); + } + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + + player.setScoreboard(scoreboard); + this.updateSidebar(sidebar, kelpPlayer); + + if (sidebar.getClass().isAssignableFrom(AnimatedSidebar.class)) { + AnimatedSidebar animatedSidebar = (AnimatedSidebar) sidebar; + objective.setDisplayName(animatedSidebar.getTitle().states().get(0)); + sidebarRepository.addAnimatedSidebar(animatedSidebar, kelpPlayer); + } else if (sidebar.getClass().isAssignableFrom(SimpleSidebar.class)) { + SimpleSidebar simpleSidebar = (SimpleSidebar) sidebar; + objective.setDisplayName(simpleSidebar.getTitle().get()); + } + + } + + @Override + public void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer) { + Scoreboard scoreboard = kelpPlayer.getBukkitPlayer().getScoreboard(); + + for (Object object : sidebar.getComponents()) { + if (!(object instanceof SidebarComponent)) { + continue; + } + + SidebarComponent component = (SidebarComponent) object; + + component.render().forEach((line, text) -> { + String teamName = "entry_" + line; + Team team = scoreboard.getTeam(teamName); + + if (team == null) { + logger.log(LogLevel.ERROR, "Cannot update component at score " + line + ", " + + "because there is no entry assigned to this score. Are you sure 'lazyUpdate' " + + "is the appropriate updating method for your case?"); + return; + } + + sidebarUtils.setTeamData(text, team); + }); + } + } + + @Override + public void updateSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { + Scoreboard scoreboard = kelpPlayer.getBukkitPlayer().getScoreboard(); + Objective objective = scoreboard.getObjective(DisplaySlot.SIDEBAR); + + if (objective == null) { + renderSidebar(sidebar, kelpPlayer); + return; + } + + for (String entry : scoreboard.getEntries()) { + Score score = objective.getScore(entry); + + if (score == null) { + continue; + } + + scoreboard.resetScores(entry); + } + + scoreboard.getTeams().forEach(Team::unregister); + + for (Object object : sidebar.getComponents()) { + if (!(object instanceof SidebarComponent)) { + continue; + } + + SidebarComponent component = (SidebarComponent) object; + + component.render().forEach((line, text) -> { + String entry = sidebarUtils.randomEmptyEntry(scoreboard); + objective.getScore(entry).setScore(line); + Team team = scoreboard.registerNewTeam("entry_" + line); + team.addEntry(entry); + + sidebarUtils.setTeamData(text, team); + }); + + } + } + +} From 681d313268cd556fcba6ea3398ec7a1d82158088 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:47:54 +0100 Subject: [PATCH 07/68] Remove old sidebar repository from KelpPlayer to avoid circular dependency --- .../java/de/pxav/kelp/core/player/KelpPlayer.java | 10 ++++++---- .../kelp/core/player/KelpPlayerRepository.java | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index 34ee9b2c..bd08ab07 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -80,7 +80,7 @@ public class KelpPlayer extends LivingKelpEntity { public KelpPlayer(Player bukkitPlayer, PlayerVersionTemplate playerVersionTemplate, - SidebarRepository sidebarRepository, + //SidebarRepository sidebarRepository, KelpInventoryRepository inventoryRepository, KelpPlayerRepository kelpPlayerRepository, ParticleVersionTemplate particleVersionTemplate, @@ -101,7 +101,7 @@ public KelpPlayer(Player bukkitPlayer, bukkitPlayer); this.bukkitPlayer = bukkitPlayer; this.playerVersionTemplate = playerVersionTemplate; - this.sidebarRepository = sidebarRepository; + //this.sidebarRepository = sidebarRepository; this.inventoryRepository = inventoryRepository; this.particleVersionTemplate = particleVersionTemplate; this.signPromptVersionTemplate = signPromptVersionTemplate; @@ -130,7 +130,8 @@ public SimpleChatPrompt openSimpleChatPrompt() { * @return the current instance of the player. */ public KelpPlayer openKelpSidebar(String identifier) { - this.sidebarRepository.openSidebar(identifier, bukkitPlayer); +// this.sidebarRepository.openSidebar(identifier, bukkitPlayer); +// return this; return this; } @@ -140,7 +141,8 @@ public KelpPlayer openKelpSidebar(String identifier) { * @return the current instance of the player. */ public KelpPlayer removeKelpSidebar() { - this.sidebarRepository.removeSidebar(bukkitPlayer); +// this.sidebarRepository.removeSidebar(bukkitPlayer); +// return this; return this; } diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java index d93c061d..8ce8f7a4 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayerRepository.java @@ -56,9 +56,18 @@ public class KelpPlayerRepository { private ChatPromptVersionTemplate chatPromptVersionTemplate; @Inject - public KelpPlayerRepository(PlayerVersionTemplate playerVersionTemplate, SidebarRepository sidebarRepository, KelpInventoryRepository inventoryRepository, KelpLogger logger, EntityVersionTemplate entityVersionTemplate, LivingEntityVersionTemplate livingEntityVersionTemplate, ParticleVersionTemplate particleVersionTemplate, SignPromptVersionTemplate signPromptVersionTemplate, AnvilPromptVersionTemplate anvilPromptVersionTemplate, ChatPromptVersionTemplate chatPromptVersionTemplate) { + public KelpPlayerRepository(PlayerVersionTemplate playerVersionTemplate, + //SidebarRepository sidebarRepository, + KelpInventoryRepository inventoryRepository, + KelpLogger logger, + EntityVersionTemplate entityVersionTemplate, + LivingEntityVersionTemplate livingEntityVersionTemplate, + ParticleVersionTemplate particleVersionTemplate, + SignPromptVersionTemplate signPromptVersionTemplate, + AnvilPromptVersionTemplate anvilPromptVersionTemplate, + ChatPromptVersionTemplate chatPromptVersionTemplate) { this.playerVersionTemplate = playerVersionTemplate; - this.sidebarRepository = sidebarRepository; + //this.sidebarRepository = sidebarRepository; this.inventoryRepository = inventoryRepository; this.logger = logger; this.entityVersionTemplate = entityVersionTemplate; @@ -217,7 +226,7 @@ public void removeKelpPlayer(UUID uuid) { private KelpPlayer newKelpPlayerFrom(Player bukkitPlayer) { return new KelpPlayer(bukkitPlayer, playerVersionTemplate, - sidebarRepository, + //sidebarRepository, inventoryRepository, this, particleVersionTemplate, From 2f53b539bfebcf5d5ef97b41fca0a9129d5ded26 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:48:25 +0100 Subject: [PATCH 08/68] Add KelpPlayer method checking whether the player has a scoreboard --- .../java/de/pxav/kelp/core/player/KelpPlayer.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index bd08ab07..19165959 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -23,6 +23,8 @@ import de.pxav.kelp.core.sound.KelpSound; import org.bukkit.Location; import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Scoreboard; import java.util.Collection; import java.util.UUID; @@ -146,6 +148,17 @@ public KelpPlayer removeKelpSidebar() { return this; } + public boolean hasScoreboard() { + Scoreboard scoreboard = bukkitPlayer.getScoreboard(); + return scoreboard.getObjective(DisplaySlot.SIDEBAR) != null + || scoreboard.getObjective(DisplaySlot.BELOW_NAME) != null + || scoreboard.getObjective(DisplaySlot.PLAYER_LIST) != null; + } + + public boolean hasSidebar() { + return false; //todo implement + } + /** * Opens a {@link KelpInventory} to the player. This * is equivalent to calling the {@link KelpInventoryRepository#openInventory(KelpInventory, KelpPlayer)} From 7d61a5bd6c94c88ec6df8cac22cec5bc68e80b5d Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:49:06 +0100 Subject: [PATCH 09/68] Add version template responsible for updating titles of sidebars --- .../version/SidebarUpdaterVersionTemplate.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java new file mode 100644 index 00000000..4f609451 --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java @@ -0,0 +1,11 @@ +package de.pxav.kelp.core.sidebar.version; + +import de.pxav.kelp.core.application.KelpVersionTemplate; +import de.pxav.kelp.core.player.KelpPlayer; + +@KelpVersionTemplate +public abstract class SidebarUpdaterVersionTemplate { + + public abstract void updateTitleOnly(String to, KelpPlayer player); + +} From c7e927e1f03b069ea40dc415448a412930d8b249 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:49:27 +0100 Subject: [PATCH 10/68] Implement updater template for spigot 1.8 --- .../sidebar/VersionedSidebarUpdater.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java new file mode 100644 index 00000000..45bcc445 --- /dev/null +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java @@ -0,0 +1,21 @@ +package de.pxav.kelp.implementation1_8.sidebar; + +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; +import de.pxav.kelp.core.version.Versioned; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; + +@Versioned +public class VersionedSidebarUpdater extends SidebarUpdaterVersionTemplate { + + @Override + public void updateTitleOnly(String to, KelpPlayer kelpPlayer) { + Scoreboard scoreboard = kelpPlayer.getBukkitPlayer().getScoreboard(); + Objective objective = scoreboard.getObjective(DisplaySlot.SIDEBAR); + + objective.setDisplayName(to); + } + +} From e19023dc7f9508c79d19ad6d750dcbd25ec39063 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:51:08 +0100 Subject: [PATCH 11/68] Make KelpSidebar generic and update basic model structure --- .../kelp/core/sidebar/type/KelpSidebar.java | 97 ++++++++++--------- 1 file changed, 52 insertions(+), 45 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java old mode 100644 new mode 100755 index 84471ffa..70607ead --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java @@ -1,55 +1,62 @@ package de.pxav.kelp.core.sidebar.type; -import org.bukkit.entity.Player; +import com.google.common.collect.Lists; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.component.SidebarComponent; import org.bukkit.scoreboard.Scoreboard; +import java.util.Collection; + /** - * This class basically is the template for each sidebar. - * If you want to make a custom sidebar, - * your class has to inherit from this class. - * - * It provides essential methods used by the repository. + * A class description goes here. * * @author pxav */ -public abstract class KelpSidebar { - - /** - * Renders the sidebar and its components. - * That means that no existing scoreboard is modified, - * but a new one will be created as well as - * a new objective. - * This method does not open the sidebar automatically. - * - * @param player The player for which the sidebar should be rendered. - * @return The final sidebar obeject. - */ - public abstract Scoreboard renderSidebar(Player player); - - /** - * Renders and opens the sidebar. - * This method basically executes the {@code #renderSidebar(player)} method - * above and directly sets the scoreboard for the given player. - * - * @param player The player who should see the scoreboard. - * @return The render result. - */ - public abstract Scoreboard renderAndOpenSidebar(Player player); - - /** - * Updates the given scoreboard without creating a new - * one. - * - * @param player The player whose scoreboard you want to update. - * @return The final scoreboard with the updated data. - */ - public abstract Scoreboard update(Player player); - - /** - * Makes the sidebar disappear from the player's screen. - * - * @param player The player whose sidebar should disappear. - */ - public abstract void hideSidebar(Player player); +public abstract class KelpSidebar { + + protected Collection components = Lists.newArrayList(); + protected int latestLines = 0; + + public T addComponent(SidebarComponent component) { + this.components.add(component); + return (T) this; + } + + public T removeComponent(SidebarComponent component) { + this.components.remove(component); + return (T) this; + } + + public T clearComponents() { + this.components.clear(); + return (T) this; + } + + public Collection getComponents() { + return this.components; + } + + public int getLatestLines() { + return latestLines; + } + + public T setLatestLines(int latestLines) { + this.latestLines = latestLines; + return (T) this; + } + + public abstract void render(KelpPlayer player); + + public abstract void update(KelpPlayer player); + + public abstract void remove(KelpPlayer player); +// +// protected void unregisterAllTeams() { +// scoreboard.getTeams().forEach(current -> { +// if (current.getName().startsWith("entry_")) { +// current.unregister(); +// } +// }); +// } } From 8d53975d3f12bedf8f2a240df0724a1d3925d1a3 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:51:56 +0100 Subject: [PATCH 12/68] Implement new sidebar model in SimpleSidebar --- .../kelp/core/sidebar/type/SimpleSidebar.java | 97 +++++++------------ 1 file changed, 35 insertions(+), 62 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java old mode 100644 new mode 100755 index f11e5a82..1fcd4b52 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java @@ -1,8 +1,13 @@ package de.pxav.kelp.core.sidebar.type; import com.google.common.collect.Lists; +import de.pxav.kelp.core.KelpPlugin; +import de.pxav.kelp.core.animation.TextAnimation; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.SidebarUtils; import de.pxav.kelp.core.sidebar.component.SidebarComponentFactory; -import de.pxav.kelp.core.sidebar.component.SimpleSidebarComponent; +import de.pxav.kelp.core.sidebar.component.SimpleSidebarComponentOld; +import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; import de.pxav.kelp.core.logger.KelpLogger; import org.bukkit.Bukkit; @@ -12,6 +17,7 @@ import org.bukkit.scoreboard.ScoreboardManager; import java.util.Collection; +import java.util.function.Supplier; /** * This class represents the most simple type @@ -22,94 +28,61 @@ * * @author pxav */ -public class SimpleSidebar extends KelpSidebar { +public class SimpleSidebar extends KelpSidebar { - // the title of the scoreboard (cannot be animated) - private String title; + private Supplier title; - // the components that should be displayed. - private Collection components; - - private KelpLogger logger; - private JavaPlugin javaPlugin; private SidebarVersionTemplate sidebarVersionTemplate; - private SidebarComponentFactory sidebarComponentFactory; - - private ScoreboardManager scoreboardManager; + private SidebarUpdaterVersionTemplate updaterVersionTemplate; - SimpleSidebar(KelpLogger logger, - JavaPlugin javaPlugin, - SidebarVersionTemplate sidebarVersionTemplate, - SidebarComponentFactory sidebarComponentFactory) { - this.logger = logger; - this.javaPlugin = javaPlugin; + public SimpleSidebar(SidebarVersionTemplate sidebarVersionTemplate, + SidebarUpdaterVersionTemplate updaterVersionTemplate) { this.sidebarVersionTemplate = sidebarVersionTemplate; - this.sidebarComponentFactory = sidebarComponentFactory; + this.updaterVersionTemplate = updaterVersionTemplate; + } - this.components = Lists.newArrayList(); - this.scoreboardManager = Bukkit.getScoreboardManager(); + public static SimpleSidebar create() { + return new SimpleSidebar( + KelpPlugin.getInjector().getInstance(SidebarVersionTemplate.class), + KelpPlugin.getInjector().getInstance(SidebarUpdaterVersionTemplate.class) + ); } - public SimpleSidebar withTitle(String title) { + public SimpleSidebar title(Supplier title) { this.title = title; return this; } - public SimpleSidebar insertLine(int line, String text) { - this.components.add(sidebarComponentFactory.simpleTextComponent(text, line)); + public SimpleSidebar staticTitle(String title) { + this.title = () -> title; return this; } - public SimpleSidebar addComponent(SimpleSidebarComponent sidebarComponent) { - this.components.add(sidebarComponent); - return this; + public Supplier getTitle() { + return title; } @Override - public Scoreboard renderSidebar(Player player) { - Scoreboard scoreboard = scoreboardManager.getNewScoreboard(); - - scoreboard.getTeams().forEach(current -> { - if (current.getName().startsWith("entry_")) { - current.unregister(); - } - }); - - if (scoreboard.getObjective("main") == null) { - sidebarVersionTemplate.createObjective(scoreboard, "main", this.title); - } - - for (SimpleSidebarComponent component : this.components) { - component.render(scoreboard); - } - - return scoreboard; + public void render(KelpPlayer player) { + sidebarVersionTemplate.renderSidebar(this, player); } - @Override - public Scoreboard renderAndOpenSidebar(Player player) { - Scoreboard scoreboard = this.renderSidebar(player); - player.setScoreboard(scoreboard); - return scoreboard; + public void updateTitleOnly(KelpPlayer player) { + updaterVersionTemplate.updateTitleOnly(title.get(), player); } @Override - public Scoreboard update(Player player) { - Scoreboard scoreboard = player.getScoreboard(); - - for (SimpleSidebarComponent component : this.components) { - component.update(scoreboard); - } + public void update(KelpPlayer player) { + sidebarVersionTemplate.updateSidebar(this, player); + } - return scoreboard; + public void lazyUpdate(KelpPlayer player) { + sidebarVersionTemplate.lazyUpdate(this, player); } @Override - public void hideSidebar(Player player) { - Bukkit.getScheduler().runTaskLater(javaPlugin, () -> { - Scoreboard emptyScoreboard = scoreboardManager.getNewScoreboard(); - player.setScoreboard(emptyScoreboard); - }, 1L); + public void remove(KelpPlayer player) { + } } From 89b86d956b9f456d085925d150b15ef8ec796caa Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:52:47 +0100 Subject: [PATCH 13/68] Implement new sidebar model in AnimatedSidebar --- .../core/sidebar/type/AnimatedSidebar.java | 102 ++++++++---------- 1 file changed, 47 insertions(+), 55 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java old mode 100644 new mode 100755 index 6e160945..e9c4ed70 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java @@ -1,97 +1,89 @@ package de.pxav.kelp.core.sidebar.type; -import com.google.common.collect.Lists; +import de.pxav.kelp.core.KelpPlugin; +import de.pxav.kelp.core.animation.StaticTextAnimation; import de.pxav.kelp.core.animation.TextAnimation; -import de.pxav.kelp.core.sidebar.component.SimpleSidebarComponent; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.SidebarUtils; +import de.pxav.kelp.core.sidebar.component.SidebarComponent; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.ScoreboardManager; -import java.util.List; +import java.util.Collection; /** - * This is a more complex type of sidebar which can - * hold animations like an animated title. - * - * Furthermore you can add simple components. + * A class description goes here. * * @author pxav */ -public class AnimatedSidebar extends KelpSidebar { +public class AnimatedSidebar extends KelpSidebar { - private TextAnimation titleAnimation; - private List simpleComponents; + private TextAnimation title; + private int titleAnimationInterval = 200; + private String clusterId = null; - private ScoreboardManager scoreboardManager; + private SidebarUtils sidebarUtils; private SidebarVersionTemplate sidebarVersionTemplate; - AnimatedSidebar(SidebarVersionTemplate sidebarVersionTemplate) { - this.scoreboardManager = Bukkit.getScoreboardManager(); + public AnimatedSidebar(SidebarUtils sidebarUtils, SidebarVersionTemplate sidebarVersionTemplate) { + this.sidebarUtils = sidebarUtils; this.sidebarVersionTemplate = sidebarVersionTemplate; - this.simpleComponents = Lists.newArrayList(); } - public AnimatedSidebar addComponent(SimpleSidebarComponent components) { - this.simpleComponents.add(components); + public static AnimatedSidebar create() { + return new AnimatedSidebar( + KelpPlugin.getInjector().getInstance(SidebarUtils.class), + KelpPlugin.getInjector().getInstance(SidebarVersionTemplate.class) + ); + } + + public AnimatedSidebar title(TextAnimation title) { + this.title = title; return this; } - public AnimatedSidebar withTitle(TextAnimation titleAnimation) { - this.titleAnimation = titleAnimation; + public AnimatedSidebar titleAnimationInterval(int titleAnimationInterval) { + this.titleAnimationInterval = titleAnimationInterval; return this; } - public void updateTitleOnly(Player player, int state) { - Scoreboard scoreboard = player.getScoreboard(); - scoreboard.getObjective("main").setDisplayName(titleAnimation.states().get(state)); + public AnimatedSidebar clusterId(String clusterId) { + this.clusterId = clusterId; + return this; } - @Override - public Scoreboard renderSidebar(Player player) { - Scoreboard scoreboard = scoreboardManager.getNewScoreboard(); - - scoreboard.getTeams().forEach(current -> { - if (current.getName().startsWith("entry_")) { - current.unregister(); - } - }); - - if (scoreboard.getObjective("main") == null) { - sidebarVersionTemplate.createObjective(scoreboard, "main", titleAnimation.states().get(0)); - } - - for (SimpleSidebarComponent component : this.simpleComponents) { - component.render(scoreboard); - } - return scoreboard; + public String getClusterId() { + return clusterId; } - @Override - public Scoreboard renderAndOpenSidebar(Player player) { - Scoreboard scoreboard = renderSidebar(player); - player.setScoreboard(scoreboard); - return scoreboard; + public TextAnimation getTitle() { + return title; } - @Override - public Scoreboard update(Player player) { - Scoreboard scoreboard = player.getScoreboard(); + public int getTitleAnimationInterval() { + return titleAnimationInterval; + } - for (SimpleSidebarComponent component : this.simpleComponents) { - component.update(scoreboard); - } - return scoreboard; + @Override + public void render(KelpPlayer player) { + sidebarVersionTemplate.renderSidebar(this, player); } @Override - public void hideSidebar(Player player) { + public void update(KelpPlayer player) { + sidebarVersionTemplate.updateSidebar(this, player); + } + public void lazyUpdate(KelpPlayer player) { + sidebarVersionTemplate.lazyUpdate(this, player); } - public int maxStates() { - return this.titleAnimation == null ? 0 : this.titleAnimation.states().size(); + @Override + public void remove(KelpPlayer player) { + } } From 74fb90a5d423dbee9d17d8e9b6500977b9e42880 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:53:35 +0100 Subject: [PATCH 14/68] Rewrite SidebarRepository with a cluster-based updating system --- .../kelp/core/sidebar/SidebarRepository.java | 398 +++++------------- 1 file changed, 99 insertions(+), 299 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java old mode 100644 new mode 100755 index b33b1bda..c1e8f670 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java @@ -1,342 +1,142 @@ package de.pxav.kelp.core.sidebar; -import com.google.common.base.Preconditions; import com.google.common.collect.Maps; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Singleton; +import com.google.common.collect.Sets; +import de.pxav.kelp.core.animation.TextAnimation; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.player.KelpPlayerRepository; +import de.pxav.kelp.core.scheduler.KelpSchedulerRepository; +import de.pxav.kelp.core.scheduler.type.RepeatingScheduler; +import de.pxav.kelp.core.scheduler.type.SchedulerFactory; import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; -import de.pxav.kelp.core.logger.KelpLogger; -import de.pxav.kelp.core.logger.LogLevel; -import de.pxav.kelp.core.reflect.MethodCriterion; -import de.pxav.kelp.core.reflect.MethodFinder; -import de.pxav.kelp.core.sidebar.type.KelpSidebar; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; +import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** - * This repository class is used to manage your sidebars. - * You can open, close and update sidebars using the - * unique identifier which is passed in the {@code CreateSidebar} - * annotation. + * A class description goes here. * * @author pxav */ @Singleton public class SidebarRepository { - // saves the methods which build the sidebar. Identifier -> Method - private final Map methods = Maps.newHashMap(); + private ConcurrentHashMap animationStates; + private ConcurrentHashMap> clusters; + private ConcurrentHashMap clusterTasks; + private ConcurrentHashMap animations; - // should the sidebar be updated asynchronously? Identifier -> async? - private final Map asyncMode = Maps.newHashMap(); - - // The sidebar which is currently opened by a player. Player -> Sidebar identifier - private final Map playerSidebars = Maps.newHashMap(); - - // The schedulers for the title animation of animated sidebars. Identifier -> Scheduler - private final Map titleScheduler = Maps.newHashMap(); - - // The current state of animation for each player. Player -> State - private final Map animationStates = Maps.newHashMap(); - - // When should the next animation state be called? Identifier -> Time in millis - private final Map titleAnimationInterval = Maps.newHashMap(); - - // the identifier of the scoreboard which should be set on join. - private String defaultScoreboard = "NONE"; - - private MethodFinder methodFinder; - private KelpLogger kelpLogger; - private Injector injector; - private ExecutorService executorService; + private KelpSchedulerRepository schedulerRepository; + private SchedulerFactory schedulerFactory; + private SidebarUpdaterVersionTemplate updaterVersionTemplate; + private KelpPlayerRepository playerRepository; @Inject - public SidebarRepository(MethodFinder methodFinder, - KelpLogger kelpLogger, - Injector injector, - ExecutorService executorService) { - this.methodFinder = methodFinder; - this.kelpLogger = kelpLogger; - this.injector = injector; - this.executorService = executorService; + public SidebarRepository(KelpSchedulerRepository schedulerRepository, + SchedulerFactory schedulerFactory, + SidebarUpdaterVersionTemplate updaterVersionTemplate, + KelpPlayerRepository playerRepository) { + this.animationStates = new ConcurrentHashMap<>(); + this.clusters = new ConcurrentHashMap<>(); + this.clusterTasks = new ConcurrentHashMap<>(); + this.animations = new ConcurrentHashMap<>(); + this.schedulerFactory = schedulerFactory; + this.schedulerRepository = schedulerRepository; + this.updaterVersionTemplate = updaterVersionTemplate; + this.playerRepository = playerRepository; } - /** - * Searches for methods annotated with a {@code CreateSidebar} annotation - * and saves as a sidebar. - * - * @param packageNames The packages in which you want to search. - * @see CreateSidebar - */ - public void loadSidebars(String... packageNames) { - kelpLogger.log("[SIDEBAR] Loading sidebars in " + Arrays.toString(packageNames)); - this.methodFinder.filter(packageNames, MethodCriterion.annotatedWith(CreateSidebar.class)) - .forEach(method -> { - CreateSidebar annotation = method.getAnnotation(CreateSidebar.class); - String identifier = annotation.identifier(); - if (identifier.equalsIgnoreCase("NONE")) { - kelpLogger.log(LogLevel.ERROR, "[SIDEBAR] Sidebar identifier 'NONE' is not allowed, " + - "because it's reserved for the system. Please choose another name."); - return; - } - - if (!identifierAvailable(identifier)) { - kelpLogger.log(LogLevel.ERROR, "[SIDEBAR] Sidebar identifier " + identifier - + " is already in use, but identifiers must be unique!" + - " Please change the identifier and reload the system."); - return; - } - - methods.put(identifier, method); - asyncMode.put(identifier, annotation.async()); - if (annotation.titleAnimationInterval() <= 0) { - kelpLogger.log(LogLevel.ERROR, "[SIDEBAR] Animation interval of sidebar '" + identifier - + "' is smaller than or equal to 0. Please change the delay to at least 1."); - return; - } - titleAnimationInterval.put(identifier, annotation.titleAnimationInterval()); - - if (defaultScoreboard.equalsIgnoreCase("NONE")) { - defaultScoreboard = annotation.identifier(); - } - - kelpLogger.log("[SIDEBAR] Sidebar " + identifier + " successfully loaded!"); - }); - kelpLogger.log("[SIDEBAR] Loading process complete. Loaded " + methods.size() + " sidebars in total so far."); - } + public void addAnimatedSidebar(AnimatedSidebar sidebar, KelpPlayer player) { - /** - * Starts the schedulers for the scoreboard animations. - * - * Each sidebar gets an own scheduler which uses the interval - * which is passed in the {@code CreateSidebar} annotation, - * while animation states are linked to each player individually, - * because players can have different animations in the same sidebar - * when for example their name is displayed in the title: - * §apxav -> 4 states - * §aOpi_CAN -> 7 states - */ - public void schedule() { - kelpLogger.log("[SIDEBAR] Enabling animation schedulers."); - for (Map.Entry entry : Maps.newHashMap(this.titleAnimationInterval).entrySet()) { - String identifier = entry.getKey(); + animationStates.put(player.getUUID(), 0); + animations.put(player.getUUID(), sidebar.getTitle()); - // check if the current sidebar is really an animated one. - // if not, remove it from the collection and continue with the next one. - if (!this.isAnimated(identifier)) { - this.titleAnimationInterval.remove(identifier); - continue; + if (sidebar.getClusterId() != null) { + if (!clusters.containsKey(sidebar.getClusterId())) { + this.addCluster(sidebar.getClusterId(), sidebar.getTitleAnimationInterval()); } - - // create a new thread containing a new scheduler - ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - - - // schedule using the time passed in the annotation. - scheduledExecutorService.scheduleAtFixedRate(() -> { - try { - - // iterate all players on the server. - for (Player player : Bukkit.getOnlinePlayers()) { - if (!animationStates.containsKey(player)) { - continue; - } - - int state = this.animationStates.get(player); - - if (this.playerSidebars.containsKey(player) - && !this.playerSidebars.get(player).equalsIgnoreCase(identifier)) - continue; - - // load the sidebar for the player - AnimatedSidebar sidebar = (AnimatedSidebar) getSidebar(identifier, player); - Preconditions.checkNotNull(sidebar); - - // update the state. If the state index it out of bounds, reset it to 0. - animationStates.put(player, animationStates.get(player) + 1); - if (state >= sidebar.maxStates() - 1) { - this.animationStates.put(player, 0); - } - - // finally update the title. - sidebar.updateTitleOnly(player, state); - - } - - } catch (Exception e) { - e.printStackTrace(); - } - }, 200L, titleAnimationInterval.get(identifier), TimeUnit.MILLISECONDS); - - // save the scheduler object in the map so that it can be canceled later. - this.titleScheduler.put(identifier, scheduledExecutorService); - } - } - - /** - * Iterates through all sidebars and cancels the animation - * scheduler if existing. - */ - public void interruptAnimations() { - for (Map.Entry entry : this.titleScheduler.entrySet()) { - entry.getValue().shutdown(); + this.addPlayerToCluster(sidebar.getClusterId(), player); } - kelpLogger.log("[SIDEBAR] Interrupted all animation schedulers."); - } - - /** - * Open the given sidebar for the given player. - * - * @param identifier The identifier of the desired sidebar. - * @param player The player who should see the sidebar. - */ - public void openSidebar(String identifier, Player player) { - checkAvailability(identifier); - - KelpSidebar sidebar = getSidebar(identifier, player); - Preconditions.checkNotNull(sidebar); - playerSidebars.put(player, identifier); - animationStates.put(player, 0); - sidebar.renderAndOpenSidebar(player); } - /** - * Updates the sidebar of a player. - * The type ((a-)sync) depends on the value - * passed in the {@code CreateSidebar} annotation - * and will be selected automatically. - * - * @param player The player whose sidebar you want to update. - */ - public void updateSidebar(Player player) { - String identifier = playerSidebars.get(player); - if (isAsync(identifier)) { - this.updateSidebarAsynchronously(player); - } else { - this.updateSidebarSynchronously(player); - } + public void removeAnimatedSidebar(KelpPlayer player) { + Maps.newHashMap(this.clusters).forEach((clusterId, playerSet) + -> playerSet.stream() + .filter(uuid -> player.getUUID() == uuid) + .findFirst() + .ifPresent(uuid -> { + playerSet.remove(uuid); + if (playerSet.isEmpty()) { + stopCluster(clusterId); + return; + } + clusters.put(clusterId, playerSet); + })); + this.animationStates.remove(player.getUUID()); + this.animations.remove(player.getUUID()); } - /** - * Updates the sidebar of the given player inside the - * main thread of the server. - * - * @param player The player whose sidebar you want to update. - */ - public void updateSidebarSynchronously(Player player) { - String identifier = playerSidebars.get(player); - checkAvailability(identifier); - - KelpSidebar kelpSidebar = getSidebar(identifier, player); - Preconditions.checkNotNull(kelpSidebar); - kelpSidebar.update(player); + public void stopAllClusters() { + Maps.newHashMap(this.clusters).forEach((clusterId, playerSet) + -> stopCluster(clusterId)); } - /** - * Updates the sidebar of the given player in a - * separate thread. - * - * @param player The player whose sidebar you want to update. - */ - public void updateSidebarAsynchronously(Player player) { - this.executorService.execute(() -> { - String identifier = playerSidebars.get(player); - checkAvailability(identifier); - - KelpSidebar kelpSidebar = getSidebar(identifier, player); - Preconditions.checkNotNull(kelpSidebar); - kelpSidebar.update(player); - }); + @EventHandler + public void handleClusterRemove(PlayerQuitEvent event) { + KelpPlayer player = playerRepository.getKelpPlayer(event.getPlayer()); + if (animationStates.containsKey(player.getUUID())) { + removeAnimatedSidebar(player); + } } - /** - * Removes a player from all lists in the cache and clears - * its sidebar. - * - * @param player The player whose sidebar should be removed. - */ - public void removeSidebar(Player player) { - this.playerSidebars.remove(player); - this.animationStates.remove(player); + private void addPlayerToCluster(String clusterId, KelpPlayer player) { + Set players = clusters.get(clusterId); + players.add(player.getUUID()); + clusters.put(clusterId, players); } - /** - * Invokes the creation method of the sidebar with the - * given identifier and returns the result. - * - * @param identifier The identifier of the sidebar you want to get. - * @param player Each sidebar method needs a player as parameter - * to also load player-specific data as well. - * So you need to give the player who should be passed - * as parameter. - * @return The final sidebar object. - */ - private KelpSidebar getSidebar(String identifier, Player player) { - if (this.identifierAvailable(identifier)) return null; - - try { - Method method = this.methods.get(identifier); - return (KelpSidebar) method.invoke(injector.getInstance(method.getDeclaringClass()), player); - } catch (IllegalAccessException | InvocationTargetException ignore) {} - return null; + private void addCluster(String clusterId, int interval) { + clusters.put(clusterId, Sets.newHashSet()); + UUID task = schedulerFactory.newRepeatingScheduler() + .async() + .every(interval) + .milliseconds() + .run(taskId -> clusters.get(clusterId).forEach(current -> { + String updateTo = incrementAnimationState(current); + updaterVersionTemplate.updateTitleOnly(updateTo, playerRepository.getKelpPlayer(current)); + })); + clusterTasks.put(clusterId, task); } - /** - * Checks whether the requested sidebar is animated. - * This means if the sidebar is of type {@code AnimatedSidebar} - * ano not just {@code SimpleSidebar} for example. - * - * @param identifier The identifier of the sidebar you want to check. - * @return {@code true} if the sidebar is of type {@code AnimatedSidebar}. - * @see AnimatedSidebar - */ - private boolean isAnimated(String identifier) { - checkAvailability(identifier); - Method method = this.methods.get(identifier); - return method.getReturnType() == AnimatedSidebar.class; - } + private String incrementAnimationState(UUID uuid) { + List states = animations.get(uuid).states(); + int current = animationStates.get(uuid); + int max = states.size(); - /** - * Checks if the requested identifier exits in the cache. - * If this is false an error message is sent to the log. - * - * @param identifier The identifier you want to check. - */ - private void checkAvailability(String identifier) { - if (identifierAvailable(identifier)) { - kelpLogger.log(LogLevel.ERROR, "Cannot access sidebar: " + - " Sidebar with identifier " + identifier + " does not exist."); + current += 1; + if (current == max) { + current = 0; } - } - /** - * @param identifier The identifier you want to check. - * @return {@code true} if the identifier is not in use already. - */ - private boolean identifierAvailable(String identifier) { - return !methods.containsKey(identifier); + animationStates.put(uuid, current); + return states.get(current); } - /** - * @param identifier The identifier of the sidebar you want to check. - * @return {@code true} if the sidebar should be handled asynchronously. - */ - private boolean isAsync(String identifier) { - return this.asyncMode.get(identifier); + private void stopCluster(String clusterId) { + if (this.clusterTasks.get(clusterId) == null) { + return; + } + schedulerRepository.interruptScheduler(clusterTasks.get(clusterId)); + clusterTasks.remove(clusterId); + clusters.remove(clusterId); } - public String getDefaultScoreboard() { - return defaultScoreboard; - } } From 9f4d18f48f853c3ccde139a335cd89beda6d0fe4 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:54:23 +0100 Subject: [PATCH 15/68] Add new SidebarRepo to main class and properly stop schedulers --- core/src/main/java/de/pxav/kelp/core/KelpPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java index 09728f9e..5f94a1fe 100644 --- a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java +++ b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java @@ -131,6 +131,7 @@ public void onDisable() { injector.getInstance(KelpNpcRepository.class).stopScheduler(); //injector.getInstance(SidebarRepository.class).interruptAnimations(); + injector.getInstance(SidebarRepository.class).stopAllClusters(); injector.getInstance(ParticleEffectRepository.class).stopAllTimers(); injector.getInstance(KelpSchedulerRepository.class).interruptAll(); From d87f3237e9dac213e50177f0473517ba5aa05123 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:54:53 +0100 Subject: [PATCH 16/68] Update SidebarFactory with new sidebar models --- .../pxav/kelp/core/sidebar/type/SidebarFactory.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java old mode 100644 new mode 100755 index c1e69831..0f6ac344 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java @@ -4,6 +4,7 @@ import com.google.inject.Singleton; import de.pxav.kelp.core.sidebar.component.SidebarComponentFactory; import de.pxav.kelp.core.logger.KelpLogger; +import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; import org.bukkit.plugin.java.JavaPlugin; @@ -26,24 +27,27 @@ public class SidebarFactory { private JavaPlugin javaPlugin; private SidebarVersionTemplate sidebarVersionTemplate; private SidebarComponentFactory sidebarComponentFactory; + private SidebarUpdaterVersionTemplate updaterVersionTemplate; @Inject public SidebarFactory(KelpLogger logger, JavaPlugin javaPlugin, SidebarVersionTemplate sidebarVersionTemplate, - SidebarComponentFactory sidebarComponentFactory) { + SidebarComponentFactory sidebarComponentFactory, + SidebarUpdaterVersionTemplate updaterVersionTemplate) { this.logger = logger; this.javaPlugin = javaPlugin; this.sidebarVersionTemplate = sidebarVersionTemplate; this.sidebarComponentFactory = sidebarComponentFactory; + this.updaterVersionTemplate = updaterVersionTemplate; } public SimpleSidebar newSimpleSidebar() { - return new SimpleSidebar(logger, javaPlugin, sidebarVersionTemplate, sidebarComponentFactory); + return new SimpleSidebar(sidebarVersionTemplate, updaterVersionTemplate); } - public AnimatedSidebar newAnimatedSidebar() { - return new AnimatedSidebar(sidebarVersionTemplate); + public AnimatedSidebarOld newAnimatedSidebar() { + return new AnimatedSidebarOld(sidebarVersionTemplate); } } From 5e47c246b93cfb2b630d7f292073b40b5c47ef92 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:55:38 +0100 Subject: [PATCH 17/68] Remove old SimpleSidebarComponent.java --- .../component/SimpleSidebarComponent.java | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleSidebarComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleSidebarComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleSidebarComponent.java deleted file mode 100644 index 1582f425..00000000 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleSidebarComponent.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.pxav.kelp.core.sidebar.component; - -import org.bukkit.scoreboard.Scoreboard; - -/** - * This interface is the template for all sidebar - * components. It provides methods to render and update - * the component. - * - * @author pxav - */ -public interface SimpleSidebarComponent { - - /** - * This method creates and renders the component - * to the given scoreboard. - * So it will create a new team and set the content. - * - * @param parent The scoreboard you want to render the component on. - */ - void render(Scoreboard parent); - - /** - * Updates the component, which means that no - * new team will be created, but the existing one - * will be updated to avoid flickering. - * - * @param parent The scoreboard on which the component should be rendered. - */ - void update(Scoreboard parent); - -} From 82b77985f693792207341a31dd7f8c97579c32ae Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 09:56:19 +0100 Subject: [PATCH 18/68] Add new abstract sidebar component class --- .../core/sidebar/component/SidebarComponent.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java new file mode 100755 index 00000000..86aa0e19 --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java @@ -0,0 +1,16 @@ +package de.pxav.kelp.core.sidebar.component; + +import java.util.Map; + +/** + * A class description goes here. + * + * @author pxav + */ +public abstract class SidebarComponent { + + public abstract Map render(); + + public abstract Map update(); + +} From aae422fc82052aa51ad4fe4f61555667311acf25 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 14:30:28 +0100 Subject: [PATCH 19/68] Adopt SimpleTextComponent to new component system --- .../component/StatelessTextComponent.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java new file mode 100755 index 00000000..c990ba86 --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java @@ -0,0 +1,61 @@ +package de.pxav.kelp.core.sidebar.component; + +import com.google.common.collect.Maps; +import de.pxav.kelp.core.KelpPlugin; +import de.pxav.kelp.core.sidebar.SidebarUtils; + +import java.util.Map; + +/** + * A class description goes here. + * + * @author pxav + */ +public class StatelessTextComponent extends SidebarComponent { + + private String text = "SimpleTextComponent"; + private int line; + + private SidebarUtils sidebarUtils; + + public StatelessTextComponent(SidebarUtils sidebarUtils) { + this.sidebarUtils = sidebarUtils; + } + + public static StatelessTextComponent create() { + return new StatelessTextComponent(KelpPlugin.getInjector().getInstance(SidebarUtils.class)); + } + + public StatelessTextComponent text(String text) { + this.text = text; + return this; + } + + public StatelessTextComponent line(int line) { + this.line = line; + return this; + } + + @Override + public Map render() { + Map output = Maps.newHashMap(); + output.put(this.line, this.text); +// String entry = sidebarUtils.randomEmptyEntry(parent); +// Objective objective = parent.getObjective(DisplaySlot.SIDEBAR); +// +// objective.getScore(entry).setScore(line); +// +// Team team = parent.registerNewTeam("entry_" + line); +// team.addEntry(entry); +// update(parent); +// return update(); + return output; + } + + @Override + public Map update() { + return null; + //return Collections.singletonList(text); + } + +} From 5566531f39e9051998db7b7506c54693d684e6d9 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 14:30:59 +0100 Subject: [PATCH 20/68] Add StatefulTextComponent to handle dynamic texts in sidebars --- .../component/StatefulTextComponent.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java new file mode 100755 index 00000000..5b5cea5e --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java @@ -0,0 +1,43 @@ +package de.pxav.kelp.core.sidebar.component; + +import com.google.common.collect.Maps; +import de.pxav.kelp.core.scheduler.synchronize.Retrievable; + +import java.util.Map; + +/** + * A class description goes here. + * + * @author pxav + */ +public class StatefulTextComponent extends SidebarComponent { + + private int line; + private Retrievable text; + + public static StatefulTextComponent create() { + return new StatefulTextComponent(); + } + + public StatefulTextComponent line(int line) { + this.line = line; + return this; + } + + public StatefulTextComponent text(Retrievable retrievableText) { + this.text = retrievableText; + return this; + } + + @Override + public Map render() { + Map output = Maps.newHashMap(); + output.put(line, String.valueOf(text.retrieve())); + return output; + } + + @Override + public Map update() { + return null; + } +} From 1aafd7ae7755ca55ed1f4cc3885c84b9c09c9542 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 14:31:24 +0100 Subject: [PATCH 21/68] Add component handling changing lists in a sidebar --- .../component/StatefulListComponent.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java new file mode 100644 index 00000000..b6a47b34 --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java @@ -0,0 +1,95 @@ +package de.pxav.kelp.core.sidebar.component; + +import com.google.common.collect.Maps; +import de.pxav.kelp.core.scheduler.synchronize.Retrievable; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +public class StatefulListComponent extends SidebarComponent { + + private Supplier> list; + private int startLine; + private int maxLine; + private boolean enableLimiter; + private boolean ascendingOrder; + + public StatefulListComponent() { + this.startLine = 0; + this.maxLine = 0; + this.enableLimiter = false; + this.ascendingOrder = false; + } + + public static StatefulListComponent create() { + return new StatefulListComponent(); + } + + public StatefulListComponent list(Supplier> listSupplier) { + this.list = listSupplier; + return this; + } + + public StatefulListComponent startFrom(int startLine) { + this.startLine = startLine; + return this; + } + + public StatefulListComponent limitTo(int maxLine) { + this.maxLine = maxLine; + this.enableLimiter = true; + return this; + } + + public StatefulListComponent disableLimiter() { + this.enableLimiter = false; + return this; + } + + public StatefulListComponent ascendingOrder() { + this.ascendingOrder = true; + return this; + } + + public StatefulListComponent descendingOrder() { + this.ascendingOrder = false; + return this; + } + + @Override + public Map render() { + Map output = Maps.newHashMap(); + List lines = list.get(); + + if (lines == null || lines.isEmpty()) { + return output; + } + + Iterator iterator = lines.iterator(); + if (ascendingOrder) { + for (int i = startLine; i < Integer.MAX_VALUE; i++) { + if (!iterator.hasNext() || (enableLimiter && i == maxLine)) { + return output; + } + output.put(i, iterator.next()); + } + } else { + for (int i = startLine; i < Integer.MAX_VALUE; i--) { + if (!iterator.hasNext() || (enableLimiter && i == maxLine)) { + return output; + } + output.put(i, iterator.next()); + } + } + + return output; + } + + @Override + public Map update() { + return null; + } + +} From b13bfa832d40df2d787641b08b1e9bda992d9e1a Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 14:34:42 +0100 Subject: [PATCH 22/68] Remove #update() method from sidebar component template --- .../de/pxav/kelp/core/sidebar/component/SidebarComponent.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java index 86aa0e19..c357c2ed 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java @@ -11,6 +11,4 @@ public abstract class SidebarComponent { public abstract Map render(); - public abstract Map update(); - } From 6a132e5d1e44d5961eefbf5b8ee2c85840219796 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 14:36:12 +0100 Subject: [PATCH 23/68] Remove #update() method from component implementations --- .../sidebar/component/StatefulListComponent.java | 5 ----- .../sidebar/component/StatefulTextComponent.java | 4 ---- .../sidebar/component/StatelessTextComponent.java | 15 --------------- 3 files changed, 24 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java index b6a47b34..2b846bb0 100644 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java @@ -87,9 +87,4 @@ public Map render() { return output; } - @Override - public Map update() { - return null; - } - } diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java index 5b5cea5e..99622549 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java @@ -36,8 +36,4 @@ public Map render() { return output; } - @Override - public Map update() { - return null; - } } diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java index c990ba86..9ba42d23 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java @@ -40,22 +40,7 @@ public StatelessTextComponent line(int line) { public Map render() { Map output = Maps.newHashMap(); output.put(this.line, this.text); -// String entry = sidebarUtils.randomEmptyEntry(parent); -// Objective objective = parent.getObjective(DisplaySlot.SIDEBAR); -// -// objective.getScore(entry).setScore(line); -// -// Team team = parent.registerNewTeam("entry_" + line); -// team.addEntry(entry); -// update(parent); -// return update(); return output; } - @Override - public Map update() { - return null; - //return Collections.singletonList(text); - } - } From d7b17095d39aadda67e02a759d1446343502afb4 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 14:36:26 +0100 Subject: [PATCH 24/68] Remove old SimpleTextComponent --- .../component/SimpleTextComponent.java | 79 ------------------- 1 file changed, 79 deletions(-) delete mode 100644 core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleTextComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleTextComponent.java deleted file mode 100644 index a814d66c..00000000 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SimpleTextComponent.java +++ /dev/null @@ -1,79 +0,0 @@ -package de.pxav.kelp.core.sidebar.component; - -import de.pxav.kelp.core.sidebar.SidebarUtils; -import de.pxav.kelp.core.logger.KelpLogger; -import de.pxav.kelp.core.logger.LogLevel; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; - -/** - * This scoreboard component is used to display - * custom text on your sidebar. - * - * @author pxav - */ -public class SimpleTextComponent implements SimpleSidebarComponent { - - private String text; - private int line; - - private SidebarUtils sidebarUtils; - private KelpLogger logger; - - public SimpleTextComponent(SidebarUtils sidebarUtils, KelpLogger logger) { - this.sidebarUtils = sidebarUtils; - this.logger = logger; - } - - public SimpleTextComponent text(String text) { - this.text = text; - return this; - } - - public SimpleTextComponent line(int line) { - this.line = line; - return this; - } - - /** - * This method creates and renders the component - * to the given scoreboard. - * So it will create a new team and set the content. - * - * @param parent The scoreboard you want to render the component on. - */ - @Override - public void render(Scoreboard parent) { - String entry = sidebarUtils.randomEmptyEntry(parent); - Objective objective = parent.getObjective(DisplaySlot.SIDEBAR); - - objective.getScore(entry).setScore(line); - - Team team = parent.registerNewTeam("entry_" + line); - team.addEntry(entry); - update(parent); - } - - /** - * Updates the component, which means that no - * new team will be created, but the existing one - * will be updated to avoid flickering. - * - * @param parent The scoreboard on which the component should be rendered. - */ - @Override - public void update(Scoreboard parent) { - String teamName = "entry_" + line; - Team team = parent.getTeam(teamName); - - if (team == null) { - logger.log(LogLevel.ERROR, "Cannot update component at score " + line + ", " - + "because there is no entry assigned to this score."); - return; - } - sidebarUtils.setTeamData(text, team); - } - -} From c69ec235adb0f5264e74b8b70105b53553c73421 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 15:00:05 +0100 Subject: [PATCH 25/68] Adopt EmptyLineComponent to new component design --- .../sidebar/component/EmptyLineComponent.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java old mode 100644 new mode 100755 index 41a34e09..8a071e94 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java @@ -1,11 +1,15 @@ package de.pxav.kelp.core.sidebar.component; +import com.google.common.collect.Maps; +import de.pxav.kelp.core.KelpPlugin; import de.pxav.kelp.core.sidebar.SidebarUtils; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; +import java.util.Map; + /** * This sidebar component can be used to generate empty lines. * You could also write them manually as a {@code SimpleTextComponent}, @@ -22,34 +26,24 @@ * * @author pxav */ -public class EmptyLineComponent implements SimpleSidebarComponent { +public class EmptyLineComponent extends SidebarComponent { private int line; - private SidebarUtils sidebarUtils; - - public EmptyLineComponent(SidebarUtils sidebarUtils) { - this.sidebarUtils = sidebarUtils; + public static EmptyLineComponent create() { + return new EmptyLineComponent(); } - public EmptyLineComponent score(int line) { + public EmptyLineComponent line(int line) { this.line = line; return this; } @Override - public void render(Scoreboard parent) { - String entry = sidebarUtils.randomEmptyEntry(parent); - Objective objective = parent.getObjective(DisplaySlot.SIDEBAR); - - objective.getScore(entry).setScore(line); - - Team team = parent.registerNewTeam("entry_" + line); - team.addEntry(entry); - sidebarUtils.setTeamData(sidebarUtils.randomEmptyEntry(parent), team); + public Map render() { + Map output = Maps.newHashMap(); + output.put(line, " "); + return output; } - @Override - public void update(Scoreboard parent) {} - } From 91673f03cc84f882278550930ccdf363d3b0512a Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 15:00:17 +0100 Subject: [PATCH 26/68] Adopt LineSeparatorComponent to new component design --- .../component/LineSeparatorComponent.java | 60 ++++++------------- 1 file changed, 17 insertions(+), 43 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java old mode 100644 new mode 100755 index 45084bc8..18b0ba48 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java @@ -1,5 +1,6 @@ package de.pxav.kelp.core.sidebar.component; +import com.google.common.collect.Maps; import de.pxav.kelp.core.sidebar.SidebarUtils; import org.bukkit.ChatColor; import org.bukkit.scoreboard.DisplaySlot; @@ -7,6 +8,8 @@ import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; +import java.util.Map; + /** * This scoreboard component is used to easily create line separators. * With these you can simply create separators between paragraphs of your @@ -22,24 +25,24 @@ * * @author pxav */ -public class LineSeparatorComponent implements SimpleSidebarComponent { +public class LineSeparatorComponent extends SidebarComponent { private int line; private int length; private char symbol; private ChatColor[] colors; - private SidebarUtils sidebarUtils; - - LineSeparatorComponent(SidebarUtils sidebarUtils) { - this.sidebarUtils = sidebarUtils; - + public LineSeparatorComponent() { this.length = SeparatorLength.FULL; this.symbol = '-'; this.colors = new ChatColor[] {ChatColor.DARK_GRAY, ChatColor.STRIKETHROUGH}; } - public LineSeparatorComponent score(int line) { + public static LineSeparatorComponent create() { + return new LineSeparatorComponent(); + } + + public LineSeparatorComponent line(int line) { this.line = line; return this; } @@ -60,49 +63,20 @@ public LineSeparatorComponent length(int length) { } @Override - public void render(Scoreboard parent) { - String entry = sidebarUtils.randomEmptyEntry(parent); - Objective objective = parent.getObjective(DisplaySlot.SIDEBAR); - - objective.getScore(entry).setScore(line); - - Team team = parent.registerNewTeam("entry_" + line); - team.addEntry(entry); - update(parent); - } - - @Override - public void update(Scoreboard parent) { - Team team = parent.getTeam("entry_" + line); - StringBuilder prefix = new StringBuilder(); - StringBuilder suffix = new StringBuilder(); - int totalLength = this.length + colors.length; + public Map render() { + Map output = Maps.newHashMap(); + StringBuilder builder = new StringBuilder(); for (ChatColor color : colors) { - prefix.append(color); - if (totalLength > 16) { - suffix.append(color); - } + builder.append(color); } for (int i = 0; i < length; i++) { - prefix.append(symbol); - if (totalLength > 16) { - suffix.append(symbol); - } - } - - if (prefix.toString().length() > 16) { - if (suffix.toString().length() > 16) { - team.setSuffix(suffix.toString().substring(0, 16)); - } else { - team.setSuffix(suffix.toString()); - } - team.setPrefix(prefix.toString().substring(0, 16)); - return; + builder.append(symbol); } - team.setPrefix(prefix.toString()); + output.put(line, builder.toString()); + return output; } public static class SeparatorLength { From 81520cf21f57c945064ebe008ed8879e7ead3972 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 15:07:06 +0100 Subject: [PATCH 27/68] StatefulTextComponent is now using Supplier instead of Retrievable --- .../sidebar/component/StatefulTextComponent.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java index 99622549..cdf0cf2c 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java @@ -1,9 +1,9 @@ package de.pxav.kelp.core.sidebar.component; import com.google.common.collect.Maps; -import de.pxav.kelp.core.scheduler.synchronize.Retrievable; import java.util.Map; +import java.util.function.Supplier; /** * A class description goes here. @@ -13,7 +13,11 @@ public class StatefulTextComponent extends SidebarComponent { private int line; - private Retrievable text; + private Supplier text; + + public StatefulTextComponent() { + text = () -> "StatefulTextComponent"; + } public static StatefulTextComponent create() { return new StatefulTextComponent(); @@ -24,15 +28,15 @@ public StatefulTextComponent line(int line) { return this; } - public StatefulTextComponent text(Retrievable retrievableText) { - this.text = retrievableText; + public StatefulTextComponent text(Supplier text) { + this.text = text; return this; } @Override public Map render() { Map output = Maps.newHashMap(); - output.put(line, String.valueOf(text.retrieve())); + output.put(line, String.valueOf(text.get())); return output; } From 4e5641a978e21843f4242136e8510188a1cc1648 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 15:51:46 +0100 Subject: [PATCH 28/68] Add autoFill feature to StatefulListComponent so that you can use it with lazyUpdate as well --- .../component/StatefulListComponent.java | 57 ++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java index 2b846bb0..3cc0e332 100644 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java @@ -1,7 +1,7 @@ package de.pxav.kelp.core.sidebar.component; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import de.pxav.kelp.core.scheduler.synchronize.Retrievable; import java.util.Iterator; import java.util.List; @@ -15,8 +15,10 @@ public class StatefulListComponent extends SidebarComponent { private int maxLine; private boolean enableLimiter; private boolean ascendingOrder; + private boolean autoFill; public StatefulListComponent() { + this.list = Lists::newArrayList; this.startLine = 0; this.maxLine = 0; this.enableLimiter = false; @@ -43,6 +45,16 @@ public StatefulListComponent limitTo(int maxLine) { return this; } + public StatefulListComponent enableAutoFill() { + this.autoFill = true; + return this; + } + + public StatefulListComponent disableAutoFill() { + this.autoFill = false; + return this; + } + public StatefulListComponent disableLimiter() { this.enableLimiter = false; return this; @@ -63,28 +75,59 @@ public Map render() { Map output = Maps.newHashMap(); List lines = list.get(); - if (lines == null || lines.isEmpty()) { - return output; - } - Iterator iterator = lines.iterator(); if (ascendingOrder) { for (int i = startLine; i < Integer.MAX_VALUE; i++) { - if (!iterator.hasNext() || (enableLimiter && i == maxLine)) { + if (!iterator.hasNext()) { + if (enableLimiter && autoFill && i <= maxLine) { + for (int fillIndex = i; fillIndex <= maxLine; fillIndex++) { + output.put(fillIndex, " "); + } + return output; + } + return output; + } + if (enableLimiter && i == maxLine) { return output; } output.put(i, iterator.next()); } } else { for (int i = startLine; i < Integer.MAX_VALUE; i--) { - if (!iterator.hasNext() || (enableLimiter && i == maxLine)) { + if (!iterator.hasNext()) { + if (enableLimiter && autoFill && i >= maxLine) { + for (int fillIndex = i; fillIndex >= maxLine; fillIndex--) { + output.put(fillIndex, " "); + } + return output; + } + return output; + } + if (enableLimiter && i == maxLine) { return output; } output.put(i, iterator.next()); } } + if (output.isEmpty() && enableLimiter && autoFill) { + if (ascendingOrder) { + for (int fillIndex = startLine; fillIndex <= maxLine; fillIndex++) { + output.put(fillIndex, " "); + } + } else { + for (int fillIndex = startLine; fillIndex >= maxLine; fillIndex--) { + output.put(fillIndex, " "); + } + } + + } + return output; } + private void fill() { + + } + } From 5c14f092948033cbb32d7cea34747a6df8f57e8e Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 16:05:47 +0100 Subject: [PATCH 29/68] Remove @CreateSidebar annotation as it is not needed in the new design anymore --- .../pxav/kelp/core/sidebar/CreateSidebar.java | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 core/src/main/java/de/pxav/kelp/core/sidebar/CreateSidebar.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/CreateSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/CreateSidebar.java deleted file mode 100644 index a9a4f9cb..00000000 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/CreateSidebar.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.pxav.kelp.core.sidebar; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This annotation is used to mark methods - * which provide a sidebar that can be used - * and opened. - * - * @author pxav - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface CreateSidebar { - - /** - * Each sidebar must have a unique identifier. - * This identifier is used to for example - * open the sidebar, etc. - * - * @return The unique identifier string. - */ - String identifier(); - - int switchInterval() default 100; - - /** - * If your sidebar title is animated - * you should specify an interval in which - * the sidebar title should be updated. - * The default value is 1000 milliseconds. - * - * @return The interval in milliseconds. - */ - int titleAnimationInterval() default 1000; - - /** - * Should your sidebar be handled asynchronously? - * This only applies for general updates, the title updates - * (if your sidebar is animated) are always asynchronous. - * - * @return {@code true} if sidebar updates should happen async. - */ - boolean async() default true; - - /** - * This attribute describes whether the scoreboard - * should be displayed automatically when a player - * joins the server. - * @return {@code true} if it should be the default scoreboard. - */ - boolean setOnJoin() default false; - -} From 13df86ff9ca80fae78f6ac6260acca2802c0938f Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 16:21:29 +0100 Subject: [PATCH 30/68] Updating sidebar titles can now also be done without clusters --- .../kelp/core/sidebar/SidebarRepository.java | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java index c1e8f670..7b80e468 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java @@ -31,6 +31,7 @@ public class SidebarRepository { private ConcurrentHashMap animationStates; private ConcurrentHashMap> clusters; private ConcurrentHashMap clusterTasks; + private ConcurrentHashMap playerTasks; private ConcurrentHashMap animations; private KelpSchedulerRepository schedulerRepository; @@ -46,6 +47,7 @@ public SidebarRepository(KelpSchedulerRepository schedulerRepository, this.animationStates = new ConcurrentHashMap<>(); this.clusters = new ConcurrentHashMap<>(); this.clusterTasks = new ConcurrentHashMap<>(); + this.playerTasks = new ConcurrentHashMap<>(); this.animations = new ConcurrentHashMap<>(); this.schedulerFactory = schedulerFactory; this.schedulerRepository = schedulerRepository; @@ -58,28 +60,47 @@ public void addAnimatedSidebar(AnimatedSidebar sidebar, KelpPlayer player) { animationStates.put(player.getUUID(), 0); animations.put(player.getUUID(), sidebar.getTitle()); + // add player to cluster or create a new cluster if needed if (sidebar.getClusterId() != null) { if (!clusters.containsKey(sidebar.getClusterId())) { this.addCluster(sidebar.getClusterId(), sidebar.getTitleAnimationInterval()); } this.addPlayerToCluster(sidebar.getClusterId(), player); + } else { + // if the sidebar does not have clusters, an individual scheduler + // has to be set up + UUID task = schedulerFactory.newRepeatingScheduler() + .async() + .every(sidebar.getTitleAnimationInterval()) + .milliseconds() + .run(taskId -> { + String updateTo = incrementAnimationState(player.getUUID()); + updaterVersionTemplate.updateTitleOnly(updateTo, player); + }); + playerTasks.put(player.getUUID(), task); } } public void removeAnimatedSidebar(KelpPlayer player) { - Maps.newHashMap(this.clusters).forEach((clusterId, playerSet) - -> playerSet.stream() - .filter(uuid -> player.getUUID() == uuid) - .findFirst() - .ifPresent(uuid -> { - playerSet.remove(uuid); - if (playerSet.isEmpty()) { - stopCluster(clusterId); - return; - } - clusters.put(clusterId, playerSet); - })); + if (playerTasks.containsKey(player.getUUID())) { + UUID task = playerTasks.get(player.getUUID()); + schedulerRepository.interruptScheduler(task); + this.playerTasks.remove(player.getUUID()); + } else { + Maps.newHashMap(this.clusters).forEach((clusterId, playerSet) + -> playerSet.stream() + .filter(uuid -> player.getUUID() == uuid) + .findFirst() + .ifPresent(uuid -> { + playerSet.remove(uuid); + if (playerSet.isEmpty()) { + stopCluster(clusterId); + return; + } + clusters.put(clusterId, playerSet); + })); + } this.animationStates.remove(player.getUUID()); this.animations.remove(player.getUUID()); } From 103db618cb74e7d6abab5759e3b0d293755c97c1 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 16:28:49 +0100 Subject: [PATCH 31/68] Text animations can now be produced using static factories --- .../de/pxav/kelp/core/animation/BuildingTextAnimation.java | 7 +++++++ .../de/pxav/kelp/core/animation/CustomTextAnimation.java | 4 ++++ .../de/pxav/kelp/core/animation/FloatingTextAnimation.java | 5 +++-- .../de/pxav/kelp/core/animation/StaticTextAnimation.java | 5 ++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/animation/BuildingTextAnimation.java b/core/src/main/java/de/pxav/kelp/core/animation/BuildingTextAnimation.java index ea3a2643..83981c9f 100644 --- a/core/src/main/java/de/pxav/kelp/core/animation/BuildingTextAnimation.java +++ b/core/src/main/java/de/pxav/kelp/core/animation/BuildingTextAnimation.java @@ -1,5 +1,6 @@ package de.pxav.kelp.core.animation; +import de.pxav.kelp.core.KelpPlugin; import de.pxav.kelp.core.common.StringUtils; import java.util.ArrayList; @@ -32,6 +33,12 @@ public BuildingTextAnimation(StringUtils stringUtils) { this.stringUtils = stringUtils; } + public static BuildingTextAnimation create() { + return new BuildingTextAnimation( + KelpPlugin.getInjector().getInstance(StringUtils.class) + ); + } + public BuildingTextAnimation text(String text) { this.text = text; return this; diff --git a/core/src/main/java/de/pxav/kelp/core/animation/CustomTextAnimation.java b/core/src/main/java/de/pxav/kelp/core/animation/CustomTextAnimation.java index 74d48447..34f50dc7 100644 --- a/core/src/main/java/de/pxav/kelp/core/animation/CustomTextAnimation.java +++ b/core/src/main/java/de/pxav/kelp/core/animation/CustomTextAnimation.java @@ -23,6 +23,10 @@ public class CustomTextAnimation implements TextAnimation { public CustomTextAnimation() {} + public static CustomTextAnimation create() { + return new CustomTextAnimation(); + } + public CustomTextAnimation addStates(String... states) { this.states.addAll(Arrays.asList(states)); return this; diff --git a/core/src/main/java/de/pxav/kelp/core/animation/FloatingTextAnimation.java b/core/src/main/java/de/pxav/kelp/core/animation/FloatingTextAnimation.java index 139aaa90..81504a98 100644 --- a/core/src/main/java/de/pxav/kelp/core/animation/FloatingTextAnimation.java +++ b/core/src/main/java/de/pxav/kelp/core/animation/FloatingTextAnimation.java @@ -16,8 +16,10 @@ public class FloatingTextAnimation implements TextAnimation { private boolean slideIn; private SlideDirection slideDirection; - public FloatingTextAnimation() { + public FloatingTextAnimation() {} + public static FloatingTextAnimation create() { + return new FloatingTextAnimation(); } public FloatingTextAnimation text(String text) { @@ -74,7 +76,6 @@ private List slideAnimation(SlideDirection slideDirection) { @Override public List states() { - return Lists.newArrayList(); } diff --git a/core/src/main/java/de/pxav/kelp/core/animation/StaticTextAnimation.java b/core/src/main/java/de/pxav/kelp/core/animation/StaticTextAnimation.java index 9adb0ff3..34e9325b 100644 --- a/core/src/main/java/de/pxav/kelp/core/animation/StaticTextAnimation.java +++ b/core/src/main/java/de/pxav/kelp/core/animation/StaticTextAnimation.java @@ -1,6 +1,5 @@ package de.pxav.kelp.core.animation; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -19,6 +18,10 @@ public final class StaticTextAnimation implements TextAnimation { StaticTextAnimation() {} + public static StaticTextAnimation create() { + return new StaticTextAnimation(); + } + public StaticTextAnimation text(String text) { this.text = text; return this; From 7e79271c390e167171bce1ccf83e12a36661421a Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 17:10:02 +0100 Subject: [PATCH 32/68] Completely remove all sidebar repo related methods from KelpPlayer --- .../de/pxav/kelp/core/player/KelpPlayer.java | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index 19165959..81f6672c 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -82,7 +82,6 @@ public class KelpPlayer extends LivingKelpEntity { public KelpPlayer(Player bukkitPlayer, PlayerVersionTemplate playerVersionTemplate, - //SidebarRepository sidebarRepository, KelpInventoryRepository inventoryRepository, KelpPlayerRepository kelpPlayerRepository, ParticleVersionTemplate particleVersionTemplate, @@ -103,7 +102,6 @@ public KelpPlayer(Player bukkitPlayer, bukkitPlayer); this.bukkitPlayer = bukkitPlayer; this.playerVersionTemplate = playerVersionTemplate; - //this.sidebarRepository = sidebarRepository; this.inventoryRepository = inventoryRepository; this.particleVersionTemplate = particleVersionTemplate; this.signPromptVersionTemplate = signPromptVersionTemplate; @@ -123,31 +121,6 @@ public SimpleChatPrompt openSimpleChatPrompt() { return new SimpleChatPrompt(this.getBukkitPlayer(), this.chatPromptVersionTemplate); } - /** - * Opens a kelp sidebar with the given identifier. This method - * only applies to sidebars created using an annotation. - * - * @param identifier The identifier of the sidebar you want to show - * to the player - * @return the current instance of the player. - */ - public KelpPlayer openKelpSidebar(String identifier) { -// this.sidebarRepository.openSidebar(identifier, bukkitPlayer); -// return this; - return this; - } - - /** - * Makes the current sidebar of the player disappear. - * - * @return the current instance of the player. - */ - public KelpPlayer removeKelpSidebar() { -// this.sidebarRepository.removeSidebar(bukkitPlayer); -// return this; - return this; - } - public boolean hasScoreboard() { Scoreboard scoreboard = bukkitPlayer.getScoreboard(); return scoreboard.getObjective(DisplaySlot.SIDEBAR) != null @@ -155,10 +128,6 @@ public boolean hasScoreboard() { || scoreboard.getObjective(DisplaySlot.PLAYER_LIST) != null; } - public boolean hasSidebar() { - return false; //todo implement - } - /** * Opens a {@link KelpInventory} to the player. This * is equivalent to calling the {@link KelpInventoryRepository#openInventory(KelpInventory, KelpPlayer)} From 1a28eb29140227af27c2cd5e5d7e0c87e2f0fc2c Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 17:15:32 +0100 Subject: [PATCH 33/68] Add documentation for #hasScoreboard in KelpPlayer --- core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index 81f6672c..d6fe0148 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -121,6 +121,12 @@ public SimpleChatPrompt openSimpleChatPrompt() { return new SimpleChatPrompt(this.getBukkitPlayer(), this.chatPromptVersionTemplate); } + /** + * Checks if the player has any scoreboard with content stored in any + * objective type ({@code SIDEBAR, PLAYER_LIST}, etc.) + * + * @return {@code true} if the player has a scoreboard with an objective. + */ public boolean hasScoreboard() { Scoreboard scoreboard = bukkitPlayer.getScoreboard(); return scoreboard.getObjective(DisplaySlot.SIDEBAR) != null From 13ea66d74ed32f0628efafc108ac41faaacfff98 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 17:16:07 +0100 Subject: [PATCH 34/68] Add method to clear a player's chat --- .../src/main/java/de/pxav/kelp/core/player/KelpPlayer.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index d6fe0148..77a98d67 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -332,6 +332,13 @@ public KelpPlayer chat(String message) { return this; } + public KelpPlayer clearChat() { + for (int i = 0; i < 103; i++) { + sendMessage(" "); + } + return this; + } + public boolean mayFly() { return playerVersionTemplate.getAllowFlight(bukkitPlayer); } From 6f577d92f7c0109a698f00432938a3f5840d2930 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:02:26 +0100 Subject: [PATCH 35/68] Remove unnecessary dependencies from StatelessTextComponent --- .../core/sidebar/component/StatelessTextComponent.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java index 9ba42d23..de9da234 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java @@ -16,14 +16,8 @@ public class StatelessTextComponent extends SidebarComponent { private String text = "SimpleTextComponent"; private int line; - private SidebarUtils sidebarUtils; - - public StatelessTextComponent(SidebarUtils sidebarUtils) { - this.sidebarUtils = sidebarUtils; - } - public static StatelessTextComponent create() { - return new StatelessTextComponent(KelpPlugin.getInjector().getInstance(SidebarUtils.class)); + return new StatelessTextComponent(); } public StatelessTextComponent text(String text) { From 5c2c92e74f0e8a17326dc02b887729123cdf1094 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:08:51 +0100 Subject: [PATCH 36/68] Add documentation to LineSeparatorComponent --- .../component/LineSeparatorComponent.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java index 18b0ba48..a28b0a8e 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java @@ -42,26 +42,67 @@ public static LineSeparatorComponent create() { return new LineSeparatorComponent(); } + /** + * Sets the line number of the component to be placed in the sidebar. + * Please note that this line id represents an absolute position and + * should therefore be unique. No components should have the same line + * number. + * + * @param line The line of the sidebar, where the component should + * be visible. + * @return The current component instance for fluent builder design. + */ public LineSeparatorComponent line(int line) { this.line = line; return this; } + /** + * Sets the symbol to be repeated n times by the component, while + * {@code n} is equal to the length set by {@link #length(int)} + * + * @param symbol The symbol you want to set. + * @return Instance of the current component for more fluent builder design. + */ public LineSeparatorComponent symbol(char symbol) { this.symbol = symbol; return this; } + /** + * The colors in which the line separator symbols should be displayed. + * You can also apply style codes such as {@link ChatColor#STRIKETHROUGH} + * here. + * + * @param colors The colors to be displayed. + * @return Instance of the current component for more fluent builder design. + */ public LineSeparatorComponent color(ChatColor... colors) { this.colors = colors; return this; } + /** + * Sets the amount of times the given symbol should be repeated. + * + * @param length The length of your line separator. + * @return Instance of the current component for more fluent builder design. + */ public LineSeparatorComponent length(int length) { this.length = length; return this; } + /** + * Renders all the information provided in the component + * to a map containing the final information to be rendered + * to the sidebar (the lines where the text should be placed and + * the text to write there). + * + * @return A map, where the key is the absolute line where + * the component should be placed in the sidebar and + * the value is the actual text for that line. + */ @Override public Map render() { Map output = Maps.newHashMap(); @@ -79,6 +120,10 @@ public Map render() { return output; } + /** + * Contains some static values for possible length of + * a line separator. + */ public static class SeparatorLength { public static final int FULL = 30; public static final int HALF = 15; From e6c0b436093e6446cb19060fb1111718febcf0d3 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:10:13 +0100 Subject: [PATCH 37/68] You can now provide multiple chars as symbol in a LineSeparatorComponent --- .../component/LineSeparatorComponent.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java index a28b0a8e..ee285813 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/LineSeparatorComponent.java @@ -29,12 +29,12 @@ public class LineSeparatorComponent extends SidebarComponent { private int line; private int length; - private char symbol; + private String symbol; private ChatColor[] colors; public LineSeparatorComponent() { this.length = SeparatorLength.FULL; - this.symbol = '-'; + this.symbol = "-"; this.colors = new ChatColor[] {ChatColor.DARK_GRAY, ChatColor.STRIKETHROUGH}; } @@ -65,6 +65,18 @@ public LineSeparatorComponent line(int line) { * @return Instance of the current component for more fluent builder design. */ public LineSeparatorComponent symbol(char symbol) { + this.symbol = String.valueOf(symbol); + return this; + } + + /** + * Sets the symbol to be repeated n times by the component, while + * {@code n} is equal to the length set by {@link #length(int)} + * + * @param symbol The symbol you want to set. + * @return Instance of the current component for more fluent builder design. + */ + public LineSeparatorComponent symbol(String symbol) { this.symbol = symbol; return this; } From 8ff70429a9d4fe687d26e9a8ab25d1cbbe0e33d6 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:17:43 +0100 Subject: [PATCH 38/68] Remove unregister teams method from KelpSidebar as it could be version dependent. --- .../java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java index 70607ead..3d9ad7b7 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java @@ -50,13 +50,5 @@ public T setLatestLines(int latestLines) { public abstract void update(KelpPlayer player); public abstract void remove(KelpPlayer player); -// -// protected void unregisterAllTeams() { -// scoreboard.getTeams().forEach(current -> { -// if (current.getName().startsWith("entry_")) { -// current.unregister(); -// } -// }); -// } } From dbd466d8d9f15b8724e731ad77f207cdff60bf6f Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:30:09 +0100 Subject: [PATCH 39/68] Add documentation to KelpSidebar --- .../kelp/core/sidebar/type/KelpSidebar.java | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java index 3d9ad7b7..48410dc1 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java @@ -3,13 +3,17 @@ import com.google.common.collect.Lists; import de.pxav.kelp.core.player.KelpPlayer; import de.pxav.kelp.core.sidebar.component.SidebarComponent; -import org.bukkit.scoreboard.Scoreboard; import java.util.Collection; /** - * A class description goes here. + * This class represents a template for Kelp sidebars. * + * + * @param The type of the current sidebar. This is needed to keep + * up a more fluent builder design as methods such as {@link #addComponent(SidebarComponent)} + * do not return a general sidebar anymore but the specific type of sidebar you are + * currently working with. * @author pxav */ public abstract class KelpSidebar { @@ -17,21 +21,46 @@ public abstract class KelpSidebar { protected Collection components = Lists.newArrayList(); protected int latestLines = 0; + /** + * Adds a new component to the sidebar. When you add it, + * it should already contain all its properties. + * + * @param component The component to be added. + * @return + */ public T addComponent(SidebarComponent component) { this.components.add(component); return (T) this; } + /** + * Removes a specific component from the sidebar permanently. + * It won't be displayed anymore until you add it again or + * display another component instead. + * + * @param component The component to be removed. + * @return + */ public T removeComponent(SidebarComponent component) { this.components.remove(component); return (T) this; } + /** + * Removes all existing components of the sidebar permanently. + * + * @return + */ public T clearComponents() { this.components.clear(); return (T) this; } + /** + * Gets a collection of all components the sidebar is currently holding. + * + * @return A collection containing all components. + */ public Collection getComponents() { return this.components; } @@ -45,10 +74,34 @@ public T setLatestLines(int latestLines) { return (T) this; } + /** + * Renders the sidebar to a specific player. This means it displays + * it for the first time (so only use this method if the player does + * not already see this sidebar to avoid flicker effects or similar behaviour). + * + * @param player The player to render the sidebar to. + */ public abstract void render(KelpPlayer player); + /** + * Updates all components of the sidebar. That means that all existing entries/lines + * are removed and the components are added to an empty scoreboard again. So you + * should only use this method if you know that the amount of lines will change or + * certain components might (dis)appear after an update. If you do a simple update, + * that only updates some text values you might want to use a {@code lazyUpdate} as this + * is safe from any flicker effects unlike this method, which can cause flicker on heavily + * loaded servers. + * + * @param player The player who should see the updated sidebar. + */ public abstract void update(KelpPlayer player); + /** + * Removes the sidebar from the given player, which means that the player + * won't be able to see it anymore. + * + * @param player The player you want to hide the sidebar from. + */ public abstract void remove(KelpPlayer player); } From 6022b124b2adbe5e02eec2bb5935a51135bcbad2 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:31:25 +0100 Subject: [PATCH 40/68] Remove latestLines methods and fields from KelpSidebar --- .../de/pxav/kelp/core/sidebar/type/KelpSidebar.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java index 48410dc1..d87cff55 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/KelpSidebar.java @@ -19,7 +19,6 @@ public abstract class KelpSidebar { protected Collection components = Lists.newArrayList(); - protected int latestLines = 0; /** * Adds a new component to the sidebar. When you add it, @@ -65,15 +64,6 @@ public Collection getComponents() { return this.components; } - public int getLatestLines() { - return latestLines; - } - - public T setLatestLines(int latestLines) { - this.latestLines = latestLines; - return (T) this; - } - /** * Renders the sidebar to a specific player. This means it displays * it for the first time (so only use this method if the player does From b481a9c42a151991c8a9eb0fd69d529469588171 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:37:41 +0100 Subject: [PATCH 41/68] Remove unnecessary dependencies from AnimatedSidebar --- .../kelp/core/sidebar/type/AnimatedSidebar.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java index e9c4ed70..988c14ad 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java @@ -4,15 +4,7 @@ import de.pxav.kelp.core.animation.StaticTextAnimation; import de.pxav.kelp.core.animation.TextAnimation; import de.pxav.kelp.core.player.KelpPlayer; -import de.pxav.kelp.core.sidebar.SidebarUtils; -import de.pxav.kelp.core.sidebar.component.SidebarComponent; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; -import org.bukkit.Bukkit; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.ScoreboardManager; - -import java.util.Collection; /** * A class description goes here. @@ -25,17 +17,14 @@ public class AnimatedSidebar extends KelpSidebar { private int titleAnimationInterval = 200; private String clusterId = null; - private SidebarUtils sidebarUtils; private SidebarVersionTemplate sidebarVersionTemplate; - public AnimatedSidebar(SidebarUtils sidebarUtils, SidebarVersionTemplate sidebarVersionTemplate) { - this.sidebarUtils = sidebarUtils; + public AnimatedSidebar(SidebarVersionTemplate sidebarVersionTemplate) { this.sidebarVersionTemplate = sidebarVersionTemplate; } public static AnimatedSidebar create() { return new AnimatedSidebar( - KelpPlugin.getInjector().getInstance(SidebarUtils.class), KelpPlugin.getInjector().getInstance(SidebarVersionTemplate.class) ); } From 2b41a3ca05e0eba6c6cde98fa3178348a6077b89 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:48:06 +0100 Subject: [PATCH 42/68] Remove unnecessary dependencies and fields from SidebarUtils --- .../main/java/de/pxav/kelp/core/sidebar/SidebarUtils.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/SidebarUtils.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarUtils.java b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarUtils.java old mode 100644 new mode 100755 index cd03c5a1..4257eda8 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarUtils.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarUtils.java @@ -22,12 +22,10 @@ @Singleton public class SidebarUtils { - private KelpLogger logger; private StringUtils stringUtils; @Inject - public SidebarUtils(KelpLogger logger, StringUtils stringUtils) { - this.logger = logger; + public SidebarUtils(StringUtils stringUtils) { this.stringUtils = stringUtils; } @@ -79,7 +77,6 @@ public void setTeamData(String text, Team team) { * @return The final generation result. */ public String randomEmptyEntry(Scoreboard scoreboard) { - int index = ThreadLocalRandom.current().nextInt(1); int colorAmount = ThreadLocalRandom.current().nextInt(3); StringBuilder stringBuilder = new StringBuilder(); Collection forbidden = usedEntries(scoreboard); From cb6a915e4d919ea67c3aed018f916c352aef8614 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 18:49:04 +0100 Subject: [PATCH 43/68] Remove SidebarStateListener.java as there are no default sidebars anymore --- .../core/sidebar/SidebarStateListener.java | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 core/src/main/java/de/pxav/kelp/core/sidebar/SidebarStateListener.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarStateListener.java b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarStateListener.java deleted file mode 100644 index 55c9212e..00000000 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarStateListener.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.pxav.kelp.core.sidebar; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -/** - * This class handles the states of sidebars. - * It gives default sidebars on every player join - * and removes any type of sidebar on every player - * quit. - * - * This avoids useless calculation for the server. - * - * @author pxav - */ -@Singleton -public class SidebarStateListener { - - private SidebarRepository sidebarRepository; - - @Inject - public SidebarStateListener(SidebarRepository sidebarRepository) { - this.sidebarRepository = sidebarRepository; - } - - /** - * This event is triggered when a player joins the server. - * In this case it gives the player the default sidebar, - * if there has been defined one (with 'setOnJoin' to true - * in the {@code @CreateSidebar} annotation). - * - * @param event Instance of the current event. - */ - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - - // if a scoreboard has 'setOnJoin' set to true, it will be shown to the player - if (!sidebarRepository.getDefaultScoreboard().equalsIgnoreCase("NONE")) { - sidebarRepository.openSidebar(sidebarRepository.getDefaultScoreboard(), player); - } - - } - - /** - * This event is triggered when a player quits the server. - * In this case it removes the sidebar for every player so - * that the server does not do useless updates on their - * sidebar. - * - * @param event Instance of the current event. - */ - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - Player player = event.getPlayer(); - sidebarRepository.removeSidebar(player); - } - -} From 714ede66caea91a841484a14e9bbb240ad151dd3 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:27:50 +0100 Subject: [PATCH 44/68] Add documentation for sidebar types --- .../core/sidebar/type/AnimatedSidebar.java | 62 ++++++++++++++++++- .../kelp/core/sidebar/type/SimpleSidebar.java | 55 ++++++++++++---- 2 files changed, 102 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java index 988c14ad..77c3df06 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/AnimatedSidebar.java @@ -1,13 +1,19 @@ package de.pxav.kelp.core.sidebar.type; import de.pxav.kelp.core.KelpPlugin; -import de.pxav.kelp.core.animation.StaticTextAnimation; import de.pxav.kelp.core.animation.TextAnimation; import de.pxav.kelp.core.player.KelpPlayer; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; /** - * A class description goes here. + * This is a specific type of sidebar which enables you + * to animate titles. Those animations can be clustered, which means + * that if you have the same update interval for different sidebars, + * you can cluster them into a group like {@code lobby_scoreboard} for + * example to reduce the total amount of schedulers required. + * + * Apart from that it is the same as {@link SimpleSidebar}, so you can + * also hold normal sidebar components and update them, etc. * * @author pxav */ @@ -29,29 +35,69 @@ public static AnimatedSidebar create() { ); } + /** + * Sets the title animation to be displayed at the top of the sidebar. + * + * @param title The title animation you want to display. + * @return Instance of the current component for more fluent builder design. + */ public AnimatedSidebar title(TextAnimation title) { this.title = title; return this; } + /** + * Sets the interval of the title animation. The given value is the period + * in milliseconds it takes between each update to the next animation state. + * + * @param titleAnimationInterval The update interval in milliseconds. + * @return Instance of the current component for more fluent builder design. + */ public AnimatedSidebar titleAnimationInterval(int titleAnimationInterval) { this.titleAnimationInterval = titleAnimationInterval; return this; } + /** + * Sets the cluster id for the current sidebar. This is an optional + * step, but it is recommended doing that if your sidebar is displayed + * to more than 2 or 3 players. It wraps all player sidebars into a + * single scheduler to save server performance instead of creating an + * individual scheduler for each player. + * + * If the given cluster does not exist, it will be created automatically by Kelp. + * + * @param clusterId The id of the cluster you want to add the sidebar to. + * @return Instance of the current component for more fluent builder design. + */ public AnimatedSidebar clusterId(String clusterId) { this.clusterId = clusterId; return this; } + /** + * Gets the cluster id of the current scoreboard. + * + * @return The current cluster id. {@code null} if no cluster id has been set. + */ public String getClusterId() { return clusterId; } + /** + * Gets the title of the sidebar as a {@link TextAnimation}. + * + * @return The sidebar's title animation. + */ public TextAnimation getTitle() { return title; } + /** + * Gets the interval in which the sidebar's title is updated in milliseconds. + * + * @return The update interval of the sidebar's title. + */ public int getTitleAnimationInterval() { return titleAnimationInterval; } @@ -66,6 +112,18 @@ public void update(KelpPlayer player) { sidebarVersionTemplate.updateSidebar(this, player); } + /** + * Performs a lazy update on the sidebar. A lazy update does not remove all entries/lines + * from a scoreboard first, like it is done by {@link #update(KelpPlayer)}. It only used the + * existing entries in the sidebar, which means that you cannot use it if you know that the amount + * of lines in the sidebar might change with an update. + * + * However this update method is completely free from any flickering effects and it is + * not as performance heavy as a normal update. So if you can, you should prefer this update + * method over a normal update. + * + * @param player The player who should see the updated sidebar. + */ public void lazyUpdate(KelpPlayer player) { sidebarVersionTemplate.lazyUpdate(this, player); } diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java index 1fcd4b52..bc0a2e01 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SimpleSidebar.java @@ -1,22 +1,10 @@ package de.pxav.kelp.core.sidebar.type; -import com.google.common.collect.Lists; import de.pxav.kelp.core.KelpPlugin; -import de.pxav.kelp.core.animation.TextAnimation; import de.pxav.kelp.core.player.KelpPlayer; -import de.pxav.kelp.core.sidebar.SidebarUtils; -import de.pxav.kelp.core.sidebar.component.SidebarComponentFactory; -import de.pxav.kelp.core.sidebar.component.SimpleSidebarComponentOld; import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; -import de.pxav.kelp.core.logger.KelpLogger; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.ScoreboardManager; - -import java.util.Collection; + import java.util.function.Supplier; /** @@ -48,16 +36,39 @@ public static SimpleSidebar create() { ); } + /** + * Sets the title of the sidebar. This method takes a {@link Supplier}, which + * allows you to create dynamic titles that can update every time you call + * {@link #updateTitleOnly(KelpPlayer)}. + * + * If you rather want a static title, choose {@link #staticTitle(String)} + * + * @param title The title do display at the top of the sidebar. + * @return Instance of the current component for more fluent builder design. + */ public SimpleSidebar title(Supplier title) { this.title = title; return this; } + /** + * Sets the title of the sidebar. This method takes a normal {@code String}, which + * means that the title is static and won't change if you call {@link #updateTitleOnly(KelpPlayer)} + * + * If you rather want a dynamic title, choose {@link #title(Supplier)} instead. + * + * @param title The title do display at the top of the sidebar. + * @return Instance of the current component for more fluent builder design. + */ public SimpleSidebar staticTitle(String title) { this.title = () -> title; return this; } + /** + * Gets the {@link Supplier} holding the current title - no matter if static or dynamic. + * @return The current title of the sidebar. + */ public Supplier getTitle() { return title; } @@ -67,6 +78,12 @@ public void render(KelpPlayer player) { sidebarVersionTemplate.renderSidebar(this, player); } + /** + * Updates the title of the sidebar without loading to changing any + * of its components. + * + * @param player The player you want to show the title update to. + */ public void updateTitleOnly(KelpPlayer player) { updaterVersionTemplate.updateTitleOnly(title.get(), player); } @@ -76,6 +93,18 @@ public void update(KelpPlayer player) { sidebarVersionTemplate.updateSidebar(this, player); } + /** + * Performs a lazy update on the sidebar. A lazy update does not remove all entries/lines + * from a scoreboard first, like it is done by {@link #update(KelpPlayer)}. It only used the + * existing entries in the sidebar, which means that you cannot use it if you know that the amount + * of lines in the sidebar might change with an update. + * + * However this update method is completely free from any flickering effects and it is + * not as performance heavy as a normal update. So if you can, you should prefer this update + * method over a normal update. + * + * @param player The player who should see the updated sidebar. + */ public void lazyUpdate(KelpPlayer player) { sidebarVersionTemplate.lazyUpdate(this, player); } From 9fbb453ae607781fd85eccf118786c6f287da75b Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:28:07 +0100 Subject: [PATCH 45/68] Add documentation for StatefulListComponent --- .../component/StatefulListComponent.java | 121 +++++++++++++++++- 1 file changed, 117 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java index 3cc0e332..94300508 100644 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulListComponent.java @@ -8,6 +8,24 @@ import java.util.Map; import java.util.function.Supplier; +/** + * This component is used to automate list displays in sidebars. + * Imagine a JumpLeague plugin for example where a list of top players + * and their progression is displayed in the sidebar. Then it would be + * useful to be able to
+ * - limit your displayed list to a specific size (to avoid having a cluttered + * scoreboard when you have 20+ players in a round)
+ * - display dynamic content (using a {@link Supplier} for example) instead of static text
+ * - keeping the list size constant for a more convenient design (when players quit for example)
+ * + * All this is supported by this component. + * + * By default this component does not support {@code lazyUpdates}, because + * the number of lines set by it may vary. To avoid this use a limiter + * {@link #limitTo(int)} and {@link #enableAutoFill()}. + * + * @author pxav + */ public class StatefulListComponent extends SidebarComponent { private Supplier> list; @@ -18,6 +36,7 @@ public class StatefulListComponent extends SidebarComponent { private boolean autoFill; public StatefulListComponent() { + // set default values this.list = Lists::newArrayList; this.startLine = 0; this.maxLine = 0; @@ -29,56 +48,146 @@ public static StatefulListComponent create() { return new StatefulListComponent(); } + /** + * The list to be displayed in the sidebar. The order of your list + * should be in the order of how they should be finally displayed. + * depending on whether you sort them with {@link #ascendingOrder()} or + * {@link #descendingOrder()}. + * + * @param listSupplier The supplier providing the list to be displayed. + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent list(Supplier> listSupplier) { this.list = listSupplier; return this; } + /** + * Defines the line in the scoreboard where the first list element should + * be placed and from where the list items should be placed. If you selected + * {@link #ascendingOrder()} the number for the next list item will be incremented + * and if you choose {@link #descendingOrder()} the number will be decremented. + * + * Please note that the given line ids are absolute and you should check whether + * no components are in range of your list items, which could cause weird behaviour. + * + * @param startLine The line from where the list should start. + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent startFrom(int startLine) { this.startLine = startLine; return this; } + /** + * Enables the line limiter for the list. So there will be only as many + * list items in the sidebar as you input here. Generally this is recommended + * if you are not completely sure how many list items will be displayed. Then + * you can make sure that those list items do not interfere with any other + * items. + * + * Please make sure that the number is reachable if you set it. If your + * list order is ascending and this number is smaller than your start line, + * this number will have no effect. + * + * @param maxLine The last line where a list item can be displayed. + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent limitTo(int maxLine) { this.maxLine = maxLine; this.enableLimiter = true; return this; } + /** + * Normally, this component is not compatible with {@code lazyUpdating}, because + * the amount of lines covered by it may vary with each update. To avoid this, enable + * the limiter with {@link #limitTo(int)} and enable auto fill by calling this method. + * + * Auto fill makes sure that if the amount of list items is smaller than the given + * maximum, more empty lines are inserted to keep the total line amount constant. + * This allows you to create flicker free sidebars using this component. + * + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent enableAutoFill() { this.autoFill = true; return this; } + /** + * Disables the auto fill feature described in {@link #enableAutoFill()}. + * + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent disableAutoFill() { this.autoFill = false; return this; } + /** + * Disables the item limiter described in {@link #limitTo(int)}. If you have + * auto fill enabled, this will also disable auto fill! + * + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent disableLimiter() { this.enableLimiter = false; return this; } + /** + * Sets the list item order to {@code ascending}. This means that + * if your start line is 10 for example, the second item will be placed + * on line 11, the third one on 12, and so one. + * + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent ascendingOrder() { this.ascendingOrder = true; return this; } + /** + * Sets the list item order to {@code descending}. This means that + * if your start line is 10 for example, the second item will be placed + * on line 9, the third one on 8, and so one. + * + * @return Instance of the current component for more fluent builder design. + */ public StatefulListComponent descendingOrder() { this.ascendingOrder = false; return this; } + /** + * Renders all the information provided in the component + * to a map containing the final information to be rendered + * to the sidebar (the lines where the text should be placed and + * the text to write there). + * + * @return A map, where the key is the absolute line where + * the component should be placed in the sidebar and + * the value is the actual text for that line. + */ @Override public Map render() { Map output = Maps.newHashMap(); List lines = list.get(); Iterator iterator = lines.iterator(); + + // before iterating through the list, the plugin checks whether + // the list should be placed in ascending or descending order, which + // is important to check whether indexes have to be decremented or incremented. if (ascendingOrder) { for (int i = startLine; i < Integer.MAX_VALUE; i++) { + if (!iterator.hasNext()) { + // if the iterator has arrived at the last item it has to check + // whether there are enough lines to fill the minimum required area + // if such an area is set with autoFill. It will then add any missing + // lines. if (enableLimiter && autoFill && i <= maxLine) { for (int fillIndex = i; fillIndex <= maxLine; fillIndex++) { output.put(fillIndex, " "); @@ -94,6 +203,10 @@ public Map render() { } } else { for (int i = startLine; i < Integer.MAX_VALUE; i--) { + + // here you can find pretty much the same as described above + // but for the descending list order. The major difference is that + // the numbers are inverted here. (++ -> -- for example) if (!iterator.hasNext()) { if (enableLimiter && autoFill && i >= maxLine) { for (int fillIndex = i; fillIndex >= maxLine; fillIndex--) { @@ -110,6 +223,10 @@ public Map render() { } } + // if the list is empty, there have been no checks whether it is + // necessary to fill up empty lines. So this is done here. If the + // limiter and auto fill mode are enabled, the plugin will add as + // many lines as needed to fill the space. if (output.isEmpty() && enableLimiter && autoFill) { if (ascendingOrder) { for (int fillIndex = startLine; fillIndex <= maxLine; fillIndex++) { @@ -126,8 +243,4 @@ public Map render() { return output; } - private void fill() { - - } - } From 113f84318e7b30227e63143ee7ca38a05d3a9921 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:28:18 +0100 Subject: [PATCH 46/68] Add documentation for EmptyLineComponent --- .../sidebar/component/EmptyLineComponent.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java index 8a071e94..ab6b3df1 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/EmptyLineComponent.java @@ -12,8 +12,8 @@ /** * This sidebar component can be used to generate empty lines. - * You could also write them manually as a {@code SimpleTextComponent}, - * but this way makes it more maintainable, because you don't + * You could also write them manually as a {@code StatelessTextComponent} + * for example, this way however makes it more maintainable, because you don't * have to choose color codes manually: * * To display an empty line in a scoreboard you have to use invisible @@ -28,17 +28,38 @@ */ public class EmptyLineComponent extends SidebarComponent { + // the line to place the component in the sidebar private int line; public static EmptyLineComponent create() { return new EmptyLineComponent(); } + /** + * Sets the line number of the component to be placed in the sidebar. + * Please note that this line id represents an absolute position and + * should therefore be unique. No components should have the same line + * number. + * + * @param line The line of the sidebar, where the component should + * be visible. + * @return The current component instance for fluent builder design. + */ public EmptyLineComponent line(int line) { this.line = line; return this; } + /** + * Renders all the information provided in the component + * to a map containing the final information to be rendered + * to the sidebar (the lines where the text should be placed and + * the text to write there). + * + * @return A map, where the key is the absolute line where + * the component should be placed in the sidebar and + * the value is the actual text for that line. + */ @Override public Map render() { Map output = Maps.newHashMap(); From ad90edbbf2cba1025f23f9c41f25192bcd091c26 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:28:34 +0100 Subject: [PATCH 47/68] Add documentation for SidebarComponent --- .../core/sidebar/component/SidebarComponent.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java index c357c2ed..c3016a3a 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponent.java @@ -3,12 +3,25 @@ import java.util.Map; /** - * A class description goes here. + * This superclass is inherited by every sidebar component. + * It contains a {@link #render()} method converting the information + * provided in your component to the final content that is + * displayed in the sidebar. * * @author pxav */ public abstract class SidebarComponent { + /** + * Renders all the information provided in the component + * to a map containing the final information to be rendered + * to the sidebar (the lines where the text should be placed and + * the text to write there). + * + * @return A map, where the key is the absolute line where + * the component should be placed in the sidebar and + * the value is the actual text for that line. + */ public abstract Map render(); } From a9e8d41d44b13b1c3784f11f07842ffabfcffbbc Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:28:49 +0100 Subject: [PATCH 48/68] Add documentation for SidebarComponentFactory --- .../component/SidebarComponentFactory.java | 84 ------------------- 1 file changed, 84 deletions(-) mode change 100644 => 100755 core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponentFactory.java diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponentFactory.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponentFactory.java old mode 100644 new mode 100755 index 450b3dac..17761aa1 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponentFactory.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/SidebarComponentFactory.java @@ -27,88 +27,4 @@ public SidebarComponentFactory(KelpLogger kelpLogger, SidebarUtils sidebarUtils) this.sidebarUtils = sidebarUtils; } - public SimpleTextComponent simpleTextComponent() { - return new SimpleTextComponent(sidebarUtils, kelpLogger); - } - - public SimpleTextComponent simpleTextComponent(String text) { - return new SimpleTextComponent(sidebarUtils, kelpLogger) - .text(text); - } - - public SimpleTextComponent simpleTextComponent(String text, int line) { - return new SimpleTextComponent(sidebarUtils, kelpLogger) - .text(text) - .line(line); - } - - public EmptyLineComponent emptyLineComponent() { - return new EmptyLineComponent(sidebarUtils); - } - - public EmptyLineComponent emptyLineComponent(int line) { - return new EmptyLineComponent(sidebarUtils).score(line); - } - - public LineSeparatorComponent lineSeparatorComponent() { - return new LineSeparatorComponent(sidebarUtils); - } - - public LineSeparatorComponent lineSeparatorComponent(int line) { - return new LineSeparatorComponent(sidebarUtils).score(line); - } - - public LineSeparatorComponent lineSeparatorComponent(char symbol) { - return new LineSeparatorComponent(sidebarUtils).symbol(symbol); - } - - public LineSeparatorComponent lineSeparatorComponent(int line, char symbol) { - return new LineSeparatorComponent(sidebarUtils) - .symbol(symbol) - .score(line); - } - - public LineSeparatorComponent lineSeparatorComponent(char symbol, ChatColor... colors) { - return new LineSeparatorComponent(sidebarUtils).symbol(symbol).color(colors); - } - - public LineSeparatorComponent lineSeparatorComponent(int line, char symbol, ChatColor... colors) { - return new LineSeparatorComponent(sidebarUtils) - .symbol(symbol) - .color(colors) - .score(line); - } - - public LineSeparatorComponent lineSeparatorComponent(ChatColor... colors) { - return new LineSeparatorComponent(sidebarUtils) - .color(colors); - } - - public LineSeparatorComponent lineSeparatorComponent(int line, ChatColor... colors) { - return new LineSeparatorComponent(sidebarUtils) - .color(colors) - .score(line); - } - - public LineSeparatorComponent lineSeparatorComponent(char symbol, int length, ChatColor... colors) { - return new LineSeparatorComponent(sidebarUtils) - .color(colors) - .symbol(symbol) - .length(length); - } - - public LineSeparatorComponent lineSeparatorComponent(int line, char symbol, int length, ChatColor... colors) { - return new LineSeparatorComponent(sidebarUtils) - .color(colors) - .symbol(symbol) - .length(length) - .score(line); - } - - public LineSeparatorComponent lineSeparatorComponent(int line, int length) { - return new LineSeparatorComponent(sidebarUtils) - .score(line) - .length(length); - } - } From 7d559100b885b07ace58d178cb23aae12e13479c Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:29:23 +0100 Subject: [PATCH 49/68] Add documentation for StatelessTextComponent --- .../component/StatelessTextComponent.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java index de9da234..52f71306 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatelessTextComponent.java @@ -7,7 +7,10 @@ import java.util.Map; /** - * A class description goes here. + * This component can display static text in a sidebar. So unlike + * the {@link StatefulListComponent} the text will not change after an + * update. This is useful to display static information such as a link + * to your website, etc. * * @author pxav */ @@ -20,16 +23,43 @@ public static StatelessTextComponent create() { return new StatelessTextComponent(); } + /** + * Sets the text to be displayed by this component. This text cannot be changed + * once it has been set. + * + * @param text The static text to be displayed. + * @return Instance of the current component for more fluent builder design. + */ public StatelessTextComponent text(String text) { this.text = text; return this; } + /** + * Sets the line number of the component to be placed in the sidebar. + * Please note that this line id represents an absolute position and + * should therefore be unique. No components should have the same line + * number. + * + * @param line The line of the sidebar, where the component should + * be visible. + * @return The current component instance for fluent builder design. + */ public StatelessTextComponent line(int line) { this.line = line; return this; } + /** + * Renders all the information provided in the component + * to a map containing the final information to be rendered + * to the sidebar (the lines where the text should be placed and + * the text to write there). + * + * @return A map, where the key is the absolute line where + * the component should be placed in the sidebar and + * the value is the actual text for that line. + */ @Override public Map render() { Map output = Maps.newHashMap(); From 5cb4418652ff126ba7dac1364015fb8ec833d052 Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:29:33 +0100 Subject: [PATCH 50/68] Add documentation for StatefulTextComponent --- .../component/StatefulTextComponent.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java index cdf0cf2c..c08f668d 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/component/StatefulTextComponent.java @@ -6,13 +6,19 @@ import java.util.function.Supplier; /** - * A class description goes here. + * This component allows you to display dynamic content + * on sidebars. While the {@link StatelessTextComponent} can only display + * static, non-updatable content, this component can be updated. + * Example use cases for that would be displaying the player's + * coins or a timer. * * @author pxav */ public class StatefulTextComponent extends SidebarComponent { + // absolute position to place the component private int line; + private Supplier text; public StatefulTextComponent() { @@ -23,16 +29,42 @@ public static StatefulTextComponent create() { return new StatefulTextComponent(); } + /** + * Sets the line number of the component to be placed in the sidebar. + * Please note that this line id represents an absolute position and + * should therefore be unique. No components should have the same line + * number. + * + * @param line The line of the sidebar, where the component should + * be visible. + * @return The current component instance for fluent builder design. + */ public StatefulTextComponent line(int line) { this.line = line; return this; } + /** + * Sets the text to be displayed in the component. + * + * @param text The dynamic text to be displayed. + * @return Instance of the current component for more fluent builder design. + */ public StatefulTextComponent text(Supplier text) { this.text = text; return this; } + /** + * Renders all the information provided in the component + * to a map containing the final information to be rendered + * to the sidebar (the lines where the text should be placed and + * the text to write there). + * + * @return A map, where the key is the absolute line where + * the component should be placed in the sidebar and + * the value is the actual text for that line. + */ @Override public Map render() { Map output = Maps.newHashMap(); From 16a9b099917c5d6a11ee6a1d0259856cba7ee58e Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:29:58 +0100 Subject: [PATCH 51/68] Add documentation for sidebar version templates --- .../SidebarUpdaterVersionTemplate.java | 10 +++++++ .../version/SidebarVersionTemplate.java | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java index 4f609451..b51270fe 100644 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarUpdaterVersionTemplate.java @@ -3,9 +3,19 @@ import de.pxav.kelp.core.application.KelpVersionTemplate; import de.pxav.kelp.core.player.KelpPlayer; +/** + * This version template is responsible for specific update operations + * other than simply updating specific components. This includes updating + * a sidebar's title for example. + */ @KelpVersionTemplate public abstract class SidebarUpdaterVersionTemplate { + /** + * Updates the title of sidebar of the given player to the given string. + * @param to The title to update to. + * @param player The player whose sidebar's title should be updated. + */ public abstract void updateTitleOnly(String to, KelpPlayer player); } diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java index 26b14c43..152e8a7b 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/version/SidebarVersionTemplate.java @@ -16,10 +16,39 @@ @KelpVersionTemplate public abstract class SidebarVersionTemplate { + /** + * Renders the sidebar to a specific player. This means it displays + * it for the first time (so only use this method if the player does + * not already see this sidebar to avoid flicker effects or similar behaviour). + * + * @param sidebar The sidebar to render to the given player. + * @param player The player to render the sidebar to. + */ public abstract void renderSidebar(KelpSidebar sidebar, KelpPlayer player); + /** + * Performs a lazy update on the sidebar. A lazy update does not remove all entries/lines + * from a scoreboard first, like it is done by {@link #updateSidebar(KelpSidebar, KelpPlayer)}. It only uses the + * existing entries in the sidebar, which means that you cannot use it if you know that the amount + * of lines in the sidebar might change with an update. + * + * However this update method is completely free from any flickering effects and it is + * not as performance heavy as a normal update. So if you can, you should prefer this update + * method over a normal update. + * + * @param sidebar The sidebar to update. + * @param kelpPlayer The player who should see the updated sidebar. + */ public abstract void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer); + /** + * Performs a full-update on the given sidebar, which means that all existing + * contents are removed and then new contents are applied. This method is safe + * against changing amounts of lines. + * + * @param sidebar The sidebar you want to update. + * @param player The player who should see the updates. + */ public abstract void updateSidebar(KelpSidebar sidebar, KelpPlayer player); } From 7b1cb7909716c2c0871acff2b564b7b8fa1a40cf Mon Sep 17 00:00:00 2001 From: pxav Date: Wed, 27 Jan 2021 21:30:20 +0100 Subject: [PATCH 52/68] Add documentation for sidebar version implementations --- .../sidebar/VersionedSidebar.java | 36 +++++++++++++++++++ .../sidebar/VersionedSidebarUpdater.java | 5 +++ 2 files changed, 41 insertions(+) diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java index 34987473..14644681 100755 --- a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java @@ -37,6 +37,14 @@ public VersionedSidebar(SidebarUtils sidebarUtils, KelpLogger logger, SidebarRep this.sidebarRepository = sidebarRepository; } + /** + * Renders the sidebar to a specific player. This means it displays + * it for the first time (so only use this method if the player does + * not already see this sidebar to avoid flicker effects or similar behaviour). + * + * @param sidebar The sidebar to render to the given player. + * @param kelpPlayer The player to render the sidebar to. + */ @Override public void renderSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { Player player = kelpPlayer.getBukkitPlayer(); @@ -57,19 +65,37 @@ public void renderSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { objective.setDisplaySlot(DisplaySlot.SIDEBAR); player.setScoreboard(scoreboard); + + // apply all contents to the sidebar. this.updateSidebar(sidebar, kelpPlayer); if (sidebar.getClass().isAssignableFrom(AnimatedSidebar.class)) { + // if the sidebar is animated start the animation schedulers in + // the sidebar repository and set the first animation state as default. AnimatedSidebar animatedSidebar = (AnimatedSidebar) sidebar; objective.setDisplayName(animatedSidebar.getTitle().states().get(0)); sidebarRepository.addAnimatedSidebar(animatedSidebar, kelpPlayer); } else if (sidebar.getClass().isAssignableFrom(SimpleSidebar.class)) { + // if the sidebar is a simple sidebar, simply set the default title. SimpleSidebar simpleSidebar = (SimpleSidebar) sidebar; objective.setDisplayName(simpleSidebar.getTitle().get()); } } + /** + * Performs a lazy update on the sidebar. A lazy update does not remove all entries/lines + * from a scoreboard first, like it is done by {@link #updateSidebar(KelpSidebar, KelpPlayer)}. It only uses the + * existing entries in the sidebar, which means that you cannot use it if you know that the amount + * of lines in the sidebar might change with an update. + * + * However this update method is completely free from any flickering effects and it is + * not as performance heavy as a normal update. So if you can, you should prefer this update + * method over a normal update. + * + * @param sidebar The sidebar to update. + * @param kelpPlayer The player who should see the updated sidebar. + */ @Override public void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer) { Scoreboard scoreboard = kelpPlayer.getBukkitPlayer().getScoreboard(); @@ -97,6 +123,14 @@ public void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer) { } } + /** + * Performs a full-update on the given sidebar, which means that all existing + * contents are removed and then new contents are applied. This method is safe + * against changing amounts of lines. + * + * @param sidebar The sidebar you want to update. + * @param kelpPlayer The player who should see the updates. + */ @Override public void updateSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { Scoreboard scoreboard = kelpPlayer.getBukkitPlayer().getScoreboard(); @@ -107,6 +141,7 @@ public void updateSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { return; } + // remove all old entries for (String entry : scoreboard.getEntries()) { Score score = objective.getScore(entry); @@ -117,6 +152,7 @@ public void updateSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { scoreboard.resetScores(entry); } + // unregister all teams scoreboard.getTeams().forEach(Team::unregister); for (Object object : sidebar.getComponents()) { diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java index 45bcc445..8850edc9 100644 --- a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebarUpdater.java @@ -10,6 +10,11 @@ @Versioned public class VersionedSidebarUpdater extends SidebarUpdaterVersionTemplate { + /** + * Updates the title of sidebar of the given player to the given string. + * @param to The title to update to. + * @param kelpPlayer The player whose sidebar's title should be updated. + */ @Override public void updateTitleOnly(String to, KelpPlayer kelpPlayer) { Scoreboard scoreboard = kelpPlayer.getBukkitPlayer().getScoreboard(); From 5d4e4b43c52a39fc2a0f044aa8d04d4be8f08e41 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 11:29:23 +0100 Subject: [PATCH 53/68] Add new event type alternative to PlayerEvent (uses KelpPlayer instead of normal player) --- .../core/event/kelpevent/KelpPlayerEvent.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerEvent.java diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerEvent.java new file mode 100644 index 00000000..b01509da --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/KelpPlayerEvent.java @@ -0,0 +1,35 @@ +package de.pxav.kelp.core.event.kelpevent; + +import de.pxav.kelp.core.player.KelpPlayer; +import org.bukkit.event.Event; + +/** + * Represents a specific type of event. It is basically a replacement + * class for bukkit's normal {@link org.bukkit.event.player.PlayerEvent}, but + * does not hold a normal {@link org.bukkit.entity.Player} instance. Instead + * the {@code #getPlayer()} method returns a {@link KelpPlayer} to offer better + * integration of custom Kelp events into your plugins. You don't need to + * manually fetch the player anymore with the {@link de.pxav.kelp.core.player.KelpPlayerRepository} + * but can directly retrieve it from the event. + * + * @author pxav + */ +public abstract class KelpPlayerEvent extends Event { + + protected KelpPlayer player; + + public KelpPlayerEvent(KelpPlayer who) { + this.player = who; + } + + /** + * Gets the player who has triggered the event or + * the player who should be handled by this event. + * + * @return The player of this event. + */ + public final KelpPlayer getPlayer() { + return this.player; + } + +} From 9575e8853abafb86b24a5dc1d539983d23d23426 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 11:29:53 +0100 Subject: [PATCH 54/68] Add basic events for sidebar actions such as remove or update --- .../sidebar/KelpSidebarRenderEvent.java | 43 ++++++++++++++ .../sidebar/KelpSidebarUpdateEvent.java | 58 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRenderEvent.java create mode 100644 core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarUpdateEvent.java diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRenderEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRenderEvent.java new file mode 100644 index 00000000..1fb05af7 --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRenderEvent.java @@ -0,0 +1,43 @@ +package de.pxav.kelp.core.event.kelpevent.sidebar; + +import de.pxav.kelp.core.event.kelpevent.KelpPlayerEvent; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.type.KelpSidebar; +import org.bukkit.event.HandlerList; + +/** + * This event is triggered when a {@link KelpSidebar} is rendered to a player, + * which means that the sidebar is displayed to them for the first time. + * + * @author pxav + */ +public class KelpSidebarRenderEvent extends KelpPlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + + private KelpSidebar sidebar; + + public KelpSidebarRenderEvent(KelpPlayer who, KelpSidebar sidebar) { + super(who); + this.sidebar = sidebar; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Gets the instance of the sidebar that has been rendered to the player. + * + * @return The current scoreboard object. + */ + public KelpSidebar getSidebar() { + return sidebar; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + +} diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarUpdateEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarUpdateEvent.java new file mode 100644 index 00000000..7183f7ec --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarUpdateEvent.java @@ -0,0 +1,58 @@ +package de.pxav.kelp.core.event.kelpevent.sidebar; + +import de.pxav.kelp.core.event.kelpevent.KelpPlayerEvent; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.type.KelpSidebar; +import org.bukkit.event.HandlerList; + +/** + * This event is triggered when any {@link KelpSidebar<>} is updated no + * matter if it is a lazy or normal update. Title updates are not + * included. + * + * @author pxav + */ +public class KelpSidebarUpdateEvent extends KelpPlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + + private boolean lazyUpdate; + private KelpSidebar sidebar; + + public KelpSidebarUpdateEvent(KelpPlayer who, KelpSidebar sidebar, boolean lazyUpdate) { + super(who); + this.sidebar = sidebar; + this.lazyUpdate = lazyUpdate; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Checks if the update was performed lazy, which means that + * no scores have been added/deleted from the board. + * + * @return {@code true} if the update was lazy. + */ + public boolean isLazyUpdate() { + return lazyUpdate; + } + + /** + * Gets an instance of the scoreboard that has been updated. + * It can be casted to the specific type such as {@link de.pxav.kelp.core.sidebar.type.AnimatedSidebar} + * for example if needed. + * + * @return The current sidebar object. + */ + public KelpSidebar getSidebar() { + return sidebar; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + +} From cb6fb77dfec29a47ac25430640f21814b200b8c6 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 11:30:27 +0100 Subject: [PATCH 55/68] Sidebars can now be removed/hidden from a player --- .../sidebar/KelpSidebarRemoveEvent.java | 32 +++++++++++++++++++ .../de/pxav/kelp/core/player/KelpPlayer.java | 13 ++++++++ .../core/player/PlayerVersionTemplate.java | 8 +++++ .../kelp/core/sidebar/SidebarRepository.java | 9 +++++- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRemoveEvent.java diff --git a/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRemoveEvent.java b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRemoveEvent.java new file mode 100644 index 00000000..cf565055 --- /dev/null +++ b/core/src/main/java/de/pxav/kelp/core/event/kelpevent/sidebar/KelpSidebarRemoveEvent.java @@ -0,0 +1,32 @@ +package de.pxav.kelp.core.event.kelpevent.sidebar; + +import de.pxav.kelp.core.event.kelpevent.KelpPlayerEvent; +import de.pxav.kelp.core.player.KelpPlayer; +import org.bukkit.event.HandlerList; + +/** + * This event is triggered when any sidebar is removed from a player + * and the corresponding animation schedulers, etc. are stopped. It + * does only handle {@link de.pxav.kelp.core.sidebar.type.KelpSidebar<>} ano + * no default bukkit scoreboards. + * + * @author pxav + */ +public class KelpSidebarRemoveEvent extends KelpPlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + + public KelpSidebarRemoveEvent(KelpPlayer who) { + super(who); + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + +} diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index 77a98d67..ba8513fd 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -5,6 +5,7 @@ import de.pxav.kelp.core.entity.LivingKelpEntity; import de.pxav.kelp.core.entity.version.EntityVersionTemplate; import de.pxav.kelp.core.entity.version.LivingEntityVersionTemplate; +import de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarRemoveEvent; import de.pxav.kelp.core.inventory.KelpInventoryRepository; import de.pxav.kelp.core.inventory.type.KelpInventory; import de.pxav.kelp.core.particle.type.ParticleType; @@ -21,6 +22,7 @@ import de.pxav.kelp.core.player.prompt.sign.SignPromptVersionTemplate; import de.pxav.kelp.core.sidebar.SidebarRepository; import de.pxav.kelp.core.sound.KelpSound; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.scoreboard.DisplaySlot; @@ -134,6 +136,17 @@ public boolean hasScoreboard() { || scoreboard.getObjective(DisplaySlot.PLAYER_LIST) != null; } + /** + * Removes the {@link de.pxav.kelp.core.sidebar.type.KelpSidebar} from the player. + * This hides the sidebar from the screen, but also stops all schedulers connected + * to it (such as title animation). This method does not effect other parts + * of the scoreboard such as the tab list. + */ + public void removeSidebar() { + Bukkit.getPluginManager().callEvent(new KelpSidebarRemoveEvent(this)); + playerVersionTemplate.removeSidebar(bukkitPlayer); + } + /** * Opens a {@link KelpInventory} to the player. This * is equivalent to calling the {@link KelpInventoryRepository#openInventory(KelpInventory, KelpPlayer)} diff --git a/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java b/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java index fe98e01b..ff033cd2 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java +++ b/core/src/main/java/de/pxav/kelp/core/player/PlayerVersionTemplate.java @@ -935,4 +935,12 @@ public abstract class PlayerVersionTemplate { */ public abstract void sendInteractiveMessage(Player player, InteractiveMessage interactiveMessage); + /** + * If the player currently sees a sidebar, it will be hidden for the given + * player. This mostly happens by replacing it with a new, empty scoreboard. + * + * @param player The player whose sidebar you want to hide/remove. + */ + public abstract void removeSidebar(Player player); + } diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java index 7b80e468..9f46547a 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/SidebarRepository.java @@ -3,10 +3,10 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import de.pxav.kelp.core.animation.TextAnimation; +import de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarRemoveEvent; import de.pxav.kelp.core.player.KelpPlayer; import de.pxav.kelp.core.player.KelpPlayerRepository; import de.pxav.kelp.core.scheduler.KelpSchedulerRepository; -import de.pxav.kelp.core.scheduler.type.RepeatingScheduler; import de.pxav.kelp.core.scheduler.type.SchedulerFactory; import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; @@ -118,6 +118,13 @@ public void handleClusterRemove(PlayerQuitEvent event) { } } + @EventHandler + public void handleSidebarRemove(KelpSidebarRemoveEvent event) { + // stops all schedulers and removes the player from the list when + // their sidebar is removed. + this.removeAnimatedSidebar(event.getPlayer()); + } + private void addPlayerToCluster(String clusterId, KelpPlayer player) { Set players = clusters.get(clusterId); players.add(player.getUUID()); From a84473a4946b63dc8ed365ccbaf40a0e0ecfc1b9 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 11:31:06 +0100 Subject: [PATCH 56/68] Write 1.8 implementation for remove mechanism and other sidebar events --- .../player/VersionedPlayer.java | 20 +++++++++++++++++++ .../sidebar/VersionedSidebar.java | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/player/VersionedPlayer.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/player/VersionedPlayer.java index e9191804..2911ee83 100644 --- a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/player/VersionedPlayer.java +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/player/VersionedPlayer.java @@ -28,6 +28,8 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.permissions.PermissionAttachment; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Scoreboard; import org.bukkit.util.Vector; import java.lang.reflect.Field; @@ -1335,6 +1337,24 @@ public void sendInteractiveMessage(Player player, InteractiveMessage interactive player.spigot().sendMessage(componentBuilder.create()); } + /** + * If the player currently sees a sidebar, it will be hidden for the given + * player. This mostly happens by replacing it with a new, empty scoreboard. + * + * @param player The player whose sidebar you want to hide/remove. + */ + @Override + public void removeSidebar(Player player) { + Scoreboard scoreboard = player.getScoreboard(); + if (scoreboard.getObjective(DisplaySlot.SIDEBAR) == null) { + return; + } + + scoreboard.getObjective(DisplaySlot.SIDEBAR).unregister(); + player.setScoreboard(scoreboard); + + } + /** * Appends a message to the given {@link ComponentBuilder}. Please note that every message you append * using this method may only have one chat color and the formatting code applies for the entire message. diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java index 14644681..a7e12353 100755 --- a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java @@ -1,6 +1,8 @@ package de.pxav.kelp.implementation1_8.sidebar; import com.google.common.base.Preconditions; +import de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarRenderEvent; +import de.pxav.kelp.core.event.kelpevent.sidebar.KelpSidebarUpdateEvent; import de.pxav.kelp.core.logger.KelpLogger; import de.pxav.kelp.core.logger.LogLevel; import de.pxav.kelp.core.player.KelpPlayer; @@ -65,6 +67,7 @@ public void renderSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { objective.setDisplaySlot(DisplaySlot.SIDEBAR); player.setScoreboard(scoreboard); + Bukkit.getPluginManager().callEvent(new KelpSidebarRenderEvent(kelpPlayer, sidebar)); // apply all contents to the sidebar. this.updateSidebar(sidebar, kelpPlayer); @@ -121,6 +124,8 @@ public void lazyUpdate(KelpSidebar sidebar, KelpPlayer kelpPlayer) { sidebarUtils.setTeamData(text, team); }); } + + Bukkit.getPluginManager().callEvent(new KelpSidebarUpdateEvent(kelpPlayer, sidebar, true)); } /** @@ -172,6 +177,8 @@ public void updateSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { }); } + + Bukkit.getPluginManager().callEvent(new KelpSidebarUpdateEvent(kelpPlayer, sidebar, false)); } } From f736c4f2cbf29ff258fe94cef611d30fc54124ab Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 11:31:20 +0100 Subject: [PATCH 57/68] Update dependencies in SidebarFactory --- .../kelp/core/sidebar/type/SidebarFactory.java | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java index 0f6ac344..148cc655 100755 --- a/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java +++ b/core/src/main/java/de/pxav/kelp/core/sidebar/type/SidebarFactory.java @@ -2,11 +2,8 @@ import com.google.inject.Inject; import com.google.inject.Singleton; -import de.pxav.kelp.core.sidebar.component.SidebarComponentFactory; -import de.pxav.kelp.core.logger.KelpLogger; import de.pxav.kelp.core.sidebar.version.SidebarUpdaterVersionTemplate; import de.pxav.kelp.core.sidebar.version.SidebarVersionTemplate; -import org.bukkit.plugin.java.JavaPlugin; /** * This class can be used to easily build @@ -23,22 +20,13 @@ @Singleton public class SidebarFactory { - private KelpLogger logger; - private JavaPlugin javaPlugin; private SidebarVersionTemplate sidebarVersionTemplate; - private SidebarComponentFactory sidebarComponentFactory; private SidebarUpdaterVersionTemplate updaterVersionTemplate; @Inject - public SidebarFactory(KelpLogger logger, - JavaPlugin javaPlugin, - SidebarVersionTemplate sidebarVersionTemplate, - SidebarComponentFactory sidebarComponentFactory, + public SidebarFactory(SidebarVersionTemplate sidebarVersionTemplate, SidebarUpdaterVersionTemplate updaterVersionTemplate) { - this.logger = logger; - this.javaPlugin = javaPlugin; this.sidebarVersionTemplate = sidebarVersionTemplate; - this.sidebarComponentFactory = sidebarComponentFactory; this.updaterVersionTemplate = updaterVersionTemplate; } @@ -46,8 +34,8 @@ public SimpleSidebar newSimpleSidebar() { return new SimpleSidebar(sidebarVersionTemplate, updaterVersionTemplate); } - public AnimatedSidebarOld newAnimatedSidebar() { - return new AnimatedSidebarOld(sidebarVersionTemplate); + public AnimatedSidebar newAnimatedSidebar() { + return new AnimatedSidebar(sidebarVersionTemplate); } } From d6666d265ad431112d90567b85fcc8dfa1343951 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 12:42:01 +0100 Subject: [PATCH 58/68] Remove old DefaultSidebarTest from testing-module --- .../testing/sidebar/DefaultSidebarTest.java | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 testing-module/src/main/java/de/pxav/kelp/testing/sidebar/DefaultSidebarTest.java diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/DefaultSidebarTest.java b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/DefaultSidebarTest.java deleted file mode 100644 index 6ab52b10..00000000 --- a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/DefaultSidebarTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package de.pxav.kelp.testing.sidebar; - -import com.google.inject.Singleton; -import de.pxav.kelp.core.animation.TextAnimation; -import de.pxav.kelp.core.animation.TextAnimationFactory; -import de.pxav.kelp.core.sidebar.CreateSidebar; -import de.pxav.kelp.core.sidebar.SidebarRepository; -import de.pxav.kelp.core.sidebar.component.SidebarComponentFactory; -import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; -import de.pxav.kelp.core.sidebar.type.SidebarFactory; -import org.bukkit.entity.Player; - -/** - * A class description goes here. - * - * @author pxav - */ -@Singleton -public class DefaultSidebarTest { - - private SidebarFactory sidebarFactory; - private SidebarComponentFactory sidebarComponentFactory; - private SidebarRepository sidebarRepository; - private TextAnimationFactory textAnimationFactory; - - public DefaultSidebarTest(SidebarFactory sidebarFactory, - SidebarComponentFactory sidebarComponentFactory, - SidebarRepository sidebarRepository, - TextAnimationFactory textAnimationFactory) { - this.sidebarFactory = sidebarFactory; - this.sidebarComponentFactory = sidebarComponentFactory; - this.sidebarRepository = sidebarRepository; - this.textAnimationFactory = textAnimationFactory; - } - - @CreateSidebar(identifier = "default", - setOnJoin = true, - titleAnimationInterval = 700) - public AnimatedSidebar defaultSidebar(Player player) { - return this.sidebarFactory.newAnimatedSidebar() - .withTitle(textAnimationFactory - .newBuildingTextAnimation() - .text("This is a test!") - .ignoreSpaces()) - .addComponent(sidebarComponentFactory.lineSeparatorComponent(10)) - .addComponent(sidebarComponentFactory.emptyLineComponent(9)) - .addComponent(sidebarComponentFactory - .simpleTextComponent() - .text("§aWelcome, ") - .line(8)) - .addComponent(sidebarComponentFactory - .simpleTextComponent() - .text(player.getName()) - .line(8)); - } -} From c67779fac77fdfbdbb81b7d968a396c046624b28 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 12:42:32 +0100 Subject: [PATCH 59/68] Add commands to testing-module for sidebar testing --- .../kelp/testing/sidebar/KSidebarCommand.java | 40 ++++++ .../kelp/testing/sidebar/RemoveCommand.java | 25 ++++ .../kelp/testing/sidebar/ShowCommand.java | 126 ++++++++++++++++++ .../kelp/testing/sidebar/UpdateCommand.java | 63 +++++++++ 4 files changed, 254 insertions(+) create mode 100644 testing-module/src/main/java/de/pxav/kelp/testing/sidebar/KSidebarCommand.java create mode 100644 testing-module/src/main/java/de/pxav/kelp/testing/sidebar/RemoveCommand.java create mode 100644 testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java create mode 100644 testing-module/src/main/java/de/pxav/kelp/testing/sidebar/UpdateCommand.java diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/KSidebarCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/KSidebarCommand.java new file mode 100644 index 00000000..24c2f5c5 --- /dev/null +++ b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/KSidebarCommand.java @@ -0,0 +1,40 @@ +package de.pxav.kelp.testing.sidebar; + +import de.pxav.kelp.core.command.CreateCommand; +import de.pxav.kelp.core.command.ExecutorType; +import de.pxav.kelp.core.command.KelpCommand; +import de.pxav.kelp.core.player.KelpPlayer; + +import javax.inject.Singleton; + +@Singleton +@CreateCommand( + name = "ksidebar", + executorType = ExecutorType.PLAYER_ONLY +) +public class KSidebarCommand extends KelpCommand { + + @Override + public void onCommandRegister() { + noPlayerMessage("§cYou have to be a player to execute this command"); + permission("kelp.test.sidebar"); + } + + @Override + public void onCommand(KelpPlayer player, String[] args) { + player.sendPrefixedMessages("§8[§2Kelp§8]", + " §8§m-------------------------", + " §7/ksidebar show ", + " §7/ksidebar update ", + " §7/ksidebar remove", + " §7", + " §7Example IDs§8:", + " §a1 §7Simple, static", + " §a2 §7Simple, updatable", + " §a3 §7Animated, updatable", + "", + " §8§m-------------------------" + ); + } + +} diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/RemoveCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/RemoveCommand.java new file mode 100644 index 00000000..19705862 --- /dev/null +++ b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/RemoveCommand.java @@ -0,0 +1,25 @@ +package de.pxav.kelp.testing.sidebar; + +import de.pxav.kelp.core.command.CreateSubCommand; +import de.pxav.kelp.core.command.ExecutorType; +import de.pxav.kelp.core.command.KelpCommand; +import de.pxav.kelp.core.player.KelpPlayer; + +@CreateSubCommand(name = "remove", + executorType = ExecutorType.PLAYER_ONLY, + parentCommand = KSidebarCommand.class +) +public class RemoveCommand extends KelpCommand { + + @Override + public void onCommandRegister() { + allowCustomParameters(false); + } + + @Override + public void onCommand(KelpPlayer player, String[] args) { + player.removeSidebar(); + player.sendMessage("§8[§2Kelp§8] §7Your sidebar has been removed."); + } + +} diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java new file mode 100644 index 00000000..dd995561 --- /dev/null +++ b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java @@ -0,0 +1,126 @@ +package de.pxav.kelp.testing.sidebar; + +import de.pxav.kelp.core.animation.BuildingTextAnimation; +import de.pxav.kelp.core.command.CreateSubCommand; +import de.pxav.kelp.core.command.ExecutorType; +import de.pxav.kelp.core.command.KelpCommand; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.component.EmptyLineComponent; +import de.pxav.kelp.core.sidebar.component.LineSeparatorComponent; +import de.pxav.kelp.core.sidebar.component.StatefulTextComponent; +import de.pxav.kelp.core.sidebar.component.StatelessTextComponent; +import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; +import de.pxav.kelp.core.sidebar.type.SimpleSidebar; +import org.bukkit.Bukkit; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.ThreadLocalRandom; + +@CreateSubCommand(name = "show", + executorType = ExecutorType.PLAYER_ONLY, + parentCommand = KSidebarCommand.class) +public class ShowCommand extends KelpCommand { + + @Override + public void onCommandRegister() { + allowCustomParameters(true); + argumentsStartFromZero(true); + } + + @Override + public void onCommand(KelpPlayer player, String[] args) { + if (args.length == 0) { + player.sendMessage("§cPlease provide an example id!"); + return; + } + + int id = 1; + + try { + id = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { + player.sendMessage("§cExample id has to be a numeric value!"); + return; + } + + if (id < 1 || id > 3) { + player.sendMessage("§cExample id is out of range!"); + return; + } + + switch (id) { + case 1: + SimpleSidebar sidebar1 = SimpleSidebar.create(); + sidebar1.staticTitle("§2KELP EXAMPLE SIDEBAR 1"); + + sidebar1.addComponent(LineSeparatorComponent.create().line(20)); + sidebar1.addComponent(EmptyLineComponent.create().line(19)); + sidebar1.addComponent(StatelessTextComponent.create().line(18).text("§2§lServer")); + sidebar1.addComponent(StatelessTextComponent.create().line(17).text("§8» §7Lobby-1")); + sidebar1.addComponent(EmptyLineComponent.create().line(16)); + + sidebar1.addComponent(StatelessTextComponent.create().line(15).text("§2§lTeamSpeak")); + sidebar1.addComponent(StatelessTextComponent.create().line(14).text("§8» §7ts.serverdomain.com")); + sidebar1.addComponent(EmptyLineComponent.create().line(13)); + + sidebar1.addComponent(StatelessTextComponent.create().line(12).text("§2§lDate")); + SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy"); + sidebar1.addComponent(StatelessTextComponent.create().line(11).text("§8» §7" + format.format(new Date()))); + sidebar1.addComponent(EmptyLineComponent.create().line(10)); + + sidebar1.render(player); + + break; + case 2: + SimpleSidebar sidebar2 = SimpleSidebar.create(); + sidebar2.title(() -> "§2KELP EXAMPLE " + ThreadLocalRandom.current().nextInt(100)); + + sidebar2.addComponent(LineSeparatorComponent.create().line(20)); + sidebar2.addComponent(EmptyLineComponent.create().line(19)); + sidebar2.addComponent(StatelessTextComponent.create().line(18).text("§2§lExperience")); + sidebar2.addComponent(StatelessTextComponent.create().line(17).text("§8» §7" + player.getLevel())); + sidebar2.addComponent(EmptyLineComponent.create().line(16)); + + sidebar2.addComponent(StatelessTextComponent.create().line(15).text("§2§lPlayers Online")); + sidebar2.addComponent(StatefulTextComponent.create().line(14).text(() -> "§8» §7" + Bukkit.getOnlinePlayers().size())); + sidebar2.addComponent(EmptyLineComponent.create().line(13)); + + sidebar2.addComponent(StatelessTextComponent.create().line(12).text("§2§lTime")); + SimpleDateFormat dateTime = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy"); + sidebar2.addComponent(StatefulTextComponent.create().line(11).text(() -> "§8» §7" + dateTime.format(new Date()))); + sidebar2.addComponent(EmptyLineComponent.create().line(10)); + + sidebar2.render(player); + + break; + case 3: + AnimatedSidebar sidebar3 = AnimatedSidebar.create(); + sidebar3.title(BuildingTextAnimation.create().text("§2§lKELP EXAMPLE SIDEBAR")); + sidebar3.titleAnimationInterval(150); + sidebar3.clusterId("example_sidebar_3"); + + sidebar3.addComponent(LineSeparatorComponent.create().line(20)); + sidebar3.addComponent(EmptyLineComponent.create().line(19)); + sidebar3.addComponent(StatelessTextComponent.create().line(18).text("§2§lExperience")); + sidebar3.addComponent(StatefulTextComponent.create().line(17).text(() -> "§8» §7" + player.getLevel())); + sidebar3.addComponent(EmptyLineComponent.create().line(16)); + + sidebar3.addComponent(StatelessTextComponent.create().line(15).text("§2§lPlayers Online")); + sidebar3.addComponent(StatefulTextComponent.create().line(14).text(() -> "§8» §7" + Bukkit.getOnlinePlayers().size())); + sidebar3.addComponent(EmptyLineComponent.create().line(13)); + + sidebar3.addComponent(StatelessTextComponent.create().line(12).text("§2§lTime")); + SimpleDateFormat dateTime2 = new SimpleDateFormat("ss:mm:HH dd.MM.yyyy"); + sidebar3.addComponent(StatefulTextComponent.create().line(11).text(() -> "§8» §7" + dateTime2.format(new Date()))); + sidebar3.addComponent(EmptyLineComponent.create().line(10)); + + sidebar3.render(player); + + break; + } + + player.sendMessage("§8[§2Kelp§8] §7Successfully rendered sidebar §a" + id + " §7to you."); + + } +} diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/UpdateCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/UpdateCommand.java new file mode 100644 index 00000000..6f463d7f --- /dev/null +++ b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/UpdateCommand.java @@ -0,0 +1,63 @@ +package de.pxav.kelp.testing.sidebar; + +import de.pxav.kelp.core.command.CreateSubCommand; +import de.pxav.kelp.core.command.ExecutorType; +import de.pxav.kelp.core.command.KelpCommand; +import de.pxav.kelp.core.player.KelpPlayer; +import de.pxav.kelp.core.sidebar.type.AnimatedSidebar; +import de.pxav.kelp.core.sidebar.type.KelpSidebar; +import de.pxav.kelp.core.sidebar.type.SimpleSidebar; + +@CreateSubCommand(name = "update", + executorType = ExecutorType.PLAYER_ONLY, + parentCommand = KSidebarCommand.class) +public class UpdateCommand extends KelpCommand { + + @Override + public void onCommandRegister() { + allowCustomParameters(true); + argumentsStartFromZero(true); + } + + @Override + public void onCommand(KelpPlayer player, String[] args) { + if (args.length == 0) { + player.sendMessage("§cPlease specify an update action."); + return; + } + + KelpSidebar sidebar = player.getCurrentSidebar(); + + if (sidebar == null) { + player.sendMessage("§cThere is no sidebar to update."); + return; + } + + if (args[0].equalsIgnoreCase("lazy")) { + if (sidebar instanceof AnimatedSidebar) { + ((AnimatedSidebar)sidebar).lazyUpdate(player); + } + if (sidebar instanceof SimpleSidebar) { + ((SimpleSidebar)sidebar).lazyUpdate(player); + } + player.sendMessage("§8[§2Kelp§8] §7A lazy update has been performed on your sidebar."); + } + + if (args[0].equalsIgnoreCase("normal")) { + sidebar.update(player); + player.sendMessage("§8[§2Kelp§8] §7A normal update has been performed on your sidebar."); + } + + if (args[0].equalsIgnoreCase("title")) { + + if (sidebar instanceof SimpleSidebar) { + ((SimpleSidebar)sidebar).updateTitleOnly(player); + } else { + player.sendMessage("§cCannot update AnimatedSidebar's title."); + } + + player.sendMessage("§8[§2Kelp§8] §7A title update has been performed on your sidebar."); + } + } + +} From fb6f9c4b421c0fe8f042b95fd2dcaa85d03d6215 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 12:43:13 +0100 Subject: [PATCH 60/68] You can now get a player's sidebar from KelpPlayer class --- .../de/pxav/kelp/core/player/KelpPlayer.java | 26 +++++++++++++++++++ .../sidebar/VersionedSidebar.java | 2 ++ 2 files changed, 28 insertions(+) diff --git a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java index ba8513fd..4f6da573 100644 --- a/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java +++ b/core/src/main/java/de/pxav/kelp/core/player/KelpPlayer.java @@ -21,6 +21,7 @@ import de.pxav.kelp.core.player.prompt.sign.SignPrompt; import de.pxav.kelp.core.player.prompt.sign.SignPromptVersionTemplate; import de.pxav.kelp.core.sidebar.SidebarRepository; +import de.pxav.kelp.core.sidebar.type.KelpSidebar; import de.pxav.kelp.core.sound.KelpSound; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -82,6 +83,8 @@ public class KelpPlayer extends LivingKelpEntity { private String tabListHeader; private String tabListFooter; + private KelpSidebar kelpSidebar; + public KelpPlayer(Player bukkitPlayer, PlayerVersionTemplate playerVersionTemplate, KelpInventoryRepository inventoryRepository, @@ -143,10 +146,33 @@ public boolean hasScoreboard() { * of the scoreboard such as the tab list. */ public void removeSidebar() { + setSidebarInternally(null); Bukkit.getPluginManager().callEvent(new KelpSidebarRemoveEvent(this)); playerVersionTemplate.removeSidebar(bukkitPlayer); } + /** + * Caches the sidebar object of the player locally. This does not + * render nor update the given sidebar. It simply changes the internal + * sidebar object which can then be retrieved to update it for + * example using {@link #getCurrentSidebar()}. + * + * @param sidebar The current sidebar of the player. + */ + public void setSidebarInternally(KelpSidebar sidebar) { + this.kelpSidebar = sidebar; + } + + /** + * Gets the sidebar the player is currently seeing. + * Will return {@code null} of the player has no sidebar. + * + * @return The current sidebar of the player. + */ + public KelpSidebar getCurrentSidebar() { + return kelpSidebar; + } + /** * Opens a {@link KelpInventory} to the player. This * is equivalent to calling the {@link KelpInventoryRepository#openInventory(KelpInventory, KelpPlayer)} diff --git a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java index a7e12353..fbcbdd50 100755 --- a/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java +++ b/v1_8_implementation/src/main/java/de/pxav/kelp/implementation1_8/sidebar/VersionedSidebar.java @@ -84,6 +84,8 @@ public void renderSidebar(KelpSidebar sidebar, KelpPlayer kelpPlayer) { objective.setDisplayName(simpleSidebar.getTitle().get()); } + kelpPlayer.setSidebarInternally(sidebar); + } /** From 88b22f9bfcae0be9542b67decfdc6b48b4f655c1 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 12:44:09 +0100 Subject: [PATCH 61/68] Refactor: move boss bar command to dedicated package --- .../TestBossBarCommand.java => bossbar/KBossBarCommand.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename testing-module/src/main/java/de/pxav/kelp/testing/{command/kbossbar/TestBossBarCommand.java => bossbar/KBossBarCommand.java} (98%) diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/command/kbossbar/TestBossBarCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/bossbar/KBossBarCommand.java similarity index 98% rename from testing-module/src/main/java/de/pxav/kelp/testing/command/kbossbar/TestBossBarCommand.java rename to testing-module/src/main/java/de/pxav/kelp/testing/bossbar/KBossBarCommand.java index de064102..6e63a7a3 100644 --- a/testing-module/src/main/java/de/pxav/kelp/testing/command/kbossbar/TestBossBarCommand.java +++ b/testing-module/src/main/java/de/pxav/kelp/testing/bossbar/KBossBarCommand.java @@ -1,4 +1,4 @@ -package de.pxav.kelp.testing.command.kbossbar; +package de.pxav.kelp.testing.bossbar; import de.pxav.kelp.core.command.CreateCommand; import de.pxav.kelp.core.command.ExecutorType; @@ -14,7 +14,7 @@ * @author pxav */ @CreateCommand(name = "kbossbar", executorType = ExecutorType.PLAYER_ONLY) -public class TestBossBarCommand extends KelpCommand { +public class KBossBarCommand extends KelpCommand { @Override public void onCommandRegister() { From 307382d9c9bbdbe617ad7e498f07d9e901224195 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 12:45:35 +0100 Subject: [PATCH 62/68] Refactor: move testing inventory command to dedicated package --- .../GiveMaterialCommand.java} | 8 ++++---- .../KMaterialCommand.java} | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) rename testing-module/src/main/java/de/pxav/kelp/testing/{command/kmaterial/GiveKelpMaterialCommands.java => inventory/GiveMaterialCommand.java} (88%) rename testing-module/src/main/java/de/pxav/kelp/testing/{command/kmaterial/KelpMaterialCommand.java => inventory/KMaterialCommand.java} (85%) diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/command/kmaterial/GiveKelpMaterialCommands.java b/testing-module/src/main/java/de/pxav/kelp/testing/inventory/GiveMaterialCommand.java similarity index 88% rename from testing-module/src/main/java/de/pxav/kelp/testing/command/kmaterial/GiveKelpMaterialCommands.java rename to testing-module/src/main/java/de/pxav/kelp/testing/inventory/GiveMaterialCommand.java index f8037e5b..9cb3827f 100644 --- a/testing-module/src/main/java/de/pxav/kelp/testing/command/kmaterial/GiveKelpMaterialCommands.java +++ b/testing-module/src/main/java/de/pxav/kelp/testing/inventory/GiveMaterialCommand.java @@ -1,4 +1,4 @@ -package de.pxav.kelp.testing.command.kmaterial; +package de.pxav.kelp.testing.inventory; import com.google.inject.Inject; import de.pxav.kelp.core.command.CreateSubCommand; @@ -18,14 +18,14 @@ * * @author pxav */ -@CreateSubCommand(name = "give", executorType = ExecutorType.PLAYER_ONLY, parentCommand = KelpMaterialCommand.class) -public class GiveKelpMaterialCommands extends KelpCommand { +@CreateSubCommand(name = "give", executorType = ExecutorType.PLAYER_ONLY, parentCommand = KMaterialCommand.class) +public class GiveMaterialCommand extends KelpCommand { private DebugCommandConfig config; private KelpItemFactory itemFactory; @Inject - public GiveKelpMaterialCommands(DebugCommandConfig config, KelpItemFactory itemFactory) { + public GiveMaterialCommand(DebugCommandConfig config, KelpItemFactory itemFactory) { this.config = config; this.itemFactory = itemFactory; } diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/command/kmaterial/KelpMaterialCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/inventory/KMaterialCommand.java similarity index 85% rename from testing-module/src/main/java/de/pxav/kelp/testing/command/kmaterial/KelpMaterialCommand.java rename to testing-module/src/main/java/de/pxav/kelp/testing/inventory/KMaterialCommand.java index 1ace59ce..6e9b9623 100644 --- a/testing-module/src/main/java/de/pxav/kelp/testing/command/kmaterial/KelpMaterialCommand.java +++ b/testing-module/src/main/java/de/pxav/kelp/testing/inventory/KMaterialCommand.java @@ -1,4 +1,4 @@ -package de.pxav.kelp.testing.command.kmaterial; +package de.pxav.kelp.testing.inventory; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -15,12 +15,12 @@ */ @Singleton @CreateCommand(name = "kmaterial", executorType = ExecutorType.PLAYER_ONLY) -public class KelpMaterialCommand extends KelpCommand { +public class KMaterialCommand extends KelpCommand { private DebugCommandConfig config; @Inject - public KelpMaterialCommand(DebugCommandConfig config) { + public KMaterialCommand(DebugCommandConfig config) { this.config = config; } From 772b8a3b30ef25aaf69d255853ebf6683e8e5401 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 12:46:43 +0100 Subject: [PATCH 63/68] Apply new sidebar repo to plugin class --- core/src/main/java/de/pxav/kelp/core/KelpPlugin.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java index 5f94a1fe..1dca462b 100644 --- a/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java +++ b/core/src/main/java/de/pxav/kelp/core/KelpPlugin.java @@ -100,9 +100,6 @@ public void onEnable() { injector.getInstance(EventHandlerRegistration.class).initialize(this.getClass().getPackage().getName()); injector.getInstance(KelpEventRepository.class).detectSubscriptions(this.getClass().getPackage().getName()); -// injector.getInstance(SidebarRepository.class).loadSidebars(this.getClass().getPackage().getName()); -// injector.getInstance(SidebarRepository.class).schedule(); - injector.getInstance(KelpCommandRepository.class).loadCommands(this.getClass().getPackage().getName()); injector.getInstance(KelpNpcRepository.class).startScheduler(); @@ -130,8 +127,8 @@ public void onDisable() { injector.getInstance(KelpApplicationRepository.class).disableApplications(); injector.getInstance(KelpNpcRepository.class).stopScheduler(); - //injector.getInstance(SidebarRepository.class).interruptAnimations(); injector.getInstance(SidebarRepository.class).stopAllClusters(); + logger().log("[SIDEBAR] Removed all animation clusters."); injector.getInstance(ParticleEffectRepository.class).stopAllTimers(); injector.getInstance(KelpSchedulerRepository.class).interruptAll(); From 0b5df8be47ee6f00aa08c49c33b4030250198d63 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 14:35:19 +0100 Subject: [PATCH 64/68] Fix time display in 3rd sidebar of testing module --- .../src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java index dd995561..f37bb018 100644 --- a/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java +++ b/testing-module/src/main/java/de/pxav/kelp/testing/sidebar/ShowCommand.java @@ -111,7 +111,7 @@ public void onCommand(KelpPlayer player, String[] args) { sidebar3.addComponent(EmptyLineComponent.create().line(13)); sidebar3.addComponent(StatelessTextComponent.create().line(12).text("§2§lTime")); - SimpleDateFormat dateTime2 = new SimpleDateFormat("ss:mm:HH dd.MM.yyyy"); + SimpleDateFormat dateTime2 = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy"); sidebar3.addComponent(StatefulTextComponent.create().line(11).text(() -> "§8» §7" + dateTime2.format(new Date()))); sidebar3.addComponent(EmptyLineComponent.create().line(10)); From c5378aedbdabb7dbf0d3af3086cf5a454f0b0af9 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 15:34:03 +0100 Subject: [PATCH 65/68] Bump project version to 0.1.0 --- core/pom.xml | 2 +- kelp-sql/pom.xml | 4 ++-- pom.xml | 2 +- testing-module/pom.xml | 4 ++-- v1_8_implementation/pom.xml | 4 ++-- v_1_14_implementation/pom.xml | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 5d4767cb..0d5a39d2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ com.github.pxav.kelp parent - 0.0.5 + 0.1.0 4.0.0 diff --git a/kelp-sql/pom.xml b/kelp-sql/pom.xml index 2dac1ee2..b1a3bd0f 100644 --- a/kelp-sql/pom.xml +++ b/kelp-sql/pom.xml @@ -5,7 +5,7 @@ parent com.github.pxav.kelp - 0.0.5 + 0.1.0 4.0.0 @@ -20,7 +20,7 @@ com.github.pxav.kelp core - 0.0.5 + 0.1.0 provided diff --git a/pom.xml b/pom.xml index 409ceb8f..45fb6f00 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.pxav.kelp parent pom - 0.0.5 + 0.1.0 Kelp A cross-version spigot framework to avoid boilerplate code and make your plugin compatible with multiple spigot versions easily diff --git a/testing-module/pom.xml b/testing-module/pom.xml index 155ed166..67fdd6c4 100644 --- a/testing-module/pom.xml +++ b/testing-module/pom.xml @@ -5,7 +5,7 @@ parent com.github.pxav.kelp - 0.0.5 + 0.1.0 4.0.0 @@ -45,7 +45,7 @@ com.github.pxav.kelp core - 0.0.5 + 0.1.0 provided diff --git a/v1_8_implementation/pom.xml b/v1_8_implementation/pom.xml index f39f45c0..96997378 100644 --- a/v1_8_implementation/pom.xml +++ b/v1_8_implementation/pom.xml @@ -5,7 +5,7 @@ com.github.pxav.kelp parent - 0.0.5 + 0.1.0 4.0.0 @@ -90,7 +90,7 @@ com.github.pxav.kelp core - 0.0.5 + 0.1.0 provided diff --git a/v_1_14_implementation/pom.xml b/v_1_14_implementation/pom.xml index 6ed2265e..f6f9a39a 100644 --- a/v_1_14_implementation/pom.xml +++ b/v_1_14_implementation/pom.xml @@ -5,7 +5,7 @@ parent com.github.pxav.kelp - 0.0.5 + 0.1.0 4.0.0 @@ -57,7 +57,7 @@ com.github.pxav.kelp core - 0.0.5 + 0.1.0 org.spigotmc From 358c4e58f07c197582c4f29469d0b211c3d19a7a Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 15:34:41 +0100 Subject: [PATCH 66/68] Add further information for central deployment in parent pom --- pom.xml | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 45fb6f00..b8301a6a 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,11 @@ central-deploy @@ -146,7 +150,7 @@ sign-artifacts - install + verify sign @@ -231,20 +235,6 @@ - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - install - - sign - - - - org.apache.maven.plugins maven-jar-plugin @@ -252,7 +242,6 @@ - \ No newline at end of file From 37b22e5e4fc597c58cc90d1d3e6dd7ada075cc38 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 15:58:02 +0100 Subject: [PATCH 67/68] Add changelog for 0.1.0 --- CHANGELOG/kelp-v0.1.0.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 CHANGELOG/kelp-v0.1.0.md diff --git a/CHANGELOG/kelp-v0.1.0.md b/CHANGELOG/kelp-v0.1.0.md new file mode 100644 index 00000000..bde9df21 --- /dev/null +++ b/CHANGELOG/kelp-v0.1.0.md @@ -0,0 +1,23 @@ +# v0.1.0 +> Release date: 28.01.2021 + +**The sidebar update**: +* Rework sidebar system: + * The old, annotation-based sidebar system using `@CreateSidebar` is not available anymore. Plugins that have been using this system will have to upgrade. + * Rework component system (stateful & stateless) + * Add new component `StatefulListComponent` to display dynamic lists in sidebars + * Developers can now choose between lazy updating (manipulating team prefixes, flicker free) or normal updating (resetting the scoreboard), which was not possible with the old system. + * Move version dependent scoreboard code out of the core module to the version modules (scoreboard team handling, etc.) + * Rework animation system by replacing it with a cluster-based system + * Add new events for handling sidebars: + * `KelpSidebarRenderEvent` + * `KelpSidebarUpdateEvent` + * `KelpSidebarRemoveEvent` + * Create new event base: `KelpPlayerEvent`, which should replace the `PlayerEvent` for better integration of `KelpPlayer` into event handling. So if you create anything player-related with custom events, use this class instead. + * Sidebar components and sidebar objects are now created using static factory methods. If you like the old approach more, you can still rely on the old factory classes such as `SidebarComponentFactory` + * Sidebars can now be properly removed/hidden from a player +* Documentation improvements in `KelpPlayer` and all newly added classes. +* `TextAnimations` can now be created using static factory methods. +* Add `ksidebar` command in testing-module to demonstrate some sidebar components. +* Refactor testing-module by assigning dedicated packages to each feature to test +* Fix bug that `TimeConverter` did not convert milliseconds <-> ticks correctly \ No newline at end of file From d39e8a80f475217c852434827222068ca99f7703 Mon Sep 17 00:00:00 2001 From: pxav Date: Thu, 28 Jan 2021 15:58:30 +0100 Subject: [PATCH 68/68] Update readme to 0.1.0 --- README.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3dddd31e..5cb0661d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Kelp -> Developed by pxav (c) 2019-2020 +> Developed by pxav (c) 2019-2021 ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/PXAV/kelp?include_prereleases&label=version&color=green) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.pxav.kelp/core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.pxav.kelp/core) ![GitHub issues](https://img.shields.io/github/issues/PXAV/kelp) ![GitHub pull requests](https://img.shields.io/github/issues-pr/PXAV/kelp) ![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/PXAV/kelp) ![Development Indicator](https://img.shields.io/badge/development-active-brightgreen) @@ -93,7 +93,8 @@ playerConnection.sendPacket(spawnPacket); - **Particle engine:** Easily create custom and prebuilt particle effects - **Schedulers**: Create sync and async schedulers and make use of powerful thread synchronization tools - **Events**: Custom events for NPCs, Inventories and more as well as new listener techniques - +- **Prompts**: Interact with your player by prompting input from chat, anvils ans signs. +- **and more** to discover in the [Wiki](https://github.com/PXAV/kelp/wiki) ## Support & Requirements @@ -119,28 +120,23 @@ There are version implementations for the following version implementations avai ## Downloading -#### Maven +### Maven ```xml com.github.pxav.kelp core - 0.0.4 + 0.1.0 ``` ### Gradle ```shell script -implementation 'com.github.pxav.kelp:core:0.0.4' +compile group: 'com.github.pxav.kelp', name: 'core', version: '0.1.0' ``` -### Bazel -```shell script -maven_jar( - name = "core", - artifact = "com.github.pxav.kelp:core:0.0.4", - sha1 = "4743f29c20f3b033de5fe8c1eddb374511fa31d8", -) -``` +### Other build tools +The dependency can be found here including suggestions for other build tools. +[Kelp Mavenrepository](https://mvnrepository.com/artifact/com.github.pxav.kelp/core/) ### Pre-built files If you are a server owner who simply needs the jar files or a developer who does not use a built tool like Maven, you can simply download the pre-built jar files from the [Releaes page](https://github.com/PXAV/kelp/releases). There you can find all versions, but it's recommended to use the latest.