Code clean up from Sonar Cloud analysis (#2068)

* Code clean up from Sonar Cloud analysis

* Fix tests

* Remove code smell

* Rename "island" which hides the field declared at line 25.

* Removed code smells.

* Rename variable record to rec

Renamed "record" variable to not match a restricted identifier.
Restricted Identifiers should not be used as identifiers. "record" is
using in Java 16.

* Added private constructor to prevent instantiation of static class

Changed variable name to rec instead of restricted "record".

* Remove Blueprint code smells.

* Use a record for database settings constructor

Code smell: Methods should not have too many parameters. I'm not sure
what methods are using this class though.

* Update MyWorlds version

The POM for MyWorlds is invalid and causes a warning, but this still
persists with this version.

* Extracted nested try block into a separate method.

Makes it clear when reading the code what might be caught

* Extracted nested try block into a separate method.

* Fixed JavaDoc /** instead of just /*

* Extracted nested try block into a separate method.

* Refactored to not assign loop counter from within the loop body.

* Better delete option. With results.

That said, this is legacy code to handle an issue that occurred a long
time ago and this whole set of code can probably be removed.

* Catch Exceptions not Throwable

* Log error with BentoBox logError

* Use computeIfAbsent

Using these instead leads to cleaner and more readable code.

* User can no longer be null

* Added the missing @Deprecated annotation and @since ref

* Added @since reference

* Merge if statements

* Use BentoBox error logging.

* Added JavaDoc @since

* Remove deprecated class and move used class

* Remove deprecated WoodType and use Type.

* Remove unused import

* Extracted nested try block into a separate method.

* Comment empty default statement

* Clean up logic; avoid switch

* Use Java instead of Guava

* private constructor to hide the implicit public one.

* Private constructor to hide the implicit public one.

Merged if statement.

* Add comment

* if merge

* Make variable constant

* Remove unused imports

* Remove deprecated and unused method

* Remove unused import

* Typo

* Remove instanceof and cast

* Remove superfluous null check

* Put constant at bottom of file because @BONNe likes it there.

* Simplify particle validation code
This commit is contained in:
tastybento 2022-12-31 16:41:17 -08:00 committed by GitHub
parent 0183380b82
commit 056cff4b6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 594 additions and 652 deletions

View File

@ -82,7 +82,7 @@
<placeholderapi.version>2.10.9</placeholderapi.version>
<githubapi.version>d5f5e0bbd8</githubapi.version>
<dynmap.version>3.0-SNAPSHOT</dynmap.version>
<myworlds.version>1.19-v2</myworlds.version>
<myworlds.version>1.19.3-v1</myworlds.version>
<!-- Revision variable removes warning about dynamic version -->
<revision>${build.version}-SNAPSHOT</revision>
<!-- Do not change unless you want different name for local builds. -->

View File

@ -87,12 +87,10 @@ public class AdminSettingsCommand extends CompositeCommand {
}
private boolean getIsland(User user, List<String> args) {
if (args.get(0).equalsIgnoreCase(SPAWN_ISLAND)) {
if (getIslands().getSpawn(getWorld()).isPresent()) {
if (args.get(0).equalsIgnoreCase(SPAWN_ISLAND) && getIslands().getSpawn(getWorld()).isPresent()) {
island = getIslands().getSpawn(getWorld()).get();
return true;
}
}
// Get target player
@Nullable UUID targetUUID = Util.getUUID(args.get(0));
if (targetUUID == null) {
@ -201,6 +199,7 @@ public class AdminSettingsCommand extends CompositeCommand {
}
case WORLD_SETTING -> f.setSetting(getWorld(), activeState);
default -> {
// Do nothing
}
}
});

View File

@ -51,7 +51,7 @@ public class AdminBlueprintSaveCommand extends ConfirmableCommand
return false;
}
if (clipboard.getBlueprint().getBedrock() == null)
if (clipboard.getBlueprint() != null && clipboard.getBlueprint().getBedrock() == null)
{
// Bedrock is required for all blueprints.
user.sendMessage("commands.admin.blueprint.bedrock-required");

View File

@ -84,9 +84,9 @@ public class IslandDeletehomeCommand extends ConfirmableCommand {
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
Island island = getIslands().getIsland(getWorld(), user.getUniqueId());
if (island != null) {
return Optional.of(Util.tabLimit(new ArrayList<>(island.getHomes().keySet()), lastArg));
Island is = getIslands().getIsland(getWorld(), user.getUniqueId());
if (is != null) {
return Optional.of(Util.tabLimit(new ArrayList<>(is.getHomes().keySet()), lastArg));
} else {
return Optional.empty();
}

View File

@ -55,14 +55,12 @@ public class IslandGoCommand extends DelayedTeleportCommand {
user.sendMessage(Flags.PREVENT_TELEPORT_WHEN_FALLING.getHintReference());
return false;
}
if (!args.isEmpty()) {
if (!getIslands().isHomeLocation(island, String.join(" ", args))) {
if (!args.isEmpty() && !getIslands().isHomeLocation(island, String.join(" ", args))) {
user.sendMessage("commands.island.go.unknown-home");
user.sendMessage("commands.island.sethome.homes-are");
island.getHomes().keySet().stream().filter(s -> !s.isEmpty()).forEach(s -> user.sendMessage("commands.island.sethome.home-list-syntax", TextVariables.NAME, s));
return false;
}
}
return true;
}

View File

@ -87,9 +87,9 @@ public class IslandRenamehomeCommand extends ConfirmableCommand {
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
Island island = getIslands().getIsland(getWorld(), user.getUniqueId());
if (island != null) {
return Optional.of(Util.tabLimit(new ArrayList<>(island.getHomes().keySet()), lastArg));
Island is = getIslands().getIsland(getWorld(), user.getUniqueId());
if (is != null) {
return Optional.of(Util.tabLimit(new ArrayList<>(is.getHomes().keySet()), lastArg));
} else {
return Optional.empty();
}

View File

@ -96,7 +96,6 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
// Remove the invite
itc.removeInvite(playerUUID);
User inviter = User.getInstance(invite.getInviter());
if (inviter != null) {
Island island = getIslands().getIsland(getWorld(), inviter);
if (island != null) {
if (island.getMemberSet(RanksManager.TRUSTED_RANK, false).size() > getIslands().getMaxMembers(island, RanksManager.TRUSTED_RANK)) {
@ -111,7 +110,10 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
.reason(IslandEvent.Reason.RANK_CHANGE)
.rankChange(island.getRank(user), RanksManager.TRUSTED_RANK)
.build();
if (inviter.isOnline()) {
inviter.sendMessage("commands.island.team.trust.success", TextVariables.NAME, user.getName());
}
if (inviter.isPlayer()) {
user.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, inviter.getName());
}
}
@ -121,7 +123,6 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
// Remove the invite
itc.removeInvite(playerUUID);
User inviter = User.getInstance(invite.getInviter());
if (inviter != null) {
Island island = getIslands().getIsland(getWorld(), inviter);
if (island != null) {
if (island.getMemberSet(RanksManager.COOP_RANK, false).size() > getIslands().getMaxMembers(island, RanksManager.COOP_RANK)) {
@ -136,7 +137,10 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
.reason(IslandEvent.Reason.RANK_CHANGE)
.rankChange(island.getRank(user), RanksManager.COOP_RANK)
.build();
if (inviter.isOnline()) {
inviter.sendMessage("commands.island.team.coop.success", TextVariables.NAME, user.getName());
}
if (inviter.isPlayer()) {
user.sendMessage("commands.island.team.coop.you-are-a-coop-member", TextVariables.NAME, inviter.getName());
}
}
@ -179,7 +183,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 != null) {
if (inviter.isOnline()) {
inviter.sendMessage("commands.island.team.invite.accept.name-joined-your-island", TextVariables.NAME, user.getName());
}
getIslands().save(teamIsland);

View File

@ -96,11 +96,11 @@ public class TemplatedPanel extends Panel
{
for (int k = 0; k < this.panelTemplate.content()[i].length; k++)
{
ItemTemplateRecord record = this.panelTemplate.content()[i][k];
ItemTemplateRecord rec = this.panelTemplate.content()[i][k];
if (record != null && record.dataMap().containsKey("type"))
if (rec != null && rec.dataMap().containsKey("type"))
{
String type = String.valueOf(record.dataMap().get("type"));
String type = String.valueOf(rec.dataMap().get("type"));
int counter = this.typeSlotMap.computeIfAbsent(type, key -> 0);
this.typeSlotMap.put(type, counter + 1);
@ -226,11 +226,11 @@ public class TemplatedPanel extends Panel
// Analyze the template
for (int i = 0; i < 5; i++)
{
ItemTemplateRecord record = this.panelTemplate.content()[0][i];
ItemTemplateRecord rec = this.panelTemplate.content()[0][i];
if (record != null && record.dataMap().containsKey("type"))
if (rec != null && rec.dataMap().containsKey("type"))
{
String type = String.valueOf(record.dataMap().get("type"));
String type = String.valueOf(rec.dataMap().get("type"));
int counter = this.typeSlotMap.computeIfAbsent(type, key -> 0);
this.typeSlotMap.put(type, counter + 1);
@ -289,11 +289,11 @@ public class TemplatedPanel extends Panel
{
for (int k = 0; k < 3; k++)
{
ItemTemplateRecord record = this.panelTemplate.content()[i][k];
ItemTemplateRecord rec = this.panelTemplate.content()[i][k];
if (record != null && record.dataMap().containsKey("type"))
if (rec != null && rec.dataMap().containsKey("type"))
{
String type = String.valueOf(record.dataMap().get("type"));
String type = String.valueOf(rec.dataMap().get("type"));
int counter = this.typeSlotMap.computeIfAbsent(type, key -> 0);
this.typeSlotMap.put(type, counter + 1);
@ -354,41 +354,41 @@ public class TemplatedPanel extends Panel
/**
* This method passes button creation from given record template.
* @param record Template of the button that must be created.
* @param rec Template of the button that must be created.
* @return PanelItem of the template, otherwise null.
*/
@Nullable
private PanelItem makeButton(@Nullable ItemTemplateRecord record)
private PanelItem makeButton(@Nullable ItemTemplateRecord rec)
{
if (record == null)
if (rec == null)
{
// Immediate exit if record is null.
return null;
}
if (record.dataMap().containsKey("type"))
if (rec.dataMap().containsKey("type"))
{
// If dataMap is not null, and it is not empty, then pass button to the object creator function.
return this.makeAddonButton(record);
return this.makeAddonButton(rec);
}
else
{
PanelItemBuilder itemBuilder = new PanelItemBuilder();
if (record.icon() != null)
if (rec.icon() != null)
{
itemBuilder.icon(record.icon().clone());
itemBuilder.icon(rec.icon().clone());
}
if (record.title() != null)
if (rec.title() != null)
{
itemBuilder.name(this.user.getTranslation(record.title()));
itemBuilder.name(this.user.getTranslation(rec.title()));
}
if (record.description() != null)
if (rec.description() != null)
{
itemBuilder.description(this.user.getTranslation(record.description()));
itemBuilder.description(this.user.getTranslation(rec.description()));
}
// If there are generic click handlers that could be added, then this is a place
@ -402,19 +402,19 @@ public class TemplatedPanel extends Panel
/**
* This method passes button to the type creator, if that exists.
* @param record Template of the button that must be created.
* @param rec Template of the button that must be created.
* @return PanelItem of the button created by typeCreator, otherwise null.
*/
@Nullable
private PanelItem makeAddonButton(@NonNull ItemTemplateRecord record)
private PanelItem makeAddonButton(@NonNull ItemTemplateRecord rec)
{
// Get object type.
String type = String.valueOf(record.dataMap().getOrDefault("type", ""));
String type = String.valueOf(rec.dataMap().getOrDefault("type", ""));
if (!this.typeCreators.containsKey(type))
{
// There are no object with a given type.
return this.makeFallBack(record.fallback());
return this.makeFallBack(rec.fallback());
}
BiFunction<ItemTemplateRecord, ItemSlot, PanelItem> buttonBuilder = this.typeCreators.get(type);
@ -426,48 +426,48 @@ public class TemplatedPanel extends Panel
this.typeIndex.put(type, itemSlot.nextItemSlot());
// Try to get next object.
PanelItem item = buttonBuilder.apply(record, itemSlot);
return item == null ? this.makeFallBack(record.fallback()) : item;
PanelItem item = buttonBuilder.apply(rec, itemSlot);
return item == null ? this.makeFallBack(rec.fallback()) : item;
}
/**
* This method creates a fall back button for given record.
* @param record Record which fallback must be created.
* @param rec Record which fallback must be created.
* @return PanelItem if fallback was creates successfully, otherwise null.
*/
@Nullable
private PanelItem makeFallBack(@Nullable ItemTemplateRecord record)
private PanelItem makeFallBack(@Nullable ItemTemplateRecord rec)
{
return record == null ? null : this.makeButton(record.fallback());
return rec == null ? null : this.makeButton(rec.fallback());
}
/**
* This method translates template record into a panel item.
* @param record Record that must be translated.
* @param rec Record that must be translated.
* @return PanelItem that contains all information from the record.
*/
private PanelItem makeTemplate(PanelTemplateRecord.TemplateItem record)
private PanelItem makeTemplate(PanelTemplateRecord.TemplateItem rec)
{
PanelItemBuilder itemBuilder = new PanelItemBuilder();
// Read icon only if it is not null.
if (record.icon() != null)
if (rec.icon() != null)
{
itemBuilder.icon(record.icon().clone());
itemBuilder.icon(rec.icon().clone());
}
// Read title only if it is not null.
if (record.title() != null)
if (rec.title() != null)
{
itemBuilder.name(this.user.getTranslation(record.title()));
itemBuilder.name(this.user.getTranslation(rec.title()));
}
// Read description only if it is not null.
if (record.description() != null)
if (rec.description() != null)
{
itemBuilder.description(this.user.getTranslation(record.description()));
itemBuilder.description(this.user.getTranslation(rec.description()));
}
// Click Handlers are managed by custom addon buttons.

View File

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

View File

@ -16,7 +16,6 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.panels.Panel;
/**
* This is template object for the panel reader. It contains data that can exist in the panel.
* PanelBuilder will use this to build panel.

View File

@ -49,6 +49,14 @@ public class TemplateReader
private static final String TYPE = "type";
/**
* Utility classes, which are collections of static members, are not meant to be instantiated.
* Even abstract utility classes, which can be extended, should not have public constructors.
* Java adds an implicit public constructor to every class which does not define at least one explicitly.
* Hence, at least one non-public constructor should be defined.
*/
private TemplateReader() {}
/**
* Read template panel panel template record.
*
@ -95,7 +103,7 @@ public class TemplateReader
return TemplateReader.loadedPanels.get(panelKey);
}
PanelTemplateRecord record;
PanelTemplateRecord rec;
try
{
@ -103,16 +111,16 @@ public class TemplateReader
YamlConfiguration config = new YamlConfiguration();
config.load(file);
// Read panel
record = readPanelTemplate(config.getConfigurationSection(panelName));
rec = readPanelTemplate(config.getConfigurationSection(panelName));
// Put panel into memory
TemplateReader.loadedPanels.put(panelKey, record);
TemplateReader.loadedPanels.put(panelKey, rec);
}
catch (IOException | InvalidConfigurationException e)
{
record = null;
rec = null;
}
return record;
return rec;
}

View File

@ -1,5 +1,7 @@
package world.bentobox.bentobox.api.user;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@ -16,6 +18,7 @@ import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.Particle;
import org.bukkit.Particle.DustTransition;
import org.bukkit.Vibration;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
@ -53,6 +56,26 @@ public class User implements MetaDataAble {
private static final Map<UUID, User> users = new HashMap<>();
// Used for particle validation
private static final Map<Particle, Class<?>> VALIDATION_CHECK;
static {
Map<Particle, Class<?>> v = new EnumMap<>(Particle.class);
v.put(Particle.REDSTONE, Particle.DustOptions.class);
v.put(Particle.ITEM_CRACK, ItemStack.class);
v.put(Particle.BLOCK_CRACK, BlockData.class);
v.put(Particle.BLOCK_DUST, BlockData.class);
v.put(Particle.FALLING_DUST, BlockData.class);
v.put(Particle.BLOCK_MARKER, BlockData.class);
v.put(Particle.DUST_COLOR_TRANSITION, DustTransition.class);
v.put(Particle.VIBRATION, Vibration.class);
v.put(Particle.SCULK_CHARGE, Float.class);
v.put(Particle.SHRIEK, Integer.class);
v.put(Particle.LEGACY_BLOCK_CRACK, BlockData.class);
v.put(Particle.LEGACY_BLOCK_DUST, BlockData.class);
v.put(Particle.LEGACY_FALLING_DUST, BlockData.class);
VALIDATION_CHECK = Collections.unmodifiableMap(v);
}
/**
* Clears all users from the user list
*/
@ -88,7 +111,8 @@ public class User implements MetaDataAble {
}
/**
* Gets an instance of User from a UUID.
* Gets an instance of User from a UUID. This will always return a user object.
* If the player is offline then the getPlayer value will be null.
* @param uuid - UUID
* @return user - user
*/
@ -97,7 +121,7 @@ public class User implements MetaDataAble {
if (users.containsKey(uuid)) {
return users.get(uuid);
}
// Return player, or null if they are not online
// Return a user instance
return new User(uuid);
}
@ -597,73 +621,18 @@ public class User implements MetaDataAble {
* @param y Y coordinate of the particle to display.
* @param z Z coordinate of the particle to display.
*/
public void spawnParticle(Particle particle, Object dustOptions, double x, double y, double z)
public void spawnParticle(Particle particle, @Nullable Object dustOptions, double x, double y, double z)
{
// Improve particle validation.
switch (particle)
{
case REDSTONE ->
{
if (!(dustOptions instanceof Particle.DustOptions))
{
throw new IllegalArgumentException("A non-null Particle.DustOptions must be provided when using Particle.REDSTONE as particle.");
}
}
case ITEM_CRACK ->
{
if (!(dustOptions instanceof ItemStack))
{
throw new IllegalArgumentException("A non-null ItemStack must be provided when using Particle.ITEM_CRACK as particle.");
}
}
case BLOCK_CRACK, BLOCK_DUST, FALLING_DUST, BLOCK_MARKER ->
{
if (!(dustOptions instanceof BlockData))
{
throw new IllegalArgumentException("A non-null BlockData must be provided when using Particle." + particle + " as particle.");
}
}
case DUST_COLOR_TRANSITION ->
{
if (!(dustOptions instanceof Particle.DustTransition))
{
throw new IllegalArgumentException("A non-null Particle.DustTransition must be provided when using Particle.DUST_COLOR_TRANSITION as particle.");
}
}
case VIBRATION ->
{
if (!(dustOptions instanceof Vibration))
{
throw new IllegalArgumentException("A non-null Vibration must be provided when using Particle.VIBRATION as particle.");
}
}
case SCULK_CHARGE ->
{
if (!(dustOptions instanceof Float))
{
throw new IllegalArgumentException("A non-null Float must be provided when using Particle.SCULK_CHARGE as particle.");
}
}
case SHRIEK ->
{
if (!(dustOptions instanceof Integer))
{
throw new IllegalArgumentException("A non-null Integer must be provided when using Particle.SHRIEK as particle.");
}
}
case LEGACY_BLOCK_CRACK, LEGACY_BLOCK_DUST, LEGACY_FALLING_DUST ->
{
if (!(dustOptions instanceof BlockData))
{
throw new IllegalArgumentException("A non-null MaterialData must be provided when using Particle." + particle + " as particle.");
}
}
default -> throw new IllegalArgumentException("Unexpected value: " + particle);
Class<?> expectedClass = VALIDATION_CHECK.get(dustOptions);
if (expectedClass == null) throw new IllegalArgumentException("Unexpected value: " + particle);
if (!(expectedClass.isInstance(dustOptions))) {
throw new IllegalArgumentException("A non-null " + expectedClass.getName() + " must be provided when using Particle." + particle + " as particle.");
}
// Check if this particle is beyond the viewing distance of the server
if (this.player != null &&
this.player.getLocation().toVector().distanceSquared(new Vector(x, y, z)) <
if (this.player != null
&& this.player.getLocation().toVector().distanceSquared(new Vector(x, y, z)) <
(Bukkit.getServer().getViewDistance() * 256 * Bukkit.getServer().getViewDistance()))
{
if (particle.equals(Particle.REDSTONE))

View File

@ -287,11 +287,9 @@ public class BlueprintClipboard {
if (entity instanceof Villager villager) {
setVillager(villager, bpe);
}
if (entity instanceof Colorable c) {
if (c.getColor() != null) {
if (entity instanceof Colorable c && c.getColor() != null) {
bpe.setColor(c.getColor());
}
}
if (entity instanceof Tameable) {
bpe.setTamed(((Tameable)entity).isTamed());
}

View File

@ -229,13 +229,13 @@ public class BlueprintPaster {
} else {
pasteState = PasteState.DONE;
String world = switch (location.getWorld().getEnvironment()) {
String dimensionType = switch (location.getWorld().getEnvironment()) {
case NETHER -> owner.map(user -> user.getTranslation("general.worlds.nether")).orElse("");
case THE_END -> owner.map(user -> user.getTranslation("general.worlds.the-end")).orElse("");
default -> owner.map(user -> user.getTranslation("general.worlds.overworld")).orElse("");
};
owner.ifPresent(user -> user.sendMessage("commands.island.create.pasting.dimension-done", "[world]", world));
owner.ifPresent(user -> user.sendMessage("commands.island.create.pasting.dimension-done", "[world]", dimensionType));
}
}
else if (pasteState.equals(PasteState.DONE)) {

View File

@ -102,7 +102,8 @@ public class Database<T> {
* Save object. Saving may be done async or sync, depending on the underlying database.
* @param instance to save
* @return true - always.
* @deprecated As of 1.13.0. Use {@link #saveObjectAsync(Object)}.
* @deprecated Use {@link #saveObjectAsync(Object)}.
* @since 1.13.0
*/
@Deprecated
public boolean saveObject(T instance) {

View File

@ -41,25 +41,33 @@ public class DatabaseConnectionSettingsImpl {
* @param databaseName - database name
* @param username - username
* @param password - password
* @param useSSL - whether to use SSL or not
* @param maxConnections - max number of connections
* @param extraProperties Map with extra properties.
*/
public DatabaseConnectionSettingsImpl(String host,
public record DatabaseSettings(String host,
int port,
String databaseName,
String username,
String password,
boolean useSSL,
int maxConnections,
Map<String, String> extraProperties)
Map<String, String> extraProperties) {}
/**
* Hosts database settings
* @param settings - database settings see {@link DatabaseSettings}
*/
public DatabaseConnectionSettingsImpl(DatabaseSettings settings)
{
this.host = host;
this.port = port;
this.databaseName = databaseName;
this.username = username;
this.password = password;
this.useSSL = useSSL;
this.maxConnections = maxConnections;
this.extraProperties = extraProperties;
this.host = settings.host;
this.port = settings.port;
this.databaseName = settings.databaseName;
this.username = settings.username;
this.password = settings.password;
this.useSSL = settings.useSSL;
this.maxConnections = settings.maxConnections;
this.extraProperties = settings.extraProperties;
}
@ -81,7 +89,7 @@ public class DatabaseConnectionSettingsImpl {
boolean useSSL,
int maxConnections)
{
this(host, port, databaseName, username, password, useSSL, maxConnections, Collections.emptyMap());
this(new DatabaseSettings(host, port, databaseName, username, password, useSSL, maxConnections, Collections.emptyMap()));
}
@ -101,7 +109,7 @@ public class DatabaseConnectionSettingsImpl {
String password,
boolean useSSL)
{
this(host, port, databaseName, username, password, useSSL, 0, Collections.emptyMap());
this(new DatabaseSettings(host, port, databaseName, username, password, useSSL, 0, Collections.emptyMap()));
}

View File

@ -166,6 +166,20 @@ public class SQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T>
if (json != null)
{
getGsonResultSet(gson, json, list);
}
}
}
catch (Exception e)
{
this.plugin.logError(COULD_NOT_LOAD_OBJECTS + e.getMessage());
}
return list;
}
private void getGsonResultSet(Gson gson, String json, List<T> list) {
try
{
T gsonResult = gson.fromJson(json, this.dataObject);
@ -180,15 +194,7 @@ public class SQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T>
this.plugin.logError(COULD_NOT_LOAD_OBJECT + ex.getMessage());
this.plugin.logError(json);
}
}
}
}
catch (Exception e)
{
this.plugin.logError(COULD_NOT_LOAD_OBJECTS + e.getMessage());
}
return list;
}
@ -198,12 +204,30 @@ public class SQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T>
@Override
public T loadObject(@NonNull String uniqueId)
{
T result = null;
try (Connection connection = this.dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(this.sqlConfig.getLoadObjectSQL()))
{
// UniqueId needs to be placed in quotes?
preparedStatement.setString(1, this.sqlConfig.isUseQuotes() ? "\"" + uniqueId + "\"" : uniqueId);
result = getObject(uniqueId, preparedStatement);
}
catch (SQLException e)
{
this.plugin.logError(COULD_NOT_LOAD_OBJECT + uniqueId + " " + e.getMessage());
}
return result;
}
/**
* 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
*/
private T getObject(@NonNull String uniqueId, PreparedStatement preparedStatement) {
try (ResultSet resultSet = preparedStatement.executeQuery())
{
if (resultSet.next())
@ -217,12 +241,6 @@ public class SQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T>
{
this.plugin.logError(COULD_NOT_LOAD_OBJECT + uniqueId + " " + e.getMessage());
}
}
catch (SQLException e)
{
this.plugin.logError(COULD_NOT_LOAD_OBJECT + uniqueId + " " + e.getMessage());
}
return null;
}

View File

@ -17,7 +17,7 @@ public class MariaDBDatabase implements DatabaseSetup
private MariaDBDatabaseConnector connector;
/*
/**
* {@inheritDoc}
*/
@Override

View File

@ -13,7 +13,7 @@ public class MySQLDatabase implements DatabaseSetup
private MySQLDatabaseConnector connector;
/*
/**
* {@inheritDoc}
*/
@Override

View File

@ -17,7 +17,7 @@ public class PostgreSQLDatabase implements DatabaseSetup
PostgreSQLDatabaseConnector connector;
/*
/**
* {@inheritDoc}
*/
@Override

View File

@ -55,7 +55,7 @@ public class PostgreSQLDatabaseHandler<T> extends SQLDatabaseHandler<T>
}
/*
/**
* {@inheritDoc}
*/
@Override

View File

@ -24,7 +24,7 @@ public class SQLiteDatabase implements DatabaseSetup
private SQLiteDatabaseConnector connector;
/*
/**
* {@inheritDoc}
*/
@Override

View File

@ -87,6 +87,18 @@ public class SQLiteDatabaseHandler<T> extends SQLDatabaseHandler<T>
String sql = this.getSqlConfig().getRenameTableSQL().replace("[oldTableName]",
this.getSqlConfig().getOldTableName().replace("[tableName]", this.getSqlConfig().getTableName()));
executeStatement(sql);
}
}
catch (Exception ex)
{
this.plugin.logError("Could not check if " + getSqlConfig().getOldTableName() + " exists for data object " +
this.dataObject.getCanonicalName() + " " + ex.getMessage());
}
}
private void executeStatement(String sql) {
try (Connection connection = this.dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql))
{
@ -98,13 +110,6 @@ public class SQLiteDatabaseHandler<T> extends SQLDatabaseHandler<T>
this.dataObject.getCanonicalName() + " " + e.getMessage());
}
}
}
catch (Exception ex)
{
this.plugin.logError("Could not check if " + getSqlConfig().getOldTableName() + " exists for data object " +
this.dataObject.getCanonicalName() + " " + ex.getMessage());
}
}
@Override

View File

@ -100,11 +100,14 @@ public class YamlDatabaseConnector implements DatabaseConnector {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(yamlFile), StandardCharsets.UTF_8))){
File temp = File.createTempFile("file", ".tmp", yamlFile.getParentFile());
writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp), StandardCharsets.UTF_8));
for (String line; (line = reader.readLine()) != null;) {
String line = reader.readLine();
while (line != null) {
line = line.replace("!!java.util.UUID", "");
writer.println(line);
line = reader.readLine();
}
if (yamlFile.delete() && !temp.renameTo(yamlFile)) {
Files.delete(yamlFile.toPath());
if (!temp.renameTo(yamlFile)) {
plugin.logError("Could not rename fixed Island object. Are the writing permissions correctly setup?");
}
} catch (Exception e) {

View File

@ -1,7 +1,5 @@
package world.bentobox.bentobox.hooks;
import java.util.logging.Level;
import org.bukkit.Material;
import org.bukkit.World;
@ -58,9 +56,8 @@ public class MyWorldsHook extends Hook implements WorldManagementHook {
.getMethod("setChunkGeneratorName", String.class)
.invoke(worldConfig, name);
*/
} catch (Throwable t) {
BentoBox.getInstance().getLogger().log(Level.SEVERE,
"Failed to register world " + world.getName() + " with MyWorlds", t);
} catch (Exception t) {
BentoBox.getInstance().logError("Failed to register world " + world.getName() + " with MyWorlds " + t.getMessage());
}
}

View File

@ -70,12 +70,12 @@ public class PlaceholderAPIHook extends PlaceholderHook {
@Override
public void registerPlaceholder(@NonNull Addon addon, @NonNull String placeholder, @NonNull PlaceholderReplacer replacer) {
// Check if the addon expansion does not exist
if (!addonsExpansions.containsKey(addon)) {
addonsExpansions.computeIfAbsent(addon, k -> {
AddonPlaceholderExpansion addonPlaceholderExpansion = new AddonPlaceholderExpansion(addon);
addonPlaceholderExpansion.register();
addonsExpansions.put(addon, addonPlaceholderExpansion);
this.addonPlaceholders.computeIfAbsent(addon, k -> new HashSet<>()).add(placeholder);
}
this.addonPlaceholders.computeIfAbsent(addon, kk -> new HashSet<>()).add(placeholder);
return addonPlaceholderExpansion;
});
addonsExpansions.get(addon).registerPlaceholder(placeholder, replacer);
}

View File

@ -50,7 +50,8 @@ public class JoinLeaveListener implements Listener {
User.removePlayer(event.getPlayer());
User user = User.getInstance(event.getPlayer());
if (user == null || user.getUniqueId() == null) {
if (!user.isPlayer() || user.getUniqueId() == null) {
// This should never be the case, but it might be caused by some fake player plugins
return;
}
UUID playerUUID = event.getPlayer().getUniqueId();

View File

@ -18,7 +18,9 @@ import world.bentobox.bentobox.database.objects.Island;
* Abstracts PlayerPortalEvent and EntityPortalEvent
* @author tastybento
* @deprecated replaced not used in new listeners.
* @since 1.12.1
*/
@Deprecated
public class PlayerEntityPortalEvent {
private final EntityPortalEvent epe;

View File

@ -43,6 +43,7 @@ import world.bentobox.bentobox.util.teleport.SafeSpotTeleport;
* @deprecated replaced by better listeners.
* @see world.bentobox.bentobox.listeners.teleports.PlayerTeleportListener
* @see world.bentobox.bentobox.listeners.teleports.EntityTeleportListener
* @since 1.12.1
*/
@Deprecated
public class PortalTeleportationListener implements Listener {
@ -268,9 +269,8 @@ public class PortalTeleportationListener implements Listener {
return null;
}
Location toLocation = e.getIsland().map(island -> island.getSpawnPoint(env)).
orElse(e.getFrom().toVector().toLocation(toWorld));
Location toLocation = Objects.requireNonNullElse(e.getIsland().map(island -> island.getSpawnPoint(env)).
orElse(e.getFrom().toVector().toLocation(toWorld)), e.getFrom().toVector().toLocation(toWorld));
// Limit Y to the min/max world height.
toLocation.setY(Math.max(Math.min(toLocation.getY(), toWorld.getMaxHeight()), toWorld.getMinHeight()));

View File

@ -122,14 +122,12 @@ public class BreakBlocksListener extends FlagListener {
if (e.getDamager() instanceof Player p) {
// Check the break blocks flag
notAllowed(e, p, e.getEntity().getLocation());
} else if (e.getDamager() instanceof Projectile p) {
// Find out who fired the arrow
if (p.getShooter() instanceof Player && notAllowed(e, (Player)p.getShooter(), e.getEntity().getLocation())) {
} else if (e.getDamager() instanceof Projectile p && // Find out who fired the arrow
p.getShooter() instanceof Player player && notAllowed(e, player, e.getEntity().getLocation())) {
e.getEntity().setFireTicks(0);
p.setFireTicks(0);
}
}
}
private boolean notAllowed(EntityDamageByEntityEvent e, Player player, Location location) {
if (!checkIsland(e, player, location, Flags.BREAK_BLOCKS)) return true;

View File

@ -18,12 +18,11 @@ public class ElytraListener extends FlagListener {
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onGlide(EntityToggleGlideEvent e) {
if (e.getEntity() instanceof Player player) {
if (!checkIsland(e, player, player.getLocation(), Flags.ELYTRA)) {
if (e.getEntity() instanceof Player player
&& !checkIsland(e, player, player.getLocation(), Flags.ELYTRA)) {
player.setGliding(false);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onGliding(PlayerTeleportEvent e) {

View File

@ -76,13 +76,11 @@ public class HurtingListener extends FlagListener {
// Get the attacker
if (damager instanceof Player) {
checkIsland(e, (Player)damager, damager.getLocation(), flag);
} else if (damager instanceof Projectile p) {
// Find out who fired the projectile
if (p.getShooter() instanceof Player && !checkIsland(e, (Player)p.getShooter(), damager.getLocation(), flag)) {
} else if (damager instanceof Projectile p && // Find out who fired the projectile
p.getShooter() instanceof Player player && !checkIsland(e, player, damager.getLocation(), flag)) {
e.getEntity().setFireTicks(0);
}
}
}
/**
* Handle attacks with a fishing rod

View File

@ -49,16 +49,14 @@ public class TNTListener extends FlagListener {
return;
}
// Stop TNT from being damaged if it is being caused by a visitor with a flaming arrow
if (e.getEntity() instanceof Projectile projectile) {
// Find out who fired it
if (projectile.getShooter() instanceof Player shooter && projectile.getFireTicks() > 0
if (e.getEntity() instanceof Projectile projectile && // Find out who fired it
projectile.getShooter() instanceof Player shooter && projectile.getFireTicks() > 0
&& !checkIsland(e, shooter, e.getBlock().getLocation(), Flags.TNT_PRIMING)) {
// Remove the arrow
projectile.remove();
e.setCancelled(true);
}
}
}
/**
* Protect against priming of TNT unless TNT priming is allowed

View File

@ -41,15 +41,16 @@ public class CreeperListener extends FlagListener {
}
// Check for griefing
Creeper creeper = (Creeper)e.getEntity();
if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld()) && creeper.getTarget() instanceof Player target && target != null) {
if (!getIslands().locationIsOnIsland(target, e.getLocation())) {
if (!Flags.CREEPER_GRIEFING.isSetForWorld(e.getLocation().getWorld())
&& creeper.getTarget() instanceof Player target // if getTarget is null this won'e be true
&& !getIslands().locationIsOnIsland(target, e.getLocation())) {
User user = User.getInstance(target);
user.notify("protection.protected", TextVariables.DESCRIPTION, user.getTranslation(Flags.CREEPER_GRIEFING.getHintReference()));
e.setCancelled(true);
e.blockList().clear();
}
}
}
/**
* Prevent entities being damaged by explosion

View File

@ -69,13 +69,13 @@ public class GeoLimitMobsListener extends FlagListener {
public void onProjectileExplode(final ExplosionPrimeEvent e) {
if (e.getEntity() instanceof Projectile && getIWM().inWorld(e.getEntity().getLocation())) {
ProjectileSource source = ((Projectile)e.getEntity()).getShooter();
if (source instanceof Entity shooter) {
if (mobSpawnTracker.containsKey(shooter)
if (source instanceof Entity shooter
&& mobSpawnTracker.containsKey(shooter)
&& !mobSpawnTracker.get(shooter).onIsland(e.getEntity().getLocation())) {
e.getEntity().remove();
e.setCancelled(true);
}
}
}
}
}

View File

@ -10,6 +10,7 @@ package world.bentobox.bentobox.listeners.teleports;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@ -46,9 +47,9 @@ public abstract class AbstractTeleportListener
}
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Section: Methods
// ---------------------------------------------------------------------
/**
@ -240,9 +241,9 @@ public abstract class AbstractTeleportListener
if (!this.isMakePortals(fromWorld, environment))
{
toLocation = this.getIsland(fromLocation).
toLocation = Objects.requireNonNullElse(this.getIsland(fromLocation).
map(island -> island.getSpawnPoint(toWorld.getEnvironment())).
orElse(toLocation);
orElse(toLocation), toLocation);
}
// Limit Y to the min/max world height.
@ -322,9 +323,9 @@ public abstract class AbstractTeleportListener
}
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**

View File

@ -390,12 +390,14 @@ public final class Flags {
// Mob spawning
/**
* @deprecated as of 1.14.0, see {@link #ANIMAL_NATURAL_SPAWN} and {@link #ANIMAL_SPAWNERS_SPAWN}.
* @deprecated see {@link #ANIMAL_NATURAL_SPAWN} and {@link #ANIMAL_SPAWNERS_SPAWN}.
* @since 1.14.0
*/
@Deprecated
public static final Flag ANIMAL_SPAWN = new Flag.Builder("ANIMAL_SPAWN", Material.APPLE).defaultSetting(true).type(Type.SETTING).build();
/**
* @deprecated as of 1.14.0, see {@link #MONSTER_NATURAL_SPAWN} and {@link #MONSTER_SPAWNERS_SPAWN}.
* @deprecated see {@link #MONSTER_NATURAL_SPAWN} and {@link #MONSTER_SPAWNERS_SPAWN}.
* @since 1.14.0
*/
@Deprecated
public static final Flag MONSTER_SPAWN = new Flag.Builder("MONSTER_SPAWN", Material.SPAWNER).defaultSetting(true).type(Type.SETTING).build();

View File

@ -21,7 +21,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
@ -341,8 +340,8 @@ public class AddonsManager {
plugin.logWarning("NOTE: DO NOT report this as a bug from BentoBox.");
StringBuilder a = new StringBuilder();
addon.getDescription().getAuthors().forEach(author -> a.append(author).append(" "));
plugin.getLogger().log(Level.SEVERE, "Please report this stack trace to the addon's author(s): " + a, e);
plugin.logError("Please report this stack trace to the addon's author(s): " + a);
plugin.logStacktrace(e);
}
private boolean isAddonCompatibleWithBentoBox(@NonNull Addon addon) {

View File

@ -1,65 +0,0 @@
package world.bentobox.bentobox.managers;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.placeholders.PlaceholderReplacer;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.GameModePlaceholder;
/**
* Registers default placeholders for all GameModes. Will not overwrite any that the gamemode addon itself implements.
* @author tastybento
* @since 1.4.0
* @deprecated As of 1.5.0, for removal.
*/
@Deprecated
public class GameModePlaceholderManager {
private final BentoBox plugin;
public GameModePlaceholderManager(BentoBox plugin) {
this.plugin = plugin;
}
/**
* @since 1.4.0
* @deprecated As of 1.5.0, for removal. Use {@link PlaceholdersManager#registerDefaultPlaceholders(GameModeAddon)} instead.
*/
@Deprecated
public void registerGameModePlaceholders(@NonNull GameModeAddon addon) {
plugin.getPlaceholdersManager().registerDefaultPlaceholders(addon);
}
}
/**
* @author tastybento
* @since 1.4.0
*/
class DefaultPlaceholder implements PlaceholderReplacer {
private final GameModeAddon addon;
private final GameModePlaceholder type;
public DefaultPlaceholder(GameModeAddon addon, GameModePlaceholder type) {
this.addon = addon;
this.type = type;
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.placeholders.PlaceholderReplacer#onReplace(world.bentobox.bentobox.api.user.User)
*/
@NonNull
@Override
public String onReplace(@Nullable User user) {
if (user == null) {
return "";
}
Island island = addon.getIslands().getIsland(addon.getOverWorld(), user);
return type.getReplacer().onReplace(addon, user, island);
}
}

View File

@ -22,11 +22,11 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.TreeSpecies;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Boat.Type;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -68,13 +68,13 @@ public class IslandsManager {
private final BentoBox plugin;
// Tree species to boat material map
private static final Map<TreeSpecies, Material> TREE_TO_BOAT = ImmutableMap.<TreeSpecies, Material>builder().
put(TreeSpecies.ACACIA, Material.ACACIA_BOAT).
put(TreeSpecies.BIRCH, Material.BIRCH_BOAT).
put(TreeSpecies.DARK_OAK, Material.DARK_OAK_BOAT).
put(TreeSpecies.JUNGLE, Material.JUNGLE_BOAT).
put(TreeSpecies.GENERIC, Material.OAK_BOAT).
put(TreeSpecies.REDWOOD, Material.SPRUCE_BOAT).build();
private static final Map<Type, Material> TREE_TO_BOAT = ImmutableMap.<Type, Material>builder().
put(Type.ACACIA, Material.ACACIA_BOAT).
put(Type.BIRCH, Material.BIRCH_BOAT).
put(Type.DARK_OAK, Material.DARK_OAK_BOAT).
put(Type.JUNGLE, Material.JUNGLE_BOAT).
put(Type.OAK, Material.OAK_BOAT).
put(Type.SPRUCE, Material.SPRUCE_BOAT).build();
/**
* One island can be spawn, this is the one - otherwise, this value is null
@ -1036,22 +1036,6 @@ public class IslandsManager {
return homeTeleportAsync(world, player, "", false);
}
/**
* Teleport player to a home location. If one cannot be found a search is done to
* find a safe place.
*
* @param world - world to check
* @param player - the player
* @param number - a number - home location to do to
* @return CompletableFuture true if successful, false if not
* @since 1.14.0
* @deprecated Use {@link #homeTeleportAsync(World, Player, String)}
*/
@Deprecated
public CompletableFuture<Boolean> homeTeleportAsync(@NonNull World world, @NonNull Player player, int number) {
return homeTeleportAsync(world, player, String.valueOf(number), false);
}
/**
* Teleport player to a home location. If one cannot be found a search is done to
* find a safe place.
@ -1095,7 +1079,7 @@ public class IslandsManager {
player.leaveVehicle();
// Remove the boat so they don't lie around everywhere
boat.remove();
player.getInventory().addItem(new ItemStack(TREE_TO_BOAT.getOrDefault(((Boat) boat).getWoodType(), Material.OAK_BOAT)));
player.getInventory().addItem(new ItemStack(TREE_TO_BOAT.getOrDefault(((Boat) boat).getBoatType(), Material.OAK_BOAT)));
player.updateInventory();
}
}
@ -1219,7 +1203,7 @@ public class IslandsManager {
player.leaveVehicle();
// Remove the boat so they don't lie around everywhere
boat.remove();
Material boatMat = Material.getMaterial(((Boat) boat).getWoodType() + "_BOAT");
Material boatMat = Material.getMaterial(((Boat) boat).getType() + "_BOAT");
if (boatMat == null) {
boatMat = Material.OAK_BOAT;
}

View File

@ -205,6 +205,14 @@ public class LocalesManager {
File targetFile = new File(localeDir, name.substring(Math.max(lastIndex, 0)));
copyFile(name, targetFile);
// Update the locale file if it exists already
updateFile(name, targetFile);
}
} catch (IOException e) {
plugin.logError("Could not copy locale files from jar " + e.getMessage());
}
}
private void updateFile(String name, File targetFile) throws IOException {
try (InputStreamReader in = new InputStreamReader(plugin.getResource(name))) {
YamlConfiguration jarLocale = new YamlConfiguration();
jarLocale.load(in);
@ -221,11 +229,6 @@ public class LocalesManager {
} catch (InvalidConfigurationException e) {
plugin.logError("Could not update locale files from jar " + e.getMessage());
}
}
} catch (IOException e) {
plugin.logError("Could not copy locale files from jar " + e.getMessage());
}
}
/**

View File

@ -11,6 +11,8 @@ import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.placeholders.PlaceholderReplacer;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.hooks.placeholders.PlaceholderAPIHook;
import world.bentobox.bentobox.lists.GameModePlaceholder;
@ -133,4 +135,30 @@ public class PlaceholdersManager {
getPlaceholderAPIHook().ifPresent(PlaceholderAPIHook::unregisterAll);
}
/**
* Default placeholder
*
*/
class DefaultPlaceholder implements PlaceholderReplacer {
private final GameModeAddon addon;
private final GameModePlaceholder type;
public DefaultPlaceholder(GameModeAddon addon, GameModePlaceholder type) {
this.addon = addon;
this.type = type;
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.placeholders.PlaceholderReplacer#onReplace(world.bentobox.bentobox.api.user.User)
*/
@NonNull
@Override
public String onReplace(@Nullable User user) {
if (user == null) {
return "";
}
Island island = addon.getIslands().getIsland(addon.getOverWorld(), user);
return type.getReplacer().onReplace(addon, user, island);
}
}
}

View File

@ -194,7 +194,9 @@ public class NewIsland {
switch (reason) {
case CREATE -> name = ((IslandCreateEvent) event).getBlueprintBundle().getUniqueId();
case RESET -> name = ((IslandResetEvent) event).getBlueprintBundle().getUniqueId();
default -> {}
default -> {
// Do nothing of other cases
}
}
// Run task to run after creating the island in one tick if island is not being pasted
@ -311,16 +313,9 @@ public class NewIsland {
}
// Fire exit event
Reason reasonDone = Reason.CREATED;
switch (reason) {
case CREATE -> reasonDone = Reason.CREATED;
case RESET -> reasonDone = Reason.RESETTED;
default -> {
}
}
IslandEvent.builder()
.involvedPlayer(user.getUniqueId())
.reason(reasonDone)
.reason(reason == Reason.RESET ? Reason.RESETTED : Reason.CREATED)
.island(island)
.location(island.getCenter())
.oldIsland(oldIsland)

View File

@ -2,7 +2,6 @@ package world.bentobox.bentobox.panels;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@ -19,8 +18,6 @@ import org.bukkit.conversations.ConversationFactory;
import org.bukkit.event.inventory.ClickType;
import org.eclipse.jdt.annotation.NonNull;
import com.google.common.collect.ImmutableMap;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.localization.TextVariables;
@ -76,8 +73,8 @@ public class BlueprintManagementPanel {
endBlueprint = new Blueprint().setIcon(Material.YELLOW_STAINED_GLASS_PANE)
.setName(user.getTranslation("general.worlds.the-end"))
.setDescription(t(INSTRUCTION));
slotToEnvironment = ImmutableMap.of(3, World.Environment.NORMAL, 5, World.Environment.NETHER, 7, World.Environment.THE_END);
environmentToBlueprint = ImmutableMap.of(World.Environment.NORMAL, normalBlueprint, World.Environment.NETHER, netherBlueprint, World.Environment.THE_END, endBlueprint);
slotToEnvironment = Map.of(3, World.Environment.NORMAL, 5, World.Environment.NETHER, 7, World.Environment.THE_END);
environmentToBlueprint = Map.of(World.Environment.NORMAL, normalBlueprint, World.Environment.NETHER, netherBlueprint, World.Environment.THE_END, endBlueprint);
}
private String t(String t) {

View File

@ -47,6 +47,8 @@ public class DefaultPasteUtil {
plugin = BentoBox.getInstance();
}
private DefaultPasteUtil() {} // private constructor to hide the implicit public one.
/**
* Set the block to the location
*

View File

@ -35,6 +35,7 @@ import world.bentobox.bentobox.BentoBox;
*/
public class ItemParser {
private ItemParser() {} // private constructor to hide the implicit public one.
/**
* Parse given string to ItemStack.
* @param text String value of item stack.
@ -110,9 +111,9 @@ public class ItemParser {
returnValue = parseItemDurabilityAndQuantity(part);
}
if (returnValue != null) {
if (returnValue != null
// If wrapper is just for code-style null-pointer checks.
if (customModelData != null) {
&& customModelData != null) {
// We have custom data model. Now assign it to the item-stack.
ItemMeta itemMeta = returnValue.getItemMeta();
@ -123,7 +124,7 @@ public class ItemParser {
returnValue.setItemMeta(itemMeta);
}
}
}
} catch (Exception exception) {
BentoBox.getInstance().logError("Could not parse item " + text + " " + exception.getLocalizedMessage());
returnValue = defaultItemStack;
@ -309,7 +310,9 @@ public class ItemParser {
// Apply new meta to the item.
playerHead.setItemMeta(meta);
} catch (Exception ignored) {}
} catch (Exception ignored) {
// Ignored
}
return playerHead;
}

View File

@ -74,22 +74,20 @@ public class ClosestSafeSpotTeleport
*/
private void checkLocation()
{
if (this.plugin.getIslandsManager().isSafeLocation(this.location))
{
if (!this.portal)
if (!this.portal && this.plugin.getIslandsManager().isSafeLocation(this.location))
{
// If this is not a portal teleport, then go to the safe location immediately
this.teleportEntity(this.location);
// Position search is completed. Quit faster.
return;
}
}
// Players should not be teleported outside protection range if they already are in it.
this.boundingBox = this.plugin.getIslandsManager().getIslandAt(this.location).
map(Island::getProtectionBoundingBox).
orElseGet(() -> {
int protectionRange = this.plugin.getIWM().getIslandProtectionRange(this.world);
double protectionRange = this.plugin.getIWM().getIslandProtectionRange(this.world);
return new BoundingBox(this.location.getBlockX() - protectionRange,
Math.max(this.world.getMinHeight(), this.location.getBlockY() - protectionRange),
@ -174,11 +172,9 @@ public class ClosestSafeSpotTeleport
int x = this.location.getBlockX();
int z = this.location.getBlockZ();
int range = 20;
// Normalize block coordinates to chunk coordinates and add extra 1 for visiting.
int numberOfChunks = (((x + range) >> 4) - ((x - range) >> 4) + 1) *
(((z + range) >> 4) - ((z - range) >> 4) + 1);
int numberOfChunks = (((x + SCAN_RANGE) >> 4) - ((x - SCAN_RANGE) >> 4) + 1) *
(((z + SCAN_RANGE) >> 4) - ((z - SCAN_RANGE) >> 4) + 1);
// Ideally it would be if visitor switch from clockwise to counter-clockwise if X % 16 < 8 and
// up to down if Z % 16 < 8.
@ -495,9 +491,9 @@ public class ClosestSafeSpotTeleport
}
// ---------------------------------------------------------------------
// Section: Builder
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Section: Builder
// ---------------------------------------------------------------------
public static class Builder
@ -775,9 +771,9 @@ public class ClosestSafeSpotTeleport
}
// ---------------------------------------------------------------------
// Section: Constants
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Section: Constants
// ---------------------------------------------------------------------
/**
* This comparator sorts position data based in order:
@ -796,9 +792,15 @@ public class ClosestSafeSpotTeleport
*/
private static final long CHUNK_LOAD_SPEED = 1;
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* Range to scan
*/
private static final int SCAN_RANGE = 20;
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
/**
* BentoBox plugin instance.

View File

@ -366,19 +366,6 @@ public class SafeSpotTeleport {
return this;
}
/**
* Set the home number to this number
*
* @param homeNumber home number
* @return Builder
* @deprecated use {@link #homeName}
*/
@Deprecated
public Builder homeNumber(int homeNumber) {
this.homeNumber = homeNumber;
return this;
}
/**
* Set the home name
*

View File

@ -7,6 +7,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -380,7 +381,7 @@ public class PortalTeleportationListenerTest {
// Event is canceled
assertTrue(e.isCancelled());
// If nether islands, then to = from but in nether
verify(from).toVector();
verify(from, times(2)).toVector();
// Do not go to spawn
verify(nether, never()).getSpawnLocation();
}
@ -416,7 +417,7 @@ public class PortalTeleportationListenerTest {
// Verify
assertTrue(e.isCancelled());
// If nether islands, then to = from but in nether
verify(from).toVector();
verify(from, times(2)).toVector();
// Do not go to spawn
verify(nether, never()).getSpawnLocation();
}
@ -447,7 +448,7 @@ public class PortalTeleportationListenerTest {
// Verify
assertTrue(e.isCancelled());
// If nether islands, then to = from but in nether
verify(from).toVector();
verify(from, times(2)).toVector();
// Do not go to spawn
verify(nether, never()).getSpawnLocation();
}