Merge pull request #2118 from BentoBoxWorld/develop

Version 1.23.0
This commit is contained in:
tastybento 2023-04-15 11:03:45 -07:00 committed by GitHub
commit 0ee9ff4f10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
216 changed files with 1302 additions and 891 deletions

View File

@ -73,10 +73,10 @@
<postgresql.version>42.2.18</postgresql.version>
<hikaricp.version>5.0.1</hikaricp.version>
<!-- More visible way to change dependency versions -->
<spigot.version>1.19.3-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.19.4-R0.1-SNAPSHOT</spigot.version>
<!-- Might differ from the last Spigot release for short periods
of time -->
<paper.version>1.19-R0.1-SNAPSHOT</paper.version>
<paper.version>1.19.3-R0.1-SNAPSHOT</paper.version>
<bstats.version>3.0.0</bstats.version>
<vault.version>1.7.1</vault.version>
<placeholderapi.version>2.10.9</placeholderapi.version>
@ -88,9 +88,10 @@
<!-- 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.22.0</build.version>
<build.version>1.23.0</build.version>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<server.jars>${project.basedir}/lib</server.jars>
</properties>
<!-- Profiles will allow to automatically change build version. -->
@ -312,7 +313,7 @@
<version>3.2.2</version>
<scope>provided</scope>
</dependency>
<!-- Spigot NMS. Used for chunk deletion and pasting. -->
<!-- Spigot NMS. Used for chunk deletion and pasting.-->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>

View File

@ -117,7 +117,7 @@ public abstract class GameModeAddon extends Addon {
/**
* Defines the world generator for this game mode
* @param worldName - name of world that this applies to
* @param id - id if any
* @param id - id if any. "delete" is used when this request is for island deletion purposes
* @return Chunk generator or null if one does not exist, e.g. the use own generator setting is true
* @since 1.2.0
*/
@ -130,5 +130,14 @@ public abstract class GameModeAddon extends Addon {
* @since 1.4.0
*/
public abstract void saveWorldSettings();
/**
* Defines if the game mode uses the latest {@link ChunkGenerator} API or
* deprecated {@link ChunkGenerator#generateChunkData(World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)} approach.
* @return true if this game mode is a void world and should just be deleted as such
*/
public boolean isUsesNewChunkGeneration() {
return false;
}
}

View File

@ -3,7 +3,7 @@
* <p>
* Addons can expose data that they want to expose. To access it, call this class with the appropriate addon name,
* the label for the data that is requested and if required, a map of key-value pairs that will be given to the addon.
*
* <p>
* <b>Note</b> Since BentoBox 1.17.0, Addons can be declared as Pladdons and be loaded by the Bukkit classloader. This
* enables Plugins to access Addon methods directly so this API is not required.
* </p>

View File

@ -121,11 +121,6 @@ public class AdminBlueprintCommand extends ConfirmableCommand {
user.spawnParticle(PARTICLE, PARTICLE_DUST_OPTIONS, maxX + 0.5, maxY + 0.5, z + 0.5);
}
// Drawing origin
if (clipboard.getOrigin() != null) {
user.spawnParticle(Particle.VILLAGER_HAPPY, null, clipboard.getOrigin().getBlockX() + 0.5, clipboard.getOrigin().getBlockY() + 0.5, clipboard.getOrigin().getBlockZ() + 0.5);
}
}
protected void hideClipboard(User user) {

View File

@ -112,8 +112,8 @@ public class IslandBanCommand extends CompositeCommand {
}
// Event is not cancelled
if (island.ban(issuer.getUniqueId(), target.getUniqueId())) {
issuer.sendMessage("commands.island.ban.player-banned", TextVariables.NAME, target.getName());
target.sendMessage("commands.island.ban.owner-banned-you", TextVariables.NAME, issuer.getName());
issuer.sendMessage("commands.island.ban.player-banned", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.ban.owner-banned-you", TextVariables.NAME, issuer.getName(), TextVariables.DISPLAY_NAME, issuer.getDisplayName());
// If the player is online, has an island and on the banned island, move them home immediately
if (target.isOnline() && getIslands().hasIsland(getWorld(), target.getUniqueId()) && island.onIsland(target.getLocation())) {
getIslands().homeTeleportAsync(getWorld(), target.getPlayer());

View File

@ -116,17 +116,17 @@ public class IslandExpelCommand extends CompositeCommand {
return false;
}
target.sendMessage("commands.island.expel.player-expelled-you", TextVariables.NAME, user.getName());
target.sendMessage("commands.island.expel.player-expelled-you", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
island.getWorld().playSound(target.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 1F, 1F);
if (getIslands().hasIsland(getWorld(), target) || getIslands().inTeam(getWorld(), target.getUniqueId())) {
// Success
user.sendMessage(SUCCESS, TextVariables.NAME, target.getName());
user.sendMessage(SUCCESS, TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
// Teleport home
getIslands().homeTeleportAsync(getWorld(), target.getPlayer());
return true;
} else if (getIslands().getSpawn(getWorld()).isPresent()){
// Success
user.sendMessage(SUCCESS, TextVariables.NAME, target.getName());
user.sendMessage(SUCCESS, TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
getIslands().spawnTeleport(getWorld(), target.getPlayer());
return true;
} else if (getIWM().getAddon(getWorld())
@ -136,7 +136,7 @@ public class IslandExpelCommand extends CompositeCommand {
.orElse(false)
&& target.performCommand(this.getTopLabel() + " create")) {
getAddon().logWarning("Expel: " + target.getName() + " had no island, so one was created");
user.sendMessage(SUCCESS, TextVariables.NAME, target.getName());
user.sendMessage(SUCCESS, TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
return true;
}

View File

@ -94,8 +94,8 @@ public class IslandUnbanCommand extends CompositeCommand {
}
// Event is not cancelled
if (island.unban(user.getUniqueId(), target.getUniqueId())) {
user.sendMessage("commands.island.unban.player-unbanned", TextVariables.NAME, target.getName());
target.sendMessage("commands.island.unban.you-are-unbanned", TextVariables.NAME, user.getName());
user.sendMessage("commands.island.unban.player-unbanned", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.unban.you-are-unbanned", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
// Set cooldown
if (getSettings().getBanCooldown() > 0 && getParent() != null) {
getParent().getSubCommand("ban").ifPresent(subCommand ->

View File

@ -105,8 +105,8 @@ public class IslandTeamCoopCommand extends CompositeCommand {
}
island.setRank(target, RanksManager.COOP_RANK);
user.sendMessage("commands.island.team.coop.success", TextVariables.NAME, target.getName());
target.sendMessage("commands.island.team.coop.you-are-a-coop-member", TextVariables.NAME, user.getName());
user.sendMessage("commands.island.team.coop.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.team.coop.you-are-a-coop-member", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
return true;
} else {

View File

@ -111,10 +111,10 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
.rankChange(island.getRank(user), RanksManager.TRUSTED_RANK)
.build();
if (inviter.isOnline()) {
inviter.sendMessage("commands.island.team.trust.success", TextVariables.NAME, user.getName());
inviter.sendMessage("commands.island.team.trust.success", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
if (inviter.isPlayer()) {
user.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, inviter.getName());
user.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, inviter.getName(), TextVariables.DISPLAY_NAME, inviter.getDisplayName());
}
}
}
@ -138,10 +138,10 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
.rankChange(island.getRank(user), RanksManager.COOP_RANK)
.build();
if (inviter.isOnline()) {
inviter.sendMessage("commands.island.team.coop.success", TextVariables.NAME, user.getName());
inviter.sendMessage("commands.island.team.coop.success", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
if (inviter.isPlayer()) {
user.sendMessage("commands.island.team.coop.you-are-a-coop-member", TextVariables.NAME, inviter.getName());
user.sendMessage("commands.island.team.coop.you-are-a-coop-member", TextVariables.NAME, inviter.getName(), TextVariables.DISPLAY_NAME, inviter.getDisplayName());
}
}
}
@ -188,7 +188,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
user.sendMessage("commands.island.team.invite.accept.you-joined-island", TextVariables.LABEL, getTopLabel());
User inviter = User.getInstance(invite.getInviter());
if (inviter.isOnline()) {
inviter.sendMessage("commands.island.team.invite.accept.name-joined-your-island", TextVariables.NAME, user.getName());
inviter.sendMessage("commands.island.team.invite.accept.name-joined-your-island", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
getIslands().save(teamIsland);
// Fire event

View File

@ -129,9 +129,9 @@ public class IslandTeamInviteCommand extends CompositeCommand {
// Put the invited player (key) onto the list with inviter (value)
// If someone else has invited a player, then this invite will overwrite the previous invite!
itc.addInvite(Invite.Type.TEAM, user.getUniqueId(), invitedPlayer.getUniqueId());
user.sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, invitedPlayer.getName());
user.sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, invitedPlayer.getName(), TextVariables.DISPLAY_NAME, invitedPlayer.getDisplayName());
// Send message to online player
invitedPlayer.sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, user.getName());
invitedPlayer.sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
invitedPlayer.sendMessage("commands.island.team.invite.to-accept-or-reject", TextVariables.LABEL, getTopLabel());
if (getIslands().hasIsland(getWorld(), invitedPlayer.getUniqueId())) {
invitedPlayer.sendMessage("commands.island.team.invite.you-will-lose-your-island");

View File

@ -42,9 +42,9 @@ public class IslandTeamInviteRejectCommand extends CompositeCommand {
}
Optional.ofNullable(itc.getInviter(playerUUID))
.map(User::getInstance)
.ifPresent(inviter ->
inviter.sendMessage("commands.island.team.invite.reject.name-rejected-your-invite", TextVariables.NAME, user.getName())
.map(User::getInstance)
.ifPresent(inviter ->
inviter.sendMessage("commands.island.team.invite.reject.name-rejected-your-invite", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName())
);
// Remove this player from the global invite list

View File

@ -70,11 +70,11 @@ public class IslandTeamKickCommand extends ConfirmableCommand {
int targetRank = Objects.requireNonNull(island).getRank(targetUUID);
if (rank <= targetRank) {
user.sendMessage("commands.island.team.kick.cannot-kick-rank",
TextVariables.NAME, getPlayers().getName(targetUUID));
user.sendMessage("commands.island.team.kick.cannot-kick-rank",
TextVariables.NAME, getPlayers().getName(targetUUID));
return false;
}
if (!getSettings().isKickConfirmation()) {
kick(user, targetUUID);
return true;
@ -96,15 +96,15 @@ public class IslandTeamKickCommand extends ConfirmableCommand {
if (event.isCancelled()) {
return;
}
target.sendMessage("commands.island.team.kick.player-kicked",
TextVariables.GAMEMODE, getAddon().getDescription().getName(),
TextVariables.NAME, user.getName());
target.sendMessage("commands.island.team.kick.player-kicked",
TextVariables.GAMEMODE, getAddon().getDescription().getName(),
TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
getIslands().removePlayer(getWorld(), targetUUID);
// Clean the target player
getPlayers().cleanLeavingPlayer(getWorld(), target, true, oldIsland);
user.sendMessage("commands.island.team.kick.success", TextVariables.NAME, target.getName());
user.sendMessage("commands.island.team.kick.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
IslandEvent.builder()
.island(oldIsland)
.involvedPlayer(user.getUniqueId())

View File

@ -78,7 +78,7 @@ public class IslandTeamLeaveCommand extends ConfirmableCommand {
}
UUID ownerUUID = getIslands().getOwner(getWorld(), user.getUniqueId());
if (ownerUUID != null) {
User.getInstance(ownerUUID).sendMessage("commands.island.team.leave.left-your-island", TextVariables.NAME, user.getName());
User.getInstance(ownerUUID).sendMessage("commands.island.team.leave.left-your-island", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
getIslands().setLeaveTeam(getWorld(), user.getUniqueId());
// Clean the player

View File

@ -82,7 +82,7 @@ public class IslandTeamPromoteCommand extends CompositeCommand {
if (nextRank != RanksManager.OWNER_RANK && nextRank > currentRank) {
getIslands().getIsland(getWorld(), user.getUniqueId()).setRank(target, nextRank);
String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(nextRank));
user.sendMessage("commands.island.team.promote.success", TextVariables.NAME, target.getName(), TextVariables.RANK, rankName);
user.sendMessage("commands.island.team.promote.success", TextVariables.NAME, target.getName(), TextVariables.RANK, rankName, TextVariables.DISPLAY_NAME, target.getDisplayName());
IslandEvent.builder()
.island(island)
.involvedPlayer(user.getUniqueId())
@ -102,7 +102,7 @@ public class IslandTeamPromoteCommand extends CompositeCommand {
if (prevRank >= RanksManager.MEMBER_RANK && prevRank < currentRank) {
getIslands().getIsland(getWorld(), user.getUniqueId()).setRank(target, prevRank);
String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(prevRank));
user.sendMessage("commands.island.team.demote.success", TextVariables.NAME, target.getName(), TextVariables.RANK, rankName);
user.sendMessage("commands.island.team.demote.success", TextVariables.NAME, target.getName(), TextVariables.RANK, rankName, TextVariables.DISPLAY_NAME, target.getDisplayName());
IslandEvent.builder()
.island(island)
.involvedPlayer(user.getUniqueId())

View File

@ -96,9 +96,9 @@ public class IslandTeamTrustCommand extends CompositeCommand {
// Put the invited player (key) onto the list with inviter (value)
// If someone else has invited a player, then this invite will overwrite the previous invite!
itc.addInvite(Type.TRUST, user.getUniqueId(), target.getUniqueId());
user.sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, target.getName());
user.sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
// Send message to online player
target.sendMessage("commands.island.team.trust.name-has-invited-you", TextVariables.NAME, user.getName());
target.sendMessage("commands.island.team.trust.name-has-invited-you", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
target.sendMessage("commands.island.team.invite.to-accept-or-reject", TextVariables.LABEL, getTopLabel());
} else {
if (island.getMemberSet(RanksManager.TRUSTED_RANK, false).size() >= getIslands().getMaxMembers(island, RanksManager.TRUSTED_RANK)) {
@ -107,8 +107,8 @@ public class IslandTeamTrustCommand extends CompositeCommand {
}
island.setRank(target, RanksManager.TRUSTED_RANK);
user.sendMessage("commands.island.team.trust.success", TextVariables.NAME, target.getName());
target.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, user.getName());
user.sendMessage("commands.island.team.trust.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
return true;
} else {

View File

@ -84,8 +84,8 @@ public class IslandTeamUncoopCommand extends CompositeCommand {
Island island = getIslands().getIsland(getWorld(), user.getUniqueId());
if (island != null) {
island.removeMember(targetUUID);
user.sendMessage("commands.island.team.uncoop.success", TextVariables.NAME, target.getName());
target.sendMessage("commands.island.team.uncoop.you-are-no-longer-a-coop-member", TextVariables.NAME, user.getName());
user.sendMessage("commands.island.team.uncoop.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.team.uncoop.you-are-no-longer-a-coop-member", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
// Set cooldown
if (getSettings().getCoopCooldown() > 0 && getParent() != null) {
getParent().getSubCommand("coop").ifPresent(subCommand ->

View File

@ -84,8 +84,8 @@ public class IslandTeamUntrustCommand extends CompositeCommand {
Island island = getIslands().getIsland(getWorld(), user.getUniqueId());
if (island != null) {
island.removeMember(targetUUID);
user.sendMessage("commands.island.team.untrust.success", TextVariables.NAME, target.getName());
target.sendMessage("commands.island.team.untrust.you-are-no-longer-trusted", TextVariables.NAME, user.getName());
user.sendMessage("commands.island.team.untrust.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.team.untrust.you-are-no-longer-trusted", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
// Set cooldown
if (getSettings().getTrustCooldown() > 0 && getParent() != null) {
getParent().getSubCommand("trust").ifPresent(subCommand ->

View File

@ -23,7 +23,7 @@ public abstract class IslandBaseEvent extends BentoBoxEvent implements Cancellab
protected final Event rawEvent;
protected IslandBaseEvent newEvent;
protected IslandBaseEvent(Island island) {
public IslandBaseEvent(Island island) {
super();
this.island = island;
playerUUID = island == null ? null : island.getOwner();
@ -38,7 +38,7 @@ public abstract class IslandBaseEvent extends BentoBoxEvent implements Cancellab
* @param admin - true if ths is due to an admin event
* @param location - the location
*/
protected IslandBaseEvent(Island island, UUID playerUUID, boolean admin, Location location) {
public IslandBaseEvent(Island island, UUID playerUUID, boolean admin, Location location) {
super();
this.island = island;
this.playerUUID = playerUUID;
@ -54,7 +54,7 @@ public abstract class IslandBaseEvent extends BentoBoxEvent implements Cancellab
* @param location - the location
* @param rawEvent - the raw event
*/
protected IslandBaseEvent(Island island, UUID playerUUID, boolean admin, Location location, Event rawEvent) {
public IslandBaseEvent(Island island, UUID playerUUID, boolean admin, Location location, Event rawEvent) {
super();
this.island = island;
this.playerUUID = playerUUID;

View File

@ -28,7 +28,7 @@ public class IslandBanEvent extends IslandBaseEvent {
return handlers;
}
IslandBanEvent(Island island, UUID player, boolean admin, Location location) {
public IslandBanEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -28,7 +28,7 @@ public class IslandCreateEvent extends IslandBaseEvent {
return handlers;
}
IslandCreateEvent(Island island, UUID player, boolean admin, Location location, @NonNull BlueprintBundle blueprintBundle) {
public IslandCreateEvent(Island island, UUID player, boolean admin, Location location, @NonNull BlueprintBundle blueprintBundle) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
this.blueprintBundle = blueprintBundle;

View File

@ -25,7 +25,7 @@ public class IslandCreatedEvent extends IslandBaseEvent {
return handlers;
}
IslandCreatedEvent(Island island, UUID player, boolean admin, Location location) {
public IslandCreatedEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -28,7 +28,7 @@ public class IslandDeleteChunksEvent extends IslandBaseEvent {
return handlers;
}
IslandDeleteChunksEvent(Island island, UUID player, boolean admin, Location location, IslandDeletion deletedIsland) {
public IslandDeleteChunksEvent(Island island, UUID player, boolean admin, Location location, IslandDeletion deletedIsland) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
this.deletedIslandInfo = deletedIsland;

View File

@ -26,7 +26,7 @@ public class IslandDeleteEvent extends IslandBaseEvent {
return handlers;
}
IslandDeleteEvent(Island island, UUID player, boolean admin, Location location) {
public IslandDeleteEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -30,7 +30,7 @@ public class IslandDeletedEvent extends IslandBaseEvent {
return handlers;
}
IslandDeletedEvent(Island island, UUID player, boolean admin, Location location, IslandDeletion deletedIsland) {
public IslandDeletedEvent(Island island, UUID player, boolean admin, Location location, IslandDeletion deletedIsland) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
this.deletedIslandInfo = deletedIsland;

View File

@ -29,7 +29,7 @@ public class IslandEnterEvent extends IslandBaseEvent {
return handlers;
}
IslandEnterEvent(Island island, UUID player, boolean admin, Location location, @Nullable Island fromIsland, Event rawEvent) {
public IslandEnterEvent(Island island, UUID player, boolean admin, Location location, @Nullable Island fromIsland, Event rawEvent) {
// Final variables have to be declared in the constructor
super(island, player, admin, location, rawEvent);
this.fromIsland = fromIsland;

View File

@ -29,7 +29,7 @@ public class IslandExitEvent extends IslandBaseEvent {
return handlers;
}
IslandExitEvent(Island island, UUID player, boolean admin, Location location, @Nullable Island toIsland, Event rawEvent) {
public IslandExitEvent(Island island, UUID player, boolean admin, Location location, @Nullable Island toIsland, Event rawEvent) {
// Final variables have to be declared in the constructor
super(island, player, admin, location, rawEvent);
this.toIsland = toIsland;

View File

@ -29,7 +29,7 @@ public class IslandExpelEvent extends IslandBaseEvent {
return handlers;
}
IslandExpelEvent(Island island, UUID player, boolean admin, Location location) {
public IslandExpelEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -26,7 +26,7 @@ public class IslandGeneralEvent extends IslandBaseEvent {
return handlers;
}
IslandGeneralEvent(Island island, UUID player, boolean admin, Location location) {
public IslandGeneralEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -26,7 +26,7 @@ public class IslandLockEvent extends IslandBaseEvent {
return handlers;
}
IslandLockEvent(Island island, UUID player, boolean admin, Location location) {
public IslandLockEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -26,7 +26,7 @@ public class IslandNewIslandEvent extends IslandBaseEvent {
return handlers;
}
IslandNewIslandEvent(Island island, UUID player, boolean admin, Location location) {
public IslandNewIslandEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -25,7 +25,7 @@ public class IslandPreCreateEvent extends IslandBaseEvent {
return handlers;
}
IslandPreCreateEvent(UUID player) {
public IslandPreCreateEvent(UUID player) {
// Final variables have to be declared in the constructor
super(null, player, false, null);
}

View File

@ -27,7 +27,7 @@ public class IslandPreclearEvent extends IslandBaseEvent {
return handlers;
}
IslandPreclearEvent(Island island, UUID player, boolean admin, Location location, @NonNull Island oldIsland) {
public IslandPreclearEvent(Island island, UUID player, boolean admin, Location location, @NonNull Island oldIsland) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
// Create a copy of the old island

View File

@ -46,7 +46,7 @@ public class IslandProtectionRangeChangeEvent extends IslandBaseEvent {
* @param newRange of type int
* @param oldRange of type int
*/
IslandProtectionRangeChangeEvent(Island island, UUID player, boolean admin, Location location, int newRange, int oldRange) {
public IslandProtectionRangeChangeEvent(Island island, UUID player, boolean admin, Location location, int newRange, int oldRange) {
super(island, player, admin, location);
this.newRange = newRange;
this.oldRange = oldRange;

View File

@ -26,7 +26,7 @@ public class IslandRegisteredEvent extends IslandBaseEvent {
return handlers;
}
IslandRegisteredEvent(Island island, UUID player, boolean admin, Location location) {
public IslandRegisteredEvent(Island island, UUID player, boolean admin, Location location) {
super(island, player, admin, location);
}
}

View File

@ -26,7 +26,7 @@ public class IslandReservedEvent extends IslandBaseEvent {
return handlers;
}
IslandReservedEvent(Island island, UUID player, boolean admin, Location location) {
public IslandReservedEvent(Island island, UUID player, boolean admin, Location location) {
super(island, player, admin, location);
}
}

View File

@ -29,7 +29,7 @@ public class IslandResetEvent extends IslandBaseEvent {
return handlers;
}
IslandResetEvent(Island island, UUID player, boolean admin, Location location, @NonNull BlueprintBundle blueprintBundle, @NonNull Island oldIsland) {
public IslandResetEvent(Island island, UUID player, boolean admin, Location location, @NonNull BlueprintBundle blueprintBundle, @NonNull Island oldIsland) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
this.blueprintBundle = blueprintBundle;

View File

@ -27,7 +27,7 @@ public class IslandResettedEvent extends IslandBaseEvent {
return handlers;
}
IslandResettedEvent(Island island, UUID player, boolean admin, Location location, Island oldIsland) {
public IslandResettedEvent(Island island, UUID player, boolean admin, Location location, Island oldIsland) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
// Create a copy of the old island

View File

@ -26,7 +26,7 @@ public class IslandUnlockEvent extends IslandBaseEvent {
return handlers;
}
IslandUnlockEvent(Island island, UUID player, boolean admin, Location location) {
public IslandUnlockEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -26,7 +26,7 @@ public class IslandUnregisteredEvent extends IslandBaseEvent {
return handlers;
}
IslandUnregisteredEvent(Island island, UUID player, boolean admin, Location location) {
public IslandUnregisteredEvent(Island island, UUID player, boolean admin, Location location) {
super(island, player, admin, location);
}
}

View File

@ -22,7 +22,7 @@ public class TeamDeleteEvent extends IslandBaseEvent {
return handlers;
}
TeamDeleteEvent(Island island, UUID player, boolean admin, Location location) {
public TeamDeleteEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamGeneralEvent extends IslandBaseEvent {
return handlers;
}
TeamGeneralEvent(Island island, UUID player, boolean admin, Location location) {
public TeamGeneralEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamInfoEvent extends IslandBaseEvent {
return handlers;
}
TeamInfoEvent(Island island, UUID player, boolean admin, Location location) {
public TeamInfoEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamInviteEvent extends IslandBaseEvent {
return handlers;
}
TeamInviteEvent(Island island, UUID player, boolean admin, Location location) {
public TeamInviteEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamJoinEvent extends IslandBaseEvent {
return handlers;
}
TeamJoinEvent(Island island, UUID player, boolean admin, Location location) {
public TeamJoinEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -34,7 +34,7 @@ public class TeamJoinedEvent extends IslandBaseEvent {
* @param location - location
* @since 1.3.0
*/
TeamJoinedEvent(Island island, UUID player, boolean admin, Location location) {
public TeamJoinedEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamKickEvent extends IslandBaseEvent {
return handlers;
}
TeamKickEvent(Island island, UUID player, boolean admin, Location location) {
public TeamKickEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -27,7 +27,7 @@ public class TeamLeaveEvent extends IslandBaseEvent {
return handlers;
}
TeamLeaveEvent(Island island, UUID player, boolean admin, Location location) {
public TeamLeaveEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamRejectEvent extends IslandBaseEvent {
return handlers;
}
TeamRejectEvent(Island island, UUID player, boolean admin, Location location) {
public TeamRejectEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -28,7 +28,7 @@ public class TeamSetownerEvent extends IslandBaseEvent {
return handlers;
}
TeamSetownerEvent(Island island, UUID player, boolean admin, Location location) {
public TeamSetownerEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -22,7 +22,7 @@ public class TeamUninviteEvent extends IslandBaseEvent {
return handlers;
}
TeamUninviteEvent(Island island, UUID player, boolean admin, Location location) {
public TeamUninviteEvent(Island island, UUID player, boolean admin, Location location) {
// Final variables have to be declared in the constructor
super(island, player, admin, location);
}

View File

@ -2,6 +2,7 @@ package world.bentobox.bentobox.api.flags;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
@ -466,6 +467,33 @@ public class Flag implements Comparable<Flag> {
public Set<Flag> getSubflags() {
return subflags;
}
/**
* Set the name of this flag for a specified locale. This enables the flag's name to be assigned via API. It will not be stored anywhere
* and must be rewritten using this call every time the flag is built.
* @param locale locale (language) to which this name should be assigned. Assigning to {@code Locale.US} will make this the default
* @param name the translated name for this flag
* @return true if successful, false if the locale is unknown to this server.
* See {@link world.bentobox.bentobox.managers.LocalesManager#getAvailableLocales(boolean sort)}
* @since 1.22.1
*/
public boolean setTranslatedName(Locale locale, String name) {
return BentoBox.getInstance().getLocalesManager().setTranslation(locale, getNameReference(), name);
}
/**
* Set the name of this flag for a specified locale. This enables the flag's name to be assigned via API. It will not be stored anywhere
* and must be rewritten using this call every time the flag is built.
* @param locale locale (language) to which this name should be assigned. Assigning to {@code Locale.US} will make this the default
* @param description the translated description for this flag
* @return true if successful, false if the locale is unknown to this server.
* See {@link world.bentobox.bentobox.managers.LocalesManager#getAvailableLocales(boolean sort)}
* @since 1.22.1
*/
public boolean setTranslatedDescription(Locale locale, String description) {
return BentoBox.getInstance().getLocalesManager().setTranslation(locale, getDescriptionReference(), description);
}
@Override
public String toString() {

View File

@ -163,7 +163,7 @@ public class BentoBoxLocale {
/**
* Returns the list of prefixes available in this locale.
* @return list of prefixes available in this locale.
* @return Set of prefixes available in this locale.
* @since 1.13.0
*/
@NonNull

View File

@ -9,6 +9,7 @@ public class TextVariables {
private TextVariables() {}
public static final String NAME = "[name]";
public static final String DISPLAY_NAME = "[display_name]";
public static final String DESCRIPTION = "[description]";
public static final String NUMBER = "[number]";
public static final String RANK = "[rank]";

View File

@ -17,8 +17,6 @@ import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord.ActionRecords;
/**
* This Record contains all necessary information about Item Template that can be used to craft panel item.
*

View File

@ -15,7 +15,6 @@ import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord.TemplateItem;
/**
* This is template object for the panel reader. It contains data that can exist in the panel.

View File

@ -206,7 +206,6 @@ public class User implements MetaDataAble {
/**
* Get the user's inventory
* @return player's inventory
* @throws {@link NullPointerException} - if user is not a player
*/
@NonNull
public PlayerInventory getInventory() {
@ -216,7 +215,6 @@ public class User implements MetaDataAble {
/**
* Get the user's location
* @return location
* @throws {@link NullPointerException} - if user is not a player
*/
@NonNull
public Location getLocation() {
@ -232,6 +230,16 @@ public class User implements MetaDataAble {
return player != null ? player.getName() : plugin.getPlayers().getName(playerUUID);
}
/**
* Get the user's display name
* @return player's display name if the player is online otherwise just their name
* @since 1.22.1
*/
@NonNull
public String getDisplayName() {
return player != null ? player.getDisplayName() : plugin.getPlayers().getName(playerUUID);
}
/**
* Check if the User is a player before calling this method. {@link #isPlayer()}
* @return the player
@ -252,7 +260,6 @@ public class User implements MetaDataAble {
* Use {@link #isOfflinePlayer()} before calling this method
* @return the offline player
* @since 1.3.0
* @throws {@link NullPointerException} - if user is not an offline player
*/
@NonNull
public OfflinePlayer getOfflinePlayer() {
@ -356,7 +363,7 @@ public class User implements MetaDataAble {
if (permissions.isEmpty()) return defaultValue;
return iteratePerms(permissions, permPrefix, defaultValue);
}
private int iteratePerms(List<String> permissions, String permPrefix, int defaultValue) {
@ -477,7 +484,7 @@ public class User implements MetaDataAble {
}
private String replaceVars(String reference, String[] variables) {
// Then replace variables
if (variables.length > 1) {
for (int i = 0; i < variables.length; i += 2) {
@ -489,7 +496,7 @@ public class User implements MetaDataAble {
if (player != null) {
reference = plugin.getPlaceholdersManager().replacePlaceholders(player, reference);
}
// If no translation has been found, return the reference for debug purposes.
return reference;
}
@ -580,7 +587,6 @@ public class User implements MetaDataAble {
/**
* Gets the current world this entity resides in
* @return World - world
* @throws {@link NullPointerException} - if user is not a player
*/
@NonNull
public World getWorld() {

View File

@ -1,6 +1,6 @@
/**
* This package contains non-API classes that handle Blueprints.
*
* <p>
* Blueprints are BentoBox's version of schematics, but contain
* additional useful info.
*

View File

@ -85,7 +85,7 @@ public class Database<T> {
/**
* Save object async. Saving may be done sync, depending on the underlying database.
* @param instance to save
* @return true if no immediate errors. If async, errors may occur later.
* @return Completable future that results in true if successful.
* @since 1.13.0
*/
public CompletableFuture<Boolean> saveObjectAsync(T instance) {

View File

@ -24,7 +24,6 @@ import org.bukkit.entity.Player;
import org.bukkit.util.BoundingBox;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
@ -725,7 +724,6 @@ public class Island implements DataObject, MetaDataAble {
* @param location - location
* @return true if in island space
*/
@SuppressWarnings("ConstantConditions")
public boolean inIslandSpace(Location location) {
return Util.sameWorld(this.world, location.getWorld()) &&
(location.getWorld().getEnvironment().equals(Environment.NORMAL) ||
@ -748,8 +746,7 @@ public class Island implements DataObject, MetaDataAble {
* @return a {@link BoundingBox} of the full island space.
* @since 1.5.2
*/
@SuppressWarnings("ConstantConditions")
@NotNull
@NonNull
public BoundingBox getBoundingBox() {
return this.getBoundingBox(Environment.NORMAL);
}
@ -779,7 +776,6 @@ public class Island implements DataObject, MetaDataAble {
else if (Environment.THE_END.equals(environment) && this.isEndIslandEnabled())
{
// If end world is generated, return end island bounding box.
//noinspection ConstantConditions
boundingBox = new BoundingBox(this.getMinX(),
this.getEndWorld().getMinHeight(),
this.getMinZ(),
@ -790,7 +786,6 @@ public class Island implements DataObject, MetaDataAble {
else if (Environment.NETHER.equals(environment) && this.isNetherIslandEnabled())
{
// If nether world is generated, return nether island bounding box.
//noinspection ConstantConditions
boundingBox = new BoundingBox(this.getMinX(),
this.getNetherWorld().getMinHeight(),
this.getMinZ(),
@ -910,7 +905,6 @@ public class Island implements DataObject, MetaDataAble {
* @param target location to check, not null
* @return {@code true} if this location is within this island's protected area, {@code false} otherwise.
*/
@SuppressWarnings("ConstantConditions")
public boolean onIsland(@NonNull Location target) {
return Util.sameWorld(this.world, target.getWorld()) &&
(target.getWorld().getEnvironment().equals(Environment.NORMAL) ||
@ -927,8 +921,7 @@ public class Island implements DataObject, MetaDataAble {
* @return a {@link BoundingBox} of this island's protected area.
* @since 1.5.2
*/
@SuppressWarnings("ConstantConditions")
@NotNull
@NonNull
public BoundingBox getProtectionBoundingBox() {
return this.getProtectionBoundingBox(Environment.NORMAL);
}
@ -959,7 +952,6 @@ public class Island implements DataObject, MetaDataAble {
else if (Environment.THE_END.equals(environment) && this.isEndIslandEnabled())
{
// If end world is generated, return end island bounding box.
//noinspection ConstantConditions
boundingBox = new BoundingBox(this.getMinProtectedX(),
this.getEndWorld().getMinHeight(),
this.getMinProtectedZ(),
@ -970,7 +962,6 @@ public class Island implements DataObject, MetaDataAble {
else if (Environment.NETHER.equals(environment) && this.isNetherIslandEnabled())
{
// If nether world is generated, return nether island bounding box.
//noinspection ConstantConditions
boundingBox = new BoundingBox(this.getMinProtectedX(),
this.getNetherWorld().getMinHeight(),
this.getMinProtectedZ(),
@ -1645,7 +1636,7 @@ public class Island implements DataObject, MetaDataAble {
* @return the homes
* @since 1.16.0
*/
@NotNull
@NonNull
public Map<String, Location> getHomes() {
if (homes == null) {
homes = new HashMap<>();

View File

@ -119,7 +119,7 @@ public class Players implements DataObject, MetaDataAble {
/**
* @param world - world
* @return List of home locations
* @return Map of home locations
* @deprecated Homes are stored in the island object now
*/
@Deprecated(since="1.18.0", forRemoval=true)

View File

@ -225,7 +225,7 @@ public class SQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T>
* Return the object decoded from JSON or null if there is an error
* @param uniqueId - unique Id of object used in error reporting
* @param preparedStatement - database statement to execute
* @return
* @return T
*/
private T getObject(@NonNull String uniqueId, PreparedStatement preparedStatement) {
try (ResultSet resultSet = preparedStatement.executeQuery())

View File

@ -91,7 +91,7 @@ public class LangUtilsHook extends Hook {
/**
* Get the item display name.
*
* <p>
* If the item contains a custom name, return its custom name.
* If the item itself does not have a custom name, the material
* name will be translated and returned.
@ -515,29 +515,74 @@ public class LangUtilsHook extends Hook {
int variant = (pcol & 255) << 24 | (bcol & 255) << 16 | (patt & 255) << 8 | type;
switch (variant) {
case 117506305: return "Anemone";
case 117899265: return "Black Tang";
case 185008129: return "Blue Tang";
case 117441793: return "Butterflyfish";
case 118161664: return "Cichlid";
case 65536 : return "Clownfish";
case 50726144 : return "Cotton Candy Betta";
case 67764993 : return "Dottyback";
case 234882305: return "Emperor Red Snapper";
case 67110144 : return "Goatfish";
case 117441025: return "Moorish Idol";
case 16778497 : return "Ornate Butterflyfish";
case 101253888: return "Parrotfish";
case 50660352 : return "Queen Angelfish";
case 918529 : return "Red Cichlid";
case 235340288: return "Red Lipped Blenny";
case 918273 : return "Red Snapper";
case 67108865 : return "Threadfin";
case 917504 : return "Tomato Clownfish";
case 459008 : return "Triggerfish";
case 67699456 : return "Yellowtail Parrotfish";
case 67371009 : return "Yellow Tang";
default : break;
case 117506305 -> {
return "Anemone";
}
case 117899265 -> {
return "Black Tang";
}
case 185008129 -> {
return "Blue Tang";
}
case 117441793 -> {
return "Butterflyfish";
}
case 118161664 -> {
return "Cichlid";
}
case 65536 -> {
return "Clownfish";
}
case 50726144 -> {
return "Cotton Candy Betta";
}
case 67764993 -> {
return "Dottyback";
}
case 234882305 -> {
return "Emperor Red Snapper";
}
case 67110144 -> {
return "Goatfish";
}
case 117441025 -> {
return "Moorish Idol";
}
case 16778497 -> {
return "Ornate Butterflyfish";
}
case 101253888 -> {
return "Parrotfish";
}
case 50660352 -> {
return "Queen Angelfish";
}
case 918529 -> {
return "Red Cichlid";
}
case 235340288 -> {
return "Red Lipped Blenny";
}
case 918273 -> {
return "Red Snapper";
}
case 67108865 -> {
return "Threadfin";
}
case 917504 -> {
return "Tomato Clownfish";
}
case 459008 -> {
return "Triggerfish";
}
case 67699456 -> {
return "Yellowtail Parrotfish";
}
case 67371009 -> {
return "Yellow Tang";
}
default -> {
}
}
}
return null;

View File

@ -36,19 +36,43 @@ public class BannedCommands implements Listener {
public void onVisitorCommand(PlayerCommandPreprocessEvent e) {
if (!plugin.getIWM().inWorld(e.getPlayer().getLocation()) || e.getPlayer().isOp()
|| e.getPlayer().hasPermission(plugin.getIWM().getPermissionPrefix(e.getPlayer().getWorld()) + "mod.bypassprotect")
|| plugin.getIslands().locationIsOnIsland(e.getPlayer(), e.getPlayer().getLocation())) {
|| plugin.getIslands().locationIsOnIsland(e.getPlayer(), e.getPlayer().getLocation())
|| e.getMessage().isEmpty()
) {
return;
}
World w = e.getPlayer().getWorld();
// Check banned commands
// Split up the entry
String[] args = e.getMessage().substring(1).toLowerCase(java.util.Locale.ENGLISH).split(" ");
if (plugin.getIWM().getVisitorBannedCommands(w).contains(args[0])) {
User user = User.getInstance(e.getPlayer());
user.notify("protection.protected", TextVariables.DESCRIPTION, user.getTranslation("protection.command-is-banned"));
e.setCancelled(true);
// Loop through each of the banned commands
for (String cmd : plugin.getIWM().getVisitorBannedCommands(w)) {
if (checkCmd(cmd, args)) {
User user = User.getInstance(e.getPlayer());
user.notify("protection.protected", TextVariables.DESCRIPTION, user.getTranslation("protection.command-is-banned"));
e.setCancelled(true);
return;
}
}
}
private boolean checkCmd(String cmd, String[] args) {
// Commands are guilty until proven innocent :-)
boolean banned = true;
// Get the elements of the banned command by splitting it
String[] bannedSplit = cmd.toLowerCase(java.util.Locale.ENGLISH).split(" ");
// If the banned command has the same number of elements or less than the entered command then it may be banned
if (bannedSplit.length <= args.length) {
for (int i = 0; i < bannedSplit.length; i++) {
if (!bannedSplit[i].equals(args[i])) {
banned = false;
break;
}
}
}
return banned;
}
/**
* Prevents falling players from using commands, like /warp
* @param e - event

View File

@ -1,7 +1,6 @@
package world.bentobox.bentobox.listeners.flags.clicklisteners;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -34,11 +33,11 @@ public class GeoMobLimitTab implements Tab, ClickHandler {
/**
* A list of all living entity types, minus some
*/
private static final List<EntityType> LIVING_ENTITY_TYPES = Collections.unmodifiableList(Arrays.stream(EntityType.values())
private static final List<EntityType> LIVING_ENTITY_TYPES = Arrays.stream(EntityType.values())
.filter(EntityType::isAlive)
.filter(t -> !(t.equals(EntityType.PLAYER) || t.equals(EntityType.GIANT) || t.equals(EntityType.ARMOR_STAND)))
.sorted(Comparator.comparing(EntityType::name))
.toList());
.toList();
public enum EntityLimitTabType {
GEO_LIMIT,

View File

@ -2,6 +2,7 @@ package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.ArmorStand;
@ -31,7 +32,26 @@ public class BreakBlocksListener extends FlagListener {
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockBreak(final BlockBreakEvent e) {
checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.BREAK_BLOCKS);
Player p = e.getPlayer();
Location l = e.getBlock().getLocation();
Material m = e.getBlock().getType();
switch (m)
{
case MELON -> this.checkIsland(e, p, l, Flags.HARVEST);
case PUMPKIN -> this.checkIsland(e, p, l, Flags.HARVEST);
default -> {
// Crops
if (Tag.CROPS.isTagged(m)
&& !m.equals(Material.MELON_STEM)
&& !m.equals(Material.PUMPKIN_STEM)
&& !m.equals(Material.ATTACHED_MELON_STEM)
&& !m.equals(Material.ATTACHED_PUMPKIN_STEM)) {
this.checkIsland(e, p, l, Flags.HARVEST);
} else {
checkIsland(e, p, l, Flags.BREAK_BLOCKS);
}
}
}
}
/**
@ -64,16 +84,18 @@ public class BreakBlocksListener extends FlagListener {
{
return;
}
Player p = e.getPlayer();
Location l = e.getClickedBlock().getLocation();
switch (e.getClickedBlock().getType())
Material m = e.getClickedBlock().getType();
switch (m)
{
case CAKE -> this.checkIsland(e, p, l, Flags.BREAK_BLOCKS);
case SPAWNER -> this.checkIsland(e, p, l, Flags.BREAK_SPAWNERS);
case DRAGON_EGG -> this.checkIsland(e, p, l, Flags.DRAGON_EGG);
case HOPPER -> this.checkIsland(e, p, l, Flags.BREAK_HOPPERS);
default -> {
// Do nothing
}
}
}

View File

@ -32,7 +32,7 @@ public class BreedingListener extends FlagListener {
/**
* A list of items that cause breeding if a player has them in their hand and they click an animal
* This list may need to be extended with future versions of Minecraft.
* See this Minecraft Wiki page for reference: https://minecraft.gamepedia.com/Breeding#Breeding_foods.
* See this Minecraft Wiki page for reference: <a href="https://minecraft.gamepedia.com/Breeding#Breeding_foods">...</a>.
*/
private static final Map<EntityType, List<Material>> BREEDING_ITEMS;
static {

View File

@ -135,7 +135,7 @@ public class LockAndBanListener extends FlagListener {
* Checks if a player is banned from this location and notifies them if so
* @param player - player
* @param loc - location to check
* @return true if banned
* @return CheckResult
*/
private CheckResult checkAndNotify(@NonNull Player player, Location loc)
{

View File

@ -1,5 +1,7 @@
package world.bentobox.bentobox.listeners.flags.protection;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -12,6 +14,7 @@ import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags;
@ -20,6 +23,7 @@ import world.bentobox.bentobox.lists.Flags;
*/
public class PlaceBlocksListener extends FlagListener
{
public static final Set<Material> SEEDS = Set.of(Material.BEETROOT_SEEDS, Material.MELON_SEEDS, Material.WHEAT_SEEDS);
/**
* Check blocks being placed in general
*
@ -28,7 +32,9 @@ public class PlaceBlocksListener extends FlagListener
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent e)
{
if (e.getBlock().getType().equals(Material.FIRE) ||
Material m = e.getBlock().getType();
Material against = e.getBlockAgainst().getType();
if (m.equals(Material.FIRE) ||
e.getItemInHand() == null || // Note that this should never happen officially, but it's possible for other plugins to cause it to happen
e.getItemInHand().getType().equals(Material.WRITABLE_BOOK) ||
e.getItemInHand().getType().equals(Material.WRITTEN_BOOK))
@ -36,8 +42,12 @@ public class PlaceBlocksListener extends FlagListener
// Books can only be placed on lecterns and as such are protected by the LECTERN flag.
return;
}
this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS);
// Crops
if (against.equals(Material.FARMLAND) && SEEDS.contains(e.getItemInHand().getType())) {
this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.CROP_PLANTING);
} else {
this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS);
}
}
@ -61,6 +71,7 @@ public class PlaceBlocksListener extends FlagListener
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerHitItemFrame(PlayerInteractEntityEvent e)
{
BentoBox.getInstance().logDebug(e.getEventName());
if (e.getRightClicked().getType().equals(EntityType.ITEM_FRAME) ||
e.getRightClicked().getType().equals(EntityType.GLOW_ITEM_FRAME))
{

View File

@ -0,0 +1,50 @@
package world.bentobox.bentobox.listeners.flags.settings;
import java.util.Optional;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityTeleportEvent;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
/**
* Handles shulker or enderman teleporting
* @author tastybento
*/
public class MobTeleportListener extends FlagListener {
/**
* Check teleport of Endermen or Shulker
* @param event EntityTeleportEvent
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onEntityTeleportEvent(EntityTeleportEvent event) {
// Only cover shulkers and enderman
if (!event.getEntityType().equals(EntityType.ENDERMAN) && !event.getEntityType().equals(EntityType.SHULKER)) {
return;
}
World w = event.getFrom().getWorld();
// If not in the right world exit immediately and check teleportation is within the same world
if (!this.getIWM().inWorld(w) || event.getTo() == null || !event.getFrom().getWorld().equals(event.getTo().getWorld())) {
return;
}
Optional<Island> island = getIslands().getIslandAt(event.getEntity().getLocation());
if (event.getEntityType().equals(EntityType.ENDERMAN) && Boolean.TRUE.equals(island.map(i -> !i.isAllowed(Flags.ENDERMAN_TELEPORT)).orElseGet(
() -> !Flags.ENDERMAN_TELEPORT.isSetForWorld(w)))) {
// Enderman teleport is disabled on island or world. Cancel it.
event.setCancelled(true);
}
if (event.getEntityType().equals(EntityType.SHULKER) && Boolean.TRUE.equals(island.map(i -> !i.isAllowed(Flags.SHULKER_TELEPORT)).orElseGet(
() -> !Flags.SHULKER_TELEPORT.isSetForWorld(w)))) {
// Shulker teleport is disabled on island or world. Cancel it.
event.setCancelled(true);
}
}
}

View File

@ -51,10 +51,10 @@ public class EntityTeleportListener extends AbstractTeleportListener implements
/**
* This listener checks entity portal events and triggers appropriate methods to transfer
* entities to the correct location in other dimension.
*
* <p>
* This event is triggered when entity is about to being teleported because of contact with the
* nether portal or end gateway portal (exit portal triggers respawn).
*
* <p>
* This event is not called if nether/end is disabled in server settings.
*
* @param event the entity portal event.

View File

@ -63,10 +63,10 @@ public class PlayerTeleportListener extends AbstractTeleportListener implements
/**
* This listener checks player portal events and triggers appropriate methods to transfer
* players to the correct location in other dimension.
*
* <p>
* This event is triggered when player is about to being teleported because of contact with the
* nether portal or end gateway portal (exit portal triggers respawn).
*
* <p>
* This event is not called if nether/end is disabled in server settings.
*
* @param event the player portal event.

View File

@ -42,6 +42,7 @@ import world.bentobox.bentobox.listeners.flags.protection.TeleportationListener;
import world.bentobox.bentobox.listeners.flags.protection.ThrowingListener;
import world.bentobox.bentobox.listeners.flags.settings.DecayListener;
import world.bentobox.bentobox.listeners.flags.settings.MobSpawnListener;
import world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener;
import world.bentobox.bentobox.listeners.flags.settings.PVPListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.ChestDamageListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.CleanSuperFlatListener;
@ -287,12 +288,12 @@ public final class Flags {
public static final Flag SHEARING = new Flag.Builder("SHEARING", Material.SHEARS).listener(new ShearingListener()).mode(Flag.Mode.ADVANCED).build();
// Item pickup or drop
public static final Flag ITEM_DROP = new Flag.Builder("ITEM_DROP", Material.DIAMOND).defaultSetting(true).listener(new ItemDropPickUpListener()).mode(Flag.Mode.BASIC).build();
public static final Flag ITEM_PICKUP = new Flag.Builder("ITEM_PICKUP", Material.SUGAR_CANE).mode(Flag.Mode.BASIC).build();
public static final Flag ITEM_DROP = new Flag.Builder("ITEM_DROP", Material.DIAMOND).defaultRank(RanksManager.VISITOR_RANK).listener(new ItemDropPickUpListener()).mode(Flag.Mode.BASIC).build();
public static final Flag ITEM_PICKUP = new Flag.Builder("ITEM_PICKUP", Material.SUGAR_CANE).mode(Flag.Mode.BASIC).defaultRank(RanksManager.VISITOR_RANK).build();
// Experience
public static final Flag EXPERIENCE_PICKUP = new Flag.Builder("EXPERIENCE_PICKUP", Material.EXPERIENCE_BOTTLE)
.listener(Util.isPaper() ? new PaperExperiencePickupListener() : new ExperiencePickupListener()).mode(Flag.Mode.ADVANCED).build();
.listener(Util.isPaper() ? new PaperExperiencePickupListener() : new ExperiencePickupListener()).mode(Flag.Mode.ADVANCED).defaultRank(RanksManager.VISITOR_RANK).build();
// Command ranks
public static final Flag COMMAND_RANKS = new Flag.Builder("COMMAND_RANKS", Material.PLAYER_HEAD)
@ -488,6 +489,21 @@ public final class Flags {
.listener(new EndermanListener())
.build();
/**
* If {@code false}, prevents Endermans from teleporting
* @since 1.22.1
*/
public static final Flag ENDERMAN_TELEPORT = new Flag.Builder("ENDERMAN_TELEPORT", Material.ENDER_PEARL).type(Type.SETTING)
.defaultSetting(true).listener(new MobTeleportListener()).mode(Flag.Mode.ADVANCED).build();
/**
* If {@code false}, prevents Shulkers from teleporting
* Uses same listener as ENDERMAN_TELEPORT
* @since 1.22.1
*/
public static final Flag SHULKER_TELEPORT = new Flag.Builder("SHULKER_TELEPORT", Material.SHULKER_SHELL).type(Type.SETTING)
.defaultSetting(true).mode(Flag.Mode.ADVANCED).build();
public static final Flag ENTER_EXIT_MESSAGES = new Flag.Builder("ENTER_EXIT_MESSAGES", Material.DIRT).defaultSetting(true).type(Type.WORLD_SETTING)
.listener(new EnterExitListener())
.build();
@ -632,6 +648,21 @@ public final class Flags {
*/
public static final Flag ENTITY_PORTAL_TELEPORT = new Flag.Builder("ENTITY_PORTAL_TELEPORT", Material.ENDER_EYE).type(Type.WORLD_SETTING).defaultSetting(false).build();
/**
* Harvest Setting
* Controls who gets to harvest any crop related contents. e.g. Wheat, Sugar Cane, melon blocks, not stems, pumpkin blocks, etc.
* @since 1.23.0
*/
public static final Flag HARVEST = new Flag.Builder("HARVEST", Material.PUMPKIN).type(Type.PROTECTION).build();
/**
* Crop Planting
* Controls who gets to plant crops on tilled soil.
* @since 1.23.0
*/
public static final Flag CROP_PLANTING = new Flag.Builder("CROP_PLANTING", Material.PUMPKIN_SEEDS).type(Type.PROTECTION).build();
/**
* Provides a list of all the Flag instances contained in this class using reflection.
* Deprecated Flags are ignored.

View File

@ -190,7 +190,7 @@ public class AddonsManager {
private PladdonData loadPladdon(YamlConfiguration data, @NonNull File f) throws InvalidAddonInheritException, MalformedURLException, InvalidAddonDescriptionException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InvalidDescriptionException {
Addon addon = null;
try {
Plugin pladdon = pluginLoader.loadPlugin(f);
Plugin pladdon = Bukkit.getPluginManager().loadPlugin(f);
if (pladdon instanceof Pladdon pl) {
addon = pl.getAddon();
addon.setDescription(AddonClassLoader.asDescription(data));
@ -314,8 +314,10 @@ public class AddonsManager {
if (addon instanceof GameModeAddon gameMode) {
// Create the gameWorlds
gameMode.createWorlds();
// Create the seed worlds
createSeedWorlds(gameMode);
if (gameMode.isUsesNewChunkGeneration()) {
// Create the seed worlds
createSeedWorlds(gameMode);
}
plugin.getIWM().addGameMode(gameMode);
// Save and load blueprints
plugin.getBlueprintsManager().extractDefaultBlueprints(gameMode);
@ -344,7 +346,6 @@ public class AddonsManager {
/**
* Create seed worlds, which are used for deletion
* @param gameMode
*/
private void createSeedWorlds(GameModeAddon gameMode) {
if (gameMode.getOverWorld() != null) {
@ -449,8 +450,8 @@ public class AddonsManager {
public void disableAddons() {
if (!getEnabledAddons().isEmpty()) {
plugin.log("Disabling addons...");
// Disable addons
getEnabledAddons().forEach(this::disable);
// Disable addons - pladdons are disabled by the server
getEnabledAddons().stream().filter(addon -> !pladdons.keySet().contains(addon)).forEach(this::disable);
plugin.log("Addons successfully disabled.");
}
// Unregister all commands

View File

@ -104,6 +104,25 @@ public class LocalesManager {
}
return null;
}
/**
* Set the translation for a reference for a specific locale. The locale must be a known locale on this server.
* User {@link #getAvailableLocales(boolean)} to find out what locales are available.
* Note, the usual default locale is {@code Locale.US}
* @param locale locale
* @param reference reference
* @param translation translation
* @return true if successful, false if the locale is not a known locale on this server
* @since 1.22.1
*/
public boolean setTranslation(Locale locale, String reference, String translation) {
// Set a translation
if (!languages.containsKey(locale)) {
return false;
}
languages.get(locale).set(reference, translation);
return true;
}
/**
* Gets the translated String corresponding to the reference from the server's or the en-US locale file.
@ -120,7 +139,7 @@ public class LocalesManager {
/**
* Gets the list of prefixes from the user's locale, the server's locale and the en-US locale file.
* @param user the user to get the locale, not null.
* @return the list of prefixes from the user's locale, the server's locale and the en-US locale file.
* @return the set of prefixes from the user's locale, the server's locale and the en-US locale file.
* @since 1.13.0
*/
public Set<String> getAvailablePrefixes(@NonNull User user) {

View File

@ -284,7 +284,7 @@ public class PlayersManager {
/**
* Provides all home locations for player
* @param playerUUID - the player's UUID
* @return List of home locations
* @return Map of home locations
* @deprecated Use {@link IslandsManager#getHomeLocations(world.bentobox.bentobox.database.objects.Island)}
*/
@Deprecated(since="1.18.0", forRemoval=true)

View File

@ -70,7 +70,7 @@ public class DefaultNewIslandLocationStrategy implements NewIslandLocationStrate
* Checks if there is an island or blocks at this location
*
* @param location - the location
* @return Result enum if island found, null if blocks found, false if nothing found
* @return Result enum indicated what was found or not found
*/
protected Result isIsland(Location location) {
// Quick check

View File

@ -3,6 +3,7 @@ package world.bentobox.bentobox.nms;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@ -24,6 +25,7 @@ import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Villager;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.material.Colorable;
import org.bukkit.scheduler.BukkitRunnable;
@ -34,6 +36,7 @@ import io.papermc.lib.PaperLib;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.database.objects.IslandDeletion;
import world.bentobox.bentobox.util.MyBiomeGrid;
/**
* Regenerates by using a seed world. The seed world is created using the same generator as the game
@ -63,6 +66,10 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator {
@Override
public CompletableFuture<Void> regenerate(GameModeAddon gm, IslandDeletion di, World world) {
return gm.isUsesNewChunkGeneration() ? regenerateCopy(gm, di, world) : regenerateSimple(gm, di, world);
}
public CompletableFuture<Void> regenerateCopy(GameModeAddon gm, IslandDeletion di, World world) {
CompletableFuture<Void> bigFuture = new CompletableFuture<>();
new BukkitRunnable() {
private int chunkX = di.getMinXChunk();
@ -263,4 +270,98 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator {
toBanner.setPatterns(banner.getPatterns());
}
}
public CompletableFuture<Void> regenerateSimple(GameModeAddon gm, IslandDeletion di, World world) {
CompletableFuture<Void> bigFuture = new CompletableFuture<>();
new BukkitRunnable() {
private int chunkX = di.getMinXChunk();
private int chunkZ = di.getMinZChunk();
CompletableFuture<Void> currentTask = CompletableFuture.completedFuture(null);
@Override
public void run() {
if (!currentTask.isDone()) return;
if (isEnded(chunkX)) {
cancel();
bigFuture.complete(null);
return;
}
List<CompletableFuture<Void>> newTasks = new ArrayList<>();
for (int i = 0; i < plugin.getSettings().getDeleteSpeed(); i++) {
if (isEnded(chunkX)) {
break;
}
final int x = chunkX;
final int z = chunkZ;
newTasks.add(regenerateChunk(gm, di, world, x, z));
chunkZ++;
if (chunkZ > di.getMaxZChunk()) {
chunkZ = di.getMinZChunk();
chunkX++;
}
}
currentTask = CompletableFuture.allOf(newTasks.toArray(new CompletableFuture[0]));
}
private boolean isEnded(int chunkX) {
return chunkX > di.getMaxXChunk();
}
}.runTaskTimer(plugin, 0L, 20L);
return bigFuture;
}
@SuppressWarnings("deprecation")
private CompletableFuture<Void> regenerateChunk(GameModeAddon gm, IslandDeletion di, World world, int chunkX, int chunkZ) {
CompletableFuture<Chunk> chunkFuture = PaperLib.getChunkAtAsync(world, chunkX, chunkZ);
CompletableFuture<Void> invFuture = chunkFuture.thenAccept(chunk ->
Arrays.stream(chunk.getTileEntities()).filter(InventoryHolder.class::isInstance)
.filter(te -> di.inBounds(te.getLocation().getBlockX(), te.getLocation().getBlockZ()))
.forEach(te -> ((InventoryHolder) te).getInventory().clear())
);
CompletableFuture<Void> entitiesFuture = chunkFuture.thenAccept(chunk -> {
for (Entity e : chunk.getEntities()) {
if (!(e instanceof Player)) {
e.remove();
}
}
});
CompletableFuture<Chunk> copyFuture = chunkFuture.thenApply(chunk -> {
// Reset blocks
MyBiomeGrid grid = new MyBiomeGrid(chunk.getWorld().getEnvironment());
ChunkGenerator cg = gm.getDefaultWorldGenerator(chunk.getWorld().getName(), "delete");
// Will be null if use-own-generator is set to true
if (cg != null) {
ChunkGenerator.ChunkData cd = cg.generateChunkData(chunk.getWorld(), new Random(), chunk.getX(), chunk.getZ(), grid);
copyChunkDataToChunk(chunk, cd, grid, di.getBox());
}
return chunk;
});
CompletableFuture<Void> postCopyFuture = copyFuture.thenAccept(chunk ->
// Remove all entities in chunk, including any dropped items as a result of clearing the blocks above
Arrays.stream(chunk.getEntities()).filter(e -> !(e instanceof Player) && di.inBounds(e.getLocation().getBlockX(), e.getLocation().getBlockZ())).forEach(Entity::remove));
return CompletableFuture.allOf(invFuture, entitiesFuture, postCopyFuture);
}
@SuppressWarnings("deprecation")
private void copyChunkDataToChunk(Chunk chunk, ChunkGenerator.ChunkData chunkData, ChunkGenerator.BiomeGrid biomeGrid, BoundingBox limitBox) {
double baseX = chunk.getX() << 4;
double baseZ = chunk.getZ() << 4;
int minHeight = chunk.getWorld().getMinHeight();
int maxHeight = chunk.getWorld().getMaxHeight();
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
if (!limitBox.contains(baseX + x, 0, baseZ + z)) {
continue;
}
for (int y = minHeight; y < maxHeight; y++) {
setBlockInNativeChunk(chunk, x, y, z, chunkData.getBlockData(x, y, z), false);
// 3D biomes, 4 blocks separated
if (x % 4 == 0 && y % 4 == 0 && z % 4 == 0) {
chunk.getBlock(x, y, z).setBiome(biomeGrid.getBiome(x, y, z));
}
}
}
}
}
}

View File

@ -11,6 +11,7 @@ import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.scheduler.BukkitRunnable;
@ -65,7 +66,12 @@ public abstract class SimpleWorldRegenerator implements WorldRegenerator {
}
final int x = chunkX;
final int z = chunkZ;
newTasks.add(regenerateChunk(gm, di, world, x, z));
// Only process non-generated chunks
if (world.isChunkGenerated(x, z)) {
newTasks.add(regenerateChunk(gm, di, world, x, z));
}
chunkZ++;
if (chunkZ > di.getMaxZChunk()) {
chunkZ = di.getMinZChunk();
@ -105,6 +111,9 @@ public abstract class SimpleWorldRegenerator implements WorldRegenerator {
if (cg != null) {
ChunkGenerator.ChunkData cd = cg.generateChunkData(chunk.getWorld(), new Random(), chunk.getX(), chunk.getZ(), grid);
copyChunkDataToChunk(chunk, cd, grid, di.getBox());
for (BlockPopulator pop : cg.getDefaultPopulators(world)) {
pop.populate(world, new Random(), chunkX, chunkZ, null);
}
}
return chunk;
});

View File

@ -0,0 +1,82 @@
package world.bentobox.bentobox.nms.v1_19_R3;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData;
import net.minecraft.core.BlockPosition;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.chunk.Chunk;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.nms.PasteHandler;
import world.bentobox.bentobox.util.DefaultPasteUtil;
import world.bentobox.bentobox.util.Util;
public class PasteHandlerImpl implements PasteHandler {
protected static final IBlockData AIR = ((CraftBlockData) Bukkit.createBlockData(Material.AIR)).getState();
@Override
public CompletableFuture<Void> pasteBlocks(Island island, World world, Map<Location, BlueprintBlock> blockMap) {
return blockMap.entrySet().stream()
.map(entry -> setBlock(island, entry.getKey(), entry.getValue()))
.collect(
Collectors.collectingAndThen(
Collectors.toList(),
list -> CompletableFuture.allOf(list.toArray(new CompletableFuture[0]))
)
);
}
@Override
public CompletableFuture<Void> pasteEntities(Island island, World world, Map<Location, List<BlueprintEntity>> entityMap) {
return entityMap.entrySet().stream()
.map(entry -> DefaultPasteUtil.setEntity(island, entry.getKey(), entry.getValue()))
.collect(
Collectors.collectingAndThen(
Collectors.toList(),
list -> CompletableFuture.allOf(list.toArray(new CompletableFuture[0]))
)
);
}
/**
* Set the block to the location
*
* @param island - island
* @param location - location
* @param bpBlock - blueprint block
*/
public static CompletableFuture<Void> setBlock(Island island, Location location, BlueprintBlock bpBlock) {
return Util.getChunkAtAsync(location).thenRun(() -> {
Block block = location.getBlock();
// Set the block data - default is AIR
BlockData bd = DefaultPasteUtil.createBlockData(bpBlock);
CraftBlockData craft = (CraftBlockData) bd;
net.minecraft.world.level.World nmsWorld = ((CraftWorld) location.getWorld()).getHandle();
Chunk nmsChunk = nmsWorld.d(location.getBlockX() >> 4, location.getBlockZ() >> 4);
BlockPosition bp = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
// Setting the block to air before setting to another state prevents some console errors
nmsChunk.a(bp, AIR, false);
nmsChunk.a(bp, craft.getState(), false);
block.setBlockData(bd, false);
DefaultPasteUtil.setBlockState(island, block, bpBlock);
// Set biome
if (bpBlock.getBiome() != null) {
block.setBiome(bpBlock.getBiome());
}
});
}
}

View File

@ -1,10 +1,10 @@
package world.bentobox.bentobox.nms.v1_19_R2;
package world.bentobox.bentobox.nms.v1_19_R3;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData;
import net.minecraft.core.BlockPosition;
import net.minecraft.world.level.World;

View File

@ -14,12 +14,13 @@ import org.eclipse.jdt.annotation.NonNull;
* @author tastybento
*
*/
@SuppressWarnings("deprecation")
public class MyBiomeGrid implements BiomeGrid {
Map<Vector, Biome> map = new HashMap<>();
private Biome defaultBiome;
public MyBiomeGrid(Environment environment) {
switch(environment) {
case NETHER:
switch (environment) {
case NETHER -> {
try {
// 1.16 onwards
defaultBiome = Biome.valueOf("NETHER_WASTES");
@ -27,13 +28,9 @@ public class MyBiomeGrid implements BiomeGrid {
// Before 1.16
defaultBiome = Biome.valueOf("NETHER");
}
break;
case THE_END:
defaultBiome = Biome.THE_END;
break;
default:
defaultBiome = Biome.PLAINS;
break;
}
case THE_END -> defaultBiome = Biome.THE_END;
default -> defaultBiome = Biome.PLAINS;
}
}

View File

@ -467,7 +467,7 @@ public class Util {
/**
* Detects if the current MC version is at least the following version.
*
* <p>
* Assumes 0 patch version.
*
* @param minor Min Minor Version
@ -738,6 +738,32 @@ public class Util {
}
return regenerator;
}
/**
* Checks what version the server is running and picks the appropriate NMS handler, or fallback
* @return PasteHandler
*/
public static PasteHandler getPasteHandler() {
if (pasteHandler == null) {
String serverPackageName = Bukkit.getServer().getClass().getPackage().getName();
String pluginPackageName = plugin.getClass().getPackage().getName();
String version = serverPackageName.substring(serverPackageName.lastIndexOf('.') + 1);
PasteHandler handler;
try {
Class<?> clazz = Class.forName(pluginPackageName + ".nms." + version + ".PasteHandlerImpl");
if (PasteHandler.class.isAssignableFrom(clazz)) {
handler = (PasteHandler) clazz.getConstructor().newInstance();
} else {
throw new IllegalStateException("Class " + clazz.getName() + " does not implement PasteHandler");
}
} catch (Exception e) {
plugin.logWarning("No PasteHandler found for " + version + ", falling back to Bukkit API.");
handler = new world.bentobox.bentobox.nms.fallback.PasteHandlerImpl();
}
setPasteHandler(handler);
}
return pasteHandler;
}
/**
* Set the paste handler the plugin will use
@ -747,17 +773,6 @@ public class Util {
Util.pasteHandler = pasteHandler;
}
/**
* Get the paste handler the plugin will use
* @return an NMS accelerated class for this server
*/
public static PasteHandler getPasteHandler() {
if (pasteHandler == null) {
setPasteHandler(new world.bentobox.bentobox.nms.fallback.PasteHandlerImpl());
}
return pasteHandler;
}
/**
* Broadcast a localized message to all players with the permission {@link Server#BROADCAST_CHANNEL_USERS}
*

View File

@ -276,7 +276,7 @@ public class ClosestSafeSpotTeleport
/**
* This method finishes the chunk loading task and checks from all remaining positions in block queue
* to find the best location for teleportation.
*
* <p>
* This method stops position finding task and process teleporation.
*/
private void finishTask()

View File

@ -214,6 +214,10 @@ public class ServerCompatibility {
* @since 1.22.0
*/
V1_19_3(Compatibility.COMPATIBLE),
/**
* @since 1.22.1
*/
V1_19_4(Compatibility.COMPATIBLE),
;
private final Compatibility compatibility;

View File

@ -851,6 +851,11 @@ protection:
name: "Shulker boxes"
description: "Toggle shulker box interaction"
hint: "Shulker box access disabled"
SHULKER_TELEPORT:
description: |-
&a Shulker can teleport
&a if active.
name: "Shulker teleport"
TRAPPED_CHEST:
name: "Trapped chests"
description: "Toggle trapped chest interaction"
@ -928,6 +933,11 @@ protection:
&a by island visitor.
name: "Creeper griefing protection"
hint: "Creeper griefing disabled"
CROP_PLANTING:
description: |-
&a Set who can plant seeds.
name: "Crop planting"
hint: "Crop planting disabled"
CROP_TRAMPLE:
description: "Toggle crop trampling"
name: "Trample crops"
@ -971,6 +981,11 @@ protection:
&a Endermen can remove
&a blocks from islands
name: "Enderman griefing"
ENDERMAN_TELEPORT:
description: |-
&a Endermen can teleport
&a if active.
name: "Enderman teleport"
ENDER_PEARL:
description: "Toggle use"
name: "EnderPearls"
@ -1031,6 +1046,13 @@ protection:
&a outside protected
&a island space
name: "&e Limit mobs to island"
HARVEST:
description: |-
&a Set who can harvest crops.
&a Don't forget to allow item
&a pickup too!
name: "Crop harvesting"
hint: "Crop harvesting disabled"
HIVE:
description: |-
&a Toggle hive harvesting.
@ -1634,7 +1656,7 @@ successfully-loaded: |2
&6 ____ _ ____
&6 | _ \ | | | _ \ &7 by &a tastybento &7 and &a Poslovitch
&6 | |_) | ___ _ __ | |_ ___ | |_) | _____ __ &7 2017 - 2022
&6 | |_) | ___ _ __ | |_ ___ | |_) | _____ __ &7 2017 - 2023
&6 | _ < / _ \ '_ \| __/ _ \| _ < / _ \ \/ /
&6 | |_) | __/ | | | || (_) | |_) | (_) > < &b v&e [version]
&6 |____/ \___|_| |_|\__\___/|____/ \___/_/\_\ &8 Loaded in &e [time]&8 ms.

View File

@ -60,3 +60,4 @@ permissions:
bentobox.version:
description: Allows to use /bentobox version
default: op

View File

@ -28,7 +28,6 @@ public class SettingsTest {
private Settings s;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -49,7 +49,7 @@ import world.bentobox.bentobox.managers.AddonsManager;
@PrepareForTest( { BentoBox.class, Bukkit.class })
public class AddonClassLoaderTest {
private enum MandatoryTags {
private enum mandatoryTags {
MAIN,
NAME,
VERSION,
@ -76,7 +76,6 @@ public class AddonClassLoaderTest {
private BentoBox plugin;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
@ -91,7 +90,7 @@ public class AddonClassLoaderTest {
}
public void makeAddon(List<MandatoryTags> missingTags) throws IOException {
public void makeAddon(List<mandatoryTags> missingTags) throws IOException {
// Make the addon
dataFolder = new File("dataFolder");
jarFile = new File("addon.jar");
@ -112,18 +111,18 @@ public class AddonClassLoaderTest {
Files.deleteIfExists(ymlFile.toPath());
}
private YamlConfiguration getYaml(List<MandatoryTags> missingTags) {
private YamlConfiguration getYaml(List<mandatoryTags> missingTags) {
YamlConfiguration r = new YamlConfiguration();
if (!missingTags.contains(MandatoryTags.NAME)) {
if (!missingTags.contains(mandatoryTags.NAME)) {
r.set("name", "TestAddon");
}
if (!missingTags.contains(MandatoryTags.MAIN)) {
if (!missingTags.contains(mandatoryTags.MAIN)) {
r.set("main", "world.bentobox.test.Test");
}
if (!missingTags.contains(MandatoryTags.VERSION)) {
if (!missingTags.contains(mandatoryTags.VERSION)) {
r.set("version", "1.0.0");
}
if (!missingTags.contains(MandatoryTags.AUTHORS)) {
if (!missingTags.contains(mandatoryTags.AUTHORS)) {
r.set("authors", "tastybento");
}
r.set("metrics", false);
@ -174,7 +173,6 @@ public class AddonClassLoaderTest {
}
/**
* @throws java.lang.Exception
*/
@After
public void TearDown() throws IOException {
@ -199,7 +197,6 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#AddonClassLoader(world.bentobox.bentobox.managers.AddonsManager, org.bukkit.configuration.file.YamlConfiguration, java.io.File, java.lang.ClassLoader)}.
* @throws MalformedURLException
*/
@Test
public void testAddonClassLoader() throws MalformedURLException {
@ -208,7 +205,6 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#asDescription(org.bukkit.configuration.file.YamlConfiguration)}.
* @throws InvalidAddonDescriptionException
*/
@Test
public void testAsDescription() throws InvalidAddonDescriptionException {
@ -232,11 +228,10 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#asDescription(org.bukkit.configuration.file.YamlConfiguration)}.
* @throws InvalidAddonDescriptionException
*/
@Test
public void testAsDescriptionNoName() {
YamlConfiguration yml = this.getYaml(List.of(MandatoryTags.NAME));
YamlConfiguration yml = this.getYaml(List.of(mandatoryTags.NAME));
try {
AddonClassLoader.asDescription(yml);
} catch (InvalidAddonDescriptionException e) {
@ -246,11 +241,10 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#asDescription(org.bukkit.configuration.file.YamlConfiguration)}.
* @throws InvalidAddonDescriptionException
*/
@Test
public void testAsDescriptionNoAuthors() {
YamlConfiguration yml = this.getYaml(List.of(MandatoryTags.AUTHORS));
YamlConfiguration yml = this.getYaml(List.of(mandatoryTags.AUTHORS));
try {
AddonClassLoader.asDescription(yml);
} catch (InvalidAddonDescriptionException e) {
@ -260,11 +254,10 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#asDescription(org.bukkit.configuration.file.YamlConfiguration)}.
* @throws InvalidAddonDescriptionException
*/
@Test
public void testAsDescriptionNoVersion() {
YamlConfiguration yml = this.getYaml(List.of(MandatoryTags.VERSION));
YamlConfiguration yml = this.getYaml(List.of(mandatoryTags.VERSION));
try {
AddonClassLoader.asDescription(yml);
} catch (InvalidAddonDescriptionException e) {
@ -274,11 +267,10 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#asDescription(org.bukkit.configuration.file.YamlConfiguration)}.
* @throws InvalidAddonDescriptionException
*/
@Test
public void testAsDescriptionNoMain() {
YamlConfiguration yml = this.getYaml(List.of(MandatoryTags.MAIN));
YamlConfiguration yml = this.getYaml(List.of(mandatoryTags.MAIN));
try {
AddonClassLoader.asDescription(yml);
} catch (InvalidAddonDescriptionException e) {
@ -288,7 +280,6 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#findClass(java.lang.String)}.
* @throws MalformedURLException
*/
@Test
public void testFindClassString() throws MalformedURLException {
@ -299,7 +290,6 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#findClass(java.lang.String, boolean)}.
* @throws MalformedURLException
*/
@Test
public void testFindClassStringBoolean() throws MalformedURLException {
@ -310,7 +300,6 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#getAddon()}.
* @throws MalformedURLException
*/
@Test
public void testGetAddon() throws MalformedURLException {
@ -321,7 +310,6 @@ public class AddonClassLoaderTest {
/**
* Test method for {@link world.bentobox.bentobox.api.addons.AddonClassLoader#getClasses()}.
* @throws MalformedURLException
*/
@Test
public void testGetClasses() throws MalformedURLException {

View File

@ -24,7 +24,6 @@ public class AddonDescriptionTest {
private ConfigurationSection configSec;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -39,7 +39,6 @@ public class DefaultHelpCommandTest {
private User user;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -80,7 +80,6 @@ public class DelayedTeleportCommandTest {
private Notifier notifier;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -45,7 +45,6 @@ public class HiddenCommandTest {
private User user;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -57,7 +57,6 @@ public class AdminDeleteCommandTest {
private UUID uuid;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -71,7 +71,6 @@ public class AdminGetrankCommandTest {
private Island island;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
@ -99,12 +98,12 @@ public class AdminGetrankCommandTest {
Map<UUID, String> online = new HashMap<>();
Set<Player> onlinePlayers = new HashSet<>();
for (int j = 0; j < NAMES.length; j++) {
for (String name : NAMES) {
Player p1 = mock(Player.class);
UUID uuid = UUID.randomUUID();
when(p1.getUniqueId()).thenReturn(uuid);
when(p1.getName()).thenReturn(NAMES[j]);
online.put(uuid, NAMES[j]);
when(p1.getName()).thenReturn(name);
online.put(uuid, name);
onlinePlayers.add(p1);
}
PowerMockito.mockStatic(Bukkit.class);
@ -115,7 +114,6 @@ public class AdminGetrankCommandTest {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() {
@ -221,15 +219,11 @@ public class AdminGetrankCommandTest {
public void testTabCompleteUserStringListOfStringWithChars() {
Optional<List<String>> result = c.tabComplete(user, "", Collections.singletonList("g"));
assertTrue(result.isPresent());
result.ifPresent(list -> {
assertEquals(1, list.size());
});
result.ifPresent(list -> assertEquals(1, list.size()));
// Two names
result = c.tabComplete(user, "", Collections.singletonList("f"));
assertTrue(result.isPresent());
result.ifPresent(list -> {
assertEquals(2, list.size());
});
result.ifPresent(list -> assertEquals(2, list.size()));
}
}

View File

@ -81,7 +81,6 @@ public class AdminInfoCommandTest {
private IslandWorldManager iwm;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
@ -141,7 +140,6 @@ public class AdminInfoCommandTest {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() {

View File

@ -68,7 +68,6 @@ public class AdminRegisterCommandTest {
private IslandDeletionManager idm;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -78,7 +78,6 @@ public class AdminResetFlagsCommandTest {
private @Nullable User user;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
@ -140,7 +139,6 @@ public class AdminResetFlagsCommandTest {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() {

View File

@ -63,7 +63,6 @@ public class AdminSetrankCommandTest {
private UUID targetUUID;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
@ -106,7 +105,6 @@ public class AdminSetrankCommandTest {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() {

View File

@ -52,7 +52,6 @@ public class AdminSetspawnCommandTest {
private IslandsManager im;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {

View File

@ -93,7 +93,6 @@ public class AdminSettingsCommandTest {
private PluginManager pluginManager;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
@ -187,7 +186,6 @@ public class AdminSettingsCommandTest {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {

Some files were not shown because too many files have changed in this diff Show More