From a6d70d6e906bf5d5ba54b9e016ce706afe217401 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 10 Sep 2021 18:39:16 -0700 Subject: [PATCH 1/2] Release 1.17.3 (#1827) * Version 1.17.1 * Add homes command to default player options. * Implements better online player counter. (#1791) Current one is based on online player count when bStats sends data to the server. This one will send data about amount of players who logged in the server. * Add Boxed Gamemode to the list. (#1793) * Add Bank addon (#1792) * Add Holographic Displays as SoftDepend for AOneBlock (#1794) * Custom date time format support for / info (#1783) Fixes #1720 * Parent/sub-flag support, split up and designate CONTAINER flag as parent flag (#1784) * Split CONTAINER flag into multiple flags CONTAINER split into - CONTAINER (Chest/Minecart Chest) - BARREL (Barrel) - COMPOSTER (Composter) - FLOWER_POT (Flower Pot) - SHULKER_BOX (Shulker Box) - TRAPPED_CHEST (Trapped Chest) Fixes #1777 * Add subflag support * Create container parent flag, chest subflag * Remove extra string from when CHEST was CONTAINER * Fix incorrect flag specified on fired event in IslandToggleClick * Add missing world subflag event firing * Remove extra import * Add world setting flag for island visitors keep inventory (#1785) * Implement 3 bar charts: addons, gamemodes, hooks (#1790) BStats supports sending Bar chart data, however, it does not display it via their site directly. It can be called manually, to view. PieChart does not work very well for addons and hooks. BarChart however allows viewing each addon separately. This change allows sending data to the server about bar charts. * Update action versions * Declare distribution - adopt * Cache Java Maven files differently. * Try dependency for shade snapshot * Add support for Minecraft 1.17.1 * Fix test by incrementing listener value check There is a new listener now. * Spigot 1.17.1 * Fix test for InventoryListener * Re-order repos. * Downgrading to 1.17 Spigot for now to enable building. * Try pluginRespositories tag in POM to enable Github actions * Version 1.17.2 * Add alternative Addon#getIslandManager method (#1797) We have already done this to the main BentoBox class. But add-ons missed it, and it still has this weird structure: Addon#getIslands().getIslands(). This will just add the same method as it is already in BentoBox class. * Fix bucket dupe (#1806) Fix https://discord.com/channels/272499714048524288/310623455462686720/867790395442462760 * Removes unneeded exploit protection code for skulls (#1810) This no longer seems to be required with 1.17.1 https://github.com/BentoBoxWorld/BSkyBlock/issues/430 * Quote filename of addon that cannot be loaded. Provides a better understanding of which addon failed. * Remove update when pasting chest. * Version 1.17.3 * Java upgrade (#1814) * Version 1.17.3 * Use Map.of and List.of instead of Immutable collections * Replace explicit type argument. * Replace lamba with method reference * Replace condition with Objects.requireNonNullElseGet * Use String.repeat * Use new switch expressions * Use instanceof patten variables which are more compact * Fuse toUnmodifiableList into stream and return it. * Remove unnecessary toString() calls. * Remove unnecessary public * Extracted common part from if * Simplify conditional expressions * Remove unused IOExceptions * Cast to long * Use Map.putAll * Use primitives * Clarify what is null or not * Addedd @Serial annotation introduced with Java 14. * Use Optional.isEmpty instead of !isPresent * Use flatMap then ifPresent * Just use Arrays.stream * Swap map and filter for null with Objects::nonNull * Use expression lambda * Update JavaDoc version to 16 * Make spawn protection area square instead of circle. https://github.com/BentoBoxWorld/BentoBox/issues/1819 * Improve ItemParser code. (#1821) * Improve ItemParser code. Add ability to parse text if Material is just a single string. Add ability to parse player heads. Add comments to the code. * Fixes failing test. * Added deprecation suppression. * Added Pladdon to loadbefore. * Prevent bucket duping when scooping obsidian Part 35 https://github.com/BentoBoxWorld/BentoBox/issues/1825 * Warns visitors that PVP is active if they teleport to an island https://github.com/BentoBoxWorld/BentoBox/issues/1780 * Prevents repeated portaling when nether is disabled. (#1826) * Prevents repeated portaling when nether is disabled. https://github.com/BentoBoxWorld/BentoBox/issues/1782 * Fix test * Hex pr 1820 (#1822) * Fix @since for subflags. (#1831) * Add Citizens to Softdepend list for NPC support (#1834) * Fix color test. * Set the default game mode when player makes island. * Corrects JavaDocs link Fixes https://github.com/BentoBoxWorld/BentoBox/issues/1838 * Update to 3.3.1-SNAPSHOT for shade plugin. * Package info files for better JavaDocs (#1839) * Added package info files for better JavaDocs * Implement Flag icon changing via Locales file. (#1829) This commit contains 2 changes: - An option for Flag to use icon that is defined in locales after "icon" string. - An option for ItemParser to parse icon or return given value, if parsing was not successful. The flag option is not ideal, but it is simpler and easier to maintain then adding new config section where icons can be changed, as the locales file already contains a lot of info about each flag. * Support glowing ink in blueprints (#1842) Fixes https://github.com/BentoBoxWorld/BentoBox/issues/1837 * Panel template (#1841) * Implement basic functionality to read data from template panels. Create TemplateReader class that has static method which generates a PanelTemplateRecord. This record contains every necessary information from user created template file so everyone could use it to generate a functional panel. These classes are just for reading templates and do not create actual panel. * Add template clearing via bentobox reload command. * Fix version command to show addon state. * Fix German flag banner description. Added more debug around error reporting. * Make variables final if they can be. (#1843) * Make variables final if they can be. * Do not use final so that test can pass. For testing, we use a trick to set this variable, but it won't work if it is final. Right now, I'd like to keep the test. * Static code analysis (#1844) * StringBuffer (Java 5) may be declared as StringBuilder * Replace map with flatMap * Use instanceof naming * No need to specify paramter types. * Remove verbose code * Fix JavaDoc issues * Make internal class a record. * Remove unused import. * Make internal class a record. * Made internal class a record. * Removed unused import * Fix typos * Fix typo in test. * Prevent home teleport when already home teleporting Home teleporting is async so it's possible to issue the command multiple times. This puts a flag in so that if a playeer is mid-teleport, then issuing the go command will just repeat the text that the player is teleporting home. https://github.com/BentoBoxWorld/BentoBox/issues/1637 * Extracted island info from the Island object. This is in preparation to have a different info for players than admins. https://github.com/BentoBoxWorld/BentoBox/issues/1501 * Slimmer trimmer island info for players. https://github.com/BentoBoxWorld/BentoBox/issues/1501 * Fixes coop and trust invites when team invites are not allowed If a member or sub-owner has coop or trust invite capability and not team invite rank, and confirm invites is on, then the invites were not working. Fixes https://github.com/BentoBoxWorld/BentoBox/issues/1452 * Remove invulnerable visitor protection if island is in PVP mode We now have alerts if a player teleports to a PVP island. https://github.com/BentoBoxWorld/BentoBox/issues/668 * Fixes NPE in admin tp if nether or end worlds don't exist. * Adds arrow sound when teleporting into a PVP island. * Fix PVPListenerTest Visitors are no longer invincible when on a PVP island. * Fix test failure in InvincibleVisitorsListenerTest * Minor JavaDoc correction. * Go command was not working second time. * Prevents console errors for missing icons in locale files. * Fixes PlAddon disabling issue. (#1847) There was a bug that did not unload PlAddon classes from JVM. This change should fix it, as it will unload PlAddons via pluginLoader. * Clear code - set worlds once on construction. * Fixes a bug when Potion metadata was not applied (#1849) There was missing potion meta data applying after creating an item. This affects both: Potions and Tipped arrows. * Adds force-shown lines to the template. (#1850) * Adds force-shown lines to the template. Fixes a bug when template type was not selected correctly. Changes "name" to "title" for border and background icons. * Create TemplatedPanel and TemplatedPanelBuilder. TemplatedPanel uses PanelTemplateRecord to create a functional panel. Builder contains button builder callbacks that are used to create buttons with custom data. * Use final vars for lambdas to avoid them changing async The processes could run async, especially when chunk loading took a while, so using fields that could change would result in blocks being missed, especially in the nether or end. Switching to final vars avoids this. Fixes https://github.com/BentoBoxWorld/BentoBox/issues/1840 * Remove travis. Co-authored-by: BONNe Co-authored-by: Fredthedoggy <45927799+Fredthedoggy@users.noreply.github.com> Co-authored-by: Justin Co-authored-by: gecko10000 <60494179+levtey@users.noreply.github.com> --- .travis.yml | 23 - README.md | 2 +- pom.xml | 6 +- .../world/bentobox/bentobox/BentoBox.java | 2 +- .../bentobox/bentobox/api/addons/Addon.java | 2 +- .../bentobox/api/addons/AddonClassLoader.java | 4 +- .../bentobox/api/addons/AddonDescription.java | 9 +- .../bentobox/bentobox/api/addons/Pladdon.java | 9 + .../api/addons/exceptions/AddonException.java | 3 + .../exceptions/AddonRequestException.java | 5 +- .../InvalidAddonDescriptionException.java | 3 + .../InvalidAddonFormatException.java | 2 + .../InvalidAddonInheritException.java | 3 + .../api/addons/exceptions/package-info.java | 10 + .../bentobox/api/addons/package-info.java | 12 + .../addons/request/AddonRequestBuilder.java | 2 +- .../api/addons/request/package-info.java | 13 + .../api/commands/CompositeCommand.java | 30 +- .../api/commands/ConfirmableCommand.java | 54 +- .../api/commands/DelayedTeleportCommand.java | 46 +- .../api/commands/admin/AdminInfoCommand.java | 9 +- .../admin/AdminResetFlagsCommand.java | 2 +- .../AdminSetProtectionCenterCommand.java | 2 +- .../commands/admin/AdminSettingsCommand.java | 26 +- .../commands/admin/AdminSwitchtoCommand.java | 2 +- .../commands/admin/AdminTeleportCommand.java | 4 + .../api/commands/admin/AdminTrashCommand.java | 3 +- .../commands/admin/AdminVersionCommand.java | 2 +- .../commands/admin/DefaultAdminCommand.java | 4 +- .../admin/purge/AdminPurgeCommand.java | 2 +- .../admin/range/AdminRangeDisplayCommand.java | 28 +- .../admin/team/AdminTeamAddCommand.java | 6 +- .../admin/team/AdminTeamKickCommand.java | 7 +- .../api/commands/island/IslandGoCommand.java | 6 + .../commands/island/IslandInfoCommand.java | 7 +- .../api/commands/island/team/Invite.java | 3 +- .../island/team/IslandTeamCommand.java | 2 +- .../island/team/IslandTeamCoopCommand.java | 2 +- .../team/IslandTeamInviteAcceptCommand.java | 31 +- .../island/team/IslandTeamInviteCommand.java | 14 +- .../team/IslandTeamInviteRejectCommand.java | 2 +- .../bentobox/api/commands/package-info.java | 18 + .../bentobox/api/configuration/Config.java | 4 +- .../bentobox/api/events/addon/AddonEvent.java | 32 +- .../api/events/island/IslandEvent.java | 143 ++--- .../bentobox/api/events/package-info.java | 8 + .../bentobox/api/events/team/TeamEvent.java | 74 +-- .../bentobox/bentobox/api/flags/Flag.java | 94 ++-- .../bentobox/api/flags/FlagListener.java | 20 + .../clicklisteners/IslandToggleClick.java | 4 +- .../flags/clicklisteners/package-info.java | 12 + .../bentobox/api/flags/package-info.java | 16 + .../bentobox/api/hooks/package-info.java | 12 + .../api/localization/BentoBoxLocale.java | 10 +- .../api/localization/package-info.java | 11 + .../bentobox/bentobox/api/logs/LogEntry.java | 2 +- .../bentobox/api/metadata/MetaDataAble.java | 4 +- .../bentobox/api/metadata/MetaDataValue.java | 4 +- .../bentobox/api/metadata/package-info.java | 11 + .../bentobox/bentobox/api/panels/Panel.java | 12 +- .../bentobox/api/panels/PanelItem.java | 2 +- .../bentobox/api/panels/TabbedPanel.java | 5 +- .../bentobox/api/panels/TemplatedPanel.java | 527 ++++++++++++++++++ .../api/panels/builders/PanelBuilder.java | 5 +- .../api/panels/builders/PanelItemBuilder.java | 5 +- .../builders/TemplatedPanelBuilder.java | 203 +++++++ .../bentobox/api/panels/package-info.java | 21 + .../api/panels/reader/ItemTemplateRecord.java | 89 +++ .../panels/reader/PanelTemplateRecord.java | 79 +++ .../api/panels/reader/TemplateReader.java | 364 ++++++++++++ .../api/placeholders/package-info.java | 7 + .../AddonPlaceholderExpansion.java | 2 +- .../BasicPlaceholderExpansion.java | 2 +- .../BentoBoxPlaceholderExpansion.java | 2 +- .../bentobox/bentobox/api/user/Notifier.java | 27 +- .../bentobox/bentobox/api/user/User.java | 9 +- .../bentobox/api/user/package-info.java | 18 + .../blueprints/BlueprintClipboard.java | 140 ++--- .../bentobox/blueprints/BlueprintPaster.java | 48 +- .../conversation/DescriptionPrompt.java | 9 +- .../DescriptionSuccessPrompt.java | 4 +- .../blueprints/conversation/NamePrompt.java | 8 +- .../conversation/NameSuccessPrompt.java | 7 +- .../dataobjects/BlueprintBlock.java | 18 + .../dataobjects/BlueprintEntity.java | 3 +- .../bentobox/blueprints/package-info.java | 10 + .../worldedit/BlueprintClipboardFormat.java | 4 +- .../worldedit/BlueprintClipboardReader.java | 7 +- .../worldedit/BlueprintClipboardWriter.java | 7 +- .../BlueprintSchematicConverter.java | 2 +- .../commands/BentoBoxReloadCommand.java | 3 + .../bentobox/commands/package-info.java | 7 + .../bentobox/bentobox/database/Database.java | 4 +- .../json/AbstractJSONDatabaseHandler.java | 2 +- .../bentobox/database/json/JSONDatabase.java | 2 +- .../database/json/JSONDatabaseConnector.java | 4 +- .../json/adapters/FlagTypeAdapter.java | 4 +- .../database/json/adapters/package-info.java | 12 + .../mongodb/MongoDBDatabaseHandler.java | 5 +- .../bentobox/database/objects/Island.java | 69 +-- .../database/objects/IslandDeletion.java | 3 +- .../objects/adapters/FlagSerializer.java | 3 +- .../objects/adapters/FlagSerializer2.java | 3 +- .../objects/adapters/FlagSerializer3.java | 3 +- .../objects/adapters/package-info.java | 6 + .../database/objects/package-info.java | 11 + .../bentobox/database/package-info.java | 21 + .../database/sql/SQLConfiguration.java | 2 +- .../database/sql/SQLDatabaseConnector.java | 2 +- .../database/sql/sqlite/SQLiteDatabase.java | 2 +- .../transition/TransitionDatabaseHandler.java | 4 +- .../bentobox/database/yaml/YamlDatabase.java | 2 +- .../database/yaml/YamlDatabaseConnector.java | 13 +- .../database/yaml/YamlDatabaseHandler.java | 16 +- .../bentobox/bentobox/hooks/DynmapHook.java | 2 +- .../bentobox/hooks/LangUtilsHook.java | 222 ++++---- .../bentobox/bentobox/hooks/package-info.java | 7 + .../placeholders/PlaceholderAPIHook.java | 2 +- .../bentobox/listeners/BannedCommands.java | 2 +- .../bentobox/listeners/BlockEndDragon.java | 2 +- .../bentobox/listeners/DeathListener.java | 2 +- .../bentobox/listeners/JoinLeaveListener.java | 11 +- .../listeners/PanelListenerManager.java | 8 +- .../listeners/PlayerEntityPortalEvent.java | 2 +- .../PortalTeleportationListener.java | 83 +-- .../StandardSpawnProtectionListener.java | 7 +- .../clicklisteners/CommandCycleClick.java | 6 +- .../CommandRankClickListener.java | 2 +- .../listeners/flags/package-info.java | 7 + .../protection/BlockInteractionListener.java | 6 +- .../flags/protection/BreakBlocksListener.java | 6 +- .../flags/protection/BreedingListener.java | 3 +- .../flags/protection/BucketListener.java | 24 +- .../flags/protection/ElytraListener.java | 3 +- .../flags/protection/HurtingListener.java | 10 +- .../flags/protection/InventoryListener.java | 3 +- .../PhysicalInteractionListener.java | 24 +- .../flags/protection/TNTListener.java | 9 +- .../listeners/flags/settings/PVPListener.java | 65 ++- .../worldsettings/CleanSuperFlatListener.java | 4 +- .../flags/worldsettings/CreeperListener.java | 3 +- .../worldsettings/GeoLimitMobsListener.java | 5 +- .../InvincibleVisitorsListener.java | 7 +- .../LiquidsFlowingOutListener.java | 2 +- .../NaturalSpawningOutsideRangeListener.java | 2 +- .../ObsidianScoopingListener.java | 16 +- .../worldsettings/PetTeleportListener.java | 3 +- .../TreesGrowingOutsideRangeListener.java | 8 +- .../world/bentobox/bentobox/lists/Flags.java | 2 +- .../bentobox/lists/GameModePlaceholder.java | 4 +- .../bentobox/bentobox/lists/package-info.java | 7 + .../bentobox/managers/AddonsManager.java | 38 +- .../managers/BlueprintClipboardManager.java | 6 +- .../bentobox/managers/BlueprintsManager.java | 9 +- .../bentobox/managers/CommandsManager.java | 2 +- .../bentobox/managers/FlagsManager.java | 7 +- .../managers/GameModePlaceholderManager.java | 2 +- .../bentobox/managers/HooksManager.java | 4 +- .../managers/IslandDeletionManager.java | 8 +- .../bentobox/managers/IslandWorldManager.java | 4 +- .../bentobox/managers/IslandsManager.java | 78 +-- .../bentobox/managers/LocalesManager.java | 4 +- .../managers/PlaceholdersManager.java | 2 +- .../bentobox/managers/PlayersManager.java | 8 +- .../bentobox/managers/WebManager.java | 12 +- .../DefaultNewIslandLocationStrategy.java | 4 +- .../bentobox/managers/island/IslandCache.java | 13 +- .../bentobox/managers/island/IslandGrid.java | 6 +- .../bentobox/managers/island/NewIsland.java | 4 +- .../bentobox/bentobox/nms/NMSAbstraction.java | 2 +- .../bentobox/bentobox/nms/package-info.java | 12 + .../panels/BlueprintManagementPanel.java | 22 +- .../bentobox/bentobox/panels/IconChanger.java | 8 +- .../bentobox/panels/IslandCreationPanel.java | 5 +- .../bentobox/panels/LanguagePanel.java | 8 +- .../bentobox/panels/ManagementPanel.java | 169 +++--- .../bentobox/panels/package-info.java | 11 + .../bentobox/panels/settings/SettingsTab.java | 16 +- .../bentobox/util/DeleteIslandChunks.java | 68 +-- .../bentobox/bentobox/util/FileLister.java | 2 +- .../bentobox/bentobox/util/IslandInfo.java | 140 +++++ .../bentobox/bentobox/util/ItemParser.java | 291 +++++++--- .../world/bentobox/bentobox/util/Pair.java | 3 +- .../world/bentobox/bentobox/util/Util.java | 94 ++-- .../bentobox/util/heads/HeadGetter.java | 2 +- .../bentobox/bentobox/util/package-info.java | 12 + .../util/teleport/SafeSpotTeleport.java | 4 +- .../versions/ServerCompatibility.java | 12 +- .../bentobox/versions/package-info.java | 11 + .../bentobox/web/catalog/CatalogEntry.java | 20 +- .../bentobox/web/credits/Contributor.java | 5 +- .../bentobox/bentobox/web/package-info.java | 7 + src/main/resources/locales/de.yml | 2 +- src/main/resources/plugin.yml | 3 +- .../bentobox/api/addons/AddonTest.java | 2 +- .../commands/admin/AdminInfoCommandTest.java | 265 +++++---- .../admin/AdminResetFlagsCommandTest.java | 2 +- .../admin/team/AdminTeamAddCommandTest.java | 109 ++-- .../admin/team/AdminTeamKickCommandTest.java | 2 +- .../commands/island/IslandGoCommandTest.java | 16 +- .../island/IslandInfoCommandTest.java | 78 ++- .../adapters/LogEntryListAdapterTest.java | 2 +- .../sql/mysql/MySQLDatabaseHandlerTest.java | 2 +- .../listeners/BannedCommandsTest.java | 2 +- .../listeners/BlockEndDragonTest.java | 2 +- .../listeners/JoinLeaveListenerTest.java | 4 +- .../listeners/PanelListenerManagerTest.java | 4 +- .../PortalTeleportationListenerTest.java | 7 +- .../StandardSpawnProtectionListenerTest.java | 4 +- .../listeners/flags/AbstractCommonSetup.java | 5 +- .../BlockInteractionListenerTest.java | 4 +- .../flags/protection/FireListenerTest.java | 2 +- .../flags/settings/PVPListenerTest.java | 54 +- .../worldsettings/EnterExitListenerTest.java | 4 +- .../InvincibleVisitorsListenerTest.java | 18 +- .../ObsidianScoopingListenerTest.java | 27 +- .../lists/GameModePlaceholderTest.java | 2 +- .../BlueprintClipboardManagerTest.java | 4 +- .../managers/BlueprintsManagerTest.java | 2 +- .../managers/IslandDeletionManagerTest.java | 2 +- .../managers/island/IslandCacheTest.java | 2 +- .../managers/island/NewIslandTest.java | 2 +- .../bentobox/util/ItemParserTest.java | 17 +- .../bentobox/bentobox/util/UtilTest.java | 41 +- 224 files changed, 3501 insertions(+), 1639 deletions(-) delete mode 100644 .travis.yml create mode 100644 src/main/java/world/bentobox/bentobox/api/addons/exceptions/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/addons/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/addons/request/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/commands/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/events/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/flags/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/hooks/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/localization/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/metadata/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java create mode 100644 src/main/java/world/bentobox/bentobox/api/panels/builders/TemplatedPanelBuilder.java create mode 100644 src/main/java/world/bentobox/bentobox/api/panels/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java create mode 100644 src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java create mode 100644 src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java create mode 100644 src/main/java/world/bentobox/bentobox/api/placeholders/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/api/user/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/blueprints/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/commands/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/database/json/adapters/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/database/objects/adapters/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/database/objects/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/database/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/hooks/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/listeners/flags/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/lists/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/nms/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/panels/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/util/IslandInfo.java create mode 100644 src/main/java/world/bentobox/bentobox/util/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/versions/package-info.java create mode 100644 src/main/java/world/bentobox/bentobox/web/package-info.java diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 77929dfeb..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: java -sudo: false -addons: - sonarcloud: - organization: "bentobox-world" - -jdk: - - openjdk8 - - openjdk11 - -matrix: - allow_failures: - - jdk: openjdk11 - -script: - - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install - - wget https://github.com/sormuras/bach/raw/master/install-jdk.sh && . ./install-jdk.sh -F 11 -L GPL - - mvn sonar:sonar -Dsonar.projectKey=BentoBoxWorld_BentoBox - -cache: - directories: - - '$HOME/.m2/repository' - - '$HOME/.sonar/cache' diff --git a/README.md b/README.md index ea309b227..28648010e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ There are also plenty of other official or community-made Addons you can try and ## Documentation * Start reading: [https://docs.bentobox.world](https://docs.bentobox.world) -* For developers: [Javadocs](https://bentoboxworld.github.io/BentoBox/) +* For developers: [Javadocs](https://ci.codemc.io/job/BentoBoxWorld/job/BentoBox/ws/target/apidocs/index.html) ## Downloads diff --git a/pom.xml b/pom.xml index db6efb907..cccabe1e3 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ -LOCAL - 1.17.2 + 1.17.3 @@ -353,7 +353,7 @@ maven-javadoc-plugin 3.3.0 - 8 + 16 private false -Xdoclint:none @@ -387,7 +387,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0-SNAPSHOT + 3.3.1-SNAPSHOT true diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 627c052fb..abb2d79e4 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -263,7 +263,7 @@ public class BentoBox extends JavaPlugin { } private void fireCriticalError(String message, String error) { - logError("*****************CRITIAL ERROR!******************"); + logError("*****************CRITICAL ERROR!******************"); logError(message); logError(error + " Disabling BentoBox..."); logError("*************************************************"); diff --git a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java index c05225ef6..54e525b3e 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java @@ -40,7 +40,7 @@ public abstract class Addon { private FileConfiguration config; private File dataFolder; private File file; - private Map requestHandlers = new HashMap<>(); + private final Map requestHandlers = new HashMap<>(); protected Addon() { state = State.DISABLED; diff --git a/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java b/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java index 3c62a4153..6f5b6a512 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java @@ -30,8 +30,8 @@ import world.bentobox.bentobox.managers.AddonsManager; public class AddonClassLoader extends URLClassLoader { private final Map> classes = new HashMap<>(); - private Addon addon; - private AddonsManager loader; + private final Addon addon; + private final AddonsManager loader; public AddonClassLoader(AddonsManager addonsManager, YamlConfiguration data, File jarFile, ClassLoader parent) throws InvalidAddonInheritException, diff --git a/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java b/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java index 1ad76c777..388aac2bc 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java @@ -163,9 +163,12 @@ public final class AddonDescription { } public static class Builder { - private @NonNull String main; - private @NonNull String name; - private @NonNull String version; + private @NonNull + final String main; + private @NonNull + final String name; + private @NonNull + final String version; private @NonNull String description = ""; private @NonNull List authors = new ArrayList<>(); private @NonNull List dependencies = new ArrayList<>(); diff --git a/src/main/java/world/bentobox/bentobox/api/addons/Pladdon.java b/src/main/java/world/bentobox/bentobox/api/addons/Pladdon.java index 0fdf15220..9f1197870 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/Pladdon.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/Pladdon.java @@ -54,4 +54,13 @@ public abstract class Pladdon extends JavaPlugin { } } + + + /** + * This method enables marks pladdons as enabled. + * By default, enable status is not set because onEnable and onLoad is not triggered. + */ + public void setEnabled() { + this.setEnabled(true); + } } diff --git a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonException.java b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonException.java index 543e20bd7..36e7a1961 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonException.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonException.java @@ -1,10 +1,13 @@ package world.bentobox.bentobox.api.addons.exceptions; +import java.io.Serial; + public abstract class AddonException extends Exception { /** * */ + @Serial private static final long serialVersionUID = 4203162022348693854L; protected AddonException(String errorMessage){ diff --git a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonRequestException.java b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonRequestException.java index 29ec3f051..bba12bf74 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonRequestException.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/AddonRequestException.java @@ -1,8 +1,11 @@ package world.bentobox.bentobox.api.addons.exceptions; +import java.io.Serial; + public class AddonRequestException extends AddonException { - private static final long serialVersionUID = -5698456013070166174L; + @Serial + private static final long serialVersionUID = -5698456013070166174L; public AddonRequestException(String errorMessage) { super(errorMessage); diff --git a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonDescriptionException.java b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonDescriptionException.java index b6f3fae62..3af6e932d 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonDescriptionException.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonDescriptionException.java @@ -1,5 +1,7 @@ package world.bentobox.bentobox.api.addons.exceptions; +import java.io.Serial; + /** * @since 1.11.0 */ @@ -8,6 +10,7 @@ public class InvalidAddonDescriptionException extends AddonException { /** * */ + @Serial private static final long serialVersionUID = 7741502900847049986L; public InvalidAddonDescriptionException(String errorMessage) { diff --git a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonFormatException.java b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonFormatException.java index dc228a1a5..d5d61d965 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonFormatException.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonFormatException.java @@ -1,5 +1,6 @@ package world.bentobox.bentobox.api.addons.exceptions; +import java.io.Serial; import java.util.logging.Level; import org.bukkit.Bukkit; @@ -9,6 +10,7 @@ public class InvalidAddonFormatException extends AddonException { /** * */ + @Serial private static final long serialVersionUID = 7741502900847049986L; public InvalidAddonFormatException(String errorMessage) { diff --git a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonInheritException.java b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonInheritException.java index dec1db6db..7a367207a 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonInheritException.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/InvalidAddonInheritException.java @@ -1,10 +1,13 @@ package world.bentobox.bentobox.api.addons.exceptions; +import java.io.Serial; + public class InvalidAddonInheritException extends AddonException { /** * */ + @Serial private static final long serialVersionUID = -5847358994397613244L; public InvalidAddonInheritException(String errorMessage) { diff --git a/src/main/java/world/bentobox/bentobox/api/addons/exceptions/package-info.java b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/package-info.java new file mode 100644 index 000000000..28daf0a6a --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/addons/exceptions/package-info.java @@ -0,0 +1,10 @@ +/** + * This package covers Addon exceptions + *

+ * These exceptions can be thrown when the addon is loaded. + *

+ * + * @since 1.0 + * @author tastybento + */ +package world.bentobox.bentobox.api.addons.exceptions; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/addons/package-info.java b/src/main/java/world/bentobox/bentobox/api/addons/package-info.java new file mode 100644 index 000000000..4d239fd0d --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/addons/package-info.java @@ -0,0 +1,12 @@ +/** + * This package covers all addon-specific API + *

+ * The Addon class and the associated Pladdon are like Bukkit plugins + * but contain extra API specific for BentoBox games. + *

+ * + * @since 1.0 + * @author tastybento + * + */ +package world.bentobox.bentobox.api.addons; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/addons/request/AddonRequestBuilder.java b/src/main/java/world/bentobox/bentobox/api/addons/request/AddonRequestBuilder.java index e5fde808e..13db8ff10 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/request/AddonRequestBuilder.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/request/AddonRequestBuilder.java @@ -20,7 +20,7 @@ public class AddonRequestBuilder { private String addonName; private String requestLabel; - private Map metaData = new HashMap<>(); + private final Map metaData = new HashMap<>(); /** * Define the addon you wish to request. diff --git a/src/main/java/world/bentobox/bentobox/api/addons/request/package-info.java b/src/main/java/world/bentobox/bentobox/api/addons/request/package-info.java new file mode 100644 index 000000000..f643446bd --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/addons/request/package-info.java @@ -0,0 +1,13 @@ +/** + * API to enable plugins to request data from addons. + *

+ * Addons can expose data that they want to expose. To access it, call this class with the appropriate addon name, + * the label for the data that is requested and if required, a map of key-value pairs that will be given to the addon. + * + * Note Since BentoBox 1.17.0, Addons can be declared as Pladdons and be loaded by the Bukkit classloader. This + * enables Plugins to access Addon methods directly so this API is not required. + *

+ * + * @author tastybento + */ +package world.bentobox.bentobox.api.addons.request; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java index 2a88cd0b4..931dd5ebe 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -33,7 +33,7 @@ import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.util.Util; /** - * BSB composite command + * BentoBox composite command. Provides an abstract implementation of a command. * @author tastybento * @author Poslovitch */ @@ -78,12 +78,12 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi /** * Map of sub commands */ - private Map subCommands; + private final Map subCommands; /** * Map of aliases for subcommands */ - private Map subCommandAliases; + private final Map subCommandAliases; /** * The command chain from the very top, e.g., island team promote */ @@ -93,7 +93,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * The prefix to be used in this command */ @Nullable - private String permissionPrefix; + private final String permissionPrefix; /** * The world that this command operates in. This is an overworld and will cover any associated nether or end @@ -104,17 +104,17 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi /** * The addon creating this command, if any */ - private Addon addon; + private final Addon addon; /** * The top level label */ - private String topLabel; + private final String topLabel; /** * Cool down tracker */ - private Map> cooldowns = new HashMap<>(); + private final Map> cooldowns = new HashMap<>(); /** * Top level command @@ -144,7 +144,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi // Run setup setup(); - if (!getSubCommand("help").isPresent() && !label.equals("help")) { + if (getSubCommand("help").isEmpty() && !label.equals("help")) { new DefaultHelpCommand(this); } } @@ -204,11 +204,11 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi p = p.getParent(); index++; } - setDescription(COMMANDS + reference.toString() + ".description"); - setParametersHelp(COMMANDS + reference.toString() + ".parameters"); + setDescription(COMMANDS + reference + ".description"); + setParametersHelp(COMMANDS + reference + ".parameters"); setup(); // If this command does not define its own help class, then use the default help command - if (!getSubCommand("help").isPresent() && !label.equals("help")) { + if (getSubCommand("help").isEmpty() && !label.equals("help")) { new DefaultHelpCommand(this); } } @@ -278,7 +278,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi // get the subcommand corresponding to the arg if (subCommand.hasSubCommands()) { Optional sub = subCommand.getSubCommand(arg); - if (!sub.isPresent()) { + if (sub.isEmpty()) { return subCommand; } // Step down one @@ -602,7 +602,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi return options; } // Add any tab completion from the subcommand - options.addAll(command.tabComplete(User.getInstance(sender), alias, new LinkedList<>(Arrays.asList(args))).orElseGet(() -> new ArrayList<>())); + options.addAll(command.tabComplete(User.getInstance(sender), alias, new LinkedList<>(Arrays.asList(args))).orElseGet(ArrayList::new)); if (command.hasSubCommands()) { options.addAll(getSubCommandLabels(sender, command)); } @@ -701,7 +701,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * @since 1.5.0 */ public void setCooldown(String uniqueId, String targetUUID, int timeInSeconds) { - cooldowns.computeIfAbsent(uniqueId, k -> new HashMap<>()).put(targetUUID, System.currentTimeMillis() + timeInSeconds * 1000); + cooldowns.computeIfAbsent(uniqueId, k -> new HashMap<>()).put(targetUUID, System.currentTimeMillis() + timeInSeconds * 1000L); } /** @@ -711,7 +711,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * @param timeInSeconds - time in seconds to cool down */ public void setCooldown(UUID uniqueId, UUID targetUUID, int timeInSeconds) { - cooldowns.computeIfAbsent(uniqueId.toString(), k -> new HashMap<>()).put(targetUUID == null ? null : targetUUID.toString(), System.currentTimeMillis() + timeInSeconds * 1000); + cooldowns.computeIfAbsent(uniqueId.toString(), k -> new HashMap<>()).put(targetUUID == null ? null : targetUUID.toString(), System.currentTimeMillis() + timeInSeconds * 1000L); } /** diff --git a/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java index 5b735b1ab..ca1e326a1 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java @@ -20,7 +20,7 @@ public abstract class ConfirmableCommand extends CompositeCommand { /** * Confirmation tracker */ - private static Map toBeConfirmed = new HashMap<>(); + private static final Map toBeConfirmed = new HashMap<>(); /** * Top level command @@ -61,9 +61,9 @@ public abstract class ConfirmableCommand extends CompositeCommand { public void askConfirmation(User user, String message, Runnable confirmed) { // Check for pending confirmations if (toBeConfirmed.containsKey(user)) { - if (toBeConfirmed.get(user).getTopLabel().equals(getTopLabel()) && toBeConfirmed.get(user).getLabel().equalsIgnoreCase(getLabel())) { - toBeConfirmed.get(user).getTask().cancel(); - Bukkit.getScheduler().runTask(getPlugin(), toBeConfirmed.get(user).getRunnable()); + if (toBeConfirmed.get(user).topLabel().equals(getTopLabel()) && toBeConfirmed.get(user).label().equalsIgnoreCase(getLabel())) { + toBeConfirmed.get(user).task().cancel(); + Bukkit.getScheduler().runTask(getPlugin(), toBeConfirmed.get(user).runnable()); toBeConfirmed.remove(user); return; } else { @@ -97,51 +97,9 @@ public abstract class ConfirmableCommand extends CompositeCommand { } /** - * Holds the data to run once the confirmation is given - * @author tastybento + * Record to hold the data to run once the confirmation is given * */ - private class Confirmer { - private final String topLabel; - private final String label; - private final Runnable runnable; - private final BukkitTask task; - - /** - * @param label - command label - * @param runnable - runnable to run when confirmed - * @param task - task ID to cancel when confirmed - */ - Confirmer(String topLabel, String label, Runnable runnable, BukkitTask task) { - this.topLabel = topLabel; - this.label = label; - this.runnable = runnable; - this.task = task; - } - /** - * @return the topLabel - */ - public String getTopLabel() { - return topLabel; - } - /** - * @return the label - */ - public String getLabel() { - return label; - } - /** - * @return the runnable - */ - public Runnable getRunnable() { - return runnable; - } - /** - * @return the task - */ - public BukkitTask getTask() { - return task; - } - } + private record Confirmer (String topLabel, String label, Runnable runnable, BukkitTask task) { } } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/DelayedTeleportCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/DelayedTeleportCommand.java index 490097099..283183d37 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/DelayedTeleportCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/DelayedTeleportCommand.java @@ -26,20 +26,20 @@ public abstract class DelayedTeleportCommand extends CompositeCommand implements /** * User monitor map */ - private static Map toBeMonitored = new HashMap<>(); + private static final Map toBeMonitored = new HashMap<>(); @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerMove(PlayerMoveEvent e) { UUID uuid = e.getPlayer().getUniqueId(); // Only check x,y,z - if (toBeMonitored.containsKey(uuid) && !e.getTo().toVector().equals(toBeMonitored.get(uuid).getLocation().toVector())) { + if (toBeMonitored.containsKey(uuid) && !e.getTo().toVector().equals(toBeMonitored.get(uuid).location().toVector())) { moved(uuid); } } private void moved(UUID uuid) { // Player moved - toBeMonitored.get(uuid).getTask().cancel(); + toBeMonitored.get(uuid).task().cancel(); toBeMonitored.remove(uuid); // Player has another outstanding confirmation request that will now be cancelled User.getInstance(uuid).notify("commands.delay.moved-so-command-cancelled"); @@ -103,7 +103,7 @@ public abstract class DelayedTeleportCommand extends CompositeCommand implements UUID uuid = user.getUniqueId(); if (toBeMonitored.containsKey(uuid)) { // A double request - clear out the old one - toBeMonitored.get(uuid).getTask().cancel(); + toBeMonitored.get(uuid).task().cancel(); toBeMonitored.remove(uuid); // Player has another outstanding confirmation request that will now be cancelled user.sendMessage("commands.delay.previous-command-cancelled"); @@ -116,7 +116,7 @@ public abstract class DelayedTeleportCommand extends CompositeCommand implements user.sendMessage("commands.delay.stand-still", "[seconds]", String.valueOf(getSettings().getDelayTime())); // Set up the run task BukkitTask task = Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { - Bukkit.getScheduler().runTask(getPlugin(), toBeMonitored.get(uuid).getRunnable()); + Bukkit.getScheduler().runTask(getPlugin(), toBeMonitored.get(uuid).runnable()); toBeMonitored.remove(uuid); }, getPlugin().getSettings().getDelayTime() * 20L); @@ -135,42 +135,8 @@ public abstract class DelayedTeleportCommand extends CompositeCommand implements /** * Holds the data to run once the confirmation is given - * @author tastybento * */ - private class DelayedCommand { - private final Runnable runnable; - private final BukkitTask task; - private final Location location; - - /** - * @param runnable - runnable to run when confirmed - * @param task - task ID to cancel when confirmed - * @param location - location - */ - DelayedCommand(Runnable runnable, BukkitTask task, Location location) { - this.runnable = runnable; - this.task = task; - this.location = location; - } - /** - * @return the runnable - */ - public Runnable getRunnable() { - return runnable; - } - /** - * @return the task - */ - public BukkitTask getTask() { - return task; - } - /** - * @return the location - */ - public Location getLocation() { - return location; - } - } + private record DelayedCommand(Runnable runnable, BukkitTask task, Location location) {} } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java index 79d9a0433..f335769cc 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java @@ -9,6 +9,7 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.util.IslandInfo; import world.bentobox.bentobox.util.Util; public class AdminInfoCommand extends CompositeCommand { @@ -34,10 +35,8 @@ public class AdminInfoCommand extends CompositeCommand { } // If there are no args, then the player wants info on the island at this location if (args.isEmpty()) { - if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.showInfo(user)).orElse(false)) { - user.sendMessage("commands.admin.info.no-island"); - return false; - } + getIslands().getIslandAt(user.getLocation()).ifPresentOrElse(i -> new IslandInfo(i).showAdminInfo(user), () -> + user.sendMessage("commands.admin.info.no-island")); return true; } // Get target player @@ -49,7 +48,7 @@ public class AdminInfoCommand extends CompositeCommand { // Show info for this player Island island = getIslands().getIsland(getWorld(), targetUUID); if (island != null) { - island.showInfo(user); + new IslandInfo(island).showAdminInfo(user); if (!getIslands().getQuarantinedIslandByUser(getWorld(), targetUUID).isEmpty()) { user.sendMessage("commands.admin.info.islands-in-trash"); } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommand.java index fa0dbc1c2..29f0a500f 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommand.java @@ -20,7 +20,7 @@ import world.bentobox.bentobox.util.Util; */ public class AdminResetFlagsCommand extends ConfirmableCommand { - private List options; + private final List options; public AdminResetFlagsCommand(CompositeCommand parent) { super(parent, "resetflags"); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetProtectionCenterCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetProtectionCenterCommand.java index 8f7766058..77de3e13e 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetProtectionCenterCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetProtectionCenterCommand.java @@ -59,7 +59,7 @@ public class AdminSetProtectionCenterCommand extends ConfirmableCommand return false; } Optional optionalIsland = getIslands().getIslandAt(targetLoc); - if (!optionalIsland.isPresent()) { + if (optionalIsland.isEmpty()) { user.sendMessage("commands.admin.setspawnpoint.no-island-here"); return false; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java index f06126b25..f8c25d8c0 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java @@ -38,8 +38,8 @@ public class AdminSettingsCommand extends CompositeCommand { private final List PROTECTION_FLAG_NAMES; private Island island; private final List SETTING_FLAG_NAMES; - private List WORLD_SETTING_FLAG_NAMES; - private @NonNull Optional flag; + private final List WORLD_SETTING_FLAG_NAMES; + private @NonNull Optional flag = Optional.empty(); private boolean activeState; private int rank; @@ -258,20 +258,14 @@ public class AdminSettingsCommand extends CompositeCommand { } } else if (args.size() == 4) { // Get flag in previous argument - options = getPlugin().getFlagsManager().getFlag(args.get(2).toUpperCase(Locale.ENGLISH)).map(f -> { - switch (f.getType()) { - case PROTECTION: - return getPlugin().getRanksManager() - .getRanks().entrySet().stream() - .filter(en -> en.getValue() > RanksManager.BANNED_RANK && en.getValue() <= RanksManager.OWNER_RANK) - .map(Entry::getKey) - .map(user::getTranslation).collect(Collectors.toList()); - case SETTING: - return Arrays.asList(active, disabled); - default: - return Collections.emptyList(); - - } + options = getPlugin().getFlagsManager().getFlag(args.get(2).toUpperCase(Locale.ENGLISH)).map(f -> switch (f.getType()) { + case PROTECTION -> getPlugin().getRanksManager() + .getRanks().entrySet().stream() + .filter(en -> en.getValue() > RanksManager.BANNED_RANK && en.getValue() <= RanksManager.OWNER_RANK) + .map(Entry::getKey) + .map(user::getTranslation).collect(Collectors.toList()); + case SETTING -> Arrays.asList(active, disabled); + default -> Collections.emptyList(); }).orElse(Collections.emptyList()); } return Optional.of(Util.tabLimit(options, lastArg)); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java index 5978050e0..3bb91c4c4 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java @@ -63,7 +63,7 @@ public class AdminSwitchtoCommand extends ConfirmableCommand { public boolean execute(User user, String label, List args) { if (NumberUtils.isDigits(args.get(1))) { try { - Integer n = Integer.valueOf(args.get(1)); + int n = Integer.parseInt(args.get(1)); if (n < 1 || n > islands.size()) { user.sendMessage("commands.admin.switchto.out-of-range", TextVariables.NUMBER, String.valueOf(islands.size()), TextVariables.LABEL, getTopLabel()); return false; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java index 42f695cf6..279531f66 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java @@ -87,6 +87,10 @@ public class AdminTeleportCommand extends CompositeCommand { world = getPlugin().getIWM().getEndWorld(getWorld()); } Location warpSpot = getSpot(world); + if (world == null || warpSpot == null) { + user.sendMessage("general.errors.no-safe-location-found"); + return false; + } // Otherwise, ask the admin to go to a safe spot String failureMessage = user.getTranslation("commands.admin.tp.manual", "[location]", warpSpot.getBlockX() + " " + warpSpot.getBlockY() + " " diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java index 2c03b8dee..e17d10041 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java @@ -7,6 +7,7 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.util.IslandInfo; public class AdminTrashCommand extends CompositeCommand { @@ -63,7 +64,7 @@ public class AdminTrashCommand extends CompositeCommand { user.sendMessage("commands.admin.trash.title"); for (int i = 0; i < islands.size(); i++) { user.sendMessage("commands.admin.trash.count", TextVariables.NUMBER, String.valueOf(i+1)); - islands.get(i).showInfo(user); + new IslandInfo(islands.get(i)).showInfo(user); } user.sendMessage("commands.admin.trash.use-switch", TextVariables.LABEL, getTopLabel()); user.sendMessage("commands.admin.trash.use-emptytrash", TextVariables.LABEL, getTopLabel()); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminVersionCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminVersionCommand.java index 788ced898..06a0d73d2 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminVersionCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminVersionCommand.java @@ -22,7 +22,7 @@ public class AdminVersionCommand extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { user.sendMessage("commands.bentobox.version.addon-syntax", TextVariables.NAME, getAddon().getDescription().getName(), - TextVariables.VERSION, getAddon().getDescription().getVersion()); + TextVariables.VERSION, getAddon().getDescription().getVersion(), "[state]", getAddon().getState().name()); return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/DefaultAdminCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/DefaultAdminCommand.java index da4a26d20..b52060b56 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/DefaultAdminCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/DefaultAdminCommand.java @@ -61,7 +61,7 @@ public abstract class DefaultAdminCommand extends CompositeCommand { new AdminTeamDisbandCommand(this); new AdminTeamSetownerCommand(this); new AdminTeamFixCommand(this); - // Schems + // Blueprints new AdminBlueprintCommand(this); // Register/unregister islands new AdminRegisterCommand(this); @@ -96,7 +96,7 @@ public abstract class DefaultAdminCommand extends CompositeCommand { /** * Defines what will be executed when this command is run. - * @see world.bentobox.bentobox.api.commands.BentoBoxCommand#execute(User, String, List<String>) + * @see world.bentobox.bentobox.api.commands.BentoBoxCommand#execute(User, String, List) */ @Override public boolean execute(User user, String label, List args) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/purge/AdminPurgeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/purge/AdminPurgeCommand.java index b7b916077..a4218ac9d 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/purge/AdminPurgeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/purge/AdminPurgeCommand.java @@ -70,7 +70,7 @@ public class AdminPurgeCommand extends CompositeCommand implements Listener { islands.clear(); this.user = user; try { - Integer days = Integer.parseInt(args.get(0)); + int days = Integer.parseInt(args.get(0)); if (days < 1) { user.sendMessage("commands.admin.purge.days-one-or-more"); return false; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeDisplayCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeDisplayCommand.java index 05392b038..0b8e726b2 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeDisplayCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeDisplayCommand.java @@ -24,7 +24,7 @@ public class AdminRangeDisplayCommand extends CompositeCommand { private static final String HIDE = "hide"; // Map of users to which ranges must be displayed - private Map displayRanges = new HashMap<>(); + private final Map displayRanges = new HashMap<>(); public AdminRangeDisplayCommand(CompositeCommand parent) { super(parent, DISPLAY, SHOW, HIDE); @@ -46,29 +46,15 @@ public class AdminRangeDisplayCommand extends CompositeCommand { if (!displayRanges.containsKey(user)) { switch (label) { - case DISPLAY: - case SHOW: - showZones(user); - break; - case HIDE: - user.sendMessage("commands.admin.range.display.already-off"); - break; - default: - showHelp(this, user); - break; + case DISPLAY, SHOW -> showZones(user); + case HIDE -> user.sendMessage("commands.admin.range.display.already-off"); + default -> showHelp(this, user); } } else { switch (label) { - case DISPLAY: - case HIDE: - hideZones(user); - break; - case SHOW: - user.sendMessage("commands.admin.range.display.already-on"); - break; - default: - showHelp(this, user); - break; + case DISPLAY, HIDE -> hideZones(user); + case SHOW -> user.sendMessage("commands.admin.range.display.already-on"); + default -> showHelp(this, user); } } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommand.java index 7153ab56f..b5feecab1 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommand.java @@ -10,6 +10,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.IslandInfo; import world.bentobox.bentobox.util.Util; public class AdminTeamAddCommand extends CompositeCommand { @@ -49,7 +50,10 @@ public class AdminTeamAddCommand extends CompositeCommand { } if (getIslands().inTeam(getWorld(), ownerUUID) && !getIslands().getOwner(getWorld(), ownerUUID).equals(ownerUUID)) { user.sendMessage("commands.admin.team.add.name-not-owner", TextVariables.NAME, args.get(0)); - getIslands().getIsland(getWorld(), ownerUUID).showMembers(user); + Island island = getIslands().getIsland(getWorld(), ownerUUID); + if (island != null) { + new IslandInfo(island).showMembers(user); + } return false; } if (getIslands().inTeam(getWorld(), targetUUID)) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java index c3cb032ca..5f44195ed 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java @@ -13,6 +13,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.IslandInfo; import world.bentobox.bentobox.util.Util; /** @@ -59,10 +60,12 @@ public class AdminTeamKickCommand extends CompositeCommand { @Override public boolean execute(User user, String label, @NonNull List args) { Island island = getIslands().getIsland(getWorld(), targetUUID); - + if (island == null) { + return false; + } if (targetUUID.equals(island.getOwner())) { user.sendMessage("commands.admin.team.kick.cannot-kick-owner"); - island.showMembers(user); + new IslandInfo(island).showMembers(user); return false; } User target = User.getInstance(targetUUID); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java index 736f85eab..055850486 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandGoCommand.java @@ -32,6 +32,12 @@ public class IslandGoCommand extends DelayedTeleportCommand { @Override public boolean canExecute(User user, String label, List args) { + // Check if mid-teleport + if (getIslands().isGoingHome(user)) { + // Tell them again that it's in progress + user.sendMessage("commands.island.go.teleport"); + return false; + } // Check if the island is reserved Island island = getIslands().getIsland(getWorld(), user.getUniqueId()); if (island == null) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommand.java index 1e4589aac..fca1faf73 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommand.java @@ -9,6 +9,7 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.util.IslandInfo; import world.bentobox.bentobox.util.Util; /** @@ -37,7 +38,7 @@ public class IslandInfoCommand extends CompositeCommand { } // If there are no args, then the player wants info on the island at this location if (args.isEmpty()) { - if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.showInfo(user)).orElse(false)) { + if (!getIslands().getIslandAt(user.getLocation()).map(i -> new IslandInfo(i).showInfo(user)).orElse(false)) { user.sendMessage("commands.admin.info.no-island"); return false; } @@ -56,10 +57,10 @@ public class IslandInfoCommand extends CompositeCommand { return false; } // Show info for this player - island.showInfo(user); + new IslandInfo(island).showInfo(user); return true; } - + @Override public Optional> tabComplete(User user, String alias, List args) { String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java index 658d0be53..aec829c17 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java @@ -75,10 +75,9 @@ public class Invite { if (obj == null) { return false; } - if (!(obj instanceof Invite)) { + if (!(obj instanceof Invite other)) { return false; } - Invite other = (Invite) obj; return Objects.equals(invitee, other.invitee) && Objects.equals(inviter, other.inviter) && type == other.type; } } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java index 6c93dc7e7..b1d2681e3 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java @@ -29,7 +29,7 @@ public class IslandTeamCommand extends CompositeCommand { * Invited list. Key is the invited party, value is the invite. * @since 1.8.0 */ - private Map inviteMap; + private final Map inviteMap; public IslandTeamCommand(CompositeCommand parent) { super(parent, "team"); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java index 55c11be17..50c1d12de 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java @@ -22,7 +22,7 @@ import world.bentobox.bentobox.util.Util; */ public class IslandTeamCoopCommand extends CompositeCommand { - private IslandTeamCommand itc; + private final IslandTeamCommand itc; private @Nullable UUID targetUUID; public IslandTeamCoopCommand(IslandTeamCommand parentCommand) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java index 2987453d4..ae8d6d9f4 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java @@ -20,7 +20,7 @@ import world.bentobox.bentobox.util.Util; */ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { - private IslandTeamCommand itc; + private final IslandTeamCommand itc; private UUID playerUUID; private UUID prospectiveOwnerUUID; @@ -50,16 +50,17 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { user.sendMessage("commands.island.team.invite.errors.invalid-invite"); return false; } - // Check rank to of inviter - Island island = getIslands().getIsland(getWorld(), prospectiveOwnerUUID); - String inviteUsage = getParent().getSubCommand("invite").map(CompositeCommand::getUsage).orElse(""); - if (island == null || island.getRank(prospectiveOwnerUUID) < island.getRankCommand(inviteUsage)) { - user.sendMessage("commands.island.team.invite.errors.invalid-invite"); - itc.removeInvite(playerUUID); - return false; - } Invite invite = itc.getInvite(playerUUID); if (invite.getType().equals(Type.TEAM)) { + // Check rank to of inviter + Island island = getIslands().getIsland(getWorld(), prospectiveOwnerUUID); + String inviteUsage = getParent().getSubCommand("invite").map(CompositeCommand::getUsage).orElse(""); + if (island == null || island.getRank(prospectiveOwnerUUID) < island.getRankCommand(inviteUsage)) { + user.sendMessage("commands.island.team.invite.errors.invalid-invite"); + itc.removeInvite(playerUUID); + return false; + } + // Check if player is already in a team if (getIslands().inTeam(getWorld(), playerUUID)) { user.sendMessage("commands.island.team.invite.errors.you-already-are-in-team"); @@ -82,14 +83,10 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { // Get the invite Invite invite = itc.getInvite(playerUUID); switch (invite.getType()) { - case COOP: - askConfirmation(user, () -> acceptCoopInvite(user, invite)); - break; - case TRUST: - askConfirmation(user, () -> acceptTrustInvite(user, invite)); - break; - default: - askConfirmation(user, user.getTranslation("commands.island.team.invite.accept.confirmation"), () -> acceptTeamInvite(user, invite)); + case COOP -> askConfirmation(user, () -> acceptCoopInvite(user, invite)); + case TRUST -> askConfirmation(user, () -> acceptTrustInvite(user, invite)); + default -> askConfirmation(user, user.getTranslation("commands.island.team.invite.accept.confirmation"), + () -> acceptTeamInvite(user, invite)); } return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java index 2de24d487..5fb312096 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java @@ -20,7 +20,7 @@ import world.bentobox.bentobox.util.Util; public class IslandTeamInviteCommand extends CompositeCommand { - private IslandTeamCommand itc; + private final IslandTeamCommand itc; private @Nullable User invitedPlayer; public IslandTeamInviteCommand(IslandTeamCommand parent) { @@ -51,15 +51,9 @@ public class IslandTeamInviteCommand extends CompositeCommand { Invite invite = itc.getInvite(playerUUID); String name = getPlayers().getName(playerUUID); switch (invite.getType()) { - case COOP: - user.sendMessage("commands.island.team.invite.name-has-invited-you.coop", TextVariables.NAME, name); - break; - case TRUST: - user.sendMessage("commands.island.team.invite.name-has-invited-you.trust", TextVariables.NAME, name); - break; - default: - user.sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, name); - break; + case COOP -> user.sendMessage("commands.island.team.invite.name-has-invited-you.coop", TextVariables.NAME, name); + case TRUST -> user.sendMessage("commands.island.team.invite.name-has-invited-you.trust", TextVariables.NAME, name); + default -> user.sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, name); } return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteRejectCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteRejectCommand.java index b93224990..963f24065 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteRejectCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteRejectCommand.java @@ -11,7 +11,7 @@ import world.bentobox.bentobox.api.user.User; public class IslandTeamInviteRejectCommand extends CompositeCommand { - private IslandTeamCommand itc; + private final IslandTeamCommand itc; public IslandTeamInviteRejectCommand(IslandTeamCommand islandTeamCommand) { super(islandTeamCommand, "reject"); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/package-info.java b/src/main/java/world/bentobox/bentobox/api/commands/package-info.java new file mode 100644 index 000000000..7c4212842 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/commands/package-info.java @@ -0,0 +1,18 @@ +/** + * API for BentoBox commands + */ +/** + *

+ * The workhorse class is the abstract class CompositeCommand. It provides all the functionality for + * a command including automatic help, sub-commands, convenience methods, etc. See examples of how to use + * it in the sub-folders admin and island. + *

+ *

+ * The package also includes abstract confirmable command and delayed teleport command classes. These can + * be extended for commands that need them. There is also a default help command. Commands can implement + * their own custom help if required, but most of the time it is not. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.api.commands; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/configuration/Config.java b/src/main/java/world/bentobox/bentobox/api/configuration/Config.java index d4d8ed688..420dd4174 100644 --- a/src/main/java/world/bentobox/bentobox/api/configuration/Config.java +++ b/src/main/java/world/bentobox/bentobox/api/configuration/Config.java @@ -22,8 +22,8 @@ import world.bentobox.bentobox.database.yaml.YamlDatabase; */ public class Config { - private AbstractDatabaseHandler handler; - private Logger logger; + private final AbstractDatabaseHandler handler; + private final Logger logger; private Addon addon; public Config(BentoBox plugin, Class type) { diff --git a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java index 76c8dfaec..78d1cd277 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java @@ -100,29 +100,21 @@ public class AddonEvent { } private AddonBaseEvent getDeprecatedEvent() { - switch (reason) { - case ENABLE: - return new AddonEnableEvent(addon, keyValues); - case DISABLE: - return new AddonDisableEvent(addon, keyValues); - case LOAD: - return new AddonLoadEvent(addon, keyValues); - default: - return new AddonGeneralEvent(addon, keyValues); - } + return switch (reason) { + case ENABLE -> new AddonEnableEvent(addon, keyValues); + case DISABLE -> new AddonDisableEvent(addon, keyValues); + case LOAD -> new AddonLoadEvent(addon, keyValues); + default -> new AddonGeneralEvent(addon, keyValues); + }; } private AddonBaseEvent getEvent() { - switch (reason) { - case ENABLE: - return new world.bentobox.bentobox.api.events.addon.AddonEnableEvent(addon, keyValues); - case DISABLE: - return new world.bentobox.bentobox.api.events.addon.AddonDisableEvent(addon, keyValues); - case LOAD: - return new world.bentobox.bentobox.api.events.addon.AddonLoadEvent(addon, keyValues); - default: - return new world.bentobox.bentobox.api.events.addon.AddonGeneralEvent(addon, keyValues); - } + return switch (reason) { + case ENABLE -> new world.bentobox.bentobox.api.events.addon.AddonEnableEvent(addon, keyValues); + case DISABLE -> new world.bentobox.bentobox.api.events.addon.AddonDisableEvent(addon, keyValues); + case LOAD -> new world.bentobox.bentobox.api.events.addon.AddonLoadEvent(addon, keyValues); + default -> new world.bentobox.bentobox.api.events.addon.AddonGeneralEvent(addon, keyValues); + }; } /** diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java index b957b127f..14aad63ff 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java @@ -801,103 +801,58 @@ public class IslandEvent extends IslandBaseEvent { * @return deprecated event */ private IslandBaseEvent getDeprecatedEvent() { - switch (reason) { - case EXPEL: - return new IslandExpelEvent(island, player, admin, location); - case BAN: - return new IslandBanEvent(island, player, admin, location); - case PRECREATE: - return new IslandPreCreateEvent(player); - case CREATE: - return new IslandCreateEvent(island, player, admin, location, blueprintBundle); - case CREATED: - return new IslandCreatedEvent(island, player, admin, location); - case DELETE: - return new IslandDeleteEvent(island, player, admin, location); - case DELETE_CHUNKS: - return new IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); - case DELETED: - return new IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); - case ENTER: - return new IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); - case EXIT: - return new IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); - case LOCK: - return new IslandLockEvent(island, player, admin, location); - case RESET: - return new IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); - case RESETTED: - return new IslandResettedEvent(island, player, admin, location, oldIsland); - case UNBAN: - return new IslandUnbanEvent(island, player, admin, location); - case UNLOCK: - return new IslandUnlockEvent(island, player, admin, location); - case REGISTERED: - return new IslandRegisteredEvent(island, player, admin, location); - case UNREGISTERED: - return new IslandUnregisteredEvent(island, player, admin, location); - case RANGE_CHANGE: - return new IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); - case PRECLEAR: - return new IslandPreclearEvent(island, player, admin, location, oldIsland); - case RESERVED: - return new IslandReservedEvent(island, player, admin, location); - case RANK_CHANGE: - return new IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); - default: - return new IslandGeneralEvent(island, player, admin, location); - } + return switch (reason) { + case EXPEL -> new IslandExpelEvent(island, player, admin, location); + case BAN -> new IslandBanEvent(island, player, admin, location); + case PRECREATE -> new IslandPreCreateEvent(player); + case CREATE -> new IslandCreateEvent(island, player, admin, location, blueprintBundle); + case CREATED -> new IslandCreatedEvent(island, player, admin, location); + case DELETE -> new IslandDeleteEvent(island, player, admin, location); + case DELETE_CHUNKS -> new IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); + case DELETED -> new IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); + case ENTER -> new IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); + case EXIT -> new IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); + case LOCK -> new IslandLockEvent(island, player, admin, location); + case RESET -> new IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); + case RESETTED -> new IslandResettedEvent(island, player, admin, location, oldIsland); + case UNBAN -> new IslandUnbanEvent(island, player, admin, location); + case UNLOCK -> new IslandUnlockEvent(island, player, admin, location); + case REGISTERED -> new IslandRegisteredEvent(island, player, admin, location); + case UNREGISTERED -> new IslandUnregisteredEvent(island, player, admin, location); + case RANGE_CHANGE -> new IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); + case PRECLEAR -> new IslandPreclearEvent(island, player, admin, location, oldIsland); + case RESERVED -> new IslandReservedEvent(island, player, admin, location); + case RANK_CHANGE -> new IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); + default -> new IslandGeneralEvent(island, player, admin, location); + }; } private IslandBaseEvent getEvent() { - switch (reason) { - case EXPEL: - return new world.bentobox.bentobox.api.events.island.IslandExpelEvent(island, player, admin, location); - case BAN: - return new world.bentobox.bentobox.api.events.island.IslandBanEvent(island, player, admin, location); - case PRECREATE: - return new world.bentobox.bentobox.api.events.island.IslandPreCreateEvent(player); - case CREATE: - return new world.bentobox.bentobox.api.events.island.IslandCreateEvent(island, player, admin, location, blueprintBundle); - case CREATED: - return new world.bentobox.bentobox.api.events.island.IslandCreatedEvent(island, player, admin, location); - case DELETE: - return new world.bentobox.bentobox.api.events.island.IslandDeleteEvent(island, player, admin, location); - case DELETE_CHUNKS: - return new world.bentobox.bentobox.api.events.island.IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); - case DELETED: - return new world.bentobox.bentobox.api.events.island.IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); - case ENTER: - return new world.bentobox.bentobox.api.events.island.IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); - case EXIT: - return new world.bentobox.bentobox.api.events.island.IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); - case LOCK: - return new world.bentobox.bentobox.api.events.island.IslandLockEvent(island, player, admin, location); - case RESET: - return new world.bentobox.bentobox.api.events.island.IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); - case RESETTED: - return new world.bentobox.bentobox.api.events.island.IslandResettedEvent(island, player, admin, location, oldIsland); - case UNBAN: - return new world.bentobox.bentobox.api.events.island.IslandUnbanEvent(island, player, admin, location); - case UNLOCK: - return new world.bentobox.bentobox.api.events.island.IslandUnlockEvent(island, player, admin, location); - case REGISTERED: - return new world.bentobox.bentobox.api.events.island.IslandRegisteredEvent(island, player, admin, location); - case UNREGISTERED: - return new world.bentobox.bentobox.api.events.island.IslandUnregisteredEvent(island, player, admin, location); - case RANGE_CHANGE: - return new world.bentobox.bentobox.api.events.island.IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); - case PRECLEAR: - return new world.bentobox.bentobox.api.events.island.IslandPreclearEvent(island, player, admin, location, oldIsland); - case RESERVED: - return new world.bentobox.bentobox.api.events.island.IslandReservedEvent(island, player, admin, location); - case RANK_CHANGE: - return new world.bentobox.bentobox.api.events.island.IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); - case NEW_ISLAND: - return new IslandNewIslandEvent(island, player, admin, location); - default: - return new world.bentobox.bentobox.api.events.island.IslandGeneralEvent(island, player, admin, location); - } + return switch (reason) { + case EXPEL -> new world.bentobox.bentobox.api.events.island.IslandExpelEvent(island, player, admin, location); + case BAN -> new world.bentobox.bentobox.api.events.island.IslandBanEvent(island, player, admin, location); + case PRECREATE -> new world.bentobox.bentobox.api.events.island.IslandPreCreateEvent(player); + case CREATE -> new world.bentobox.bentobox.api.events.island.IslandCreateEvent(island, player, admin, location, blueprintBundle); + case CREATED -> new world.bentobox.bentobox.api.events.island.IslandCreatedEvent(island, player, admin, location); + case DELETE -> new world.bentobox.bentobox.api.events.island.IslandDeleteEvent(island, player, admin, location); + case DELETE_CHUNKS -> new world.bentobox.bentobox.api.events.island.IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); + case DELETED -> new world.bentobox.bentobox.api.events.island.IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); + case ENTER -> new world.bentobox.bentobox.api.events.island.IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); + case EXIT -> new world.bentobox.bentobox.api.events.island.IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); + case LOCK -> new world.bentobox.bentobox.api.events.island.IslandLockEvent(island, player, admin, location); + case RESET -> new world.bentobox.bentobox.api.events.island.IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); + case RESETTED -> new world.bentobox.bentobox.api.events.island.IslandResettedEvent(island, player, admin, location, oldIsland); + case UNBAN -> new world.bentobox.bentobox.api.events.island.IslandUnbanEvent(island, player, admin, location); + case UNLOCK -> new world.bentobox.bentobox.api.events.island.IslandUnlockEvent(island, player, admin, location); + case REGISTERED -> new world.bentobox.bentobox.api.events.island.IslandRegisteredEvent(island, player, admin, location); + case UNREGISTERED -> new world.bentobox.bentobox.api.events.island.IslandUnregisteredEvent(island, player, admin, location); + case RANGE_CHANGE -> new world.bentobox.bentobox.api.events.island.IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); + case PRECLEAR -> new world.bentobox.bentobox.api.events.island.IslandPreclearEvent(island, player, admin, location, oldIsland); + case RESERVED -> new world.bentobox.bentobox.api.events.island.IslandReservedEvent(island, player, admin, location); + case RANK_CHANGE -> new world.bentobox.bentobox.api.events.island.IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); + case NEW_ISLAND -> new IslandNewIslandEvent(island, player, admin, location); + default -> new world.bentobox.bentobox.api.events.island.IslandGeneralEvent(island, player, admin, location); + }; } /** diff --git a/src/main/java/world/bentobox/bentobox/api/events/package-info.java b/src/main/java/world/bentobox/bentobox/api/events/package-info.java new file mode 100644 index 000000000..326a59c8c --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/events/package-info.java @@ -0,0 +1,8 @@ +/** + * API for all the events that BentoBox generates + */ +/** + * @author tastybento + * + */ +package world.bentobox.bentobox.api.events; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java index 19303c307..94791ef72 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java @@ -237,57 +237,35 @@ public class TeamEvent { } private IslandBaseEvent getDeprecatedEvent() { - switch (reason) { - case JOIN: - return new TeamJoinEvent(island, player, admin, location); - case JOINED: - return new TeamJoinedEvent(island, player, admin, location); - case INVITE: - return new TeamInviteEvent(island, player, admin, location); - case LEAVE: - return new TeamLeaveEvent(island, player, admin, location); - case REJECT: - return new TeamRejectEvent(island, player, admin, location); - case KICK: - return new TeamKickEvent(island, player, admin, location); - case SETOWNER: - return new TeamSetownerEvent(island, player, admin, location); - case INFO: - return new TeamInfoEvent(island, player, admin, location); - case DELETE: - return new TeamDeleteEvent(island, player, admin, location); - case UNINVITE: - return new TeamUninviteEvent(island, player, admin, location); - default: - return new TeamGeneralEvent(island, player, admin, location); - } + return switch (reason) { + case JOIN -> new TeamJoinEvent(island, player, admin, location); + case JOINED -> new TeamJoinedEvent(island, player, admin, location); + case INVITE -> new TeamInviteEvent(island, player, admin, location); + case LEAVE -> new TeamLeaveEvent(island, player, admin, location); + case REJECT -> new TeamRejectEvent(island, player, admin, location); + case KICK -> new TeamKickEvent(island, player, admin, location); + case SETOWNER -> new TeamSetownerEvent(island, player, admin, location); + case INFO -> new TeamInfoEvent(island, player, admin, location); + case DELETE -> new TeamDeleteEvent(island, player, admin, location); + case UNINVITE -> new TeamUninviteEvent(island, player, admin, location); + default -> new TeamGeneralEvent(island, player, admin, location); + }; } private IslandBaseEvent getEvent() { - switch (reason) { - case JOIN: - return new world.bentobox.bentobox.api.events.team.TeamJoinEvent(island, player, admin, location); - case JOINED: - return new world.bentobox.bentobox.api.events.team.TeamJoinedEvent(island, player, admin, location); - case INVITE: - return new world.bentobox.bentobox.api.events.team.TeamInviteEvent(island, player, admin, location); - case LEAVE: - return new world.bentobox.bentobox.api.events.team.TeamLeaveEvent(island, player, admin, location); - case REJECT: - return new world.bentobox.bentobox.api.events.team.TeamRejectEvent(island, player, admin, location); - case KICK: - return new world.bentobox.bentobox.api.events.team.TeamKickEvent(island, player, admin, location); - case SETOWNER: - return new world.bentobox.bentobox.api.events.team.TeamSetownerEvent(island, player, admin, location); - case INFO: - return new world.bentobox.bentobox.api.events.team.TeamInfoEvent(island, player, admin, location); - case DELETE: - return new world.bentobox.bentobox.api.events.team.TeamDeleteEvent(island, player, admin, location); - case UNINVITE: - return new world.bentobox.bentobox.api.events.team.TeamUninviteEvent(island, player, admin, location); - default: - return new world.bentobox.bentobox.api.events.team.TeamGeneralEvent(island, player, admin, location); - } + return switch (reason) { + case JOIN -> new world.bentobox.bentobox.api.events.team.TeamJoinEvent(island, player, admin, location); + case JOINED -> new world.bentobox.bentobox.api.events.team.TeamJoinedEvent(island, player, admin, location); + case INVITE -> new world.bentobox.bentobox.api.events.team.TeamInviteEvent(island, player, admin, location); + case LEAVE -> new world.bentobox.bentobox.api.events.team.TeamLeaveEvent(island, player, admin, location); + case REJECT -> new world.bentobox.bentobox.api.events.team.TeamRejectEvent(island, player, admin, location); + case KICK -> new world.bentobox.bentobox.api.events.team.TeamKickEvent(island, player, admin, location); + case SETOWNER -> new world.bentobox.bentobox.api.events.team.TeamSetownerEvent(island, player, admin, location); + case INFO -> new world.bentobox.bentobox.api.events.team.TeamInfoEvent(island, player, admin, location); + case DELETE -> new world.bentobox.bentobox.api.events.team.TeamDeleteEvent(island, player, admin, location); + case UNINVITE -> new world.bentobox.bentobox.api.events.team.TeamUninviteEvent(island, player, admin, location); + default -> new world.bentobox.bentobox.api.events.team.TeamGeneralEvent(island, player, admin, location); + }; } /** diff --git a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java index 754cdf325..ed60c42ff 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -25,6 +25,8 @@ import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.ItemParser; + public class Flag implements Comparable { @@ -51,7 +53,8 @@ public class Flag implements Comparable { */ WORLD_SETTING(Material.GRASS_BLOCK); - private @NonNull Material icon; + private @NonNull + final Material icon; Type(@NonNull Material icon) { this.icon = icon; @@ -91,14 +94,11 @@ public class Flag implements Comparable { * @return next ranking mode */ public Mode getNext() { - switch(this) { - case ADVANCED: - return EXPERT; - case BASIC: - return ADVANCED; - default: - return BASIC; - } + return switch (this) { + case ADVANCED -> EXPERT; + case BASIC -> ADVANCED; + default -> BASIC; + }; } /** @@ -107,14 +107,11 @@ public class Flag implements Comparable { * @return true if ranked greater */ public boolean isGreaterThan(Mode rank) { - switch(this) { - case EXPERT: - return rank.equals(BASIC) || rank.equals(ADVANCED); - case ADVANCED: - return rank.equals(BASIC); - default: - return false; - } + return switch (this) { + case EXPERT -> rank.equals(BASIC) || rank.equals(ADVANCED); + case ADVANCED -> rank.equals(BASIC); + default -> false; + }; } } @@ -207,12 +204,12 @@ public class Flag implements Comparable { // Subflag support if (hasSubflags()) { subflags.stream() - .filter(subflag -> subflag.getType().equals(Type.WORLD_SETTING) || subflag.getType().equals(Type.PROTECTION)) - .forEach(subflag -> BentoBox.getInstance() - .getIWM() - .getWorldSettings(world) - .getWorldFlags() - .put(subflag.getID(), setting)); + .filter(subflag -> subflag.getType().equals(Type.WORLD_SETTING) || subflag.getType().equals(Type.PROTECTION)) + .forEach(subflag -> BentoBox.getInstance() + .getIWM() + .getWorldSettings(world) + .getWorldFlags() + .put(subflag.getID(), setting)); } // Save config file @@ -222,7 +219,7 @@ public class Flag implements Comparable { /** * Set the original status of this flag for locations outside of island spaces. - * May be overriden by the the setting for this world. + * May be overridden by the setting for this world. * Does not affect subflags. * @param defaultSetting - true means it is allowed. false means it is not allowed */ @@ -300,10 +297,9 @@ public class Flag implements Comparable { if (obj == null) { return false; } - if (!(obj instanceof Flag)) { + if (!(obj instanceof Flag other)) { return false; } - Flag other = (Flag) obj; if (id == null) { if (other.id != null) { return false; @@ -322,6 +318,13 @@ public class Flag implements Comparable { return PROTECTION_FLAGS + this.id + ".name"; } + /** + * @return a locale reference for the icon of this protection flag + */ + public String getIconReference() { + return PROTECTION_FLAGS + this.id + ".icon"; + } + /** * @return a locale reference for the description of this protection flag */ @@ -384,7 +387,7 @@ public class Flag implements Comparable { } // Start the flag conversion PanelItemBuilder pib = new PanelItemBuilder() - .icon(new ItemStack(icon)) + .icon(ItemParser.parse(user.getTranslationOrNothing(this.getIconReference()), new ItemStack(icon))) .name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, user.getTranslation(getNameReference()))) .clickHandler(clickHandler) .invisible(invisible); @@ -392,16 +395,11 @@ public class Flag implements Comparable { pib.description(user.getTranslation("protection.panel.flag-item.menu-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); return pib.build(); } - switch(getType()) { - case PROTECTION: - return createProtectionFlag(plugin, user, island, pib).build(); - case SETTING: - return createSettingFlag(user, island, pib).build(); - case WORLD_SETTING: - return createWorldSettingFlag(user, pib).build(); - default: - return pib.build(); - } + return switch (getType()) { + case PROTECTION -> createProtectionFlag(plugin, user, island, pib).build(); + case SETTING -> createSettingFlag(user, island, pib).build(); + case WORLD_SETTING -> createWorldSettingFlag(user, pib).build(); + }; } private PanelItemBuilder createWorldSettingFlag(User user, PanelItemBuilder pib) { @@ -484,8 +482,8 @@ public class Flag implements Comparable { */ public static class Builder { // Mandatory fields - private String id; - private Material icon; + private final String id; + private final Material icon; // Listener private Listener listener; @@ -514,7 +512,7 @@ public class Flag implements Comparable { private Mode mode = Mode.EXPERT; // Subflags - private Set subflags; + private final Set subflags; /** * Builder for making flags @@ -638,7 +636,7 @@ public class Flag implements Comparable { * Take extra care to ensure that subflags have the same number of possible values as the parent flag. * @param flags all Flags that are subflags * @return Builder - flag builder - * @since 1.17.0 + * @since 1.17.1 */ public Builder subflags(Flag... flags) { this.subflags.addAll(Arrays.asList(flags)); @@ -653,17 +651,9 @@ public class Flag implements Comparable { // If no clickHandler has been set, then apply default ones if (clickHandler == null) { switch (type) { - case SETTING: - clickHandler = new IslandToggleClick(id); - break; - case WORLD_SETTING: - clickHandler = new WorldToggleClick(id); - break; - case PROTECTION: - // Default option - default: - clickHandler = new CycleClick(id); - break; + case SETTING -> clickHandler = new IslandToggleClick(id); + case WORLD_SETTING -> clickHandler = new WorldToggleClick(id); + default -> clickHandler = new CycleClick(id); } } diff --git a/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java b/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java index 20b27b4fc..dc62e87b4 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java @@ -4,6 +4,7 @@ import java.util.Optional; import java.util.UUID; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; @@ -18,6 +19,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.metadata.MetaDataValue; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.util.Util; @@ -253,4 +255,22 @@ public abstract class FlagListener implements Listener { protected IslandWorldManager getIWM() { return plugin.getIWM(); } + + /** + * Check if PVP is allowed here or not + * @param location location where action is taking + * @return true if PVP is allowed, false if not + */ + protected boolean PVPAllowed(Location location) { + return plugin.getIslands().getIslandAt(location).map(i -> i.isAllowed(this.getFlag(location.getWorld()))).orElse(false); + } + + protected Flag getFlag(World w) { + return switch (w.getEnvironment()) { + case NETHER -> Flags.PVP_NETHER; + case THE_END -> Flags.PVP_END; + default -> Flags.PVP_OVERWORLD; + }; + } + } diff --git a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java index 2afcd6b96..ddb5d2bd3 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java @@ -23,8 +23,8 @@ import world.bentobox.bentobox.util.Util; */ public class IslandToggleClick implements ClickHandler { - private BentoBox plugin = BentoBox.getInstance(); - private String id; + private final BentoBox plugin = BentoBox.getInstance(); + private final String id; /** * @param id - the flag ID that this click listener is associated with diff --git a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/package-info.java b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/package-info.java new file mode 100644 index 000000000..bf34c7ff9 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/package-info.java @@ -0,0 +1,12 @@ +/** + * This package contains click listener classes used when clicking on icons in settings + * + *

+ * CycleClick will cycle through different settings. IslandLock is specific to locking or unlocking an island. + * IslandToggleClick is a toggle-based selection. WorldToggleClick toggles world settings. + */ +/** + * @author tastybento + * + */ +package world.bentobox.bentobox.api.flags.clicklisteners; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/flags/package-info.java b/src/main/java/world/bentobox/bentobox/api/flags/package-info.java new file mode 100644 index 000000000..ca61498db --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/flags/package-info.java @@ -0,0 +1,16 @@ +/** + * This package contains the API for protection and settings flags + * + *

+ * New flags should use the Flag.Builder to create a flag. Listeners for flag related events should + * extend the abstract FlagListener class. + *

+ *

+ * Click listeners are different types of listeners specific to clicking on the settings UI in which the + * flags are shown. + *

+ * + * @author tastybento + * + */ +package world.bentobox.bentobox.api.flags; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/hooks/package-info.java b/src/main/java/world/bentobox/bentobox/api/hooks/package-info.java new file mode 100644 index 000000000..d23024e38 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/hooks/package-info.java @@ -0,0 +1,12 @@ +/** + * Provides API to enable BentoBox to hook into other plugins. + * + *

+ * This is used to hook into plugins like Placeholder API + *

+ */ +/** + * @author Poslovich + * + */ +package world.bentobox.bentobox.api.hooks; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/localization/BentoBoxLocale.java b/src/main/java/world/bentobox/bentobox/api/localization/BentoBoxLocale.java index c6c05e8d0..4d9a0674a 100644 --- a/src/main/java/world/bentobox/bentobox/api/localization/BentoBoxLocale.java +++ b/src/main/java/world/bentobox/bentobox/api/localization/BentoBoxLocale.java @@ -20,16 +20,16 @@ public class BentoBoxLocale { private static final String UNKNOWN = "unknown"; - private Locale locale; - private YamlConfiguration config; - private ItemStack banner; - private List authors; + private final Locale locale; + private final YamlConfiguration config; + private final ItemStack banner; + private final List authors; /** * List of available prefixes in this locale. * @since 1.12.0 */ - private Set prefixes; + private final Set prefixes; public BentoBoxLocale(Locale locale, YamlConfiguration config) { this.locale = locale; diff --git a/src/main/java/world/bentobox/bentobox/api/localization/package-info.java b/src/main/java/world/bentobox/bentobox/api/localization/package-info.java new file mode 100644 index 000000000..72ed5c7bd --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/localization/package-info.java @@ -0,0 +1,11 @@ +/** + * API for localization. + * + *

+ * BentoBoxLocale holds all the information required to specify a locale in BentoBox. + * TextVariables contains a static constants that are used as place holders in user messaging. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.api.localization; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java b/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java index 6112b8a57..583bd24a9 100644 --- a/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java +++ b/src/main/java/world/bentobox/bentobox/api/logs/LogEntry.java @@ -47,7 +47,7 @@ public class LogEntry { public static class Builder { private long timestamp; - private String type; + private final String type; private Map data; public Builder(@NonNull String type) { diff --git a/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataAble.java b/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataAble.java index 6e706505b..5233d0d23 100644 --- a/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataAble.java +++ b/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataAble.java @@ -13,13 +13,13 @@ public interface MetaDataAble { /** * @return the metaData */ - public Optional> getMetaData(); + Optional> getMetaData(); /** * @param metaData the metaData to set * @since 1.15.4 */ - public void setMetaData(Map metaData); + void setMetaData(Map metaData); /** * Get meta data by key diff --git a/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataValue.java b/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataValue.java index 4ae5c6d14..ea6d7c0a9 100644 --- a/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataValue.java +++ b/src/main/java/world/bentobox/bentobox/api/metadata/MetaDataValue.java @@ -29,7 +29,7 @@ public class MetaDataValue { @Expose private Boolean booleanValue; @Expose - private @NonNull String stringValue; + private String stringValue; /** * Initialize this meta data value @@ -85,6 +85,6 @@ public class MetaDataValue { @NonNull public String asString() { - return stringValue; + return stringValue == null ? "" : stringValue; } } diff --git a/src/main/java/world/bentobox/bentobox/api/metadata/package-info.java b/src/main/java/world/bentobox/bentobox/api/metadata/package-info.java new file mode 100644 index 000000000..15517d0d0 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/metadata/package-info.java @@ -0,0 +1,11 @@ +/** + * Metadata API for storing data in BentoBox database objects + *

+ * This API draws on the same concepts as Bukkit's meta data API. + * Classes capable of storing meta data will implement the MetaDataAble interface. + * MetaDataValue provides the actual object in which data is stored. +/*

+ * @author tastybento + * @since 1.15.4 + */ +package world.bentobox.bentobox.api.metadata; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/panels/Panel.java b/src/main/java/world/bentobox/bentobox/api/panels/Panel.java index 39d330465..9691371ad 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/Panel.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/Panel.java @@ -80,15 +80,9 @@ public class Panel implements HeadRequester, InventoryHolder { // Create panel switch (type) { - case INVENTORY: - inventory = Bukkit.createInventory(null, fixSize(size), name); - break; - case HOPPER: - inventory = Bukkit.createInventory(null, InventoryType.HOPPER, name); - break; - case DROPPER: - inventory = Bukkit.createInventory(null, InventoryType.DROPPER, name); - break; + case INVENTORY -> inventory = Bukkit.createInventory(null, fixSize(size), name); + case HOPPER -> inventory = Bukkit.createInventory(null, InventoryType.HOPPER, name); + case DROPPER -> inventory = Bukkit.createInventory(null, InventoryType.DROPPER, name); } // Fill the inventory and return diff --git a/src/main/java/world/bentobox/bentobox/api/panels/PanelItem.java b/src/main/java/world/bentobox/bentobox/api/panels/PanelItem.java index 1fe59e9ff..e347f200a 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/PanelItem.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/PanelItem.java @@ -29,7 +29,7 @@ public class PanelItem { private String name; private boolean glow; private ItemMeta meta; - private String playerHeadName; + private final String playerHeadName; private boolean invisible; public PanelItem(PanelItemBuilder builtItem) { diff --git a/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java b/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java index d9527a0f7..9ff12d57c 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java @@ -31,7 +31,8 @@ public class TabbedPanel extends Panel implements PanelListener { private static final String PROTECTION_PANEL = "protection.panel."; private static final long ITEMS_PER_PAGE = 36; private final TabbedPanelBuilder tpb; - private @NonNull BentoBox plugin = BentoBox.getInstance(); + private @NonNull + final BentoBox plugin = BentoBox.getInstance(); private int activeTab; private int activePage; private boolean closed; @@ -146,7 +147,7 @@ public class TabbedPanel extends Panel implements PanelListener { } } // Add any subsidiary icons - tab.getTabIcons().forEach(items::put); + items.putAll(tab.getTabIcons()); } private void setupFooter(TreeMap items) { diff --git a/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java b/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java new file mode 100644 index 000000000..279d51af3 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java @@ -0,0 +1,527 @@ +// +// Created by BONNe +// Copyright - 2021 +// + + +package world.bentobox.bentobox.api.panels; + + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import java.util.*; +import java.util.function.BiFunction; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; +import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder; +import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord; +import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord; +import world.bentobox.bentobox.api.user.User; + + +/** + * This class creates a new Panel from the template record. + * @author BONNe + * @since 1.17.3 + */ +public class TemplatedPanel extends Panel +{ + /** + * TemplatedPanel constructor class which generates functional panel. + * @param builder Builder that contains all information about the panel that must be generated. + */ + public TemplatedPanel(@NonNull TemplatedPanelBuilder builder) + { + this.user = builder.getUser(); + this.setWorld(builder.getWorld()); + this.setListener(builder.getListener()); + + this.panelTemplate = builder.getPanelTemplate(); + // Init type creators + this.typeCreators = new HashMap<>(builder.getObjectCreatorMap()); + this.typeIndex = new HashMap<>(builder.getObjectCreatorMap().size()); + this.typeSlotMap = new HashMap<>(builder.getObjectCreatorMap().size()); + + if (this.panelTemplate == null) + { + BentoBox.getInstance().logError("Cannot generate panel because template is not loaded."); + } + else + { + this.generatePanel(); + } + } + + + /** + * This method generates the panel from the template. + */ + private void generatePanel() + { + Map items = switch (this.panelTemplate.type()) + { + case INVENTORY -> this.populateInventoryPanel(); + case HOPPER -> this.populateHopperPanel(); + case DROPPER -> this.populateDropperPanel(); + }; + + super.makePanel(this.user.getTranslation(this.panelTemplate.title()), + items, + items.keySet().stream().max(Comparator.naturalOrder()).orElse(9), + this.user, + this.getListener().orElse(null), + this.panelTemplate.type()); + } + + + /** + * This method creates map with item indexes and their icons that will be added into + * Inventory Panel. + * @return Map that contains indexes linked to the correct panel item. + */ + @NonNull + private Map populateInventoryPanel() + { + // Init item array with the max available size. + PanelItem[][] itemArray = new PanelItem[6][9]; + + // Analyze the GUI button layout a bit. + for (int i = 0; i < this.panelTemplate.content().length; i++) + { + for (int k = 0; k < this.panelTemplate.content()[i].length; k++) + { + ItemTemplateRecord record = this.panelTemplate.content()[i][k]; + + if (record != null && record.dataMap().containsKey("type")) + { + String type = String.valueOf(record.dataMap().get("type")); + + int counter = this.typeSlotMap.computeIfAbsent(type, key -> 1); + this.typeSlotMap.put(type, counter + 1); + } + } + } + + // Make buttons for the GUI + for (int i = 0; i < this.panelTemplate.content().length; i++) + { + for (int k = 0; k < this.panelTemplate.content()[i].length; k++) + { + itemArray[i][k] = this.makeButton(this.panelTemplate.content()[i][k]); + } + } + + // After items are created, remove empty lines. + boolean[] showLine = this.panelTemplate.forcedRows(); + + for (int i = 0; i < this.panelTemplate.content().length; i++) + { + boolean emptyLine = true; + + for (int k = 0; emptyLine && k < this.panelTemplate.content()[i].length; k++) + { + emptyLine = itemArray[i][k] == null; + } + + // Do not generate fallback for "empty" lines. + showLine[i] = showLine[i] || !emptyLine; + } + + // Now fill the border. + if (this.panelTemplate.border() != null) + { + PanelItem template = this.makeTemplate(this.panelTemplate.border()); + + // Hard codded 6 + for (int i = 0; i < 6; i++) + { + if (i == 0 || i == 5) + { + // Fill first and last row completely with border. + for (int k = 0; k < 9; k++) + { + if (itemArray[i][k] == null) + { + itemArray[i][k] = template; + } + } + } + else + { + // Fill first and last element in row with border. + if (itemArray[i][0] == null) + { + itemArray[i][0] = template; + } + + if (itemArray[i][8] == null) + { + itemArray[i][8] = template; + } + } + } + + showLine[0] = true; + showLine[5] = true; + } + + // Now fill the background. + if (this.panelTemplate.background() != null) + { + PanelItem template = this.makeTemplate(this.panelTemplate.background()); + + for (int i = 0; i < 6; i++) + { + for (int k = 0; k < 9; k++) + { + if (itemArray[i][k] == null) + { + itemArray[i][k] = template; + } + } + } + } + + // Now place all panel items with their indexes into item map. + Map itemMap = new HashMap<>(6 * 9); + + int correctIndex = 0; + + for (int i = 0; i < itemArray.length; i++) + { + final boolean iterate = showLine[i]; + + for (int k = 0; iterate && k < itemArray[i].length; k++) + { + if (itemArray[i][k] != null) + { + itemMap.put(correctIndex, itemArray[i][k]); + } + + correctIndex++; + } + } + + return itemMap; + } + + + /** + * This method creates map with item indexes and their icons that will be added into + * hopper Panel. + * @return Map that contains indexes linked to the correct panel item. + */ + @NonNull + private Map populateHopperPanel() + { + // Init item array with the max available size. + PanelItem[] itemArray = new PanelItem[5]; + + // Analyze the template + for (int i = 0; i < 5; i++) + { + ItemTemplateRecord record = this.panelTemplate.content()[0][i]; + + if (record != null && record.dataMap().containsKey("type")) + { + String type = String.valueOf(record.dataMap().get("type")); + + int counter = this.typeSlotMap.computeIfAbsent(type, key -> 1); + this.typeSlotMap.put(type, counter + 1); + } + } + + // Make buttons + for (int i = 0; i < 5; i++) + { + itemArray[i] = this.makeButton(this.panelTemplate.content()[0][i]); + } + + // Now fill the background. + if (this.panelTemplate.background() != null) + { + PanelItem template = this.makeTemplate(this.panelTemplate.background()); + + for (int i = 0; i < 5; i++) + { + if (itemArray[i] == null) + { + itemArray[i] = template; + } + } + } + + // Now place all panel items with their indexes into item map. + Map itemMap = new HashMap<>(5); + + int correctIndex = 0; + + for (PanelItem panelItem : itemArray) + { + if (panelItem != null) + { + itemMap.put(correctIndex, panelItem); + } + + correctIndex++; + } + + return itemMap; + } + + + /** + * This method creates map with item indexes and their icons that will be added into + * dropper Panel. + * @return Map that contains indexes linked to the correct panel item. + */ + @NonNull + private Map populateDropperPanel() + { + // Analyze the template + for (int i = 0; i < 3; i++) + { + for (int k = 0; k < 3; k++) + { + ItemTemplateRecord record = this.panelTemplate.content()[i][k]; + + if (record != null && record.dataMap().containsKey("type")) + { + String type = String.valueOf(record.dataMap().get("type")); + + int counter = this.typeSlotMap.computeIfAbsent(type, key -> 1); + this.typeSlotMap.put(type, counter + 1); + } + } + } + + // Init item array with the max available size. + PanelItem[][] itemArray = new PanelItem[3][3]; + + // Make buttons + for (int i = 0; i < 3; i++) + { + for (int k = 0; k < 3; k++) + { + itemArray[i][k] = this.makeButton(this.panelTemplate.content()[i][k]); + } + } + + // Now fill the background. + if (this.panelTemplate.background() != null) + { + PanelItem template = this.makeTemplate(this.panelTemplate.background()); + + for (int i = 0; i < 3; i++) + { + for (int k = 0; k < 3; k++) + { + if (itemArray[i][k] == null) + { + itemArray[i][k] = template; + } + } + } + } + + // Init item map with the max available size. + Map itemMap = new HashMap<>(9); + + int correctIndex = 0; + + for (int i = 0; i < 3; i++) + { + for (int k = 0; k < 3; k++) + { + if (itemArray[i][k] != null) + { + itemMap.put(correctIndex, itemArray[i][k]); + } + + correctIndex++; + } + } + + return itemMap; + } + + + /** + * This method passes button creation from given record template. + * @param record Template of the button that must be created. + * @return PanelItem of the template, otherwise null. + */ + @Nullable + private PanelItem makeButton(@Nullable ItemTemplateRecord record) + { + if (record == null) + { + // Immediate exit if record is null. + return null; + } + + if (record.dataMap().containsKey("type")) + { + // If dataMap is not null, and it is not empty, then pass button to the object creator function. + + return this.makeAddonButton(record); + } + else + { + PanelItemBuilder itemBuilder = new PanelItemBuilder(); + + if (record.icon() != null) + { + itemBuilder.icon(record.icon().clone()); + } + + if (record.title() != null) + { + itemBuilder.name(this.user.getTranslation(record.title())); + } + + if (record.description() != null) + { + itemBuilder.description(this.user.getTranslation(record.description())); + } + + // If there are generic click handlers that could be added, then this is a place + // where to process them. + + // Click Handlers are managed by custom addon buttons. + return itemBuilder.build(); + } + } + + + /** + * This method passes button to the type creator, if that exists. + * @param record Template of the button that must be created. + * @return PanelItem of the button created by typeCreator, otherwise null. + */ + @Nullable + private PanelItem makeAddonButton(@NonNull ItemTemplateRecord record) + { + // Get object type. + String type = String.valueOf(record.dataMap().getOrDefault("type", "")); + + if (!this.typeCreators.containsKey(type)) + { + // There are no object with a given type. + return this.makeFallBack(record.fallback()); + } + + BiFunction buttonBuilder = this.typeCreators.get(type); + + // Get next slot index. + ItemSlot itemSlot = this.typeIndex.containsKey(type) ? + this.typeIndex.get(type) : + new ItemSlot(0, this.typeSlotMap); + this.typeIndex.put(type, itemSlot.nextItemSlot()); + + // Try to get next object. + PanelItem item = buttonBuilder.apply(record, itemSlot); + return item == null ? this.makeFallBack(record.fallback()) : item; + } + + + /** + * This method creates a fall back button for given record. + * @param record Record which fallback must be created. + * @return PanelItem if fallback was creates successfully, otherwise null. + */ + @Nullable + private PanelItem makeFallBack(@Nullable ItemTemplateRecord record) + { + return record == null ? null : this.makeButton(record.fallback()); + } + + + /** + * This method translates template record into a panel item. + * @param record Record that must be translated. + * @return PanelItem that contains all information from the record. + */ + private PanelItem makeTemplate(PanelTemplateRecord.TemplateItem record) + { + PanelItemBuilder itemBuilder = new PanelItemBuilder(); + + // Read icon only if it is not null. + if (record.icon() != null) + { + itemBuilder.icon(record.icon().clone()); + } + + // Read title only if it is not null. + if (record.title() != null) + { + itemBuilder.name(this.user.getTranslation(record.title())); + } + + // Read description only if it is not null. + if (record.description() != null) + { + itemBuilder.description(this.user.getTranslation(record.description())); + } + + // Click Handlers are managed by custom addon buttons. + return itemBuilder.build(); + } + + +// --------------------------------------------------------------------- +// Section: Classes +// --------------------------------------------------------------------- + + + /** + * This record contains current slot object and map that links types with a number of slots in + * panel with it. + * Some buttons need information about all types, like previous/next. + * @param slot Index of object in current panel. + * @param amountMap Map that links types with number of objects in panel. + */ + public record ItemSlot(int slot, Map amountMap) + { + /** + * This method returns new record object with iterative slot index. + * @return New ItemSlot object that has increased slot index by 1. + */ + ItemSlot nextItemSlot() + { + return new ItemSlot(this.slot() + 1, this.amountMap()); + } + } + + +// --------------------------------------------------------------------- +// Section: Variables +// --------------------------------------------------------------------- + + + /** + * The GUI template record. + */ + private final PanelTemplateRecord panelTemplate; + + /** + * The user who opens the GUI. + */ + private final User user; + + /** + * This map links custom types with their info object. + */ + private final Map> typeCreators; + + /** + * Stores the item slot information for each type. + */ + private final Map typeIndex; + + /** + * Stores the number of items with given type in whole panel. + */ + private final Map typeSlotMap; +} diff --git a/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelBuilder.java b/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelBuilder.java index 0aef22784..608a185c4 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelBuilder.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelBuilder.java @@ -3,13 +3,14 @@ package world.bentobox.bentobox.api.panels.builders; import java.util.SortedMap; import java.util.TreeMap; -import org.bukkit.ChatColor; import org.bukkit.World; import world.bentobox.bentobox.api.panels.Panel; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.PanelListener; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.util.Util; + /** * Builds panels @@ -26,7 +27,7 @@ public class PanelBuilder { private World world; public PanelBuilder name(String name) { - this.name = ChatColor.translateAlternateColorCodes('&', name); + this.name = Util.translateColorCodes(name); return this; } diff --git a/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java b/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java index cdcd7b65a..c3c10317b 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java @@ -5,13 +5,14 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler; +import world.bentobox.bentobox.util.Util; + public class PanelItemBuilder { private ItemStack icon = new ItemStack(Material.AIR); @@ -59,7 +60,7 @@ public class PanelItemBuilder { } public PanelItemBuilder name(@Nullable String name) { - this.name = name != null ? ChatColor.translateAlternateColorCodes('&', name) : null; + this.name = name != null ? Util.translateColorCodes(name) : null; return this; } diff --git a/src/main/java/world/bentobox/bentobox/api/panels/builders/TemplatedPanelBuilder.java b/src/main/java/world/bentobox/bentobox/api/panels/builders/TemplatedPanelBuilder.java new file mode 100644 index 000000000..fa8ea51e3 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/panels/builders/TemplatedPanelBuilder.java @@ -0,0 +1,203 @@ +// +// Created by BONNe +// Copyright - 2021 +// + + +package world.bentobox.bentobox.api.panels.builders; + + +import org.bukkit.World; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; + +import world.bentobox.bentobox.api.panels.PanelItem; +import world.bentobox.bentobox.api.panels.PanelListener; +import world.bentobox.bentobox.api.panels.TemplatedPanel; +import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord; +import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord; +import world.bentobox.bentobox.api.panels.reader.TemplateReader; +import world.bentobox.bentobox.api.user.User; + + +/** + * Builds {@link TemplatedPanel}'s + * @author BONNe + * @since 1.17.3 + */ +public class TemplatedPanelBuilder +{ +// --------------------------------------------------------------------- +// Section: Builder +// --------------------------------------------------------------------- + + /** + * Adds the template that must be loaded for Template panel builder. + * + * @param guiName the gui name + * @param dataFolder the data folder + * @return the template panel builder + */ + public TemplatedPanelBuilder template(String guiName, File dataFolder) + { + this.panelTemplate = TemplateReader.readTemplatePanel(guiName, dataFolder); + return this; + } + + + /** + * Adds the user for template panel builder. + * + * @param user the user + * @return the template panel builder + */ + public TemplatedPanelBuilder user(User user) + { + this.user = user; + return this; + } + + + /** + * Adds the world for template panel builder. + * + * @param world the world + * @return the template panel builder + */ + public TemplatedPanelBuilder world(World world) + { + this.world = world; + return this; + } + + + /** + * Adds the panel listener for template panel builder. + * + * @param listener the listener + * @return the template panel builder + */ + public TemplatedPanelBuilder listener(PanelListener listener) + { + this.listener = listener; + return this; + } + + + /** + * Registers new button type builder for template panel builder. + * + * @param type the type + * @param buttonCreator the button creator + * @return the template panel builder + */ + public TemplatedPanelBuilder registerTypeBuilder(String type, BiFunction buttonCreator) + { + this.objectCreatorMap.put(type, buttonCreator); + return this; + } + + + /** + * Build templated panel. + * + * @return the templated panel + */ + public TemplatedPanel build() + { + return new TemplatedPanel(this); + } + + +// --------------------------------------------------------------------- +// Section: Getters +// --------------------------------------------------------------------- + + + /** + * Gets panel template. + * + * @return the panel template + */ + public PanelTemplateRecord getPanelTemplate() + { + return this.panelTemplate; + } + + + /** + * Gets user. + * + * @return the user + */ + public User getUser() + { + return this.user; + } + + + /** + * Gets world. + * + * @return the world + */ + public World getWorld() + { + return this.world; + } + + + /** + * Gets listener. + * + * @return the listener + */ + public PanelListener getListener() + { + return this.listener; + } + + + /** + * Gets object creator map. + * + * @return the object creator map + */ + public Map> getObjectCreatorMap() + { + return this.objectCreatorMap; + } + + +// --------------------------------------------------------------------- +// Section: Variables +// --------------------------------------------------------------------- + + + /** + * The GUI template record. + */ + private PanelTemplateRecord panelTemplate; + + /** + * The user who opens the GUI. + */ + private User user; + + /** + * The world where GUI operates. + */ + private World world; + + /** + * Panel Listener + */ + private PanelListener listener; + + /** + * Map that links objects with their panel item creators. + */ + private final Map> objectCreatorMap = new HashMap<>(); +} diff --git a/src/main/java/world/bentobox/bentobox/api/panels/package-info.java b/src/main/java/world/bentobox/bentobox/api/panels/package-info.java new file mode 100644 index 000000000..3cc88a0c1 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/panels/package-info.java @@ -0,0 +1,21 @@ +/** + * API for GUI panel creation and usage. + * + *

+ * BentoBox provides an API that enables Addon developers to display a GUI. + * There is the basic Panel and the more advanced TabbedPanel. Both use Builders + * to make them. For examples, look at the Settings classes. + *

+ *

+ * Clicking on a panel item is handled by classes that implement the PanelListener interface. + * When a click is made, the listener is called with various parameters available. It is possible + * to have an overall listener for the whole panel and also individual listeners just for the + * icon that was clicked. + *

+ * The tabbed panel contains Tabs that are accessible via icons at the top of the panel. + *

+ * + * @author tastybento + * @since 1.7.0 + */ +package world.bentobox.bentobox.api.panels; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java new file mode 100644 index 000000000..fe8e39974 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java @@ -0,0 +1,89 @@ +// +// Created by BONNe +// Copyright - 2021 +// + + +package world.bentobox.bentobox.api.panels.reader; + + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * This Record contains all necessary information about Item Template that can be used to craft panel item. + * + * @param icon ItemStack of the Item + * @param title Title of the item + * @param description Lore message of the item + * @param actions List of Actions for a button + * @param dataMap DataMap that links additional objects for a button. + * @param fallback FallBack item if current one is not possible to generate. + * + * @since 1.17.3 + */ +public record ItemTemplateRecord(@Nullable ItemStack icon, + @Nullable String title, + @Nullable String description, + @NonNull List actions, + @NonNull Map dataMap, + @Nullable ItemTemplateRecord fallback) +{ + /** + * Instantiates a new Item template record without actions and data map. + * + * @param icon the icon + * @param title the title + * @param description the description + * @param fallback the fallback + */ + public ItemTemplateRecord(ItemStack icon, String title, String description, ItemTemplateRecord fallback) + { + this(icon, title, description, new ArrayList<>(6), new HashMap<>(0), fallback); + } + + + /** + * This method adds given object associated with key into data map. + * @param key Key value of object. + * @param data Data that is associated with a key. + */ + public void addData(String key, Object data) + { + this.dataMap.put(key, data); + } + + + /** + * Add action to the actions list. + * + * @param actionData the action data + */ + public void addAction(ActionRecords actionData) + { + this.actions.add(actionData); + } + + + // --------------------------------------------------------------------- + // Section: Classes + // --------------------------------------------------------------------- + + + /** + * The Action Records holds data about each action. + * + * @param clickType the click type + * @param actionType the string that represents action type + * @param content the content of the action + * @param tooltip the tooltip of action + */ + public record ActionRecords(ClickType clickType, String actionType, String content, String tooltip) {} +} diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java new file mode 100644 index 000000000..f2c48dbf5 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java @@ -0,0 +1,79 @@ +// +// Created by BONNe +// Copyright - 2021 +// + + +package world.bentobox.bentobox.api.panels.reader; + + +import org.bukkit.inventory.ItemStack; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import world.bentobox.bentobox.api.panels.Panel; + + +/** + * This is template object for the panel reader. It contains data that can exist in the panel. + * PanelBuilder will use this to build panel. + * + * @param type the type of GUI + * @param title the title of GUI + * @param border the border block for GUI + * @param background the background block for GUI. + * @param forcedRows the array of boolean that indicate which rows must be force loaded. + * @param content The 2D array of ItemTemplateRecords + * + * @since 1.17.3 + */ +public record PanelTemplateRecord(Panel.Type type, + @Nullable String title, + @Nullable TemplateItem border, + @Nullable TemplateItem background, + boolean[] forcedRows, + @NonNull ItemTemplateRecord[][] content) +{ + /** + * Instantiates a new Panel template record with empty content. + * + * @param type the type + * @param title the title + * @param border the border + * @param background the background + * @param forcedRows the forced rows array + */ + public PanelTemplateRecord(Panel.Type type, String title, TemplateItem border, TemplateItem background, boolean[] forcedRows) + { + this(type, title, border, background, forcedRows, new ItemTemplateRecord[6][9]); + } + + + /** + * This method adds give item template record in given slot. + * @param rowIndex row index of content array + * @param columnIndex column index of content array. + * @param panelItemTemplate item template record that must be added. + */ + public void addButtonTemplate(int rowIndex, int columnIndex, ItemTemplateRecord panelItemTemplate) + { + this.content[rowIndex][columnIndex] = panelItemTemplate; + } + + + // --------------------------------------------------------------------- + // Section: Classes + // --------------------------------------------------------------------- + + + /** + * This record contains info about border and background item. + */ + public record TemplateItem(ItemStack icon, String title, String description) + { + public TemplateItem(ItemStack icon) + { + this(icon, null, null); + } + } +} diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java new file mode 100644 index 000000000..2213cad90 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java @@ -0,0 +1,364 @@ +// +// Created by BONNe +// Copyright - 2021 +// + + +package world.bentobox.bentobox.api.panels.reader; + + +import com.google.common.base.Enums; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.inventory.ClickType; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import world.bentobox.bentobox.api.panels.Panel; +import world.bentobox.bentobox.util.ItemParser; + + +/** + * This class manages Template file reading, creating PanelTemplateRecord object and storing it internally. + * This class just reads and returns given panel template. It does not create a functional panel. + * + * @since 1.17.3 + */ +public class TemplateReader +{ + /** + * Read template panel panel template record. + * + * @param panelName the panel name + * @param panelLocation the panel location directory + * @return the panel template record + */ + public static PanelTemplateRecord readTemplatePanel(@NonNull String panelName, @NonNull File panelLocation) + { + if (!panelLocation.exists()) + { + // Return null because folder does not exist. + return null; + } + + File file = new File(panelLocation, panelName.endsWith(".yml") ? panelName : panelName + ".yml"); + + if (!file.exists()) + { + // Return as file does not exist. + return null; + } + + // Check if panel is already crafted. + if (TemplateReader.loadedPanels.containsKey(file.getAbsolutePath())) + { + return TemplateReader.loadedPanels.get(file.getAbsolutePath()); + } + + PanelTemplateRecord record; + + try + { + // Load config + YamlConfiguration config = new YamlConfiguration(); + config.load(file); + // Read panel + record = readPanelTemplate(config.getConfigurationSection(panelName)); + // Put panel into memory + TemplateReader.loadedPanels.put(file.getAbsolutePath(), record); + } + catch (IOException | InvalidConfigurationException e) + { + record = null; + } + + return record; + } + + + /** + * This method reads panel template from given configuration section. + * @param configurationSection Section that contains panel template data. + * @return Panel Template. + */ + private static PanelTemplateRecord readPanelTemplate(@Nullable ConfigurationSection configurationSection) + { + if (configurationSection == null) + { + // No data to return. + return null; + } + + String title = configurationSection.getString("title"); + Panel.Type type = + Enums.getIfPresent(Panel.Type.class, configurationSection.getString("type", "INVENTORY")). + or(Panel.Type.INVENTORY); + + PanelTemplateRecord.TemplateItem borderItem = null; + + // Read Border Icon. + if (configurationSection.isConfigurationSection("border")) + { + // Process border icon if it contains more options. + ConfigurationSection borderSection = configurationSection.getConfigurationSection("border"); + + if (borderSection != null) + { + borderItem = new PanelTemplateRecord.TemplateItem( + ItemParser.parse((borderSection.getString("icon", Material.AIR.name()))), + borderSection.getString("title", null), + borderSection.getString("description", null)); + } + } + else if (configurationSection.isString("border")) + { + // Process border icon if it contains only icon. + + borderItem = new PanelTemplateRecord.TemplateItem( + ItemParser.parse((configurationSection.getString("border", Material.AIR.name())))); + } + + PanelTemplateRecord.TemplateItem backgroundItem = null; + + // Read Background block + if (configurationSection.isConfigurationSection("background")) + { + // Process border icon if it contains more options. + ConfigurationSection backgroundSection = configurationSection.getConfigurationSection("background"); + + if (backgroundSection != null) + { + backgroundItem = new PanelTemplateRecord.TemplateItem( + ItemParser.parse((backgroundSection.getString("icon", Material.AIR.name()))), + backgroundSection.getString("title", null), + backgroundSection.getString("description", null)); + } + } + else if (configurationSection.isString("background")) + { + // Process background icon if it contains only icon. + + backgroundItem = new PanelTemplateRecord.TemplateItem( + ItemParser.parse((configurationSection.getString("background", Material.AIR.name())))); + } + + // Read reusable + Map panelItemDataMap = new HashMap<>(); + ConfigurationSection reusable = configurationSection.getConfigurationSection("reusable"); + + if (reusable != null) + { + // Add all reusables to the local storage. + reusable.getKeys(false).forEach(key -> + readPanelItemTemplate(reusable.getConfigurationSection(key), key, panelItemDataMap)); + } + + // Read content + boolean[] forcedRows = readForcedRows(configurationSection); + + // Create template record. + PanelTemplateRecord template = new PanelTemplateRecord(type, title, borderItem, backgroundItem, forcedRows); + + // Read content + ConfigurationSection content = configurationSection.getConfigurationSection("content"); + + if (content == null) + { + // Return empty template. + return template; + } + + for (int rowIndex = 0; rowIndex < 6; rowIndex++) + { + // Read each line. + if (content.isConfigurationSection(String.valueOf(rowIndex + 1))) + { + ConfigurationSection line = content.getConfigurationSection(String.valueOf(rowIndex + 1)); + + if (line != null) + { + // Populate existing lines with items. + for (int columnIndex = 0; columnIndex < 9; columnIndex++) + { + if (line.isConfigurationSection(String.valueOf(columnIndex + 1))) + { + // If it contains a section, then build a new button template from it. + template.addButtonTemplate(rowIndex, + columnIndex, + readPanelItemTemplate(line.getConfigurationSection(String.valueOf(columnIndex + 1)))); + } + else if (line.isString(String.valueOf(columnIndex + 1))) + { + // If it contains just a single word, assume it is a reusable. + template.addButtonTemplate(rowIndex, + columnIndex, + panelItemDataMap.get(line.getString(String.valueOf(columnIndex + 1)))); + } + } + } + } + } + + // Garbage collector. + panelItemDataMap.clear(); + + return template; + } + + + /** + * This method reads force shown rows that must be always displayed. + * @param section Configuration section that contains force-shown path. + * @return boolean array that contains which lines are force loaded. + */ + private static boolean[] readForcedRows(@Nullable ConfigurationSection section) + { + boolean[] forceShow = new boolean[6]; + + if (section != null && section.contains("force-shown")) + { + if (section.isInt("force-shown")) + { + int value = section.getInt("force-shown"); + + if (value > 0 && value < 7) + { + forceShow[value-1] = true; + } + } + else if (section.isList("force-shown")) + { + section.getIntegerList("force-shown").forEach(number -> { + if (number > 0 && number < 7) + { + forceShow[number-1] = true; + } + }); + } + } + + return forceShow; + } + + + /** + * This method creates PanelItemTemplate from a given configuration section. + * @param section Section that should contain all information about the panel item template. + * @return PanelItemTemplate that should represent button from a section. + */ + @Nullable + private static ItemTemplateRecord readPanelItemTemplate(@Nullable ConfigurationSection section) + { + return readPanelItemTemplate(section, null, null); + } + + + + /** + * This method creates PanelItemTemplate from a given configuration section. + * @param section Section that should contain all information about the panel item template. + * @return PanelItemTemplate that should represent button from a section. + */ + @Nullable + private static ItemTemplateRecord readPanelItemTemplate(@Nullable ConfigurationSection section, + String itemKey, + Map reusableItemMap) + { + if (section == null) + { + // No section, no item. + return null; + } + + ItemTemplateRecord fallback; + + if (section.isConfigurationSection("fallback")) + { + fallback = readPanelItemTemplate(section.getConfigurationSection("fallback")); + } + else if (section.isString("fallback") && reusableItemMap != null) + { + fallback = reusableItemMap.get(section.getString("fallback")); + } + else + { + fallback = null; + } + + // Create Item Record + ItemTemplateRecord itemRecord = new ItemTemplateRecord(ItemParser.parse(section.getString("icon")), + section.getString("title", null), + section.getString("description", null), + fallback); + + // Read data + if (section.isConfigurationSection("data")) + { + ConfigurationSection dataSection = section.getConfigurationSection("data"); + + if (dataSection != null) + { + dataSection.getKeys(false).forEach(key -> itemRecord.addData(key, dataSection.get(key))); + } + } + + // Read Click data + if (section.isConfigurationSection("actions")) + { + ConfigurationSection actionSection = section.getConfigurationSection("actions"); + + if (actionSection != null) + { + actionSection.getKeys(false).forEach(actionKey -> { + ClickType clickType = Enums.getIfPresent(ClickType.class, actionKey.toUpperCase()).orNull(); + + if (clickType != null) + { + ConfigurationSection actionDataSection = actionSection.getConfigurationSection(actionKey); + + if (actionDataSection != null) + { + ItemTemplateRecord.ActionRecords actionData = + new ItemTemplateRecord.ActionRecords(clickType, + actionDataSection.getString("type"), + actionDataSection.getString("content"), + actionDataSection.getString("tooltip")); + + itemRecord.addAction(actionData); + } + } + }); + } + } + + // Add item to the map + if (reusableItemMap != null && itemKey != null) + { + reusableItemMap.put(itemKey, itemRecord); + } + + return itemRecord; + } + + + /** + * This method clears loaded panels from the cache. + */ + public static void clearPanels() + { + loadedPanels.clear(); + } + + + /** + * This map contains already read panels and their location. + * This improves performance for GUI opening, with a some memory usage. + */ + private static final Map loadedPanels = new HashMap<>(); +} diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/package-info.java b/src/main/java/world/bentobox/bentobox/api/placeholders/package-info.java new file mode 100644 index 000000000..3f0426d18 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/package-info.java @@ -0,0 +1,7 @@ +/** + * API for placeholder replacement. + * + * @since 1.5.0 + * @author Poslovitch + */ +package world.bentobox.bentobox.api.placeholders; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java index c066261c9..d428b5708 100644 --- a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java @@ -3,7 +3,7 @@ package world.bentobox.bentobox.api.placeholders.placeholderapi; import world.bentobox.bentobox.api.addons.Addon; public class AddonPlaceholderExpansion extends BasicPlaceholderExpansion { - private Addon addon; + private final Addon addon; public AddonPlaceholderExpansion(Addon addon) { this.addon = addon; diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java index 40b67a02a..e8a8a91f3 100644 --- a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java @@ -16,7 +16,7 @@ import world.bentobox.bentobox.api.user.User; */ abstract class BasicPlaceholderExpansion extends PlaceholderExpansion { @NonNull - private Map<@NonNull String, @NonNull PlaceholderReplacer> placeholders; + private final Map<@NonNull String, @NonNull PlaceholderReplacer> placeholders; BasicPlaceholderExpansion() { super(); diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java index e2acd7805..da290c84e 100644 --- a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java @@ -3,7 +3,7 @@ package world.bentobox.bentobox.api.placeholders.placeholderapi; import world.bentobox.bentobox.BentoBox; public class BentoBoxPlaceholderExpansion extends BasicPlaceholderExpansion { - private BentoBox plugin; + private final BentoBox plugin; public BentoBoxPlaceholderExpansion(BentoBox plugin) { super(); diff --git a/src/main/java/world/bentobox/bentobox/api/user/Notifier.java b/src/main/java/world/bentobox/bentobox/api/user/Notifier.java index c6027af03..e75adff03 100644 --- a/src/main/java/world/bentobox/bentobox/api/user/Notifier.java +++ b/src/main/java/world/bentobox/bentobox/api/user/Notifier.java @@ -9,7 +9,7 @@ import com.google.common.cache.LoadingCache; /** * Utilities class that helps to avoid spamming the User with potential repeated messages - * @author Poslovitch + * @author Poslovitch, tastybento */ public class Notifier { @@ -18,17 +18,19 @@ public class Notifier { */ private static final int NOTIFICATION_DELAY = 4; + private record Notification(String message, long time) {} + private final LoadingCache notificationCache = CacheBuilder.newBuilder() .expireAfterAccess(NOTIFICATION_DELAY, TimeUnit.SECONDS) .maximumSize(500) .build( - new CacheLoader() { + new CacheLoader<>() { @Override public Notification load(User user) { return new Notification(null, 0); } } - ); + ); /** * Sends message to a user only if the message hasn't been sent recently @@ -41,7 +43,7 @@ public class Notifier { Notification lastNotification = notificationCache.get(user); long now = System.currentTimeMillis(); - if (now >= lastNotification.getTime() + (NOTIFICATION_DELAY * 1000) || !message.equals(lastNotification.getMessage())) { + if (now >= lastNotification.time() + (NOTIFICATION_DELAY * 1000) || !message.equals(lastNotification.message())) { notificationCache.put(user, new Notification(message, now)); user.sendRawMessage(message); return true; @@ -52,21 +54,4 @@ public class Notifier { } } - private class Notification { - private final String message; - private final long time; - - private Notification(String message, long time) { - this.message = message; - this.time = time; - } - - public String getMessage() { - return message; - } - - public long getTime() { - return time; - } - } } diff --git a/src/main/java/world/bentobox/bentobox/api/user/User.java b/src/main/java/world/bentobox/bentobox/api/user/User.java index 9fa33b437..b032a2988 100644 --- a/src/main/java/world/bentobox/bentobox/api/user/User.java +++ b/src/main/java/world/bentobox/bentobox/api/user/User.java @@ -47,7 +47,7 @@ import world.bentobox.bentobox.util.Util; */ public class User implements MetaDataAble { - private static Map users = new HashMap<>(); + private static final Map users = new HashMap<>(); /** * Clears all users from the user list @@ -136,7 +136,7 @@ public class User implements MetaDataAble { private static BentoBox plugin = BentoBox.getInstance(); @Nullable - private Player player; + private final Player player; private OfflinePlayer offlinePlayer; private final UUID playerUUID; @Nullable @@ -410,7 +410,7 @@ public class User implements MetaDataAble { translation = plugin.getPlaceholdersManager().replacePlaceholders(player, translation); } - return Util.stripSpaceAfterColorCodes(ChatColor.translateAlternateColorCodes('&', translation)); + return Util.translateColorCodes(translation); } } @@ -618,10 +618,9 @@ public class User implements MetaDataAble { if (obj == null) { return false; } - if (!(obj instanceof User)) { + if (!(obj instanceof User other)) { return false; } - User other = (User) obj; if (playerUUID == null) { return other.playerUUID == null; } else return playerUUID.equals(other.playerUUID); diff --git a/src/main/java/world/bentobox/bentobox/api/user/package-info.java b/src/main/java/world/bentobox/bentobox/api/user/package-info.java new file mode 100644 index 000000000..f7218e606 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/user/package-info.java @@ -0,0 +1,18 @@ +/** + * API for BentoBox Users + * + *

+ * BentoBox has extended the Bukkit Player class to become a User with the primary reason + * to enable localized messaging. Apart from that a User can be an OfflinePlayer, a Player, + * or even the Console. Users are used throughout the BentoBox code base, e.g., for commands + * instead of Players. It is possible to get a Player from a User if the User is a player. + *

+ *

+ * Notifier is a special kind of messaging class that prevents spamming of messages to a + * user in chat. It is useful for cases when the same message may be generated many times, e.g., in + * a protection scenario. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.api.user; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java index f02173dd5..034cdf919 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java @@ -63,10 +63,10 @@ public class BlueprintClipboard { private boolean copying; private int index; private int lastPercentage; - private Map> bpEntities = new LinkedHashMap<>(); - private Map bpAttachable = new LinkedHashMap<>(); - private Map bpBlocks = new LinkedHashMap<>(); - private BentoBox plugin = BentoBox.getInstance(); + private final Map> bpEntities = new LinkedHashMap<>(); + private final Map bpAttachable = new LinkedHashMap<>(); + private final Map bpBlocks = new LinkedHashMap<>(); + private final BentoBox plugin = BentoBox.getInstance(); /** * Create a clipboard for blueprint @@ -190,48 +190,7 @@ public class BlueprintClipboard { Vector pos = new Vector(x, y, z); // Set entities - List bpEnts = new ArrayList<>(); - for (LivingEntity entity: entities) { - BlueprintEntity bpe = new BlueprintEntity(); - bpe.setType(entity.getType()); - bpe.setCustomName(entity.getCustomName()); - if (entity instanceof Villager) { - setVillager(entity, bpe); - } - if (entity instanceof Colorable) { - Colorable c = (Colorable)entity; - if (c.getColor() != null) { - bpe.setColor(c.getColor()); - } - } - if (entity instanceof Tameable) { - bpe.setTamed(((Tameable)entity).isTamed()); - } - if (entity instanceof ChestedHorse) { - bpe.setChest(((ChestedHorse)entity).isCarryingChest()); - } - // Only set if child. Most animals are adults - if (entity instanceof Ageable && !((Ageable)entity).isAdult()) { - bpe.setAdult(false); - } - if (entity instanceof AbstractHorse) { - AbstractHorse horse = (AbstractHorse)entity; - bpe.setDomestication(horse.getDomestication()); - bpe.setInventory(new HashMap<>()); - for (int i = 0; i < horse.getInventory().getSize(); i++) { - ItemStack item = horse.getInventory().getItem(i); - if (item != null) { - bpe.getInventory().put(i, item); - } - } - } - - if (entity instanceof Horse) { - Horse horse = (Horse)entity; - bpe.setStyle(horse.getStyle()); - } - bpEnts.add(bpe); - } + List bpEnts = setEntities(entities); // Store if (!bpEnts.isEmpty()) { bpEntities.put(pos, bpEnts); @@ -242,22 +201,31 @@ public class BlueprintClipboard { return true; } + + BlueprintBlock b = bluePrintBlock(pos, block); + if (b != null) { + this.bpBlocks.put(pos, b); + } + return true; + } + + private BlueprintBlock bluePrintBlock(Vector pos, Block block) { // Block state BlockState blockState = block.getState(); BlueprintBlock b = new BlueprintBlock(block.getBlockData().getAsString()); // Biome b.setBiome(block.getBiome()); // Signs - if (blockState instanceof Sign) { - Sign sign = (Sign)blockState; + if (blockState instanceof Sign sign) { b.setSignLines(Arrays.asList(sign.getLines())); + b.setGlowingText(sign.isGlowingText()); } // Set block data if (blockState.getData() instanceof Attachable) { // Placeholder for attachment bpBlocks.put(pos, new BlueprintBlock("minecraft:air")); bpAttachable.put(pos, b); - return true; + return null; } if (block.getType().equals(Material.BEDROCK)) { @@ -272,9 +240,8 @@ public class BlueprintClipboard { } // Chests - if (blockState instanceof InventoryHolder) { + if (blockState instanceof InventoryHolder ih) { b.setInventory(new HashMap<>()); - InventoryHolder ih = (InventoryHolder)blockState; for (int i = 0; i < ih.getInventory().getSize(); i++) { ItemStack item = ih.getInventory().getItem(i); if (item != null) { @@ -283,17 +250,8 @@ public class BlueprintClipboard { } } - if (blockState instanceof CreatureSpawner) { - CreatureSpawner spawner = (CreatureSpawner)blockState; - BlueprintCreatureSpawner cs = new BlueprintCreatureSpawner(); - cs.setSpawnedType(spawner.getSpawnedType()); - cs.setDelay(spawner.getDelay()); - cs.setMaxNearbyEntities(spawner.getMaxNearbyEntities()); - cs.setMaxSpawnDelay(spawner.getMaxSpawnDelay()); - cs.setMinSpawnDelay(spawner.getMinSpawnDelay()); - cs.setRequiredPlayerRange(spawner.getRequiredPlayerRange()); - cs.setSpawnRange(spawner.getSpawnRange()); - b.setCreatureSpawner(cs); + if (blockState instanceof CreatureSpawner spawner) { + b.setCreatureSpawner(getSpawner(spawner)); } // Banners @@ -301,8 +259,62 @@ public class BlueprintClipboard { b.setBannerPatterns(((Banner) blockState).getPatterns()); } - this.bpBlocks.put(pos, b); - return true; + return b; + } + + private BlueprintCreatureSpawner getSpawner(CreatureSpawner spawner) { + BlueprintCreatureSpawner cs = new BlueprintCreatureSpawner(); + cs.setSpawnedType(spawner.getSpawnedType()); + cs.setDelay(spawner.getDelay()); + cs.setMaxNearbyEntities(spawner.getMaxNearbyEntities()); + cs.setMaxSpawnDelay(spawner.getMaxSpawnDelay()); + cs.setMinSpawnDelay(spawner.getMinSpawnDelay()); + cs.setRequiredPlayerRange(spawner.getRequiredPlayerRange()); + cs.setSpawnRange(spawner.getSpawnRange()); + return cs; + } + + private List setEntities(Collection entities) { + List bpEnts = new ArrayList<>(); + for (LivingEntity entity: entities) { + BlueprintEntity bpe = new BlueprintEntity(); + bpe.setType(entity.getType()); + bpe.setCustomName(entity.getCustomName()); + if (entity instanceof Villager) { + setVillager(entity, bpe); + } + if (entity instanceof Colorable c) { + if (c.getColor() != null) { + bpe.setColor(c.getColor()); + } + } + if (entity instanceof Tameable) { + bpe.setTamed(((Tameable)entity).isTamed()); + } + if (entity instanceof ChestedHorse) { + bpe.setChest(((ChestedHorse)entity).isCarryingChest()); + } + // Only set if child. Most animals are adults + if (entity instanceof Ageable && !((Ageable)entity).isAdult()) { + bpe.setAdult(false); + } + if (entity instanceof AbstractHorse horse) { + bpe.setDomestication(horse.getDomestication()); + bpe.setInventory(new HashMap<>()); + for (int i = 0; i < horse.getInventory().getSize(); i++) { + ItemStack item = horse.getInventory().getItem(i); + if (item != null) { + bpe.getInventory().put(i, item); + } + } + } + + if (entity instanceof Horse horse) { + bpe.setStyle(horse.getStyle()); + } + bpEnts.add(bpe); + } + return bpEnts; } /** diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java index d6f754863..cde794edd 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java @@ -13,7 +13,6 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -73,7 +72,7 @@ public class BlueprintPaster { private static final Map BLOCK_CONVERSION = ImmutableMap.of("sign", "oak_sign", "wall_sign", "oak_wall_sign"); - private BentoBox plugin; + private final BentoBox plugin; // The minimum block position (x,y,z) private Location pos1; // The maximum block position (x,y,z) @@ -86,19 +85,19 @@ public class BlueprintPaster { * The Blueprint to paste. */ @NonNull - private Blueprint blueprint; + private final Blueprint blueprint; /** * The Location to paste to. */ @NonNull - private Location location; + private final Location location; /** * Island related to this paste, may be null. */ @Nullable - private Island island; + private final Island island; /** * Paste a clipboard to a location and run task @@ -291,37 +290,39 @@ public class BlueprintPaster { // Get the block state BlockState bs = block.getState(); // Signs - if (bs instanceof org.bukkit.block.Sign) { - writeSign(block, bpBlock.getSignLines()); + if (bs instanceof org.bukkit.block.Sign sign) { + writeSign(block, bpBlock.getSignLines(), bpBlock.isGlowingText()); } // Chests, in general if (bs instanceof InventoryHolder) { Inventory ih = ((InventoryHolder)bs).getInventory(); - // Double chests are pasted as two blocks so inventory is filled twice. This code stops over filling for the first block. + // Double chests are pasted as two blocks so inventory is filled twice. + // This code stops over-filling for the first block. bpBlock.getInventory().forEach(ih::setItem); } // Mob spawners - if (bs instanceof CreatureSpawner) { - CreatureSpawner spawner = ((CreatureSpawner) bs); - BlueprintCreatureSpawner s = bpBlock.getCreatureSpawner(); - spawner.setSpawnedType(s.getSpawnedType()); - spawner.setMaxNearbyEntities(s.getMaxNearbyEntities()); - spawner.setMaxSpawnDelay(s.getMaxSpawnDelay()); - spawner.setMinSpawnDelay(s.getMinSpawnDelay()); - spawner.setDelay(s.getDelay()); - spawner.setRequiredPlayerRange(s.getRequiredPlayerRange()); - spawner.setSpawnRange(s.getSpawnRange()); - bs.update(true, false); + if (bs instanceof CreatureSpawner spawner) { + setSpawner(spawner, bpBlock.getCreatureSpawner()); } // Banners - if (bs instanceof Banner && bpBlock.getBannerPatterns() != null) { - Banner banner = (Banner) bs; + if (bs instanceof Banner banner && bpBlock.getBannerPatterns() != null) { bpBlock.getBannerPatterns().removeIf(Objects::isNull); banner.setPatterns(bpBlock.getBannerPatterns()); banner.update(true, false); } } + private void setSpawner(CreatureSpawner spawner, BlueprintCreatureSpawner s) { + spawner.setSpawnedType(s.getSpawnedType()); + spawner.setMaxNearbyEntities(s.getMaxNearbyEntities()); + spawner.setMaxSpawnDelay(s.getMaxSpawnDelay()); + spawner.setMinSpawnDelay(s.getMinSpawnDelay()); + spawner.setDelay(s.getDelay()); + spawner.setRequiredPlayerRange(s.getRequiredPlayerRange()); + spawner.setSpawnRange(s.getSpawnRange()); + spawner.update(true, false); + } + /** * Sets any entity that is in this location * @param location - location @@ -386,7 +387,7 @@ public class BlueprintPaster { } } - private void writeSign(final Block block, final List lines) { + private void writeSign(final Block block, final List lines, boolean glow) { BlockFace bf; if (block.getType().name().contains("WALL_SIGN")) { WallSign wallSign = (WallSign)block.getBlockData(); @@ -416,7 +417,7 @@ public class BlueprintPaster { // Get the addon that is operating in this world String addonName = plugin.getIWM().getAddon(island.getWorld()).map(addon -> addon.getDescription().getName().toLowerCase(Locale.ENGLISH)).orElse(""); for (int i = 0; i < 4; i++) { - s.setLine(i, ChatColor.translateAlternateColorCodes('&', plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()), + s.setLine(i, Util.translateColorCodes(plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()), addonName + ".sign.line" + i,"").replace(TextVariables.NAME, name))); } } else { @@ -425,6 +426,7 @@ public class BlueprintPaster { s.setLine(i, lines.get(i)); } } + s.setGlowingText(glow); // Update the sign s.update(); } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java index c56d0a3d6..4493d9c47 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java @@ -3,7 +3,6 @@ package world.bentobox.bentobox.blueprints.conversation; import java.util.ArrayList; import java.util.List; -import org.bukkit.ChatColor; import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.Prompt; import org.bukkit.conversations.StringPrompt; @@ -13,6 +12,8 @@ import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; +import world.bentobox.bentobox.util.Util; + /** * Collects a description @@ -22,8 +23,8 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; public class DescriptionPrompt extends StringPrompt { private static final String DESCRIPTION = "description"; - private GameModeAddon addon; - private BlueprintBundle bb; + private final GameModeAddon addon; + private final BlueprintBundle bb; public DescriptionPrompt(GameModeAddon addon, BlueprintBundle bb) { this.addon = addon; @@ -57,7 +58,7 @@ public class DescriptionPrompt extends StringPrompt { if (context.getSessionData(DESCRIPTION) != null) { desc = ((List) context.getSessionData(DESCRIPTION)); } - desc.add(ChatColor.translateAlternateColorCodes('&', input)); + desc.add(Util.translateColorCodes(input)); context.setSessionData(DESCRIPTION, desc); return this; } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java index 1a69cd089..b28546a9c 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java @@ -15,8 +15,8 @@ import world.bentobox.bentobox.panels.BlueprintManagementPanel; public class DescriptionSuccessPrompt extends MessagePrompt { - private GameModeAddon addon; - private BlueprintBundle bb; + private final GameModeAddon addon; + private final BlueprintBundle bb; /** * @param addon game mode addon diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java index db637fd13..5dd8a6294 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java @@ -15,12 +15,14 @@ import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.blueprints.Blueprint; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; import world.bentobox.bentobox.managers.BlueprintsManager; +import world.bentobox.bentobox.util.Util; + public class NamePrompt extends StringPrompt { - private GameModeAddon addon; + private final GameModeAddon addon; @Nullable - private BlueprintBundle bb; + private final BlueprintBundle bb; @Nullable private Blueprint bp; @@ -45,7 +47,7 @@ public class NamePrompt extends StringPrompt { public Prompt acceptInput(ConversationContext context, String input) { User user = User.getInstance((Player)context.getForWhom()); // Convert color codes - input = ChatColor.translateAlternateColorCodes('&', input); + input = Util.translateColorCodes(input); if (ChatColor.stripColor(input).length() > 32) { context.getForWhom().sendRawMessage("Too long"); return this; diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java index ad9422f32..8fe5d8c51 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java @@ -17,9 +17,9 @@ import world.bentobox.bentobox.panels.BlueprintManagementPanel; public class NameSuccessPrompt extends MessagePrompt { - private GameModeAddon addon; + private final GameModeAddon addon; private BlueprintBundle bb; - private Blueprint bp; + private final Blueprint bp; /** * Handles the name processing @@ -42,7 +42,6 @@ public class NameSuccessPrompt extends MessagePrompt { if (bp != null) { BentoBox.getInstance().getBlueprintsManager().renameBlueprint(addon, bp, name); new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openBB(bb); - return user.getTranslation("commands.admin.blueprint.management.description.success"); } else { // Blueprint Bundle if (bb == null) { @@ -61,8 +60,8 @@ public class NameSuccessPrompt extends MessagePrompt { new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openPanel(); // Set the name // if successfully - return user.getTranslation("commands.admin.blueprint.management.description.success"); } + return user.getTranslation("commands.admin.blueprint.management.description.success"); } @Override diff --git a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java index 4aa327bdf..7b2584087 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java @@ -34,6 +34,8 @@ public class BlueprintBlock { */ @Expose private List bannerPatterns; + @Expose + private boolean glowingText; public BlueprintBlock(String blockData) { this.blockData = blockData; @@ -124,4 +126,20 @@ public class BlueprintBlock { public void setBiome(Biome biome) { this.biome = biome; } + + /** + * @return the glowingText + */ + public boolean isGlowingText() { + return glowingText; + } + + /** + * @param glowingText the glowingText to set + */ + public void setGlowingText(boolean glowingText) { + this.glowingText = glowingText; + } + + } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java index a99e972d9..e173f6b86 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java @@ -75,8 +75,7 @@ public class BlueprintEntity { ((Ageable)e).setBaby(); } } - if (e instanceof AbstractHorse) { - AbstractHorse horse = (AbstractHorse)e; + if (e instanceof AbstractHorse horse) { if (domestication != null) horse.setDomestication(domestication); if (inventory != null) { inventory.forEach(horse.getInventory()::setItem); diff --git a/src/main/java/world/bentobox/bentobox/blueprints/package-info.java b/src/main/java/world/bentobox/bentobox/blueprints/package-info.java new file mode 100644 index 000000000..36d90d13a --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/blueprints/package-info.java @@ -0,0 +1,10 @@ +/** + * This package contains non-API classes that handle Blueprints. + * + * Blueprints are BentoBox's version of schematics, but contain + * additional useful info. + * + * @author tastybento + * + */ +package world.bentobox.bentobox.blueprints; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java index 2cc438013..602827df5 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardFormat.java @@ -49,12 +49,12 @@ public class BlueprintClipboardFormat implements ClipboardFormat { } @Override - public ClipboardReader getReader(InputStream inputStream) throws IOException { + public ClipboardReader getReader(InputStream inputStream) { return new BlueprintClipboardReader(inputStream); } @Override - public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + public ClipboardWriter getWriter(OutputStream outputStream) { return new BlueprintClipboardWriter(outputStream); } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java index c944294ee..c0701ba1f 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardReader.java @@ -1,6 +1,5 @@ package world.bentobox.bentobox.blueprints.worldedit; -import java.io.IOException; import java.io.InputStream; import com.sk89q.worldedit.extent.clipboard.Clipboard; @@ -12,19 +11,19 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; */ public class BlueprintClipboardReader implements ClipboardReader { - private InputStream inputStream; + private final InputStream inputStream; public BlueprintClipboardReader(InputStream inputStream) { this.inputStream = inputStream; } @Override - public Clipboard read() throws IOException { + public Clipboard read() { throw new UnsupportedOperationException(); // TODO } @Override - public void close() throws IOException { + public void close() { throw new UnsupportedOperationException(); // TODO } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java index 105b19b87..095ffbf3f 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintClipboardWriter.java @@ -1,6 +1,5 @@ package world.bentobox.bentobox.blueprints.worldedit; -import java.io.IOException; import java.io.OutputStream; import com.sk89q.worldedit.extent.clipboard.Clipboard; @@ -12,18 +11,18 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; */ public class BlueprintClipboardWriter implements ClipboardWriter { - private OutputStream outputStream; + private final OutputStream outputStream; public BlueprintClipboardWriter(OutputStream outputStream) { this.outputStream = outputStream; } @Override - public void write(Clipboard clipboard) throws IOException { + public void write(Clipboard clipboard) { throw new UnsupportedOperationException(); // TODO } @Override - public void close() throws IOException { + public void close() { throw new UnsupportedOperationException(); // TODO } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java index 6a1708006..05c4621a9 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/worldedit/BlueprintSchematicConverter.java @@ -18,7 +18,7 @@ public class BlueprintSchematicConverter { private File blueprintFile; public BlueprintSchematicConverter(File blueprintFile) { - if(!BentoBox.getInstance().getHooks().getHook("WorldEdit").isPresent()) { + if(BentoBox.getInstance().getHooks().getHook("WorldEdit").isEmpty()) { BentoBox.getInstance().logError("WorldEdit must be installed to use that class !"); return; } diff --git a/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java b/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java index 85ca4c7af..4ee6838c6 100644 --- a/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java +++ b/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java @@ -7,6 +7,7 @@ import org.bukkit.Bukkit; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.events.BentoBoxReadyEvent; +import world.bentobox.bentobox.api.panels.reader.TemplateReader; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.commands.reload.BentoBoxReloadLocalesCommand; import world.bentobox.bentobox.listeners.PanelListenerManager; @@ -45,6 +46,8 @@ public class BentoBoxReloadCommand extends ConfirmableCommand { // Close all open panels PanelListenerManager.closeAllPanels(); + // Clear all template panels. + TemplateReader.clearPanels(); // Reload settings getPlugin().loadSettings(); diff --git a/src/main/java/world/bentobox/bentobox/commands/package-info.java b/src/main/java/world/bentobox/bentobox/commands/package-info.java new file mode 100644 index 000000000..4893d86de --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/commands/package-info.java @@ -0,0 +1,7 @@ +/** + * The package contains non-API commands for BentoBox itself. + * + * @author tastybento + * + */ +package world.bentobox.bentobox.commands; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/database/Database.java b/src/main/java/world/bentobox/bentobox/database/Database.java index 7b193e117..5da65334f 100644 --- a/src/main/java/world/bentobox/bentobox/database/Database.java +++ b/src/main/java/world/bentobox/bentobox/database/Database.java @@ -21,8 +21,8 @@ import world.bentobox.bentobox.api.addons.Addon; */ public class Database { - private AbstractDatabaseHandler handler; - private Logger logger; + private final AbstractDatabaseHandler handler; + private final Logger logger; private static DatabaseSetup databaseSetup = DatabaseSetup.getDatabase(); /** diff --git a/src/main/java/world/bentobox/bentobox/database/json/AbstractJSONDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/json/AbstractJSONDatabaseHandler.java index 20e312c68..8f4e7e105 100644 --- a/src/main/java/world/bentobox/bentobox/database/json/AbstractJSONDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/json/AbstractJSONDatabaseHandler.java @@ -17,7 +17,7 @@ import world.bentobox.bentobox.database.DatabaseConnector; */ public abstract class AbstractJSONDatabaseHandler extends AbstractDatabaseHandler { - private Gson gson; + private final Gson gson; /** * Constructor diff --git a/src/main/java/world/bentobox/bentobox/database/json/JSONDatabase.java b/src/main/java/world/bentobox/bentobox/database/json/JSONDatabase.java index b2b2ce108..0435d3acf 100644 --- a/src/main/java/world/bentobox/bentobox/database/json/JSONDatabase.java +++ b/src/main/java/world/bentobox/bentobox/database/json/JSONDatabase.java @@ -6,7 +6,7 @@ import world.bentobox.bentobox.database.DatabaseSetup; public class JSONDatabase implements DatabaseSetup { - private JSONDatabaseConnector connector = new JSONDatabaseConnector(BentoBox.getInstance()); + private final JSONDatabaseConnector connector = new JSONDatabaseConnector(BentoBox.getInstance()); /* (non-Javadoc) * @see world.bentobox.bentobox.database.DatabaseSetup#getHandler(java.lang.Class) diff --git a/src/main/java/world/bentobox/bentobox/database/json/JSONDatabaseConnector.java b/src/main/java/world/bentobox/bentobox/database/json/JSONDatabaseConnector.java index fab8aa33e..82a49c031 100644 --- a/src/main/java/world/bentobox/bentobox/database/json/JSONDatabaseConnector.java +++ b/src/main/java/world/bentobox/bentobox/database/json/JSONDatabaseConnector.java @@ -23,11 +23,11 @@ public class JSONDatabaseConnector implements DatabaseConnector { @NonNull public String getUniqueId(String tableName) { UUID uuid = UUID.randomUUID(); - File file = new File(dataFolder, tableName + File.separator + uuid.toString() + JSON); + File file = new File(dataFolder, tableName + File.separator + uuid + JSON); int limit = 0; while (file.exists() && limit++ < MAX_LOOPS) { uuid = UUID.randomUUID(); - file = new File(dataFolder, tableName + File.separator + uuid.toString() + JSON); + file = new File(dataFolder, tableName + File.separator + uuid + JSON); } return uuid.toString(); } diff --git a/src/main/java/world/bentobox/bentobox/database/json/adapters/FlagTypeAdapter.java b/src/main/java/world/bentobox/bentobox/database/json/adapters/FlagTypeAdapter.java index 2b283ae93..7d673182c 100644 --- a/src/main/java/world/bentobox/bentobox/database/json/adapters/FlagTypeAdapter.java +++ b/src/main/java/world/bentobox/bentobox/database/json/adapters/FlagTypeAdapter.java @@ -15,7 +15,7 @@ import world.bentobox.bentobox.api.flags.Flag; public class FlagTypeAdapter extends TypeAdapter { - private BentoBox plugin; + private final BentoBox plugin; public FlagTypeAdapter(BentoBox plugin) { this.plugin = plugin; @@ -42,7 +42,7 @@ public class FlagTypeAdapter extends TypeAdapter { // Flags can end up null if an addon that created one is removed or if a flag name was changed if (f == null) { // Create a temporary flag with a unique key. It will be immediately deleted after loading - f = new Flag.Builder("NULL_FLAG_"+ UUID.randomUUID().toString(), Material.STONE).build(); + f = new Flag.Builder("NULL_FLAG_"+ UUID.randomUUID(), Material.STONE).build(); } return f; } diff --git a/src/main/java/world/bentobox/bentobox/database/json/adapters/package-info.java b/src/main/java/world/bentobox/bentobox/database/json/adapters/package-info.java new file mode 100644 index 000000000..e39cd5320 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/database/json/adapters/package-info.java @@ -0,0 +1,12 @@ +/** + * These are GSON adapters used to serialize and deserialize various data types. + *

+ * The {@link world.bentobox.bentobox.database.json.adapters.BukkitObjectTypeAdapter} + * is a catch-all adapter that uses the built-in Bukkit serialization capabilities. Before + * we knew about this, there were other ones built, like for Location, that have to remain + * for backwards compatibility reasons. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.database.json.adapters; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java index a347b94dd..02c0744a9 100644 --- a/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java @@ -40,7 +40,7 @@ public class MongoDBDatabaseHandler extends AbstractJSONDatabaseHandler { private static final String MONGO_ID = "_id"; private MongoCollection collection; - private DatabaseConnector dbConnecter; + private final DatabaseConnector dbConnecter; /** * Handles the connection to the database and creation of the initial database schema (tables) for @@ -142,12 +142,11 @@ public class MongoDBDatabaseHandler extends AbstractJSONDatabaseHandler { completableFuture.complete(false); return completableFuture; } - if (!(instance instanceof DataObject)) { + if (!(instance instanceof DataObject dataObj)) { plugin.logError("This class is not a DataObject: " + instance.getClass().getName()); completableFuture.complete(false); return completableFuture; } - DataObject dataObj = (DataObject)instance; try { Gson gson = getGson(); String toStore = gson.toJson(instance); diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Island.java b/src/main/java/world/bentobox/bentobox/database/objects/Island.java index a2273e16f..8d7a2cd14 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -1,8 +1,6 @@ package world.bentobox.bentobox.database.objects; import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; @@ -23,7 +21,6 @@ import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.entity.Player; import org.bukkit.util.BoundingBox; -import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.jetbrains.annotations.NotNull; @@ -37,7 +34,6 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.flags.Flag; -import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.metadata.MetaDataAble; import world.bentobox.bentobox.api.metadata.MetaDataValue; @@ -49,6 +45,7 @@ import world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter; import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.IslandInfo; import world.bentobox.bentobox.util.Pair; import world.bentobox.bentobox.util.Util; @@ -1080,71 +1077,21 @@ public class Island implements DataObject, MetaDataAble { * Shows info of this island to this user. * @param user the User who is requesting it * @return always true + * @deprecated Use {@link IslandInfo#showInfo(User) instead} */ + @Deprecated public boolean showInfo(User user) { - BentoBox plugin = BentoBox.getInstance(); - user.sendMessage("commands.admin.info.title"); - user.sendMessage("commands.admin.info.island-uuid", "[uuid]", this.getUniqueId()); - if (getOwner() == null) { - user.sendMessage("commands.admin.info.unowned"); - } else { - user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(getOwner()), "[uuid]", getOwner().toString()); - - // Fixes #getLastPlayed() returning 0 when it is the owner's first connection. - long lastPlayed = (Bukkit.getServer().getOfflinePlayer(getOwner()).getLastPlayed() != 0) ? - Bukkit.getServer().getOfflinePlayer(getOwner()).getLastPlayed() : Bukkit.getServer().getOfflinePlayer(getOwner()).getFirstPlayed(); - String formattedDate; - try { - String dateTimeFormat = plugin.getLocalesManager().get("commands.admin.info.last-login-date-time-format"); - formattedDate = new SimpleDateFormat(dateTimeFormat).format(new Date(lastPlayed)); - } catch (NullPointerException | IllegalArgumentException ignored) { - formattedDate = new Date(lastPlayed).toString(); - } - user.sendMessage("commands.admin.info.last-login","[date]", formattedDate); - - user.sendMessage("commands.admin.info.deaths", "[number]", String.valueOf(plugin.getPlayers().getDeaths(getWorld(), getOwner()))); - String resets = String.valueOf(plugin.getPlayers().getResets(getWorld(), getOwner())); - String total = plugin.getIWM().getResetLimit(getWorld()) < 0 ? "Unlimited" : String.valueOf(plugin.getIWM().getResetLimit(getWorld())); - user.sendMessage("commands.admin.info.resets-left", "[number]", resets, "[total]", total); - // Show team members - showMembers(user); - } - Vector location = getProtectionCenter().toVector(); - user.sendMessage("commands.admin.info.island-protection-center", TextVariables.XYZ, Util.xyz(location)); - user.sendMessage("commands.admin.info.island-center", TextVariables.XYZ, Util.xyz(getCenter().toVector())); - user.sendMessage("commands.admin.info.island-coords", "[xz1]", Util.xyz(new Vector(this.getMinX(), 0, getMinZ())), "[xz2]", Util.xyz(new Vector(this.getMaxX(), 0, getMaxZ()))); - user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(getProtectionRange())); - user.sendMessage("commands.admin.info.max-protection-range", "[range]", String.valueOf(getMaxEverProtectionRange())); - user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(this.getMinProtectedX(), 0, getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(this.getMaxProtectedX(), 0, getMaxProtectedZ()))); - if (spawn) { - user.sendMessage("commands.admin.info.is-spawn"); - } - if (!getBanned().isEmpty()) { - user.sendMessage("commands.admin.info.banned-players"); - getBanned().forEach(u -> user.sendMessage("commands.admin.info.banned-format", TextVariables.NAME, plugin.getPlayers().getName(u))); - } - if (getPurgeProtected()) { - user.sendMessage("commands.admin.info.purge-protected"); - } - return true; + return new IslandInfo(this).showInfo(user); } /** * Shows the members of this island to this user. * @param user the User who is requesting it + * @deprecated Use {@link IslandInfo#showMembers(User) instead} */ + @Deprecated public void showMembers(User user) { - BentoBox plugin = BentoBox.getInstance(); - user.sendMessage("commands.admin.info.team-members-title"); - members.forEach((u, i) -> { - if (owner.equals(u)) { - user.sendMessage("commands.admin.info.team-owner-format", TextVariables.NAME, plugin.getPlayers().getName(u) - , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); - } else if (i > RanksManager.VISITOR_RANK){ - user.sendMessage("commands.admin.info.team-member-format", TextVariables.NAME, plugin.getPlayers().getName(u) - , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); - } - }); + new IslandInfo(this).showMembers(user); } /** @@ -1346,7 +1293,7 @@ public class Island implements DataObject, MetaDataAble { * @param flag - Flag to cooldown */ public void setCooldown(Flag flag) { - cooldowns.put(flag, flag.getCooldown() * 1000 + System.currentTimeMillis()); + cooldowns.put(flag, flag.getCooldown() * 1000L + System.currentTimeMillis()); setChanged(); } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/IslandDeletion.java b/src/main/java/world/bentobox/bentobox/database/objects/IslandDeletion.java index 30a5a9697..2b444a5e6 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/IslandDeletion.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/IslandDeletion.java @@ -79,10 +79,9 @@ public class IslandDeletion implements DataObject { if (obj == null) { return false; } - if (!(obj instanceof IslandDeletion)) { + if (!(obj instanceof IslandDeletion other)) { return false; } - IslandDeletion other = (IslandDeletion) obj; if (uniqueId == null) { return other.uniqueId == null; } else return uniqueId.equals(other.uniqueId); diff --git a/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer.java b/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer.java index 118bd0932..128ede5a8 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer.java @@ -26,8 +26,7 @@ public class FlagSerializer implements AdapterInterface, Map< return result; } // For YAML - if (object instanceof MemorySection) { - MemorySection section = (MemorySection) object; + if (object instanceof MemorySection section) { for (String key : section.getKeys(false)) { BentoBox.getInstance().getFlagsManager().getFlag(key).ifPresent(flag -> result.put(flag, section.getInt(key))); } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer2.java b/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer2.java index 564eec52c..0c43f6de7 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer2.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer2.java @@ -23,8 +23,7 @@ public class FlagSerializer2 implements AdapterInterface, Map return result; } // For YAML - if (object instanceof MemorySection) { - MemorySection section = (MemorySection) object; + if (object instanceof MemorySection section) { for (String key : section.getKeys(false)) { BentoBox.getInstance().getFlagsManager().getFlag(key).ifPresent(flag -> result.put(flag, section.getBoolean(key) ? 0 : -1)); } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer3.java b/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer3.java index 7ef181eeb..c6997f8fc 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer3.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/adapters/FlagSerializer3.java @@ -26,8 +26,7 @@ public class FlagSerializer3 implements AdapterInterface, Map result.put(flag, section.getLong(key))); } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/adapters/package-info.java b/src/main/java/world/bentobox/bentobox/database/objects/adapters/package-info.java new file mode 100644 index 000000000..e5a955634 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/database/objects/adapters/package-info.java @@ -0,0 +1,6 @@ +/** + * These adapters are used by the YAML database, which is now only used + * for configuration storage and management. For the GSON adapters used + * by the "real" databases, see {@link world.bentobox.bentobox.database.json.adapters} + */ +package world.bentobox.bentobox.database.objects.adapters; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/database/objects/package-info.java b/src/main/java/world/bentobox/bentobox/database/objects/package-info.java new file mode 100644 index 000000000..dee4be6e1 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/database/objects/package-info.java @@ -0,0 +1,11 @@ +/** + * These are the data objects and adapters that BentoBox uses to store its data. + * + *

+ * Key objects are Island and Players. BentoBox loads all Island objects on startup into RAM. Players are loaded + * as and when required. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.database.objects; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/database/package-info.java b/src/main/java/world/bentobox/bentobox/database/package-info.java new file mode 100644 index 000000000..d8873e206 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/database/package-info.java @@ -0,0 +1,21 @@ +/** + * Provides an abstract database for storing Java POJOs + * and also YAML config files. + * + *

+ * The database supports concrete implementations for JSON flat file, MongoDB, MySQL, PostgreSQL, SQLite + * and the ability to transition between them. + *

+ *

+ * Storage of POJOs is done via GSON, i.e, the object is serialized and then stored. Each data object must + * implement the DataObject interface, which requires a uniqueId field. This is what is used for indexing + * and finding. + *

+ *

+ * Performance with JSON is generally very good, and the other databases are really there for concurrent usage + * by other applications. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.database; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/database/sql/SQLConfiguration.java b/src/main/java/world/bentobox/bentobox/database/sql/SQLConfiguration.java index baafdad8b..373d4f04b 100644 --- a/src/main/java/world/bentobox/bentobox/database/sql/SQLConfiguration.java +++ b/src/main/java/world/bentobox/bentobox/database/sql/SQLConfiguration.java @@ -18,7 +18,7 @@ public class SQLConfiguration { private String loadObjectsSQL; private String renameTableSQL; private final String tableName; - private boolean renameRequired; + private final boolean renameRequired; private final String oldTableName; public SQLConfiguration(BentoBox plugin, Class type) { diff --git a/src/main/java/world/bentobox/bentobox/database/sql/SQLDatabaseConnector.java b/src/main/java/world/bentobox/bentobox/database/sql/SQLDatabaseConnector.java index bc4383fac..3770062fc 100644 --- a/src/main/java/world/bentobox/bentobox/database/sql/SQLDatabaseConnector.java +++ b/src/main/java/world/bentobox/bentobox/database/sql/SQLDatabaseConnector.java @@ -15,7 +15,7 @@ import world.bentobox.bentobox.database.DatabaseConnector; public abstract class SQLDatabaseConnector implements DatabaseConnector { protected String connectionUrl; - private DatabaseConnectionSettingsImpl dbSettings; + private final DatabaseConnectionSettingsImpl dbSettings; protected static Connection connection = null; protected static Set> types = new HashSet<>(); diff --git a/src/main/java/world/bentobox/bentobox/database/sql/sqlite/SQLiteDatabase.java b/src/main/java/world/bentobox/bentobox/database/sql/sqlite/SQLiteDatabase.java index ff599734b..327bdb657 100644 --- a/src/main/java/world/bentobox/bentobox/database/sql/sqlite/SQLiteDatabase.java +++ b/src/main/java/world/bentobox/bentobox/database/sql/sqlite/SQLiteDatabase.java @@ -10,7 +10,7 @@ import world.bentobox.bentobox.database.DatabaseSetup; */ public class SQLiteDatabase implements DatabaseSetup { - private SQLiteDatabaseConnector connector = new SQLiteDatabaseConnector(BentoBox.getInstance()); + private final SQLiteDatabaseConnector connector = new SQLiteDatabaseConnector(BentoBox.getInstance()); @Override public AbstractDatabaseHandler getHandler(Class dataObjectClass) { diff --git a/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java index 325837f99..a3bb314bd 100644 --- a/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java @@ -19,8 +19,8 @@ import world.bentobox.bentobox.database.AbstractDatabaseHandler; */ public class TransitionDatabaseHandler extends AbstractDatabaseHandler { - private AbstractDatabaseHandler fromHandler; - private AbstractDatabaseHandler toHandler; + private final AbstractDatabaseHandler fromHandler; + private final AbstractDatabaseHandler toHandler; /** * Constructor diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabase.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabase.java index 597a24384..4df6fb9cf 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabase.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabase.java @@ -6,7 +6,7 @@ import world.bentobox.bentobox.database.DatabaseSetup; public class YamlDatabase implements DatabaseSetup { - private YamlDatabaseConnector connector = new YamlDatabaseConnector(BentoBox.getInstance()); + private final YamlDatabaseConnector connector = new YamlDatabaseConnector(BentoBox.getInstance()); /** * Get the config diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java index c7a132965..aacc05b97 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java @@ -151,12 +151,9 @@ public class YamlDatabaseConnector implements DatabaseConnector { for (Entry e : commentMap.entrySet()) { if (nextLine.contains(e.getKey())) { // We want the comment to start at the same level as the entry - StringBuilder commentLine = new StringBuilder(); - for (int i = 0; i < nextLine.indexOf(e.getKey()); i++){ - commentLine.append(' '); - } - commentLine.append(e.getValue()); - nextLine = commentLine.toString(); + String commentLine = " ".repeat(Math.max(0, nextLine.indexOf(e.getKey()))) + + e.getValue(); + nextLine = commentLine; break; } } @@ -191,11 +188,11 @@ public class YamlDatabaseConnector implements DatabaseConnector { @NonNull public String getUniqueId(String tableName) { UUID uuid = UUID.randomUUID(); - File file = new File(dataFolder, tableName + File.separator + uuid.toString() + YML); + File file = new File(dataFolder, tableName + File.separator + uuid + YML); int limit = 0; while (file.exists() && limit++ < MAX_LOOPS) { uuid = UUID.randomUUID(); - file = new File(dataFolder, tableName + File.separator + uuid.toString() + YML); + file = new File(dataFolder, tableName + File.separator + uuid + YML); } return uuid.toString(); } diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java index 6cad6bd8d..6c9d56dd5 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java @@ -534,7 +534,7 @@ public class YamlDatabaseHandler extends AbstractDatabaseHandler { } private void setComment(@NonNull String comment, @NonNull YamlConfiguration config, @NonNull Map yamlComments, @NonNull String parent) { - String random = "comment-" + UUID.randomUUID().toString(); + String random = "comment-" + UUID.randomUUID(); // Store placeholder config.set(parent + random, " "); // Create comment @@ -554,20 +554,20 @@ public class YamlDatabaseHandler extends AbstractDatabaseHandler { } // UUID has it's own serialization, that is not picked up automatically if (object instanceof UUID) { - return ((UUID)object).toString(); + return object.toString(); } // Only the world name is needed for worlds - if (object instanceof World) { - return ((World)object).getName(); + if (object instanceof World w) { + return w.getName(); } // Location - if (object instanceof Location) { - return Util.getStringLocation((Location)object); + if (object instanceof Location l) { + return Util.getStringLocation(l); } // Enums - if (object instanceof Enum) { + if (object instanceof Enum e) { //Custom enums are a child of the Enum class. Just get the names of each one. - return ((Enum)object).name(); + return e.name(); } return object; } diff --git a/src/main/java/world/bentobox/bentobox/hooks/DynmapHook.java b/src/main/java/world/bentobox/bentobox/hooks/DynmapHook.java index 3eb8c5347..a14cbaf93 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/DynmapHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/DynmapHook.java @@ -24,7 +24,7 @@ public class DynmapHook extends Hook { private MarkerAPI markerAPI; @NonNull - private Map<@NonNull GameModeAddon, @NonNull MarkerSet> markerSets; + private final Map<@NonNull GameModeAddon, @NonNull MarkerSet> markerSets; public DynmapHook() { super("dynmap", Material.FILLED_MAP); diff --git a/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java b/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java index 2d5aa10ae..d7e630f16 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java @@ -262,31 +262,29 @@ public class LangUtilsHook extends Hook { if (hooked) { return LanguageHelper.getPotionName(potionType, getUserLocale(user)); } - switch (potionType) { - case UNCRAFTABLE: return "Uncraftable Potion"; - case WATER: return "Water Bottle"; - case MUNDANE: return "Mundane Potion"; - case THICK: return "Thick Potion"; - case AWKWARD: return "Awkward Potion"; - case NIGHT_VISION: return "Potion of Night Vision"; - case INVISIBILITY: return "Potion of Invisibility"; - case JUMP: return "Potion of Leaping"; - case FIRE_RESISTANCE: return "Potion of Fire Resistance"; - case SPEED: return "Potion of Swiftness"; - case SLOWNESS: return "Potion of Slowness"; - case WATER_BREATHING: return "Potion of Water Breathing"; - case INSTANT_HEAL: return "Potion of Healing"; - case INSTANT_DAMAGE: return "Potion of Harming"; - case POISON: return "Potion of Poison"; - case REGEN: return "Potion of Regeneration"; - case STRENGTH: return "Potion of Strength"; - case WEAKNESS: return "Potion of Weakness"; - case LUCK: return "Potion of Luck"; - case TURTLE_MASTER: return "Potion of the Turtle Master"; - case SLOW_FALLING: return "Potion of Slow Falling"; - default: - return Util.prettifyText(potionType.name()); - } + return switch (potionType) { + case UNCRAFTABLE -> "Uncraftable Potion"; + case WATER -> "Water Bottle"; + case MUNDANE -> "Mundane Potion"; + case THICK -> "Thick Potion"; + case AWKWARD -> "Awkward Potion"; + case NIGHT_VISION -> "Potion of Night Vision"; + case INVISIBILITY -> "Potion of Invisibility"; + case JUMP -> "Potion of Leaping"; + case FIRE_RESISTANCE -> "Potion of Fire Resistance"; + case SPEED -> "Potion of Swiftness"; + case SLOWNESS -> "Potion of Slowness"; + case WATER_BREATHING -> "Potion of Water Breathing"; + case INSTANT_HEAL -> "Potion of Healing"; + case INSTANT_DAMAGE -> "Potion of Harming"; + case POISON -> "Potion of Poison"; + case REGEN -> "Potion of Regeneration"; + case STRENGTH -> "Potion of Strength"; + case WEAKNESS -> "Potion of Weakness"; + case LUCK -> "Potion of Luck"; + case TURTLE_MASTER -> "Potion of the Turtle Master"; + case SLOW_FALLING -> "Potion of Slow Falling"; + }; } @@ -301,31 +299,29 @@ public class LangUtilsHook extends Hook { if (hooked) { return LanguageHelper.getSplashPotionName(potionType, getUserLocale(user)); } - switch (potionType) { - case UNCRAFTABLE: return "Splash Uncraftable Potion"; - case WATER: return "Splash Water Bottle"; - case MUNDANE: return "Mundane Splash Potion"; - case THICK: return "Thick Splash Potion"; - case AWKWARD: return "Awkward Splash Potion"; - case NIGHT_VISION: return "Splash Potion of Night Vision"; - case INVISIBILITY: return "Splash Potion of Invisibility"; - case JUMP: return "Splash Potion of Leaping"; - case FIRE_RESISTANCE: return "Splash Potion of Fire Resistance"; - case SPEED: return "Splash Potion of Swiftness"; - case SLOWNESS: return "Splash Potion of Slowness"; - case WATER_BREATHING: return "Splash Potion of Water Breathing"; - case INSTANT_HEAL: return "Splash Potion of Healing"; - case INSTANT_DAMAGE: return "Splash Potion of Harming"; - case POISON: return "Splash Potion of Poison"; - case REGEN: return "Splash Potion of Regeneration"; - case STRENGTH: return "Splash Potion of Strength"; - case WEAKNESS: return "Splash Potion of Weakness"; - case LUCK: return "Splash Potion of Luck"; - case TURTLE_MASTER: return "Splash Potion of the Turtle Master"; - case SLOW_FALLING: return "Splash Potion of Slow Falling"; - default: - return Util.prettifyText(potionType.name()); - } + return switch (potionType) { + case UNCRAFTABLE -> "Splash Uncraftable Potion"; + case WATER -> "Splash Water Bottle"; + case MUNDANE -> "Mundane Splash Potion"; + case THICK -> "Thick Splash Potion"; + case AWKWARD -> "Awkward Splash Potion"; + case NIGHT_VISION -> "Splash Potion of Night Vision"; + case INVISIBILITY -> "Splash Potion of Invisibility"; + case JUMP -> "Splash Potion of Leaping"; + case FIRE_RESISTANCE -> "Splash Potion of Fire Resistance"; + case SPEED -> "Splash Potion of Swiftness"; + case SLOWNESS -> "Splash Potion of Slowness"; + case WATER_BREATHING -> "Splash Potion of Water Breathing"; + case INSTANT_HEAL -> "Splash Potion of Healing"; + case INSTANT_DAMAGE -> "Splash Potion of Harming"; + case POISON -> "Splash Potion of Poison"; + case REGEN -> "Splash Potion of Regeneration"; + case STRENGTH -> "Splash Potion of Strength"; + case WEAKNESS -> "Splash Potion of Weakness"; + case LUCK -> "Splash Potion of Luck"; + case TURTLE_MASTER -> "Splash Potion of the Turtle Master"; + case SLOW_FALLING -> "Splash Potion of Slow Falling"; + }; } /** @@ -339,31 +335,29 @@ public class LangUtilsHook extends Hook { if (hooked) { return LanguageHelper.getLingeringPotionName(potionType, getUserLocale(user)); } - switch (potionType) { - case UNCRAFTABLE: return "Lingering Uncraftable Potion"; - case WATER: return "Lingering Water Bottle"; - case MUNDANE: return "Mundane Lingering Potion"; - case THICK: return "Thick Lingering Potion"; - case AWKWARD: return "Awkward Lingering Potion"; - case NIGHT_VISION: return "Lingering Potion of Night Vision"; - case INVISIBILITY: return "Lingering Potion of Invisibility"; - case JUMP: return "Lingering Potion of Leaping"; - case FIRE_RESISTANCE: return "Lingering Potion of Fire Resistance"; - case SPEED: return "Lingering Potion of Swiftness"; - case SLOWNESS: return "Lingering Potion of Slowness"; - case WATER_BREATHING: return "Lingering Potion of Water Breathing"; - case INSTANT_HEAL: return "Lingering Potion of Healing"; - case INSTANT_DAMAGE: return "Lingering Potion of Harming"; - case POISON: return "Lingering Potion of Poison"; - case REGEN: return "Lingering Potion of Regeneration"; - case STRENGTH: return "Lingering Potion of Strength"; - case WEAKNESS: return "Lingering Potion of Weakness"; - case LUCK: return "Lingering Potion of Luck"; - case TURTLE_MASTER: return "Lingering Potion of the Turtle Master"; - case SLOW_FALLING: return "Lingering Potion of Slow Falling"; - default: - return Util.prettifyText(potionType.name()); - } + return switch (potionType) { + case UNCRAFTABLE -> "Lingering Uncraftable Potion"; + case WATER -> "Lingering Water Bottle"; + case MUNDANE -> "Mundane Lingering Potion"; + case THICK -> "Thick Lingering Potion"; + case AWKWARD -> "Awkward Lingering Potion"; + case NIGHT_VISION -> "Lingering Potion of Night Vision"; + case INVISIBILITY -> "Lingering Potion of Invisibility"; + case JUMP -> "Lingering Potion of Leaping"; + case FIRE_RESISTANCE -> "Lingering Potion of Fire Resistance"; + case SPEED -> "Lingering Potion of Swiftness"; + case SLOWNESS -> "Lingering Potion of Slowness"; + case WATER_BREATHING -> "Lingering Potion of Water Breathing"; + case INSTANT_HEAL -> "Lingering Potion of Healing"; + case INSTANT_DAMAGE -> "Lingering Potion of Harming"; + case POISON -> "Lingering Potion of Poison"; + case REGEN -> "Lingering Potion of Regeneration"; + case STRENGTH -> "Lingering Potion of Strength"; + case WEAKNESS -> "Lingering Potion of Weakness"; + case LUCK -> "Lingering Potion of Luck"; + case TURTLE_MASTER -> "Lingering Potion of the Turtle Master"; + case SLOW_FALLING -> "Lingering Potion of Slow Falling"; + }; } /** @@ -377,31 +371,27 @@ public class LangUtilsHook extends Hook { if (hooked) { return LanguageHelper.getTippedArrowName(potionType, getUserLocale(user)); } - switch (potionType) { - case UNCRAFTABLE: return "Uncraftable Tipped Arrow"; - case WATER: return "Arrow of Splashing"; - case MUNDANE: - case THICK: - case AWKWARD: return "Tipped Arrow"; - case NIGHT_VISION: return "Arrow of Night Vision"; - case INVISIBILITY: return "Arrow of Invisibility"; - case JUMP: return "Arrow of Leaping"; - case FIRE_RESISTANCE: return "Arrow of Fire Resistance"; - case SPEED: return "Arrow of Swiftness"; - case SLOWNESS: return "Arrow of Slowness"; - case WATER_BREATHING: return "Arrow of Water Breathing"; - case INSTANT_HEAL: return "Arrow of Healing"; - case INSTANT_DAMAGE: return "Arrow of Harming"; - case POISON: return "Arrow of Poison"; - case REGEN: return "Arrow of Regeneration"; - case STRENGTH: return "Arrow of Strength"; - case WEAKNESS: return "Arrow of Weakness"; - case LUCK: return "Arrow of Luck"; - case TURTLE_MASTER: return "Arrow of the Turtle Master"; - case SLOW_FALLING: return "Arrow of Slow Falling"; - default: - return Util.prettifyText(potionType.name()); - } + return switch (potionType) { + case UNCRAFTABLE -> "Uncraftable Tipped Arrow"; + case WATER -> "Arrow of Splashing"; + case MUNDANE, THICK, AWKWARD -> "Tipped Arrow"; + case NIGHT_VISION -> "Arrow of Night Vision"; + case INVISIBILITY -> "Arrow of Invisibility"; + case JUMP -> "Arrow of Leaping"; + case FIRE_RESISTANCE -> "Arrow of Fire Resistance"; + case SPEED -> "Arrow of Swiftness"; + case SLOWNESS -> "Arrow of Slowness"; + case WATER_BREATHING -> "Arrow of Water Breathing"; + case INSTANT_HEAL -> "Arrow of Healing"; + case INSTANT_DAMAGE -> "Arrow of Harming"; + case POISON -> "Arrow of Poison"; + case REGEN -> "Arrow of Regeneration"; + case STRENGTH -> "Arrow of Strength"; + case WEAKNESS -> "Arrow of Weakness"; + case LUCK -> "Arrow of Luck"; + case TURTLE_MASTER -> "Arrow of the Turtle Master"; + case SLOW_FALLING -> "Arrow of Slow Falling"; + }; } /** @@ -620,22 +610,22 @@ public class LangUtilsHook extends Hook { // The description of the music record is the same in any language, // so directly output it here. - switch (material) { - case MUSIC_DISC_13 : return "C418 - 13"; - case MUSIC_DISC_CAT : return "C418 - cat"; - case MUSIC_DISC_BLOCKS : return "C418 - blocks"; - case MUSIC_DISC_CHIRP : return "C418 - chirp"; - case MUSIC_DISC_FAR : return "C418 - far"; - case MUSIC_DISC_MALL : return "C418 - mall"; - case MUSIC_DISC_MELLOHI : return "C418 - mellohi"; - case MUSIC_DISC_STAL : return "C418 - stal"; - case MUSIC_DISC_STRAD : return "C418 - strad"; - case MUSIC_DISC_WARD : return "C418 - ward"; - case MUSIC_DISC_11 : return "C418 - 11"; - case MUSIC_DISC_WAIT : return "C418 - wait"; - case MUSIC_DISC_PIGSTEP : return "Lena Raine - Pigstep"; - default : return null; - } + return switch (material) { + case MUSIC_DISC_13 -> "C418 - 13"; + case MUSIC_DISC_CAT -> "C418 - cat"; + case MUSIC_DISC_BLOCKS -> "C418 - blocks"; + case MUSIC_DISC_CHIRP -> "C418 - chirp"; + case MUSIC_DISC_FAR -> "C418 - far"; + case MUSIC_DISC_MALL -> "C418 - mall"; + case MUSIC_DISC_MELLOHI -> "C418 - mellohi"; + case MUSIC_DISC_STAL -> "C418 - stal"; + case MUSIC_DISC_STRAD -> "C418 - strad"; + case MUSIC_DISC_WARD -> "C418 - ward"; + case MUSIC_DISC_11 -> "C418 - 11"; + case MUSIC_DISC_WAIT -> "C418 - wait"; + case MUSIC_DISC_PIGSTEP -> "Lena Raine - Pigstep"; + default -> null; + }; } } diff --git a/src/main/java/world/bentobox/bentobox/hooks/package-info.java b/src/main/java/world/bentobox/bentobox/hooks/package-info.java new file mode 100644 index 000000000..86ce95aae --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/hooks/package-info.java @@ -0,0 +1,7 @@ +/** + * This is where hooks into other plugins go. + * + * @author Poslovitch + * + */ +package world.bentobox.bentobox.hooks; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java b/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java index 91177291e..7b3b174fd 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java @@ -26,7 +26,7 @@ import world.bentobox.bentobox.api.placeholders.placeholderapi.BentoBoxPlacehold public class PlaceholderAPIHook extends PlaceholderHook { private BentoBoxPlaceholderExpansion bentoboxExpansion; - private Map addonsExpansions; + private final Map addonsExpansions; private final Set bentoBoxPlaceholders; private final Map> addonPlaceholders; diff --git a/src/main/java/world/bentobox/bentobox/listeners/BannedCommands.java b/src/main/java/world/bentobox/bentobox/listeners/BannedCommands.java index e1828f93e..c9dc27be1 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/BannedCommands.java +++ b/src/main/java/world/bentobox/bentobox/listeners/BannedCommands.java @@ -19,7 +19,7 @@ import world.bentobox.bentobox.lists.Flags; */ public class BannedCommands implements Listener { - private BentoBox plugin; + private final BentoBox plugin; /** * @param plugin - plugin diff --git a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java index 380264da7..8c219a353 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java +++ b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java @@ -18,7 +18,7 @@ import world.bentobox.bentobox.lists.Flags; public class BlockEndDragon implements Listener { - private BentoBox plugin; + private final BentoBox plugin; public BlockEndDragon(@NonNull BentoBox plugin) { this.plugin = plugin; diff --git a/src/main/java/world/bentobox/bentobox/listeners/DeathListener.java b/src/main/java/world/bentobox/bentobox/listeners/DeathListener.java index 22edcd57c..5cc4c73dc 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/DeathListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/DeathListener.java @@ -15,7 +15,7 @@ import world.bentobox.bentobox.BentoBox; */ public class DeathListener implements Listener { - private BentoBox plugin; + private final BentoBox plugin; public DeathListener(@NonNull BentoBox plugin) { super(); diff --git a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java index bac2aa6b1..e1f28b671 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java @@ -32,8 +32,8 @@ import world.bentobox.bentobox.util.Util; public class JoinLeaveListener implements Listener { - private BentoBox plugin; - private PlayersManager players; + private final BentoBox plugin; + private final PlayersManager players; /** * @param plugin - plugin object @@ -80,7 +80,7 @@ public class JoinLeaveListener implements Listener { players.setPlayerName(user); players.save(playerUUID); } else { - plugin.logWarning("Player that just logged in has no name! " + playerUUID.toString()); + plugin.logWarning("Player that just logged in has no name! " + playerUUID); } // If mobs have to be removed when a player joins, then wipe all the mobs on his island. @@ -126,9 +126,8 @@ public class JoinLeaveListener implements Listener { // - abort on logout is false // - abort on logout is true && user is online if (!plugin.getIWM().isCreateIslandOnFirstLoginAbortOnLogout(w) || user.isOnline()){ - plugin.getIWM().getAddon(w).ifPresent(addon -> addon.getPlayerCommand() - .map(command -> command.getSubCommand("create").orElse(null)) - .ifPresent(command -> command.execute(user, "create", Collections.singletonList(BlueprintsManager.DEFAULT_BUNDLE_NAME)))); + plugin.getIWM().getAddon(w).flatMap(addon -> addon.getPlayerCommand().flatMap(command -> command.getSubCommand("create"))) + .ifPresent(command -> command.execute(user, "create", Collections.singletonList(BlueprintsManager.DEFAULT_BUNDLE_NAME))); } }; diff --git a/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java b/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java index 70d39b6d9..53d402c5e 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java +++ b/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java @@ -1,9 +1,9 @@ package world.bentobox.bentobox.listeners; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.UUID; -import java.util.stream.Collectors; import org.bukkit.ChatColor; import org.bukkit.entity.HumanEntity; @@ -24,7 +24,7 @@ import world.bentobox.bentobox.api.user.User; public class PanelListenerManager implements Listener { - private static HashMap openPanels = new HashMap<>(); + private static final HashMap openPanels = new HashMap<>(); @EventHandler(priority = EventPriority.HIGHEST) public void onInventoryClick(InventoryClickEvent event) { @@ -97,8 +97,8 @@ public class PanelListenerManager implements Listener { */ public static void closeAllPanels() { // Use stream clones to avoid concurrent modification exceptions - openPanels.values().stream().collect(Collectors.toList()).forEach(p -> - p.getInventory().getViewers().stream().collect(Collectors.toList()).forEach(HumanEntity::closeInventory)); + new ArrayList<>(openPanels.values()).forEach(p -> + new ArrayList<>(p.getInventory().getViewers()).forEach(HumanEntity::closeInventory)); } /** diff --git a/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java b/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java index ed0cff519..3a8c04cd4 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java +++ b/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java @@ -47,7 +47,7 @@ public class PlayerEntityPortalEvent { * @return whether there should create be a destination portal created */ public boolean getCanCreatePortal() { - return epe == null ? ppe.getCanCreatePortal() : false; + return epe == null && ppe.getCanCreatePortal(); } /** diff --git a/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java b/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java index 495d4e1ab..d0e55998d 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java @@ -20,8 +20,8 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPortalEvent; -import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; @@ -43,18 +43,13 @@ import world.bentobox.bentobox.util.teleport.SafeSpotTeleport; public class PortalTeleportationListener implements Listener { private final BentoBox plugin; - private Set inPortal; + private final Set inPortal; + private final Set inTeleport; public PortalTeleportationListener(@NonNull BentoBox plugin) { this.plugin = plugin; inPortal = new HashSet<>(); - } - - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onPlayerTeleport(PlayerTeleportEvent e) { - // Remove player from inPortal after a teleport - inPortal.remove(e.getPlayer().getUniqueId()); + inTeleport = new HashSet<>(); } /** @@ -72,19 +67,13 @@ public class PortalTeleportationListener implements Listener { if (inPortal.contains(uuid) || !plugin.getIWM().inWorld(Util.getWorld(e.getLocation().getWorld()))) { return; } + inPortal.add(uuid); if (!Bukkit.getAllowNether() && type.equals(Material.NETHER_PORTAL)) { - inPortal.add(uuid); // Schedule a time Bukkit.getScheduler().runTaskLater(plugin, () -> { // Check again if still in portal - if (entity.getLocation().getBlock().getType().equals(Material.NETHER_PORTAL)) { - PlayerPortalEvent en = new PlayerPortalEvent((Player)entity, e.getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0); - if (!this.onIslandPortal(en)) { - // Failed - inPortal.remove(uuid); - } - } else { - inPortal.remove(uuid); + if (inPortal.contains(uuid)) { + this.onIslandPortal(new PlayerPortalEvent((Player)entity, e.getLocation(), null, TeleportCause.NETHER_PORTAL, 0, false, 0)); } }, 40); return; @@ -104,7 +93,6 @@ public class PortalTeleportationListener implements Listener { /** * Handles non-player portal use. - * Currently disables portal use by entities to prevent dupe glitching. * * @param e - event */ @@ -117,7 +105,7 @@ public class PortalTeleportationListener implements Listener { || m.equals(Material.END_PORTAL) || m.equals(Material.END_GATEWAY)) .findFirst(); - if (!mat.isPresent()) { + if (mat.isEmpty()) { e.setCancelled(true); return false; } else if (mat.get().equals(Material.NETHER_PORTAL)){ @@ -129,21 +117,32 @@ public class PortalTeleportationListener implements Listener { return false; } + /** + * Remove inPortal flag only when player exits the portal + * @param e player move event + */ + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onExitPortal(PlayerMoveEvent e) { + if (!inPortal.contains(e.getPlayer().getUniqueId())) { + return; + } + if (e.getTo() != null && !e.getTo().getBlock().getType().equals(Material.NETHER_PORTAL)) { + inPortal.remove(e.getPlayer().getUniqueId()); + inTeleport.remove(e.getPlayer().getUniqueId()); + } + } + /** * Handles nether or end portals * @param e - event */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public boolean onIslandPortal(PlayerPortalEvent e) { - switch (e.getCause()) { - case END_GATEWAY: - case END_PORTAL: - return processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END); - case NETHER_PORTAL: - return processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER); - default: - return false; - } + return switch (e.getCause()) { + case END_GATEWAY, END_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.THE_END); + case NETHER_PORTAL -> processPortal(new PlayerEntityPortalEvent(e), Environment.NETHER); + default -> false; + }; } @@ -154,18 +153,27 @@ public class PortalTeleportationListener implements Listener { * @return true if portal happens, false if not */ private boolean processPortal(final PlayerEntityPortalEvent e, final Environment env) { - World fromWorld = e.getFrom().getWorld(); World overWorld = Util.getWorld(fromWorld); if (fromWorld == null || !plugin.getIWM().inWorld(overWorld)) { // Do nothing special return false; } - // 1.14.4 requires explicit cancellation to prevent teleporting to the normal nether + if (!isGenerate(overWorld, env)) { e.setCancelled(true); return false; } + + if (!Bukkit.getServer().getAllowNether()) { + e.setCancelled(true); + } + + if (inTeleport.contains(e.getEntity().getUniqueId())) { + return false; + } + inTeleport.add(e.getEntity().getUniqueId()); + // STANDARD NETHER OR END if (!isIslands(overWorld, env)) { handleStandardNetherOrEnd(e, fromWorld, overWorld, env); @@ -198,7 +206,6 @@ public class PortalTeleportationListener implements Listener { && e.getIsland().filter(i -> !hasPartnerIsland(i, env)).map(i -> { // No nether island present so paste the default one e.setCancelled(true); - inPortal.remove(e.getEntity().getUniqueId()); pasteNewIsland((Player)e.getEntity(), e.getTo(), i, env); return true; }).orElse(false)) { @@ -207,7 +214,6 @@ public class PortalTeleportationListener implements Listener { } if (e.getCanCreatePortal()) { // Let the server teleport - inPortal.remove(e.getEntity().getUniqueId()); return true; } if (env.equals(Environment.THE_END)) { @@ -216,10 +222,10 @@ public class PortalTeleportationListener implements Listener { e.getEntity().setFallDistance(0); } - // If we do not generate portals, teleporation should happen manually with safe spot builder. - // Otherwise, we could end up with situations when player is placed in mid air, if teleporation + // If we do not generate portals, teleportation should happen manually with safe spot builder. + // Otherwise, we could end up with situations when player is placed in mid air, if teleportation // is done instantly. - // Our safe spot task is triggered in next tick, however, end teleporation happens in the same tick. + // Our safe spot task is triggered in next tick, however, end teleportation happens in the same tick. // It is placed outside THE_END check, as technically it could happen with the nether portal too. e.setCancelled(true); @@ -232,7 +238,6 @@ public class PortalTeleportationListener implements Listener { .location(e.getTo()) .portal() .thenRun(() -> { - inPortal.remove(e.getEntity().getUniqueId()); e.getEntity().setVelocity(new Vector(0,0,0)); e.getEntity().setFallDistance(0); }) @@ -361,7 +366,6 @@ public class PortalTeleportationListener implements Listener { e.setTo(e.getFrom().toVector().toLocation(overWorld)); // Find distance from edge of island's protection plugin.getIslands().getIslandAt(e.getFrom()).ifPresent(i -> setSeachRadius(e, i)); - inPortal.remove(e.getEntity().getUniqueId()); return; } // Custom portals @@ -374,7 +378,6 @@ public class PortalTeleportationListener implements Listener { .entity(e.getEntity()) .location(to) .portal() - .thenRun(() -> inPortal.remove(e.getEntity().getUniqueId())) .build(); } @@ -412,7 +415,7 @@ public class PortalTeleportationListener implements Listener { // From standard nether or end else if (e.getEntity() instanceof Player){ e.setCancelled(true); - plugin.getIslands().homeTeleportAsync(overWorld, (Player)e.getEntity()).thenAccept(b -> inPortal.remove(e.getEntity().getUniqueId())); + plugin.getIslands().homeTeleportAsync(overWorld, (Player)e.getEntity()); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListener.java b/src/main/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListener.java index f07965dfa..737a219a2 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListener.java @@ -111,8 +111,9 @@ public class StandardSpawnProtectionListener implements Listener { private boolean atSpawn(@NonNull Location location) { Vector p = location.toVector().multiply(new Vector(1, 0, 1)); Vector spawn = location.getWorld().getSpawnLocation().toVector().multiply(new Vector(1, 0, 1)); - int radiusSquared = plugin.getIWM().getNetherSpawnRadius(location.getWorld()) * plugin.getIWM().getNetherSpawnRadius(location.getWorld()); - return (spawn.distanceSquared(p) < radiusSquared); + int radius = plugin.getIWM().getNetherSpawnRadius(location.getWorld()); + Vector diff = p.subtract(spawn); + return Math.abs(diff.getBlockX()) <= radius && Math.abs(diff.getBlockZ()) <= radius; } /** @@ -123,7 +124,7 @@ public class StandardSpawnProtectionListener implements Listener { * @return true if nothing needs to be done */ private boolean noAction(@NonNull Player player) { - return (player.isOp() || player.getWorld().getEnvironment().equals(World.Environment.NORMAL) + return (player.isOp() || player.getWorld().getEnvironment().equals(World.Environment.NORMAL) || !plugin.getIWM().inWorld(Util.getWorld(player.getWorld())) || (player.getWorld().getEnvironment().equals(World.Environment.NETHER) && plugin.getIWM().isNetherIslands(player.getWorld())) || (player.getWorld().getEnvironment().equals(World.Environment.THE_END) && plugin.getIWM().isEndIslands(player.getWorld()))); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java index 4d730fe7d..8db7760e7 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java @@ -17,9 +17,9 @@ import world.bentobox.bentobox.managers.RanksManager; */ public class CommandCycleClick implements ClickHandler { - private BentoBox plugin = BentoBox.getInstance(); - private String command; - private CommandRankClickListener commandRankClickListener; + private final BentoBox plugin = BentoBox.getInstance(); + private final String command; + private final CommandRankClickListener commandRankClickListener; public CommandCycleClick(CommandRankClickListener commandRankClickListener, String c) { this.commandRankClickListener = commandRankClickListener; diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java index e98abc574..d5ce0fecc 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java @@ -29,7 +29,7 @@ import world.bentobox.bentobox.util.Util; */ public class CommandRankClickListener implements ClickHandler { - private BentoBox plugin = BentoBox.getInstance(); + private final BentoBox plugin = BentoBox.getInstance(); /* (non-Javadoc) * @see world.bentobox.bentobox.api.panels.PanelItem.ClickHandler#onClick(world.bentobox.bentobox.api.panels.Panel, world.bentobox.bentobox.api.user.User, org.bukkit.event.inventory.ClickType, int) diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/package-info.java b/src/main/java/world/bentobox/bentobox/listeners/flags/package-info.java new file mode 100644 index 000000000..6527fd8ba --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/package-info.java @@ -0,0 +1,7 @@ +/** + * Contains listeners specific to settings flags. + * + * @author tastybento + * + */ +package world.bentobox.bentobox.listeners.flags; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java index faf4408ad..98a382cec 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java @@ -1,7 +1,5 @@ package world.bentobox.bentobox.listeners.flags.protection; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -36,9 +34,7 @@ public class BlockInteractionListener extends FlagListener { */ private final static Map stringFlags; static { - Map f = new HashMap<>(); - f.put("RESPAWN_ANCHOR", "PLACE_BLOCKS"); - stringFlags = Collections.unmodifiableMap(f); + stringFlags = Map.of("RESPAWN_ANCHOR", "PLACE_BLOCKS"); } /** diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java index 35b4bc0ea..391f2605d 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java @@ -46,9 +46,8 @@ public class BreakBlocksListener extends FlagListener { checkIsland(e, (Player)e.getRemover(), e.getEntity().getLocation(), Flags.BREAK_BLOCKS); } // Check for projectiles - if (e.getRemover() instanceof Projectile) { + if (e.getRemover() instanceof Projectile p) { // Find out who fired it - Projectile p = (Projectile)e.getRemover(); if (p.getShooter() instanceof Player) { checkIsland(e, (Player)p.getShooter(), e.getEntity().getLocation(), Flags.BREAK_BLOCKS); } @@ -118,9 +117,8 @@ public class BreakBlocksListener extends FlagListener { if (e.getDamager() instanceof Player) { // Check the break blocks flag notAllowed(e, (Player)e.getDamager(), e.getEntity().getLocation()); - } else if (e.getDamager() instanceof Projectile) { + } else if (e.getDamager() instanceof Projectile p) { // Find out who fired the arrow - Projectile p = (Projectile) e.getDamager(); if (p.getShooter() instanceof Player && notAllowed(e, (Player)p.getShooter(), e.getEntity().getLocation())) { e.getEntity().setFireTicks(0); p.setFireTicks(0); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreedingListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreedingListener.java index d509d9627..1548535b2 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreedingListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreedingListener.java @@ -73,8 +73,7 @@ public class BreedingListener extends FlagListener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true) public void onPlayerInteract(final PlayerInteractAtEntityEvent e) { Player p = e.getPlayer(); - if (e.getRightClicked() instanceof Animals && BREEDING_ITEMS.containsKey(e.getRightClicked().getType())) { - Animals animal = (Animals) e.getRightClicked(); + if (e.getRightClicked() instanceof Animals animal && BREEDING_ITEMS.containsKey(e.getRightClicked().getType())) { ItemStack inHand = p.getInventory().getItemInMainHand(); if (e.getHand().equals(EquipmentSlot.OFF_HAND)) { inHand = p.getInventory().getItemInOffHand(); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java index 3dd360185..02426ea85 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java @@ -40,18 +40,18 @@ public class BucketListener extends FlagListener { public void onBucketFill(final PlayerBucketFillEvent e) { // Check filling of various liquids switch (e.getItemStack().getType()) { - case LAVA_BUCKET: - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.COLLECT_LAVA); - return; - case WATER_BUCKET: - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.COLLECT_WATER); - return; - case MILK_BUCKET: - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.MILKING); - return; - default: - // Check general bucket use - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.BUCKET); + case LAVA_BUCKET -> { + checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.COLLECT_LAVA); + } + case WATER_BUCKET -> { + checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.COLLECT_WATER); + } + case MILK_BUCKET -> { + checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.MILKING); + } + default -> + // Check general bucket use + checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.BUCKET); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ElytraListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ElytraListener.java index 9338e5a9c..f3d4b585c 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ElytraListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ElytraListener.java @@ -18,8 +18,7 @@ public class ElytraListener extends FlagListener { */ @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onGlide(EntityToggleGlideEvent e) { - if (e.getEntity() instanceof Player) { - Player player = (Player) e.getEntity(); + if (e.getEntity() instanceof Player player) { if (!checkIsland(e, player, player.getLocation(), Flags.ELYTRA)) { player.setGliding(false); } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/HurtingListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/HurtingListener.java index d0e060912..887c278ef 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/HurtingListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/HurtingListener.java @@ -41,8 +41,8 @@ import world.bentobox.bentobox.versions.ServerCompatibility; */ public class HurtingListener extends FlagListener { - private Map thrownPotions = new HashMap<>(); - private Map firedFireworks = new WeakHashMap<>(); + private final Map thrownPotions = new HashMap<>(); + private final Map firedFireworks = new WeakHashMap<>(); /** * Handles mob and monster protection @@ -71,9 +71,8 @@ public class HurtingListener extends FlagListener { // Get the attacker if (damager instanceof Player) { checkIsland(e, (Player)damager, damager.getLocation(), flag); - } else if (damager instanceof Projectile) { + } else if (damager instanceof Projectile p) { // Find out who fired the projectile - Projectile p = (Projectile) damager; if (p.getShooter() instanceof Player && !checkIsland(e, (Player)p.getShooter(), damager.getLocation(), flag)) { e.getEntity().setFireTicks(0); } @@ -123,8 +122,7 @@ public class HurtingListener extends FlagListener { public void onSplashPotionSplash(final PotionSplashEvent e) { // Try to get the shooter Projectile projectile = e.getEntity(); - if (projectile.getShooter() instanceof Player) { - Player attacker = (Player)projectile.getShooter(); + if (projectile.getShooter() instanceof Player attacker) { // Run through all the affected entities for (LivingEntity entity: e.getAffectedEntities()) { // Self damage diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/InventoryListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/InventoryListener.java index f9e5275be..250969322 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/InventoryListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/InventoryListener.java @@ -72,9 +72,8 @@ public class InventoryListener extends FlagListener { else if (inventoryHolder instanceof ShulkerBox) { checkIsland(e, player, e.getInventory().getLocation(), Flags.SHULKER_BOX); } - else if (inventoryHolder instanceof Chest) { + else if (inventoryHolder instanceof Chest chestInventoryHolder) { // To differentiate between a Chest and a Trapped Chest we need to get the Block corresponding to the inventory - Chest chestInventoryHolder = (Chest) inventoryHolder; try { if (chestInventoryHolder.getType() == Material.TRAPPED_CHEST) { checkIsland(e, player, e.getInventory().getLocation(), Flags.TRAPPED_CHEST); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PhysicalInteractionListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PhysicalInteractionListener.java index d29e4330b..26ef9d7d8 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PhysicalInteractionListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PhysicalInteractionListener.java @@ -53,10 +53,9 @@ public class PhysicalInteractionListener extends FlagListener { */ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onProjectileHit(EntityInteractEvent e) { - if (!(e.getEntity() instanceof Projectile)) { + if (!(e.getEntity() instanceof Projectile p)) { return; } - Projectile p = (Projectile)e.getEntity(); if (p.getShooter() instanceof Player) { if (Tag.WOODEN_BUTTONS.isTagged(e.getBlock().getType())) { checkIsland(e, (Player)p.getShooter(), e.getBlock().getLocation(), Flags.BUTTON); @@ -71,23 +70,10 @@ public class PhysicalInteractionListener extends FlagListener { } private boolean isPressurePlate(Material material) { - switch(material) { - case STONE_PRESSURE_PLATE: - case POLISHED_BLACKSTONE_PRESSURE_PLATE: - case ACACIA_PRESSURE_PLATE: - case BIRCH_PRESSURE_PLATE: - case CRIMSON_PRESSURE_PLATE: - case DARK_OAK_PRESSURE_PLATE: - case HEAVY_WEIGHTED_PRESSURE_PLATE: - case JUNGLE_PRESSURE_PLATE: - case LIGHT_WEIGHTED_PRESSURE_PLATE: - case OAK_PRESSURE_PLATE: - case SPRUCE_PRESSURE_PLATE: - case WARPED_PRESSURE_PLATE: - return true; - default: - return false; - } + return switch (material) { + case STONE_PRESSURE_PLATE, POLISHED_BLACKSTONE_PRESSURE_PLATE, ACACIA_PRESSURE_PLATE, BIRCH_PRESSURE_PLATE, CRIMSON_PRESSURE_PLATE, DARK_OAK_PRESSURE_PLATE, HEAVY_WEIGHTED_PRESSURE_PLATE, JUNGLE_PRESSURE_PLATE, LIGHT_WEIGHTED_PRESSURE_PLATE, OAK_PRESSURE_PLATE, SPRUCE_PRESSURE_PLATE, WARPED_PRESSURE_PLATE -> true; + default -> false; + }; } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/TNTListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/TNTListener.java index 514d255bf..1d1b43a2e 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/TNTListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/TNTListener.java @@ -1,7 +1,5 @@ package world.bentobox.bentobox.listeners.flags.protection; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import org.bukkit.Location; @@ -31,13 +29,13 @@ public class TNTListener extends FlagListener { * Contains {@link EntityType}s that generates an explosion. * @since 1.5.0 */ - private static final List TNT_TYPES = Collections.unmodifiableList(Arrays.asList(EntityType.PRIMED_TNT, EntityType.MINECART_TNT)); + private static final List TNT_TYPES = List.of(EntityType.PRIMED_TNT, EntityType.MINECART_TNT); /** * Contains {@link Material}s that can be used to prime a TNT. * @since 1.5.0 */ - private static final List PRIMING_ITEMS = Collections.unmodifiableList(Arrays.asList(Material.FLINT_AND_STEEL, Material.FIRE_CHARGE)); + private static final List PRIMING_ITEMS = List.of(Material.FLINT_AND_STEEL, Material.FIRE_CHARGE); /** * Protect TNT from being set light by a fire arrow @@ -50,8 +48,7 @@ public class TNTListener extends FlagListener { return false; } // Stop TNT from being damaged if it is being caused by a visitor with a flaming arrow - if (e.getEntity() instanceof Projectile) { - Projectile projectile = (Projectile) e.getEntity(); + if (e.getEntity() instanceof Projectile projectile) { // Find out who fired it if (projectile.getShooter() instanceof Player && projectile.getFireTicks() > 0 && !checkIsland(e, (Player)projectile.getShooter(), e.getBlock().getLocation(), Flags.TNT_PRIMING)) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java index 0a39e2ad7..2cc2fee54 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java @@ -2,11 +2,12 @@ package world.bentobox.bentobox.listeners.flags.settings; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.WeakHashMap; import org.bukkit.Bukkit; -import org.bukkit.World; +import org.bukkit.Sound; import org.bukkit.entity.Entity; import org.bukkit.entity.Firework; import org.bukkit.entity.LivingEntity; @@ -23,6 +24,7 @@ import org.bukkit.event.entity.EntityShootBowEvent; import org.bukkit.event.entity.LingeringPotionSplashEvent; import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import world.bentobox.bentobox.api.events.flags.FlagSettingChangeEvent; import world.bentobox.bentobox.api.flags.Flag; @@ -38,8 +40,8 @@ import world.bentobox.bentobox.managers.RanksManager; */ public class PVPListener extends FlagListener { - private Map thrownPotions = new HashMap<>(); - private Map firedFireworks = new WeakHashMap<>(); + private final Map thrownPotions = new HashMap<>(); + private final Map firedFireworks = new WeakHashMap<>(); /** * This method protects players from PVP if it is not allowed and from @@ -54,6 +56,10 @@ public class PVPListener extends FlagListener { if (e.getEntity().equals(e.getDamager()) || e.getEntity().hasMetadata("NPC")) { return; } + // Is PVP allowed here? + if (this.PVPAllowed(e.getEntity().getLocation())) { + return; + } // Protect visitors if (e.getCause().equals(DamageCause.ENTITY_ATTACK) && protectedVisitor((Player)e.getEntity())) { if (e.getDamager() instanceof Player) { @@ -83,9 +89,8 @@ public class PVPListener extends FlagListener { user.notify(getFlag(damager.getWorld()).getHintReference()); e.setCancelled(true); } - } else if (damager instanceof Projectile && ((Projectile)damager).getShooter() instanceof Player) { + } else if (damager instanceof Projectile p && ((Projectile)damager).getShooter() instanceof Player) { // Find out who fired the arrow - Projectile p = (Projectile) damager; Player shooter =(Player)p.getShooter(); processDamage(e, damager, shooter, hurtEntity, flag); } else if (damager instanceof Firework && firedFireworks.containsKey(damager)) { @@ -116,6 +121,10 @@ public class PVPListener extends FlagListener { if (e.getCaught().equals(e.getPlayer()) || e.getCaught().hasMetadata("NPC")) { return; } + // Is PVP allowed here? + if (this.PVPAllowed(e.getCaught().getLocation())) { + return; + } // Protect visitors if (protectedVisitor((Player)e.getCaught())) { User.getInstance(e.getPlayer()).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); @@ -136,6 +145,10 @@ public class PVPListener extends FlagListener { public void onSplashPotionSplash(final PotionSplashEvent e) { if (e.getEntity().getShooter() instanceof Player && getPlugin().getIWM().inWorld(e.getEntity().getWorld())) { User user = User.getInstance((Player)e.getEntity().getShooter()); + // Is PVP allowed here? + if (this.PVPAllowed(e.getEntity().getLocation())) { + return; + } // Run through affected entities and cancel the splash for protected players for (LivingEntity le : e.getAffectedEntities()) { if (!le.getUniqueId().equals(user.getUniqueId()) && blockPVP(user, le, e, getFlag(e.getEntity().getWorld()))) { @@ -197,17 +210,6 @@ public class PVPListener extends FlagListener { } } - private Flag getFlag(World w) { - switch (w.getEnvironment()) { - case NETHER: - return Flags.PVP_NETHER; - case THE_END: - return Flags.PVP_END; - default: - return Flags.PVP_OVERWORLD; - } - } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true) public void onPlayerShootFireworkEvent(final EntityShootBowEvent e) { // Only care about players shooting fireworks @@ -228,4 +230,35 @@ public class PVPListener extends FlagListener { e.getIsland().getMemberSet(RanksManager.COOP_RANK).forEach(member -> User.getInstance(member).sendMessage(message)); } } + + /** + * Warn visitors if the island they are teleporting to has PVP on + * @param e teleport event + */ + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true) + public void onPlayerTeleport(PlayerTeleportEvent e) { + if (e.getTo() == null) { + return; + } + getIslands().getIslandAt(e.getTo()).ifPresent(island -> { + if (island.getMemberSet(RanksManager.COOP_RANK).contains(e.getPlayer().getUniqueId())) { + return; + } + if (island.isAllowed(Flags.PVP_OVERWORLD)) { + alertUser(e.getPlayer(), Flags.PVP_OVERWORLD); + } + if (island.isAllowed(Flags.PVP_NETHER)) { + alertUser(e.getPlayer(), Flags.PVP_NETHER); + } + if (island.isAllowed(Flags.PVP_END)) { + alertUser(e.getPlayer(), Flags.PVP_END); + } + }); + } + + private void alertUser(Player player, Flag flag) { + String message = "protection.flags." + flag.getID() + ".enabled"; + Objects.requireNonNull(User.getInstance(player)).sendMessage(message); + player.playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER,2F, 1F); + } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CleanSuperFlatListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CleanSuperFlatListener.java index 0a4390815..ed28ece90 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CleanSuperFlatListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CleanSuperFlatListener.java @@ -31,14 +31,14 @@ import world.bentobox.bentobox.util.Pair; */ public class CleanSuperFlatListener extends FlagListener { - private BentoBox plugin = BentoBox.getInstance(); + private final BentoBox plugin = BentoBox.getInstance(); /** * Stores pairs of X,Z coordinates of chunks that need to be regenerated. * @since 1.1 */ @NonNull - private Queue<@NonNull Pair<@NonNull Integer, @NonNull Integer>> chunkQueue = new LinkedList<>(); + private final Queue<@NonNull Pair<@NonNull Integer, @NonNull Integer>> chunkQueue = new LinkedList<>(); /** * Task that runs each tick to regenerate chunks that are in the {@link #chunkQueue}. diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java index e70571b83..814c982ed 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java @@ -41,8 +41,7 @@ public class CreeperListener extends FlagListener { } // Check for griefing Creeper creeper = (Creeper)e.getEntity(); - if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld()) && creeper.getTarget() instanceof Player) { - Player target = (Player)creeper.getTarget(); + if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld()) && creeper.getTarget() instanceof Player target) { if (!getIslands().locationIsOnIsland(target, e.getLocation())) { User user = User.getInstance(target); user.notify("protection.protected", TextVariables.DESCRIPTION, user.getTranslation(Flags.CREEPER_GRIEFING.getHintReference())); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/GeoLimitMobsListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/GeoLimitMobsListener.java index bded3d444..ae536c2f7 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/GeoLimitMobsListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/GeoLimitMobsListener.java @@ -24,7 +24,7 @@ import world.bentobox.bentobox.database.objects.Island; */ public class GeoLimitMobsListener extends FlagListener { - private Map mobSpawnTracker = new WeakHashMap<>(); + private final Map mobSpawnTracker = new WeakHashMap<>(); /** * Start the tracker when the plugin is loaded @@ -69,8 +69,7 @@ public class GeoLimitMobsListener extends FlagListener { public void onProjectileExplode(final ExplosionPrimeEvent e) { if (e.getEntity() instanceof Projectile && getIWM().inWorld(e.getEntity().getLocation())) { ProjectileSource source = ((Projectile)e.getEntity()).getShooter(); - if (source instanceof Entity) { - Entity shooter = (Entity)source; + if (source instanceof Entity shooter) { if (mobSpawnTracker.containsKey(shooter) && !mobSpawnTracker.get(shooter).onIsland(e.getEntity().getLocation())) { e.getEntity().remove(); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java index 87bbb4379..d8890723a 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java @@ -124,16 +124,17 @@ public class InvincibleVisitorsListener extends FlagListener implements ClickHan @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onVisitorGetDamage(EntityDamageEvent e) { World world = e.getEntity().getWorld(); - if (!(e.getEntity() instanceof Player) + if (!(e.getEntity() instanceof Player p) || !getIWM().inWorld(world) || e.getEntity().hasMetadata("NPC") || !getIWM().getIvSettings(world).contains(e.getCause().name()) - || getIslands().userIsOnIsland(world, User.getInstance(e.getEntity()))) { + || getIslands().userIsOnIsland(world, User.getInstance(e.getEntity())) + || PVPAllowed(p.getLocation()) + ) { return; } // Player is a visitor and should be protected from damage e.setCancelled(true); - Player p = (Player) e.getEntity(); // Handle the void - teleport player back to island in a safe spot if(e.getCause().equals(DamageCause.VOID)) { if (getIslands().getIslandAt(p.getLocation()).isPresent()) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/LiquidsFlowingOutListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/LiquidsFlowingOutListener.java index 9cb5b6e3a..3c533adbf 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/LiquidsFlowingOutListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/LiquidsFlowingOutListener.java @@ -38,7 +38,7 @@ public class LiquidsFlowingOutListener extends FlagListener { // Only prevent if it is flowing into the area between islands or into another island. Optional fromIsland = getIslands().getProtectedIslandAt(from.getLocation()); Optional toIsland = getIslands().getProtectedIslandAt(to.getLocation()); - if (!toIsland.isPresent() || (fromIsland.isPresent() && !fromIsland.equals(toIsland))) { + if (toIsland.isEmpty() || (fromIsland.isPresent() && !fromIsland.equals(toIsland))) { e.setCancelled(true); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/NaturalSpawningOutsideRangeListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/NaturalSpawningOutsideRangeListener.java index 769078eae..ade03ed48 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/NaturalSpawningOutsideRangeListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/NaturalSpawningOutsideRangeListener.java @@ -23,7 +23,7 @@ public class NaturalSpawningOutsideRangeListener extends FlagListener { } // If it is a natural spawn and there is no protected island at the location, block the spawn. - if (e.getSpawnReason() == CreatureSpawnEvent.SpawnReason.NATURAL && !getIslands().getProtectedIslandAt(e.getLocation()).isPresent()) { + if (e.getSpawnReason() == CreatureSpawnEvent.SpawnReason.NATURAL && getIslands().getProtectedIslandAt(e.getLocation()).isEmpty()) { e.setCancelled(true); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListener.java index bcff672a1..b312edab4 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListener.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.List; import org.bukkit.Bukkit; +import org.bukkit.FluidCollisionMode; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.Sound; @@ -51,7 +52,13 @@ public class ObsidianScoopingListener extends FlagListener { private boolean lookForLava(PlayerInteractEvent e) { Player player = e.getPlayer(); ItemStack bucket = e.getItem(); - Block b = e.getClickedBlock(); + + // Get block player is looking at + Block b = e.getPlayer().rayTraceBlocks(5, FluidCollisionMode.ALWAYS).getHitBlock(); + if (!b.getType().equals(Material.OBSIDIAN)) { + // This should not be needed but might catch some attempts + return false; + } User user = User.getInstance(player); if (getIslands().userIsOnIsland(user.getWorld(), user)) { // Look around to see if this is a lone obsidian block @@ -61,15 +68,14 @@ public class ObsidianScoopingListener extends FlagListener { } user.sendMessage("protection.flags.OBSIDIAN_SCOOPING.scooping"); player.getWorld().playSound(player.getLocation(), Sound.ITEM_BUCKET_FILL_LAVA, 1F, 1F); - b.setType(Material.AIR); e.setCancelled(true); - Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> givePlayerLava(player, bucket)); + Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> givePlayerLava(player, b, bucket)); return true; } return false; } - private void givePlayerLava(Player player, ItemStack bucket) { + private void givePlayerLava(Player player, Block b, ItemStack bucket) { if (bucket.getAmount() == 1) { // Needs some special handling when there is only 1 bucket in the stack bucket.setType(Material.LAVA_BUCKET); @@ -81,6 +87,8 @@ public class ObsidianScoopingListener extends FlagListener { map.values().forEach(i -> player.getWorld().dropItem(player.getLocation(), i)); } } + // Set block to air only after giving bucket + b.setType(Material.AIR); } private List getBlocksAround(Block b) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/PetTeleportListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/PetTeleportListener.java index 379c44de3..ced124ed8 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/PetTeleportListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/PetTeleportListener.java @@ -25,9 +25,8 @@ public class PetTeleportListener extends FlagListener { if (e.getTo() == null || !getIWM().inWorld(e.getFrom()) || !Flags.PETS_STAY_AT_HOME.isSetForWorld(e.getFrom().getWorld()) - || !(e.getEntity() instanceof Tameable) + || !(e.getEntity() instanceof Tameable t) ) return; - Tameable t = (Tameable)e.getEntity(); if (t.isTamed() && t.getOwner() != null) { // Get where the pet is going e.setCancelled(getIslands().getProtectedIslandAt(e.getTo()) diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/TreesGrowingOutsideRangeListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/TreesGrowingOutsideRangeListener.java index e927acd07..9f77ec728 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/TreesGrowingOutsideRangeListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/TreesGrowingOutsideRangeListener.java @@ -24,14 +24,14 @@ public class TreesGrowingOutsideRangeListener extends FlagListener { } // If there is no protected island at the location of the sapling, just cancel the event (prevents the sapling from growing). - if (!getIslands().getProtectedIslandAt(e.getLocation()).isPresent()) { + if (getIslands().getProtectedIslandAt(e.getLocation()).isEmpty()) { e.setCancelled(true); return; } // Now, run through all the blocks that will be generated and if there is no protected island at their location, turn them into AIR. e.getBlocks().stream() - .filter(blockState -> !getIslands().getProtectedIslandAt(blockState.getLocation()).isPresent()) + .filter(blockState -> getIslands().getProtectedIslandAt(blockState.getLocation()).isEmpty()) .forEach(blockState -> blockState.setType(Material.AIR)); } @@ -45,13 +45,13 @@ public class TreesGrowingOutsideRangeListener extends FlagListener { } // If there is no protected island at the location of the chorus flower, just cancel the event (prevents the flower from growing). - if (!getIslands().getProtectedIslandAt(e.getSource().getLocation()).isPresent()) { + if (getIslands().getProtectedIslandAt(e.getSource().getLocation()).isEmpty()) { e.setCancelled(true); return; } // Now prevent the flower to grow if this is growing outside the island - if (!getIslands().getProtectedIslandAt(e.getBlock().getLocation()).isPresent()) { + if (getIslands().getProtectedIslandAt(e.getBlock().getLocation()).isEmpty()) { e.setCancelled(true); } } diff --git a/src/main/java/world/bentobox/bentobox/lists/Flags.java b/src/main/java/world/bentobox/bentobox/lists/Flags.java index 057082afe..ec832e32c 100644 --- a/src/main/java/world/bentobox/bentobox/lists/Flags.java +++ b/src/main/java/world/bentobox/bentobox/lists/Flags.java @@ -422,7 +422,7 @@ public final class Flags { .listener(new PistonPushListener()) .build(); - private static InvincibleVisitorsListener ilv = new InvincibleVisitorsListener(); + private static final InvincibleVisitorsListener ilv = new InvincibleVisitorsListener(); public static final Flag INVINCIBLE_VISITORS = new Flag.Builder("INVINCIBLE_VISITORS", Material.DIAMOND_CHESTPLATE).type(Type.WORLD_SETTING) .listener(ilv).clickHandler(ilv).usePanel(true).build(); diff --git a/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java b/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java index 6378569dd..13bf14790 100644 --- a/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java +++ b/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java @@ -319,11 +319,11 @@ public enum GameModePlaceholder { */ OWNS_ISLAND("owns_island", (addon, user, island) -> String.valueOf(island != null && user != null && user.getUniqueId().equals(island.getOwner()))); - private String placeholder; + private final String placeholder; /** * @since 1.5.0 */ - private GameModePlaceholderReplacer replacer; + private final GameModePlaceholderReplacer replacer; GameModePlaceholder(String placeholder, GameModePlaceholderReplacer replacer) { this.placeholder = placeholder; diff --git a/src/main/java/world/bentobox/bentobox/lists/package-info.java b/src/main/java/world/bentobox/bentobox/lists/package-info.java new file mode 100644 index 000000000..d50fe1765 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/lists/package-info.java @@ -0,0 +1,7 @@ +/** + * This is where lists of things are put. For example Flags. + * + * @author tastybento, Poslovitch + * + */ +package world.bentobox.bentobox.lists; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index 9e0ae0d45..b7853161d 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -62,14 +62,18 @@ public class AddonsManager { private static final String GAMEMODE = "[gamemode]."; @NonNull - private List addons; + private final List addons; @NonNull - private Map<@NonNull Addon, @Nullable AddonClassLoader> loaders; + private final Map<@NonNull Addon, @Nullable AddonClassLoader> loaders; + @NonNull + private final Map<@NonNull Addon, @Nullable Plugin> pladdons; @NonNull private final Map> classes; - private BentoBox plugin; - private @NonNull Map<@NonNull String, @Nullable GameModeAddon> worldNames; - private @NonNull Map<@NonNull Addon, @NonNull List> listeners; + private final BentoBox plugin; + private @NonNull + final Map<@NonNull String, @Nullable GameModeAddon> worldNames; + private @NonNull + final Map<@NonNull Addon, @NonNull List> listeners; private final PluginLoader pluginLoader; @@ -77,6 +81,7 @@ public class AddonsManager { this.plugin = plugin; addons = new ArrayList<>(); loaders = new HashMap<>(); + pladdons = new HashMap<>(); classes = new HashMap<>(); listeners = new HashMap<>(); worldNames = new HashMap<>(); @@ -159,6 +164,9 @@ public class AddonsManager { if (pladdon instanceof Pladdon) { addon = ((Pladdon) pladdon).getAddon(); addon.setDescription(AddonClassLoader.asDescription(data)); + // Mark pladdon as enabled. + ((Pladdon) pladdon).setEnabled(); + pladdons.put(addon, pladdon); } else { plugin.logError("Could not load pladdon!"); return; @@ -211,8 +219,7 @@ public class AddonsManager { // Run the onLoad. addon.onLoad(); // if game mode, get the world name and generate - if (addon instanceof GameModeAddon && !addon.getState().equals(State.DISABLED)) { - GameModeAddon gameMode = (GameModeAddon) addon; + if (addon instanceof GameModeAddon gameMode && !addon.getState().equals(State.DISABLED)) { if (!gameMode.getWorldSettings().getWorldName().isEmpty()) { worldNames.put(gameMode.getWorldSettings().getWorldName().toLowerCase(Locale.ENGLISH), gameMode); } @@ -282,8 +289,7 @@ public class AddonsManager { plugin.log("Enabling " + addon.getDescription().getName() + " (" + addon.getDescription().getVersion() + ")..."); try { // If this is a GameModeAddon create the worlds, register it and load the blueprints - if (addon instanceof GameModeAddon) { - GameModeAddon gameMode = (GameModeAddon) addon; + if (addon instanceof GameModeAddon gameMode) { // Create the gameWorlds gameMode.createWorlds(); plugin.getIWM().addGameMode(gameMode); @@ -296,8 +302,7 @@ public class AddonsManager { plugin.log(addon.getDescription().getName() + " is disabled."); return; } - if (addon instanceof GameModeAddon) { - GameModeAddon gameMode = (GameModeAddon) addon; + if (addon instanceof GameModeAddon gameMode) { // Set the worlds for the commands gameMode.getPlayerCommand().ifPresent(c -> c.setWorld(gameMode.getOverWorld())); gameMode.getAdminCommand().ifPresent(c -> c.setWorld(gameMode.getOverWorld())); @@ -327,7 +332,7 @@ public class AddonsManager { plugin.logWarning("NOTE: DO NOT report this as a bug from BentoBox."); StringBuilder a = new StringBuilder(); addon.getDescription().getAuthors().forEach(author -> a.append(author).append(" ")); - plugin.getLogger().log(Level.SEVERE, "Please report this stack trace to the addon's author(s): " + a.toString(), e); + plugin.getLogger().log(Level.SEVERE, "Please report this stack trace to the addon's author(s): " + a, e); } @@ -404,6 +409,7 @@ public class AddonsManager { plugin.getCommandsManager().unregisterCommands(); // Clear all maps listeners.clear(); + pladdons.clear(); addons.clear(); loaders.clear(); classes.clear(); @@ -605,7 +611,7 @@ public class AddonsManager { try { addon.onDisable(); } catch (Exception e) { - plugin.logError("Error occured when disabling addon " + addon.getDescription().getName()); + plugin.logError("Error occurred when disabling addon " + addon.getDescription().getName()); plugin.logError("Report this to the addon's author(s)"); addon.getDescription().getAuthors().forEach(plugin::logError); plugin.logStacktrace(e); @@ -621,7 +627,11 @@ public class AddonsManager { addon.setState(State.DISABLED); loaders.remove(addon); } - + // Disable pladdons + if (pladdons.containsKey(addon)) { + this.pluginLoader.disablePlugin(Objects.requireNonNull(this.pladdons.get(addon))); + pladdons.remove(addon); + } // Remove it from the addons list addons.remove(addon); } diff --git a/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java b/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java index a14612107..2c852c593 100644 --- a/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java @@ -35,13 +35,13 @@ public class BlueprintClipboardManager { private static final String LOAD_ERROR = "Could not load blueprint file - does not exist : "; - private File blueprintFolder; + private final File blueprintFolder; private BlueprintClipboard clipboard; private Gson gson; - private BentoBox plugin; + private final BentoBox plugin; public BlueprintClipboardManager(BentoBox plugin, File blueprintFolder) { this(plugin, blueprintFolder, null); @@ -77,7 +77,7 @@ public class BlueprintClipboardManager { /** * Load a file to clipboard * @param fileName - filename in blueprints folder - * @throws IOException - if there's a load error with unziping or name + * @throws IOException - if there's a load error with unzipping or name */ public void load(String fileName) throws IOException { clipboard = new BlueprintClipboard(loadBlueprint(fileName)); diff --git a/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java b/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java index 8d7978686..6ef338ee2 100644 --- a/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java @@ -67,13 +67,15 @@ public class BlueprintsManager { * Inner map's key is the uniqueId of the blueprint bundle so it's * easy to get from a UI */ - private @NonNull Map> blueprintBundles; + private @NonNull + final Map> blueprintBundles; /** * Map of blueprints. There can be many blueprints per game mode addon * Inner map's key is the blueprint's name so it's easy to get from a UI */ - private @NonNull Map> blueprints; + private @NonNull + final Map> blueprints; /** * Gson used for serializing/deserializing the bundle class @@ -82,7 +84,8 @@ public class BlueprintsManager { private final @NonNull BentoBox plugin; - private @NonNull Set blueprintsLoaded; + private @NonNull + final Set blueprintsLoaded; public BlueprintsManager(@NonNull BentoBox plugin) { diff --git a/src/main/java/world/bentobox/bentobox/managers/CommandsManager.java b/src/main/java/world/bentobox/bentobox/managers/CommandsManager.java index 73e9297a9..571ed90bc 100644 --- a/src/main/java/world/bentobox/bentobox/managers/CommandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/CommandsManager.java @@ -18,7 +18,7 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; public class CommandsManager { @NonNull - private Map<@NonNull String, @NonNull CompositeCommand> commands = new HashMap<>(); + private final Map<@NonNull String, @NonNull CompositeCommand> commands = new HashMap<>(); private SimpleCommandMap commandMap; public void registerCommand(@NonNull CompositeCommand command) { diff --git a/src/main/java/world/bentobox/bentobox/managers/FlagsManager.java b/src/main/java/world/bentobox/bentobox/managers/FlagsManager.java index 49bcd4d85..1c35ab0a7 100644 --- a/src/main/java/world/bentobox/bentobox/managers/FlagsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/FlagsManager.java @@ -23,8 +23,9 @@ import world.bentobox.bentobox.lists.Flags; */ public class FlagsManager { - private @NonNull BentoBox plugin; - private Map<@NonNull Flag, @Nullable Addon> flags = new HashMap<>(); + private @NonNull + final BentoBox plugin; + private final Map<@NonNull Flag, @Nullable Addon> flags = new HashMap<>(); /** * Stores the flag listeners that have already been registered into Bukkit's API to avoid duplicates. @@ -32,7 +33,7 @@ public class FlagsManager { * This helps to make sure each flag listener is loaded correctly. * @see #registerListeners() */ - private Map<@NonNull Listener, @NonNull Boolean> registeredListeners = new HashMap<>(); + private final Map<@NonNull Listener, @NonNull Boolean> registeredListeners = new HashMap<>(); public FlagsManager(@NonNull BentoBox plugin) { this.plugin = plugin; diff --git a/src/main/java/world/bentobox/bentobox/managers/GameModePlaceholderManager.java b/src/main/java/world/bentobox/bentobox/managers/GameModePlaceholderManager.java index 3bab214d4..ba044cd1f 100644 --- a/src/main/java/world/bentobox/bentobox/managers/GameModePlaceholderManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/GameModePlaceholderManager.java @@ -19,7 +19,7 @@ import world.bentobox.bentobox.lists.GameModePlaceholder; @Deprecated public class GameModePlaceholderManager { - private BentoBox plugin; + private final BentoBox plugin; public GameModePlaceholderManager(BentoBox plugin) { this.plugin = plugin; diff --git a/src/main/java/world/bentobox/bentobox/managers/HooksManager.java b/src/main/java/world/bentobox/bentobox/managers/HooksManager.java index 9aa59843b..409fa73a5 100644 --- a/src/main/java/world/bentobox/bentobox/managers/HooksManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/HooksManager.java @@ -14,11 +14,11 @@ import world.bentobox.bentobox.api.hooks.Hook; */ public class HooksManager { - private BentoBox plugin; + private final BentoBox plugin; /** * List of successfully registered hooks. */ - private List hooks; + private final List hooks; public HooksManager(BentoBox plugin) { this.plugin = plugin; diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandDeletionManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandDeletionManager.java index 9f7e959eb..99206a296 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandDeletionManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandDeletionManager.java @@ -26,12 +26,12 @@ import world.bentobox.bentobox.util.Util; */ public class IslandDeletionManager implements Listener { - private BentoBox plugin; + private final BentoBox plugin; /** * Queue of islands to delete */ - private Database handler; - private Set inDeletion; + private final Database handler; + private final Set inDeletion; public IslandDeletionManager(BentoBox plugin) { this.plugin = plugin; @@ -52,7 +52,7 @@ public class IslandDeletionManager implements Listener { plugin.log("There are " + toBeDeleted.size() + " islands pending deletion."); toBeDeleted.forEach(di -> { if (di.getLocation() == null || di.getLocation().getWorld() == null) { - plugin.logError("Island queued for deletion refers to a non-existant game world. Skipping..."); + plugin.logError("Island queued for deletion refers to a non-existent game world. Skipping..."); toBeRemoved.add(di); } else { plugin.log("Resuming deletion of island at " + di.getLocation().getWorld().getName() + " " + Util.xyz(di.getLocation().toVector())); diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java index 18de91cb6..10a2f363a 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java @@ -34,11 +34,11 @@ import world.bentobox.bentobox.lists.Flags; */ public class IslandWorldManager { - private BentoBox plugin; + private final BentoBox plugin; /** * Map associating Worlds (Overworld, Nether and End) with the GameModeAddon that creates them. */ - private Map<@NonNull World, @NonNull GameModeAddon> gameModes; + private final Map<@NonNull World, @NonNull GameModeAddon> gameModes; /** * Manages worlds registered with BentoBox diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index bc0bfb1d8..b7c433759 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -66,7 +66,7 @@ import world.bentobox.bentobox.util.teleport.SafeSpotTeleport; */ public class IslandsManager { - private BentoBox plugin; + private final BentoBox plugin; // Tree species to boat material map private static final Map TREE_TO_BOAT = ImmutableMap.builder(). @@ -81,7 +81,7 @@ public class IslandsManager { * One island can be spawn, this is the one - otherwise, this value is null */ @NonNull - private Map<@NonNull World, @Nullable Island> spawn; + private final Map<@NonNull World, @Nullable Island> spawn; @NonNull private Database handler; @@ -90,20 +90,22 @@ public class IslandsManager { * The last locations where an island were put. * This is not stored persistently and resets when the server starts */ - private Map last; + private final Map last; // Island Cache @NonNull private IslandCache islandCache; // Quarantined islands @NonNull - private Map> quarantineCache; + private final Map> quarantineCache; // Deleted islands @NonNull - private List deletedIslands; + private final List deletedIslands; private boolean isSaveTaskRunning; + private final Set goingHome; + /** * Islands Manager * @param plugin - plugin @@ -119,6 +121,8 @@ public class IslandsManager { // This list should always be empty unless database deletion failed // In that case a purge utility may be required in the future deletedIslands = new ArrayList<>(); + // Mid-teleport players going home + goingHome = new HashSet<>(); } /** @@ -144,7 +148,7 @@ public class IslandsManager { depth = i; } else { Optional island = getIslandAt(l); - if (!island.isPresent()) { + if (island.isEmpty()) { return null; } i = island.get().getProtectionRange(); @@ -270,31 +274,12 @@ public class IslandsManager { return false; } // Known unsafe blocks - switch (ground) { + return switch (ground) { // Unsafe - case ANVIL: - case BARRIER: - case CACTUS: - case END_PORTAL: - case END_ROD: - case FIRE: - case FLOWER_POT: - case LADDER: - case LEVER: - case TALL_GRASS: - case PISTON_HEAD: - case MOVING_PISTON: - case TORCH: - case WALL_TORCH: - case TRIPWIRE: - case WATER: - case COBWEB: - case NETHER_PORTAL: - case MAGMA_BLOCK: - return false; - default: - return true; - } + case ANVIL, BARRIER, CACTUS, END_PORTAL, END_ROD, FIRE, FLOWER_POT, LADDER, LEVER, TALL_GRASS, PISTON_HEAD, + MOVING_PISTON, TORCH, WALL_TORCH, TRIPWIRE, WATER, COBWEB, NETHER_PORTAL, MAGMA_BLOCK -> false; + default -> true; + }; } /** @@ -324,7 +309,7 @@ public class IslandsManager { // This should never happen, so although this is a potential infinite loop I'm going to leave it here because // it will be bad if this does occur and the server should crash. plugin.logWarning("Duplicate island UUID occurred"); - island.setUniqueId(gmName + UUID.randomUUID().toString()); + island.setUniqueId(gmName + UUID.randomUUID()); } if (islandCache.addIsland(island)) { return island; @@ -453,7 +438,7 @@ public class IslandsManager { * * @param world - world to check * @param uuid - the player's UUID - * @return Location of the center of the player's protection area or null if an island does not exist. + * @return Location of the center of the player's protection area or null if an island does not exist. * Returns an island location OR a team island location */ @Nullable @@ -503,7 +488,7 @@ public class IslandsManager { * Will update the value based on world settings or island owner permissions (if online). * If the island is unowned, then this value will be 0. * @param island - island - * @param rank {@link RanksManager.MEMBER_RANK}, {@link RanksManager.COOP_RANK}, or {@link RanksManager.TRUSTED_RANK} + * @param rank {@link RanksManager#MEMBER_RANK}, {@link RanksManager#COOP_RANK}, or {@link RanksManager#TRUSTED_RANK} * @return max number of members. If negative, then this means unlimited. * @since 1.16.0 */ @@ -540,7 +525,7 @@ public class IslandsManager { /** * Sets the island max member size. * @param island - island - * @param rank {@link RanksManager.MEMBER_RANK}, {@link RanksManager.COOP_RANK}, or {@link RanksManager.TRUSTED_RANK} + * @param rank {@link RanksManager#MEMBER_RANK}, {@link RanksManager#COOP_RANK}, or {@link RanksManager#TRUSTED_RANK} * @param maxMembers - max number of members. If negative, then this means unlimited. Null means the world * default will be used. * @since 1.16.0 @@ -875,7 +860,7 @@ public class IslandsManager { } if (island.getOwner().equals(uuid)) { // Owner - island.setHomes(homes.entrySet().stream().collect(Collectors.toMap(this::getHomeName, Map.Entry::getKey))); + island.setHomes(homes.entrySet().stream().collect(Collectors.toMap(this::getHomeName, Map.Entry::getKey))); plugin.getPlayers().clearHomeLocations(world, uuid); } } @@ -919,7 +904,7 @@ public class IslandsManager { * @since 1.16.0 */ public boolean removeHomeLocation(@Nullable Island island, String name) { - return island == null ? false : island.removeHome(name); + return island != null && island.removeHome(name); } /** @@ -930,7 +915,7 @@ public class IslandsManager { * @return true if successful, false if not */ public boolean renameHomeLocation(@Nullable Island island, String oldName, String newName) { - return island == null ? false : island.renameHome(oldName, newName); + return island != null && island.renameHome(oldName, newName); } /** @@ -1076,6 +1061,7 @@ public class IslandsManager { CompletableFuture result = new CompletableFuture<>(); User user = User.getInstance(player); user.sendMessage("commands.island.go.teleport"); + goingHome.add(user.getUniqueId()); // Stop any gliding player.setGliding(false); // Check if the player is a passenger in a boat @@ -1172,7 +1158,13 @@ public class IslandsManager { if (plugin.getIWM().isOnJoinResetXP(world)) { user.getPlayer().setTotalExperience(0); } + + // Set the game mode + user.setGameMode(plugin.getIWM().getDefaultGameMode(world)); + } + // Remove from mid-teleport set + goingHome.remove(user.getUniqueId()); } /** @@ -1200,7 +1192,7 @@ public class IslandsManager { player.leaveVehicle(); // Remove the boat so they don't lie around everywhere boat.remove(); - Material boatMat = Material.getMaterial(((Boat) boat).getWoodType().toString() + "_BOAT"); + Material boatMat = Material.getMaterial(((Boat) boat).getWoodType() + "_BOAT"); if (boatMat == null) { boatMat = Material.OAK_BOAT; } @@ -1796,7 +1788,7 @@ public class IslandsManager { * @since 1.7.0 */ public boolean nameExists(@NonNull World world, @NonNull String name) { - return getIslands(world).stream().filter(island -> island.getName() != null).map(Island::getName) + return getIslands(world).stream().map(Island::getName).filter(Objects::nonNull) .anyMatch(n -> ChatColor.stripColor(n).equals(ChatColor.stripColor(name))); } @@ -1898,4 +1890,12 @@ public class IslandsManager { return r; } + /** + * Is user mid home teleport? + * @return true or false + */ + public boolean isGoingHome(User user) { + return goingHome.contains(user.getUniqueId()); + } + } diff --git a/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java b/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java index 9f0a4838e..934148c78 100644 --- a/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/LocalesManager.java @@ -35,8 +35,8 @@ import world.bentobox.bentobox.util.Util; */ public class LocalesManager { - private BentoBox plugin; - private Map languages = new HashMap<>(); + private final BentoBox plugin; + private final Map languages = new HashMap<>(); private static final String LOCALE_FOLDER = "locales"; private static final String BENTOBOX = "BentoBox"; private static final String SPACER = "*************************************************"; diff --git a/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java index bf5d8b9ca..b7e538c04 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java @@ -21,7 +21,7 @@ import world.bentobox.bentobox.lists.GameModePlaceholder; */ public class PlaceholdersManager { - private BentoBox plugin; + private final BentoBox plugin; public PlaceholdersManager(BentoBox plugin) { this.plugin = plugin; diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java index 5d5c260c9..03609dd48 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -28,12 +28,12 @@ import world.bentobox.bentobox.util.Util; public class PlayersManager { - private BentoBox plugin; + private final BentoBox plugin; private Database handler; - private Database names; + private final Database names; - private Map playerCache; - private Set inTeleport; + private final Map playerCache; + private final Set inTeleport; private boolean isSaveTaskRunning; diff --git a/src/main/java/world/bentobox/bentobox/managers/WebManager.java b/src/main/java/world/bentobox/bentobox/managers/WebManager.java index d06c236b7..dbd5ef1d5 100644 --- a/src/main/java/world/bentobox/bentobox/managers/WebManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/WebManager.java @@ -34,11 +34,15 @@ import world.bentobox.bentobox.web.credits.Contributor; */ public class WebManager { - private @NonNull BentoBox plugin; + private @NonNull + final BentoBox plugin; private @Nullable GitHubWebAPI gitHub; - private @NonNull List addonsCatalog; - private @NonNull List gamemodesCatalog; - private @NonNull Map> contributors; + private @NonNull + final List addonsCatalog; + private @NonNull + final List gamemodesCatalog; + private @NonNull + final Map> contributors; public WebManager(@NonNull BentoBox plugin) { this.plugin = plugin; diff --git a/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java b/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java index 11d3a117f..532699419 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java @@ -23,7 +23,7 @@ import world.bentobox.bentobox.util.Util; public class DefaultNewIslandLocationStrategy implements NewIslandLocationStrategy { /** - * The amount times to tolerate island check returning blocks without kwnon + * The amount times to tolerate island check returning blocks without known * island. */ protected static final Integer MAX_UNOWNED_ISLANDS = 20; @@ -102,7 +102,7 @@ public class DefaultNewIslandLocationStrategy implements NewIslandLocationStrate // Block check if (plugin.getIWM().isCheckForBlocks(world) && !plugin.getIWM().isUseOwnGenerator(world) - && Arrays.asList(BlockFace.values()).stream().anyMatch(bf -> + && Arrays.stream(BlockFace.values()).anyMatch(bf -> !location.getBlock().getRelative(bf).isEmpty() && !location.getBlock().getRelative(bf).getType().equals(Material.WATER))) { // Block found diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java index c0cf5278c..a577d601d 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -1,15 +1,12 @@ package world.bentobox.bentobox.managers.island; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; import org.bukkit.Location; import org.bukkit.World; @@ -115,7 +112,7 @@ public class IslandCache { grids.putIfAbsent(island.getWorld(), new IslandGrid()); return grids.get(island.getWorld()).removeFromGrid(island); } - + /** * Delete island from the cache by ID. Does not remove blocks. * @param uniqueId - island unique ID @@ -180,12 +177,10 @@ public class IslandCache { @NonNull public Collection getIslands(@NonNull World world) { World overworld = Util.getWorld(world); - List islandsInWorld = islandsByLocation.entrySet().stream() - .filter(entry -> overworld.equals(Util.getWorld(entry.getKey().getWorld()))) // shouldn't make NPEs - .map(Map.Entry::getValue) - .collect(Collectors.toCollection(ArrayList::new)); - return Collections.unmodifiableCollection(islandsInWorld); + return islandsByLocation.entrySet().stream() + .filter(entry -> overworld.equals(Util.getWorld(entry.getKey().getWorld()))) // shouldn't make NPEs + .map(Map.Entry::getValue).toList(); } /** diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java index bf49c8dd3..db404f1a3 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java @@ -12,8 +12,8 @@ import world.bentobox.bentobox.database.objects.Island; * */ class IslandGrid { - private TreeMap> grid = new TreeMap<>(); - private BentoBox plugin = BentoBox.getInstance(); + private final TreeMap> grid = new TreeMap<>(); + private final BentoBox plugin = BentoBox.getInstance(); /** * Adds island to grid @@ -39,7 +39,7 @@ class IslandGrid { if (firstLoaded.getOwner().equals(island.getOwner())) { // Find out which one is the original if (firstLoaded.getCreatedDate() > island.getCreatedDate()) { - plugin.logError("Same owner duplicate. Swaping based on creation date."); + plugin.logError("Same owner duplicate. Swapping based on creation date."); // FirstLoaded is the newer firstLoaded = new Island(island); zEntry.put(island.getMinZ(), firstLoaded); diff --git a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java index 5ccc74dbe..80c2cd9bf 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java @@ -26,14 +26,14 @@ import world.bentobox.bentobox.managers.BlueprintsManager; * */ public class NewIsland { - private BentoBox plugin; + private final BentoBox plugin; private Island island; private final User user; private final Reason reason; private final World world; private String name; private final boolean noPaste; - private GameModeAddon addon; + private final GameModeAddon addon; private NewIslandLocationStrategy locationStrategy; diff --git a/src/main/java/world/bentobox/bentobox/nms/NMSAbstraction.java b/src/main/java/world/bentobox/bentobox/nms/NMSAbstraction.java index 24bca0842..f2e30c157 100644 --- a/src/main/java/world/bentobox/bentobox/nms/NMSAbstraction.java +++ b/src/main/java/world/bentobox/bentobox/nms/NMSAbstraction.java @@ -16,6 +16,6 @@ public interface NMSAbstraction { * @param blockData - block data to set the block * @param applyPhysics - apply physics or not */ - public void setBlockInNativeChunk(Chunk chunk, int x, int y, int z, BlockData blockData, boolean applyPhysics); + void setBlockInNativeChunk(Chunk chunk, int x, int y, int z, BlockData blockData, boolean applyPhysics); } diff --git a/src/main/java/world/bentobox/bentobox/nms/package-info.java b/src/main/java/world/bentobox/bentobox/nms/package-info.java new file mode 100644 index 000000000..f0a4744d3 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/nms/package-info.java @@ -0,0 +1,12 @@ +/** + * Contains NMS related classes. + * + *

+ * Due to limitations in Maven and public building on CI's, only the most recent version of Minecraft + * is supported. + *

+ * + * @author tastybento + * + */ +package world.bentobox.bentobox.nms; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java b/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java index 304ae8c79..cee6b2d2f 100644 --- a/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/BlueprintManagementPanel.java @@ -9,7 +9,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.World; @@ -53,7 +52,7 @@ public class BlueprintManagementPanel { public static final int MAX_BP_SLOT = 35; private static final String INSTRUCTION = "instruction"; private Entry selected; - private Map blueprints = new HashMap<>(); + private final Map blueprints = new HashMap<>(); private final User user; private final GameModeAddon addon; @@ -242,7 +241,7 @@ public class BlueprintManagementPanel { protected PanelItem getBundleIcon(BlueprintBundle bb) { return new PanelItemBuilder() .name(t("edit-description")) - .description(bb.getDescription().stream().map(l -> ChatColor.translateAlternateColorCodes('&', l)).collect(Collectors.toList())) + .description(bb.getDescription().stream().map(Util::translateColorCodes).collect(Collectors.toList())) .icon(bb.getIcon()) .clickHandler((panel, u, clickType, slot) -> { u.closeInventory(); @@ -257,21 +256,22 @@ public class BlueprintManagementPanel { Material icon; String worldName; switch (env) { - case NORMAL: + case NORMAL -> { icon = Material.GRASS_BLOCK; worldName = normalBlueprint.getName(); - break; - case NETHER: + } + case NETHER -> { icon = Material.NETHERRACK; worldName = netherBlueprint.getName(); - break; - case THE_END: + } + case THE_END -> { icon = Material.END_STONE; worldName = endBlueprint.getName(); - break; - default: + } + default -> { icon = Material.STONE; worldName = Util.prettifyText(env.name()); + } } return new PanelItemBuilder() @@ -339,7 +339,7 @@ public class BlueprintManagementPanel { protected PanelItem getBlueprintItem(GameModeAddon addon, int pos, BlueprintBundle bb, Blueprint blueprint) { // Create description List desc = blueprint.getDescription() == null ? new ArrayList<>() : blueprint.getDescription(); - desc = desc.stream().map(l -> ChatColor.translateAlternateColorCodes('&', l)).collect(Collectors.toList()); + desc = desc.stream().map(Util::translateColorCodes).collect(Collectors.toList()); if ((!blueprint.equals(endBlueprint) && !blueprint.equals(normalBlueprint) && !blueprint.equals(netherBlueprint))) { if ((pos > MIN_WORLD_SLOT && pos < MAX_WORLD_SLOT)) { desc.add(t("remove")); diff --git a/src/main/java/world/bentobox/bentobox/panels/IconChanger.java b/src/main/java/world/bentobox/bentobox/panels/IconChanger.java index 7b138e65a..809b15455 100644 --- a/src/main/java/world/bentobox/bentobox/panels/IconChanger.java +++ b/src/main/java/world/bentobox/bentobox/panels/IconChanger.java @@ -21,10 +21,10 @@ import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; */ public class IconChanger implements PanelListener { - private GameModeAddon addon; - private BlueprintBundle bb; - private BlueprintManagementPanel blueprintManagementPanel; - private BentoBox plugin; + private final GameModeAddon addon; + private final BlueprintBundle bb; + private final BlueprintManagementPanel blueprintManagementPanel; + private final BentoBox plugin; /** * Change the icon of a blueprint bundle or blueprint diff --git a/src/main/java/world/bentobox/bentobox/panels/IslandCreationPanel.java b/src/main/java/world/bentobox/bentobox/panels/IslandCreationPanel.java index b4d5a21d5..b1a002bc6 100644 --- a/src/main/java/world/bentobox/bentobox/panels/IslandCreationPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/IslandCreationPanel.java @@ -5,7 +5,6 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; -import org.bukkit.ChatColor; import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.BentoBox; @@ -16,6 +15,8 @@ import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; import world.bentobox.bentobox.managers.BlueprintsManager; +import world.bentobox.bentobox.util.Util; + /** * Displays the available BlueprintBundles to pick up as the island. @@ -49,7 +50,7 @@ public class IslandCreationPanel { // Add an item PanelItem item = new PanelItemBuilder() .name(bb.getDisplayName()) - .description(bb.getDescription().stream().map(l -> ChatColor.translateAlternateColorCodes('&', l)).collect(Collectors.toList())) + .description(bb.getDescription().stream().map(Util::translateColorCodes).collect(Collectors.toList())) .icon(bb.getIcon()).clickHandler((panel, user1, clickType, slot1) -> { user1.closeInventory(); command.execute(user1, label, Collections.singletonList(bb.getUniqueId())); diff --git a/src/main/java/world/bentobox/bentobox/panels/LanguagePanel.java b/src/main/java/world/bentobox/bentobox/panels/LanguagePanel.java index cf4c2e830..ca2e96ef0 100644 --- a/src/main/java/world/bentobox/bentobox/panels/LanguagePanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/LanguagePanel.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.panels; import java.util.Locale; +import java.util.Objects; import org.apache.commons.lang.WordUtils; import org.bukkit.ChatColor; @@ -38,11 +39,8 @@ public class LanguagePanel { BentoBoxLocale language = localesManager.getLanguages().get(locale); ItemStack localeBanner = language.getBanner(); - if (localeBanner != null) { - localeIcon.icon(localeBanner); - } else { - localeIcon.icon(new ItemStack(Material.WHITE_BANNER, 1)); // Set to a blank banner. - } + // Set to a blank banner. + localeIcon.icon(Objects.requireNonNullElseGet(localeBanner, () -> new ItemStack(Material.WHITE_BANNER, 1))); localeIcon.name(ChatColor.WHITE + WordUtils.capitalize(locale.getDisplayName(user.getLocale()))) .clickHandler((panel, u, click, slot) -> { BentoBox.getInstance().getPlayers().setLocale(u.getUniqueId(), locale.toLanguageTag()); diff --git a/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java b/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java index b1f5a0e6e..3c6293c6a 100644 --- a/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java +++ b/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java @@ -53,86 +53,86 @@ public class ManagementPanel { int i = 0; List addons; switch (view) { - case GAMEMODES: - addons = plugin.getAddonsManager().getGameModeAddons(); - if (addons.isEmpty()) { - looksEmpty(builder, user); - break; - } - for (Addon addon : addons) { - GameModeAddon gameModeAddon = (GameModeAddon) addon; - PanelItem addonItem = new PanelItemBuilder() - .icon(addon.getDescription().getIcon()) - .name(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.name", TextVariables.NAME, addon.getDescription().getName())) - .description(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.description", - "[islands]", String.valueOf(addon.getIslands().getIslandCount(gameModeAddon.getOverWorld())))) - .clickHandler((panel, user1, clickType, slot) -> { - if (clickType.equals(ClickType.MIDDLE)) { - CreditsPanel.openPanel(user, addon); - } - return true; - }) - .build(); + case GAMEMODES -> { + addons = plugin.getAddonsManager().getGameModeAddons(); + if (addons.isEmpty()) { + looksEmpty(builder, user); + break; + } + for (Addon addon : addons) { + GameModeAddon gameModeAddon = (GameModeAddon) addon; + PanelItem addonItem = new PanelItemBuilder() + .icon(addon.getDescription().getIcon()) + .name(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.name", TextVariables.NAME, addon.getDescription().getName())) + .description(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.description", + "[islands]", String.valueOf(addon.getIslands().getIslandCount(gameModeAddon.getOverWorld())))) + .clickHandler((panel, user1, clickType, slot) -> { + if (clickType.equals(ClickType.MIDDLE)) { + CreditsPanel.openPanel(user, addon); + } + return true; + }) + .build(); - builder.item(startSlot + i, addonItem); + builder.item(startSlot + i, addonItem); - PanelItem blueprints = new PanelItemBuilder() - .icon(Material.STRUCTURE_BLOCK) - .name(user.getTranslation(LOCALE_REF + "views.gamemodes.blueprints.name")) - .description(user.getTranslation(LOCALE_REF + "views.gamemodes.blueprints.description")) - .clickHandler((panel, user1, clickType, slot) -> { - new BlueprintManagementPanel(plugin, user, gameModeAddon).openPanel(); - return true; - }) - .build(); + PanelItem blueprints = new PanelItemBuilder() + .icon(Material.STRUCTURE_BLOCK) + .name(user.getTranslation(LOCALE_REF + "views.gamemodes.blueprints.name")) + .description(user.getTranslation(LOCALE_REF + "views.gamemodes.blueprints.description")) + .clickHandler((panel, user1, clickType, slot) -> { + new BlueprintManagementPanel(plugin, user, gameModeAddon).openPanel(); + return true; + }) + .build(); - builder.item(startSlot + i + 9, blueprints); - i++; - } - break; - case ADDONS: - addons = plugin.getAddonsManager().getEnabledAddons().stream().filter(addon -> !(addon instanceof GameModeAddon)).collect(Collectors.toList()); - if (addons.isEmpty()) { - looksEmpty(builder, user); - break; - } - for (Addon addon : addons) { - PanelItem addonItem = new PanelItemBuilder() - .icon(addon.getDescription().getIcon()) - .name(ChatColor.WHITE + addon.getDescription().getName()) - .clickHandler((panel, user1, clickType, slot) -> { - if (clickType.equals(ClickType.MIDDLE)) { - CreditsPanel.openPanel(user, addon); - } - return true; - }) - .build(); - - builder.item(startSlot + i, addonItem); - i++; - if (builder.slotOccupied(startSlot + i)) { - i = i+2; + builder.item(startSlot + i + 9, blueprints); + i++; } } - break; - case HOOKS: - if (plugin.getHooks().getHooks().isEmpty()) { - looksEmpty(builder, user); - break; - } - for (Hook hook : plugin.getHooks().getHooks()) { - PanelItem hookItem = new PanelItemBuilder() - .icon(hook.getIcon()) - .name(ChatColor.WHITE + hook.getPluginName()) - .build(); + case ADDONS -> { + addons = plugin.getAddonsManager().getEnabledAddons().stream().filter(addon -> !(addon instanceof GameModeAddon)).collect(Collectors.toList()); + if (addons.isEmpty()) { + looksEmpty(builder, user); + break; + } + for (Addon addon : addons) { + PanelItem addonItem = new PanelItemBuilder() + .icon(addon.getDescription().getIcon()) + .name(ChatColor.WHITE + addon.getDescription().getName()) + .clickHandler((panel, user1, clickType, slot) -> { + if (clickType.equals(ClickType.MIDDLE)) { + CreditsPanel.openPanel(user, addon); + } + return true; + }) + .build(); - builder.item(startSlot + i, hookItem); - i++; - if (builder.slotOccupied(startSlot + i)) { - i = i+2; + builder.item(startSlot + i, addonItem); + i++; + if (builder.slotOccupied(startSlot + i)) { + i = i + 2; + } + } + } + case HOOKS -> { + if (plugin.getHooks().getHooks().isEmpty()) { + looksEmpty(builder, user); + break; + } + for (Hook hook : plugin.getHooks().getHooks()) { + PanelItem hookItem = new PanelItemBuilder() + .icon(hook.getIcon()) + .name(ChatColor.WHITE + hook.getPluginName()) + .build(); + + builder.item(startSlot + i, hookItem); + i++; + if (builder.slotOccupied(startSlot + i)) { + i = i + 2; + } } } - break; } // Setup a few more buttons @@ -196,15 +196,9 @@ public class ManagementPanel { }); switch (view) { - case GAMEMODES: - gamemodesIconBuilder.glow(true); - break; - case ADDONS: - addonsIconBuilder.glow(true); - break; - case HOOKS: - hooksIconBuilder.glow(true); - break; + case GAMEMODES -> gamemodesIconBuilder.glow(true); + case ADDONS -> addonsIconBuilder.glow(true); + case HOOKS -> hooksIconBuilder.glow(true); } builder.item(1, gamemodesIconBuilder.build()); @@ -235,16 +229,9 @@ public class ManagementPanel { TextVariables.VERSION, serverVersion != null ? serverVersion.toString() : user.getTranslation("general.invalid"))); switch (compatibility) { - case COMPATIBLE: - case SUPPORTED: - compatibilityItemBuilder.icon(Material.GREEN_CONCRETE); - break; - case NOT_SUPPORTED: - compatibilityItemBuilder.icon(Material.ORANGE_CONCRETE); - break; - case INCOMPATIBLE: - compatibilityItemBuilder.icon(Material.RED_CONCRETE); - break; + case COMPATIBLE, SUPPORTED -> compatibilityItemBuilder.icon(Material.GREEN_CONCRETE); + case NOT_SUPPORTED -> compatibilityItemBuilder.icon(Material.ORANGE_CONCRETE); + case INCOMPATIBLE -> compatibilityItemBuilder.icon(Material.RED_CONCRETE); } builder.item(7, compatibilityItemBuilder.build()); diff --git a/src/main/java/world/bentobox/bentobox/panels/package-info.java b/src/main/java/world/bentobox/bentobox/panels/package-info.java new file mode 100644 index 000000000..48ad3f9c2 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/panels/package-info.java @@ -0,0 +1,11 @@ +/** + * Contains non-API panel implementations used by BentoBox + * + *

+ * These are GUIs such as the settings, blueprints, island creation panels, etc. + * They use the Panel API. + *

+ * @author tastybento + * + */ +package world.bentobox.bentobox.panels; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java index 9e9e2d97c..cc3dcbcd7 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java @@ -135,27 +135,22 @@ public class SettingsTab implements Tab, ClickHandler { icons.put(5, Flags.LOCK.toPanelItem(plugin, user, island, false)); } // Add the mode icon - switch(plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId())) { - case ADVANCED: - icons.put(7, new PanelItemBuilder().icon(Material.GOLD_INGOT) + switch (plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId())) { + case ADVANCED -> icons.put(7, new PanelItemBuilder().icon(Material.GOLD_INGOT) .name(user.getTranslation(PROTECTION_PANEL + "mode.advanced.name")) .description(user.getTranslation(PROTECTION_PANEL + "mode.advanced.description"), "", user.getTranslation(CLICK_TO_SWITCH, TextVariables.NEXT, user.getTranslation(PROTECTION_PANEL + "mode.expert.name"))) .clickHandler(this) .build()); - break; - case EXPERT: - icons.put(7, new PanelItemBuilder().icon(Material.NETHER_BRICK) + case EXPERT -> icons.put(7, new PanelItemBuilder().icon(Material.NETHER_BRICK) .name(user.getTranslation(PROTECTION_PANEL + "mode.expert.name")) .description(user.getTranslation(PROTECTION_PANEL + "mode.expert.description"), "", user.getTranslation(CLICK_TO_SWITCH, TextVariables.NEXT, user.getTranslation(PROTECTION_PANEL + "mode.basic.name"))) .clickHandler(this) .build()); - break; - default: - icons.put(7, new PanelItemBuilder().icon(Material.IRON_INGOT) + default -> icons.put(7, new PanelItemBuilder().icon(Material.IRON_INGOT) .name(user.getTranslation(PROTECTION_PANEL + "mode.basic.name")) .description(user.getTranslation(PROTECTION_PANEL + "mode.basic.description"), "", user.getTranslation(CLICK_TO_SWITCH, @@ -219,8 +214,7 @@ public class SettingsTab implements Tab, ClickHandler { public boolean onClick(Panel panel, User user, ClickType clickType, int slot) { // Cycle the mode plugin.getPlayers().setFlagsDisplayMode(user.getUniqueId(), plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId()).getNext()); - if (panel instanceof TabbedPanel) { - TabbedPanel tp = ((TabbedPanel)panel); + if (panel instanceof TabbedPanel tp) { tp.setActivePage(0); tp.refreshPanel(); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_OFF, 1F, 1F); diff --git a/src/main/java/world/bentobox/bentobox/util/DeleteIslandChunks.java b/src/main/java/world/bentobox/bentobox/util/DeleteIslandChunks.java index fc81f2104..593b550d8 100644 --- a/src/main/java/world/bentobox/bentobox/util/DeleteIslandChunks.java +++ b/src/main/java/world/bentobox/bentobox/util/DeleteIslandChunks.java @@ -7,7 +7,6 @@ import java.util.concurrent.CompletableFuture; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; -import org.bukkit.World.Environment; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.generator.ChunkGenerator; @@ -33,22 +32,38 @@ public class DeleteIslandChunks { private int chunkX; private int chunkZ; private BukkitTask task; - private IslandDeletion di; + private final IslandDeletion di; private boolean inDelete; - private BentoBox plugin; + private final BentoBox plugin; private NMSAbstraction nms; + private final World netherWorld; + private final World endWorld; public DeleteIslandChunks(BentoBox plugin, IslandDeletion di) { this.plugin = plugin; this.chunkX = di.getMinXChunk(); this.chunkZ = di.getMinZChunk(); this.di = di; + // Nether + if (plugin.getIWM().isNetherGenerate(di.getWorld()) && plugin.getIWM().isNetherIslands(di.getWorld())) { + netherWorld = plugin.getIWM().getNetherWorld(di.getWorld()); + } else { + netherWorld = null; + } + // End + if (plugin.getIWM().isEndGenerate(di.getWorld()) && plugin.getIWM().isEndIslands(di.getWorld())) { + endWorld = plugin.getIWM().getEndWorld(di.getWorld()); + } else { + endWorld = null; + } + // NMS try { this.nms = Util.getNMS(); } catch (Exception e) { plugin.logError("Could not delete chunks because of NMS error"); return; } + // Fire event IslandEvent.builder().deletedIslandInfo(di).reason(Reason.DELETE_CHUNKS).build(); regenerateChunks(); @@ -62,13 +77,15 @@ public class DeleteIslandChunks { inDelete = true; for (int i = 0; i < plugin.getSettings().getDeleteSpeed(); i++) { boolean last = i == plugin.getSettings().getDeleteSpeed() -1; + final int x = chunkX; + final int z = chunkZ; plugin.getIWM().getAddon(di.getWorld()).ifPresent(gm -> // Overworld - processChunk(gm, Environment.NORMAL, chunkX, chunkZ).thenRun(() -> + processChunk(gm, di.getWorld(), x, z).thenRun(() -> // Nether - processChunk(gm, Environment.NETHER, chunkX, chunkZ).thenRun(() -> + processChunk(gm, netherWorld, x, z).thenRun(() -> // End - processChunk(gm, Environment.THE_END, chunkX, chunkZ).thenRun(() -> finish(last))))); + processChunk(gm, endWorld, x, z).thenRun(() -> finish(last, x))))); chunkZ++; if (chunkZ > di.getMaxZChunk()) { chunkZ = di.getMinZChunk(); @@ -79,8 +96,8 @@ public class DeleteIslandChunks { } - private void finish(boolean last) { - if (chunkX > di.getMaxXChunk()) { + private void finish(boolean last, int x) { + if (x > di.getMaxXChunk()) { // Fire event IslandEvent.builder().deletedIslandInfo(di).reason(Reason.DELETED).build(); // We're done @@ -91,41 +108,26 @@ public class DeleteIslandChunks { } } - private CompletableFuture processChunk(GameModeAddon gm, Environment env, int x, int z) { - World world = di.getWorld(); - switch (env) { - case NETHER: - // Nether - if (plugin.getIWM().isNetherGenerate(di.getWorld()) && plugin.getIWM().isNetherIslands(di.getWorld())) { - world = plugin.getIWM().getNetherWorld(di.getWorld()); - } else { - return CompletableFuture.completedFuture(false); - } - break; - case THE_END: - // End - if (plugin.getIWM().isEndGenerate(di.getWorld()) && plugin.getIWM().isEndIslands(di.getWorld())) { - world = plugin.getIWM().getEndWorld(di.getWorld()); - } else { - return CompletableFuture.completedFuture(false); - } - break; - default: - break; - } - if (PaperLib.isChunkGenerated(world, x, z)) { + private CompletableFuture processChunk(GameModeAddon gm, World world, int x, int z) { + if (world != null) { CompletableFuture r = new CompletableFuture<>(); - PaperLib.getChunkAtAsync(world, x, z).thenAccept(chunk -> regenerateChunk(r, gm, chunk)); + PaperLib.getChunkAtAsync(world, x, z).thenAccept(chunk -> regenerateChunk(r, gm, chunk, x, z)); return r; } return CompletableFuture.completedFuture(false); } - private void regenerateChunk(CompletableFuture r, GameModeAddon gm, Chunk chunk) { + private void regenerateChunk(CompletableFuture r, GameModeAddon gm, Chunk chunk, int x, int z) { // Clear all inventories Arrays.stream(chunk.getTileEntities()).filter(te -> (te instanceof InventoryHolder)) .filter(te -> di.inBounds(te.getLocation().getBlockX(), te.getLocation().getBlockZ())) .forEach(te -> ((InventoryHolder)te).getInventory().clear()); + // Remove all entities + for (Entity e : chunk.getEntities()) { + if (!(e instanceof Player)) { + e.remove(); + } + } // Reset blocks MyBiomeGrid grid = new MyBiomeGrid(chunk.getWorld().getEnvironment()); ChunkGenerator cg = gm.getDefaultWorldGenerator(chunk.getWorld().getName(), "delete"); diff --git a/src/main/java/world/bentobox/bentobox/util/FileLister.java b/src/main/java/world/bentobox/bentobox/util/FileLister.java index 836ad575b..42e027d12 100644 --- a/src/main/java/world/bentobox/bentobox/util/FileLister.java +++ b/src/main/java/world/bentobox/bentobox/util/FileLister.java @@ -20,7 +20,7 @@ import org.bukkit.plugin.java.JavaPlugin; * @author Poslovitch */ public class FileLister{ - private Plugin plugin; + private final Plugin plugin; public FileLister(Plugin level){ plugin = level; diff --git a/src/main/java/world/bentobox/bentobox/util/IslandInfo.java b/src/main/java/world/bentobox/bentobox/util/IslandInfo.java new file mode 100644 index 000000000..99886efd0 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/util/IslandInfo.java @@ -0,0 +1,140 @@ +package world.bentobox.bentobox.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.Nullable; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.localization.TextVariables; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.RanksManager; + +/** + * @author tastybento + * @since 1.17.3 + */ +public class IslandInfo { + + private final BentoBox plugin; + private final Island island; + private final @Nullable UUID owner; + private final World world; + + + /** + * @param plugin + * @param island Island to show info + */ + public IslandInfo(Island island) { + this.plugin = BentoBox.getInstance(); + this.island = island; + this.owner = island.getOwner(); + this.world = island.getWorld(); + } + + /** + * Shows admin info of this island + * @param user user asking + */ + public void showAdminInfo(User user) { + user.sendMessage("commands.admin.info.title"); + user.sendMessage("commands.admin.info.island-uuid", "[uuid]", island.getUniqueId()); + if (owner == null) { + user.sendMessage("commands.admin.info.unowned"); + } else { + user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(owner), "[uuid]", owner.toString()); + + // Fixes #getLastPlayed() returning 0 when it is the owner's first connection. + long lastPlayed = (Bukkit.getOfflinePlayer(owner).getLastPlayed() != 0) ? + Bukkit.getOfflinePlayer(owner).getLastPlayed() : Bukkit.getOfflinePlayer(owner).getFirstPlayed(); + String formattedDate; + try { + String dateTimeFormat = plugin.getLocalesManager().get("commands.admin.info.last-login-date-time-format"); + formattedDate = new SimpleDateFormat(dateTimeFormat).format(new Date(lastPlayed)); + } catch (NullPointerException | IllegalArgumentException ignored) { + formattedDate = new Date(lastPlayed).toString(); + } + user.sendMessage("commands.admin.info.last-login","[date]", formattedDate); + + user.sendMessage("commands.admin.info.deaths", "[number]", String.valueOf(plugin.getPlayers().getDeaths(world, owner))); + String resets = String.valueOf(plugin.getPlayers().getResets(world, owner)); + String total = plugin.getIWM().getResetLimit(world) < 0 ? "Unlimited" : String.valueOf(plugin.getIWM().getResetLimit(world)); + user.sendMessage("commands.admin.info.resets-left", "[number]", resets, "[total]", total); + // Show team members + showMembers(user); + } + Vector location = island.getProtectionCenter().toVector(); + user.sendMessage("commands.admin.info.island-protection-center", TextVariables.XYZ, Util.xyz(location)); + user.sendMessage("commands.admin.info.island-center", TextVariables.XYZ, Util.xyz(island.getCenter().toVector())); + user.sendMessage("commands.admin.info.island-coords", "[xz1]", Util.xyz(new Vector(island.getMinX(), 0, island.getMinZ())), "[xz2]", Util.xyz(new Vector(island.getMaxX(), 0, island.getMaxZ()))); + user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(island.getProtectionRange())); + user.sendMessage("commands.admin.info.max-protection-range", "[range]", String.valueOf(island.getMaxEverProtectionRange())); + user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX(), 0, island.getMaxProtectedZ()))); + if (island.isSpawn()) { + user.sendMessage("commands.admin.info.is-spawn"); + } + if (!island.getBanned().isEmpty()) { + user.sendMessage("commands.admin.info.banned-players"); + island.getBanned().forEach(u -> user.sendMessage("commands.admin.info.banned-format", TextVariables.NAME, plugin.getPlayers().getName(u))); + } + if (island.getPurgeProtected()) { + user.sendMessage("commands.admin.info.purge-protected"); + } + } + + + /** + * Shows info of this island to this user. + * @param user the User who is requesting it + * @return always true + */ + public boolean showInfo(User user) { + user.sendMessage("commands.admin.info.title"); + if (owner == null) { + user.sendMessage("commands.admin.info.unowned"); + } else { + user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(owner)); + user.sendMessage("commands.admin.info.deaths", "[number]", String.valueOf(plugin.getPlayers().getDeaths(world, owner))); + String resets = String.valueOf(plugin.getPlayers().getResets(world, owner)); + String total = plugin.getIWM().getResetLimit(world) < 0 ? "Unlimited" : String.valueOf(plugin.getIWM().getResetLimit(world)); + user.sendMessage("commands.admin.info.resets-left", "[number]", resets, "[total]", total); + // Show team members + showMembers(user); + } + Vector location = island.getProtectionCenter().toVector(); + user.sendMessage("commands.admin.info.island-center", TextVariables.XYZ, Util.xyz(location)); + user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(island.getProtectionRange())); + user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX(), 0, island.getMaxProtectedZ()))); + if (island.isSpawn()) { + user.sendMessage("commands.admin.info.is-spawn"); + } + if (!island.getBanned().isEmpty()) { + user.sendMessage("commands.admin.info.banned-players"); + island.getBanned().forEach(u -> user.sendMessage("commands.admin.info.banned-format", TextVariables.NAME, plugin.getPlayers().getName(u))); + } + return true; + } + + /** + * Shows the members of this island to this user. + * @param user the User who is requesting it + */ + public void showMembers(User user) { + user.sendMessage("commands.admin.info.team-members-title"); + island.getMembers().forEach((u, i) -> { + if (owner.equals(u)) { + user.sendMessage("commands.admin.info.team-owner-format", TextVariables.NAME, plugin.getPlayers().getName(u) + , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); + } else if (i > RanksManager.VISITOR_RANK){ + user.sendMessage("commands.admin.info.team-member-format", TextVariables.NAME, plugin.getPlayers().getName(u) + , "[rank]", user.getTranslation(plugin.getRanksManager().getRank(i))); + } + }); + } +} diff --git a/src/main/java/world/bentobox/bentobox/util/ItemParser.java b/src/main/java/world/bentobox/bentobox/util/ItemParser.java index 7b751483b..feb21ae42 100644 --- a/src/main/java/world/bentobox/bentobox/util/ItemParser.java +++ b/src/main/java/world/bentobox/bentobox/util/ItemParser.java @@ -1,17 +1,25 @@ package world.bentobox.bentobox.util; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.PatternType; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BannerMeta; -import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.*; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType; +import org.eclipse.jdt.annotation.Nullable; + +import java.lang.reflect.Field; +import java.util.MissingFormatArgumentException; +import java.util.UUID; import world.bentobox.bentobox.BentoBox; + /** * Utility class that parses a String into an ItemStack. * It is used for converting config file entries to objects. @@ -20,63 +28,123 @@ import world.bentobox.bentobox.BentoBox; */ public class ItemParser { - private ItemParser() {} - - public static ItemStack parse(String s){ - if (s == null) { - return null; - } - String[] part = s.split(":"); - - // Material-specific handling - if (part[0].contains("POTION") || part[0].equalsIgnoreCase("TIPPED_ARROW")) { - return potion(part); - } else if (part[0].contains("BANNER")) { - return banner(part); - } - - // Generic handling - if (part.length == 2) { - // Material:Qty - return two(part); - } else if (part.length == 3) { - // Material:Durability:Qty - return three(part); - } - return null; + /** + * Parse given string to ItemStack. + * @param text String value of item stack. + * @return ItemStack of parsed item or null. + */ + public static ItemStack parse(String text) { + return ItemParser.parse(text, null); } - private static ItemStack two(String[] part) { - int reqAmount; - try { - reqAmount = Integer.parseInt(part[1]); - } catch (Exception e) { - return null; + + /** + * Parse given string to ItemStack. + * @param text String value of item stack. + * @param defaultItemStack Material that should be returned if parsing failed. + * @return ItemStack of parsed item or defaultItemStack. + */ + @Nullable + public static ItemStack parse(@Nullable String text, @Nullable ItemStack defaultItemStack) { + if (text == null || text.isBlank()) { + // Text does not exist or is empty. + return defaultItemStack; } - Material reqItem = Material.getMaterial(part[0].toUpperCase(java.util.Locale.ENGLISH)); - if (reqItem == null) { - return null; + String[] part = text.split(":"); + + try { + // Check if there are more properties for the item stack + if (part.length == 1) { + // Parse material directly. It does not have any extra properties. + return new ItemStack(Material.valueOf(text.toUpperCase())); + } + // Material-specific handling + else if (part[0].contains("POTION") || part[0].equalsIgnoreCase("TIPPED_ARROW")) { + // Parse Potions and Tipped Arrows + return parsePotion(part); + } else if (part[0].contains("BANNER")) { + // Parse Banners + return parseBanner(part); + } else if (part[0].equalsIgnoreCase("PLAYER_HEAD")) { + // Parse Player Heads + return parsePlayerHead(part); + } + // Generic handling + else if (part.length == 2) { + // Material:Qty + return parseItemQuantity(part); + } else if (part.length == 3) { + // Material:Durability:Qty + return parseItemDurabilityAndQuantity(part); + } + } catch (Exception exception) { + BentoBox.getInstance().logError("Could not parse item " + text + " " + exception.getLocalizedMessage()); } + + return defaultItemStack; + } + + + /** + * This method parses array of 2 items into an item stack. + * First array element is material, while second array element is integer, that represents item count. + * Example: + * DIAMOND:20 + * @param part String array that contains 2 elements. + * @return ItemStack with material from first array element and amount based on second array element. + */ + private static ItemStack parseItemQuantity(String[] part) { + int reqAmount = Integer.parseInt(part[1]); + Material reqItem = Material.getMaterial(part[0].toUpperCase(java.util.Locale.ENGLISH)); + + if (reqItem == null) { + throw new IllegalArgumentException(part[0] + " is not a valid Material."); + } + return new ItemStack(reqItem, reqAmount); } - private static ItemStack three(String[] part) { + + /** + * This method parses array of 3 items into an item stack. + * First array element is material, while second and third array element are integers. + * The middle element represents durability, while third element represents quantity. + * Example: + * IRON_SWORD:20:1 + * @param part String array that contains 3 elements. + * @return ItemStack with material from first array element, durability from second element and amount based on third array element. + */ + private static ItemStack parseItemDurabilityAndQuantity(String[] part) { // Rearrange - String[] twoer = {part[0], part[2]}; - return two(twoer); + String[] parsable = {part[0], part[2]}; + ItemStack durability = parseItemQuantity(parsable); + + ItemMeta meta = durability.getItemMeta(); + + if (meta instanceof Damageable) { + ((Damageable) meta).setDamage(Integer.parseInt(part[1])); + durability.setItemMeta(meta); + } + + return durability; } - private static ItemStack potion(String[] part) { + + /** + * This method parses array of 6 items into an item stack. + * Format: + * POTION:NAME::::QTY + * Example: + * POTION:STRENGTH:1:EXTENDED:SPLASH:1 + * @param part String array that contains 6 elements. + * @return Potion with given properties. + */ + private static ItemStack parsePotion(String[] part) { if (part.length != 6) { - return null; - } - int reqAmount; - try { - reqAmount = Integer.parseInt(part[5]); - } catch (Exception e) { - return null; + throw new MissingFormatArgumentException("Potion parsing requires 6 parts."); } + /* * # Format POTION:NAME::::QTY # LEVEL, EXTENDED, SPLASH, LINGER are optional. @@ -103,35 +171,118 @@ public class ItemParser { boolean isExtended = part[3].equalsIgnoreCase("EXTENDED"); PotionData data = new PotionData(type, isExtended, isUpgraded); potionMeta.setBasePotionData(data); - - result.setAmount(reqAmount); + result.setItemMeta(potionMeta); + result.setAmount(Integer.parseInt(part[5])); return result; } - private static ItemStack banner(String[] part) { - try { - if (part.length >= 2) { - Material bannerMat = Material.getMaterial(part[0]); - if (bannerMat == null) { - BentoBox.getInstance().logError("Could not parse banner item " + part[0] + " so using a white banner."); - bannerMat = Material.WHITE_BANNER; - } - ItemStack result = new ItemStack(bannerMat, Integer.parseInt(part[1])); - BannerMeta meta = (BannerMeta) result.getItemMeta(); - if (meta != null) { - for (int i = 2; i < part.length; i += 2) { - meta.addPattern(new Pattern(DyeColor.valueOf(part[i + 1]), PatternType.valueOf(part[i]))); - } - result.setItemMeta(meta); - } - - return result; - } else { - return null; + /** + * This method parses array of multiple elements for the Banner. + * @param part String array that contains at least 2 elements. + * @return Banner as item stack. + */ + private static ItemStack parseBanner(String[] part) { + if (part.length >= 2) { + Material bannerMat = Material.getMaterial(part[0]); + if (bannerMat == null) { + BentoBox.getInstance().logError("Could not parse banner item " + part[0] + " so using a white banner."); + bannerMat = Material.WHITE_BANNER; } - } catch (Exception e) { - return null; + ItemStack result = new ItemStack(bannerMat, Integer.parseInt(part[1])); + + BannerMeta meta = (BannerMeta) result.getItemMeta(); + if (meta != null) { + for (int i = 2; i < part.length; i += 2) { + meta.addPattern(new Pattern(DyeColor.valueOf(part[i + 1]), PatternType.valueOf(part[i]))); + } + result.setItemMeta(meta); + } + + return result; + } else { + throw new MissingFormatArgumentException("Banner parsing requires at least 2 parts."); + } + } + + + /** + * This method parses array of 2 to 3 elements that represents player head. + * Format: + * PLAYER_HEAD::QTY + * PLAYER_HEAD: + * PLAYER_HEAD:QTY + * Example: + * PLAYER_HEAD:1 + * PLAYER_HEAD:BONNe1704 + * PLAYER_HEAD:eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWY1ZjE1OTg4NmNjNTMxZmZlYTBkOGFhNWY5MmVkNGU1ZGE2NWY3MjRjMDU3MGFmODZhOTBiZjAwYzY3YzQyZSJ9fX0:1 + * @param part String array that contains at least 2 elements. + * @return Player head with given properties. + */ + @SuppressWarnings("deprecation") + private static ItemStack parsePlayerHead(String[] part) { + ItemStack playerHead; + + if (part.length == 3) { + String[] parsable = {part[0], part[2]}; + // create parse item and quantity. + playerHead = parseItemQuantity(parsable); + } else if (isNumeric(part[1])) { + // there is no meta item for player head. + return parseItemQuantity(part); + } else { + // create new player head item stack. + playerHead = new ItemStack(Material.PLAYER_HEAD); + } + + // Set correct Skull texture + try { + SkullMeta meta = (SkullMeta) playerHead.getItemMeta(); + + if (part[1].length() < 17) { + // Minecraft player names are in length between 3 and 16 chars. + meta.setOwner(part[1]); + } else if (part[1].length() == 32) { + // trimmed UUID length are 32 chars. + meta.setOwningPlayer(Bukkit.getOfflinePlayer( + UUID.fromString(part[1].replaceAll("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")))); + } else if (part[1].length() == 36) { + // full UUID length are 36 chars. + meta.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString(part[1]))); + } else { + // If chars are more than 36, apparently it is base64 encoded texture. + GameProfile profile = new GameProfile(UUID.randomUUID(), ""); + profile.getProperties().put("textures", new Property("textures", part[1])); + + // Null pointer will be caught and ignored. + Field profileField = meta.getClass().getDeclaredField("profile"); + profileField.setAccessible(true); + profileField.set(meta, profile); + } + + // Apply new meta to the item. + playerHead.setItemMeta(meta); + } catch (Exception ignored) {} + + return playerHead; + } + + + /** + * Check if given sting is an integer. + * @param string Value that must be checked. + * @return {@code true} if value is integer, {@code false} otherwise. + */ + private static boolean isNumeric(String string) { + if(string == null || string.equals("")) { + return false; + } + + try { + Integer.parseInt(string); + return true; + } catch (NumberFormatException e) { + return false; } } } diff --git a/src/main/java/world/bentobox/bentobox/util/Pair.java b/src/main/java/world/bentobox/bentobox/util/Pair.java index 775c5f111..d2109480a 100644 --- a/src/main/java/world/bentobox/bentobox/util/Pair.java +++ b/src/main/java/world/bentobox/bentobox/util/Pair.java @@ -67,10 +67,9 @@ public class Pair { if (obj == null) { return false; } - if (!(obj instanceof Pair)) { + if (!(obj instanceof Pair other)) { return false; } - Pair other = (Pair) obj; if (x == null) { if (other.x != null) { return false; diff --git a/src/main/java/world/bentobox/bentobox/util/Util.java b/src/main/java/world/bentobox/bentobox/util/Util.java index 82eda60b5..953952dcb 100644 --- a/src/main/java/world/bentobox/bentobox/util/Util.java +++ b/src/main/java/world/bentobox/bentobox/util/Util.java @@ -11,6 +11,8 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.lang.Validate; @@ -55,7 +57,10 @@ import world.bentobox.bentobox.nms.NMSAbstraction; * @author Poslovitch */ public class Util { - + /** + * Use standard color code definition: &. + */ + private static final Pattern HEX_PATTERN = Pattern.compile("&#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"); private static final String NETHER = "_nether"; private static final String THE_END = "_the_end"; private static String serverVersion = null; @@ -278,38 +283,23 @@ public class Util { * @return degrees */ public static float blockFaceToFloat(BlockFace face) { - switch (face) { - case EAST: - return 90F; - case EAST_NORTH_EAST: - return 67.5F; - case NORTH_EAST: - return 45F; - case NORTH_NORTH_EAST: - return 22.5F; - case NORTH_NORTH_WEST: - return 337.5F; - case NORTH_WEST: - return 315F; - case SOUTH: - return 180F; - case SOUTH_EAST: - return 135F; - case SOUTH_SOUTH_EAST: - return 157.5F; - case SOUTH_SOUTH_WEST: - return 202.5F; - case SOUTH_WEST: - return 225F; - case WEST: - return 270F; - case WEST_NORTH_WEST: - return 292.5F; - case WEST_SOUTH_WEST: - return 247.5F; - default: - return 0F; - } + return switch (face) { + case EAST -> 90F; + case EAST_NORTH_EAST -> 67.5F; + case NORTH_EAST -> 45F; + case NORTH_NORTH_EAST -> 22.5F; + case NORTH_NORTH_WEST -> 337.5F; + case NORTH_WEST -> 315F; + case SOUTH -> 180F; + case SOUTH_EAST -> 135F; + case SOUTH_SOUTH_EAST -> 157.5F; + case SOUTH_SOUTH_WEST -> 202.5F; + case SOUTH_WEST -> 225F; + case WEST -> 270F; + case WEST_NORTH_WEST -> 292.5F; + case WEST_SOUTH_WEST -> 247.5F; + default -> 0F; + }; } /** @@ -538,6 +528,44 @@ public class Util { return false; } + + /** + * This method translates color codes in given string and strips whitespace after them. + * This code parses both: hex and old color codes. + * @param textToColor Text which color codes must be parsed. + * @return String text with parsed colors and stripped whitespaces after them. + */ + @NonNull + public static String translateColorCodes(@NonNull String textToColor) { + // Use matcher to find hex patterns in given text. + Matcher matcher = HEX_PATTERN.matcher(textToColor); + // Increase buffer size by 32 like it is in bungee cord api. Use buffer because it is sync. + StringBuilder buffer = new StringBuilder(textToColor.length() + 32); + + while (matcher.find()) { + String group = matcher.group(1); + + if (group.length() == 6) { + // Parses #ffffff to a color text. + matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x" + + ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(1) + + ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(3) + + ChatColor.COLOR_CHAR + group.charAt(4) + ChatColor.COLOR_CHAR + group.charAt(5)); + } else { + // Parses #fff to a color text. + matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x" + + ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(0) + + ChatColor.COLOR_CHAR + group.charAt(1) + ChatColor.COLOR_CHAR + group.charAt(1) + + ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(2)); + } + } + + // transform normal codes and strip spaces after color code. + return Util.stripSpaceAfterColorCodes( + ChatColor.translateAlternateColorCodes('&', matcher.appendTail(buffer).toString())); + } + + /** * Strips spaces immediately after color codes. Used by {@link User#getTranslation(String, String...)}. * @param textToStrip - text to strip diff --git a/src/main/java/world/bentobox/bentobox/util/heads/HeadGetter.java b/src/main/java/world/bentobox/bentobox/util/heads/HeadGetter.java index e171b9c79..04012b0e1 100644 --- a/src/main/java/world/bentobox/bentobox/util/heads/HeadGetter.java +++ b/src/main/java/world/bentobox/bentobox/util/heads/HeadGetter.java @@ -72,7 +72,7 @@ public class HeadGetter { HeadCache cache = cachedHeads.get(panelItem.getPlayerHeadName()); - // Get value from config. Multiply value to 60 000 as internally it uses miliseconds. + // Get value from config. Multiply value to 60 000 as internally it uses milliseconds. // Config value stores minutes. long cacheTimeout = BentoBox.getInstance().getSettings().getPlayerHeadCacheTime() * 60 * 1000; diff --git a/src/main/java/world/bentobox/bentobox/util/package-info.java b/src/main/java/world/bentobox/bentobox/util/package-info.java new file mode 100644 index 000000000..3b6d6e5c3 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/util/package-info.java @@ -0,0 +1,12 @@ +/** + * API that provides useful (and not so useful) utility functions. + * + *

+ * Look here before you write your own utility function. If it isn't here, but would be useful + * the submit a PR so others can avoid duplicating code! + *

+ * + * @author various + * + */ +package world.bentobox.bentobox.util; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java b/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java index 7136461e4..9879cb469 100644 --- a/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java +++ b/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java @@ -300,7 +300,7 @@ public class SafeSpotTeleport { private String failureMessage = ""; private Location location; private Runnable runnable; - private CompletableFuture result = new CompletableFuture<>(); + private final CompletableFuture result = new CompletableFuture<>(); public Builder(BentoBox plugin) { this.plugin = plugin; @@ -380,7 +380,7 @@ public class SafeSpotTeleport { /** * Try to teleport the player - * @return CompletableFuture that will become true if successfull and false if not + * @return CompletableFuture that will become true if successful and false if not * @since 1.14.0 */ @Nullable diff --git a/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java b/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java index 54b365fab..fb966c959 100644 --- a/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java +++ b/src/main/java/world/bentobox/bentobox/versions/ServerCompatibility.java @@ -17,7 +17,7 @@ public class ServerCompatibility { // ---- SINGLETON ---- - private static ServerCompatibility instance = new ServerCompatibility(); + private static final ServerCompatibility instance = new ServerCompatibility(); public static ServerCompatibility getInstance() { return instance; @@ -54,7 +54,7 @@ public class ServerCompatibility { */ INCOMPATIBLE(false); - private boolean canLaunch; + private final boolean canLaunch; Compatibility(boolean canLaunch) { this.canLaunch = canLaunch; @@ -85,7 +85,7 @@ public class ServerCompatibility { */ UNKNOWN(Compatibility.INCOMPATIBLE); - private Compatibility compatibility; + private final Compatibility compatibility; /** * @since 1.14.0 */ @@ -190,7 +190,7 @@ public class ServerCompatibility { V1_17_1(Compatibility.COMPATIBLE) ; - private Compatibility compatibility; + private final Compatibility compatibility; ServerVersion(Compatibility compatibility) { this.compatibility = compatibility; @@ -308,9 +308,9 @@ public class ServerCompatibility { } /** - * Returns whether the server runs on the specified softwares. + * Returns whether the server runs on the specified software. * @param softwares the {@link ServerSoftware}s to check. - * @return {@code true} if the server runs on on of these softwares, {@code false} otherwise. + * @return {@code true} if the server runs on on of these software, {@code false} otherwise. * @since 1.5.0 */ public boolean isSoftware(@NonNull ServerSoftware... softwares) { diff --git a/src/main/java/world/bentobox/bentobox/versions/package-info.java b/src/main/java/world/bentobox/bentobox/versions/package-info.java new file mode 100644 index 000000000..65cd12b0e --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/versions/package-info.java @@ -0,0 +1,11 @@ +/** + * Holds a class that decides whether BentoBox is compatible with the server or not. + * + *

+ * This has to be updated with each new release of the server. + *

+ * + * @author Poslovich + * + */ +package world.bentobox.bentobox.versions; \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/web/catalog/CatalogEntry.java b/src/main/java/world/bentobox/bentobox/web/catalog/CatalogEntry.java index fea1bc1cf..2a73ffd6c 100644 --- a/src/main/java/world/bentobox/bentobox/web/catalog/CatalogEntry.java +++ b/src/main/java/world/bentobox/bentobox/web/catalog/CatalogEntry.java @@ -13,16 +13,22 @@ import com.google.gson.JsonObject; */ public class CatalogEntry { - private int slot; + private final int slot; /** * Defaults to {@link Material#PAPER}. */ - private @NonNull Material icon; - private @NonNull String name; - private @NonNull String description; - private @Nullable String topic; - private @Nullable String tag; - private @NonNull String repository; + private @NonNull + final Material icon; + private @NonNull + final String name; + private @NonNull + final String description; + private @Nullable + final String topic; + private @Nullable + final String tag; + private @NonNull + final String repository; public CatalogEntry(@NonNull JsonObject object) { this.slot = object.get("slot").getAsInt(); diff --git a/src/main/java/world/bentobox/bentobox/web/credits/Contributor.java b/src/main/java/world/bentobox/bentobox/web/credits/Contributor.java index c6d2f28ff..8d0bf328b 100644 --- a/src/main/java/world/bentobox/bentobox/web/credits/Contributor.java +++ b/src/main/java/world/bentobox/bentobox/web/credits/Contributor.java @@ -9,8 +9,9 @@ import org.eclipse.jdt.annotation.NonNull; */ public class Contributor { - private @NonNull String name; - private int commits; + private @NonNull + final String name; + private final int commits; public Contributor(@NonNull String name, int commits) { this.name = name; diff --git a/src/main/java/world/bentobox/bentobox/web/package-info.java b/src/main/java/world/bentobox/bentobox/web/package-info.java new file mode 100644 index 000000000..ec8c9b812 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/web/package-info.java @@ -0,0 +1,7 @@ +/** + * Fetches data from the web, such as the catalog. + * + * @author Poslovitch + * + */ +package world.bentobox.bentobox.web; \ No newline at end of file diff --git a/src/main/resources/locales/de.yml b/src/main/resources/locales/de.yml index f35bbb9b4..ce5daf42a 100644 --- a/src/main/resources/locales/de.yml +++ b/src/main/resources/locales/de.yml @@ -3,7 +3,7 @@ meta: authors: - xXjojojXx - Poslovitch - banner: RED_BANNER:1:STRIPE_RIGHT:BLACK:LEFT_STRIPE:YELLOW + banner: RED_BANNER:1:STRIPE_RIGHT:BLACK:STRIPE_LEFT:YELLOW commands: admin: setrank: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f080ab77f..351640149 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,9 +10,10 @@ description: ${project.description} load: STARTUP -loadbefore: [Multiverse-Core, Residence] +loadbefore: [Pladdon, Multiverse-Core, Residence] softdepend: + - Citizens - Vault - PlaceholderAPI - dynmap diff --git a/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java b/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java index d4e684c5b..6bb9c3e84 100644 --- a/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java +++ b/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java @@ -301,7 +301,7 @@ public class AddonTest { * Utility methods */ private void createJarArchive(File archiveFile, List tobeJaredList) { - byte buffer[] = new byte[BUFFER_SIZE]; + byte[] buffer = new byte[BUFFER_SIZE]; // Open archive file try (FileOutputStream stream = new FileOutputStream(archiveFile)) { try (JarOutputStream out = new JarOutputStream(stream, new Manifest())) { diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java index 1f5c90a81..4cf7dad10 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java @@ -1,27 +1,35 @@ package world.bentobox.bentobox.api.commands.admin; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.Collections; import java.util.Optional; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.NonNull; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -35,7 +43,9 @@ import world.bentobox.bentobox.managers.CommandsManager; import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; +import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.PlayersManager; +import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; /** @@ -43,16 +53,32 @@ import world.bentobox.bentobox.util.Util; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) +@PrepareForTest({Bukkit.class, BentoBox.class, Util.class}) public class AdminInfoCommandTest { - private BentoBox plugin; - private CompositeCommand ac; - private UUID uuid; + @Mock + private CompositeCommand ic; + @Mock private User user; + @Mock private IslandsManager im; + @Mock private PlayersManager pm; - private UUID notUUID; + + private Island island; + + private AdminInfoCommand iic; + + @Mock + private Player player; + @Mock + private World world; + @Mock + private PlaceholdersManager phm; + @Mock + private @NonNull Location location; + @Mock + private IslandWorldManager iwm; /** * @throws java.lang.Exception @@ -60,69 +86,62 @@ public class AdminInfoCommandTest { @Before public void setUp() throws Exception { // Set up plugin - plugin = mock(BentoBox.class); + BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); - Util.setPlugin(plugin); + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(plugin.getRanksManager()).thenReturn(new RanksManager()); + // Bukkit + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); // Command manager CommandsManager cm = mock(CommandsManager.class); when(plugin.getCommandsManager()).thenReturn(cm); // Player - Player p = mock(Player.class); - // Sometimes use Mockito.withSettings().verboseLogging() - user = mock(User.class); - when(user.isOp()).thenReturn(false); - uuid = UUID.randomUUID(); - notUUID = UUID.randomUUID(); - while(notUUID.equals(uuid)) { - notUUID = UUID.randomUUID(); - } + when(player.isOp()).thenReturn(false); + UUID uuid = UUID.randomUUID(); when(user.getUniqueId()).thenReturn(uuid); - when(user.getPlayer()).thenReturn(p); when(user.getName()).thenReturn("tastybento"); + when(user.getWorld()).thenReturn(world); + when(user.getPlayer()).thenReturn(player); + when(user.isPlayer()).thenReturn(true); + //user = User.getInstance(player); + // Set the User class plugin as this one User.setPlugin(plugin); - // Parent command has no aliases - ac = mock(CompositeCommand.class); - when(ac.getSubCommandAliases()).thenReturn(new HashMap<>()); - - // Island World Manager - IslandWorldManager iwm = mock(IslandWorldManager.class); - when(iwm.getFriendlyName(Mockito.any())).thenReturn("BSkyBlock"); - when(plugin.getIWM()).thenReturn(iwm); - - - // Player has island to begin with - im = mock(IslandsManager.class); - when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true); - when(im.hasIsland(Mockito.any(), Mockito.any(User.class))).thenReturn(true); - when(im.isOwner(Mockito.any(),Mockito.any())).thenReturn(true); - when(im.getOwner(Mockito.any(),Mockito.any())).thenReturn(uuid); - when(plugin.getIslands()).thenReturn(im); - - // Has team - pm = mock(PlayersManager.class); - when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(true); - - when(plugin.getPlayers()).thenReturn(pm); - - // Server & Scheduler - BukkitScheduler sch = mock(BukkitScheduler.class); - PowerMockito.mockStatic(Bukkit.class); - when(Bukkit.getScheduler()).thenReturn(sch); - // Locales LocalesManager lm = mock(LocalesManager.class); - when(lm.get(Mockito.any(), Mockito.any())).thenReturn("mock translation"); + when(lm.get(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); when(plugin.getLocalesManager()).thenReturn(lm); + // Return the same string + when(phm.replacePlaceholders(any(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + when(plugin.getPlaceholdersManager()).thenReturn(phm); + // Translate + when(user.getTranslation(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + when(user.getTranslation(anyString(), anyString(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); - // Addon - when(iwm.getAddon(Mockito.any())).thenReturn(Optional.empty()); + // Island manager + island = new Island(location, uuid, 100); + when(location.toVector()).thenReturn(new Vector(1,2,3)); + when(plugin.getIslands()).thenReturn(im); + Optional optionalIsland = Optional.of(island); + when(im.getIslandAt(any())).thenReturn(optionalIsland); + when(im.getIsland(any(), any(UUID.class))).thenReturn(island); + // Players manager + when(plugin.getPlayers()).thenReturn(pm); + when(pm.getUUID(any())).thenReturn(uuid); + + + // Command + iic = new AdminInfoCommand(ic); } + /** + * @throws java.lang.Exception + */ @After public void tearDown() { User.clearUsers(); @@ -130,93 +149,111 @@ public class AdminInfoCommandTest { } /** - * Test method for {@link AdminInfoCommand#execute(User, String, List)}. + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#setup()}. */ @Test - public void testExecuteNoTargetConsole() { - AdminInfoCommand itl = new AdminInfoCommand(ac); - CommandSender sender = mock(CommandSender.class); - User console = User.getInstance(sender); - assertFalse(itl.execute(console, itl.getLabel(), new ArrayList<>())); - // Show help + public void testSetup() { + assertEquals("mod.info", iic.getPermission()); + assertFalse(iic.isOnlyPlayer()); + assertEquals("commands.admin.info.parameters", iic.getParameters()); + assertEquals("commands.admin.info.description", iic.getDescription()); } /** - * Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminInfoCommand#execute(User, String, List)} . + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecuteUnknownPlayer() { - AdminInfoCommand itl = new AdminInfoCommand(ac); - String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(null); - assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("general.errors.unknown-player", "[name]", name[0]); + public void testExecuteUserStringListOfStringTooManyArgs() { + assertFalse(iic.execute(user, "", Arrays.asList("hdhh", "hdhdhd"))); + verify(user).sendMessage("commands.help.header", "[label]", "commands.help.console"); } /** - * Test method for . + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecutePlayerHasNoIsland() { - AdminInfoCommand itl = new AdminInfoCommand(ac); - String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(notUUID); - when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(false); - when(im.inTeam(Mockito.any(), Mockito.any())).thenReturn(false); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(null); - assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage(Mockito.eq("general.errors.player-has-no-island")); + public void testExecuteUserStringListOfStringNoArgsConsole() { + CommandSender console = mock(CommandSender.class); + User sender = User.getInstance(console); + assertFalse(iic.execute(sender, "", Collections.emptyList())); + verify(user, never()).sendMessage("commands.help.header", "[label]", "commands.help.console"); } /** - * Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminInfoCommand#execute(User, String, List)}. + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecuteSuccess() { - AdminInfoCommand itl = new AdminInfoCommand(ac); - String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(notUUID); - when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true); - Island is = mock(Island.class); - when(im.getIsland(Mockito.any(), Mockito.eq(notUUID))).thenReturn(is); - assertTrue(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(is).showInfo(Mockito.eq(user)); + public void testExecuteUserStringListOfStringNoArgsNoIsland() { + when(im.getIslandAt(any())).thenReturn(Optional.empty()); + assertTrue(iic.execute(user, "", Collections.emptyList())); + verify(user).sendMessage("commands.admin.info.no-island"); } /** - * Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminInfoCommand#execute(User, String, List)}. + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecuteUserNotOnIsland() { - when(user.isPlayer()).thenReturn(true); - AdminInfoCommand itl = new AdminInfoCommand(ac); - // No island here - when(im.getIslandAt(Mockito.any())).thenReturn(Optional.empty()); - assertFalse(itl.execute(user, itl.getLabel(), new ArrayList<>())); - // Confirm other verifications - Mockito.verify(user).sendMessage("commands.admin.info.no-island"); + public void testExecuteUserStringListOfStringNoArgsSuccess() { + assertTrue(iic.execute(user, "", Collections.emptyList())); + verify(user).sendMessage("commands.admin.info.title"); + verify(user).sendMessage(eq("commands.admin.info.island-uuid"), eq("[uuid]"), any()); + verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null), eq("[uuid]"), any()); + verify(user).sendMessage(eq("commands.admin.info.last-login"), eq("[date]"), any()); + verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); + verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); + verify(user).sendMessage("commands.admin.info.team-members-title"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.island-protection-center", "[xyz]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.island-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); + verify(user).sendMessage("commands.admin.info.max-protection-range", "[range]", "100"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); } /** - * Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminInfoCommand#execute(User, String, List)}. + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecuteSuccessUserOnIsland() { - when(user.isPlayer()).thenReturn(true); - AdminInfoCommand itl = new AdminInfoCommand(ac); - Location loc = mock(Location.class); + public void testExecuteUserStringListOfStringArgsSuccess() { + assertTrue(iic.execute(user, "", Collections.singletonList("tastybento"))); + verify(user).sendMessage("commands.admin.info.title"); + verify(user).sendMessage(eq("commands.admin.info.island-uuid"), eq("[uuid]"), any()); + verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null), eq("[uuid]"), any()); + verify(user).sendMessage(eq("commands.admin.info.last-login"), eq("[date]"), any()); + verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); + verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); + verify(user).sendMessage("commands.admin.info.team-members-title"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.island-protection-center", "[xyz]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.island-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); + verify(user).sendMessage("commands.admin.info.max-protection-range", "[range]", "100"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); - // Island has owner - Island is = mock(Island.class); - when(is.getOwner()).thenReturn(uuid); - when(is.showInfo(Mockito.any())).thenReturn(true); - Optional opi = Optional.of(is); - when(im.getIslandAt(Mockito.any())).thenReturn(opi); - when(user.getLocation()).thenReturn(loc); - - - assertTrue(itl.execute(user, itl.getLabel(), new ArrayList<>())); - // Confirm other verifications - Mockito.verify(is).showInfo(Mockito.eq(user)); } -} \ No newline at end of file + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringArgsNoIsland() { + when(im.getIsland(any(), any(UUID.class))).thenReturn(null); + assertFalse(iic.execute(user, "", Collections.singletonList("tastybento"))); + verify(user).sendMessage("general.errors.player-has-no-island"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.AdminInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringArgsUnknownPlayer() { + PowerMockito.mockStatic(Util.class); + when(Util.getUUID(any())).thenReturn(null); + assertFalse(iic.execute(user, "", Collections.singletonList("tastybento"))); + verify(user).sendMessage("general.errors.unknown-player", "[name]", "tastybento"); + + } + +} diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommandTest.java index 22d7b7178..4f5e64f4f 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminResetFlagsCommandTest.java @@ -58,7 +58,7 @@ public class AdminResetFlagsCommandTest { @Mock private CompositeCommand ac; - private UUID uuid = UUID.randomUUID(); + private final UUID uuid = UUID.randomUUID(); @Mock private IslandsManager im; @Mock diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommandTest.java index 15f13eddd..c44e696ab 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamAddCommandTest.java @@ -2,7 +2,10 @@ package world.bentobox.bentobox.api.commands.admin.team; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; @@ -90,15 +93,15 @@ public class AdminTeamAddCommandTest { // Player has island to begin with im = mock(IslandsManager.class); - when(im.hasIsland(Mockito.any(), Mockito.any(User.class))).thenReturn(true); - when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true); - when(im.isOwner(Mockito.any(), Mockito.any())).thenReturn(true); - when(im.getOwner(Mockito.any(), Mockito.any())).thenReturn(uuid); + when(im.hasIsland(any(), any(User.class))).thenReturn(true); + when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); + when(im.isOwner(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(uuid); when(plugin.getIslands()).thenReturn(im); // Has team pm = mock(PlayersManager.class); - when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(true); + when(im.inTeam(any(), eq(uuid))).thenReturn(true); when(plugin.getPlayers()).thenReturn(pm); @@ -112,16 +115,16 @@ public class AdminTeamAddCommandTest { // Locales LocalesManager lm = mock(LocalesManager.class); - when(lm.get(Mockito.any(), Mockito.any())).thenReturn("mock translation"); + when(lm.get(any(), any())).thenReturn("mock translation"); when(plugin.getLocalesManager()).thenReturn(lm); // Island World Manager IslandWorldManager iwm = mock(IslandWorldManager.class); - when(iwm.getFriendlyName(Mockito.any())).thenReturn("BSkyBlock"); + when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); when(plugin.getIWM()).thenReturn(iwm); // Addon - when(iwm.getAddon(Mockito.any())).thenReturn(Optional.empty()); + when(iwm.getAddon(any())).thenReturn(Optional.empty()); } @@ -158,16 +161,16 @@ public class AdminTeamAddCommandTest { String[] name = {"tastybento", "poslovich"}; // Unknown owner - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(null); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(null); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); assertFalse(itl.execute(user, ac.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("general.errors.unknown-player", "[name]", "tastybento"); + verify(user).sendMessage("general.errors.unknown-player", "[name]", "tastybento"); // Unknown target - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(null); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(null); assertFalse(itl.execute(user, ac.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("general.errors.unknown-player", "[name]", "poslovich"); + verify(user).sendMessage("general.errors.unknown-player", "[name]", "poslovich"); } /** @@ -178,13 +181,13 @@ public class AdminTeamAddCommandTest { AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); String[] name = {"tastybento", "poslovich"}; - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); - when(im.inTeam(Mockito.any(), Mockito.eq(notUUID))).thenReturn(true); + when(im.inTeam(any(), eq(notUUID))).thenReturn(true); assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage(Mockito.eq("commands.island.team.invite.errors.already-on-team")); + verify(user).sendMessage(eq("commands.island.team.invite.errors.already-on-team")); } @@ -196,14 +199,14 @@ public class AdminTeamAddCommandTest { AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); String[] name = {"tastybento", "poslovich"}; - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); // No island, - when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(false); + when(im.hasIsland(any(), eq(uuid))).thenReturn(false); assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("general.errors.player-has-no-island"); + verify(user).sendMessage("general.errors.player-has-no-island"); } @@ -215,21 +218,21 @@ public class AdminTeamAddCommandTest { AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); String[] name = {"tastybento", "poslovich"}; - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); // Has island, has team, but not an owner - when(im.hasIsland(Mockito.any(),Mockito.eq(uuid))).thenReturn(true); - when(im.inTeam(Mockito.any(),Mockito.eq(uuid))).thenReturn(true); - when(im.getOwner(Mockito.any(),Mockito.eq(uuid))).thenReturn(notUUID); + when(im.hasIsland(any(),eq(uuid))).thenReturn(true); + when(im.inTeam(any(),eq(uuid))).thenReturn(true); + when(im.getOwner(any(),eq(uuid))).thenReturn(notUUID); // Island Island island = mock(Island.class); - when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(island); + when(im.getIsland(any(), eq(uuid))).thenReturn(island); assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("commands.admin.team.add.name-not-owner", "[name]", "tastybento"); - Mockito.verify(island).showMembers(Mockito.any()); + verify(user).sendMessage("commands.admin.team.add.name-not-owner", "[name]", "tastybento"); + verify(user).sendMessage("commands.admin.info.team-members-title"); } /** @@ -240,19 +243,19 @@ public class AdminTeamAddCommandTest { AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); String[] name = {"tastybento", "poslovich"}; - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); // Has island, has team, is owner - when(im.hasIsland(Mockito.any(),Mockito.eq(uuid))).thenReturn(true); - when(im.inTeam(Mockito.any(),Mockito.eq(uuid))).thenReturn(true); - when(im.getOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(uuid); + when(im.hasIsland(any(),eq(uuid))).thenReturn(true); + when(im.inTeam(any(),eq(uuid))).thenReturn(true); + when(im.getOwner(any(), eq(uuid))).thenReturn(uuid); // Target has island - when(im.hasIsland(Mockito.any(), Mockito.eq(notUUID))).thenReturn(true); + when(im.hasIsland(any(), eq(notUUID))).thenReturn(true); assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("commands.admin.team.add.name-has-island", "[name]", "poslovich"); + verify(user).sendMessage("commands.admin.team.add.name-has-island", "[name]", "poslovich"); } @@ -264,18 +267,18 @@ public class AdminTeamAddCommandTest { AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); String[] name = {"tastybento", "poslovich"}; - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); // Has island, no team - when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true); - when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false); + when(im.hasIsland(any(), eq(uuid))).thenReturn(true); + when(im.inTeam(any(), eq(uuid))).thenReturn(false); // Target has island - when(im.hasIsland(Mockito.any(), Mockito.eq(notUUID))).thenReturn(true); + when(im.hasIsland(any(), eq(notUUID))).thenReturn(true); assertFalse(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("commands.admin.team.add.name-has-island", "[name]", "poslovich"); + verify(user).sendMessage("commands.admin.team.add.name-has-island", "[name]", "poslovich"); } @@ -287,29 +290,29 @@ public class AdminTeamAddCommandTest { AdminTeamAddCommand itl = new AdminTeamAddCommand(ac); String[] name = {"tastybento", "poslovich"}; - when(pm.getUUID(Mockito.eq("tastybento"))).thenReturn(uuid); - when(pm.getUUID(Mockito.eq("poslovich"))).thenReturn(notUUID); + when(pm.getUUID(eq("tastybento"))).thenReturn(uuid); + when(pm.getUUID(eq("poslovich"))).thenReturn(notUUID); // Has island, no team - when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true); - when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false); + when(im.hasIsland(any(), eq(uuid))).thenReturn(true); + when(im.inTeam(any(), eq(uuid))).thenReturn(false); // Target has no island - when(im.hasIsland(Mockito.any(), Mockito.eq(notUUID))).thenReturn(false); + when(im.hasIsland(any(), eq(notUUID))).thenReturn(false); // Island Island island = mock(Island.class); - when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(island); + when(im.getIsland(any(), eq(uuid))).thenReturn(island); // Player name - when(pm.getName(Mockito.eq(uuid))).thenReturn("tastybento"); - when(pm.getName(Mockito.eq(notUUID))).thenReturn("poslovich"); + when(pm.getName(eq(uuid))).thenReturn("tastybento"); + when(pm.getName(eq(notUUID))).thenReturn("poslovich"); when(plugin.getPlayers()).thenReturn(pm); // Success assertTrue(itl.execute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(im).setJoinTeam(Mockito.eq(island), Mockito.eq(notUUID)); - Mockito.verify(user).sendMessage("commands.admin.team.add.success", TextVariables.NAME, name[1], "[owner]", name[0]); + verify(im).setJoinTeam(eq(island), eq(notUUID)); + verify(user).sendMessage("commands.admin.team.add.success", TextVariables.NAME, name[1], "[owner]", name[0]); } } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java index 6161b07a4..aed70d1c0 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java @@ -190,7 +190,7 @@ public class AdminTeamKickCommandTest { assertTrue(itl.canExecute(user, itl.getLabel(), Collections.singletonList("tastybento"))); assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("tastybento"))); verify(user).sendMessage(eq("commands.admin.team.kick.cannot-kick-owner")); - verify(is).showMembers(any()); + verify(user).sendMessage("commands.admin.info.team-members-title"); verify(im, never()).removePlayer(eq(world), eq(notUUID)); verify(pm, never()).clearHomeLocations(eq(world), eq(notUUID)); verify(user, never()).sendMessage(eq("commands.admin.team.kick.success"), anyString(), anyString(), anyString(), anyString()); diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandGoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandGoCommandTest.java index ce858a90c..a9a2c752f 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandGoCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandGoCommandTest.java @@ -162,7 +162,7 @@ public class IslandGoCommandTest { // Locales LocalesManager lm = mock(LocalesManager.class); - when(lm.get(Mockito.any(), Mockito.any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); + when(lm.get(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); when(plugin.getLocalesManager()).thenReturn(lm); // Return the same string PlaceholdersManager phm = mock(PlaceholdersManager.class); @@ -172,8 +172,8 @@ public class IslandGoCommandTest { // Notifier when(plugin.getNotifier()).thenReturn(notifier); - // Util strip spaces - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); // Command igc = new IslandGoCommand(ic); @@ -186,6 +186,16 @@ public class IslandGoCommandTest { Mockito.framework().clearInlineMocks(); } + /** + * Test method for {@link IslandGoCommand#canExecute(User, String, List)} + */ + @Test + public void testExecuteMidTeleport() { + when(im.isGoingHome(user)).thenReturn(true); + assertFalse(igc.canExecute(user, igc.getLabel(), Collections.emptyList())); + verify(player).sendMessage("commands.island.go.teleport"); + } + /** * Test method for {@link IslandGoCommand#canExecute(User, String, List)} */ diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java index ef19a03f0..db650ebb5 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java @@ -5,7 +5,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -15,9 +17,12 @@ import java.util.Optional; import java.util.UUID; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.NonNull; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -25,6 +30,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; @@ -34,10 +40,12 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.PlayersManager; +import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; /** @@ -50,13 +58,13 @@ public class IslandInfoCommandTest { @Mock private CompositeCommand ic; + @Mock private User user; @Mock private IslandsManager im; @Mock private PlayersManager pm; - @Mock private Island island; private IslandInfoCommand iic; @@ -67,6 +75,10 @@ public class IslandInfoCommandTest { private World world; @Mock private PlaceholdersManager phm; + @Mock + private @NonNull Location location; + @Mock + private IslandWorldManager iwm; /** * @throws java.lang.Exception @@ -77,6 +89,12 @@ public class IslandInfoCommandTest { BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); + // IWM + when(plugin.getIWM()).thenReturn(iwm); + when(plugin.getRanksManager()).thenReturn(new RanksManager()); + + // Bukkit + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); // Command manager CommandsManager cm = mock(CommandsManager.class); when(plugin.getCommandsManager()).thenReturn(cm); @@ -84,10 +102,12 @@ public class IslandInfoCommandTest { // Player when(player.isOp()).thenReturn(false); UUID uuid = UUID.randomUUID(); - when(player.getUniqueId()).thenReturn(uuid); - when(player.getName()).thenReturn("tastybento"); - when(player.getWorld()).thenReturn(world); - user = User.getInstance(player); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getName()).thenReturn("tastybento"); + when(user.getWorld()).thenReturn(world); + when(user.getPlayer()).thenReturn(player); + when(user.isPlayer()).thenReturn(true); + //user = User.getInstance(player); // Set the User class plugin as this one User.setPlugin(plugin); @@ -98,12 +118,16 @@ public class IslandInfoCommandTest { // Return the same string when(phm.replacePlaceholders(any(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); when(plugin.getPlaceholdersManager()).thenReturn(phm); + // Translate + when(user.getTranslation(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + when(user.getTranslation(anyString(), anyString(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); // Island manager + island = new Island(location, uuid, 100); + when(location.toVector()).thenReturn(new Vector(1,2,3)); when(plugin.getIslands()).thenReturn(im); Optional optionalIsland = Optional.of(island); when(im.getIslandAt(any())).thenReturn(optionalIsland); - when(island.showInfo(any())).thenReturn(true); when(im.getIsland(any(), any(UUID.class))).thenReturn(island); // Players manager @@ -141,7 +165,7 @@ public class IslandInfoCommandTest { @Test public void testExecuteUserStringListOfStringTooManyArgs() { assertFalse(iic.execute(user, "", Arrays.asList("hdhh", "hdhdhd"))); - verify(player).sendMessage("commands.help.header"); + verify(user).sendMessage("commands.help.header", "[label]", "commands.help.console"); } /** @@ -152,17 +176,7 @@ public class IslandInfoCommandTest { CommandSender console = mock(CommandSender.class); User sender = User.getInstance(console); assertFalse(iic.execute(sender, "", Collections.emptyList())); - verify(console).sendMessage("commands.help.header"); - } - - /** - * Test method for {@link world.bentobox.bentobox.api.commands.island.IslandInfoCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfStringNoArgsNoIslandFalseInfo() { - when(island.showInfo(any())).thenReturn(false); - assertFalse(iic.execute(user, "", Collections.emptyList())); - verify(player).sendMessage("commands.admin.info.no-island"); + verify(user, never()).sendMessage("commands.help.header", "[label]", "commands.help.console"); } /** @@ -172,7 +186,7 @@ public class IslandInfoCommandTest { public void testExecuteUserStringListOfStringNoArgsNoIsland() { when(im.getIslandAt(any())).thenReturn(Optional.empty()); assertFalse(iic.execute(user, "", Collections.emptyList())); - verify(player).sendMessage("commands.admin.info.no-island"); + verify(user).sendMessage("commands.admin.info.no-island"); } /** @@ -181,7 +195,15 @@ public class IslandInfoCommandTest { @Test public void testExecuteUserStringListOfStringNoArgsSuccess() { assertTrue(iic.execute(user, "", Collections.emptyList())); - verify(island).showInfo(any()); + verify(user).sendMessage("commands.admin.info.title"); + verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null)); + verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); + verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); + verify(user).sendMessage("commands.admin.info.team-members-title"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); } /** @@ -190,7 +212,15 @@ public class IslandInfoCommandTest { @Test public void testExecuteUserStringListOfStringArgsSuccess() { assertTrue(iic.execute(user, "", Collections.singletonList("tastybento"))); - verify(island).showInfo(any()); + verify(user).sendMessage("commands.admin.info.title"); + verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null)); + verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); + verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); + verify(user).sendMessage("commands.admin.info.team-members-title"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); } /** @@ -200,7 +230,7 @@ public class IslandInfoCommandTest { public void testExecuteUserStringListOfStringArgsNoIsland() { when(im.getIsland(any(), any(UUID.class))).thenReturn(null); assertFalse(iic.execute(user, "", Collections.singletonList("tastybento"))); - verify(player).sendMessage("general.errors.player-has-no-island"); + verify(user).sendMessage("general.errors.player-has-no-island"); } /** @@ -210,8 +240,8 @@ public class IslandInfoCommandTest { public void testExecuteUserStringListOfStringArgsUnknownPlayer() { when(pm.getUUID(any())).thenReturn(null); assertFalse(iic.execute(user, "", Collections.singletonList("tastybento"))); - verify(player).sendMessage("general.errors.unknown-player"); - verify(phm).replacePlaceholders(player, "general.errors.unknown-player"); + verify(user).sendMessage("general.errors.unknown-player", "[name]", "tastybento"); + } } diff --git a/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java b/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java index 2399f3912..97240fff6 100644 --- a/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java +++ b/src/test/java/world/bentobox/bentobox/database/objects/adapters/LogEntryListAdapterTest.java @@ -23,7 +23,7 @@ public class LogEntryListAdapterTest { private LogEntryListAdapter a; private YamlConfiguration config; - private List history = new LinkedList<>(); + private final List history = new LinkedList<>(); private UUID target; private UUID issuer; private List toLog; diff --git a/src/test/java/world/bentobox/bentobox/database/sql/mysql/MySQLDatabaseHandlerTest.java b/src/test/java/world/bentobox/bentobox/database/sql/mysql/MySQLDatabaseHandlerTest.java index b7a788282..eb0cfff35 100644 --- a/src/test/java/world/bentobox/bentobox/database/sql/mysql/MySQLDatabaseHandlerTest.java +++ b/src/test/java/world/bentobox/bentobox/database/sql/mysql/MySQLDatabaseHandlerTest.java @@ -66,7 +66,7 @@ public class MySQLDatabaseHandlerTest { "}"; private MySQLDatabaseHandler handler; private Island instance; - private String UNIQUE_ID = "xyz"; + private final String UNIQUE_ID = "xyz"; @Mock private MySQLDatabaseConnector dbConn; @Mock diff --git a/src/test/java/world/bentobox/bentobox/listeners/BannedCommandsTest.java b/src/test/java/world/bentobox/bentobox/listeners/BannedCommandsTest.java index 71d87891e..2779bbbeb 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/BannedCommandsTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/BannedCommandsTest.java @@ -320,7 +320,7 @@ public class BannedCommandsTest { */ class MyWorldSettings implements WorldSettings { - private Map worldFlags = new HashMap<>(); + private final Map worldFlags = new HashMap<>(); @Override public @NonNull List getOnLeaveCommands() { diff --git a/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java b/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java index 251db34a3..11ad13ffb 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/BlockEndDragonTest.java @@ -277,7 +277,7 @@ public class BlockEndDragonTest { */ class MyWorldSettings implements WorldSettings { - private Map worldFlags = new HashMap<>(); + private final Map worldFlags = new HashMap<>(); @Override public @NonNull List getOnLeaveCommands() { diff --git a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java index 763625cf1..6a1bc21d7 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java @@ -194,10 +194,10 @@ public class JoinLeaveListenerTest { // Util PowerMockito.mockStatic(Util.class); when(Util.getWorld(any())).thenReturn(world); - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); // user text - LocalesManager lm = mock(LocalesManager.class); when(plugin.getLocalesManager()).thenReturn(lm); when(lm.get(any(), anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); diff --git a/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java b/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java index 3e043401d..eedbac464 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java @@ -128,8 +128,8 @@ public class PanelListenerManagerTest { class MyView extends InventoryView { - private Inventory top; - private String name; + private final Inventory top; + private final String name; /** * @param name diff --git a/src/test/java/world/bentobox/bentobox/listeners/PortalTeleportationListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/PortalTeleportationListenerTest.java index b1f0dd5ce..d46c61259 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/PortalTeleportationListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/PortalTeleportationListenerTest.java @@ -7,7 +7,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -19,6 +18,7 @@ import java.util.concurrent.CompletableFuture; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Server; import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.block.Block; @@ -154,6 +154,9 @@ public class PortalTeleportationListenerTest { BukkitScheduler sch = mock(BukkitScheduler.class); PowerMockito.mockStatic(Bukkit.class); when(Bukkit.getScheduler()).thenReturn(sch); + Server server = mock(Server.class); + when(server.getAllowNether()).thenReturn(true); + when(Bukkit.getServer()).thenReturn(server); // Locales LocalesManager lm = mock(LocalesManager.class); @@ -284,7 +287,7 @@ public class PortalTeleportationListenerTest { when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); np.onIslandPortal(e); assertTrue(e.isCancelled()); - verify(im, times(2)).homeTeleportAsync(any(), eq(player)); + verify(im).homeTeleportAsync(any(), eq(player)); } /** diff --git a/src/test/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListenerTest.java index ee85f7d23..daec95f7e 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/StandardSpawnProtectionListenerTest.java @@ -129,8 +129,8 @@ public class StandardSpawnProtectionListenerTest { // Block when(block.getLocation()).thenReturn(location); - // Util strip spaces - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); // Set up class ssp = new StandardSpawnProtectionListener(plugin); diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java b/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java index c4d8aafce..ba9131e91 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java @@ -161,9 +161,8 @@ public abstract class AbstractCommonSetup { PowerMockito.mockStatic(Util.class); when(Util.getWorld(any())).thenReturn(mock(World.class)); - // Util strip spaces - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); - + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); } diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListenerTest.java index ad3cac559..8c722f717 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListenerTest.java @@ -56,9 +56,9 @@ public class BlockInteractionListenerTest extends AbstractCommonSetup { @Mock private Block clickedBlock; - private Map inHandItems = new EnumMap<>(Material.class); + private final Map inHandItems = new EnumMap<>(Material.class); - private Map clickedBlocks = new EnumMap<>(Material.class); + private final Map clickedBlocks = new EnumMap<>(Material.class); private void setFlags() { inHandItems.put(Material.ENDER_PEARL, Flags.ENDER_PEARL); diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/FireListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/FireListenerTest.java index 3764bde23..f43634ea8 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/FireListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/FireListenerTest.java @@ -61,7 +61,7 @@ public class FireListenerTest { @Mock private World world; - private Map worldFlags = new HashMap<>(); + private final Map worldFlags = new HashMap<>(); @Before public void setUp() { diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java index b67dd9706..be381b07a 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/settings/PVPListenerTest.java @@ -230,8 +230,8 @@ public class PVPListenerTest { // Addon when(iwm.getAddon(any())).thenReturn(Optional.empty()); - // Util strip spaces - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); } @@ -303,6 +303,8 @@ public class PVPListenerTest { when(world.getEnvironment()).thenReturn(World.Environment.NORMAL); when(damager.getWorld()).thenReturn(world); when(damagee.getWorld()).thenReturn(world); + when(damager.getLocation()).thenReturn(loc); + when(damagee.getLocation()).thenReturn(loc); EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)), new EnumMap>(ImmutableMap.of(DamageModifier.BASE, Functions.constant(-0.0)))); @@ -337,7 +339,8 @@ public class PVPListenerTest { when(world.getEnvironment()).thenReturn(World.Environment.NORMAL); when(damager.getWorld()).thenReturn(world); when(damagee.getWorld()).thenReturn(world); - + when(damager.getLocation()).thenReturn(loc); + when(damagee.getLocation()).thenReturn(loc); // Protect visitors List visitorProtectionList = new ArrayList<>(); visitorProtectionList.add("ENTITY_ATTACK"); @@ -367,7 +370,8 @@ public class PVPListenerTest { Entity damagee = mock(Player.class); when(damager.getWorld()).thenReturn(world); when(damagee.getWorld()).thenReturn(world); - + when(damager.getLocation()).thenReturn(loc); + when(damagee.getLocation()).thenReturn(loc); // Protect visitors when(iwm.getIvSettings(world)).thenReturn(Collections.singletonList("ENTITY_ATTACK")); // This player is a visitor @@ -391,7 +395,8 @@ public class PVPListenerTest { when(world.getEnvironment()).thenReturn(World.Environment.NORMAL); when(damager.getWorld()).thenReturn(world); when(damagee.getWorld()).thenReturn(world); - + when(damager.getLocation()).thenReturn(loc); + when(damagee.getLocation()).thenReturn(loc); // Protect visitors List visitorProtectionList = new ArrayList<>(); visitorProtectionList.add("ENTITY_ATTACK"); @@ -418,7 +423,8 @@ public class PVPListenerTest { when(world.getEnvironment()).thenReturn(World.Environment.NORMAL); when(damager.getWorld()).thenReturn(world); when(damagee.getWorld()).thenReturn(world); - + when(damager.getLocation()).thenReturn(loc); + when(damagee.getLocation()).thenReturn(loc); // Protect visitors List visitorProtectionList = new ArrayList<>(); visitorProtectionList.add("ENTITY_ATTACK"); @@ -448,7 +454,8 @@ public class PVPListenerTest { when(world.getEnvironment()).thenReturn(World.Environment.NORMAL); when(damager.getWorld()).thenReturn(world); when(damagee.getWorld()).thenReturn(world); - + when(damager.getLocation()).thenReturn(loc); + when(damagee.getLocation()).thenReturn(loc); // This player is a visitor when(im.userIsOnIsland(any(), any())).thenReturn(false); @@ -532,9 +539,8 @@ public class PVPListenerTest { when(im.userIsOnIsland(any(), any())).thenReturn(false); when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK")); new PVPListener().onEntityDamage(e); - // visitor should be protected - assertTrue(e.isCancelled()); - verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference())); + // visitor should not be protected + assertFalse(e.isCancelled()); } @@ -606,9 +612,8 @@ public class PVPListenerTest { when(im.userIsOnIsland(any(), any())).thenReturn(false); when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK")); new PVPListener().onEntityDamage(e); - // visitor should be protected - assertTrue(e.isCancelled()); - verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference())); + // visitor should not be protected + assertFalse(e.isCancelled()); } @@ -723,9 +728,8 @@ public class PVPListenerTest { when(im.userIsOnIsland(any(), any())).thenReturn(false); when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK")); new PVPListener().onFishing(pfe); - // visitor should be protected - assertTrue(pfe.isCancelled()); - verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference())); + // visitor should not be protected + assertFalse(pfe.isCancelled()); } /** @@ -785,10 +789,13 @@ public class PVPListenerTest { ThrownPotion tp = mock(ThrownPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); // Create a damage map Map map = new HashMap<>(); map.put(zombie, 100D); map.put(creeper, 10D); + when(zombie.getLocation()).thenReturn(loc); + when(creeper.getLocation()).thenReturn(loc); PotionSplashEvent e = new PotionSplashEvent(tp, map); new PVPListener().onSplashPotionSplash(e); assertFalse(e.isCancelled()); @@ -805,6 +812,7 @@ public class PVPListenerTest { ThrownPotion tp = mock(ThrownPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); // Create a damage map Map map = new HashMap<>(); map.put(player2, 100D); @@ -835,6 +843,7 @@ public class PVPListenerTest { ThrownPotion tp = mock(ThrownPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); // Create a damage map Map map = new HashMap<>(); map.put(player, 100D); @@ -862,6 +871,7 @@ public class PVPListenerTest { ThrownPotion tp = mock(ThrownPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); // Create a damage map Map map = new HashMap<>(); map.put(player2, 100D); @@ -887,6 +897,7 @@ public class PVPListenerTest { ThrownPotion tp = mock(ThrownPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); // Create a damage map Map map = new HashMap<>(); map.put(player2, 100D); @@ -898,11 +909,10 @@ public class PVPListenerTest { when(im.userIsOnIsland(any(), any())).thenReturn(false); when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK")); new PVPListener().onSplashPotionSplash(e); - // visitor should be protected - assertFalse(e.getAffectedEntities().contains(player2)); + // visitor should not be protected + assertTrue(e.getAffectedEntities().contains(player2)); assertTrue(e.getAffectedEntities().contains(zombie)); assertTrue(e.getAffectedEntities().contains(creeper)); - verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference())); // Wrong world wrongWorld(); @@ -919,6 +929,7 @@ public class PVPListenerTest { LingeringPotion tp = mock(LingeringPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); AreaEffectCloud cloud = mock(AreaEffectCloud.class); LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud); new PVPListener().onLingeringPotionSplash(e); @@ -938,6 +949,7 @@ public class PVPListenerTest { LingeringPotion tp = mock(LingeringPotion.class); when(tp.getShooter()).thenReturn(creeper); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); AreaEffectCloud cloud = mock(AreaEffectCloud.class); LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud); new PVPListener().onLingeringPotionSplash(e); @@ -959,6 +971,7 @@ public class PVPListenerTest { LingeringPotion tp = mock(LingeringPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); AreaEffectCloud cloud = mock(AreaEffectCloud.class); when(cloud.getWorld()).thenReturn(world); LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud); @@ -995,6 +1008,7 @@ public class PVPListenerTest { LingeringPotion tp = mock(LingeringPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); AreaEffectCloud cloud = mock(AreaEffectCloud.class); when(cloud.getWorld()).thenReturn(world); LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud); @@ -1029,6 +1043,7 @@ public class PVPListenerTest { LingeringPotion tp = mock(LingeringPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); AreaEffectCloud cloud = mock(AreaEffectCloud.class); when(cloud.getWorld()).thenReturn(world); LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud); @@ -1069,6 +1084,7 @@ public class PVPListenerTest { LingeringPotion tp = mock(LingeringPotion.class); when(tp.getShooter()).thenReturn(player); when(tp.getWorld()).thenReturn(world); + when(tp.getLocation()).thenReturn(loc); AreaEffectCloud cloud = mock(AreaEffectCloud.class); when(cloud.getWorld()).thenReturn(world); LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud); diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java index b80c776a4..4a3df7dd2 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java @@ -204,8 +204,8 @@ public class EnterExitListenerTest { // Flags Flags.ENTER_EXIT_MESSAGES.setSetting(world, true); - // Util strip spaces - when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); } @After diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListenerTest.java index b88b496b4..4697a8d61 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListenerTest.java @@ -27,6 +27,7 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.World.Environment; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageEvent; @@ -43,6 +44,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -79,6 +81,10 @@ public class InvincibleVisitorsListenerTest { private Optional optionalIsland; @Mock private GameModeAddon addon; + @Mock + private Location location; + @Mock + private World world; /** * @throws java.lang.Exception @@ -113,10 +119,12 @@ public class InvincibleVisitorsListenerTest { when(panel.getItems()).thenReturn(map); // Sometimes use Mockito.withSettings().verboseLogging() when(user.inWorld()).thenReturn(true); - when(user.getWorld()).thenReturn(mock(World.class)); - when(player.getWorld()).thenReturn(mock(World.class)); - when(user.getLocation()).thenReturn(mock(Location.class)); - when(player.getLocation()).thenReturn(mock(Location.class)); + when(user.getWorld()).thenReturn(world); + when(player.getWorld()).thenReturn(world); + when(location.getWorld()).thenReturn(world); + when(user.getLocation()).thenReturn(location); + when(player.getLocation()).thenReturn(location); + when(world.getEnvironment()).thenReturn(Environment.NORMAL); when(user.getPlayer()).thenReturn(player); when(user.hasPermission(anyString())).thenReturn(true); when(user.getTranslation(anyString())).thenReturn("panel"); @@ -127,6 +135,8 @@ public class InvincibleVisitorsListenerTest { PowerMockito.mockStatic(Util.class); when(Util.getWorld(any())).thenReturn(mock(World.class)); when(Util.prettifyText(anyString())).thenCallRealMethod(); + // Util translate color codes (used in user translate methods) + when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); FlagsManager fm = mock(FlagsManager.class); Flag flag = mock(Flag.class); when(flag.isSetForWorld(any())).thenReturn(false); diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListenerTest.java index 8c486d774..73f134462 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/ObsidianScoopingListenerTest.java @@ -12,6 +12,7 @@ import java.util.Optional; import java.util.logging.Logger; import org.bukkit.Bukkit; +import org.bukkit.FluidCollisionMode; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -27,6 +28,7 @@ import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.PluginManager; +import org.bukkit.util.RayTraceResult; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -60,7 +62,7 @@ public class ObsidianScoopingListenerTest { @Mock private BentoBox plugin; @Mock - private Player who; + private Player p; @Mock private IslandWorldManager iwm; @Mock @@ -93,16 +95,19 @@ public class ObsidianScoopingListenerTest { listener = new ObsidianScoopingListener(); // Mock player - when(who.getWorld()).thenReturn(world); + when(p.getWorld()).thenReturn(world); + RayTraceResult rtr = mock(RayTraceResult.class); + when(p.rayTraceBlocks(5, FluidCollisionMode.ALWAYS)).thenReturn(rtr); + when(rtr.getHitBlock()).thenReturn(clickedBlock); Location location = mock(Location.class); when(location.getWorld()).thenReturn(world); when(location.getBlockX()).thenReturn(0); when(location.getBlockY()).thenReturn(0); when(location.getBlockZ()).thenReturn(0); - when(who.getLocation()).thenReturn(location); + when(p.getLocation()).thenReturn(location); - when(who.getInventory()).thenReturn(mock(PlayerInventory.class)); + when(p.getInventory()).thenReturn(mock(PlayerInventory.class)); // Worlds when(plugin.getIWM()).thenReturn(iwm); @@ -130,7 +135,7 @@ public class ObsidianScoopingListenerTest { // Put player on island when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(true); // Set as survival - when(who.getGameMode()).thenReturn(GameMode.SURVIVAL); + when(p.getGameMode()).thenReturn(GameMode.SURVIVAL); // Locales when(plugin.getLocalesManager()).thenReturn(lm); @@ -208,7 +213,7 @@ public class ObsidianScoopingListenerTest { @Test public void testOnPlayerInteractNotInWorld() { - PlayerInteractEvent event = new PlayerInteractEvent(who, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); + PlayerInteractEvent event = new PlayerInteractEvent(p, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); // Test not in world when(iwm.inWorld(any(World.class))).thenReturn(false); when(iwm.inWorld(any(Location.class))).thenReturn(false); @@ -224,11 +229,11 @@ public class ObsidianScoopingListenerTest { @Test public void testOnPlayerInteractGameModes() { - PlayerInteractEvent event = new PlayerInteractEvent(who, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); + PlayerInteractEvent event = new PlayerInteractEvent(p, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); // Test different game modes for (GameMode gm : GameMode.values()) { - when(who.getGameMode()).thenReturn(gm); + when(p.getGameMode()).thenReturn(gm); if (!gm.equals(GameMode.SURVIVAL)) { assertFalse(listener.onPlayerInteract(event)); } @@ -237,10 +242,10 @@ public class ObsidianScoopingListenerTest { @Test public void testOnPlayerInteractSurvivalNotOnIsland() { - PlayerInteractEvent event = new PlayerInteractEvent(who, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); + PlayerInteractEvent event = new PlayerInteractEvent(p, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); // Set as survival - when(who.getGameMode()).thenReturn(GameMode.SURVIVAL); + when(p.getGameMode()).thenReturn(GameMode.SURVIVAL); // Positive test with 1 bucket in the stack inHand = Material.BUCKET; @@ -262,7 +267,7 @@ public class ObsidianScoopingListenerTest { when(airBlock.getType()).thenReturn(Material.AIR); ObsidianScoopingListener listener = new ObsidianScoopingListener(); - PlayerInteractEvent event = new PlayerInteractEvent(who, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); + PlayerInteractEvent event = new PlayerInteractEvent(p, Action.RIGHT_CLICK_BLOCK, item, clickedBlock, BlockFace.EAST); if (!item.getType().equals(Material.BUCKET) || !clickedBlock.getType().equals(Material.OBSIDIAN)) { assertFalse(listener.onPlayerInteract(event)); diff --git a/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java b/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java index 52fc327bc..7de4357d5 100644 --- a/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java +++ b/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java @@ -58,7 +58,7 @@ public class GameModePlaceholderTest { private IslandWorldManager iwm; @Mock private IslandsManager im; - private RanksManager rm = new RanksManager(); + private final RanksManager rm = new RanksManager(); @Mock private @Nullable Location location; diff --git a/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java index 976a40b0f..d0f259b4b 100644 --- a/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java @@ -56,7 +56,7 @@ public class BlueprintClipboardManagerTest { private File blueprintFolder; - private String json = "{\n" + + private final String json = "{\n" + " \"name\": \"blueprint\",\n" + " \"attached\": {},\n" + " \"entities\": {},\n" + @@ -78,7 +78,7 @@ public class BlueprintClipboardManagerTest { " \"bedrock\": [-2.0, -16.0, -1.0]\n" + "}"; - private String jsonNoBedrock = "{\n" + + private final String jsonNoBedrock = "{\n" + " \"name\": \"blueprint\",\n" + " \"attached\": {},\n" + " \"entities\": {},\n" + diff --git a/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java index 357ddbf30..ae96e552c 100644 --- a/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java @@ -667,7 +667,7 @@ public class BlueprintsManagerTest { * Utility methods */ private void createJarArchive(File archiveFile, File folder, List tobeJaredList) { - byte buffer[] = new byte[BUFFER_SIZE]; + byte[] buffer = new byte[BUFFER_SIZE]; // Open archive file try (FileOutputStream stream = new FileOutputStream(archiveFile)) { try (JarOutputStream out = new JarOutputStream(stream, new Manifest())) { diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandDeletionManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandDeletionManagerTest.java index 2eafddbf6..9567fabe2 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandDeletionManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandDeletionManagerTest.java @@ -138,7 +138,7 @@ public class IslandDeletionManagerTest { BentoBoxReadyEvent e = new BentoBoxReadyEvent(); idm.onBentoBoxReady(e); verify(plugin).log("There are 1 islands pending deletion."); - verify(plugin).logError("Island queued for deletion refers to a non-existant game world. Skipping..."); + verify(plugin).logError("Island queued for deletion refers to a non-existent game world. Skipping..."); } /** diff --git a/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java b/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java index cea1f3251..fd11d337b 100644 --- a/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/island/IslandCacheTest.java @@ -49,7 +49,7 @@ public class IslandCacheTest { @Mock private Island island; // UUID - private UUID owner = UUID.randomUUID(); + private final UUID owner = UUID.randomUUID(); @Mock private Location location; // Test class diff --git a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java index eae058f24..87c690e32 100644 --- a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java @@ -93,7 +93,7 @@ public class NewIslandTest { @Mock private BlueprintBundle bpb; - private UUID uuid = UUID.randomUUID(); + private final UUID uuid = UUID.randomUUID(); @Mock private BlueprintsManager bpm; diff --git a/src/test/java/world/bentobox/bentobox/util/ItemParserTest.java b/src/test/java/world/bentobox/bentobox/util/ItemParserTest.java index a9dd12849..7ebecd6cd 100644 --- a/src/test/java/world/bentobox/bentobox/util/ItemParserTest.java +++ b/src/test/java/world/bentobox/bentobox/util/ItemParserTest.java @@ -27,18 +27,24 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import world.bentobox.bentobox.BentoBox; + + @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class}) +@PrepareForTest({BentoBox.class, Bukkit.class}) public class ItemParserTest { private PotionMeta potionMeta; private BannerMeta bannerMeta; + private ItemStack defaultItem; @Before public void setUp() throws Exception { PowerMockito.mockStatic(Bukkit.class); + PowerMockito.mockStatic(BentoBox.class); ItemFactory itemFactory = mock(ItemFactory.class); when(Bukkit.getItemFactory()).thenReturn(itemFactory); + when(BentoBox.getInstance()).thenReturn(mock(BentoBox.class)); potionMeta = mock(PotionMeta.class); /* when(itemFactory.getItemMeta(Mockito.eq(Material.POTION))).thenReturn(potionMeta); @@ -62,6 +68,7 @@ public class ItemParserTest { } }); + defaultItem = new ItemStack(Material.STONE); } @After @@ -72,16 +79,19 @@ public class ItemParserTest { @Test public void testParseNull() { assertNull(ItemParser.parse(null)); + assertEquals(defaultItem, ItemParser.parse(null, defaultItem)); } @Test public void testParseBlank() { assertNull(ItemParser.parse("")); + assertEquals(defaultItem, ItemParser.parse("", defaultItem)); } @Test public void testParseNoColons() { assertNull(ItemParser.parse("NOCOLONS")); + assertEquals(defaultItem, ItemParser.parse("NOCOLONS", defaultItem)); } /* @@ -253,6 +263,8 @@ public class ItemParserTest { @Test public void testParseBadTwoItem() { assertNull(ItemParser.parse("STNE:5")); + assertEquals(defaultItem, ItemParser.parse("STNE:3", defaultItem)); + assertEquals(defaultItem, ItemParser.parse("STNE:Z", defaultItem)); } @Test @@ -265,5 +277,8 @@ public class ItemParserTest { @Test public void testParseBadThreeItem() { assertNull(ItemParser.parse("STNE:5:5")); + assertEquals(defaultItem, ItemParser.parse("STNE:5:5", defaultItem)); + assertEquals(defaultItem, ItemParser.parse("STNE:AA:5", defaultItem)); + assertEquals(defaultItem, ItemParser.parse("WOODEN_SWORD:4:AA", defaultItem)); } } diff --git a/src/test/java/world/bentobox/bentobox/util/UtilTest.java b/src/test/java/world/bentobox/bentobox/util/UtilTest.java index 639a58e08..684a2ff63 100644 --- a/src/test/java/world/bentobox/bentobox/util/UtilTest.java +++ b/src/test/java/world/bentobox/bentobox/util/UtilTest.java @@ -41,6 +41,7 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import net.md_5.bungee.api.ChatColor; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; @@ -125,7 +126,7 @@ public class UtilTest { when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer) invocation -> invocation.getArgument(1, String.class)); when(plugin.getLocalesManager()).thenReturn(lm); - + } @After @@ -458,7 +459,7 @@ public class UtilTest { Bukkit.dispatchCommand(sender, "replace tastybento"); verify(plugin).logError("Could not execute test command as console: replace tastybento"); } - + /** * Test for {@link Util#broadcast(String, String...)} */ @@ -468,7 +469,7 @@ public class UtilTest { int result = Util.broadcast("test.key", TextVariables.DESCRIPTION, "hello"); assertEquals(0, result); } - + /** * Test for {@link Util#broadcast(String, String...)} */ @@ -476,6 +477,38 @@ public class UtilTest { public void testBroadcastStringStringHasPerm() { int result = Util.broadcast("test.key", TextVariables.DESCRIPTION, "hello"); assertEquals(11, result); - + + } + + /** + * Test for {@link Util#translateColorCodes(String)} + */ + @Test + public void testTranslateColorCodesAmpersand() { + assertEquals("", Util.translateColorCodes("")); + assertEquals("abcdef ABCDEF", Util.translateColorCodes("abcdef ABCDEF")); + assertEquals("white space after ", Util.translateColorCodes("white space after ")); + assertEquals("§ared color", Util.translateColorCodes("&a red color")); + assertEquals("§a big space", Util.translateColorCodes("&a big space")); + assertEquals("§ared color", Util.translateColorCodes("&ared color")); + assertEquals("§ared §bcolor §cgreen §fheheh", Util.translateColorCodes("&ared &bcolor &c green &f heheh")); + } + + /** + * Test for {@link Util#translateColorCodes(String)} + */ + @Test + public void testTranslateColorCodesHex() { + // Use Bungee Chat parsing for single color test to validate correct parsing + assertEquals(ChatColor.of("#ff0000").toString(), Util.translateColorCodes("&#ff0000")); + assertEquals(ChatColor.of("#ff2200").toString(), Util.translateColorCodes("&#f20")); + + assertEquals("&#f single char", Util.translateColorCodes("&#f single char")); + assertEquals("&#f0 two chars", Util.translateColorCodes("&#f0 two chars")); + assertEquals("§x§f§f§0§0§0§0shorten hex", Util.translateColorCodes("&#f00 shorten hex")); + assertEquals("§x§f§f§0§0§0§01 four chars", Util.translateColorCodes("&#f001 four chars")); + assertEquals("§x§f§f§0§0§0§01f five chars", Util.translateColorCodes("&#f001f five chars")); + assertEquals("§x§f§f§0§0§0§0full hex", Util.translateColorCodes("&#ff0000 full hex")); + assertEquals("&#ggg outside hex range", Util.translateColorCodes("&#ggg outside hex range")); } } From df2b445002a256697fd06c3d3fb2df79d045ce79 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Nov 2021 21:28:12 -0800 Subject: [PATCH 2/2] Release 1.18.0 (#1876) ## Change Log * Island range perms could be 2x island distance This could allow protection ranges to be much greater than the island range and therefore overflow into adjacent islands. https://github.com/BentoBoxWorld/BentoBox/issues/1851 * Ensure maxEverProtectionRange is less than range. https://github.com/BentoBoxWorld/BentoBox/issues/1851 * Added test class for Island. * Added access to private fields for JUnit tests * Added Sonar Properties to POM * Changes to analyze using sonar. * Remove zip reference * Avoid zipSlip vulnerability. * Removed the unused WorldEdit hook. (#1853) If someone wants to add it back later they can, but this code does nothing right now. * Requires nonNull parameters for User.instanceOf (#1852) * Requires nonNull parameters for User.instanceOf The only reason why User.instanceOf was returning a potential null was if the parameter was null. Further absolutely no null checking was being done, so the assumption was that User.instanceOf should never return a null. This corrects the annotations and requires non-Null parameters. * Remove null player test * Fix JavaDoc for GameModeAddon inWorld method * Fix max-range bug * Remove illegal tag as it's not needed * Code smell reduction * Add missing packages so tests can pass. * Non null user methods (#1856) * This makes some User methods non-null. Instead of returning null, some methods will throw an error if they are called on non-Players. This means code does not have to do null checks. * Perform null check in method. * Null check * Fix test * Fix test. * Npe squashing (#1857) * Fix hanging [uuid] in info. * NPE checking * Make getProtectionCenter nonNull * More NPE fixes. * Fix test * Make getPlayer() and getOfflinePlayer() nonNull returns This requires addons to not use null checks and instead us the isPlayer or isOfflinePlayer methods. * NPE blockers * Deprecate CompositeCommand isPlayer method. * Fix test * Use isPlayer instead of null check. Refactor code to be easier to understand. * Fix * Fix some code smells. * Prevent NPE possibility. * Fix "ugly" enchant name. (#1858) Enchant names did not have a touch of Util#prettifyText code. * Remove deprecated events. * Fix IslandSethomeCommand test * Fix tests - just counts of events. * Added API to get a translation without color conversion It may be necessary to read the translation without converting colors to Bukkit colors. * Fix tests. * Fix test. * Version NPE protections. * 1.18.0 (#1860) * Mark all home-related methods in PlayersManager as deprecated. * Fix bug where maxHomes was shown as null * Version 1.18.0 API changes may break compatibility with Addons. * Remove usage of deprecated methods except for migration code. * Prevent NPE. Check isPlayer instead of getWorld() == null * Fix nullability issue and added to @Deprecated annotations * Added deprecation notices to home methods in Players * Fix missing color conversion for translations. * Fix mis-statement of island protection coordinates in info command. * Fix tests * Fix missing edge deletion of island. The bounding box was erroneously being made smaller when it was not required because the inBounds check does that already. https://github.com/BentoBoxWorld/BentoBox/issues/1863 * Prevent rare NPE * Ensure oldIsland is never null. * Refactored setowner command and added test class * API: Require getWorldSettings to be a game mode world * Fix tests and refactor code * Fix test IWM inWworld needs to return true * Fix test IWM inWorld must return true * Put default getHandlers back in for backwards compatibility Without them, too many older addons break. They need updating to have their own handlers. Once that is done, the default ones can be removed maybe. * Refactor code for clarity. * NPE protections * Prevent NPE @Poslovich - you were right! * Throw an error if player is null * Prevent NPE * Prevent NPE * Do a null check * World should never be null. * Require non-null world * Require owner to be non-null. It should never be null * Prevent NPEs * Clear the going home flag for edge cases There were a few potential times when the flag may not have been cleared. These were mostly teleport failure scenarios. Hopefully, this is all of them. https://github.com/BentoBoxWorld/BentoBox/issues/1864 * Shift priority of EntityPortalEnterEvent to HIGH https://github.com/BentoBoxWorld/BentoBox/issues/1866 This will allow other plugins running at NORMAL to cancel the event before BentoBox does something. * Increase priority of EntityPortalEvent listener https://github.com/BentoBoxWorld/BentoBox/issues/1866 * Fixes https://github.com/BentoBoxWorld/BentoBox/issues/1868 * Code refactoring around User.getInstance(player) Co-authored-by: BONNe Co-authored-by: Fredthedoggy <45927799+Fredthedoggy@users.noreply.github.com> Co-authored-by: Justin Co-authored-by: gecko10000 <60494179+levtey@users.noreply.github.com> --- .github/workflows/build.yml | 17 +- pom.xml | 36 +- .../world/bentobox/bentobox/BentoBox.java | 10 +- .../bentobox/api/addons/AddonClassLoader.java | 6 +- .../bentobox/api/addons/AddonDescription.java | 39 +- .../bentobox/api/addons/GameModeAddon.java | 8 +- .../api/commands/CompositeCommand.java | 17 +- .../commands/admin/AdminDeleteCommand.java | 71 +- .../commands/admin/AdminSetrankCommand.java | 4 + .../commands/admin/AdminSetspawnCommand.java | 6 +- .../commands/admin/AdminSwitchCommand.java | 6 +- .../commands/admin/AdminTeleportCommand.java | 13 +- .../admin/AdminUnregisterCommand.java | 5 +- .../blueprints/AdminBlueprintCommand.java | 9 +- .../AdminBlueprintOriginCommand.java | 3 +- .../blueprints/AdminBlueprintPos1Command.java | 2 +- .../blueprints/AdminBlueprintPos2Command.java | 2 +- .../blueprints/AdminBlueprintSaveCommand.java | 2 +- .../admin/conversations/NamePrompt.java | 6 +- .../admin/range/AdminRangeAddCommand.java | 3 +- .../admin/range/AdminRangeRemoveCommand.java | 3 +- .../admin/range/AdminRangeResetCommand.java | 3 +- .../admin/range/AdminRangeSetCommand.java | 3 +- .../admin/team/AdminTeamKickCommand.java | 1 - .../admin/team/AdminTeamSetownerCommand.java | 23 +- .../api/commands/island/IslandBanCommand.java | 8 +- .../commands/island/IslandResetCommand.java | 49 +- .../commands/island/IslandSethomeCommand.java | 12 +- .../commands/island/IslandUnbanCommand.java | 10 +- .../team/IslandTeamInviteAcceptCommand.java | 7 +- .../island/team/IslandTeamKickCommand.java | 2 +- .../island/team/IslandTeamPromoteCommand.java | 2 +- .../team/IslandTeamSetownerCommand.java | 29 +- .../bentobox/api/events/BentoBoxEvent.java | 46 +- .../api/events/BentoBoxReadyEvent.java | 3 +- .../api/events/OfflineMessageEvent.java | 3 +- .../api/events/addon/AddonDisableEvent.java | 3 +- .../api/events/addon/AddonEnableEvent.java | 3 +- .../bentobox/api/events/addon/AddonEvent.java | 72 +- .../api/events/addon/AddonGeneralEvent.java | 3 +- .../api/events/addon/AddonLoadEvent.java | 3 +- .../api/events/command/CommandEvent.java | 3 +- .../flags/FlagProtectionChangeEvent.java | 3 +- .../events/flags/FlagSettingChangeEvent.java | 3 +- .../flags/FlagWorldSettingChangeEvent.java | 3 +- .../api/events/island/IslandBanEvent.java | 3 +- .../api/events/island/IslandCreateEvent.java | 2 +- .../api/events/island/IslandCreatedEvent.java | 3 +- .../island/IslandDeleteChunksEvent.java | 3 +- .../api/events/island/IslandDeleteEvent.java | 3 +- .../api/events/island/IslandDeletedEvent.java | 3 +- .../api/events/island/IslandEnterEvent.java | 5 +- .../api/events/island/IslandEvent.java | 576 +------- .../api/events/island/IslandExitEvent.java | 5 +- .../api/events/island/IslandExpelEvent.java | 3 +- .../api/events/island/IslandGeneralEvent.java | 3 +- .../api/events/island/IslandLockEvent.java | 3 +- .../events/island/IslandNewIslandEvent.java | 3 +- .../events/island/IslandPreCreateEvent.java | 3 +- .../events/island/IslandPreclearEvent.java | 2 +- .../IslandProtectionRangeChangeEvent.java | 3 +- .../events/island/IslandRankChangeEvent.java | 3 +- .../events/island/IslandRegisteredEvent.java | 3 +- .../events/island/IslandReservedEvent.java | 3 +- .../api/events/island/IslandResetEvent.java | 2 +- .../events/island/IslandResettedEvent.java | 2 +- .../api/events/island/IslandUnbanEvent.java | 3 +- .../api/events/island/IslandUnlockEvent.java | 3 +- .../island/IslandUnregisteredEvent.java | 3 +- .../api/events/team/TeamDeleteEvent.java | 3 +- .../bentobox/api/events/team/TeamEvent.java | 199 +-- .../api/events/team/TeamGeneralEvent.java | 3 +- .../api/events/team/TeamInfoEvent.java | 3 +- .../api/events/team/TeamInviteEvent.java | 3 +- .../api/events/team/TeamJoinEvent.java | 3 +- .../api/events/team/TeamJoinedEvent.java | 3 +- .../api/events/team/TeamKickEvent.java | 3 +- .../api/events/team/TeamLeaveEvent.java | 3 +- .../api/events/team/TeamRejectEvent.java | 3 +- .../api/events/team/TeamSetownerEvent.java | 3 +- .../api/events/team/TeamUninviteEvent.java | 3 +- .../bentobox/bentobox/api/flags/Flag.java | 9 +- .../bentobox/api/flags/FlagListener.java | 4 +- .../api/flags/clicklisteners/CycleClick.java | 2 +- .../api/localization/TextVariables.java | 4 + .../api/panels/builders/PanelItemBuilder.java | 2 +- .../api/panels/reader/TemplateReader.java | 89 +- .../AddonPlaceholderExpansion.java | 7 +- .../BasicPlaceholderExpansion.java | 10 +- .../BentoBoxPlaceholderExpansion.java | 7 +- .../bentobox/bentobox/api/user/Notifier.java | 3 +- .../bentobox/bentobox/api/user/User.java | 111 +- .../bentobox/blueprints/Blueprint.java | 2 +- .../blueprints/BlueprintClipboard.java | 8 +- .../bentobox/blueprints/BlueprintPaster.java | 10 +- .../conversation/DescriptionPrompt.java | 3 +- .../DescriptionSuccessPrompt.java | 5 +- .../conversation/NameConversationPrefix.java | 3 +- .../blueprints/conversation/NamePrompt.java | 2 +- .../conversation/NameSuccessPrompt.java | 4 +- .../json/BentoboxTypeAdapterFactory.java | 2 +- .../mongodb/MongoDBDatabaseHandler.java | 3 +- .../bentobox/database/objects/Island.java | 109 +- .../bentobox/database/objects/Players.java | 24 +- .../transition/TransitionDatabaseHandler.java | 3 +- .../database/yaml/YamlDatabaseConnector.java | 2 +- .../database/yaml/YamlDatabaseHandler.java | 2 +- .../bentobox/hooks/LangUtilsHook.java | 6 +- .../bentobox/hooks/WorldEditHook.java | 41 - .../placeholders/PlaceholderAPIHook.java | 2 +- .../hooks/placeholders/PlaceholderHook.java | 4 +- .../bentobox/listeners/BlockEndDragon.java | 10 +- .../bentobox/listeners/JoinLeaveListener.java | 4 +- .../listeners/PlayerEntityPortalEvent.java | 5 +- .../PortalTeleportationListener.java | 9 +- .../clicklisteners/CommandCycleClick.java | 2 +- .../CommandRankClickListener.java | 4 +- .../clicklisteners/GeoLimitClickListener.java | 5 +- .../clicklisteners/MobLimitClickListener.java | 5 +- .../protection/BlockInteractionListener.java | 2 +- .../flags/protection/BreakBlocksListener.java | 50 +- .../flags/protection/BucketListener.java | 20 +- .../protection/EntityInteractListener.java | 19 +- .../protection/ExperiencePickupListener.java | 6 +- .../flags/protection/LockAndBanListener.java | 5 +- .../flags/settings/MobSpawnListener.java | 2 +- .../listeners/flags/settings/PVPListener.java | 37 +- .../flags/worldsettings/CreeperListener.java | 2 +- .../worldsettings/EnterExitListener.java | 16 +- .../InvincibleVisitorsListener.java | 4 +- .../worldsettings/IslandRespawnListener.java | 2 +- .../bentobox/managers/AddonsManager.java | 20 +- .../managers/BlueprintClipboardManager.java | 16 +- .../bentobox/managers/IslandWorldManager.java | 11 +- .../bentobox/managers/IslandsManager.java | 63 +- .../bentobox/managers/PlayersManager.java | 16 + .../DefaultNewIslandLocationStrategy.java | 2 +- .../bentobox/managers/island/NewIsland.java | 6 +- .../settings/WorldDefaultSettingsTab.java | 3 +- .../bentobox/bentobox/util/IslandInfo.java | 12 +- .../bentobox/bentobox/util/MyBiomeGrid.java | 9 +- .../util/teleport/SafeSpotTeleport.java | 26 + .../admin/AdminDeleteCommandTest.java | 61 +- .../commands/admin/AdminInfoCommandTest.java | 4 +- .../admin/AdminTeleportCommandTest.java | 5 + .../admin/AdminUnregisterCommandTest.java | 3 - .../team/AdminTeamDisbandCommandTest.java | 4 +- .../admin/team/AdminTeamKickCommandTest.java | 6 +- .../island/IslandInfoCommandTest.java | 8 +- .../island/IslandResetCommandTest.java | 8 +- .../island/IslandSethomeCommandTest.java | 6 +- .../island/IslandUnbanCommandTest.java | 30 +- .../IslandTeamInviteAcceptCommandTest.java | 5 +- .../team/IslandTeamInviteCommandTest.java | 7 +- .../team/IslandTeamSetownerCommandTest.java | 279 ++++ .../api/events/island/IslandEventTest.java | 2 +- .../bentobox/bentobox/api/flags/FlagTest.java | 4 +- .../bentobox/bentobox/api/user/UserTest.java | 27 +- .../bentobox/database/objects/IslandTest.java | 1253 +++++++++++++++++ .../listeners/JoinLeaveListenerTest.java | 4 +- .../flags/settings/MobSpawnListenerTest.java | 4 + .../worldsettings/EnterExitListenerTest.java | 1 + .../worldsettings/PistonPushListenerTest.java | 27 +- .../worldsettings/RemoveMobsListenerTest.java | 1 + .../managers/IslandWorldManagerTest.java | 8 - .../bentobox/managers/IslandsManagerTest.java | 2 - .../bentobox/managers/PlayersManagerTest.java | 38 - .../managers/island/NewIslandTest.java | 21 +- 168 files changed, 2503 insertions(+), 1633 deletions(-) delete mode 100644 src/main/java/world/bentobox/bentobox/hooks/WorldEditHook.java create mode 100644 src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java create mode 100644 src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2e3dc802..4c3b6a629 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,15 +24,18 @@ jobs: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - - name: Cache local Maven repository + - name: Cache Maven packages uses: actions/cache@v2 with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn --batch-mode clean org.jacoco:jacoco-maven-plugin:prepare-agent install + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=BentoBoxWorld_BentoBox + - run: mvn --batch-mode clean org.jacoco:jacoco-maven-plugin:prepare-agent install - run: mkdir staging && cp target/*.jar staging - name: Save artifacts uses: actions/upload-artifact@v2 diff --git a/pom.xml b/pom.xml index cccabe1e3..7cd32f209 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,9 @@ -LOCAL - 1.17.3 + 1.18.0 + bentobox-world + https://sonarcloud.io @@ -339,7 +341,33 @@ 3.0.0-M5 - --illegal-access=permit + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.math=ALL-UNNAMED + --add-opens java.base/java.io=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED + --add-opens + java.base/java.util.stream=ALL-UNNAMED + --add-opens java.base/java.text=ALL-UNNAMED + --add-opens + java.base/java.util.regex=ALL-UNNAMED + --add-opens + java.base/java.nio.channels.spi=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED + --add-opens java.base/java.net=ALL-UNNAMED + --add-opens + java.base/java.util.concurrent=ALL-UNNAMED + --add-opens java.base/sun.nio.fs=ALL-UNNAMED + --add-opens java.base/sun.nio.cs=ALL-UNNAMED + --add-opens java.base/java.nio.file=ALL-UNNAMED + --add-opens + java.base/java.nio.charset=ALL-UNNAMED + --add-opens + java.base/java.lang.reflect=ALL-UNNAMED + --add-opens + java.logging/java.util.logging=ALL-UNNAMED + --add-opens java.base/java.lang.ref=ALL-UNNAMED + --add-opens java.base/java.util.jar=ALL-UNNAMED + --add-opens java.base/java.util.zip=ALL-UNNAMED
@@ -358,12 +386,12 @@ false -Xdoclint:none - + ${java.home}/bin/javadoc
attach-javadocs - install + package jar diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index abb2d79e4..e510c6bb3 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -2,7 +2,6 @@ package world.bentobox.bentobox; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import org.apache.commons.lang.exception.ExceptionUtils; import org.bukkit.Bukkit; @@ -23,7 +22,6 @@ import world.bentobox.bentobox.database.DatabaseSetup; import world.bentobox.bentobox.hooks.DynmapHook; import world.bentobox.bentobox.hooks.MultiverseCoreHook; import world.bentobox.bentobox.hooks.VaultHook; -import world.bentobox.bentobox.hooks.WorldEditHook; import world.bentobox.bentobox.hooks.placeholders.PlaceholderAPIHook; import world.bentobox.bentobox.listeners.BannedCommands; import world.bentobox.bentobox.listeners.BlockEndDragon; @@ -103,7 +101,7 @@ public class BentoBox extends JavaPlugin { logWarning("BentoBox is tested only on the following Spigot versions:"); List versions = ServerCompatibility.ServerVersion.getVersions(ServerCompatibility.Compatibility.COMPATIBLE, ServerCompatibility.Compatibility.SUPPORTED) - .stream().map(ServerCompatibility.ServerVersion::toString).collect(Collectors.toList()); + .stream().map(ServerCompatibility.ServerVersion::toString).toList(); logWarning(String.join(", ", versions)); logWarning("**************************************"); @@ -172,6 +170,7 @@ public class BentoBox extends JavaPlugin { completeSetup(loadTime); } catch (Exception e) { fireCriticalError(e.getMessage(), ""); + e.printStackTrace(); } }); } @@ -227,7 +226,6 @@ public class BentoBox extends JavaPlugin { // Register additional hooks hooksManager.registerHook(new DynmapHook()); - hooksManager.registerHook(new WorldEditHook()); // TODO: re-enable after rework //hooksManager.registerHook(new LangUtilsHook()); @@ -333,7 +331,7 @@ public class BentoBox extends JavaPlugin { * @since 1.16.0 */ public PlayersManager getPlayersManager() { - return playersManager; + return getPlayers(); } /** @@ -352,7 +350,7 @@ public class BentoBox extends JavaPlugin { * @since 1.16.0 */ public IslandsManager getIslandsManager() { - return islandsManager; + return getIslands(); } private static void setInstance(BentoBox plugin) { diff --git a/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java b/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java index 6f5b6a512..85ba85c88 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java @@ -79,8 +79,8 @@ public class AddonClassLoader extends URLClassLoader { */ @NonNull public static AddonDescription asDescription(YamlConfiguration data) throws InvalidAddonDescriptionException { - AddonDescription.Builder builder = new AddonDescription.Builder(data.getString("main"), data.getString("name"), data.getString("version")) - .authors(data.getString("authors")) + AddonDescription.Builder builder = new AddonDescription.Builder(Objects.requireNonNull(data.getString("main")), Objects.requireNonNull(data.getString("name")), Objects.requireNonNull(data.getString("version"))) + .authors(Objects.requireNonNull(data.getString("authors"))) .metrics(data.getBoolean("metrics", true)) .repository(data.getString("repository", "")); @@ -92,7 +92,7 @@ public class AddonClassLoader extends URLClassLoader { if (softDepend != null) { builder.softDependencies(Arrays.asList(softDepend.split("\\s*,\\s*"))); } - builder.icon(Material.getMaterial(data.getString("icon", "PAPER"))); + builder.icon(Objects.requireNonNull(Material.getMaterial(data.getString("icon", "PAPER")))); String apiVersion = data.getString("api-version"); if (apiVersion != null) { diff --git a/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java b/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java index 388aac2bc..b7e35b142 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/AddonDescription.java @@ -158,26 +158,35 @@ public final class AddonDescription { * @return the permissions * @since 1.13.0 */ + @Nullable public ConfigurationSection getPermissions() { return permissions; } public static class Builder { - private @NonNull - final String main; - private @NonNull - final String name; - private @NonNull - final String version; - private @NonNull String description = ""; - private @NonNull List authors = new ArrayList<>(); - private @NonNull List dependencies = new ArrayList<>(); - private @NonNull List softDependencies = new ArrayList<>(); + @NonNull + private final String main; + @NonNull + private final String name; + @NonNull + private final String version; + @NonNull + private String description = ""; + @NonNull + private List authors = new ArrayList<>(); + @NonNull + private List dependencies = new ArrayList<>(); + @NonNull + private List softDependencies = new ArrayList<>(); private boolean metrics = true; - private @NonNull String repository = ""; - private @NonNull Material icon = Material.PAPER; - private @NonNull String apiVersion = "1"; - private @Nullable ConfigurationSection permissions; + @NonNull + private String repository = ""; + @NonNull + private Material icon = Material.PAPER; + @NonNull + private String apiVersion = "1"; + @Nullable + private ConfigurationSection permissions; /** * @since 1.1 @@ -279,6 +288,6 @@ public final class AddonDescription { @Override public String toString() { return "AddonDescription [" + (name != null ? "name=" + name + ", " : "") - + (version != null ? "version=" + version : "") + "]"; + + "version=" + version + "]"; } } diff --git a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java index 0474cb021..54cd8f6a1 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java @@ -52,9 +52,9 @@ public abstract class GameModeAddon extends Addon { public abstract WorldSettings getWorldSettings(); /** - * Checks if a player is in any of the island worlds - * @param loc - player to check - * @return true if in a world or false if not + * Checks if location is governed by this game mode + * @param loc - location to check + * @return true if location in covered by this addon or false if not */ public boolean inWorld(Location loc) { return Util.sameWorld(loc.getWorld(), islandWorld); @@ -63,7 +63,7 @@ public abstract class GameModeAddon extends Addon { /** * Checks if world is governed by this game mode * @param world - world to check - * @return true if in a world or false if not + * @return true if world in covered by this addon or false if not * @since 1.2.0 */ public boolean inWorld(World world) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java index 931dd5ebe..d2a8d6f73 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -218,7 +218,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * subcommands until it finds the right object and then runs execute on it. */ @Override - public boolean execute(CommandSender sender, String label, String[] args) { + public boolean execute(@NonNull CommandSender sender, @NonNull String label, String[] args) { // Get the User instance for this sender User user = User.getInstance(sender); // Fire an event to see if this command should be cancelled @@ -352,7 +352,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi } @Override - public BentoBox getPlugin() { + public @NonNull BentoBox getPlugin() { return plugin; } @@ -422,7 +422,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi } @Override - public String getUsage() { + public @NonNull String getUsage() { return "/" + usage; } @@ -476,9 +476,12 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * Convenience method to check if a user is a player * @param user - the User * @return true if sender is a player + * @deprecated use {@link User#isPlayer()} + * @forRemove 1.18.0 */ + @Deprecated protected boolean isPlayer(User user) { - return user.getPlayer() != null; + return user.isPlayer(); } /** @@ -521,7 +524,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * @return The instance of this {@link Command}. */ @Override - public Command setDescription(String description) { + public @NonNull Command setDescription(@NonNull String description) { super.setDescription(description); return this; } @@ -575,7 +578,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * This creates the full linking chain of commands */ @Override - public Command setUsage(String usage) { + public @NonNull Command setUsage(@NonNull String usage) { // Go up the chain CompositeCommand parentCommand = getParent(); StringBuilder u = new StringBuilder().append(getLabel()).append(" ").append(usage); @@ -590,7 +593,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi @Override @NonNull - public List tabComplete(final CommandSender sender, final String alias, final String[] args) { + public List tabComplete(final @NonNull CommandSender sender, final @NonNull String alias, final String[] args) { List options = new ArrayList<>(); // Get command object based on args entered so far CompositeCommand command = getCommandFromArgs(args); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java index c7791be91..256c65d9d 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java @@ -41,12 +41,14 @@ public class AdminDeleteCommand extends ConfirmableCommand { user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); return false; } - if (!getIslands().hasIsland(getWorld(), targetUUID)) { + UUID owner = getIslands().getOwner(getWorld(), targetUUID); + if (owner == null) { user.sendMessage("general.errors.player-has-no-island"); return false; } + // Team members should be kicked before deleting otherwise the whole team will become weird - if (getIslands().inTeam(getWorld(), targetUUID) && getIslands().getOwner(getWorld(), targetUUID).equals(targetUUID)) { + if (getIslands().inTeam(getWorld(), targetUUID) && owner.equals(targetUUID)) { user.sendMessage("commands.admin.delete.cannot-delete-owner"); return false; } @@ -55,11 +57,6 @@ public class AdminDeleteCommand extends ConfirmableCommand { @Override public boolean execute(User user, String label, List args) { - // If args are not right, show help - if (args.size() != 1) { - showHelp(this, user); - return false; - } // Get target UUID targetUUID = getPlayers().getUUID(args.get(0)); // Confirm @@ -85,38 +82,12 @@ public class AdminDeleteCommand extends ConfirmableCommand { User target = User.getInstance(targetUUID); // Remove them from this island (it still exists and will be deleted later) getIslands().removePlayer(getWorld(), targetUUID); - if (target.isOnline()) { - // Execute commands when leaving - Util.runCommands(user, getIWM().getOnLeaveCommands(getWorld()), "leave"); - // Remove money inventory etc. - if (getIWM().isOnLeaveResetEnderChest(getWorld())) { - target.getPlayer().getEnderChest().clear(); - } - if (getIWM().isOnLeaveResetInventory(getWorld())) { - target.getPlayer().getInventory().clear(); - } - if (getSettings().isUseEconomy() && getIWM().isOnLeaveResetMoney(getWorld())) { - getPlugin().getVault().ifPresent(vault -> vault.withdraw(target, vault.getBalance(target))); - } - // Reset the health - if (getIWM().isOnLeaveResetHealth(getWorld())) { - Util.resetHealth(target.getPlayer()); - } - - // Reset the hunger - if (getIWM().isOnLeaveResetHunger(getWorld())) { - target.getPlayer().setFoodLevel(20); - } - - // Reset the XP - if (getIWM().isOnLeaveResetXP(getWorld())) { - target.getPlayer().setTotalExperience(0); - } + if (target.isPlayer() && target.isOnline()) { + cleanUp(user, target); } vector = oldIsland.getCenter().toVector(); getIslands().deleteIsland(oldIsland, true, targetUUID); } - getPlayers().clearHomeLocations(getWorld(), targetUUID); if (vector == null) { user.sendMessage("general.success"); } else { @@ -124,6 +95,36 @@ public class AdminDeleteCommand extends ConfirmableCommand { } } + private void cleanUp(User user, User target) { + // Execute commands when leaving + Util.runCommands(user, getIWM().getOnLeaveCommands(getWorld()), "leave"); + // Remove money inventory etc. + if (getIWM().isOnLeaveResetEnderChest(getWorld())) { + target.getPlayer().getEnderChest().clear(); + } + if (getIWM().isOnLeaveResetInventory(getWorld())) { + target.getPlayer().getInventory().clear(); + } + if (getSettings().isUseEconomy() && getIWM().isOnLeaveResetMoney(getWorld())) { + getPlugin().getVault().ifPresent(vault -> vault.withdraw(target, vault.getBalance(target))); + } + // Reset the health + if (getIWM().isOnLeaveResetHealth(getWorld())) { + Util.resetHealth(target.getPlayer()); + } + + // Reset the hunger + if (getIWM().isOnLeaveResetHunger(getWorld())) { + target.getPlayer().setFoodLevel(20); + } + + // Reset the XP + if (getIWM().isOnLeaveResetXP(getWorld())) { + target.getPlayer().setTotalExperience(0); + } + + } + @Override public Optional> tabComplete(User user, String alias, List args) { String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java index 43b9297a7..7a835c70a 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java @@ -101,6 +101,10 @@ public class AdminSetrankCommand extends CompositeCommand { } else { island = getIslands().getIsland(getWorld(), targetUUID); } + if (island == null) { + user.sendMessage("general.errors.player-has-no-island"); + return false; + } int currentRank = island.getRank(target); island.setRank(target, rankValue); IslandEvent.builder() diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetspawnCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetspawnCommand.java index be634c117..ef7476e4f 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetspawnCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetspawnCommand.java @@ -65,10 +65,8 @@ public class AdminSetspawnCommand extends ConfirmableCommand { .build(); } // If island is owned, then unregister the owner and any members - new ImmutableSet.Builder().addAll(i.getMembers().keySet()).build().forEach(m -> { - getIslands().removePlayer(getWorld(), m); - getPlayers().clearHomeLocations(getWorld(), m); - }); + new ImmutableSet.Builder().addAll(i.getMembers().keySet()).build().forEach(m -> + getIslands().removePlayer(getWorld(), m)); } getIslands().setSpawn(i); i.setSpawnPoint(World.Environment.NORMAL, user.getLocation()); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchCommand.java index c1b5cd39d..7e0b822f6 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchCommand.java @@ -44,15 +44,15 @@ public class AdminSwitchCommand extends ConfirmableCommand { @Override public boolean execute(User user, String label, List args) { - boolean switchState = user.getMetaData("AdminCommandSwitch").map(MetaDataValue::asBoolean).orElse(false); + boolean switchState = user.getMetaData(META_TAG).map(MetaDataValue::asBoolean).orElse(false); if (switchState) { // Turn off - user.putMetaData("AdminCommandSwitch", new MetaDataValue(false)); + user.putMetaData(META_TAG, new MetaDataValue(false)); user.sendMessage("commands.admin.switch.adding"); // Adding protection bypass user.sendMessage("general.success"); } else { // Turn on - user.putMetaData("AdminCommandSwitch", new MetaDataValue(true)); + user.putMetaData(META_TAG, new MetaDataValue(true)); user.sendMessage("commands.admin.switch.removing"); // Removing protection bypass user.sendMessage("general.success"); } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java index 279531f66..abdeffe81 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java @@ -19,6 +19,7 @@ import world.bentobox.bentobox.util.teleport.SafeSpotTeleport; public class AdminTeleportCommand extends CompositeCommand { + private static final String NOT_SAFE = "general.errors.no-safe-location-found"; private @Nullable UUID targetUUID; private @Nullable User userToTeleport; @@ -86,9 +87,13 @@ public class AdminTeleportCommand extends CompositeCommand { } else if (getLabel().equals("tpend")) { world = getPlugin().getIWM().getEndWorld(getWorld()); } + if (world == null) { + user.sendMessage(NOT_SAFE); + return false; + } Location warpSpot = getSpot(world); - if (world == null || warpSpot == null) { - user.sendMessage("general.errors.no-safe-location-found"); + if (warpSpot == null) { + user.sendMessage(NOT_SAFE); return false; } @@ -99,7 +104,7 @@ public class AdminTeleportCommand extends CompositeCommand { Player player = user.getPlayer(); if (args.size() == 2) { player = userToTeleport.getPlayer(); - failureMessage = userToTeleport.getTranslation("general.errors.no-safe-location-found"); + failureMessage = userToTeleport.getTranslation(NOT_SAFE); } // Teleport @@ -118,7 +123,7 @@ public class AdminTeleportCommand extends CompositeCommand { return island.getSpawnPoint(world.getEnvironment()); } // Return the default island protection center - return getIslands().getIslandLocation(getWorld(), targetUUID).toVector().toLocation(world); + return island.getProtectionCenter().toVector().toLocation(world); } @Override diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java index bdc933463..3d64b3f1f 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java @@ -75,10 +75,7 @@ public class AdminUnregisterCommand extends ConfirmableCommand { .rankChange(RanksManager.OWNER_RANK, RanksManager.VISITOR_RANK) .build(); // Remove all island members - oldIsland.getMemberSet().forEach(m -> { - getIslands().removePlayer(getWorld(), m); - getPlayers().clearHomeLocations(getWorld(), m); - }); + oldIsland.getMemberSet().forEach(m -> getIslands().removePlayer(getWorld(), m)); // Remove all island players that reference this island oldIsland.getMembers().clear(); getIslands().save(oldIsland); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintCommand.java index 2d7514c90..a869ed72a 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintCommand.java @@ -64,21 +64,22 @@ public class AdminBlueprintCommand extends ConfirmableCommand { protected void showClipboard(User user) { displayClipboards.putIfAbsent(user, Bukkit.getScheduler().scheduleSyncRepeatingTask(getPlugin(), () -> { - if (!user.getPlayer().isOnline()) { + if (!user.isPlayer() || !user.getPlayer().isOnline()) { hideClipboard(user); } if (clipboards.containsKey(user.getUniqueId())) { BlueprintClipboard clipboard = clipboards.get(user.getUniqueId()); - if (clipboard.getPos1() != null && clipboard.getPos2() != null) { - paintAxis(user, clipboard); - } + paintAxis(user, clipboard); } }, 20, 20)); } private void paintAxis(User user, BlueprintClipboard clipboard) { + if (clipboard.getPos1() == null || clipboard.getPos2() == null) { + return; + } int minX = Math.min(clipboard.getPos1().getBlockX(), clipboard.getPos2().getBlockX()); int minY = Math.min(clipboard.getPos1().getBlockY(), clipboard.getPos2().getBlockY()); int minZ = Math.min(clipboard.getPos1().getBlockZ(), clipboard.getPos2().getBlockZ()); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintOriginCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintOriginCommand.java index 0a4def22e..df254b3bb 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintOriginCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintOriginCommand.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.api.commands.admin.blueprints; import java.util.List; +import java.util.Objects; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -34,7 +35,7 @@ public class AdminBlueprintOriginCommand extends CompositeCommand { } // Get the block player is looking at - Block b = user.getPlayer().getLineOfSight(null, 20).stream().filter(x -> !x.getType().equals(Material.AIR)).findFirst().orElse(null); + Block b = Objects.requireNonNull(user.getPlayer()).getLineOfSight(null, 20).stream().filter(x -> !x.getType().equals(Material.AIR)).findFirst().orElse(null); if (b != null) { clipboard.setOrigin(b.getLocation().toVector()); user.getPlayer().sendBlockChange(b.getLocation(), Material.REDSTONE_BLOCK.createBlockData()); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos1Command.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos1Command.java index 1fa6d9e44..534124ce6 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos1Command.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos1Command.java @@ -30,7 +30,7 @@ public class AdminBlueprintPos1Command extends CompositeCommand { return false; } clipboard.setPos1(user.getLocation()); - user.sendMessage("commands.admin.blueprint.set-pos1", "[vector]", Util.xyz(clipboard.getPos1().toVector())); + user.sendMessage("commands.admin.blueprint.set-pos1", "[vector]", Util.xyz(user.getLocation().toVector())); parent.getClipboards().put(user.getUniqueId(), clipboard); parent.showClipboard(user); return true; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos2Command.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos2Command.java index 481ece58c..9c1bcae44 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos2Command.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintPos2Command.java @@ -30,7 +30,7 @@ public class AdminBlueprintPos2Command extends CompositeCommand { return false; } clipboard.setPos2(user.getLocation()); - user.sendMessage("commands.admin.blueprint.set-pos2", "[vector]", Util.xyz((clipboard.getPos2()).toVector())); + user.sendMessage("commands.admin.blueprint.set-pos2", "[vector]", Util.xyz(user.getLocation().toVector())); parent.getClipboards().put(user.getUniqueId(), clipboard); parent.showClipboard(user); return true; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommand.java index 7c7cece13..7ec6af2ba 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/blueprints/AdminBlueprintSaveCommand.java @@ -55,7 +55,7 @@ public class AdminBlueprintSaveCommand extends ConfirmableCommand { private boolean hideAndSave(User user, AdminBlueprintCommand parent, BlueprintClipboard clipboard, String name) { parent.hideClipboard(user); boolean result = new BlueprintClipboardManager(getPlugin(), parent.getBlueprintsFolder(), clipboard).save(user, name); - if (result) { + if (result && clipboard.getBlueprint() != null) { getPlugin().getBlueprintsManager().addBlueprint(getAddon(), clipboard.getBlueprint()); } return result; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java index 62d2055d1..4569489e8 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java @@ -22,7 +22,7 @@ public class NamePrompt extends StringPrompt { private final String oldName; private final BentoBox plugin; - public NamePrompt(BentoBox plugin, @NonNull Island island, User user, String oldName) { + public NamePrompt(BentoBox plugin, @NonNull Island island, @NonNull User user, String oldName) { this.plugin = plugin; this.island = island; this.user = user; @@ -30,12 +30,12 @@ public class NamePrompt extends StringPrompt { } @Override - public String getPromptText(ConversationContext context) { + public @NonNull String getPromptText(@NonNull ConversationContext context) { return user.getTranslation("commands.island.renamehome.enter-new-name"); } @Override - public Prompt acceptInput(ConversationContext context, String input) { + public Prompt acceptInput(@NonNull ConversationContext context, String input) { if (island.renameHome(oldName, input)) { plugin.getIslands().save(island); Bukkit.getScheduler().runTask(plugin, () -> user.sendMessage("general.success")); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeAddCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeAddCommand.java index 67a9981c4..ff64a6796 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeAddCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeAddCommand.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.api.commands.admin.range; import java.util.List; +import java.util.Objects; import java.util.UUID; import org.eclipse.jdt.annotation.NonNull; @@ -52,7 +53,7 @@ public class AdminRangeAddCommand extends CompositeCommand { return false; } - Island island = getIslands().getIsland(getWorld(), targetUUID); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); int newRange = island.getProtectionRange() + Integer.parseInt(args.get(1)); if (newRange > island.getRange() * 2) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeRemoveCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeRemoveCommand.java index ee7692a11..5615ec5e7 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeRemoveCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeRemoveCommand.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.api.commands.admin.range; import java.util.List; +import java.util.Objects; import java.util.UUID; import org.eclipse.jdt.annotation.NonNull; @@ -52,7 +53,7 @@ public class AdminRangeRemoveCommand extends CompositeCommand { return false; } - Island island = getIslands().getIsland(getWorld(), targetUUID); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); int newRange = island.getProtectionRange() - Integer.parseInt(args.get(1)); if (newRange <= 1) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeResetCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeResetCommand.java index dce72db0d..4a76593d9 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeResetCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeResetCommand.java @@ -2,6 +2,7 @@ package world.bentobox.bentobox.api.commands.admin.range; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -45,7 +46,7 @@ public class AdminRangeResetCommand extends CompositeCommand { } // Get island - Island island = getIslands().getIsland(getWorld(), targetUUID); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); // Get old range for event int oldRange = island.getProtectionRange(); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeSetCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeSetCommand.java index aff757749..c63912004 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeSetCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/range/AdminRangeSetCommand.java @@ -2,6 +2,7 @@ package world.bentobox.bentobox.api.commands.admin.range; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -52,7 +53,7 @@ public class AdminRangeSetCommand extends CompositeCommand { int range = Integer.parseInt(args.get(1)); // Get island - Island island = getIslands().getIsland(getWorld(), targetUUID); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); // Do some sanity checks to make sure the new protection range won't cause problems if (range < 1) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java index 5f44195ed..77c5174a3 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommand.java @@ -72,7 +72,6 @@ public class AdminTeamKickCommand extends CompositeCommand { target.sendMessage("commands.admin.team.kick.admin-kicked"); getIslands().removePlayer(getWorld(), targetUUID); - getPlayers().clearHomeLocations(getWorld(), targetUUID); user.sendMessage("commands.admin.team.kick.success", TextVariables.NAME, target.getName(), "[owner]", getPlayers().getName(island.getOwner())); // Fire event so add-ons know diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamSetownerCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamSetownerCommand.java index 77945a9ba..2001367cc 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamSetownerCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamSetownerCommand.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.api.commands.admin.team; import java.util.List; +import java.util.Objects; import java.util.UUID; import world.bentobox.bentobox.api.commands.CompositeCommand; @@ -54,11 +55,10 @@ public class AdminTeamSetownerCommand extends CompositeCommand { } // Get the User corresponding to the current owner - User previousOwner = User.getInstance(previousOwnerUUID); User target = User.getInstance(targetUUID); // Fire event so add-ons know - Island island = getIslands().getIsland(getWorld(), targetUUID); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); // Call the setowner event TeamEvent.builder() .island(island) @@ -82,15 +82,16 @@ public class AdminTeamSetownerCommand extends CompositeCommand { user.sendMessage("commands.admin.team.setowner.success", TextVariables.NAME, args.get(0)); // Call the rank change event for the old island owner - // We need to call it AFTER the actual change. - IslandEvent.builder() - .island(island) - .involvedPlayer(previousOwnerUUID) - .admin(true) - .reason(IslandEvent.Reason.RANK_CHANGE) - .rankChange(RanksManager.OWNER_RANK, island.getRank(previousOwner)) - .build(); - + if (previousOwnerUUID != null) { + // We need to call it AFTER the actual change. + IslandEvent.builder() + .island(island) + .involvedPlayer(previousOwnerUUID) + .admin(true) + .reason(IslandEvent.Reason.RANK_CHANGE) + .rankChange(RanksManager.OWNER_RANK, island.getRank(previousOwnerUUID)) + .build(); + } return true; } } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java index ce9788d3a..7d65bf42f 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java @@ -51,8 +51,8 @@ public class IslandBanCommand extends CompositeCommand { return false; } // Check rank to use command - Island island = getIslands().getIsland(getWorld(), user); - int rank = Objects.requireNonNull(island).getRank(user); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), user)); + int rank = island.getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); return false; @@ -72,7 +72,7 @@ public class IslandBanCommand extends CompositeCommand { user.sendMessage("commands.island.ban.cannot-ban-member"); return false; } - if (getIslands().getIsland(getWorld(), playerUUID).isBanned(targetUUID)) { + if (island.isBanned(targetUUID)) { user.sendMessage("commands.island.ban.player-already-banned"); return false; } @@ -95,7 +95,7 @@ public class IslandBanCommand extends CompositeCommand { } private boolean ban(@NonNull User issuer, User target) { - Island island = getIslands().getIsland(getWorld(), issuer.getUniqueId()); + Island island = Objects.requireNonNull(getIslands().getIsland(getWorld(), issuer.getUniqueId())); // Check if player can ban any more players int banLimit = issuer.getPermissionValue(getPermissionPrefix() + "ban.maxlimit", getIWM().getBanLimit(getWorld())); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java index 0d12369c9..6e059af6b 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java @@ -113,31 +113,19 @@ public class IslandResetCommand extends ConfirmableCommand { } } + /** + * Reset island + * @param user user + * @param name name of Blueprint Bundle + * @return true if successful + */ private boolean resetIsland(User user, String name) { // Get the player's old island Island oldIsland = getIslands().getIsland(getWorld(), user); - - // Fire island preclear event - IslandEvent.builder() - .involvedPlayer(user.getUniqueId()) - .reason(Reason.PRECLEAR) - .island(oldIsland) - .oldIsland(oldIsland) - .location(oldIsland.getCenter()) - .build(); - - // Reset the island + if (oldIsland != null) { + deleteOldIsland(user, oldIsland); + } user.sendMessage("commands.island.create.creating-island"); - - // Kick all island members (including the owner) - kickMembers(oldIsland); - - // Add a reset - getPlayers().addReset(getWorld(), user.getUniqueId()); - - // Reset the homes of the player - getPlayers().clearHomeLocations(getWorld(), user.getUniqueId()); - // Create new island and then delete the old one try { Builder builder = NewIsland.builder() @@ -157,6 +145,25 @@ public class IslandResetCommand extends ConfirmableCommand { return true; } + private void deleteOldIsland(User user, Island oldIsland) { + // Fire island preclear event + IslandEvent.builder() + .involvedPlayer(user.getUniqueId()) + .reason(Reason.PRECLEAR) + .island(oldIsland) + .oldIsland(oldIsland) + .location(oldIsland.getCenter()) + .build(); + + // Reset the island + + // Kick all island members (including the owner) + kickMembers(oldIsland); + + // Add a reset + getPlayers().addReset(getWorld(), user.getUniqueId()); + } + /** * Kicks the members (incl. owner) of the island. * @since 1.7.0 diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java index 2a7a84168..5b8b5e139 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java @@ -6,6 +6,7 @@ import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.ConfirmableCommand; +import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; @@ -40,7 +41,7 @@ public class IslandSethomeCommand extends ConfirmableCommand { // Check number of homes int maxHomes = getIslands().getMaxHomes(island); if (getIslands().getNumberOfHomesIfAdded(island, String.join(" ", args)) > maxHomes) { - user.sendMessage("commands.island.sethome.too-many-homes", TextVariables.NUMBER, String.valueOf(island.getMaxHomes())); + user.sendMessage("commands.island.sethome.too-many-homes", TextVariables.NUMBER, String.valueOf(maxHomes)); user.sendMessage("commands.island.sethome.homes-are"); island.getHomes().keySet().stream().filter(s -> !s.isEmpty()).forEach(s -> user.sendMessage("commands.island.sethome.home-list-syntax", TextVariables.NAME, s)); return false; @@ -51,29 +52,30 @@ public class IslandSethomeCommand extends ConfirmableCommand { @Override public boolean execute(User user, String label, List args) { String number = String.join(" ", args); + WorldSettings ws = getIWM().getWorldSettings(user.getWorld()); // Check if the player is in the Nether if (getIWM().isNether(user.getWorld())) { // Check if he is (not) allowed to set his home here - if (!getIWM().getWorldSettings(user.getWorld()).isAllowSetHomeInNether()) { + if (!ws.isAllowSetHomeInNether()) { user.sendMessage("commands.island.sethome.nether.not-allowed"); return false; } // Check if a confirmation is required - if (getIWM().getWorldSettings(user.getWorld()).isRequireConfirmationToSetHomeInNether()) { + if (ws.isRequireConfirmationToSetHomeInNether()) { askConfirmation(user, user.getTranslation("commands.island.sethome.nether.confirmation"), () -> doSetHome(user, number)); } else { doSetHome(user, number); } } else if (getIWM().isEnd(user.getWorld())) { // Check if the player is in the End // Check if he is (not) allowed to set his home here - if (!getIWM().getWorldSettings(user.getWorld()).isAllowSetHomeInTheEnd()) { + if (!ws.isAllowSetHomeInTheEnd()) { user.sendMessage("commands.island.sethome.the-end.not-allowed"); return false; } // Check if a confirmation is required - if (getIWM().getWorldSettings(user.getWorld()).isRequireConfirmationToSetHomeInTheEnd()) { + if (ws.isRequireConfirmationToSetHomeInTheEnd()) { askConfirmation(user, user.getTranslation("commands.island.sethome.the-end.confirmation"), () -> doSetHome(user, number)); } else { doSetHome(user, number); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java index ae8d0f78e..595e6ae68 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java @@ -6,6 +6,8 @@ import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.Nullable; + import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.api.events.island.IslandEvent; @@ -21,6 +23,8 @@ import world.bentobox.bentobox.util.Util; */ public class IslandUnbanCommand extends CompositeCommand { + private @Nullable UUID targetUUID; + public IslandUnbanCommand(CompositeCommand islandCommand) { super(islandCommand, "unban", "pardon"); } @@ -55,7 +59,7 @@ public class IslandUnbanCommand extends CompositeCommand { return false; } // Get target player - UUID targetUUID = getPlayers().getUUID(args.get(0)); + targetUUID = getPlayers().getUUID(args.get(0)); if (targetUUID == null) { user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); return false; @@ -65,7 +69,7 @@ public class IslandUnbanCommand extends CompositeCommand { user.sendMessage("commands.island.unban.cannot-unban-yourself"); return false; } - if (!getIslands().getIsland(getWorld(), playerUUID).isBanned(targetUUID)) { + if (!island.isBanned(targetUUID)) { user.sendMessage("commands.island.unban.player-not-banned"); return false; } @@ -75,7 +79,7 @@ public class IslandUnbanCommand extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { - User target = User.getInstance(getPlayers().getUUID(args.get(0))); + User target = User.getInstance(targetUUID); Island island = getIslands().getIsland(getWorld(), user.getUniqueId()); // Run the event diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java index ae8d6d9f4..f24ed207c 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java @@ -148,6 +148,10 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { Island island = getIslands().getIsland(getWorld(), playerUUID); // Get the team's island Island teamIsland = getIslands().getIsland(getWorld(), prospectiveOwnerUUID); + if (teamIsland == null) { + user.sendMessage("commands.island.team.invite.errors.invalid-invite"); + return; + } if (teamIsland.getMemberSet(RanksManager.MEMBER_RANK, true).size() > getIslands().getMaxMembers(teamIsland, RanksManager.MEMBER_RANK)) { user.sendMessage("commands.island.team.invite.errors.island-is-full"); return; @@ -158,8 +162,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { cleanPlayer(user); // Add the player as a team member of the new island getIslands().setJoinTeam(teamIsland, playerUUID); - //Move player to team's island - getPlayers().clearHomeLocations(getWorld(), playerUUID); + // Move player to team's island getIslands().homeTeleportAsync(getWorld(), user.getPlayer()).thenRun(() -> { // Delete the old island if (island != null) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java index 550c557a4..2aab070fa 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java @@ -83,7 +83,7 @@ public class IslandTeamKickCommand extends ConfirmableCommand { private void kick(User user, UUID targetUUID) { User target = User.getInstance(targetUUID); - Island oldIsland = getIslands().getIsland(getWorld(), targetUUID); + Island oldIsland = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); // Should never be null because of checks above // Fire event IslandBaseEvent event = TeamEvent.builder() .island(oldIsland) diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java index 6d3ee539c..49ff21566 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java @@ -66,7 +66,7 @@ public class IslandTeamPromoteCommand extends CompositeCommand { user.sendMessage("commands.island.team.demote.errors.cant-demote-yourself"); return true; } - if (!inTeam(getWorld(), target) || !getOwner(getWorld(), user).equals(getOwner(getWorld(), target))) { + if (!inTeam(getWorld(), target) || !Objects.requireNonNull(getOwner(getWorld(), user), "Island has no owner!").equals(getOwner(getWorld(), target))) { user.sendMessage("general.errors.not-in-team"); return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java index e9b565271..f4f8b6aa3 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java @@ -1,12 +1,9 @@ package world.bentobox.bentobox.api.commands.island.team; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; -import org.bukkit.Bukkit; - import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.api.events.island.IslandEvent; @@ -35,9 +32,13 @@ public class IslandTeamSetownerCommand extends CompositeCommand { public boolean execute(User user, String label, List args) { UUID playerUUID = user.getUniqueId(); // Can use if in a team - boolean inTeam = getPlugin().getIslands().inTeam(getWorld(), playerUUID); + boolean inTeam = getIslands().inTeam(getWorld(), playerUUID); + if (!inTeam) { + user.sendMessage("general.errors.no-team"); + return false; + } UUID ownerUUID = getOwner(getWorld(), user); - if (!(inTeam && ownerUUID.equals(playerUUID))) { + if (ownerUUID == null || !ownerUUID.equals(playerUUID)) { user.sendMessage("general.errors.not-owner"); return false; } @@ -51,27 +52,23 @@ public class IslandTeamSetownerCommand extends CompositeCommand { user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); return false; } - if (!getIslands().inTeam(getWorld(), playerUUID)) { - user.sendMessage("general.errors.no-team"); - return false; - } if (targetUUID.equals(playerUUID)) { user.sendMessage("commands.island.team.setowner.errors.cant-transfer-to-yourself"); return false; } - if (!getPlugin().getIslands().getMembers(getWorld(), playerUUID).contains(targetUUID)) { + if (!getIslands().getMembers(getWorld(), playerUUID).contains(targetUUID)) { user.sendMessage("commands.island.team.setowner.errors.target-is-not-member"); return false; } // Fire event so add-ons can run commands, etc. - Island island = getIslands().getIsland(getWorld(), playerUUID); + Island island = getIslands().getIsland(getWorld(), user); // Fire event so add-ons can run commands, etc. IslandBaseEvent e = TeamEvent.builder() - .island(getIslands().getIsland(getWorld(), user.getUniqueId())) + .island(island) .reason(TeamEvent.Reason.SETOWNER) .involvedPlayer(targetUUID) .build(); - if (e.getNewEvent().map(IslandBaseEvent::isCancelled).orElse(e.isCancelled())) { + if (e.isCancelled()) { return false; } getIslands().setOwner(getWorld(), user, targetUUID); @@ -97,12 +94,8 @@ public class IslandTeamSetownerCommand extends CompositeCommand { @Override public Optional> tabComplete(User user, String alias, List args) { - List options = new ArrayList<>(); String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; - for (UUID member : getPlugin().getIslands().getMembers(getWorld(), user.getUniqueId())) { - options.add(Bukkit.getServer().getOfflinePlayer(member).getName()); - } - return Optional.of(Util.tabLimit(options, lastArg)); + return Optional.of(Util.tabLimit(getIslands().getMembers(getWorld(), user.getUniqueId()).stream().map(getPlayers()::getName).toList(), lastArg)); } } \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/events/BentoBoxEvent.java b/src/main/java/world/bentobox/bentobox/api/events/BentoBoxEvent.java index b4e45d432..efa217869 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/BentoBoxEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/BentoBoxEvent.java @@ -11,6 +11,7 @@ import java.util.Objects; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.BentoBox; @@ -22,14 +23,24 @@ import world.bentobox.bentobox.BentoBox; */ public abstract class BentoBoxEvent extends Event { - /** - * Event handler list - * @deprecated This field will be removed from BentoBoxEvent. - * Events must provide their own handlers. - */ - @Deprecated private static final HandlerList handlers = new HandlerList(); + /** + * This is here just for backwards compatibility. Users of BentoBoxEvent should implement their own getHandlers + */ + @Override + public @NonNull HandlerList getHandlers() { + return getHandlerList(); + } + + /** + * This is here just for backwards compatibility. Users of BentoBoxEvent should implement their own getHandlers + * @return HandlerList + */ + public static HandlerList getHandlerList() { + return handlers; + } + /** * The default constructor is defined for cleaner code. * This constructor assumes the BentoBoxEvent is synchronous. @@ -47,29 +58,6 @@ public abstract class BentoBoxEvent extends Event { super(async); } - /** - * @return HandlerList - * @deprecated this method will no longer be in future versions of the BentoBoxEvent. - * Each event must declare its own static handler and handler methods. - * Will be removed by https://github.com/BentoBoxWorld/BentoBox/pull/1615 - */ - @Override - @Deprecated - public HandlerList getHandlers() { - return getHandlerList(); - } - - /** - * @return HandlerList - * @deprecated this method will no longer be in future versions of the BentoBoxEvent. - * Each event must declare its own static handler and handler methods. - * Will be removed by https://github.com/BentoBoxWorld/BentoBox/pull/1615 - */ - @Deprecated - public static HandlerList getHandlerList() { - return handlers; - } - /** * Get a map of key value pairs derived from the fields of this class by reflection. * @return map diff --git a/src/main/java/world/bentobox/bentobox/api/events/BentoBoxReadyEvent.java b/src/main/java/world/bentobox/bentobox/api/events/BentoBoxReadyEvent.java index 0cb851a1d..d2b360f1b 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/BentoBoxReadyEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/BentoBoxReadyEvent.java @@ -1,6 +1,7 @@ package world.bentobox.bentobox.api.events; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; /** * Fired when plugin is ready to play and all files are loaded @@ -12,7 +13,7 @@ public class BentoBoxReadyEvent extends BentoBoxEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/OfflineMessageEvent.java b/src/main/java/world/bentobox/bentobox/api/events/OfflineMessageEvent.java index 5f906b8fc..f841e3337 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/OfflineMessageEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/OfflineMessageEvent.java @@ -3,6 +3,7 @@ package world.bentobox.bentobox.api.events; import java.util.UUID; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; /** * Fired when a message is going to an offline player @@ -16,7 +17,7 @@ public class OfflineMessageEvent extends BentoBoxEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonDisableEvent.java b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonDisableEvent.java index 8b23f342d..24e384702 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonDisableEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonDisableEvent.java @@ -4,6 +4,7 @@ import java.util.Map; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.addons.Addon; /** @@ -16,7 +17,7 @@ public class AddonDisableEvent extends AddonBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEnableEvent.java b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEnableEvent.java index b0ed6b4c4..0b15d1ff2 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEnableEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEnableEvent.java @@ -4,6 +4,7 @@ import java.util.Map; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.addons.Addon; /** @@ -16,7 +17,7 @@ public class AddonEnableEvent extends AddonBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java index 78d1cd277..46b7cb5f5 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonEvent.java @@ -25,54 +25,6 @@ public class AddonEvent { return new AddonEventBuilder(); } - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.addon.AddonEnableEvent} - */ - @Deprecated - public class AddonEnableEvent extends AddonBaseEvent { - private AddonEnableEvent(Addon addon, Map keyValues) { - // Final variables have to be declared in the constructor - super(addon, keyValues); - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.addon.AddonDisableEvent} - */ - @Deprecated - public class AddonDisableEvent extends AddonBaseEvent { - private AddonDisableEvent(Addon addon, Map keyValues) { - // Final variables have to be declared in the constructor - super(addon, keyValues); - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.addon.AddonLoadEvent} - */ - @Deprecated - public class AddonLoadEvent extends AddonBaseEvent { - private AddonLoadEvent(Addon addon, Map keyValues) { - // Final variables have to be declared in the constructor - super(addon, keyValues); - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.addon.AddonGeneralEvent} - */ - @Deprecated - public class AddonGeneralEvent extends AddonBaseEvent { - private AddonGeneralEvent(Addon addon, Map keyValues) { - // Final variables have to be declared in the constructor - super(addon, keyValues); - } - } - public class AddonEventBuilder { // Here field are NOT final. They are just used for the building. private Addon addon; @@ -99,21 +51,12 @@ public class AddonEvent { return this; } - private AddonBaseEvent getDeprecatedEvent() { - return switch (reason) { - case ENABLE -> new AddonEnableEvent(addon, keyValues); - case DISABLE -> new AddonDisableEvent(addon, keyValues); - case LOAD -> new AddonLoadEvent(addon, keyValues); - default -> new AddonGeneralEvent(addon, keyValues); - }; - } - private AddonBaseEvent getEvent() { return switch (reason) { - case ENABLE -> new world.bentobox.bentobox.api.events.addon.AddonEnableEvent(addon, keyValues); - case DISABLE -> new world.bentobox.bentobox.api.events.addon.AddonDisableEvent(addon, keyValues); - case LOAD -> new world.bentobox.bentobox.api.events.addon.AddonLoadEvent(addon, keyValues); - default -> new world.bentobox.bentobox.api.events.addon.AddonGeneralEvent(addon, keyValues); + case ENABLE -> new AddonEnableEvent(addon, keyValues); + case DISABLE -> new AddonDisableEvent(addon, keyValues); + case LOAD -> new AddonLoadEvent(addon, keyValues); + default -> new AddonGeneralEvent(addon, keyValues); }; } @@ -125,12 +68,7 @@ public class AddonEvent { // Call new event AddonBaseEvent newEvent = getEvent(); Bukkit.getPluginManager().callEvent(newEvent); - // Get the old event - AddonBaseEvent e = getDeprecatedEvent(); - e.setNewEvent(newEvent); - // Call deprecated event - Bukkit.getPluginManager().callEvent(e); - return e; + return newEvent; } } } diff --git a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonGeneralEvent.java b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonGeneralEvent.java index 18fce6493..8d6a70931 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonGeneralEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonGeneralEvent.java @@ -4,6 +4,7 @@ import java.util.Map; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.addons.Addon; /** @@ -16,7 +17,7 @@ public class AddonGeneralEvent extends AddonBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonLoadEvent.java b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonLoadEvent.java index 9f4ff3508..4228ff623 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/addon/AddonLoadEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/addon/AddonLoadEvent.java @@ -4,6 +4,7 @@ import java.util.Map; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.addons.Addon; /** @@ -16,7 +17,7 @@ public class AddonLoadEvent extends AddonBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/command/CommandEvent.java b/src/main/java/world/bentobox/bentobox/api/events/command/CommandEvent.java index ba1c7c59a..2686d6a84 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/command/CommandEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/command/CommandEvent.java @@ -6,6 +6,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.BentoBoxEvent; /** @@ -24,7 +25,7 @@ public class CommandEvent extends BentoBoxEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/flags/FlagProtectionChangeEvent.java b/src/main/java/world/bentobox/bentobox/api/events/flags/FlagProtectionChangeEvent.java index 44b692e11..1b6f3c018 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/flags/FlagProtectionChangeEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/flags/FlagProtectionChangeEvent.java @@ -4,6 +4,7 @@ import java.util.UUID; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.database.objects.Island; @@ -18,7 +19,7 @@ public class FlagProtectionChangeEvent extends FlagChangeEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/flags/FlagSettingChangeEvent.java b/src/main/java/world/bentobox/bentobox/api/events/flags/FlagSettingChangeEvent.java index 6608755fe..bbe6d8d0c 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/flags/FlagSettingChangeEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/flags/FlagSettingChangeEvent.java @@ -4,6 +4,7 @@ import java.util.UUID; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.database.objects.Island; @@ -18,7 +19,7 @@ public class FlagSettingChangeEvent extends FlagChangeEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/flags/FlagWorldSettingChangeEvent.java b/src/main/java/world/bentobox/bentobox/api/events/flags/FlagWorldSettingChangeEvent.java index c7a62b873..307542a82 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/flags/FlagWorldSettingChangeEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/flags/FlagWorldSettingChangeEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.World; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.flags.Flag; /** @@ -18,7 +19,7 @@ public class FlagWorldSettingChangeEvent extends FlagChangeEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandBanEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandBanEvent.java index b610008f3..fb078e00e 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandBanEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandBanEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -19,7 +20,7 @@ public class IslandBanEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreateEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreateEvent.java index d855d3ace..75d56792f 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreateEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreateEvent.java @@ -20,7 +20,7 @@ public class IslandCreateEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreatedEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreatedEvent.java index e31de98af..dcfb602cf 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreatedEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandCreatedEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -16,7 +17,7 @@ public class IslandCreatedEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteChunksEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteChunksEvent.java index a1647b2e8..380da8974 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteChunksEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteChunksEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.IslandDeletion; @@ -19,7 +20,7 @@ public class IslandDeleteChunksEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteEvent.java index bfa21a47c..4a46eba36 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeleteEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandDeleteEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeletedEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeletedEvent.java index a6af36f75..b566f9b32 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeletedEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandDeletedEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.IslandDeletion; @@ -21,7 +22,7 @@ public class IslandDeletedEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandEnterEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandEnterEvent.java index b1125f652..eaf732e4b 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandEnterEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandEnterEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.events.IslandBaseEvent; @@ -20,7 +21,7 @@ public class IslandEnterEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } @@ -28,7 +29,7 @@ public class IslandEnterEvent extends IslandBaseEvent { return handlers; } - IslandEnterEvent(Island island, UUID player, boolean admin, Location location, Island fromIsland, Event rawEvent) { + IslandEnterEvent(Island island, UUID player, boolean admin, Location location, @Nullable Island fromIsland, Event rawEvent) { // Final variables have to be declared in the constructor super(island, player, admin, location, rawEvent); this.fromIsland = fromIsland; diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java index 14aad63ff..701d553d3 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandEvent.java @@ -7,7 +7,6 @@ import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; @@ -26,7 +25,7 @@ public class IslandEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } @@ -177,496 +176,6 @@ public class IslandEvent extends IslandBaseEvent { return new IslandEventBuilder(); } - /** - * Fired when a player's rank has changed on an island. - * Cancellation has no effect. - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandRankChangeEvent} - * @since 1.13.0 - */ - @Deprecated - public static class IslandRankChangeEvent extends IslandBaseEvent { - - private final int oldRank; - private final int newRank; - - public IslandRankChangeEvent(Island island, UUID playerUUID, boolean admin, Location location, int oldRank, int newRank) { - super(island, playerUUID, admin, location); - this.oldRank = oldRank; - this.newRank = newRank; - } - - public int getOldRank() { - return oldRank; - } - - public int getNewRank(){ - return newRank; - } - } - - /** - * Fired when a player will be expelled from an island. - * May be cancelled. - * Cancellation will result in the expel being aborted. - * - * @since 1.4.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandExpelEvent} - */ - @Deprecated - public static class IslandExpelEvent extends IslandBaseEvent { - private IslandExpelEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * Fired when a player will be banned from an island. - * May be cancelled. - * Cancellation will result in the ban being aborted. - * - * @since 1.1 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandBanEvent} - */ - @Deprecated - public static class IslandBanEvent extends IslandBaseEvent { - private IslandBanEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * Fired when a player will be banned from an island. - * May be cancelled. - * Cancellation will result in the unban being aborted. - * - * @since 1.1 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandUnbanEvent} - */ - @Deprecated - public static class IslandUnbanEvent extends IslandBaseEvent { - public IslandUnbanEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * Fired when attempting to make a new island. - * May be cancelled. No island object exists at this point. - * @since 1.15.1 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandPreCreateEvent} - */ - @Deprecated - public static class IslandPreCreateEvent extends IslandBaseEvent { - private IslandPreCreateEvent(UUID player) { - // Final variables have to be declared in the constructor - super(null, player, false, null); - } - } - - /** - * Fired when an island is going to be created. - * May be cancelled. - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandCreateEvent} - */ - @Deprecated - public static class IslandCreateEvent extends IslandBaseEvent { - private @NonNull BlueprintBundle blueprintBundle; - - private IslandCreateEvent(Island island, UUID player, boolean admin, Location location, @NonNull BlueprintBundle blueprintBundle) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - this.blueprintBundle = blueprintBundle; - } - - /** - * @since 1.6.0 - */ - @NonNull - public BlueprintBundle getBlueprintBundle() { - return blueprintBundle; - } - - /** - * @since 1.6.0 - */ - public void setBlueprintBundle(@NonNull BlueprintBundle blueprintBundle) { - this.blueprintBundle = blueprintBundle; - } - } - /** - * Fired when an island is created. - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandCreatedEvent} - */ - @Deprecated - public static class IslandCreatedEvent extends IslandBaseEvent { - private IslandCreatedEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * Fired when an island is going to be deleted. - * May be cancelled. - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandDeleteEvent} - */ - @Deprecated - public static class IslandDeleteEvent extends IslandBaseEvent { - private IslandDeleteEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * Fired when an island chunks are going to be deleted. - * May be cancelled. - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandDeleteChunksEvent} - */ - @Deprecated - public static class IslandDeleteChunksEvent extends IslandBaseEvent { - private final IslandDeletion deletedIslandInfo; - - private IslandDeleteChunksEvent(Island island, UUID player, boolean admin, Location location, IslandDeletion deletedIsland) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - this.deletedIslandInfo = deletedIsland; - } - - public IslandDeletion getDeletedIslandInfo() { - return deletedIslandInfo; - } - } - /** - * Fired when island blocks are going to be deleted. - * If canceled, the island blocks will not be deleted. Note that by the time this is called - * the ownership of the island may have been removed. This event is just for detecting - * that the island blocks are going to be removed. - * - * @deprecated This event is moving to its own class. - * - */ - @Deprecated - public static class IslandDeletedEvent extends IslandBaseEvent { - private final IslandDeletion deletedIslandInfo; - - private IslandDeletedEvent(Island island, UUID player, boolean admin, Location location, IslandDeletion deletedIsland) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - this.deletedIslandInfo = deletedIsland; - } - - public IslandDeletion getDeletedIslandInfo() { - return deletedIslandInfo; - } - } - - /** - * Fired when a player is unregistered from an island. - * @since 1.3.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandUnregisteredEvent} - */ - @Deprecated - public static class IslandUnregisteredEvent extends IslandBaseEvent { - private IslandUnregisteredEvent(Island island, UUID player, boolean admin, Location location) { - super(island, player, admin, location); - } - } - - /** - * Fired when a player is registered from an island. - * @since 1.3.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandRegisteredEvent} - */ - @Deprecated - public static class IslandRegisteredEvent extends IslandBaseEvent { - private IslandRegisteredEvent(Island island, UUID player, boolean admin, Location location) { - super(island, player, admin, location); - } - } - - /** - * Fired when an island is reserved for a player - * @since 1.12.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandReservedEvent} - */ - @Deprecated - public static class IslandReservedEvent extends IslandBaseEvent { - private IslandReservedEvent(Island island, UUID player, boolean admin, Location location) { - super(island, player, admin, location); - } - } - - /** - * Fired when an a player enters an island. - * Cancellation has no effect. - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandEnterEvent} - */ - @Deprecated - public static class IslandEnterEvent extends IslandBaseEvent { - - private final @Nullable Island fromIsland; - - private IslandEnterEvent(Island island, UUID player, boolean admin, Location location, Island fromIsland, Event rawEvent) { - // Final variables have to be declared in the constructor - super(island, player, admin, location, rawEvent); - this.fromIsland = fromIsland; - } - - @Nullable - public Island getFromIsland() { - return fromIsland; - } - } - /** - * Fired when a player exits an island. - * Cancellation has no effect. - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandExitEvent} - */ - @Deprecated - public static class IslandExitEvent extends IslandBaseEvent { - - private final @Nullable Island toIsland; - - - private IslandExitEvent(Island island, UUID player, boolean admin, Location location, Island toIsland, Event rawEvent) { - // Final variables have to be declared in the constructor - super(island, player, admin, location, rawEvent); - this.toIsland = toIsland; - } - - @Nullable - public Island getToIsland() { - return toIsland; - } - - - } - /** - * Fired when an island is locked - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandLockEvent} - */ - @Deprecated - public static class IslandLockEvent extends IslandBaseEvent { - private IslandLockEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * Fired when an island is unlocked - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandUnlockEvent} - */ - @Deprecated - public static class IslandUnlockEvent extends IslandBaseEvent { - private IslandUnlockEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * Fired before an island has its player data cleared, e.g., just before a reset - * @since 1.12.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandPreclearEvent} - */ - @Deprecated - public static class IslandPreclearEvent extends IslandBaseEvent { - private final @NonNull Island oldIsland; - - private IslandPreclearEvent(Island island, UUID player, boolean admin, Location location, @NonNull Island oldIsland) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - // Create a copy of the old island - this.oldIsland = new Island(oldIsland); - } - - /** - * @since 1.12.0 - */ - @NonNull - public Island getOldIsland() { - return oldIsland; - } - } - - /** - * Fired when an island is going to be reset. - * May be cancelled. - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandResetEvent} - */ - @Deprecated - public static class IslandResetEvent extends IslandBaseEvent { - private final @NonNull Island oldIsland; - private @NonNull BlueprintBundle blueprintBundle; - - private IslandResetEvent(Island island, UUID player, boolean admin, Location location, @NonNull BlueprintBundle blueprintBundle, @NonNull Island oldIsland) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - this.blueprintBundle = blueprintBundle; - // Create a copy of the old island - this.oldIsland = new Island(oldIsland); - } - - /** - * @since 1.12.0 - */ - @NonNull - public Island getOldIsland() { - return oldIsland; - } - - /** - * @since 1.6.0 - */ - @NonNull - public BlueprintBundle getBlueprintBundle() { - return blueprintBundle; - } - - /** - * @since 1.6.0 - */ - public void setBlueprintBundle(@NonNull BlueprintBundle blueprintBundle) { - this.blueprintBundle = blueprintBundle; - } - } - /** - * Fired after an island is reset - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandResettedEvent} - */ - @Deprecated - public static class IslandResettedEvent extends IslandBaseEvent { - private final @NonNull Island oldIsland; - - private IslandResettedEvent(Island island, UUID player, boolean admin, Location location, Island oldIsland) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - // Create a copy of the old island - this.oldIsland = new Island(oldIsland); - } - - /** - * @since 1.12.0 - */ - @NonNull - public Island getOldIsland() { - return oldIsland; - } - } - /** - * Fired when something happens to the island not covered by other events - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandGeneralEvent} - */ - @Deprecated - public static class IslandGeneralEvent extends IslandBaseEvent { - private IslandGeneralEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - - /** - * Fired when island protection range is changed. - * @since 1.11.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.island.IslandProtectionRangeChangeEvent} - */ - @Deprecated - public static class IslandProtectionRangeChangeEvent extends IslandBaseEvent { - /** - * New protection range value. - */ - private int newRange; - - /** - * Old protection range value. - */ - private int oldRange; - - /** - * Constructor IslandProtectionRangeChange creates a new IslandProtectionRangeChange instance. - * - * @param island of type Island - * @param player of type UUID - * @param admin of type boolean - * @param location of type Location - * @param newRange of type int - * @param oldRange of type int - */ - private IslandProtectionRangeChangeEvent(Island island, UUID player, boolean admin, Location location, int newRange, int oldRange) { - super(island, player, admin, location); - this.newRange = newRange; - this.oldRange = oldRange; - } - - - /** - * This method returns the newRange value. - * @return the value of newRange. - */ - public int getNewRange() { - return newRange; - } - - - /** - * This method returns the oldRange value. - * @return the value of oldRange. - */ - public int getOldRange() { - return oldRange; - } - - - /** - * This method sets the newRange value. - * @param newRange the newRange new value. - */ - public void setNewRange(int newRange) { - this.newRange = newRange; - } - - - /** - * This method sets the oldRange value. - * @param oldRange the oldRange new value. - */ - public void setOldRange(int oldRange) { - this.oldRange = oldRange; - } - } - public static class IslandEventBuilder { // Here field are NOT final. They are just used for the building. @@ -796,62 +305,31 @@ public class IslandEvent extends IslandBaseEvent { return this; } - /** - * Get the deprecated IslandEvent - * @return deprecated event - */ - private IslandBaseEvent getDeprecatedEvent() { - return switch (reason) { - case EXPEL -> new IslandExpelEvent(island, player, admin, location); - case BAN -> new IslandBanEvent(island, player, admin, location); - case PRECREATE -> new IslandPreCreateEvent(player); - case CREATE -> new IslandCreateEvent(island, player, admin, location, blueprintBundle); - case CREATED -> new IslandCreatedEvent(island, player, admin, location); - case DELETE -> new IslandDeleteEvent(island, player, admin, location); - case DELETE_CHUNKS -> new IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); - case DELETED -> new IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); - case ENTER -> new IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); - case EXIT -> new IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); - case LOCK -> new IslandLockEvent(island, player, admin, location); - case RESET -> new IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); - case RESETTED -> new IslandResettedEvent(island, player, admin, location, oldIsland); - case UNBAN -> new IslandUnbanEvent(island, player, admin, location); - case UNLOCK -> new IslandUnlockEvent(island, player, admin, location); - case REGISTERED -> new IslandRegisteredEvent(island, player, admin, location); - case UNREGISTERED -> new IslandUnregisteredEvent(island, player, admin, location); - case RANGE_CHANGE -> new IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); - case PRECLEAR -> new IslandPreclearEvent(island, player, admin, location, oldIsland); - case RESERVED -> new IslandReservedEvent(island, player, admin, location); - case RANK_CHANGE -> new IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); - default -> new IslandGeneralEvent(island, player, admin, location); - }; - } - private IslandBaseEvent getEvent() { return switch (reason) { - case EXPEL -> new world.bentobox.bentobox.api.events.island.IslandExpelEvent(island, player, admin, location); - case BAN -> new world.bentobox.bentobox.api.events.island.IslandBanEvent(island, player, admin, location); - case PRECREATE -> new world.bentobox.bentobox.api.events.island.IslandPreCreateEvent(player); - case CREATE -> new world.bentobox.bentobox.api.events.island.IslandCreateEvent(island, player, admin, location, blueprintBundle); - case CREATED -> new world.bentobox.bentobox.api.events.island.IslandCreatedEvent(island, player, admin, location); - case DELETE -> new world.bentobox.bentobox.api.events.island.IslandDeleteEvent(island, player, admin, location); - case DELETE_CHUNKS -> new world.bentobox.bentobox.api.events.island.IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); - case DELETED -> new world.bentobox.bentobox.api.events.island.IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); - case ENTER -> new world.bentobox.bentobox.api.events.island.IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); - case EXIT -> new world.bentobox.bentobox.api.events.island.IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); - case LOCK -> new world.bentobox.bentobox.api.events.island.IslandLockEvent(island, player, admin, location); - case RESET -> new world.bentobox.bentobox.api.events.island.IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); - case RESETTED -> new world.bentobox.bentobox.api.events.island.IslandResettedEvent(island, player, admin, location, oldIsland); - case UNBAN -> new world.bentobox.bentobox.api.events.island.IslandUnbanEvent(island, player, admin, location); - case UNLOCK -> new world.bentobox.bentobox.api.events.island.IslandUnlockEvent(island, player, admin, location); - case REGISTERED -> new world.bentobox.bentobox.api.events.island.IslandRegisteredEvent(island, player, admin, location); - case UNREGISTERED -> new world.bentobox.bentobox.api.events.island.IslandUnregisteredEvent(island, player, admin, location); - case RANGE_CHANGE -> new world.bentobox.bentobox.api.events.island.IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); - case PRECLEAR -> new world.bentobox.bentobox.api.events.island.IslandPreclearEvent(island, player, admin, location, oldIsland); - case RESERVED -> new world.bentobox.bentobox.api.events.island.IslandReservedEvent(island, player, admin, location); - case RANK_CHANGE -> new world.bentobox.bentobox.api.events.island.IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); - case NEW_ISLAND -> new IslandNewIslandEvent(island, player, admin, location); - default -> new world.bentobox.bentobox.api.events.island.IslandGeneralEvent(island, player, admin, location); + case EXPEL -> new IslandExpelEvent(island, player, admin, location); + case BAN -> new IslandBanEvent(island, player, admin, location); + case PRECREATE -> new IslandPreCreateEvent(player); + case CREATE -> new IslandCreateEvent(island, player, admin, location, blueprintBundle); + case CREATED -> new IslandCreatedEvent(island, player, admin, location); + case DELETE -> new IslandDeleteEvent(island, player, admin, location); + case DELETE_CHUNKS -> new IslandDeleteChunksEvent(island, player, admin, location, deletedIslandInfo); + case DELETED -> new IslandDeletedEvent(island, player, admin, location, deletedIslandInfo); + case ENTER -> new IslandEnterEvent(island, player, admin, location, oldIsland, rawEvent); + case EXIT -> new IslandExitEvent(island, player, admin, location, oldIsland, rawEvent); + case LOCK -> new IslandLockEvent(island, player, admin, location); + case RESET -> new IslandResetEvent(island, player, admin, location, blueprintBundle, oldIsland); + case RESETTED -> new IslandResettedEvent(island, player, admin, location, oldIsland); + case UNBAN -> new IslandUnbanEvent(island, player, admin, location); + case UNLOCK -> new IslandUnlockEvent(island, player, admin, location); + case REGISTERED -> new IslandRegisteredEvent(island, player, admin, location); + case UNREGISTERED -> new IslandUnregisteredEvent(island, player, admin, location); + case RANGE_CHANGE -> new IslandProtectionRangeChangeEvent(island, player, admin, location, newRange, oldRange); + case PRECLEAR -> new IslandPreclearEvent(island, player, admin, location, oldIsland); + case RESERVED -> new IslandReservedEvent(island, player, admin, location); + case RANK_CHANGE -> new IslandRankChangeEvent(island, player, admin, location, oldRank, newRank); + case NEW_ISLAND -> new IslandNewIslandEvent(island, player, admin, location); + default -> new IslandGeneralEvent(island, player, admin, location); }; } @@ -865,11 +343,7 @@ public class IslandEvent extends IslandBaseEvent { // Generate new event IslandBaseEvent newEvent = getEvent(); Bukkit.getPluginManager().callEvent(newEvent); - // Generate deprecated events - IslandBaseEvent e = getDeprecatedEvent(); - e.setNewEvent(newEvent); - Bukkit.getPluginManager().callEvent(e); - return e; + return newEvent; } } } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandExitEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandExitEvent.java index 62302be7d..c378a473f 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandExitEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandExitEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.events.IslandBaseEvent; @@ -20,7 +21,7 @@ public class IslandExitEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } @@ -28,7 +29,7 @@ public class IslandExitEvent extends IslandBaseEvent { return handlers; } - IslandExitEvent(Island island, UUID player, boolean admin, Location location, Island toIsland, Event rawEvent) { + IslandExitEvent(Island island, UUID player, boolean admin, Location location, @Nullable Island toIsland, Event rawEvent) { // Final variables have to be declared in the constructor super(island, player, admin, location, rawEvent); this.toIsland = toIsland; diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandExpelEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandExpelEvent.java index a263c7f30..f60d1a770 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandExpelEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandExpelEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -20,7 +21,7 @@ public class IslandExpelEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandGeneralEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandGeneralEvent.java index ef02c2ea5..c8f9cc3ae 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandGeneralEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandGeneralEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandGeneralEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandLockEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandLockEvent.java index 023d13b49..9783c9e1c 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandLockEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandLockEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandLockEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandNewIslandEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandNewIslandEvent.java index bdc2a38af..583cbea40 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandNewIslandEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandNewIslandEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandNewIslandEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreCreateEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreCreateEvent.java index 95d405eb4..99fa17e2f 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreCreateEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreCreateEvent.java @@ -4,6 +4,7 @@ import java.util.UUID; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; /** @@ -16,7 +17,7 @@ public class IslandPreCreateEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreclearEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreclearEvent.java index acc482a08..5b9d54381 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreclearEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandPreclearEvent.java @@ -19,7 +19,7 @@ public class IslandPreclearEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandProtectionRangeChangeEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandProtectionRangeChangeEvent.java index b23dc7503..d033f5fa5 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandProtectionRangeChangeEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandProtectionRangeChangeEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandProtectionRangeChangeEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandRankChangeEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandRankChangeEvent.java index 96aef05da..e27f1b0ca 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandRankChangeEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandRankChangeEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -20,7 +21,7 @@ public class IslandRankChangeEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandRegisteredEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandRegisteredEvent.java index 7e39e5509..c8b77c2a8 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandRegisteredEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandRegisteredEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandRegisteredEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandReservedEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandReservedEvent.java index e18f9d976..e8dc7738b 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandReservedEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandReservedEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandReservedEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandResetEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandResetEvent.java index 980438689..1b7a4043c 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandResetEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandResetEvent.java @@ -21,7 +21,7 @@ public class IslandResetEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandResettedEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandResettedEvent.java index 448a96758..5b8200a7c 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandResettedEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandResettedEvent.java @@ -19,7 +19,7 @@ public class IslandResettedEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnbanEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnbanEvent.java index b4c497d59..94ab59e1e 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnbanEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnbanEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -20,7 +21,7 @@ public class IslandUnbanEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnlockEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnlockEvent.java index f2eefc8e1..c44437497 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnlockEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnlockEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandUnlockEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnregisteredEvent.java b/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnregisteredEvent.java index 36a2f0e91..c3304cf9e 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnregisteredEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/island/IslandUnregisteredEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class IslandUnregisteredEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamDeleteEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamDeleteEvent.java index 73351cefc..863a6591c 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamDeleteEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamDeleteEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamDeleteEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java index 94791ef72..d587e6af7 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamEvent.java @@ -36,161 +36,6 @@ public class TeamEvent { return new TeamEventBuilder(); } - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamJoinEvent} - */ - @Deprecated - public static class TeamJoinEvent extends IslandBaseEvent { - private TeamJoinEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * Called after a player has joined an island - * @since 1.3.0 - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamJoinedEvent} - */ - @Deprecated - public static class TeamJoinedEvent extends IslandBaseEvent { - /** - * Called after a player has joined an island - * @param island - island - * @param player - player - * @param admin - whether this was due to an admin action - * @param location - location - * @since 1.3.0 - */ - private TeamJoinedEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamInviteEvent} - */ - @Deprecated - public static class TeamInviteEvent extends IslandBaseEvent { - private TeamInviteEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamLeaveEvent} - */ - @Deprecated - public static class TeamLeaveEvent extends IslandBaseEvent { - private TeamLeaveEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamRejectEvent} - */ - @Deprecated - public static class TeamRejectEvent extends IslandBaseEvent { - private TeamRejectEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamKickEvent} - */ - @Deprecated - public static class TeamKickEvent extends IslandBaseEvent { - private TeamKickEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - /** - * Event fires before a setowner is performed on an island. - * To get the old owner, get from the island object. The new owner is the player's UUID. - * @author tastybento - * - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamSetownerEvent} - */ - @Deprecated - public static class TeamSetownerEvent extends IslandBaseEvent { - private TeamSetownerEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - /** - * Convenience method to get the old owner of the island - * @return UUID of old owner - */ - public UUID getOldOwner() { - return island.getOwner(); - } - /** - * Convenience method to get the new owner of the island - * @return UUID of new owner - */ - public UUID getNewOwner() { - return playerUUID; - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamInfoEvent} - */ - @Deprecated - public static class TeamInfoEvent extends IslandBaseEvent { - private TeamInfoEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamDeleteEvent} - */ - @Deprecated - public static class TeamDeleteEvent extends IslandBaseEvent { - private TeamDeleteEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamUninviteEvent} - */ - @Deprecated - public static class TeamUninviteEvent extends IslandBaseEvent { - private TeamUninviteEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - - /** - * @deprecated This event is moving to its own class. - * Use {@link world.bentobox.bentobox.api.events.team.TeamGeneralEvent} - */ - @Deprecated - public static class TeamGeneralEvent extends IslandBaseEvent { - private TeamGeneralEvent(Island island, UUID player, boolean admin, Location location) { - // Final variables have to be declared in the constructor - super(island, player, admin, location); - } - } - public static class TeamEventBuilder { private Island island; private UUID player; @@ -236,35 +81,19 @@ public class TeamEvent { return this; } - private IslandBaseEvent getDeprecatedEvent() { - return switch (reason) { - case JOIN -> new TeamJoinEvent(island, player, admin, location); - case JOINED -> new TeamJoinedEvent(island, player, admin, location); - case INVITE -> new TeamInviteEvent(island, player, admin, location); - case LEAVE -> new TeamLeaveEvent(island, player, admin, location); - case REJECT -> new TeamRejectEvent(island, player, admin, location); - case KICK -> new TeamKickEvent(island, player, admin, location); - case SETOWNER -> new TeamSetownerEvent(island, player, admin, location); - case INFO -> new TeamInfoEvent(island, player, admin, location); - case DELETE -> new TeamDeleteEvent(island, player, admin, location); - case UNINVITE -> new TeamUninviteEvent(island, player, admin, location); - default -> new TeamGeneralEvent(island, player, admin, location); - }; - } - private IslandBaseEvent getEvent() { return switch (reason) { - case JOIN -> new world.bentobox.bentobox.api.events.team.TeamJoinEvent(island, player, admin, location); - case JOINED -> new world.bentobox.bentobox.api.events.team.TeamJoinedEvent(island, player, admin, location); - case INVITE -> new world.bentobox.bentobox.api.events.team.TeamInviteEvent(island, player, admin, location); - case LEAVE -> new world.bentobox.bentobox.api.events.team.TeamLeaveEvent(island, player, admin, location); - case REJECT -> new world.bentobox.bentobox.api.events.team.TeamRejectEvent(island, player, admin, location); - case KICK -> new world.bentobox.bentobox.api.events.team.TeamKickEvent(island, player, admin, location); - case SETOWNER -> new world.bentobox.bentobox.api.events.team.TeamSetownerEvent(island, player, admin, location); - case INFO -> new world.bentobox.bentobox.api.events.team.TeamInfoEvent(island, player, admin, location); - case DELETE -> new world.bentobox.bentobox.api.events.team.TeamDeleteEvent(island, player, admin, location); - case UNINVITE -> new world.bentobox.bentobox.api.events.team.TeamUninviteEvent(island, player, admin, location); - default -> new world.bentobox.bentobox.api.events.team.TeamGeneralEvent(island, player, admin, location); + case JOIN -> new TeamJoinEvent(island, player, admin, location); + case JOINED -> new TeamJoinedEvent(island, player, admin, location); + case INVITE -> new TeamInviteEvent(island, player, admin, location); + case LEAVE -> new TeamLeaveEvent(island, player, admin, location); + case REJECT -> new TeamRejectEvent(island, player, admin, location); + case KICK -> new TeamKickEvent(island, player, admin, location); + case SETOWNER -> new TeamSetownerEvent(island, player, admin, location); + case INFO -> new TeamInfoEvent(island, player, admin, location); + case DELETE -> new TeamDeleteEvent(island, player, admin, location); + case UNINVITE -> new TeamUninviteEvent(island, player, admin, location); + default -> new TeamGeneralEvent(island, player, admin, location); }; } @@ -276,11 +105,7 @@ public class TeamEvent { // Generate new event IslandBaseEvent newEvent = getEvent(); Bukkit.getPluginManager().callEvent(newEvent); - // Generate deprecated events - IslandBaseEvent e = getDeprecatedEvent(); - e.setNewEvent(newEvent); - Bukkit.getPluginManager().callEvent(e); - return e; + return newEvent; } } } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamGeneralEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamGeneralEvent.java index ccfa53cbf..1e71493eb 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamGeneralEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamGeneralEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamGeneralEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamInfoEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamInfoEvent.java index bb945a6aa..14dbc8214 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamInfoEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamInfoEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamInfoEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamInviteEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamInviteEvent.java index 6322d6e9e..1a1fca2f2 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamInviteEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamInviteEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamInviteEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinEvent.java index 72eb10e0c..73940e019 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamJoinEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinedEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinedEvent.java index 051b8bf44..e750154a0 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinedEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamJoinedEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -17,7 +18,7 @@ public class TeamJoinedEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamKickEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamKickEvent.java index 9b9a253af..00a8a11ff 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamKickEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamKickEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamKickEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamLeaveEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamLeaveEvent.java index 95f5b732b..28ca431a0 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamLeaveEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamLeaveEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -18,7 +19,7 @@ public class TeamLeaveEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamRejectEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamRejectEvent.java index 6352a742f..adcd4359c 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamRejectEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamRejectEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamRejectEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamSetownerEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamSetownerEvent.java index f0abd6647..2d0b81892 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamSetownerEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamSetownerEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -19,7 +20,7 @@ public class TeamSetownerEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/events/team/TeamUninviteEvent.java b/src/main/java/world/bentobox/bentobox/api/events/team/TeamUninviteEvent.java index 8c7371529..60953cd8e 100644 --- a/src/main/java/world/bentobox/bentobox/api/events/team/TeamUninviteEvent.java +++ b/src/main/java/world/bentobox/bentobox/api/events/team/TeamUninviteEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Location; import org.bukkit.event.HandlerList; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.database.objects.Island; @@ -13,7 +14,7 @@ public class TeamUninviteEvent extends IslandBaseEvent { private static final HandlerList handlers = new HandlerList(); @Override - public HandlerList getHandlers() { + public @NonNull HandlerList getHandlers() { return getHandlerList(); } diff --git a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java index ed60c42ff..2acd4f604 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -175,8 +175,10 @@ public class Flag implements Comparable { * If world is not a game world, then the result will always be false! */ public boolean isSetForWorld(World world) { + if (!BentoBox.getInstance().getIWM().inWorld(world)) { + return false; + } WorldSettings ws = BentoBox.getInstance().getIWM().getWorldSettings(world); - if (ws == null) return false; if (type.equals(Type.WORLD_SETTING) || type.equals(Type.PROTECTION)) { if (!ws.getWorldFlags().containsKey(getID())) { ws.getWorldFlags().put(getID(), setting); @@ -234,12 +236,11 @@ public class Flag implements Comparable { * @param defaultSetting - true means it is allowed. false means it is not allowed */ public void setDefaultSetting(World world, boolean defaultSetting) { - WorldSettings ws = BentoBox.getInstance().getIWM().getWorldSettings(world); - if (ws == null ) { + if (!BentoBox.getInstance().getIWM().inWorld(world)) { BentoBox.getInstance().logError("Attempt to set default world setting for unregistered world. Register flags in onEnable."); return; } - ws.getWorldFlags().put(getID(), defaultSetting); + BentoBox.getInstance().getIWM().getWorldSettings(world).getWorldFlags().put(getID(), defaultSetting); // Save config file BentoBox.getInstance().getIWM().getAddon(world).ifPresent(GameModeAddon::saveWorldSettings); } diff --git a/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java b/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java index dc62e87b4..fcd2ddde5 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/FlagListener.java @@ -126,9 +126,9 @@ public abstract class FlagListener implements Listener { */ public boolean checkIsland(@NonNull Event e, @Nullable Player player, @Nullable Location loc, @NonNull Flag flag, boolean silent) { // Set user - user = User.getInstance(player); + user = player == null ? null : User.getInstance(player); if (loc == null) { - if (user.getLocation() != null && user.getLocation().getWorld() != null) { + if (user != null && user.getLocation() != null && user.getLocation().getWorld() != null) { report(user, e, user.getLocation(), flag, Why.NULL_LOCATION); } return true; diff --git a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java index 922337133..d8c0f2e0c 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java @@ -24,7 +24,7 @@ import world.bentobox.bentobox.util.Util; */ public class CycleClick implements PanelItem.ClickHandler { - protected BentoBox plugin = BentoBox.getInstance(); + protected final BentoBox plugin = BentoBox.getInstance(); protected Island island; protected User user; protected boolean changeOccurred; diff --git a/src/main/java/world/bentobox/bentobox/api/localization/TextVariables.java b/src/main/java/world/bentobox/bentobox/api/localization/TextVariables.java index 85c778d7c..61bce6fb5 100644 --- a/src/main/java/world/bentobox/bentobox/api/localization/TextVariables.java +++ b/src/main/java/world/bentobox/bentobox/api/localization/TextVariables.java @@ -34,4 +34,8 @@ public class TextVariables { * @since 1.16.0 */ public static final String XYZ = "[xyz]"; + /** + * @since 1.17.2 + */ + public static final String UUID = "[uuid]"; } diff --git a/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java b/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java index c3c10317b..ebe17e3c4 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/builders/PanelItemBuilder.java @@ -137,7 +137,7 @@ public class PanelItemBuilder { /** * @return the name */ - public String getName() { + public @Nullable String getName() { return name; } diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java index 2213cad90..7721746b0 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java @@ -32,6 +32,14 @@ import world.bentobox.bentobox.util.ItemParser; */ public class TemplateReader { + private static final String TITLE = "title"; + private static final String ICON = "icon"; + private static final String DESCRIPTION = "description"; + private static final String BACKGROUND = "background"; + private static final String BORDER = "border"; + private static final String FORCE_SHOWN = "force-shown"; + private static final String FALLBACK = "fallback"; + /** * Read template panel panel template record. * @@ -95,57 +103,57 @@ public class TemplateReader return null; } - String title = configurationSection.getString("title"); + String title = configurationSection.getString(TITLE); Panel.Type type = - Enums.getIfPresent(Panel.Type.class, configurationSection.getString("type", "INVENTORY")). + Enums.getIfPresent(Panel.Type.class, configurationSection.getString("type", "INVENTORY")). or(Panel.Type.INVENTORY); PanelTemplateRecord.TemplateItem borderItem = null; // Read Border Icon. - if (configurationSection.isConfigurationSection("border")) + if (configurationSection.isConfigurationSection(BORDER)) { // Process border icon if it contains more options. - ConfigurationSection borderSection = configurationSection.getConfigurationSection("border"); + ConfigurationSection borderSection = configurationSection.getConfigurationSection(BORDER); if (borderSection != null) { borderItem = new PanelTemplateRecord.TemplateItem( - ItemParser.parse((borderSection.getString("icon", Material.AIR.name()))), - borderSection.getString("title", null), - borderSection.getString("description", null)); + ItemParser.parse((borderSection.getString(ICON, Material.AIR.name()))), + borderSection.getString(TITLE, null), + borderSection.getString(DESCRIPTION, null)); } } - else if (configurationSection.isString("border")) + else if (configurationSection.isString(BORDER)) { // Process border icon if it contains only icon. borderItem = new PanelTemplateRecord.TemplateItem( - ItemParser.parse((configurationSection.getString("border", Material.AIR.name())))); + ItemParser.parse((configurationSection.getString(BORDER, Material.AIR.name())))); } PanelTemplateRecord.TemplateItem backgroundItem = null; // Read Background block - if (configurationSection.isConfigurationSection("background")) + if (configurationSection.isConfigurationSection(BACKGROUND)) { // Process border icon if it contains more options. - ConfigurationSection backgroundSection = configurationSection.getConfigurationSection("background"); + ConfigurationSection backgroundSection = configurationSection.getConfigurationSection(BACKGROUND); if (backgroundSection != null) { backgroundItem = new PanelTemplateRecord.TemplateItem( - ItemParser.parse((backgroundSection.getString("icon", Material.AIR.name()))), - backgroundSection.getString("title", null), - backgroundSection.getString("description", null)); + ItemParser.parse((backgroundSection.getString(ICON, Material.AIR.name()))), + backgroundSection.getString(TITLE, null), + backgroundSection.getString(DESCRIPTION, null)); } } - else if (configurationSection.isString("background")) + else if (configurationSection.isString(BACKGROUND)) { // Process background icon if it contains only icon. backgroundItem = new PanelTemplateRecord.TemplateItem( - ItemParser.parse((configurationSection.getString("background", Material.AIR.name())))); + ItemParser.parse((configurationSection.getString(BACKGROUND, Material.AIR.name())))); } // Read reusable @@ -156,7 +164,7 @@ public class TemplateReader { // Add all reusables to the local storage. reusable.getKeys(false).forEach(key -> - readPanelItemTemplate(reusable.getConfigurationSection(key), key, panelItemDataMap)); + readPanelItemTemplate(reusable.getConfigurationSection(key), key, panelItemDataMap)); } // Read content @@ -190,15 +198,15 @@ public class TemplateReader { // If it contains a section, then build a new button template from it. template.addButtonTemplate(rowIndex, - columnIndex, - readPanelItemTemplate(line.getConfigurationSection(String.valueOf(columnIndex + 1)))); + columnIndex, + readPanelItemTemplate(line.getConfigurationSection(String.valueOf(columnIndex + 1)))); } else if (line.isString(String.valueOf(columnIndex + 1))) { // If it contains just a single word, assume it is a reusable. template.addButtonTemplate(rowIndex, - columnIndex, - panelItemDataMap.get(line.getString(String.valueOf(columnIndex + 1)))); + columnIndex, + panelItemDataMap.get(line.getString(String.valueOf(columnIndex + 1)))); } } } @@ -221,20 +229,20 @@ public class TemplateReader { boolean[] forceShow = new boolean[6]; - if (section != null && section.contains("force-shown")) + if (section != null && section.contains(FORCE_SHOWN)) { - if (section.isInt("force-shown")) + if (section.isInt(FORCE_SHOWN)) { - int value = section.getInt("force-shown"); + int value = section.getInt(FORCE_SHOWN); if (value > 0 && value < 7) { forceShow[value-1] = true; } } - else if (section.isList("force-shown")) + else if (section.isList(FORCE_SHOWN)) { - section.getIntegerList("force-shown").forEach(number -> { + section.getIntegerList(FORCE_SHOWN).forEach(number -> { if (number > 0 && number < 7) { forceShow[number-1] = true; @@ -267,8 +275,8 @@ public class TemplateReader */ @Nullable private static ItemTemplateRecord readPanelItemTemplate(@Nullable ConfigurationSection section, - String itemKey, - Map reusableItemMap) + String itemKey, + Map reusableItemMap) { if (section == null) { @@ -278,13 +286,13 @@ public class TemplateReader ItemTemplateRecord fallback; - if (section.isConfigurationSection("fallback")) + if (section.isConfigurationSection(FALLBACK)) { - fallback = readPanelItemTemplate(section.getConfigurationSection("fallback")); + fallback = readPanelItemTemplate(section.getConfigurationSection(FALLBACK)); } - else if (section.isString("fallback") && reusableItemMap != null) + else if (section.isString(FALLBACK) && reusableItemMap != null) { - fallback = reusableItemMap.get(section.getString("fallback")); + fallback = reusableItemMap.get(section.getString(FALLBACK)); } else { @@ -292,10 +300,10 @@ public class TemplateReader } // Create Item Record - ItemTemplateRecord itemRecord = new ItemTemplateRecord(ItemParser.parse(section.getString("icon")), - section.getString("title", null), - section.getString("description", null), - fallback); + ItemTemplateRecord itemRecord = new ItemTemplateRecord(ItemParser.parse(section.getString(ICON)), + section.getString(TITLE, null), + section.getString(DESCRIPTION, null), + fallback); // Read data if (section.isConfigurationSection("data")) @@ -325,11 +333,10 @@ public class TemplateReader if (actionDataSection != null) { ItemTemplateRecord.ActionRecords actionData = - new ItemTemplateRecord.ActionRecords(clickType, - actionDataSection.getString("type"), - actionDataSection.getString("content"), - actionDataSection.getString("tooltip")); - + new ItemTemplateRecord.ActionRecords(clickType, + actionDataSection.getString("type"), + actionDataSection.getString("content"), + actionDataSection.getString("tooltip")); itemRecord.addAction(actionData); } } diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java index d428b5708..83115c750 100644 --- a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/AddonPlaceholderExpansion.java @@ -1,5 +1,6 @@ package world.bentobox.bentobox.api.placeholders.placeholderapi; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.addons.Addon; public class AddonPlaceholderExpansion extends BasicPlaceholderExpansion { @@ -10,17 +11,17 @@ public class AddonPlaceholderExpansion extends BasicPlaceholderExpansion { } @Override - public String getName() { + public @NonNull String getName() { return addon.getDescription().getName(); } @Override - public String getAuthor() { + public @NonNull String getAuthor() { return addon.getDescription().getAuthors().get(0); } @Override - public String getVersion() { + public @NonNull String getVersion() { return addon.getDescription().getVersion(); } } diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java index e8a8a91f3..0a506073b 100644 --- a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BasicPlaceholderExpansion.java @@ -24,7 +24,7 @@ abstract class BasicPlaceholderExpansion extends PlaceholderExpansion { } @Override - public String getIdentifier() { + public @NonNull String getIdentifier() { return getName().toLowerCase(Locale.ENGLISH); } @@ -42,13 +42,13 @@ abstract class BasicPlaceholderExpansion extends PlaceholderExpansion { } @Override - public String onPlaceholderRequest(Player p, String placeholder) { - if (placeholders.containsKey(placeholder)) { + public String onPlaceholderRequest(Player p, @NonNull String placeholder) { + if (placeholders.containsKey(placeholder) && p != null) { return placeholders.get(placeholder).onReplace(User.getInstance(p)); } return null; } - + /** * Checks if a placeholder with this name is already registered * @param placeholder - name of placeholder @@ -56,7 +56,7 @@ abstract class BasicPlaceholderExpansion extends PlaceholderExpansion { * @since 1.4.0 */ public boolean isPlaceholder(@NonNull String placeholder) { - return placeholders.containsKey(placeholder); + return placeholders.containsKey(placeholder); } @Override diff --git a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java index da290c84e..c00e98384 100644 --- a/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java +++ b/src/main/java/world/bentobox/bentobox/api/placeholders/placeholderapi/BentoBoxPlaceholderExpansion.java @@ -1,5 +1,6 @@ package world.bentobox.bentobox.api.placeholders.placeholderapi; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.BentoBox; public class BentoBoxPlaceholderExpansion extends BasicPlaceholderExpansion { @@ -11,17 +12,17 @@ public class BentoBoxPlaceholderExpansion extends BasicPlaceholderExpansion { } @Override - public String getName() { + public @NonNull String getName() { return plugin.getName(); } @Override - public String getAuthor() { + public @NonNull String getAuthor() { return "Tastybento and Poslovitch"; } @Override - public String getVersion() { + public @NonNull String getVersion() { return plugin.getDescription().getVersion(); } } \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/user/Notifier.java b/src/main/java/world/bentobox/bentobox/api/user/Notifier.java index e75adff03..b78888cd8 100644 --- a/src/main/java/world/bentobox/bentobox/api/user/Notifier.java +++ b/src/main/java/world/bentobox/bentobox/api/user/Notifier.java @@ -6,6 +6,7 @@ import java.util.concurrent.TimeUnit; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import org.eclipse.jdt.annotation.NonNull; /** * Utilities class that helps to avoid spamming the User with potential repeated messages @@ -26,7 +27,7 @@ public class Notifier { .build( new CacheLoader<>() { @Override - public Notification load(User user) { + public Notification load(@NonNull User user) { return new Notification(null, 0); } } diff --git a/src/main/java/world/bentobox/bentobox/api/user/User.java b/src/main/java/world/bentobox/bentobox/api/user/User.java index b032a2988..2c241e453 100644 --- a/src/main/java/world/bentobox/bentobox/api/user/User.java +++ b/src/main/java/world/bentobox/bentobox/api/user/User.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -32,6 +33,7 @@ import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.events.OfflineMessageEvent; import world.bentobox.bentobox.api.metadata.MetaDataAble; import world.bentobox.bentobox.api.metadata.MetaDataValue; +import world.bentobox.bentobox.database.objects.Players; import world.bentobox.bentobox.util.Util; /** @@ -61,25 +63,22 @@ public class User implements MetaDataAble { * @param sender - command sender, e.g. console * @return user - user */ - @Nullable - public static User getInstance(CommandSender sender) { - if (sender instanceof Player) { - return getInstance((Player)sender); + @NonNull + public static User getInstance(@NonNull CommandSender sender) { + if (sender instanceof Player p) { + return getInstance(p); } // Console return new User(sender); } /** - * Gets an instance of User from a Player object + * Gets an instance of User from a Player object. * @param player - the player * @return user - user */ - @Nullable - public static User getInstance(Player player) { - if (player == null) { - return null; - } + @NonNull + public static User getInstance(@NonNull Player player) { if (users.containsKey(player.getUniqueId())) { return users.get(player.getUniqueId()); } @@ -87,15 +86,12 @@ public class User implements MetaDataAble { } /** - * Gets an instance of User from a UUID + * Gets an instance of User from a UUID. * @param uuid - UUID * @return user - user */ - @Nullable - public static User getInstance(@Nullable UUID uuid) { - if (uuid == null) { - return null; - } + @NonNull + public static User getInstance(@NonNull UUID uuid) { if (users.containsKey(uuid)) { return users.get(uuid); } @@ -109,11 +105,8 @@ public class User implements MetaDataAble { * @return user * @since 1.3.0 */ - @Nullable - public static User getInstance(OfflinePlayer offlinePlayer) { - if (offlinePlayer == null) { - return null; - } + @NonNull + public static User getInstance(@NonNull OfflinePlayer offlinePlayer) { if (users.containsKey(offlinePlayer.getUniqueId())) { return users.get(offlinePlayer.getUniqueId()); } @@ -144,7 +137,7 @@ public class User implements MetaDataAble { private Addon addon; - private User(CommandSender sender) { + private User(@Nullable CommandSender sender) { player = null; playerUUID = null; this.sender = sender; @@ -184,25 +177,42 @@ public class User implements MetaDataAble { return sender.getEffectivePermissions(); } - @Nullable + /** + * Get the user's inventory + * @return player's inventory + * @throws {@link NullPointerException} - if user is not a player + */ + @NonNull public PlayerInventory getInventory() { - return player != null ? player.getInventory() : null; + return Objects.requireNonNull(player, "getInventory can only be called for online players!").getInventory(); } - @Nullable + /** + * Get the user's location + * @return location + * @throws {@link NullPointerException} - if user is not a player + */ + @NonNull public Location getLocation() { - return player != null ? player.getLocation() : null; + return Objects.requireNonNull(player, "getLocation can only be called for online players!").getLocation(); } + /** + * Get the user's name + * @return player's name + */ + @NonNull public String getName() { return player != null ? player.getName() : plugin.getPlayers().getName(playerUUID); } /** + * Check if the User is a player before calling this method. {@link #isPlayer()} * @return the player */ + @NonNull public Player getPlayer() { - return player; + return Objects.requireNonNull(player, "User is not a player!"); } /** @@ -213,11 +223,14 @@ public class User implements MetaDataAble { } /** + * Use {@link #isOfflinePlayer()} before calling this method * @return the offline player * @since 1.3.0 + * @throws {@link NullPointerException} - if user is not an offline player */ + @NonNull public OfflinePlayer getOfflinePlayer() { - return offlinePlayer; + return Objects.requireNonNull(offlinePlayer, "User is not an OfflinePlayer!"); } /** @@ -354,11 +367,11 @@ public class User implements MetaDataAble { // Get translation. String addonPrefix = plugin.getIWM() .getAddon(world).map(a -> a.getDescription().getName().toLowerCase(Locale.ENGLISH) + ".").orElse(""); - return translate(addonPrefix, reference, variables); + return Util.translateColorCodes(translate(addonPrefix, reference, variables)); } /** - * Gets a translation of this reference for this user. Translations may be overridden by Addons + * Gets a translation of this reference for this user with colors converted. Translations may be overridden by Addons * by using the same reference prefixed by the addon name (from the Addon Description) in lower case. * @param reference - reference found in a locale file * @param variables - variables to insert into translated string. Variables go in pairs, for example @@ -366,6 +379,21 @@ public class User implements MetaDataAble { * @return Translated string with colors converted, or the reference if nothing has been found */ public String getTranslation(String reference, String... variables) { + // Get addonPrefix + String addonPrefix = addon == null ? "" : addon.getDescription().getName().toLowerCase(Locale.ENGLISH) + "."; + return Util.translateColorCodes(translate(addonPrefix, reference, variables)); + } + + /** + * Gets a translation of this reference for this user without colors translated. Translations may be overridden by Addons + * by using the same reference prefixed by the addon name (from the Addon Description) in lower case. + * @param reference - reference found in a locale file + * @param variables - variables to insert into translated string. Variables go in pairs, for example + * "[name]", "tastybento" + * @return Translated string or the reference if nothing has been found + * @since 1.17.4 + */ + public String getTranslationNoColor(String reference, String... variables) { // Get addonPrefix String addonPrefix = addon == null ? "" : addon.getDescription().getName().toLowerCase(Locale.ENGLISH) + "."; return translate(addonPrefix, reference, variables); @@ -392,7 +420,7 @@ public class User implements MetaDataAble { // Replace the [gamemode] text variable prefixTranslation = prefixTranslation.replace("[gamemode]", addon != null ? addon.getDescription().getName() : "[gamemode]"); // Replace the [friendly_name] text variable - prefixTranslation = prefixTranslation.replace("[friendly_name]", getWorld() != null ? plugin.getIWM().getFriendlyName(getWorld()) : "[friendly_name]"); + prefixTranslation = prefixTranslation.replace("[friendly_name]", isPlayer() ? plugin.getIWM().getFriendlyName(getWorld()) : "[friendly_name]"); // Replace the prefix in the actual message translation = translation.replace("[prefix_" + prefix + "]", prefixTranslation); @@ -410,7 +438,7 @@ public class User implements MetaDataAble { translation = plugin.getPlaceholdersManager().replacePlaceholders(player, translation); } - return Util.translateColorCodes(translation); + return translation; } } @@ -499,10 +527,13 @@ public class User implements MetaDataAble { /** * Gets the current world this entity resides in - * @return World - world or null + * @return World - world + * @throws {@link NullPointerException} - if user is not a player */ + @NonNull public World getWorld() { - return player == null ? null : player.getWorld(); + Objects.requireNonNull(player, "Cannot be called on a non-player User!"); + return Objects.requireNonNull(player.getWorld(), "Player's world cannot be null!"); } /** @@ -641,10 +672,10 @@ public class User implements MetaDataAble { */ @Override public Optional> getMetaData() { - return plugin + Players p = plugin .getPlayers() - .getPlayer(playerUUID) - .getMetaData(); + .getPlayer(playerUUID); + return Objects.requireNonNull(p, "Unknown player for " + playerUUID).getMetaData(); } /** @@ -653,7 +684,11 @@ public class User implements MetaDataAble { */ @Override public void setMetaData(Map metaData) { - plugin.getPlayers().getPlayer(playerUUID).setMetaData(metaData); + Players p = plugin + .getPlayers() + .getPlayer(playerUUID); + + Objects.requireNonNull(p, "Unknown player for " + playerUUID).setMetaData(metaData); } } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/Blueprint.java b/src/main/java/world/bentobox/bentobox/blueprints/Blueprint.java index fe47de567..38d73eec8 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/Blueprint.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/Blueprint.java @@ -79,7 +79,7 @@ public class Blueprint { /** * @return the icon */ - public Material getIcon() { + public @NonNull Material getIcon() { return icon; } /** diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java index 034cdf919..7d0c01b82 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java @@ -139,7 +139,7 @@ public class BlueprintClipboard { Math.rint(e.getLocation().getY()), Math.rint(e.getLocation().getZ())).equals(v)) .collect(Collectors.toList()); - if (copyBlock(v.toLocation(world), origin, copyAir, ents)) { + if (copyBlock(v.toLocation(world), copyAir, ents)) { count++; } }); @@ -151,6 +151,7 @@ public class BlueprintClipboard { } if (index > vectorsToCopy.size()) { copyTask.cancel(); + assert blueprint != null; blueprint.setAttached(bpAttachable); blueprint.setBlocks(bpBlocks); blueprint.setEntities(bpEntities); @@ -178,12 +179,13 @@ public class BlueprintClipboard { return r; } - private boolean copyBlock(Location l, @Nullable Vector origin2, boolean copyAir, Collection entities) { + private boolean copyBlock(Location l, boolean copyAir, Collection entities) { Block block = l.getBlock(); if (!copyAir && block.getType().equals(Material.AIR) && entities.isEmpty()) { return false; } // Create position + Vector origin2 = origin == null ? new Vector(0,0,0) : origin; int x = l.getBlockX() - origin2.getBlockX(); int y = l.getBlockY() - origin2.getBlockY(); int z = l.getBlockZ() - origin2.getBlockZ(); @@ -398,7 +400,7 @@ public class BlueprintClipboard { /** * @return the blueprint */ - public Blueprint getBlueprint() { + public @Nullable Blueprint getBlueprint() { return blueprint; } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java index cde794edd..6528f58bd 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintPaster.java @@ -109,7 +109,7 @@ public class BlueprintPaster { this.plugin = plugin; this.clipboard = clipboard; // Calculate location for pasting - this.blueprint = clipboard.getBlueprint(); + this.blueprint = Objects.requireNonNull(clipboard.getBlueprint(), "Clipboard cannot have a null Blueprint"); this.location = location; this.island = null; @@ -416,9 +416,11 @@ public class BlueprintPaster { if (island != null && !lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.START_TEXT)) { // Get the addon that is operating in this world String addonName = plugin.getIWM().getAddon(island.getWorld()).map(addon -> addon.getDescription().getName().toLowerCase(Locale.ENGLISH)).orElse(""); - for (int i = 0; i < 4; i++) { - s.setLine(i, Util.translateColorCodes(plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()), - addonName + ".sign.line" + i,"").replace(TextVariables.NAME, name))); + if (island.getOwner() != null) { + for (int i = 0; i < 4; i++) { + s.setLine(i, Util.translateColorCodes(plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()), + addonName + ".sign.line" + i,"").replace(TextVariables.NAME, name))); + } } } else { // Just paste diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java index 4493d9c47..661b6000d 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionPrompt.java @@ -8,6 +8,7 @@ import org.bukkit.conversations.Prompt; import org.bukkit.conversations.StringPrompt; import org.bukkit.entity.Player; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; @@ -33,7 +34,7 @@ public class DescriptionPrompt extends StringPrompt { @SuppressWarnings("unchecked") @Override - public String getPromptText(ConversationContext context) { + public @NonNull String getPromptText(ConversationContext context) { User user = User.getInstance((Player)context.getForWhom()); if (context.getSessionData(DESCRIPTION) != null) { StringBuilder sb = new StringBuilder(); diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java index b28546a9c..e5e78341e 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/DescriptionSuccessPrompt.java @@ -7,6 +7,7 @@ import org.bukkit.conversations.MessagePrompt; import org.bukkit.conversations.Prompt; import org.bukkit.entity.Player; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.user.User; @@ -28,7 +29,7 @@ public class DescriptionSuccessPrompt extends MessagePrompt { } @Override - public String getPromptText(ConversationContext context) { + public @NonNull String getPromptText(ConversationContext context) { User user = User.getInstance((Player)context.getForWhom()); @SuppressWarnings("unchecked") List description = (List)context.getSessionData("description"); @@ -46,7 +47,7 @@ public class DescriptionSuccessPrompt extends MessagePrompt { } @Override - protected Prompt getNextPrompt(ConversationContext context) { + protected Prompt getNextPrompt(@NonNull ConversationContext context) { return Prompt.END_OF_CONVERSATION; } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameConversationPrefix.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameConversationPrefix.java index 719342de5..0da78ac24 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameConversationPrefix.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameConversationPrefix.java @@ -4,12 +4,13 @@ import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.ConversationPrefix; import org.bukkit.entity.Player; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.user.User; public class NameConversationPrefix implements ConversationPrefix { @Override - public String getPrefix(ConversationContext context) { + public @NonNull String getPrefix(ConversationContext context) { User user = User.getInstance((Player)context.getForWhom()); return user.getTranslation("commands.admin.blueprint.management.name.conversation-prefix"); } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java index 5dd8a6294..2677cda44 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NamePrompt.java @@ -38,7 +38,7 @@ public class NamePrompt extends StringPrompt { } @Override - public String getPromptText(ConversationContext context) { + public @NonNull String getPromptText(ConversationContext context) { User user = User.getInstance((Player)context.getForWhom()); return user.getTranslation("commands.admin.blueprint.management.name.prompt"); } diff --git a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java index 8fe5d8c51..9e990fefe 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/conversation/NameSuccessPrompt.java @@ -34,7 +34,7 @@ public class NameSuccessPrompt extends MessagePrompt { } @Override - public String getPromptText(ConversationContext context) { + public @NonNull String getPromptText(ConversationContext context) { String name = (String) context.getSessionData("name"); String uniqueId = (String) context.getSessionData("uniqueId"); User user = User.getInstance((Player)context.getForWhom()); @@ -65,7 +65,7 @@ public class NameSuccessPrompt extends MessagePrompt { } @Override - protected Prompt getNextPrompt(ConversationContext context) { + protected Prompt getNextPrompt(@NonNull ConversationContext context) { return Prompt.END_OF_CONVERSATION; } diff --git a/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java b/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java index d6693a073..09d738c34 100644 --- a/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java +++ b/src/main/java/world/bentobox/bentobox/database/json/BentoboxTypeAdapterFactory.java @@ -33,7 +33,7 @@ import world.bentobox.bentobox.database.json.adapters.WorldTypeAdapter; */ public class BentoboxTypeAdapterFactory implements TypeAdapterFactory { - BentoBox plugin; + final BentoBox plugin; /** * @param plugin plugin diff --git a/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java index 02c0744a9..f9efcb15c 100644 --- a/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java @@ -19,6 +19,7 @@ import com.mongodb.client.model.IndexOptions; import com.mongodb.client.model.Indexes; import com.mongodb.util.JSON; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.database.DatabaseConnector; import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler; @@ -125,7 +126,7 @@ public class MongoDBDatabaseHandler extends AbstractJSONDatabaseHandler { } @Override - public T loadObject(String uniqueId) { + public T loadObject(@NonNull String uniqueId) { Document doc = collection.find(new Document(MONGO_ID, uniqueId)).limit(1).first(); Gson gson = getGson(); String json = JSON.serialize(doc).replaceFirst(MONGO_ID, UNIQUEID); diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Island.java b/src/main/java/world/bentobox/bentobox/database/objects/Island.java index 8d7a2cd14..57f0a0306 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -16,7 +16,6 @@ import java.util.stream.Collectors; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.entity.Player; @@ -43,9 +42,7 @@ import world.bentobox.bentobox.database.objects.adapters.FlagSerializer; import world.bentobox.bentobox.database.objects.adapters.FlagSerializer3; import world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter; import world.bentobox.bentobox.lists.Flags; -import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.RanksManager; -import world.bentobox.bentobox.util.IslandInfo; import world.bentobox.bentobox.util.Pair; import world.bentobox.bentobox.util.Util; @@ -76,7 +73,6 @@ public class Island implements DataObject, MetaDataAble { //// Island //// // The center of the island space @Expose - @Nullable private Location center; /** @@ -164,8 +160,6 @@ public class Island implements DataObject, MetaDataAble { @Expose private List history = new LinkedList<>(); - @Expose - private int levelHandicap; @Expose private Map spawnPoint = new EnumMap<>(Environment.class); @@ -197,7 +191,7 @@ public class Island implements DataObject, MetaDataAble { private Boolean reserved = null; /** - * A place to store meta data for this island. + * A place to store metadata for this island. * @since 1.15.4 */ @Expose @@ -258,7 +252,6 @@ public class Island implements DataObject, MetaDataAble { this.gameMode = island.getGameMode(); this.homes = new HashMap<>(island.getHomes()); this.history.addAll(island.getHistory()); - this.levelHandicap = island.getLevelHandicap(); this.location = island.getProtectionCenter(); this.maxEverProtectionRange = island.getMaxEverProtectionRange(); this.maxHomes = island.getMaxHomes(); @@ -346,9 +339,9 @@ public class Island implements DataObject, MetaDataAble { * Returns a clone of the location of the center of this island. * @return clone of the center Location */ - @Nullable + @NonNull public Location getCenter(){ - return center == null ? null : center.clone(); + return Objects.requireNonNull(center, "Island getCenter requires a non-null center").clone(); } /** @@ -359,7 +352,7 @@ public class Island implements DataObject, MetaDataAble { } /** - * Gets the Island Guard flag's setting. If this is a protection flag, the this will be the + * Gets the Island Guard flag's setting. If this is a protection flag, then this will be the * rank needed to bypass this flag. If it is a Settings flag, any non-zero value means the * setting is allowed. * @param flag - flag @@ -376,13 +369,6 @@ public class Island implements DataObject, MetaDataAble { return flags; } - /** - * @return the levelHandicap - */ - public int getLevelHandicap() { - return levelHandicap; - } - /** * Returns the members of this island. * It contains all players that have any rank on this island, including {@link RanksManager#BANNED_RANK BANNED}, @@ -439,41 +425,41 @@ public class Island implements DataObject, MetaDataAble { } /** - * Get the minimum protected X block coord based on the island location. + * Get the minimum protected X block coordinate based on the island location. * It will never be less than {@link #getMinX()} * @return the minProtectedX */ public int getMinProtectedX() { - return getProtectionCenter() == null ? 0 : Math.max(getMinX(), getProtectionCenter().getBlockX() - protectionRange); + return Math.max(getMinX(), getProtectionCenter().getBlockX() - protectionRange); } /** - * Get the maximum protected X block coord based on the island location. + * Get the maximum protected X block coordinate based on the island location. * It will never be more than {@link #getMaxX()} * @return the maxProtectedX * @since 1.5.2 */ public int getMaxProtectedX() { - return getProtectionCenter() == null ? 0 : Math.min(getMaxX(), getProtectionCenter().getBlockX() + protectionRange); + return Math.min(getMaxX(), getProtectionCenter().getBlockX() + protectionRange); } /** - * Get the minimum protected Z block coord based on the island location. + * Get the minimum protected Z block coordinate based on the island location. * It will never be less than {@link #getMinZ()} * @return the minProtectedZ */ public int getMinProtectedZ() { - return getProtectionCenter() == null ? 0 : Math.max(getMinZ(), getProtectionCenter().getBlockZ() - protectionRange); + return Math.max(getMinZ(), getProtectionCenter().getBlockZ() - protectionRange); } /** - * Get the maximum protected Z block coord based on the island location. + * Get the maximum protected Z block coordinate based on the island location. * It will never be more than {@link #getMinZ()} * @return the maxProtectedZ * @since 1.5.2 */ public int getMaxProtectedZ() { - return getProtectionCenter() == null ? 0 : Math.min(getMaxZ(), getProtectionCenter().getBlockZ() + protectionRange); + return Math.min(getMaxZ(), getProtectionCenter().getBlockZ() + protectionRange); } /** @@ -561,6 +547,9 @@ public class Island implements DataObject, MetaDataAble { * @return the maxEverProtectionRange or the protection range, whichever is larger */ public int getMaxEverProtectionRange() { + if (maxEverProtectionRange > this.range) { + maxEverProtectionRange = this.range; + } return Math.max(protectionRange, maxEverProtectionRange); } @@ -569,6 +558,9 @@ public class Island implements DataObject, MetaDataAble { */ public void setMaxEverProtectionRange(int maxEverProtectionRange) { this.maxEverProtectionRange = maxEverProtectionRange; + if (maxEverProtectionRange > this.range) { + this.maxEverProtectionRange = this.range; + } setChanged(); } @@ -609,7 +601,7 @@ public class Island implements DataObject, MetaDataAble { } @Override - public String getUniqueId() { + public @NonNull String getUniqueId() { return uniqueId; } @@ -682,7 +674,7 @@ public class Island implements DataObject, MetaDataAble { * @since 1.5.2 */ public BoundingBox getBoundingBox() { - return new BoundingBox(getMinX(), 0.0D, getMinZ(), getMaxX()-1.0D, world.getMaxHeight(), getMaxZ()-1.0D); + return new BoundingBox(getMinX(), 0.0D, getMinZ(), getMaxX(), world.getMaxHeight(), getMaxZ()); } /** @@ -803,10 +795,8 @@ public class Island implements DataObject, MetaDataAble { /** * @param center the center to set */ - public void setCenter(@Nullable Location center) { - if (center != null) { - this.world = center.getWorld(); - } + public void setCenter(@NonNull Location center) { + this.world = center.getWorld(); this.center = center; setChanged(); } @@ -869,14 +859,6 @@ public class Island implements DataObject, MetaDataAble { setChanged(); } - /** - * @param levelHandicap the levelHandicap to set - */ - public void setLevelHandicap(int levelHandicap) { - this.levelHandicap = levelHandicap; - setChanged(); - } - /** * @param members the members to set */ @@ -1014,7 +996,7 @@ public class Island implements DataObject, MetaDataAble { * Sets whether this island is a spawn or not. *
* If {@code true}, the members and the owner will be removed from this island. - * The flags will also be resetted to default values. + * The flags will also be reset to default values. * @param isSpawn {@code true} if the island is a spawn, {@code false} otherwise. */ public void setSpawn(boolean isSpawn){ @@ -1073,27 +1055,6 @@ public class Island implements DataObject, MetaDataAble { setChanged(); } - /** - * Shows info of this island to this user. - * @param user the User who is requesting it - * @return always true - * @deprecated Use {@link IslandInfo#showInfo(User) instead} - */ - @Deprecated - public boolean showInfo(User user) { - return new IslandInfo(this).showInfo(user); - } - - /** - * Shows the members of this island to this user. - * @param user the User who is requesting it - * @deprecated Use {@link IslandInfo#showMembers(User) instead} - */ - @Deprecated - public void showMembers(User user) { - new IslandInfo(this).showMembers(user); - } - /** * Toggles a settings flag * This method affects subflags (if the given flag is a parent flag) @@ -1253,11 +1214,9 @@ public class Island implements DataObject, MetaDataAble { * @return {@code true} if this island has its nether island generated, {@code false} otherwise. * @since 1.5.0 */ - public boolean hasNetherIsland(){ - IslandWorldManager iwm = BentoBox.getInstance().getIWM(); - return iwm.isNetherGenerate(getWorld()) && iwm.isNetherIslands(getWorld()) && - iwm.getNetherWorld(getWorld()) != null && - !getCenter().toVector().toLocation(iwm.getNetherWorld(getWorld())).getBlock().getType().equals(Material.AIR); + public boolean hasNetherIsland() { + World nether = BentoBox.getInstance().getIWM().getNetherWorld(getWorld()); + return nether != null && !getCenter().toVector().toLocation(nether).getBlock().getType().isAir(); } /** @@ -1265,11 +1224,9 @@ public class Island implements DataObject, MetaDataAble { * @return {@code true} if this island has its end island generated, {@code false} otherwise. * @since 1.5.0 */ - public boolean hasEndIsland(){ - IslandWorldManager iwm = BentoBox.getInstance().getIWM(); - return iwm.isEndGenerate(getWorld()) && iwm.isEndIslands(getWorld()) && - iwm.getEndWorld(getWorld()) != null && - !getCenter().toVector().toLocation(iwm.getEndWorld(getWorld())).getBlock().getType().equals(Material.AIR); + public boolean hasEndIsland() { + World end = BentoBox.getInstance().getIWM().getEndWorld(getWorld()); + return end != null && !getCenter().toVector().toLocation(end).getBlock().getType().isAir(); } @@ -1417,7 +1374,7 @@ public class Island implements DataObject, MetaDataAble { * @return a clone of the protection center location * @since 1.16.0 */ - @Nullable + @NonNull public Location getProtectionCenter() { return location == null ? getCenter() : location.clone(); } @@ -1504,6 +1461,8 @@ public class Island implements DataObject, MetaDataAble { } /** + * Get the max homes. You shouldn't access this directly. + * Use {@link world.bentobox.bentobox.managers.IslandsManager#getMaxHomes(Island)} * @return the maxHomes. If null, then the world default should be used. * @since 1.16.0 */ @@ -1514,6 +1473,8 @@ public class Island implements DataObject, MetaDataAble { /** * @param maxHomes the maxHomes to set. If null then the world default will be used. + * You shouldn't access this directly. + * Use {@link world.bentobox.bentobox.managers.IslandsManager#setMaxHomes(Island, Integer)} * @since 1.16.0 */ public void setMaxHomes(@Nullable Integer maxHomes) { @@ -1574,7 +1535,7 @@ public class Island implements DataObject, MetaDataAble { + ", name=" + name + ", createdDate=" + createdDate + ", updatedDate=" + updatedDate + ", owner=" + owner + ", members=" + members + ", maxMembers=" + maxMembers + ", spawn=" + spawn + ", purgeProtected=" + purgeProtected + ", flags=" + flags + ", history=" + history - + ", levelHandicap=" + levelHandicap + ", spawnPoint=" + spawnPoint + ", doNotLoad=" + doNotLoad + + ", spawnPoint=" + spawnPoint + ", doNotLoad=" + doNotLoad + ", cooldowns=" + cooldowns + ", commandRanks=" + commandRanks + ", reserved=" + reserved + ", metaData=" + metaData + ", homes=" + homes + ", maxHomes=" + maxHomes + "]"; } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Players.java b/src/main/java/world/bentobox/bentobox/database/objects/Players.java index bf9164386..2a3e6dbb7 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Players.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Players.java @@ -90,7 +90,9 @@ public class Players implements DataObject, MetaDataAble { * Gets the default home location. * @param world - world to check * @return Location - home location in world + * @deprecated Homes are stored in the Island object now */ + @Deprecated(since="1.18.0", forRemoval=true) @Nullable public Location getHomeLocation(World world) { return getHomeLocation(world, 1); // Default @@ -101,7 +103,9 @@ public class Players implements DataObject, MetaDataAble { * @param world - includes world and any related nether or end worlds * @param number - a number * @return Location of this home or null if not available + * @deprecated Homes are stored in the island object now */ + @Deprecated(since="1.18.0", forRemoval=true) @Nullable public Location getHomeLocation(World world, int number) { // Remove any lost worlds/locations @@ -116,7 +120,9 @@ public class Players implements DataObject, MetaDataAble { /** * @param world - world * @return List of home locations + * @deprecated Homes are stored in the island object now */ + @Deprecated(since="1.18.0", forRemoval=true) public Map getHomeLocations(World world) { // Remove any lost worlds/locations homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null); @@ -126,7 +132,9 @@ public class Players implements DataObject, MetaDataAble { /** * @return the homeLocations + * @deprecated Homes are stored in the Island object now */ + @Deprecated(since="1.18.0", forRemoval=true) public Map getHomeLocations() { // Remove any lost worlds/locations homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null); @@ -135,7 +143,9 @@ public class Players implements DataObject, MetaDataAble { /** * @param homeLocations the homeLocations to set + * @deprecated Homes are stored in the Island object now */ + @Deprecated(since="1.18.0", forRemoval=true) public void setHomeLocations(Map homeLocations) { this.homeLocations = homeLocations; // Remove any lost worlds/locations @@ -195,9 +205,10 @@ public class Players implements DataObject, MetaDataAble { /** * Stores the home location of the player in a String format * - * @param l - * a Bukkit location + * @param l a Bukkit location + * @deprecated Home locations are stored in islands */ + @Deprecated(since="1.18.0", forRemoval=true) public void setHomeLocation(final Location l) { setHomeLocation(l, 1); } @@ -206,7 +217,9 @@ public class Players implements DataObject, MetaDataAble { * Stores the numbered home location of the player. Numbering starts at 1. * @param location - the location * @param number - a number + * @deprecated Home locations are no longer stored for players. They are stored in islands. */ + @Deprecated(since="1.18.0", forRemoval=true) public void setHomeLocation(Location location, int number) { // Remove any home locations in the same world with the same number homeLocations.entrySet().removeIf(e -> e.getKey() == null || (Util.sameWorld(location.getWorld(), e.getKey().getWorld()) && e.getValue().equals(number))); @@ -224,7 +237,9 @@ public class Players implements DataObject, MetaDataAble { /** * Clears all home Locations in world * @param world - world + * @deprecated Home locations are no longer stored for players. Use {@link IslandManager} */ + @Deprecated(since="1.18.0", forRemoval=true) public void clearHomeLocations(World world) { homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null || Util.sameWorld(l.getWorld(), world)); } @@ -329,7 +344,10 @@ public class Players implements DataObject, MetaDataAble { */ public void addToPendingKick(World world) { - this.pendingKicks.add(Util.getWorld(world).getName()); + World w = Util.getWorld(world); + if (w != null) { + this.pendingKicks.add(w.getName()); + } } /** diff --git a/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java index a3bb314bd..c1402be8a 100644 --- a/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/transition/TransitionDatabaseHandler.java @@ -5,6 +5,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.concurrent.CompletableFuture; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.database.AbstractDatabaseHandler; @@ -55,7 +56,7 @@ public class TransitionDatabaseHandler extends AbstractDatabaseHandler { * @see world.bentobox.bentobox.database.AbstractDatabaseHandler#loadObject(java.lang.String) */ @Override - public T loadObject(String uniqueId) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, NoSuchMethodException { + public T loadObject(@NonNull String uniqueId) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, NoSuchMethodException { // Try destination database @Nullable T object = toHandler.loadObject(uniqueId); diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java index aacc05b97..62e9b3094 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseConnector.java @@ -144,7 +144,7 @@ public class YamlDatabaseConnector implements DatabaseConnector { // Run through the file and add in the comments File commentedFile = new File(file.getPath() + ".tmp"); List newFile = new ArrayList<>(); - try (Scanner scanner = new Scanner(file, "UTF-8")) { + try (Scanner scanner = new Scanner(file, StandardCharsets.UTF_8)) { while (scanner.hasNextLine()) { String nextLine = scanner.nextLine(); // See if there are any comments in this line diff --git a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java index 6c9d56dd5..05b42d537 100644 --- a/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/yaml/YamlDatabaseHandler.java @@ -80,7 +80,7 @@ public class YamlDatabaseHandler extends AbstractDatabaseHandler { * @see world.bentobox.bentobox.database.AbstractDatabaseHandler#loadObject(java.lang.String) */ @Override - public T loadObject(String key) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, NoSuchMethodException { + public T loadObject(@NonNull String key) throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, NoSuchMethodException { // Objects are loaded from a folder named after the simple name of the class being stored String path = DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName(); // This path and key can be overridden by the StoreAt annotation in the code diff --git a/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java b/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java index d7e630f16..01c584594 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/LangUtilsHook.java @@ -207,7 +207,7 @@ public class LangUtilsHook extends Hook { public static String getEnchantDisplayName(Enchantment ench, int level, User user) { return hooked ? LanguageHelper.getEnchantmentDisplayName(ench, level, getUserLocale(user)) - : ench.getKey().getKey() + " " + level; + : Util.prettifyText(ench.getKey().getKey()) + " " + level; } /** @@ -221,7 +221,7 @@ public class LangUtilsHook extends Hook { public static String getEnchantDisplayName(Entry entry, User user) { return hooked ? LanguageHelper.getEnchantmentDisplayName(entry, getUserLocale(user)) - : entry.getKey().getKey().getKey() + " " + entry.getValue(); + : Util.prettifyText(entry.getKey().getKey().getKey()) + " " + entry.getValue(); } /** @@ -234,7 +234,7 @@ public class LangUtilsHook extends Hook { public static String getEnchantName(Enchantment enchant, User user) { return hooked ? LanguageHelper.getEnchantmentName(enchant, getUserLocale(user)) - : enchant.getKey().getKey(); + : Util.prettifyText(enchant.getKey().getKey()); } /** diff --git a/src/main/java/world/bentobox/bentobox/hooks/WorldEditHook.java b/src/main/java/world/bentobox/bentobox/hooks/WorldEditHook.java deleted file mode 100644 index a77579dbc..000000000 --- a/src/main/java/world/bentobox/bentobox/hooks/WorldEditHook.java +++ /dev/null @@ -1,41 +0,0 @@ -package world.bentobox.bentobox.hooks; - -import org.bukkit.Material; -import org.eclipse.jdt.annotation.Nullable; - -import com.sk89q.worldedit.WorldEdit; - -import world.bentobox.bentobox.api.hooks.Hook; -import world.bentobox.bentobox.blueprints.worldedit.BlueprintClipboardFormat; - -/** - * @since 1.6.0 - * @author Poslovitch - */ -public class WorldEditHook extends Hook { - - public WorldEditHook() { - super("WorldEdit", Material.WOODEN_AXE); - } - - @Override - public boolean hook() { - - WorldEdit instance; - try { - instance = WorldEdit.getInstance(); - new BlueprintClipboardFormat(); - } catch (Exception e) { - return false; - } - - return instance != null; - - } - - @Override - @Nullable - public String getFailureCause() { - return null; // The process shouldn't fail - } -} diff --git a/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java b/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java index 7b3b174fd..bf0583c16 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderAPIHook.java @@ -32,7 +32,7 @@ public class PlaceholderAPIHook extends PlaceholderHook { public PlaceholderAPIHook() { - super("PlaceholderAPI"); + super(); this.addonsExpansions = new HashMap<>(); this.bentoBoxPlaceholders = new HashSet<>(); this.addonPlaceholders = new HashMap<>(); diff --git a/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderHook.java b/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderHook.java index f8218d8d7..78653f78b 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/placeholders/PlaceholderHook.java @@ -14,8 +14,8 @@ import world.bentobox.bentobox.api.placeholders.PlaceholderReplacer; */ public abstract class PlaceholderHook extends Hook { - protected PlaceholderHook(@NonNull String pluginName) { - super(pluginName, Material.NAME_TAG); + protected PlaceholderHook() { + super("PlaceholderAPI", Material.NAME_TAG); } /** diff --git a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java index 8c219a353..47819492c 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java +++ b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java @@ -2,6 +2,7 @@ package world.bentobox.bentobox.listeners; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; @@ -35,14 +36,15 @@ public class BlockEndDragon implements Listener { } private void testLocation(Location location) { - if (!plugin.getIWM().isIslandEnd(location.getWorld()) - || !Flags.REMOVE_END_EXIT_ISLAND.isSetForWorld(location.getWorld()) - || location.getWorld().getBlockAt(0, 255, 0).getType().equals(Material.END_PORTAL)) { + World w = location.getWorld(); + if (w == null || !plugin.getIWM().isIslandEnd(w) + || !Flags.REMOVE_END_EXIT_ISLAND.isSetForWorld(w) + || w.getBlockAt(0, 255, 0).getType().equals(Material.END_PORTAL)) { return; } // Setting a End Portal at the top will trick dragon legacy check. - location.getWorld().getBlockAt(0, 255, 0).setType(Material.END_PORTAL, false); + w.getBlockAt(0, 255, 0).setType(Material.END_PORTAL, false); } /** diff --git a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java index e1f28b671..a716ef566 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java @@ -220,8 +220,8 @@ public class JoinLeaveListener implements Listener { if (island != null) { // Check if new owner has a different range permission than the island size int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.range", island.getProtectionRange()); - // Range cannot be greater than the island distance * 2 - range = Math.min(range, 2 * plugin.getIWM().getIslandDistance(island.getWorld())); + // Range cannot be greater than the island distance + range = Math.min(range, plugin.getIWM().getIslandDistance(island.getWorld())); // Range can go up or down if (range != island.getProtectionRange()) { user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range)); diff --git a/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java b/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java index 3a8c04cd4..f1c29abc3 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java +++ b/src/main/java/world/bentobox/bentobox/listeners/PlayerEntityPortalEvent.java @@ -1,5 +1,6 @@ package world.bentobox.bentobox.listeners; +import java.util.Objects; import java.util.Optional; import org.bukkit.Location; @@ -153,8 +154,8 @@ public class PlayerEntityPortalEvent { * Get the from world * @return from world */ - @Nullable + @NonNull public World getWorld() { - return getFrom().getWorld(); + return Objects.requireNonNull(getFrom().getWorld(), "From world is null!"); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java b/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java index d0e55998d..f16766a37 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/PortalTeleportationListener.java @@ -2,6 +2,7 @@ package world.bentobox.bentobox.listeners; import java.util.Arrays; import java.util.HashSet; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -56,7 +57,7 @@ public class PortalTeleportationListener implements Listener { * Fires the event if nether or end is disabled at the system level * @param e - EntityPortalEnterEvent */ - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onPlayerPortal(EntityPortalEnterEvent e) { if (!(e.getEntity() instanceof Player)) { return; @@ -96,7 +97,7 @@ public class PortalTeleportationListener implements Listener { * * @param e - event */ - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public boolean onEntityPortal(EntityPortalEvent e) { if (plugin.getIWM().inWorld(e.getFrom())) { Optional mat = Arrays.stream(BlockFace.values()) @@ -155,7 +156,7 @@ public class PortalTeleportationListener implements Listener { private boolean processPortal(final PlayerEntityPortalEvent e, final Environment env) { World fromWorld = e.getFrom().getWorld(); World overWorld = Util.getWorld(fromWorld); - if (fromWorld == null || !plugin.getIWM().inWorld(overWorld)) { + if (overWorld == null || fromWorld == null || !plugin.getIWM().inWorld(overWorld)) { // Do nothing special return false; } @@ -392,7 +393,7 @@ public class PortalTeleportationListener implements Listener { */ private void handleStandardNetherOrEnd(PlayerEntityPortalEvent e, World fromWorld, World overWorld, Environment env) { if (fromWorld.getEnvironment() != env) { - World toWorld = getNetherEndWorld(overWorld, env); + World toWorld = Objects.requireNonNull(getNetherEndWorld(overWorld, env)); Location spawnPoint = toWorld.getSpawnLocation(); // If spawn is set as 0,63,0 in the End then move it to 100, 50 ,0. if (env.equals(Environment.THE_END) && spawnPoint.getBlockX() == 0 && spawnPoint.getBlockZ() == 0) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java index 8db7760e7..c86c0008f 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java @@ -36,7 +36,7 @@ public class CommandCycleClick implements ClickHandler { // Get the user's island for the game world World world = panel.getWorld().orElse(user.getWorld()); Island island = plugin.getIslands().getIsland(world, user.getUniqueId()); - if (island != null && island.getOwner().equals(user.getUniqueId())) { + if (island != null && island.getOwner() != null && island.getOwner().equals(user.getUniqueId())) { RanksManager rm = plugin.getRanksManager(); int currentRank = island.getRankCommand(command); if (click.equals(ClickType.LEFT)) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java index d5ce0fecc..201b3ced3 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java @@ -2,6 +2,7 @@ package world.bentobox.bentobox.listeners.flags.clicklisteners; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -43,7 +44,8 @@ public class CommandRankClickListener implements ClickHandler { } // Check if has permission - String prefix = plugin.getIWM().getPermissionPrefix(Util.getWorld(panel.getWorld().orElse(user.getWorld()))); + World w = Objects.requireNonNull(Util.getWorld(panel.getWorld().orElse(user.getWorld()))); + String prefix = plugin.getIWM().getPermissionPrefix(w); String reqPerm = prefix + "settings." + Flags.COMMAND_RANKS.getID(); String allPerms = prefix + "settings.*"; if (!user.hasPermission(reqPerm) && !user.hasPermission(allPerms) diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/GeoLimitClickListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/GeoLimitClickListener.java index 98e1495a7..c01177afb 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/GeoLimitClickListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/GeoLimitClickListener.java @@ -1,5 +1,7 @@ package world.bentobox.bentobox.listeners.flags.clicklisteners; +import java.util.Objects; + import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.event.inventory.ClickType; @@ -29,7 +31,8 @@ public class GeoLimitClickListener implements ClickHandler { } World world = panel.getWorld().orElse(user.getWorld()); IslandWorldManager iwm = BentoBox.getInstance().getIWM(); - String reqPerm = iwm.getPermissionPrefix(Util.getWorld(world)) + "admin.settings.GEO_LIMIT_MOBS"; + World w = Objects.requireNonNull(Util.getWorld(world)); + String reqPerm = iwm.getPermissionPrefix(w) + "admin.settings.GEO_LIMIT_MOBS"; if (!user.hasPermission(reqPerm)) { user.sendMessage("general.errors.no-permission", "[permission]", reqPerm); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/MobLimitClickListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/MobLimitClickListener.java index 07b7c7ec9..deb629812 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/MobLimitClickListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/MobLimitClickListener.java @@ -1,5 +1,7 @@ package world.bentobox.bentobox.listeners.flags.clicklisteners; +import java.util.Objects; + import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.event.inventory.ClickType; @@ -29,7 +31,8 @@ public class MobLimitClickListener implements ClickHandler { } World world = panel.getWorld().orElse(user.getWorld()); IslandWorldManager iwm = BentoBox.getInstance().getIWM(); - String reqPerm = iwm.getPermissionPrefix(Util.getWorld(world)) + "admin.settings.LIMIT_MOBS"; + World w = Objects.requireNonNull(Util.getWorld(world)); + String reqPerm = iwm.getPermissionPrefix(w) + "admin.settings.LIMIT_MOBS"; if (!user.hasPermission(reqPerm)) { user.sendMessage("general.errors.no-permission", "[permission]", reqPerm); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java index 98a382cec..55deac57e 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java @@ -44,7 +44,7 @@ public class BlockInteractionListener extends FlagListener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerInteract(final PlayerInteractEvent e) { // We only care about the RIGHT_CLICK_BLOCK action. - if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) { + if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK) || e.getClickedBlock() == null) { return; } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java index 391f2605d..6defb0ef6 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BreakBlocksListener.java @@ -42,15 +42,13 @@ public class BreakBlocksListener extends FlagListener { */ @EventHandler(priority = EventPriority.LOW) public void onBreakHanging(final HangingBreakByEntityEvent e) { - if (e.getRemover() instanceof Player) { - checkIsland(e, (Player)e.getRemover(), e.getEntity().getLocation(), Flags.BREAK_BLOCKS); + if (e.getRemover() instanceof Player r) { + checkIsland(e, r, e.getEntity().getLocation(), Flags.BREAK_BLOCKS); } // Check for projectiles - if (e.getRemover() instanceof Projectile p) { - // Find out who fired it - if (p.getShooter() instanceof Player) { - checkIsland(e, (Player)p.getShooter(), e.getEntity().getLocation(), Flags.BREAK_BLOCKS); - } + // Find out who fired it + if (e.getRemover() instanceof Projectile p && p.getShooter() instanceof Player s) { + checkIsland(e, s, e.getEntity().getLocation(), Flags.BREAK_BLOCKS); } } @@ -65,21 +63,14 @@ public class BreakBlocksListener extends FlagListener { if (!e.getAction().equals(Action.LEFT_CLICK_BLOCK)) { return; } + Player p = e.getPlayer(); + Location l = e.getClickedBlock().getLocation(); switch (e.getClickedBlock().getType()) { - case CAKE: - checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BREAK_BLOCKS); - break; - case SPAWNER: - checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BREAK_SPAWNERS); - break; - case DRAGON_EGG: - checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.DRAGON_EGG); - break; - case HOPPER: - checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BREAK_HOPPERS); - break; - default: - break; + case CAKE -> checkIsland(e, p, l, Flags.BREAK_BLOCKS); + case SPAWNER -> checkIsland(e, p, l, Flags.BREAK_SPAWNERS); + case DRAGON_EGG -> checkIsland(e, p, l, Flags.DRAGON_EGG); + case HOPPER -> checkIsland(e, p, l, Flags.BREAK_HOPPERS); + default -> {} } } @@ -89,14 +80,15 @@ public class BreakBlocksListener extends FlagListener { */ @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) public void onVehicleDamageEvent(VehicleDamageEvent e) { - if (getIWM().inWorld(e.getVehicle().getLocation()) && e.getAttacker() instanceof Player) { + Location l = e.getVehicle().getLocation(); + if (getIWM().inWorld(l) && e.getAttacker() instanceof Player p) { String vehicleType = e.getVehicle().getType().toString(); if (e.getVehicle().getType().equals(EntityType.BOAT)) { - checkIsland(e, (Player) e.getAttacker(), e.getVehicle().getLocation(), Flags.BOAT); + checkIsland(e, p, l, Flags.BOAT); } else if (vehicleType.contains("MINECART")) { - checkIsland(e, (Player) e.getAttacker(), e.getVehicle().getLocation(), Flags.MINECART); + checkIsland(e, p, l, Flags.MINECART); } else { - checkIsland(e, (Player) e.getAttacker(), e.getVehicle().getLocation(), Flags.BREAK_BLOCKS); + checkIsland(e, p, l, Flags.BREAK_BLOCKS); } } } @@ -114,9 +106,9 @@ public class BreakBlocksListener extends FlagListener { return; } // Get the attacker - if (e.getDamager() instanceof Player) { + if (e.getDamager() instanceof Player p) { // Check the break blocks flag - notAllowed(e, (Player)e.getDamager(), e.getEntity().getLocation()); + notAllowed(e, p, e.getEntity().getLocation()); } else if (e.getDamager() instanceof Projectile p) { // Find out who fired the arrow if (p.getShooter() instanceof Player && notAllowed(e, (Player)p.getShooter(), e.getEntity().getLocation())) { @@ -153,8 +145,8 @@ public class BreakBlocksListener extends FlagListener { } // Find out who fired the arrow - if (e.getEntity().getShooter() instanceof Player && - !checkIsland(e, (Player) e.getEntity().getShooter(), e.getHitBlock().getLocation(), Flags.BREAK_BLOCKS)) { + if (e.getEntity().getShooter() instanceof Player s && + !checkIsland(e, s, e.getHitBlock().getLocation(), Flags.BREAK_BLOCKS)) { final BlockData data = e.getHitBlock().getBlockData(); // We seemingly can't prevent the block from being destroyed // So we need to put it back with a slight delay (yup, this is hacky - it makes the block flicker sometimes) diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java index 02426ea85..3f411267f 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BucketListener.java @@ -1,8 +1,10 @@ package world.bentobox.bentobox.listeners.flags.protection; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.MushroomCow; +import org.bukkit.entity.Player; import org.bukkit.entity.TropicalFish; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -38,20 +40,14 @@ public class BucketListener extends FlagListener { */ @EventHandler(priority = EventPriority.LOW) public void onBucketFill(final PlayerBucketFillEvent e) { + Player p = e.getPlayer(); + Location l = e.getBlockClicked().getLocation(); // Check filling of various liquids switch (e.getItemStack().getType()) { - case LAVA_BUCKET -> { - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.COLLECT_LAVA); - } - case WATER_BUCKET -> { - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.COLLECT_WATER); - } - case MILK_BUCKET -> { - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.MILKING); - } - default -> - // Check general bucket use - checkIsland(e, e.getPlayer(), e.getBlockClicked().getLocation(), Flags.BUCKET); + case LAVA_BUCKET -> checkIsland(e, p, l, Flags.COLLECT_LAVA); + case WATER_BUCKET -> checkIsland(e, p, l, Flags.COLLECT_WATER); + case MILK_BUCKET -> checkIsland(e, p, l, Flags.MILKING); + default -> checkIsland(e, p, l, Flags.BUCKET); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/EntityInteractListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/EntityInteractListener.java index 403fa9871..3f273b5c3 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/EntityInteractListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/EntityInteractListener.java @@ -1,11 +1,14 @@ package world.bentobox.bentobox.listeners.flags.protection; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Animals; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Boat; +import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; import org.bukkit.entity.Villager; +import org.bukkit.entity.WanderingTrader; import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -32,31 +35,33 @@ public class EntityInteractListener extends FlagListener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onPlayerInteractEntity(PlayerInteractEntityEvent e) { + Player p = e.getPlayer(); + Location l = e.getRightClicked().getLocation(); if (e.getRightClicked() instanceof Vehicle) { // Animal riding if (e.getRightClicked() instanceof Animals) { - checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.RIDING); + checkIsland(e, p, l, Flags.RIDING); } // Minecart riding else if (e.getRightClicked() instanceof RideableMinecart) { - checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.MINECART); + checkIsland(e, p, l, Flags.MINECART); } // Boat riding else if (e.getRightClicked() instanceof Boat) { - checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.BOAT); + checkIsland(e, p, l, Flags.BOAT); } } // Villager trading - else if (e.getRightClicked() instanceof Villager || e.getRightClicked().getType().name().equals("WANDERING_TRADER")) { // TODO: Simplify when 1.13.2 support is dropped + else if (e.getRightClicked() instanceof Villager || e.getRightClicked() instanceof WanderingTrader) { // Check naming and check trading - checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.TRADING); + checkIsland(e, p, l, Flags.TRADING); if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG)) { - checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.NAME_TAG); + checkIsland(e, p, l, Flags.NAME_TAG); } } // Name tags else if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG)) { - checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.NAME_TAG); + checkIsland(e, p, l, Flags.NAME_TAG); } } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ExperiencePickupListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ExperiencePickupListener.java index b2233740f..71f8d6cf9 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ExperiencePickupListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/ExperiencePickupListener.java @@ -19,9 +19,9 @@ public class ExperiencePickupListener extends FlagListener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onExperienceOrbTargetPlayer(EntityTargetLivingEntityEvent e) { // Make sure the target is a Player and the entity is an experience orb - if (e.getTarget() instanceof Player && e.getEntity() instanceof ExperienceOrb - && !checkIsland(e, (Player) e.getTarget(), e.getEntity().getLocation(), Flags.EXPERIENCE_PICKUP)) { - // Cancelling the event won't work, we need to explicitly set the target to null + if (e.getTarget() instanceof Player p && e.getEntity() instanceof ExperienceOrb o + && !checkIsland(e, p, o.getLocation(), Flags.EXPERIENCE_PICKUP)) { + // Canceling the event won't work, we need to explicitly set the target to null e.setTarget(null); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java index 072032bd0..37ec8be1e 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java @@ -11,6 +11,7 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.vehicle.VehicleMoveEvent; import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.NonNull; import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; @@ -103,7 +104,7 @@ public class LockAndBanListener extends FlagListener { * @param loc - location to check * @return CheckResult LOCKED, BANNED or OPEN. If an island is locked, that will take priority over banned */ - private CheckResult check(Player player, Location loc) { + private CheckResult check(@NonNull Player player, Location loc) { // Ops or NPC's are allowed everywhere if (player.isOp() || player.hasMetadata("NPC")) { return CheckResult.OPEN; @@ -127,7 +128,7 @@ public class LockAndBanListener extends FlagListener { * @param loc - location to check * @return true if banned */ - private CheckResult checkAndNotify(Player player, Location loc) { + private CheckResult checkAndNotify(@NonNull Player player, Location loc) { CheckResult r = check(player,loc); switch (r) { case BANNED: diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java index 34caba40b..8ae046632 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java @@ -47,7 +47,7 @@ public class MobSpawnListener extends FlagListener { case RAID: case REINFORCEMENTS: case SILVERFISH_BLOCK: - //case SLIME_SPLIT: messes with slimes from spawners, slime must have previously existed to create another + //case SLIME_SPLIT: messes with slimes from spawners, slime must have previously existed to create another case TRAP: case VILLAGE_DEFENSE: case VILLAGE_INVASION: diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java index 2cc2fee54..23ea9cf5d 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/PVPListener.java @@ -2,7 +2,6 @@ package world.bentobox.bentobox.listeners.flags.settings; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.UUID; import java.util.WeakHashMap; @@ -25,6 +24,7 @@ import org.bukkit.event.entity.LingeringPotionSplashEvent; import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.events.flags.FlagSettingChangeEvent; import world.bentobox.bentobox.api.flags.Flag; @@ -62,10 +62,10 @@ public class PVPListener extends FlagListener { } // Protect visitors if (e.getCause().equals(DamageCause.ENTITY_ATTACK) && protectedVisitor((Player)e.getEntity())) { - if (e.getDamager() instanceof Player) { - User.getInstance(e.getDamager()).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); - } else if (e.getDamager() instanceof Projectile && ((Projectile)e.getDamager()).getShooter() instanceof Player) { - User.getInstance((Player)((Projectile)e.getDamager()).getShooter()).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); + if (e.getDamager() instanceof Player p && p != null) { + User.getInstance(p).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); + } else if (e.getDamager() instanceof Projectile pr && pr.getShooter() instanceof Player sh && sh != null) { + User.getInstance(sh).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); } e.setCancelled(true); } else { @@ -89,9 +89,8 @@ public class PVPListener extends FlagListener { user.notify(getFlag(damager.getWorld()).getHintReference()); e.setCancelled(true); } - } else if (damager instanceof Projectile p && ((Projectile)damager).getShooter() instanceof Player) { + } else if (damager instanceof Projectile p && ((Projectile)damager).getShooter() instanceof Player shooter) { // Find out who fired the arrow - Player shooter =(Player)p.getShooter(); processDamage(e, damager, shooter, hurtEntity, flag); } else if (damager instanceof Firework && firedFireworks.containsKey(damager)) { Player shooter = firedFireworks.get(damager); @@ -101,7 +100,7 @@ public class PVPListener extends FlagListener { private void processDamage(Cancellable e, Entity damager, Player shooter, Entity hurtEntity, Flag flag) { // Allow self damage - if (hurtEntity.equals(shooter)) { + if (hurtEntity.equals(shooter) || shooter == null) { return; } User user = User.getInstance(shooter); @@ -116,9 +115,13 @@ public class PVPListener extends FlagListener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onFishing(PlayerFishEvent e) { - if (e.getCaught() instanceof Player && getPlugin().getIWM().inWorld(e.getCaught().getLocation())) { + if (e.getCaught() instanceof Player c && getPlugin().getIWM().inWorld(c.getLocation())) { // Allow self-inflicted damage or NPC damage - if (e.getCaught().equals(e.getPlayer()) || e.getCaught().hasMetadata("NPC")) { + if (c.equals(e.getPlayer()) || c.hasMetadata("NPC")) { + return; + } + // Is PVP allowed here? + if (this.PVPAllowed(c.getLocation())) { return; } // Is PVP allowed here? @@ -126,12 +129,12 @@ public class PVPListener extends FlagListener { return; } // Protect visitors - if (protectedVisitor((Player)e.getCaught())) { + if (protectedVisitor(c)) { User.getInstance(e.getPlayer()).notify(Flags.INVINCIBLE_VISITORS.getHintReference()); e.setCancelled(true); - } else if (!checkIsland(e, e.getPlayer(), e.getCaught().getLocation(), getFlag(e.getCaught().getWorld()))) { + } else if (!checkIsland(e, e.getPlayer(), c.getLocation(), getFlag(c.getWorld()))) { e.getHook().remove(); - User.getInstance(e.getPlayer()).notify(getFlag(e.getCaught().getWorld()).getHintReference()); + User.getInstance(e.getPlayer()).notify(getFlag(c.getWorld()).getHintReference()); e.setCancelled(true); } } @@ -143,8 +146,8 @@ public class PVPListener extends FlagListener { */ @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) public void onSplashPotionSplash(final PotionSplashEvent e) { - if (e.getEntity().getShooter() instanceof Player && getPlugin().getIWM().inWorld(e.getEntity().getWorld())) { - User user = User.getInstance((Player)e.getEntity().getShooter()); + if (e.getEntity().getShooter() instanceof Player p && p != null && getPlugin().getIWM().inWorld(e.getEntity().getWorld())) { + User user = User.getInstance(p); // Is PVP allowed here? if (this.PVPAllowed(e.getEntity().getLocation())) { return; @@ -256,9 +259,9 @@ public class PVPListener extends FlagListener { }); } - private void alertUser(Player player, Flag flag) { + private void alertUser(@NonNull Player player, Flag flag) { String message = "protection.flags." + flag.getID() + ".enabled"; - Objects.requireNonNull(User.getInstance(player)).sendMessage(message); + User.getInstance(player).sendMessage(message); player.playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER,2F, 1F); } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java index 814c982ed..cb03897de 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/CreeperListener.java @@ -41,7 +41,7 @@ public class CreeperListener extends FlagListener { } // Check for griefing Creeper creeper = (Creeper)e.getEntity(); - if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld()) && creeper.getTarget() instanceof Player target) { + if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld()) && creeper.getTarget() instanceof Player target && target != null) { if (!getIslands().locationIsOnIsland(target, e.getLocation())) { User user = User.getInstance(target); user.notify("protection.protected", TextVariables.DESCRIPTION, user.getTranslation(Flags.CREEPER_GRIEFING.getHintReference())); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListener.java index 4740b551f..02404a7bc 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListener.java @@ -105,14 +105,12 @@ public class EnterExitListener extends FlagListener { // Send message if island is owned by someone if (island.isOwned()) { // Leave messages are always specific to this world - + String islandMessage = user.getTranslation(island.getWorld(), ISLAND_MESSAGE, TextVariables.NAME, getPlugin().getPlayers().getName(island.getOwner())); // Send specific message if the player is member of this island if (island.getMemberSet().contains(user.getUniqueId())) { - user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-leaving-your-island", TextVariables.NAME, (island.getName() != null) ? island.getName() : - user.getTranslation(island.getWorld(), ISLAND_MESSAGE, TextVariables.NAME, getPlugin().getPlayers().getName(island.getOwner()))); + user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-leaving-your-island", TextVariables.NAME, (island.getName() != null) ? island.getName() : islandMessage); } else { - user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-leaving", TextVariables.NAME, (island.getName() != null) ? island.getName() : - user.getTranslation(island.getWorld(), ISLAND_MESSAGE, TextVariables.NAME, getPlugin().getPlayers().getName(island.getOwner()))); + user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-leaving", TextVariables.NAME, (island.getName() != null) ? island.getName() : islandMessage); } } // Send message if island is unowned, but has a name @@ -132,17 +130,15 @@ public class EnterExitListener extends FlagListener { if (!Flags.ENTER_EXIT_MESSAGES.isSetForWorld(island.getWorld())) { return; } - // Send message if island is owned by someone if (island.isOwned()) { // Enter messages are always specific to this world + String islandMessage = user.getTranslation(island.getWorld(), ISLAND_MESSAGE, TextVariables.NAME, getPlugin().getPlayers().getName(island.getOwner())); // Send specific message if the player is member of this island if (island.getMemberSet().contains(user.getUniqueId())) { - user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-entering-your-island", TextVariables.NAME, (island.getName() != null) ? island.getName() : - user.getTranslation(island.getWorld(), ISLAND_MESSAGE, TextVariables.NAME, getPlugin().getPlayers().getName(island.getOwner()))); + user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-entering-your-island", TextVariables.NAME, (island.getName() != null) ? island.getName() : islandMessage); } else { - user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-entering", TextVariables.NAME, (island.getName() != null) ? island.getName() : - user.getTranslation(island.getWorld(), ISLAND_MESSAGE, TextVariables.NAME, getPlugin().getPlayers().getName(island.getOwner()))); + user.notify(island.getWorld(), "protection.flags.ENTER_EXIT_MESSAGES.now-entering", TextVariables.NAME, (island.getName() != null) ? island.getName() : islandMessage); } } // Send message if island is unowned, but has a name diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java index d8890723a..140eceecd 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/InvincibleVisitorsListener.java @@ -2,6 +2,7 @@ package world.bentobox.bentobox.listeners.flags.worldsettings; import java.util.Arrays; import java.util.Comparator; +import java.util.Objects; import org.bukkit.Material; import org.bukkit.Sound; @@ -39,7 +40,8 @@ public class InvincibleVisitorsListener extends FlagListener implements ClickHan user.sendMessage("general.errors.wrong-world"); return true; } - String reqPerm = getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + "admin.settings.INVINCIBLE_VISITORS"; + World w = Objects.requireNonNull(Util.getWorld(user.getWorld())); + String reqPerm = getIWM().getPermissionPrefix(w) + "admin.settings.INVINCIBLE_VISITORS"; if (!user.hasPermission(reqPerm)) { user.sendMessage("general.errors.no-permission", "[permission]", reqPerm); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java index 0a8d411d7..8a0c32618 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListener.java @@ -32,7 +32,7 @@ public class IslandRespawnListener extends FlagListener { @EventHandler(priority = EventPriority.LOW) public void onPlayerDeath(PlayerDeathEvent e) { World world = Util.getWorld(e.getEntity().getWorld()); - if (!getIWM().inWorld(world)) { + if (world == null || !getIWM().inWorld(world)) { return; // not in the island world } if (!Flags.ISLAND_RESPAWN.isSetForWorld(world)) { diff --git a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java index b7853161d..707a9051e 100644 --- a/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/AddonsManager.java @@ -1,9 +1,6 @@ package world.bentobox.bentobox.managers; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -97,8 +94,13 @@ public class AddonsManager { plugin.log("Registering " + parent.getDescription().getName()); // Get description in the addon.yml file + InputStream resource = parent.getResource("addon.yml"); + if (resource == null) { + plugin.logError("Failed to register addon: no addon.yml found"); + return; + } // Open a reader to the jar - try (BufferedReader reader = new BufferedReader(new InputStreamReader(parent.getResource("addon.yml")))) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) { setAddonFile(parent, addon); // Grab the description in the addon.yml file YamlConfiguration data = new YamlConfiguration(); @@ -266,7 +268,11 @@ public class AddonsManager { } void registerPermission(ConfigurationSection perms, String perm) throws InvalidAddonDescriptionException { - PermissionDefault pd = PermissionDefault.getByName(perms.getString(perm + DEFAULT)); + String name = perms.getString(perm + DEFAULT); + if (name == null) { + throw new InvalidAddonDescriptionException("Permission default is invalid in addon.yml: " + perm + DEFAULT); + } + PermissionDefault pd = PermissionDefault.getByName(name); if (pd == null) { throw new InvalidAddonDescriptionException("Permission default is invalid in addon.yml: " + perm + DEFAULT); } @@ -503,7 +509,7 @@ public class AddonsManager { @Nullable public Class getClassByName(@NonNull final String name) { try { - return classes.getOrDefault(name, loaders.values().stream().map(l -> l.findClass(name, false)).filter(Objects::nonNull).findFirst().orElse(null)); + return classes.getOrDefault(name, loaders.values().stream().filter(Objects::nonNull).map(l -> l.findClass(name, false)).filter(Objects::nonNull).findFirst().orElse(null)); } catch (Exception ignored) { // Ignored. } diff --git a/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java b/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java index 2c852c593..cc7ea3c16 100644 --- a/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/BlueprintClipboardManager.java @@ -144,10 +144,12 @@ public class BlueprintClipboardManager { * @return - true if successful, false if error */ public boolean save(User user, String newName) { - clipboard.getBlueprint().setName(newName); - if (saveBlueprint(clipboard.getBlueprint())) { - user.sendMessage("general.success"); - return true; + if (clipboard.getBlueprint() != null) { + clipboard.getBlueprint().setName(newName); + if (saveBlueprint(clipboard.getBlueprint())) { + user.sendMessage("general.success"); + return true; + } } user.sendMessage("commands.admin.blueprint.could-not-save", "[message]", "Could not save temp blueprint file."); return false; @@ -192,6 +194,9 @@ public class BlueprintClipboardManager { if (!entry.isDirectory()) { unzipFiles(zipInputStream, filePath); } else { + if (!filePath.startsWith(blueprintFolder.getAbsolutePath())) { + throw new IOException("Entry is outside of the target directory"); + } Files.createDirectories(filePath); } @@ -202,6 +207,9 @@ public class BlueprintClipboardManager { } private void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException { + if (!unzipFilePath.toAbsolutePath().toString().startsWith(blueprintFolder.getAbsolutePath())) { + throw new IOException("Entry is outside of the target directory"); + } try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) { byte[] bytesIn = new byte[1024]; int read; diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java index 10a2f363a..72405a848 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandWorldManager.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -199,11 +200,11 @@ public class IslandWorldManager { * Get the settings for this world or sub-worlds (nether, end) * * @param world world - * @return world settings, or null if world is unknown + * @return world settings */ - @Nullable + @NonNull public WorldSettings getWorldSettings(@NonNull World world) { - return gameModes.containsKey(world) ? gameModes.get(world).getWorldSettings() : null; + return Objects.requireNonNull(gameModes.get(world), "Attempt to get WorldSettings for non-game world " + world.getName()).getWorldSettings(); } /** @@ -678,7 +679,7 @@ public class IslandWorldManager { * @return data folder file object or the plugin's data folder if none found */ public File getDataFolder(@NonNull World world) { - return getAddon(world).map(GameModeAddon::getDataFolder).orElseGet(() -> plugin.getDataFolder()); + return getAddon(world).map(GameModeAddon::getDataFolder).orElseGet(plugin::getDataFolder); } /** @@ -725,7 +726,7 @@ public class IslandWorldManager { public boolean isUseOwnGenerator(@NonNull World world) { return gameModes.containsKey(world) && gameModes.get(world).getWorldSettings().isUseOwnGenerator(); } - + /** * Check for blocks when searching for a new island. This is a safety net check that does a look * around the new island location (3x3x3 block check). If any non-air or non-water blocks are found diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index b7c433759..7a0931f04 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -129,7 +129,7 @@ public class IslandsManager { * Used only for testing. Sets the database to a mock database. * @param handler - handler */ - public void setHandler(Database handler) { + public void setHandler(@NonNull Database handler) { this.handler = handler; } @@ -549,6 +549,7 @@ public class IslandsManager { islandMax = owner.getPermissionValue(plugin.getIWM().getPermissionPrefix(island.getWorld()) + "island.maxhomes", islandMax); } + // If the island maxHomes is just the same as the world default, then set to null island.setMaxHomes(islandMax == plugin.getIWM().getMaxHomes(island.getWorld()) ? null : islandMax); this.save(island); return islandMax; @@ -668,6 +669,7 @@ public class IslandsManager { * @param name - named home location. Blank means default. * @return Location of a safe teleport spot or {@code null} if one cannot be found or if the world is not an island world. */ + @Nullable public Location getSafeHomeLocation(@NonNull World world, @NonNull User user, String name) { // Check if the world is a gamemode world if (!plugin.getIWM().inWorld(world)) { @@ -745,6 +747,17 @@ public class IslandsManager { return null; } + /** + * Sets a default home location on user's island. Replaces previous default location. + * @param user - user + * @param location - location on island + * @return true if home location was set. False if this location is not on the island. + * @since 1.18.0 + */ + public boolean setHomeLocation(@NonNull User user, Location location) { + return setHomeLocation(user.getUniqueId(), location, ""); + } + /** * Sets a home location on user's island. Replaces previous location if the same name is used * @param user - user @@ -801,10 +814,10 @@ public class IslandsManager { * Get the home location for user in world * @param world - world * @param user - user - * @return home location + * @return home location or null if there is no home * @since 1.16.0 */ - @NonNull + @Nullable public Location getHomeLocation(@NonNull World world, @NonNull User user) { return getHomeLocation(world, user, ""); } @@ -813,10 +826,10 @@ public class IslandsManager { * Get the home location for player's UUID in world * @param world - world * @param uuid - uuid of player - * @return home location + * @return home location or null if there is no home * @since 1.16.0 */ - @NonNull + @Nullable public Location getHomeLocation(@NonNull World world, @NonNull UUID uuid) { return getHomeLocation(world, uuid, ""); } @@ -826,10 +839,10 @@ public class IslandsManager { * @param world - world * @param user - user * @param name - name of home, or blank for default - * @return home location + * @return home location or null if there is no home * @since 1.16.0 */ - @NonNull + @Nullable public Location getHomeLocation(@NonNull World world, @NonNull User user, String name) { return getHomeLocation(world, user.getUniqueId(), name); } @@ -839,13 +852,16 @@ public class IslandsManager { * @param world - world * @param uuid - uuid of player * @param name - name of home, or blank for default - * @return home location + * @return home location or null if there is no home * @since 1.16.0 */ - @NonNull + @Nullable public Location getHomeLocation(@NonNull World world, @NonNull UUID uuid, String name) { // Migrate from player homes to island homes Island island = this.getIsland(world, uuid); + if (island == null) { + return null; + } migrateHomes(world, uuid, name, island); return getHomeLocation(island, name); } @@ -880,7 +896,7 @@ public class IslandsManager { * @since 1.16.0 */ @NonNull - public Location getHomeLocation(@Nullable Island island) { + public Location getHomeLocation(@NonNull Island island) { return getHomeLocation(island, ""); } @@ -888,12 +904,12 @@ public class IslandsManager { * Get the named home location for this island * @param island - island * @param name - name of home, or blank for default - * @return home location + * @return home location or if there is none, then the island's center * @since 1.16.0 */ @NonNull - public Location getHomeLocation(@Nullable Island island, String name) { - return island == null ? null : island.getHome(name); + public Location getHomeLocation(@NonNull Island island, @NonNull String name) { + return Objects.requireNonNullElse(island.getHome(name), island.getCenter()); } /** @@ -903,8 +919,8 @@ public class IslandsManager { * @return true if successful, false if not * @since 1.16.0 */ - public boolean removeHomeLocation(@Nullable Island island, String name) { - return island != null && island.removeHome(name); + public boolean removeHomeLocation(@NonNull Island island, @NonNull String name) { + return island.removeHome(name); } /** @@ -914,8 +930,8 @@ public class IslandsManager { * @param newName - new name * @return true if successful, false if not */ - public boolean renameHomeLocation(@Nullable Island island, String oldName, String newName) { - return island != null && island.renameHome(oldName, newName); + public boolean renameHomeLocation(@NonNull Island island, @NonNull String oldName, @NonNull String newName) { + return island.renameHome(oldName, newName); } /** @@ -935,7 +951,7 @@ public class IslandsManager { * @param name - name being checked * @return true if it exists or not */ - public boolean isHomeLocation(@NonNull Island island, String name) { + public boolean isHomeLocation(@NonNull Island island, @NonNull String name) { return island.getHomes().containsKey(name.toLowerCase()); } @@ -945,7 +961,7 @@ public class IslandsManager { * @param name - name * @return number of homes after adding this one */ - public int getNumberOfHomesIfAdded(@NonNull Island island, String name) { + public int getNumberOfHomesIfAdded(@NonNull Island island, @NonNull String name) { return isHomeLocation(island, name) ? getHomeLocations(island).size() : getHomeLocations(island).size() + 1; } @@ -964,6 +980,7 @@ public class IslandsManager { * @param world - world * @return the spawnPoint or null if spawn does not exist */ + @Nullable public Location getSpawnPoint(@NonNull World world) { return spawn.containsKey(world) ? spawn.get(world).getSpawnPoint(world.getEnvironment()) : null; } @@ -1084,6 +1101,7 @@ public class IslandsManager { .island(island) .homeName(name) .thenRun(() -> teleported(world, user, name, newIsland, island)) + .ifFail(() -> goingHome.remove(user.getUniqueId())) .buildFuture() .thenAccept(result::complete); return; @@ -1098,9 +1116,10 @@ public class IslandsManager { teleported(world, user, name, newIsland, island); result.complete(true); } else { + // Remove from mid-teleport set + goingHome.remove(user.getUniqueId()); result.complete(false); } - }); }); return result; @@ -1118,6 +1137,8 @@ public class IslandsManager { if (!name.isEmpty()) { user.sendMessage("commands.island.go.teleported", TextVariables.NUMBER, name); } + // Remove from mid-teleport set + goingHome.remove(user.getUniqueId()); // If this is a new island, then run commands and do resets if (newIsland) { // Fire event @@ -1161,7 +1182,6 @@ public class IslandsManager { // Set the game mode user.setGameMode(plugin.getIWM().getDefaultGameMode(world)); - } // Remove from mid-teleport set goingHome.remove(user.getUniqueId()); @@ -1530,7 +1550,6 @@ public class IslandsManager { * @param uuid - the player's UUID */ public void setLeaveTeam(World world, UUID uuid) { - plugin.getPlayers().clearHomeLocations(world, uuid); removePlayer(world, uuid); } diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java index 03609dd48..c43702250 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -195,7 +195,9 @@ public class PlayersManager { * @param user - the player * @param location - the location * @param number - a number - 1 is default. Can be any number. + * @deprecated Use {@link IslandsManager#setHomeLocation(User, Location, String)} */ + @Deprecated(since="1.18.0", forRemoval=true) public void setHomeLocation(User user, Location location, int number) { setHomeLocation(user.getUniqueId(), location,number); } @@ -205,7 +207,9 @@ public class PlayersManager { * @param playerUUID - the player's UUID * @param location - the location * @param number - a number - 1 is default. Can be any number. + * @deprecated Use {@link IslandsManager#setHomeLocation(UUID, Location, String)} */ + @Deprecated(since="1.18.0", forRemoval=true) public void setHomeLocation(UUID playerUUID, Location location, int number) { addPlayer(playerUUID); playerCache.get(playerUUID).setHomeLocation(location,number); @@ -215,7 +219,9 @@ public class PlayersManager { * Set the default home location for player * @param playerUUID - the player's UUID * @param location - the location + * @deprecated Use {@link IslandsManager#setHomeLocation(UUID, Location)} */ + @Deprecated(since="1.18.0", forRemoval=true) public void setHomeLocation(UUID playerUUID, Location location) { setHomeLocation(playerUUID, location,1); } @@ -224,7 +230,9 @@ public class PlayersManager { * Clears any home locations for player * @param world - world * @param playerUUID - the player's UUID + * @deprecated Not used anymore. Home locations are stored on islands. */ + @Deprecated(since="1.18.0", forRemoval=true) public void clearHomeLocations(World world, UUID playerUUID) { addPlayer(playerUUID); playerCache.get(playerUUID).clearHomeLocations(world); @@ -237,7 +245,9 @@ public class PlayersManager { * @param user - the player * @param number - a number * @return Home location or null if none + * @deprecated Use {@link IslandsManager#getHomeLocation(World, User, String)} */ + @Deprecated(since="1.18.0", forRemoval=true) public Location getHomeLocation(World world, User user, int number) { addPlayer(user.getUniqueId()); return playerCache.get(user.getUniqueId()).getHomeLocation(world, number); @@ -250,7 +260,9 @@ public class PlayersManager { * @param playerUUID - the player's UUID * @param number - a number * @return Home location or null if none + * @deprecated Use {@link IslandsManager#getHomeLocation(World, UUID, String)} */ + @Deprecated(since="1.18.0", forRemoval=true) public Location getHomeLocation(World world, UUID playerUUID, int number) { addPlayer(playerUUID); return playerCache.get(playerUUID).getHomeLocation(world, number); @@ -260,7 +272,9 @@ public class PlayersManager { * Gets the default home location for player * @param playerUUID - the player's UUID * @return Home location or null if none + * @deprecated Use {@link IslandsManager#getHomeLocation(World, UUID)} */ + @Deprecated(since="1.18.0", forRemoval=true) public Location getHomeLocation(World world, UUID playerUUID) { addPlayer(playerUUID); return playerCache.get(playerUUID).getHomeLocation(world, 1); @@ -270,7 +284,9 @@ public class PlayersManager { * Provides all home locations for player * @param playerUUID - the player's UUID * @return List of home locations + * @deprecated Use {@link IslandsManager#getHomeLocations(world.bentobox.bentobox.database.objects.Island)} */ + @Deprecated(since="1.18.0", forRemoval=true) public Map getHomeLocations(World world, UUID playerUUID) { addPlayer(playerUUID); return playerCache.get(playerUUID).getHomeLocations(world); diff --git a/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java b/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java index 532699419..26593d042 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/DefaultNewIslandLocationStrategy.java @@ -32,7 +32,7 @@ public class DefaultNewIslandLocationStrategy implements NewIslandLocationStrate ISLAND_FOUND, BLOCKS_IN_AREA, FREE } - protected BentoBox plugin = BentoBox.getInstance(); + protected final BentoBox plugin = BentoBox.getInstance(); @Override public Location getNextLocation(World world) { diff --git a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java index 80c2cd9bf..06da94064 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java @@ -224,7 +224,7 @@ public class NewIsland { private void postCreationTask(Island oldIsland) { // Set initial spawn point if one exists if (island.getSpawnPoint(Environment.NORMAL) != null) { - plugin.getPlayers().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL), 1); + plugin.getIslands().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL)); } // Stop the player from falling or moving if they are if (user.isOnline()) { @@ -252,10 +252,8 @@ public class NewIsland { * @param loc - the new island location */ private void cleanUpUser(Location loc) { - // Clear any old home locations (they should be clear, but just in case) - plugin.getPlayers().clearHomeLocations(world, user.getUniqueId()); // Set home location - plugin.getPlayers().setHomeLocation(user, new Location(loc.getWorld(), loc.getX() + 0.5D, loc.getY(), loc.getZ() + 0.5D), 1); + plugin.getIslands().setHomeLocation(user, new Location(loc.getWorld(), loc.getX() + 0.5D, loc.getY(), loc.getZ() + 0.5D)); // Reset deaths if (plugin.getIWM().isDeathsResetOnNewIsland(world)) { plugin.getPlayers().setDeaths(world, user.getUniqueId(), 0); diff --git a/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java b/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java index 68b3ed5d1..b41f651b6 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java @@ -7,6 +7,7 @@ import java.util.stream.Collectors; import org.bukkit.Material; import org.bukkit.World; +import org.eclipse.jdt.annotation.NonNull; import world.bentobox.bentobox.api.flags.Flag.Type; import world.bentobox.bentobox.api.flags.clicklisteners.WorldToggleClick; import world.bentobox.bentobox.api.localization.TextVariables; @@ -68,7 +69,7 @@ public class WorldDefaultSettingsTab extends SettingsTab implements Tab { * @return list of all the panel items for this flag type */ @Override - public List getPanelItems() { + public @NonNull List getPanelItems() { // Different description and click handlers return getFlags().stream().map(f -> { PanelItem i = f.toPanelItem(plugin, user, null, false); diff --git a/src/main/java/world/bentobox/bentobox/util/IslandInfo.java b/src/main/java/world/bentobox/bentobox/util/IslandInfo.java index 99886efd0..e1b809bc0 100644 --- a/src/main/java/world/bentobox/bentobox/util/IslandInfo.java +++ b/src/main/java/world/bentobox/bentobox/util/IslandInfo.java @@ -28,7 +28,7 @@ public class IslandInfo { /** - * @param plugin + * Get island Info * @param island Island to show info */ public IslandInfo(Island island) { @@ -44,11 +44,11 @@ public class IslandInfo { */ public void showAdminInfo(User user) { user.sendMessage("commands.admin.info.title"); - user.sendMessage("commands.admin.info.island-uuid", "[uuid]", island.getUniqueId()); + user.sendMessage("commands.admin.info.island-uuid", TextVariables.UUID, island.getUniqueId()); if (owner == null) { user.sendMessage("commands.admin.info.unowned"); } else { - user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(owner), "[uuid]", owner.toString()); + user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(owner), TextVariables.UUID, owner.toString()); // Fixes #getLastPlayed() returning 0 when it is the owner's first connection. long lastPlayed = (Bukkit.getOfflinePlayer(owner).getLastPlayed() != 0) ? @@ -75,7 +75,7 @@ public class IslandInfo { user.sendMessage("commands.admin.info.island-coords", "[xz1]", Util.xyz(new Vector(island.getMinX(), 0, island.getMinZ())), "[xz2]", Util.xyz(new Vector(island.getMaxX(), 0, island.getMaxZ()))); user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(island.getProtectionRange())); user.sendMessage("commands.admin.info.max-protection-range", "[range]", String.valueOf(island.getMaxEverProtectionRange())); - user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX(), 0, island.getMaxProtectedZ()))); + user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX() - 1, 0, island.getMaxProtectedZ() - 1))); if (island.isSpawn()) { user.sendMessage("commands.admin.info.is-spawn"); } @@ -99,7 +99,7 @@ public class IslandInfo { if (owner == null) { user.sendMessage("commands.admin.info.unowned"); } else { - user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(owner)); + user.sendMessage("commands.admin.info.owner", "[owner]", plugin.getPlayers().getName(owner), TextVariables.UUID, owner.toString()); user.sendMessage("commands.admin.info.deaths", "[number]", String.valueOf(plugin.getPlayers().getDeaths(world, owner))); String resets = String.valueOf(plugin.getPlayers().getResets(world, owner)); String total = plugin.getIWM().getResetLimit(world) < 0 ? "Unlimited" : String.valueOf(plugin.getIWM().getResetLimit(world)); @@ -110,7 +110,7 @@ public class IslandInfo { Vector location = island.getProtectionCenter().toVector(); user.sendMessage("commands.admin.info.island-center", TextVariables.XYZ, Util.xyz(location)); user.sendMessage("commands.admin.info.protection-range", "[range]", String.valueOf(island.getProtectionRange())); - user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX(), 0, island.getMaxProtectedZ()))); + user.sendMessage("commands.admin.info.protection-coords", "[xz1]", Util.xyz(new Vector(island.getMinProtectedX(), 0, island.getMinProtectedZ())), "[xz2]", Util.xyz(new Vector(island.getMaxProtectedX() - 1, 0, island.getMaxProtectedZ() - 1))); if (island.isSpawn()) { user.sendMessage("commands.admin.info.is-spawn"); } diff --git a/src/main/java/world/bentobox/bentobox/util/MyBiomeGrid.java b/src/main/java/world/bentobox/bentobox/util/MyBiomeGrid.java index 848b4088d..56d17a8ce 100644 --- a/src/main/java/world/bentobox/bentobox/util/MyBiomeGrid.java +++ b/src/main/java/world/bentobox/bentobox/util/MyBiomeGrid.java @@ -7,6 +7,7 @@ import org.bukkit.World.Environment; import org.bukkit.block.Biome; import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.NonNull; /** * A biome grid for generators @@ -37,19 +38,19 @@ public class MyBiomeGrid implements BiomeGrid { } @Override - public Biome getBiome(int x, int z) { + public @NonNull Biome getBiome(int x, int z) { return map.getOrDefault(new Vector(x,0,z), defaultBiome); } @Override - public void setBiome(int x, int z, Biome bio) { + public void setBiome(int x, int z, @NonNull Biome bio) { map.put(new Vector(x,0,z), bio); } @Override - public Biome getBiome(int x, int y, int z) { + public @NonNull Biome getBiome(int x, int y, int z) { return map.getOrDefault(new Vector(x,y,z), defaultBiome); } @Override - public void setBiome(int x, int y, int z, Biome bio) { + public void setBiome(int x, int y, int z, @NonNull Biome bio) { map.put(new Vector(x, y, z), bio); } diff --git a/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java b/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java index 9879cb469..fedad9a52 100644 --- a/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java +++ b/src/main/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleport.java @@ -49,6 +49,7 @@ public class SafeSpotTeleport { private final BentoBox plugin; private List> chunksToScan; private final Runnable runnable; + private final Runnable failRunnable; private final CompletableFuture result; private final String homeName; private final int maxHeight; @@ -65,6 +66,7 @@ public class SafeSpotTeleport { this.homeNumber = builder.getHomeNumber(); this.homeName = builder.getHomeName(); this.runnable = builder.getRunnable(); + this.failRunnable = builder.getFailRunnable(); this.result = builder.getResult(); this.maxHeight = location.getWorld().getMaxHeight() - 20; // Try to go @@ -151,9 +153,15 @@ public class SafeSpotTeleport { makeAndTelport(Material.COBBLESTONE); } } + if (failRunnable != null) { + Bukkit.getScheduler().runTask(plugin, failRunnable); + } result.complete(false); }); } else { + if (failRunnable != null) { + Bukkit.getScheduler().runTask(plugin, failRunnable); + } result.complete(false); } } @@ -300,6 +308,7 @@ public class SafeSpotTeleport { private String failureMessage = ""; private Location location; private Runnable runnable; + private Runnable failRunnable; private final CompletableFuture result = new CompletableFuture<>(); public Builder(BentoBox plugin) { @@ -423,6 +432,16 @@ public class SafeSpotTeleport { return this; } + /** + * The task to run if the player is not safely teleported + * @param runnable - task + * @return Builder + * @since 1.18.0 + */ + public Builder ifFail(Runnable rannable) { + this.failRunnable = runnable; + return this; + } /** * @return the plugin */ @@ -487,6 +506,13 @@ public class SafeSpotTeleport { return result; } + /** + * @return the failRunnable + */ + public Runnable getFailRunnable() { + return failRunnable; + } + } } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommandTest.java index c2bbb65db..eafab8ab5 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommandTest.java @@ -2,7 +2,10 @@ package world.bentobox.bentobox.api.commands.admin; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; @@ -101,15 +104,15 @@ public class AdminDeleteCommandTest { // Player has island to begin with im = mock(IslandsManager.class); - when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true); - when(im.hasIsland(Mockito.any(), Mockito.any(User.class))).thenReturn(true); - when(im.isOwner(Mockito.any(),Mockito.any())).thenReturn(true); - when(im.getOwner(Mockito.any(),Mockito.any())).thenReturn(uuid); + when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); + when(im.hasIsland(any(), any(User.class))).thenReturn(true); + when(im.isOwner(any(),any())).thenReturn(true); + when(im.getOwner(any(),any())).thenReturn(uuid); when(plugin.getIslands()).thenReturn(im); // Has team pm = mock(PlayersManager.class); - when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(true); + when(im.inTeam(any(), eq(uuid))).thenReturn(true); when(plugin.getPlayers()).thenReturn(pm); @@ -118,11 +121,11 @@ public class AdminDeleteCommandTest { PowerMockito.mockStatic(Bukkit.class); when(Bukkit.getScheduler()).thenReturn(sch); BukkitTask task = mock(BukkitTask.class); - when(sch.runTaskLater(Mockito.any(), Mockito.any(Runnable.class), Mockito.any(Long.class))).thenReturn(task); + when(sch.runTaskLater(any(), any(Runnable.class), any(Long.class))).thenReturn(task); // Locales LocalesManager lm = mock(LocalesManager.class); - when(lm.get(Mockito.any(), Mockito.any())).thenReturn("mock translation"); + when(lm.get(any(), any())).thenReturn("mock translation"); when(plugin.getLocalesManager()).thenReturn(lm); } @@ -149,9 +152,9 @@ public class AdminDeleteCommandTest { public void testExecuteUnknownPlayer() { AdminDeleteCommand itl = new AdminDeleteCommand(ac); String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(null); + when(pm.getUUID(any())).thenReturn(null); assertFalse(itl.canExecute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("general.errors.unknown-player", "[name]", name[0]); + verify(user).sendMessage("general.errors.unknown-player", "[name]", name[0]); } /** @@ -161,10 +164,10 @@ public class AdminDeleteCommandTest { public void testExecutePlayerNoIsland() { AdminDeleteCommand itl = new AdminDeleteCommand(ac); String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(notUUID); - when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(false); + when(pm.getUUID(any())).thenReturn(notUUID); + when(im.getOwner(any(), any())).thenReturn(null); assertFalse(itl.canExecute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage(Mockito.eq("general.errors.player-has-no-island")); + verify(user).sendMessage(eq("general.errors.player-has-no-island")); } /** @@ -172,13 +175,13 @@ public class AdminDeleteCommandTest { */ @Test public void testExecuteOwner() { - when(im.inTeam(Mockito.any(),Mockito.any())).thenReturn(true); - when(im.getOwner(Mockito.any(), Mockito.any())).thenReturn(notUUID); + when(im.inTeam(any(),any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(notUUID); String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(notUUID); + when(pm.getUUID(any())).thenReturn(notUUID); AdminDeleteCommand itl = new AdminDeleteCommand(ac); assertFalse(itl.canExecute(user, itl.getLabel(), Arrays.asList(name))); - Mockito.verify(user).sendMessage("commands.admin.delete.cannot-delete-owner"); + verify(user).sendMessage("commands.admin.delete.cannot-delete-owner"); } /** @@ -186,15 +189,15 @@ public class AdminDeleteCommandTest { */ @Test public void testcanExecuteSuccessUUID() { - when(im.inTeam(Mockito.any(), Mockito.any())).thenReturn(false); - when(im.getOwner(Mockito.any(), Mockito.any())).thenReturn(uuid); + when(im.inTeam(any(), any())).thenReturn(false); + when(im.getOwner(any(), any())).thenReturn(uuid); Island is = mock(Island.class); Location loc = mock(Location.class); when(loc.toVector()).thenReturn(new Vector(123,123,432)); when(is.getCenter()).thenReturn(loc); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(is); + when(im.getIsland(any(), any(UUID.class))).thenReturn(is); // No such name - when(pm.getUUID(Mockito.any())).thenReturn(null); + when(pm.getUUID(any())).thenReturn(null); AdminDeleteCommand itl = new AdminDeleteCommand(ac); // Success because it's a valid UUID @@ -205,15 +208,15 @@ public class AdminDeleteCommandTest { */ @Test public void testExecuteFailUUID() { - when(im.inTeam(Mockito.any(), Mockito.any())).thenReturn(false); - when(im.getOwner(Mockito.any(), Mockito.any())).thenReturn(uuid); + when(im.inTeam(any(), any())).thenReturn(false); + when(im.getOwner(any(), any())).thenReturn(uuid); Island is = mock(Island.class); Location loc = mock(Location.class); when(loc.toVector()).thenReturn(new Vector(123,123,432)); when(is.getCenter()).thenReturn(loc); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(is); + when(im.getIsland(any(), any(UUID.class))).thenReturn(is); // No such name - when(pm.getUUID(Mockito.any())).thenReturn(null); + when(pm.getUUID(any())).thenReturn(null); AdminDeleteCommand itl = new AdminDeleteCommand(ac); // Fail because it's not a UUID @@ -225,21 +228,21 @@ public class AdminDeleteCommandTest { */ @Test public void testCanExecuteSuccess() { - when(im.inTeam(Mockito.any(), Mockito.any())).thenReturn(false); - when(im.getOwner(Mockito.any(), Mockito.any())).thenReturn(uuid); + when(im.inTeam(any(), any())).thenReturn(false); + when(im.getOwner(any(), any())).thenReturn(uuid); Island is = mock(Island.class); Location loc = mock(Location.class); when(loc.toVector()).thenReturn(new Vector(123,123,432)); when(is.getCenter()).thenReturn(loc); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(is); + when(im.getIsland(any(), any(UUID.class))).thenReturn(is); String[] name = {"tastybento"}; - when(pm.getUUID(Mockito.any())).thenReturn(notUUID); + when(pm.getUUID(any())).thenReturn(notUUID); AdminDeleteCommand itl = new AdminDeleteCommand(ac); assertTrue(itl.canExecute(user, itl.getLabel(), Arrays.asList(name))); // Confirm itl.execute(user, itl.getLabel(), Arrays.asList(name)); - Mockito.verify(user).sendMessage("commands.confirmation.confirm", "[seconds]", "0"); + verify(user).sendMessage("commands.confirmation.confirm", "[seconds]", "0"); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java index 4cf7dad10..6aeb4f8c1 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java @@ -208,7 +208,7 @@ public class AdminInfoCommandTest { verify(user).sendMessage("commands.admin.info.island-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); verify(user).sendMessage("commands.admin.info.max-protection-range", "[range]", "100"); - verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "-1,0,-1"); } /** @@ -230,7 +230,7 @@ public class AdminInfoCommandTest { verify(user).sendMessage("commands.admin.info.island-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); verify(user).sendMessage("commands.admin.info.max-protection-range", "[range]", "100"); - verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "-1,0,-1"); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java index 1457140d2..71960c644 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommandTest.java @@ -164,6 +164,11 @@ public class AdminTeleportCommandTest { // Return an island for spawn checking when(im.getIsland(any(), any(UUID.class))).thenReturn(island); + + when(island.getCenter()).thenReturn(location); + when(location.clone()).thenReturn(location); + when(location.toVector()).thenReturn(new Vector(0,0,0)); + when(island.getProtectionCenter()).thenReturn(location); // Util PowerMockito.mockStatic(Util.class, Mockito.RETURNS_MOCKS); when(Util.getUUID(anyString())).thenCallRealMethod(); diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java index 15d1ff897..66fe237f3 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java @@ -231,9 +231,6 @@ public class AdminUnregisterCommandTest { verify(im).removePlayer(any(), eq(uuid1)); verify(im).removePlayer(any(), eq(uuid2)); verify(im).removePlayer(any(), eq(uuid3)); - verify(pm).clearHomeLocations(any(), eq(uuid1)); - verify(pm).clearHomeLocations(any(), eq(uuid2)); - verify(pm).clearHomeLocations(any(), eq(uuid3)); verify(im, never()).removePlayer(any(), eq(uuid4)); } } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamDisbandCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamDisbandCommandTest.java index 8efaa603a..d0da960d7 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamDisbandCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamDisbandCommandTest.java @@ -235,7 +235,7 @@ public class AdminTeamDisbandCommandTest { verify(user).sendMessage("commands.admin.team.disband.success", TextVariables.NAME, name[0]); verify(p).sendMessage("commands.admin.team.disband.disbanded"); verify(p2).sendMessage("commands.admin.team.disband.disbanded"); - // 2 * 2 + 1 - verify(pim, times(5)).callEvent(any()); + // 2 + 1 + verify(pim, times(3)).callEvent(any()); } } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java index aed70d1c0..b49839e55 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/team/AdminTeamKickCommandTest.java @@ -192,7 +192,6 @@ public class AdminTeamKickCommandTest { verify(user).sendMessage(eq("commands.admin.team.kick.cannot-kick-owner")); verify(user).sendMessage("commands.admin.info.team-members-title"); verify(im, never()).removePlayer(eq(world), eq(notUUID)); - verify(pm, never()).clearHomeLocations(eq(world), eq(notUUID)); verify(user, never()).sendMessage(eq("commands.admin.team.kick.success"), anyString(), anyString(), anyString(), anyString()); verify(pim, never()).callEvent(any()); } @@ -215,10 +214,9 @@ public class AdminTeamKickCommandTest { assertTrue(itl.canExecute(user, itl.getLabel(), Collections.singletonList(name))); assertTrue(itl.execute(user, itl.getLabel(), Collections.singletonList(name))); verify(im).removePlayer(eq(world), eq(notUUID)); - verify(pm).clearHomeLocations(eq(world), eq(notUUID)); verify(user).sendMessage(eq("commands.admin.team.kick.success"), eq(TextVariables.NAME), eq(name), eq("[owner]"), anyString()); - // Offline so event will be called six time - verify(pim, times(6)).callEvent(any()); + // Offline so event will be called 4 times + verify(pim, times(4)).callEvent(any()); } } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java index db650ebb5..893df02bc 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java @@ -196,14 +196,14 @@ public class IslandInfoCommandTest { public void testExecuteUserStringListOfStringNoArgsSuccess() { assertTrue(iic.execute(user, "", Collections.emptyList())); verify(user).sendMessage("commands.admin.info.title"); - verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null)); + verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null), eq("[uuid]"), anyString()); verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); verify(user).sendMessage("commands.admin.info.team-members-title"); verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); - verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "-1,0,-1"); } /** @@ -213,14 +213,14 @@ public class IslandInfoCommandTest { public void testExecuteUserStringListOfStringArgsSuccess() { assertTrue(iic.execute(user, "", Collections.singletonList("tastybento"))); verify(user).sendMessage("commands.admin.info.title"); - verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null)); + verify(user).sendMessage(eq("commands.admin.info.owner"), eq("[owner]"), eq(null), eq("[uuid]"), anyString()); verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); verify(user).sendMessage("commands.admin.info.team-members-title"); verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); - verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "0,0,0"); + verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "0,0,0", "[xz2]", "-1,0,-1"); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java index 5a7da91cc..29dd09124 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java @@ -257,8 +257,8 @@ public class IslandResetCommandTest { assertTrue(irc.execute(user, irc.getLabel(), Collections.emptyList())); // TODO Verify that panel was shown // verify(bpm).showPanel(any(), eq(user), eq(irc.getLabel())); - // Verify event (13 * 2 + 1) - verify(pim, times(27)).callEvent(any(IslandBaseEvent.class)); + // Verify event (13 * 2) + verify(pim, times(14)).callEvent(any(IslandBaseEvent.class)); // Verify messaging verify(user).sendMessage("commands.island.create.creating-island"); verify(user, never()).sendMessage(eq("commands.island.reset.kicked-from-island"), eq(TextVariables.GAMEMODE), anyString()); @@ -446,8 +446,8 @@ public class IslandResetCommandTest { // Reset command, no confirmation required assertTrue(irc.execute(user, irc.getLabel(), Collections.singletonList("custom"))); verify(user).sendMessage("commands.island.create.creating-island"); - // Verify event (13 * 2 + 1) - verify(pim, times(27)).callEvent(any(IslandBaseEvent.class)); + // Verify event (13 * 2) + verify(pim, times(14)).callEvent(any(IslandBaseEvent.class)); } } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommandTest.java index ad9062fbe..41cdc0e3b 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommandTest.java @@ -62,6 +62,8 @@ public class IslandSethomeCommandTest { private Island island; @Mock private IslandWorldManager iwm; + @Mock + private WorldSettings ws; /** * @throws java.lang.Exception @@ -128,6 +130,8 @@ public class IslandSethomeCommandTest { // Number of homes default when(iwm.getMaxHomes(any())).thenReturn(3); when(plugin.getIWM()).thenReturn(iwm); + // World settings + when(iwm.getWorldSettings(any(World.class))).thenReturn(ws); // Number of homes PowerMockito.mockStatic(Util.class); @@ -223,7 +227,7 @@ public class IslandSethomeCommandTest { */ @Test public void testExecuteUserStringListOfStringMultiHomeTooMany() { - when(island.getMaxHomes()).thenReturn(3); + when(im.getMaxHomes(island)).thenReturn(3); when(im.getNumberOfHomesIfAdded(eq(island), anyString())).thenReturn(4); IslandSethomeCommand isc = new IslandSethomeCommand(ic); assertFalse(isc.canExecute(user, "island", Collections.singletonList("13"))); diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java index 0d24ad434..bc439fe80 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java @@ -6,7 +6,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -248,39 +247,12 @@ public class IslandUnbanCommandTest { // Allow removing from ban list when(island.unban(any(), any())).thenReturn(true); - + assertTrue(iubc.canExecute(user, iubc.getLabel(), Collections.singletonList("bill"))); assertTrue(iubc.execute(user, iubc.getLabel(), Collections.singletonList("bill"))); verify(user).sendMessage("commands.island.unban.player-unbanned", TextVariables.NAME, targetUser.getName()); verify(targetUser).sendMessage("commands.island.unban.you-are-unbanned", TextVariables.NAME, user.getName()); } - /** - * Test method for {@link IslandUnbanCommand#execute(User, String, List)} - */ - @Test - public void testCancelledUnban() { - IslandUnbanCommand iubc = new IslandUnbanCommand(ic); - when(im.hasIsland(any(), eq(uuid))).thenReturn(true); - when(im.isOwner(any(), eq(uuid))).thenReturn(true); - UUID targetUUID = UUID.randomUUID(); - when(pm.getUUID(Mockito.anyString())).thenReturn(targetUUID); - PowerMockito.mockStatic(User.class); - User targetUser = mock(User.class); - when(targetUser.isOp()).thenReturn(false); - when(targetUser.isPlayer()).thenReturn(true); - when(targetUser.isOnline()).thenReturn(false); - when(User.getInstance(any(UUID.class))).thenReturn(targetUser); - // Mark as banned - when(island.isBanned(eq(targetUUID))).thenReturn(true); - - // Allow removing from ban list - when(island.unban(any(), any())).thenReturn(false); - - assertFalse(iubc.execute(user, iubc.getLabel(), Collections.singletonList("bill"))); - verify(user, never()).sendMessage("commands.island.unban.player-unbanned", TextVariables.NAME, targetUser.getName()); - verify(targetUser, never()).sendMessage("commands.island.unban.you-are-unbanned", "[owner]", user.getName()); - } - /** * Test method for {@link IslandUnbanCommand#tabComplete(User, String, List)} */ diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java index f32814177..acd8c421c 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java @@ -10,7 +10,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.times; import java.util.Collections; import java.util.HashMap; @@ -223,7 +222,7 @@ public class IslandTeamInviteAcceptCommandTest { assertTrue(c.canExecute(user, "accept", Collections.emptyList())); verify(user, never()).sendMessage("commands.island.team.invite.errors.you-already-are-in-team"); verify(user, never()).sendMessage("commands.island.team.invite.errors.invalid-invite"); - verify(pim, times(2)).callEvent(any()); + verify(pim).callEvent(any()); } /** @@ -250,7 +249,7 @@ public class IslandTeamInviteAcceptCommandTest { assertTrue(c.canExecute(user, "accept", Collections.emptyList())); verify(user, never()).sendMessage("commands.island.team.invite.errors.you-already-are-in-team"); verify(user, never()).sendMessage("commands.island.team.invite.errors.invalid-invite"); - verify(pim, times(2)).callEvent(any()); + verify(pim).callEvent(any()); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java index 5e389fd4d..e935341a7 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java @@ -10,7 +10,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.times; import java.util.Collections; import java.util.HashMap; @@ -296,7 +295,7 @@ public class IslandTeamInviteCommandTest { when(im.hasIsland(any(), eq(notUUID))).thenReturn(true); testCanExecuteSuccess(); assertTrue(itl.execute(user, itl.getLabel(), Collections.singletonList("target"))); - verify(pim, times(2)).callEvent(any(IslandBaseEvent.class)); + verify(pim).callEvent(any(IslandBaseEvent.class)); verify(user, never()).sendMessage(eq("commands.island.team.invite.removing-invite")); verify(ic).addInvite(eq(Invite.Type.TEAM), eq(uuid), eq(notUUID)); verify(user).sendMessage(eq("commands.island.team.invite.invitation-sent"), eq(TextVariables.NAME), eq("target")); @@ -313,7 +312,7 @@ public class IslandTeamInviteCommandTest { public void testExecuteSuccessTargetHasNoIsland() { testCanExecuteSuccess(); assertTrue(itl.execute(user, itl.getLabel(), Collections.singletonList("target"))); - verify(pim, times(2)).callEvent(any(IslandBaseEvent.class)); + verify(pim).callEvent(any(IslandBaseEvent.class)); verify(user, never()).sendMessage(eq("commands.island.team.invite.removing-invite")); verify(ic).addInvite(eq(Invite.Type.TEAM), eq(uuid), eq(notUUID)); verify(user).sendMessage(eq("commands.island.team.invite.invitation-sent"), eq(TextVariables.NAME), eq("target")); @@ -337,7 +336,7 @@ public class IslandTeamInviteCommandTest { when(invite.getType()).thenReturn(Type.TEAM); when(ic.getInvite(eq(notUUID))).thenReturn(invite); assertTrue(itl.execute(user, itl.getLabel(), Collections.singletonList("target"))); - verify(pim, times(2)).callEvent(any(IslandBaseEvent.class)); + verify(pim).callEvent(any(IslandBaseEvent.class)); verify(ic).removeInvite(eq(notUUID)); verify(user).sendMessage(eq("commands.island.team.invite.removing-invite")); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java new file mode 100644 index 000000000..c0b16321b --- /dev/null +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java @@ -0,0 +1,279 @@ +package world.bentobox.bentobox.api.commands.island.team; + +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Optional; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.scheduler.BukkitScheduler; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.Settings; +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.localization.TextVariables; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.CommandsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.IslandsManager; +import world.bentobox.bentobox.managers.PlayersManager; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) +public class IslandTeamSetownerCommandTest { + + @Mock + private CompositeCommand ic; + private UUID uuid; + @Mock + private User user; + @Mock + private Settings s; + @Mock + private IslandsManager im; + @Mock + private IslandWorldManager iwm; + @Mock + private Player player; + @Mock + private CompositeCommand subCommand; + @Mock + private PlayersManager pm; + @Mock + private World world; + private IslandTeamSetownerCommand its; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // Set up plugin + BentoBox plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + + // Command manager + CommandsManager cm = mock(CommandsManager.class); + when(plugin.getCommandsManager()).thenReturn(cm); + + // Settings + when(s.getResetCooldown()).thenReturn(0); + when(plugin.getSettings()).thenReturn(s); + + // Player + // Sometimes use Mockito.withSettings().verboseLogging() + when(user.isOp()).thenReturn(false); + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getPlayer()).thenReturn(player); + when(user.getName()).thenReturn("tastybento"); + + // Parent command has no aliases + ic = mock(CompositeCommand.class); + when(ic.getSubCommandAliases()).thenReturn(new HashMap<>()); + Optional optionalCommand = Optional.of(subCommand); + when(ic.getSubCommand(Mockito.anyString())).thenReturn(optionalCommand); + when(ic.getWorld()).thenReturn(world); + + // Player has island to begin with + when(im.hasIsland(any(), Mockito.any(UUID.class))).thenReturn(true); + when(im.isOwner(any(), any())).thenReturn(true); + when(plugin.getIslands()).thenReturn(im); + + // Has team + when(im.inTeam(any(), eq(uuid))).thenReturn(true); + when(plugin.getPlayers()).thenReturn(pm); + + // Server & Scheduler + BukkitScheduler sch = mock(BukkitScheduler.class); + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getScheduler()).thenReturn(sch); + + // Island World Manager + when(plugin.getIWM()).thenReturn(iwm); + + // Plugin Manager + PluginManager pim = mock(PluginManager.class); + when(Bukkit.getPluginManager()).thenReturn(pim); + + // Island + Island island = mock(Island.class); + when(island.getUniqueId()).thenReturn("uniqueid"); + when(im.getIsland(any(), Mockito.any(User.class))).thenReturn(island); + + // Class under test + its = new IslandTeamSetownerCommand(ic); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("island.team.setowner", its.getPermission()); + assertTrue(its.isOnlyPlayer()); + assertEquals("commands.island.team.setowner.parameters", its.getParameters()); + assertEquals("commands.island.team.setowner.description", its.getDescription()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNullOwner() { + when(im.getOwner(any(), any())).thenReturn(null); + assertFalse(its.execute(user, "", Collections.emptyList())); + verify(user).sendMessage("general.errors.not-owner"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNotInTeam() { + when(im.inTeam(any(), any())).thenReturn(false); + assertFalse(its.execute(user, "", Collections.emptyList())); + verify(user).sendMessage("general.errors.no-team"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringNotOwner() { + when(im.inTeam(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(UUID.randomUUID()); + assertFalse(its.execute(user, "", Collections.emptyList())); + verify(user).sendMessage("general.errors.not-owner"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringShowHelp() { + when(im.inTeam(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(uuid); + assertFalse(its.execute(user, "", Collections.emptyList())); + verify(user).sendMessage("commands.help.header","[label]", null); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringUnknownPlayer() { + when(im.inTeam(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(uuid); + when(pm.getUUID(anyString())).thenReturn(null); + assertFalse(its.execute(user, "", Collections.singletonList("tastybento"))); + verify(user).sendMessage("general.errors.unknown-player", TextVariables.NAME, "tastybento"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringSamePlayer() { + when(im.inTeam(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(uuid); + when(pm.getUUID(anyString())).thenReturn(uuid); + assertFalse(its.execute(user, "", Collections.singletonList("tastybento"))); + verify(user).sendMessage("commands.island.team.setowner.errors.cant-transfer-to-yourself"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringTargetNotInTeam() { + when(im.inTeam(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(uuid); + when(pm.getUUID(anyString())).thenReturn(UUID.randomUUID()); + when(im.getMembers(any(), any())).thenReturn(Collections.singleton(uuid)); + assertFalse(its.execute(user, "", Collections.singletonList("tastybento"))); + verify(user).sendMessage("commands.island.team.setowner.errors.target-is-not-member"); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringSuccess() { + when(im.inTeam(any(), any())).thenReturn(true); + when(im.getOwner(any(), any())).thenReturn(uuid); + UUID target = UUID.randomUUID(); + when(pm.getUUID(anyString())).thenReturn(target); + when(im.getMembers(any(), any())).thenReturn(Collections.singleton(target)); + @Nullable + Island island = mock(Island.class); + when(im.getIsland(any(), any(User.class))).thenReturn(island); + + assertTrue(its.execute(user, "", Collections.singletonList("tastybento"))); + verify(im).setOwner(any(), eq(user), eq(target)); + verify(im).save(island); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfString() { + assertTrue(its.tabComplete(user, "", Collections.emptyList()).get().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfStringUnknown() { + assertTrue(its.tabComplete(user, "ta", Collections.emptyList()).get().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamSetownerCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testTabCompleteUserStringListOfStringMember() { + UUID target = UUID.randomUUID(); + when(pm.getName(any())).thenReturn("tastybento"); + when(im.getMembers(any(), any())).thenReturn(Collections.singleton(target)); + assertEquals("tastybento", its.tabComplete(user, "", Collections.emptyList()).get().get(0)); + } + +} diff --git a/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java b/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java index 13ae82e9c..d5add7b9e 100644 --- a/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java +++ b/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java @@ -168,7 +168,7 @@ public class IslandEventTest { } } - verify(pim, Mockito.times(Reason.values().length * 3)).callEvent(any()); + verify(pim, Mockito.times(Reason.values().length * 2)).callEvent(any()); } } diff --git a/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java b/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java index ef8db233c..a25c7d88c 100644 --- a/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java +++ b/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java @@ -86,7 +86,7 @@ public class FlagTest { GameModeAddon gma = mock(GameModeAddon.class); Optional opGma = Optional.of(gma ); when(iwm.getAddon(any())).thenReturn(opGma); - + when(iwm.inWorld(any(World.class))).thenReturn(true); worldFlags = new HashMap<>(); when(ws.getWorldFlags()).thenReturn(worldFlags); @@ -223,7 +223,7 @@ public class FlagTest { */ @Test public void testSetDefaultSettingWorldBooleanNullWorldSettings() { - when(iwm.getWorldSettings(any())).thenReturn(null); + when(iwm.inWorld(any(World.class))).thenReturn(false); f.setDefaultSetting(world, true); verify(plugin).logError("Attempt to set default world setting for unregistered world. Register flags in onEnable."); } diff --git a/src/test/java/world/bentobox/bentobox/api/user/UserTest.java b/src/test/java/world/bentobox/bentobox/api/user/UserTest.java index 16436000d..d8427d24e 100644 --- a/src/test/java/world/bentobox/bentobox/api/user/UserTest.java +++ b/src/test/java/world/bentobox/bentobox/api/user/UserTest.java @@ -4,7 +4,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -64,7 +63,8 @@ import world.bentobox.bentobox.managers.PlayersManager; @PrepareForTest({ BentoBox.class, Bukkit.class }) public class UserTest { - private static final String TEST_TRANSLATION = "mock translation [test]"; + private static final String TEST_TRANSLATION = "mock &a translation &b [test]"; + private static final String TEST_TRANSLATION_WITH_COLOR = "mock §atranslation §b[test]"; @Mock private Player player; @Mock @@ -164,7 +164,6 @@ public class UserTest { // If the player has been removed from the cache, then code will ask server for player // Return null and check if instance is null will show that the player is not in the cache when(Bukkit.getPlayer(any(UUID.class))).thenReturn(null); - assertNull(User.getInstance(uuid).getPlayer()); verify(pm).removePlayer(player); } @@ -245,7 +244,7 @@ public class UserTest { @Test public void testHasPermission() { - // default behaviours + // default behaviors assertTrue(user.hasPermission("")); assertTrue(user.hasPermission(null)); @@ -278,12 +277,20 @@ public class UserTest { @Test public void testGetTranslation() { - assertEquals("mock translation [test]", user.getTranslation("a.reference")); + assertEquals(TEST_TRANSLATION_WITH_COLOR, user.getTranslation("a.reference")); + } + + /** + * Test for {@link User#getTranslationNoColor(String, String...)} + */ + @Test + public void testGetTranslationNoColor() { + assertEquals(TEST_TRANSLATION, user.getTranslationNoColor("a.reference")); } @Test public void testGetTranslationWithVariable() { - assertEquals("mock translation variable", user.getTranslation("a.reference", "[test]", "variable")); + assertEquals("mock §atranslation §bvariable", user.getTranslation("a.reference", "[test]", "variable")); } @Test @@ -308,7 +315,7 @@ public class UserTest { @Test public void testSendMessage() { user.sendMessage("a.reference"); - verify(player).sendMessage(eq(TEST_TRANSLATION)); + verify(player).sendMessage(TEST_TRANSLATION_WITH_COLOR); } @Test @@ -476,12 +483,6 @@ public class UserTest { assertTrue(user1.hashCode() == user2.hashCode()); } - @Test - public void testNullPlayer() { - User user = User.getInstance((Player)null); - assertNull(user); - } - /** * Test for {@link User#getPermissionValue(String, int)} */ diff --git a/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java b/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java new file mode 100644 index 000000000..edb9830e2 --- /dev/null +++ b/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java @@ -0,0 +1,1253 @@ +/** + * + */ +package world.bentobox.bentobox.database.objects; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Block; +import org.eclipse.jdt.annotation.NonNull; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.flags.Flag; +import world.bentobox.bentobox.api.flags.Flag.Type; +import world.bentobox.bentobox.api.logs.LogEntry; +import world.bentobox.bentobox.api.metadata.MetaDataValue; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.FlagsManager; +import world.bentobox.bentobox.managers.IslandWorldManager; +import world.bentobox.bentobox.managers.RanksManager; +import world.bentobox.bentobox.util.Pair; + +/** + * @author tastybento + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({Bukkit.class}) +public class IslandTest { + + private final UUID uuid = UUID.randomUUID(); + private final UUID m = UUID.randomUUID(); + private Island i; + @Mock + private @NonNull Location location; + @Mock + private BentoBox plugin; + @Mock + private IslandWorldManager iwm; + @Mock + private World world; + @Mock + private User user; + + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + // Set up plugin + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + + // Max range + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getIslandDistance(any())).thenReturn(400); + + // Location + //when(location.getWorld()).thenReturn(world); + when(location.clone()).thenReturn(location); + when(world.getName()).thenReturn("bskyblock_world"); + + // User + when(user.getUniqueId()).thenReturn(uuid); + + // Bukkit + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); + when(Bukkit.getOnlinePlayers()).thenReturn(Collections.emptyList()); + + FlagsManager fm = new FlagsManager(plugin); + // Flags + when(plugin.getFlagsManager()).thenReturn(fm); + + i = new Island(new Island(location, uuid , 100)); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception { + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#Island(org.bukkit.Location, java.util.UUID, int)}. + */ + @Test + public void testIslandLocationUUIDInt() { + assertEquals("Location{world=null,x=0.0,y=0.0,z=0.0,pitch=0.0,yaw=0.0}", i.getCenter().toString()); + assertEquals(uuid, i.getOwner()); + assertEquals(400, i.getRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#Island(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testIslandIsland() { + assertEquals("Location{world=null,x=0.0,y=0.0,z=0.0,pitch=0.0,yaw=0.0}", i.getCenter().toString()); + assertEquals(uuid, i.getOwner()); + assertEquals(400, i.getRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#addMember(java.util.UUID)}. + */ + @Test + public void testAddMember() { + i.addMember(m); + assertTrue(i.getMemberSet().contains(m)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#ban(java.util.UUID, java.util.UUID)}. + */ + @Test + public void testBan() { + i.ban(uuid, m); + assertTrue(i.isBanned(m)); + assertFalse(i.isBanned(uuid)); + assertFalse(i.isBanned(UUID.randomUUID())); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getBanned()}. + */ + @Test + public void testGetBanned() { + assertTrue(i.getBanned().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#unban(java.util.UUID, java.util.UUID)}. + */ + @Test + public void testUnban() { + i.ban(uuid, m); + assertTrue(i.isBanned(m)); + i.unban(uuid, m); + assertFalse(i.isBanned(m)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getCenter()}. + */ + @Test + public void testGetCenter() { + assertEquals("Location{world=null,x=0.0,y=0.0,z=0.0,pitch=0.0,yaw=0.0}", i.getCenter().toString()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getCreatedDate()}. + */ + @Test + public void testGetCreatedDate() { + assertTrue(i.getCreatedDate() > 0); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getFlag(world.bentobox.bentobox.api.flags.Flag)}. + */ + @Test + public void testGetFlag() { + assertEquals(500, i.getFlag(Flags.BREAK_BLOCKS)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getFlags()}. + */ + @Test + public void testGetFlags() { + assertTrue(i.getFlags().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMembers()}. + */ + @Test + public void testGetMembers() { + assertEquals(1, i.getMembers().size()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMemberSet()}. + */ + @Test + public void testGetMemberSet() { + assertEquals(1, i.getMembers().size()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMemberSet(int)}. + */ + @Test + public void testGetMemberSetInt() { + assertFalse(i.getMemberSet(500).isEmpty()); + assertEquals(1, i.getMemberSet(500).size()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMemberSet(int, boolean)}. + */ + @Test + public void testGetMemberSetIntBoolean() { + assertFalse(i.getMemberSet(500, true).isEmpty()); + assertTrue(i.getMemberSet(500, false).isEmpty()); + assertFalse(i.getMemberSet(1000, true).isEmpty()); + assertFalse(i.getMemberSet(1000, false).isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMinProtectedX()}. + */ + @Test + public void testGetMinProtectedX() { + assertEquals(-100, i.getMinProtectedX()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxProtectedX()}. + */ + @Test + public void testGetMaxProtectedX() { + assertEquals(100, i.getMaxProtectedX()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMinProtectedZ()}. + */ + @Test + public void testGetMinProtectedZ() { + assertEquals(-100, i.getMinProtectedZ()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxProtectedZ()}. + */ + @Test + public void testGetMaxProtectedZ() { + assertEquals(100, i.getMaxProtectedZ()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMinX()}. + */ + @Test + public void testGetMinX() { + assertEquals(-400, i.getMinX()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxX()}. + */ + @Test + public void testGetMaxX() { + assertEquals(400, i.getMaxX()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMinZ()}. + */ + @Test + public void testGetMinZ() { + assertEquals(-400, i.getMinZ()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxZ()}. + */ + @Test + public void testGetMaxZ() { + assertEquals(400, i.getMaxZ()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getName()}. + */ + @Test + public void testGetName() { + assertNull(i.getName()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getOwner()}. + */ + @Test + public void testGetOwner() { + assertEquals(uuid, i.getOwner()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isOwned()}. + */ + @Test + public void testIsOwned() { + assertTrue(i.isOwned()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isUnowned()}. + */ + @Test + public void testIsUnowned() { + assertFalse(i.isUnowned()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getProtectionRange()}. + */ + @Test + public void testGetProtectionRange() { + assertEquals(100, i.getProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxEverProtectionRange()}. + */ + @Test + public void testGetMaxEverProtectionRange() { + assertEquals(100, i.getMaxEverProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setMaxEverProtectionRange(int)}. + */ + @Test + public void testSetMaxEverProtectionRange() { + i.setMaxEverProtectionRange(50); + assertEquals(100, i.getMaxEverProtectionRange()); + i.setMaxEverProtectionRange(150); + assertEquals(150, i.getMaxEverProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getPurgeProtected()}. + */ + @Test + public void testGetPurgeProtected() { + assertFalse(i.getPurgeProtected()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getRange()}. + */ + @Test + public void testGetRange() { + assertEquals(400, i.getRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getRank(world.bentobox.bentobox.api.user.User)}. + */ + @Test + public void testGetRankUser() { + assertEquals(RanksManager.OWNER_RANK, i.getRank(user)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getRank(java.util.UUID)}. + */ + @Test + public void testGetRankUUID() { + assertEquals(RanksManager.OWNER_RANK, i.getRank(uuid)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getUniqueId()}. + */ + @Test + public void testGetUniqueId() { + assertFalse(i.getUniqueId().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getUpdatedDate()}. + */ + @Test + public void testGetUpdatedDate() { + assertTrue(i.getUpdatedDate() > 0); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getWorld()}. + */ + @Test + public void testGetWorld() { + assertNull(i.getWorld()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getX()}. + */ + @Test + public void testGetX() { + assertEquals(0, i.getX()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getY()}. + */ + @Test + public void testGetY() { + assertEquals(0, i.getY()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getZ()}. + */ + @Test + public void testGetZ() { + assertEquals(0, i.getZ()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#inIslandSpace(int, int)}. + */ + @Test + public void testInIslandSpaceIntInt() { + assertTrue(i.inIslandSpace(0,0)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#inIslandSpace(org.bukkit.Location)}. + */ + @Test + public void testInIslandSpaceLocation() { + i.setWorld(world); + when(location.getWorld()).thenReturn(world); + assertTrue(i.inIslandSpace(location)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#inIslandSpace(world.bentobox.bentobox.util.Pair)}. + */ + @Test + public void testInIslandSpacePairOfIntegerInteger() { + assertTrue(i.inIslandSpace(new Pair(0,0))); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getBoundingBox()}. + */ + @Test + public void testGetBoundingBox() { + i.setWorld(world); + when(location.getWorld()).thenReturn(world); + assertNotNull(i.getBoundingBox()); + assertEquals("BoundingBox [minX=-400.0, minY=0.0, minZ=-400.0, maxX=400.0, maxY=0.0, maxZ=400.0]", i.getBoundingBox().toString()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getVisitors()}. + */ + @Test + public void testGetVisitors() { + assertTrue(i.getVisitors().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#hasVisitors()}. + */ + @Test + public void testHasVisitors() { + assertFalse(i.hasVisitors()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getPlayersOnIsland()}. + */ + @Test + public void testGetPlayersOnIsland() { + assertTrue(i.getPlayersOnIsland().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#hasPlayersOnIsland()}. + */ + @Test + public void testHasPlayersOnIsland() { + assertFalse(i.hasPlayersOnIsland()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isAllowed(world.bentobox.bentobox.api.flags.Flag)}. + */ + @Test + public void testIsAllowedFlag() { + assertFalse(i.isAllowed(Flags.PVP_OVERWORLD)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isAllowed(world.bentobox.bentobox.api.user.User, world.bentobox.bentobox.api.flags.Flag)}. + */ + @Test + public void testIsAllowedUserFlag() { + assertTrue(i.isAllowed(user, Flags.BREAK_BLOCKS)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isBanned(java.util.UUID)}. + */ + @Test + public void testIsBanned() { + assertFalse(i.isBanned(uuid)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isSpawn()}. + */ + @Test + public void testIsSpawn() { + assertFalse(i.isSpawn()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#onIsland(org.bukkit.Location)}. + */ + @Test + public void testOnIsland() { + i.setWorld(world); + when(location.getWorld()).thenReturn(world); + assertTrue(i.onIsland(location)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getProtectionBoundingBox()}. + */ + @Test + public void testGetProtectionBoundingBox() { + i.setWorld(world); + assertNotNull(i.getProtectionBoundingBox()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#removeMember(java.util.UUID)}. + */ + @Test + public void testRemoveMember() { + i.removeMember(uuid); + assertTrue(i.getMemberSet().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setCenter(org.bukkit.Location)}. + */ + @Test + public void testSetCenter() { + when(location.getWorld()).thenReturn(world); + i.setCenter(location); + assertEquals(location, i.getCenter()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setCreatedDate(long)}. + */ + @Test + public void testSetCreatedDate() { + i.setCreatedDate(123456L); + assertEquals(123456L, i.getCreatedDate()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setFlag(world.bentobox.bentobox.api.flags.Flag, int)}. + */ + @Test + public void testSetFlagFlagInt() { + i.setFlag(Flags.BREAK_BLOCKS, 100); + assertTrue(i.isChanged()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setFlag(world.bentobox.bentobox.api.flags.Flag, int, boolean)}. + */ + @Test + public void testSetFlagFlagIntBoolean() { + Flag f = Flags.values().stream().filter(fl -> fl.hasSubflags()).findFirst().orElse(null); + if (f != null) { + i.setFlag(f, 100, true); + assertTrue(i.isChanged()); + } + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setFlags(java.util.Map)}. + */ + @Test + public void testSetFlags() { + i.setFlags(Collections.emptyMap()); + assertTrue(i.getFlags().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setFlagsDefaults()}. + */ + @Test + public void testSetFlagsDefaults() { + i.setFlagsDefaults(); + assertFalse(i.getFlags().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setMembers(java.util.Map)}. + */ + @Test + public void testSetMembers() { + i.setMembers(Collections.emptyMap()); + assertTrue(i.getMembers().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setName(java.lang.String)}. + */ + @Test + public void testSetName() { + i.setName("hello"); + assertEquals("hello", i.getName()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setOwner(java.util.UUID)}. + */ + @Test + public void testSetOwner() { + UUID owner = UUID.randomUUID(); + i.setOwner(owner); + assertEquals(owner, i.getOwner()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setProtectionRange(int)}. + */ + @Test + public void testSetProtectionRange() { + i.setProtectionRange(0); + assertEquals(0, i.getProtectionRange()); + i.setProtectionRange(50); + assertEquals(50, i.getProtectionRange()); + i.setProtectionRange(100); + assertEquals(100, i.getProtectionRange()); + i.setProtectionRange(1000); + assertEquals(1000, i.getProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#updateMaxEverProtectionRange()}. + */ + @Test + public void testUpdateMaxEverProtectionRange() { + i.setProtectionRange(1000); + assertEquals(1000, i.getMaxEverProtectionRange()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setPurgeProtected(boolean)}. + */ + @Test + public void testSetPurgeProtected() { + i.setPurgeProtected(true); + assertTrue(i.getPurgeProtected()); + i.setPurgeProtected(false); + assertFalse(i.getPurgeProtected()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setRange(int)}. + */ + @Test + public void testSetRange() { + i.setRange(123); + assertEquals(123, i.getRange()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setRank(world.bentobox.bentobox.api.user.User, int)}. + */ + @Test + public void testSetRankUserInt() { + i.setRank(user, 600); + assertEquals(600, i.getRank(user)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setRank(java.util.UUID, int)}. + */ + @Test + public void testSetRankUUIDInt() { + i.setRank(uuid, 603); + assertEquals(603, i.getRank(uuid)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setRanks(java.util.Map)}. + */ + @Test + public void testSetRanks() { + UUID u = UUID.randomUUID(); + i.setRanks(Collections.singletonMap(u, 123)); + assertEquals(123, i.getRank(u)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setSpawn(boolean)}. + */ + @Test + public void testSetSpawn() { + assertFalse(i.isSpawn()); + i.setSpawn(true); + assertTrue(i.isSpawn()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getSpawnPoint()}. + */ + @Test + public void testGetSpawnPoint() { + assertTrue(i.getSpawnPoint().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setSpawnPoint(java.util.Map)}. + */ + @Test + public void testSetSpawnPointMapOfEnvironmentLocation() { + Map m = new EnumMap<>(Environment.class); + m.put(Environment.THE_END, location); + i.setSpawnPoint(m); + assertEquals(location, i.getSpawnPoint(Environment.THE_END)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setUniqueId(java.lang.String)}. + */ + @Test + public void testSetUniqueId() { + String u = UUID.randomUUID().toString(); + i.setUniqueId(u); + assertEquals(u, i.getUniqueId()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setUpdatedDate(long)}. + */ + @Test + public void testSetUpdatedDate() { + i.setUpdatedDate(566789L); + assertEquals(566789L, i.getUpdatedDate()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setWorld(org.bukkit.World)}. + */ + @Test + public void testSetWorld() { + World w = Mockito.mock(World.class); + i.setWorld(w); + assertEquals(w, i.getWorld()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#toggleFlag(world.bentobox.bentobox.api.flags.Flag)}. + */ + @Test + public void testToggleFlagFlag() { + assertFalse(i.isAllowed(Flags.PVP_END)); + i.toggleFlag(Flags.PVP_END); + assertTrue(i.isAllowed(Flags.PVP_END)); + i.toggleFlag(Flags.PVP_END); + assertFalse(i.isAllowed(Flags.PVP_END)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#toggleFlag(world.bentobox.bentobox.api.flags.Flag, boolean)}. + */ + @Test + public void testToggleFlagFlagBoolean() { + Flag f = Flags.values().stream().filter(fl -> fl.hasSubflags()) + .filter(fl -> fl.getType().equals(Type.SETTING)) + .findFirst().orElse(null); + if (f != null) { + i.toggleFlag(f, true); + assertTrue(i.isAllowed(f)); + i.toggleFlag(f, true); + assertFalse(i.isAllowed(f)); + } else { + System.out.println("No settings flag with subflags yet"); + } + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setSettingsFlag(world.bentobox.bentobox.api.flags.Flag, boolean)}. + */ + @Test + public void testSetSettingsFlagFlagBoolean() { + i.setSettingsFlag(Flags.PVP_NETHER, true); + assertTrue(i.isAllowed(Flags.PVP_NETHER)); + i.setSettingsFlag(Flags.PVP_NETHER, false); + assertFalse(i.isAllowed(Flags.PVP_NETHER)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setSettingsFlag(world.bentobox.bentobox.api.flags.Flag, boolean, boolean)}. + */ + @Test + public void testSetSettingsFlagFlagBooleanBoolean() { + i.setSettingsFlag(Flags.PVP_NETHER, true, true); + assertTrue(i.isAllowed(Flags.PVP_NETHER)); + i.setSettingsFlag(Flags.PVP_NETHER, false, true); + assertFalse(i.isAllowed(Flags.PVP_NETHER)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setSpawnPoint(org.bukkit.World.Environment, org.bukkit.Location)}. + */ + @Test + public void testSetSpawnPointEnvironmentLocation() { + i.setSpawnPoint(Environment.THE_END, location); + assertEquals(location, i.getSpawnPoint(Environment.THE_END)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getSpawnPoint(org.bukkit.World.Environment)}. + */ + @Test + public void testGetSpawnPointEnvironment() { + i.setSpawnPoint(Environment.THE_END, location); + assertEquals(location, i.getSpawnPoint(Environment.THE_END)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#removeRank(java.lang.Integer)}. + */ + @Test + public void testRemoveRank() { + assertFalse(i.getMembers().isEmpty()); + i.removeRank(RanksManager.OWNER_RANK); + assertTrue(i.getMembers().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getHistory()}. + */ + @Test + public void testGetHistory() { + assertTrue(i.getHistory().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#log(world.bentobox.bentobox.api.logs.LogEntry)}. + */ + @Test + public void testLog() { + LogEntry le = Mockito.mock(LogEntry.class); + i.log(le); + assertEquals(le, i.getHistory().get(0)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setHistory(java.util.List)}. + */ + @Test + public void testSetHistory() { + LogEntry le = Mockito.mock(LogEntry.class); + i.setHistory(List.of(le)); + assertEquals(le, i.getHistory().get(0)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isDoNotLoad()}. + */ + @Test + public void testIsDoNotLoad() { + assertFalse(i.isDoNotLoad()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setDoNotLoad(boolean)}. + */ + @Test + public void testSetDoNotLoad() { + i.setDoNotLoad(true); + assertTrue(i.isDoNotLoad()); + i.setDoNotLoad(false); + assertFalse(i.isDoNotLoad()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isDeleted()}. + */ + @Test + public void testIsDeleted() { + assertFalse(i.isDeleted()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setDeleted(boolean)}. + */ + @Test + public void testSetDeleted() { + i.setDeleted(true); + assertTrue(i.isDeleted()); + i.setDeleted(false); + assertFalse(i.isDeleted()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getGameMode()}. + */ + @Test + public void testGetGameMode() { + assertNull(i.getGameMode()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setGameMode(java.lang.String)}. + */ + @Test + public void testSetGameMode() { + i.setGameMode("BSkyBlock"); + assertEquals("BSkyBlock", i.getGameMode()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#hasNetherIsland()}. + */ + @Test + public void testHasNetherIsland() { + i.setWorld(world); + when(iwm.isNetherGenerate(any())).thenReturn(true); + when(iwm.isNetherIslands(any())).thenReturn(true); + when(iwm.getNetherWorld(world)).thenReturn(world); + Block block = Mockito.mock(Block.class); + when(block.getType()).thenReturn(Material.BEDROCK); + when(world.getBlockAt(any())).thenReturn(block); + assertTrue(i.hasNetherIsland()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#hasEndIsland()}. + */ + @Test + public void testHasEndIsland() { + i.setWorld(world); + when(iwm.isEndGenerate(any())).thenReturn(true); + when(iwm.isEndIslands(any())).thenReturn(true); + when(iwm.getEndWorld(world)).thenReturn(world); + Block block = Mockito.mock(Block.class); + when(block.getType()).thenReturn(Material.BEDROCK); + when(world.getBlockAt(any())).thenReturn(block); + assertTrue(i.hasEndIsland()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isCooldown(world.bentobox.bentobox.api.flags.Flag)}. + */ + @Test + public void testIsCooldown() { + assertFalse(i.isCooldown(Flags.BREAK_BLOCKS)); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setCooldown(world.bentobox.bentobox.api.flags.Flag)}. + */ + @Test + public void testSetCooldown() { + assertTrue(i.getCooldowns().isEmpty()); + i.setCooldown(Flags.BREAK_BLOCKS); + assertFalse(i.getCooldowns().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getCooldowns()}. + */ + @Test + public void testGetCooldowns() { + assertTrue(i.getCooldowns().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setCooldowns(java.util.Map)}. + */ + @Test + public void testSetCooldowns() { + i.setCooldowns(Collections.singletonMap(Flags.BREAK_BLOCKS, 123L)); + assertFalse(i.getCooldowns().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getCommandRanks()}. + */ + @Test + public void testGetCommandRanks() { + assertNull(i.getCommandRanks()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setCommandRanks(java.util.Map)}. + */ + @Test + public void testSetCommandRanks() { + i.setCommandRanks(Collections.singletonMap("hello", 123)); + assertFalse(i.getCommandRanks().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getRankCommand(java.lang.String)}. + */ + @Test + public void testGetRankCommand() { + assertEquals(RanksManager.OWNER_RANK, i.getRankCommand("test")); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setRankCommand(java.lang.String, int)}. + */ + @Test + public void testSetRankCommand() { + i.setRankCommand("test", RanksManager.COOP_RANK); + assertEquals(RanksManager.COOP_RANK, i.getRankCommand("test")); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isReserved()}. + */ + @Test + public void testIsReserved() { + assertFalse(i.isReserved()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setReserved(boolean)}. + */ + @Test + public void testSetReserved() { + i.setReserved(true); + assertTrue(i.isReserved()); + i.setReserved(false); + assertFalse(i.isReserved()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMetaData()}. + */ + @Test + public void testGetMetaData() { + assertTrue(i.getMetaData().get().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setMetaData(java.util.Map)}. + */ + @Test + public void testSetMetaData() { + MetaDataValue meta = new MetaDataValue("hello"); + i.setMetaData(Collections.singletonMap("test", meta)); + assertFalse(i.getMetaData().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#isChanged()}. + */ + @Test + public void testIsChanged() { + assertTrue(i.isChanged()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setChanged()}. + */ + @Test + public void testSetChanged() { + Island ii = new Island(); + ii.setChanged(); + assertTrue(ii.isChanged()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setChanged(boolean)}. + */ + @Test + public void testSetChangedBoolean() { + i.setChanged(false); + assertFalse(i.isChanged()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getProtectionCenter()}. + */ + @Test + public void testGetProtectionCenter() { + assertEquals("Location{world=null,x=0.0,y=0.0,z=0.0,pitch=0.0,yaw=0.0}", i.getProtectionCenter().toString()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setProtectionCenter(org.bukkit.Location)}. + * @throws IOException if the location is not in island space + */ + @Test + public void testSetProtectionCenter() throws IOException { + i.setWorld(world); + when(world.getName()).thenReturn("bskyblock_wworld"); + when(location.getWorld()).thenReturn(world); + i.setProtectionCenter(location); + assertEquals(location, i.getProtectionCenter()); + + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getHomes()}. + */ + @Test + public void testGetHomes() { + assertTrue(i.getHomes().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getHome(java.lang.String)}. + */ + @Test + public void testGetHome() { + assertNull(i.getHome("default")); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setHomes(java.util.Map)}. + */ + @Test + public void testSetHomes() { + i.setHomes(Collections.singletonMap("hello", location)); + assertFalse(i.getHomes().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#addHome(java.lang.String, org.bukkit.Location)}. + */ + @Test + public void testAddHome() { + i.addHome("backyard", location); + assertEquals(location, i.getHome("backyard")); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#removeHome(java.lang.String)}. + */ + @Test + public void testRemoveHome() { + testAddHome(); + i.removeHome("backyard"); + assertTrue(i.getHomes().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#renameHome(java.lang.String, java.lang.String)}. + */ + @Test + public void testRenameHome() { + testAddHome(); + assertTrue(i.renameHome("backyard", "new")); + assertFalse(i.renameHome("new", "new")); + assertFalse(i.renameHome("nhelloew", "hfhhf")); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxHomes()}. + */ + @Test + public void testGetMaxHomes() { + assertNull(i.getMaxHomes()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setMaxHomes(java.lang.Integer)}. + */ + @Test + public void testSetMaxHomes() { + i.setMaxHomes(23); + assertEquals(23, i.getMaxHomes().intValue()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxMembers()}. + */ + @Test + public void testGetMaxMembers() { + assertTrue(i.getMaxMembers().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setMaxMembers(java.util.Map)}. + */ + @Test + public void testSetMaxMembersMapOfIntegerInteger() { + i.setMaxMembers(Collections.singletonMap(2345, 400)); + assertFalse(i.getMaxMembers().isEmpty()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#getMaxMembers(int)}. + */ + @Test + public void testGetMaxMembersInt() { + assertNull(i.getMaxMembers(1000)); + i.setMaxMembers(Collections.singletonMap(1000, 400)); + assertEquals(400, i.getMaxMembers(1000).intValue()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#setMaxMembers(int, java.lang.Integer)}. + */ + @Test + public void testSetMaxMembersIntInteger() { + i.setMaxMembers(1000, 400); + assertEquals(400, i.getMaxMembers(1000).intValue()); + } + + /** + * Test method for {@link world.bentobox.bentobox.database.objects.Island#toString()}. + */ + @Test + public void testToString() { + assertFalse(i.toString().isBlank()); + } + +} diff --git a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java index 6a1bc21d7..3edd9bfdb 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java @@ -246,9 +246,9 @@ public class JoinLeaveListenerTest { // Verify verify(player).sendMessage(eq("commands.admin.setrange.range-updated")); // Verify island setting - verify(island).setProtectionRange(eq(200)); + verify(island).setProtectionRange(eq(100)); // Verify log - verify(plugin).log("Island protection range changed from 50 to 200 for tastybento due to permission."); + verify(plugin).log("Island protection range changed from 50 to 100 for tastybento due to permission."); } /** diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListenerTest.java index 4a2d74871..d3021e0be 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListenerTest.java @@ -104,10 +104,14 @@ public class MobSpawnListenerTest { when(zombie.getLocation()).thenReturn(location); when(slime.getLocation()).thenReturn(location); when(cow.getLocation()).thenReturn(location); + when(zombie.getWorld()).thenReturn(world); + when(slime.getWorld()).thenReturn(world); + when(cow.getWorld()).thenReturn(world); // Worlds when(plugin.getIWM()).thenReturn(iwm); when(iwm.inWorld(any(Location.class))).thenReturn(true); + when(iwm.inWorld(any(World.class))).thenReturn(true); when(plugin.getIWM()).thenReturn(iwm); // Util class diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java index 4a3df7dd2..be3620e11 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/EnterExitListenerTest.java @@ -140,6 +140,7 @@ public class EnterExitListenerTest { when(island.getOwner()).thenReturn(uuid); when(island.getMemberSet()).thenReturn(ImmutableSet.of(uuid)); when(island.isOwned()).thenReturn(true); + when(island.getWorld()).thenReturn(world); when(im.getIsland(any(), any(UUID.class))).thenReturn(island); diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/PistonPushListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/PistonPushListenerTest.java index be02e9d8e..1fe59ca16 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/PistonPushListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/PistonPushListenerTest.java @@ -3,6 +3,7 @@ package world.bentobox.bentobox.listeners.flags.worldsettings; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -22,6 +23,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -42,8 +44,11 @@ import world.bentobox.bentobox.util.Util; @PrepareForTest({BentoBox.class, Util.class }) public class PistonPushListenerTest { + @Mock private Island island; + @Mock private World world; + @Mock private Block block; private List blocks; @@ -53,36 +58,33 @@ public class PistonPushListenerTest { BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); - // World - world = mock(World.class); - // Owner UUID uuid = UUID.randomUUID(); // Island initialization - island = mock(Island.class); when(island.getOwner()).thenReturn(uuid); IslandsManager im = mock(IslandsManager.class); when(plugin.getIslands()).thenReturn(im); - when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island); + when(im.getIsland(any(), any(UUID.class))).thenReturn(island); Location inside = mock(Location.class); + when(inside.getWorld()).thenReturn(world); Optional opIsland = Optional.ofNullable(island); - when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(opIsland); + when(im.getProtectedIslandAt(eq(inside))).thenReturn(opIsland); // Blocks - block = mock(Block.class); when(block.getWorld()).thenReturn(world); when(block.getLocation()).thenReturn(inside); Block blockPushed = mock(Block.class); - when(block.getRelative(Mockito.any(BlockFace.class))).thenReturn(blockPushed); + when(block.getRelative(any(BlockFace.class))).thenReturn(blockPushed); // The blocks in the pushed list are all inside the island when(blockPushed.getLocation()).thenReturn(inside); + when(blockPushed.getWorld()).thenReturn(world); // Make a list of ten blocks blocks = new ArrayList<>(); @@ -91,18 +93,19 @@ public class PistonPushListenerTest { } PowerMockito.mockStatic(Util.class); - when(Util.getWorld(Mockito.any())).thenReturn(world); + when(Util.getWorld(any())).thenReturn(world); // World Settings IslandWorldManager iwm = mock(IslandWorldManager.class); when(plugin.getIWM()).thenReturn(iwm); WorldSettings ws = mock(WorldSettings.class); - when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws); + when(iwm.getWorldSettings(any())).thenReturn(ws); Map worldFlags = new HashMap<>(); when(ws.getWorldFlags()).thenReturn(worldFlags); GameModeAddon gma = mock(GameModeAddon.class); Optional opGma = Optional.of(gma ); when(iwm.getAddon(any())).thenReturn(opGma); + when(iwm.inWorld(world)).thenReturn(true); // Set default on Flags.PISTON_PUSH.setSetting(world, true); @@ -129,7 +132,7 @@ public class PistonPushListenerTest { public void testOnPistonExtendFlagSetOnIsland() { // The blocks in the pushed list are all inside the island - when(island.onIsland(Mockito.any())).thenReturn(true); + when(island.onIsland(any())).thenReturn(true); BlockPistonExtendEvent e = new BlockPistonExtendEvent(block, blocks, BlockFace.EAST); new PistonPushListener().onPistonExtend(e); @@ -141,7 +144,7 @@ public class PistonPushListenerTest { @Test public void testOnPistonExtendFlagSetOffIsland() { // The blocks in the pushed list are all outside the island - when(island.onIsland(Mockito.any())).thenReturn(false); + when(island.onIsland(any())).thenReturn(false); BlockPistonExtendEvent e = new BlockPistonExtendEvent(block, blocks, BlockFace.EAST); new PistonPushListener().onPistonExtend(e); diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java index ac828f0d4..463d883df 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java @@ -106,6 +106,7 @@ public class RemoveMobsListenerTest { Map worldFlags = new HashMap<>(); when(ws.getWorldFlags()).thenReturn(worldFlags); Flags.REMOVE_MOBS.setSetting(world, true); + when(iwm.inWorld(world)).thenReturn(true); // Sometimes use Mockito.withSettings().verboseLogging() UUID uuid = UUID.randomUUID(); diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java index 9bd967213..8613406ed 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java @@ -211,14 +211,6 @@ public class IslandWorldManagerTest { assertEquals(ws, iwm.getWorldSettings(world)); } - /** - * Test method for {@link world.bentobox.bentobox.managers.IslandWorldManager#getWorldSettings(org.bukkit.World)}. - */ - @Test - public void testGetWorldSettingsNull() { - assertNull(iwm.getWorldSettings(null)); - } - /** * Test method for {@link world.bentobox.bentobox.managers.IslandWorldManager#getOverWorld(java.lang.String)}. */ diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java index b52339032..abd630ab5 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java @@ -191,7 +191,6 @@ public class IslandsManagerTest { // Player's manager when(plugin.getPlayers()).thenReturn(pm); - when(pm.getHomeLocations(any(), any())).thenReturn(Collections.emptyMap()); // Scheduler BukkitScheduler sch = mock(BukkitScheduler.class); @@ -726,7 +725,6 @@ public class IslandsManagerTest { */ @Test public void testGetSafeHomeLocationNoIsland() { - when(pm.getHomeLocation(eq(world), eq(user), eq(0))).thenReturn(null); assertNull(im.getSafeHomeLocation(world, user, "")); verify(plugin).logWarning(eq("null player has no island in world world!")); } diff --git a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java index d7a34500d..44cd67b08 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -2,7 +2,6 @@ package world.bentobox.bentobox.managers; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -316,43 +315,6 @@ public class PlayersManagerTest { assertTrue(pm.isKnown(notUUID)); } - /** - * Test method for {@link world.bentobox.bentobox.managers.PlayersManager#setHomeLocation(User, org.bukkit.Location, int)}. - */ - @Test - public void testSetAndGetHomeLocationUserLocationInt() { - Location l = mock(Location.class); - when(l.getWorld()).thenReturn(world); - Location l2 = mock(Location.class); - when(l2.getWorld()).thenReturn(nether); - Location l3 = mock(Location.class); - when(l3.getWorld()).thenReturn(end); - - pm.setHomeLocation(uuid, l, 1); - pm.setHomeLocation(uuid, l2, 0); - pm.setHomeLocation(uuid, l3, 10); - assertEquals(l, pm.getHomeLocation(world, uuid)); - assertEquals(l2, pm.getHomeLocation(world, uuid, 0)); - assertEquals(l3, pm.getHomeLocation(world, uuid, 10)); - assertNotEquals(l, pm.getHomeLocation(world, uuid, 20)); - } - - @Test - public void testClearHomeLocations() { - Location l = mock(Location.class); - when(l.getWorld()).thenReturn(world); - Location l2 = mock(Location.class); - when(l2.getWorld()).thenReturn(nether); - Location l3 = mock(Location.class); - when(l3.getWorld()).thenReturn(end); - pm.setHomeLocation(uuid, l, 1); - pm.setHomeLocation(uuid, l2, 0); - pm.setHomeLocation(uuid, l3, 10); - assertFalse(pm.getHomeLocations(world, uuid).isEmpty()); - pm.clearHomeLocations(world, uuid); - assertTrue(pm.getHomeLocations(world, uuid).isEmpty()); - } - /** * Test method for {@link world.bentobox.bentobox.managers.PlayersManager#getUUID(java.lang.String)}. */ diff --git a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java index 87c690e32..74b36a812 100644 --- a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java @@ -202,8 +202,7 @@ public class NewIslandTest { verify(bpb).getUniqueId(); verify(ice).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); verify(island).setProtectionRange(eq(20)); } @@ -224,8 +223,7 @@ public class NewIslandTest { verify(ice, never()).getBlueprintBundle(); verify(ire).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); } /** @@ -243,8 +241,7 @@ public class NewIslandTest { verify(bpb).getUniqueId(); verify(ice).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); } /** @@ -262,8 +259,7 @@ public class NewIslandTest { verify(bpb).getUniqueId(); verify(ice).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); } /** @@ -282,8 +278,7 @@ public class NewIslandTest { verify(bpb).getUniqueId(); verify(ice).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); verify(island).setProtectionRange(eq(20)); verify(island).setReserved(eq(false)); } @@ -305,8 +300,7 @@ public class NewIslandTest { verify(bpb).getUniqueId(); verify(ice).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); verify(island).setProtectionRange(eq(20)); verify(plugin).logError("New island for user tastybento was not reserved!"); } @@ -328,8 +322,7 @@ public class NewIslandTest { verify(bpb).getUniqueId(); verify(ice).getBlueprintBundle(); verify(pm).setDeaths(eq(world), eq(uuid), eq(0)); - verify(pm).setHomeLocation(eq(user), any(), eq(1)); - verify(pm).clearHomeLocations(eq(world), any(UUID.class)); + verify(im).setHomeLocation(eq(user), any()); verify(island).setProtectionRange(eq(20)); verify(plugin).logError("New island for user tastybento was not reserved!"); }