package com.alttd.cometskyblock.challenges; import com.alttd.cometskyblock.CometSkyBlockPlugin; import com.alttd.cometskyblock.api.challenges.ChallengeDifficulty; import com.alttd.cometskyblock.api.challenges.ChallengeType; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.ItemStack; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * Data loader for challenges * Parse the data and build the challenges to be used by the plugin. */ public class ChallengeLoader extends YamlConfiguration { private final CometSkyBlockPlugin plugin; private final File file; private final Object saveLock = new Object(); private final Object2IntMap difficultyLevels = new Object2IntOpenHashMap<>(); public ChallengeLoader(CometSkyBlockPlugin plugin) { super(); this.plugin = plugin; this.file = new File(plugin.getDataFolder(), "challenges.yml"); difficultyLevels.defaultReturnValue(0); reload(); } private void reload() { synchronized (saveLock) { try { load(file); } catch (Exception ignore) { } } } // Todo - do we continue loading or end the loading procedure? public void loadAllChallenges() { for (ChallengeDifficulty difficulty : ChallengeDifficulty.values()) { if (!loadChallenges(difficulty)) { plugin.getLogger().warning(String.format("could not load %s challenges", difficulty.toString())); } loadDifficultyLevel(difficulty); } } private void loadDifficultyLevel(ChallengeDifficulty challengeDifficulty) { if (challengeDifficulty == null) { plugin.getLogger().warning("Could not load challenges!"); return; } String difficulty = challengeDifficulty.toString().toLowerCase(); int level = getInt("level." + difficulty, 0); if (level > 0) difficultyLevels.put(challengeDifficulty, level); } private boolean loadChallenges(ChallengeDifficulty challengeDifficulty) { if (challengeDifficulty == null) { plugin.getLogger().warning("Could not load challenges!"); return false; } String difficulty = challengeDifficulty.toString().toLowerCase(); ConfigurationSection section = getConfigurationSection(difficulty); if (section == null) { plugin.getLogger().warning(String.format("could not load challenges for difficulty %s", difficulty)); return false; } Set challenges = section.getKeys(false); for (String currentChallenge : challenges) { String challengeName = section.getString(currentChallenge + ".name"); String key = section.getString(currentChallenge + ".key"); String shownItem = section.getString(currentChallenge + ".shown-item"); if (shownItem == null || shownItem.isEmpty() || isNotMaterial(shownItem)) { plugin.getLogger().warning(String.format("could not load challenge %s material data", currentChallenge)); continue; } Material shownItemMaterial = Material.getMaterial(shownItem.toUpperCase()); ChallengeType challengeType = ChallengeType.of(section.getString(currentChallenge + ".challenge-type")); String description = section.getString(currentChallenge + ".description"); String requiredText = section.getString(currentChallenge + ".required-text"); String rewardText = section.getString(currentChallenge + ".reward-text"); String repeatRewardText = section.getString(currentChallenge + ".repeat-reward-text"); List rewards = section.getStringList(currentChallenge + ".reward-items"); List repeatRewards = section.getStringList(currentChallenge + ".repeat-reward-items"); List requiredItems = section.getStringList(currentChallenge + ".required-items"); Integer requiredLevel = section.getInt(currentChallenge + ".required-level", 0); Integer radius = section.getInt(currentChallenge + ".radius", 50); // Build the challenge Challenge challenge = new Challenge() .challengeName(challengeName) .difficulty(challengeDifficulty) .key(key) .shownItem(shownItemMaterial) .description(description) .requiredText(requiredText) .rewardText(rewardText) .repeatRewardText(repeatRewardText) .requiredLevel(requiredLevel) .challengeType(challengeType) .rewards(createItems(rewards)) .repeatRewards(createItems(repeatRewards)) .requiredItems(createItems(requiredItems)) .radius(radius); if (!validateChallenge(challenge)) { plugin.getLogger().warning(String.format("Invalid %s challenge: %s", difficulty, currentChallenge)); continue; } plugin.challengeHandler().addChallenge(challenge); } return true; } private boolean isNotMaterial(String material) { return Material.matchMaterial(material.toUpperCase()) == null; } private List createItems(List items) { List itemStacks = new ArrayList<>(); for (String currentItem : items) { String material = currentItem; int amount = 1; if (currentItem.contains(";")) { String[] strings = currentItem.split(";"); if (strings.length != 2) { plugin.getLogger().warning(String.format("Could not make itemstack for item %s, invalid separator", currentItem)); continue; } if (strings[0].equalsIgnoreCase("loottable")) { itemStacks.add(Bukkit.lootTableItem(strings[1])); continue; } if (!isNumber(strings[1])) { plugin.getLogger().warning(String.format("Could not make itemstack for item %s, %s is not an int", currentItem, strings[1])); continue; } material = strings[0]; amount = Integer.parseInt(strings[1]); } ItemStack itemStack = makeItemStack(material, amount); if (itemStack == null) { plugin.getLogger().warning(String.format("Could not make itemstack for item %s", currentItem)); continue; } itemStacks.add(itemStack); } return itemStacks; } private ItemStack makeItemStack(String materialString, int amount) { if (materialString == null || materialString.isEmpty() || isNotMaterial(materialString)) { return null; } Material material = Material.getMaterial(materialString.toUpperCase()); if (material == null) { return null; } return new ItemStack(material, amount); } private boolean validateChallenge(Challenge challenge) { if (challenge.challengeName() != null && challenge.key() != null && challenge.challengeType() != null && challenge.description() != null && challenge.difficulty() != null && challenge.shownItem() != null && challenge.requiredText() != null && challenge.rewardText() != null && challenge.rewards() != null && !challenge.rewards().isEmpty() ) { switch (challenge.challengeType()) { case ISLAND_LEVEL -> { if (challenge.requiredLevel() != null) return true; } case ON_ISLAND -> { if (challenge.requiredItems() != null && !challenge.requiredItems().isEmpty() && challenge.radius() != null) return true; } case ON_PLAYER -> { if (challenge.requiredItems() != null && !challenge.requiredItems().isEmpty() && challenge.repeatRewards() != null && !challenge.repeatRewards().isEmpty() && challenge.repeatRewardText() != null) return true; } default -> { return false; } } } return false; } public int requiredLevel(ChallengeDifficulty challengeDifficulty) { return difficultyLevels.getInt(challengeDifficulty); } private boolean isNumber(String s) { try { Integer.parseInt(s); } catch (NumberFormatException nfe) { return false; } return true; } }