diff --git a/buildsystem-api/javadoc/overview.html b/buildsystem-api/javadoc/overview.html index 2c679fc3..1b9d9413 100644 --- a/buildsystem-api/javadoc/overview.html +++ b/buildsystem-api/javadoc/overview.html @@ -1,11 +1,11 @@
- BuildSystem is a utility plugin targeted towards build-teams. - It allows worlds to be easily managed and also provides handy tools to assist with building. + BuildSystem is a utility plugin targeted towards build-teams. + It allows worlds to be easily managed and also provides handy tools to assist with building.
- * If the player has the permission {@code buildsystem.admin}, unlimited worlds can be created. - * Otherwise, there are two different permissions to set said amount: + * If the player has the permission {@code buildsystem.admin}, unlimited worlds can be created. Otherwise, there are two different permissions to set said amount: *
* To set the maximum of... *
+ * Not equivalent to {@link World#getUID()}. + * + * @return The uuid of the world + */ + UUID getUniqueId(); + + /** + * Sets the name of the world. * * @param name The name to set to */ @@ -51,7 +64,7 @@ public interface BuildWorld extends Displayable { Profileable asProfilable(); /** - * Get world's type. + * Gets the world's type. * * @return The {@link BuildWorldType} of the world */ @@ -65,14 +78,7 @@ public interface BuildWorld extends Displayable { WorldData getData(); /** - * Get the creation date of the world. - * - * @return The number of milliseconds that have passed since {@code January 1, 1970 UTC}, until the world was created. - */ - long getCreationDate(); - - /** - * Get the custom chunk generator used to generate the world. + * Gets the custom chunk generator used to generate the world. * * @return The custom chunk generator used to generate the world. */ @@ -85,48 +91,58 @@ public interface BuildWorld extends Displayable { void cycleDifficulty(); /** - * Get a list of all builders who can modify the world. + * Gets a list of all builders who can modify the world. * * @return the list of all builders */ Builders getBuilders(); /** - * Get the time in the {@link World} linked to the build world. + * Gets the time in the {@link World} linked to the build world. * * @return The world time */ String getWorldTime(); /** - * Get whether the world is currently loaded, allowing a player to enter it. + * Gets whether the world is currently loaded, allowing a player to enter it. * * @return {@code true} if the world is loaded, otherwise {@code false} */ boolean isLoaded(); /** - * Set whether the world is currently loaded, allowing a player to enter it. + * Sets whether the world is currently loaded, allowing a player to enter it. * * @param loaded {@code true} if the world is loaded, otherwise {@code false} */ void setLoaded(boolean loaded); /** - * Get the {@link WorldLoader} used to load the world. + * Gets the {@link WorldLoader} used to load the world. * * @return The {@link WorldLoader} used to load the world */ WorldLoader getLoader(); /** - * Get the {@link WorldUnloader} used to unload the world. + * Gets the {@link WorldUnloader} used to unload the world. * * @return The {@link WorldUnloader} used to unload the world */ WorldUnloader getUnloader(); + /** + * Gets the {@link WorldTeleporter} used to teleport players to the world. + * + * @return The {@link WorldTeleporter} used to teleport players to the world + */ WorldTeleporter getTeleporter(); + /** + * Gets the {@link WorldPermissions} associated with the world. + * + * @return The {@link WorldPermissions} for the world + */ WorldPermissions getPermissions(); } \ No newline at end of file diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/WorldService.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/WorldService.java index 9ccf2cb6..9a3a5f5e 100644 --- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/WorldService.java +++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/WorldService.java @@ -20,6 +20,9 @@ import de.eintosti.buildsystem.api.storage.FolderStorage; import de.eintosti.buildsystem.api.storage.WorldStorage; +/** + * @since 3.0.0 + */ public interface WorldService { WorldStorage getWorldStorage(); diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builder.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builder.java index a6465d2b..b90ca3bd 100644 --- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builder.java +++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builder.java @@ -17,11 +17,16 @@ */ package de.eintosti.buildsystem.api.world.builder; +import de.eintosti.buildsystem.api.world.BuildWorld; +import java.util.UUID; import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; -import java.util.UUID; - +/** + * A {@link Builder} represents a player allowed to build in a {@link BuildWorld}. + * + * @since 3.0.0 + */ public interface Builder { /** diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/BuilderImpl.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/BuilderImpl.java index 274870f2..f0336163 100644 --- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/BuilderImpl.java +++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/BuilderImpl.java @@ -19,6 +19,11 @@ import java.util.UUID; +/** + * Concrete implementation of the {@link Builder} interface. + * + * @since 3.0.0 + */ final class BuilderImpl implements Builder { static final String SEPARATOR = ","; diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builders.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builders.java index f08169b5..5276be70 100644 --- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builders.java +++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/builder/Builders.java @@ -17,6 +17,7 @@ */ package de.eintosti.buildsystem.api.world.builder; +import de.eintosti.buildsystem.api.world.BuildWorld; import java.util.Collection; import java.util.List; import java.util.UUID; @@ -25,7 +26,9 @@ import org.jetbrains.annotations.Nullable; /** - * Interface for managing builders in a {@link de.eintosti.buildsystem.api.world.BuildWorld}. + * Interface for managing builders in a {@link BuildWorld}. + * + * @since 3.0.0 */ public interface Builders { diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/BuildWorldCreator.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/BuildWorldCreator.java index 237e67a8..9f474446 100644 --- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/BuildWorldCreator.java +++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/BuildWorldCreator.java @@ -19,14 +19,20 @@ import de.eintosti.buildsystem.api.world.BuildWorld; import de.eintosti.buildsystem.api.world.builder.Builder; -import de.eintosti.buildsystem.api.world.data.BuildWorldType; import de.eintosti.buildsystem.api.world.creation.generator.CustomGenerator; +import de.eintosti.buildsystem.api.world.data.BuildWorldType; +import de.eintosti.buildsystem.api.world.display.Folder; import org.bukkit.Difficulty; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.generator.ChunkGenerator; import org.jetbrains.annotations.Nullable; +/** + * Represents a creator for a {@link BuildWorld}. + * + * @since 3.0.0 + */ public interface BuildWorldCreator { /** @@ -71,37 +77,75 @@ public interface BuildWorldCreator { */ BuildWorldCreator setCustomGenerator(CustomGenerator customGenerator); + /** + * Sets the folder in which the world should be created. + * + * @param folder The folder where the world should be created + * @return The world creator object + */ + BuildWorldCreator setFolder(Folder folder); + + /** + * Sets whether the world should be private or not. + * + * @param privateWorld Whether the world should be private + * @return The world creator object + */ BuildWorldCreator setPrivate(boolean privateWorld); + /** + * Sets the difficulty of the world. + * + * @param difficulty The difficulty + * @return The world creator object + */ BuildWorldCreator setDifficulty(Difficulty difficulty); + /** + * Sets the creation date of the world. + * + * @param creationDate The creation date in milliseconds since epoch + * @return The world creator object + */ BuildWorldCreator setCreationDate(long creationDate); /** - * Depending on the {@link BuildWorld}'s {@link BuildWorldType}, the corresponding {@link World} will be generated in a different way. - * Then, if the creation of the world was successful and the config is set accordingly, the player is teleported to the world. + * Creates and generates a new {@link BuildWorld} using the settings configured in this builder. + *
+ * This process includes creating the world files, registering the world with the plugin, and notifying the player of the progress. * * @param player The player who is creating the world */ void createWorld(Player player); /** - * Imports an existing world as a {@link BuildWorld}. + * Imports an existing world directory as a new {@link BuildWorld}. * * @param player The player who is importing the world - * @param teleport Should the player be teleported to the world after importing is finished + * @param teleport If true, the player will be teleported to the world after the import is finished */ void importWorld(Player player, boolean teleport); + /** + * Generates the underlying Bukkit {@link World} and applies post-generation settings. + *
+ * Only generates the world if the world was not created in a newer Minecraft version that the server is running.
+ *
+ * @param buildWorld The build world to generate
+ * @return The generated {@link World}, or {@code null} if generation failed
+ */
@Nullable
- World generateBukkitWorld();
+ default World generateBukkitWorld(BuildWorld buildWorld) {
+ return generateBukkitWorld(buildWorld, true);
+ }
/**
- * Generate the {@link World} linked to a {@link BuildWorld}.
+ * Generates the underlying Bukkit {@link World} and applies post-generation settings.
*
- * @param checkVersion Should the world version be checked
- * @return The world object
+ * @param buildWorld The build world to generate
+ * @param checkVersion If true, verify that the world's data version is compatible
+ * @return The generated {@link World}, or {@code null} if generation failed.
*/
@Nullable
- World generateBukkitWorld(boolean checkVersion);
+ World generateBukkitWorld(BuildWorld buildWorld, boolean checkVersion);
}
\ No newline at end of file
diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/CustomGenerator.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/CustomGenerator.java
index 50f0fcb4..445bde9c 100644
--- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/CustomGenerator.java
+++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/CustomGenerator.java
@@ -19,6 +19,11 @@
import org.bukkit.generator.ChunkGenerator;
+/**
+ * Represents a custom chunk generator for a world.
+ *
+ * @since 3.0.0
+ */
public interface CustomGenerator {
/**
diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/Generator.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/Generator.java
index 73e6768e..47602745 100644
--- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/Generator.java
+++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/creation/generator/Generator.java
@@ -17,6 +17,13 @@
*/
package de.eintosti.buildsystem.api.world.creation.generator;
+import de.eintosti.buildsystem.api.world.BuildWorld;
+
+/**
+ * Different kinds of world generators that can be used for a {@link BuildWorld}.
+ *
+ * @since 3.0.0
+ */
public enum Generator {
/**
diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldStatus.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldStatus.java
index f9c371d1..fbd3b6ed 100644
--- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldStatus.java
+++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldStatus.java
@@ -21,6 +21,9 @@
import java.util.Locale;
import org.jetbrains.annotations.ApiStatus.Internal;
+/**
+ * @since 3.0.0
+ */
public enum BuildWorldStatus {
/**
@@ -83,8 +86,7 @@ public String getPermission() {
}
/**
- * Gets the stage in which the {@link BuildWorld} is currently in.
- * A higher value means the world is further in development.
+ * Gets the stage in which the {@link BuildWorld} is currently in. A higher value means the world is further in development.
*
* @return the stage in which the world is currently in.
*/
diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldType.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldType.java
index c3621840..a78ee2d5 100644
--- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldType.java
+++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/BuildWorldType.java
@@ -21,6 +21,9 @@
import org.jetbrains.annotations.ApiStatus.Internal;
import org.jetbrains.annotations.Nullable;
+/**
+ * @since 3.0.0
+ */
public enum BuildWorldType {
/**
diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/Visibility.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/Visibility.java
index c03388c9..489a9d4e 100644
--- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/Visibility.java
+++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/Visibility.java
@@ -17,6 +17,9 @@
*/
package de.eintosti.buildsystem.api.world.data;
+/**
+ * @since 3.0.0
+ */
public enum Visibility {
/**
diff --git a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/WorldData.java b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/WorldData.java
index 2803af30..b8ebd99f 100644
--- a/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/WorldData.java
+++ b/buildsystem-api/src/main/java/de/eintosti/buildsystem/api/world/data/WorldData.java
@@ -24,6 +24,9 @@
import org.bukkit.Location;
import org.jetbrains.annotations.Nullable;
+/**
+ * @since 3.0.0
+ */
public interface WorldData {
/**
@@ -45,7 +48,7 @@ public interface WorldData {
/**
* Gets the permission needed to enter the {@link BuildWorld}.
*
- * @return The permission
+ * @return The permission, or '{@code -}' if no permission is required
*/
Type
+ * The method applies the following logic:
+ *
- * The following logic is applied to determine the above:
- *
- * If the clicked item is the icon of a {@link BuildWorld}, the click is managed by {@link #manageWorldItemClick(InventoryClickEvent, Player, ItemMeta, BuildWorld)}. Otherwise,
- * the {@link NavigatorInventory} is opened if the glass pane at the bottom of the inventory is clicked.
- *
- * @param event The click event object to modify
- * @param player The player who clicked
- * @param itemStack The clicked item
- */
- public void manageInventoryClick(InventoryClickEvent event, Player player, ItemStack itemStack) {
- if (itemStack == null || itemStack.getItemMeta() == null) {
- return;
- }
-
- int slot = event.getSlot();
- ItemMeta itemMeta = itemStack.getItemMeta();
- String displayName = itemMeta.getDisplayName();
-
- if (slot == 22 &&
- displayName.equals(Messages.getString("world_navigator_no_worlds", player))
- || displayName.equals(Messages.getString("archive_no_worlds", player))
- || displayName.equals(Messages.getString("private_no_worlds", player))) {
- return;
- }
-
- if (slot >= 9 && slot <= 44) {
- BuildWorld buildWorld = worldService.getWorldStorage().getBuildWorld(getWorldName(player, displayName));
- manageWorldItemClick(event, player, itemMeta, buildWorld);
- return;
- }
-
- if (slot >= 45 && slot <= 53 && itemStack.getType() != XMaterial.PLAYER_HEAD.get()) {
- XSound.BLOCK_CHEST_OPEN.play(player);
- plugin.getNavigatorInventory().openInventory(player);
- }
- }
-
- /**
- * Parse the name of a world from the given input.
- *
- * @param player The player used to parse the placeholders
- * @param input The string to parse the name from
- * @return The name of the world
- */
- private String getWorldName(Player player, String input) {
- String template = Messages.getString("world_item_title", player, new AbstractMap.SimpleEntry<>("%world%", ""));
- return StringUtils.difference(template, input);
- }
-
- /**
- * Manage the clicking of an {@link ItemStack} that represents a {@link BuildWorld}.
- *
- * If the click is a...
- *
+ *
+ * This ensures that:
+ *
+ *
+ *
+ * @return A list of {@link Displayable} items to be presented in the UI, sorted with folders first.
+ */
+ protected @NotNull List
- *
- *
- * @param player The player who the world will be shown to
- * @param buildWorld The world to show
- * @return {@code true} if the world should be shown to the player in the navigator, {@code false} otherwise
- */
- private boolean isValidWorld(Player player, BuildWorld buildWorld) {
- WorldData worldData = buildWorld.getData();
- if (!worldService.getWorldStorage().isCorrectVisibility(worldData.privateWorld().get(), visibility)) {
- return false;
- }
-
- if (!validStatus.contains(worldData.status().get())) {
- return false;
- }
-
- if (!buildWorld.getPermissions().canEnter(player)) {
- return false;
- }
-
- return Bukkit.getWorld(buildWorld.getName()) != null || !buildWorld.isLoaded();
- }
-
- @EventHandler
- public void onInventoryClick(InventoryClickEvent event) {
- if (!InventoryUtils.isValidClick(event, inventoryName)) {
- return;
- }
-
- ItemStack itemStack = event.getCurrentItem();
- if (itemStack == null) {
- return;
- }
-
- Player player = (Player) event.getWhoClicked();
- Settings settings = settingsManager.getSettings(player);
- WorldDisplay worldDisplay = settings.getWorldDisplay();
-
- switch (event.getSlot()) {
- case 45:
- Function
- *
- *
- * @param event The click event to modify
- * @param player The player who clicked
- * @param itemMeta The item meta of the clicked item
- * @param buildWorld The world represented by the clicked item
- */
- private void manageWorldItemClick(InventoryClickEvent event, Player player, ItemMeta itemMeta, BuildWorld buildWorld) {
- if (event.isLeftClick() || buildWorld.getPermissions().canPerformCommand(player, WorldsTabComplete.WorldsArgument.EDIT.getPermission())) {
- performNonEditClick(player, itemMeta);
- return;
- }
-
- if (buildWorld.isLoaded()) {
- playerService.getPlayerStorage().getBuildPlayer(player).setCachedWorld(buildWorld);
- XSound.BLOCK_CHEST_OPEN.play(player);
- plugin.getEditInventory().openInventory(player, buildWorld);
- } else {
- player.closeInventory();
- XSound.ENTITY_ZOMBIE_BREAK_WOODEN_DOOR.play(player);
- Titles.sendTitle(player, 5, 70, 20, " ", Messages.getString("world_not_loaded", player));
- }
- }
-
- /**
- * A "non-edit click" is a click (i.e., a right click) which does not open the {@link EditInventory}.
- *
- * @param player The player who clicked
- * @param itemMeta The item meta of the clicked item
- */
- private void performNonEditClick(Player player, ItemMeta itemMeta) {
- playerService.closeNavigator(player);
- String worldName = getWorldName(player, itemMeta.getDisplayName());
- BuildWorld buildWorld = worldService.getWorldStorage().getBuildWorld(worldName);
- if (buildWorld == null) {
- plugin.getLogger().warning("Could not find world " + worldName);
- return;
- }
- buildWorld.getTeleporter().teleport(player);
- }
-}
\ No newline at end of file
diff --git a/buildsystem-core/src/main/java/de/eintosti/buildsystem/navigator/inventory/FolderContentInventory.java b/buildsystem-core/src/main/java/de/eintosti/buildsystem/navigator/inventory/FolderContentInventory.java
new file mode 100644
index 00000000..91fe62db
--- /dev/null
+++ b/buildsystem-core/src/main/java/de/eintosti/buildsystem/navigator/inventory/FolderContentInventory.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018-2025, Thomas Meaney
+ * Copyright (c) contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see