mirror of
https://github.com/BentoBoxWorld/Challenges.git
synced 2024-11-28 13:36:06 +01:00
Add validation methods to challenge and challengeLevel.
Do not load into local cache invalid data. Add error warnings about it.
This commit is contained in:
parent
7060799bcc
commit
504c0b410e
@ -279,6 +279,17 @@ public class ChallengesManager
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!challenge.isValid())
|
||||||
|
{
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
user.sendMessage("challenges.errors.invalid-challenge", "[challenge]", challenge.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addon.logWarning("Data for challenge `" + challenge.getUniqueId() + "` is not valid. It could be NULL element in item-stack!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.challengeCacheData.containsKey(challenge.getUniqueId()))
|
if (this.challengeCacheData.containsKey(challenge.getUniqueId()))
|
||||||
{
|
{
|
||||||
if (!overwrite)
|
if (!overwrite)
|
||||||
@ -352,6 +363,17 @@ public class ChallengesManager
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!level.isValid())
|
||||||
|
{
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
user.sendMessage("challenges.errors.invalid-level", "[level]", level.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addon.logWarning("Data for level `" + level.getUniqueId() + "` is not valid. It could be NULL element in item-stack!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.isValidLevel(level))
|
if (!this.isValidLevel(level))
|
||||||
{
|
{
|
||||||
if (user != null)
|
if (user != null)
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
package world.bentobox.challenges.database.object;
|
package world.bentobox.challenges.database.object;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -18,6 +13,7 @@ import org.eclipse.jdt.annotation.NonNull;
|
|||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
|
|
||||||
|
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.EntityCompatibilityAdapter;
|
||||||
@ -1104,6 +1100,32 @@ public class Challenge implements DataObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if variable values are valid for current level.
|
||||||
|
* @return {@code true} if all object values are valid, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isValid()
|
||||||
|
{
|
||||||
|
return this.uniqueId != null &&
|
||||||
|
!this.uniqueId.isEmpty() &&
|
||||||
|
this.friendlyName != null &&
|
||||||
|
this.description != null &&
|
||||||
|
this.icon != null &&
|
||||||
|
this.challengeType != null &&
|
||||||
|
this.environment != null &&
|
||||||
|
this.level != null &&
|
||||||
|
|
||||||
|
this.requirements.isValid() &&
|
||||||
|
|
||||||
|
this.rewardText != null &&
|
||||||
|
this.rewardItems.stream().noneMatch(Objects::isNull) &&
|
||||||
|
this.rewardCommands != null &&
|
||||||
|
|
||||||
|
this.repeatRewardText != null &&
|
||||||
|
this.repeatItemReward.stream().noneMatch(Objects::isNull) &&
|
||||||
|
this.repeatRewardCommands != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone method that returns clone of current challenge.
|
* Clone method that returns clone of current challenge.
|
||||||
* @return Challenge that is cloned from current object.
|
* @return Challenge that is cloned from current object.
|
||||||
@ -1114,13 +1136,8 @@ public class Challenge implements DataObject
|
|||||||
Challenge clone;
|
Challenge clone;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
|
||||||
clone = (Challenge) super.clone();
|
|
||||||
}
|
|
||||||
catch (CloneNotSupportedException e)
|
|
||||||
{
|
{
|
||||||
clone = new Challenge();
|
clone = new Challenge();
|
||||||
|
|
||||||
clone.setUniqueId(this.uniqueId);
|
clone.setUniqueId(this.uniqueId);
|
||||||
clone.setFriendlyName(this.friendlyName);
|
clone.setFriendlyName(this.friendlyName);
|
||||||
clone.setDeployed(this.deployed);
|
clone.setDeployed(this.deployed);
|
||||||
@ -1133,7 +1150,9 @@ public class Challenge implements DataObject
|
|||||||
clone.setRemoveWhenCompleted(this.removeWhenCompleted);
|
clone.setRemoveWhenCompleted(this.removeWhenCompleted);
|
||||||
clone.setRequirements(this.requirements.clone());
|
clone.setRequirements(this.requirements.clone());
|
||||||
clone.setRewardText(this.rewardText);
|
clone.setRewardText(this.rewardText);
|
||||||
clone.setRewardItems(this.rewardItems.stream().map(ItemStack::clone).
|
clone.setRewardItems(
|
||||||
|
this.rewardItems.stream().
|
||||||
|
map(ItemStack::clone).
|
||||||
collect(Collectors.toCollection(() -> new ArrayList<>(this.rewardItems.size()))));
|
collect(Collectors.toCollection(() -> new ArrayList<>(this.rewardItems.size()))));
|
||||||
clone.setRewardExperience(this.rewardExperience);
|
clone.setRewardExperience(this.rewardExperience);
|
||||||
clone.setRewardMoney(this.rewardMoney);
|
clone.setRewardMoney(this.rewardMoney);
|
||||||
@ -1142,11 +1161,20 @@ public class Challenge implements DataObject
|
|||||||
clone.setRepeatRewardText(this.repeatRewardText);
|
clone.setRepeatRewardText(this.repeatRewardText);
|
||||||
clone.setMaxTimes(this.maxTimes);
|
clone.setMaxTimes(this.maxTimes);
|
||||||
clone.setRepeatExperienceReward(this.repeatExperienceReward);
|
clone.setRepeatExperienceReward(this.repeatExperienceReward);
|
||||||
clone.setRepeatItemReward(this.repeatItemReward.stream().map(ItemStack::clone).
|
clone.setRepeatItemReward(
|
||||||
|
this.repeatItemReward.stream().
|
||||||
|
map(ItemStack::clone).
|
||||||
collect(Collectors.toCollection(() -> new ArrayList<>(this.repeatItemReward.size()))));
|
collect(Collectors.toCollection(() -> new ArrayList<>(this.repeatItemReward.size()))));
|
||||||
clone.setRepeatMoneyReward(this.repeatMoneyReward);
|
clone.setRepeatMoneyReward(this.repeatMoneyReward);
|
||||||
clone.setRepeatRewardCommands(new ArrayList<>(this.repeatRewardCommands));
|
clone.setRepeatRewardCommands(new ArrayList<>(this.repeatRewardCommands));
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
BentoBox.getInstance().logError("Failed to clone Challenge " + this.uniqueId);
|
||||||
|
BentoBox.getInstance().logStacktrace(e);
|
||||||
|
clone = this;
|
||||||
|
this.deployed = false;
|
||||||
|
}
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package world.bentobox.challenges.database.object;
|
package world.bentobox.challenges.database.object;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -12,11 +9,13 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.configuration.ConfigComment;
|
import world.bentobox.bentobox.api.configuration.ConfigComment;
|
||||||
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.ChallengesManager;
|
import world.bentobox.challenges.ChallengesManager;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent a challenge level
|
* Represent a challenge level
|
||||||
* @author tastybento
|
* @author tastybento
|
||||||
@ -520,6 +519,25 @@ public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if variable values are valid for current level.
|
||||||
|
* @return {@code true} if all object values are valid, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isValid()
|
||||||
|
{
|
||||||
|
return this.uniqueId != null &&
|
||||||
|
!this.uniqueId.isEmpty() &&
|
||||||
|
this.friendlyName != null &&
|
||||||
|
this.challenges != null &&
|
||||||
|
this.icon != null &&
|
||||||
|
this.world != null &&
|
||||||
|
this.unlockMessage != null &&
|
||||||
|
this.rewardText != null &&
|
||||||
|
this.rewardItems.stream().noneMatch(Objects::isNull) &&
|
||||||
|
this.rewardCommands != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
@ -527,15 +545,10 @@ public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
|
|||||||
@Override
|
@Override
|
||||||
public ChallengeLevel clone()
|
public ChallengeLevel clone()
|
||||||
{
|
{
|
||||||
ChallengeLevel clone;
|
ChallengeLevel clone = new ChallengeLevel();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
clone = (ChallengeLevel) super.clone();
|
|
||||||
}
|
|
||||||
catch (CloneNotSupportedException e)
|
|
||||||
{
|
|
||||||
clone = new ChallengeLevel();
|
|
||||||
clone.setUniqueId(this.uniqueId);
|
clone.setUniqueId(this.uniqueId);
|
||||||
clone.setFriendlyName(this.friendlyName);
|
clone.setFriendlyName(this.friendlyName);
|
||||||
clone.setIcon(this.icon.clone());
|
clone.setIcon(this.icon.clone());
|
||||||
@ -545,12 +558,21 @@ public class ChallengeLevel implements DataObject, Comparable<ChallengeLevel>
|
|||||||
clone.setWaiverAmount(this.waiverAmount);
|
clone.setWaiverAmount(this.waiverAmount);
|
||||||
clone.setUnlockMessage(this.unlockMessage);
|
clone.setUnlockMessage(this.unlockMessage);
|
||||||
clone.setRewardText(this.rewardText);
|
clone.setRewardText(this.rewardText);
|
||||||
clone.setRewardItems(this.rewardItems.stream().map(ItemStack::clone).collect(Collectors.toCollection(() -> new ArrayList<>(this.rewardItems.size()))));
|
clone.setRewardItems(
|
||||||
|
this.rewardItems.stream().
|
||||||
|
map(ItemStack::clone).
|
||||||
|
collect(Collectors.toCollection(() -> new ArrayList<>(this.rewardItems.size()))));
|
||||||
clone.setRewardExperience(this.rewardExperience);
|
clone.setRewardExperience(this.rewardExperience);
|
||||||
clone.setRewardMoney(this.rewardMoney);
|
clone.setRewardMoney(this.rewardMoney);
|
||||||
clone.setRewardCommands(new ArrayList<>(this.rewardCommands));
|
clone.setRewardCommands(new ArrayList<>(this.rewardCommands));
|
||||||
clone.setChallenges(new HashSet<>(this.challenges));
|
clone.setChallenges(new HashSet<>(this.challenges));
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
BentoBox.getInstance().logError("Failed to clone ChallengeLevel " + this.uniqueId);
|
||||||
|
BentoBox.getInstance().logStacktrace(e);
|
||||||
|
clone = this;
|
||||||
|
}
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ package world.bentobox.challenges.database.object.requirements;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -85,6 +86,19 @@ public class InventoryRequirements extends Requirements
|
|||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method isValid returns if given requirement data is valid or not.
|
||||||
|
*
|
||||||
|
* @return {@code true} if data is valid, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isValid()
|
||||||
|
{
|
||||||
|
return super.isValid() &&
|
||||||
|
this.requiredItems != null && this.requiredItems.stream().noneMatch(Objects::isNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary
|
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary
|
||||||
* to use it.
|
* to use it.
|
||||||
|
@ -7,10 +7,7 @@
|
|||||||
package world.bentobox.challenges.database.object.requirements;
|
package world.bentobox.challenges.database.object.requirements;
|
||||||
|
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
@ -153,6 +150,20 @@ public class IslandRequirements extends Requirements
|
|||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method isValid returns if given requirement data is valid or not.
|
||||||
|
*
|
||||||
|
* @return {@code true} if data is valid, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isValid()
|
||||||
|
{
|
||||||
|
return super.isValid() &&
|
||||||
|
this.requiredBlocks != null && this.requiredBlocks.keySet().stream().noneMatch(Objects::isNull) &&
|
||||||
|
this.requiredEntities != null && this.requiredEntities.keySet().stream().noneMatch(Objects::isNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary
|
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary
|
||||||
* to use it.
|
* to use it.
|
||||||
|
@ -59,6 +59,16 @@ public abstract class Requirements
|
|||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method isValid returns if given requirement data is valid or not.
|
||||||
|
* @return {@code true} if data is valid, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isValid()
|
||||||
|
{
|
||||||
|
return this.requiredPermissions != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary
|
* Method Requirements#clone allows to clone Requirements object, to avoid changing content when it is necessary
|
||||||
* to use it.
|
* to use it.
|
||||||
|
@ -1006,11 +1006,13 @@ public abstract class CommonGUI
|
|||||||
}
|
}
|
||||||
else if (meta instanceof TropicalFishBucketMeta)
|
else if (meta instanceof TropicalFishBucketMeta)
|
||||||
{
|
{
|
||||||
result.add(this.user.getTranslation("challenges.gui.item-description.fish-meta",
|
if (((TropicalFishBucketMeta) meta).hasVariant())
|
||||||
|
{
|
||||||
|
result.add(this.user.getTranslation("challenges.gui.item-description.fish-meta",
|
||||||
"[pattern]", Util.prettifyText(((TropicalFishBucketMeta) meta).getPattern().name()),
|
"[pattern]", Util.prettifyText(((TropicalFishBucketMeta) meta).getPattern().name()),
|
||||||
"[pattern-color]", Util.prettifyText(((TropicalFishBucketMeta) meta).getPatternColor().name()),
|
"[pattern-color]", Util.prettifyText(((TropicalFishBucketMeta) meta).getPatternColor().name()),
|
||||||
"[body-color]", Util.prettifyText(((TropicalFishBucketMeta) meta).getBodyColor().name())));
|
"[body-color]", Util.prettifyText(((TropicalFishBucketMeta) meta).getBodyColor().name())));
|
||||||
// parse ne
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta.hasEnchants())
|
if (meta.hasEnchants())
|
||||||
|
@ -595,6 +595,8 @@ challenges:
|
|||||||
missing-level: '&c Challenge Level [level] is not defined in the database. It may cause errors!'
|
missing-level: '&c Challenge Level [level] is not defined in the database. It may cause errors!'
|
||||||
missing-arguments: '&c Command is missing arguments.'
|
missing-arguments: '&c Command is missing arguments.'
|
||||||
no-multiple-permission: "&c You do not have permission to complete this challenge multiple times at once."
|
no-multiple-permission: "&c You do not have permission to complete this challenge multiple times at once."
|
||||||
|
invalid-level: "&c Level [level] contains invalid data. It will not be loaded from database!"
|
||||||
|
invalid-challenge: "&c Challenge [challenge] contains invalid data. It will not be loaded from database!"
|
||||||
protection:
|
protection:
|
||||||
flags:
|
flags:
|
||||||
CHALLENGES_ISLAND_PROTECTION:
|
CHALLENGES_ISLAND_PROTECTION:
|
||||||
|
Loading…
Reference in New Issue
Block a user