diff --git a/plugin/bukkit/src/main/java/org/screamingsandals/bedwars/bukkit/listener/BungeeMotdListener.java b/plugin/bukkit/src/main/java/org/screamingsandals/bedwars/bukkit/listener/BungeeMotdListener.java index e2aa4a17b..198ed4904 100644 --- a/plugin/bukkit/src/main/java/org/screamingsandals/bedwars/bukkit/listener/BungeeMotdListener.java +++ b/plugin/bukkit/src/main/java/org/screamingsandals/bedwars/bukkit/listener/BungeeMotdListener.java @@ -23,6 +23,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.plugin.Plugin; +import org.screamingsandals.bedwars.api.game.Game; import org.screamingsandals.bedwars.config.MainConfig; import org.screamingsandals.bedwars.game.GameImpl; import org.screamingsandals.bedwars.game.GameManagerImpl; @@ -51,12 +52,24 @@ public void onServerListPing(ServerListPingEvent slpe) { return; } - GameImpl game = games.get(0); + Game gameA = null; + if (GameManagerImpl.getInstance().isDoGamePreselection()) { + gameA = GameManagerImpl.getInstance().getPreselectedGame(); + } + if (gameA == null) { + if (MainConfig.getInstance().node("bungee", "random-game-selection", "enabled").getBoolean()) { + gameA = GameManagerImpl.getInstance().getGameWithHighestPlayers().orElse(null); + } else { + gameA = games.get(0); + } + } - if (game == null) { + if (!(gameA instanceof GameImpl)) { return; } + var game = (GameImpl) gameA; + String string = null; switch (game.getStatus()) { diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/config/MainConfig.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/config/MainConfig.java index 1e7c77710..98f9b3181 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/config/MainConfig.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/config/MainConfig.java @@ -183,7 +183,10 @@ public void load() { .key("server").defValue("hub") .key("auto-game-connect").defValue(false) .key("kick-when-proxy-too-slow").defValue(true) - .key("select-random-game").defValue(true) + .section("random-game-selection") + .key("enabled").migrateOldAbsoluteKey("bungee", "select-random-game").defValue(true) + .key("preselect-games").defValue(true) + .back() .section("motd") .key("enabled").defValue(false) .key("waiting").defValue("%name%: Waiting for players [%current%/%max%]") @@ -341,6 +344,7 @@ public void load() { .key("items-on-row").defValue(LocalOptions.ITEMS_ON_ROW) .key("show-page-numbers").defValue(LocalOptions.SHOW_PAGE_NUMBER) .key("inventory-type").defValue(LocalOptions.INVENTORY_TYPE) + .key("allow-execution-of-console-commands").defValue(true) .back() .section("items") .key("jointeam").defValue("COMPASS") diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/database/DatabaseManager.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/database/DatabaseManager.java index 7aaf8b589..12618ce88 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/database/DatabaseManager.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/database/DatabaseManager.java @@ -101,7 +101,7 @@ public void initialize() { driverClassName = reader.readLine(); if (driverClassName != null) { // All characters after '#' should be ignored, whitespaces around the qualified name are also ignored - driverClassName = driver.split("#", 2)[0].trim(); + driverClassName = driverClassName.split("#", 2)[0].trim(); } } while (driverClassName != null && driverClassName.isEmpty()); } diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameImpl.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameImpl.java index 4f78d4995..382b9f491 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameImpl.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameImpl.java @@ -2213,6 +2213,8 @@ public void run() { } if (isBungeeEnabled()) { + GameManagerImpl.getInstance().reselectGame(); + preServerRestart = true; if (!getConnectedPlayers().isEmpty()) { @@ -2226,6 +2228,8 @@ public void run() { Server.getConsoleSender().tryToDispatchCommand("restart"); } else if (MainConfig.getInstance().node("bungee", "serverStop").getBoolean()) { Server.shutdown(); + } else { + preServerRestart = false; } }, 30, TaskerTime.TICKS); } @@ -2248,7 +2252,7 @@ public void rebuild() { }); otherVisuals.clear(); Debug.info(name + ": rebuilding starts"); - teamsInGame.forEach(TeamImpl::destroy); + teams.forEach(TeamImpl::destroy); // Not destroyed teams may not be in teamsInGame teamsInGame.clear(); activeSpecialItems.clear(); activeDelays.clear(); diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameManagerImpl.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameManagerImpl.java index 14549f360..14acec274 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameManagerImpl.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/game/GameManagerImpl.java @@ -19,12 +19,18 @@ package org.screamingsandals.bedwars.game; +import lombok.Getter; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.screamingsandals.bedwars.api.game.Game; import org.screamingsandals.bedwars.api.game.GameManager; +import org.screamingsandals.bedwars.config.MainConfig; import org.screamingsandals.bedwars.utils.MiscUtils; import org.screamingsandals.bedwars.variants.VariantManagerImpl; import org.screamingsandals.lib.plugin.ServiceManager; +import org.screamingsandals.lib.tasker.DefaultThreads; +import org.screamingsandals.lib.tasker.Tasker; import org.screamingsandals.lib.utils.annotations.Service; import org.screamingsandals.lib.utils.annotations.ServiceDependencies; import org.screamingsandals.lib.utils.annotations.methods.OnPostEnable; @@ -49,6 +55,11 @@ public class GameManagerImpl implements GameManager { private final LoggerWrapper logger; private final List games = new LinkedList<>(); + @Getter + private @Nullable Game preselectedGame; + @Getter + private boolean doGamePreselection; + public static GameManagerImpl getInstance() { return ServiceManager.get(GameManagerImpl.class); } @@ -141,14 +152,33 @@ public void onPostEnable() { e.printStackTrace(); } } + + if ( + MainConfig.getInstance().node("bungee", "enabled").getBoolean() + && MainConfig.getInstance().node("bungee", "random-game-selection", "enabled").getBoolean() + && MainConfig.getInstance().node("bungee", "random-game-selection", "preselect-games").getBoolean() + ) { + Tasker.run(DefaultThreads.GLOBAL_THREAD, () -> { + preselectedGame = getGameWithHighestPlayers().orElse(null); + doGamePreselection = true; + }); + } } @OnPreDisable public void onPreDisable() { + preselectedGame = null; + doGamePreselection = false; games.forEach(GameImpl::stop); games.clear(); } + public void reselectGame() { + if (doGamePreselection) { + preselectedGame = getGameWithHighestPlayers().orElse(null); + } + } + @Override public Optional getGameWithHighestPlayers() { return getGameWithHighestPlayers(false); diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/inventories/ShopInventory.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/inventories/ShopInventory.java index aea92cb79..82251bb15 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/inventories/ShopInventory.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/inventories/ShopInventory.java @@ -277,6 +277,7 @@ private void loadNewShop(String name, File file) { .genericShop(true) .genericShopPriceTypeRequired(true) .animationsEnabled(true) + .allowAccessToConsole(MainConfig.getInstance().node("shop", "allow-execution-of-console-commands").getBoolean()) .categoryOptions(localOptionsBuilder -> localOptionsBuilder .backItem(mainConfig.readDefinedItem("shopback", "BARRIER"), itemBuilder -> @@ -468,7 +469,7 @@ private void handleBuy(OnTradeEvent event) { } var originalMaxStackSize = newItem.getMaterial().maxStackSize(); - if (clickType.isShiftClick() && originalMaxStackSize > 1) { + if (!event.isHasAnyExecutions() && clickType.isShiftClick() && originalMaxStackSize > 1) { double priceOfOne = (double) priceAmount / amount; double maxStackSize; int finalStackSize; @@ -528,9 +529,13 @@ else if (propertyData.get(PermaItemListener.getPermItemPropKey()) != null) { } event.sellStack(materialItem); - var notFit = event.buyStack(newItem); - if (!notFit.isEmpty()) { - notFit.forEach(stack -> Entities.dropItem(stack, player.getLocation())); + if (event.isHasAnyExecutions()) { + event.setRunExecutions(true); // SIv2 will handle that when this is set to true + } else { + var notFit = event.buyStack(newItem); + if (!notFit.isEmpty()) { + notFit.forEach(stack -> Entities.dropItem(stack, player.getLocation())); + } } if (!mainConfig.node("removePurchaseMessages").getBoolean()) { diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/listener/PlayerListener.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/listener/PlayerListener.java index 4bcf1303d..8356c987c 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/listener/PlayerListener.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/listener/PlayerListener.java @@ -23,6 +23,7 @@ import org.screamingsandals.bedwars.PlatformService; import org.screamingsandals.bedwars.api.config.GameConfigurationContainer; import org.screamingsandals.bedwars.api.events.TargetInvalidationReason; +import org.screamingsandals.bedwars.api.game.Game; import org.screamingsandals.bedwars.api.game.GameStatus; import org.screamingsandals.bedwars.commands.BedWarsPermission; import org.screamingsandals.bedwars.commands.admin.JoinTeamCommand; @@ -343,21 +344,29 @@ public void onPlayerJoin(PlayerJoinEvent event) { try { Debug.info("Selecting game for " + event.player().getName()); var gameManager = GameManagerImpl.getInstance(); - var game = ( - MainConfig.getInstance().node("bungee", "select-random-game").getBoolean() - ? gameManager.getGameWithHighestPlayers() - : gameManager.getFirstWaitingGame() - ).or(gameManager::getFirstRunningGame); - if (game.isEmpty()) { // still nothing? + Game game = null; + if (MainConfig.getInstance().node("bungee", "random-game-selection", "enabled").getBoolean()) { + if (gameManager.isDoGamePreselection()) { + game = gameManager.getPreselectedGame(); + } + } + if (game == null) { + game = ( + MainConfig.getInstance().node("bungee", "random-game-selection", "enabled").getBoolean() + ? gameManager.getGameWithHighestPlayers() + : gameManager.getFirstWaitingGame() + ).or(gameManager::getFirstRunningGame).orElse(null); + } + if (game == null) { // still nothing? if (!player.hasPermission(BedWarsPermission.ADMIN_PERMISSION.asPermission())) { Debug.info(event.player().getName() + " is not connecting to any game! Kicking..."); BungeeUtils.movePlayerToBungeeServer(player, false); } return; } - Debug.info(event.player().getName() + " is connecting to " + game.get().getName()); + Debug.info(event.player().getName() + " is connecting to " + game.getName()); - game.get().joinToGame(PlayerManagerImpl.getInstance().getPlayerOrCreate(player)); + game.joinToGame(PlayerManagerImpl.getInstance().getPlayerOrCreate(player)); } catch (NullPointerException ignored) { if (!player.hasPermission(BedWarsPermission.ADMIN_PERMISSION.asPermission())) { Debug.info(event.player().getName() + " is not connecting to any game! Kicking..."); diff --git a/plugin/common/src/main/java/org/screamingsandals/bedwars/placeholderapi/BedwarsExpansion.java b/plugin/common/src/main/java/org/screamingsandals/bedwars/placeholderapi/BedwarsExpansion.java index 16f5aaa0c..58fe0f0a9 100644 --- a/plugin/common/src/main/java/org/screamingsandals/bedwars/placeholderapi/BedwarsExpansion.java +++ b/plugin/common/src/main/java/org/screamingsandals/bedwars/placeholderapi/BedwarsExpansion.java @@ -21,11 +21,17 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.screamingsandals.bedwars.api.config.GameConfigurationContainer; import org.screamingsandals.bedwars.api.game.GameStatus; +import org.screamingsandals.bedwars.config.MainConfig; import org.screamingsandals.bedwars.game.GameImpl; import org.screamingsandals.bedwars.game.GameManagerImpl; +import org.screamingsandals.bedwars.game.TeamImpl; +import org.screamingsandals.bedwars.game.target.ATargetCountdown; +import org.screamingsandals.bedwars.game.target.TargetBlockImpl; import org.screamingsandals.bedwars.player.PlayerManagerImpl; import org.screamingsandals.bedwars.statistics.PlayerStatisticManager; +import org.screamingsandals.lib.lang.Message; import org.screamingsandals.lib.placeholders.PlaceholderExpansion; import org.screamingsandals.lib.player.Players; import org.screamingsandals.lib.sender.MultiPlatformOfflinePlayer; @@ -49,19 +55,67 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull if (identifier.startsWith("game_")) { var gameName = identifier.substring(5); var index = gameName.lastIndexOf("_"); - var operation = gameName.substring(index + 1).toLowerCase(); + var operation = gameName.substring(index + 1).toLowerCase(Locale.ROOT); if (operation.equals("teams")) { index = gameName.lastIndexOf("_", index - 1); - operation = gameName.substring(index + 1).toLowerCase(); + operation = gameName.substring(index + 1).toLowerCase(Locale.ROOT); + } else if (gameName.contains("_team_")) { + index = gameName.indexOf("_team_"); + operation = gameName.substring(index + 1).toLowerCase(Locale.ROOT); } gameName = gameName.substring(0, index); var gameOpt = GameManagerImpl.getInstance().getGame(gameName); if (gameOpt.isPresent()) { var game = gameOpt.get(); + if (operation.startsWith("team_")) { + index = operation.lastIndexOf("_"); + if (index != -1) { + var teamName = operation.substring(5, index); + var teamOperation = operation.substring(index + 1).toLowerCase(Locale.ROOT); + + TeamImpl team = game.getTeamFromName(teamName); + + if (team != null) { + switch (teamOperation) { + case "colored": + return Component.text(team.getName(), team.getColor().getTextColor()); + case "color": + return Component.text("", team.getColor().getTextColor()); + case "ingame": + return Component.text(team.isStarted() ? "yes" : "no"); + case "players": + return Component.text(team.countConnectedPlayers()); + case "maxplayers": + return Component.text(team.getMaxPlayers()); + case "bed": // 0.2.x + case "targetvalid": + return Component.text(team.isStarted() && team.getTarget().isValid() ? "yes" : "no"); + case "bedsymbol": // 0.2.x + case "targetvalidsymbol": { + if (team.isStarted() && team.getTarget().isValid()) { + if (team.getTarget() instanceof TargetBlockImpl && ((TargetBlockImpl) team.getTarget()).isEmpty()) { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_ANCHOR_EMPTY, "")).asComponent(); + } else if (team.getTarget() instanceof ATargetCountdown && ((ATargetCountdown) team.getTarget()).getRemainingTime() < 30) { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TEAM_COUNT, "")) + .placeholder("count", Component.text(((ATargetCountdown) team.getTarget()).getRemainingTime() + " ")) + .asComponent(); + } else { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TARGET_BLOCK_EXISTS, "")).asComponent(); + } + } else { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TARGET_BLOCK_LOST, "")).asComponent(); + } + } + case "teamchests": + return Component.text(team.countTeamChests()); + } + } + } + } switch (operation) { case "name": return Component.text(game.getName()); - case "displayName": + case "displayname": return game.getDisplayNameComponent().asComponent(); case "players": return Component.text(game.countConnectedPlayers()); @@ -69,6 +123,34 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull return Component.text(game.getMaxPlayers()); case "minplayers": return Component.text(game.getMinPlayers()); + case "time": + return Component.text(game.getTimeLeft()); + case "timeformat": + return Component.text(game.getFormattedTimeLeft()); + case "elapsedtime": + switch (game.getStatus()) { + case WAITING: + return Component.text(game.getLobbyCountdown() - game.getTimeLeft()); + case RUNNING: + return Component.text(game.getGameTime() - game.getTimeLeft()); + case GAME_END_CELEBRATING: + return Component.text(game.getPostGameWaiting() - game.getTimeLeft()); + case REBUILDING: + case DISABLED: + return Component.text("0"); + } + case "elapsedtimeformat": + switch (game.getStatus()) { + case WAITING: + return Component.text(game.getFormattedTimeLeft(game.getLobbyCountdown() - game.getTimeLeft())); + case RUNNING: + return Component.text(game.getFormattedTimeLeft(game.getGameTime() - game.getTimeLeft())); + case GAME_END_CELEBRATING: + return Component.text(game.getFormattedTimeLeft(game.getPostGameWaiting() - game.getTimeLeft())); + case REBUILDING: + case DISABLED: + return Component.text(game.getFormattedTimeLeft(0)); + } case "world": return Component.text(game.getWorld().getName()); case "state": @@ -101,10 +183,10 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull } var playerName = identifier.substring(11); var index = playerName.lastIndexOf("_"); - var operation = playerName.substring(index + 1).toLowerCase(); + var operation = playerName.substring(index + 1).toLowerCase(Locale.ROOT); if (operation.equals("beds")) { index = playerName.lastIndexOf("_", index - 1); - operation = playerName.substring(index + 1).toLowerCase(); + operation = playerName.substring(index + 1).toLowerCase(Locale.ROOT); } playerName = playerName.substring(0, index); @@ -142,17 +224,111 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull } if (identifier.startsWith("current_")) { + if (identifier.toLowerCase(Locale.ROOT).startsWith("current_game_team_")) { + String operation = identifier.substring(18); + int index = operation.lastIndexOf("_"); + if (index != -1) { + String teamName = operation.substring(0, index); + String teamOperation = operation.substring(index + 1).toLowerCase(Locale.ROOT); + + var game = PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()).orElse(null); + if (game != null) { + TeamImpl team = game.getTeamFromName(teamName); + + if (team != null) { + switch (teamOperation) { + case "colored": + return Component.text(team.getName(), team.getColor().getTextColor()); + case "color": + return Component.text("", team.getColor().getTextColor()); + case "ingame": + return Component.text(team.isStarted() ? "yes" : "no"); + case "players": + return Component.text(team.countConnectedPlayers()); + case "maxplayers": + return Component.text(team.getMaxPlayers()); + case "bed": // 0.2.x + case "targetvalid": + return Component.text(team.isStarted() && team.getTarget().isValid() ? "yes" : "no"); + case "bedsymbol": // 0.2.x + case "targetvalidsymbol": { + if (team.isStarted() && team.getTarget().isValid()) { + if (team.getTarget() instanceof TargetBlockImpl && ((TargetBlockImpl) team.getTarget()).isEmpty()) { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_ANCHOR_EMPTY, "")).asComponent(); + } else if (team.getTarget() instanceof ATargetCountdown && ((ATargetCountdown) team.getTarget()).getRemainingTime() < 30) { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TEAM_COUNT, "")) + .placeholder("count", Component.text(((ATargetCountdown) team.getTarget()).getRemainingTime() + " ")) + .asComponent(); + } else { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TARGET_BLOCK_EXISTS, "")).asComponent(); + } + } else { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TARGET_BLOCK_LOST, "")).asComponent(); + } + } + case "teamchests": + return Component.text(team.countTeamChests()); + } + } + } + } + } // current game - switch (identifier.toLowerCase().substring(8)) { + switch (identifier.toLowerCase(Locale.ROOT).substring(8)) { case "game": return Component.text(PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()).map(GameImpl::getName).orElse("none")); + case "game_displayname": + return PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()).map(GameImpl::getDisplayNameComponent).orElseGet(() -> Component.text("none")); case "game_players": return PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()).map(g -> Component.text(g.countConnectedPlayers())).orElseGet(() -> Component.text("0")); - case "game_time": + case "game_time": { var m_Game = PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()); - if (m_Game.isEmpty() || m_Game.get().getStatus() != GameStatus.RUNNING) + if (m_Game.isEmpty() || m_Game.get().getStatus() != GameStatus.RUNNING) { return Component.text("0"); + } + return Component.text(m_Game.get().getTimeLeft()); + } + case "game_timeformat": { + var m_Game = PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()); + if (m_Game.isEmpty() || m_Game.get().getStatus() != GameStatus.RUNNING) { + return Component.text("0"); + } return Component.text(m_Game.get().getFormattedTimeLeft()); + } + case "game_elapsedtime": { + var m_Game = PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()); + if (m_Game.isEmpty() || m_Game.get().getStatus() != GameStatus.RUNNING) { + return Component.text("0"); + } + switch (m_Game.get().getStatus()) { + case WAITING: + return Component.text(m_Game.get().getLobbyCountdown() - m_Game.get().getTimeLeft()); + case RUNNING: + return Component.text(m_Game.get().getGameTime() - m_Game.get().getTimeLeft()); + case GAME_END_CELEBRATING: + return Component.text(m_Game.get().getPostGameWaiting() - m_Game.get().getTimeLeft()); + case REBUILDING: + case DISABLED: + return Component.text("0"); + } + } + case "game_elapsedtimeformat": { + var m_Game = PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()); + if (m_Game.isEmpty() || m_Game.get().getStatus() != GameStatus.RUNNING) { + return Component.text("0"); + } + switch (m_Game.get().getStatus()) { + case WAITING: + return Component.text(m_Game.get().getFormattedTimeLeft(m_Game.get().getLobbyCountdown() - m_Game.get().getTimeLeft())); + case RUNNING: + return Component.text(m_Game.get().getFormattedTimeLeft(m_Game.get().getGameTime() - m_Game.get().getTimeLeft())); + case GAME_END_CELEBRATING: + return Component.text(m_Game.get().getFormattedTimeLeft(m_Game.get().getPostGameWaiting() - m_Game.get().getTimeLeft())); + case REBUILDING: + case DISABLED: + return Component.text("0"); + } + } case "game_maxplayers": return PlayerManagerImpl.getInstance().getGameOfPlayer(player.getUuid()).map(g -> Component.text(g.getMaxPlayers())).orElseGet(() -> Component.text("0")); case "game_minplayers": @@ -224,7 +400,8 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull } } return Component.text("0"); - case "team_bed": + case "team_bed": // 0.2.x + case "team_targetvalid": if (PlayerManagerImpl.getInstance().isPlayerInGame(player.getUuid())) { var gPlayer = PlayerManagerImpl.getInstance().getPlayer(player.getUuid()).orElseThrow(); var game = gPlayer.getGame(); @@ -234,6 +411,28 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull } } return Component.text("no"); + case "team_bedsymbol": // 0.2.x + case "team_targetvalidsymbol": { + if (PlayerManagerImpl.getInstance().isPlayerInGame(player.getUuid())) { + var gPlayer = PlayerManagerImpl.getInstance().getPlayer(player.getUuid()).orElseThrow(); + var game = gPlayer.getGame(); + var team = game.getPlayerTeam(gPlayer); + if (team != null && team.getTarget().isValid()) { + if (team.getTarget() instanceof TargetBlockImpl && ((TargetBlockImpl) team.getTarget()).isEmpty()) { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_ANCHOR_EMPTY, "")).asComponent(); + } else if (team.getTarget() instanceof ATargetCountdown && ((ATargetCountdown) team.getTarget()).getRemainingTime() < 30) { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TEAM_COUNT, "")) + .placeholder("count", Component.text(((ATargetCountdown) team.getTarget()).getRemainingTime() + " ")) + .asComponent(); + } else { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TARGET_BLOCK_EXISTS, "")).asComponent(); + } + } else { + return Message.ofRichText(game.getConfigurationContainer().getOrDefault(GameConfigurationContainer.SIDEBAR_GAME_TEAM_PREFIXES_TARGET_BLOCK_LOST, "")).asComponent(); + } + } + return Message.ofRichText(MainConfig.getInstance().node("sidebar", "game", "team-prefixes", "target-block-lost").getString("no")).asComponent(); + } case "team_teamchests": if (PlayerManagerImpl.getInstance().isPlayerInGame(player.getUuid())) { var gPlayer = PlayerManagerImpl.getInstance().getPlayer(player.getUuid()).orElseThrow(); @@ -260,7 +459,7 @@ public Component onRequest(@Nullable MultiPlatformOfflinePlayer player, @NotNull return null; } - switch (identifier.toLowerCase().substring(6)) { + switch (identifier.toLowerCase(Locale.ROOT).substring(6)) { case "deaths": return Component.text(stats.getDeaths()); case "destroyed_beds":