Skip to content

Commit

Permalink
Merge pull request #2514 from BentoBoxWorld/develop
Browse files Browse the repository at this point in the history
Release 2.5.4
  • Loading branch information
tastybento authored Sep 22, 2024
2 parents e5469b7 + a5fee6b commit 234fa63
Show file tree
Hide file tree
Showing 20 changed files with 401 additions and 57 deletions.
6 changes: 1 addition & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>2.5.3</build.version>
<build.version>2.5.4</build.version>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<server.jars>${project.basedir}/lib</server.jars>
Expand Down Expand Up @@ -157,10 +157,6 @@
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public</url>
</repository>
<repository>
<id>placeholderapi-repo</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>dynmap-repo</id>
<url>https://repo.mikeprimm.com/</url>
Expand Down
22 changes: 21 additions & 1 deletion src/main/java/world/bentobox/bentobox/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ public class Settings implements ConfigObject {
private Set<String> fakePlayers = new HashSet<>();

/* PANELS */

@ConfigComment("Toggle whether panels should be closed or not when the player clicks anywhere outside of the inventory view.")
@ConfigEntry(path = "panel.close-on-click-outside")
private boolean closePanelOnClickOutside = true;
Expand Down Expand Up @@ -189,6 +188,13 @@ public class Settings implements ConfigObject {
/*
* Island
*/
@ConfigComment("Override island distance mismatch checking. BentoBox normally refuses to run if")
@ConfigComment("the island distance in the gamemode config is different to the one stored in the database")
@ConfigComment("for safety. This overrides that check. You should never need this, and if you do not understand it")
@ConfigComment("keep it as false")
@ConfigEntry(path = "island.override-safety-check")
private boolean overrideSafetyCheck = false;

// Number of islands
@ConfigComment("The default number of concurrent islands a player may have.")
@ConfigComment("This may be overridden by individual game mode config settings.")
Expand Down Expand Up @@ -1034,4 +1040,18 @@ public void setHideUsedBlueprints(boolean hideUsedBlueprints) {
this.hideUsedBlueprints = hideUsedBlueprints;
}

/**
* @return the overrideSafetyCheck
*/
public boolean isOverrideSafetyCheck() {
return overrideSafetyCheck;
}

/**
* @param overrideSafetyCheck the overrideSafetyCheck to set
*/
public void setOverrideSafetyCheck(boolean overrideSafetyCheck) {
this.overrideSafetyCheck = overrideSafetyCheck;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Set<String> getOldIslands(int days) {
// Process islands in one pass, logging and adding to the set if applicable
getPlugin().getIslands().getIslands().stream()
.filter(i -> !i.isSpawn()).filter(i -> !i.getPurgeProtected())
.filter(i -> i.getWorld() != null) // to handle currently unloaded world islands
.filter(i -> i.getWorld().equals(this.getWorld())).filter(Island::isOwned).filter(
i -> i.getMemberSet().stream()
.allMatch(member -> (currentTimeMillis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ public PanelItemBuilder description(String... description) {
* @return PanelItemBuilder
*/
public PanelItemBuilder description(String description) {
Collections.addAll(this.description, description.split("\n"));
if (description != null) {
Collections.addAll(this.description, description.split("\n"));
}
return this;
}

Expand Down Expand Up @@ -168,7 +170,7 @@ public PanelItem.ClickHandler getClickHandler() {
public boolean isPlayerHead() {
return playerHeadName != null && !playerHeadName.isEmpty();
}

/**
* @return the playerHead
* @since 1.9.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
public class ProfessionTypeAdapter extends TypeAdapter<Profession> {

@Override
public void write(JsonWriter out, Profession profession) throws IOException {
out.value(profession.name());
public void write(JsonWriter out, Profession profession) throws IOException {
if (profession != null) {
out.value(profession.name());
return;
}
out.nullValue();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
public class VillagerTypeAdapter extends TypeAdapter<Villager.Type> {

@Override
public void write(JsonWriter out, Villager.Type type) throws IOException {
public void write(JsonWriter out, Villager.Type type) throws IOException {
if (type == null) {
out.nullValue();
return;
}
out.value(type.name());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,17 +253,42 @@ public void addToPendingKick(World world)
public Optional<Map<String, MetaDataValue>> getMetaData() {
if (metaData == null) {
metaData = new HashMap<>();
} else if (isImmutable(metaData)) {
metaData = new HashMap<>(metaData); // Convert immutable map to mutable
}
return Optional.of(metaData);
}

private boolean isImmutable(Map<String, MetaDataValue> map) {
try {
String testKey = "testKey";
MetaDataValue testValue = new MetaDataValue("test");

// If the map already contains keys, use one of them
if (!map.isEmpty()) {
String existingKey = map.keySet().iterator().next();
map.put(existingKey, map.get(existingKey)); // Attempt to replace value
} else {
// Use a unique key-value pair
map.put(testKey, testValue);
map.remove(testKey);
}
return false; // No exception means the map is mutable
} catch (UnsupportedOperationException e) {
return true; // Exception means the map is immutable
}
}

/**
* @param metaData the metaData to set
* @since 1.15.4
* @see User#setMetaData(Map)
*/
@Override
public void setMetaData(Map<String, MetaDataValue> metaData) {
if (isImmutable(metaData)) {
throw new IllegalArgumentException("Provided map is immutable and cannot be set.");
}
this.metaData = metaData;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import org.bukkit.Material;
Expand All @@ -26,6 +27,7 @@
import world.bentobox.bentobox.util.Util;

/**
*
* @author tastybento
*
*/
Expand Down Expand Up @@ -108,11 +110,19 @@ private void openPanel(User user, String panelName, World world) {
*/
public PanelItem getPanelItem(String c, User user, World world) {
PanelItemBuilder pib = new PanelItemBuilder();
pib.name(c);
pib.name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, c));
pib.clickHandler(new CommandCycleClick(this, c));
pib.icon(Material.MAP);
// TODO: use specific layout
String d = user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, "");
String result = "";
// Remove the first word (everything before the first space)
String[] words = c.split(" ", 2); // Split into two parts, the first word and the rest
if (words.length > 1) {
result = words[1].replace(" ", "-"); // Replace spaces with hyphens
}
String ref = "protection.panel.flag-item.command-instructions." + result.toLowerCase(Locale.ENGLISH);
String commandDescription = user.getTranslationOrNothing(ref);
String d = user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION,
commandDescription);
pib.description(d);
RanksManager.getInstance().getRanks().forEach((reference, score) -> {
if (score >= RanksManager.MEMBER_RANK && score < island.getRankCommand(c)) {
Expand All @@ -133,7 +143,7 @@ private List<String> getCommands(World world, User user) {
.filter(c -> c.getWorld() != null && c.getWorld().equals(world)) // Only allow commands in this world
.filter(c -> c.testPermission(user.getSender())) // Only allow them to see commands they have permission to see
.flatMap(c -> getCmdRecursively("/", c).stream())
.filter(label -> user.isOp() || !hiddenItems.contains(CommandCycleClick.COMMAND_RANK_PREFIX + label))
.filter(label -> user.isOp() || !hiddenItems.contains(CommandCycleClick.COMMAND_RANK_PREFIX + label)) // Hide any hidden commands
.limit(49) // Silently limit to 49
.toList();
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ public void onBreakHanging(final HangingBreakByEntityEvent e) {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEvent e)
{
if (e.getClickedBlock() == null) {
return;
}
Player p = e.getPlayer();
Location l = e.getClickedBlock().getLocation();
Material m = e.getClickedBlock().getType();
Expand All @@ -95,7 +98,7 @@ public void onPlayerInteract(final PlayerInteractEvent e)
if (((CaveVinesPlant) e.getClickedBlock().getBlockData()).isBerries()) {
this.checkIsland(e, p, l, Flags.HARVEST);
}
}
}
case SWEET_BERRY_BUSH -> this.checkIsland(e, p, l, Flags.HARVEST);
case ROOTED_DIRT -> this.checkIsland(e, p, l, Flags.BREAK_BLOCKS);
default -> { // Do nothing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;

Expand Down Expand Up @@ -40,9 +38,10 @@ public void onExplosion(final EntityExplodeEvent e) {
if (!Flags.CREEPER_DAMAGE.isSetForWorld(e.getLocation().getWorld())) {
// If any were removed, then prevent damage too
e.blockList().clear();
e.setCancelled(true);
return;
// Still allow player and mob damage
e.setCancelled(false);
}

// Check for griefing
Creeper creeper = (Creeper)e.getEntity();
if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld())
Expand All @@ -55,25 +54,6 @@ public void onExplosion(final EntityExplodeEvent e) {
}
}


/**
* Prevent entities being damaged by explosion
* @param e - event
* @since 1.10.0
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onExplosion(final EntityDamageByEntityEvent e) {
if (!e.getCause().equals(EntityDamageEvent.DamageCause.ENTITY_EXPLOSION) || !getIWM().inWorld(e.getEntity().getLocation())
|| !e.getDamager().getType().equals(EntityType.CREEPER)) {
return;
}
// If creeper damage is not allowed in world cancel the damage
if (!Flags.CREEPER_DAMAGE.isSetForWorld(e.getEntity().getWorld())) {
e.setCancelled(true);
}
}


/**
* Prevent creepers from igniting if they are not allowed to grief
* @param e - event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.flags.FlagListener;
Expand Down Expand Up @@ -36,15 +37,16 @@ public void onTeleport(PlayerTeleportEvent e) {
handleEnterExit(User.getInstance(e.getPlayer()), e.getFrom(), e.getTo(), e);
}

private void handleEnterExit(@NonNull User user, @NonNull Location from, @NonNull Location to, @NonNull PlayerMoveEvent e) {
private void handleEnterExit(@NonNull User user, @NonNull Location from, @Nullable Location to,
@NonNull PlayerMoveEvent e) {
// Only process if there is a change in X or Z coords
if (from.getWorld() != null && from.getWorld().equals(to.getWorld())
if (from.getWorld() != null && to != null && from.getWorld().equals(to.getWorld())
&& from.toVector().multiply(XZ).equals(to.toVector().multiply(XZ))) {
return;
}

Optional<Island> islandFrom = getIslands().getProtectedIslandAt(from);
Optional<Island> islandTo = getIslands().getProtectedIslandAt(to);
Optional<Island> islandTo = to == null ? Optional.empty() : getIslands().getProtectedIslandAt(to);

/*
* Options:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public CompositeCommand getCommand(@NonNull String command) {
}

/**
* Get a map of every command registered in BentoBox
* @return the commands
*/
@NonNull
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/world/bentobox/bentobox/managers/IslandsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1267,15 +1267,18 @@ public void load() throws IOException {
// These will be deleted later
deletedIslands.add(island.getUniqueId());
} // Check island distance and if incorrect stop BentoBox
else if (island.getWorld() != null && plugin.getIWM().inWorld(island.getWorld())
else if (!plugin.getSettings().isOverrideSafetyCheck() && island.getWorld() != null
&& plugin.getIWM().inWorld(island.getWorld())
&& island.getRange() != plugin.getIWM().getIslandDistance(island.getWorld())) {
throw new IOException("Island distance mismatch!\n" + "World '" + island.getWorld().getName()
+ "' distance " + plugin.getIWM().getIslandDistance(island.getWorld()) + " != island range "
+ island.getRange() + "!\n" + "Island ID in database is " + island.getUniqueId() + ".\n"
+ "Island distance in config.yml cannot be changed mid-game! Fix config.yml or clean database.");
} else {
// Fix island center if it is off
fixIslandCenter(island);
if (!plugin.getSettings().isOverrideSafetyCheck()) {
// Fix island center if it is off
fixIslandCenter(island);
}
islandCache.addIsland(island, true);

if (island.isSpawn()) {
Expand Down Expand Up @@ -1650,6 +1653,10 @@ public void clearArea(Location loc) {
* @param uniqueId - UUID of player
*/
public void clearRank(int rank, UUID uniqueId) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> clearRankSync(rank, uniqueId));
}

void clearRankSync(int rank, UUID uniqueId) {
islandCache.getCachedIslands().forEach(
i -> i.getMembers().entrySet().removeIf(e -> e.getKey().equals(uniqueId) && e.getValue() == rank));
}
Expand Down
Loading

0 comments on commit 234fa63

Please sign in to comment.