mirror of
https://github.com/BentoBoxWorld/Challenges.git
synced 2024-11-26 04:25:13 +01:00
Work on fixing some crashes related to incorrect data.
Optimize some lambda functions. Add method that validates challenge's levels. If level does not exits in database, then challenge's level is set to FREE. Fix crash with migration: Free challenges level does not require migration. This relates to issue #181
This commit is contained in:
parent
92c2ba12b7
commit
3501db7002
@ -3,7 +3,19 @@ package world.bentobox.challenges;
|
|||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -190,6 +202,9 @@ public class ChallengesManager
|
|||||||
this.challengeDatabase.loadObjects().forEach(this::loadChallenge);
|
this.challengeDatabase.loadObjects().forEach(this::loadChallenge);
|
||||||
this.levelDatabase.loadObjects().forEach(this::loadLevel);
|
this.levelDatabase.loadObjects().forEach(this::loadLevel);
|
||||||
|
|
||||||
|
// this validate challenge levels
|
||||||
|
this.validateChallenges();
|
||||||
|
|
||||||
// It is not necessary to load all players in memory.
|
// It is not necessary to load all players in memory.
|
||||||
// this.playersDatabase.loadObjects().forEach(this::loadPlayerData);
|
// this.playersDatabase.loadObjects().forEach(this::loadPlayerData);
|
||||||
}
|
}
|
||||||
@ -214,6 +229,8 @@ public class ChallengesManager
|
|||||||
|
|
||||||
this.challengeDatabase.loadObjects().forEach(this::loadChallenge);
|
this.challengeDatabase.loadObjects().forEach(this::loadChallenge);
|
||||||
this.levelDatabase.loadObjects().forEach(this::loadLevel);
|
this.levelDatabase.loadObjects().forEach(this::loadLevel);
|
||||||
|
|
||||||
|
this.validateChallenges();
|
||||||
// It is not necessary to load all players in memory.
|
// It is not necessary to load all players in memory.
|
||||||
// this.playersDatabase.loadObjects().forEach(this::loadPlayerData);
|
// this.playersDatabase.loadObjects().forEach(this::loadPlayerData);
|
||||||
}
|
}
|
||||||
@ -241,13 +258,14 @@ public class ChallengesManager
|
|||||||
* @return - true if imported
|
* @return - true if imported
|
||||||
*/
|
*/
|
||||||
public boolean loadChallenge(@NonNull Challenge challenge,
|
public boolean loadChallenge(@NonNull Challenge challenge,
|
||||||
boolean overwrite,
|
boolean overwrite,
|
||||||
User user,
|
User user,
|
||||||
boolean silent)
|
boolean silent)
|
||||||
{
|
{
|
||||||
if (challenge == null)
|
if (challenge == null)
|
||||||
{
|
{
|
||||||
this.addon.logError("Tried to load NULL element from Database. One challenge is broken and will not work.");
|
this.addon.logError(
|
||||||
|
"Tried to load NULL element from Database. One challenge is broken and will not work.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +276,7 @@ public class ChallengesManager
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
user.sendMessage("challenges.messages.load-skipping",
|
user.sendMessage("challenges.messages.load-skipping",
|
||||||
"[value]", challenge.getFriendlyName());
|
"[value]", challenge.getFriendlyName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -268,7 +286,7 @@ public class ChallengesManager
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
user.sendMessage("challenges.messages.load-overwriting",
|
user.sendMessage("challenges.messages.load-overwriting",
|
||||||
"[value]", challenge.getFriendlyName());
|
"[value]", challenge.getFriendlyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,7 +295,7 @@ public class ChallengesManager
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
user.sendMessage("challenges.messages.load-add",
|
user.sendMessage("challenges.messages.load-add",
|
||||||
"[value]", challenge.getFriendlyName());
|
"[value]", challenge.getFriendlyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,19 +316,24 @@ public class ChallengesManager
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method loads given level into local cache. It provides functionality to
|
* This method loads given level into local cache. It provides functionality to overwrite local
|
||||||
* overwrite local value with new one, and send message to given user.
|
* value with new one, and send message to given user.
|
||||||
|
*
|
||||||
* @param level of type ChallengeLevel that must be loaded in local cache.
|
* @param level of type ChallengeLevel that must be loaded in local cache.
|
||||||
* @param overwrite of type boolean that indicate if local element must be overwritten.
|
* @param overwrite of type boolean that indicate if local element must be overwritten.
|
||||||
* @param user of type User who will receive messages.
|
* @param user of type User who will receive messages.
|
||||||
* @param silent of type boolean that indicate if message to user must be sent.
|
* @param silent of type boolean that indicate if message to user must be sent.
|
||||||
* @return boolean that indicate about load status.
|
* @return boolean that indicate about load status.
|
||||||
*/
|
*/
|
||||||
public boolean loadLevel(@NonNull ChallengeLevel level, boolean overwrite, User user, boolean silent)
|
public boolean loadLevel(@NonNull ChallengeLevel level,
|
||||||
|
boolean overwrite,
|
||||||
|
User user,
|
||||||
|
boolean silent)
|
||||||
{
|
{
|
||||||
if (level == null)
|
if (level == null)
|
||||||
{
|
{
|
||||||
this.addon.logError("Tried to load NULL element from Database. One level is broken and will not work.");
|
this.addon.logError(
|
||||||
|
"Tried to load NULL element from Database. One level is broken and will not work.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +346,8 @@ public class ChallengesManager
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.addon.logError("Challenge Level '" + level.getUniqueId() + "' is not valid and skipped");
|
this.addon.logError(
|
||||||
|
"Challenge Level '" + level.getUniqueId() + "' is not valid and skipped");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -336,7 +360,7 @@ public class ChallengesManager
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
user.sendMessage("challenges.messages.load-skipping",
|
user.sendMessage("challenges.messages.load-skipping",
|
||||||
"[value]", level.getFriendlyName());
|
"[value]", level.getFriendlyName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -346,7 +370,7 @@ public class ChallengesManager
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
user.sendMessage("challenges.messages.load-overwriting",
|
user.sendMessage("challenges.messages.load-overwriting",
|
||||||
"[value]", level.getFriendlyName());
|
"[value]", level.getFriendlyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,7 +379,7 @@ public class ChallengesManager
|
|||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
user.sendMessage("challenges.messages.load-add",
|
user.sendMessage("challenges.messages.load-add",
|
||||||
"[value]", level.getFriendlyName());
|
"[value]", level.getFriendlyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,6 +390,7 @@ public class ChallengesManager
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method stores PlayerData into local cache.
|
* This method stores PlayerData into local cache.
|
||||||
|
*
|
||||||
* @param playerData ChallengesPlayerData that must be loaded.
|
* @param playerData ChallengesPlayerData that must be loaded.
|
||||||
*/
|
*/
|
||||||
private void loadPlayerData(@NonNull ChallengesPlayerData playerData)
|
private void loadPlayerData(@NonNull ChallengesPlayerData playerData)
|
||||||
@ -383,6 +408,7 @@ public class ChallengesManager
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method removes given player from cache data.
|
* This method removes given player from cache data.
|
||||||
|
*
|
||||||
* @param playerID player ID which cache data must be removed.
|
* @param playerID player ID which cache data must be removed.
|
||||||
*/
|
*/
|
||||||
public void removeFromCache(UUID playerID)
|
public void removeFromCache(UUID playerID)
|
||||||
@ -408,6 +434,43 @@ public class ChallengesManager
|
|||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method iterates through all challenges that is loaded from database and removes levels
|
||||||
|
* that are not found.
|
||||||
|
*/
|
||||||
|
private void validateChallenges()
|
||||||
|
{
|
||||||
|
this.challengeCacheData.values().forEach(challenge -> {
|
||||||
|
if (!this.isValidChallenge(challenge))
|
||||||
|
{
|
||||||
|
// If challenge's level is not found, then set it as free challenge.
|
||||||
|
challenge.setLevel(FREE);
|
||||||
|
this.addon.logWarning("Challenge's " + challenge.getUniqueId() + " level was not found in database. " +
|
||||||
|
"To avoid any errors with missing level, challenge were added to FREE level!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks if given challenge's level exists in local cache or database.
|
||||||
|
* @param challenge that must be validated
|
||||||
|
* @return true ir challenge's level exists, otherwise false.
|
||||||
|
*/
|
||||||
|
private boolean isValidChallenge(@NonNull Challenge challenge)
|
||||||
|
{
|
||||||
|
if (challenge.getLevel().equals(FREE) || this.getLevel(challenge.getLevel()) != null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.addon.logError("Cannot find " + challenge.getUniqueId() + " challenge's level " + challenge.getLevel() + " in database.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks if given level all challenges exists in local cache or database.
|
* This method checks if given level all challenges exists in local cache or database.
|
||||||
* It also checks if world where level must operate exists.
|
* It also checks if world where level must operate exists.
|
||||||
@ -657,7 +720,12 @@ public class ChallengesManager
|
|||||||
this.challengeCacheData.remove(challenge.getUniqueId());
|
this.challengeCacheData.remove(challenge.getUniqueId());
|
||||||
|
|
||||||
challenge.setUniqueId(addonName + challenge.getUniqueId().substring(world.getName().length()));
|
challenge.setUniqueId(addonName + challenge.getUniqueId().substring(world.getName().length()));
|
||||||
challenge.setLevel(addonName + challenge.getLevel().substring(world.getName().length()));
|
|
||||||
|
if (!challenge.getLevel().equals(FREE))
|
||||||
|
{
|
||||||
|
challenge.setLevel(addonName + challenge.getLevel().substring(world.getName().length()));
|
||||||
|
}
|
||||||
|
|
||||||
updated = true;
|
updated = true;
|
||||||
|
|
||||||
this.challengeDatabase.saveObject(challenge);
|
this.challengeDatabase.saveObject(challenge);
|
||||||
@ -995,11 +1063,11 @@ public class ChallengesManager
|
|||||||
doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count();
|
doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count();
|
||||||
|
|
||||||
result.add(new LevelStatus(
|
result.add(new LevelStatus(
|
||||||
level,
|
level,
|
||||||
previousLevel,
|
previousLevel,
|
||||||
challengesToDo,
|
challengesToDo,
|
||||||
level.getChallenges().size() == doneChallengeCount,
|
level.getChallenges().size() == doneChallengeCount,
|
||||||
challengesToDo <= 0));
|
challengesToDo <= 0));
|
||||||
|
|
||||||
previousLevel = level;
|
previousLevel = level;
|
||||||
}
|
}
|
||||||
@ -1316,9 +1384,23 @@ public class ChallengesManager
|
|||||||
* @return - true if completed
|
* @return - true if completed
|
||||||
*/
|
*/
|
||||||
public long getChallengeTimes(User user, World world, Challenge challenge)
|
public long getChallengeTimes(User user, World world, Challenge challenge)
|
||||||
|
{
|
||||||
|
return this.getChallengeTimes(user, world, challenge.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a challenge is complete or not
|
||||||
|
*
|
||||||
|
* @param user - User that must be checked.
|
||||||
|
* @param world - World where challenge operates.
|
||||||
|
* @param challenge - Challenge that must be checked.
|
||||||
|
* @return - true if completed
|
||||||
|
*/
|
||||||
|
public long getChallengeTimes(User user, World world, String challenge)
|
||||||
{
|
{
|
||||||
world = Util.getWorld(world);
|
world = Util.getWorld(world);
|
||||||
return this.getChallengeTimes(this.getDataUniqueID(user, world), challenge.getUniqueId());
|
return this.getChallengeTimes(this.getDataUniqueID(user, world), challenge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1429,8 +1511,8 @@ public class ChallengesManager
|
|||||||
{
|
{
|
||||||
return this.islandWorldManager.getAddon(world).map(gameMode ->
|
return this.islandWorldManager.getAddon(world).map(gameMode ->
|
||||||
this.challengeCacheData.values().stream().
|
this.challengeCacheData.values().stream().
|
||||||
sorted(this.challengeComparator).
|
|
||||||
filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())).
|
filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())).
|
||||||
|
sorted(this.challengeComparator).
|
||||||
map(Challenge::getUniqueId).
|
map(Challenge::getUniqueId).
|
||||||
collect(Collectors.toList())).
|
collect(Collectors.toList())).
|
||||||
orElse(Collections.emptyList());
|
orElse(Collections.emptyList());
|
||||||
@ -1447,8 +1529,8 @@ public class ChallengesManager
|
|||||||
{
|
{
|
||||||
return this.islandWorldManager.getAddon(world).map(gameMode ->
|
return this.islandWorldManager.getAddon(world).map(gameMode ->
|
||||||
this.challengeCacheData.values().stream().
|
this.challengeCacheData.values().stream().
|
||||||
sorted(this.challengeComparator).
|
|
||||||
filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())).
|
filter(challenge -> challenge.matchGameMode(gameMode.getDescription().getName())).
|
||||||
|
sorted(this.challengeComparator).
|
||||||
collect(Collectors.toList())).
|
collect(Collectors.toList())).
|
||||||
orElse(Collections.emptyList());
|
orElse(Collections.emptyList());
|
||||||
}
|
}
|
||||||
@ -1459,13 +1541,16 @@ public class ChallengesManager
|
|||||||
* @param world World in which challenges must be searched.
|
* @param world World in which challenges must be searched.
|
||||||
* @return List with free challenges in given world.
|
* @return List with free challenges in given world.
|
||||||
*/
|
*/
|
||||||
public List<Challenge> getFreeChallenges(World world)
|
public List<Challenge> getFreeChallenges(@NonNull World world)
|
||||||
{
|
{
|
||||||
// Free Challenges hides under FREE level.
|
// Free Challenges hides under FREE level.
|
||||||
return this.getAllChallenges(world).stream().
|
return this.islandWorldManager.getAddon(world).map(gameMode ->
|
||||||
filter(challenge -> challenge.getLevel().equals(FREE)).
|
this.challengeCacheData.values().stream().
|
||||||
|
filter(challenge -> challenge.getLevel().equals(FREE) &&
|
||||||
|
challenge.matchGameMode(gameMode.getDescription().getName())).
|
||||||
sorted(Comparator.comparing(Challenge::getOrder)).
|
sorted(Comparator.comparing(Challenge::getOrder)).
|
||||||
collect(Collectors.toList());
|
collect(Collectors.toList())).
|
||||||
|
orElse(Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1477,10 +1562,10 @@ public class ChallengesManager
|
|||||||
public List<Challenge> getLevelChallenges(ChallengeLevel level)
|
public List<Challenge> getLevelChallenges(ChallengeLevel level)
|
||||||
{
|
{
|
||||||
return level.getChallenges().stream().
|
return level.getChallenges().stream().
|
||||||
map(this::getChallenge).
|
map(this::getChallenge).
|
||||||
filter(Objects::nonNull).
|
filter(Objects::nonNull).
|
||||||
sorted(Comparator.comparing(Challenge::getOrder)).
|
sorted(Comparator.comparing(Challenge::getOrder)).
|
||||||
collect(Collectors.toList());
|
collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1620,9 +1705,9 @@ public class ChallengesManager
|
|||||||
{
|
{
|
||||||
// TODO: Probably need to check also database.
|
// TODO: Probably need to check also database.
|
||||||
return this.levelCacheData.values().stream().
|
return this.levelCacheData.values().stream().
|
||||||
sorted(ChallengeLevel::compareTo).
|
sorted(ChallengeLevel::compareTo).
|
||||||
filter(level -> level.matchGameMode(gameMode)).
|
filter(level -> level.matchGameMode(gameMode)).
|
||||||
collect(Collectors.toList());
|
collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user