Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '17'
java-version: '21'
- name: Cache SonarCloud packages
uses: actions/cache@v3
with:
Expand Down
46 changes: 27 additions & 19 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,20 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<java.version>21</java.version>
<!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.21.8-R0.1-SNAPSHOT</spigot.version>
<paper.version>1.21.8-R0.1-SNAPSHOT</paper.version>
<bentobox.version>3.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.16.0</build.version>
<build.version>1.17.0</build.version>
<!-- Sonar Cloud -->
<sonar.projectKey>BentoBoxWorld_Warps</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
Expand Down Expand Up @@ -112,6 +113,10 @@
</profiles>

<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
Expand All @@ -131,6 +136,13 @@
</repositories>

<dependencies>
<!-- Paper API -->
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>${paper.version}</version>
<scope>provided</scope>
</dependency>
<!-- Spigot API -->
<dependency>
<groupId>org.spigotmc</groupId>
Expand Down Expand Up @@ -223,40 +235,36 @@
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<version>3.5.2</version>
<!--suppress MavenModelInspection -->
<configuration>
<argLine>
${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.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/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/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.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
--add-opens=java.base/java.security=ALL-UNNAMED
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
Expand Down
73 changes: 52 additions & 21 deletions src/main/java/world/bentobox/warps/listeners/WarpSignsListener.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package world.bentobox.warps.listeners;

import java.util.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import org.bukkit.Bukkit;
Expand All @@ -10,6 +15,8 @@
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.block.sign.Side;
import org.bukkit.block.sign.SignSide;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
Expand All @@ -18,7 +25,6 @@
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.eclipse.jdt.annotation.Nullable;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.addon.AddonEvent;
Expand All @@ -28,9 +34,9 @@
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;
import world.bentobox.warps.objects.PlayerWarp;
import world.bentobox.warps.Warp;
import world.bentobox.warps.event.WarpRemoveEvent;
import world.bentobox.warps.objects.PlayerWarp;

/**
* Handles warping. Players can add one sign
Expand Down Expand Up @@ -106,7 +112,6 @@ public void onSignBreak(BlockBreakEvent e) {
Block b = e.getBlock();
boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld());
// Signs only
// FIXME: When we drop support for 1.13, switch to Tag.SIGNS
if (!b.getType().name().contains("SIGN")
|| (inWorld && !addon.inRegisteredWorld(b.getWorld()))
|| (!inWorld && !addon.getSettings().isAllowInOtherWorlds())
Expand All @@ -125,6 +130,13 @@ public void onSignBreak(BlockBreakEvent e) {
}
}

/**
* Check if this block is a registered warp sign owned by player so that it can be acted on
* @param player - player trying to do something to the sign
* @param b - sign block
* @param inWorld - true if this is a BentoBox game world
* @return true if this player is op, has mod bypass permission, or is the sign owner
*/
private boolean isPlayersSign(Player player, Block b, boolean inWorld) {
// Welcome sign detected - check to see if it is this player's sign
Map<UUID, PlayerWarp> list = addon.getWarpSignsManager().getWarpMap(b.getWorld());
Expand All @@ -133,10 +145,19 @@ private boolean isPlayersSign(Player player, Block b, boolean inWorld) {
|| player.isOp() || player.hasPermission(reqPerm));
}

/**
* Checks if this block is a warp sign. Requires it to have the correct title and be registered as a warp sign
* @param b warp sign block
* @return true if it is a valid warp sign
*/
private boolean isWarpSign(Block b) {
Sign s = (Sign) b.getState();
return s.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())
&& addon.getWarpSignsManager().getWarpMap(b.getWorld()).values().stream().anyMatch(playerWarp -> playerWarp.getLocation().equals(s.getLocation()));
if (b.getState() instanceof Sign s) {
SignSide side = s.getSide(Side.FRONT);
return side.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())
&& addon.getWarpSignsManager().getWarpMap(b.getWorld()).values().stream()
.anyMatch(playerWarp -> playerWarp.getLocation().equals(s.getLocation()));
}
return false;
}

/**
Expand All @@ -146,24 +167,27 @@ private boolean isWarpSign(Block b) {
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onSignWarpCreate(SignChangeEvent e) {
User user = Objects.requireNonNull(User.getInstance(e.getPlayer()));
Block b = e.getBlock();
Location loc = b.getLocation();
boolean inWorld = addon.getPlugin().getIWM().inWorld(b.getWorld());
if ((inWorld && !addon.inRegisteredWorld(b.getWorld())) || (!inWorld && !addon.getSettings().isAllowInOtherWorlds()) ) {
return;
}
String title = e.getLine(0);
User user = Objects.requireNonNull(User.getInstance(e.getPlayer()));
if (title != null && !title.equalsIgnoreCase(addon.getSettings().getWelcomeLine()) && addon.getWarpSignsManager().isWarpAt(loc)) {
UUID owner = addon.getWarpSignsManager().getWarpOwnerUUID(loc).orElse(null);
addon.getWarpSignsManager().removeWarp(loc);
Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(loc, user.getUniqueId(), owner));
return;
}
// Check if someone is changing their own sign
if (title != null && title.equalsIgnoreCase(addon.getSettings().getWelcomeLine())) {
// Welcome sign detected - check permissions
if (noPerms(user, b.getWorld(), inWorld)) {
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())) {
e.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
return;
Expand All @@ -182,25 +206,32 @@ public void onSignWarpCreate(SignChangeEvent e) {
// so,
// deactivate it
Block oldSignBlock = oldSignLoc.getBlock();
// FIXME: When we drop support for 1.13, switch to Tag.SIGNS
if (oldSignBlock.getType().name().contains("SIGN")) {
if (oldSignBlock.getState() instanceof Sign oldSign) {
// The block is still a sign
Sign oldSign = (Sign) oldSignBlock.getState();
if (oldSign.getLine(0).equalsIgnoreCase(ChatColor.GREEN + addon.getSettings().getWelcomeLine())) {
oldSign.setLine(0, ChatColor.RED + addon.getSettings().getWelcomeLine());
SignSide front = oldSign.getSide(Side.FRONT);
SignSide back = oldSign.getSide(Side.BACK);
String welcome = ChatColor.GREEN + addon.getSettings().getWelcomeLine();
String disabled = ChatColor.RED + addon.getSettings().getWelcomeLine();
boolean remove = false;
if (front.getLine(0).equalsIgnoreCase(welcome)) {
front.setLine(0, disabled);
remove = true;
} else if (back.getLine(0).equalsIgnoreCase(welcome)) {
back.setLine(0, disabled);
remove = true;
}
if (remove) {
oldSign.update(true, false);
user.sendMessage(WARPS_DEACTIVATE);
addon.getWarpSignsManager().removeWarp(oldSignBlock.getWorld(), user.getUniqueId());
@Nullable
UUID owner = addon.getWarpSignsManager().getWarpOwnerUUID(oldSignLoc).orElse(null);
addon.getWarpSignsManager().removeWarp(oldSignBlock.getWorld(), user.getUniqueId());
Bukkit.getPluginManager().callEvent(new WarpRemoveEvent(oldSign.getLocation(), user.getUniqueId(), owner));
}
}
// Set up the new warp sign
}
addSign(e, user, b);
}

}

private boolean hasCorrectIslandRank(Block b, User user) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ public Optional<UUID> getWarpOwnerUUID(Location location) {
return getWarpMap(location.getWorld()).entrySet().stream().filter(en -> en.getValue().getLocation().equals(location))
.findFirst().map(Map.Entry::getKey);
}

/**
* Check if there is a warp sign at this location
* @param location location to check
* @return true if there is a warp sign at this location
*/
public boolean isWarpAt(Location location) {
return getWarpMap(location.getWorld()).entrySet().stream().map(en -> en.getValue().getLocation().equals(location)).findFirst().isPresent();
}

/**
* Get sorted list of warps with most recent players listed first
Expand Down
Loading