Address some code quality reports from SonarCloud.

Most of the errors are just sanity checks, as the most of null-pointers were already checked in other ways.
This commit is contained in:
BONNe 2021-12-01 11:30:02 +02:00
parent e7b84768aa
commit 7fbffbb6d2
38 changed files with 336 additions and 343 deletions

View File

@ -19,7 +19,7 @@ import world.bentobox.challenges.utils.Utils;
public class ChallengesGlobalPlayerCommand extends CompositeCommand public class ChallengesGlobalPlayerCommand extends CompositeCommand
{ {
/** /**
* Constructor that inits command with given string. * Constructor that init command with given string.
* @param addon Challenges Addon * @param addon Challenges Addon
* @param gameModeAddons List with GameModes where challenges addon operates. * @param gameModeAddons List with GameModes where challenges addon operates.
*/ */

View File

@ -16,7 +16,7 @@ import world.bentobox.challenges.utils.Utils;
/** /**
* This command allows to complete challenges without a gui. * This command allows completing challenges without a gui.
*/ */
public class CompleteChallengeCommand extends CompositeCommand public class CompleteChallengeCommand extends CompositeCommand
{ {

View File

@ -10,11 +10,11 @@ import world.bentobox.challenges.panel.admin.AdminPanel;
public class ChallengesAdminCommand extends CompositeCommand public class ChallengesAdminCommand extends CompositeCommand
{ {
/** /**
* Admin command for challenges * Instantiates a new Challenges' admin command.
* *
* @param parent * @param addon the addon
* @param parent the parent
*/ */
public ChallengesAdminCommand(ChallengesAddon addon, CompositeCommand parent) public ChallengesAdminCommand(ChallengesAddon addon, CompositeCommand parent)
{ {

View File

@ -6,7 +6,6 @@ import java.util.List;
import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesAddon;
import world.bentobox.challenges.panel.user.GameModePanel; import world.bentobox.challenges.panel.user.GameModePanel;
import world.bentobox.challenges.utils.Constants; import world.bentobox.challenges.utils.Constants;
@ -19,7 +18,7 @@ import world.bentobox.challenges.utils.Utils;
public class ChallengesGlobalAdminCommand extends CompositeCommand public class ChallengesGlobalAdminCommand extends CompositeCommand
{ {
/** /**
* Constructor that inits command with given string. * Constructor that init command with given string.
* @param addon Challenges Addon * @param addon Challenges Addon
* @param gameModeAddons List with GameModes where challenges addon operates. * @param gameModeAddons List with GameModes where challenges addon operates.
*/ */

View File

@ -20,7 +20,7 @@ import world.bentobox.challenges.utils.Utils;
/** /**
* This command allows to complete challenges without a gui. * This command allows completing challenges without a gui.
*/ */
public class CompleteCommand extends CompositeCommand public class CompleteCommand extends CompositeCommand
{ {
@ -99,24 +99,26 @@ public class CompleteCommand extends CompositeCommand
// Add world name back at the start // Add world name back at the start
String challengeName = Utils.getGameMode(this.getWorld()) + "_" + args.get(1); String challengeName = Utils.getGameMode(this.getWorld()) + "_" + args.get(1);
Challenge challenge = this.addon.getChallengesManager().getChallenge(challengeName); Challenge challenge = this.addon.getChallengesManager().getChallenge(challengeName);
User target = User.getInstance(targetUUID);
if (challenge != null) if (challenge != null && target != null)
{ {
if (!this.addon.getChallengesManager().isChallengeComplete(targetUUID, this.getWorld(), challenge)) if (!this.addon.getChallengesManager().isChallengeComplete(targetUUID, this.getWorld(), challenge))
{ {
this.addon.getChallengesManager().setChallengeComplete( this.addon.getChallengesManager().setChallengeComplete(
targetUUID, this.getWorld(), challenge, user.getUniqueId()); targetUUID, this.getWorld(), challenge, user.getUniqueId());
if (user.isPlayer()) if (user.isPlayer())
{ {
Utils.sendMessage(user, user.getTranslation("challenges.messages.completed", Utils.sendMessage(user, user.getTranslation("challenges.messages.completed",
Constants.PARAMETER_NAME, challenge.getFriendlyName(), Constants.PARAMETER_NAME, challenge.getFriendlyName(),
Constants.PARAMETER_PLAYER, User.getInstance(targetUUID).getName())); Constants.PARAMETER_PLAYER, target.getName()));
} }
else else
{ {
this.addon.log("Challenge " + challenge.getFriendlyName() + " completed for player " + this.addon.log("Challenge " + challenge.getFriendlyName() + " completed for player " +
User.getInstance(targetUUID).getName()); target.getName());
} }
} }
else else
@ -166,23 +168,16 @@ public class CompleteCommand extends CompositeCommand
switch (size) switch (size)
{ {
case 3: case 3 ->
// Create suggestions with all challenges that is available for users. // Create suggestions with all challenges that is available for users.
returnList.addAll(Util.getOnlinePlayerList(user)); returnList.addAll(Util.getOnlinePlayerList(user));
break; case 4 ->
case 4:
// Create suggestions with all challenges that is available for users. // Create suggestions with all challenges that is available for users.
returnList.addAll(this.addon.getChallengesManager().getAllChallengesNames(this.getWorld()).stream(). returnList.addAll(this.addon.getChallengesManager().getAllChallengesNames(this.getWorld()).stream().
map(challenge -> challenge.substring(Utils.getGameMode(this.getWorld()).length() + 1)). map(challenge -> challenge.substring(Utils.getGameMode(this.getWorld()).length() + 1)).
collect(Collectors.toList())); collect(Collectors.toList()));
default ->
break;
default:
{
returnList.addAll(Collections.singletonList("help")); returnList.addAll(Collections.singletonList("help"));
break;
}
} }
return Optional.of(Util.tabLimit(returnList, lastString)); return Optional.of(Util.tabLimit(returnList, lastString));

View File

@ -9,27 +9,32 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesAddon;
public class MigrateCommand extends CompositeCommand { public class MigrateCommand extends CompositeCommand
{
/** /**
* Migrates challenges * Instantiates a new Migrate command command.
* @param addon *
* @param cmd * @param addon the addon
* @param cmd the cmd
*/ */
public MigrateCommand(Addon addon, CompositeCommand cmd) { public MigrateCommand(Addon addon, CompositeCommand cmd)
{
super(addon, cmd, "migrate"); super(addon, cmd, "migrate");
} }
@Override @Override
public boolean execute(User user, String label, List<String> args) { public boolean execute(User user, String label, List<String> args)
((ChallengesAddon)getAddon()).getChallengesManager().migrateDatabase(user, getWorld()); {
((ChallengesAddon) getAddon()).getChallengesManager().migrateDatabase(user, getWorld());
return true; return true;
} }
@Override @Override
public void setup() { public void setup()
{
this.setPermission("challenges.admin"); this.setPermission("challenges.admin");
this.setParametersHelp("challenges.commands.admin.migrate.parameters"); this.setParametersHelp("challenges.commands.admin.migrate.parameters");
this.setDescription("challenges.commands.admin.migrate.description"); this.setDescription("challenges.commands.admin.migrate.description");

View File

@ -11,13 +11,15 @@ import world.bentobox.challenges.utils.Utils;
/** /**
* This class allows to reload challenges addon. * This class allows reloading challenges addon.
*/ */
public class ReloadChallenges extends CompositeCommand public class ReloadChallenges extends CompositeCommand
{ {
/** /**
* Admin command to reloads challenges addon. * Instantiates a new Reload challenges command.
* @param parent *
* @param addon the addon
* @param parent the parent
*/ */
public ReloadChallenges(Addon addon, CompositeCommand parent) public ReloadChallenges(Addon addon, CompositeCommand parent)
{ {
@ -69,5 +71,8 @@ public class ReloadChallenges extends CompositeCommand
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private ChallengesManager manager; /**
* Addon Manager instance.
*/
private final ChallengesManager manager;
} }

View File

@ -20,7 +20,7 @@ import world.bentobox.challenges.utils.Utils;
/** /**
* This command allows to reset challenges without a gui. * This command allows resetting challenges without a gui.
*/ */
public class ResetCommand extends CompositeCommand public class ResetCommand extends CompositeCommand
{ {
@ -79,8 +79,9 @@ public class ResetCommand extends CompositeCommand
else if (!args.get(1).isEmpty()) else if (!args.get(1).isEmpty())
{ {
UUID targetUUID = this.getPlayers().getUUID(args.get(0)); UUID targetUUID = this.getPlayers().getUUID(args.get(0));
User target = User.getInstance(targetUUID);
if (targetUUID == null) if (targetUUID == null || target == null)
{ {
if (user.isPlayer()) if (user.isPlayer())
{ {
@ -104,12 +105,11 @@ public class ResetCommand extends CompositeCommand
if (user.isPlayer()) if (user.isPlayer())
{ {
Utils.sendMessage(user, user.getTranslation("challenges.messages.reset-all", Utils.sendMessage(user, user.getTranslation("challenges.messages.reset-all",
Constants.PARAMETER_PLAYER, User.getInstance(targetUUID).getName())); Constants.PARAMETER_PLAYER, target.getName()));
} }
else else
{ {
this.addon.log("All challenges for user " + this.addon.log("All challenges for user " + target.getName() + " was reset!");
User.getInstance(targetUUID).getName() + " was reset!");
} }
return true; return true;
@ -129,12 +129,12 @@ public class ResetCommand extends CompositeCommand
{ {
Utils.sendMessage(user, user.getTranslation("challenges.messages.reset", Utils.sendMessage(user, user.getTranslation("challenges.messages.reset",
Constants.PARAMETER_NAME, challenge.getFriendlyName(), Constants.PARAMETER_NAME, challenge.getFriendlyName(),
Constants.PARAMETER_PLAYER, User.getInstance(targetUUID).getName())); Constants.PARAMETER_PLAYER, target.getName()));
} }
else else
{ {
this.addon.log("Challenge " + challenge.getFriendlyName() + " was reset for player " + this.addon.log("Challenge " + challenge.getFriendlyName() + " was reset for player " +
User.getInstance(targetUUID).getName()); target.getName());
} }
} }
else else
@ -185,25 +185,18 @@ public class ResetCommand extends CompositeCommand
switch (size) switch (size)
{ {
case 3: case 3 ->
// Create suggestions with all challenges that is available for users. // Create suggestions with all challenges that is available for users.
returnList.addAll(Util.getOnlinePlayerList(user)); returnList.addAll(Util.getOnlinePlayerList(user));
break; case 4 -> {
case 4:
// Create suggestions with all challenges that is available for users. // Create suggestions with all challenges that is available for users.
returnList.addAll(this.addon.getChallengesManager().getAllChallengesNames(this.getWorld()).stream(). returnList.addAll(this.addon.getChallengesManager().getAllChallengesNames(this.getWorld()).stream().
map(challenge -> challenge.substring(Utils.getGameMode(this.getWorld()).length() + 1)). map(challenge -> challenge.substring(Utils.getGameMode(this.getWorld()).length() + 1)).
collect(Collectors.toList())); collect(Collectors.toList()));
returnList.add("all"); returnList.add("all");
break;
default:
{
returnList.addAll(Collections.singletonList("help"));
break;
} }
default ->
returnList.addAll(Collections.singletonList("help"));
} }
return Optional.of(Util.tabLimit(returnList, lastString)); return Optional.of(Util.tabLimit(returnList, lastString));
@ -217,5 +210,5 @@ public class ResetCommand extends CompositeCommand
/** /**
* Variable that holds challenge addon. Single casting. * Variable that holds challenge addon. Single casting.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -7,27 +7,32 @@ import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesAddon;
public class ShowChallenges extends CompositeCommand { public class ShowChallenges extends CompositeCommand
{
/** /**
* Admin command to show challenges and manage them * Instantiates a new Show challenges command.
* @param parent *
* @param addon the addon
* @param parent the parent
*/ */
public ShowChallenges(Addon addon, CompositeCommand parent) { public ShowChallenges(Addon addon, CompositeCommand parent)
{
super(addon, parent, "show"); super(addon, parent, "show");
} }
@Override @Override
public void setup() { public void setup()
{
this.setPermission("admin.challenges"); this.setPermission("admin.challenges");
this.setParametersHelp("challenges.commands.admin.show.parameters"); this.setParametersHelp("challenges.commands.admin.show.parameters");
this.setDescription("challenges.commands.admin.show.description"); this.setDescription("challenges.commands.admin.show.description");
} }
@Override @Override
public boolean execute(User user, String label, List<String> args) { public boolean execute(User user, String label, List<String> args)
{
if (user.isPlayer()) if (user.isPlayer())
{ {
((ChallengesAddon) getAddon()).getChallengesManager(). ((ChallengesAddon) getAddon()).getChallengesManager().
@ -40,7 +45,5 @@ public class ShowChallenges extends CompositeCommand {
} }
return true; return true;
} }
} }

View File

@ -6,7 +6,6 @@ import java.util.stream.Collectors;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
@ -16,7 +15,6 @@ import com.google.gson.annotations.JsonAdapter;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.DataObject; import world.bentobox.bentobox.database.objects.DataObject;
import world.bentobox.bentobox.database.objects.Table; import world.bentobox.bentobox.database.objects.Table;
import world.bentobox.challenges.database.object.adapters.EntityCompatibilityAdapter;
import world.bentobox.challenges.database.object.adapters.RequirementsAdapter; import world.bentobox.challenges.database.object.adapters.RequirementsAdapter;
import world.bentobox.challenges.database.object.adapters.TypeMigrationAdapter; import world.bentobox.challenges.database.object.adapters.TypeMigrationAdapter;
import world.bentobox.challenges.database.object.requirements.Requirements; import world.bentobox.challenges.database.object.requirements.Requirements;
@ -838,7 +836,7 @@ public class Challenge implements DataObject
clone.setEnvironment(new HashSet<>(this.environment)); clone.setEnvironment(new HashSet<>(this.environment));
clone.setLevel(this.level); clone.setLevel(this.level);
clone.setRemoveWhenCompleted(this.removeWhenCompleted); clone.setRemoveWhenCompleted(this.removeWhenCompleted);
clone.setRequirements(this.requirements.clone()); clone.setRequirements(this.requirements.copy());
clone.setRewardText(this.rewardText); clone.setRewardText(this.rewardText);
clone.setRewardItems( clone.setRewardItems(
this.rewardItems.stream(). this.rewardItems.stream().

View File

@ -6,6 +6,7 @@ import java.util.stream.Collectors;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
@ -449,7 +450,7 @@ public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public int compareTo(ChallengeLevel o) public int compareTo(@NotNull ChallengeLevel o)
{ {
if (this.equals(o)) if (this.equals(o))
{ {
@ -501,13 +502,11 @@ public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
return true; return true;
} }
if (!(obj instanceof ChallengeLevel)) if (!(obj instanceof ChallengeLevel other))
{ {
return false; return false;
} }
ChallengeLevel other = (ChallengeLevel) obj;
if (uniqueId == null) if (uniqueId == null)
{ {
return other.uniqueId == null; return other.uniqueId == null;
@ -542,8 +541,7 @@ public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
* Clone method that returns clone of current challengeLevel. * Clone method that returns clone of current challengeLevel.
* @return ChallengeLevel that is cloned from current object. * @return ChallengeLevel that is cloned from current object.
*/ */
@Override public ChallengeLevel copy()
public ChallengeLevel clone()
{ {
ChallengeLevel clone = new ChallengeLevel(); ChallengeLevel clone = new ChallengeLevel();

View File

@ -65,7 +65,7 @@ public class ChallengesPlayerData implements DataObject
private Map<String, Integer> challengeStatus = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private Map<String, Integer> challengeStatus = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
/** /**
* Map of challenges completion time where key is challenges unique id and value is * Map of challenges completion time when key is challenges unique id and value is
* timestamp when challenge was completed last time. * timestamp when challenge was completed last time.
*/ */
@Expose @Expose
@ -353,13 +353,11 @@ public class ChallengesPlayerData implements DataObject
return true; return true;
} }
if (!(obj instanceof ChallengesPlayerData)) if (!(obj instanceof ChallengesPlayerData other))
{ {
return false; return false;
} }
ChallengesPlayerData other = (ChallengesPlayerData) obj;
if (uniqueId == null) if (uniqueId == null)
{ {
return other.uniqueId == null; return other.uniqueId == null;

View File

@ -33,10 +33,7 @@ public class EntityCompatibilityAdapter implements
{ {
JsonObject jsonArray = new JsonObject(); JsonObject jsonArray = new JsonObject();
src.forEach((entity, number) -> src.forEach((entity, number) -> jsonArray.addProperty(entity.name(), number));
{
jsonArray.addProperty(entity.name(), number);
});
return jsonArray; return jsonArray;
} }
@ -46,7 +43,6 @@ public class EntityCompatibilityAdapter implements
* This method deserializes json object that stores Entity Name and amount as integer. * This method deserializes json object that stores Entity Name and amount as integer.
* @param json Json element that must be parsed. * @param json Json element that must be parsed.
* @return EnumMap that contains EntityType as key and Integer as value. * @return EnumMap that contains EntityType as key and Integer as value.
* @throws JsonParseException
*/ */
@Override @Override
public Map<EntityType, Integer> deserialize(JsonElement json, public Map<EntityType, Integer> deserialize(JsonElement json,

View File

@ -42,7 +42,6 @@ public class TypeMigrationAdapter implements JsonSerializer<Challenge.ChallengeT
return switch (primitive.getAsString()) return switch (primitive.getAsString())
{ {
case "ISLAND", "ISLAND_TYPE" -> Challenge.ChallengeType.ISLAND_TYPE;
case "INVENTORY", "INVENTORY_TYPE" -> Challenge.ChallengeType.INVENTORY_TYPE; case "INVENTORY", "INVENTORY_TYPE" -> Challenge.ChallengeType.INVENTORY_TYPE;
case "OTHER", "OTHER_TYPE" -> Challenge.ChallengeType.OTHER_TYPE; case "OTHER", "OTHER_TYPE" -> Challenge.ChallengeType.OTHER_TYPE;
case "STATISTIC", "STATISTIC_TYPE" -> Challenge.ChallengeType.STATISTIC_TYPE; case "STATISTIC", "STATISTIC_TYPE" -> Challenge.ChallengeType.STATISTIC_TYPE;

View File

@ -126,12 +126,12 @@ public class InventoryRequirements extends Requirements
/** /**
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary * Method Requirements#copy allows copies Requirements object, to avoid changing content when it is necessary
* to use it. * to use it.
* @return InventoryRequirements clone * @return InventoryRequirements copy
*/ */
@Override @Override
public Requirements clone() public Requirements copy()
{ {
InventoryRequirements clone = new InventoryRequirements(); InventoryRequirements clone = new InventoryRequirements();
clone.setRequiredPermissions(new HashSet<>(this.getRequiredPermissions())); clone.setRequiredPermissions(new HashSet<>(this.getRequiredPermissions()));

View File

@ -165,12 +165,12 @@ public class IslandRequirements extends Requirements
/** /**
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary * Method Requirements#copy allows copies Requirements object, to avoid changing content when it is necessary
* to use it. * to use it.
* @return IslandRequirements clone * @return IslandRequirements copy
*/ */
@Override @Override
public Requirements clone() public Requirements copy()
{ {
IslandRequirements clone = new IslandRequirements(); IslandRequirements clone = new IslandRequirements();
clone.setRequiredPermissions(new HashSet<>(this.getRequiredPermissions())); clone.setRequiredPermissions(new HashSet<>(this.getRequiredPermissions()));

View File

@ -147,12 +147,12 @@ public class OtherRequirements extends Requirements
/** /**
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary * Method Requirements#copy allows copies Requirements object, to avoid changing content when it is necessary
* to use it. * to use it.
* @return OtherRequirements clone * @return OtherRequirements copy
*/ */
@Override @Override
public Requirements clone() public Requirements copy()
{ {
OtherRequirements clone = new OtherRequirements(); OtherRequirements clone = new OtherRequirements();
clone.setRequiredPermissions(new HashSet<>(this.getRequiredPermissions())); clone.setRequiredPermissions(new HashSet<>(this.getRequiredPermissions()));

View File

@ -70,12 +70,11 @@ public abstract class Requirements
/** /**
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary * Method Requirements#copy allows to copy Requirements object, to avoid changing content when it is necessary
* to use it. * to use it.
* @return Requirements clone * @return Requirements copy
*/ */
@Override public abstract Requirements copy();
public abstract Requirements clone();
// --------------------------------------------------------------------- // ---------------------------------------------------------------------

View File

@ -11,7 +11,6 @@ import com.google.gson.annotations.Expose;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Statistic; import org.bukkit.Statistic;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -27,11 +26,11 @@ public class StatisticRequirements extends Requirements
/** /**
* This method clones given statistic object. * This method copies given statistic object.
* @return Clone of this object. * @return Copy of this object.
*/ */
@Override @Override
public Requirements clone() public Requirements copy()
{ {
StatisticRequirements requirements = new StatisticRequirements(); StatisticRequirements requirements = new StatisticRequirements();
requirements.setStatistic(this.statistic); requirements.setStatistic(this.statistic);
@ -96,7 +95,7 @@ public class StatisticRequirements extends Requirements
* *
* @param statistic the statistic * @param statistic the statistic
*/ */
public void setStatistic(@NonNull Statistic statistic) public void setStatistic(@Nullable Statistic statistic)
{ {
this.statistic = statistic; this.statistic = statistic;
} }

View File

@ -101,5 +101,5 @@ public class ChallengeDataRequestHandler extends AddonRequestHandler
/** /**
* Variable stores challenges addon. * Variable stores challenges addon.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World;
import world.bentobox.bentobox.api.addons.request.AddonRequestHandler; import world.bentobox.bentobox.api.addons.request.AddonRequestHandler;
import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesAddon;
@ -43,15 +44,21 @@ public class ChallengeListRequestHandler extends AddonRequestHandler
*/ */
if (metaData == null || if (metaData == null ||
metaData.isEmpty() || metaData.isEmpty() ||
metaData.get("world-name") == null || metaData.get("world-name") == null ||
!(metaData.get("world-name") instanceof String) || !(metaData.get("world-name") instanceof String))
Bukkit.getWorld((String) metaData.get("world-name")) == null)
{ {
return Collections.emptyList(); return Collections.emptyList();
} }
return this.addon.getChallengesManager().getAllChallengesNames(Bukkit.getWorld((String) metaData.get("world-name"))); World world = Bukkit.getWorld((String) metaData.get("world-name"));
if (world == null)
{
return Collections.emptyList();
}
return this.addon.getChallengesManager().getAllChallengesNames(world);
} }
@ -63,5 +70,5 @@ public class ChallengeListRequestHandler extends AddonRequestHandler
/** /**
* Variable stores challenges addon. * Variable stores challenges addon.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -50,24 +50,27 @@ public class CompletedChallengesRequestHandler extends AddonRequestHandler
*/ */
if (metaData == null || if (metaData == null ||
metaData.isEmpty() || metaData.isEmpty() ||
metaData.get("world-name") == null || metaData.get("world-name") == null ||
!(metaData.get("world-name") instanceof String) || !(metaData.get("world-name") instanceof String) ||
metaData.get("player") == null || metaData.get("player") == null ||
!(metaData.get("player") instanceof UUID) || !(metaData.get("player") instanceof UUID player))
Bukkit.getWorld((String) metaData.get("world-name")) == null)
{ {
return Collections.emptySet(); return Collections.emptySet();
} }
World world = Bukkit.getWorld((String) metaData.get("world-name")); World world = Bukkit.getWorld((String) metaData.get("world-name"));
UUID player = (UUID) metaData.get("player");
if (world == null)
{
return Collections.emptySet();
}
ChallengesManager manager = this.addon.getChallengesManager(); ChallengesManager manager = this.addon.getChallengesManager();
return manager.getAllChallengesNames(world).stream(). return manager.getAllChallengesNames(world).stream().
filter(challenge -> manager.isChallengeComplete(player, world, challenge)). filter(challenge -> manager.isChallengeComplete(player, world, challenge)).
collect(Collectors.toSet()); collect(Collectors.toSet());
} }
@ -79,5 +82,5 @@ public class CompletedChallengesRequestHandler extends AddonRequestHandler
/** /**
* Variable stores challenges addon. * Variable stores challenges addon.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -94,5 +94,5 @@ public class LevelDataRequestHandler extends AddonRequestHandler
/** /**
* Variable stores challenges addon. * Variable stores challenges addon.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World;
import world.bentobox.bentobox.api.addons.request.AddonRequestHandler; import world.bentobox.bentobox.api.addons.request.AddonRequestHandler;
import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesAddon;
@ -44,16 +45,21 @@ public class LevelListRequestHandler extends AddonRequestHandler
*/ */
if (metaData == null || if (metaData == null ||
metaData.isEmpty() || metaData.isEmpty() ||
metaData.get("world-name") == null || metaData.get("world-name") == null ||
!(metaData.get("world-name") instanceof String) || !(metaData.get("world-name") instanceof String))
Bukkit.getWorld((String) metaData.get("world-name")) == null)
{ {
return Collections.emptyList(); return Collections.emptyList();
} }
return this.addon.getChallengesManager().getLevelNames( World world = Bukkit.getWorld((String) metaData.get("world-name"));
Bukkit.getWorld((String) metaData.get("world-name")));
if (world == null)
{
return Collections.emptyList();
}
return this.addon.getChallengesManager().getLevelNames(world);
} }
@ -65,5 +71,5 @@ public class LevelListRequestHandler extends AddonRequestHandler
/** /**
* Variable stores challenges addon. * Variable stores challenges addon.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -50,5 +50,5 @@ public class SaveListener implements Listener
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private ChallengesAddon addon; private final ChallengesAddon addon;
} }

View File

@ -27,6 +27,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import lv.id.bonne.panelutils.PanelUtils;
import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
@ -661,14 +662,21 @@ public class ChallengesImportManager
*/ */
public void importDatabaseFile(User user, World world, String fileName) public void importDatabaseFile(User user, World world, String fileName)
{ {
World correctWorld = Util.getWorld(world);
if (correctWorld == null)
{
this.addon.logError("Given world is not part of BentoBox");
return;
}
ChallengesManager manager = this.addon.getChallengesManager(); ChallengesManager manager = this.addon.getChallengesManager();
// If exist any generator that is bound to current world, then do not load generators. // If exist any generator that is bound to current world, then do not load generators.
if (manager.hasAnyChallengeData(world.getName())) if (manager.hasAnyChallengeData(world.getName()))
{ {
this.addon.getPlugin().getIWM().getAddon(world).ifPresent(gameModeAddon -> { this.addon.getPlugin().getIWM().getAddon(world).ifPresent(gameModeAddon ->
manager.wipeDatabase(gameModeAddon.getDescription().getName().toLowerCase()); manager.wipeDatabase(gameModeAddon.getDescription().getName().toLowerCase()));
});
} }
try try
@ -700,7 +708,7 @@ public class ChallengesImportManager
// Set correct level ID // Set correct level ID
challengeLevel.setUniqueId(uniqueIDPrefix + challengeLevel.getUniqueId()); challengeLevel.setUniqueId(uniqueIDPrefix + challengeLevel.getUniqueId());
// Set correct world name // Set correct world name
challengeLevel.setWorld(Util.getWorld(world).getName()); challengeLevel.setWorld(correctWorld.getName());
// Reset names for all challenges. // Reset names for all challenges.
challengeLevel.setChallenges(challengeLevel.getChallenges().stream(). challengeLevel.setChallenges(challengeLevel.getChallenges().stream().
map(challenge -> uniqueIDPrefix + challenge). map(challenge -> uniqueIDPrefix + challenge).
@ -728,6 +736,14 @@ public class ChallengesImportManager
*/ */
public void loadDownloadedChallenges(User user, World world, String downloadString) public void loadDownloadedChallenges(User user, World world, String downloadString)
{ {
World correctWorld = Util.getWorld(world);
if (correctWorld == null)
{
this.addon.logError("Given world is not part of BentoBox");
return;
}
ChallengesManager manager = this.addon.getChallengesManager(); ChallengesManager manager = this.addon.getChallengesManager();
// If exist any challenge or level that is bound to current world, then do not load default challenges. // If exist any challenge or level that is bound to current world, then do not load default challenges.
@ -769,7 +785,7 @@ public class ChallengesImportManager
// Set correct level ID // Set correct level ID
challengeLevel.setUniqueId(uniqueIDPrefix + challengeLevel.getUniqueId()); challengeLevel.setUniqueId(uniqueIDPrefix + challengeLevel.getUniqueId());
// Set correct world name // Set correct world name
challengeLevel.setWorld(Util.getWorld(world).getName()); challengeLevel.setWorld(correctWorld.getName());
// Reset names for all challenges. // Reset names for all challenges.
challengeLevel.setChallenges(challengeLevel.getChallenges().stream(). challengeLevel.setChallenges(challengeLevel.getChallenges().stream().
map(challenge -> uniqueIDPrefix + challenge). map(challenge -> uniqueIDPrefix + challenge).
@ -840,7 +856,7 @@ public class ChallengesImportManager
stream(). stream().
map(challengeLevel -> { map(challengeLevel -> {
// Use clone to avoid any changes in existing levels. // Use clone to avoid any changes in existing levels.
ChallengeLevel clone = challengeLevel.clone(); ChallengeLevel clone = challengeLevel.copy();
// Remove world name from level ID. // Remove world name from level ID.
clone.setUniqueId(challengeLevel.getUniqueId().replaceFirst(replacementString, "")); clone.setUniqueId(challengeLevel.getUniqueId().replaceFirst(replacementString, ""));
// Remove world name. // Remove world name.

View File

@ -12,7 +12,6 @@ import org.bukkit.entity.EntityType;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.database.Database;
@ -24,9 +23,6 @@ import world.bentobox.challenges.config.Settings;
import world.bentobox.challenges.database.object.Challenge; import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.ChallengeLevel; import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.database.object.ChallengesPlayerData; import world.bentobox.challenges.database.object.ChallengesPlayerData;
import world.bentobox.challenges.database.object.requirements.InventoryRequirements;
import world.bentobox.challenges.database.object.requirements.IslandRequirements;
import world.bentobox.challenges.database.object.requirements.OtherRequirements;
import world.bentobox.challenges.database.object.requirements.Requirements; import world.bentobox.challenges.database.object.requirements.Requirements;
import world.bentobox.challenges.events.ChallengeCompletedEvent; import world.bentobox.challenges.events.ChallengeCompletedEvent;
import world.bentobox.challenges.events.ChallengeResetAllEvent; import world.bentobox.challenges.events.ChallengeResetAllEvent;
@ -57,7 +53,7 @@ public class ChallengesManager
private final Database<ChallengeLevel> levelDatabase; private final Database<ChallengeLevel> levelDatabase;
/** /**
* This database allows to access player challenge data. * This database allows accessing player challenge data.
*/ */
private final Database<ChallengesPlayerData> playersDatabase; private final Database<ChallengesPlayerData> playersDatabase;
@ -77,17 +73,17 @@ public class ChallengesManager
private final Map<String, ChallengesPlayerData> playerCacheData; private final Map<String, ChallengesPlayerData> playerCacheData;
/** /**
* This variable allows to access ChallengesAddon. * This variable allows accessing ChallengesAddon.
*/ */
private final ChallengesAddon addon; private final ChallengesAddon addon;
/** /**
* This variable allows to access ChallengesAddon settings. * This variable allows accessing ChallengesAddon settings.
*/ */
private final Settings settings; private final Settings settings;
/** /**
* Island world manager allows to detect which world refferes to which gamemode addon. * Island world manager allows detecting which world refers to which gamemode addon.
*/ */
private final IslandWorldManager islandWorldManager; private final IslandWorldManager islandWorldManager;
@ -121,7 +117,7 @@ public class ChallengesManager
{ {
if (o1.getOrder() == o2.getOrder()) if (o1.getOrder() == o2.getOrder())
{ {
// If orders are equal, sort by unique Id // If orders are equal, sort by unique id
return o1.getUniqueId().compareToIgnoreCase(o2.getUniqueId()); return o1.getUniqueId().compareToIgnoreCase(o2.getUniqueId());
} }
else else
@ -139,9 +135,18 @@ public class ChallengesManager
} }
else else
{ {
// Sort by challenges level order numbers ChallengeLevel o1Level = this.getLevel(o1.getLevel());
return Integer.compare(this.getLevel(o1.getLevel()).getOrder(), ChallengeLevel o2Level = this.getLevel(o2.getLevel());
this.getLevel(o2.getLevel()).getOrder());
if (o1Level == null || o2Level == null)
{
return Boolean.compare(o1Level == null, o2Level == null);
}
else
{
// Sort by challenges level order numbers
return Integer.compare(o1Level.getOrder(), o2Level.getOrder());
}
} }
} }
}; };
@ -166,7 +171,7 @@ public class ChallengesManager
// Set up the configs // Set up the configs
this.challengeDatabase = new Database<>(addon, Challenge.class); this.challengeDatabase = new Database<>(addon, Challenge.class);
this.levelDatabase = new Database<>(addon, ChallengeLevel.class); this.levelDatabase = new Database<>(addon, ChallengeLevel.class);
// Players is where all the player history will be stored // playersDatabase is where all the player history will be stored
this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class); this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class);
// Init all cache objects. // Init all cache objects.
@ -226,9 +231,10 @@ public class ChallengesManager
// store player data before cleaning. // store player data before cleaning.
this.savePlayersData(); this.savePlayersData();
} }
//this.challengeDatabase = new Database<>(addon, Challenge.class);
//this.levelDatabase = new Database<>(addon, ChallengeLevel.class); // this.challengeDatabase = new Database<>(addon, Challenge.class);
//this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class); // this.levelDatabase = new Database<>(addon, ChallengeLevel.class);
// this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class);
this.loadAndValidate(); this.loadAndValidate();
} }
@ -420,26 +426,6 @@ public class ChallengesManager
} }
/**
* This method stores PlayerData into local cache.
*
* @param playerData ChallengesPlayerData that must be loaded.
*
* TODO: Remove this unused method?
*/
private void loadPlayerData(@NonNull ChallengesPlayerData playerData)
{
try
{
this.playerCacheData.put(playerData.getUniqueId(), playerData);
}
catch (Exception e)
{
this.addon.getLogger().severe("UUID for player in challenge data file is invalid!");
}
}
/** /**
* This method removes given player from cache data. * This method removes given player from cache data.
* *

View File

@ -528,11 +528,9 @@ public abstract class CommonPanel
switch (requirement.getStatistic().getType()) switch (requirement.getStatistic().getType())
{ {
case UNTYPED -> { case UNTYPED -> statistic = this.user.getTranslationOrNothing(reference + "statistic",
statistic = this.user.getTranslationOrNothing(reference + "statistic", "[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user),
"[statistic]", Utils.prettifyObject(requirement.getStatistic(), this.user), "[number]", String.valueOf(requirement.getAmount()));
"[number]", String.valueOf(requirement.getAmount()));
}
case ITEM, BLOCK -> { case ITEM, BLOCK -> {
if (requirement.getAmount() > 1) if (requirement.getAmount() > 1)
{ {
@ -563,9 +561,7 @@ public abstract class CommonPanel
"[target]", Utils.prettifyObject(requirement.getEntity(), this.user)); "[target]", Utils.prettifyObject(requirement.getEntity(), this.user));
} }
} }
default -> { default -> statistic = "";
statistic = "";
}
} }
String warning = requirement.isReduceStatistic() ? String warning = requirement.isReduceStatistic() ?

View File

@ -41,9 +41,9 @@ public class ConversationUtils
* @param user User who is targeted with current confirmation. * @param user User who is targeted with current confirmation.
*/ */
public static void createConfirmation(Consumer<Boolean> consumer, public static void createConfirmation(Consumer<Boolean> consumer,
User user, User user,
@NotNull String question, @NotNull String question,
@Nullable String successMessage) @Nullable String successMessage)
{ {
ValidatingPrompt confirmationPrompt = new ValidatingPrompt() ValidatingPrompt confirmationPrompt = new ValidatingPrompt()
{ {
@ -77,7 +77,6 @@ public class ConversationUtils
* @return the prompt * @return the prompt
*/ */
@Override @Override
@Nullable
protected Prompt acceptValidatedInput(@NotNull ConversationContext context, @NotNull String input) protected Prompt acceptValidatedInput(@NotNull ConversationContext context, @NotNull String input)
{ {
String validEntry = user.getTranslation(Constants.CONVERSATIONS + "confirm-string").toLowerCase(); String validEntry = user.getTranslation(Constants.CONVERSATIONS + "confirm-string").toLowerCase();
@ -105,7 +104,8 @@ public class ConversationUtils
* @see Prompt#getPromptText(ConversationContext) * @see Prompt#getPromptText(ConversationContext)
*/ */
@Override @Override
public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) @NotNull
public String getPromptText(@NotNull ConversationContext conversationContext)
{ {
// Close input GUI. // Close input GUI.
user.closeInventory(); user.closeInventory();
@ -137,11 +137,11 @@ public class ConversationUtils
* @param user User who is targeted with current confirmation. * @param user User who is targeted with current confirmation.
*/ */
public static void createIDStringInput(Consumer<String> consumer, public static void createIDStringInput(Consumer<String> consumer,
Function<String, Boolean> validation, Function<String, Boolean> validation,
User user, User user,
@NotNull String question, @NotNull String question,
@Nullable String successMessage, @Nullable String successMessage,
@Nullable String failTranslationLocation) @Nullable String failTranslationLocation)
{ {
ValidatingPrompt validatingPrompt = new ValidatingPrompt() ValidatingPrompt validatingPrompt = new ValidatingPrompt()
{ {
@ -154,7 +154,8 @@ public class ConversationUtils
* @return The text to display. * @return The text to display.
*/ */
@Override @Override
public String getPromptText(ConversationContext context) @NotNull
public String getPromptText(@NotNull ConversationContext context)
{ {
// Close input GUI. // Close input GUI.
user.closeInventory(); user.closeInventory();
@ -175,7 +176,7 @@ public class ConversationUtils
* validity of the input. * validity of the input.
*/ */
@Override @Override
protected boolean isInputValid(ConversationContext context, String input) protected boolean isInputValid(@NotNull ConversationContext context, @NotNull String input)
{ {
return validation.apply(input); return validation.apply(input);
} }
@ -194,8 +195,8 @@ public class ConversationUtils
* correct the input. * correct the input.
*/ */
@Override @Override
protected String getFailedValidationText(ConversationContext context, protected String getFailedValidationText(@NotNull ConversationContext context,
String invalidInput) @NotNull String invalidInput)
{ {
return user.getTranslation(failTranslationLocation, return user.getTranslation(failTranslationLocation,
Constants.PARAMETER_ID, Constants.PARAMETER_ID,
@ -216,7 +217,7 @@ public class ConversationUtils
* @return The next Prompt in the prompt graph. * @return The next Prompt in the prompt graph.
*/ */
@Override @Override
protected Prompt acceptValidatedInput(ConversationContext context, String input) protected Prompt acceptValidatedInput(@NotNull ConversationContext context, @NotNull String input)
{ {
// Add answer to consumer. // Add answer to consumer.
consumer.accept(input); consumer.accept(input);
@ -247,10 +248,10 @@ public class ConversationUtils
* @param question Message that will be displayed in chat when player triggers conversion. * @param question Message that will be displayed in chat when player triggers conversion.
*/ */
public static void createNumericInput(Consumer<Number> consumer, public static void createNumericInput(Consumer<Number> consumer,
@NotNull User user, @NotNull User user,
@NotNull String question, @NotNull String question,
Number minValue, Number minValue,
Number maxValue) Number maxValue)
{ {
// Create NumericPromt instance that will validate and process input. // Create NumericPromt instance that will validate and process input.
NumericPrompt numberPrompt = new NumericPrompt() NumericPrompt numberPrompt = new NumericPrompt()
@ -267,7 +268,7 @@ public class ConversationUtils
* graph. * graph.
*/ */
@Override @Override
protected Prompt acceptValidatedInput(ConversationContext context, Number input) protected Prompt acceptValidatedInput(@NotNull ConversationContext context, @NotNull Number input)
{ {
// Add answer to consumer. // Add answer to consumer.
consumer.accept(input); consumer.accept(input);
@ -285,7 +286,7 @@ public class ConversationUtils
* @return The validity of the player's input. * @return The validity of the player's input.
*/ */
@Override @Override
protected boolean isNumberValid(ConversationContext context, Number input) protected boolean isNumberValid(@NotNull ConversationContext context, Number input)
{ {
return input.doubleValue() >= minValue.doubleValue() && return input.doubleValue() >= minValue.doubleValue() &&
input.doubleValue() <= maxValue.doubleValue(); input.doubleValue() <= maxValue.doubleValue();
@ -301,7 +302,7 @@ public class ConversationUtils
* @return A message explaining how to correct the input. * @return A message explaining how to correct the input.
*/ */
@Override @Override
protected String getInputNotNumericText(ConversationContext context, String invalidInput) protected String getInputNotNumericText(@NotNull ConversationContext context, @NotNull String invalidInput)
{ {
return user.getTranslation(Constants.CONVERSATIONS + "numeric-only", Constants.PARAMETER_VALUE, invalidInput); return user.getTranslation(Constants.CONVERSATIONS + "numeric-only", Constants.PARAMETER_VALUE, invalidInput);
} }
@ -316,7 +317,7 @@ public class ConversationUtils
* @return A message explaining how to correct the input. * @return A message explaining how to correct the input.
*/ */
@Override @Override
protected String getFailedValidationText(ConversationContext context, Number invalidInput) protected String getFailedValidationText(@NotNull ConversationContext context, Number invalidInput)
{ {
return user.getTranslation(Constants.CONVERSATIONS + "not-valid-value", return user.getTranslation(Constants.CONVERSATIONS + "not-valid-value",
Constants.PARAMETER_VALUE, invalidInput.toString(), Constants.PARAMETER_VALUE, invalidInput.toString(),
@ -329,7 +330,8 @@ public class ConversationUtils
* @see Prompt#getPromptText(ConversationContext) * @see Prompt#getPromptText(ConversationContext)
*/ */
@Override @Override
public String getPromptText(ConversationContext conversationContext) @NotNull
public String getPromptText(@NotNull ConversationContext conversationContext)
{ {
// Close input GUI. // Close input GUI.
user.closeInventory(); user.closeInventory();
@ -363,9 +365,9 @@ public class ConversationUtils
* @param user User who is targeted with current confirmation. * @param user User who is targeted with current confirmation.
*/ */
public static void createStringListInput(Consumer<List<String>> consumer, public static void createStringListInput(Consumer<List<String>> consumer,
User user, User user,
@NotNull String question, @NotNull String question,
@NotNull String successMessage) @NotNull String successMessage)
{ {
final String SESSION_CONSTANT = Constants.CONVERSATIONS + user.getUniqueId(); final String SESSION_CONSTANT = Constants.CONVERSATIONS + user.getUniqueId();
@ -373,13 +375,12 @@ public class ConversationUtils
MessagePrompt messagePrompt = new MessagePrompt() MessagePrompt messagePrompt = new MessagePrompt()
{ {
@Override @Override
public @NotNull String getPromptText(@NotNull ConversationContext context) @NotNull
public String getPromptText(@NotNull ConversationContext context)
{ {
List<String> description = (List<String>) context.getSessionData(SESSION_CONSTANT); if (context.getSessionData(SESSION_CONSTANT) instanceof List description)
if (description != null)
{ {
consumer.accept(description); consumer.accept((List<String>) description);
return successMessage; return successMessage;
} }
else else
@ -400,7 +401,8 @@ public class ConversationUtils
StringPrompt stringPrompt = new StringPrompt() StringPrompt stringPrompt = new StringPrompt()
{ {
@Override @Override
public @NotNull String getPromptText(@NotNull ConversationContext context) @NotNull
public String getPromptText(@NotNull ConversationContext context)
{ {
user.closeInventory(); user.closeInventory();
@ -424,7 +426,7 @@ public class ConversationUtils
@Override @Override
public @Nullable Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input)
{ {
String[] exit = user.getTranslation(Constants.CONVERSATIONS + "exit-string"). String[] exit = user.getTranslation(Constants.CONVERSATIONS + "exit-string").
toLowerCase().replaceAll("\\s", ""). toLowerCase().replaceAll("\\s", "").
@ -437,9 +439,9 @@ public class ConversationUtils
List<String> desc = new ArrayList<>(); List<String> desc = new ArrayList<>();
if (context.getSessionData(SESSION_CONSTANT) != null) if (context.getSessionData(SESSION_CONSTANT) instanceof List list)
{ {
desc = ((List<String>) context.getSessionData(SESSION_CONSTANT)); desc = (List<String>) list;
} }
if (input != null) { if (input != null) {
desc.add(ChatColor.translateAlternateColorCodes('&', input)); desc.add(ChatColor.translateAlternateColorCodes('&', input));
@ -471,15 +473,16 @@ public class ConversationUtils
* @param user User who is targeted with current confirmation. * @param user User who is targeted with current confirmation.
*/ */
public static void createStringInput(Consumer<String> consumer, public static void createStringInput(Consumer<String> consumer,
User user, User user,
@NotNull String question, @NotNull String question,
@Nullable String successMessage) @Nullable String successMessage)
{ {
// Text input message. // Text input message.
StringPrompt stringPrompt = new StringPrompt() StringPrompt stringPrompt = new StringPrompt()
{ {
@Override @Override
public @NotNull String getPromptText(@NotNull ConversationContext context) @NotNull
public String getPromptText(@NotNull ConversationContext context)
{ {
user.closeInventory(); user.closeInventory();
return question; return question;
@ -487,7 +490,8 @@ public class ConversationUtils
@Override @Override
public @NotNull Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) @NotNull
public Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input)
{ {
consumer.accept(input); consumer.accept(input);
return ConversationUtils.endMessagePrompt(successMessage); return ConversationUtils.endMessagePrompt(successMessage);
@ -519,14 +523,16 @@ public class ConversationUtils
return new MessagePrompt() return new MessagePrompt()
{ {
@Override @Override
public @NotNull String getPromptText(@NotNull ConversationContext context) @NotNull
public String getPromptText(@NotNull ConversationContext context)
{ {
return message == null ? "" : message; return message == null ? "" : message;
} }
@Override @Override
protected @Nullable Prompt getNextPrompt(@NotNull ConversationContext context) @Nullable
protected Prompt getNextPrompt(@NotNull ConversationContext context)
{ {
return Prompt.END_OF_CONVERSATION; return Prompt.END_OF_CONVERSATION;
} }

View File

@ -158,10 +158,9 @@ public class ManageBlocksPanel extends CommonPagedPanel<Material>
if (!this.selectedMaterials.isEmpty()) if (!this.selectedMaterials.isEmpty())
{ {
description.add(this.user.getTranslation(reference + "title")); description.add(this.user.getTranslation(reference + "title"));
this.selectedMaterials.forEach(material -> { this.selectedMaterials.forEach(material ->
description.add(this.user.getTranslation(reference + "material", description.add(this.user.getTranslation(reference + "material",
"[material]", Utils.prettifyObject(material, this.user))); "[material]", Utils.prettifyObject(material, this.user))));
});
} }
icon = new ItemStack(Material.LAVA_BUCKET); icon = new ItemStack(Material.LAVA_BUCKET);

View File

@ -155,10 +155,9 @@ public class ManageEntitiesPanel extends CommonPagedPanel<EntityType>
if (!this.selectedEntities.isEmpty()) if (!this.selectedEntities.isEmpty())
{ {
description.add(this.user.getTranslation(reference + "title")); description.add(this.user.getTranslation(reference + "title"));
this.selectedEntities.forEach(entity -> { this.selectedEntities.forEach(entity ->
description.add(this.user.getTranslation(reference + "entity", description.add(this.user.getTranslation(reference + "entity",
"[entity]", Utils.prettifyObject(entity, this.user))); "[entity]", Utils.prettifyObject(entity, this.user))));
});
} }
icon = new ItemStack(Material.LAVA_BUCKET); icon = new ItemStack(Material.LAVA_BUCKET);

View File

@ -120,10 +120,9 @@ public class ChallengeSelector extends PagedSelector<Challenge>
if (!this.selectedElements.isEmpty()) if (!this.selectedElements.isEmpty())
{ {
description.add(this.user.getTranslation(reference + "title")); description.add(this.user.getTranslation(reference + "title"));
this.selectedElements.forEach(challenge -> { this.selectedElements.forEach(challenge ->
description.add(this.user.getTranslation(reference + "element", description.add(this.user.getTranslation(reference + "element",
"[element]", challenge.getFriendlyName())); "[element]", challenge.getFriendlyName())));
});
} }
icon = new ItemStack(Material.COMMAND_BLOCK); icon = new ItemStack(Material.COMMAND_BLOCK);

View File

@ -143,10 +143,9 @@ public record EnvironmentSelector(User user, Set<World.Environment> values, BiCo
if (!this.values.isEmpty()) if (!this.values.isEmpty())
{ {
description.add(this.user.getTranslation(reference + "title")); description.add(this.user.getTranslation(reference + "title"));
this.values.forEach(element -> { this.values.forEach(element ->
description.add(this.user.getTranslation(reference + "element", description.add(this.user.getTranslation(reference + "element",
"[element]", Utils.prettifyObject(element, this.user))); "[element]", Utils.prettifyObject(element, this.user))));
});
} }
icon = new ItemStack(Material.COMMAND_BLOCK); icon = new ItemStack(Material.COMMAND_BLOCK);

View File

@ -160,10 +160,9 @@ public class MultiBlockSelector extends PagedSelector<Material>
if (!this.selectedElements.isEmpty()) if (!this.selectedElements.isEmpty())
{ {
description.add(this.user.getTranslation(reference + "title")); description.add(this.user.getTranslation(reference + "title"));
this.selectedElements.forEach(material -> { this.selectedElements.forEach(material ->
description.add(this.user.getTranslation(reference + "element", description.add(this.user.getTranslation(reference + "element",
"[element]", Utils.prettifyObject(material, this.user))); "[element]", Utils.prettifyObject(material, this.user))));
});
} }
icon = new ItemStack(Material.COMMAND_BLOCK); icon = new ItemStack(Material.COMMAND_BLOCK);

View File

@ -144,10 +144,9 @@ public class MultiEntitySelector extends PagedSelector<EntityType>
if (!this.selectedElements.isEmpty()) if (!this.selectedElements.isEmpty())
{ {
description.add(this.user.getTranslation(reference + "title")); description.add(this.user.getTranslation(reference + "title"));
this.selectedElements.forEach(material -> { this.selectedElements.forEach(material ->
description.add(this.user.getTranslation(reference + "element", description.add(this.user.getTranslation(reference + "element",
"[element]", Utils.prettifyObject(material, this.user))); "[element]", Utils.prettifyObject(material, this.user))));
});
} }
icon = new ItemStack(Material.COMMAND_BLOCK); icon = new ItemStack(Material.COMMAND_BLOCK);

View File

@ -4,7 +4,6 @@ package world.bentobox.challenges.tasks;
import com.google.common.collect.UnmodifiableIterator; import com.google.common.collect.UnmodifiableIterator;
import java.time.*; import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap; import java.util.EnumMap;
@ -61,7 +60,7 @@ public class TryToComplete
/** /**
* Challenges addon variable. * Challenges addon variable.
*/ */
private ChallengesAddon addon; private final ChallengesAddon addon;
/** /**
* Challenges manager for addon. * Challenges manager for addon.
@ -83,11 +82,6 @@ public class TryToComplete
*/ */
private String permissionPrefix; private String permissionPrefix;
/**
* Top command first label.
*/
private String topLabel;
/** /**
* Challenge that should be completed. * Challenge that should be completed.
*/ */
@ -102,13 +96,6 @@ public class TryToComplete
// Section: Builder // Section: Builder
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@Deprecated
public TryToComplete label(String label)
{
this.topLabel = label;
return this;
}
@Deprecated @Deprecated
public TryToComplete user(User user) public TryToComplete user(User user)
@ -118,38 +105,6 @@ public class TryToComplete
} }
@Deprecated
public TryToComplete manager(ChallengesManager manager)
{
this.manager = manager;
return this;
}
@Deprecated
public TryToComplete challenge(Challenge challenge)
{
this.challenge = challenge;
return this;
}
@Deprecated
public TryToComplete world(World world)
{
this.world = world;
return this;
}
@Deprecated
public TryToComplete permPrefix(String prefix)
{
this.permissionPrefix = prefix;
return this;
}
@Deprecated @Deprecated
public TryToComplete(ChallengesAddon addon) public TryToComplete(ChallengesAddon addon)
{ {
@ -185,7 +140,6 @@ public class TryToComplete
// To avoid any modifications that may occur to challenges in current completion // To avoid any modifications that may occur to challenges in current completion
// just clone it. // just clone it.
this.challenge = challenge.clone(); this.challenge = challenge.clone();
this.topLabel = topLabel;
} }
@ -254,6 +208,13 @@ public class TryToComplete
return result; return result;
} }
if (this.user.getLocation() == null || this.user.getInventory() == null)
{
// This is just a cleaning check. There is no situations where location or inventory
// could be null at this point of code.
return result;
}
this.fullFillRequirements(result); this.fullFillRequirements(result);
// Validation to avoid rewarding if something goes wrong in removing requirements. // Validation to avoid rewarding if something goes wrong in removing requirements.
@ -314,23 +275,21 @@ public class TryToComplete
filter(player -> this.user.getUniqueId().equals(player.getUniqueId())). filter(player -> this.user.getUniqueId().equals(player.getUniqueId())).
map(User::getInstance). map(User::getInstance).
filter(Objects::nonNull). filter(Objects::nonNull).
forEach(user -> { forEach(user -> Utils.sendMessage(user, user.getTranslation(
Utils.sendMessage(user, user.getTranslation( "challenges.messages.name-has-completed-challenge",
"challenges.messages.name-has-completed-challenge", Constants.PARAMETER_NAME, this.user.getName(),
Constants.PARAMETER_NAME, this.user.getName(), "[value]", this.challenge.getFriendlyName())));
"[value]", this.challenge.getFriendlyName()));
});
} }
// sends title to player on challenge completion // sends title to player on challenge completion
if (this.addon.getChallengesSettings().isShowCompletionTitle()) if (this.addon.getChallengesSettings().isShowCompletionTitle())
{ {
this.user.getPlayer().sendTitle( this.user.getPlayer().sendTitle(
this.parseChallenge(this.user.getTranslation("challenges.titles.challenge-title"), this.challenge), this.parseChallenge(this.user.getTranslation("challenges.titles.challenge-title"), this.challenge),
this.parseChallenge(this.user.getTranslation("challenges.titles.challenge-subtitle"), this.challenge), this.parseChallenge(this.user.getTranslation("challenges.titles.challenge-subtitle"), this.challenge),
10, 10,
this.addon.getChallengesSettings().getTitleShowtime(), this.addon.getChallengesSettings().getTitleShowtime(),
20); 20);
} }
} }
@ -355,7 +314,7 @@ public class TryToComplete
if (this.addon.isEconomyProvided()) if (this.addon.isEconomyProvided())
{ {
this.addon.getEconomyProvider().deposit(this.user, this.addon.getEconomyProvider().deposit(this.user,
(double)this.challenge.getRepeatMoneyReward() * rewardFactor); this.challenge.getRepeatMoneyReward() * rewardFactor);
} }
// Experience Repeat Reward // Experience Repeat Reward
@ -424,12 +383,10 @@ public class TryToComplete
filter(player -> this.user.getUniqueId().equals(player.getUniqueId())). filter(player -> this.user.getUniqueId().equals(player.getUniqueId())).
map(User::getInstance). map(User::getInstance).
filter(Objects::nonNull). filter(Objects::nonNull).
forEach(user -> { forEach(user -> Utils.sendMessage(user, user.getTranslation(
Utils.sendMessage(user, user.getTranslation( "challenges.messages.name-has-completed-level",
"challenges.messages.name-has-completed-level", Constants.PARAMETER_NAME, this.user.getName(),
Constants.PARAMETER_NAME, this.user.getName(), "[value]", level.getFriendlyName())));
"[value]", level.getFriendlyName()));
});
} }
this.manager.setLevelComplete(this.user, this.world, level); this.manager.setLevelComplete(this.user, this.world, level);
@ -453,7 +410,7 @@ public class TryToComplete
/** /**
* This method full fills all challenge type requirements, that is not full filled yet. * This method fulfills all challenge type requirements, that is not fulfilled yet.
* @param result Challenge Results * @param result Challenge Results
*/ */
private void fullFillRequirements(ChallengeResult result) private void fullFillRequirements(ChallengeResult result)
@ -520,7 +477,7 @@ public class TryToComplete
case STATISTIC_TYPE -> { case STATISTIC_TYPE -> {
StatisticRequirements requirements = this.challenge.getRequirements(); StatisticRequirements requirements = this.challenge.getRequirements();
if (requirements.isReduceStatistic()) if (requirements.isReduceStatistic() && requirements.getStatistic() != null)
{ {
int removeAmount = result.getFactor() * requirements.getAmount(); int removeAmount = result.getFactor() * requirements.getAmount();
@ -544,7 +501,12 @@ public class TryToComplete
case ITEM, BLOCK -> { case ITEM, BLOCK -> {
int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic()); int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic());
if (removeAmount >= statistic) if (requirements.getMaterial() == null)
{
// Just a sanity check. Material cannot be null at this point of code.
removeAmount = 0;
}
else if (removeAmount >= statistic)
{ {
this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getMaterial(), 0); this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getMaterial(), 0);
removeAmount -= statistic; removeAmount -= statistic;
@ -560,7 +522,12 @@ public class TryToComplete
case ENTITY -> { case ENTITY -> {
int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic()); int statistic = this.user.getPlayer().getStatistic(requirements.getStatistic());
if (removeAmount >= statistic) if (requirements.getEntity() == null)
{
// Just a sanity check. Entity cannot be null at this point of code.
removeAmount = 0;
}
else if (removeAmount >= statistic)
{ {
this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getEntity(), 0); this.user.getPlayer().setStatistic(requirements.getStatistic(), requirements.getEntity(), 0);
removeAmount -= statistic; removeAmount -= statistic;
@ -616,7 +583,12 @@ public class TryToComplete
case ITEM, BLOCK -> { case ITEM, BLOCK -> {
int statistic = player.getStatistic(requirements.getStatistic()); int statistic = player.getStatistic(requirements.getStatistic());
if (removeAmount >= statistic) if (requirements.getMaterial() == null)
{
// Just a sanity check. Entity cannot be null at this point of code.
removeAmount = 0;
}
else if (removeAmount >= statistic)
{ {
removeAmount -= statistic; removeAmount -= statistic;
player.setStatistic(requirements.getStatistic(), requirements.getMaterial(), 0); player.setStatistic(requirements.getStatistic(), requirements.getMaterial(), 0);
@ -632,7 +604,12 @@ public class TryToComplete
case ENTITY -> { case ENTITY -> {
int statistic = player.getStatistic(requirements.getStatistic()); int statistic = player.getStatistic(requirements.getStatistic());
if (removeAmount >= statistic) if (requirements.getEntity() == null)
{
// Just a sanity check. Entity cannot be null at this point of code.
removeAmount = 0;
}
else if (removeAmount >= statistic)
{ {
removeAmount -= statistic; removeAmount -= statistic;
player.setStatistic(requirements.getStatistic(), requirements.getEntity(), 0); player.setStatistic(requirements.getStatistic(), requirements.getEntity(), 0);
@ -676,13 +653,14 @@ public class TryToComplete
result = EMPTY_RESULT; result = EMPTY_RESULT;
} }
else if (Util.getWorld(this.world) != Util.getWorld(this.user.getWorld()) || else if (Util.getWorld(this.world) != Util.getWorld(this.user.getWorld()) ||
!this.challenge.matchGameMode(Utils.getGameMode(this.world))) !this.challenge.matchGameMode(Utils.getGameMode(this.world)))
{ {
Utils.sendMessage(this.user, this.user.getTranslation("general.errors.wrong-world")); Utils.sendMessage(this.user, this.user.getTranslation("general.errors.wrong-world"));
result = EMPTY_RESULT; result = EMPTY_RESULT;
} }
// Player is not on island // Player is not on island
else if (ChallengesAddon.CHALLENGES_WORLD_PROTECTION.isSetForWorld(this.world) && else if (this.user.getLocation() == null ||
ChallengesAddon.CHALLENGES_WORLD_PROTECTION.isSetForWorld(this.world) &&
!this.addon.getIslands().locationIsOnIsland(this.user.getPlayer(), this.user.getLocation())) !this.addon.getIslands().locationIsOnIsland(this.user.getPlayer(), this.user.getLocation()))
{ {
Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.not-on-island")); Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.not-on-island"));
@ -690,22 +668,22 @@ public class TryToComplete
} }
// Check player permission // Check player permission
else if (!this.addon.getIslands().getIslandAt(this.user.getLocation()). else if (!this.addon.getIslands().getIslandAt(this.user.getLocation()).
map(i -> i.isAllowed(this.user, ChallengesAddon.CHALLENGES_ISLAND_PROTECTION)). map(i -> i.isAllowed(this.user, ChallengesAddon.CHALLENGES_ISLAND_PROTECTION)).
orElse(false)) orElse(false))
{ {
Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.no-rank")); Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.no-rank"));
result = EMPTY_RESULT; result = EMPTY_RESULT;
} }
// Check if user has unlocked challenges level. // Check if user has unlocked challenges level.
else if (!this.challenge.getLevel().equals(ChallengesManager.FREE) && else if (!this.challenge.getLevel().equals(ChallengesManager.FREE) &&
!this.manager.isLevelUnlocked(this.user, this.world, this.manager.getLevel(this.challenge.getLevel()))) !this.manager.isLevelUnlocked(this.user, this.world, this.manager.getLevel(this.challenge.getLevel())))
{ {
Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.challenge-level-not-available")); Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.challenge-level-not-available"));
result = EMPTY_RESULT; result = EMPTY_RESULT;
} }
// Check max times // Check max times
else if (this.challenge.isRepeatable() && this.challenge.getMaxTimes() > 0 && else if (this.challenge.isRepeatable() && this.challenge.getMaxTimes() > 0 &&
this.manager.getChallengeTimes(this.user, this.world, this.challenge) >= this.challenge.getMaxTimes()) this.manager.getChallengeTimes(this.user, this.world, this.challenge) >= this.challenge.getMaxTimes())
{ {
Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.not-repeatable")); Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.not-repeatable"));
result = EMPTY_RESULT; result = EMPTY_RESULT;
@ -729,7 +707,7 @@ public class TryToComplete
} }
// Check environment // Check environment
else if (!this.challenge.getEnvironment().isEmpty() && else if (!this.challenge.getEnvironment().isEmpty() &&
!this.challenge.getEnvironment().contains(this.user.getWorld().getEnvironment())) !this.challenge.getEnvironment().contains(this.user.getWorld().getEnvironment()))
{ {
Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.wrong-environment")); Utils.sendMessage(this.user, this.user.getTranslation("challenges.errors.wrong-environment"));
result = EMPTY_RESULT; result = EMPTY_RESULT;
@ -827,7 +805,7 @@ public class TryToComplete
{ {
String alert = "Running command '" + cmd + "' as " + this.user.getName(); String alert = "Running command '" + cmd + "' as " + this.user.getName();
this.addon.getLogger().info(alert); this.addon.getLogger().info(alert);
cmd = cmd.substring(6, cmd.length()).replace(Constants.PARAMETER_PLAYER, this.user.getName()).trim(); cmd = cmd.substring(6).replace(Constants.PARAMETER_PLAYER, this.user.getName()).trim();
try try
{ {
if (!user.performCommand(cmd)) if (!user.performCommand(cmd))
@ -896,7 +874,12 @@ public class TryToComplete
{ {
int numInInventory; int numInInventory;
if (this.getInventoryRequirements().getIgnoreMetaData().contains(required.getType())) if (this.user.getInventory() == null)
{
// Sanity check. User always has inventory at this point of code.
numInInventory = 0;
}
else if (this.getInventoryRequirements().getIgnoreMetaData().contains(required.getType()))
{ {
numInInventory = Arrays.stream(this.user.getInventory().getContents()). numInInventory = Arrays.stream(this.user.getInventory().getContents()).
filter(Objects::nonNull). filter(Objects::nonNull).
@ -951,7 +934,12 @@ public class TryToComplete
int amountToBeRemoved = required.getAmount() * factor; int amountToBeRemoved = required.getAmount() * factor;
List<ItemStack> itemsInInventory; List<ItemStack> itemsInInventory;
if (this.getInventoryRequirements().getIgnoreMetaData().contains(required.getType())) if (this.user.getInventory() == null)
{
// Sanity check. User always has inventory at this point of code.
itemsInInventory = Collections.emptyList();
}
else if (this.getInventoryRequirements().getIgnoreMetaData().contains(required.getType()))
{ {
// Use collecting method that ignores item meta. // Use collecting method that ignores item meta.
itemsInInventory = Arrays.stream(user.getInventory().getContents()). itemsInInventory = Arrays.stream(user.getInventory().getContents()).
@ -1065,14 +1053,14 @@ public class TryToComplete
// Protection code. Do not allow to select too large region for completing challenge. // Protection code. Do not allow to select too large region for completing challenge.
if (boundingBox.getWidthX() > distance * 2 + 3 || if (boundingBox.getWidthX() > distance * 2 + 3 ||
boundingBox.getWidthZ() > distance * 2 + 3 || boundingBox.getWidthZ() > distance * 2 + 3 ||
boundingBox.getHeight() > distance * 2 + 3) boundingBox.getHeight() > distance * 2 + 3)
{ {
this.addon.logError("BoundingBox is larger than SearchRadius. " + this.addon.logError("BoundingBox is larger than SearchRadius. " +
" | BoundingBox: " + boundingBox.toString() + " | BoundingBox: " + boundingBox +
" | Search Distance: " + requirements.getSearchRadius() + " | Search Distance: " + requirements.getSearchRadius() +
" | Location: " + this.user.getLocation().toString() + " | Location: " + this.user.getLocation() +
" | Center: " + island.getCenter().toString() + " | Center: " + island.getCenter() +
" | Range: " + range); " | Range: " + range);
return EMPTY_RESULT; return EMPTY_RESULT;
@ -1110,10 +1098,10 @@ public class TryToComplete
// This queue will contain only blocks whit required type ordered by distance till player. // This queue will contain only blocks whit required type ordered by distance till player.
Queue<Block> blockFromWorld = new PriorityQueue<>((o1, o2) -> { Queue<Block> blockFromWorld = new PriorityQueue<>((o1, o2) -> {
if (o1.getType().equals(o2.getType())) if (o1.getType().equals(o2.getType()) && this.user.getLocation() != null)
{ {
return Double.compare(o1.getLocation().distance(this.user.getLocation()), return Double.compare(o1.getLocation().distance(this.user.getLocation()),
o2.getLocation().distance(this.user.getLocation())); o2.getLocation().distance(this.user.getLocation()));
} }
else else
{ {
@ -1210,10 +1198,10 @@ public class TryToComplete
// Create queue that contains all required entities ordered by distance till player. // Create queue that contains all required entities ordered by distance till player.
Queue<Entity> entityQueue = new PriorityQueue<>((o1, o2) -> { Queue<Entity> entityQueue = new PriorityQueue<>((o1, o2) -> {
if (o1.getType().equals(o2.getType())) if (o1.getType().equals(o2.getType()) && this.user.getLocation() != null)
{ {
return Double.compare(o1.getLocation().distance(this.user.getLocation()), return Double.compare(o1.getLocation().distance(this.user.getLocation()),
o2.getLocation().distance(this.user.getLocation())); o2.getLocation().distance(this.user.getLocation()));
} }
else else
{ {
@ -1408,6 +1396,12 @@ public class TryToComplete
int currentValue; int currentValue;
if (requirements.getStatistic() == null)
{
// Sanity check.
return EMPTY_RESULT;
}
switch (requirements.getStatistic().getType()) switch (requirements.getStatistic().getType())
{ {
case UNTYPED -> currentValue = case UNTYPED -> currentValue =
@ -1454,7 +1448,10 @@ public class TryToComplete
if (inputMessage.contains("[") && inputMessage.contains("]")) if (inputMessage.contains("[") && inputMessage.contains("]"))
{ {
outputMessage = outputMessage.replace("[friendlyName]", challenge.getFriendlyName()); outputMessage = outputMessage.replace("[friendlyName]", challenge.getFriendlyName());
outputMessage = outputMessage.replace("[level]", challenge.getLevel().isEmpty() ? "" : this.manager.getLevel(challenge.getLevel()).getFriendlyName());
ChallengeLevel level = challenge.getLevel().isEmpty() ? null : this.manager.getLevel(challenge.getLevel());
outputMessage = outputMessage.replace("[level]", level == null ? "" : level.getFriendlyName());
outputMessage = outputMessage.replace("[rewardText]", challenge.getRewardText()); outputMessage = outputMessage.replace("[rewardText]", challenge.getRewardText());
} }

View File

@ -19,7 +19,7 @@ public class LevelStatus {
* @param previousLevel - previous level * @param previousLevel - previous level
* @param numberOfChallengesStillToDo - number of challenges still to do on this level * @param numberOfChallengesStillToDo - number of challenges still to do on this level
* @param complete - whether complete or not * @param complete - whether complete or not
* @param isUnlocked * @param isUnlocked - if level is unlocked or not.
*/ */
public LevelStatus(ChallengeLevel level, ChallengeLevel previousLevel, int numberOfChallengesStillToDo, boolean complete, boolean isUnlocked) { public LevelStatus(ChallengeLevel level, ChallengeLevel previousLevel, int numberOfChallengesStillToDo, boolean complete, boolean isUnlocked) {
super(); super();

View File

@ -63,7 +63,7 @@ public class Utils
i++; i++;
} }
if (isUnique && item != null) if (isUnique)
{ {
// The same issue as in other places. Clone prevents from changing original item. // The same issue as in other places. Clone prevents from changing original item.
returnItems.add(item.clone()); returnItems.add(item.clone());
@ -95,7 +95,7 @@ public class Utils
* @param <T> Instance of given object. * @param <T> Instance of given object.
* @return Next value after currentValue in values array. * @return Next value after currentValue in values array.
*/ */
public static <T extends Object> T getNextValue(T[] values, T currentValue) public static <T> T getNextValue(T[] values, T currentValue)
{ {
for (int i = 0; i < values.length; i++) for (int i = 0; i < values.length; i++)
{ {
@ -123,7 +123,7 @@ public class Utils
* @param <T> Instance of given object. * @param <T> Instance of given object.
* @return Previous value before currentValue in values array. * @return Previous value before currentValue in values array.
*/ */
public static <T extends Object> T getPreviousValue(T[] values, T currentValue) public static <T> T getPreviousValue(T[] values, T currentValue)
{ {
for (int i = 0; i < values.length; i++) for (int i = 0; i < values.length; i++)
{ {
@ -544,19 +544,15 @@ public class Utils
String translation; String translation;
switch (object.getType()) switch (object.getType())
{ {
case POTION, SPLASH_POTION, LINGERING_POTION, TIPPED_ARROW -> { case POTION, SPLASH_POTION, LINGERING_POTION, TIPPED_ARROW ->
// Get Potion Meta // Get Potion Meta
translation = prettifyObject(object, (PotionMeta) object.getItemMeta(), user); translation = prettifyObject(object, (PotionMeta) object.getItemMeta(), user);
} case PLAYER_HEAD, PLAYER_WALL_HEAD ->
case PLAYER_HEAD, PLAYER_WALL_HEAD -> {
translation = prettifyObject(object, (SkullMeta) object.getItemMeta(), user); translation = prettifyObject(object, (SkullMeta) object.getItemMeta(), user);
} case ENCHANTED_BOOK ->
case ENCHANTED_BOOK -> {
translation = prettifyObject(object, (EnchantmentStorageMeta) object.getItemMeta(), user); translation = prettifyObject(object, (EnchantmentStorageMeta) object.getItemMeta(), user);
} case WRITTEN_BOOK, WRITABLE_BOOK ->
case WRITTEN_BOOK, WRITABLE_BOOK -> {
translation = prettifyObject(object, (BookMeta) object.getItemMeta(), user); translation = prettifyObject(object, (BookMeta) object.getItemMeta(), user);
}
case LEATHER_BOOTS,LEATHER_CHESTPLATE,LEATHER_HELMET,LEATHER_LEGGINGS,LEATHER_HORSE_ARMOR, case LEATHER_BOOTS,LEATHER_CHESTPLATE,LEATHER_HELMET,LEATHER_LEGGINGS,LEATHER_HORSE_ARMOR,
TRIDENT,CROSSBOW,CHAINMAIL_HELMET,CHAINMAIL_CHESTPLATE,CHAINMAIL_LEGGINGS,CHAINMAIL_BOOTS,IRON_HELMET, TRIDENT,CROSSBOW,CHAINMAIL_HELMET,CHAINMAIL_CHESTPLATE,CHAINMAIL_LEGGINGS,CHAINMAIL_BOOTS,IRON_HELMET,
IRON_CHESTPLATE,IRON_LEGGINGS,IRON_BOOTS,DIAMOND_HELMET,DIAMOND_CHESTPLATE,DIAMOND_LEGGINGS,DIAMOND_BOOTS, IRON_CHESTPLATE,IRON_LEGGINGS,IRON_BOOTS,DIAMOND_HELMET,DIAMOND_CHESTPLATE,DIAMOND_LEGGINGS,DIAMOND_BOOTS,
@ -565,9 +561,8 @@ public class Utils
STONE_SWORD,STONE_SHOVEL,STONE_PICKAXE,STONE_AXE,STONE_HOE,GOLDEN_SWORD,GOLDEN_SHOVEL,GOLDEN_PICKAXE, STONE_SWORD,STONE_SHOVEL,STONE_PICKAXE,STONE_AXE,STONE_HOE,GOLDEN_SWORD,GOLDEN_SHOVEL,GOLDEN_PICKAXE,
GOLDEN_AXE,GOLDEN_HOE,IRON_SWORD,IRON_SHOVEL,IRON_PICKAXE,IRON_AXE,IRON_HOE,DIAMOND_SWORD,DIAMOND_SHOVEL, GOLDEN_AXE,GOLDEN_HOE,IRON_SWORD,IRON_SHOVEL,IRON_PICKAXE,IRON_AXE,IRON_HOE,DIAMOND_SWORD,DIAMOND_SHOVEL,
DIAMOND_PICKAXE,DIAMOND_AXE,DIAMOND_HOE,NETHERITE_SWORD,NETHERITE_SHOVEL,NETHERITE_PICKAXE,NETHERITE_AXE, DIAMOND_PICKAXE,DIAMOND_AXE,DIAMOND_HOE,NETHERITE_SWORD,NETHERITE_SHOVEL,NETHERITE_PICKAXE,NETHERITE_AXE,
NETHERITE_HOE,TURTLE_HELMET,SHEARS,SHIELD,FLINT_AND_STEEL,BOW -> { NETHERITE_HOE,TURTLE_HELMET,SHEARS,SHIELD,FLINT_AND_STEEL,BOW ->
translation = prettifyObject(object, object.getItemMeta(), user); translation = prettifyObject(object, object.getItemMeta(), user);
}
default -> default ->
translation = ""; translation = "";
} }