CometSkyBlock/plugin/src/main/java/com/alttd/cometskyblock/challenges/ChallengeLoader.java

218 lines
9.1 KiB
Java

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<ChallengeDifficulty> 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<String> 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<String> rewards = section.getStringList(currentChallenge + ".reward-items");
List<String> repeatRewards = section.getStringList(currentChallenge + ".repeat-reward-items");
List<String> 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<ItemStack> createItems(List<String> items) {
List<ItemStack> 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;
}
}