From 590b3f114cbcf65c53503bf585a0caad48e77c72 Mon Sep 17 00:00:00 2001 From: BONNe1704 Date: Wed, 23 Jan 2019 17:30:30 +0200 Subject: [PATCH] Rework ChallengesManager. Implement all methods that were only placeholders. Remove all unnecessary old methods. Implement new methods in all classes. User and Admin command now opens new GUI. --- .../challenges/ChallengesImportManager.java | 6 +- .../challenges/ChallengesManager.java | 1437 ++++++++++------- .../commands/ChallengesCommand.java | 10 +- .../challenges/commands/admin/Challenges.java | 13 +- .../commands/admin/CompleteChallenge.java | 6 +- .../commands/admin/ResetChallenge.java | 6 +- .../commands/admin/ShowChallenges.java | 2 +- .../admin/SurroundChallengeBuilder.java | 2 +- .../challenges/listeners/ResetListener.java | 3 +- .../challenges/listeners/SaveListener.java | 2 +- .../challenges/panel/ChallengesPanels.java | 28 +- .../challenges/panel/ChallengesPanels2.java | 32 +- .../panel/CreateChallengeListener.java | 2 +- .../challenges/panel/TryToComplete.java | 12 +- .../challenges/panel/admin/AdminGUI.java | 41 +- .../challenges/panel/admin/EditLevelGUI.java | 10 +- .../panel/admin/ListChallengesGUI.java | 2 +- .../challenges/panel/admin/ListLevelsGUI.java | 2 +- .../challenges/panel/admin/ListUsersGUI.java | 10 +- .../challenges/panel/user/ChallengesGUI.java | 8 +- .../bentobox/challenges/utils/GuiUtils.java | 27 +- 21 files changed, 981 insertions(+), 680 deletions(-) diff --git a/src/main/java/world/bentobox/challenges/ChallengesImportManager.java b/src/main/java/world/bentobox/challenges/ChallengesImportManager.java index 8f4df1f..8040590 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesImportManager.java +++ b/src/main/java/world/bentobox/challenges/ChallengesImportManager.java @@ -97,7 +97,7 @@ public class ChallengesImportManager challengeLevel.setRewardExperience(unlock.getInt("expReward")); challengeLevel.setRewardCommands(unlock.getStringList("commands")); } - addon.getChallengesManager().storeLevel(challengeLevel); + addon.getChallengesManager().loadLevel(challengeLevel, overwrite, user, false); } } else { user.sendMessage("challenges.admin.import.no-levels"); @@ -118,7 +118,7 @@ public class ChallengesImportManager newChallenge.setDeployed(true); ConfigurationSection details = chals.getConfigurationSection(challenge); newChallenge.setFriendlyName(details.getString("friendlyname", challenge)); - newChallenge.setDescription(addon.getChallengesManager().stringSplit(details.getString("description", ""))); + newChallenge.setDescription(GuiUtils.stringSplit(details.getString("description", ""))); newChallenge.setIcon(ItemParser.parse(details.getString("icon") + ":1")); newChallenge.setChallengeType(Challenge.ChallengeType.valueOf(details.getString("type","INVENTORY").toUpperCase())); newChallenge.setTakeItems(details.getBoolean("takeItems",true)); @@ -149,7 +149,7 @@ public class ChallengesImportManager this.addon.getChallengesManager().addChallengeToLevel(newChallenge, addon.getChallengesManager().getLevel(Util.getWorld(world).getName() + "_" + details.getString("level"))); - if (addon.getChallengesManager().storeChallenge(newChallenge, overwrite, user, false)) { + if (addon.getChallengesManager().loadChallenge(newChallenge, overwrite, user, false)) { size++; } } diff --git a/src/main/java/world/bentobox/challenges/ChallengesManager.java b/src/main/java/world/bentobox/challenges/ChallengesManager.java index 8941337..4112609 100644 --- a/src/main/java/world/bentobox/challenges/ChallengesManager.java +++ b/src/main/java/world/bentobox/challenges/ChallengesManager.java @@ -1,654 +1,915 @@ package world.bentobox.challenges; -import org.apache.commons.lang.WordUtils; -import org.bukkit.ChatColor; -import org.bukkit.Material; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import java.util.*; -import java.util.Map.Entry; import java.util.stream.Collectors; import world.bentobox.bentobox.api.configuration.Config; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.util.Util; -import world.bentobox.challenges.commands.admin.SurroundChallengeBuilder; import world.bentobox.challenges.database.object.ChallengeLevel; import world.bentobox.challenges.database.object.Challenge; -import world.bentobox.challenges.database.object.Challenge.ChallengeType; import world.bentobox.challenges.database.object.ChallengesPlayerData; -import world.bentobox.challenges.panel.ChallengesPanels; import world.bentobox.challenges.utils.LevelStatus; -public class ChallengesManager { +/** + * This class manges challenges. It allows access to all data that is stored to database. + * It also provides information about challenge level status for each user. + */ +public class ChallengesManager +{ +// --------------------------------------------------------------------- +// Section: Variables +// --------------------------------------------------------------------- - public static final String FREE = "Free"; - private Map> challengeMap; - private Config chConfig; - private Config lvConfig; - private Database players; - private ChallengesPanels challengesPanels; - private Map playerData; - private ChallengesAddon addon; + /** + * This config object stores structures for challenge objects. + */ + private Database challengeDatabase; - public ChallengesManager(ChallengesAddon addon) { - this.addon = addon; - // Set up the configs - chConfig = new Config<>(addon, Challenge.class); - lvConfig = new Config<>(addon, ChallengeLevel.class); - // Players is where all the player history will be stored - players = new Database<>(addon, ChallengesPlayerData.class); - // Cache of challenges - challengeMap = new LinkedHashMap<>(); - // Cache of player data - playerData = new HashMap<>(); - load(); - } + /** + * This config object stores structures for challenge level objects. + */ + private Database levelDatabase; - /** - * Load player from database into the cache or create new player data - * @param user - user to add - */ - private void addPlayer(User user) { - if (playerData.containsKey(user.getUniqueId())) { - return; - } - // The player is not in the cache - // Check if the player exists in the database - if (players.objectExists(user.getUniqueId().toString())) { - // Load player from database - ChallengesPlayerData data = players.loadObject(user.getUniqueId().toString()); - // Store in cache - playerData.put(user.getUniqueId(), data); - } else { - // Create the player data - ChallengesPlayerData pd = new ChallengesPlayerData(user.getUniqueId().toString()); - players.saveObject(pd); - // Add to cache - playerData.put(user.getUniqueId(), pd); - } - } + /** + * This database allows to access player challenge data. + */ + private Database playersDatabase; - /** - * Check how many times a player has done a challenge before - * @param user - user - * @param challenge - challenge - * @return - number of times - */ - public long checkChallengeTimes(User user, Challenge challenge, World world) { - addPlayer(user); - return playerData.get(user.getUniqueId()).getTimes(challenge.getUniqueId()); - } + /** + * This is local cache that links challenge unique id with challenge object. + */ + private Map challengeCacheData; - /** - * Creates a simple example description of the requirements - * @param user - user of this command - * @param requiredItems - list of items - * @return Description list - */ - private List createDescription(User user, List requiredItems) { - addPlayer(user); - List result = new ArrayList<>(); - result.add(user.getTranslation("challenges.admin.create.description")); - for (ItemStack item : requiredItems) { - result.add(user.getTranslation("challenges.admin.create.description-item-color") + item.getAmount() + " x " + Util.prettifyText(item.getType().toString())); - } - return result; - } + /** + * This is local cache that links level unique id with level object. + */ + private Map levelCacheData; - /** - * Creates an inventory challenge - * @param user - the user who is making the challenge - * @param inventory - the inventory that will be used to make the challenge - */ - public boolean createInvChallenge(User user, Inventory inventory) { - addPlayer(user); - if (inventory.getContents().length == 0) { - return false; - } - Challenge newChallenge = new Challenge(); - newChallenge.setChallengeType(ChallengeType.INVENTORY); - newChallenge.setFriendlyName(inventory.getTitle()); - newChallenge.setDeployed(false); - List requiredItems = new ArrayList<>(); - inventory.forEach(item -> { - if (item != null && !item.getType().equals(Material.AIR)) { - requiredItems.add(item); - } - }); - newChallenge.setRequiredItems(requiredItems); - newChallenge.setTakeItems(true); - newChallenge.setUniqueId(inventory.getTitle()); - newChallenge.setIcon(new ItemStack(Material.MAP)); - newChallenge.setLevel(FREE); - newChallenge.setDescription(createDescription(user, requiredItems)); + /** + * This is local cache that links UUID with corresponding player challenge data. + */ + private Map playerCacheData; - // Move all the items back to the player's inventory - inventory.forEach(item -> { - if (item != null) { - Map residual = user.getInventory().addItem(item); - // Drop any residual items at the foot of the player - residual.forEach((k, v) -> user.getWorld().dropItem(user.getLocation(), v)); - } - }); - - // Save the challenge - if (!chConfig.saveConfigObject(newChallenge)) { - user.sendRawMessage(ChatColor.RED + "Challenge creation failed!"); - return false; - } - user.sendRawMessage("Success"); - return true; - } - - /** - * Create a surrounding challenge - * @param challengeInfo - info on the challenge from the builder - * @return true if successful, false if not - */ - public boolean createSurroundingChallenge(SurroundChallengeBuilder challengeInfo) { - if (challengeInfo.getReqBlocks().isEmpty() && challengeInfo.getReqEntities().isEmpty()) { - challengeInfo.getOwner().sendMessage("challenges.error.no-items-clicked"); - return false; - } - Challenge newChallenge = new Challenge(); - newChallenge.setChallengeType(ChallengeType.ISLAND); - newChallenge.setFriendlyName(challengeInfo.getName()); - newChallenge.setDeployed(true); - newChallenge.setRequiredBlocks(challengeInfo.getReqBlocks()); - newChallenge.setRequiredEntities(challengeInfo.getReqEntities()); - newChallenge.setUniqueId(challengeInfo.getName()); - newChallenge.setIcon(new ItemStack(Material.ARMOR_STAND)); - newChallenge.setLevel(FREE); - - // Save the challenge - if (!chConfig.saveConfigObject(newChallenge)) { - challengeInfo.getOwner().sendMessage("challenges.error.could-not-save"); - return false; - } - return true; - } - - /** - * Get the list of all challenge unique names. - * @return List of challenge names - */ - public List getAllChallengesList() { - List result = new ArrayList<>(); - challengeMap.values().forEach(ch -> ch.forEach(c -> result.add(c.getUniqueId()))); - return result; - } - - /** - * Get the list of all challenge unique names for world. - * @param world - the world to check - * @return List of challenge names - */ - public List getAllChallengesList(World world) { - List result = new ArrayList<>(); - challengeMap.values().forEach(ch -> ch.stream().filter(c -> c.getUniqueId().startsWith(Util.getWorld(world).getName())).forEach(c -> result.add(c.getUniqueId()))); - return result; - } - - /** - * Get challenge by name - * @param name - unique name of challenge - * @param world - world to check - * @return - challenge or null if it does not exist - */ - public Challenge getChallenge(String name, World world) { - String worldName = Util.getWorld(world).getName(); - for (Set ch : challengeMap.values()) { - Optional challenge = ch.stream().filter(c -> c.getUniqueId().equalsIgnoreCase(worldName + name)).findFirst(); - if (challenge.isPresent()) { - return challenge.get(); - } - } - return null; - } - - /** - * Get the status on every level - * @param user - user - * @param world - world to check - * @return Level status - how many challenges still to do on which level - */ - public List getChallengeLevelStatus(User user, World world) - { - this.addPlayer(user); - ChallengesPlayerData playerData = this.playerData.get(user.getUniqueId()); - List result = new ArrayList<>(); - - // The first level is always unlocked - ChallengeLevel previousLevel = null; - int doneChallengeCount = Integer.MAX_VALUE; - - // For each challenge level, check how many the user has done - for (Entry> entry : this.challengeMap.entrySet()) - { - // Check how much challenges must be done in previous level. - int challengesToDo = Math.max(0, entry.getKey().getWaiverAmount() - doneChallengeCount); - - doneChallengeCount = (int) entry.getValue().stream().filter( - ch -> playerData.isChallengeDone(ch.getUniqueId())).count(); - - // Create result class with the data - result.add(new LevelStatus( - entry.getKey(), - previousLevel, - challengesToDo, - entry.getValue().size() == doneChallengeCount, - challengesToDo <= 0)); - - // Set up the next level for the next loop - previousLevel = entry.getKey(); - } - - return result; - } - - /** - * Get the challenge list - * @return the challengeList - */ - public Map> getChallengeList() { - // TODO return the challenges for world - return challengeMap; - } - - /** - * Get the set of challenges for this level for this world - * @param level - the level required - * @param world - * @return the set of challenges for this level, or the first set of challenges if level is blank, or a blank list if there are no challenges - */ - public Set getChallenges(String level, World world) { - String worldName = Util.getWorld(world).getName(); - Optional lv = challengeMap.keySet().stream().filter(l -> l.getUniqueId().equalsIgnoreCase(level)).findFirst(); - // Get the challenges applicable to this world - return lv.isPresent() ? challengeMap.get(lv.get()).stream() - .filter(c -> c.getUniqueId().startsWith(worldName)).collect(Collectors.toSet()) - : new HashSet<>(); - } - - /** - * @return the challengesPanels - */ - public ChallengesPanels getChallengesPanels() { - return challengesPanels; - } - - /** - * Get the previous level to the one supplied - * @param currentLevel - the current level - * @return the previous level, or null if there is none - */ - public ChallengeLevel getPreviousLevel(ChallengeLevel currentLevel) { - ChallengeLevel result = null; - for (ChallengeLevel level : challengeMap.keySet()) { - if (level.equals(currentLevel)) { - return result; - } - result = level; - } - return result; - } - - /** - * Check if a challenge exists - case insensitive - * @param name - name of challenge - * @return true if it exists, otherwise false - */ - public boolean isChallenge(String name) { - for (Set ch : challengeMap.values()) { - if (ch.stream().anyMatch(c -> c.getUniqueId().equalsIgnoreCase(name))) { - return true; - } - } - return false; - } - - /** - * Check if a challenge exists in world - case insensitive - * @param world - world to check - * @param name - name of challenge - * @return true if it exists, otherwise false - */ - public boolean isChallenge(World world, String name) { - for (Set ch : challengeMap.values()) { - if (ch.stream().filter(c -> c.getUniqueId().startsWith(Util.getWorld(world).getName())).anyMatch(c -> c.getUniqueId().equalsIgnoreCase(name))) { - return true; - } - } - return false; - } - - /** - * Checks if a challenge is complete or not - * @param challengeName - Challenge uniqueId - * @return - true if completed - */ - public boolean isChallengeComplete(User user, String challengeName, World world) { - addPlayer(user); - return playerData.get(user.getUniqueId()).isChallengeDone(challengeName); - } - - /** - * Check is user can see level - * @param user - user - * @param level - level unique id - * @return true if level is unlocked - */ - public boolean isLevelUnlocked(User user, String level, World world) { - addPlayer(user); - return getChallengeLevelStatus(user, world).stream().filter(LevelStatus::isUnlocked).anyMatch(lv -> lv.getLevel().getUniqueId().equalsIgnoreCase(level)); - } - - /** - * Clear and reload all challenges - */ - public void load() { - // Load the challenges - challengeMap.clear(); - addon.getLogger().info("Loading challenges..."); - chConfig.loadConfigObjects().forEach(this::storeChallenge); - sortChallenges(); - players.loadObjects().forEach(pd -> { - try { - UUID uuid = UUID.fromString(pd.getUniqueId()); - playerData.put(uuid,pd); - } catch (Exception e) { - addon.getLogger().severe("UUID for player in challenge data file is invalid!"); - } - }); - } - - /** - * Save configs and player data - */ - public void save() { - challengeMap.entrySet().forEach(en -> { - lvConfig.saveConfigObject(en.getKey()); - en.getValue().forEach(chConfig::saveConfigObject); - }); - savePlayers(); - } - - private void savePlayers() { - playerData.values().forEach(players :: saveObject); - } - - private void savePlayer(UUID playerUUID) { - if (playerData.containsKey(playerUUID)) { - players.saveObject(playerData.get(playerUUID)); - } - } - - /** - * Sets the challenge as complete and increments the number of times it has been completed - * @param user - user - * @param challengeUniqueId - unique challenge id - * @param world - world to set - */ - public void setChallengeComplete(User user, String challengeUniqueId, World world) { - addPlayer(user); - playerData.get(user.getUniqueId()).setChallengeDone(challengeUniqueId); - // Save - savePlayer(user.getUniqueId()); - } - - /** - * Reset the challenge to zero time / not done - * @param user - user - * @param challengeUniqueId - unique challenge id - * @param world - world to set - */ - public void setResetChallenge(User user, String challengeUniqueId, World world) { - addPlayer(user); - playerData.get(user.getUniqueId()).setChallengeTimes(challengeUniqueId, 0); - // Save - savePlayer(user.getUniqueId()); - } - - /** - * @param challengeList the challengeList to set - */ - public void setChallengeList(Map> challengeList) { - this.challengeMap = challengeList; - } - - public void sortChallenges() { - // Sort the challenge list into level order - challengeMap = challengeMap.entrySet().stream() - .sorted(Map.Entry.comparingByKey()) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, - (oldValue, newValue) -> oldValue, LinkedHashMap::new)); - } + /** + * This variable allows to access ChallengesAddon. + */ + private ChallengesAddon addon; - /** - * Store challenge silently. Used when loading. - * @param challenge - * @return true if successful - */ - private boolean storeChallenge(Challenge challenge) { - return storeChallenge(challenge, true, null, true); - } - - /** - * Stores the challenge. - * @param challenge - challenge - * @param overwrite - true if previous challenge should be overwritten - * @param user - user making the request - * @param silent - if true, no messages are sent to user - * @return - true if imported - */ - public boolean storeChallenge(Challenge challenge, boolean overwrite, User user, boolean silent) { - // See if we have this level already - ChallengeLevel level; - if (lvConfig.configObjectExists(challenge.getLevel())) { - // Get it from the database - level = lvConfig.loadConfigObject(challenge.getLevel()); - } else { - // Make it - level = new ChallengeLevel(); - level.setUniqueId(challenge.getLevel()); - lvConfig.saveConfigObject(level); - } - challengeMap.putIfAbsent(level, new HashSet<>()); - if (challengeMap.get(level).contains(challenge)) { - if (!overwrite) { - if (!silent) { - user.sendMessage("challenges.admin.import.skipping", "[challenge]", challenge.getFriendlyName()); - } - return false; - } else { - if (!silent) { - user.sendMessage("challenges.admin.import.overwriting", "[challenge]", challenge.getFriendlyName()); - } - challengeMap.get(level).add(challenge); - return true; - } - } - if (!silent) { - user.sendMessage("challenges.admin.import.imported", "[challenge]", challenge.getFriendlyName()); - } - challengeMap.get(level).add(challenge); - return true; - } - - /** - * Store a challenge level - * @param level the challenge level - */ - public void storeLevel(ChallengeLevel level) { - lvConfig.saveConfigObject(level); - } - - /** - * Simple splitter - * @param string - string to be split - * @return list of split strings - */ - public List stringSplit(String string) { - string = ChatColor.translateAlternateColorCodes('&', string); - // Check length of lines - List result = new ArrayList<>(); - Arrays.asList(string.split("\\|")).forEach(line -> result.addAll(Arrays.asList(WordUtils.wrap(line,25).split("\\n")))); - return result; - } - - /** - * Resets all the challenges for user in world - * @param uuid - island owner's UUID - * @param world - world - */ - public void resetAllChallenges(UUID uuid, World world) { - User user = User.getInstance(uuid); - addPlayer(user); - playerData.get(user.getUniqueId()).reset(world); - // Save - savePlayer(user.getUniqueId()); - - } +// --------------------------------------------------------------------- +// Section: Constants +// --------------------------------------------------------------------- - public Challenge createChallenge() - { - return new Challenge(); - } + /** + * String for free Challenge Level. + */ + public static final String FREE = ""; - public List getChallenges(ChallengeLevel challengeLevel) - { - return new ArrayList<>(this.challengeMap.get(challengeLevel)); - } +// --------------------------------------------------------------------- +// Section: Constructor +// --------------------------------------------------------------------- - public List getChallengeLevelList() - { - return new ArrayList<>(this.challengeMap.keySet()); - } - - - public List getChallengesList() - { - return new ArrayList<>(); - } - - - public void deleteChallenge(Challenge selectedChallenge) - { - - } - - - public void deleteChallengeLevel(ChallengeLevel valueObject) - { - - } - - public void resetAllChallenges(User uuid, World world) - { - - } - - - public Challenge createChallenge(String reply) + /** + * Initial constructor. Inits and loads all data. + * @param addon challenges addon. + */ + public ChallengesManager(ChallengesAddon addon) { - return new Challenge(); + this.addon = addon; + // Set up the configs + this.challengeDatabase = new Database<>(addon, Challenge.class); + this.levelDatabase = new Database<>(addon, ChallengeLevel.class); + // Players is where all the player history will be stored + this.playersDatabase = new Database<>(addon, ChallengesPlayerData.class); + + // Init all cache objects. + this.challengeCacheData = new HashMap<>(); + this.levelCacheData = new HashMap<>(); + this.playerCacheData = new HashMap<>(); + + this.load(); } - public boolean validateChallengeUniqueID(World world, String reply) +// --------------------------------------------------------------------- +// Section: Loading and storing methods +// --------------------------------------------------------------------- + + + /** + * Clear and reload all challenges + */ + public void load() { + this.challengeCacheData.clear(); + this.levelCacheData.clear(); + this.playerCacheData.clear(); + + this.addon.getLogger().info("Loading challenges..."); + + this.challengeDatabase.loadObjects().forEach(this::loadChallenge); + this.levelDatabase.loadObjects().forEach(this::loadLevel); + this.playersDatabase.loadObjects().forEach(this::loadPlayerData); + } + + + /** + * Load challenge silently. Used when loading. + * + * @param challenge Challenge that must be loaded. + * @return true if successful + */ + private void loadChallenge(Challenge challenge) + { + this.loadChallenge(challenge, true, null, true); + } + + + /** + * Load the challenge. + * + * @param challenge - challenge + * @param overwrite - true if previous challenge should be overwritten + * @param user - user making the request + * @param silent - if true, no messages are sent to user + * @return - true if imported + */ + public boolean loadChallenge(Challenge challenge, + boolean overwrite, + User user, + boolean silent) + { + if (this.challengeCacheData.containsKey(challenge.getUniqueId())) + { + if (!overwrite) + { + if (!silent) + { + user.sendMessage("challenges.admin.import.skip", + "[object]", challenge.getFriendlyName()); + } + + return false; + } + else + { + if (!silent) + { + user.sendMessage("challenges.admin.import.overwriting", + "[object]", challenge.getFriendlyName()); + } + } + } + else + { + if (!silent) + { + user.sendMessage("challenges.admin.import.add", + "[object]", challenge.getFriendlyName()); + } + } + + this.challengeCacheData.put(challenge.getUniqueId(), challenge); return true; } - public boolean validateLevelUniqueID(World world, String reply) + /** + * Store a challenge level + * + * @param level the challenge level + */ + private void loadLevel(ChallengeLevel level) { - return false; + this.loadLevel(level, true, null, true); } - public ChallengeLevel createLevel(String reply) + /** + * This method loads given level into local cache. It provides functionality to + * overwrite local value with new one, and send message to given user. + * @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 user of type User who will receive messages. + * @param silent of type boolean that indicate if message to user must be sent. + * @return boolean that indicate about load status. + */ + public boolean loadLevel(ChallengeLevel level, boolean overwrite, User user, boolean silent) { - return new ChallengeLevel(); + if (!this.isValidLevel(level)) + { + user.sendMessage("challenges.admin.import.error", + "[object]", level.getFriendlyName()); + + return false; + } + + if (this.levelCacheData.containsKey(level.getUniqueId())) + { + if (!overwrite) + { + if (!silent) + { + user.sendMessage("challenges.admin.import.skip", + "[object]", level.getFriendlyName()); + } + + return false; + } + else + { + if (!silent) + { + user.sendMessage("challenges.admin.import.overwriting", + "[object]", level.getFriendlyName()); + } + } + } + else + { + if (!silent) + { + user.sendMessage("challenges.admin.import.add", + "[object]", level.getFriendlyName()); + } + } + + this.levelCacheData.put(level.getUniqueId(), level); + return true; } - public void unlinkChallenge(ChallengeLevel challengeLevel, Challenge value) + /** + * This method stores PlayerData into local cache. + * @param playerData ChallengesPlayerData that must be loaded. + */ + private void loadPlayerData(ChallengesPlayerData playerData) { - + try + { + UUID uuid = UUID.fromString(playerData.getUniqueId()); + this.playerCacheData.put(uuid, playerData); + } + catch (Exception e) + { + this.addon.getLogger().severe("UUID for player in challenge data file is invalid!"); + } } - public void linkChallenge(ChallengeLevel challengeLevel, Challenge value) - { +// --------------------------------------------------------------------- +// Section: Other storing related methods +// --------------------------------------------------------------------- + + /** + * This method checks if given level all challenges exists in local cache or database. + * It also checks if world where level must operate exists. + * @param level that must be validated + * @return true ir level is valid, otherwise false. + */ + private boolean isValidLevel(ChallengeLevel level) + { + if (!this.addon.getPlugin().getIWM().inWorld(Bukkit.getWorld(level.getWorld()))) + { + return false; + } + + for (String uniqueID : level.getChallenges()) + { + if (!this.challengeCacheData.containsKey(uniqueID)) + { + if (this.challengeDatabase.objectExists(uniqueID)) + { + this.loadChallenge(this.challengeDatabase.loadObject(uniqueID)); + } + else + { + return false; + } + } + } + + return true; } - public void resetChallenge(UUID uniqueId, Challenge value) - { - - } - - - public void completeChallenge(UUID uniqueId, Challenge value) - { - - } - - - public List getFreeChallenges(User user, World world) - { - return Collections.emptyList(); - } - - - public String getChallengesLevel(Challenge challenge) - { - return "HERE NEED LEVEL NAME"; - } - - - public boolean isChallengeComplete(User user, Challenge challenge) - { - return this.isChallengeComplete(user, challenge.getUniqueId(), user.getWorld()); - } - - - public long checkChallengeTimes(User user, Challenge challenge) - { - return this.checkChallengeTimes(user, challenge, user.getWorld()); - } - - - public List getPlayers(World world) - { - List playerList = new ArrayList<>(); - - - return playerList; - } - - - - public ChallengeLevel getLevel(String level) + /** + * Load player from database into the cache or create new player data + * + * @param user - user to add + */ + private void addPlayer(User user) { + if (this.playerCacheData.containsKey(user.getUniqueId())) + { + return; + } + + // The player is not in the cache + // Check if the player exists in the database + + if (this.playersDatabase.objectExists(user.getUniqueId().toString())) + { + // Load player from database + ChallengesPlayerData data = this.playersDatabase.loadObject(user.getUniqueId().toString()); + // Store in cache + this.playerCacheData.put(user.getUniqueId(), data); + } + else + { + // Create the player data + ChallengesPlayerData pd = new ChallengesPlayerData(user.getUniqueId().toString()); + this.playersDatabase.saveObject(pd); + // Add to cache + this.playerCacheData.put(user.getUniqueId(), pd); + } + } + + +// --------------------------------------------------------------------- +// Section: Saving methods +// --------------------------------------------------------------------- + + + /** + * This method init all cached object saving to database. + */ + public void save() + { + this.saveChallenges(); + this.saveLevels(); + this.savePlayers(); + } + + + /** + * This method saves all challenges to database. + */ + private void saveChallenges() + { + this.challengeCacheData.values().forEach(this.challengeDatabase::saveObject); + } + + + /** + * This method saves given challenge object to database. + * @param challenge object that must be saved + */ + private void saveChallenge(Challenge challenge) + { + this.challengeDatabase.saveObject(challenge); + } + + + /** + * This method saves all levels to database. + */ + private void saveLevels() + { + this.levelCacheData.values().forEach(this.levelDatabase::saveObject); + } + + + /** + * This method saves given level into database. + * @param level object that must be saved + */ + private void saveLevel(ChallengeLevel level) + { + this.levelDatabase.saveObject(level); + } + + + /** + * This method saves all players to database. + */ + private void savePlayers() + { + this.playerCacheData.values().forEach(this.playersDatabase::saveObject); + } + + + /** + * This method saves player with given UUID. + * @param playerUUID users UUID. + */ + private void savePlayer(UUID playerUUID) + { + if (this.playerCacheData.containsKey(playerUUID)) + { + this.playersDatabase.saveObject(this.playerCacheData.get(playerUUID)); + } + } + + +// --------------------------------------------------------------------- +// Section: Player Data related methods +// --------------------------------------------------------------------- + + + /** + * This method returns all players who have done at least one challenge in given world. + * @param world World in which must search challenges. + * @return List with players who have done at least on challenge. + */ + public List getPlayers(World world) + { + List allChallengeList = this.getAllChallengesNames(world); + + // This is using Database, as some users may not be in the cache. + + return this.playersDatabase.loadObjects().stream().filter(playerData -> + allChallengeList.stream().anyMatch(playerData::isChallengeDone)). + map(playerData -> Bukkit.getPlayer(UUID.fromString(playerData.getUniqueId()))). + collect(Collectors.toList()); + } + + + /** + * This method returns how many times a player has done a challenge before + * @param user - user + * @param challenge - challenge + * @return - number of times + */ + public long getChallengeTimes(User user, Challenge challenge) + { + this.addPlayer(user); + return this.playerCacheData.get(user.getUniqueId()).getTimes(challenge.getUniqueId()); + } + + + /** + * Checks if a challenge is complete or not + * + * @param user - User who must be checked. + * @param challenge - Challenge + * @return - true if completed + */ + public boolean isChallengeComplete(User user, Challenge challenge) + { + this.addPlayer(user); + return this.playerCacheData.get(user.getUniqueId()).isChallengeDone(challenge.getUniqueId()); + } + + + /** + * Get the status on every level + * + * @param user - user + * @param world - world + * @return Level status - how many challenges still to do on which level + */ + public List getChallengeLevelStatus(User user, World world) + { + this.addPlayer(user); + ChallengesPlayerData playerData = this.playerCacheData.get(user.getUniqueId()); + + List challengeLevelList = this.getLevels(world); + + List result = new ArrayList<>(); + + // The first level is always unlocked and previous for it is null. + ChallengeLevel previousLevel = null; + int doneChallengeCount = 0; + + // For each challenge level, check how many the user has done + for (ChallengeLevel level : challengeLevelList) + { + // To find how many challenges user still must do in previous level, we must + // know how many challenges there were and how many has been done. Then + // from waiver amount remove calculated value and you get count. + + int challengesToDo = previousLevel == null ? 0 : + level.getWaiverAmount() - (previousLevel.getChallenges().size() - doneChallengeCount); + + // As level already contains unique ids of challenges, just iterate through them. + doneChallengeCount = (int) level.getChallenges().stream().filter(playerData::isChallengeDone).count(); + + result.add(new LevelStatus( + level, + previousLevel, + challengesToDo, + level.getChallenges().size() == doneChallengeCount, + challengesToDo <= 0)); + + previousLevel = level; + } + + return result; + } + + + /** + * Check is user can see given level. + * + * @param user - user + * @param world - world + * @param level - level + * @return true if level is unlocked + */ + public boolean isLevelUnlocked(User user, World world, ChallengeLevel level) + { + this.addPlayer(user); + + return this.getChallengeLevelStatus(user, world).stream(). + filter(LevelStatus::isUnlocked). + anyMatch(lv -> lv.getLevel().equals(level)); + } + + + /** + * Sets the challenge as complete and increments the number of times it has been + * completed + * + * @param user - user + * @param challenge - challenge + */ + public void setChallengeComplete(User user, Challenge challenge) + { + this.addPlayer(user); + this.playerCacheData.get(user.getUniqueId()).setChallengeDone(challenge.getUniqueId()); + // Save + this.savePlayer(user.getUniqueId()); + } + + + /** + * Reset the challenge to zero time / not done + * + * @param user - user + * @param challenge - challenge + */ + public void resetChallenge(User user, Challenge challenge) + { + this.addPlayer(user); + this.playerCacheData.get(user.getUniqueId()).setChallengeTimes(challenge.getUniqueId(), 0); + // Save + this.savePlayer(user.getUniqueId()); + } + + + + /** + * Resets all the challenges for user in world + * + * @param user - island owner's UUID + * @param world - world + */ + public void resetAllChallenges(User user, World world) + { + this.addPlayer(user); + this.playerCacheData.get(user.getUniqueId()).reset(world); + // Save + this.savePlayer(user.getUniqueId()); + } + + +// --------------------------------------------------------------------- +// Section: Challenges related methods +// --------------------------------------------------------------------- + + + /** + * Get the list of all challenge unique names for world. + * + * @param world - the world to check + * @return List of challenge names + */ + public List getAllChallengesNames(World world) + { + String worldName = Util.getWorld(world).getName(); + // TODO: Probably need to check also database. + return this.challengeCacheData.values().stream(). + sorted(Comparator.comparing(Challenge::getOrder)). + filter(challenge -> challenge.getUniqueId().startsWith(worldName)). + map(Challenge::getUniqueId). + collect(Collectors.toList()); + } + + + /** + * Get the list of all challenge for world. + * + * @param world - the world to check + * @return List of challenges + */ + public List getAllChallenges(World world) + { + String worldName = Util.getWorld(world).getName(); + // TODO: Probably need to check also database. + return this.challengeCacheData.values().stream(). + sorted(Comparator.comparing(Challenge::getOrder)). + filter(challenge -> challenge.getUniqueId().startsWith(worldName)). + collect(Collectors.toList()); + } + + + /** + * Free challenges... Challenges without a level. + * @param world World in which challenges must be searched. + * @return List with free challenges in given world. + */ + public List getFreeChallenges(World world) + { + // Free Challenges hides under FREE level. + return this.getAllChallenges(world).stream(). + filter(challenge -> challenge.getLevel().equals(FREE)). + collect(Collectors.toList()); + } + + + /** + * Level which challenges must be received + * @param level Challenge level. + * @return List with challenges in given level. + */ + public List getLevelChallenges(ChallengeLevel level) + { + return level.getChallenges().stream(). + map(this::getChallenge). + filter(Objects::nonNull). + collect(Collectors.toList()); + } + + + /** + * Get challenge by name. Case sensitive + * + * @param name - unique name of challenge + * @return - challenge or null if it does not exist + */ + public Challenge getChallenge(String name) + { + if (this.challengeCacheData.containsKey(name)) + { + return this.challengeCacheData.get(name); + } + else + { + // check database. + if (this.challengeDatabase.objectExists(name)) + { + Challenge challenge = this.challengeDatabase.loadObject(name); + this.challengeCacheData.put(name, challenge); + return challenge; + } + } + return null; } - public void addChallengeToLevel(Challenge newChallenge, ChallengeLevel level) + /** + * Check if a challenge exists - case insensitive + * + * @param name - name of challenge + * @return true if it exists, otherwise false + */ + public boolean containsChallenge(String name) { + if (this.challengeCacheData.containsKey(name)) + { + return true; + } + else + { + // check database. + if (this.challengeDatabase.objectExists(name)) + { + Challenge challenge = this.challengeDatabase.loadObject(name); + this.challengeCacheData.put(name, challenge); + return true; + } + } + return false; } -} + + + /** + * This method creates and returns new challenge with given uniqueID. + * @param uniqueID - new ID for challenge. + * @return Challenge that is currently created. + */ + public Challenge createChallenge(String uniqueID) + { + if (!this.containsChallenge(uniqueID)) + { + Challenge challenge = new Challenge(); + challenge.setUniqueId(uniqueID); + + this.saveChallenge(challenge); + this.loadChallenge(challenge); + + return challenge; + } + else + { + return null; + } + } + + + /** + * This method removes challenge from cache and memory. + * @param challenge that must be removed. + */ + public void deleteChallenge(Challenge challenge) + { + if (this.challengeCacheData.containsKey(challenge.getUniqueId())) + { + this.challengeCacheData.remove(challenge.getUniqueId()); + this.challengeDatabase.deleteObject(challenge); + } + } + + +// --------------------------------------------------------------------- +// Section: Level related methods +// --------------------------------------------------------------------- + + + /** + * This method returns list of challenge levels in given world. + * @param world for which levels must be searched. + * @return List with challenges in given world. + */ + public List getLevels(World world) + { + String worldName = Util.getWorld(world).getName(); + // TODO: Probably need to check also database. + return this.levelCacheData.values().stream(). + sorted(ChallengeLevel::compareTo). + filter(challenge -> challenge.getUniqueId().startsWith(worldName)). + collect(Collectors.toList()); + } + + + /** + * Get challenge level by its challenge. + * + * @param challenge - challenge which level must be returned. + * @return - challenge level or null if it does not exist + */ + public ChallengeLevel getLevel(Challenge challenge) + { + if (!challenge.getLevel().equals(FREE)) + { + return this.getLevel(challenge.getLevel()); + } + + return new ChallengeLevel(); + } + + + /** + * Get challenge level by name. Case sensitive + * + * @param name - unique name of challenge level + * @return - challenge level or null if it does not exist + */ + public ChallengeLevel getLevel(String name) + { + if (this.levelCacheData.containsKey(name)) + { + return this.levelCacheData.get(name); + } + else + { + // check database. + if (this.levelDatabase.objectExists(name)) + { + ChallengeLevel level = this.levelDatabase.loadObject(name); + this.levelCacheData.put(name, level); + return level; + } + } + + return null; + } + + + /** + * Check if a challenge level exists - case insensitive + * + * @param name - name of challenge level + * @return true if it exists, otherwise false + */ + public boolean containsLevel(String name) + { + if (this.levelCacheData.containsKey(name)) + { + return true; + } + else + { + // check database. + if (this.levelDatabase.objectExists(name)) + { + ChallengeLevel level = this.levelDatabase.loadObject(name); + this.levelCacheData.put(name, level); + return true; + } + } + + return false; + } + + + /** + * This method adds given challenge to given challenge level. + * @param newChallenge Challenge who must change owner. + * @param newLevel Level who must add new challenge + */ + public void addChallengeToLevel(Challenge newChallenge, ChallengeLevel newLevel) + { + if (newChallenge.getLevel().equals(FREE)) + { + newLevel.getChallenges().add(newChallenge.getUniqueId()); + newChallenge.setLevel(newLevel.getUniqueId()); + + this.saveLevel(newLevel); + this.saveChallenge(newChallenge); + } + else + { + ChallengeLevel oldLevel = this.getLevel(newChallenge.getLevel()); + + if (!oldLevel.equals(newLevel)) + { + this.removeChallengeFromLevel(newChallenge, newLevel); + newLevel.getChallenges().add(newChallenge.getUniqueId()); + newChallenge.setLevel(newLevel.getUniqueId()); + + this.saveLevel(newLevel); + this.saveChallenge(newChallenge); + } + } + } + + + /** + * This method removes given challenge from given challenge level. + * @param challenge Challenge which must leave level. + * @param level level which lost challenge + */ + public void removeChallengeFromLevel(Challenge challenge, ChallengeLevel level) + { + if (level.getChallenges().contains(challenge.getUniqueId())) + { + level.getChallenges().remove(challenge.getUniqueId()); + challenge.setLevel(FREE); + this.saveLevel(level); + this.saveChallenge(challenge); + } + } + + + /** + * This method creates and returns new challenges level with given uniqueID. + * @param uniqueID - new ID for challenge level. + * @return ChallengeLevel that is currently created. + */ + public ChallengeLevel createLevel(String uniqueID) + { + if (!this.containsLevel(uniqueID)) + { + ChallengeLevel level = new ChallengeLevel(); + level.setUniqueId(uniqueID); + + this.saveLevel(level); + this.loadLevel(level); + + return level; + } + else + { + return null; + } + } + + + /** + * This method removes challenge level from cache and memory. + * @param challengeLevel Level that must be removed. + */ + public void deleteChallengeLevel(ChallengeLevel challengeLevel) + { + if (this.levelCacheData.containsKey(challengeLevel.getUniqueId())) + { + this.levelCacheData.remove(challengeLevel.getUniqueId()); + this.levelDatabase.deleteObject(challengeLevel); + } + } +} \ No newline at end of file diff --git a/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java b/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java index bb2cc7a..67ddf60 100644 --- a/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java +++ b/src/main/java/world/bentobox/challenges/commands/ChallengesCommand.java @@ -3,10 +3,10 @@ package world.bentobox.challenges.commands; import java.util.List; import world.bentobox.challenges.ChallengesAddon; -import world.bentobox.challenges.panel.ChallengesPanels2; -import world.bentobox.challenges.panel.ChallengesPanels2.Mode; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; +import world.bentobox.challenges.panel.user.ChallengesGUI; + public class ChallengesCommand extends CompositeCommand { public static final String CHALLENGE_COMMAND = "challenges"; @@ -19,7 +19,11 @@ public class ChallengesCommand extends CompositeCommand { public boolean execute(User user, String label, List args) { // Open up the challenges GUI if (user.isPlayer()) { - new ChallengesPanels2((ChallengesAddon) getAddon(), user, user, args.isEmpty() ? "" : args.get(0), getWorld(), getPermissionPrefix(), getTopLabel(), Mode.PLAYER); + new ChallengesGUI((ChallengesAddon) this.getAddon(), + this.getWorld(), + user, + this.getTopLabel(), + this.getPermissionPrefix()).build(); return true; } // Show help diff --git a/src/main/java/world/bentobox/challenges/commands/admin/Challenges.java b/src/main/java/world/bentobox/challenges/commands/admin/Challenges.java index 1115ff7..a73a127 100644 --- a/src/main/java/world/bentobox/challenges/commands/admin/Challenges.java +++ b/src/main/java/world/bentobox/challenges/commands/admin/Challenges.java @@ -3,10 +3,10 @@ package world.bentobox.challenges.commands.admin; import java.util.List; import world.bentobox.challenges.ChallengesAddon; -import world.bentobox.challenges.panel.ChallengesPanels2; -import world.bentobox.challenges.panel.ChallengesPanels2.Mode; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; +import world.bentobox.challenges.panel.admin.AdminGUI; + public class Challenges extends CompositeCommand { @@ -25,7 +25,7 @@ public class Challenges extends CompositeCommand { this.setDescription("challenges.admin.description"); // Register sub commands new ImportCommand(getAddon(), this); - new CompleteChallenge(getAddon(), this); + // new CompleteChallenge(getAddon(), this); new ReloadChallenges(getAddon(), this); new ResetChallenge(getAddon(), this); //new ShowChallenges(getAddon(), this); @@ -37,7 +37,12 @@ public class Challenges extends CompositeCommand { public boolean execute(User user, String label, List args) { // Open up the admin challenges GUI if (user.isPlayer()) { - new ChallengesPanels2((ChallengesAddon) getAddon(), user, user, args.isEmpty() ? "" : args.get(0), getWorld(), getPermissionPrefix(), getTopLabel(), Mode.ADMIN); + new AdminGUI((ChallengesAddon) this.getAddon(), + this.getWorld(), + user, + this.getTopLabel(), + this.getPermissionPrefix()).build(); + return true; } return false; diff --git a/src/main/java/world/bentobox/challenges/commands/admin/CompleteChallenge.java b/src/main/java/world/bentobox/challenges/commands/admin/CompleteChallenge.java index 486662a..1a156fe 100644 --- a/src/main/java/world/bentobox/challenges/commands/admin/CompleteChallenge.java +++ b/src/main/java/world/bentobox/challenges/commands/admin/CompleteChallenge.java @@ -51,13 +51,13 @@ public class CompleteChallenge extends CompositeCommand { return false; } // Check for valid challenge name - if (!manager.isChallenge(getWorld(), args.get(1))) { + if (!manager.containsChallenge(args.get(1))) { user.sendMessage("challenges.admin.complete.unknown-challenge"); return false; } // Complete challenge User target = User.getInstance(targetUUID); - manager.setChallengeComplete(target, args.get(1), getWorld()); + manager.setChallengeComplete(target, this.manager.getChallenge(args.get(1))); user.sendMessage("general.success"); return true; } @@ -70,7 +70,7 @@ public class CompleteChallenge extends CompositeCommand { return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg)); } else if (args.size() == 4) { // Challenges in this world - return Optional.of(Util.tabLimit(manager.getAllChallengesList(getWorld()), lastArg)); + return Optional.of(Util.tabLimit(manager.getAllChallengesNames(getWorld()), lastArg)); } return Optional.empty(); } diff --git a/src/main/java/world/bentobox/challenges/commands/admin/ResetChallenge.java b/src/main/java/world/bentobox/challenges/commands/admin/ResetChallenge.java index 0774072..5e762d5 100644 --- a/src/main/java/world/bentobox/challenges/commands/admin/ResetChallenge.java +++ b/src/main/java/world/bentobox/challenges/commands/admin/ResetChallenge.java @@ -56,13 +56,13 @@ public class ResetChallenge extends CompositeCommand { return false; } // Check for valid challenge name - if (!manager.isChallenge(getWorld(), args.get(1))) { + if (!manager.containsChallenge(args.get(1))) { user.sendMessage("challenges.admin.complete.unknown-challenge"); return false; } // Complete challenge User target = User.getInstance(targetUUID); - manager.setResetChallenge(target, args.get(1), getWorld()); + manager.resetChallenge(target, manager.getChallenge(args.get(1))); user.sendMessage("general.success"); return true; } @@ -75,7 +75,7 @@ public class ResetChallenge extends CompositeCommand { return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg)); } else if (args.size() == 4) { // Challenges in this world - return Optional.of(Util.tabLimit(manager.getAllChallengesList(getWorld()), lastArg)); + return Optional.of(Util.tabLimit(manager.getAllChallengesNames(getWorld()), lastArg)); } return Optional.empty(); } diff --git a/src/main/java/world/bentobox/challenges/commands/admin/ShowChallenges.java b/src/main/java/world/bentobox/challenges/commands/admin/ShowChallenges.java index 8842647..97eb1bb 100644 --- a/src/main/java/world/bentobox/challenges/commands/admin/ShowChallenges.java +++ b/src/main/java/world/bentobox/challenges/commands/admin/ShowChallenges.java @@ -28,7 +28,7 @@ public class ShowChallenges extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { - ((ChallengesAddon)getAddon()).getChallengesManager().getAllChallengesList().forEach(user::sendRawMessage); + ((ChallengesAddon)getAddon()).getChallengesManager().getAllChallengesNames(this.getWorld()).forEach(user::sendRawMessage); return true; } diff --git a/src/main/java/world/bentobox/challenges/commands/admin/SurroundChallengeBuilder.java b/src/main/java/world/bentobox/challenges/commands/admin/SurroundChallengeBuilder.java index ed4791c..037b0af 100644 --- a/src/main/java/world/bentobox/challenges/commands/admin/SurroundChallengeBuilder.java +++ b/src/main/java/world/bentobox/challenges/commands/admin/SurroundChallengeBuilder.java @@ -77,7 +77,7 @@ public class SurroundChallengeBuilder { } public boolean build() { - return addon.getChallengesManager().createSurroundingChallenge(this); + return false; //addon.getChallengesManager().createSurroundingChallenge(this); } diff --git a/src/main/java/world/bentobox/challenges/listeners/ResetListener.java b/src/main/java/world/bentobox/challenges/listeners/ResetListener.java index df0d401..4ee56a9 100644 --- a/src/main/java/world/bentobox/challenges/listeners/ResetListener.java +++ b/src/main/java/world/bentobox/challenges/listeners/ResetListener.java @@ -7,6 +7,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import world.bentobox.bentobox.api.user.User; import world.bentobox.challenges.ChallengesAddon; import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; @@ -27,7 +28,7 @@ public class ResetListener implements Listener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onIslandReset(IslandEvent e) { if (e.getReason().equals(Reason.CREATED) || (addon.getChallengesSettings().isResetChallenges() && e.getReason().equals(Reason.RESETTED))) { - addon.getChallengesManager().resetAllChallenges(e.getOwner(), e.getLocation().getWorld()); + addon.getChallengesManager().resetAllChallenges(User.getInstance(e.getOwner()), e.getLocation().getWorld()); } } } diff --git a/src/main/java/world/bentobox/challenges/listeners/SaveListener.java b/src/main/java/world/bentobox/challenges/listeners/SaveListener.java index 5f411ed..313d2ba 100644 --- a/src/main/java/world/bentobox/challenges/listeners/SaveListener.java +++ b/src/main/java/world/bentobox/challenges/listeners/SaveListener.java @@ -23,7 +23,7 @@ public class SaveListener implements Listener @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onWorldSave(WorldSaveEvent e) { - if (!this.addon.getChallengesManager().getAllChallengesList(e.getWorld()).isEmpty()) + if (!this.addon.getChallengesManager().getAllChallenges(e.getWorld()).isEmpty()) { this.addon.getChallengesManager().save(); } diff --git a/src/main/java/world/bentobox/challenges/panel/ChallengesPanels.java b/src/main/java/world/bentobox/challenges/panel/ChallengesPanels.java index 6e80a53..c3d8f35 100644 --- a/src/main/java/world/bentobox/challenges/panel/ChallengesPanels.java +++ b/src/main/java/world/bentobox/challenges/panel/ChallengesPanels.java @@ -11,6 +11,8 @@ import org.bukkit.inventory.ItemStack; import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesManager; +import world.bentobox.challenges.database.object.ChallengeLevel; +import world.bentobox.challenges.utils.GuiUtils; import world.bentobox.challenges.utils.LevelStatus; import world.bentobox.challenges.commands.ChallengesCommand; import world.bentobox.challenges.database.object.Challenge; @@ -30,7 +32,7 @@ public class ChallengesPanels { private ChallengesAddon addon; private ChallengesManager manager; private User user; - private String level; + private ChallengeLevel level; private World world; private String permPrefix; private String label; @@ -43,17 +45,17 @@ public class ChallengesPanels { this.permPrefix = permPrefix; this.label = label; - if (manager.getChallengeList().isEmpty()) { + if (manager.getAllChallenges(world).isEmpty()) { addon.getLogger().severe("There are no challenges set up!"); user.sendMessage("general.errors.general"); return; } if (level.isEmpty()) { - level = manager.getChallengeList().keySet().iterator().next().getUniqueId(); + level = manager.getLevels(world).iterator().next().getUniqueId(); } - this.level = level; + this.level = this.manager.getLevel(level); // Check if level is valid - if (!manager.isLevelUnlocked(user, level, world)) { + if (!manager.isLevelUnlocked(user, world, this.level)) { return; } PanelBuilder panelBuilder = new PanelBuilder() @@ -69,7 +71,7 @@ public class ChallengesPanels { } private void addChallengeItems(PanelBuilder panelBuilder) { - Set levelChallenges = manager.getChallenges(level, world); + List levelChallenges = manager.getLevelChallenges(level); // Only show a control panel for the level requested. for (Challenge challenge : levelChallenges) { createItem(panelBuilder, challenge); @@ -77,7 +79,7 @@ public class ChallengesPanels { } private void addFreeChallanges(PanelBuilder panelBuilder) { - manager.getChallenges(ChallengesManager.FREE, world).forEach(challenge -> createItem(panelBuilder, challenge)); + manager.getFreeChallenges(world).forEach(challenge -> createItem(panelBuilder, challenge)); } @@ -88,7 +90,7 @@ public class ChallengesPanels { */ private void createItem(PanelBuilder panelBuilder, Challenge challenge) { // Check completion - boolean completed = manager.isChallengeComplete(user, challenge.getUniqueId(), world); + boolean completed = manager.isChallengeComplete(user, challenge); // If challenge is removed after completion, remove it if (completed && challenge.isRemoveWhenCompleted()) { return; @@ -130,7 +132,7 @@ public class ChallengesPanels { PanelItem item = new PanelItemBuilder() .icon(new ItemStack(Material.ENCHANTED_BOOK)) .name(name) - .description(manager.stringSplit(user.getTranslation("challenges.navigation","[level]",name))) + .description(GuiUtils.stringSplit(user.getTranslation("challenges.navigation","[level]",name))) .clickHandler((p, u, c, s) -> { u.closeInventory(); u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId()); @@ -144,7 +146,7 @@ public class ChallengesPanels { PanelItem item = new PanelItemBuilder() .icon(new ItemStack(Material.BOOK)) .name(name) - .description(manager.stringSplit(user.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName))) + .description(GuiUtils.stringSplit(user.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName))) .build(); panelBuilder.item(item); } @@ -167,9 +169,9 @@ public class ChallengesPanels { } // Check if completed or not - boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge.getUniqueId(), world); + boolean complete = addon.getChallengesManager().isChallengeComplete(user, challenge); int maxTimes = challenge.getMaxTimes(); - long doneTimes = addon.getChallengesManager().checkChallengeTimes(user, challenge, world); + long doneTimes = addon.getChallengesManager().getChallengeTimes(user, challenge); if (complete) { result.add(user.getTranslation("challenges.complete")); } @@ -234,6 +236,6 @@ public class ChallengesPanels { } private Collection splitTrans(User user, String string, String...strings) { - return addon.getChallengesManager().stringSplit(user.getTranslation(string, strings)); + return GuiUtils.stringSplit(user.getTranslation(string, strings)); } } diff --git a/src/main/java/world/bentobox/challenges/panel/ChallengesPanels2.java b/src/main/java/world/bentobox/challenges/panel/ChallengesPanels2.java index c432ce6..ea56420 100644 --- a/src/main/java/world/bentobox/challenges/panel/ChallengesPanels2.java +++ b/src/main/java/world/bentobox/challenges/panel/ChallengesPanels2.java @@ -10,6 +10,8 @@ import org.bukkit.inventory.ItemStack; import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.ChallengesManager; +import world.bentobox.challenges.database.object.ChallengeLevel; +import world.bentobox.challenges.utils.GuiUtils; import world.bentobox.challenges.utils.LevelStatus; import world.bentobox.challenges.commands.ChallengesCommand; import world.bentobox.challenges.database.object.Challenge; @@ -35,7 +37,7 @@ public class ChallengesPanels2 { private ChallengesAddon addon; private ChallengesManager manager; private User requester; - private String level; + private ChallengeLevel level; private World world; private String permPrefix; private String label; @@ -52,18 +54,18 @@ public class ChallengesPanels2 { this.label = label; this.mode = mode; - if (manager.getChallengeList().isEmpty()) { + if (manager.getAllChallenges(world).isEmpty()) { addon.getLogger().severe("There are no challenges set up!"); requester.sendMessage("general.errors.general"); return; } if (level.isEmpty()) { // TODO: open the farthest challenge panel - level = manager.getChallengeList().keySet().iterator().next().getUniqueId(); + level = manager.getLevels(world).iterator().next().getUniqueId(); } - this.level = level; + this.level = manager.getLevel(level); // Check if level is valid - if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, level, world)) { + if (mode.equals(Mode.PLAYER) && !manager.isLevelUnlocked(requester, world, this.level)) { return; } PanelBuilder panelBuilder = new PanelBuilder(); @@ -93,13 +95,13 @@ public class ChallengesPanels2 { private void addChallengeItems(PanelBuilder panelBuilder) { // Only show a control panel for the level requested. - for (Challenge challenge : manager.getChallenges(level, world)) { + for (Challenge challenge : manager.getLevelChallenges(level)) { createItem(panelBuilder, challenge); } } private void addFreeChallanges(PanelBuilder panelBuilder) { - manager.getChallenges(ChallengesManager.FREE, world).forEach(challenge -> createItem(panelBuilder, challenge)); + manager.getFreeChallenges(world).forEach(challenge -> createItem(panelBuilder, challenge)); } @@ -116,10 +118,10 @@ public class ChallengesPanels2 { glow = challenge.isDeployed(); break; case EDIT: - glow = manager.isChallengeComplete(requester, challenge.getUniqueId(), world); + glow = manager.isChallengeComplete(requester, challenge); break; case PLAYER: - glow = manager.isChallengeComplete(requester, challenge.getUniqueId(), world); + glow = manager.isChallengeComplete(requester, challenge); break; default: break; @@ -169,7 +171,7 @@ public class ChallengesPanels2 { // Add navigation to other levels for (LevelStatus status: manager.getChallengeLevelStatus(requester, world)) { - if (status.getLevel().getUniqueId().equalsIgnoreCase(level)) { + if (status.getLevel().getUniqueId().equalsIgnoreCase(level.getUniqueId())) { // Skip if this is the current level previousStatus = status; continue; @@ -182,7 +184,7 @@ public class ChallengesPanels2 { PanelItem item = new PanelItemBuilder() .icon(new ItemStack(Material.ENCHANTED_BOOK)) .name(name) - .description(manager.stringSplit(requester.getTranslation("challenges.navigation","[level]",name))) + .description(GuiUtils.stringSplit(requester.getTranslation("challenges.navigation","[level]",name))) .clickHandler((p, u, c, s) -> { u.closeInventory(); u.performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + status.getLevel().getUniqueId()); @@ -196,7 +198,7 @@ public class ChallengesPanels2 { PanelItem item = new PanelItemBuilder() .icon(new ItemStack(Material.BOOK)) .name(name) - .description(manager.stringSplit(requester.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName))) + .description(GuiUtils.stringSplit(requester.getTranslation("challenges.to-complete", "[challengesToDo]",String.valueOf(previousStatus != null ? previousStatus.getNumberOfChallengesStillToDo() : ""), "[thisLevel]", previousLevelName))) .build(); panelBuilder.item(item); } @@ -230,9 +232,9 @@ public class ChallengesPanels2 { result.addAll(addRewards(challenge, true, true)); } else { // Check if completed or not - boolean complete = addon.getChallengesManager().isChallengeComplete(requester, challenge.getUniqueId(), world); + boolean complete = addon.getChallengesManager().isChallengeComplete(requester, challenge); int maxTimes = challenge.getMaxTimes(); - long doneTimes = addon.getChallengesManager().checkChallengeTimes(requester, challenge, world); + long doneTimes = addon.getChallengesManager().getChallengeTimes(requester, challenge); if (complete) { result.add(requester.getTranslation("challenges.complete")); } @@ -307,6 +309,6 @@ public class ChallengesPanels2 { } private Collection splitTrans(User user, String string, String...strings) { - return addon.getChallengesManager().stringSplit(user.getTranslation(string, strings)); + return GuiUtils.stringSplit(user.getTranslation(string, strings)); } } diff --git a/src/main/java/world/bentobox/challenges/panel/CreateChallengeListener.java b/src/main/java/world/bentobox/challenges/panel/CreateChallengeListener.java index 978b64b..d0b63ee 100644 --- a/src/main/java/world/bentobox/challenges/panel/CreateChallengeListener.java +++ b/src/main/java/world/bentobox/challenges/panel/CreateChallengeListener.java @@ -29,7 +29,7 @@ public class CreateChallengeListener implements PanelListener { @Override public void onInventoryClose(InventoryCloseEvent event) { - addon.getChallengesManager().createInvChallenge(user, event.getInventory()); + addon.getChallengesManager().createChallenge("uniqueID"); } @Override diff --git a/src/main/java/world/bentobox/challenges/panel/TryToComplete.java b/src/main/java/world/bentobox/challenges/panel/TryToComplete.java index ffe8709..aadbc38 100644 --- a/src/main/java/world/bentobox/challenges/panel/TryToComplete.java +++ b/src/main/java/world/bentobox/challenges/panel/TryToComplete.java @@ -124,7 +124,7 @@ public class TryToComplete { user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName()); } // Mark as complete - manager.setChallengeComplete(user, challenge.getUniqueId(), world); + manager.setChallengeComplete(user, challenge); user.closeInventory(); user.getPlayer().performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel()); return result; @@ -189,7 +189,7 @@ public class TryToComplete { user.sendMessage("challenges.you-repeated", "[challenge]", challenge.getFriendlyName()); } // Mark as complete - manager.setChallengeComplete(user, challenge.getUniqueId(), world); + manager.setChallengeComplete(user, challenge); user.closeInventory(); user.getPlayer().performCommand(label + " " + ChallengesCommand.CHALLENGE_COMMAND + " " + challenge.getLevel()); } @@ -204,17 +204,17 @@ public class TryToComplete { return new ChallengeResult(); } // Check if user has the - if (!challenge.getLevel().equals(ChallengesManager.FREE) && !manager.isLevelUnlocked(user, challenge.getLevel(), world)) { + if (!challenge.getLevel().equals(ChallengesManager.FREE) && !manager.isLevelUnlocked(user, world, manager.getLevel(challenge.getLevel()))) { user.sendMessage("challenges.errors.challenge-level-not-available"); return new ChallengeResult(); } // Check max times - if (challenge.isRepeatable() && challenge.getMaxTimes() > 0 && manager.checkChallengeTimes(user, challenge, world) >= challenge.getMaxTimes()) { + if (challenge.isRepeatable() && challenge.getMaxTimes() > 0 && manager.getChallengeTimes(user, challenge) >= challenge.getMaxTimes()) { user.sendMessage("challenges.not-repeatable"); return new ChallengeResult(); } // Check repeatability - if (manager.isChallengeComplete(user, challenge.getUniqueId(), world) + if (manager.isChallengeComplete(user, challenge) && (!challenge.isRepeatable() || challenge.getChallengeType().equals(ChallengeType.OTHER) || challenge.getChallengeType().equals(ChallengeType.ISLAND))) { user.sendMessage("challenges.not-repeatable"); @@ -288,7 +288,7 @@ public class TryToComplete { this.removeMoney(); // Return the result - return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge.getUniqueId(), world)); + return new ChallengeResult().setMeetsRequirements().setRepeat(manager.isChallengeComplete(user, challenge)); } diff --git a/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java index 97ae16e..d93d5b5 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/AdminGUI.java @@ -11,6 +11,7 @@ import net.wesjd.anvilgui.AnvilGUI; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.util.Util; import world.bentobox.challenges.ChallengesAddon; import world.bentobox.challenges.panel.CommonGUI; import world.bentobox.challenges.utils.GuiUtils; @@ -198,25 +199,25 @@ public class AdminGUI extends CommonGUI this.user.getPlayer(), "unique_id", (player, reply) -> { + String newName = Util.getWorld(this.world).getName() + "_" + reply; - if (this.addon.getChallengesManager().validateChallengeUniqueID(this.world, reply)) - { - new EditChallengeGUI(this.addon, - this.world, - this.user, - this.addon.getChallengesManager().createChallenge(reply), - this.topLabel, - this.permissionPrefix, - this).build(); - } - else - { - this.user.sendMessage("challenges.errors.unique-id", "[id]", reply); - this.build(); - } + if (this.addon.getChallengesManager().containsChallenge(newName)) + { + new EditChallengeGUI(this.addon, + this.world, + this.user, + this.addon.getChallengesManager().createChallenge(reply), + this.topLabel, + this.permissionPrefix, + this).build(); + } + else + { + this.user.sendMessage("challenges.errors.unique-id", "[id]", reply); + } - return reply; - }); + return reply; + }); return true; }; @@ -234,8 +235,9 @@ public class AdminGUI extends CommonGUI this.user.getPlayer(), "unique_id", (player, reply) -> { + String newName = Util.getWorld(this.world).getName() + "_" + reply; - if (this.addon.getChallengesManager().validateLevelUniqueID(this.world, reply)) + if (this.addon.getChallengesManager().containsLevel(newName)) { new EditLevelGUI(this.addon, this.world, @@ -248,7 +250,6 @@ public class AdminGUI extends CommonGUI else { this.user.sendMessage("challenges.errors.unique-id", "[id]", reply); - this.build(); } return reply; @@ -410,4 +411,4 @@ public class AdminGUI extends CommonGUI return new PanelItem(icon, name, description, glow, clickHandler, false); } -} +} \ No newline at end of file diff --git a/src/main/java/world/bentobox/challenges/panel/admin/EditLevelGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/EditLevelGUI.java index fbcf53c..41517a7 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/EditLevelGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/EditLevelGUI.java @@ -145,7 +145,7 @@ public class EditLevelGUI extends CommonGUI */ private void buildChallengesPanel(PanelBuilder panelBuilder) { - List challengeList = this.addon.getChallengesManager().getChallenges(this.challengeLevel); + List challengeList = this.addon.getChallengesManager().getLevelChallenges(this.challengeLevel); final int MAX_ELEMENTS = 21; @@ -538,8 +538,8 @@ public class EditLevelGUI extends CommonGUI ChallengesManager manager = this.addon.getChallengesManager(); // Get all challenge that is not in current challenge. - List challengeList = manager.getChallengesList(); - challengeList.removeAll(manager.getChallenges(this.challengeLevel)); + List challengeList = manager.getAllChallenges(this.world); + challengeList.removeAll(manager.getLevelChallenges(this.challengeLevel)); new SelectChallengeGUI(this.user, challengeList, (status, value) -> { if (status) @@ -563,10 +563,10 @@ public class EditLevelGUI extends CommonGUI clickHandler = (panel, user, clickType, slot) -> { ChallengesManager manager = this.addon.getChallengesManager(); - new SelectChallengeGUI(this.user, manager.getChallenges(this.challengeLevel), (status, value) -> { + new SelectChallengeGUI(this.user, manager.getLevelChallenges(this.challengeLevel), (status, value) -> { if (status) { - manager.unlinkChallenge(this.challengeLevel, value); + manager.removeChallengeFromLevel(value, this.challengeLevel); } this.build(); diff --git a/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java index 700efe6..77e98f8 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/ListChallengesGUI.java @@ -82,7 +82,7 @@ public class ListChallengesGUI extends CommonGUI GuiUtils.fillBorder(panelBuilder); } - List challengeList = this.addon.getChallengesManager().getChallengesList(); + List challengeList = this.addon.getChallengesManager().getAllChallenges(this.world); final int MAX_ELEMENTS = 21; diff --git a/src/main/java/world/bentobox/challenges/panel/admin/ListLevelsGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/ListLevelsGUI.java index 3c33dd7..6a9b967 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/ListLevelsGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/ListLevelsGUI.java @@ -82,7 +82,7 @@ public class ListLevelsGUI extends CommonGUI GuiUtils.fillBorder(panelBuilder); } - List levelList = this.addon.getChallengesManager().getChallengeLevelList(); + List levelList = this.addon.getChallengesManager().getLevels(this.world); final int MAX_ELEMENTS = 21; diff --git a/src/main/java/world/bentobox/challenges/panel/admin/ListUsersGUI.java b/src/main/java/world/bentobox/challenges/panel/admin/ListUsersGUI.java index b6c9d99..284c8cd 100644 --- a/src/main/java/world/bentobox/challenges/panel/admin/ListUsersGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/admin/ListUsersGUI.java @@ -178,20 +178,20 @@ public class ListUsersGUI extends CommonGUI switch (this.operationMode) { case COMPLETE: - new SelectChallengeGUI(this.user, manager.getChallengesList(), (status, value) -> { + new SelectChallengeGUI(this.user, manager.getAllChallenges(this.world), (status, value) -> { if (status) { - manager.completeChallenge(player.getUniqueId(), value); + manager.setChallengeComplete(User.getInstance(player), value); } this.build(); }); break; case RESET: - new SelectChallengeGUI(this.user, manager.getChallengesList(), (status, value) -> { + new SelectChallengeGUI(this.user, manager.getAllChallenges(this.world), (status, value) -> { if (status) { - manager.resetChallenge(player.getUniqueId(), value); + manager.resetChallenge(User.getInstance(player), value); } this.build(); @@ -292,4 +292,4 @@ public class ListUsersGUI extends CommonGUI return true; }).build(); } -} +} \ No newline at end of file diff --git a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java index d021247..d9c54e6 100644 --- a/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java +++ b/src/main/java/world/bentobox/challenges/panel/user/ChallengesGUI.java @@ -123,7 +123,7 @@ public class ChallengesGUI extends CommonGUI */ private void addFreeChallenges(PanelBuilder panelBuilder) { - List freeChallenges = this.challengesManager.getFreeChallenges(this.user, this.world); + List freeChallenges = this.challengesManager.getFreeChallenges(this.world); final int freeChallengesCount = freeChallenges.size(); if (freeChallengesCount > 18) @@ -185,7 +185,7 @@ public class ChallengesGUI extends CommonGUI { if (this.lastSelectedLevel != null) { - List challenges = this.challengesManager.getChallenges(this.lastSelectedLevel.getLevel()); + List challenges = this.challengesManager.getLevelChallenges(this.lastSelectedLevel.getLevel()); final int challengesCount = challenges.size(); if (challengesCount > 18) @@ -346,7 +346,7 @@ public class ChallengesGUI extends CommonGUI List result = new ArrayList<>(); result.add(this.user.getTranslation("challenges.level", - "[level]", this.challengesManager.getChallengesLevel(challenge))); + "[level]", this.challengesManager.getLevel(challenge).getFriendlyName())); boolean completed = this.challengesManager.isChallengeComplete(this.user, challenge); @@ -358,7 +358,7 @@ public class ChallengesGUI extends CommonGUI if (challenge.isRepeatable()) { int maxTimes = challenge.getMaxTimes(); - long doneTimes = this.challengesManager.checkChallengeTimes(this.user, challenge); + long doneTimes = this.challengesManager.getChallengeTimes(this.user, challenge); if (maxTimes > 0) { diff --git a/src/main/java/world/bentobox/challenges/utils/GuiUtils.java b/src/main/java/world/bentobox/challenges/utils/GuiUtils.java index 34b6107..ecde0d0 100644 --- a/src/main/java/world/bentobox/challenges/utils/GuiUtils.java +++ b/src/main/java/world/bentobox/challenges/utils/GuiUtils.java @@ -1,11 +1,16 @@ package world.bentobox.challenges.utils; +import org.apache.commons.lang.WordUtils; +import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.List; import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.builders.PanelBuilder; @@ -360,4 +365,24 @@ public class GuiUtils return new BorderBlock(itemStack); } } -} + + + /** + * Simple splitter + * + * @param string - string to be split + * @return list of split strings + */ + public static List stringSplit(String string) + { + string = ChatColor.translateAlternateColorCodes('&', string); + // Check length of lines + List result = new ArrayList<>(); + + Arrays.asList(string.split("\\|")). + forEach(line -> result.addAll( + Arrays.asList(WordUtils.wrap(line, 25).split("\\n")))); + + return result; + } +} \ No newline at end of file