diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/UHCReloaded.java b/src/main/java/eu/carrade/amaury/UHCReloaded/UHCReloaded.java index cb8ffff..21e5de3 100644 --- a/src/main/java/eu/carrade/amaury/UHCReloaded/UHCReloaded.java +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/UHCReloaded.java @@ -29,7 +29,6 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-B license and that you accept its terms. */ - package eu.carrade.amaury.UHCReloaded; import eu.carrade.amaury.UHCReloaded.borders.BorderManager; @@ -52,6 +51,7 @@ import eu.carrade.amaury.UHCReloaded.recipes.RecipesManager; import eu.carrade.amaury.UHCReloaded.scoreboard.ScoreboardManager; import eu.carrade.amaury.UHCReloaded.spawns.SpawnsManager; +import eu.carrade.amaury.UHCReloaded.spectators.SpectatorsManager; import eu.carrade.amaury.UHCReloaded.task.UpdateTimerTask; import eu.carrade.amaury.UHCReloaded.teams.TeamChatManager; import eu.carrade.amaury.UHCReloaded.teams.TeamManager; @@ -69,6 +69,7 @@ public class UHCReloaded extends ZPlugin private TeamManager teamManager = null; private SpawnsManager spawnsManager = null; private UHGameManager gameManager = null; + private SpectatorsManager spectatorsManager = null; private ScoreboardManager scoreboardManager = null; private MOTDManager motdManager = null; private PlayerListHeaderFooterManager playerListHeaderFooterManager = null; @@ -109,10 +110,17 @@ public void onEnable() loadComponents(SidebarScoreboard.class); + wbintegration = new UHWorldBorderIntegration(); spintegration = new UHSpectatorPlusIntegration(this); dynmapintegration = new UHDynmapIntegration(this); + // Needed to avoid a NoClassDefFoundError. + // I don't like this way of doing this, but else, the plugin will not load without ProtocolLib. + protocollibintegrationwrapper = new UHProtocolLibIntegrationWrapper(this); + + + spectatorsManager = SpectatorsManager.getInstance(); teamManager = new TeamManager(this); gameManager = new UHGameManager(this); spawnsManager = new SpawnsManager(this); @@ -131,10 +139,6 @@ public void onEnable() motdManager = new MOTDManager(this); playerListHeaderFooterManager = new PlayerListHeaderFooterManager(); - // Needed to avoid a NoClassDefFoundError. - // I don't like this way of doing this, but else, the plugin will not load without ProtocolLib. - protocollibintegrationwrapper = new UHProtocolLibIntegrationWrapper(this); - UHCommandExecutor executor = new UHCommandExecutor(this); for (String commandName : getDescription().getCommands().keySet()) { @@ -214,6 +218,14 @@ public UHGameManager getGameManager() return gameManager; } + /** + * @return the spectators manager. + */ + public SpectatorsManager getSpectatorsManager() + { + return spectatorsManager; + } + /** * Returns the scoreboard manager. * diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/commands/commands/uh/UHSpectatorsCommand.java b/src/main/java/eu/carrade/amaury/UHCReloaded/commands/commands/uh/UHSpectatorsCommand.java index 3ddf960..0629eaf 100644 --- a/src/main/java/eu/carrade/amaury/UHCReloaded/commands/commands/uh/UHSpectatorsCommand.java +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/commands/commands/uh/UHSpectatorsCommand.java @@ -173,11 +173,6 @@ public List help(CommandSender sender) help.add(i.t("cmd.specHelpTitle")); - if (!p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) - { - help.add(i.t("cmd.specHelpNoticeSpectatorPlusNotInstalled")); - } - help.add(i.t("cmd.specHelpAdd")); help.add(i.t("cmd.specHelpRemove")); help.add(i.t("cmd.specHelpList")); diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/game/UHGameManager.java b/src/main/java/eu/carrade/amaury/UHCReloaded/game/UHGameManager.java index 383b9f2..0e62569 100644 --- a/src/main/java/eu/carrade/amaury/UHCReloaded/game/UHGameManager.java +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/game/UHGameManager.java @@ -183,10 +183,7 @@ public void run() }, 20L); // Disable the spectator mode if the game is not started. - if (p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) - { - p.getSpectatorPlusIntegration().getSPAPI().setSpectating(player, false); - } + p.getSpectatorsManager().setSpectating(player, false); // Resets the achievements if (p.getConfig().getBoolean("achievements.resetAchievementsAtStartup", true)) @@ -333,12 +330,9 @@ public void start(final CommandSender sender, final Boolean slow, Boolean ignore /** Initialization of the spectator mode **/ - if (p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) + for (Player player : Bukkit.getOnlinePlayers()) { - for (Player player : Bukkit.getOnlinePlayers()) - { - p.getSpectatorPlusIntegration().getSPAPI().setSpectating(player, spectators.contains(player.getUniqueId())); - } + p.getSpectatorsManager().setSpectating(player, spectators.contains(player.getUniqueId())); } diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/listeners/GameListener.java b/src/main/java/eu/carrade/amaury/UHCReloaded/listeners/GameListener.java index db1b382..cd5dbc5 100644 --- a/src/main/java/eu/carrade/amaury/UHCReloaded/listeners/GameListener.java +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/listeners/GameListener.java @@ -47,6 +47,7 @@ import eu.carrade.amaury.UHCReloaded.misc.RuntimeCommandsExecutor; import eu.carrade.amaury.UHCReloaded.teams.UHTeam; import eu.carrade.amaury.UHCReloaded.utils.UHSound; +import fr.zcraft.zlib.tools.runners.RunTask; import fr.zcraft.zlib.tools.text.Titles; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -73,20 +74,25 @@ import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerStatisticIncrementEvent; import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.UUID; public class GameListener implements Listener { + private final UHCReloaded p; + private final I18n i; + + private final Set enableSpectatorModeOnRespawn = new HashSet<>(); - private UHCReloaded p = null; - private I18n i = null; public GameListener(UHCReloaded p) { @@ -140,6 +146,9 @@ public void onPlayerDeath(final PlayerDeathEvent ev) // Removes the player from the alive players. this.p.getGameManager().addDead(ev.getEntity()); + // Remember to enable spectator mode on respawn + enableSpectatorModeOnRespawn.add(ev.getEntity().getUniqueId()); + // Kicks the player if needed. if (this.p.getConfig().getBoolean("death.kick.do", true)) { @@ -298,6 +307,25 @@ public void run() } + /** + * Used to enable the spectator mode when the player respawns. + */ + @EventHandler + public void onPlayerRespawn(final PlayerRespawnEvent ev) + { + if (enableSpectatorModeOnRespawn.remove(ev.getPlayer().getUniqueId())) + { + RunTask.nextTick(new Runnable() { + @Override + public void run() + { + p.getSpectatorsManager().setSpectating(ev.getPlayer(), true); + } + }); + } + } + + /** * Used to disable all damages if the game is not started. * @@ -482,13 +510,6 @@ public void run() ev.getPlayer().sendMessage(i.t("load.WBNotInstalled3")); } - // The same for SpectatorPlus - if (!p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) - { - ev.getPlayer().sendMessage(i.t("load.SPNotInstalled1")); - ev.getPlayer().sendMessage(i.t("load.SPNotInstalled2")); - } - // The same for ProtocolLib if (!p.getProtocolLibIntegrationWrapper().isProtocolLibIntegrationEnabled()) { @@ -526,10 +547,9 @@ public void run() // If the player is a new one, the game is started, and the option is set to true... if (p.getGameManager().isGameRunning() && p.getConfig().getBoolean("spectatorModeWhenNewPlayerJoinAfterStart") - && !p.getGameManager().getAlivePlayers().contains(ev.getPlayer()) - && p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) + && !p.getGameManager().getAlivePlayers().contains(ev.getPlayer())) { - p.getSpectatorPlusIntegration().getSPAPI().setSpectating(ev.getPlayer(), true); + p.getSpectatorsManager().setSpectating(ev.getPlayer(), true); } } @@ -772,10 +792,7 @@ public void run() public void onPlayerResurrected(UHPlayerResurrectedEvent ev) { // Spectator mode disabled - if (p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) - { - p.getSpectatorPlusIntegration().getSPAPI().setSpectating(ev.getPlayer(), false); - } + p.getSpectatorsManager().setSpectating(ev.getPlayer(), false); // Death point removed on the dynmap p.getDynmapIntegration().hideDeathLocation(ev.getPlayer()); diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/SPlusSpectatorsManager.java b/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/SPlusSpectatorsManager.java new file mode 100644 index 0000000..7ab6344 --- /dev/null +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/SPlusSpectatorsManager.java @@ -0,0 +1,62 @@ +/* + * Copyright or © or Copr. Amaury Carrade (2014 - 2016) + * + * http://amaury.carrade.eu + * + * This software is governed by the CeCILL-B license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-B + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-B license and that you accept its terms. + */ +package eu.carrade.amaury.UHCReloaded.spectators; + +import eu.carrade.amaury.UHCReloaded.UHCReloaded; +import org.bukkit.entity.Player; + + +/** + * Spectators managed through the SpectatorsPlus Bukkit plugin by PGMann and AmauryPi. + */ +public class SPlusSpectatorsManager extends SpectatorsManager +{ + UHCReloaded p; + + public SPlusSpectatorsManager() + { + p = UHCReloaded.get(); + } + + @Override + public void setSpectating(final Player player, final boolean spectating) + { + if (player != null && p.getSpectatorPlusIntegration().isSPIntegrationEnabled()) + p.getSpectatorPlusIntegration().getSPAPI().setSpectating(player, spectating); + } + + @Override + public boolean isSpectating(Player player) + { + return player != null && p.getSpectatorPlusIntegration().isSPIntegrationEnabled() && p.getSpectatorPlusIntegration().getSPAPI().isSpectator(player); + } +} diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/SpectatorsManager.java b/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/SpectatorsManager.java new file mode 100644 index 0000000..8acba07 --- /dev/null +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/SpectatorsManager.java @@ -0,0 +1,98 @@ +/* + * Copyright or © or Copr. Amaury Carrade (2014 - 2016) + * + * http://amaury.carrade.eu + * + * This software is governed by the CeCILL-B license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-B + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-B license and that you accept its terms. + */ +package eu.carrade.amaury.UHCReloaded.spectators; + +import eu.carrade.amaury.UHCReloaded.UHCReloaded; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.UUID; + + +/** + * Represents a spectator manager, able to put players in or remove players from spectator mode. + */ +public abstract class SpectatorsManager +{ + /** + * Changes the spectating mode of a player. + * + * @param player The player. + * @param spectating {@code true} to enable the spectator mode; {@code false} to disable it. + */ + public abstract void setSpectating(final Player player, final boolean spectating); + + /** + * Checks if the given player is currently spectating. + * + * @param player The player. + * + * @return {@code true} if spectating. + */ + public abstract boolean isSpectating(final Player player); + + /** + * Changes the spectating mode of a player. + * + * @param playerID The player's UUID. + * @param spectating {@code true} to enable the spectator mode; {@code false} to disable it. + */ + public void setSpectating(final UUID playerID, final boolean spectating) + { + setSpectating(Bukkit.getPlayer(playerID), spectating); + } + + /** + * Checks if the given player is currently spectating. + * + * @param playerID The player's UUID. + * + * @return {@code true} if spectating. + */ + public boolean isSpectating(final UUID playerID) + { + return isSpectating(Bukkit.getPlayer(playerID)); + } + + + /** + * @return an instance of a {@link SpectatorsManager}: {@link SPlusSpectatorsManager} if the + * SpectatorPlus plugin is available; {@link VanillaSpectatorsManager} else. + */ + public static SpectatorsManager getInstance() + { + if (UHCReloaded.get().getSpectatorPlusIntegration().isSPIntegrationEnabled()) + return new SPlusSpectatorsManager(); + else + return new VanillaSpectatorsManager(); + } +} diff --git a/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/VanillaSpectatorsManager.java b/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/VanillaSpectatorsManager.java new file mode 100644 index 0000000..81d175c --- /dev/null +++ b/src/main/java/eu/carrade/amaury/UHCReloaded/spectators/VanillaSpectatorsManager.java @@ -0,0 +1,83 @@ +/* + * Copyright or © or Copr. Amaury Carrade (2014 - 2016) + * + * http://amaury.carrade.eu + * + * This software is governed by the CeCILL-B license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-B + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-B license and that you accept its terms. + */ +package eu.carrade.amaury.UHCReloaded.spectators; + + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + + +/** + * Vanilla spectator mode + */ +public class VanillaSpectatorsManager extends SpectatorsManager +{ + /** + * Stores the previous gamemodes of the players. + */ + private Map oldGameModes = new HashMap<>(); + + + @Override + public void setSpectating(final Player player, final boolean spectating) + { + if (player == null) + return; + + if (spectating) + { + if (player.getGameMode() != GameMode.SPECTATOR) + { + oldGameModes.put(player.getUniqueId(), player.getGameMode()); + player.setGameMode(GameMode.SPECTATOR); + } + } + else + { + GameMode previousMode = oldGameModes.get(player.getUniqueId()); + player.setGameMode(previousMode != null ? previousMode : Bukkit.getDefaultGameMode()); + + oldGameModes.remove(player.getUniqueId()); + } + } + + @Override + public boolean isSpectating(Player player) + { + return player != null && player.getGameMode() == GameMode.SPECTATOR; + } +}