diff --git a/README.md b/README.md
index f95d526..e8e3dee 100644
--- a/README.md
+++ b/README.md
@@ -7,14 +7,12 @@ Add-on for BentoBox to provide challenges for any BentoBox GameMode.
## Where to find
Currently Challenges Addon is in **Beta stage**, so it may or may not contain bugs... a lot of bugs. Also it means, that some features are not working or implemented.
-Latest official **Beta Release is 0.8.1**, and you can download it from [Release tab](https://github.com/BentoBoxWorld/Challenges/releases)
-But it will work with BentoBox 1.6.x and BentoBox 1.7.x.
+Latest official **Beta Release is 0.8.3**, and you can download it from [Release tab](https://github.com/BentoBoxWorld/Challenges/releases)
+But it will work with BentoBox 1.14.
-Latest development builds will be based on **Minecraft 1.14.4** and **BentoBox 1.8.0**.
+Latest development builds will be based on **Minecraft 1.16.1** and **BentoBox 1.14.0**.
**Nightly builds** are available in [Jenkins Server](https://ci.codemc.org/job/BentoBoxWorld/job/Challenges/lastStableBuild/).
-Be aware that 0.8.0 stores data differently than it is in 0.7.5 and below. It will be necessary to migrate data via command `/[gamemode_admin] challenges migrate`.
-
If you like this addon but something is missing or is not working as you want, you can always submit an [Issue request](https://github.com/BentoBoxWorld/Challenges/issues) or get a support in Discord [BentoBox ![icon](https://avatars2.githubusercontent.com/u/41555324?s=15&v=4)](https://discord.bentobox.world)
## Translations
@@ -38,7 +36,7 @@ There exist also Web Library, where users can download public challenges. It is
## Compatibility
-- [x] BentoBox - 1.6.x and 1.7.x versions
+- [x] BentoBox - 1.14 versions
- [x] BSkyBlock
- [x] AcidIsland
- [x] SkyGrid
@@ -46,4 +44,4 @@ There exist also Web Library, where users can download public challenges. It is
## Information
-More information can be found in [Wiki Pages](https://github.com/BentoBoxWorld/Challenges/wiki).
+More information can be found in [Wiki Pages](https://docs.bentobox.world/addons/Challenges/).
diff --git a/pom.xml b/pom.xml
index bc35c4d..ca3beb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,14 +35,14 @@
1.8
2.0.2
- 1.14.4-R0.1-SNAPSHOT
- 1.7.0
+ 1.15.2-R0.1-SNAPSHOT
+ 1.14.0
1.6.0
1.7
${build.version}-SNAPSHOT
- 0.8.2
+ 0.8.3
-LOCAL
diff --git a/src/main/java/world/bentobox/challenges/ChallengesAddon.java b/src/main/java/world/bentobox/challenges/ChallengesAddon.java
index e2fd286..8436dc5 100644
--- a/src/main/java/world/bentobox/challenges/ChallengesAddon.java
+++ b/src/main/java/world/bentobox/challenges/ChallengesAddon.java
@@ -179,6 +179,9 @@ public class ChallengesAddon extends Addon {
CHALLENGES_ISLAND_PROTECTION.addGameModeAddon(gameModeAddon);
this.registerPlaceholders(gameModeAddon);
+
+ // TODO: this is old placeholders. Remove when backward compatibility ends.
+ this.registerPlaceholdersOld(gameModeAddon);
}
});
@@ -283,7 +286,14 @@ public class ChallengesAddon extends Addon {
if (this.hooked) {
this.challengesManager.save();
}
+ }
+
+ /**
+ * This method saves addon settings into file.
+ */
+ public void saveSettings()
+ {
if (this.settings != null)
{
new Config<>(this, Settings.class).saveConfigObject(this.settings);
@@ -320,6 +330,93 @@ public class ChallengesAddon extends Addon {
* @param gameModeAddon GameMode addon where placeholders must be hooked in.
*/
private void registerPlaceholders(GameModeAddon gameModeAddon)
+ {
+ final String addonName = this.getDescription().getName().toLowerCase();
+ final World world = gameModeAddon.getOverWorld();
+
+ // Number of completions for all challenges placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_total_completion_count",
+ user -> String.valueOf(this.challengesManager.getTotalChallengeCompletionCount(user, world)));
+
+ // Completed challenge count placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_completed_count",
+ user -> String.valueOf(this.challengesManager.getCompletedChallengeCount(user, world)));
+
+ // Uncompleted challenge count placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_uncompleted_count",
+ user -> String.valueOf(this.challengesManager.getChallengeCount(world) -
+ this.challengesManager.getCompletedChallengeCount(user, world)));
+
+ // Completed challenge level count placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_completed_level_count",
+ user -> String.valueOf(this.challengesManager.getCompletedLevelCount(user, world)));
+
+ // Uncompleted challenge level count placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_uncompleted_level_count",
+ user -> String.valueOf(this.challengesManager.getLevelCount(world) -
+ this.challengesManager.getCompletedLevelCount(user, world)));
+
+ // Unlocked challenge level count placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_unlocked_level_count",
+ user -> String.valueOf(this.challengesManager.getLevelCount(world) -
+ this.challengesManager.getUnlockedLevelCount(user, world)));
+
+ // Locked challenge level count placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_locked_level_count",
+ user -> String.valueOf(this.challengesManager.getLevelCount(world) -
+ this.challengesManager.getUnlockedLevelCount(user, world)));
+
+ // Latest challenge level name placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_latest_level_name",
+ user -> {
+ ChallengeLevel level = this.challengesManager.getLatestUnlockedLevel(user, world);
+ return level != null ? level.getFriendlyName() : "";
+ });
+
+ // Latest challenge level id placeholder
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_latest_level_id",
+ user -> {
+ ChallengeLevel level = this.challengesManager.getLatestUnlockedLevel(user, world);
+ return level != null ? level.getUniqueId() : "";
+ });
+
+ // Completed challenge count in latest level
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_latest_level_completed_count",
+ user -> {
+ ChallengeLevel level = this.challengesManager.getLatestUnlockedLevel(user, world);
+ return String.valueOf(level != null ?
+ this.challengesManager.getLevelCompletedChallengeCount(user, world, level) : 0);
+ });
+
+ // Uncompleted challenge count in latest level
+ this.getPlugin().getPlaceholdersManager().registerPlaceholder(gameModeAddon,
+ addonName + "_latest_level_uncompleted_count",
+ user -> {
+ ChallengeLevel level = this.challengesManager.getLatestUnlockedLevel(user, world);
+ return String.valueOf(level != null ?
+ level.getChallenges().size() - this.challengesManager.getLevelCompletedChallengeCount(user, world, level) : 0);
+ });
+ }
+
+
+ /**
+ * This method registers placeholders into GameMode addon.
+ * @param gameModeAddon GameMode addon where placeholders must be hooked in.
+ * @since 0.8.1
+ * @deprecated remove after 0.9.0
+ */
+ @Deprecated
+ private void registerPlaceholdersOld(GameModeAddon gameModeAddon)
{
final String gameMode = gameModeAddon.getDescription().getName().toLowerCase();
final World world = gameModeAddon.getOverWorld();
diff --git a/src/main/java/world/bentobox/challenges/ChallengesImportManager.java b/src/main/java/world/bentobox/challenges/ChallengesImportManager.java
index e0feb65..36b5655 100644
--- a/src/main/java/world/bentobox/challenges/ChallengesImportManager.java
+++ b/src/main/java/world/bentobox/challenges/ChallengesImportManager.java
@@ -126,7 +126,8 @@ public class ChallengesImportManager
return false;
}
- this.addon.getChallengesManager().save();
+ this.addon.getChallengesManager().saveChallenges();
+ this.addon.getChallengesManager().saveLevels();
if (removeAtEnd)
{
@@ -203,7 +204,8 @@ public class ChallengesImportManager
return false;
}
- this.addon.getChallengesManager().save();
+ this.addon.getChallengesManager().saveChallenges();
+ this.addon.getChallengesManager().saveLevels();
return true;
}
diff --git a/src/main/java/world/bentobox/challenges/ChallengesManager.java b/src/main/java/world/bentobox/challenges/ChallengesManager.java
index 26e7653..6be8e14 100644
--- a/src/main/java/world/bentobox/challenges/ChallengesManager.java
+++ b/src/main/java/world/bentobox/challenges/ChallengesManager.java
@@ -206,11 +206,15 @@ public class ChallengesManager
}
this.playerCacheData.clear();
- loadAndValidate();
+ this.loadAndValidate();
}
- private void loadAndValidate() {
+ /**
+ * This method loads and validates all challenges and levels.
+ */
+ private void loadAndValidate()
+ {
this.challengeDatabase.loadObjects().forEach(this::loadChallenge);
this.levelDatabase.loadObjects().forEach(this::loadLevel);
// this validate challenge levels
@@ -233,7 +237,7 @@ public class ChallengesManager
//this.levelDatabase = new Database<>(addon, ChallengeLevel.class);
//this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class);
- loadAndValidate();
+ this.loadAndValidate();
}
@@ -263,6 +267,18 @@ public class ChallengesManager
User user,
boolean silent)
{
+ // This may happen if database somehow failed to load challenge and return
+ // null as input.
+ if (challenge == null)
+ {
+ if (!silent)
+ {
+ user.sendMessage("load-error", "[value]", "NULL");
+ }
+
+ return false;
+ }
+
if (this.challengeCacheData.containsKey(challenge.getUniqueId()))
{
if (!overwrite)
@@ -324,6 +340,18 @@ public class ChallengesManager
User user,
boolean silent)
{
+ // This may happen if database somehow failed to load challenge and return
+ // null as input.
+ if (level == null)
+ {
+ if (!silent)
+ {
+ user.sendMessage("load-error", "[value]", "NULL");
+ }
+
+ return false;
+ }
+
if (!this.isValidLevel(level))
{
if (user != null)
@@ -402,12 +430,15 @@ public class ChallengesManager
*/
public void removeFromCache(UUID playerID)
{
- if (!this.settings.isStoreAsIslandData() && this.playerCacheData.containsKey(playerID.toString()))
- {
- // save before remove
- this.savePlayerData(playerID.toString());
- this.playerCacheData.remove(playerID.toString());
- }
+// Remove due possible issues with saving... (#246)
+// if (!this.settings.isStoreAsIslandData() && this.playerCacheData.containsKey(playerID.toString()))
+// {
+// // save before remove
+// this.savePlayerData(playerID.toString());
+// this.playerCacheData.remove(playerID.toString());
+// }
+
+ this.savePlayerData(playerID.toString());
// TODO: It would be necessary to remove also data, if they stores islands.
// Unfortunately, I do not know all worlds. Checking everything would be bad. Probably, I could
@@ -474,11 +505,8 @@ public class ChallengesManager
{
if (!this.challengeCacheData.containsKey(uniqueID))
{
- if (this.challengeDatabase.objectExists(uniqueID))
- {
- this.loadChallenge(this.challengeDatabase.loadObject(uniqueID));
- }
- else
+ if (!this.challengeDatabase.objectExists(uniqueID) ||
+ !this.loadChallenge(this.challengeDatabase.loadObject(uniqueID), false, null, true))
{
this.addon.logError("Cannot find " + uniqueID + " challenge for " + level.getUniqueId());
return false;
@@ -524,7 +552,7 @@ public class ChallengesManager
{
// Create the player data
ChallengesPlayerData pd = new ChallengesPlayerData(uniqueID);
- this.playersDatabase.saveObject(pd);
+ this.playersDatabase.saveObjectAsync(pd);
// Add to cache
this.playerCacheData.put(uniqueID, pd);
}
@@ -671,7 +699,7 @@ public class ChallengesManager
challengesID.forEach(challenge ->
level.getChallenges().add(addonName + challenge.substring(world.getName().length())));
- this.levelDatabase.saveObject(level);
+ this.levelDatabase.saveObjectAsync(level);
this.levelCacheData.put(level.getUniqueId(), level);
updated = true;
@@ -715,7 +743,7 @@ public class ChallengesManager
updated = true;
- this.challengeDatabase.saveObject(challenge);
+ this.challengeDatabase.saveObjectAsync(challenge);
this.challengeCacheData.put(challenge.getUniqueId(), challenge);
}
@@ -758,7 +786,7 @@ public class ChallengesManager
// This save should not involve any upgrades in other parts.
- this.challengeDatabase.saveObject(challenge);
+ this.challengeDatabase.saveObjectAsync(challenge);
this.challengeCacheData.put(challenge.getUniqueId(), challenge);
}
}
@@ -809,7 +837,7 @@ public class ChallengesManager
}
});
- this.playersDatabase.saveObject(playerData);
+ this.playersDatabase.saveObjectAsync(playerData);
});
}
@@ -824,8 +852,11 @@ public class ChallengesManager
*/
public void save()
{
- this.saveChallenges();
- this.saveLevels();
+ // Challenges and Levels are saved on modifications only to avoid issues with
+ // NULL's in data after interrupting server while in saving stage.
+ // this.saveChallenges();
+ // this.saveLevels();
+
this.savePlayersData();
}
@@ -833,9 +864,9 @@ public class ChallengesManager
/**
* This method saves all challenges to database.
*/
- private void saveChallenges()
+ public void saveChallenges()
{
- this.challengeCacheData.values().forEach(this.challengeDatabase::saveObject);
+ this.challengeCacheData.values().forEach(this::saveChallenge);
}
@@ -845,16 +876,16 @@ public class ChallengesManager
*/
public void saveChallenge(Challenge challenge)
{
- this.challengeDatabase.saveObject(challenge);
+ this.challengeDatabase.saveObjectAsync(challenge);
}
/**
* This method saves all levels to database.
*/
- private void saveLevels()
+ public void saveLevels()
{
- this.levelCacheData.values().forEach(this.levelDatabase::saveObject);
+ this.levelCacheData.values().forEach(this::saveLevel);
}
@@ -864,7 +895,7 @@ public class ChallengesManager
*/
public void saveLevel(ChallengeLevel level)
{
- this.levelDatabase.saveObject(level);
+ this.levelDatabase.saveObjectAsync(level);
}
@@ -873,7 +904,7 @@ public class ChallengesManager
*/
private void savePlayersData()
{
- this.playerCacheData.values().forEach(this.playersDatabase::saveObject);
+ this.playerCacheData.values().forEach(this.playersDatabase::saveObjectAsync);
}
@@ -902,7 +933,7 @@ public class ChallengesManager
}
}
- this.playersDatabase.saveObject(cachedData);
+ this.playersDatabase.saveObjectAsync(cachedData);
}
}
@@ -1053,7 +1084,20 @@ public class ChallengesManager
private void resetAllChallenges(@NonNull String storageDataID, @NonNull String gameMode)
{
this.addPlayerData(storageDataID);
- this.playerCacheData.get(storageDataID).reset(gameMode);
+
+ if (this.playerCacheData.containsKey(storageDataID))
+ {
+ // There may be a rare situation when player data cannot be loaded. Just avoid
+ // error.
+ this.playerCacheData.get(storageDataID).reset(gameMode);
+ }
+ else
+ {
+ // If object cannot be loaded remove it completely.
+ this.playersDatabase.deleteID(storageDataID);
+ this.addon.logError("Database object was not loaded. It is removed completely. Object Id: " + storageDataID);
+ }
+
// Save
this.savePlayerData(storageDataID);
}
@@ -1079,6 +1123,7 @@ public class ChallengesManager
// The first level is always unlocked and previous for it is null.
ChallengeLevel previousLevel = null;
int doneChallengeCount = 0;
+ boolean previousUnlocked = true;
// For each challenge level, check how many the storageDataID has done
for (ChallengeLevel level : challengeLevelList)
@@ -1088,20 +1133,25 @@ public class ChallengesManager
// remove waiver amount to get count of challenges that still necessary to do.
int challengesToDo = previousLevel == null ? 0 :
- (previousLevel.getChallenges().size() - doneChallengeCount - level.getWaiverAmount());
+ (previousLevel.getChallenges().size() - doneChallengeCount - previousLevel.getWaiverAmount());
// As level already contains unique ids of challenges, just iterate through them.
doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count();
+ // Mark if level is unlocked
+ boolean unlocked = previousUnlocked && challengesToDo <= 0;
+
result.add(new LevelStatus(
level,
previousLevel,
challengesToDo,
level.getChallenges().size() == doneChallengeCount,
- challengesToDo <= 0));
+ unlocked));
previousLevel = level;
+ previousUnlocked = unlocked;
}
+
return result;
}
@@ -1132,7 +1182,7 @@ public class ChallengesManager
ChallengeLevel previousLevel = levelIndex < 1 ? null : challengeLevelList.get(levelIndex - 1);
int challengesToDo = previousLevel == null ? 0 :
- (previousLevel.getChallenges().size() - level.getWaiverAmount()) -
+ (previousLevel.getChallenges().size() - previousLevel.getWaiverAmount()) -
(int) previousLevel.getChallenges().stream().filter(playerData::isChallengeDone).count();
// As level already contains unique ids of challenges, just iterate through them.
@@ -1362,7 +1412,7 @@ public class ChallengesManager
* @param world - World where challenges must be reset.
* @param adminID - admin iD
*/
- public void resetAllChallenges(UUID userID, World world, UUID adminID)
+ public void resetAllChallenges(@NonNull UUID userID, World world, @Nullable UUID adminID)
{
String storageID = this.getDataUniqueID(userID, Util.getWorld(world));
@@ -1526,12 +1576,12 @@ public class ChallengesManager
LevelStatus lastStatus = null;
for (Iterator statusIterator = this.getAllChallengeLevelStatus(user, world).iterator();
- statusIterator.hasNext() && (lastStatus == null || !lastStatus.isUnlocked());)
+ statusIterator.hasNext() && (lastStatus == null || lastStatus.isUnlocked());)
{
lastStatus = statusIterator.next();
}
- return lastStatus != null ? lastStatus.getLevel() : null;
+ return lastStatus != null ? lastStatus.getPreviousLevel() : null;
}
@@ -1752,6 +1802,21 @@ public class ChallengesManager
}
+ /**
+ * This method returns completed challenge count in given level.
+ * @param user User which should be checked
+ * @param world World where challenges are operating
+ * @param level Level which challenges must be checked.
+ * @return Number of completed challenges in given level.
+ */
+ public long getLevelCompletedChallengeCount(User user, World world, ChallengeLevel level)
+ {
+ return this.getLevelChallenges(level).stream().
+ filter(challenge -> this.getChallengeTimes(user, world, challenge) > 0).
+ count();
+ }
+
+
// ---------------------------------------------------------------------
// Section: Level related methods
// ---------------------------------------------------------------------
diff --git a/src/main/java/world/bentobox/challenges/config/Settings.java b/src/main/java/world/bentobox/challenges/config/Settings.java
index 49df416..2332b46 100644
--- a/src/main/java/world/bentobox/challenges/config/Settings.java
+++ b/src/main/java/world/bentobox/challenges/config/Settings.java
@@ -1,7 +1,7 @@
package world.bentobox.challenges.config;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -34,14 +34,14 @@ public class Settings implements ConfigObject
@ConfigComment("Allows to define common challenges command that will open User GUI")
@ConfigComment("with all GameMode selection or Challenges from user world.")
@ConfigComment("This will not affect /{gamemode_user} challenges command.")
- @ConfigEntry(path = "commands.user", needsReset = true)
+ @ConfigEntry(path = "commands.user", needsRestart = true)
private String userCommand = "challenges c";
@ConfigComment("")
@ConfigComment("Allows to define common challenges command that will open Admin GUI")
@ConfigComment("with all GameMode selection.")
@ConfigComment("This will not affect /{gamemode_admin} challenges command.")
- @ConfigEntry(path = "commands.admin", needsReset = true)
+ @ConfigEntry(path = "commands.admin", needsRestart = true)
private String adminCommand = "challengesadmin chadmin";
@ConfigComment("")
@@ -49,7 +49,7 @@ public class Settings implements ConfigObject
@ConfigComment("all GameModes. For admins it will open selection with all GameModes")
@ConfigComment("(unless there is one), but for users it will open GUI that corresponds")
@ConfigComment("to their world (unless it is specified other way in Admin GUI).")
- @ConfigEntry(path = "commands.single-gui", needsReset = true)
+ @ConfigEntry(path = "commands.single-gui", needsRestart = true)
private boolean useCommonGUI = false;
@ConfigComment("")
@@ -130,7 +130,7 @@ public class Settings implements ConfigObject
@ConfigComment("Requirement and reward items, blocks and entities that are defined in challenge and can be customized under 'challenges.gui.item-description.*'")
@ConfigEntry(path = "gui-settings.challenge-lore")
@Adapter(ChallengeLoreAdapter.class)
- private List challengeLoreMessage = new ArrayList<>();
+ private List challengeLoreMessage = Arrays.asList(ChallengeLore.values());
@ConfigComment("")
@ConfigComment("This string allows to change element order in Level description. Each letter represents")
@@ -149,7 +149,7 @@ public class Settings implements ConfigObject
@ConfigComment("Reward items that are defined in challenge level and can be customized under 'challenges.gui.item-description.*'")
@ConfigEntry(path = "gui-settings.level-lore")
@Adapter(LevelLoreAdapter.class)
- private List levelLoreMessage = new ArrayList<>();
+ private List levelLoreMessage = Arrays.asList(LevelLore.values());
@ConfigComment("")
@ConfigComment("This indicate if challenges data will be stored per island (true) or per player (false).")
diff --git a/src/main/java/world/bentobox/challenges/database/object/Challenge.java b/src/main/java/world/bentobox/challenges/database/object/Challenge.java
index cff291f..a8990cc 100644
--- a/src/main/java/world/bentobox/challenges/database/object/Challenge.java
+++ b/src/main/java/world/bentobox/challenges/database/object/Challenge.java
@@ -19,6 +19,8 @@ import com.google.gson.annotations.Expose;
import com.google.gson.annotations.JsonAdapter;
import world.bentobox.bentobox.database.objects.DataObject;
+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.requirements.Requirements;
@@ -28,6 +30,7 @@ import world.bentobox.challenges.database.object.requirements.Requirements;
* @author tastybento
*
*/
+@Table(name = "Challenge")
public class Challenge implements DataObject
{
/**
@@ -156,6 +159,7 @@ public class Challenge implements DataObject
@Deprecated
@Expose
+ @JsonAdapter(EntityCompatibilityAdapter.class)
private Map requiredEntities = new EnumMap<>(EntityType.class);
@Deprecated
diff --git a/src/main/java/world/bentobox/challenges/database/object/ChallengeLevel.java b/src/main/java/world/bentobox/challenges/database/object/ChallengeLevel.java
index 7fb26bf..63c108d 100644
--- a/src/main/java/world/bentobox/challenges/database/object/ChallengeLevel.java
+++ b/src/main/java/world/bentobox/challenges/database/object/ChallengeLevel.java
@@ -14,6 +14,7 @@ import com.google.gson.annotations.Expose;
import world.bentobox.bentobox.api.configuration.ConfigComment;
import world.bentobox.bentobox.database.objects.DataObject;
+import world.bentobox.bentobox.database.objects.Table;
import world.bentobox.challenges.ChallengesManager;
/**
@@ -21,6 +22,7 @@ import world.bentobox.challenges.ChallengesManager;
* @author tastybento
*
*/
+@Table(name = "ChallengeLevel")
public class ChallengeLevel implements DataObject, Comparable
{
/**
diff --git a/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java b/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java
index db306a9..c1de447 100644
--- a/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java
+++ b/src/main/java/world/bentobox/challenges/database/object/ChallengesPlayerData.java
@@ -14,6 +14,7 @@ import com.google.gson.annotations.Expose;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.database.objects.DataObject;
+import world.bentobox.bentobox.database.objects.Table;
import world.bentobox.bentobox.database.objects.adapters.Adapter;
import world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter;
@@ -23,6 +24,7 @@ import world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter;
* @author tastybento
*
*/
+@Table(name = "ChallengesPlayerData")
public class ChallengesPlayerData implements DataObject
{
/**
diff --git a/src/main/java/world/bentobox/challenges/database/object/adapters/EntityCompatibilityAdapter.java b/src/main/java/world/bentobox/challenges/database/object/adapters/EntityCompatibilityAdapter.java
new file mode 100644
index 0000000..b64a32f
--- /dev/null
+++ b/src/main/java/world/bentobox/challenges/database/object/adapters/EntityCompatibilityAdapter.java
@@ -0,0 +1,92 @@
+//
+// Created by BONNe
+// Copyright - 2020
+//
+
+
+package world.bentobox.challenges.database.object.adapters;
+
+
+import com.google.gson.*;
+import org.bukkit.entity.EntityType;
+import java.lang.reflect.Type;
+import java.util.EnumMap;
+import java.util.Map;
+
+import world.bentobox.bentobox.BentoBox;
+
+
+/**
+ * This is compatibility class for dealing with Mojang renamed entities.
+ * Created for update 1.16.
+ */
+public class EntityCompatibilityAdapter implements
+ JsonSerializer