Compare commits

...

67 Commits

Author SHA1 Message Date
tastybento 519a2d05fc Version 1.15.0 2024-02-03 08:30:12 -08:00
tastybento 86c089b694 Update tipped arrows in GUI Panel 2024-01-21 09:09:17 -08:00
tastybento 3417633c4d Version 1.14.1 2024-01-21 09:09:12 -08:00
tastybento b16d5102b1
Merge pull request #129 from BentoBoxWorld/tastybento-patch-1
Update addon.yml
2024-01-12 14:37:29 -08:00
tastybento 4375eba030
Update addon.yml
Fix because the warps command got its own perm from a1e03af
2024-01-12 14:36:38 -08:00
tastybento bc1e92ee8d Add support for hanging signs.
Warps to below the sign.
2024-01-06 22:00:24 +09:00
tastybento b88497397f
Merge pull request #126 from BentoBoxWorld/gitlocalize-27267
Add Ukrainian locale
2023-11-26 10:00:25 -08:00
GIGABAIT b45c88025f Translate uk.yml via GitLocalize 2023-11-26 11:18:41 +00:00
tastybento 3c9515295d Merge branch 'develop' of https://github.com/BentoBoxWorld/Warps.git into develop 2023-11-12 13:25:11 -08:00
tastybento 82a0630ca3 BentoBox API 2.0.0 2023-11-12 13:25:03 -08:00
BONNe 6dbdb0f8aa
Update WarpsCommandTest.java 2023-11-05 22:00:28 +02:00
BONNe a1e03af13a
Update WarpsCommand.java 2023-11-05 21:35:59 +02:00
tastybento 2558d9d1ab
Merge pull request #124 from rchomczyk/fix-pl-translation
Improve polish translation
2023-09-04 07:46:24 -07:00
Rafał Chomczyk d346b7864e
Fix invalid placeholder name for warp's description; improve translations by a little, fix typo 2023-09-03 17:50:30 +02:00
BONNe 0e1cd1353c
Version Up 2023-07-26 15:37:35 +03:00
tastybento 9657d11af7
Update pom.xml 2023-07-10 21:39:57 -07:00
tastybento ab1a1e203c Update Jacoco 2023-07-10 21:24:40 -07:00
tastybento 1a90acb65f Update GitHub Action versions 2023-06-24 13:49:47 -07:00
tastybento ae172b9fdf Minor variable rename 2023-06-24 13:49:33 -07:00
tastybento ecebbcd039
Merge pull request #122 from BentoBoxWorld/gitlocalize-24193
Spanish
2023-05-29 09:40:06 -07:00
tastybento 3faed651aa
Merge pull request #123 from BentoBoxWorld/gitlocalize-24194
Indonesian
2023-05-29 09:39:49 -07:00
Dusty 0585fd7f3a Translate id.yml via GitLocalize 2023-05-29 16:35:40 +00:00
Espan 2f59225718 Translate es.yml via GitLocalize 2023-05-29 16:35:13 +00:00
tastybento 9e57851c62 Update GitHub build script to Java 17 2023-04-16 11:02:01 -07:00
tastybento b998b46fd5 User BentoBox release build 2023-04-16 11:00:06 -07:00
tastybento cb165e52b0 Updated POM; fixed tests. 2023-04-15 13:08:55 -07:00
BONNe ebb3f05d78
Merge pull request #119 from BentoBoxWorld/return-to-plugin
Return to plugin.yml
2023-04-08 19:10:40 +03:00
BONNe fe6b020ac8
Update WarpsPladdon.java 2023-04-08 19:10:32 +03:00
BONNe d2dde61d8b
Update pom.xml 2023-04-08 19:10:15 +03:00
BONNe e58010547b
Create plugin.yml 2023-04-08 19:09:38 +03:00
tastybento 5a9f6495ad Updated pladdon dependencies. Removed unused imports. 2023-03-25 10:12:07 -07:00
tastybento ff4850d32a Use addon name in annotation 2023-03-25 09:59:53 -07:00
DevSolaris 7a26acefd9
Flip bool expression (#114) 2023-02-12 10:44:49 -08:00
tastybento 2be57a66d2 Fix SonarCloud bugs and smells. 2023-02-09 17:44:25 -08:00
tastybento 67c5c9f8c3 Updated Jacoco POM 2023-02-09 17:38:25 -08:00
tastybento 62f1f2e966
Add ${argLine} to get jacoco coverage 2023-02-09 15:13:34 -08:00
BONNe 5a37c3da75
Merge pull request #118 from BentoBoxWorld/gitlocalize-22781
Update NL
2023-01-24 15:18:17 +02:00
DevSolaris 94e9208941 Translate nl.yml via GitLocalize 2023-01-24 13:18:06 +00:00
BONNe 225b4d66f8
Update Warp.java 2023-01-19 23:15:38 +02:00
BONNe d3b45396fd
Add missing import 2023-01-19 23:10:00 +02:00
BONNe d2b9540650
Update locale 2023-01-19 23:06:57 +02:00
BONNe 363a628244
Improve create warps flag.
Rename the flag to PLACE_WARP as it is a more proper name.
Also, add a click handler that limits setting value from member to owner, as visitors should not be allowed.

Also, set default value outside island range as false.
2023-01-19 23:06:45 +02:00
DevSolaris 8be844b59f
Closes #69 - Fix message from being sent when the user is banned. (#116) 2023-01-19 21:59:39 +01:00
DevSolaris b3a36c75bb
Create set warp flag (#117) 2023-01-19 21:56:31 +01:00
DevSolaris 7dbb5d39ad
Add gamemode placeholder to message (#115) 2023-01-18 22:14:50 +01:00
BONNe fb1090717b
Merge pull request #113 from BentoBoxWorld/gitlocalize-20471
Update Polish translation
2022-08-23 10:54:09 +03:00
mt-gitlocalize 39b94e09d8 Translate pl.yml via GitLocalize 2022-08-23 07:53:37 +00:00
wiktorm12 5716214527 Translate pl.yml via GitLocalize 2022-08-23 07:53:37 +00:00
BONNe 153e8be6a0
Init next version 2022-05-17 12:32:25 +03:00
BONNe 0dea651274
Fix build number for warps
1.11.2 was already released.
2022-05-17 12:20:13 +03:00
BONNe 63b51fb26e
Merge pull request #109 from BentoBoxWorld/gitlocalize-18727
Update German translation
2022-04-09 12:32:55 +03:00
Patrick 15a699037a Translate de.yml via GitLocalize 2022-04-09 09:30:14 +00:00
BONNe cbaf6ce16c Implement customizable Warps Panel.
Relates to #BentoBox/issues/1931
These changes includes to removing some obsolete config settings and locales string.
Also, moved some classes around to clean up directory.
2022-03-11 12:34:16 +02:00
Huynh Tien b12a6dcff9
Update id.yml (#108) 2022-01-28 07:13:25 -08:00
gitlocalize-app[bot] 89bcc54e23
Translate it.yml via GitLocalize (#107)
Co-authored-by: Pirlas <alexpirlas@outlook.it>
2022-01-01 16:47:50 -08:00
gitlocalize-app[bot] 6db80f73f8
Taiwan translation (#106)
* Translate zh-TW.yml via GitLocalize

* Translate zh-TW.yml via GitLocalize

Co-authored-by: Shaowing <lien78520@gmail.com>
Co-authored-by: mt-gitlocalize <mt@gitlocalize.com>
2022-01-01 16:47:40 -08:00
gitlocalize-app[bot] 87d04302d2
Indonesian Translation (#105)
* Translate id.yml via GitLocalize

* Translate id.yml via GitLocalize

* Translate id.yml via GitLocalize

Co-authored-by: Alunite? <xcionsspro30@gmail.com>
Co-authored-by: mt-gitlocalize <mt@gitlocalize.com>
Co-authored-by: gitlocalize-app[bot] <55277160+gitlocalize-app[bot]@users.noreply.github.com>
2022-01-01 16:47:29 -08:00
gitlocalize-app[bot] 9b0f00f2a0
Translate hu.yml via GitLocalize (#104)
Co-authored-by: driverdakid <tamascsiszar99@icloud.com>
2022-01-01 16:47:18 -08:00
gitlocalize-app[bot] 048f7237da
French translation (#103)
* Translate fr.yml via GitLocalize

* Translate fr.yml via GitLocalize

Co-authored-by: Aksel <afgameytb@gmail.com>
Co-authored-by: HipppB <hippolyte.bach@eleve.isep.fr>
2022-01-01 16:47:08 -08:00
gitlocalize-app[bot] 49d461d224
Translate tr.yml via GitLocalize (#102)
Co-authored-by: Over_Brave <soncesurlar@gmail.com>
2022-01-01 16:46:54 -08:00
Huynh Tien 6cfaa0e9c0
Fix null player on removeWarp (#100) 2021-12-31 08:25:05 -08:00
tastybento 9290503be3 Fix plugin.yml 2021-12-21 14:13:48 -08:00
tastybento 079dba0f41 Merge branch 'develop' of https://github.com/BentoBoxWorld/Warps.git into develop 2021-10-01 19:04:19 -07:00
tastybento 60c427c2a9 Build to BentoBox 1.18 API 2021-10-01 19:04:09 -07:00
KrazyxWolf 6caa652162
Update es.yml (#98) 2021-08-26 18:02:37 -07:00
tastybento 4ebaa22f37 Renamed plugin Pladdon 2021-08-12 18:48:39 -07:00
tastybento f0780d91ba Version 1.11.2 2021-08-12 18:48:29 -07:00
35 changed files with 1534 additions and 906 deletions

View File

@ -11,22 +11,22 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 16
uses: actions/setup-java@v2
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '16'
java-version: '17'
- name: Cache SonarCloud packages
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}

48
pom.xml
View File

@ -54,19 +54,19 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>16</java.version>
<java.version>17</java.version>
<!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.17-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>1.17.0</bentobox.version>
<spigot.version>1.19.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
<level.version>2.7.0-SNAPSHOT</level.version>
<!-- Revision variable removes warning about dynamic version -->
<revision>${build.version}-SNAPSHOT</revision>
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>1.11.1</build.version>
<build.version>1.15.0</build.version>
<!-- Sonar Cloud -->
<sonar.projectKey>BentoBoxWorld_Warps</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
@ -229,7 +229,34 @@
<version>3.0.0-M5</version>
<configuration>
<argLine>
--illegal-access=permit
${argLine}
--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
</argLine>
</configuration>
</plugin>
@ -285,7 +312,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<version>0.8.10</version>
<configuration>
<append>true</append>
<excludes>
@ -296,16 +323,21 @@
</configuration>
<executions>
<execution>
<id>pre-unit-test</id>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
<configuration>
<formats>
<format>XML</format>
</formats>
</configuration>
</execution>
</executions>
</plugin>

View File

@ -7,16 +7,23 @@ import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.configuration.Config;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
import world.bentobox.level.Level;
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 +45,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.
*/
@ -68,6 +75,11 @@ public class Warp extends Addon {
*/
private Config<Settings> settingsConfig;
/**
* Create Warp Flag
*/
private Flag createWarpFlag;
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
@ -136,13 +148,25 @@ 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 {
logWarning("Addon did not hook into anything and is not running stand-alone");
this.setState(State.DISABLED);
}
this.createWarpFlag = new Flag.Builder("PLACE_WARP", Material.OAK_SIGN)
.addon(this)
.defaultRank(RanksManager.MEMBER_RANK)
.clickHandler(new CycleClick("PLACE_WARP",
RanksManager.MEMBER_RANK,
RanksManager.OWNER_RANK))
.defaultSetting(false)
.mode(Flag.Mode.EXPERT)
.build();
getPlugin().getFlagsManager().registerFlag(this, this.createWarpFlag);
}
@ -169,17 +193,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() {
@ -206,6 +234,13 @@ public class Warp extends Addon {
return settings;
}
/**
* @return the createWarpFlag
*/
public Flag getCreateWarpFlag() {
return createWarpFlag;
}
/**
* Get the island level
* @param world - world
@ -217,8 +252,11 @@ public class Warp extends Addon {
String name = this.getPlugin().getIWM().getAddon(world).map(g -> g.getDescription().getName()).orElse("");
return this.getPlugin().getAddonsManager().getAddonByName(LEVEL_ADDON_NAME)
.map(l -> {
if (!name.isEmpty() && ((Level) l).getSettings().getGameModes().contains(name)) {
return ((Level) l).getIslandLevel(world, uniqueId);
final Level addon = (Level) l;
//getGameModes is a list of gamemodes that Level is DISABLED in,
//so we need the opposite of the contains.
if (!name.isEmpty() && !addon.getSettings().getGameModes().contains(name)) {
return addon.getIslandLevel(world, uniqueId);
}
return null;
}).orElse(null);

View File

@ -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<Void> buildPanel(PanelBuilder panelBuilder, User user, int index, World world) {
CompletableFuture<Void> r = new CompletableFuture<>();
processSigns(r, panelBuilder, user, index, world);
return r;
}
void processSigns(CompletableFuture<Void> r, PanelBuilder panelBuilder, User user, int index, World world) {
addon.getWarpSignsManager().getSortedWarps(world).thenAccept(warps -> {
// Cache and clean the signs
Iterator<UUID> 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<UUID> 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<UUID> 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();
}
}

View File

@ -1,8 +1,10 @@
package world.bentobox.warps;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.addons.Pladdon;
public class WarpsPladdon extends Pladdon {
@Override

View File

@ -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
@ -32,7 +34,7 @@ public class WarpsCommand extends CompositeCommand {
*/
@Override
public void setup() {
this.setPermission(this.getParent() == null ? Warp.WELCOME_WARP_SIGNS + ".warp" : "island.warp");
this.setPermission(this.getParent() == null ? Warp.WELCOME_WARP_SIGNS + ".warps" : "island.warps");
this.setOnlyPlayer(true);
this.setDescription("warps.help.description");
}
@ -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;
}

View File

@ -23,20 +23,19 @@ public class Settings implements ConfigObject
@ConfigEntry(path = "warplevelrestriction")
private int warpLevelRestriction = 10;
@ConfigComment("")
@ConfigComment("Should warps be removed when the island protection settings")
@ConfigComment("change, and the owner of the warp does no longer have")
@ConfigComment("the correct rank")
@ConfigEntry(path = "removeExistingWarpsWhenFlagChanges")
private boolean removeExistingWarpsWhenFlagChanges = false;
@ConfigComment("")
@ConfigComment("Text that player must put on sign to make it a warp sign")
@ConfigComment("Not case sensitive!")
@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 +44,12 @@ public class Settings implements ConfigObject
@ConfigEntry(path = "disabled-gamemodes")
private Set<String> 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")
@ -74,7 +62,6 @@ public class Settings implements ConfigObject
@ConfigEntry(path = "warps-command")
String warpsCommand = "warps";
// ---------------------------------------------------------------------
// Section: Constructor
// ---------------------------------------------------------------------
@ -155,42 +142,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 +158,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
*/
@ -270,5 +205,17 @@ public class Settings implements ConfigObject
this.warpsCommand = warpsCommand;
}
/**
* @return the removeExistingWarpsWhenFlagChanges
*/
public boolean getRemoveExistingWarpsWhenFlagChanges() {
return removeExistingWarpsWhenFlagChanges;
}
/**
* @param removeExistingWarpsWhenFlagChanges the removeExistingWarpsWhenFlagChanges to set
*/
public void setRemoveExistingWarpsWhenFlagChanges(boolean removeExistingWarpsWhenFlagChanges) {
this.removeExistingWarpsWhenFlagChanges = removeExistingWarpsWhenFlagChanges;
}
}

View File

@ -1,10 +1,7 @@
package world.bentobox.warps.listeners;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -25,9 +22,11 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.addon.AddonEvent;
import world.bentobox.bentobox.api.events.flags.FlagProtectionChangeEvent;
import world.bentobox.bentobox.api.events.team.TeamKickEvent;
import world.bentobox.bentobox.api.events.team.TeamLeaveEvent;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.Warp;
import world.bentobox.warps.event.WarpRemoveEvent;
@ -72,7 +71,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;
}
}
@ -114,7 +113,6 @@ public class WarpSignsListener implements Listener {
return;
}
User user = User.getInstance(e.getPlayer());
if (user == null) return;
UUID owner = addon.getWarpSignsManager().getWarpOwnerUUID(b.getLocation()).orElse(null);
if (isPlayersSign(e.getPlayer(), b, inWorld)) {
addon.getWarpSignsManager().removeWarp(b.getLocation());
@ -164,6 +162,13 @@ public class WarpSignsListener implements Listener {
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
return;
}
if(!hasCorrectIslandRank(b, user)) {
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
user.sendMessage("warps.error.not-correct-rank");
return;
}
// Check if the player already has a sign
final Location oldSignLoc = addon.getWarpSignsManager().getWarp(b.getWorld(), user.getUniqueId());
if (oldSignLoc != null) {
@ -192,6 +197,46 @@ public class WarpSignsListener implements Listener {
}
private boolean hasCorrectIslandRank(Block b, User user) {
final Optional<Island> islandOpt = plugin.getIslands().getIslandAt(b.getLocation());
if(islandOpt.isEmpty()) return false;
final Island island = islandOpt.get();
final int userRank = island.getRank(user);
return userRank >= island.getFlag(addon.getCreateWarpFlag());
}
@EventHandler
public void onFlagChange(FlagProtectionChangeEvent e) {
if(!e.getEditedFlag().equals(addon.getCreateWarpFlag())) return;
if(!addon.getSettings().getRemoveExistingWarpsWhenFlagChanges()) return;
final Island island = e.getIsland();
final Map<UUID, Location> islandWarps = addon
.getWarpSignsManager()
.getWarpMap(island.getWorld())
.entrySet()
.stream()
.filter(x -> island.inIslandSpace(x.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
for(Map.Entry<UUID, Location> entry : islandWarps.entrySet()) {
if(island.getRank(entry.getKey()) >= e.getSetTo()) continue;
//The user has a lower rank than the new set value.
//We need to remove the warp.
addon.getWarpSignsManager().removeWarp(island.getWorld(), entry.getKey());
if(Bukkit.getPlayer(entry.getKey()) != null) {
Objects.requireNonNull(User.getInstance(entry.getKey())).sendMessage(WARPS_DEACTIVATE);
}
}
}
private boolean noLevelOrIsland(User user, World world) {
// Get level if level addon is available
Long level = addon.getLevel(Util.getWorld(world), user.getUniqueId());

View File

@ -1,4 +1,4 @@
package world.bentobox.warps;
package world.bentobox.warps.managers;
import java.util.List;

View File

@ -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;
}

View File

@ -1,4 +1,4 @@
package world.bentobox.warps;
package world.bentobox.warps.managers;
import java.util.ArrayList;
import java.util.Arrays;
@ -21,12 +21,12 @@ import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@ -37,8 +37,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
@ -150,7 +153,7 @@ public class WarpSignsManager {
return r;
}
List<UUID> processWarpMap(CompletableFuture<List<UUID>> r, @NonNull World world) {
public List<UUID> processWarpMap(CompletableFuture<List<UUID>> 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
@ -190,22 +193,22 @@ 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)) {
warpsData = handler.loadObject(WARPS);
// Load into map
if (warpsData != null) {
warpsData.getWarpSigns().forEach((k,v) -> {
if (k != null && k.getWorld() != null) {
if (k.getWorld().isChunkLoaded(k.getBlockX() >> 4, k.getBlockZ() >> 4)
&& !k.getBlock().getType().name().contains("SIGN")) {
warpsData.getWarpSigns().forEach((location,uuid) -> {
if (location != null && location.getWorld() != null) {
if (location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)
&& !location.getBlock().getType().name().contains("SIGN")) {
return;
}
// Add to map
getWarpMap(k.getWorld()).put(v, k);
getWarpMap(location.getWorld()).put(uuid, location);
}
});
} else {
@ -241,13 +244,11 @@ public class WarpSignsManager {
Entry<UUID, Location> en = it.next();
if (en.getValue().equals(loc)) {
// Inform player
User user = User.getInstance(addon.getServer().getPlayer(en.getKey()));
if (user != null) {
// Inform the player
user.sendMessage("warps.sign-removed");
}
Optional.ofNullable(addon.getServer().getPlayer(en.getKey()))
.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();
}
}
@ -266,7 +267,7 @@ public class WarpSignsManager {
}
// Remove sign from warp panel cache
addon.getWarpPanelManager().removeWarp(world, uuid);
addon.getSignCacheManager().removeWarp(world, uuid);
saveWarpList();
}
@ -284,7 +285,7 @@ public class WarpSignsManager {
*/
public void saveWarpList() {
handler.saveObjectAsync(warpsData.save(worldsWarpList));
addon.getWarpPanelManager().saveCache();
addon.getSignCacheManager().saveCache();
}
/**
@ -312,7 +313,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;
@ -320,20 +320,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);
}
}
/**
@ -349,21 +350,33 @@ public class WarpSignsManager {
float yaw = Util.blockFaceToFloat(directionFacing);
final Location actualWarp = new Location(inFront.getWorld(), inFront.getBlockX() + 0.5D, inFront.getBlockY(),
inFront.getBlockZ() + 0.5D, yaw, 30F);
Util.teleportAsync(user.getPlayer(), actualWarp, TeleportCause.COMMAND);
User warpOwner = Objects.requireNonNull(User.getInstance(signOwner));
// Hide invisible players
if (warpOwner.isOnline() && !warpOwner.getPlayer().canSee(user.getPlayer())) {
return;
}
if (pvp) {
user.sendMessage("protection.flags.PVP_OVERWORLD.enabled");
user.getWorld().playSound(Objects.requireNonNull(user.getLocation()), Sound.ENTITY_ARROW_HIT, 1F, 1F);
} else {
user.getWorld().playSound(Objects.requireNonNull(user.getLocation()), Sound.ENTITY_BAT_TAKEOFF, 1F, 1F);
}
if (!warpOwner.equals(user)) {
warpOwner.sendMessage("warps.player-warped", "[name]", user.getName());
}
//BentoBox prevents people from teleporting to an island when
//the user is banned from the island for example.
//By checking if the teleport succeeded before sending the messages,
//we prevent issues where no one teleported, but people still
//get messages about it.
Util.teleportAsync(user.getPlayer(), actualWarp, TeleportCause.COMMAND).thenAccept(tpResult -> {
if(Boolean.FALSE.equals(tpResult)) return;
User warpOwner = Objects.requireNonNull(User.getInstance(signOwner));
// Hide invisible players
if (warpOwner.isOnline() && !warpOwner.getPlayer().canSee(user.getPlayer())) {
return;
}
if (pvp) {
user.sendMessage("protection.flags.PVP_OVERWORLD.enabled");
user.getWorld().playSound(Objects.requireNonNull(user.getLocation()), Sound.ENTITY_ARROW_HIT, 1F, 1F);
} else {
user.getWorld().playSound(Objects.requireNonNull(user.getLocation()), Sound.ENTITY_BAT_TAKEOFF, 1F, 1F);
}
if (!warpOwner.equals(user)) {
final String gameMode = BentoBox
.getInstance()
.getIWM()
.getFriendlyName(actualWarp.getWorld());
warpOwner.sendMessage("warps.player-warped", "[name]", user.getName(), "[gamemode]", gameMode);
}
});
}
/**
@ -411,7 +424,7 @@ public class WarpSignsManager {
}
// Find out which direction the warp is facing
Block b = warpSpot.getBlock();
if (b.getType().name().contains("WALL_SIGN")) {
if (Tag.WALL_SIGNS.isTagged(b.getType())) {
org.bukkit.block.data.type.WallSign s = (org.bukkit.block.data.type.WallSign) b.getBlockData();
BlockFace directionFacing = s.getFacing();
Location inFront = b.getRelative(directionFacing).getLocation();
@ -424,7 +437,13 @@ public class WarpSignsManager {
warpPlayer(user, oneDown, owner, directionFacing, pvp);
return;
}
} else if (b.getType().name().contains("SIGN")) {
} else if (Tag.ALL_HANGING_SIGNS.isTagged(b.getType())) {
Location below = b.getRelative(BlockFace.DOWN).getRelative(BlockFace.DOWN).getLocation();
if ((addon.getIslands().isSafeLocation(below))) {
warpPlayer(user, below, owner, BlockFace.DOWN, pvp);
return;
}
} else if (Tag.STANDING_SIGNS.isTagged(b.getType())) {
org.bukkit.block.data.type.Sign s = (org.bukkit.block.data.type.Sign) b.getBlockData();
BlockFace directionFacing = s.getRotation();
Location inFront = b.getRelative(directionFacing).getLocation();
@ -461,54 +480,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<String> 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;
}
}

View File

@ -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 {

View File

@ -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<String> 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;
}
}

View File

@ -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<Boolean> completed)
{
this.addon.getWarpSignsManager().getSortedWarps(this.world).
thenAccept(warps ->
{
// Cache and clean the signs
Iterator<UUID> 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<Boolean> 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<String> 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<String> 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("(?<!\\\\)\\|", "\n").
replaceAll("\\\\\\|", "|");
}
else
{
descriptionText = this.user.getTranslationOrNothing(reference + "description",
"[name]", ownerName,
"[sign_text]", String.join("|", signCache.getSignText()));
// Clean up description text and split it into parts.
descriptionText = descriptionText.replaceAll("(?m)^[ \\t]*\\r?\\n", "").
replaceAll("(?<!\\\\)\\|", "\n").
replaceAll("\\\\\\|", "|");
}
builder.description(descriptionText);
// Add ClickHandler
builder.clickHandler((panel, user, clickType, i) ->
{
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<String> 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<UUID> 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();
}

View File

@ -10,7 +10,10 @@ softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
permissions:
'[gamemode].island.warp':
description: Player can use warp or warps commands
description: Player can use warp command
default: true
'[gamemode].island.warps':
description: Player can use the warps command
default: true
'[gamemode].island.addwarp':
description: Player can create a welcome warp sign

View File

@ -7,34 +7,26 @@
# Warp Restriction - needed levels to be able to create a warp
# 0 or negative values will disable this restriction 10 is default
warplevelrestriction: 10
#
# Should warps be removed when the island protection settings
# change, and the owner of the warp does no longer have
# the correct rank
removeExistingWarpsWhenFlagChanges: true
#
# Text that player must put on sign to make it a warp sign
# 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
#

View File

@ -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: <Spielername>
parameters: "<player name>"
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"

View File

@ -18,16 +18,50 @@ warps:
not-on-island: "&c You must be on your island to do that!"
not-safe: "&c That warp is not safe!"
your-level-is: "&c Your island level is only [level] and must be higher than [required]. Run the level command."
help:
not-correct-rank: "&c You do not have the correct rank to set a warp!"
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"
player-warped: "&2 [name] warped to your [gamemode] warp sign!"
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"
protection:
flags:
PLACE_WARP:
name: Place Warp
description: Allow placing warp sign

View File

@ -1,30 +1,53 @@
###########################################################################################################
# Este es un archivo YML. Tenga cuidado al editar. Revisa tus ediciones en un verificador de YAML como #
# el de http://yaml-online-parser.appspot.com #
###########################################################################################################
warp:
help:
description: "Teletransportarte hacia el warp del jugador"
parameters: <name>
warps:
deactivate: "&cViejo cartel a sido desactivado!"
error:
does-not-exist: "&cOh snap! Ese warp ya no existe!"
no-permission: "&CNo tienes permiso para hacer eso!"
no-remove: "&CNo puedes quitar ese cartel!"
no-warps-yet: "&CNo hay warps disponibles aun"
not-enough-level: "&CTu nivel de isla no es lo suficientemente alto!"
not-on-island: "&CDebes estar en tu isla para hacer eso!"
not-safe: "&cEse warp no es seguro!"
your-level-is: "&cTu nivel de isla es solo [level] y debe ser mayor que [required]"
help:
description: "Abre el panel de warps"
next: "&6Siguiente página"
player-warped: "&2[name] teletransportarte a tu warp!"
previous: "&6Pagina anterior"
sign-removed: "&CCartel removido!"
success: "&AExito!"
title: "Carteles de Warps"
warpTip: "&6Coloca un cartel con este texto [text] arriba"
warpToPlayersSign: "&6Teletransportandote al warp de [player]"
---
warp:
help:
description: Teletransportarte hacia el warp del jugador
parameters: "<player name>"
warps:
deactivate: "&c ¡Antiguo cartel de teletransportación desactivado!"
error:
does-not-exist: "&c ¡Oh, chasquido! ¡Ese teletransporte ya no existe!"
no-permission: "&c ¡No tienes permisos para hacer eso!"
no-remove: "&c ¡No puedes quitar ese cartel!"
no-warps-yet: "&c No hay teletransportes disponibles todavía"
not-enough-level: "&c ¡Tu nivel de isla no es lo suficientemente alto!"
not-on-island: "&c ¡Debes estar en tu isla para hacer eso!"
not-safe: "&c ¡Ese teletransporte no es seguro!"
your-level-is: "&c Tu nivel de isla es solo [level] y debe ser mayor que [required].
Ejecuta el comando de nivel."
not-correct-rank: "&c ¡No tienes el rango correcto para crear un teletransporte!"
help:
description: Abre el panel de warps
player-warped: "&2 [name] se ha teletransportado a tu cartel de teletransportación
de [gamemode]!"
sign-removed: "&c Cartel de teletransportación eliminado!"
success: "&a Éxito!"
warpTip: "&6 Coloca un cartel con [text] en la parte superior"
warpToPlayersSign: "&6 Teletransportandote al cartel del jugador [player]"
gui:
titles:
warp-title: "&0&l Carteles de Teletransporte"
buttons:
previous:
name: "&f&l Página Anterior"
description: "&7 Ir a la página [number]"
next:
name: "&f&l Siguiente Página"
description: "&7 Ir a la página [number]"
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Teletransporte aleatorio"
description: "&7 Hmm, ¿Dónde apareceré?"
tips:
click-to-previous: "&e Clic &7 para ver la página anterior."
click-to-next: "&e Clic &7 para ver la página siguiente."
click-to-warp: "&e Clic &7 para teletransportarse."
conversations:
prefix: "&l&6 [BentoBox]: &r"
protection:
flags:
PLACE_WARP:
name: Colocar Teletransporte
description: Permitir colocar un cartel de teletransporte

View File

@ -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]"

View File

@ -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: <player name>
warps:
---
warp:
help:
description: Teleportálás a játékos teleport táblájához
parameters: "<játékosnév>"
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"

View File

@ -0,0 +1,52 @@
---
warp:
help:
description: warp ke tanda warp pemain
parameters: "<player name>"
warps:
deactivate: "&c Tanda warp lama dinonaktifkan!"
error:
does-not-exist: "&c Oh! Warp itu tidak ada lagi!"
no-permission: "&c Kamu tidak punya izin untuk melakukan itu!"
no-remove: "&c Kamu tidak bisa 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 Kamu harus berada di pulaumu untuk melakukan itu!"
not-safe: "&c Warp itu tidak aman!"
your-level-is: "&c Level pulau Anda hanya [level] dan harus lebih tinggi dari
[required]. Jalankan perintah level."
not-correct-rank: "&c Kamu tidak punya rank yang benar untuk mengatur warp!"
help:
description: buka panel warps
player-warped: "&2 [name] nge-warp ke tanda warp [gamemode] kamu!"
sign-removed: "&c Tanda warp dihilangkan!"
success: "&a Sukses!"
warpTip: "&6 Tempatkan tanda warp dengan [text] di atas\n"
warpToPlayersSign: "&6 Pergi ke tanda [player]"
gui:
titles:
warp-title: "&0&l Tanda Warp"
buttons:
previous:
name: "&f&l Halaman Sebelumnya"
description: "&7 Beralih ke halaman [number]"
next:
name: "&f&l Halaman Selanjutnya"
description: "&7 Beralih ke halaman [number]"
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Warp Acak"
description: "&7 Hmm, di mana aku akan muncul?"
tips:
click-to-previous: "&e Klik &7 untuk melihat halaman sebelumnya."
click-to-next: "&e Klik &7 untuk melihat halaman selanjutnya."
click-to-warp: "&e Klik &7 untuk warp."
conversations:
prefix: "&l&6 [BentoBox]: &r"
protection:
flags:
PLACE_WARP:
name: Tempatkan Warp
description: Izinkan menempatkan tanda warp

View File

@ -0,0 +1,29 @@
---
warp:
help:
description: teletrasporto al cartello Warp del giocatore
parameters: "<nome giocatore>"
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]"

View File

@ -0,0 +1,52 @@
---
warp:
help:
description: teleporteer naar een speler zijn warp bord
parameters: "<speler>"
warps:
deactivate: "&c Oude warp bord is gedeactiveerd!"
error:
does-not-exist: "&c Oh nee! Deze warp bestaat niet meer!"
no-permission: "&c Je hebt geen permissies om dit te doen!"
no-remove: "&c Je kan dit bord niet weghalen!"
no-warps-yet: "&c Er bestaan nog geen warps op dit moment"
not-enough-level: "&c Je eiland level is nog niet hoog genoeg!"
not-on-island: "&c Je moet een eiland hebben om dit te doen!"
not-safe: "&c Deze warp is niet veilig!"
your-level-is: "&c Je eiland level is [level], maar het moet op zijn minst [required]
zijn. Gebruik het level commando."
not-correct-rank: "&c Je hebt niet de correcte rank om een warp te maken!"
help:
description: open het warp paneel
player-warped: "&2 [name] teleporteerde naar jou [gamemode] warp!"
sign-removed: "&c Warp bord verwijderd!"
success: "&a Geslaagd!"
warpTip: "&6 Plaats een warp bord met [text] op de eerste regel"
warpToPlayersSign: "&6 Teleporteren naar [player]'s warp"
gui:
titles:
warp-title: "&0&l Warp Borden"
buttons:
previous:
name: "&f&l Vorige pagina"
description: "&7 Ga naar pagina [number]"
next:
name: "&f&l Volgende pagina"
description: "&7 Ga naar pagina [number]"
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Willekeurige Warp"
description: "&7 Hmm, waar ga ik heen?"
tips:
click-to-previous: "&e Klik &7 om naar de vorige pagina te gaan."
click-to-next: "&e Klik &7 om naar de volgende pagina te gaan."
click-to-warp: "&e Klik &7 om te teleporteren."
conversations:
prefix: "&l&6 [BentoBox]: &r"
protection:
flags:
PLACE_WARP:
name: Plaats warp
description: Staat het toe om een warp bord te plaatsen

View File

@ -1,27 +1,46 @@
---
warp:
help:
description: teleportuje cię do tabliczki innego gracza
parameters: <gracz>
parameters: "<gracz>"
warps:
deactivate: '&c Stary teleport zdezaktywowany!'
deactivate: "&c Stary teleport został zdezaktywowany!"
error:
does-not-exist: '&c Ten teleport nie istnieje.'
no-permission: '&c Brak uprawnień!'
no-remove: '&c Nie możesz usunąć tej tabliczki!'
no-warps-yet: '&c Nie ma jeszcze teleportów.'
not-enough-level: '&c Twój poziom wyspy nie jest wystarczająco wysoki!'
not-on-island: '&c Musisz być na wyspie, by to zrobić.'
not-safe: '&c Ten teleport nie jest bezpieczny!'
your-level-is: '&c Twój poziom wyspy to [level], a musi wynosić co namniej [required].
Użyj komendy /is level.'
does-not-exist: "&c Ten teleport nie istnieje."
no-permission: "&c Brak uprawnień!"
no-remove: "&c Nie możesz usunąć tej tabliczki!"
no-warps-yet: "&c Nie ma jeszcze stworzonych teleportów."
not-enough-level: "&c Twój poziom wyspy nie jest wystarczająco wysoki!"
not-on-island: "&c Musisz być na wyspie, by to zrobić."
not-safe: "&c Ten teleport nie jest bezpieczny!"
your-level-is: "&c Twój poziom wyspy to [level], a musi wynosić co najmniej [required].
Użyj komendy /is level."
help:
description: otwiera panel warpów
next: '&6 Następna strona'
player-warped: '&2 [name] teleportował się do twojej tabliczki!'
previous: '&6 Poprzednia strona'
random: '&4 Losowy teleport'
sign-removed: '&c Usunięto tabliczkę!'
success: '&a Sukces!'
title: Tabliczki teleportacyjne
warpTip: '&6 Postaw tabliczkę z napisem [text]'
warpToPlayersSign: '&6 Teleportowanie do tabliczki gracza [player]'
player-warped: "&2 [name] teleportował się do twojej tabliczki!"
sign-removed: "&c Usunięto tabliczkę!"
success: "&a Sukces!"
warpTip: "&6 Postaw tabliczkę z napisem [text]"
warpToPlayersSign: "&6 Teleportowanie do tabliczki gracza [player]"
gui:
titles:
warp-title: "&0&l Lista dostępnych wysp"
buttons:
previous:
name: "&f&l Poprzednia strona"
description: "&7 Przełącz na stronę [number]"
next:
name: "&f&l następna strona"
description: "&7 Przełącz na stronę [number]"
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Losowa wyspa"
description: "&7 Hmm, gdzie się pojawię?"
tips:
click-to-previous: "&e Kliknij &7, aby wyświetlić poprzednią stronę."
click-to-next: "&e Kliknij &7, aby wyświetlić następną stronę."
click-to-warp: "&e Kliknij &7, aby przenieść."
conversations:
prefix: "&l&6 [BentoBox]: &r"

View File

@ -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!"

View File

@ -0,0 +1,52 @@
---
warp:
help:
description: телепортація на знак варпа гравця
parameters: "<player name>"
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]. Виконайте команду рівня."
not-correct-rank: "&c Ви не маєте належного рангу, щоб встановити варп!"
help:
description: відкрити панель варпів
player-warped: "&2 [name] телепортовано до вашого знака варпу [gamemode]!"
sign-removed: "&c Знак варпу видалено!"
success: "&a Успіх!"
warpTip: "&6 Розмістіть знак варпу з [text] угорі"
warpToPlayersSign: "&6 Телепортація на знак [player]."
gui:
titles:
warp-title: "&0&l Знаки варпів"
buttons:
previous:
name: "&f&l Попередня сторінка"
description: "&7 Перейти на сторінку [number]."
next:
name: "&f&l Наступна сторінка"
description: "&7 Перейти на сторінку [number]."
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Випадковий варп"
description: "&7 Хм, а де я з'явлюся?"
tips:
click-to-previous: "&e Натисніть &7, щоб переглянути попередню сторінку."
click-to-next: "&e Натисніть &7, щоб переглянути наступну сторінку."
click-to-warp: "&e Натисніть &7, щоб деформувати."
conversations:
prefix: "&l&6 [BentoBox]: &r"
protection:
flags:
PLACE_WARP:
name: Розмістіть варп
description: Дозволити розміщення варпів

View File

@ -0,0 +1,27 @@
---
warp:
help:
description: 傳送到該玩家的傳送木牌處
parameters: "<player name>"
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] 的牌子"

View File

@ -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{CustomPotionColor:11546150}
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{CustomPotionColor:8439583}
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

View File

@ -1,8 +1,9 @@
name: Warps
name: BentoBox-Warps
main: world.bentobox.warps.WarpsPladdon
version: ${version}
api-version: 1.17
description: A Warp Pladdon for BentoBox
author: tastybento
depend:
- BentoBox
version: ${project.version}${build.number}
api-version: "1.17"
authors: [tastybento]
contributors: ["The BentoBoxWorld Community"]
website: https://bentobox.world
description: ${project.description}

View File

@ -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<Object> handler;
@Mock
private BukkitScheduler scheduler;
private List<UUID> list;
// Class under test
private WarpPanelManager wpm;
@SuppressWarnings("unchecked")
@BeforeClass
public static void beforeClass() {
// This has to be done beforeClass otherwise the tests will interfere with each other
handler = mock(AbstractDatabaseHandler.class);
// Database
PowerMockito.mockStatic(DatabaseSetup.class);
DatabaseSetup dbSetup = mock(DatabaseSetup.class);
when(DatabaseSetup.getDatabase()).thenReturn(dbSetup);
when(dbSetup.getHandler(any())).thenReturn(handler);
}
/**
*/
@Before
public void setUp() {
when(addon.getWarpSignsManager()).thenReturn(wsm);
// Fill with 200 fake warps (I'm banking on them all being different, but there could be a clash)
list = new ArrayList<>();
for (int i = 0; i< 200; i++) {
list.add(UUID.randomUUID());
}
// One final one
UUID uuid = UUID.randomUUID();
list.add(uuid);
when(wsm.getSortedWarps(any())).thenReturn(CompletableFuture.completedFuture(list));
// User and player
when(user.getPlayer()).thenReturn(player);
when(user.getTranslation(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// BentoBox
BentoBox plugin = mock(BentoBox.class);
PlayersManager pm = mock(PlayersManager.class);
when(pm.getName(any())).thenReturn("name");
when(plugin.getPlayers()).thenReturn(pm);
when(addon.getPlugin()).thenReturn(plugin);
// Bukkit
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
ItemFactory itemF = mock(ItemFactory.class);
ItemMeta imeta = mock(ItemMeta.class);
when(itemF.getItemMeta(any())).thenReturn(imeta);
when(Bukkit.getItemFactory()).thenReturn(itemF);
when(Bukkit.getScheduler()).thenReturn(scheduler);
// Inventory
when(top.getSize()).thenReturn(9);
when(Bukkit.createInventory(any(), anyInt(), any())).thenReturn(top);
when(settings.getIcon()).thenReturn("SIGN");
when(addon.getSettings()).thenReturn(settings);
Location location = mock(Location.class);
Block block = mock(Block.class);
Material signType;
try {
signType = Material.valueOf("SIGN");
} catch (Exception e) {
signType = Material.valueOf("OAK_SIGN");
}
when(block.getType()).thenReturn(signType);
when(location.getBlock()).thenReturn(block);
// Sign block
when(wsm.getWarp(any(), any())).thenReturn(location);
// Sign cache
SignCacheItem sc = new SignCacheItem(Collections.singletonList("[welcome]"), signType);
when(wsm.getSignInfo(any(), any())).thenReturn(sc);
// Class under test
wpm = new WarpPanelManager(addon);
}
/**
* Test method for {@link WarpPanelManager#processSigns(CompletableFuture, PanelBuilder, User, int, World)}.
*/
@Test
public void testShowWarpPanelTestCache() {
PanelBuilder pb = mock(PanelBuilder.class);
// Do initial lookups of sign text
wpm.processSigns(new CompletableFuture<>(), pb, user, 3, world);
// Get the panel again
wpm.processSigns(new CompletableFuture<>(), pb, user, 3, world);
// Should only check this 201 times in total because the sign text is cached
verify(wsm, times(201)).getSignInfo(any(), any());
}
/**
* Test method for {@link WarpPanelManager#removeWarp(org.bukkit.World, java.util.UUID)}.
*/
@Test
public void testRemoveWarp() {
assertFalse(wpm.removeWarp(world, UUID.randomUUID()));
}
/**
* Test method for {@link WarpPanelManager#buildPanel(PanelBuilder, User, int, World)}
*/
@Test
public void testBuildPanel() {
PanelBuilder pb = mock(PanelBuilder.class);
wpm.buildPanel(pb, user, 3, world);
// Removing the UUID should force a refresh and therefore 201 lookups
verify(wsm, times(201)).getSignInfo(any(), any());
}
/**
* Test method for {@link WarpPanelManager#addNavigation(PanelBuilder, User, World, int, int, int)}
*/
@Test
public void testAddNavigationNoNav() {
PanelBuilder pb = mock(PanelBuilder.class);
wpm.addNavigation(pb, user, world, 0, 0, 0);
verify(pb, never()).item(any());
}
/**
* Test method for {@link WarpPanelManager#addNavigation(PanelBuilder, User, World, int, int, int)}
*/
@Test
public void testAddNavigationNoNavNext() {
PanelBuilder pb = mock(PanelBuilder.class);
wpm.addNavigation(pb, user, world, 0, 0, 100);
verify(pb).item(any());
verify(user).getTranslation("warps.next");
}
/**
* Test method for {@link WarpPanelManager#addNavigation(PanelBuilder, User, World, int, int, int)}
*/
@Test
public void testAddNavigationNoNavPrev() {
PanelBuilder pb = mock(PanelBuilder.class);
wpm.addNavigation(pb, user, world, 60, 2, 20);
verify(pb).item(any());
verify(user).getTranslation("warps.previous");
}
/**
* Test method for {@link WarpPanelManager#addNavigation(PanelBuilder, User, World, int, int, int)}
*/
@Test
public void testAddNavigationNoNavNextAndPrev() {
PanelBuilder pb = mock(PanelBuilder.class);
wpm.addNavigation(pb, user, world, 60, 2, 100);
verify(pb, times(2)).item(any());
verify(user).getTranslation("warps.previous");
verify(user).getTranslation("warps.next");
}
private int mainBod(int page, int j, boolean random) {
when(settings.isRandomAllowed()).thenReturn(random);
PanelBuilder pb = mock(PanelBuilder.class);
int r = wpm.buildMainBody(pb, user, page, world, list);
verify(pb, times(j)).item(any());
if (random && page <= 0) {
verify(user).getTranslation("warps.random");
} else {
verify(user, never()).getTranslation("warps.random");
}
return r;
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyNoRandomPage0() {
assertEquals(201, mainBod(0, 201, false));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyNoRandomPage1() {
assertEquals(201, mainBod(1, 149, false));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyNoRandomPage2() {
assertEquals(201, mainBod(2, 97, false));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyNoRandomPage3() {
assertEquals(201, mainBod(3, 45, false));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyNoRandomPageMinus1() {
assertEquals(201, mainBod(-1, 201, false));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyRandomPage0() {
assertEquals(201, mainBod(0, 201, true));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyRandomPage1() {
assertEquals(201, mainBod(1, 149, true));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyRandomPage2() {
assertEquals(201, mainBod(2, 97, true));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyRandomPage3() {
assertEquals(201, mainBod(3, 45, true));
}
/**
* Test method for {@link WarpPanelManager#buildMainBody(PanelBuilder, User, int, World, List, boolean)}
*/
@Test
public void testBuildMainBodyRandomPageMinus1() {
assertEquals(201, mainBod(-1, 201, true));
}
}

View File

@ -21,11 +21,11 @@ import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
@ -61,14 +61,17 @@ import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.config.Settings;
import world.bentobox.warps.event.WarpInitiateEvent;
import world.bentobox.warps.managers.SignCacheManager;
import world.bentobox.warps.managers.WarpSignsManager;
import world.bentobox.warps.objects.WarpsData;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class, Util.class, DatabaseSetup.class, ChatColor.class})
@PrepareForTest({Bukkit.class, Util.class, DatabaseSetup.class})
public class WarpSignsManagerTest {
@Mock
@ -98,7 +101,7 @@ public class WarpSignsManagerTest {
@Mock
private Player player;
@Mock
private WarpPanelManager wpm;
private SignCacheManager wpm;
@Mock
private PlayersManager pm;
@Mock
@ -136,12 +139,15 @@ public class WarpSignsManagerTest {
// Player
when(player.getUniqueId()).thenReturn(uuid);
when(player.isOnline()).thenReturn(true);
when(player.canSee(any(Player.class))).thenReturn(true);
User.setPlugin(plugin);
User.getInstance(player);
// Locales
LocalesManager lm = mock(LocalesManager.class);
when(lm.get(Mockito.any(), Mockito.any())).thenReturn(null);
when(lm.getAvailablePrefixes(any())).thenReturn(Collections.emptySet());
when(lm.get(Mockito.any(), Mockito.any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
when(plugin.getLocalesManager()).thenReturn(lm);
// Return the same string
PlaceholdersManager phm = mock(PlaceholdersManager.class);
@ -157,6 +163,7 @@ public class WarpSignsManagerTest {
PowerMockito.mockStatic(Util.class);
when(Util.getWorld(any())).thenAnswer((Answer<World>) invocation -> invocation.getArgument(0, World.class));
when(Util.sameWorld(any(), any())).thenReturn(true);
when(Util.translateColorCodes(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// Location
when(location.getWorld()).thenReturn(world);
@ -192,12 +199,14 @@ public class WarpSignsManagerTest {
when(addon.getSettings()).thenReturn(settings);
when(settings.getWelcomeLine()).thenReturn("[Welcome]");
when(settings.getLoreFormat()).thenReturn("&f");
when(settings.getIcon()).thenReturn("SIGN");
// Bukkit
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
when(Bukkit.getPluginManager()).thenReturn(pim);
// Tags
when(Tag.STANDING_SIGNS.isTagged(Material.ACACIA_SIGN)).thenReturn(true);
// Players Manager
when(plugin.getPlayers()).thenReturn(pm);
when(pm.getName(uuid)).thenReturn("tastybento");
@ -209,6 +218,7 @@ public class WarpSignsManagerTest {
// IWM
when(plugin.getIWM()).thenReturn(iwm);
when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock.");
when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock");
// Island Manager
when(addon.getIslands()).thenReturn(im);
@ -216,7 +226,7 @@ public class WarpSignsManagerTest {
when(im.isSafeLocation(any())).thenReturn(true);
// WarpPanelManager
when(addon.getWarpPanelManager()).thenReturn(wpm);
when(addon.getSignCacheManager()).thenReturn(wpm);
wsm = new WarpSignsManager(addon, plugin);
}
@ -229,7 +239,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getWarpMap(org.bukkit.World)}.
*/
@Test
public void testGetWarpMap() {
@ -237,7 +247,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getWarpMap(org.bukkit.World)}.
*/
@Test
public void testGetWarpMapNullWorld() {
@ -247,7 +257,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getWarpMap(org.bukkit.World)}.
*/
@Test
public void testGetWarpMapWrongBlockType() {
@ -257,7 +267,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getWarpMap(org.bukkit.World)}.
*/
@Test
public void testGetWarpMapNullLocation() {
@ -268,7 +278,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getWarpMap(org.bukkit.World)}.
* @throws Exception exception
*/
@Test
@ -279,7 +289,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getWarpMap(org.bukkit.World)}.
*/
@Test
public void testGetWarpMapNothingInDatabase() {
@ -289,7 +299,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#WarpSignsManager(world.bentobox.warps.Warp, world.bentobox.bentobox.BentoBox)}.
* Test method for {@link WarpSignsManager#WarpSignsManager(world.bentobox.warps.Warp, world.bentobox.bentobox.BentoBox)}.
*/
@Test
public void testWarpSignsManager() {
@ -299,7 +309,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@Test
public void testAddWarpNullPlayer() {
@ -307,7 +317,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@Test
public void testAddWarpNullLocation() {
@ -315,7 +325,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@Test
public void testAddWarpReplaceOldSign() {
@ -324,7 +334,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@Test
public void testAddWarpReplaceOldSignDifferentPlayer() {
@ -333,7 +343,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@Test
public void testAddWarp() {
@ -343,7 +353,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}.
* Test method for {@link WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}.
*/
@Test
public void testGetWarpWorldWorld() {
@ -351,7 +361,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}.
* Test method for {@link WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}.
*/
@Test
public void testGetWarp() {
@ -359,7 +369,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpOwner(org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#getWarpOwner(org.bukkit.Location)}.
*/
@Test
public void testGetWarpOwner() {
@ -367,7 +377,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getSortedWarps(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#getSortedWarps(org.bukkit.World)}.
*/
@Test
public void testGetSortedWarps() {
@ -376,7 +386,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#listWarps(org.bukkit.World)}.
* Test method for {@link WarpSignsManager#listWarps(org.bukkit.World)}.
*/
@Test
public void testListWarps() {
@ -385,7 +395,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#removeWarp(org.bukkit.Location)}.
* Test method for {@link WarpSignsManager#removeWarp(org.bukkit.Location)}.
*/
@Test
public void testRemoveWarpLocation() {
@ -394,7 +404,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#removeWarp(org.bukkit.World, java.util.UUID)}.
* Test method for {@link WarpSignsManager#removeWarp(org.bukkit.World, java.util.UUID)}.
*/
@Test
public void testRemoveWarpWorldUUID() {
@ -403,7 +413,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#saveWarpList()}.
* Test method for {@link WarpSignsManager#saveWarpList()}.
* @throws Exception general exception
*/
@Test
@ -413,16 +423,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getSignInfo(org.bukkit.World, java.util.UUID)}.
*/
@Test
public void testGetSignInfo() {
SignCacheItem sc = wsm.getSignInfo(world, uuid);
assertEquals(Material.ACACIA_SIGN, sc.getType());
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#warpPlayer(org.bukkit.World, world.bentobox.bentobox.api.user.User, java.util.UUID)}.
* Test method for {@link WarpSignsManager#warpPlayer(org.bukkit.World, world.bentobox.bentobox.api.user.User, java.util.UUID)}.
*/
@Test
public void testWarpPlayer() {
@ -431,16 +432,19 @@ public class WarpSignsManagerTest {
when(p.getWorld()).thenReturn(world);
when(p.getName()).thenReturn("tastybento");
when(p.getLocation()).thenReturn(location);
when(p.isOnline()).thenReturn(true);
when(p.canSee(any(Player.class))).thenReturn(true);
@Nullable
User u = User.getInstance(p);
PowerMockito.when(Util.teleportAsync(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(true));
wsm.warpPlayer(world, u, uuid);
PowerMockito.verifyStatic(Util.class);
Util.teleportAsync(eq(p), any(), eq(TeleportCause.COMMAND));
verify(player).sendMessage("warps.player-warped");
verify(player).sendMessage(anyString());
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#hasWarp(org.bukkit.World, java.util.UUID)}.
* Test method for {@link WarpSignsManager#hasWarp(org.bukkit.World, java.util.UUID)}.
*/
@Test
public void testHasWarp() {
@ -450,7 +454,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#loadWarpList()}.
* Test method for {@link WarpSignsManager#loadWarpList()}.
*/
@Test
public void testLoadWarpListNoWarpTable() {
@ -465,7 +469,7 @@ public class WarpSignsManagerTest {
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#loadWarpList()}.
* Test method for {@link WarpSignsManager#loadWarpList()}.
* @throws Exception exception
*/
@Test

View File

@ -38,7 +38,7 @@ import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.warps.Warp;
import world.bentobox.warps.WarpSignsManager;
import world.bentobox.warps.managers.WarpSignsManager;
import world.bentobox.warps.config.Settings;
/**

View File

@ -7,10 +7,8 @@ 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.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.World;
@ -29,9 +27,9 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.warps.managers.SignCacheManager;
import world.bentobox.warps.Warp;
import world.bentobox.warps.WarpPanelManager;
import world.bentobox.warps.WarpSignsManager;
import world.bentobox.warps.managers.WarpSignsManager;
import world.bentobox.warps.config.Settings;
/**
@ -62,7 +60,7 @@ public class WarpsCommandTest {
@Mock
private PlayersManager pm;
@Mock
private WarpPanelManager wpm;
private SignCacheManager wpm;
/**
*/
@ -99,8 +97,13 @@ public class WarpsCommandTest {
set.add(UUID.randomUUID());
when(wsm.listWarps(world)).thenReturn(set);
CompletableFuture<List<UUID>> warps = new CompletableFuture<>();
warps.complete(set.stream().toList());
when(wsm.getSortedWarps(world)).thenReturn(warps);
// Warp Panel Manager
when(addon.getWarpPanelManager()).thenReturn(wpm);
when(addon.getSignCacheManager()).thenReturn(wpm);
}
@ -120,7 +123,7 @@ public class WarpsCommandTest {
@Test
public void testSetupWarpCompositeCommand() {
warpCommandWarpsCompositeCommand();
assertEquals("bskyblock.island.warp", wc.getPermission());
assertEquals("bskyblock.island.warps", wc.getPermission());
assertTrue(wc.isOnlyPlayer());
assertEquals("warps.help.description", wc.getDescription());
}
@ -131,7 +134,7 @@ public class WarpsCommandTest {
@Test
public void testSetupWarp() {
warpCommandWarps();
assertEquals(Warp.WELCOME_WARP_SIGNS + ".warp", wc.getPermission());
assertEquals(Warp.WELCOME_WARP_SIGNS + ".warps", wc.getPermission());
assertTrue(wc.isOnlyPlayer());
assertEquals("warps.help.description", wc.getDescription());
}
@ -168,7 +171,6 @@ public class WarpsCommandTest {
public void testExecuteUserStringListOfString() {
warpCommandWarpsCompositeCommand();
assertTrue(wc.execute(user, "warps", Collections.emptyList()));
verify(wpm).showWarpPanel(world, user, 0);
}
/**
@ -178,7 +180,6 @@ public class WarpsCommandTest {
public void testExecuteUserStringListOfStringNoAddon() {
warpCommandWarps();
assertTrue(wc.execute(user, "warps", Collections.emptyList()));
verify(wpm).showWarpPanel(world, user, 0);
}
}

View File

@ -8,10 +8,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
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.*;
import java.util.HashMap;
import java.util.Map;
@ -44,14 +41,17 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.flags.FlagProtectionChangeEvent;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
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.util.Util;
import world.bentobox.warps.Warp;
import world.bentobox.warps.WarpSignsManager;
import world.bentobox.warps.managers.WarpSignsManager;
import world.bentobox.warps.config.Settings;
/**
@ -83,6 +83,8 @@ public class WarpSignsListenerTest {
private IslandsManager im;
@Mock
private IslandWorldManager iwm;
@Mock
private Island island;
@Before
public void setUp() {
@ -148,6 +150,9 @@ public class WarpSignsListenerTest {
when(settings.getWelcomeLine()).thenReturn("[WELCOME]");
when(addon.getSettings()).thenReturn(settings);
island = mock(Island.class);
when(im.getIslandAt(any())).thenReturn(Optional.of(island));
// On island
when(plugin.getIslands()).thenReturn(im);
when(im.userIsOnIsland(any(World.class), any(User.class))).thenReturn(true);
@ -166,6 +171,7 @@ public class WarpSignsListenerTest {
PowerMockito.mockStatic(Util.class);
when(Util.getWorld(any())).thenReturn(world);
when(Util.stripSpaceAfterColorCodes(anyString())).thenAnswer(invocation -> invocation.getArgument(0, String.class));
when(Util.translateColorCodes(any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// Locales
when(lm.get(any(User.class), anyString())).thenAnswer(answer);
@ -298,6 +304,54 @@ public class WarpSignsListenerTest {
assertEquals(ChatColor.GREEN + "[WELCOME]", e.getLine(0));
}
@Test
public void testOnCreateWithoutCorrectRankNotAllowed() {
WarpSignsListener wsl = new WarpSignsListener(addon);
SignChangeEvent e = new SignChangeEvent(block, player, lines);
when(player.hasPermission(anyString())).thenReturn(true);
when(addon.inRegisteredWorld(any())).thenReturn(true);
when(island.getRank(player.getUniqueId())).thenReturn(0);
when(island.getFlag(any())).thenReturn(1000);
wsl.onSignWarpCreate(e);
verify(player).sendMessage("warps.error.not-correct-rank");
}
@Test
public void testOnFlagChangeWhenSettingIsOffNothingHappens() {
Flag flag = mock(Flag.class);
when(addon.getCreateWarpFlag()).thenReturn(flag);
when(settings.getRemoveExistingWarpsWhenFlagChanges()).thenReturn(false);
WarpSignsListener wsl = new WarpSignsListener(addon);
FlagProtectionChangeEvent e = new FlagProtectionChangeEvent(island, player.getUniqueId(), flag, 1000);
wsl.onFlagChange(e);
verifyNoInteractions(island);
}
@Test
public void testOnFlagChangeWhenSettingIsOnWarpGetsRemoved() {
Flag flag = mock(Flag.class);
when(addon.getCreateWarpFlag()).thenReturn(flag);
when(settings.getRemoveExistingWarpsWhenFlagChanges()).thenReturn(true);
WarpSignsListener wsl = new WarpSignsListener(addon);
Map<UUID, Location> warps = Map.of(
player.getUniqueId(), block.getLocation()
);
when(wsm.getWarpMap(any())).thenReturn(warps);
when(island.inIslandSpace(any(Location.class))).thenReturn(true);
FlagProtectionChangeEvent e = new FlagProtectionChangeEvent(island, player.getUniqueId(), flag, 1000);
wsl.onFlagChange(e);
verify(addon.getWarpSignsManager()).removeWarp(any(), any());
}
@Test
public void testOnCreateNotGameWorldNotAllowed() {
when(settings.isAllowInOtherWorlds()).thenReturn(false);