├── .gitignore ├── API ├── pom.xml └── src │ └── main │ └── java │ └── ca │ └── nicbo │ └── invadedlandsevents │ └── api │ ├── InvadedLandsEvents.java │ ├── InvadedLandsEventsProvider.java │ ├── configuration │ ├── ConfigHandler.java │ ├── ConfigSection.java │ ├── ConfigValueType.java │ ├── ConfigurationHandler.java │ ├── ConfigurationManager.java │ ├── MessagesHandler.java │ └── WandLocationHolder.java │ ├── data │ ├── PlayerData.java │ ├── PlayerDataManager.java │ └── PlayerEventData.java │ ├── event │ ├── Event.java │ ├── EventManager.java │ ├── EventState.java │ ├── EventType.java │ └── event │ │ ├── EventEvent.java │ │ ├── EventPostCountdownEvent.java │ │ ├── EventPostEndEvent.java │ │ ├── EventPostForceEndEvent.java │ │ ├── EventPostStartEvent.java │ │ ├── EventPostStopEvent.java │ │ ├── EventPreCountdownEvent.java │ │ ├── EventPreEndEvent.java │ │ ├── EventPreForceEndEvent.java │ │ ├── EventPreStartEvent.java │ │ ├── EventPreStopEvent.java │ │ └── player │ │ ├── EventPlayerEvent.java │ │ ├── EventPlayerPostJoinEvent.java │ │ ├── EventPlayerPostLeaveEvent.java │ │ ├── EventPlayerPostSpectateEvent.java │ │ ├── EventPlayerPostWinEvent.java │ │ ├── EventPlayerPreJoinEvent.java │ │ ├── EventPlayerPreLeaveEvent.java │ │ ├── EventPlayerPreSpectateEvent.java │ │ └── EventPlayerPreWinEvent.java │ ├── gui │ ├── Button.java │ ├── Gui.java │ ├── GuiManager.java │ └── event │ │ ├── GuiCloseEvent.java │ │ ├── GuiEvent.java │ │ └── GuiOpenEvent.java │ ├── kit │ └── Kit.java │ ├── permission │ └── EventPermission.java │ ├── region │ └── CuboidRegion.java │ └── util │ ├── Callback.java │ └── Validate.java ├── LICENSE.md ├── Plugin ├── pom.xml └── src │ └── main │ ├── java │ └── ca │ │ └── nicbo │ │ └── invadedlandsevents │ │ ├── InvadedLandsEventsPlugin.java │ │ ├── command │ │ ├── EventCommand.java │ │ └── EventConfigCommand.java │ │ ├── compatibility │ │ ├── Colour.java │ │ ├── CompatibleMaterial.java │ │ └── NMSVersion.java │ │ ├── configuration │ │ ├── ConfigSerialization.java │ │ ├── ConfigurationFile.java │ │ ├── InvadedConfigHandler.java │ │ ├── InvadedConfigSection.java │ │ ├── InvadedConfigurationHandler.java │ │ ├── InvadedConfigurationManager.java │ │ ├── InvadedMessagesHandler.java │ │ ├── InvadedWandLocationHolder.java │ │ ├── ListMessage.java │ │ └── Message.java │ │ ├── data │ │ ├── InvadedPlayerData.java │ │ ├── InvadedPlayerDataManager.java │ │ └── InvadedPlayerEventData.java │ │ ├── event │ │ ├── InvadedEvent.java │ │ ├── InvadedEventManager.java │ │ ├── InvadedEventTeam.java │ │ ├── InvadedEventValidationResult.java │ │ ├── duel │ │ │ ├── DuelEvent.java │ │ │ ├── brackets │ │ │ │ ├── Brackets.java │ │ │ │ ├── Brackets1v1.java │ │ │ │ ├── Brackets2v2.java │ │ │ │ └── Brackets3v3.java │ │ │ └── sumo │ │ │ │ ├── Sumo.java │ │ │ │ ├── Sumo1v1.java │ │ │ │ ├── Sumo2v2.java │ │ │ │ └── Sumo3v3.java │ │ ├── event │ │ │ └── player │ │ │ │ └── EventPlayerDamageByEventPlayerEvent.java │ │ ├── misc │ │ │ └── TeamDeathmatch.java │ │ ├── round │ │ │ ├── Redrover.java │ │ │ ├── RoundEvent.java │ │ │ ├── TNTTag.java │ │ │ ├── Waterdrop.java │ │ │ └── WoolShuffle.java │ │ └── timer │ │ │ ├── KingOfTheHill.java │ │ │ ├── LastManStanding.java │ │ │ ├── OneInTheChamber.java │ │ │ ├── RaceOfDeath.java │ │ │ ├── Spleef.java │ │ │ └── TimerEvent.java │ │ ├── exception │ │ └── UnsupportedVersionException.java │ │ ├── gui │ │ ├── InvadedButton.java │ │ ├── InvadedGui.java │ │ ├── InvadedGuiManager.java │ │ ├── config │ │ │ └── KitViewGui.java │ │ └── host │ │ │ ├── BracketsHostGui.java │ │ │ ├── HostButton.java │ │ │ ├── HostButtonType.java │ │ │ ├── HostGui.java │ │ │ ├── MainHostGui.java │ │ │ └── SumoHostGui.java │ │ ├── kit │ │ └── InvadedKit.java │ │ ├── listener │ │ └── ActiveListener.java │ │ ├── region │ │ └── InvadedCuboidRegion.java │ │ ├── scoreboard │ │ ├── EventScoreboard.java │ │ ├── EventScoreboardLine.java │ │ └── EventScoreboardManager.java │ │ ├── task │ │ ├── SyncedTask.java │ │ ├── event │ │ │ └── MatchCountdownTask.java │ │ └── world │ │ │ └── BlockPlacementTask.java │ │ └── util │ │ ├── CollectionUtils.java │ │ ├── CompositeImmutableList.java │ │ ├── ItemStackBuilder.java │ │ ├── RandomUtils.java │ │ ├── RandomWeightedCollection.java │ │ ├── SpigotUtils.java │ │ └── StringUtils.java │ └── resources │ ├── config.yml │ ├── messages.yml │ └── plugin.yml ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ 2 | out/ 3 | *.iml 4 | *.ipr 5 | *.iws 6 | .idea/ 7 | 8 | # Maven 9 | target/ 10 | pom.xml.tag 11 | pom.xml.releaseBackup 12 | pom.xml.versionsBackup 13 | pom.xml.next 14 | release.properties 15 | dependency-reduced-pom.xml 16 | buildNumber.properties 17 | .mvn/timing.properties 18 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 19 | .mvn/wrapper/maven-wrapper.jar 20 | -------------------------------------------------------------------------------- /API/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | ca.nicbo.invadedlandsevents 9 | invadedlandsevents-parent 10 | 2.0.0-ALPHA.3 11 | 12 | 13 | invadedlandsevents-api 14 | 15 | 16 | 17 | org.jetbrains 18 | annotations 19 | 22.0.0 20 | provided 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/InvadedLandsEvents.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api; 2 | 3 | import ca.nicbo.invadedlandsevents.api.configuration.ConfigurationManager; 4 | import ca.nicbo.invadedlandsevents.api.data.PlayerDataManager; 5 | import ca.nicbo.invadedlandsevents.api.event.EventManager; 6 | import ca.nicbo.invadedlandsevents.api.gui.Button; 7 | import ca.nicbo.invadedlandsevents.api.gui.Gui; 8 | import ca.nicbo.invadedlandsevents.api.gui.GuiManager; 9 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 10 | import ca.nicbo.invadedlandsevents.api.region.CuboidRegion; 11 | import ca.nicbo.invadedlandsevents.api.util.Callback; 12 | import org.bukkit.Location; 13 | import org.bukkit.entity.Player; 14 | import org.bukkit.inventory.ItemStack; 15 | import org.jetbrains.annotations.NotNull; 16 | import org.jetbrains.annotations.Nullable; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * The InvadedLandsEvents API. 22 | * 23 | * @author Nicbo 24 | */ 25 | public interface InvadedLandsEvents { 26 | /** 27 | * Returns the configuration manager. 28 | * 29 | * @return the configuration manager 30 | * @throws IllegalStateException if the configuration manager is not ready 31 | */ 32 | @NotNull 33 | ConfigurationManager getConfigurationManager(); 34 | 35 | /** 36 | * Returns the player data manager. 37 | * 38 | * @return the player data manager 39 | * @throws IllegalStateException if the player data manager is not ready 40 | */ 41 | @NotNull 42 | PlayerDataManager getPlayerDataManager(); 43 | 44 | /** 45 | * Returns the event manager. 46 | * 47 | * @return the event manager 48 | * @throws IllegalStateException if the event manager is not ready 49 | */ 50 | @NotNull 51 | EventManager getEventManager(); 52 | 53 | /** 54 | * Returns the GUI manager. 55 | * 56 | * @return the GUI manager 57 | * @throws IllegalStateException if the GUI manager is not ready 58 | */ 59 | @NotNull 60 | GuiManager getGuiManager(); 61 | 62 | // Factory methods 63 | 64 | /** 65 | * Returns a new instance of a GUI with the provided components. 66 | * 67 | * @param player the player who it belongs to 68 | * @param title the title 69 | * @param size the size 70 | * @return a new GUI 71 | * @throws IllegalArgumentException if the size is not a multiple of 9 and between 9 and 54 slots 72 | * @throws NullPointerException if the player or title is null 73 | */ 74 | @NotNull 75 | Gui createGui(@NotNull Player player, @NotNull String title, int size); 76 | 77 | /** 78 | * Returns a new instance of a button with the provided components. 79 | * 80 | * @param itemStack the item stack to use 81 | * @param callback the function to call when the button is clicked 82 | * @return a new button 83 | * @throws NullPointerException if the itemStack is null 84 | */ 85 | @NotNull 86 | Button createButton(@NotNull ItemStack itemStack, @Nullable Callback callback); 87 | 88 | /** 89 | * Returns a new instance of a kit with the provided components. 90 | * 91 | * @param items the items 92 | * @param armour the armour 93 | * @param offhand the offhand 94 | * @return a new kit 95 | * @throws NullPointerException if the items or armour is null 96 | */ 97 | @NotNull 98 | Kit createKit(@NotNull List items, @NotNull List armour, @Nullable ItemStack offhand); 99 | 100 | /** 101 | * Returns a new instance of a region with the provided components. 102 | * 103 | * @param locationOne the first corner 104 | * @param locationTwo the second corner 105 | * @return a new region 106 | * @throws IllegalArgumentException if the location worlds are not the same 107 | * @throws NullPointerException if either location is null or has a null world 108 | */ 109 | @NotNull 110 | CuboidRegion createRegion(@NotNull Location locationOne, @NotNull Location locationTwo); 111 | } 112 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/InvadedLandsEventsProvider.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | /** 7 | * Allows static access of the InvadedLandsEvents API. 8 | *

9 | * Using the bukkit services manager is preferred. 10 | * 11 | * @author Nicbo 12 | */ 13 | public final class InvadedLandsEventsProvider { 14 | private static InvadedLandsEvents instance; // this is set using reflection 15 | 16 | private InvadedLandsEventsProvider() { 17 | } 18 | 19 | /** 20 | * Returns the instance of InvadedLandsEvents. 21 | * 22 | * @return the instance 23 | * @throws IllegalStateException if the instance has not been set 24 | */ 25 | @NotNull 26 | public static InvadedLandsEvents getInstance() { 27 | Validate.checkState(instance != null, "instance has not been set"); 28 | return instance; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/configuration/ConfigHandler.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.configuration; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.Set; 6 | 7 | /** 8 | * Handles config.yml. 9 | * 10 | * @author Nicbo 11 | */ 12 | public interface ConfigHandler extends ConfigurationHandler { 13 | /** 14 | * Returns the config section by the provided name. 15 | * 16 | * @param name the name of the config section 17 | * @return the config section 18 | * @throws NullPointerException if the name is null 19 | */ 20 | @NotNull 21 | ConfigSection getConfigSection(@NotNull String name); 22 | 23 | /** 24 | * Returns the config section names in config.yml. 25 | * 26 | * @return the config section names 27 | */ 28 | @NotNull 29 | Set getConfigSectionNames(); 30 | } 31 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/configuration/ConfigValueType.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.configuration; 2 | 3 | /** 4 | * The different config value types. 5 | * 6 | * @author Nicbo 7 | */ 8 | public enum ConfigValueType { 9 | BOOLEAN, 10 | INTEGER, 11 | KIT, 12 | LOCATION, 13 | REGION, 14 | STRING_LIST 15 | } 16 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/configuration/ConfigurationHandler.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.configuration; 2 | 3 | /** 4 | * Handles a configuration file. 5 | * 6 | * @author Nicbo 7 | */ 8 | public interface ConfigurationHandler { 9 | /** 10 | * Returns the version of the configuration file. 11 | * 12 | * @return the version 13 | */ 14 | int getVersion(); 15 | 16 | /** 17 | * Saves the configuration file to disk. 18 | */ 19 | void save(); 20 | 21 | /** 22 | * Reloads the configuration file from disk. 23 | */ 24 | void reload(); 25 | } 26 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/configuration/ConfigurationManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.configuration; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * Manages the configuration. 10 | * 11 | * @author Nicbo 12 | */ 13 | public interface ConfigurationManager { 14 | /** 15 | * Returns the handler for config.yml. 16 | * 17 | * @return the config handler 18 | */ 19 | @NotNull 20 | ConfigHandler getConfigHandler(); 21 | 22 | /** 23 | * Returns the handler for messages.yml. 24 | * 25 | * @return the messages handler 26 | */ 27 | @NotNull 28 | MessagesHandler getMessagesHandler(); 29 | 30 | /** 31 | * Returns the wand location holder for the provided player. 32 | * 33 | * @param player the player 34 | * @return the wand location holder 35 | * @throws NullPointerException if the player is null 36 | */ 37 | @NotNull 38 | WandLocationHolder getWandLocationHolder(@NotNull Player player); 39 | 40 | /** 41 | * Returns an unmodifiable view on the wand location holder map. 42 | * 43 | * @return an unmodifiable view on the wand location holder map 44 | */ 45 | @NotNull 46 | Map getWandLocationHolderMap(); 47 | } 48 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/configuration/MessagesHandler.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.configuration; 2 | 3 | /** 4 | * Handles messages.yml. 5 | * 6 | * @author Nicbo 7 | */ 8 | public interface MessagesHandler extends ConfigurationHandler { 9 | } 10 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/configuration/WandLocationHolder.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.configuration; 2 | 3 | import org.bukkit.Location; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | /** 7 | * Holds both locations for a player's wand. 8 | * 9 | * @author Nicbo 10 | */ 11 | public interface WandLocationHolder { 12 | /** 13 | * Returns a copy of the location for left click. 14 | * 15 | * @return the location 16 | */ 17 | @Nullable 18 | Location getLocationOne(); 19 | 20 | /** 21 | * Sets the location for left click. 22 | * 23 | * @param locationOne the location 24 | */ 25 | void setLocationOne(@Nullable Location locationOne); 26 | 27 | /** 28 | * Returns a copy of the location for right click. 29 | * 30 | * @return the location 31 | */ 32 | @Nullable 33 | Location getLocationTwo(); 34 | 35 | /** 36 | * Sets the location for right click. 37 | * 38 | * @param locationTwo the location 39 | */ 40 | void setLocationTwo(@Nullable Location locationTwo); 41 | } 42 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/data/PlayerData.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.data; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.EventType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.io.IOException; 7 | import java.util.Map; 8 | import java.util.UUID; 9 | 10 | /** 11 | * Holds all the player's data. 12 | * 13 | * @author Nicbo 14 | */ 15 | public interface PlayerData { 16 | /** 17 | * Returns the player's UUID. 18 | * 19 | * @return the player's UUID 20 | */ 21 | @NotNull 22 | UUID getPlayerUUID(); 23 | 24 | /** 25 | * Returns the event data associated with the provided event type. 26 | * 27 | * @param eventType the event type 28 | * @return the event data 29 | * @throws NullPointerException if the eventType is null 30 | */ 31 | @NotNull 32 | PlayerEventData getEventData(@NotNull EventType eventType); 33 | 34 | /** 35 | * Returns an unmodifiable view of the event data map. This map is guaranteed to have every event type. 36 | * 37 | * @return an unmodifiable view of the event data map 38 | */ 39 | @NotNull 40 | Map getEventDataMap(); 41 | 42 | /** 43 | * Attempts to save the data to the file. 44 | * 45 | * @throws IOException if the file cannot be written to 46 | */ 47 | void saveToFile() throws IOException; 48 | } 49 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/data/PlayerDataManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.data; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.Map; 6 | import java.util.UUID; 7 | 8 | /** 9 | * Manages the {@link PlayerData} for the online players. 10 | *

11 | * All player data is stored in the playerdata folder at the root of the plugin's data folder. 12 | * 13 | * @author Nicbo 14 | */ 15 | public interface PlayerDataManager { 16 | /** 17 | * Returns the player data associated with the provided player UUID. 18 | * 19 | * @param uuid the player's UUID 20 | * @return the player data 21 | * @throws NullPointerException if the uuid is null 22 | */ 23 | @NotNull 24 | PlayerData getPlayerData(@NotNull UUID uuid); 25 | 26 | /** 27 | * Returns an unmodifiable view of the online player's data map. 28 | * 29 | * @return an unmodifiable view of the online player's data map 30 | */ 31 | @NotNull 32 | Map getPlayerDataMap(); 33 | 34 | /** 35 | * Returns an unmodifiable map of all the data in the player data folder. Note that this operation could take a long 36 | * time depending on how many players have logged in to the server. 37 | * 38 | * @return an unmodifiable map of all the data in the player data folder 39 | */ 40 | @NotNull 41 | Map getGlobalPlayerDataMap(); 42 | } 43 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/data/PlayerEventData.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.data; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.EventType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | /** 7 | * Holds all the player's data for an event type. 8 | * 9 | * @author Nicbo 10 | */ 11 | public interface PlayerEventData { 12 | /** 13 | * Returns the event type. 14 | * 15 | * @return the event type 16 | */ 17 | @NotNull 18 | EventType getEventType(); 19 | 20 | /** 21 | * Returns the timestamp of when the player last hosted the event or 0 if they have never hosted this event type. 22 | * 23 | * @return the timestamp 24 | */ 25 | long getHostTimestamp(); 26 | 27 | /** 28 | * Sets the timestamp of when the player last hosted the event. 29 | * 30 | * @param hostTimestamp the timestamp 31 | */ 32 | void setHostTimestamp(long hostTimestamp); 33 | 34 | /** 35 | * Returns the number of times the player has won the event. 36 | * 37 | * @return the number of wins 38 | */ 39 | int getWins(); 40 | 41 | /** 42 | * Sets the number of times the player has won the event. 43 | * 44 | * @param wins the number of wins 45 | */ 46 | void setWins(int wins); 47 | } 48 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/Event.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Represents an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public interface Event { 14 | /** 15 | * Returns the number of seconds left in this event's countdown. 16 | * 17 | * @return the number of seconds 18 | */ 19 | int getCountdown(); 20 | 21 | /** 22 | * Returns the name of the sender who hosted this event. 23 | * 24 | * @return the host name 25 | */ 26 | @NotNull 27 | String getHostName(); 28 | 29 | /** 30 | * Returns the type of this event. 31 | * 32 | * @return the event type 33 | */ 34 | @NotNull 35 | EventType getEventType(); 36 | 37 | /** 38 | * Returns an unmodifiable view of the players. 39 | * 40 | * @return an unmodifiable view of the players 41 | */ 42 | @NotNull 43 | List getPlayers(); 44 | 45 | /** 46 | * Returns an unmodifiable view of the spectators. 47 | * 48 | * @return an unmodifiable view of the spectators 49 | */ 50 | @NotNull 51 | List getSpectators(); 52 | 53 | /** 54 | * Adds the player to this event's players. 55 | * 56 | * @param player the player 57 | * @throws IllegalArgumentException if player is already participating in the event 58 | * @throws IllegalStateException if the event is not in the {@link EventState#COUNTDOWN} state 59 | * @throws NullPointerException if the player is null 60 | */ 61 | void join(@NotNull Player player); 62 | 63 | /** 64 | * Removes the player from this event's players or spectators. 65 | * 66 | * @param player the player 67 | * @throws IllegalArgumentException if player is not participating in the event 68 | * @throws IllegalStateException if the event is not in the {@link EventState#COUNTDOWN}, {@link 69 | * EventState#STARTED} or {@link EventState#ENDED} state 70 | * @throws NullPointerException if the player is null 71 | */ 72 | void leave(@NotNull Player player); 73 | 74 | /** 75 | * Adds the player to this event's spectators. 76 | * 77 | * @param player the player 78 | * @throws IllegalArgumentException if player is already participating in the event 79 | * @throws IllegalStateException if the event is not in the {@link EventState#COUNTDOWN} or {@link 80 | * EventState#STARTED} state 81 | * @throws NullPointerException if the player is null 82 | */ 83 | void spectate(@NotNull Player player); 84 | 85 | /** 86 | * Force ends this event. 87 | * 88 | * @param silent true if a message should not be sent out 89 | * @throws IllegalStateException if the event is not in the {@link EventState#COUNTDOWN} or {@link 90 | * EventState#STARTED} state 91 | */ 92 | void forceEnd(boolean silent); 93 | 94 | /** 95 | * Sends a message to every participant of this event. 96 | *

97 | * The message is not altered before being broadcasted, any formatting must be done beforehand. 98 | * 99 | * @param message the message to send 100 | * @throws NullPointerException if the message is null 101 | */ 102 | void broadcastMessage(@NotNull String message); 103 | 104 | /** 105 | * Returns the state of this event 106 | * 107 | * @return the state 108 | */ 109 | @NotNull 110 | EventState getState(); 111 | } 112 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/EventManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | /** 9 | * Manages the state of the current {@link Event}. 10 | *

11 | * This is what most of the user commands interact with. If you want to bypass certain checks, it might be a good idea 12 | * to interact with the event directly through {@link #getCurrentEvent()}. 13 | * 14 | * @author Nicbo 15 | */ 16 | public interface EventManager { 17 | /** 18 | * Attempts to host the provided event type with the provided sender. 19 | * 20 | * @param eventType the event type 21 | * @param sender the sender 22 | * @return true if it was successful 23 | * @throws NullPointerException if the eventType or sender is null 24 | */ 25 | boolean hostEvent(@NotNull EventType eventType, @NotNull CommandSender sender); 26 | 27 | /** 28 | * Attempts to add the provided player to the current event's players. 29 | * 30 | * @param player the player 31 | * @return true if it was successful 32 | * @throws NullPointerException if the player is null 33 | */ 34 | boolean joinCurrentEvent(@NotNull Player player); 35 | 36 | /** 37 | * Attempts to remove the provided player from the current event. 38 | * 39 | * @param player the player 40 | * @return true if it was successful 41 | * @throws NullPointerException if the player is null 42 | */ 43 | boolean leaveCurrentEvent(@NotNull Player player); 44 | 45 | /** 46 | * Attempts to add the provided player to the current event's spectators. 47 | * 48 | * @param player the player 49 | * @return true if it was successful 50 | * @throws NullPointerException if the player is null 51 | */ 52 | boolean spectateCurrentEvent(@NotNull Player player); 53 | 54 | /** 55 | * Attempts to force end the current event. 56 | * 57 | * @param sender the sender that initiated the force end 58 | * @return true if it was successful 59 | * @throws NullPointerException if the sender is null 60 | */ 61 | boolean forceEndCurrentEvent(@NotNull CommandSender sender); 62 | 63 | /** 64 | * Attempts to send the provided sender the current event's information. 65 | * 66 | * @param sender the sender 67 | * @return true if it was successful 68 | * @throws NullPointerException if the sender is null 69 | */ 70 | boolean sendCurrentEventInfo(@NotNull CommandSender sender); 71 | 72 | /** 73 | * Attempts to send the provided sender the provided player's statistics. 74 | * 75 | * @param sender the sender 76 | * @param player the player 77 | * @return true if it was successful 78 | * @throws NullPointerException if the sender or player is null 79 | */ 80 | boolean sendEventStats(@NotNull CommandSender sender, @NotNull Player player); 81 | 82 | /** 83 | * Returns the current event or null if an event is not active. 84 | * 85 | * @return the current event 86 | */ 87 | @Nullable 88 | Event getCurrentEvent(); 89 | 90 | /** 91 | * Returns true if the provided event type is enabled. 92 | * 93 | * @param eventType the event type 94 | * @return true if the provided event type is enabled 95 | * @throws NullPointerException if the eventType is null 96 | */ 97 | boolean isEventEnabled(@NotNull EventType eventType); 98 | } 99 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/EventState.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event; 2 | 3 | /** 4 | * The different states an {@link Event} can be in. 5 | * 6 | * @author Nicbo 7 | */ 8 | public enum EventState { 9 | WAITING, 10 | COUNTDOWN, 11 | STARTED, 12 | ENDED, 13 | STOPPED 14 | } 15 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/EventType.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.permission.EventPermission; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | /** 7 | * The different {@link Event} types. 8 | * 9 | * @author Nicbo 10 | */ 11 | public enum EventType { 12 | BRACKETS_1V1("1v1 Brackets", "brackets1v1", EventPermission.HOST_BRACKETS_1V1), 13 | BRACKETS_2V2("2v2 Brackets", "brackets2v2", EventPermission.HOST_BRACKETS_2V2), 14 | BRACKETS_3V3("3v3 Brackets", "brackets3v3", EventPermission.HOST_BRACKETS_3V3), 15 | KING_OF_THE_HILL("King of the Hill", "koth", EventPermission.HOST_KOTH), 16 | LAST_MAN_STANDING("Last Man Standing", "lms", EventPermission.HOST_LMS), 17 | ONE_IN_THE_CHAMBER("One in the Chamber", "oitc", EventPermission.HOST_OITC), 18 | REDROVER("Redrover", "redrover", EventPermission.HOST_REDROVER), 19 | RACE_OF_DEATH("Race of Death", "rod", EventPermission.HOST_ROD), 20 | SPLEEF("Spleef", "spleef", EventPermission.HOST_SPLEEF), 21 | SUMO_1V1("1v1 Sumo", "sumo1v1", EventPermission.HOST_SUMO_1V1), 22 | SUMO_2V2("2v2 Sumo", "sumo2v2", EventPermission.HOST_SUMO_2V2), 23 | SUMO_3V3("3v3 Sumo", "sumo3v3", EventPermission.HOST_SUMO_3V3), 24 | TEAM_DEATHMATCH("Team Deathmatch", "tdm", EventPermission.HOST_TDM), 25 | TNT_TAG("TNT Tag", "tnttag", EventPermission.HOST_TNTTAG), 26 | WATERDROP("Waterdrop", "waterdrop", EventPermission.HOST_WATERDROP), 27 | WOOL_SHUFFLE("Wool Shuffle", "woolshuffle", EventPermission.HOST_WOOLSHUFFLE); 28 | 29 | private final String displayName; 30 | private final String configName; 31 | private final String permission; 32 | 33 | EventType(@NotNull String displayName, @NotNull String configName, @NotNull String permission) { 34 | this.displayName = displayName; 35 | this.configName = configName; 36 | this.permission = permission; 37 | } 38 | 39 | /** 40 | * Returns the display name of the event type. 41 | * 42 | * @return the display name 43 | */ 44 | @NotNull 45 | public String getDisplayName() { 46 | return displayName; 47 | } 48 | 49 | /** 50 | * Returns the config name of the event type. 51 | * 52 | * @return the config name 53 | */ 54 | @NotNull 55 | public String getConfigName() { 56 | return configName; 57 | } 58 | 59 | /** 60 | * Returns the permission node required to host this event type. 61 | * 62 | * @return the permission node 63 | */ 64 | @NotNull 65 | public String getPermission() { 66 | return permission; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Represents an {@link Event} related event. 9 | * 10 | * @author Nicbo 11 | */ 12 | public abstract class EventEvent extends org.bukkit.event.Event { 13 | private final Event event; 14 | 15 | /** 16 | * Creates an EventEvent. 17 | * 18 | * @param event the event involved with the event 19 | * @throws NullPointerException if the event is null 20 | */ 21 | protected EventEvent(@NotNull Event event) { 22 | Validate.checkArgumentNotNull(event, "event"); 23 | this.event = event; 24 | } 25 | 26 | /** 27 | * Returns the event involved with the event. 28 | * 29 | * @return the event 30 | */ 31 | @NotNull 32 | public Event getEvent() { 33 | return event; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPostCountdownEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called after an event starts its countdown. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPostCountdownEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPostCountdownEvent. 17 | * 18 | * @param event the event that started its countdown 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPostCountdownEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPostEndEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called after an event ends. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPostEndEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPostEndEvent. 17 | * 18 | * @param event the event that ended 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPostEndEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPostForceEndEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called after an event force ends. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPostForceEndEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPostForceEndEvent. 17 | * 18 | * @param event the event that force ended 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPostForceEndEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPostStartEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called after an event starts. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPostStartEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPostStartEvent. 17 | * 18 | * @param event the event that started 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPostStartEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPostStopEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called after an event stops. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPostStopEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPostStopEvent. 17 | * 18 | * @param event the event that stopped 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPostStopEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPreCountdownEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called before an event starts its countdown. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPreCountdownEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPreCountdownEvent. 17 | * 18 | * @param event the event that is going to start its countdown 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPreCountdownEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPreEndEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called before an event ends. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPreEndEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPreEndEvent. 17 | * 18 | * @param event the event that is going to end 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPreEndEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPreForceEndEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called before an event force ends. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPreForceEndEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPreForceEndEvent. 17 | * 18 | * @param event the event that is going to force end 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPreForceEndEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPreStartEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called before an event starts. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPreStartEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPreStartEvent. 17 | * 18 | * @param event the event that is going to start 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPreStartEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/EventPreStopEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called before an event stops. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventPreStopEvent extends EventEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates an EventPreStopEvent. 17 | * 18 | * @param event the event that is going to stop 19 | * @throws NullPointerException if the event is null 20 | */ 21 | public EventPreStopEvent(@NotNull Event event) { 22 | super(event); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import ca.nicbo.invadedlandsevents.api.event.event.EventEvent; 5 | import ca.nicbo.invadedlandsevents.api.util.Validate; 6 | import org.bukkit.entity.Player; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | /** 10 | * Represents a player related {@link EventEvent}. 11 | * 12 | * @author Nicbo 13 | */ 14 | public abstract class EventPlayerEvent extends EventEvent { 15 | private final Player player; 16 | 17 | /** 18 | * Creates an EventPlayerEvent. 19 | * 20 | * @param event the event that the player is interacting with 21 | * @param player the player involved with the event 22 | * @throws NullPointerException if the event or player is null 23 | */ 24 | protected EventPlayerEvent(@NotNull Event event, @NotNull Player player) { 25 | super(event); 26 | Validate.checkArgumentNotNull(player, "player"); 27 | this.player = player; 28 | } 29 | 30 | /** 31 | * Returns the player involved with the event. 32 | * 33 | * @return the player 34 | */ 35 | @NotNull 36 | public Player getPlayer() { 37 | return player; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPostJoinEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called after a player joins an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPostJoinEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPostJoinEvent. 18 | * 19 | * @param event the event that the player joined 20 | * @param player the player who joined the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPostJoinEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPostLeaveEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called after a player leaves an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPostLeaveEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPostLeaveEvent. 18 | * 19 | * @param event the event that the player left 20 | * @param player the player who left the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPostLeaveEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPostSpectateEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called after a player spectates an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPostSpectateEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPostSpectateEvent. 18 | * 19 | * @param event the event that the player spectated 20 | * @param player the player who spectated the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPostSpectateEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPostWinEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called after a player wins an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPostWinEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPostWinEvent. 18 | * 19 | * @param event the event that the player won. 20 | * @param player the player who won the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPostWinEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPreJoinEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called before a player joins an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPreJoinEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPreJoinEvent. 18 | * 19 | * @param event the event that the player is joining 20 | * @param player the player who is joining the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPreJoinEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPreLeaveEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called before a player leaves an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPreLeaveEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPreLeaveEvent. 18 | * 19 | * @param event the event that the player is leaving 20 | * @param player the player who is leaving the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPreLeaveEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPreSpectateEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called before a player spectates an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPreSpectateEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPreSpectateEvent. 18 | * 19 | * @param event the event that the player is going to spectate 20 | * @param player the player who is going to spectate the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPreSpectateEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/event/event/player/EventPlayerPreWinEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Called before a player wins an event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class EventPlayerPreWinEvent extends EventPlayerEvent { 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | /** 17 | * Creates an EventPlayerPreWinEvent. 18 | * 19 | * @param event the event that the player is going to win 20 | * @param player the player who is going to win the event 21 | * @throws NullPointerException if the event or player is null 22 | */ 23 | public EventPlayerPreWinEvent(@NotNull Event event, @NotNull Player player) { 24 | super(event, player); 25 | } 26 | 27 | @Override 28 | @NotNull 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @NotNull 34 | public static HandlerList getHandlerList() { 35 | return HANDLERS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/gui/Button.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.gui; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Callback; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | /** 9 | * Represents a button on the {@link Gui}. 10 | * 11 | * @author Nicbo 12 | */ 13 | public interface Button { 14 | /** 15 | * Returns a copy of the item stack. 16 | * 17 | * @return the item stack 18 | */ 19 | @NotNull 20 | ItemStack getItemStack(); 21 | 22 | /** 23 | * Sets the item stack. 24 | * 25 | * @param itemStack the item stack 26 | * @throws NullPointerException if the itemStack is null 27 | */ 28 | void setItemStack(@NotNull ItemStack itemStack); 29 | 30 | /** 31 | * Returns the callback that is called when the button is clicked. 32 | * 33 | * @return the callback 34 | */ 35 | @Nullable 36 | Callback getCallback(); 37 | 38 | /** 39 | * Sets the callback that is called when the button is clicked. 40 | * 41 | * @param callback the callback 42 | */ 43 | void setCallback(@Nullable Callback callback); 44 | } 45 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/gui/Gui.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.gui; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.inventory.Inventory; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * Represents a GUI for the player. 12 | * 13 | * @author Nicbo 14 | */ 15 | public interface Gui { 16 | /** 17 | * Opens the GUI. 18 | */ 19 | void open(); 20 | 21 | /** 22 | * Closes the GUI. 23 | */ 24 | void close(); 25 | 26 | /** 27 | * Returns the player who owns the GUI. 28 | * 29 | * @return the player 30 | */ 31 | @NotNull 32 | Player getPlayer(); 33 | 34 | /** 35 | * Returns the title. 36 | * 37 | * @return the title 38 | */ 39 | @NotNull 40 | String getTitle(); 41 | 42 | /** 43 | * Returns the amount of slots. 44 | * 45 | * @return the size 46 | */ 47 | int getSize(); 48 | 49 | /** 50 | * Returns the button at the provided slot or null if no button is using that slot. 51 | * 52 | * @param slot the slot number 53 | * @return the button 54 | */ 55 | @Nullable 56 | Button getButton(int slot); 57 | 58 | /** 59 | * Sets the button at the provided slot. 60 | * 61 | * @param slot the slot number 62 | * @param button the button 63 | * @throws IllegalArgumentException if slot < 0 || slot >= size 64 | */ 65 | void setButton(int slot, @Nullable Button button); 66 | 67 | /** 68 | * Returns true if the slot is not occupied by a button. 69 | * 70 | * @param slot the slot number 71 | * @return true if the slot is not occupied by a button 72 | */ 73 | boolean isSlotEmpty(int slot); 74 | 75 | /** 76 | * Returns an unmodifiable view of the button map. 77 | * 78 | * @return an unmodifiable view of the button map 79 | */ 80 | @NotNull 81 | Map getButtonMap(); 82 | 83 | /** 84 | * Returns true if the provided inventory is equal to the internal inventory. 85 | * 86 | * @param inventory the inventory 87 | * @return true if the inventories are equal 88 | */ 89 | boolean isInventoryEqual(@Nullable Inventory inventory); 90 | 91 | /** 92 | * Updates the GUI. 93 | */ 94 | void update(); 95 | } 96 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/gui/GuiManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.gui; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * Manages each player's {@link Gui}. 11 | * 12 | * @author Nicbo 13 | */ 14 | public interface GuiManager { 15 | /** 16 | * Returns the GUI that the player currently has open or null. 17 | * 18 | * @param player the player 19 | * @return the GUI 20 | * @throws NullPointerException if the player is null 21 | */ 22 | @Nullable 23 | Gui getGui(@NotNull Player player); 24 | 25 | /** 26 | * Returns an unmodifiable view of the GUI map. 27 | * 28 | * @return an unmodifiable view of the GUI map 29 | */ 30 | @NotNull 31 | Map getGuiMap(); 32 | } 33 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/gui/event/GuiCloseEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.gui.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.gui.Gui; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called when a GUI is closed. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class GuiCloseEvent extends GuiEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates a GuiCloseEvent. 17 | * 18 | * @param gui the GUI that was closed 19 | * @throws NullPointerException if the GUI is null 20 | */ 21 | public GuiCloseEvent(@NotNull Gui gui) { 22 | super(gui); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/gui/event/GuiEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.gui.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.gui.Gui; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import org.bukkit.event.Event; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Represents a GUI related event. 10 | * 11 | * @author Nicbo 12 | */ 13 | public abstract class GuiEvent extends Event { 14 | private final Gui gui; 15 | 16 | /** 17 | * Creates a GuiEvent. 18 | * 19 | * @param gui the GUI involved with the event 20 | * @throws NullPointerException if the GUI is null 21 | */ 22 | protected GuiEvent(@NotNull Gui gui) { 23 | Validate.checkArgumentNotNull(gui, "gui"); 24 | this.gui = gui; 25 | } 26 | 27 | /** 28 | * Returns the GUI involved with the event. 29 | * 30 | * @return the GUI 31 | */ 32 | @NotNull 33 | public Gui getGui() { 34 | return gui; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/gui/event/GuiOpenEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.gui.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.gui.Gui; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Called when a GUI is opened. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class GuiOpenEvent extends GuiEvent { 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | /** 16 | * Creates a GuiOpenEvent. 17 | * 18 | * @param gui the GUI that was opened 19 | * @throws NullPointerException if the GUI is null 20 | */ 21 | public GuiOpenEvent(@NotNull Gui gui) { 22 | super(gui); 23 | } 24 | 25 | @Override 26 | @NotNull 27 | public HandlerList getHandlers() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | public static HandlerList getHandlerList() { 33 | return HANDLERS; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/kit/Kit.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.kit; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * A kit consisting of items, armour and possibly an offhand item. 12 | * 13 | * @author Nicbo 14 | */ 15 | public interface Kit { 16 | /** 17 | * Applies the kit to the provided player. Note that the offhand slot will not be applied on versions <1.9. 18 | * 19 | * @param player the player that is receiving the kit 20 | * @throws NullPointerException if the player is null 21 | */ 22 | void apply(@NotNull Player player); 23 | 24 | /** 25 | * Returns an unmodifiable list of the items. This list is guaranteed to have a size of 36 and empty items will be 26 | * null instead of air. 27 | * 28 | * @return an unmodifiable list of the items 29 | */ 30 | @NotNull 31 | List getItems(); 32 | 33 | /** 34 | * Returns an unmodifiable list of the armour. This list is guaranteed to have a size of 4 and empty items will be 35 | * null instead of air. 36 | * 37 | * @return an unmodifiable list of the armour 38 | */ 39 | @NotNull 40 | List getArmour(); 41 | 42 | /** 43 | * Returns the offhand item stack or null if it does not exist 44 | * 45 | * @return the offhand item stack 46 | */ 47 | @Nullable 48 | ItemStack getOffhand(); 49 | } 50 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/permission/EventPermission.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.permission; 2 | 3 | /** 4 | * Constant strings representing every permission node in InvadedLandsEvents. 5 | * 6 | * @author Nicbo 7 | */ 8 | public final class EventPermission { 9 | public static final String CONFIG = "ile.eventconfig"; 10 | 11 | public static final String COMMAND_BYPASS = "ile.event.commandbypass"; 12 | public static final String HOST_COOLDOWN_BYPASS = "ile.event.host.cooldownbypass"; 13 | public static final String FORCE_END = "ile.event.forceend"; 14 | public static final String JOIN = "ile.event.join"; 15 | public static final String HOST = "ile.event.host"; 16 | public static final String LEAVE = "ile.event.leave"; 17 | public static final String SPECTATE = "ile.event.spectate"; 18 | public static final String INFO = "ile.event.info"; 19 | public static final String STATS = "ile.event.stats"; 20 | public static final String STATS_OTHER = "ile.event.stats.other"; 21 | 22 | public static final String HOST_SUMO_1V1 = "ile.event.host.sumo1v1"; 23 | public static final String HOST_SUMO_2V2 = "ile.event.host.sumo2v2"; 24 | public static final String HOST_SUMO_3V3 = "ile.event.host.sumo3v3"; 25 | public static final String HOST_BRACKETS_1V1 = "ile.event.host.brackets1v1"; 26 | public static final String HOST_BRACKETS_2V2 = "ile.event.host.brackets2v2"; 27 | public static final String HOST_BRACKETS_3V3 = "ile.event.host.brackets3v3"; 28 | public static final String HOST_KOTH = "ile.event.host.koth"; 29 | public static final String HOST_LMS = "ile.event.host.lms"; 30 | public static final String HOST_OITC = "ile.event.host.oitc"; 31 | public static final String HOST_REDROVER = "ile.event.host.redrover"; 32 | public static final String HOST_ROD = "ile.event.host.rod"; 33 | public static final String HOST_SPLEEF = "ile.event.host.spleef"; 34 | public static final String HOST_TDM = "ile.event.host.tdm"; 35 | public static final String HOST_TNTTAG = "ile.event.host.tnttag"; 36 | public static final String HOST_WATERDROP = "ile.event.host.waterdrop"; 37 | public static final String HOST_WOOLSHUFFLE = "ile.event.host.woolshuffle"; 38 | 39 | private EventPermission() { 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/region/CuboidRegion.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.region; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.World; 5 | import org.bukkit.block.Block; 6 | import org.bukkit.entity.Entity; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Represents a region. 13 | * 14 | * @author Nicbo 15 | */ 16 | public interface CuboidRegion { 17 | /** 18 | * Returns the world of this region. 19 | * 20 | * @return the world 21 | */ 22 | @NotNull 23 | World getWorld(); 24 | 25 | /** 26 | * Returns the first corner of this region. 27 | * 28 | * @return the first corner 29 | */ 30 | @NotNull 31 | Location getLocationOne(); 32 | 33 | /** 34 | * Returns the second corner of this region. 35 | * 36 | * @return the second corner 37 | */ 38 | @NotNull 39 | Location getLocationTwo(); 40 | 41 | /** 42 | * Returns the lowest x value of this region. 43 | * 44 | * @return the lowest x value 45 | */ 46 | int getMinX(); 47 | 48 | /** 49 | * Returns the highest x value of this region. 50 | * 51 | * @return the highest x value. 52 | */ 53 | int getMaxX(); 54 | 55 | /** 56 | * Returns the lowest y value of this region. 57 | * 58 | * @return the lowest y value 59 | */ 60 | int getMinY(); 61 | 62 | /** 63 | * Returns the highest y value of this region. 64 | * 65 | * @return the highest y value 66 | */ 67 | int getMaxY(); 68 | 69 | /** 70 | * Returns the lowest z value of this region. 71 | * 72 | * @return the lowest z value 73 | */ 74 | int getMinZ(); 75 | 76 | /** 77 | * Returns the highest z value of this region. 78 | * 79 | * @return the highest z value 80 | */ 81 | int getMaxZ(); 82 | 83 | /** 84 | * Returns the length of this region's x-axis. 85 | * 86 | * @return the length of the x-axis 87 | */ 88 | int getLengthX(); 89 | 90 | /** 91 | * Returns the length of this region's y-axis. 92 | * 93 | * @return the length of the y-axis 94 | */ 95 | int getLengthY(); 96 | 97 | /** 98 | * Returns the length of this region's z-axis. 99 | * 100 | * @return the length of the z-axis 101 | */ 102 | int getLengthZ(); 103 | 104 | /** 105 | * Returns the total number of blocks in this region. 106 | * 107 | * @return the total number of blocks 108 | */ 109 | int getSize(); 110 | 111 | /** 112 | * Returns true if this region contains the provided entity. 113 | * 114 | * @param entity the entity 115 | * @return true if this region contains the provided entity 116 | * @throws NullPointerException if the entity is null 117 | */ 118 | boolean contains(@NotNull Entity entity); 119 | 120 | /** 121 | * Returns true if this region contains the provided block. 122 | * 123 | * @param block the block 124 | * @return true if this region contains the provided block 125 | * @throws NullPointerException if the block is null 126 | */ 127 | boolean contains(@NotNull Block block); 128 | 129 | /** 130 | * Returns true if this region contains the provided location. 131 | * 132 | * @param location the location 133 | * @return true if this region contains the provided location 134 | * @throws NullPointerException if the location is null 135 | */ 136 | boolean contains(@NotNull Location location); 137 | 138 | /** 139 | * Returns a list of the blocks in this region. 140 | * 141 | * @return the blocks 142 | */ 143 | @NotNull 144 | List getBlocks(); 145 | } 146 | -------------------------------------------------------------------------------- /API/src/main/java/ca/nicbo/invadedlandsevents/api/util/Callback.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.api.util; 2 | 3 | /** 4 | * Used for callback functions. 5 | * 6 | * @author Nicbo 7 | */ 8 | @FunctionalInterface 9 | public interface Callback { 10 | /** 11 | * Invokes the callback. 12 | */ 13 | void call(); 14 | } 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Nicbo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /Plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | ca.nicbo.invadedlandsevents 9 | invadedlandsevents-parent 10 | 2.0.0-ALPHA.3 11 | 12 | 13 | invadedlandsevents-plugin 14 | 15 | 16 | 17 | ca.nicbo.invadedlandsevents 18 | invadedlandsevents-api 19 | ${project.version} 20 | 21 | 22 | org.jetbrains 23 | annotations 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | src/main/resources 33 | true 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-shade-plugin 40 | 3.2.4 41 | 42 | 43 | package 44 | 45 | shade 46 | 47 | 48 | 49 | 50 | ${project.parent.name}-${project.version} 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/compatibility/Colour.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.compatibility; 2 | 3 | /** 4 | * The different colours that some materials can have. 5 | * 6 | * @author Nicbo 7 | */ 8 | public enum Colour { 9 | WHITE(0), 10 | ORANGE(1), 11 | MAGENTA(2), 12 | LIGHT_BLUE(3), 13 | YELLOW(4), 14 | LIME(5), 15 | PINK(6), 16 | GREY(7), 17 | LIGHT_GREY(8), 18 | CYAN(9), 19 | PURPLE(10), 20 | BLUE(11), 21 | BROWN(12), 22 | GREEN(13), 23 | RED(14), 24 | BLACK(15); 25 | 26 | private final short data; 27 | 28 | Colour(int data) { 29 | this.data = (short) data; 30 | } 31 | 32 | public short getData() { 33 | return data; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/compatibility/CompatibleMaterial.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.compatibility; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | /** 7 | * Compatible materials for the changes from legacy to 1.13. 8 | * 9 | * @author Nicbo 10 | */ 11 | public enum CompatibleMaterial { 12 | WOODEN_SWORD("WOODEN_SWORD", "WOOD_SWORD"), 13 | GOLDEN_SWORD("GOLDEN_SWORD", "GOLD_SWORD"), 14 | GOLDEN_AXE("GOLDEN_AXE", "GOLD_AXE"), 15 | DIAMOND_SHOVEL("DIAMOND_SHOVEL", "DIAMOND_SPADE"), 16 | RAIL("RAIL", "RAILS"), 17 | LEAD("LEAD", "LEASH"), 18 | SNOWBALL("SNOWBALL", "SNOW_BALL"), 19 | WHITE_WOOL("WHITE_WOOL", "WOOL", Colour.WHITE), 20 | ORANGE_WOOL("ORANGE_WOOL", "WOOL", Colour.ORANGE), 21 | MAGENTA_WOOL("MAGENTA_WOOL", "WOOL", Colour.MAGENTA), 22 | LIGHT_BLUE_WOOL("LIGHT_BLUE_WOOL", "WOOL", Colour.BLUE), 23 | YELLOW_WOOL("YELLOW_WOOL", "WOOL", Colour.YELLOW), 24 | LIME_WOOL("LIME_WOOL", "WOOL", Colour.LIME), 25 | PINK_WOOL("PINK_WOOL", "WOOL", Colour.PINK), 26 | GREY_WOOL("GRAY_WOOL", "WOOL", Colour.GREY), 27 | LIGHT_GREY_WOOL("LIGHT_GRAY_WOOL", "WOOL", Colour.LIGHT_GREY), 28 | CYAN_WOOL("CYAN_WOOL", "WOOL", Colour.CYAN), 29 | PURPLE_WOOL("PURPLE_WOOL", "WOOL", Colour.PURPLE), 30 | BLUE_WOOL("BLUE_WOOL", "WOOL", Colour.BLUE), 31 | BROWN_WOOL("BROWN_WOOL", "WOOL", Colour.BROWN), 32 | GREEN_WOOL("GREEN_WOOL", "WOOL", Colour.GREEN), 33 | RED_WOOL("RED_WOOL", "WOOL", Colour.RED), 34 | BLACK_WOOL("BLACK_WOOL", "WOOL", Colour.BLACK), 35 | WHITE_GLASS_PANE("WHITE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.WHITE), 36 | ORANGE_GLASS_PANE("ORANGE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.ORANGE), 37 | MAGENTA_GLASS_PANE("MAGENTA_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.MAGENTA), 38 | LIGHT_BLUE_GLASS_PANE("LIGHT_BLUE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.LIGHT_BLUE), 39 | YELLOW_GLASS_PANE("YELLOW_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.YELLOW), 40 | LIME_GLASS_PANE("LIME_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.LIME), 41 | PINK_GLASS_PANE("PINK_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.PINK), 42 | GREY_GLASS_PANE("GRAY_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.GREY), 43 | LIGHT_GREY_GLASS_PANE("LIGHT_GRAY_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.LIGHT_GREY), 44 | CYAN_GLASS_PANE("CYAN_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.CYAN), 45 | PURPLE_GLASS_PANE("PURPLE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.PURPLE), 46 | BLUE_GLASS_PANE("BLUE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.BLUE), 47 | BROWN_GLASS_PANE("BROWN_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.BROWN), 48 | GREEN_GLASS_PANE("GREEN_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.GREEN), 49 | RED_GLASS_PANE("RED_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.RED), 50 | BLACK_GLASS_PANE("BLACK_STAINED_GLASS_PANE", "STAINED_GLASS_PANE", Colour.BLACK); 51 | 52 | private final String name; 53 | private final String legacyName; 54 | private final Colour colour; 55 | 56 | CompatibleMaterial(String name, String legacyName) { 57 | this(name, legacyName, null); 58 | } 59 | 60 | CompatibleMaterial(String name, String legacyName, Colour colour) { 61 | this.name = name; 62 | this.legacyName = legacyName; 63 | this.colour = colour; 64 | } 65 | 66 | public String getName() { 67 | return name; 68 | } 69 | 70 | public String getLegacyName() { 71 | return legacyName; 72 | } 73 | 74 | public Colour getColour() { 75 | return colour; 76 | } 77 | 78 | public ItemStack createItemStack() { 79 | return createItemStack(1); 80 | } 81 | 82 | public ItemStack createItemStack(int amount) { 83 | Material material = createMaterial(); 84 | ItemStack item = new ItemStack(material); 85 | 86 | if (NMSVersion.getCurrentVersion().isLegacy() && colour != null) { 87 | // noinspection deprecation (compatibility) 88 | item.setDurability(colour.getData()); 89 | } 90 | 91 | item.setAmount(amount); 92 | return item; 93 | } 94 | 95 | public Material createMaterial() { 96 | return Material.valueOf(NMSVersion.getCurrentVersion().isLegacy() ? legacyName : name); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/compatibility/NMSVersion.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.compatibility; 2 | 3 | import ca.nicbo.invadedlandsevents.exception.UnsupportedVersionException; 4 | import org.bukkit.Bukkit; 5 | 6 | /** 7 | * The different supported NMS versions. 8 | * 9 | * @author Nicbo 10 | */ 11 | public enum NMSVersion { 12 | v1_8_R1, v1_8_R2, v1_8_R3, 13 | v1_9_R1, v1_9_R2, 14 | v1_10_R1, 15 | v1_11_R1, 16 | v1_12_R1, 17 | v1_13_R1, v1_13_R2, 18 | v1_14_R1, 19 | v1_15_R1, 20 | v1_16_R1, v1_16_R2, v1_16_R3, 21 | v1_17_R1, 22 | v1_18_R1, v1_18_R2; 23 | 24 | private static final NMSVersion CURRENT_VERSION; 25 | 26 | static { 27 | String packageVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; 28 | try { 29 | CURRENT_VERSION = NMSVersion.valueOf(packageVersion); 30 | } catch (IllegalArgumentException e) { 31 | throw new UnsupportedVersionException("unsupported NMS version: " + packageVersion, e); 32 | } 33 | } 34 | 35 | public boolean isPreCombatUpdate() { 36 | return compareTo(v1_9_R1) < 0; 37 | } 38 | 39 | public boolean isLegacy() { 40 | return compareTo(v1_13_R1) < 0; 41 | } 42 | 43 | public static NMSVersion getCurrentVersion() { 44 | return CURRENT_VERSION; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/ConfigSerialization.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 4 | import ca.nicbo.invadedlandsevents.api.region.CuboidRegion; 5 | import ca.nicbo.invadedlandsevents.api.util.Validate; 6 | import ca.nicbo.invadedlandsevents.kit.InvadedKit; 7 | import ca.nicbo.invadedlandsevents.region.InvadedCuboidRegion; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.Location; 10 | import org.bukkit.World; 11 | import org.bukkit.configuration.InvalidConfigurationException; 12 | import org.bukkit.configuration.file.YamlConfiguration; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * Used for serializing and deserializing objects in config.yml. 19 | * 20 | * @author Nicbo 21 | */ 22 | public final class ConfigSerialization { 23 | private ConfigSerialization() { 24 | } 25 | 26 | public static String serializeLocation(Location location) { 27 | Validate.checkArgumentNotNull(location, "location"); 28 | Validate.checkArgumentNotNull(location.getWorld(), "location's world"); 29 | 30 | return location.getWorld().getName() + ";" + 31 | location.getX() + ";" + 32 | location.getY() + ";" + 33 | location.getZ() + ";" + 34 | location.getYaw() + ";" + 35 | location.getPitch(); 36 | } 37 | 38 | public static Location deserializeLocation(String serializedLocation) { 39 | Validate.checkArgumentNotNull(serializedLocation, "serializedLocation"); 40 | String[] splitLoc = serializedLocation.split(";"); 41 | Validate.checkArgument(splitLoc.length >= 6, "serializedLocation does not contain enough data: %s", serializedLocation); 42 | 43 | World world = Bukkit.getWorld(splitLoc[0]); 44 | 45 | if (world == null) { 46 | world = Bukkit.getWorlds().get(0); 47 | } 48 | 49 | double x = Double.parseDouble(splitLoc[1]); 50 | double y = Double.parseDouble(splitLoc[2]); 51 | double z = Double.parseDouble(splitLoc[3]); 52 | float yaw = Float.parseFloat(splitLoc[4]); 53 | float pitch = Float.parseFloat(splitLoc[5]); 54 | return new Location(world, x, y, z, yaw, pitch); 55 | } 56 | 57 | public static String serializeRegion(CuboidRegion region) { 58 | Validate.checkArgumentNotNull(region, "region"); 59 | Validate.checkArgumentNotNull(region.getLocationOne(), "region's first location"); 60 | Validate.checkArgumentNotNull(region.getLocationTwo(), "region's second location"); 61 | return serializeLocation(region.getLocationOne()) + "|" + serializeLocation(region.getLocationTwo()); 62 | } 63 | 64 | public static CuboidRegion deserializeRegion(String serializedRegion) { 65 | Validate.checkArgumentNotNull(serializedRegion, "serializedRegion"); 66 | String[] serializedLocations = serializedRegion.split("\\|"); 67 | Validate.checkArgument(serializedLocations.length >= 2, "serializedRegion does not contain enough data: %s", serializedRegion); 68 | return new InvadedCuboidRegion(deserializeLocation(serializedLocations[0]), deserializeLocation(serializedLocations[1])); 69 | } 70 | 71 | public static String serializeKit(Kit kit) { 72 | Validate.checkArgumentNotNull(kit, "kit"); 73 | YamlConfiguration config = new YamlConfiguration(); 74 | config.set("items", kit.getItems()); 75 | config.set("armour", kit.getArmour()); 76 | config.set("offhand", kit.getOffhand()); 77 | return config.saveToString(); 78 | } 79 | 80 | @SuppressWarnings("unchecked") 81 | public static Kit deserializeKit(String serializedKit) { 82 | Validate.checkArgumentNotNull(serializedKit, "serializedKit"); 83 | 84 | YamlConfiguration configuration = new YamlConfiguration(); 85 | try { 86 | configuration.loadFromString(serializedKit); 87 | } catch (InvalidConfigurationException e) { 88 | throw new IllegalArgumentException("serializedKit is invalid", e); 89 | } 90 | 91 | List items = (List) configuration.getList("items"); 92 | List armour = (List) configuration.getList("armour"); 93 | ItemStack offhand = configuration.getItemStack("offhand"); 94 | return new InvadedKit(items, armour, offhand); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/ConfigurationFile.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import org.bukkit.configuration.InvalidConfigurationException; 6 | import org.bukkit.configuration.file.FileConfiguration; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.util.logging.Level; 12 | import java.util.logging.Logger; 13 | 14 | /** 15 | * A configuration file. 16 | * 17 | * @author thehydrogen 18 | * @author Nicbo 19 | */ 20 | public class ConfigurationFile { 21 | private final String name; 22 | private final File file; 23 | private final boolean existed; 24 | private final FileConfiguration config; 25 | private final Logger logger; 26 | 27 | public ConfigurationFile(String fileName, InvadedLandsEventsPlugin plugin) { 28 | Validate.checkArgumentNotNull(fileName, "fileName"); 29 | Validate.checkArgumentNotNull(plugin, "plugin"); 30 | 31 | this.name = fileName; 32 | this.file = new File(plugin.getDataFolder(), fileName); 33 | this.existed = file.exists(); 34 | 35 | if (!existed) { 36 | plugin.saveResource(fileName, false); 37 | } 38 | 39 | this.config = YamlConfiguration.loadConfiguration(file); 40 | this.logger = plugin.getLogger(); 41 | } 42 | 43 | public void save() { 44 | try { 45 | config.save(file); 46 | } catch (IOException e) { 47 | logger.log(Level.SEVERE, "could not save " + name, e); 48 | } 49 | } 50 | 51 | public void reload() { 52 | try { 53 | config.load(file); 54 | } catch (IOException | InvalidConfigurationException e) { 55 | logger.log(Level.SEVERE, "could not reload " + name, e); 56 | } 57 | } 58 | 59 | public boolean existed() { 60 | return existed; 61 | } 62 | 63 | public FileConfiguration getConfig() { 64 | return config; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/InvadedConfigSection.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.api.configuration.ConfigSection; 4 | import ca.nicbo.invadedlandsevents.api.configuration.ConfigValueType; 5 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 6 | import ca.nicbo.invadedlandsevents.api.region.CuboidRegion; 7 | import ca.nicbo.invadedlandsevents.api.util.Validate; 8 | import org.bukkit.Location; 9 | import org.bukkit.configuration.ConfigurationSection; 10 | 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | /** 15 | * Implementation of {@link ConfigSection}. 16 | * 17 | * @author Nicbo 18 | */ 19 | public class InvadedConfigSection implements ConfigSection { 20 | private static final String TYPE_SUFFIX = ".type"; 21 | private static final String DESCRIPTION_SUFFIX = ".description"; 22 | private static final String VALUE_SUFFIX = ".value"; 23 | 24 | private final String name; 25 | private final InvadedConfigHandler configHandler; 26 | 27 | private final ConfigurationSection configurationSection; 28 | 29 | public InvadedConfigSection(String name, InvadedConfigHandler configHandler) { 30 | Validate.checkArgumentNotNull(name, "name"); 31 | Validate.checkArgumentNotNull(configHandler, "configHandler"); 32 | this.name = name; 33 | this.configHandler = configHandler; 34 | this.configurationSection = configHandler.getInternalConfiguration().getConfigurationSection(name); 35 | Validate.checkNotNull(configurationSection, "config.yml does not contain %s", name); 36 | } 37 | 38 | @Override 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | @Override 44 | public boolean getBoolean(String key) { 45 | checkContainsKeyWithCorrectType(key, ConfigValueType.BOOLEAN); 46 | return configurationSection.getBoolean(key + VALUE_SUFFIX); 47 | } 48 | 49 | @Override 50 | public void setBoolean(String key, boolean value) { 51 | setValue(key, ConfigValueType.BOOLEAN, value); 52 | } 53 | 54 | @Override 55 | public int getInteger(String key) { 56 | checkContainsKeyWithCorrectType(key, ConfigValueType.INTEGER); 57 | return configurationSection.getInt(key + VALUE_SUFFIX); 58 | } 59 | 60 | @Override 61 | public void setInteger(String key, int value) { 62 | setValue(key, ConfigValueType.INTEGER, value); 63 | } 64 | 65 | @Override 66 | public Kit getKit(String key) { 67 | checkContainsKeyWithCorrectType(key, ConfigValueType.KIT); 68 | return ConfigSerialization.deserializeKit(configurationSection.getString(key + VALUE_SUFFIX)); 69 | } 70 | 71 | @Override 72 | public void setKit(String key, Kit value) { 73 | setValue(key, ConfigValueType.KIT, ConfigSerialization.serializeKit(value)); 74 | } 75 | 76 | @Override 77 | public Location getLocation(String key) { 78 | checkContainsKeyWithCorrectType(key, ConfigValueType.LOCATION); 79 | return ConfigSerialization.deserializeLocation(configurationSection.getString(key + VALUE_SUFFIX)); 80 | } 81 | 82 | @Override 83 | public void setLocation(String key, Location value) { 84 | setValue(key, ConfigValueType.LOCATION, ConfigSerialization.serializeLocation(value)); 85 | } 86 | 87 | @Override 88 | public CuboidRegion getRegion(String key) { 89 | checkContainsKeyWithCorrectType(key, ConfigValueType.REGION); 90 | return ConfigSerialization.deserializeRegion(configurationSection.getString(key + VALUE_SUFFIX)); 91 | } 92 | 93 | @Override 94 | public void setRegion(String key, CuboidRegion value) { 95 | setValue(key, ConfigValueType.REGION, ConfigSerialization.serializeRegion(value)); 96 | } 97 | 98 | @Override 99 | public List getStringList(String key) { 100 | checkContainsKeyWithCorrectType(key, ConfigValueType.STRING_LIST); 101 | return configurationSection.getStringList(key + VALUE_SUFFIX); 102 | } 103 | 104 | @Override 105 | public void setStringList(String key, List value) { 106 | setValue(key, ConfigValueType.STRING_LIST, value); 107 | } 108 | 109 | @Override 110 | public ConfigValueType getType(String key) { 111 | checkContainsKey(key); 112 | return ConfigValueType.valueOf(configurationSection.getString(key + TYPE_SUFFIX)); 113 | } 114 | 115 | @Override 116 | public String getDescription(String key) { 117 | checkContainsKey(key); 118 | // noinspection ConstantConditions (we check if the key exists beforehand, this will not return null) 119 | return configurationSection.getString(key + DESCRIPTION_SUFFIX); 120 | } 121 | 122 | @Override 123 | public Set getKeys() { 124 | return configurationSection.getKeys(false); 125 | } 126 | 127 | private void setValue(String key, ConfigValueType type, Object value) { 128 | checkContainsKeyWithCorrectType(key, type); 129 | Validate.checkArgumentNotNull(value, "value"); 130 | configurationSection.set(key + VALUE_SUFFIX, value); 131 | configHandler.save(); 132 | } 133 | 134 | // Checks if section contains key 135 | private void checkContainsKey(String key) { 136 | Validate.checkArgumentNotNull(key, "key"); 137 | Validate.checkArgument(configurationSection.contains(key), "%s does not contain %s", key, key); 138 | } 139 | 140 | // Checks if section contains key and the type is correct 141 | private void checkContainsKeyWithCorrectType(String key, ConfigValueType type) { 142 | ConfigValueType configType = getType(key); // calls checkContainsKey 143 | Validate.checkArgumentNotNull(type, "type"); 144 | Validate.checkArgument(type == configType, "config value type for %s is %s, not %s", key, configType, type); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/InvadedConfigurationHandler.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.configuration.ConfigurationHandler; 5 | import ca.nicbo.invadedlandsevents.api.util.Validate; 6 | import org.bukkit.configuration.file.FileConfiguration; 7 | 8 | /** 9 | * Implementation of {@link ConfigurationHandler}. 10 | * 11 | * @author Nicbo 12 | */ 13 | public abstract class InvadedConfigurationHandler implements ConfigurationHandler { 14 | private final ConfigurationFile configurationFile; 15 | 16 | protected InvadedConfigurationHandler(String configFileName, InvadedLandsEventsPlugin plugin) { 17 | Validate.checkArgumentNotNull(configFileName, "configFileName"); 18 | Validate.checkArgumentNotNull(plugin, "plugin"); 19 | this.configurationFile = new ConfigurationFile(configFileName, plugin); 20 | } 21 | 22 | public FileConfiguration getInternalConfiguration() { 23 | return configurationFile.getConfig(); 24 | } 25 | 26 | public boolean isInitial() { 27 | return !configurationFile.existed(); 28 | } 29 | 30 | @Override 31 | public int getVersion() { 32 | return getInternalConfiguration().getInt("version"); 33 | } 34 | 35 | @Override 36 | public void save() { 37 | configurationFile.save(); 38 | } 39 | 40 | @Override 41 | public void reload() { 42 | configurationFile.reload(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/InvadedConfigurationManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.configuration.ConfigurationManager; 5 | import ca.nicbo.invadedlandsevents.api.configuration.WandLocationHolder; 6 | import ca.nicbo.invadedlandsevents.api.permission.EventPermission; 7 | import ca.nicbo.invadedlandsevents.api.util.Validate; 8 | import ca.nicbo.invadedlandsevents.compatibility.CompatibleMaterial; 9 | import ca.nicbo.invadedlandsevents.util.ItemStackBuilder; 10 | import ca.nicbo.invadedlandsevents.util.SpigotUtils; 11 | import ca.nicbo.invadedlandsevents.util.StringUtils; 12 | import org.bukkit.Location; 13 | import org.bukkit.block.Block; 14 | import org.bukkit.entity.Player; 15 | import org.bukkit.event.EventHandler; 16 | import org.bukkit.event.EventPriority; 17 | import org.bukkit.event.Listener; 18 | import org.bukkit.event.block.Action; 19 | import org.bukkit.event.player.PlayerInteractEvent; 20 | import org.bukkit.event.player.PlayerItemDamageEvent; 21 | import org.bukkit.event.player.PlayerQuitEvent; 22 | import org.bukkit.inventory.ItemStack; 23 | 24 | import java.util.Collections; 25 | import java.util.HashMap; 26 | import java.util.Map; 27 | 28 | /** 29 | * Implementation of {@link ConfigurationManager}. 30 | * 31 | * @author Nicbo 32 | */ 33 | public class InvadedConfigurationManager implements ConfigurationManager, Listener { 34 | public static final ItemStack WAND = new ItemStackBuilder(CompatibleMaterial.GOLDEN_AXE) 35 | .setName("&6InvadedLandsEvents Region Wand") 36 | .addLore("&7The &6region wand &7for &6InvadedLandsEvents") 37 | .addLore("&7Obtained with &6/econfig wand") 38 | .addLore("&6Left click &7a block to set &6location one") 39 | .addLore("&6Right click &7a block to set &6location two") 40 | .addLore("&7You must have &6" + EventPermission.CONFIG + "&7 to use this wand") 41 | .hideAttributes() 42 | .build(); 43 | 44 | private static final String PREFIX = "&e[&6ILE&e] "; 45 | 46 | private final InvadedConfigHandler configHandler; 47 | private final InvadedMessagesHandler messagesHandler; 48 | private final Map wandLocationHolderMap; 49 | 50 | public InvadedConfigurationManager(InvadedLandsEventsPlugin plugin) { 51 | Validate.checkArgumentNotNull(plugin, "plugin"); 52 | this.configHandler = new InvadedConfigHandler(plugin); 53 | this.messagesHandler = new InvadedMessagesHandler(plugin); 54 | this.wandLocationHolderMap = new HashMap<>(); 55 | } 56 | 57 | @Override 58 | public InvadedConfigHandler getConfigHandler() { 59 | return configHandler; 60 | } 61 | 62 | @Override 63 | public InvadedMessagesHandler getMessagesHandler() { 64 | return messagesHandler; 65 | } 66 | 67 | @EventHandler(priority = EventPriority.HIGHEST) 68 | public void onPlayerInteract(PlayerInteractEvent event) { 69 | Player player = event.getPlayer(); 70 | Block block = event.getClickedBlock(); 71 | if (event.getItem() != null && block != null && event.getItem().isSimilar(WAND) && player.hasPermission(EventPermission.CONFIG)) { 72 | Action action = event.getAction(); 73 | Location location = block.getLocation(); 74 | 75 | final String locationNumber; 76 | if (action == Action.LEFT_CLICK_BLOCK) { 77 | locationNumber = "First"; 78 | wandLocationHolderMap.computeIfAbsent(player, p -> new InvadedWandLocationHolder()).setLocationOne(location); 79 | } else if (action == Action.RIGHT_CLICK_BLOCK) { 80 | locationNumber = "Second"; 81 | wandLocationHolderMap.computeIfAbsent(player, p -> new InvadedWandLocationHolder()).setLocationTwo(location); 82 | } else { 83 | return; 84 | } 85 | 86 | SpigotUtils.sendMessage(player, PREFIX + "&e" + locationNumber + " location set to &6" + StringUtils.locationToString(location, false) + "&e."); 87 | event.setCancelled(true); 88 | } 89 | } 90 | 91 | // Using this instead of setUnbreakable because of compatibility issues 92 | @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) 93 | public void onPlayerItemDamage(PlayerItemDamageEvent event) { 94 | Player player = event.getPlayer(); 95 | if (event.getItem().isSimilar(WAND) && player.hasPermission(EventPermission.CONFIG)) { 96 | event.setCancelled(true); 97 | } 98 | } 99 | 100 | @EventHandler(priority = EventPriority.MONITOR) 101 | public void onPlayerQuit(PlayerQuitEvent event) { 102 | wandLocationHolderMap.remove(event.getPlayer()); 103 | } 104 | 105 | @Override 106 | public WandLocationHolder getWandLocationHolder(Player player) { 107 | Validate.checkArgumentNotNull(player, "player"); 108 | return wandLocationHolderMap.getOrDefault(player, new InvadedWandLocationHolder()); 109 | } 110 | 111 | @Override 112 | public Map getWandLocationHolderMap() { 113 | return Collections.unmodifiableMap(wandLocationHolderMap); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/InvadedMessagesHandler.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.configuration.MessagesHandler; 5 | import org.bukkit.configuration.file.FileConfiguration; 6 | 7 | /** 8 | * Implementation of {@link MessagesHandler}. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class InvadedMessagesHandler extends InvadedConfigurationHandler implements MessagesHandler { 13 | private static final String CONFIG_FILE_NAME = "messages.yml"; 14 | 15 | public InvadedMessagesHandler(InvadedLandsEventsPlugin plugin) { 16 | super(CONFIG_FILE_NAME, plugin); 17 | } 18 | 19 | @Override 20 | public void reload() { 21 | super.reload(); 22 | load(); 23 | } 24 | 25 | public void load() { 26 | FileConfiguration config = getInternalConfiguration(); 27 | Message.setConfig(config); 28 | ListMessage.setConfig(config); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/InvadedWandLocationHolder.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.api.configuration.WandLocationHolder; 4 | import ca.nicbo.invadedlandsevents.util.StringUtils; 5 | import org.bukkit.Location; 6 | 7 | /** 8 | * Implementation of {@link WandLocationHolder}. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class InvadedWandLocationHolder implements WandLocationHolder { 13 | private Location locationOne; 14 | private Location locationTwo; 15 | 16 | @Override 17 | public Location getLocationOne() { 18 | return cloneOrNull(locationOne); 19 | } 20 | 21 | @Override 22 | public void setLocationOne(Location locationOne) { 23 | this.locationOne = locationOne; 24 | } 25 | 26 | @Override 27 | public Location getLocationTwo() { 28 | return cloneOrNull(locationTwo); 29 | } 30 | 31 | @Override 32 | public void setLocationTwo(Location locationTwo) { 33 | this.locationTwo = locationTwo; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "(" + StringUtils.locationToString(locationOne, false) + ", " + StringUtils.locationToString(locationTwo, false) + ")"; 39 | } 40 | 41 | private static Location cloneOrNull(Location location) { 42 | return location == null ? null : location.clone(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/configuration/ListMessage.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.configuration; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import ca.nicbo.invadedlandsevents.util.StringUtils; 5 | import org.bukkit.configuration.file.FileConfiguration; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * All customizable list messages. 11 | * 12 | * @author Nicbo 13 | */ 14 | public enum ListMessage { 15 | INFO_MESSAGES("general.INFO_MESSAGES"), 16 | STATS_MESSAGES("general.STATS_MESSAGES"), 17 | USAGE_MESSAGES("general.USAGE_MESSAGES"), 18 | WIN_MESSAGES("general.WIN_MESSAGES"), 19 | 20 | TDM_WINNERS("tdm.WINNERS"), 21 | TDM_WINNERS_LIST("tdm.WINNERS_LIST"), 22 | 23 | BRACKETS1V1_DESCRIPTION("description.BRACKETS1V1"), 24 | BRACKETS2V2_DESCRIPTION("description.BRACKETS2V2"), 25 | BRACKETS3V3_DESCRIPTION("description.BRACKETS3V3"), 26 | SUMO1V1_DESCRIPTION("description.SUMO1V1"), 27 | SUMO2V2_DESCRIPTION("description.SUMO2V2"), 28 | SUMO3V3_DESCRIPTION("description.SUMO3V3"), 29 | KOTH_DESCRIPTION("description.KOTH"), 30 | LMS_DESCRIPTION("description.LMS"), 31 | OITC_DESCRIPTION("description.OITC"), 32 | REDROVER_DESCRIPTION("description.REDROVER"), 33 | ROD_DESCRIPTION("description.ROD"), 34 | SPLEEF_DESCRIPTION("description.SPLEEF"), 35 | TDM_DESCRIPTION("description.TDM"), 36 | TNTTAG_DESCRIPTION("description.TNTTAG"), 37 | WATERDROP_DESCRIPTION("description.WATERDROP"), 38 | WOOLSHUFFLE("description.WOOLSHUFFLE"); 39 | 40 | private static FileConfiguration config; 41 | 42 | private final String path; 43 | 44 | ListMessage(String path) { 45 | this.path = path; 46 | } 47 | 48 | public List get() { 49 | Validate.checkState(config != null, "config has not been set yet"); 50 | List messages = config.getStringList(path); 51 | Validate.checkNotNull(messages.isEmpty() ? null : messages, "could not find %s", path); 52 | return StringUtils.colour(messages); 53 | } 54 | 55 | public String getPath() { 56 | return path; 57 | } 58 | 59 | static void setConfig(FileConfiguration config) { 60 | Validate.checkArgumentNotNull(config, "config"); 61 | ListMessage.config = config; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/data/InvadedPlayerData.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.data; 2 | 3 | import ca.nicbo.invadedlandsevents.api.data.PlayerData; 4 | import ca.nicbo.invadedlandsevents.api.data.PlayerEventData; 5 | import ca.nicbo.invadedlandsevents.api.event.EventType; 6 | import ca.nicbo.invadedlandsevents.api.util.Validate; 7 | import org.bukkit.configuration.file.FileConfiguration; 8 | import org.bukkit.configuration.file.YamlConfiguration; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.util.Collections; 13 | import java.util.EnumMap; 14 | import java.util.Map; 15 | import java.util.UUID; 16 | 17 | /** 18 | * Implementation of {@link PlayerData}. 19 | * 20 | * @author Nicbo 21 | */ 22 | public class InvadedPlayerData implements PlayerData { 23 | private final UUID uuid; 24 | private final File file; 25 | private final FileConfiguration config; 26 | 27 | private final Map eventDataMap; 28 | 29 | public InvadedPlayerData(UUID uuid, File file) { 30 | Validate.checkArgumentNotNull(uuid, "uuid"); 31 | Validate.checkArgumentNotNull(file, "file"); 32 | this.uuid = uuid; 33 | this.file = file; 34 | this.config = YamlConfiguration.loadConfiguration(file); 35 | Map eventDataMap = new EnumMap<>(EventType.class); 36 | 37 | for (EventType eventType : EventType.values()) { 38 | final String path = eventType.getConfigName() + "."; 39 | final long timestamp = config.getLong(path + "timestamp"); 40 | final int wins = config.getInt(path + "wins"); 41 | eventDataMap.put(eventType, new InvadedPlayerEventData(eventType, timestamp, wins)); 42 | } 43 | 44 | this.eventDataMap = Collections.unmodifiableMap(eventDataMap); 45 | } 46 | 47 | @Override 48 | public UUID getPlayerUUID() { 49 | return uuid; 50 | } 51 | 52 | @Override 53 | public PlayerEventData getEventData(EventType eventType) { 54 | Validate.checkArgumentNotNull(eventType, "eventType"); 55 | return eventDataMap.get(eventType); 56 | } 57 | 58 | @Override 59 | public Map getEventDataMap() { 60 | return eventDataMap; 61 | } 62 | 63 | @Override 64 | public void saveToFile() throws IOException { 65 | // Save event data 66 | for (Map.Entry entry : eventDataMap.entrySet()) { 67 | final String path = entry.getKey().getConfigName() + "."; 68 | PlayerEventData eventData = entry.getValue(); 69 | config.set(path + "timestamp", eventData.getHostTimestamp()); 70 | config.set(path + "wins", eventData.getWins()); 71 | } 72 | 73 | config.save(file); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/data/InvadedPlayerEventData.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.data; 2 | 3 | import ca.nicbo.invadedlandsevents.api.data.PlayerEventData; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.api.util.Validate; 6 | 7 | /** 8 | * Implementation of {@link PlayerEventData}. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class InvadedPlayerEventData implements PlayerEventData { 13 | private final EventType eventType; 14 | private long hostTimestamp; 15 | private int wins; 16 | 17 | public InvadedPlayerEventData(EventType eventType, long hostTimestamp, int wins) { 18 | Validate.checkArgumentNotNull(eventType, "eventType"); 19 | this.eventType = eventType; 20 | this.hostTimestamp = hostTimestamp; 21 | this.wins = wins; 22 | } 23 | 24 | @Override 25 | public EventType getEventType() { 26 | return eventType; 27 | } 28 | 29 | @Override 30 | public long getHostTimestamp() { 31 | return hostTimestamp; 32 | } 33 | 34 | @Override 35 | public void setHostTimestamp(long hostTimestamp) { 36 | this.hostTimestamp = hostTimestamp; 37 | } 38 | 39 | @Override 40 | public int getWins() { 41 | return wins; 42 | } 43 | 44 | @Override 45 | public void setWins(int wins) { 46 | this.wins = wins; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/InvadedEventTeam.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import ca.nicbo.invadedlandsevents.util.CollectionUtils; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.Collections; 8 | import java.util.HashSet; 9 | import java.util.Iterator; 10 | import java.util.Objects; 11 | import java.util.Set; 12 | import java.util.stream.Stream; 13 | 14 | /** 15 | * A team of players in the {@link InvadedEvent}. 16 | * 17 | * @author Nicbo 18 | */ 19 | public class InvadedEventTeam implements Iterable { 20 | private final String name; 21 | private final Set players; 22 | private Set playersBackup; 23 | 24 | public InvadedEventTeam(String name) { 25 | this(name, new HashSet<>()); 26 | } 27 | 28 | public InvadedEventTeam(String name, Set players) { 29 | Validate.checkArgumentNotNull(name, "name"); 30 | Validate.checkArgumentNotNull(players, "players"); 31 | this.name = name; 32 | this.players = players; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public void add(Player player) { 40 | Validate.checkNotNull(player, "player"); 41 | players.add(player); 42 | } 43 | 44 | public void remove(Player player) { 45 | Validate.checkNotNull(player, "player"); 46 | players.remove(player); 47 | } 48 | 49 | public boolean contains(Player player) { 50 | Validate.checkNotNull(player, "player"); 51 | return players.contains(player); 52 | } 53 | 54 | public boolean isEmpty() { 55 | return players.isEmpty(); 56 | } 57 | 58 | public int size() { 59 | return players.size(); 60 | } 61 | 62 | public void clear() { 63 | players.clear(); 64 | } 65 | 66 | public void backup() { 67 | playersBackup = new HashSet<>(players); 68 | } 69 | 70 | public Set getPlayersBackup() { 71 | return playersBackup != null ? 72 | Collections.unmodifiableSet(playersBackup) : 73 | Collections.emptySet(); 74 | } 75 | 76 | @Override 77 | public int hashCode() { 78 | return Objects.hash(name, players, playersBackup); 79 | } 80 | 81 | @Override 82 | public boolean equals(Object obj) { 83 | if (this == obj) { 84 | return true; 85 | } 86 | 87 | if (!(obj instanceof InvadedEventTeam)) { 88 | return false; 89 | } 90 | 91 | InvadedEventTeam other = (InvadedEventTeam) obj; 92 | return name.equals(other.name) && players.equals(other.players) && Objects.equals(playersBackup, other.playersBackup); 93 | } 94 | 95 | @Override 96 | public Iterator iterator() { 97 | return players.iterator(); 98 | } 99 | 100 | public Stream stream() { 101 | return players.stream(); 102 | } 103 | 104 | public static InvadedEventTeam unmodifiableOf(InvadedEventTeam original) { 105 | Validate.checkArgumentNotNull(original, "original"); 106 | return new InvadedEventUnmodifiableTeam(original); 107 | } 108 | 109 | private static final class InvadedEventUnmodifiableTeam extends InvadedEventTeam { 110 | private InvadedEventUnmodifiableTeam(InvadedEventTeam original) { 111 | super(original.name, original.players); 112 | } 113 | 114 | @Override 115 | public void add(Player player) { 116 | throw new UnsupportedOperationException("can't add to an unmodifiable team"); 117 | } 118 | 119 | @Override 120 | public void remove(Player player) { 121 | throw new UnsupportedOperationException("can't remove from an unmodifiable team"); 122 | } 123 | 124 | @Override 125 | public void clear() { 126 | throw new UnsupportedOperationException("can't clear an unmodifiable team"); 127 | } 128 | 129 | @Override 130 | public void backup() { 131 | throw new UnsupportedOperationException("can't backup an unmodifiable team"); 132 | } 133 | 134 | @Override 135 | public Iterator iterator() { 136 | return CollectionUtils.unmodifiableIterator(super.iterator()); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/InvadedEventValidationResult.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | 5 | /** 6 | * The result of validating an {@link InvadedEvent}. 7 | * 8 | * @author Nicbo 9 | */ 10 | public class InvadedEventValidationResult { 11 | private static final String DEFAULT_VALID_MESSAGE = "Event is valid"; 12 | private static final String DEFAULT_INVALID_MESSAGE = "Event is invalid"; 13 | 14 | private final boolean valid; 15 | private final String message; 16 | 17 | public InvadedEventValidationResult(boolean valid) { 18 | this(valid, valid ? DEFAULT_VALID_MESSAGE : DEFAULT_INVALID_MESSAGE); 19 | } 20 | 21 | public InvadedEventValidationResult(boolean valid, String message) { 22 | Validate.checkArgumentNotNull(message, "message"); 23 | this.valid = valid; 24 | this.message = message; 25 | } 26 | 27 | public boolean isValid() { 28 | return valid; 29 | } 30 | 31 | public String getMessage() { 32 | return message; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/brackets/Brackets.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.brackets; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.event.duel.DuelEvent; 6 | import ca.nicbo.invadedlandsevents.event.event.player.EventPlayerDamageByEventPlayerEvent; 7 | import org.bukkit.event.EventHandler; 8 | import org.bukkit.event.EventPriority; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Brackets. 14 | * 15 | * @author Nicbo 16 | */ 17 | public abstract class Brackets extends DuelEvent { 18 | protected Brackets(InvadedLandsEventsPlugin plugin, EventType eventType, String hostName, List description, int teamSize) { 19 | super(plugin, eventType, hostName, description, teamSize); 20 | } 21 | 22 | @Override 23 | @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) 24 | public void onEventPlayerDamageByEventPlayer(EventPlayerDamageByEventPlayerEvent event) { 25 | super.onEventPlayerDamageByEventPlayer(event); 26 | 27 | if (event.isCancelled()) { 28 | return; 29 | } 30 | 31 | if (event.isKillingBlow()) { 32 | event.doFakeDeath(); 33 | eliminatePlayer(event.getPlayer(), false); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/brackets/Brackets1v1.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.brackets; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 6 | 7 | /** 8 | * Brackets 1v1. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class Brackets1v1 extends Brackets { 13 | public Brackets1v1(InvadedLandsEventsPlugin plugin, String hostName) { 14 | super(plugin, EventType.BRACKETS_1V1, hostName, ListMessage.BRACKETS1V1_DESCRIPTION.get(), 1); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/brackets/Brackets2v2.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.brackets; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 6 | 7 | /** 8 | * Brackets 2v2. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class Brackets2v2 extends Brackets { 13 | public Brackets2v2(InvadedLandsEventsPlugin plugin, String hostName) { 14 | super(plugin, EventType.BRACKETS_2V2, hostName, ListMessage.BRACKETS2V2_DESCRIPTION.get(), 2); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/brackets/Brackets3v3.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.brackets; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 6 | 7 | /** 8 | * Brackets 3v3. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class Brackets3v3 extends Brackets { 13 | public Brackets3v3(InvadedLandsEventsPlugin plugin, String hostName) { 14 | super(plugin, EventType.BRACKETS_3V3, hostName, ListMessage.BRACKETS3V3_DESCRIPTION.get(), 3); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/sumo/Sumo.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.sumo; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostEndEvent; 6 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostStartEvent; 7 | import ca.nicbo.invadedlandsevents.event.duel.DuelEvent; 8 | import ca.nicbo.invadedlandsevents.event.event.player.EventPlayerDamageByEventPlayerEvent; 9 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.EventPriority; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Sumo. 17 | * 18 | * @author Nicbo 19 | */ 20 | public abstract class Sumo extends DuelEvent { 21 | private final int minY; 22 | private final EliminationTask eliminationTask; 23 | 24 | protected Sumo(InvadedLandsEventsPlugin plugin, EventType eventType, String hostName, List description, int teamSize) { 25 | super(plugin, eventType, hostName, description, teamSize); 26 | this.minY = getEventConfig().getInteger("min-y"); 27 | this.eliminationTask = new EliminationTask(); 28 | } 29 | 30 | @EventHandler(priority = EventPriority.MONITOR) 31 | public void onEventPostStart(EventPostStartEvent event) { 32 | super.onEventPostStart(event); 33 | this.eliminationTask.start(getPlugin()); 34 | } 35 | 36 | @Override 37 | @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) 38 | public void onEventPlayerDamageByEventPlayer(EventPlayerDamageByEventPlayerEvent event) { 39 | super.onEventPlayerDamageByEventPlayer(event); 40 | 41 | if (event.isCancelled()) { 42 | return; 43 | } 44 | 45 | event.setDamage(0); 46 | } 47 | 48 | @EventHandler(priority = EventPriority.MONITOR) 49 | public void onEventPostEnd(EventPostEndEvent event) { 50 | super.onEventPostEnd(event); 51 | this.eliminationTask.stop(); 52 | } 53 | 54 | private class EliminationTask extends SyncedTask { 55 | private static final long DELAY = 0; 56 | private static final long PERIOD = 1; 57 | 58 | public EliminationTask() { 59 | super(DELAY, PERIOD); 60 | } 61 | 62 | @Override 63 | protected void run() { 64 | // Since you can't tie sumo, don't have an eliminated list, just eliminate the first one found... 65 | getFightingPlayers().stream() 66 | .filter(player -> player.getLocation().getY() < minY) 67 | .findAny() 68 | .ifPresent(player -> eliminatePlayer(player, false)); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/sumo/Sumo1v1.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.sumo; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 6 | 7 | /** 8 | * Sumo 1v1. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class Sumo1v1 extends Sumo { 13 | public Sumo1v1(InvadedLandsEventsPlugin plugin, String hostName) { 14 | super(plugin, EventType.SUMO_1V1, hostName, ListMessage.SUMO1V1_DESCRIPTION.get(), 1); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/sumo/Sumo2v2.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.sumo; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 6 | 7 | /** 8 | * Sumo 2v2. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class Sumo2v2 extends Sumo { 13 | public Sumo2v2(InvadedLandsEventsPlugin plugin, String hostName) { 14 | super(plugin, EventType.SUMO_2V2, hostName, ListMessage.SUMO2V2_DESCRIPTION.get(), 2); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/duel/sumo/Sumo3v3.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.duel.sumo; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 6 | 7 | /** 8 | * Sumo 3v3. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class Sumo3v3 extends Sumo { 13 | public Sumo3v3(InvadedLandsEventsPlugin plugin, String hostName) { 14 | super(plugin, EventType.SUMO_3V3, hostName, ListMessage.SUMO3V3_DESCRIPTION.get(), 3); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/event/player/EventPlayerDamageByEventPlayerEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.event.player; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.Event; 4 | import ca.nicbo.invadedlandsevents.api.event.event.player.EventPlayerEvent; 5 | import ca.nicbo.invadedlandsevents.api.util.Validate; 6 | import ca.nicbo.invadedlandsevents.util.SpigotUtils; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.entity.Projectile; 9 | import org.bukkit.event.Cancellable; 10 | import org.bukkit.event.HandlerList; 11 | import org.bukkit.event.entity.EntityDamageByEntityEvent; 12 | 13 | /** 14 | * Called when an event player damages an event player. 15 | * 16 | * @author Nicbo 17 | */ 18 | public class EventPlayerDamageByEventPlayerEvent extends EventPlayerEvent implements Cancellable { 19 | private static final HandlerList HANDLERS = new HandlerList(); 20 | 21 | private final Player damager; 22 | private final Projectile projectile; 23 | private final EntityDamageByEntityEvent originalEvent; 24 | 25 | private boolean applyingKnockback; 26 | 27 | public EventPlayerDamageByEventPlayerEvent(Event event, Player player, Player damager, EntityDamageByEntityEvent originalEvent) { 28 | super(event, player); 29 | Validate.checkArgumentNotNull(damager, "damager"); 30 | Validate.checkArgumentNotNull(originalEvent, "originalEvent"); 31 | this.damager = damager; 32 | this.projectile = originalEvent.getDamager() instanceof Projectile ? (Projectile) originalEvent.getDamager() : null; 33 | this.originalEvent = originalEvent; 34 | this.applyingKnockback = true; 35 | } 36 | 37 | public boolean isKillingBlow() { 38 | return getPlayer().getHealth() - getFinalDamage() <= 0; 39 | } 40 | 41 | public void doFakeDeath() { 42 | setDamage(0); 43 | setApplyingKnockback(false); 44 | SpigotUtils.clear(getPlayer()); 45 | } 46 | 47 | public double getDamage() { 48 | return originalEvent.getDamage(); 49 | } 50 | 51 | public void setDamage(double damage) { 52 | originalEvent.setDamage(damage); 53 | } 54 | 55 | public double getFinalDamage() { 56 | return originalEvent.getFinalDamage(); 57 | } 58 | 59 | public Player getDamager() { 60 | return damager; 61 | } 62 | 63 | public Projectile getProjectile() { 64 | return projectile; 65 | } 66 | 67 | public boolean isApplyingKnockback() { 68 | return applyingKnockback; 69 | } 70 | 71 | public void setApplyingKnockback(boolean applyingKnockback) { 72 | this.applyingKnockback = applyingKnockback; 73 | } 74 | 75 | @Override 76 | public HandlerList getHandlers() { 77 | return HANDLERS; 78 | } 79 | 80 | @Override 81 | public boolean isCancelled() { 82 | return originalEvent.isCancelled(); 83 | } 84 | 85 | @Override 86 | public void setCancelled(boolean cancel) { 87 | originalEvent.setCancelled(cancel); 88 | } 89 | 90 | public static HandlerList getHandlerList() { 91 | return HANDLERS; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/round/RoundEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.round; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventState; 5 | import ca.nicbo.invadedlandsevents.api.event.EventType; 6 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostEndEvent; 7 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostStartEvent; 8 | import ca.nicbo.invadedlandsevents.event.InvadedEvent; 9 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.EventPriority; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Partial implementation of {@link InvadedEvent}. 17 | *

18 | * This type of event has rounds that end based on the provided times. If a player fails to meet the requirements by the 19 | * end of the round, they will be eliminated. 20 | * 21 | * @author Nicbo 22 | */ 23 | public abstract class RoundEvent extends InvadedEvent { 24 | private final int[] times; 25 | 26 | private final RoundTimerTask roundTimerTask; 27 | 28 | private int timer; 29 | private int round; 30 | 31 | protected RoundEvent(InvadedLandsEventsPlugin plugin, EventType eventType, String hostName, List description, int[] times) { 32 | super(plugin, eventType, hostName, description); 33 | this.times = times; 34 | this.roundTimerTask = new RoundTimerTask(); 35 | this.timer = times[0]; 36 | this.round = 1; 37 | } 38 | 39 | @EventHandler(priority = EventPriority.MONITOR) 40 | public void onEventPostStart(EventPostStartEvent event) { 41 | onStartRound(); 42 | roundTimerTask.start(getPlugin()); 43 | } 44 | 45 | @EventHandler(priority = EventPriority.MONITOR) 46 | public void onEventPostEnd(EventPostEndEvent event) { 47 | roundTimerTask.stop(); 48 | } 49 | 50 | protected abstract void onStartRound(); 51 | 52 | protected abstract void onEndRound(); 53 | 54 | // ---------- Getters for Plugin module users ---------- 55 | 56 | public int getTimer() { 57 | return timer; 58 | } 59 | 60 | public int getRound() { 61 | return round; 62 | } 63 | 64 | // ----------------------------------------------------- 65 | 66 | private class RoundTimerTask extends SyncedTask { 67 | private static final long DELAY = 0; 68 | private static final long PERIOD = 20; 69 | 70 | public RoundTimerTask() { 71 | super(DELAY, PERIOD); 72 | } 73 | 74 | @Override 75 | protected void run() { 76 | if (--timer <= 0) { 77 | if (++round < times.length) { 78 | timer = times[round - 1]; 79 | } else { 80 | timer = times[times.length - 1]; 81 | } 82 | 83 | onEndRound(); 84 | if (isState(EventState.STARTED)) { 85 | onStartRound(); 86 | } 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/timer/LastManStanding.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.timer; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostEndEvent; 6 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostStartEvent; 7 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 8 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 9 | import ca.nicbo.invadedlandsevents.configuration.Message; 10 | import ca.nicbo.invadedlandsevents.event.event.player.EventPlayerDamageByEventPlayerEvent; 11 | import ca.nicbo.invadedlandsevents.scoreboard.EventScoreboard; 12 | import ca.nicbo.invadedlandsevents.scoreboard.EventScoreboardLine; 13 | import ca.nicbo.invadedlandsevents.task.event.MatchCountdownTask; 14 | import ca.nicbo.invadedlandsevents.util.StringUtils; 15 | import org.bukkit.Location; 16 | import org.bukkit.entity.Player; 17 | import org.bukkit.event.EventHandler; 18 | import org.bukkit.event.EventPriority; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * Last Man Standing. 24 | * 25 | * @author Nicbo 26 | */ 27 | public class LastManStanding extends TimerEvent { 28 | private final Kit kit; 29 | private final Location startOne; 30 | private final Location startTwo; 31 | private final MatchCountdownTask matchCountdownTask; 32 | 33 | public LastManStanding(InvadedLandsEventsPlugin plugin, String hostName) { 34 | super(plugin, EventType.LAST_MAN_STANDING, hostName, ListMessage.LMS_DESCRIPTION.get()); 35 | this.kit = getEventConfig().getKit("kit"); 36 | this.startOne = getEventConfig().getLocation("start-1"); 37 | this.startTwo = getEventConfig().getLocation("start-2"); 38 | this.matchCountdownTask = new MatchCountdownTask.Builder(this::broadcastMessage) 39 | .setStarting(Message.LMS_MATCH_STARTING.get()) 40 | .setCounter(Message.LMS_MATCH_COUNTER.get()) 41 | .setStarted(Message.LMS_MATCH_STARTED.get()) 42 | .build(); 43 | } 44 | 45 | @Override 46 | protected EventScoreboard createEventScoreboard(Player player) { 47 | return new LastManStandingScoreboard(player); 48 | } 49 | 50 | @Override 51 | @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) 52 | public void onEventPlayerDamageByEventPlayer(EventPlayerDamageByEventPlayerEvent event) { 53 | super.onEventPlayerDamageByEventPlayer(event); 54 | 55 | Player player = event.getPlayer(); 56 | if (event.isCancelled()) { 57 | return; 58 | } 59 | 60 | if (matchCountdownTask.isRunning()) { 61 | event.setCancelled(true); 62 | return; 63 | } 64 | 65 | if (event.isKillingBlow()) { 66 | broadcastMessage(Message.LMS_ELIMINATED.get() 67 | .replace("{player}", player.getName()) 68 | .replace("{remaining}", String.valueOf(getPlayersSize() - 1))); 69 | event.doFakeDeath(); 70 | lose(player); 71 | } 72 | } 73 | 74 | @EventHandler(priority = EventPriority.MONITOR) 75 | public void onEventPostStart(EventPostStartEvent event) { 76 | super.onEventPostStart(event); 77 | 78 | List players = getPlayers(); 79 | for (int i = 0; i < players.size(); i++) { 80 | Player player = players.get(i); 81 | player.teleport(i % 2 == 0 ? startOne : startTwo); 82 | kit.apply(player); 83 | } 84 | 85 | matchCountdownTask.start(getPlugin()); 86 | } 87 | 88 | @EventHandler(priority = EventPriority.MONITOR) 89 | public void onEventPostEnd(EventPostEndEvent event) { 90 | super.onEventPostEnd(event); 91 | if (matchCountdownTask.isRunning()) { 92 | matchCountdownTask.stop(); 93 | } 94 | } 95 | 96 | private class LastManStandingScoreboard extends EventScoreboard { 97 | private final EventScoreboardLine playerCountLine; 98 | private final EventScoreboardLine spectatorCountLine; 99 | private final EventScoreboardLine timeRemainingLine; 100 | 101 | public LastManStandingScoreboard(Player player) { 102 | super(player, Message.TITLE_LMS.get(), getConfigName()); 103 | this.playerCountLine = new EventScoreboardLine(4); 104 | this.spectatorCountLine = new EventScoreboardLine(3); 105 | this.timeRemainingLine = new EventScoreboardLine(2); 106 | this.setLines(playerCountLine, spectatorCountLine, timeRemainingLine); 107 | } 108 | 109 | @Override 110 | protected void refresh() { 111 | playerCountLine.setText("&ePlayers: &6" + getPlayersSize()); 112 | spectatorCountLine.setText("&eSpectators: &6" + getSpectatorsSize()); 113 | timeRemainingLine.setText("&eTime Remaining: &6" + StringUtils.formatSeconds(getTimeLeft())); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/timer/RaceOfDeath.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.timer; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostEndEvent; 6 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostStartEvent; 7 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 8 | import ca.nicbo.invadedlandsevents.api.region.CuboidRegion; 9 | import ca.nicbo.invadedlandsevents.configuration.ListMessage; 10 | import ca.nicbo.invadedlandsevents.configuration.Message; 11 | import ca.nicbo.invadedlandsevents.event.event.player.EventPlayerDamageByEventPlayerEvent; 12 | import ca.nicbo.invadedlandsevents.scoreboard.EventScoreboard; 13 | import ca.nicbo.invadedlandsevents.scoreboard.EventScoreboardLine; 14 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 15 | import ca.nicbo.invadedlandsevents.util.StringUtils; 16 | import org.bukkit.Location; 17 | import org.bukkit.entity.Player; 18 | import org.bukkit.event.EventHandler; 19 | import org.bukkit.event.EventPriority; 20 | import org.bukkit.potion.PotionEffect; 21 | import org.bukkit.potion.PotionEffectType; 22 | 23 | /** 24 | * Race of Death. 25 | * 26 | * @author Nicbo 27 | */ 28 | public class RaceOfDeath extends TimerEvent { 29 | private final CuboidRegion winRegion; 30 | private final Location startLoc; 31 | private final Kit kit; 32 | private final WinRegionMonitorTask winRegionMonitorTask; 33 | 34 | public RaceOfDeath(InvadedLandsEventsPlugin plugin, String hostName) { 35 | super(plugin, EventType.RACE_OF_DEATH, hostName, ListMessage.ROD_DESCRIPTION.get()); 36 | this.winRegion = getEventConfig().getRegion("win-region"); 37 | this.startLoc = getEventConfig().getLocation("start"); 38 | this.kit = getEventConfig().getKit("kit"); 39 | this.winRegionMonitorTask = new WinRegionMonitorTask(); 40 | } 41 | 42 | @EventHandler(priority = EventPriority.MONITOR) 43 | public void onEventPostStart(EventPostStartEvent event) { 44 | super.onEventPostStart(event); 45 | PotionEffect invisibility = new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false, false); 46 | 47 | for (Player player : getPlayers()) { 48 | kit.apply(player); 49 | player.addPotionEffect(invisibility); 50 | player.teleport(startLoc); 51 | player.sendMessage(Message.ROD_START.get()); 52 | } 53 | 54 | this.winRegionMonitorTask.start(getPlugin()); 55 | } 56 | 57 | @EventHandler(priority = EventPriority.MONITOR) 58 | public void onEventPostEnd(EventPostEndEvent event) { 59 | super.onEventPostEnd(event); 60 | this.winRegionMonitorTask.stop(); 61 | } 62 | 63 | @Override 64 | protected EventScoreboard createEventScoreboard(Player player) { 65 | return new RaceOfDeathScoreboard(player); 66 | } 67 | 68 | @Override 69 | @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) 70 | public void onEventPlayerDamageByEventPlayer(EventPlayerDamageByEventPlayerEvent event) { 71 | event.setCancelled(true); 72 | } 73 | 74 | private class WinRegionMonitorTask extends SyncedTask { 75 | private static final long DELAY = 0; 76 | private static final long PERIOD = 1; 77 | 78 | public WinRegionMonitorTask() { 79 | super(DELAY, PERIOD); 80 | } 81 | 82 | @Override 83 | protected void run() { 84 | getPlayers().stream() 85 | .filter(winRegion::contains) 86 | .findAny() 87 | .ifPresent(player -> end(new EventEndingContext(player))); 88 | } 89 | } 90 | 91 | private class RaceOfDeathScoreboard extends EventScoreboard { 92 | private final EventScoreboardLine playerCountLine; 93 | private final EventScoreboardLine spectatorCountLine; 94 | private final EventScoreboardLine timeRemainingLine; 95 | 96 | public RaceOfDeathScoreboard(Player player) { 97 | super(player, Message.TITLE_ROD.get(), getConfigName()); 98 | this.playerCountLine = new EventScoreboardLine(4); 99 | this.spectatorCountLine = new EventScoreboardLine(3); 100 | this.timeRemainingLine = new EventScoreboardLine(2); 101 | this.setLines(playerCountLine, spectatorCountLine, timeRemainingLine); 102 | } 103 | 104 | @Override 105 | protected void refresh() { 106 | playerCountLine.setText("&ePlayers: &6" + getPlayersSize()); 107 | spectatorCountLine.setText("&eSpectators: &6" + getSpectatorsSize()); 108 | timeRemainingLine.setText("&eTime Remaining: &6" + StringUtils.formatSeconds(getTimeLeft())); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/event/timer/TimerEvent.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.event.timer; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.EventType; 5 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostEndEvent; 6 | import ca.nicbo.invadedlandsevents.api.event.event.EventPostStartEvent; 7 | import ca.nicbo.invadedlandsevents.event.InvadedEvent; 8 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.EventPriority; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Partial implementation of {@link InvadedEvent}. 17 | *

18 | * This type of event has a timer that will end the event when it reaches 0. 19 | * 20 | * @author Nicbo 21 | */ 22 | public abstract class TimerEvent extends InvadedEvent { 23 | private final TimerTask timerTask; 24 | private int timeLeft; 25 | 26 | protected TimerEvent(InvadedLandsEventsPlugin plugin, EventType eventType, String hostName, List description) { 27 | super(plugin, eventType, hostName, description); 28 | this.timerTask = new TimerTask(); 29 | this.timeLeft = getEventConfig().getInteger("time-limit"); 30 | } 31 | 32 | @EventHandler(priority = EventPriority.MONITOR) 33 | public void onEventPostStart(EventPostStartEvent event) { 34 | timerTask.start(getPlugin()); 35 | } 36 | 37 | @EventHandler(priority = EventPriority.MONITOR) 38 | public void onEventPostEnd(EventPostEndEvent event) { 39 | timerTask.stop(); 40 | } 41 | 42 | // ---------- Getters for Plugin module users ---------- 43 | 44 | public Player getCurrentWinner() { 45 | return null; 46 | } 47 | 48 | public int getTimeLeft() { 49 | return timeLeft; 50 | } 51 | 52 | // ----------------------------------------------------- 53 | 54 | private class TimerTask extends SyncedTask { 55 | private static final long DELAY = 0; 56 | private static final long PERIOD = 20; 57 | 58 | protected TimerTask() { 59 | super(DELAY, PERIOD); 60 | } 61 | 62 | @Override 63 | protected void run() { 64 | if (--timeLeft == 0) { 65 | Player winner = getCurrentWinner(); 66 | if (winner != null) { 67 | end(new EventEndingContext(winner)); 68 | } else { 69 | end(new EventEndingContext()); 70 | } 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/exception/UnsupportedVersionException.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.exception; 2 | 3 | /** 4 | * Thrown when the version is unsupported. 5 | * 6 | * @author Nicbo 7 | */ 8 | public class UnsupportedVersionException extends RuntimeException { 9 | public UnsupportedVersionException() { 10 | super(); 11 | } 12 | 13 | public UnsupportedVersionException(String message) { 14 | super(message); 15 | } 16 | 17 | public UnsupportedVersionException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public UnsupportedVersionException(Throwable cause) { 22 | super(cause); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/InvadedButton.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui; 2 | 3 | import ca.nicbo.invadedlandsevents.api.gui.Button; 4 | import ca.nicbo.invadedlandsevents.api.util.Callback; 5 | import ca.nicbo.invadedlandsevents.api.util.Validate; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | /** 9 | * Implementation of {@link Button}. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class InvadedButton implements Button { 14 | private ItemStack itemStack; 15 | private Callback callback; 16 | 17 | public InvadedButton(ItemStack itemStack) { 18 | this(itemStack, null); 19 | } 20 | 21 | public InvadedButton(ItemStack itemStack, Callback callback) { 22 | Validate.checkArgumentNotNull(itemStack, "itemStack"); 23 | this.itemStack = itemStack; 24 | this.callback = callback; 25 | } 26 | 27 | @Override 28 | public ItemStack getItemStack() { 29 | return itemStack.clone(); 30 | } 31 | 32 | @Override 33 | public void setItemStack(ItemStack itemStack) { 34 | Validate.checkArgumentNotNull(itemStack, "itemStack"); 35 | this.itemStack = itemStack; 36 | } 37 | 38 | @Override 39 | public Callback getCallback() { 40 | return callback; 41 | } 42 | 43 | @Override 44 | public void setCallback(Callback callback) { 45 | this.callback = callback; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/InvadedGui.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui; 2 | 3 | import ca.nicbo.invadedlandsevents.api.gui.Button; 4 | import ca.nicbo.invadedlandsevents.api.gui.Gui; 5 | import ca.nicbo.invadedlandsevents.api.gui.event.GuiOpenEvent; 6 | import ca.nicbo.invadedlandsevents.api.util.Validate; 7 | import ca.nicbo.invadedlandsevents.util.StringUtils; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.Inventory; 11 | 12 | import java.util.Collections; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * Implementation of {@link Gui}. 18 | * 19 | * @author Nicbo 20 | */ 21 | public class InvadedGui implements Gui { 22 | private final Player player; 23 | private final String title; 24 | private final int size; 25 | private final Inventory inventory; 26 | private final Map buttonMap; 27 | 28 | public InvadedGui(Player player, String title, int size) { 29 | Validate.checkArgumentNotNull(player, "player"); 30 | Validate.checkArgumentNotNull(title, "title"); 31 | Validate.checkArgument(size % 9 == 0 && size >= 9 && size <= 54, "size must be a multiple of 9 between 9 and 54 slots, size: %d", size); 32 | this.player = player; 33 | this.title = StringUtils.colour(title); 34 | this.size = size; 35 | this.inventory = Bukkit.createInventory(null, size, this.title); 36 | this.buttonMap = new HashMap<>(); 37 | } 38 | 39 | @Override 40 | public void open() { 41 | player.openInventory(inventory); 42 | Bukkit.getPluginManager().callEvent(new GuiOpenEvent(this)); 43 | } 44 | 45 | @Override 46 | public void close() { 47 | player.closeInventory(); 48 | // No need to call GuiCloseEvent - InventoryCloseEvent handles it in GuiManager 49 | } 50 | 51 | @Override 52 | public Player getPlayer() { 53 | return player; 54 | } 55 | 56 | @Override 57 | public String getTitle() { 58 | return title; 59 | } 60 | 61 | @Override 62 | public int getSize() { 63 | return size; 64 | } 65 | 66 | @Override 67 | public Button getButton(int slot) { 68 | return buttonMap.get(slot); 69 | } 70 | 71 | @Override 72 | public void setButton(int slot, Button button) { 73 | Validate.checkArgument(slot >= 0 && slot < size, "slot must be >=0 && <%d, provided: %d", size, slot); 74 | inventory.setItem(slot, button == null ? null : button.getItemStack()); 75 | buttonMap.put(slot, button); 76 | } 77 | 78 | @Override 79 | public boolean isSlotEmpty(int slot) { 80 | return !buttonMap.containsKey(slot); 81 | } 82 | 83 | @Override 84 | public Map getButtonMap() { 85 | return Collections.unmodifiableMap(buttonMap); 86 | } 87 | 88 | @Override 89 | public boolean isInventoryEqual(Inventory inventory) { 90 | return this.inventory.equals(inventory); 91 | } 92 | 93 | @Override 94 | public void update() { 95 | for (Map.Entry entry : buttonMap.entrySet()) { 96 | if (entry.getValue() == null) { 97 | continue; 98 | } 99 | 100 | inventory.setItem(entry.getKey(), entry.getValue().getItemStack()); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/InvadedGuiManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.gui.Button; 5 | import ca.nicbo.invadedlandsevents.api.gui.Gui; 6 | import ca.nicbo.invadedlandsevents.api.gui.GuiManager; 7 | import ca.nicbo.invadedlandsevents.api.gui.event.GuiCloseEvent; 8 | import ca.nicbo.invadedlandsevents.api.gui.event.GuiOpenEvent; 9 | import ca.nicbo.invadedlandsevents.api.util.Callback; 10 | import ca.nicbo.invadedlandsevents.api.util.Validate; 11 | import org.bukkit.Bukkit; 12 | import org.bukkit.entity.Player; 13 | import org.bukkit.event.EventHandler; 14 | import org.bukkit.event.EventPriority; 15 | import org.bukkit.event.Listener; 16 | import org.bukkit.event.inventory.InventoryClickEvent; 17 | import org.bukkit.event.inventory.InventoryCloseEvent; 18 | import org.bukkit.event.player.PlayerQuitEvent; 19 | 20 | import java.util.Collections; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | /** 25 | * Implementation of {@link GuiManager}. 26 | * 27 | * @author Nicbo 28 | */ 29 | public class InvadedGuiManager implements GuiManager, Listener { 30 | private final Map guiMap; 31 | 32 | public InvadedGuiManager() { 33 | this.guiMap = new HashMap<>(); 34 | } 35 | 36 | public void startUpdating(InvadedLandsEventsPlugin plugin) { 37 | Validate.checkArgumentNotNull(plugin, "plugin"); 38 | plugin.getServer().getScheduler().runTaskTimer(plugin, () -> { 39 | for (Gui gui : guiMap.values()) { 40 | gui.update(); 41 | } 42 | }, 0, 10); 43 | } 44 | 45 | @Override 46 | public Gui getGui(Player player) { 47 | Validate.checkArgumentNotNull(player, "player"); 48 | return guiMap.get(player); 49 | } 50 | 51 | @Override 52 | public Map getGuiMap() { 53 | return Collections.unmodifiableMap(guiMap); 54 | } 55 | 56 | @EventHandler(priority = EventPriority.MONITOR) 57 | public void onPlayerQuit(PlayerQuitEvent event) { 58 | Gui gui = guiMap.get(event.getPlayer()); 59 | if (gui != null) { 60 | gui.close(); 61 | } 62 | } 63 | 64 | @EventHandler(priority = EventPriority.MONITOR) 65 | public void onInventoryClose(InventoryCloseEvent event) { 66 | if (event.getPlayer() instanceof Player) { 67 | Player player = (Player) event.getPlayer(); 68 | Gui gui = guiMap.get(player); 69 | if (gui != null) { 70 | Bukkit.getPluginManager().callEvent(new GuiCloseEvent(gui)); 71 | } 72 | } 73 | } 74 | 75 | @EventHandler(priority = EventPriority.MONITOR) 76 | public void onGuiOpen(GuiOpenEvent event) { 77 | Gui gui = event.getGui(); 78 | guiMap.put(gui.getPlayer(), gui); 79 | } 80 | 81 | @EventHandler(priority = EventPriority.MONITOR) 82 | public void onGuiClose(GuiCloseEvent event) { 83 | guiMap.remove(event.getGui().getPlayer()); 84 | } 85 | 86 | @EventHandler(priority = EventPriority.HIGHEST) 87 | public void onInventoryClick(InventoryClickEvent event) { 88 | if (event.getWhoClicked() instanceof Player) { 89 | Player player = (Player) event.getWhoClicked(); 90 | Gui gui = guiMap.get(player); 91 | if (gui != null && gui.isInventoryEqual(event.getClickedInventory())) { 92 | event.setCancelled(true); 93 | Button button = gui.getButton(event.getSlot()); 94 | if (button != null) { 95 | Callback action = button.getCallback(); 96 | if (action != null) { 97 | action.call(); 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/config/KitViewGui.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui.config; 2 | 3 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.compatibility.CompatibleMaterial; 6 | import ca.nicbo.invadedlandsevents.gui.InvadedButton; 7 | import ca.nicbo.invadedlandsevents.gui.InvadedGui; 8 | import ca.nicbo.invadedlandsevents.kit.InvadedKit; 9 | import ca.nicbo.invadedlandsevents.util.CollectionUtils; 10 | import ca.nicbo.invadedlandsevents.util.ItemStackBuilder; 11 | import org.bukkit.ChatColor; 12 | import org.bukkit.entity.Player; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * Displays an {@link InvadedKit} to the player. 19 | * 20 | * @author Nicbo 21 | */ 22 | public final class KitViewGui extends InvadedGui { 23 | private static final ItemStack EMPTY = new ItemStackBuilder(CompatibleMaterial.RED_GLASS_PANE) 24 | .setName(ChatColor.GRAY.toString()) 25 | .build(); 26 | private static final ItemStack BLANK = new ItemStackBuilder(CompatibleMaterial.GREY_GLASS_PANE) 27 | .setName(ChatColor.GRAY.toString()) 28 | .build(); 29 | 30 | public KitViewGui(Player player, String title) { 31 | super(player, title, 54); 32 | } 33 | 34 | private static ItemStack emptyIfNull(ItemStack item) { 35 | return item == null ? EMPTY : item; 36 | } 37 | 38 | public static KitViewGui create(Player player, String title, Kit kit) { 39 | Validate.checkArgumentNotNull(kit, "kit"); 40 | 41 | KitViewGui gui = new KitViewGui(player, title); 42 | List items = kit.getItems(); 43 | List armour = CollectionUtils.reversedCopy(kit.getArmour()); // armour is backwards in this list 44 | 45 | // Top 3 rows 46 | for (int i = 0; i < 27; i++) { 47 | ItemStack kitItem = items.get(i + 9); 48 | gui.setButton(i, new InvadedButton(emptyIfNull(kitItem))); 49 | } 50 | 51 | // Hotbar 52 | for (int i = 0; i < 9; i++) { 53 | ItemStack kitItem = items.get(i); 54 | gui.setButton(i + 27, new InvadedButton(emptyIfNull(kitItem))); 55 | } 56 | 57 | // Blanks 58 | for (int i = 36; i < 49; i++) { 59 | gui.setButton(i, new InvadedButton(BLANK)); 60 | } 61 | 62 | // Armour 63 | for (int i = 0; i < 4; i++) { 64 | ItemStack kitItem = armour.get(i); 65 | gui.setButton(i + 49, new InvadedButton(emptyIfNull(kitItem))); 66 | } 67 | 68 | // Offhand slot (if it exists) 69 | ItemStack offhand = kit.getOffhand(); 70 | gui.setButton(53, new InvadedButton(emptyIfNull(offhand))); 71 | 72 | return gui; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/host/BracketsHostGui.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui.host; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import org.bukkit.entity.Player; 5 | 6 | /** 7 | * The {@link HostGui} for /e host brackets. 8 | * 9 | * @author Nicbo 10 | */ 11 | public final class BracketsHostGui extends HostGui { 12 | private BracketsHostGui(Player player, InvadedLandsEventsPlugin plugin) { 13 | super(player, "Host Brackets", 9, plugin); 14 | } 15 | 16 | public static BracketsHostGui create(Player player, InvadedLandsEventsPlugin plugin) { 17 | BracketsHostGui gui = new BracketsHostGui(player, plugin); 18 | gui.setButton(0, gui.createHostButton(HostButtonType.BRACKETS_1V1)); 19 | gui.setButton(1, gui.createHostButton(HostButtonType.BRACKETS_2V2)); 20 | gui.setButton(2, gui.createHostButton(HostButtonType.BRACKETS_3V3)); 21 | return gui; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/host/HostButton.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui.host; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Callback; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.gui.InvadedButton; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | /** 9 | * A button that hosts an event when clicked. 10 | * 11 | * @author Nicbo 12 | */ 13 | public class HostButton extends InvadedButton { 14 | private final HostButtonType type; 15 | 16 | public HostButton(ItemStack itemStack, Callback callback, HostButtonType type) { 17 | super(itemStack, callback); 18 | Validate.checkArgumentNotNull(type, "type"); 19 | this.type = type; 20 | } 21 | 22 | public HostButtonType getType() { 23 | return type; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/host/HostButtonType.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui.host; 2 | 3 | import ca.nicbo.invadedlandsevents.api.event.EventType; 4 | 5 | /** 6 | * The different {@link HostButton} types. 7 | * 8 | * @author Nicbo 9 | */ 10 | public enum HostButtonType { 11 | BRACKETS(null), 12 | BRACKETS_1V1(EventType.BRACKETS_1V1), 13 | BRACKETS_2V2(EventType.BRACKETS_2V2), 14 | BRACKETS_3V3(EventType.BRACKETS_3V3), 15 | KING_OF_THE_HILL(EventType.KING_OF_THE_HILL), 16 | LAST_MAN_STANDING(EventType.LAST_MAN_STANDING), 17 | ONE_IN_THE_CHAMBER(EventType.ONE_IN_THE_CHAMBER), 18 | REDROVER(EventType.REDROVER), 19 | RACE_OF_DEATH(EventType.RACE_OF_DEATH), 20 | SPLEEF(EventType.SPLEEF), 21 | SUMO(null), 22 | SUMO_1V1(EventType.SUMO_1V1), 23 | SUMO_2V2(EventType.SUMO_2V2), 24 | SUMO_3V3(EventType.SUMO_3V3), 25 | TEAM_DEATHMATCH(EventType.TEAM_DEATHMATCH), 26 | TNT_TAG(EventType.TNT_TAG), 27 | WATERDROP(EventType.WATERDROP), 28 | WOOL_SHUFFLE(EventType.WOOL_SHUFFLE); 29 | 30 | private final EventType eventType; 31 | 32 | HostButtonType(EventType eventType) { 33 | this.eventType = eventType; 34 | } 35 | 36 | public EventType getEventType() { 37 | return eventType; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/host/MainHostGui.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui.host; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.gui.Button; 5 | import ca.nicbo.invadedlandsevents.compatibility.CompatibleMaterial; 6 | import ca.nicbo.invadedlandsevents.gui.InvadedButton; 7 | import ca.nicbo.invadedlandsevents.util.CollectionUtils; 8 | import ca.nicbo.invadedlandsevents.util.ItemStackBuilder; 9 | import ca.nicbo.invadedlandsevents.util.RandomUtils; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.inventory.ItemStack; 12 | import org.bukkit.inventory.meta.ItemMeta; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * The {@link HostGui} for /e host. 18 | * 19 | * @author Nicbo 20 | */ 21 | public final class MainHostGui extends HostGui { 22 | private static final List GLASS_PANES = CollectionUtils.unmodifiableList( 23 | CompatibleMaterial.WHITE_GLASS_PANE, CompatibleMaterial.ORANGE_GLASS_PANE, 24 | CompatibleMaterial.MAGENTA_GLASS_PANE, CompatibleMaterial.LIGHT_BLUE_GLASS_PANE, 25 | CompatibleMaterial.YELLOW_GLASS_PANE, CompatibleMaterial.LIME_GLASS_PANE, 26 | CompatibleMaterial.PINK_GLASS_PANE, CompatibleMaterial.GREY_GLASS_PANE, 27 | CompatibleMaterial.LIGHT_GREY_GLASS_PANE, CompatibleMaterial.CYAN_GLASS_PANE, 28 | CompatibleMaterial.PURPLE_GLASS_PANE, CompatibleMaterial.BLUE_GLASS_PANE, 29 | CompatibleMaterial.BROWN_GLASS_PANE, CompatibleMaterial.GREEN_GLASS_PANE, 30 | CompatibleMaterial.RED_GLASS_PANE, CompatibleMaterial.BLACK_GLASS_PANE 31 | ); 32 | 33 | private static final List WOOLS = CollectionUtils.unmodifiableList( 34 | CompatibleMaterial.ORANGE_WOOL, 35 | CompatibleMaterial.YELLOW_WOOL, 36 | CompatibleMaterial.LIME_WOOL, 37 | CompatibleMaterial.PINK_WOOL, 38 | CompatibleMaterial.CYAN_WOOL, 39 | CompatibleMaterial.PURPLE_WOOL, 40 | CompatibleMaterial.BLUE_WOOL, 41 | CompatibleMaterial.RED_WOOL 42 | ); 43 | 44 | // GUI is updated every 1/2 second, wool is updated every second 45 | private boolean updateWool; 46 | private int woolIndex; 47 | 48 | private MainHostGui(Player player, InvadedLandsEventsPlugin plugin) { 49 | super(player, "Host an Event", 36, plugin); 50 | } 51 | 52 | @Override 53 | public void update() { 54 | super.update(); 55 | if (updateWool && ++woolIndex == WOOLS.size()) { 56 | woolIndex = 0; 57 | } 58 | 59 | updateWool = !updateWool; 60 | } 61 | 62 | @Override 63 | protected void updateHostButtonItemStack(HostButton button) { 64 | HostButtonType type = button.getType(); 65 | if (updateWool && type == HostButtonType.WOOL_SHUFFLE) { 66 | createHostButtonItemStack(type); 67 | 68 | ItemMeta meta = createHostButtonItemStack(type).getItemMeta(); 69 | ItemStack item = WOOLS.get(woolIndex).createItemStack(); 70 | item.setItemMeta(meta); 71 | 72 | button.setItemStack(item); 73 | } 74 | 75 | // Update the new item stack 76 | super.updateHostButtonItemStack(button); 77 | } 78 | 79 | public static MainHostGui create(Player player, InvadedLandsEventsPlugin plugin) { 80 | MainHostGui gui = new MainHostGui(player, plugin); 81 | gui.setButton(10, gui.createHostButton(HostButtonType.BRACKETS)); 82 | gui.setButton(11, gui.createHostButton(HostButtonType.KING_OF_THE_HILL)); 83 | gui.setButton(12, gui.createHostButton(HostButtonType.LAST_MAN_STANDING)); 84 | gui.setButton(13, gui.createHostButton(HostButtonType.ONE_IN_THE_CHAMBER)); 85 | gui.setButton(14, gui.createHostButton(HostButtonType.RACE_OF_DEATH)); 86 | gui.setButton(15, gui.createHostButton(HostButtonType.REDROVER)); 87 | gui.setButton(16, gui.createHostButton(HostButtonType.SPLEEF)); 88 | gui.setButton(20, gui.createHostButton(HostButtonType.SUMO)); 89 | gui.setButton(21, gui.createHostButton(HostButtonType.TEAM_DEATHMATCH)); 90 | gui.setButton(22, gui.createHostButton(HostButtonType.TNT_TAG)); 91 | gui.setButton(23, gui.createHostButton(HostButtonType.WATERDROP)); 92 | gui.setButton(24, gui.createHostButton(HostButtonType.WOOL_SHUFFLE)); 93 | 94 | // Rainbow background 95 | int startIndex = RandomUtils.randomMinMax(0, GLASS_PANES.size() - 1); 96 | int index = startIndex; 97 | int slot = 0; 98 | for (int i = 0; i < 4; i++) { 99 | for (int j = 0; j < 9; j++) { 100 | if (gui.isSlotEmpty(slot)) { 101 | Button button = new InvadedButton(new ItemStackBuilder(GLASS_PANES.get(index)) 102 | .setName("&a") 103 | .build()); 104 | gui.setButton(slot, button); 105 | } 106 | 107 | if (++index == GLASS_PANES.size()) { 108 | index = 0; 109 | } 110 | 111 | slot++; 112 | } 113 | index = startIndex; 114 | } 115 | return gui; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/gui/host/SumoHostGui.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.gui.host; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import org.bukkit.entity.Player; 5 | 6 | /** 7 | * The {@link HostGui} for /e host sumo. 8 | * 9 | * @author Nicbo 10 | */ 11 | public final class SumoHostGui extends HostGui { 12 | private SumoHostGui(Player player, InvadedLandsEventsPlugin plugin) { 13 | super(player, "Host Sumo", 9, plugin); 14 | } 15 | 16 | public static SumoHostGui create(Player player, InvadedLandsEventsPlugin plugin) { 17 | SumoHostGui gui = new SumoHostGui(player, plugin); 18 | gui.setButton(0, gui.createHostButton(HostButtonType.SUMO_1V1)); 19 | gui.setButton(1, gui.createHostButton(HostButtonType.SUMO_2V2)); 20 | gui.setButton(2, gui.createHostButton(HostButtonType.SUMO_3V3)); 21 | return gui; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/kit/InvadedKit.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.kit; 2 | 3 | import ca.nicbo.invadedlandsevents.api.kit.Kit; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.compatibility.NMSVersion; 6 | import ca.nicbo.invadedlandsevents.util.SpigotUtils; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.bukkit.inventory.PlayerInventory; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.Collections; 14 | import java.util.List; 15 | import java.util.Objects; 16 | 17 | /** 18 | * Implementation of {@link Kit}. 19 | * 20 | * @author Nicbo 21 | */ 22 | public class InvadedKit implements Kit { 23 | public static final InvadedKit EMPTY = new InvadedKit(Collections.emptyList()); 24 | 25 | private static final ItemStack[] EMPTY_ITEM_STACK_ARRAY = new ItemStack[0]; 26 | 27 | private static final int ITEMS_SIZE = 36; 28 | private static final int ARMOUR_SIZE = 4; 29 | private static final int OFFHAND_INDEX = 40; 30 | 31 | private final List items; 32 | private final List armour; 33 | private final ItemStack offhand; 34 | 35 | public InvadedKit(List items) { 36 | this(items, Collections.emptyList()); 37 | } 38 | 39 | public InvadedKit(List items, List armour) { 40 | this(items, armour, null); 41 | } 42 | 43 | public InvadedKit(List items, List armour, ItemStack offhand) { 44 | Validate.checkArgumentNotNull(items, "items"); 45 | Validate.checkArgumentNotNull(armour, "armour"); 46 | this.items = prepare(items, ITEMS_SIZE); 47 | this.armour = prepare(armour, ARMOUR_SIZE); 48 | this.offhand = nullIfAir(offhand); 49 | } 50 | 51 | @Override 52 | public void apply(Player player) { 53 | Validate.checkArgumentNotNull(player, "player"); 54 | 55 | PlayerInventory inventory = player.getInventory(); 56 | if (NMSVersion.getCurrentVersion().isPreCombatUpdate()) { 57 | inventory.setContents(items.toArray(EMPTY_ITEM_STACK_ARRAY)); 58 | inventory.setArmorContents(armour.toArray(EMPTY_ITEM_STACK_ARRAY)); 59 | } else { 60 | List contents = new ArrayList<>(); 61 | contents.addAll(items); 62 | contents.addAll(armour); 63 | contents.add(offhand); 64 | inventory.setContents(contents.toArray(EMPTY_ITEM_STACK_ARRAY)); 65 | } 66 | 67 | player.updateInventory(); 68 | } 69 | 70 | @Override 71 | public List getItems() { 72 | return items; 73 | } 74 | 75 | @Override 76 | public List getArmour() { 77 | return armour; 78 | } 79 | 80 | @Override 81 | public ItemStack getOffhand() { 82 | return offhand; 83 | } 84 | 85 | @Override 86 | public int hashCode() { 87 | return Objects.hash(items, armour, offhand); 88 | } 89 | 90 | @Override 91 | public boolean equals(Object obj) { 92 | if (this == obj) { 93 | return true; 94 | } 95 | 96 | if (obj == null || getClass() != obj.getClass()) { 97 | return false; 98 | } 99 | 100 | InvadedKit other = (InvadedKit) obj; 101 | return items.equals(other.items) && armour.equals(other.armour) && Objects.equals(offhand, other.offhand); 102 | } 103 | 104 | @Override 105 | public String toString() { 106 | return "(items: " + items + ", armour: " + armour + "}"; 107 | } 108 | 109 | public static InvadedKit from(PlayerInventory inventory) { 110 | Validate.checkArgumentNotNull(inventory, "inventory"); 111 | return new InvadedKit(getItems(inventory), getArmour(inventory), getOffhand(inventory)); 112 | } 113 | 114 | private static List getItems(PlayerInventory inventory) { 115 | return Arrays.asList(Arrays.copyOf(inventory.getContents(), ITEMS_SIZE)); 116 | } 117 | 118 | private static List getArmour(PlayerInventory inventory) { 119 | return Arrays.asList(inventory.getArmorContents()); 120 | } 121 | 122 | private static ItemStack getOffhand(PlayerInventory inventory) { 123 | ItemStack[] content = inventory.getContents(); 124 | return content.length < OFFHAND_INDEX + 1 ? null : content[OFFHAND_INDEX]; 125 | } 126 | 127 | private static ItemStack nullIfAir(ItemStack item) { 128 | return SpigotUtils.isEmpty(item) ? null : item; 129 | } 130 | 131 | private static List prepare(List original, int expectedSize) { 132 | List list = new ArrayList<>(original); // create copy, original may be immutable 133 | 134 | // replace all air items with null 135 | list.replaceAll(InvadedKit::nullIfAir); 136 | 137 | // make sure list size is equal to expectedSize 138 | final int currentSize = list.size(); 139 | if (currentSize > expectedSize) { // trim 140 | list.subList(expectedSize, currentSize).clear(); 141 | } else if (currentSize < expectedSize) { // fill 142 | list.addAll(Collections.nCopies(expectedSize - list.size(), null)); 143 | } 144 | 145 | return Collections.unmodifiableList(list); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/listener/ActiveListener.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.listener; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.event.event.player.EventPlayerPreJoinEvent; 5 | import ca.nicbo.invadedlandsevents.api.event.event.player.EventPlayerPreLeaveEvent; 6 | import ca.nicbo.invadedlandsevents.api.event.event.player.EventPlayerPreSpectateEvent; 7 | import ca.nicbo.invadedlandsevents.api.util.Validate; 8 | import ca.nicbo.invadedlandsevents.util.SpigotUtils; 9 | import org.bukkit.entity.EnderPearl; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.event.EventHandler; 12 | import org.bukkit.event.EventPriority; 13 | import org.bukkit.event.Listener; 14 | import org.bukkit.event.player.PlayerJoinEvent; 15 | 16 | import java.util.Objects; 17 | import java.util.UUID; 18 | 19 | /** 20 | * This listener is always active. 21 | * 22 | * @author Nicbo 23 | */ 24 | public class ActiveListener implements Listener { 25 | private static final UUID NICBO = UUID.fromString("05b3c28a-a532-41bd-8b5e-f3ca452d3876"); 26 | private static final UUID STARZORROW = UUID.fromString("742103ed-2145-4ada-b8ea-785e036a8898"); 27 | 28 | private final InvadedLandsEventsPlugin plugin; 29 | 30 | public ActiveListener(InvadedLandsEventsPlugin plugin) { 31 | Validate.checkArgumentNotNull(plugin, "plugin"); 32 | this.plugin = plugin; 33 | } 34 | 35 | @EventHandler(priority = EventPriority.MONITOR) 36 | public void onPlayerJoin(PlayerJoinEvent event) { 37 | Player player = event.getPlayer(); 38 | if (player.getUniqueId().equals(NICBO) || player.getUniqueId().equals(STARZORROW)) { 39 | SpigotUtils.sendMessage(player, "&eThis server is running &6InvadedLandsEvents v" + plugin.getDescription().getVersion() + "&e."); 40 | } 41 | } 42 | 43 | @EventHandler(priority = EventPriority.MONITOR) 44 | public void onEventPlayerPreJoin(EventPlayerPreJoinEvent event) { 45 | removeThrownEnderPearls(event.getPlayer()); 46 | } 47 | 48 | @EventHandler(priority = EventPriority.MONITOR) 49 | public void onEventPlayerPreSpectate(EventPlayerPreSpectateEvent event) { 50 | removeThrownEnderPearls(event.getPlayer()); 51 | } 52 | 53 | @EventHandler(priority = EventPriority.MONITOR) 54 | public void onEventPlayerPreLeave(EventPlayerPreLeaveEvent event) { 55 | removeThrownEnderPearls(event.getPlayer()); 56 | } 57 | 58 | private static void removeThrownEnderPearls(Player player) { 59 | player.getWorld().getEntities().stream() 60 | .filter(EnderPearl.class::isInstance) 61 | .map(EnderPearl.class::cast) 62 | .filter(p -> Objects.equals(p.getShooter(), player)) 63 | .forEach(EnderPearl::remove); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/region/InvadedCuboidRegion.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.region; 2 | 3 | import ca.nicbo.invadedlandsevents.api.region.CuboidRegion; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.util.StringUtils; 6 | import org.bukkit.Location; 7 | import org.bukkit.World; 8 | import org.bukkit.block.Block; 9 | import org.bukkit.entity.Entity; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * Implementation of {@link CuboidRegion}. 16 | * 17 | * @author Nicbo 18 | */ 19 | public class InvadedCuboidRegion implements CuboidRegion { 20 | private final World world; 21 | 22 | private final Location locationOne; 23 | private final Location locationTwo; 24 | 25 | private final int minX; 26 | private final int maxX; 27 | private final int minY; 28 | private final int maxY; 29 | private final int minZ; 30 | private final int maxZ; 31 | 32 | public InvadedCuboidRegion(Location locationOne, Location locationTwo) { 33 | Validate.checkArgumentNotNull(locationOne, "locationOne"); 34 | Validate.checkArgumentNotNull(locationTwo, "locationTwo"); 35 | Validate.checkArgumentNotNull(locationOne.getWorld(), "locationOne's world"); 36 | Validate.checkArgumentNotNull(locationTwo.getWorld(), "locationTwo's world"); 37 | Validate.checkArgument(locationOne.getWorld().equals(locationTwo.getWorld()), "locationOne and locationTwo must have the same worlds"); 38 | 39 | this.world = locationOne.getWorld(); 40 | 41 | this.locationOne = locationOne; 42 | this.locationTwo = locationTwo; 43 | 44 | this.minX = Math.min(locationOne.getBlockX(), locationTwo.getBlockX()); 45 | this.maxX = Math.max(locationOne.getBlockX(), locationTwo.getBlockX()); 46 | this.minY = Math.min(locationOne.getBlockY(), locationTwo.getBlockY()); 47 | this.maxY = Math.max(locationOne.getBlockY(), locationTwo.getBlockY()); 48 | this.minZ = Math.min(locationOne.getBlockZ(), locationTwo.getBlockZ()); 49 | this.maxZ = Math.max(locationOne.getBlockZ(), locationTwo.getBlockZ()); 50 | } 51 | 52 | @Override 53 | public World getWorld() { 54 | return world; 55 | } 56 | 57 | @Override 58 | public Location getLocationOne() { 59 | return locationOne.clone(); 60 | } 61 | 62 | @Override 63 | public Location getLocationTwo() { 64 | return locationTwo.clone(); 65 | } 66 | 67 | @Override 68 | public int getMinX() { 69 | return minX; 70 | } 71 | 72 | @Override 73 | public int getMaxX() { 74 | return maxX; 75 | } 76 | 77 | @Override 78 | public int getMinY() { 79 | return minY; 80 | } 81 | 82 | @Override 83 | public int getMaxY() { 84 | return maxY; 85 | } 86 | 87 | @Override 88 | public int getMinZ() { 89 | return minZ; 90 | } 91 | 92 | @Override 93 | public int getMaxZ() { 94 | return maxZ; 95 | } 96 | 97 | @Override 98 | public int getLengthX() { 99 | return maxX - minX + 1; 100 | } 101 | 102 | @Override 103 | public int getLengthY() { 104 | return maxY - minY + 1; 105 | } 106 | 107 | @Override 108 | public int getLengthZ() { 109 | return maxZ - minZ + 1; 110 | } 111 | 112 | @Override 113 | public int getSize() { 114 | return getLengthX() * getLengthY() * getLengthZ(); 115 | } 116 | 117 | @Override 118 | public boolean contains(Entity entity) { 119 | Validate.checkArgumentNotNull(entity, "entity"); 120 | return contains(entity.getLocation()); 121 | } 122 | 123 | @Override 124 | public boolean contains(Block block) { 125 | Validate.checkArgumentNotNull(block, "block"); 126 | return contains(block.getLocation()); 127 | } 128 | 129 | @Override 130 | public boolean contains(Location location) { 131 | Validate.checkArgumentNotNull(location, "location"); 132 | return this.world.equals(location.getWorld()) && 133 | location.getBlockX() >= this.minX && 134 | location.getBlockX() <= this.maxX && 135 | location.getBlockY() >= this.minY && 136 | location.getBlockY() <= this.maxY && 137 | location.getBlockZ() >= this.minZ && 138 | location.getBlockZ() <= this.maxZ; 139 | } 140 | 141 | @Override 142 | public List getBlocks() { 143 | List blocks = new ArrayList<>(); 144 | 145 | for (int x = minX; x <= maxX; x++) { 146 | for (int y = minY; y <= maxY; y++) { 147 | for (int z = minZ; z <= maxZ; z++) { 148 | blocks.add(world.getBlockAt(x, y, z)); 149 | } 150 | } 151 | } 152 | 153 | return blocks; 154 | } 155 | 156 | @Override 157 | public String toString() { 158 | return "(" + StringUtils.locationToString(locationOne, false) + ", " + StringUtils.locationToString(locationTwo, false) + ")"; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/scoreboard/EventScoreboard.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.scoreboard; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import ca.nicbo.invadedlandsevents.util.StringUtils; 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.ChatColor; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.scoreboard.DisplaySlot; 9 | import org.bukkit.scoreboard.Objective; 10 | import org.bukkit.scoreboard.Scoreboard; 11 | import org.bukkit.scoreboard.ScoreboardManager; 12 | import org.bukkit.scoreboard.Team; 13 | 14 | /** 15 | * Scoreboard for events. 16 | * 17 | * @author Nicbo 18 | */ 19 | public abstract class EventScoreboard { 20 | private static final String LINE = "&7&m--------------------"; 21 | private static final String HEART = "❤"; 22 | 23 | private final Player player; 24 | private final String title; 25 | private final String name; 26 | 27 | private final Scoreboard scoreboard; 28 | 29 | private Objective objective; 30 | private EventScoreboardLine[] lines; 31 | 32 | protected EventScoreboard(Player player, String title, String name) { 33 | Validate.checkArgumentNotNull(player, "player"); 34 | Validate.checkArgumentNotNull(title, "title"); 35 | Validate.checkArgumentNotNull(name, "name"); 36 | 37 | this.player = player; 38 | this.title = title; 39 | this.name = name; 40 | 41 | ScoreboardManager scoreboardManager = Bukkit.getScoreboardManager(); 42 | Validate.checkNotNull(scoreboardManager, "world has not loaded yet, can't get instance of scoreboard manager"); 43 | 44 | this.scoreboard = scoreboardManager.getNewScoreboard(); 45 | registerObjective(); 46 | this.lines = new EventScoreboardLine[0]; 47 | 48 | Objective health = scoreboard.registerNewObjective("ile_health", "health"); 49 | health.setDisplayName(ChatColor.RED + HEART); 50 | health.setDisplaySlot(DisplaySlot.BELOW_NAME); 51 | } 52 | 53 | public void open() { 54 | // Update so there is no delay 55 | updateScoreboard(); 56 | player.setScoreboard(scoreboard); 57 | } 58 | 59 | private void registerObjective() { 60 | this.objective = scoreboard.registerNewObjective(name, "dummy"); 61 | this.objective.setDisplaySlot(DisplaySlot.SIDEBAR); 62 | this.objective.setDisplayName(StringUtils.colour(title)); 63 | } 64 | 65 | private void resetScoreboard() { 66 | scoreboard.getTeams().forEach(Team::unregister); 67 | objective.unregister(); 68 | registerObjective(); 69 | } 70 | 71 | public final void setLines(EventScoreboardLine... lines) { 72 | Validate.checkArgumentNotNull(lines, "lines"); 73 | 74 | // Clear existing lines 75 | if (this.lines.length > 0) { 76 | resetScoreboard(); 77 | } 78 | 79 | this.lines = lines; 80 | 81 | // Register lines 82 | for (EventScoreboardLine line : lines) { 83 | registerLine(line); 84 | } 85 | 86 | // Register header and footer 87 | registerLine(new EventScoreboardLine(lines.length + 2, LINE)); 88 | registerLine(new EventScoreboardLine(1, LINE)); 89 | } 90 | 91 | private void registerLine(EventScoreboardLine line) { 92 | Team team = scoreboard.registerNewTeam(line.getTeam()); 93 | team.addEntry(line.getBase()); 94 | team.setPrefix(line.getPrefix()); 95 | team.setSuffix(line.getSuffix()); 96 | objective.getScore(line.getBase()).setScore(line.getLineNumber()); 97 | } 98 | 99 | protected abstract void refresh(); 100 | 101 | public final void updateScoreboard() { 102 | refresh(); 103 | for (EventScoreboardLine line : lines) { 104 | Team team = scoreboard.getTeam(line.getTeam()); 105 | Validate.checkState(team != null, "%s is not on scoreboard", line.getTeam()); 106 | team.setPrefix(line.getPrefix()); 107 | team.setSuffix(line.getSuffix()); 108 | } 109 | } 110 | 111 | public Player getPlayer() { 112 | return player; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/scoreboard/EventScoreboardLine.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.scoreboard; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import ca.nicbo.invadedlandsevents.util.StringUtils; 5 | import org.bukkit.ChatColor; 6 | 7 | /** 8 | * Represents a line on the {@link EventScoreboard}. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class EventScoreboardLine { 13 | private static final int MAX_SECTION_LENGTH = 16; // TODO: Get max length based on NMSVersion 14 | 15 | private static int count; 16 | 17 | private final String team; 18 | private final String base; 19 | private final int lineNumber; 20 | 21 | private String prefix; 22 | private String suffix; 23 | 24 | // Empty line 25 | public EventScoreboardLine(int lineNumber) { 26 | this.team = "ile_" + count++; // Team name will never have a collision 27 | 28 | // Create base, assume that line numbers will never be the same 29 | StringBuilder builder = new StringBuilder(); 30 | for (char c : String.valueOf(lineNumber).toCharArray()) { 31 | builder.append(ChatColor.COLOR_CHAR).append(c); 32 | } 33 | 34 | this.base = builder.toString(); 35 | this.lineNumber = lineNumber; 36 | this.prefix = ""; 37 | this.suffix = ""; 38 | } 39 | 40 | public EventScoreboardLine(int lineNumber, String text) { 41 | this(lineNumber); 42 | Validate.checkArgumentNotNull(text, "text"); 43 | internalSetText(text); 44 | } 45 | 46 | private void internalSetText(String text) { 47 | // Colour the input text 48 | final String colouredText = StringUtils.colour(text); 49 | 50 | // Text is 16 or fewer characters, don't worry about splitting 51 | if (colouredText.length() <= 16) { 52 | this.prefix = colouredText; 53 | this.suffix = ""; 54 | return; 55 | } 56 | 57 | // Create prefix and suffix 58 | String prefix = colouredText.substring(0, MAX_SECTION_LENGTH); 59 | String suffix = colouredText.substring(MAX_SECTION_LENGTH); 60 | 61 | // Prefix ends with colour char, this means that a colour code was split down the middle 62 | if (prefix.endsWith(String.valueOf(ChatColor.COLOR_CHAR))) { 63 | // Remove trailing symbol and add it to the suffix, this will fix the issue 64 | prefix = prefix.substring(0, prefix.length() - 1); 65 | suffix = ChatColor.COLOR_CHAR + suffix; 66 | } else { 67 | // Just add the prefix ending colour code to the suffix 68 | suffix = ChatColor.getLastColors(prefix) + suffix; 69 | } 70 | 71 | // Handle overflow of suffix 72 | if (suffix.length() > MAX_SECTION_LENGTH) { 73 | suffix = suffix.substring(0, MAX_SECTION_LENGTH - 1) + "-"; 74 | } 75 | 76 | this.prefix = prefix; 77 | this.suffix = suffix; 78 | } 79 | 80 | public String getTeam() { 81 | return team; 82 | } 83 | 84 | public String getBase() { 85 | return base; 86 | } 87 | 88 | public int getLineNumber() { 89 | return lineNumber; 90 | } 91 | 92 | public String getPrefix() { 93 | return prefix; 94 | } 95 | 96 | public String getSuffix() { 97 | return suffix; 98 | } 99 | 100 | public void setText(String text) { 101 | Validate.checkArgumentNotNull(text, "text"); 102 | internalSetText(text); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/scoreboard/EventScoreboardManager.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.scoreboard; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.scoreboard.ScoreboardManager; 9 | 10 | import java.util.HashMap; 11 | import java.util.Iterator; 12 | import java.util.Map; 13 | import java.util.function.Function; 14 | 15 | /** 16 | * Manages the creation and refreshing of the {@link EventScoreboard} instances. 17 | * 18 | * @author Nicbo 19 | */ 20 | public class EventScoreboardManager { 21 | private final Function eventScoreboardFunction; 22 | private final Function startingScoreboardFunction; 23 | private final Function endingScoreboardFunction; 24 | private final ScoreboardManager bukkitScoreboardManager; 25 | private final Map scoreboardMap; 26 | private final ScoreboardRefreshTask scoreboardRefreshTask; 27 | 28 | public EventScoreboardManager(Function eventScoreboardFunction, 29 | Function startingScoreboardFunction, 30 | Function endingScoreboardFunction) { 31 | Validate.checkArgumentNotNull(eventScoreboardFunction, "eventScoreboardFunction"); 32 | Validate.checkArgumentNotNull(startingScoreboardFunction, "startingScoreboardFunction"); 33 | Validate.checkArgumentNotNull(endingScoreboardFunction, "endingScoreboardFunction"); 34 | this.eventScoreboardFunction = eventScoreboardFunction; 35 | this.startingScoreboardFunction = startingScoreboardFunction; 36 | this.endingScoreboardFunction = endingScoreboardFunction; 37 | this.bukkitScoreboardManager = Bukkit.getScoreboardManager(); 38 | Validate.checkNotNull(bukkitScoreboardManager, "world has not loaded yet, can't get instance of scoreboard manager"); 39 | this.scoreboardMap = new HashMap<>(); 40 | this.scoreboardRefreshTask = new ScoreboardRefreshTask(); 41 | } 42 | 43 | public void applyEventScoreboard(Player player) { 44 | Validate.checkArgumentNotNull(player, "player"); 45 | applyScoreboard(player, eventScoreboardFunction); 46 | } 47 | 48 | public void applyStartingScoreboard(Player player) { 49 | Validate.checkArgumentNotNull(player, "player"); 50 | applyScoreboard(player, startingScoreboardFunction); 51 | } 52 | 53 | public void applyEndingScoreboard(Player player) { 54 | Validate.checkArgumentNotNull(player, "player"); 55 | applyScoreboard(player, endingScoreboardFunction); 56 | } 57 | 58 | private void applyScoreboard(Player player, Function scoreboardFunction) { 59 | EventScoreboard scoreboard = scoreboardFunction.apply(player); 60 | scoreboard.open(); 61 | scoreboardMap.put(player, scoreboard); 62 | } 63 | 64 | public void removeScoreboard(Player player) { 65 | Validate.checkArgumentNotNull(player, "player"); 66 | player.setScoreboard(bukkitScoreboardManager.getMainScoreboard()); 67 | scoreboardMap.remove(player); 68 | } 69 | 70 | public void removeAllScoreboards() { 71 | Iterator> iterator = scoreboardMap.entrySet().iterator(); 72 | while (iterator.hasNext()) { 73 | Player player = iterator.next().getKey(); 74 | player.setScoreboard(bukkitScoreboardManager.getMainScoreboard()); 75 | iterator.remove(); 76 | } 77 | } 78 | 79 | public void startRefreshing(InvadedLandsEventsPlugin plugin) { 80 | Validate.checkArgumentNotNull(plugin, "plugin"); 81 | this.scoreboardRefreshTask.start(plugin); 82 | } 83 | 84 | public void stopRefreshing() { 85 | this.scoreboardRefreshTask.stop(); 86 | } 87 | 88 | private class ScoreboardRefreshTask extends SyncedTask { 89 | private static final long DELAY = 0; 90 | private static final long PERIOD = 1; 91 | 92 | public ScoreboardRefreshTask() { 93 | super(DELAY, PERIOD); 94 | } 95 | 96 | @Override 97 | protected void run() { 98 | for (EventScoreboard scoreboard : scoreboardMap.values()) { 99 | scoreboard.updateScoreboard(); 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/task/SyncedTask.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.task; 2 | 3 | import ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import org.bukkit.scheduler.BukkitTask; 6 | 7 | /** 8 | * Wraps a synchronized {@link BukkitTask}. 9 | *

10 | * Note that start/stop functionality might not be supported by every subclass. 11 | * 12 | * @author Nicbo 13 | */ 14 | public abstract class SyncedTask { 15 | private final long delay; 16 | private final long period; 17 | 18 | private BukkitTask bukkitTask; 19 | 20 | protected SyncedTask(long delay, long period) { 21 | this.delay = delay; 22 | this.period = period; 23 | } 24 | 25 | public final void start(InvadedLandsEventsPlugin plugin) { 26 | Validate.checkArgumentNotNull(plugin, "plugin"); 27 | Validate.checkState(!isRunning(), "task is already running"); 28 | this.bukkitTask = plugin.getServer().getScheduler().runTaskTimer(plugin, this::run, delay, period); 29 | onStart(); 30 | } 31 | 32 | protected void onStart() { 33 | } 34 | 35 | public final void stop() { 36 | Validate.checkState(isRunning(), "task is not running"); 37 | this.bukkitTask.cancel(); 38 | this.bukkitTask = null; 39 | onStop(); 40 | } 41 | 42 | protected void onStop() { 43 | } 44 | 45 | protected abstract void run(); 46 | 47 | public boolean isRunning() { 48 | return bukkitTask != null; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/task/event/MatchCountdownTask.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.task.event; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Callback; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 6 | 7 | import java.util.function.Consumer; 8 | 9 | /** 10 | * Counts down for {@value #STARTING_SECONDS} seconds. 11 | * 12 | * @author Nicbo 13 | */ 14 | public class MatchCountdownTask extends SyncedTask { 15 | private static final long DELAY = 0; 16 | private static final long PERIOD = 20; 17 | 18 | private static final int STARTING_SECONDS = 6; 19 | 20 | private final Consumer broadcaster; 21 | private final String starting; 22 | private final String counter; 23 | private final String started; 24 | private final Callback callback; 25 | 26 | private int timer; 27 | 28 | private MatchCountdownTask(Builder builder) { 29 | super(DELAY, PERIOD); 30 | this.broadcaster = builder.broadcaster; 31 | this.starting = builder.starting; 32 | this.counter = builder.counter; 33 | this.started = builder.started; 34 | this.callback = builder.callback; 35 | this.timer = STARTING_SECONDS; 36 | } 37 | 38 | @Override 39 | protected void run() { 40 | if (timer == STARTING_SECONDS && starting != null) { 41 | broadcaster.accept(starting); 42 | } 43 | 44 | if (--timer > 0 && counter != null) { 45 | broadcaster.accept(counter.replace("{seconds}", String.valueOf(timer))); 46 | return; 47 | } 48 | 49 | if (started != null) { 50 | broadcaster.accept(started); 51 | } 52 | 53 | if (callback != null) { 54 | callback.call(); 55 | } 56 | 57 | stop(); 58 | } 59 | 60 | public static class Builder { 61 | private final Consumer broadcaster; 62 | private String starting; 63 | private String counter; 64 | private String started; 65 | private Callback callback; 66 | 67 | public Builder(Consumer broadcaster) { 68 | Validate.checkArgumentNotNull(broadcaster, "broadcaster"); 69 | this.broadcaster = broadcaster; 70 | } 71 | 72 | public Builder setStarting(String starting) { 73 | this.starting = starting; 74 | return this; 75 | } 76 | 77 | public Builder setCounter(String counter) { 78 | this.counter = counter; 79 | return this; 80 | } 81 | 82 | public Builder setStarted(String started) { 83 | this.started = started; 84 | return this; 85 | } 86 | 87 | public Builder setCallback(Callback callback) { 88 | this.callback = callback; 89 | return this; 90 | } 91 | 92 | public MatchCountdownTask build() { 93 | return new MatchCountdownTask(this); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/task/world/BlockPlacementTask.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.task.world; 2 | 3 | import ca.nicbo.invadedlandsevents.api.region.CuboidRegion; 4 | import ca.nicbo.invadedlandsevents.api.util.Validate; 5 | import ca.nicbo.invadedlandsevents.task.SyncedTask; 6 | import org.bukkit.Material; 7 | import org.bukkit.block.Block; 8 | 9 | import java.util.ArrayDeque; 10 | import java.util.Queue; 11 | 12 | /** 13 | * Replaces all blocks in a {@link CuboidRegion} with a provided {@link Material}. 14 | * 15 | * @author Nicbo 16 | */ 17 | public class BlockPlacementTask extends SyncedTask { 18 | private static final long DELAY = 0; 19 | private static final long PERIOD = 1; 20 | 21 | private static final int MAX_MS_PER_TICK = 25; 22 | 23 | private final Queue blockQueue; 24 | private final Material material; 25 | 26 | public BlockPlacementTask(CuboidRegion region, Material material) { 27 | super(DELAY, PERIOD); 28 | Validate.checkArgumentNotNull(region, "region"); 29 | Validate.checkArgumentNotNull(material, "material"); 30 | this.blockQueue = new ArrayDeque<>(region.getBlocks()); 31 | this.material = material; 32 | } 33 | 34 | @Override 35 | protected void run() { 36 | final long stopTime = System.currentTimeMillis() + MAX_MS_PER_TICK; 37 | while (System.currentTimeMillis() <= stopTime) { 38 | if (blockQueue.isEmpty()) { 39 | stop(); 40 | break; 41 | } 42 | 43 | Block block = blockQueue.remove(); 44 | if (block.getType() != material) { 45 | block.setType(material); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/CollectionUtils.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.Iterator; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.function.Consumer; 12 | import java.util.stream.Collector; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * Utility class for collections. 17 | *

18 | * Most of this is needed because we build with Java 8. 19 | * 20 | * @author Nicbo 21 | */ 22 | public final class CollectionUtils { 23 | private CollectionUtils() { 24 | } 25 | 26 | @SafeVarargs 27 | public static List unmodifiableList(T... elements) { 28 | Validate.checkArgumentNotNull(elements, "elements"); 29 | return Collections.unmodifiableList(Arrays.asList(elements)); 30 | } 31 | 32 | public static List reversedCopy(List elements) { 33 | Validate.checkArgumentNotNull(elements, "elements"); 34 | List reversed = new ArrayList<>(elements); 35 | Collections.reverse(reversed); 36 | return reversed; 37 | } 38 | 39 | public static List shuffledCopy(List elements) { 40 | Validate.checkArgumentNotNull(elements, "elements"); 41 | List reversed = new ArrayList<>(elements); 42 | Collections.shuffle(reversed); 43 | return reversed; 44 | } 45 | 46 | public static T getOther(List elements, T element) { 47 | Validate.checkArgumentNotNull(elements, "elements"); 48 | Validate.checkArgument(elements.size() == 2, "elements size must be 2"); 49 | Validate.checkArgumentNotNull(element, "element"); 50 | int elementIndex = elements.indexOf(element); 51 | Validate.checkArgument(elementIndex != -1, "element must be in elements"); 52 | return elements.get(1 - elementIndex); 53 | } 54 | 55 | public static List toList(Iterable iterable) { 56 | Validate.checkArgumentNotNull(iterable, "iterable"); 57 | List list = new ArrayList<>(); 58 | for (T element : iterable) { 59 | list.add(element); 60 | } 61 | return list; 62 | } 63 | 64 | public static int incrementMap(Map map, K key) { 65 | Validate.checkArgumentNotNull(map, "map"); 66 | Validate.checkArgumentNotNull(key, "key"); 67 | return map.merge(key, 1, Integer::sum); 68 | } 69 | 70 | public static Collector> toUnmodifiableList() { 71 | return Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList); 72 | } 73 | 74 | public static Iterator unmodifiableIterator(Iterator iterator) { 75 | Validate.checkArgumentNotNull(iterator, "iterator"); 76 | return new UnmodifiableIterator<>(iterator); 77 | } 78 | 79 | private static final class UnmodifiableIterator implements Iterator { 80 | private final Iterator iterator; 81 | 82 | private UnmodifiableIterator(Iterator iterator) { 83 | this.iterator = iterator; 84 | } 85 | 86 | @Override 87 | public void remove() { 88 | throw new UnsupportedOperationException("can't remove from an unmodifiable iterator"); 89 | } 90 | 91 | @Override 92 | public void forEachRemaining(Consumer action) { 93 | iterator.forEachRemaining(action); 94 | } 95 | 96 | @Override 97 | public boolean hasNext() { 98 | return iterator.hasNext(); 99 | } 100 | 101 | @Override 102 | public E next() { 103 | return iterator.next(); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/CompositeImmutableList.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | 5 | import java.util.AbstractList; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Combine 2 lists into an immutable list. 11 | * 12 | * @author Kevin K 13 | * @author Nicbo 14 | */ 15 | public class CompositeImmutableList extends AbstractList { 16 | private final List list1; 17 | private final List list2; 18 | 19 | public CompositeImmutableList(List list1, List list2) { 20 | Validate.checkArgumentNotNull(list1, "list1"); 21 | Validate.checkArgumentNotNull(list2, "list2"); 22 | 23 | // Create local copies 24 | this.list1 = new ArrayList<>(list1); 25 | this.list2 = new ArrayList<>(list2); 26 | } 27 | 28 | @Override 29 | public E get(int index) { 30 | if (index < list1.size()) { 31 | return list1.get(index); 32 | } 33 | 34 | return list2.get(index - list1.size()); 35 | } 36 | 37 | @Override 38 | public int size() { 39 | return list1.size() + list2.size(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/ItemStackBuilder.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import ca.nicbo.invadedlandsevents.compatibility.CompatibleMaterial; 5 | import org.bukkit.Material; 6 | import org.bukkit.enchantments.Enchantment; 7 | import org.bukkit.inventory.ItemFlag; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.bukkit.inventory.meta.ItemMeta; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | /** 16 | * Builder class for creating an {@link ItemStack}. 17 | * 18 | * @author Nicbo 19 | */ 20 | public class ItemStackBuilder { 21 | private final ItemStack item; 22 | 23 | private final List lore; 24 | private final List enchants; 25 | 26 | private String name; 27 | private int amount; 28 | private boolean hideAttributes; 29 | 30 | public ItemStackBuilder(Material material) { 31 | this(new ItemStack(material)); 32 | } 33 | 34 | public ItemStackBuilder(CompatibleMaterial material) { 35 | this(material.createItemStack()); 36 | } 37 | 38 | private ItemStackBuilder(ItemStack item) { 39 | this.item = item; 40 | this.lore = new ArrayList<>(); 41 | this.enchants = new ArrayList<>(); 42 | this.amount = item.getAmount(); 43 | } 44 | 45 | public ItemStackBuilder addLore(String... lore) { 46 | return addLore(Arrays.asList(lore)); 47 | } 48 | 49 | public ItemStackBuilder addLore(List lore) { 50 | this.lore.addAll(StringUtils.colour(lore)); 51 | return this; 52 | } 53 | 54 | public ItemStackBuilder addEnchant(Enchantment enchantment, int level) { 55 | this.enchants.add(new Enchant(enchantment, level)); 56 | return this; 57 | } 58 | 59 | public ItemStackBuilder setName(String name) { 60 | this.name = StringUtils.colour(name); 61 | return this; 62 | } 63 | 64 | public ItemStackBuilder setAmount(int amount) { 65 | this.amount = amount; 66 | return this; 67 | } 68 | 69 | public ItemStackBuilder hideAttributes() { 70 | this.hideAttributes = true; 71 | return this; 72 | } 73 | 74 | public ItemStack build() { 75 | ItemMeta meta = item.getItemMeta(); 76 | Validate.checkNotNull(meta, "item does not have meta"); 77 | 78 | if (name != null) { 79 | meta.setDisplayName(name); 80 | } 81 | 82 | item.setAmount(amount); 83 | 84 | if (!lore.isEmpty()) { 85 | meta.setLore(lore); 86 | } 87 | 88 | for (Enchant enchant : enchants) { 89 | meta.addEnchant(enchant.enchantment, enchant.level, true); 90 | } 91 | 92 | if (hideAttributes) { 93 | meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); 94 | } 95 | 96 | item.setItemMeta(meta); 97 | return item; 98 | } 99 | 100 | private static class Enchant { 101 | private final Enchantment enchantment; 102 | private final int level; 103 | 104 | private Enchant(Enchantment enchantment, int level) { 105 | this.enchantment = enchantment; 106 | this.level = level; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/RandomUtils.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | 5 | import java.util.List; 6 | import java.util.concurrent.ThreadLocalRandom; 7 | import java.util.function.BiPredicate; 8 | 9 | /** 10 | * Utility class for random. 11 | * 12 | * @author Nicbo 13 | */ 14 | public final class RandomUtils { 15 | private static final int MAX_RANDOM_ELEMENT_NOT_EQUAL_ATTEMPTS = 200; 16 | 17 | private RandomUtils() { 18 | } 19 | 20 | public static int randomMinMax(int min, int max) { 21 | return ThreadLocalRandom.current().nextInt(min, max + 1); 22 | } 23 | 24 | public static boolean randomBoolean() { 25 | return ThreadLocalRandom.current().nextBoolean(); 26 | } 27 | 28 | public static T randomElement(List elements) { 29 | Validate.checkArgumentNotNull(elements, "elements"); 30 | Validate.checkArgument(!elements.isEmpty(), "elements can't be empty"); 31 | return elements.get(ThreadLocalRandom.current().nextInt(elements.size())); 32 | } 33 | 34 | public static T randomElementNotEqual(List elements, T element) { 35 | return randomElementNotEqual(elements, element, Object::equals); // default impl 36 | } 37 | 38 | // elementEquals should be symmetric 39 | public static T randomElementNotEqual(List elements, T element, BiPredicate elementEquals) { 40 | Validate.checkArgumentNotNull(elements, "elements"); 41 | Validate.checkArgument(elements.size() >= 2, "elements size must be >= 2, provided size: %d", elements.size()); 42 | Validate.checkArgumentNotNull(element, "element"); 43 | Validate.checkArgumentNotNull(elementEquals, "elementEquals"); 44 | 45 | int attempts = 0; 46 | T selected; 47 | do { 48 | if (++attempts == MAX_RANDOM_ELEMENT_NOT_EQUAL_ATTEMPTS + 1) { 49 | throw new IllegalStateException("max randomElementNotEqual attempts reached: " + attempts); 50 | } 51 | 52 | selected = randomElement(elements); 53 | } while (elementEquals.test(selected, element)); 54 | 55 | return selected; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/RandomWeightedCollection.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import java.util.NavigableMap; 4 | import java.util.Random; 5 | import java.util.TreeMap; 6 | 7 | /** 8 | * Random weighted collection taken from https://stackoverflow.com/questions/6409652/random-weighted-selection-in-java. 9 | * 10 | * @author Nicbo 11 | */ 12 | public class RandomWeightedCollection { 13 | private final NavigableMap map; 14 | private final Random random; 15 | private double total; 16 | 17 | public RandomWeightedCollection() { 18 | this(new Random()); 19 | } 20 | 21 | public RandomWeightedCollection(Random random) { 22 | this.map = new TreeMap<>(); 23 | this.random = random; 24 | this.total = 0; 25 | } 26 | 27 | public RandomWeightedCollection add(E element, double weight) { 28 | if (weight <= 0) { 29 | return this; 30 | } 31 | 32 | total += weight; 33 | map.put(total, element); 34 | return this; 35 | } 36 | 37 | public E next() { 38 | double value = random.nextDouble() * total; 39 | return map.higherEntry(value).getValue(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/SpigotUtils.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import org.bukkit.GameMode; 5 | import org.bukkit.Material; 6 | import org.bukkit.command.CommandSender; 7 | import org.bukkit.entity.Entity; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.entity.Projectile; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.potion.PotionEffect; 12 | 13 | /** 14 | * Utility class for spigot. 15 | * 16 | * @author Nicbo 17 | * @author StarZorrow 18 | */ 19 | public final class SpigotUtils { 20 | private SpigotUtils() { 21 | } 22 | 23 | public static void clear(Player player) { 24 | Validate.checkArgumentNotNull(player, "player"); 25 | clearPotionEffects(player); 26 | clearInventory(player); 27 | player.setGameMode(GameMode.SURVIVAL); 28 | player.setMaximumNoDamageTicks(20); 29 | player.setFoodLevel(20); 30 | player.setHealth(20); 31 | player.setFireTicks(0); 32 | player.setFallDistance(0.0f); 33 | player.setFlying(false); 34 | } 35 | 36 | public static void clearPotionEffects(Player player) { 37 | Validate.checkArgumentNotNull(player, "player"); 38 | for (PotionEffect potion : player.getActivePotionEffects()) { 39 | player.removePotionEffect(potion.getType()); 40 | } 41 | } 42 | 43 | public static void clearInventory(Player player) { 44 | Validate.checkArgumentNotNull(player, "player"); 45 | player.setItemOnCursor(null); 46 | player.getInventory().clear(); 47 | player.getInventory().setArmorContents(null); 48 | } 49 | 50 | public static void fillHotbar(Player player, ItemStack item) { 51 | Validate.checkArgumentNotNull(player, "player"); 52 | Validate.checkArgumentNotNull(item, "item"); 53 | for (int i = 0; i < 9; i++) { 54 | player.getInventory().setItem(i, item); 55 | } 56 | } 57 | 58 | public static boolean isInventoryEmpty(Player player) { 59 | Validate.checkArgumentNotNull(player, "player"); 60 | 61 | for (ItemStack item : player.getInventory().getContents()) { 62 | if (!SpigotUtils.isEmpty(item)) { 63 | return false; 64 | } 65 | } 66 | 67 | for (ItemStack armor : player.getInventory().getArmorContents()) { 68 | if (!SpigotUtils.isEmpty(armor)) { 69 | return false; 70 | } 71 | } 72 | 73 | return true; 74 | } 75 | 76 | public static boolean isPlayerOnGround(Player player) { 77 | Validate.checkArgumentNotNull(player, "player"); 78 | return !player.isFlying() && player.getLocation().getY() % (1 / 64d) == 0; 79 | } 80 | 81 | public static Player getPlayerFromDamager(Entity damager) { 82 | Validate.checkArgumentNotNull(damager, "damager"); 83 | if (damager instanceof Player) { 84 | return (Player) damager; 85 | } 86 | 87 | if (damager instanceof Projectile) { 88 | Projectile projectile = (Projectile) damager; 89 | if (projectile.getShooter() instanceof Player) { 90 | return (Player) projectile.getShooter(); 91 | } 92 | } 93 | 94 | return null; 95 | } 96 | 97 | public static boolean isEmpty(ItemStack item) { 98 | return item == null || item.getType() == Material.AIR; 99 | } 100 | 101 | public static void sendMessage(CommandSender sender, String message) { 102 | Validate.checkArgumentNotNull(sender, "sender"); 103 | Validate.checkArgumentNotNull(message, "message"); 104 | sender.sendMessage(StringUtils.colour(message)); 105 | } 106 | 107 | public static void sendMessages(CommandSender sender, Iterable messages) { 108 | Validate.checkArgumentNotNull(messages, "messages"); 109 | for (String message : messages) { 110 | sendMessage(sender, message); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Plugin/src/main/java/ca/nicbo/invadedlandsevents/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package ca.nicbo.invadedlandsevents.util; 2 | 3 | import ca.nicbo.invadedlandsevents.api.util.Validate; 4 | import org.bukkit.ChatColor; 5 | import org.bukkit.Location; 6 | import org.bukkit.World; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Utility class for strings. 13 | * 14 | * @author Nicbo 15 | */ 16 | public final class StringUtils { 17 | private StringUtils() { 18 | } 19 | 20 | public static String locationToString(Location location) { 21 | return locationToString(location, true); 22 | } 23 | 24 | public static String locationToString(Location location, boolean includeYawPitch) { 25 | if (location == null) { 26 | return "null"; 27 | } 28 | 29 | World world = location.getWorld(); 30 | 31 | StringBuilder builder = new StringBuilder() 32 | .append("(") 33 | .append(world == null ? "null" : world.getName()) 34 | .append(", ") 35 | .append(String.format("%.2f", location.getX())) 36 | .append(", ") 37 | .append(String.format("%.2f", location.getY())) 38 | .append(", ") 39 | .append(String.format("%.2f", location.getZ())) 40 | .append(")"); 41 | 42 | if (includeYawPitch) { 43 | builder.append(" [") 44 | .append(String.format("%.2f", location.getYaw())) 45 | .append(", ") 46 | .append(String.format("%.2f", location.getPitch())) 47 | .append("]"); 48 | } 49 | 50 | return builder.toString(); 51 | } 52 | 53 | public static String colour(String message) { 54 | Validate.checkArgumentNotNull(message, "message"); 55 | return ChatColor.translateAlternateColorCodes('&', message); 56 | } 57 | 58 | public static List colour(List messages) { 59 | Validate.checkArgumentNotNull(messages, "messages"); 60 | List translated = new ArrayList<>(); 61 | for (String str : messages) { 62 | translated.add(colour(str)); 63 | } 64 | return translated; 65 | } 66 | 67 | public static String formatSeconds(long totalSeconds) { 68 | long totalSecondsAbs = Math.abs(totalSeconds); 69 | long seconds = totalSecondsAbs % 60; 70 | long totalMinutes = totalSecondsAbs / 60; 71 | long minutes = totalMinutes % 60; 72 | long hours = totalMinutes / 60; 73 | 74 | StringBuilder builder = new StringBuilder(); 75 | 76 | if (totalSeconds < 0) { 77 | builder.append("-"); 78 | } 79 | if (hours != 0) { 80 | builder.append(hours).append("h "); 81 | } 82 | if (minutes != 0) { 83 | builder.append(minutes).append("m "); 84 | } 85 | if (seconds != 0 || totalSecondsAbs == 0) { 86 | builder.append(seconds).append("s "); 87 | } 88 | 89 | // trim trailing whitespace 90 | builder.setLength(builder.length() - 1); 91 | return builder.toString(); 92 | } 93 | 94 | public static boolean equalsAnyIgnoreCase(String target, String... strings) { 95 | Validate.checkArgumentNotNull(target, "target"); 96 | Validate.checkArgumentNotNull(strings, "strings"); 97 | for (String string : strings) { 98 | if (target.equalsIgnoreCase(string)) { 99 | return true; 100 | } 101 | } 102 | return false; 103 | } 104 | 105 | public static String formatStringList(List strings) { 106 | Validate.checkArgumentNotNull(strings, "strings"); 107 | 108 | StringBuilder builder = new StringBuilder(); 109 | for (int i = 0; i < strings.size(); i++) { 110 | builder.append(ChatColor.YELLOW) 111 | .append(strings.get(i)) 112 | .append(ChatColor.GOLD) 113 | .append(i < strings.size() - 1 ? ", " : "."); 114 | } 115 | 116 | return builder.toString(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Plugin/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | main: ca.nicbo.invadedlandsevents.InvadedLandsEventsPlugin 2 | name: InvadedLandsEvents 3 | version: ${project.version} 4 | description: A replica of the invadedlands.net event plugin 5 | author: Nicbo 6 | website: https://www.spigotmc.org/resources/invadedlandsevents.83772/ 7 | api-version: 1.13 8 | 9 | commands: 10 | event: 11 | description: Handles event commands 12 | usage: / 13 | aliases: [ e ] 14 | eventconfig: 15 | description: Handles event config commands 16 | usage: / 17 | aliases: [ econfig ] 18 | 19 | permissions: 20 | ile.*: 21 | description: Gives the player every permission in InvadedLandsEvents 22 | default: op 23 | children: 24 | ile.eventconfig: true 25 | ile.event.*: true 26 | ile.eventconfig: 27 | description: Allows the player to configure events 28 | ile.event.*: 29 | description: Gives the player all event permissions 30 | children: 31 | ile.event.commandbypass: true 32 | ile.event.forceend: true 33 | ile.event.player: true 34 | ile.event.host.*: true 35 | ile.event.commandbypass: 36 | description: Allows the player to bypass command restrictions in events 37 | ile.event.forceend: 38 | description: Allows the player to force end the event 39 | ile.event.player: 40 | description: Gives the player all event permissions that players need 41 | children: 42 | ile.event.join: true 43 | ile.event.leave: true 44 | ile.event.spectate: true 45 | ile.event.info: true 46 | ile.event.stats.*: true 47 | ile.event.host: true 48 | ile.event.join: 49 | description: Allows the player to join events 50 | ile.event.leave: 51 | description: Allows the player to leave events 52 | ile.event.spectate: 53 | description: Allows the player to spectate events 54 | ile.event.info: 55 | description: Allows the player to see the current events info 56 | ile.event.stats.*: 57 | description: Allows the player to see players' event stats 58 | children: 59 | ile.event.stats: true 60 | ile.event.stats.other: true 61 | ile.event.stats: 62 | description: Allows the player to see their event stats 63 | ile.event.stats.other: 64 | description: Allows the player to see other players' event stats 65 | ile.event.host.*: 66 | description: Allows the player to host every event and bypass host cooldowns 67 | children: 68 | ile.event.host.all: true 69 | ile.event.host.cooldownbypass: true 70 | ile.event.host: 71 | description: Allows the player to host events 72 | ile.event.host.all: 73 | description: Allows the player to host every event 74 | children: 75 | ile.event.host.brackets1v1: true 76 | ile.event.host.brackets2v2: true 77 | ile.event.host.brackets3v3: true 78 | ile.event.host.koth: true 79 | ile.event.host.lms: true 80 | ile.event.host.oitc: true 81 | ile.event.host.redrover: true 82 | ile.event.host.rod: true 83 | ile.event.host.spleef: true 84 | ile.event.host.sumo1v1: true 85 | ile.event.host.sumo2v2: true 86 | ile.event.host.sumo3v3: true 87 | ile.event.host.tdm: true 88 | ile.event.host.tnttag: true 89 | ile.event.host.waterdrop: true 90 | ile.event.host.woolshuffle: true 91 | ile.event.host.cooldownbypass: 92 | description: Allows the player to bypass event host cooldowns 93 | ile.event.host.brackets1v1: 94 | description: Allows the player to host 1v1 brackets 95 | ile.event.host.brackets2v2: 96 | description: Allows the player to host 2v2 brackets 97 | ile.event.host.brackets3v3: 98 | description: Allows the player to host 3v3 brackets 99 | ile.event.host.koth: 100 | description: Allows the player to host koth 101 | ile.event.host.lms: 102 | description: Allows the player to host lms 103 | ile.event.host.oitc: 104 | description: Allows the player to host oitc 105 | ile.event.host.redrover: 106 | description: Allows the player to host redrover 107 | ile.event.host.rod: 108 | description: Allows the player to host rod 109 | ile.event.host.spleef: 110 | description: Allows the player to host spleef 111 | ile.event.host.sumo1v1: 112 | description: Allows the player to host 1v1 sumo 113 | ile.event.host.sumo2v2: 114 | description: Allows the player to host 2v2 sumo 115 | ile.event.host.sumo3v3: 116 | description: Allows the player to host 3v3 sumo 117 | ile.event.host.tdm: 118 | description: Allows the player to host tdm 119 | ile.event.host.tnttag: 120 | description: Allows the player to host tnt tag 121 | ile.event.host.waterdrop: 122 | description: Allows the player to host waterdrop 123 | ile.event.host.woolshuffle: 124 | description: Allows the player to host wool shuffle 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InvadedLandsEvents 2 | A replica of the invadedlands.net event plugin. 3 | 4 | ## Spigot Page 5 | - https://www.spigotmc.org/resources/invadedlandsevents.83772/ 6 | 7 | ## Dependencies 8 | - Minimum of Java 8 9 | 10 | ## Discord 11 | - Receive updates and real time code changes 12 | - Talk with the community 13 | - Ask any questions you may have 14 | - Create bug reports and suggestions 15 | - https://discord.gg/ychwA4h 16 | 17 | ## Tutorial Video 18 | - https://www.youtube.com/watch?v=GCN_d83mG_4 19 | 20 | ## Download 21 | - Prereleases are on GitHub 22 | - Releases are on Spigot 23 | 24 | ## TODO 25 | - Configurable 26 | - GUIs 27 | - Scoreboards 28 | - Placeholders 29 | - Various clean up 30 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | ca.nicbo.invadedlandsevents 8 | invadedlandsevents-parent 9 | 2.0.0-ALPHA.3 10 | pom 11 | InvadedLandsEvents 12 | https://github.com/Nicbo/InvadedLandsEvents 13 | 14 | 15 | API 16 | Plugin 17 | 18 | 19 | 20 | UTF-8 21 | 1.8 22 | 1.8 23 | 24 | 25 | 26 | 27 | org.spigotmc 28 | spigot-api 29 | 1.18.2-R0.1-SNAPSHOT 30 | provided 31 | 32 | 33 | 34 | 35 | 36 | spigot-repo 37 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------