diff --git a/pom.xml b/pom.xml
index 049b07a..0c9c8b5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,7 +66,7 @@
-LOCAL
- 1.11.2
+ 1.12.0
BentoBoxWorld_Warps
bentobox-world
@@ -138,6 +138,11 @@
${spigot.version}
provided
+
+ org.spigotmc
+ plugin-annotations
+ 1.2.3-SNAPSHOT
+
org.mockito
diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java
index 5bd6f6f..fc762a8 100644
--- a/src/main/java/world/bentobox/warps/Warp.java
+++ b/src/main/java/world/bentobox/warps/Warp.java
@@ -17,6 +17,9 @@ import world.bentobox.warps.commands.WarpCommand;
import world.bentobox.warps.commands.WarpsCommand;
import world.bentobox.warps.config.Settings;
import world.bentobox.warps.listeners.WarpSignsListener;
+import world.bentobox.warps.managers.SignCacheManager;
+import world.bentobox.warps.managers.WarpSignsManager;
+
/**
* Addin to BentoBox that enables welcome warp signs
@@ -38,16 +41,16 @@ public class Warp extends Addon {
*/
public static final String WELCOME_WARP_SIGNS = "welcomewarpsigns";
- /**
- * Warp panel Manager
- */
- private WarpPanelManager warpPanelManager;
-
/**
* Worlds Sign manager.
*/
private WarpSignsManager warpSignsManager;
+ /**
+ * Sign Cache Manager
+ */
+ private SignCacheManager signCacheManager;
+
/**
* This variable stores in which worlds this addon is working.
*/
@@ -136,7 +139,7 @@ public class Warp extends Addon {
{
// Start warp signs
warpSignsManager = new WarpSignsManager(this, this.getPlugin());
- warpPanelManager = new WarpPanelManager(this);
+ signCacheManager = new SignCacheManager(this);
// Load the listener
this.registerListener(new WarpSignsListener(this));
} else {
@@ -169,17 +172,21 @@ public class Warp extends Addon {
this.setState(State.DISABLED);
return false;
}
+
+ // Save existing panels.
+ this.saveResource("panels/warps_panel.yml", false);
+
settingsConfig.saveConfigObject(settings);
return true;
}
/**
- * Get warp panel manager
- * @return Warp Panel Manager
+ * Get sign cache manager
+ * @return Sign Cache Manager
*/
- public WarpPanelManager getWarpPanelManager() {
- return warpPanelManager;
+ public SignCacheManager getSignCacheManager() {
+ return signCacheManager;
}
public WarpSignsManager getWarpSignsManager() {
diff --git a/src/main/java/world/bentobox/warps/WarpPanelManager.java b/src/main/java/world/bentobox/warps/WarpPanelManager.java
deleted file mode 100644
index 2ef77ea..0000000
--- a/src/main/java/world/bentobox/warps/WarpPanelManager.java
+++ /dev/null
@@ -1,187 +0,0 @@
-package world.bentobox.warps;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.command.Command;
-import org.bukkit.inventory.ItemStack;
-import org.eclipse.jdt.annotation.NonNull;
-
-import world.bentobox.bentobox.api.panels.PanelItem;
-import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
-import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
-import world.bentobox.bentobox.api.user.User;
-
-public class WarpPanelManager {
-
- private static final int PANEL_MAX_SIZE = 52;
- private final Warp addon;
- // This is a cache of signs
- private final SignCacheManager signCacheManager;
-
- public WarpPanelManager(Warp addon) {
- this.addon = addon;
- signCacheManager = new SignCacheManager(addon);
- }
-
- private PanelItem getPanelItem(World world, UUID warpOwner, SignCacheItem sign) {
-
- PanelItemBuilder pib = new PanelItemBuilder()
- .name(addon.getSettings().getNameFormat() + addon.getPlugin().getPlayers().getName(warpOwner))
- .description(sign.getSignText())
- .clickHandler((panel, clicker, click, slot) -> hander(world, clicker, warpOwner));
- Material icon = sign.getType();
- if (icon.equals(Material.PLAYER_HEAD)) {
- return pib.icon(addon.getPlayers().getName(warpOwner)).build();
- } else {
- return pib.icon(icon).build();
- }
- }
-
- private boolean hander(World world, User clicker, UUID warpOwner) {
- clicker.closeInventory();
- String playerCommand = addon.getPlugin().getIWM().getAddon(world).map(gm -> gm.getPlayerCommand().map(Command::getLabel).orElse("")).orElse("");
- String command = addon.getSettings().getWarpCommand() + " " + addon.getPlayers().getName(warpOwner);
- clicker.getPlayer().performCommand((playerCommand.isEmpty() ? "" : playerCommand + " ") + command);
- return true;
- }
-
- private PanelItem getRandomButton(World world, User user, UUID warpOwner) {
- return new PanelItemBuilder()
- .name(addon.getSettings().getNameFormat() + user.getTranslation("warps.random"))
- .clickHandler((panel, clicker, click, slot) -> hander(world, clicker, warpOwner))
- .icon(Material.END_CRYSTAL).build();
- }
-
- /**
- * Show the warp panel for the user
- * @param world - world
- * @param user - user
- * @param index - page to show - 0 is first
- */
- public void showWarpPanel(World world, User user, int index) {
-
- PanelBuilder panelBuilder = new PanelBuilder()
- .user(user)
- .name(user.getTranslation("warps.title") + " " + (index + 1));
-
- buildPanel(panelBuilder, user, index, world).thenRun(panelBuilder::build);
- }
-
- CompletableFuture buildPanel(PanelBuilder panelBuilder, User user, int index, World world) {
- CompletableFuture r = new CompletableFuture<>();
- processSigns(r, panelBuilder, user, index, world);
- return r;
- }
-
- void processSigns(CompletableFuture r, PanelBuilder panelBuilder, User user, int index, World world) {
- addon.getWarpSignsManager().getSortedWarps(world).thenAccept(warps -> {
- // Cache and clean the signs
- Iterator it = warps.iterator();
- while(it.hasNext()) {
- UUID warpOwner = it.next();
- @NonNull
- SignCacheItem sign = signCacheManager.getSignItem(world, warpOwner);
- if (!sign.isReal()) {
- it.remove();
- addon.getWarpSignsManager().removeWarpFromMap(world, warpOwner);
- }
- }
- // Add random warp
- getRandomWarp(warps);
- // Build the main body
- int i = buildMainBody(panelBuilder, user, index, world, warps);
- // Add navigation
- addNavigation(panelBuilder, user, world, i, index, warps.size());
- r.complete(null);
- });
- }
-
- private void getRandomWarp(List warps) {
- // Add random warp
- if (!warps.isEmpty() && addon.getSettings().isRandomAllowed()) {
- warps.add(0, warps.get(new Random().nextInt(warps.size())));
- }
- }
-
- int buildMainBody(PanelBuilder panelBuilder, User user, int index, World world, List warps) {
- if (index < 0) {
- index = 0;
- } else if (index > (warps.size() / PANEL_MAX_SIZE)) {
- index = warps.size() / PANEL_MAX_SIZE;
- }
-
- int i = index * PANEL_MAX_SIZE;
- for (; panelBuilder.getItems().size() < PANEL_MAX_SIZE && i < warps.size(); i++) {
- UUID warpOwner = warps.get(i);
- if (addon.getSettings().isRandomAllowed() && i == 0) {
- panelBuilder.item(getRandomButton(world, user, warpOwner));
- } else {
- @NonNull
- SignCacheItem sign = signCacheManager.getSignItem(world, warpOwner);
- if (sign.isReal()) {
- panelBuilder.item(getPanelItem(world, warpOwner, sign));
- } else {
- addon.getWarpSignsManager().removeWarpFromMap(world, warpOwner);
- }
- }
- }
- return i;
- }
-
- /**
- * Add Next and Previous icons to navigate
- * @param panelBuilder - the panel builder
- * @param user - user
- * @param world - world
- * @param numOfItems - number of items shown so far including in previous panels
- * @param panelNum - panel number (page)
- * @param totalNum - total number of items in the list
- */
- void addNavigation(PanelBuilder panelBuilder, User user, World world, int numOfItems, int panelNum, int totalNum) {
- // Previous
- if (panelNum > 0 && numOfItems > PANEL_MAX_SIZE) {
- // Previous
- panelBuilder.item(new PanelItemBuilder()
- .name(user.getTranslation("warps.previous"))
- .icon(new ItemStack(Material.COBBLESTONE))
- .clickHandler((panel, clicker, click, slot) -> {
- user.closeInventory();
- showWarpPanel(world, user, panelNum-1);
- return true;
- }).build());
- }
- // Next
- if (numOfItems < totalNum) {
- // Next
- panelBuilder.item(new PanelItemBuilder()
- .name(user.getTranslation("warps.next"))
- .icon(new ItemStack(Material.STONE))
- .clickHandler((panel, clicker, click, slot) -> {
- user.closeInventory();
- showWarpPanel(world, user, panelNum+1);
- return true;
- }).build());
- }
- }
-
- /**
- * Removes sign text from the cache
- * @param world - world
- * @param key - uuid of owner
- * @return true if the item was removed from the cache
- */
- public boolean removeWarp(World world, UUID key) {
- return signCacheManager.removeWarp(world, key);
- }
-
- public void saveCache() {
- signCacheManager.saveCache();
- }
-
-}
diff --git a/src/main/java/world/bentobox/warps/WarpsPladdon.java b/src/main/java/world/bentobox/warps/WarpsPladdon.java
index d27866a..44bd214 100644
--- a/src/main/java/world/bentobox/warps/WarpsPladdon.java
+++ b/src/main/java/world/bentobox/warps/WarpsPladdon.java
@@ -1,8 +1,15 @@
package world.bentobox.warps;
+import org.bukkit.plugin.java.annotation.dependency.Dependency;
+import org.bukkit.plugin.java.annotation.plugin.ApiVersion;
+import org.bukkit.plugin.java.annotation.plugin.Plugin;
+
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.addons.Pladdon;
+@Plugin(name="Pladdon", version="1.0")
+@ApiVersion(ApiVersion.Target.v1_16)
+@Dependency(value = "BentoBox")
public class WarpsPladdon extends Pladdon {
@Override
diff --git a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java
index ca9f2d8..108a255 100644
--- a/src/main/java/world/bentobox/warps/commands/WarpsCommand.java
+++ b/src/main/java/world/bentobox/warps/commands/WarpsCommand.java
@@ -7,6 +7,8 @@ import org.bukkit.World;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.warps.Warp;
+import world.bentobox.warps.panels.WarpsPanel;
+
/**
* Handles the warps command
@@ -51,7 +53,9 @@ public class WarpsCommand extends CompositeCommand {
user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine());
return false;
}
- addon.getWarpPanelManager().showWarpPanel(world, user, 0);
+
+ WarpsPanel.openPanel(this.addon, world, user);
+
return true;
}
diff --git a/src/main/java/world/bentobox/warps/config/Settings.java b/src/main/java/world/bentobox/warps/config/Settings.java
index 7b51024..5e9bfbb 100644
--- a/src/main/java/world/bentobox/warps/config/Settings.java
+++ b/src/main/java/world/bentobox/warps/config/Settings.java
@@ -29,14 +29,6 @@ public class Settings implements ConfigObject
@ConfigEntry(path = "welcomeLine")
private String welcomeLine = "[Welcome]";
- @ConfigComment("")
- @ConfigComment("Icon that will be displayed in Warps list. SIGN counts for any kind of sign and the type of")
- @ConfigComment("wood used will be reflected in the panel if the server supports it.")
- @ConfigComment("It uses native Minecraft material strings, but using string 'PLAYER_HEAD', it is possible to")
- @ConfigComment("use player heads instead. Beware that Mojang API rate limiting may prevent heads from loading.")
- @ConfigEntry(path = "icon")
- private String icon = "SIGN";
-
@ConfigComment("")
@ConfigComment("This list stores GameModes in which Level addon should not work.")
@ConfigComment("To disable addon it is necessary to write its name in new line that starts with -. Example:")
@@ -45,23 +37,12 @@ public class Settings implements ConfigObject
@ConfigEntry(path = "disabled-gamemodes")
private Set disabledGameModes = new HashSet<>();
- @ConfigComment("")
- @ConfigComment("Warp panel name formatting.")
- @ConfigComment("Example: &c will make names red. &f is white")
- @ConfigEntry(path = "name-format")
- private String nameFormat = "&f";
-
@ConfigComment("")
@ConfigComment("Warp panel default lore formatting.")
@ConfigComment("Example: &c will make lore red. &f is white")
@ConfigEntry(path = "lore-format")
private String loreFormat = "&f";
- @ConfigComment("")
- @ConfigComment("Allow random teleport - adds a button to the warp panel that goes to a random warp sign")
- @ConfigEntry(path = "random-allowed")
- private boolean randomAllowed = true;
-
@ConfigComment("")
@ConfigComment("Allow use in other worlds. Players must have the welcomewarpsigns.warp permission.")
@ConfigEntry(path = "allow-in-other-worlds")
@@ -155,42 +136,6 @@ public class Settings implements ConfigObject
}
- /**
- * This method returns the icon object.
- * @return the icon object.
- */
- public String getIcon()
- {
- return icon;
- }
-
-
- /**
- * This method sets the icon object value.
- * @param icon the icon object new value.
- */
- public void setIcon(String icon)
- {
- this.icon = icon;
- }
-
-
- /**
- * @return the nameFormat
- */
- public String getNameFormat() {
- return nameFormat;
- }
-
-
- /**
- * @param nameFormat the nameFormat to set
- */
- public void setNameFormat(String nameFormat) {
- this.nameFormat = nameFormat;
- }
-
-
/**
* @return the loreFormat
*/
@@ -207,22 +152,6 @@ public class Settings implements ConfigObject
}
- /**
- * @return the randomAllowed
- */
- public boolean isRandomAllowed() {
- return randomAllowed;
- }
-
-
- /**
- * @param randomAllowed the randomAllowed to set
- */
- public void setRandomAllowed(boolean randomAllowed) {
- this.randomAllowed = randomAllowed;
- }
-
-
/**
* @return the allowInOtherWorlds
*/
@@ -269,6 +198,4 @@ public class Settings implements ConfigObject
public void setWarpsCommand(String warpsCommand) {
this.warpsCommand = warpsCommand;
}
-
-
}
diff --git a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java
index a581d69..36d2805 100644
--- a/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java
+++ b/src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java
@@ -72,7 +72,7 @@ public class WarpSignsListener implements Listener {
&& !Tag.SIGNS.isTagged(location.getBlock().getType())) {
iterator.remove();
// Remove sign from warp panel cache
- addon.getWarpPanelManager().removeWarp(event.getWorld(), uuid);
+ addon.getSignCacheManager().removeWarp(event.getWorld(), uuid);
changed = true;
}
}
diff --git a/src/main/java/world/bentobox/warps/SignCacheItem.java b/src/main/java/world/bentobox/warps/managers/SignCacheItem.java
similarity index 96%
rename from src/main/java/world/bentobox/warps/SignCacheItem.java
rename to src/main/java/world/bentobox/warps/managers/SignCacheItem.java
index 1d0df5f..10e45af 100644
--- a/src/main/java/world/bentobox/warps/SignCacheItem.java
+++ b/src/main/java/world/bentobox/warps/managers/SignCacheItem.java
@@ -1,4 +1,4 @@
-package world.bentobox.warps;
+package world.bentobox.warps.managers;
import java.util.List;
diff --git a/src/main/java/world/bentobox/warps/SignCacheManager.java b/src/main/java/world/bentobox/warps/managers/SignCacheManager.java
similarity index 91%
rename from src/main/java/world/bentobox/warps/SignCacheManager.java
rename to src/main/java/world/bentobox/warps/managers/SignCacheManager.java
index 5c7a03e..596d718 100644
--- a/src/main/java/world/bentobox/warps/SignCacheManager.java
+++ b/src/main/java/world/bentobox/warps/managers/SignCacheManager.java
@@ -1,4 +1,4 @@
-package world.bentobox.warps;
+package world.bentobox.warps.managers;
import java.util.HashMap;
import java.util.Map;
@@ -10,6 +10,7 @@ import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.database.Database;
+import world.bentobox.warps.Warp;
import world.bentobox.warps.objects.SignCache;
public class SignCacheManager {
@@ -36,7 +37,7 @@ public class SignCacheManager {
});
}
- void saveCache() {
+ public void saveCache() {
cachedSigns.forEach((w, m) -> handler.saveObjectAsync(new SignCache(w, m)));
}
@@ -47,7 +48,7 @@ public class SignCacheManager {
* @return SignCacheItem
*/
@NonNull
- SignCacheItem getSignItem(World world, UUID warpOwner) {
+ public SignCacheItem getSignItem(World world, UUID warpOwner) {
// Add the worlds if we haven't seen this before
cachedSigns.putIfAbsent(world, new HashMap<>());
// Get from cache if available
@@ -70,7 +71,7 @@ public class SignCacheManager {
* @param key - uuid of owner
* @return true if item is removed from cache
*/
- boolean removeWarp(World world, UUID key) {
+ public boolean removeWarp(World world, UUID key) {
if (cachedSigns.containsKey(world)) {
return cachedSigns.get(world).remove(key) != null;
}
diff --git a/src/main/java/world/bentobox/warps/WarpSignsManager.java b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java
similarity index 87%
rename from src/main/java/world/bentobox/warps/WarpSignsManager.java
rename to src/main/java/world/bentobox/warps/managers/WarpSignsManager.java
index b4686f2..62a7e07 100644
--- a/src/main/java/world/bentobox/warps/WarpSignsManager.java
+++ b/src/main/java/world/bentobox/warps/managers/WarpSignsManager.java
@@ -1,4 +1,4 @@
-package world.bentobox.warps;
+package world.bentobox.warps.managers;
import java.util.ArrayList;
import java.util.Arrays;
@@ -38,8 +38,11 @@ import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.util.Util;
+import world.bentobox.warps.Warp;
import world.bentobox.warps.event.WarpInitiateEvent;
import world.bentobox.warps.objects.WarpsData;
+import world.bentobox.warps.panels.Utils;
+
/**
* Handles warping. Players can add one sign
@@ -151,7 +154,7 @@ public class WarpSignsManager {
return r;
}
- List processWarpMap(CompletableFuture> r, @NonNull World world) {
+ public List processWarpMap(CompletableFuture> r, @NonNull World world) {
// Remove any null locations - this can happen if an admin changes the name of the world and signs point to old locations
getWarpMap(world).values().removeIf(Objects::isNull);
// Bigger value of time means a more recent login
@@ -191,7 +194,7 @@ public class WarpSignsManager {
/**
* Load the warps and check if they still exist
*/
- void loadWarpList() {
+ public void loadWarpList() {
addon.log("Loading warps...");
worldsWarpList = new HashMap<>();
if (handler.objectExists(WARPS)) {
@@ -246,7 +249,7 @@ public class WarpSignsManager {
.map(User::getInstance)
.ifPresent(user -> user.sendMessage("warps.sign-removed"));
// Remove sign from warp panel cache
- addon.getWarpPanelManager().removeWarp(loc.getWorld(), en.getKey());
+ addon.getSignCacheManager().removeWarp(loc.getWorld(), en.getKey());
it.remove();
}
}
@@ -265,7 +268,7 @@ public class WarpSignsManager {
}
// Remove sign from warp panel cache
- addon.getWarpPanelManager().removeWarp(world, uuid);
+ addon.getSignCacheManager().removeWarp(world, uuid);
saveWarpList();
}
@@ -283,7 +286,7 @@ public class WarpSignsManager {
*/
public void saveWarpList() {
handler.saveObjectAsync(warpsData.save(worldsWarpList));
- addon.getWarpPanelManager().saveCache();
+ addon.getSignCacheManager().saveCache();
}
/**
@@ -311,7 +314,6 @@ public class WarpSignsManager {
result.set(i, ChatColor.translateAlternateColorCodes('&', addon.getSettings().getLoreFormat()) + result.get(i));
}
// Get the sign type
-
String prefix = plugin.getIWM().getAddon(world).map(Addon::getPermissionPrefix).orElse("");
Material icon;
@@ -319,20 +321,21 @@ public class WarpSignsManager {
if (!prefix.isEmpty())
{
icon = Material.matchMaterial(
- this.getPermissionValue(Objects.requireNonNull(User.getInstance(uuid)),
- prefix + "island.warp",
- this.addon.getSettings().getIcon()));
+ Utils.getPermissionValue(User.getInstance(uuid), prefix + "island.warp",
+ Material.OAK_SIGN.name()));
}
else
{
- icon = Material.matchMaterial(this.addon.getSettings().getIcon());
+ icon = null;
}
- if (icon == null || icon.name().contains("SIGN")) {
+ if (icon != null && icon.name().contains("SIGN")) {
return new SignCacheItem(result, Material.valueOf(sign.getType().name().replace("WALL_", "")));
}
- return new SignCacheItem(result, icon);
-
+ else
+ {
+ return new SignCacheItem(result, icon);
+ }
}
/**
@@ -460,54 +463,4 @@ public class WarpSignsManager {
public boolean hasWarp(@NonNull World world, @NonNull UUID playerUUID) {
return getWarpMap(world).containsKey(playerUUID);
}
-
-
- // ---------------------------------------------------------------------
- // Section: Other methods
- // ---------------------------------------------------------------------
-
-
- /**
- * This method gets string value of given permission prefix. If user does not have
- * given permission or it have all (*), then return default value.
- * @param user User who's permission should be checked.
- * @param permissionPrefix Prefix that need to be found.
- * @param defaultValue Default value that will be returned if permission not found.
- * @return String value that follows permissionPrefix.
- */
- private String getPermissionValue(@NonNull User user, @NonNull String permissionPrefix, @NonNull String defaultValue)
- {
- if (user.isPlayer())
- {
- if (permissionPrefix.endsWith("."))
- {
- permissionPrefix = permissionPrefix.substring(0, permissionPrefix.length() - 1);
- }
-
- String permPrefix = permissionPrefix + ".";
-
- List permissions = user.getEffectivePermissions().stream()
- .map(PermissionAttachmentInfo::getPermission)
- .filter(permission -> permission.startsWith(permPrefix))
- .toList();
-
- for (String permission : permissions)
- {
- if (permission.contains(permPrefix + "*"))
- {
- // * means all. So continue to search more specific.
- continue;
- }
-
- String[] parts = permission.split(permPrefix);
-
- if (parts.length > 1)
- {
- return parts[1];
- }
- }
- }
-
- return defaultValue;
- }
}
diff --git a/src/main/java/world/bentobox/warps/objects/SignCache.java b/src/main/java/world/bentobox/warps/objects/SignCache.java
index 8f8e3e6..16b41bc 100644
--- a/src/main/java/world/bentobox/warps/objects/SignCache.java
+++ b/src/main/java/world/bentobox/warps/objects/SignCache.java
@@ -10,7 +10,7 @@ import com.google.gson.annotations.Expose;
import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.database.objects.Table;
-import world.bentobox.warps.SignCacheItem;
+import world.bentobox.warps.managers.SignCacheItem;
@Table(name = "WarpSignCache")
public class SignCache implements DataObject {
diff --git a/src/main/java/world/bentobox/warps/panels/Utils.java b/src/main/java/world/bentobox/warps/panels/Utils.java
new file mode 100644
index 0000000..2c4b8c8
--- /dev/null
+++ b/src/main/java/world/bentobox/warps/panels/Utils.java
@@ -0,0 +1,76 @@
+//
+// Created by BONNe
+// Copyright - 2021
+//
+
+
+package world.bentobox.warps.panels;
+
+
+import org.bukkit.permissions.PermissionAttachmentInfo;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import world.bentobox.bentobox.api.user.User;
+
+
+public class Utils
+{
+ /**
+ * This method sends a message to the user with appended "prefix" text before message.
+ * @param user User who receives message.
+ * @param translationText Translation text of the message.
+ * @param parameters Parameters for the translation text.
+ */
+ public static void sendMessage(User user, String translationText, String... parameters)
+ {
+ user.sendMessage(user.getTranslation( "warps.conversations.prefix") +
+ user.getTranslation( translationText, parameters));
+ }
+
+
+ /**
+ * This method gets string value of given permission prefix. If user does not have given permission or it have all
+ * (*), then return default value.
+ *
+ * @param user User who's permission should be checked.
+ * @param permissionPrefix Prefix that need to be found.
+ * @param defaultValue Default value that will be returned if permission not found.
+ * @return String value that follows permissionPrefix.
+ */
+ public static String getPermissionValue(User user, String permissionPrefix, String defaultValue)
+ {
+ if (user.isPlayer())
+ {
+ if (permissionPrefix.endsWith("."))
+ {
+ permissionPrefix = permissionPrefix.substring(0, permissionPrefix.length() - 1);
+ }
+
+ String permPrefix = permissionPrefix + ".";
+
+ List permissions = user.getEffectivePermissions().stream().
+ map(PermissionAttachmentInfo::getPermission).
+ filter(permission -> permission.startsWith(permPrefix)).
+ collect(Collectors.toList());
+
+ for (String permission : permissions)
+ {
+ if (permission.contains(permPrefix + "*"))
+ {
+ // * means all. So continue to search more specific.
+ continue;
+ }
+
+ String[] parts = permission.split(permPrefix);
+
+ if (parts.length > 1)
+ {
+ return parts[1];
+ }
+ }
+ }
+
+ return defaultValue;
+ }
+}
diff --git a/src/main/java/world/bentobox/warps/panels/WarpsPanel.java b/src/main/java/world/bentobox/warps/panels/WarpsPanel.java
new file mode 100644
index 0000000..0942783
--- /dev/null
+++ b/src/main/java/world/bentobox/warps/panels/WarpsPanel.java
@@ -0,0 +1,598 @@
+//
+// Created by BONNe
+// Copyright - 2021
+//
+
+package world.bentobox.warps.panels;
+
+
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+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.io.File;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import world.bentobox.bentobox.api.panels.PanelItem;
+import world.bentobox.bentobox.api.panels.TemplatedPanel;
+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.user.User;
+import world.bentobox.warps.managers.SignCacheItem;
+import world.bentobox.warps.managers.SignCacheManager;
+import world.bentobox.warps.Warp;
+
+
+/**
+ * This class shows how to set up easy panel by using BentoBox PanelBuilder API
+ */
+public class WarpsPanel
+{
+// ---------------------------------------------------------------------
+// Section: Constructor
+// ---------------------------------------------------------------------
+
+
+ /**
+ * This is internal constructor. It is used internally in current class to avoid creating objects everywhere.
+ *
+ * @param addon VisitAddon object
+ * @param world World where user will be teleported
+ * @param user User who opens panel
+ */
+ private WarpsPanel(Warp addon,
+ World world,
+ User user)
+ {
+ this.addon = addon;
+ this.manager = this.addon.getSignCacheManager();
+ this.user = user;
+ this.world = world;
+ }
+
+
+// ---------------------------------------------------------------------
+// Section: Methods
+// ---------------------------------------------------------------------
+
+
+ /**
+ * This method collects and validates sign warps that could be displayed in GUI.
+ * @param completed CompletableFeature that triggers panel opening.
+ */
+ private void collectValidWarps(CompletableFuture completed)
+ {
+ this.addon.getWarpSignsManager().getSortedWarps(this.world).
+ thenAccept(warps ->
+ {
+ // Cache and clean the signs
+ Iterator iterator = warps.iterator();
+
+ while (iterator.hasNext())
+ {
+ UUID warpOwner = iterator.next();
+ @NonNull
+ SignCacheItem sign = this.manager.getSignItem(this.world, warpOwner);
+
+ if (!sign.isReal())
+ {
+ iterator.remove();
+ this.addon.getWarpSignsManager().removeWarpFromMap(this.world, warpOwner);
+ }
+ }
+
+ // Assign warps to element list.
+ this.elementList = warps;
+
+ // Build the main body
+ completed.complete(true);
+ });
+ }
+
+
+ /**
+ * This is wrapper around builder to trigger main GUI building.
+ */
+ private void initBuild()
+ {
+ CompletableFuture collectWarps = new CompletableFuture<>();
+ this.collectValidWarps(collectWarps);
+ collectWarps.thenAccept(done -> {
+ if (done)
+ {
+ this.build();
+ }
+ });
+ }
+
+
+ /**
+ * Build method manages current panel opening. It uses BentoBox PanelAPI that is easy to use and users can get nice
+ * panels.
+ */
+ private void build()
+ {
+ // Do not open gui if there is no magic sticks.
+ if (this.elementList.isEmpty())
+ {
+ this.addon.logError("There are no available islands for visiting!");
+ Utils.sendMessage(this.user, "warps.error.no-warps-yet",
+ "[gamemode]", this.addon.getPlugin().getIWM().getAddon(this.world).
+ map(gamemode -> gamemode.getDescription().getName()).
+ orElse(""));
+ return;
+ }
+
+ // Start building panel.
+ TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder();
+
+ // Set main template.
+ panelBuilder.template("warps_panel", new File(this.addon.getDataFolder(), "panels"));
+ panelBuilder.user(this.user);
+ panelBuilder.world(this.user.getWorld());
+
+ // Register button builders
+ panelBuilder.registerTypeBuilder("WARP", this::createWarpButton);
+ panelBuilder.registerTypeBuilder("RANDOM", this::createRandomButton);
+
+ // Register next and previous builders
+ panelBuilder.registerTypeBuilder("NEXT", this::createNextButton);
+ panelBuilder.registerTypeBuilder("PREVIOUS", this::createPreviousButton);
+
+ // Register unknown type builder.
+ panelBuilder.build();
+ }
+
+
+// ---------------------------------------------------------------------
+// Section: Buttons
+// ---------------------------------------------------------------------
+
+
+ /**
+ * Create next button panel item.
+ *
+ * @param template the template
+ * @param slot the slot
+ * @return the panel item
+ */
+ @Nullable
+ private PanelItem createNextButton(@NonNull ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
+ {
+ int size = this.elementList.size();
+
+ if (size <= slot.amountMap().getOrDefault("WARP", 1) ||
+ 1.0 * size / slot.amountMap().getOrDefault("WARP", 1) <= this.pageIndex + 1)
+ {
+ // There are no next elements
+ return null;
+ }
+
+ int nextPageIndex = this.pageIndex + 2;
+
+ PanelItemBuilder builder = new PanelItemBuilder();
+
+ if (template.icon() != null)
+ {
+ ItemStack clone = template.icon().clone();
+
+ if ((Boolean) template.dataMap().getOrDefault("indexing", false))
+ {
+ clone.setAmount(nextPageIndex);
+ }
+
+ builder.icon(clone);
+ }
+
+ if (template.title() != null)
+ {
+ builder.name(this.user.getTranslation(this.world, template.title()));
+ }
+
+ if (template.description() != null)
+ {
+ builder.description(this.user.getTranslation(this.world, template.description(),
+ "[number]", String.valueOf(nextPageIndex)));
+ }
+
+ // Add ClickHandler
+ builder.clickHandler((panel, user, clickType, i) ->
+ {
+ template.actions().forEach(action -> {
+ if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN)
+ {
+ if ("NEXT".equalsIgnoreCase(action.actionType()))
+ {
+ // Next button ignores click type currently.
+ this.pageIndex++;
+ this.build();
+ }
+ }
+ });
+
+ // Always return true.
+ return true;
+ });
+
+ // Collect tooltips.
+ List tooltips = template.actions().stream().
+ filter(action -> action.tooltip() != null).
+ map(action -> this.user.getTranslation(this.world, action.tooltip())).
+ filter(text -> !text.isBlank()).
+ collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size())));
+
+ // Add tooltips.
+ if (!tooltips.isEmpty())
+ {
+ // Empty line and tooltips.
+ builder.description("");
+ builder.description(tooltips);
+ }
+
+ return builder.build();
+ }
+
+
+ /**
+ * Create previous button panel item.
+ *
+ * @param template the template
+ * @param slot the slot
+ * @return the panel item
+ */
+ @Nullable
+ private PanelItem createPreviousButton(@NonNull ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
+ {
+ if (this.pageIndex == 0)
+ {
+ // There are no next elements
+ return null;
+ }
+
+ int previousPageIndex = this.pageIndex;
+
+ PanelItemBuilder builder = new PanelItemBuilder();
+
+ if (template.icon() != null)
+ {
+ ItemStack clone = template.icon().clone();
+
+ if ((Boolean) template.dataMap().getOrDefault("indexing", false))
+ {
+ clone.setAmount(previousPageIndex);
+ }
+
+ builder.icon(clone);
+ }
+
+ if (template.title() != null)
+ {
+ builder.name(this.user.getTranslation(this.world, template.title()));
+ }
+
+ if (template.description() != null)
+ {
+ builder.description(this.user.getTranslation(this.world, template.description(),
+ "[number]", String.valueOf(previousPageIndex)));
+ }
+
+ // Add ClickHandler
+ // Add ClickHandler
+ builder.clickHandler((panel, user, clickType, i) ->
+ {
+ template.actions().forEach(action -> {
+ if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN)
+ {
+ if ("PREVIOUS".equalsIgnoreCase(action.actionType()))
+ {
+ // Next button ignores click type currently.
+ this.pageIndex--;
+ this.build();
+ }
+ }
+ });
+
+ // Always return true.
+ return true;
+ });
+
+ // Collect tooltips.
+ List tooltips = template.actions().stream().
+ filter(action -> action.tooltip() != null).
+ map(action -> this.user.getTranslation(this.world, action.tooltip())).
+ filter(text -> !text.isBlank()).
+ collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size())));
+
+ // Add tooltips.
+ if (!tooltips.isEmpty())
+ {
+ // Empty line and tooltips.
+ builder.description("");
+ builder.description(tooltips);
+ }
+
+ return builder.build();
+ }
+
+
+ /**
+ * This method creates and returns warp button.
+ *
+ * @return PanelItem that represents warp button.
+ */
+ @Nullable
+ private PanelItem createWarpButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
+ {
+ if (this.elementList.isEmpty())
+ {
+ // Does not contain any sticks.
+ return null;
+ }
+
+ int index = this.pageIndex * slot.amountMap().getOrDefault("WARP", 1) + slot.slot();
+
+ if (index >= this.elementList.size())
+ {
+ // Out of index.
+ return null;
+ }
+
+ return this.createWarpButton(template, this.elementList.get(index), "warp");
+ }
+
+
+ /**
+ * This method creates and returns random warp button.
+ *
+ * @return PanelItem that represents random warp button.
+ */
+ @Nullable
+ private PanelItem createRandomButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot)
+ {
+ if (this.elementList.size() < 2)
+ {
+ // Does not contain any sticks.
+ return null;
+ }
+
+ int index = random.nextInt(this.elementList.size());
+ return this.createWarpButton(template, this.elementList.get(index), "random");
+ }
+
+
+// ---------------------------------------------------------------------
+// Section: Other methods
+// ---------------------------------------------------------------------
+
+
+ /**
+ * This method creates and returns button that switch to next page in view mode.
+ *
+ * @return PanelItem that allows to select next owner view page.
+ */
+ private PanelItem createWarpButton(ItemTemplateRecord template, UUID ownerUUID, String type)
+ {
+ if (ownerUUID == null)
+ {
+ // return as owner has no owner. Empty button will be created.
+ return null;
+ }
+
+ SignCacheItem signCache = this.manager.getSignItem(this.world, ownerUUID);
+
+ if (!signCache.isReal())
+ {
+ this.addon.getWarpSignsManager().removeWarpFromMap(this.world, ownerUUID);
+ // return as signCache is not real anymore.
+ return null;
+ }
+
+ final String reference = "warps.gui.buttons." + type + ".";
+
+ String ownerName = addon.getPlugin().getPlayers().getName(ownerUUID);
+
+ // Get settings for owner.
+ PanelItemBuilder builder = new PanelItemBuilder();
+
+ if (template.icon() != null)
+ {
+ if (template.icon().getType().equals(Material.PLAYER_HEAD))
+ {
+ builder.icon(ownerName);
+ }
+ else
+ {
+ builder.icon(template.icon().clone());
+ }
+ }
+ else
+ {
+ // Check owner for a specific icon
+ Material material = signCache.getType();
+
+ if (material == null)
+ {
+ // Set oak sign as icon was not specified.
+ material = Material.OAK_SIGN;
+ }
+
+ if (material == Material.PLAYER_HEAD)
+ {
+ builder.icon(ownerName);
+ }
+ else
+ {
+ builder.icon(material);
+ }
+ }
+
+ if (template.title() != null)
+ {
+ builder.name(this.user.getTranslation(this.world, template.title(),
+ "[name]", ownerName));
+ }
+ else
+ {
+ builder.name(this.user.getTranslation(reference + "name",
+ "[name]", ownerName));
+ }
+
+ // Process Description of the button.
+ // Generate [sign_text] text
+
+ String descriptionText;
+
+ if (template.description() != null)
+ {
+ descriptionText = this.user.getTranslationOrNothing(template.description(),
+ "[name]", ownerName,
+ "[sign_text]", String.join("\n", signCache.getSignText())).
+ replaceAll("(?m)^[ \\t]*\\r?\\n", "").
+ replaceAll("(?
+ {
+ template.actions().forEach(action -> {
+ if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN)
+ {
+ if ("WARP".equalsIgnoreCase(action.actionType()))
+ {
+ this.runCommandCall(ownerName);
+ }
+ }
+ });
+
+ // Always return true.
+ return true;
+ });
+
+ // Collect tooltips.
+ List tooltips = template.actions().stream().
+ filter(action -> action.tooltip() != null).
+ map(action -> this.user.getTranslation(this.world, action.tooltip())).
+ filter(text -> !text.isBlank()).
+ collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size())));
+
+ // Add tooltips.
+ if (!tooltips.isEmpty())
+ {
+ // Empty line and tooltips.
+ builder.description("");
+ builder.description(tooltips);
+ }
+
+ return builder.build();
+ }
+
+
+ /**
+ * This method runs command call that allows player to visit clicked island.
+ */
+ private void runCommandCall(String ownerName)
+ {
+ // Get first player command label.
+ String command = this.addon.getSettings().getWarpCommand().split(" ")[0];
+
+ String gamemodeCommand = this.addon.getPlugin().getIWM().getAddon(this.world).
+ map(gamemode -> gamemode.getPlayerCommand().map(Command::getLabel).orElse("")).
+ orElse("");
+
+ if (gamemodeCommand.isEmpty())
+ {
+ this.addon.log(this.user.getName() + " called: `" + command + " " + ownerName + "`");
+ this.user.performCommand(command + " " + ownerName);
+ }
+ else
+ {
+ this.addon.log(this.user.getName() + " called: `" + gamemodeCommand + " " + command + " " + ownerName + "`");
+ this.user.performCommand(gamemodeCommand + " " + command + " " + ownerName);
+ }
+
+ // Close inventory
+ this.user.closeInventory();
+ }
+
+
+// ---------------------------------------------------------------------
+// Section: Static methods
+// ---------------------------------------------------------------------
+
+
+ /**
+ * This method is used to open UserPanel outside this class. It will be much easier to open panel with single method
+ * call then initializing new object.
+ *
+ * @param addon Warps object
+ * @param world World where user will be teleported
+ * @param user User who opens panel
+ */
+ public static void openPanel(Warp addon,
+ World world,
+ User user)
+ {
+ new WarpsPanel(addon, world, user).initBuild();
+ }
+
+
+// ---------------------------------------------------------------------
+// Section: Variables
+// ---------------------------------------------------------------------
+
+
+ /**
+ * This variable allows to access addon object.
+ */
+ private final Warp addon;
+
+ /**
+ * This variable allows to access addon manager object.
+ */
+ private final SignCacheManager manager;
+
+ /**
+ * This variable holds user who opens panel. Without it panel cannot be opened.
+ */
+ private final User user;
+
+ /**
+ * This variable holds world where panel is opened. Without it panel cannot be opened.
+ */
+ private final World world;
+
+ /**
+ * This variable stores filtered elements.
+ */
+ private List elementList;
+
+ /**
+ * This variable holds current pageIndex for multi-page island choosing.
+ */
+ private int pageIndex;
+
+ /**
+ * Random for finding random warp.
+ */
+ private static final Random random = new Random();
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 3a8818b..a647e5c 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -12,29 +12,16 @@ warplevelrestriction: 10
# Not case sensitive!
welcomeLine: '[Welcome]'
#
-# Icon that will be displayed in Warps list. SIGN counts for any kind of sign and the type of
-# wood used will be reflected in the panel if the server supports it.
-# It uses native Minecraft material strings, but using string 'PLAYER_HEAD', it is possible to
-# use player heads instead. Beware that Mojang API rate limiting may prevent heads from loading.
-icon: 'SIGN'
-#
# This list stores GameModes in which Level addon should not work.
# To disable addon it is necessary to write its name in new line that starts with -. Example:
# disabled-gamemodes:
# - BSkyBlock
disabled-gamemodes: []
#
-# Warp panel name formatting.
-# Example: &c will make names red, &f is white
-name-format: "&f"
-#
# Warp panel default lore formatting.
# Example: &c will make lore red. &f is white
lore-format: "&f"
#
-# Allow random teleport - adds a button to the warp panel that goes to a random warp sign
-random-allowed: true
-#
# Allow use in other worlds. Players must have the welcomewarpsigns.warp permission.
allow-in-other-worlds: false
#
diff --git a/src/main/resources/locales/de.yml b/src/main/resources/locales/de.yml
index e5b24dd..a18411b 100644
--- a/src/main/resources/locales/de.yml
+++ b/src/main/resources/locales/de.yml
@@ -1,30 +1,46 @@
-#
-# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
-# the one at http://yaml-online-parser.appspot.com #
+---
warp:
help:
description: Warpt dich zu dem Warp Schild von dem Spieler
- parameters:
+ parameters: ""
warps:
- deactivate: '&c Altes Warp Schild deaktiviert!'
+ deactivate: "&c Altes Warp Schild deaktiviert!"
error:
- does-not-exist: '&c Oh nein! Dieser Warp existiert nicht mehr!'
- no-permission: '&c Hierfür hast du keine Rechte!'
- no-remove: '&c Du kannst dieses Schild nicht entfernen!'
- no-warps-yet: '&c Es sind noch keine Warps verfügbar'
- not-enough-level: '&c Dein Insel-Level ist nicht hoch gneug!'
- not-on-island: '&c Dafür musst du auf deiner Insel sein!'
- not-safe: '&c Dieser Warp ist nicht sicher!'
- your-level-is: '&c Dein Insel-Level ist erst [level] und muss höher als [required] sein.
- Nutze das Level Kommando.'
+ does-not-exist: "&c Oh nein! Dieser Warp existiert nicht mehr!"
+ no-permission: "&c Hierfür hast du keine Rechte!"
+ no-remove: "&c Du kannst dieses Schild nicht entfernen!"
+ no-warps-yet: "&c Es sind noch keine Warps verfügbar"
+ not-enough-level: "&c Dein Insel-Level ist nicht hoch gneug!"
+ not-on-island: "&c Dafür musst du auf deiner Insel sein!"
+ not-safe: "&c Dieser Warp ist nicht sicher!"
+ your-level-is: "&c Dein Insel-Level ist erst [level] und muss höher als [required]
+ sein. Nutze das Level Kommando."
help:
description: Öffnet das Warps Panel
- next: '&6 Nächste Seite'
- player-warped: '&2 [name] hat sich zu deinem Warp Schild gewarpt!'
- previous: '&6 Vorherige Seite'
- random: '&4 Zufälliger Warp'
- sign-removed: '&c Warp Schild entfernt!'
- success: '&a Erfolg!'
- title: Warp Schilder
- warpTip: '&6 Platziere ein Warp Schild mit [text] in der ersten Zeile'
- warpToPlayersSign: '&6 Warpe zu [player]''s Schild'
+ player-warped: "&2 [name] hat sich zu deinem Warp Schild gewarpt!"
+ sign-removed: "&c Warp Schild entfernt!"
+ success: "&a Erfolg!"
+ warpTip: "&6 Platziere ein Warp Schild mit [text] in der ersten Zeile"
+ warpToPlayersSign: "&6 Warpe zu [player]'s Schild"
+ gui:
+ titles:
+ warp-title: "&0&l Warp-Schild"
+ buttons:
+ previous:
+ name: "&f&l Vorherige Seite"
+ description: "&7 Zur Seite [number] wechseln"
+ next:
+ name: "&f&l Nächste Seite"
+ description: "&7 Zur Seite [number] wechseln"
+ warp:
+ name: "&f&l [name]"
+ description: "[sign_text]"
+ random:
+ name: "&f&l Random Warp"
+ description: "&7 Hmm, wo werde ich erscheinen?"
+ tips:
+ click-to-previous: "&e Klicken &7, um die vorherige Seite anzuzeigen."
+ click-to-next: "&e Klicken &7, um die nächste Seite anzuzeigen."
+ click-to-warp: "&e Zum Warpen &7 klicken."
+ conversations:
+ prefix: "&l&6 [BentoBox]: &r"
diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml
index 93ae795..757677e 100755
--- a/src/main/resources/locales/en-US.yml
+++ b/src/main/resources/locales/en-US.yml
@@ -20,14 +20,43 @@ warps:
your-level-is: "&c Your island level is only [level] and must be higher than [required]. Run the level command."
help:
description: "open the warps panel"
- next: "&6 Next page"
player-warped: "&2 [name] warped to your warp sign!"
- previous: "&6 Previous page"
- random: "&4 Random Warp"
sign-removed: "&c Warp sign removed!"
success: "&a Success!"
- title: "Warp Signs"
warpTip: "&6 Place a warp sign with [text] on the top"
warpToPlayersSign: "&6 Warping to [player]'s sign"
+ gui:
+ titles:
+ # The title of warp panel
+ warp-title: '&0&l Warp Signs'
+ buttons:
+ # Button that is used in multi-page GUIs which allows to return to previous page.
+ previous:
+ name: "&f&l Previous Page"
+ description: |-
+ &7 Switch to [number] page
+ # Button that is used in multi-page GUIs which allows to go to next page.
+ next:
+ name: "&f&l Next Page"
+ description: |-
+ &7 Switch to [number] page
+ # Button for a warp
+ warp:
+ name: "&f&l [name]"
+ description: |-
+ [sign_text]
+ # Button for a random warp
+ random:
+ name: "&f&l Random Warp"
+ description: |-
+ &7 Hmm, where will I appear?
+ tips:
+ click-to-previous: "&e Click &7 to view previous page."
+ click-to-next: "&e Click &7 to view next page."
+ click-to-warp: "&e Click &7 to warp."
+ conversations:
+ # Prefix for messages that are send from server.
+ prefix: "&l&6 [BentoBox]: &r"
+
diff --git a/src/main/resources/locales/fr.yml b/src/main/resources/locales/fr.yml
index 0fcee35..bf15dcd 100644
--- a/src/main/resources/locales/fr.yml
+++ b/src/main/resources/locales/fr.yml
@@ -9,20 +9,20 @@ warps:
does-not-exist: "&cCe Warp n'existe plus !"
no-permission: "&cVous n'avez pas la permission pour faire cela !"
no-remove: "&cVous ne pouvez pas supprimer ce panneau !"
+ no-warps-yet: "&cIl n'y a encore aucun Warp sur ce serveur."
not-enough-level: "&cVotre niveau d'île n'est pas assez élevé pour faire cela
!"
not-on-island: "&cVous devez être sur votre île pour faire cela !"
not-safe: "&cCe Warp n'est pas sûr!"
- no-warps-yet: "&cIl n'y a encore aucun Warp sur ce serveur."
your-level-is: "&cVotre île est seulement niveau [level] et doit être niveau [required]."
help:
description: Ouvre le menu des Warps
next: "&6Page suivante"
- player-warped: "&2[name] s'est téléporté sur votre île !"
+ player-warped: "& 2 [pseudo] s'est téléporté à votre panneau Warp !"
previous: "&6Page précédente"
+ random: "&4 Warp aléatoire "
sign-removed: "&cPanneau de Warp supprimé !"
success: "&aSuccès !"
title: Panneau Warp
warpTip: "&6Placez un panneau et écrivez [text] sur la première ligne."
- warpToPlayersSign: "&6Téléportation sur l'île de [player]..."
- random: "&4Warp aléatoire"
+ warpToPlayersSign: "&6 Téléportation vers le panneau de [pseudo]"
diff --git a/src/main/resources/locales/hu.yml b/src/main/resources/locales/hu.yml
index 6c7e508..0e6f473 100644
--- a/src/main/resources/locales/hu.yml
+++ b/src/main/resources/locales/hu.yml
@@ -1,15 +1,11 @@
-###########################################################################################
-# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
-# the one at http://yaml-online-parser.appspot.com #
-###########################################################################################
-
-warp:
- help:
- description: "Teleportálás a játékos teleport táblájához"
- parameters:
-warps:
+---
+warp:
+ help:
+ description: Teleportálás a játékos teleport táblájához
+ parameters: ""
+warps:
deactivate: "&cRégi teleport tábla deaktiválva!"
- error:
+ error:
does-not-exist: "&cAjjaj! Ez a teleport nem létezik!"
no-permission: "&cNincs jogod ehhez!"
no-remove: "&cNem törölheted ezt a táblát!"
@@ -17,17 +13,16 @@ warps:
not-enough-level: "&cA szigeted szintje nem elég magas!"
not-on-island: "&cEhhez szigeten kell lenned!"
not-safe: "&cEz a teleport nem biztonságos!"
- your-level-is: "&cJelenleg a sziget szinted [level], és nagyobbnak kell lennie, mint [required]."
- help:
- description: "Teleportok panel megnyitása"
+ your-level-is: "&cJelenleg a sziget szinted [level], és nagyobbnak kell lennie,
+ mint [required]."
+ help:
+ description: Teleportok panel megnyitása
next: "&6Következő oldal"
player-warped: "&2[name] teleportált a teleport tábládhoz!"
previous: "&6Előző oldal"
random: "&4Véletlenszerű Teleport"
sign-removed: "&cTeleport tábla törölve!"
success: "&aSikeres!"
- title: "Teleport Táblák"
+ title: Teleport Táblák
warpTip: "&6Helyezz le egy teleport táblát a következő szöveggel [text] a tetején"
warpToPlayersSign: "&6Teleportálás [player] táblájához"
-
-
diff --git a/src/main/resources/locales/id.yml b/src/main/resources/locales/id.yml
new file mode 100644
index 0000000..c7e4a8e
--- /dev/null
+++ b/src/main/resources/locales/id.yml
@@ -0,0 +1,28 @@
+---
+warp:
+ help:
+ description: warp ke tanda warp pemain
+ parameters: ""
+warps:
+ deactivate: "&c Tanda warp lama dinonaktifkan!"
+ error:
+ does-not-exist: "&c Oh! Warp itu tidak ada lagi!"
+ no-permission: "&c Anda tidak memiliki izin untuk melakukan itu!"
+ no-remove: "&c Anda tidak dapat menghapus tanda itu!"
+ no-warps-yet: "&c Belum ada warps yang tersedia"
+ not-enough-level: "&c Level pulaumu tidak cukup tinggi!"
+ not-on-island: "&c Anda harus berada di pulau Anda untuk melakukan itu!"
+ not-safe: "&c Lengkungan itu tidak aman!"
+ your-level-is: "&c Level pulau Anda hanya [level] dan harus lebih tinggi dari
+ [required]. Jalankan perintah level."
+ help:
+ description: buka panel warps
+ next: "&6 Halaman berikutnya"
+ player-warped: "&2 [name] mengunjungi tanda warp Anda!"
+ previous: "&6 Halaman sebelumnya"
+ random: "&4 Warp Acak"
+ sign-removed: "&c Tanda warp dihilangkan!"
+ success: "&a Sukses!"
+ title: Tanda Warp
+ warpTip: "&6 Tempatkan tanda warp dengan [text] di atas\n"
+ warpToPlayersSign: "&6 Pergi ke tanda [player]'s"
diff --git a/src/main/resources/locales/it.yml b/src/main/resources/locales/it.yml
new file mode 100644
index 0000000..ccde20d
--- /dev/null
+++ b/src/main/resources/locales/it.yml
@@ -0,0 +1,29 @@
+---
+warp:
+ help:
+ description: teletrasporto al cartello Warp del giocatore
+ parameters: ""
+warps:
+ deactivate: "&c Vecchio cartello Warp disattivato!"
+ error:
+ does-not-exist: "&c Quel cartello Warp non esiste più!"
+ no-permission: "&c Non hai i permessi per farlo!"
+ no-remove: "&c Non puoi rimuovere quel cartello!"
+ no-warps-yet: "&c Non ci sono ancora Warp disponibili"
+ not-enough-level: "&c Il tuo livello dell'isola non è abbastanza alto!"
+ not-on-island: "&c Devi essere nella tua isola per farlo!"
+ not-safe: "&c Il Warp non è sicuro!"
+ your-level-is: "&c Il tuo livello dell''isola è solo di [level] e deve essere
+ maggiore di [required]. Esegui il comando del calcolo dei livelli per aggiornare
+ il livello."
+ help:
+ description: apri il pannello dei Warp
+ next: "&6 Pagina Successiva"
+ player-warped: "&2 [name] teletrasportato al tuo cartello Warp!"
+ previous: "&6 Pagina Precedente"
+ random: "&4 Warp Random"
+ sign-removed: "&c Cartello Warp rimosso!"
+ success: "&a Successo!"
+ title: Cartelli Warp
+ warpTip: "&6 Piazza un cartello Warp con [text] scritto nella prima riga"
+ warpToPlayersSign: "&6 Teletrasporto al cartello Warp di [player]"
diff --git a/src/main/resources/locales/tr.yml b/src/main/resources/locales/tr.yml
index 5da34df..d60612c 100644
--- a/src/main/resources/locales/tr.yml
+++ b/src/main/resources/locales/tr.yml
@@ -8,20 +8,19 @@ warps:
error:
does-not-exist: "&cÜzgünüm. Böyle bir bölge artık yok!"
no-permission: "&4Buna yetkin yok!"
- not-safe: "&4Ada bölgesi güvenli değil!"
no-remove: "&4Bu tabelayı kıramazsın!"
no-warps-yet: "&4Böyle bir bölge henüz yok."
not-enough-level: "&4Bunu koyman için daha fazla ada leveline ihtiyacın var."
not-on-island: "&4Adanda değilsin."
+ not-safe: "&4Ada bölgesi güvenli değil!"
your-level-is: "&9Ada levelin &e[level] &9ve &e[required]&9'den fazla olması gerek!"
help:
description: Bölge panelini açar.
+ next: "&6Sonraki Sayfa"
player-warped: "&d[name] &9ada bölgene ışınlandı!"
+ previous: "&6Önceki sayfa"
+ random: "&4Rastgele bölgeye git!"
sign-removed: "&4Ada tabelası kaldırıldı!"
- success: "&aBaşarılı!"
title: "&dOyuncu bölgeleri &8- &5"
warpTip: "&6Ada bölgesi açmak için tabelanın en üstüne &a[text] &9yaz!"
warpToPlayersSign: "&d[player] &9bölgesine gidiliyor!"
- next: "&6Sonraki Sayfa"
- previous: "&6Önceki sayfa"
- random: "&4Rastgele bölgeye git!"
diff --git a/src/main/resources/locales/zh-TW.yml b/src/main/resources/locales/zh-TW.yml
new file mode 100644
index 0000000..62e8656
--- /dev/null
+++ b/src/main/resources/locales/zh-TW.yml
@@ -0,0 +1,27 @@
+---
+warp:
+ help:
+ description: 傳送到該玩家的傳送木牌處
+ parameters: ""
+warps:
+ deactivate: "&c 舊傳送牌已停用!"
+ error:
+ does-not-exist: "&c 哦不!那個傳送點已經沒了!"
+ no-permission: "&c 你沒有權限這樣做!"
+ no-remove: "&c 你拿不掉那個牌子的!"
+ no-warps-yet: "&c 暫無可用傳送點"
+ not-enough-level: "&c 你的島嶼等級不夠高!"
+ not-on-island: "&c 你得在自己的島嶼上操作!"
+ not-safe: "&c 目標傳送點不安全!"
+ your-level-is: "&c 你的島嶼現在 [level] 級,需要 [required] 級。 試試島嶼等級命令吧。"
+ help:
+ description: 打開傳送面板
+ next: "&6 下一頁"
+ player-warped: "&2 [name] 傳送到了你的傳送牌!"
+ previous: "&6 上一頁"
+ random: "&4 隨機傳送"
+ sign-removed: "&c 拆掉傳送牌了!"
+ success: "&成功!"
+ title: 傳送告示牌
+ warpTip: "&6 放個牌子第一行寫 [text] "
+ warpToPlayersSign: "&6 正傳送到 [player] 的牌子"
diff --git a/src/main/resources/panels/warps_panel.yml b/src/main/resources/panels/warps_panel.yml
new file mode 100644
index 0000000..9a7464f
--- /dev/null
+++ b/src/main/resources/panels/warps_panel.yml
@@ -0,0 +1,79 @@
+warps_panel:
+ title: warps.gui.titles.warp-title
+ type: INVENTORY
+ background:
+ icon: BLACK_STAINED_GLASS_PANE
+ title: "&b&r" # Empty text
+ border:
+ icon: BLACK_STAINED_GLASS_PANE
+ title: "&b&r" # Empty text
+ force-shown: []
+ content:
+ 2:
+ 2: warp_button
+ 3: warp_button
+ 4: warp_button
+ 5: warp_button
+ 6: warp_button
+ 7: warp_button
+ 8: warp_button
+ 3:
+ 1:
+ icon: TIPPED_ARROW:INSTANT_HEAL::::1
+ title: warps.gui.buttons.previous.name
+ description: warps.gui.buttons.previous.description
+ data:
+ type: PREVIOUS
+ indexing: true
+ actions:
+ left:
+ type: PREVIOUS
+ tooltip: warps.gui.tips.click-to-previous
+ 2: warp_button
+ 3: warp_button
+ 4: warp_button
+ 5: warp_button
+ 6: warp_button
+ 7: warp_button
+ 8: warp_button
+ 9:
+ icon: TIPPED_ARROW:JUMP::::1
+ title: warps.gui.buttons.next.name
+ description: warps.gui.buttons.next.description
+ data:
+ type: NEXT
+ indexing: true
+ actions:
+ left:
+ type: NEXT
+ tooltip: warps.gui.tips.click-to-next
+ 4:
+ 2: warp_button
+ 3: warp_button
+ 4: warp_button
+ 5: warp_button
+ 6: warp_button
+ 7: warp_button
+ 8: warp_button
+ 6:
+ 5:
+ icon: DROPPER
+ title: warps.gui.buttons.random.name
+ description: warps.gui.buttons.random.description
+ data:
+ type: RANDOM
+ actions:
+ warp:
+ click-type: left
+ tooltip: warps.gui.tips.click-to-warp
+ reusable:
+ warp_button:
+ icon: PLAYER_HEAD
+ title: warps.gui.buttons.warp.name
+ description: warps.gui.buttons.warp.description
+ data:
+ type: WARP
+ actions:
+ warp:
+ click-type: left
+ tooltip: warps.gui.tips.click-to-warp
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
deleted file mode 100644
index f26fe60..0000000
--- a/src/main/resources/plugin.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: Pladdon
-main: world.bentobox.warps.WarpsPladdon
-version: ${version}
-api-version: 1.16
-description: A Warp Pladdon for BentoBox
-author: tastybento
-depend:
- - BentoBox
diff --git a/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java b/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java
deleted file mode 100644
index d2af1f6..0000000
--- a/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java
+++ /dev/null
@@ -1,329 +0,0 @@
-package world.bentobox.warps;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.ItemFactory;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.scheduler.BukkitScheduler;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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;
-
-import world.bentobox.bentobox.BentoBox;
-import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
-import world.bentobox.bentobox.api.user.User;
-import world.bentobox.bentobox.database.AbstractDatabaseHandler;
-import world.bentobox.bentobox.database.DatabaseSetup;
-import world.bentobox.bentobox.managers.PlayersManager;
-import world.bentobox.warps.config.Settings;
-
-/**
- * @author tastybento
- *
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Bukkit.class, DatabaseSetup.class})
-public class WarpPanelManagerTest {
-
- @Mock
- private WarpSignsManager wsm;
- @Mock
- private Warp addon;
- @Mock
- private Player player;
- @Mock
- private User user;
- @Mock
- private World world;
- @Mock
- private Inventory top;
- @Mock
- private Settings settings;
- @Mock
- private static AbstractDatabaseHandler