1
0
mirror of https://github.com/BentoBoxWorld/Warps.git synced 2024-09-27 14:52:55 +02:00

Compare commits

...

36 Commits

Author SHA1 Message Date
tastybento
26170204f2
Merge pull request #137 from BentoBoxWorld/gitlocalize-30095
Czech translation
2024-09-07 10:26:24 -07:00
tastybento
9286b79fc9
Merge pull request #138 from BentoBoxWorld/gitlocalize-30096
Chinese translation
2024-09-07 10:26:12 -07:00
tastybento
412ef0e8e3
Merge pull request #139 from BentoBoxWorld/gitlocalize-30098
French translation
2024-09-07 10:26:00 -07:00
tastybento
7853d67f79
Merge pull request #140 from BentoBoxWorld/gitlocalize-30099
German translation
2024-09-07 10:25:49 -07:00
tastybento
aceb15b399
Merge pull request #141 from BentoBoxWorld/gitlocalize-30100
Japanese translation
2024-09-07 10:25:40 -07:00
tastybento
fa0b25769d
Update README.md
Added graphic.
2024-08-21 07:56:23 -07:00
tastybento
fe83d097ca Merge branch 'develop' of https://github.com/BentoBoxWorld/Warps.git into develop 2024-07-02 09:36:17 -07:00
tastybento
87f3ea732b Return pladdon that was made. 2024-07-02 09:36:09 -07:00
tastybento
2e13892ab8 Version 1.15.1 2024-07-02 09:35:53 -07:00
tastybento
623e93ce7c Translate ja.yml via GitLocalize 2024-06-28 16:26:52 +00:00
mt-gitlocalize
924cb0f9be Translate ja.yml via GitLocalize 2024-06-28 16:26:52 +00:00
mt-gitlocalize
1f434131af Translate de.yml via GitLocalize 2024-06-28 16:24:47 +00:00
tastybento
7a55573072 Translate de.yml via GitLocalize 2024-06-28 16:24:47 +00:00
mt-gitlocalize
77e345566a Translate fr.yml via GitLocalize 2024-06-28 16:23:49 +00:00
mt-gitlocalize
0e8ab9c3f9 Translate zh-CN.yml via GitLocalize 2024-06-28 16:22:53 +00:00
mt-gitlocalize
b7f0b170fa Translate cs.yml via GitLocalize 2024-06-28 16:21:54 +00:00
tastybento
3fa1ddc860 Translate cs.yml via GitLocalize 2024-06-28 16:21:53 +00:00
tastybento
18b63f4e79
Merge pull request #135 from TreemanKing/toggle-warp
feat: toggle warp command
2024-06-21 20:18:57 -07:00
TreemanK
4bacbd7c5a feat: suggestions
- getToggleCommand is linked to toggleWarpCommand instead of hardcoded
- warpSigns is now null and not empty
2024-06-22 13:16:47 +10:00
tastybento
7f9f35253d
Merge pull request #136 from TreemanKing/fix-other-worlds
fix (partial): other worlds can be used
2024-06-21 08:16:47 -07:00
TreemanK
599a6e1d08 style: added TODO
Currently, `noLevelOrIsland and hasCorrectIslandRank` require the sign to be on an island. Currently this means the flag/level requirement are non-existent in the case of a sign being placed on a non-BSB island. This gives a possible solution if new API comes to light.
2024-06-22 00:06:21 +10:00
TreemanK
1054518831 fix: fix create warp/sign in non-island world
Currently, you can't create a warp in another world (even with permissions) as it goes into hasCorrectIslandRank. In this case, it is always false as there is no island at the block location meaning it will always go into this whilst creating a warp in other worlds.
2024-06-21 23:06:02 +10:00
TreemanK
abd526b06d feat: add toggle event 2024-06-21 20:42:31 +10:00
TreemanK
eeead7fb49 feat: toggle warp command 2024-06-21 20:19:24 +10:00
TreemanK
ef81a1c2f0 style: change method name to getWarpLocation
note `line 294` of `warp.java`, I am unsure what this does and whether it should be `getWarpLocation` or not. I will leave it for the time being.
2024-06-21 02:23:38 +10:00
TreemanK
64f8a4899a feat: make sure old data is not lost!
Now, I was thinking if there is a way to directly convert it but there isn't because of the way it was structured. This *ISN'T* the best way around things but if someone can find a better way around it, be my guest.
2024-06-21 01:49:30 +10:00
TreemanK
0a343219bc feat: changed location to playerwarp in preparation of toggle state 2024-06-20 21:57:50 +10:00
tastybento
0a12a26b06
Merge pull request #134 from BentoBoxWorld/gitlocalize-29839
French translation
2024-06-08 10:12:36 -07:00
ISOURA
b860a4dac5 Translate fr.yml via GitLocalize 2024-06-08 17:08:20 +00:00
tastybento
2da0e5e82b
Merge pull request #133 from RUYSUE/develop
updated zh-CN locale
2024-06-08 08:52:53 -07:00
RUYSUE
a39b6a3f4a
Update zh-CN.yml 2024-06-08 17:20:14 +08:00
tastybento
d70ee5d755
Merge pull request #132 from BentoBoxWorld/131_WarpCreateEvent_doesn't_fire
Call events correctly. #131
2024-06-05 14:12:29 -07:00
tastybento
efc6b795d1 Call events correctly. #131 2024-06-05 14:09:02 -07:00
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
25 changed files with 591 additions and 159 deletions

View File

@ -3,6 +3,10 @@ Add-on for BentoBox to add personal warp signs for players of BSkyBlock or AcidI
This add-on will work for all game modes installed on a BentoBox server. Use config settings This add-on will work for all game modes installed on a BentoBox server. Use config settings
to disable use by gamemode. to disable use by gamemode.
![warps](https://github.com/user-attachments/assets/3454b7ec-d9bf-4631-9e5a-d6e603ac5f15)
## How to use ## How to use
### Note: Java 16 and Minecraft 17, or later are required. ### Note: Java 16 and Minecraft 17, or later are required.

View File

@ -66,7 +66,7 @@
<!-- Do not change unless you want different name for local builds. --> <!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number> <build.number>-LOCAL</build.number>
<!-- This allows to change between versions. --> <!-- This allows to change between versions. -->
<build.version>1.14.0</build.version> <build.version>1.15.1</build.version>
<!-- Sonar Cloud --> <!-- Sonar Cloud -->
<sonar.projectKey>BentoBoxWorld_Warps</sonar.projectKey> <sonar.projectKey>BentoBoxWorld_Warps</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization> <sonar.organization>bentobox-world</sonar.organization>

View File

@ -17,6 +17,7 @@ import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.level.Level; import world.bentobox.level.Level;
import world.bentobox.warps.commands.ToggleWarpCommand;
import world.bentobox.warps.commands.WarpCommand; import world.bentobox.warps.commands.WarpCommand;
import world.bentobox.warps.commands.WarpsCommand; import world.bentobox.warps.commands.WarpsCommand;
import world.bentobox.warps.config.Settings; import world.bentobox.warps.config.Settings;
@ -100,6 +101,7 @@ public class Warp extends Addon {
// Load the master warp and warps command // Load the master warp and warps command
new WarpCommand(this); new WarpCommand(this);
new WarpsCommand(this); new WarpsCommand(this);
new ToggleWarpCommand(this);
} }
} }
@ -140,6 +142,7 @@ public class Warp extends Addon {
new WarpCommand(this, gameModeAddon.getPlayerCommand().get()); new WarpCommand(this, gameModeAddon.getPlayerCommand().get());
new WarpsCommand(this, gameModeAddon.getPlayerCommand().get()); new WarpsCommand(this, gameModeAddon.getPlayerCommand().get());
new ToggleWarpCommand(this, gameModeAddon.getPlayerCommand().get());
this.hooked = true; this.hooked = true;
} }
}); });
@ -288,7 +291,7 @@ public class Warp extends Addon {
} }
return switch (requestLabel) { return switch (requestLabel) {
case "getSortedWarps" -> getWarpSignsManager().getSortedWarps(world); case "getSortedWarps" -> getWarpSignsManager().getSortedWarps(world);
case "getWarp" -> uuid == null ? null : getWarpSignsManager().getWarp(world, uuid); case "getWarp" -> uuid == null ? null : getWarpSignsManager().getWarpLocation(world, uuid);
case "getWarpMap" -> getWarpSignsManager().getWarpMap(world); case "getWarpMap" -> getWarpSignsManager().getWarpMap(world);
case "hasWarp" -> uuid == null ? null : getWarpSignsManager().hasWarp(world, uuid); case "hasWarp" -> uuid == null ? null : getWarpSignsManager().hasWarp(world, uuid);
case "listWarps" -> getWarpSignsManager().listWarps(world); case "listWarps" -> getWarpSignsManager().listWarps(world);

View File

@ -6,9 +6,13 @@ import world.bentobox.bentobox.api.addons.Pladdon;
public class WarpsPladdon extends Pladdon { public class WarpsPladdon extends Pladdon {
private Addon addon;
@Override @Override
public Addon getAddon() { public Addon getAddon() {
return new Warp(); if (addon == null) {
addon = new Warp();
}
return addon;
} }
} }

View File

@ -0,0 +1,61 @@
package world.bentobox.warps.commands;
import org.bukkit.Bukkit;
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.event.WarpToggleEvent;
import world.bentobox.warps.objects.PlayerWarp;
import java.util.List;
import java.util.UUID;
public class ToggleWarpCommand extends CompositeCommand {
private final Warp addon;
public ToggleWarpCommand(Warp addon, CompositeCommand bsbIslandCmd) {
super(bsbIslandCmd, addon.getSettings().getToggleWarpCommand());
this.addon = addon;
}
public ToggleWarpCommand(Warp addon) {
super(addon.getSettings().getToggleWarpCommand());
this.addon = addon;
}
@Override
public void setup() {
this.setPermission(this.getParent() == null ? Warp.WELCOME_WARP_SIGNS + ".togglewarp" : "island.warp.toggle");
this.setOnlyPlayer(true);
this.setDescription("togglewarp.help.description");
}
@Override
public boolean execute(User user, String s, List<String> list) {
UUID userUUID = user.getUniqueId();
World userWorld = user.getWorld();
// Check if the user has a warp
boolean hasWarp = addon.getWarpSignsManager().hasWarp(userWorld, userUUID);
if (hasWarp) {
// If the user has a warp, toggle its visibility
PlayerWarp warp = addon.getWarpSignsManager().getPlayerWarp(userWorld, userUUID);
// Check extreme case if PlayerWarp is null
if (warp == null) {
user.sendMessage("togglewarp.error.generic");
return false;
}
warp.toggle();
Bukkit.getPluginManager().callEvent(new WarpToggleEvent(userUUID, warp));
String message = warp.isEnabled() ? "togglewarp.enabled" : "togglewarp.disabled";
user.sendMessage(message);
} else {
user.sendMessage("togglewarp.error.no-warp");
}
return false;
}
}

View File

@ -50,12 +50,12 @@ public class WarpCommand extends DelayedTeleportCommand {
user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine()); user.sendMessage("warps.warpTip", "[text]", addon.getSettings().getWelcomeLine());
return false; return false;
} else { } else {
// Attemp to find warp with exact player's name // Attempt to find warp with exact player's name
UUID foundWarp = warpList.stream().filter(u -> getPlayers().getName(u).equalsIgnoreCase(args.get(0))).findFirst().orElse(null); UUID foundWarp = warpList.stream().filter(u -> getPlayers().getName(u).equalsIgnoreCase(args.get(0))).findFirst().orElse(null);
if (foundWarp == null) { if (foundWarp == null) {
// Atempt to find warp which starts with the given name // Attempt to find warp which starts with the given name
UUID foundAlernativeWarp = warpList.stream().filter(u -> getPlayers().getName(u).toLowerCase().startsWith(args.get(0).toLowerCase())).findFirst().orElse(null); UUID foundAlernativeWarp = warpList.stream().filter(u -> getPlayers().getName(u).toLowerCase().startsWith(args.get(0).toLowerCase())).findFirst().orElse(null);
if (foundAlernativeWarp == null) { if (foundAlernativeWarp == null) {

View File

@ -61,6 +61,8 @@ public class Settings implements ConfigObject
String warpCommand = "warp"; String warpCommand = "warp";
@ConfigEntry(path = "warps-command") @ConfigEntry(path = "warps-command")
String warpsCommand = "warps"; String warpsCommand = "warps";
@ConfigEntry(path = "togglewarp-command")
String toggleWarpCommand = "togglewarp";
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Section: Constructor // Section: Constructor
@ -205,6 +207,21 @@ public class Settings implements ConfigObject
this.warpsCommand = warpsCommand; this.warpsCommand = warpsCommand;
} }
/**
* @return the toggleWarpCommand
*/
public String getToggleWarpCommand() {
return toggleWarpCommand;
}
/**
* @param toggleWarpCommand the toggleWarpCommand to set
*/
public void setToggleWarpCommand(String toggleWarpCommand) {
this.toggleWarpCommand = toggleWarpCommand;
}
/** /**
* @return the removeExistingWarpsWhenFlagChanges * @return the removeExistingWarpsWhenFlagChanges
*/ */

View File

@ -15,7 +15,7 @@ import world.bentobox.warps.Warp;
* @author Poslovitch * @author Poslovitch
* *
*/ */
public class WarpCreateEvent extends Event{ public class WarpCreateEvent extends Event {
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private final Location warpLoc; private final Location warpLoc;

View File

@ -0,0 +1,72 @@
package world.bentobox.warps.event;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import world.bentobox.warps.objects.PlayerWarp;
import java.util.UUID;
/**
* This event is fired when a warp is toggled
* A Listener to this event can use it only to get information. e.g: broadcast something
*
* @since 1.16.0
* @author TreemanKing
*/
public class WarpToggleEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final UUID user;
private final PlayerWarp playerWarp;
public WarpToggleEvent(UUID user, PlayerWarp playerWarp) {
this.playerWarp = playerWarp;
this.user = user;
}
/**
* Gets the user who has toggled the warp
*
* @return the UUID of the player who toggled the warp
*/
public UUID getUser() {
return user;
}
/**
* Gets the state of the warp
*
* @return true if the warp is enabled, false otherwise
*/
public boolean isEnabled() {
return playerWarp.isEnabled();
}
/**
* Gets the PlayerWarp object
*
* @return the PlayerWarp object
*/
public PlayerWarp getPlayerWarp() {
return playerWarp;
}
/**
* Gets the location of the toggled warp
*
* @return the location of the warp
*/
public Location getLocation() {
return playerWarp.getLocation();
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -28,6 +28,7 @@ import world.bentobox.bentobox.api.events.team.TeamLeaveEvent;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.objects.PlayerWarp;
import world.bentobox.warps.Warp; import world.bentobox.warps.Warp;
import world.bentobox.warps.event.WarpRemoveEvent; import world.bentobox.warps.event.WarpRemoveEvent;
@ -60,12 +61,12 @@ public class WarpSignsListener implements Listener {
@Override @Override
public void run() { public void run() {
boolean changed = false; boolean changed = false;
Iterator<Map.Entry<UUID, Location>> iterator = Iterator<Map.Entry<UUID, PlayerWarp>> iterator =
addon.getWarpSignsManager().getWarpMap(event.getWorld()).entrySet().iterator(); addon.getWarpSignsManager().getWarpMap(event.getWorld()).entrySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Map.Entry<UUID, Location> entry = iterator.next(); Map.Entry<UUID, PlayerWarp> entry = iterator.next();
UUID uuid = entry.getKey(); UUID uuid = entry.getKey();
Location location = entry.getValue(); Location location = entry.getValue().getLocation();
if (event.getChunk().getX() == location.getBlockX() >> 4 if (event.getChunk().getX() == location.getBlockX() >> 4
&& event.getChunk().getZ() == location.getBlockZ() >> 4 && event.getChunk().getZ() == location.getBlockZ() >> 4
&& !Tag.SIGNS.isTagged(location.getBlock().getType())) { && !Tag.SIGNS.isTagged(location.getBlock().getType())) {
@ -126,16 +127,16 @@ public class WarpSignsListener implements Listener {
private boolean isPlayersSign(Player player, Block b, boolean inWorld) { private boolean isPlayersSign(Player player, Block b, boolean inWorld) {
// Welcome sign detected - check to see if it is this player's sign // Welcome sign detected - check to see if it is this player's sign
Map<UUID, Location> list = addon.getWarpSignsManager().getWarpMap(b.getWorld()); Map<UUID, PlayerWarp> list = addon.getWarpSignsManager().getWarpMap(b.getWorld());
String reqPerm = inWorld ? addon.getPermPrefix(b.getWorld()) + "mod.removesign" : Warp.WELCOME_WARP_SIGNS + ".mod.removesign"; String reqPerm = inWorld ? addon.getPermPrefix(b.getWorld()) + "mod.removesign" : Warp.WELCOME_WARP_SIGNS + ".mod.removesign";
return ((list.containsKey(player.getUniqueId()) && list.get(player.getUniqueId()).equals(b.getLocation())) return ((list.containsKey(player.getUniqueId()) && list.get(player.getUniqueId()).getLocation().equals(b.getLocation()))
|| player.isOp() || player.hasPermission(reqPerm)); || player.isOp() || player.hasPermission(reqPerm));
} }
private boolean isWarpSign(Block b) { private boolean isWarpSign(Block b) {
Sign s = (Sign) b.getState(); Sign s = (Sign) b.getState();
return s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine()) return s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())
&& addon.getWarpSignsManager().getWarpMap(b.getWorld()).containsValue(s.getLocation()); && addon.getWarpSignsManager().getWarpMap(b.getWorld()).values().stream().anyMatch(playerWarp -> playerWarp.getLocation().equals(s.getLocation()));
} }
/** /**
@ -158,19 +159,24 @@ public class WarpSignsListener implements Listener {
if (noPerms(user, b.getWorld(), inWorld)) { if (noPerms(user, b.getWorld(), inWorld)) {
return; return;
} }
// TODO: These checks are useless if the sign is placed outside a BSB world.
// This will mean level and rank requirements are nil in the case of allow-in-other-worlds: true.
// I'm not sure if there is a better way around this without adding new API checking for primary
// or last island accessed with relevant permissions.
// ignored.
if (inWorld && noLevelOrIsland(user, b.getWorld())) { if (inWorld && noLevelOrIsland(user, b.getWorld())) {
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
return; return;
} }
if(!hasCorrectIslandRank(b, user)) { if (inWorld && !hasCorrectIslandRank(b, user)) {
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine()); e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
user.sendMessage("warps.error.not-correct-rank"); user.sendMessage("warps.error.not-correct-rank");
return; return;
} }
// Check if the player already has a sign // Check if the player already has a sign
final Location oldSignLoc = addon.getWarpSignsManager().getWarp(b.getWorld(), user.getUniqueId()); final Location oldSignLoc = addon.getWarpSignsManager().getWarpLocation(b.getWorld(), user.getUniqueId());
if (oldSignLoc != null) { if (oldSignLoc != null) {
// A sign already exists. Check if it still there and if // A sign already exists. Check if it still there and if
// so, // so,
@ -216,15 +222,15 @@ public class WarpSignsListener implements Listener {
final Island island = e.getIsland(); final Island island = e.getIsland();
final Map<UUID, Location> islandWarps = addon final Map<UUID, PlayerWarp> islandWarps = addon
.getWarpSignsManager() .getWarpSignsManager()
.getWarpMap(island.getWorld()) .getWarpMap(island.getWorld())
.entrySet() .entrySet()
.stream() .stream()
.filter(x -> island.inIslandSpace(x.getValue())) .filter(x -> island.inIslandSpace(x.getValue().getLocation()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
for(Map.Entry<UUID, Location> entry : islandWarps.entrySet()) { for(Map.Entry<UUID, PlayerWarp> entry : islandWarps.entrySet()) {
if(island.getRank(entry.getKey()) >= e.getSetTo()) continue; if(island.getRank(entry.getKey()) >= e.getSetTo()) continue;
//The user has a lower rank than the new set value. //The user has a lower rank than the new set value.

View File

@ -37,7 +37,9 @@ import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.objects.PlayerWarp;
import world.bentobox.warps.Warp; import world.bentobox.warps.Warp;
import world.bentobox.warps.event.WarpCreateEvent;
import world.bentobox.warps.event.WarpInitiateEvent; import world.bentobox.warps.event.WarpInitiateEvent;
import world.bentobox.warps.objects.WarpsData; import world.bentobox.warps.objects.WarpsData;
import world.bentobox.warps.panels.Utils; import world.bentobox.warps.panels.Utils;
@ -54,7 +56,7 @@ public class WarpSignsManager {
private static final String WARPS = "warps"; private static final String WARPS = "warps";
private final BentoBox plugin; private final BentoBox plugin;
// Map of all warps stored as player, warp sign Location // Map of all warps stored as player, warp sign Location
private Map<World, Map<UUID, Location>> worldsWarpList; private Map<World, Map<UUID, PlayerWarp>> worldsWarpList;
// Database handler for level data // Database handler for level data
private final Database<WarpsData> handler; private final Database<WarpsData> handler;
@ -67,7 +69,7 @@ public class WarpSignsManager {
* @return map of warps * @return map of warps
*/ */
@NonNull @NonNull
public Map<UUID, Location> getWarpMap(@Nullable World world) { public Map<UUID, PlayerWarp> getWarpMap(@Nullable World world) {
return worldsWarpList.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>()); return worldsWarpList.computeIfAbsent(Util.getWorld(world), k -> new HashMap<>());
} }
@ -99,13 +101,15 @@ public class WarpSignsManager {
return false; return false;
} }
// Check for warps placed in a location where there was a warp before // Check for warps placed in a location where there was a warp before
if (getWarpMap(loc.getWorld()).containsValue(loc)) { for (PlayerWarp playerWarp : getWarpMap(loc.getWorld()).values()) {
// remove the warp at this location, then place it if (playerWarp.getLocation().equals(loc)) {
this.removeWarp(loc); this.removeWarp(loc);
break;
}
} }
getWarpMap(loc.getWorld()).put(playerUUID, loc); getWarpMap(loc.getWorld()).put(playerUUID, new PlayerWarp(loc, true));
saveWarpList(); saveWarpList();
Bukkit.getPluginManager().callEvent(new WarpInitiateEvent(addon, loc, playerUUID)); Bukkit.getPluginManager().callEvent(new WarpCreateEvent(addon, loc, playerUUID));
return true; return true;
} }
@ -118,7 +122,13 @@ public class WarpSignsManager {
* @return Location of warp or null * @return Location of warp or null
*/ */
@Nullable @Nullable
public Location getWarp(World world, UUID playerUUID) { public Location getWarpLocation(World world, UUID playerUUID) {
PlayerWarp playerWarp = getWarpMap(world).get(playerUUID);
return playerWarp != null ? playerWarp.getLocation() : null;
}
@Nullable
public PlayerWarp getPlayerWarp(World world, UUID playerUUID) {
return getWarpMap(world).get(playerUUID); return getWarpMap(world).get(playerUUID);
} }
@ -129,7 +139,7 @@ public class WarpSignsManager {
*/ */
@NonNull @NonNull
public String getWarpOwner(Location location) { public String getWarpOwner(Location location) {
return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().equals(location)) return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().getLocation().equals(location))
.findFirst().map(en -> plugin.getPlayers().getName(en.getKey())).orElse(""); .findFirst().map(en -> plugin.getPlayers().getName(en.getKey())).orElse("");
} }
@ -139,7 +149,7 @@ public class WarpSignsManager {
* @return Optional UUID of warp owner or empty if there is none * @return Optional UUID of warp owner or empty if there is none
*/ */
public Optional<UUID> getWarpOwnerUUID(Location location) { public Optional<UUID> getWarpOwnerUUID(Location location) {
return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().equals(location)) return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().getLocation().equals(location))
.findFirst().map(Map.Entry::getKey); .findFirst().map(Map.Entry::getKey);
} }
@ -159,6 +169,10 @@ public class WarpSignsManager {
// Bigger value of time means a more recent login // Bigger value of time means a more recent login
TreeMap<Long, UUID> map = new TreeMap<>(); TreeMap<Long, UUID> map = new TreeMap<>();
getWarpMap(world).forEach((uuid, value) -> { getWarpMap(world).forEach((uuid, value) -> {
// If the warp is not enabled, skip this iteration
if (!value.isEnabled()) {
return;
}
// If never played, will be zero // If never played, will be zero
long lastPlayed = addon.getServer().getOfflinePlayer(uuid).getLastPlayed(); long lastPlayed = addon.getServer().getOfflinePlayer(uuid).getLastPlayed();
// This aims to avoid the chance that players logged off at exactly the same time // This aims to avoid the chance that players logged off at exactly the same time
@ -187,7 +201,11 @@ public class WarpSignsManager {
public Set<UUID> listWarps(@NonNull World world) { public Set<UUID> listWarps(@NonNull World world) {
// Remove any null locations // Remove any null locations
getWarpMap(world).values().removeIf(Objects::isNull); getWarpMap(world).values().removeIf(Objects::isNull);
return getWarpMap(world).entrySet().stream().filter(e -> Util.sameWorld(world, Objects.requireNonNull(e.getValue().getWorld()))).map(Map.Entry::getKey).collect(Collectors.toSet()); // Remove any warps that have not been toggled on
Map<UUID, PlayerWarp> enabledWarps = getWarpMap(world).entrySet().stream()
.filter(entry -> entry.getValue().isEnabled())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return enabledWarps.keySet();
} }
/** /**
@ -200,7 +218,8 @@ public class WarpSignsManager {
warpsData = handler.loadObject(WARPS); warpsData = handler.loadObject(WARPS);
// Load into map // Load into map
if (warpsData != null) { if (warpsData != null) {
warpsData.getWarpSigns().forEach((location,uuid) -> { warpsData.getWarpSigns().forEach((pw, uuid) -> {
Location location = pw.getLocation();
if (location != null && location.getWorld() != null) { if (location != null && location.getWorld() != null) {
if (location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4) if (location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)
&& !location.getBlock().getType().name().contains("SIGN")) { && !location.getBlock().getType().name().contains("SIGN")) {
@ -208,7 +227,7 @@ public class WarpSignsManager {
} }
// Add to map // Add to map
getWarpMap(location.getWorld()).put(uuid, location); getWarpMap(location.getWorld()).put(uuid, new PlayerWarp(location, true));
} }
}); });
} else { } else {
@ -239,10 +258,10 @@ public class WarpSignsManager {
*/ */
public void removeWarp(Location loc) { public void removeWarp(Location loc) {
popSign(loc); popSign(loc);
Iterator<Entry<UUID, Location>> it = getWarpMap(loc.getWorld()).entrySet().iterator(); Iterator<Entry<UUID, PlayerWarp>> it = getWarpMap(loc.getWorld()).entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Entry<UUID, Location> en = it.next(); Entry<UUID, PlayerWarp> en = it.next();
if (en.getValue().equals(loc)) { if (en.getValue().getLocation().equals(loc)) {
// Inform player // Inform player
Optional.ofNullable(addon.getServer().getPlayer(en.getKey())) Optional.ofNullable(addon.getServer().getPlayer(en.getKey()))
.map(User::getInstance) .map(User::getInstance)
@ -262,7 +281,7 @@ public class WarpSignsManager {
*/ */
public void removeWarp(World world, UUID uuid) { public void removeWarp(World world, UUID uuid) {
if (getWarpMap(world).containsKey(uuid)) { if (getWarpMap(world).containsKey(uuid)) {
popSign(getWarpMap(world).get(uuid)); popSign(getWarpMap(world).get(uuid).getLocation());
getWarpMap(world).remove(uuid); getWarpMap(world).remove(uuid);
} }
@ -298,7 +317,7 @@ public class WarpSignsManager {
@NonNull @NonNull
public SignCacheItem getSignInfo(@NonNull World world, @NonNull UUID uuid) { public SignCacheItem getSignInfo(@NonNull World world, @NonNull UUID uuid) {
//get the sign info //get the sign info
Location signLocation = getWarp(world, uuid); Location signLocation = getWarpLocation(world, uuid);
if (signLocation == null || !signLocation.getBlock().getType().name().contains("SIGN")) { if (signLocation == null || !signLocation.getBlock().getType().name().contains("SIGN")) {
return new SignCacheItem(); return new SignCacheItem();
} }
@ -350,6 +369,11 @@ public class WarpSignsManager {
float yaw = Util.blockFaceToFloat(directionFacing); float yaw = Util.blockFaceToFloat(directionFacing);
final Location actualWarp = new Location(inFront.getWorld(), inFront.getBlockX() + 0.5D, inFront.getBlockY(), final Location actualWarp = new Location(inFront.getWorld(), inFront.getBlockX() + 0.5D, inFront.getBlockY(),
inFront.getBlockZ() + 0.5D, yaw, 30F); inFront.getBlockZ() + 0.5D, yaw, 30F);
WarpInitiateEvent e = new WarpInitiateEvent(addon, actualWarp, user.getUniqueId());
Bukkit.getPluginManager().callEvent(e);
if (e.isCancelled()) {
return;
}
//BentoBox prevents people from teleporting to an island when //BentoBox prevents people from teleporting to an island when
//the user is banned from the island for example. //the user is banned from the island for example.
//By checking if the teleport succeeded before sending the messages, //By checking if the teleport succeeded before sending the messages,
@ -387,7 +411,7 @@ public class WarpSignsManager {
* @param owner - owner of the warp * @param owner - owner of the warp
*/ */
public void warpPlayer(@NonNull World world, @NonNull User user, @NonNull UUID owner) { public void warpPlayer(@NonNull World world, @NonNull User user, @NonNull UUID owner) {
final Location warpSpot = getWarp(world, owner); final Location warpSpot = getWarpLocation(world, owner);
// Check if the warp spot is safe // Check if the warp spot is safe
if (warpSpot == null) { if (warpSpot == null) {
user.sendMessage("warps.error.does-not-exist"); user.sendMessage("warps.error.does-not-exist");

View File

@ -0,0 +1,32 @@
package world.bentobox.warps.objects;
import com.google.gson.annotations.Expose;
import org.bukkit.Location;
import java.io.Serializable;
public class PlayerWarp implements Serializable {
@Expose
private final Location location;
@Expose
private boolean isEnabled;
public PlayerWarp(Location location, boolean isEnabled) {
this.location = location;
this.isEnabled = isEnabled;
}
public Location getLocation() {
return location;
}
public boolean isEnabled() {
return isEnabled;
}
public void toggle() {
isEnabled = !isEnabled;
}
}

View File

@ -17,9 +17,13 @@ public class WarpsData implements DataObject {
@Expose @Expose
private String uniqueId = "warps"; private String uniqueId = "warps";
@Expose
@Deprecated @Expose
private Map<Location, UUID> warpSigns = new HashMap<>(); private Map<Location, UUID> warpSigns = new HashMap<>();
@Expose
private Map<PlayerWarp, UUID> newWarpSigns = new HashMap<>();
public WarpsData() { public WarpsData() {
// Required by YAML database // Required by YAML database
} }
@ -34,24 +38,40 @@ public class WarpsData implements DataObject {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
} }
public Map<Location, UUID> getWarpSigns() { public Map<PlayerWarp, UUID> getWarpSigns() {
if (warpSigns == null) convertOldWarpSigns();
if (newWarpSigns == null)
return new HashMap<>(); return new HashMap<>();
return warpSigns; return newWarpSigns;
}
public void setWarpSigns(Map<Location, UUID> warpSigns) {
this.warpSigns = warpSigns;
} }
/** /**
* Puts all the data from the map into this objects ready for saving * Method for converting old warp signs to new warp signs
*/
public void convertOldWarpSigns() {
if (warpSigns == null) {
return;
}
for (Map.Entry<Location, UUID> entry : warpSigns.entrySet()) {
PlayerWarp playerWarp = new PlayerWarp(entry.getKey(), true);
newWarpSigns.put(playerWarp, entry.getValue());
}
warpSigns = null;
}
public void setWarpSigns(Map<PlayerWarp, UUID> warpSigns) {
this.newWarpSigns = warpSigns;
}
/**
* Puts all the data from the map into these objects ready for saving
* @param worldsWarpList 2D map of warp locations by world vs UUID * @param worldsWarpList 2D map of warp locations by world vs UUID
* @return this class filled with data * @return this class filled with data
*/ */
public WarpsData save(Map<World, Map<UUID, Location>> worldsWarpList) { public WarpsData save(Map<World, Map<UUID, PlayerWarp>> worldsWarpList) {
getWarpSigns().clear(); getWarpSigns().clear();
worldsWarpList.values().forEach(world -> world.forEach((uuid,location) -> warpSigns.put(location, uuid))); worldsWarpList.values().forEach(world -> world.forEach((uuid,playerWarp) -> newWarpSigns.put(playerWarp, uuid)));
return this; return this;
} }

View File

@ -52,7 +52,7 @@ public class Utils
List<String> permissions = user.getEffectivePermissions().stream(). List<String> permissions = user.getEffectivePermissions().stream().
map(PermissionAttachmentInfo::getPermission). map(PermissionAttachmentInfo::getPermission).
filter(permission -> permission.startsWith(permPrefix)). filter(permission -> permission.startsWith(permPrefix)).
collect(Collectors.toList()); toList();
for (String permission : permissions) for (String permission : permissions)
{ {

View File

@ -18,3 +18,6 @@ permissions:
'[gamemode].island.addwarp': '[gamemode].island.addwarp':
description: Player can create a welcome warp sign description: Player can create a welcome warp sign
default: true default: true
'[gamemode].island.togglewarp':
description: Player can toggle a warp sign
default: true

View File

@ -33,3 +33,4 @@ allow-in-other-worlds: false
# Warp and warps commands. You can change them if they clash with other addons or plugins. # Warp and warps commands. You can change them if they clash with other addons or plugins.
warp-command: warp warp-command: warp
warps-command: warps warps-command: warps
togglewarp-command: togglewarp

View File

@ -1,14 +1,8 @@
########################################################################################### ---
# 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 #
# #
# Translation by: CZghost #
###########################################################################################
warp: warp:
help: help:
description: "Teleportovat se na warp ceduli hráče" description: Teleportovat se na warp ceduli hráče
parameters: <player name> parameters: "<player name>"
warps: warps:
deactivate: "&c Stará warp cedule deaktivována!" deactivate: "&c Stará warp cedule deaktivována!"
error: error:
@ -19,17 +13,49 @@ warps:
not-enough-level: "&c Úroveň tvého ostrova není dostatečně vysoká!" not-enough-level: "&c Úroveň tvého ostrova není dostatečně vysoká!"
not-on-island: "&c K tomuto musíš být na svém ostrově!" not-on-island: "&c K tomuto musíš být na svém ostrově!"
not-safe: "&c Tento warp není bezpečný!" not-safe: "&c Tento warp není bezpečný!"
your-level-is: "&c Úroveň tvého ostrova je jen [level], musí být vyšší než [required]. Spusť příkaz pro úroveň." your-level-is: "&c Úroveň tvého ostrova je jen [level], musí být vyšší než [required].
Spusť příkaz pro úroveň."
not-correct-rank: "&c Nemáte správnou hodnost pro nastavení warpu!"
help: help:
description: "otevřít panel warpů" description: otevřít panel warpů
next: "&6 Další stránka" player-warped: "&2 [name] se pokřivilo na váš [gamemode] warp znamení!"
player-warped: "&2 [name] se teleportoval na tvou warp ceduli!"
previous: "&6 Předchozí stránka"
random: "&4 Náhodný warp"
sign-removed: "&c Warp cedule odstraněna!" sign-removed: "&c Warp cedule odstraněna!"
success: "&a Úspěch!" success: "&a Úspěch!"
title: "Warp cedule"
warpTip: "&6 Polož warp ceduli s [text] na vrchu" warpTip: "&6 Polož warp ceduli s [text] na vrchu"
warpToPlayersSign: "&6 Teleportuji tě na ceduli [player]" warpToPlayersSign: "&6 Teleportuji tě na ceduli [player]"
gui:
titles:
warp-title: "&0&l Warp Signs"
buttons:
previous:
name: "&f&l Předchozí stránka"
description: "&7 Přepnout na stránku [number]"
next:
name: "&f&l Další stránka"
description: "&7 Přepnout na stránku [number]"
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Náhodné pokřivení"
description: "&7 Hmm, kde se objevím?"
tips:
click-to-previous: "&e Klepnutím na &7 zobrazíte předchozí stránku."
click-to-next: "&e Klepnutím na &7 zobrazíte další stránku."
click-to-warp: "&e Klikněte na &7 pro deformaci."
conversations:
prefix: "&l&6 [BentoBox]: &r"
togglewarp:
help:
description: přepnout znak warp
enabled: "&a Vaše warp je nyní viditelný!"
disabled: "&c Váš warp je nyní skrytý!"
error:
no-permission: "&c K tomu nemáte oprávnění!"
generic: "&c Při přepínání vašeho warpu došlo k chybě."
no-warp: "&c Nemáte warp k přepínání!"
protection:
flags:
PLACE_WARP:
name: Umístěte Warp
description: Povolit umístění warp znamení

View File

@ -15,9 +15,10 @@ warps:
not-safe: "&c Dieser Warp ist nicht sicher!" not-safe: "&c Dieser Warp ist nicht sicher!"
your-level-is: "&c Dein Insel-Level ist erst [level] und muss höher als [required] your-level-is: "&c Dein Insel-Level ist erst [level] und muss höher als [required]
sein. Nutze das Level Kommando." sein. Nutze das Level Kommando."
not-correct-rank: "&c Sie haben nicht den richtigen Rang, um einen Warp einzustellen!"
help: help:
description: Öffnet das Warps Panel description: Öffnet das Warps Panel
player-warped: "&2 [name] hat sich zu deinem Warp Schild gewarpt!" player-warped: "&2 [name] ist zu deinem [gamemode]-Warp-Zeichen gesprungen!"
sign-removed: "&c Warp Schild entfernt!" sign-removed: "&c Warp Schild entfernt!"
success: "&a Erfolg!" success: "&a Erfolg!"
warpTip: "&6 Platziere ein Warp Schild mit [text] in der ersten Zeile" warpTip: "&6 Platziere ein Warp Schild mit [text] in der ersten Zeile"
@ -44,3 +45,17 @@ warps:
click-to-warp: "&e Zum Warpen &7 klicken." click-to-warp: "&e Zum Warpen &7 klicken."
conversations: conversations:
prefix: "&l&6 [BentoBox]: &r" prefix: "&l&6 [BentoBox]: &r"
togglewarp:
help:
description: das Warp-Zeichen umschalten
enabled: "&a Ihr Warp ist jetzt sichtbar!"
disabled: "&c Ihr Warp ist jetzt verborgen!"
error:
no-permission: "&c Sie haben keine Berechtigung, das zu tun!"
generic: "&c Beim Umschalten Ihres Warps ist ein Fehler aufgetreten."
no-warp: "&c Sie haben keinen Warp zum Umschalten!"
protection:
flags:
PLACE_WARP:
name: Warp platzieren
description: Platzieren von Warp-Zeichen zulassen

View File

@ -60,6 +60,16 @@ warps:
# Prefix for messages that are send from server. # Prefix for messages that are send from server.
prefix: "&l&6 [BentoBox]: &r" prefix: "&l&6 [BentoBox]: &r"
togglewarp:
help:
description: "toggle the warp sign"
enabled: "&a Your warp is now visible!"
disabled: "&c Your warp is now hidden!"
error:
no-permission: "&c You do not have permission to do that!"
generic: "&c An error occurred while toggling your warp."
no-warp: "&c You do not have a warp to toggle!"
protection: protection:
flags: flags:
PLACE_WARP: PLACE_WARP:

View File

@ -4,25 +4,59 @@ warp:
description: te téléporte au Warp d'un autre joueur description: te téléporte au Warp d'un autre joueur
parameters: "<pseudo>" parameters: "<pseudo>"
warps: warps:
deactivate: "&cAncien panneau de Warp désactivé !" deactivate: "&c Ancienne pancarte de warp désactivée !"
error: error:
does-not-exist: "&cCe Warp n'existe plus !" does-not-exist: "&c Oh ! Cette téléportation n'existe plus !"
no-permission: "&cVous n'avez pas la permission pour faire cela !" no-permission: "&c Vous n'avez pas le droit de faire cela !"
no-remove: "&cVous ne pouvez pas supprimer ce panneau !" no-remove: "&c Vous ne pouvez pas enlever cette pancarte !"
no-warps-yet: "&cIl n'y a encore aucun Warp sur ce serveur." no-warps-yet: "&c Il n'y a pas encore de téléportation disponible"
not-enough-level: "&cVotre niveau d'île n'est pas assez élevé pour faire cela not-enough-level: "&c Le niveau de votre île n'est pas assez élevé !"
!" not-on-island: "&c Vous devez être sur votre île pour faire cela !"
not-on-island: "&cVous devez être sur votre île pour faire cela !" not-safe: "&c Cette téléportation n'est pas sûre !"
not-safe: "&cCe Warp n'est pas sûr!" your-level-is: "&c Le niveau de votre île n'est que [level] et doit être supérieur
your-level-is: "&cVotre île est seulement niveau [level] et doit être niveau [required]." à [required]. Exécutez la commande level."
not-correct-rank: "&c Vous n'avez pas le grade adéquat pour poser une chaîne !"
help: help:
description: Ouvre le menu des Warps description: Ouvre le menu des Warps
next: "&6Page suivante" player-warped: "&2 [name] s'est rendu à votre pancarte de téléportation [gamemode]
player-warped: "& 2 [pseudo] s'est téléporté à votre panneau Warp !" !"
previous: "&6Page précédente" sign-removed: "&c Panneau de téléportation enlevé !"
random: "&4 Warp aléatoire " success: "&a Succès !"
sign-removed: "&cPanneau de Warp supprimé !" warpTip: "&6 Placer une pancarte de téléportation avec [text] sur le dessus"
success: "&aSuccès !" warpToPlayersSign: "&6 Téléportation a la pancarte de [player]"
title: Panneau Warp gui:
warpTip: "&6Placez un panneau et écrivez [text] sur la première ligne." titles:
warpToPlayersSign: "&6 Téléportation vers le panneau de [pseudo]" warp-title: "&0&l Pancarte de téléportation"
buttons:
previous:
name: "&f&l Page précédente"
description: "&7 Aller à la page [numéro]."
next:
name: "&f&l Page suivante"
description: "&7 Passer à la page [numéro]."
warp:
name: "&f&l [name]"
description: "[sign_text]"
random:
name: "&f&l Téléportation aléatoire"
description: "&7 Hmm, où vais-je apparaître ?"
tips:
click-to-previous: "&e Cliquez sur &7 pour afficher la page précédente."
click-to-next: "&e Cliquez sur &7 pour afficher la page suivante."
click-to-warp: "&e Cliquez sur &7 pour te téléporter."
conversations:
prefix: "&l&6 [BentoBox]: &r"
togglewarp:
help:
description: basculer le signe de distorsion
enabled: "&a Votre chaîne est maintenant visible !"
disabled: "&c Votre chaîne est maintenant cachée !"
error:
no-permission: "&c Vous n'avez pas la permission de faire ça !"
generic: "&c Une erreur s'est produite lors du basculement de votre chaîne."
no-warp: "&c Vous n'avez pas de chaîne à activer !"
protection:
flags:
PLACE_WARP:
name: Place téléportation
description: Autoriser le placement d'un panneau téléportation

View File

@ -1,32 +1,60 @@
########################################################################################### ---
# 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: warp:
help: help:
description: "プレイヤーのワープサインにワープする" description: プレイヤーのワープサインにワープする
parameters: <名> parameters: "<名>"
warps: warps:
deactivate: "&c前のワープサインが無効になりました!" deactivate: "&c 古いワープサインが無効になりました!"
error: error:
does-not-exist: "&cそのワープはもう存在しません" does-not-exist: "&c ああ、やられた!そのワープはもう存在しない!"
no-permission: "&C許可がありません" no-permission: "&c あなたにはそれを実行する権限がありません!"
no-remove: "&Cワープサインは外せません" no-remove: "&c その標識は削除できません!"
no-warps-yet: "&C利用可能なワープはまだありません" no-warps-yet: "&c ワープはまだ利用できません"
not-enough-level: "&C島のレベルは十分に高くありません" not-enough-level: "&c あなたの島のレベルは十分に高くありません!"
not-on-island: "&Cあなたの島にいなければなりません" not-on-island: "&c それを実行するには、自分の島にいる必要があります。"
not-safe: "&cワープは安全ではありません。!" not-safe: "&c そのワープは安全ではありません!"
your-level-is: "&c島レベルはわずか[level]で、[required]より高くなければなりません" your-level-is: "&c あなたの島のレベルは [level] のみで、[required] より高くなければなりません。level コマンドを実行してください。"
not-correct-rank: "&c ワープを設定するための適切なランクがありません。"
help: help:
description: "ワープパネルを開く" description: ワープパネルを開く
next: "&6次のページ" player-warped: "&2 [name] があなたの [gamemode] ワープサインにワープしました!"
player-warped: "&2[name]はあなたのワープサインに反った!" sign-removed: "&c ワープサインが削除されました!"
previous: "&6前のページ" success: "&a 成功しました!"
sign-removed: "&Cワープサインを削除!" warpTip: "&6 [text]を上部に記したワープサインを配置する"
success: "&A完了!" warpToPlayersSign: "&6 [player]のサインにワープ"
title: "ワープサイン" gui:
warpTip: "&6最初の行に[text]と一緒にワープサインを置きます" titles:
warpToPlayersSign: "&6[player]のサインに反っている" 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 [弁当箱]: &r"
togglewarp:
help:
description: ワープサインを切り替える
enabled: "&a ワープが見えるようになりました!"
disabled: "&c ワープが非表示になりました!"
error:
no-permission: "&c あなたにはそれを実行する権限がありません!"
generic: "&c ワープの切り替え中にエラーが発生しました。"
no-warp: "&c 切り替えるワープがありません!"
protection:
flags:
PLACE_WARP:
name: ワープを配置
description: ワープサインの設置を許可する

View File

@ -1,27 +1,60 @@
--- ---
warp: warp:
help: help:
description: 传送到该玩家的传送木牌处 description: 传送至对应玩家的坐标告示牌
parameters: "<player name>" parameters: "<player name>"
warps: warps:
help: deactivate: "&c检测到不活跃的坐标告示牌!"
description: 打开传送面板
title: 传送木牌
deactivate: "&c 旧传送牌已停用!"
error: error:
does-not-exist: "&c 哦不!那个传送点已经没了!" does-not-exist: "&c啊哦! 那个传送点已经不存在了!"
no-permission: "&c 你无权那样做!" no-permission: "&c你没有权限做这件事!"
no-remove: "&c 你拿不掉那个牌子的!" no-remove: "&c你不能移除该告示牌!"
no-warps-yet: "&c 暂无可用传送点" no-warps-yet: "&c尚无可用传送点."
not-enough-level: "&c 你的岛等级不够高!" not-enough-level: "&c你空岛的等级还不够高!"
not-on-island: "&c 你得在自己的岛屿上操作!" not-on-island: "&c你必须在自己的空岛上做这件事!"
not-safe: "&c 目标传送点不安全!" not-safe: "&c该传送点不安全!"
your-level-is: "&c 你的岛现在 [level] 级,需要 [required] 级。 试试岛屿等级命令吧。" your-level-is: "&c你空岛的等级只有[level], 但必须高于[required]. 使用/is level查看等级."
next: "&6 次页" not-correct-rank: "&c你在团队中的地位不足以让你设立传送点!"
player-warped: "&2 [name] 传送到了你的传送牌!" help:
previous: "&6 前页" description: 打开传送点面板
random: "&4 随机传送" player-warped: "&2 [name]传送到了你[gamemode]的坐标告示牌!"
sign-removed: "&c 拆掉传送牌了!" sign-removed: "&c坐标告示牌已移除!"
success: "&a 成了!" success: "&a成功!"
warpTip: "&6 放个牌子第一行写 [text]" warpTip: "&6放置一个顶部为[text]的坐标告示牌"
warpToPlayersSign: "&6 正传送到 [player] 的牌子" 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"
togglewarp:
help:
description: 切换扭曲符号
enabled: "&a 你的扭曲现在可见了!"
disabled: "&c 你的扭曲现已隐藏!"
error:
no-permission: "&c您没有权限这么做"
generic: "&c 切换扭曲时发生错误。"
no-warp: "&c 您没有可​​切换的扭曲!"
protection:
flags:
PLACE_WARP:
name: 放置传送点
description: 允许放置坐标告示牌

View File

@ -19,7 +19,7 @@ warps_panel:
8: warp_button 8: warp_button
3: 3:
1: 1:
icon: TIPPED_ARROW:INSTANT_HEAL::::1 icon: tipped_arrow{CustomPotionColor:11546150}
title: warps.gui.buttons.previous.name title: warps.gui.buttons.previous.name
description: warps.gui.buttons.previous.description description: warps.gui.buttons.previous.description
data: data:
@ -37,7 +37,7 @@ warps_panel:
7: warp_button 7: warp_button
8: warp_button 8: warp_button
9: 9:
icon: TIPPED_ARROW:JUMP::::1 icon: tipped_arrow{CustomPotionColor:8439583}
title: warps.gui.buttons.next.name title: warps.gui.buttons.next.name
description: warps.gui.buttons.next.description description: warps.gui.buttons.next.description
data: data:

View File

@ -8,7 +8,9 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -40,6 +42,7 @@ import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
@ -60,9 +63,11 @@ import world.bentobox.bentobox.managers.PlaceholdersManager;
import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.config.Settings; import world.bentobox.warps.config.Settings;
import world.bentobox.warps.event.WarpCreateEvent;
import world.bentobox.warps.event.WarpInitiateEvent; import world.bentobox.warps.event.WarpInitiateEvent;
import world.bentobox.warps.managers.SignCacheManager; import world.bentobox.warps.managers.SignCacheManager;
import world.bentobox.warps.managers.WarpSignsManager; import world.bentobox.warps.managers.WarpSignsManager;
import world.bentobox.warps.objects.PlayerWarp;
import world.bentobox.warps.objects.WarpsData; import world.bentobox.warps.objects.WarpsData;
@ -191,7 +196,7 @@ public class WarpSignsManagerTest {
// Handler // Handler
when(handler.objectExists("warps")).thenReturn(true); when(handler.objectExists("warps")).thenReturn(true);
Map<Location, UUID> warpMap = Collections.singletonMap(location, uuid); Map<PlayerWarp, UUID> warpMap = Collections.singletonMap(new PlayerWarp(location, true), uuid);
when(load.getWarpSigns()).thenReturn(warpMap); when(load.getWarpSigns()).thenReturn(warpMap);
when(handler.loadObject(anyString())).thenReturn(load); when(handler.loadObject(anyString())).thenReturn(load);
@ -271,7 +276,8 @@ public class WarpSignsManagerTest {
*/ */
@Test @Test
public void testGetWarpMapNullLocation() { public void testGetWarpMapNullLocation() {
Map<Location, UUID> warpMap = Collections.singletonMap(null, uuid); PlayerWarp playerWarp = new PlayerWarp(null, true);
Map<PlayerWarp, UUID> warpMap = Collections.singletonMap(playerWarp, uuid);
when(load.getWarpSigns()).thenReturn(warpMap); when(load.getWarpSigns()).thenReturn(warpMap);
wsm = new WarpSignsManager(addon, plugin); wsm = new WarpSignsManager(addon, plugin);
assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty()); assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty());
@ -349,23 +355,23 @@ public class WarpSignsManagerTest {
public void testAddWarp() { public void testAddWarp() {
Location loc = mock(Location.class); Location loc = mock(Location.class);
assertTrue(wsm.addWarp(uuid, loc)); assertTrue(wsm.addWarp(uuid, loc));
verify(pim).callEvent(any(WarpInitiateEvent.class)); verify(pim).callEvent(any(WarpCreateEvent.class));
} }
/** /**
* Test method for {@link WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}. * Test method for {@link WarpSignsManager#getWarpLocation(org.bukkit.World, java.util.UUID)}.
*/ */
@Test @Test
public void testGetWarpWorldWorld() { public void testGetWarpWorldWorld() {
assertNull(wsm.getWarp(mock(World.class), uuid)); assertNull(wsm.getWarpLocation(mock(World.class), uuid));
} }
/** /**
* Test method for {@link WarpSignsManager#getWarp(org.bukkit.World, java.util.UUID)}. * Test method for {@link WarpSignsManager#getWarpLocation(org.bukkit.World, java.util.UUID)}.
*/ */
@Test @Test
public void testGetWarp() { public void testGetWarp() {
assertEquals(location, wsm.getWarp(world, uuid)); assertEquals(location, wsm.getWarpLocation(world, uuid));
} }
/** /**
@ -441,6 +447,38 @@ public class WarpSignsManagerTest {
PowerMockito.verifyStatic(Util.class); PowerMockito.verifyStatic(Util.class);
Util.teleportAsync(eq(p), any(), eq(TeleportCause.COMMAND)); Util.teleportAsync(eq(p), any(), eq(TeleportCause.COMMAND));
verify(player).sendMessage(anyString()); verify(player).sendMessage(anyString());
verify(pim).callEvent(any(WarpInitiateEvent.class));
}
/**
* Test method for {@link WarpSignsManager#warpPlayer(org.bukkit.World, world.bentobox.bentobox.api.user.User, java.util.UUID)}.
*/
@Test
public void testWarpPlayerEventCancelled() {
// Capture the event passed to callEvent
ArgumentCaptor<WarpInitiateEvent> eventCaptor = ArgumentCaptor.forClass(WarpInitiateEvent.class);
// Simulate the event being called and cancelled
doAnswer(invocation -> {
WarpInitiateEvent event = (WarpInitiateEvent) invocation.getArgument(0);
event.setCancelled(true);
return null;
}).when(pim).callEvent(eventCaptor.capture());
Player p = mock(Player.class);
when(p.getUniqueId()).thenReturn(UUID.randomUUID());
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, never());
Util.teleportAsync(eq(p), any(), eq(TeleportCause.COMMAND));
verify(player, never()).sendMessage(anyString());
} }
/** /**

View File

@ -50,6 +50,7 @@ import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.LocalesManager;
import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.PlaceholdersManager;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.objects.PlayerWarp;
import world.bentobox.warps.Warp; import world.bentobox.warps.Warp;
import world.bentobox.warps.managers.WarpSignsManager; import world.bentobox.warps.managers.WarpSignsManager;
import world.bentobox.warps.config.Settings; import world.bentobox.warps.config.Settings;
@ -123,16 +124,16 @@ public class WarpSignsListenerTest {
when(block.getState()).thenReturn(s); when(block.getState()).thenReturn(s);
// warp signs manager // warp signs manager
when(addon.getWarpSignsManager()).thenReturn(wsm); when(addon.getWarpSignsManager()).thenReturn(wsm);
Map<UUID, Location> list = new HashMap<>(); Map<UUID, PlayerWarp> list = new HashMap<>();
Location location = mock(Location.class); Location location = mock(Location.class);
when(location.getBlock()).thenReturn(block); when(location.getBlock()).thenReturn(block);
when(s.getLocation()).thenReturn(location); when(s.getLocation()).thenReturn(location);
when(block.getLocation()).thenReturn(location); when(block.getLocation()).thenReturn(location);
list.put(uuid, location); list.put(uuid, new PlayerWarp(location, true));
// Player is in world // Player is in world
when(wsm.getWarpMap(world)).thenReturn(list); when(wsm.getWarpMap(world)).thenReturn(list);
//Player has a warp sign already here //Player has a warp sign already here
when(wsm.getWarp(any(), any())).thenReturn(location); when(wsm.getWarpLocation(any(), any())).thenReturn(location);
// Unique spot // Unique spot
when(wsm.addWarp(any(), any())).thenReturn(true); when(wsm.addWarp(any(), any())).thenReturn(true);
// Bentobox // Bentobox
@ -339,8 +340,8 @@ public class WarpSignsListenerTest {
when(settings.getRemoveExistingWarpsWhenFlagChanges()).thenReturn(true); when(settings.getRemoveExistingWarpsWhenFlagChanges()).thenReturn(true);
WarpSignsListener wsl = new WarpSignsListener(addon); WarpSignsListener wsl = new WarpSignsListener(addon);
Map<UUID, Location> warps = Map.of( Map<UUID, PlayerWarp> warps = Map.of(
player.getUniqueId(), block.getLocation() player.getUniqueId(), new PlayerWarp(block.getLocation(), true)
); );
when(wsm.getWarpMap(any())).thenReturn(warps); when(wsm.getWarpMap(any())).thenReturn(warps);
@ -420,7 +421,7 @@ public class WarpSignsListenerTest {
@Test @Test
public void testCreateNoSignAlreadyUniqueSpot() { public void testCreateNoSignAlreadyUniqueSpot() {
when(wsm.getWarp(any(), any())).thenReturn(null); when(wsm.getWarpLocation(any(), any())).thenReturn(null);
when(player.hasPermission(anyString())).thenReturn(true); when(player.hasPermission(anyString())).thenReturn(true);
WarpSignsListener wsl = new WarpSignsListener(addon); WarpSignsListener wsl = new WarpSignsListener(addon);
SignChangeEvent e = new SignChangeEvent(block, player, lines); SignChangeEvent e = new SignChangeEvent(block, player, lines);