218 lines
9.1 KiB
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;
|
|
}
|
|
}
|