New config folders for storing and organizing skills, waypoints, loot chests, exp tables, attributes.

This commit is contained in:
Jules 2024-07-26 14:03:51 -07:00
parent d248f11a0e
commit 44f846f591
126 changed files with 408 additions and 384 deletions

View File

@ -303,8 +303,6 @@ public class MMOCore extends MMOPlugin {
configManager = new ConfigManager();
if (clearBefore)
MythicLib.plugin.getSkills().initialize(true);
skillManager.initialize(clearBefore);
mineManager.initialize(clearBefore);
partyManager.initialize(clearBefore);

View File

@ -33,11 +33,11 @@ import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.binding.SkillSlot;
import net.Indyuce.mmocore.skill.cast.ComboMap;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.Indyuce.mmocore.util.ConfigUtils;
import net.Indyuce.mmocore.util.FileUtils;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
@ -94,7 +94,7 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
}
});
public PlayerClass(String id, FileConfiguration config) {
public PlayerClass(String id, ConfigurationSection config) {
postLoadAction.cacheConfig(config);
this.id = id.toUpperCase().replace("-", "_").replace(" ", "_");
@ -189,7 +189,7 @@ public class PlayerClass implements ExperienceObject, PreloadedObject {
// Skill slots
if (config.isConfigurationSection("skill-slots"))
ConfigUtils.iterateConfigSectionList(
FileUtils.iterateConfigSectionList(
config.getConfigurationSection("skill-slots"),
skillSlots,
SkillSlot::new,

View File

@ -34,7 +34,7 @@ public class Quest implements PreloadedObject {
parents.add(MMOCore.plugin.questManager.getOrThrow(parent.toLowerCase().replace(" ", "-").replace("_", "-")));
});
public Quest(String id, FileConfiguration config) {
public Quest(String id, ConfigurationSection config) {
postLoadAction.cacheConfig(config);
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");

View File

@ -46,6 +46,7 @@ public class MMOCoreUtils {
return player.getName() == null;
}
@Deprecated
public static String displayName(ItemStack item) {
return item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName()
: UtilityMethods.caseOnWords(item.getType().name().replace("_", " "));
@ -80,32 +81,9 @@ public class MMOCoreUtils {
return str.toLowerCase().replace("_", "-").replace(" ", "-");
}
/**
* @param value an integer you want to convert
* @return the string representing the integer but with roman letters
*/
@Deprecated
public static String toRomanNumerals(int value) {
LinkedHashMap<String, Integer> roman_numerals = new LinkedHashMap<String, Integer>();
roman_numerals.put("M", 1000);
roman_numerals.put("CM", 900);
roman_numerals.put("D", 500);
roman_numerals.put("CD", 400);
roman_numerals.put("C", 100);
roman_numerals.put("XC", 90);
roman_numerals.put("L", 50);
roman_numerals.put("XL", 40);
roman_numerals.put("X", 10);
roman_numerals.put("IX", 9);
roman_numerals.put("V", 5);
roman_numerals.put("IV", 4);
roman_numerals.put("I", 1);
String res = "";
for (Map.Entry<String, Integer> entry : roman_numerals.entrySet()) {
int matches = value / entry.getValue();
res += repeat(entry.getKey(), matches);
value = value % entry.getValue();
}
return res;
return intToRoman(value);
}
private static String repeat(String s, int n) {
@ -256,6 +234,7 @@ public class MMOCoreUtils {
return entities;
}
@Deprecated
public static void heal(LivingEntity target, double value) {
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
double gain = Math.min(max, target.getHealth() + value) - target.getHealth();

View File

@ -31,25 +31,29 @@ public class ExpCurve {
/**
* Reads an exp curve from a text file, one line after the other. Each exp
* value has to be the only thing written on every line
*
*
* @param file Text file to read data from
* @throws IOException IO exception when reading file
*/
public ExpCurve(File file) throws IOException {
this.id = file.getName().replace(".txt", "").toLowerCase().replace("_", "-").replace(" ", "-");
public ExpCurve(File file) {
this.id = file.getName().replace(".txt", "").toLowerCase().replace("_", "-").replace(" ", "-");
BufferedReader reader = new BufferedReader(new FileReader(file));
String readLine;
while ((readLine = reader.readLine()) != null)
experience.add(Integer.valueOf(readLine));
reader.close();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String readLine;
while ((readLine = reader.readLine()) != null)
experience.add(Integer.valueOf(readLine));
reader.close();
Validate.isTrue(!experience.isEmpty(), "There must be at least one exp value in your exp curve");
}
Validate.isTrue(!experience.isEmpty(), "There must be at least one exp value in your exp curve");
} catch(Throwable throwable) {
throw new RuntimeException(throwable);
}
}
/**
* Public constructor for external plugins
*
*
* @param id Some unique identifier to let other plugin features refer
* to your exp curve.
* @param values The exp values, at to be at least one or the constructor

View File

@ -9,6 +9,7 @@ import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -37,7 +38,7 @@ public class Profession implements ExperienceObject, PreloadedObject {
MMOCore.plugin.professionManager.loadProfessionConfigurations(this, config);
});
public Profession(String id, FileConfiguration config) {
public Profession(String id, ConfigurationSection config) {
postLoadAction.cacheConfig(config);
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");

View File

@ -0,0 +1,37 @@
package net.Indyuce.mmocore.loot.chest;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.util.configobject.ConfigSectionObject;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.droptable.DropTable;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.Nullable;
public class StaticLootChest {
private final String id;
private final Location location;
private final DropTable table;
@Nullable
private String permission;
public StaticLootChest(ConfigurationSection config) {
this.id = config.getName();
this.location = UtilityMethods.readLocation(new ConfigSectionObject(config.getConfigurationSection("location")));
this.table = MMOCore.plugin.dropTableManager.loadDropTable(config.get("drops"));
}
public String getId() {
return id;
}
public Location getLocation() {
return location;
}
public DropTable getTable() {
return table;
}
}

View File

@ -5,6 +5,8 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.player.attribute.MMOCoreAttributeStatHandler;
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.util.FileUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -38,14 +40,10 @@ public class AttributeManager implements MMOCoreManager {
MythicLib.plugin.getStats().clearRegisteredStats(handler -> handler instanceof MMOCoreAttributeStatHandler);
}
final ConfigFile config = new ConfigFile("attributes");
for (String key : config.getConfig().getKeys(false))
try {
String path = key.toLowerCase().replace("_", "-").replace(" ", "-");
map.put(path, new PlayerAttribute(config.getConfig().getConfigurationSection(key)));
} catch (IllegalArgumentException exception) {
MMOCore.log(Level.WARNING, "Could not load attribute '" + key + "': " + exception.getMessage());
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "attributes", false, (key, config) -> {
final String path = key.toLowerCase().replace("_", "-").replace(" ", "-");
map.put(path, new PlayerAttribute(config));
}, "Could not load attribute '%s' from file '%s': %s");
final ConfigurationSection statsConfig = new ConfigFile(MythicLib.plugin, "", "stats").getConfig();
for (PlayerAttribute attr : getAll()) {

View File

@ -1,17 +1,17 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.profess.event.trigger.*;
import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import net.Indyuce.mmocore.api.player.profess.event.trigger.*;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.util.FileUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.HandlerList;
import java.io.File;
import java.util.*;
import java.util.logging.Level;
@ -83,13 +83,9 @@ public class ClassManager implements MMOCoreManager {
triggerHandlers.forEach(HandlerList::unregisterAll);
}
for (File file : new File(MMOCore.plugin.getDataFolder() + "/classes").listFiles())
try {
String id = file.getName().substring(0, file.getName().length() - 4);
register(new PlayerClass(id, YamlConfiguration.loadConfiguration(file)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load class '" + file.getName() + "': " + exception.getMessage());
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "classes", true, (name, config) -> {
register(new PlayerClass(name, config));
}, "Could not load class from file '%s': %s");
for (PlayerClass profess : map.values())
try {

View File

@ -8,6 +8,7 @@ import net.Indyuce.mmocore.api.util.input.ChatInput;
import net.Indyuce.mmocore.api.util.input.PlayerInput;
import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
import net.Indyuce.mmocore.command.api.CommandVerbose;
import net.Indyuce.mmocore.util.FileUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
@ -18,8 +19,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
@ -45,65 +44,81 @@ public class ConfigManager {
* already loaded based on the config
*/
public ConfigManager() {
// loadDefaultFile("recipes", "brewing.yml");
// loadDefaultFile("recipes", "furnace.yml");
if (!new File(MMOCore.plugin.getDataFolder() + "/drop-tables").exists())
loadDefaultFile("drop-tables", "example-drop-tables.yml");
if (!new File(MMOCore.plugin.getDataFolder() + "/professions").exists()) {
loadDefaultFile("professions", "alchemy.yml");
loadDefaultFile("professions", "farming.yml");
loadDefaultFile("professions", "fishing.yml");
loadDefaultFile("professions", "mining.yml");
loadDefaultFile("professions", "smelting.yml");
loadDefaultFile("professions", "smithing.yml");
loadDefaultFile("professions", "woodcutting.yml");
loadDefaultFile("professions", "enchanting.yml");
// Backwards compatibility for older configs
{
FileUtils.moveIfExists(MMOCore.plugin, "attributes.yml", "attributes");
FileUtils.moveIfExists(MMOCore.plugin, "exp-tables.yml", "exp-tables");
FileUtils.moveIfExists(MMOCore.plugin, "loot-chests.yml", "loot-chests");
FileUtils.moveIfExists(MMOCore.plugin, "waypoints.yml", "waypoints");
}
if (!new File(MMOCore.plugin.getDataFolder() + "/quests").exists()) {
loadDefaultFile("quests", "adv-begins.yml");
loadDefaultFile("quests", "tutorial.yml");
loadDefaultFile("quests", "fetch-mango.yml");
if (!FileUtils.getFile(MMOCore.plugin, "attributes").exists()) {
copyDefaultFile("attributes/default_attributes.yml");
}
if (!new File(MMOCore.plugin.getDataFolder() + "/classes").exists()) {
loadDefaultFile("classes", "arcane-mage.yml");
loadDefaultFile("classes", "human.yml");
loadDefaultFile("classes", "mage.yml");
loadDefaultFile("classes", "marksman.yml");
loadDefaultFile("classes", "paladin.yml");
loadDefaultFile("classes", "rogue.yml");
loadDefaultFile("classes", "warrior.yml");
if (!FileUtils.getFile(MMOCore.plugin, "classes").exists()) {
copyDefaultFile("classes/mage/arcane-mage.yml");
copyDefaultFile("classes/mage/mage.yml");
copyDefaultFile("classes/human.yml");
copyDefaultFile("classes/marksman.yml");
copyDefaultFile("classes/paladin.yml");
copyDefaultFile("classes/rogue.yml");
copyDefaultFile("classes/warrior.yml");
}
if (!new File(MMOCore.plugin.getDataFolder() + "/expcurves").exists()) {
loadDefaultFile("expcurves", "levels.txt");
loadDefaultFile("expcurves", "mining.txt");
if (!FileUtils.getFile(MMOCore.plugin, "drop-tables").exists())
copyDefaultFile("drop-tables/example_drop_tables.yml");
if (!FileUtils.getFile(MMOCore.plugin, "exp-tables").exists())
copyDefaultFile("exp-tables/default_exp_tables.yml");
if (!FileUtils.getFile(MMOCore.plugin, "expcurves").exists()) {
copyDefaultFile("expcurves/levels.txt");
copyDefaultFile("expcurves/mining.txt");
copyDefaultFile("expcurves/skill-tree-node.txt");
}
if (!new File(MMOCore.plugin.getDataFolder() + "/skill-trees").exists()) {
loadDefaultFile("skill-trees", "combat.yml");
loadDefaultFile("skill-trees", "mage-arcane-mage.yml");
loadDefaultFile("skill-trees", "rogue-marksman.yml");
loadDefaultFile("skill-trees", "warrior-paladin.yml");
loadDefaultFile("skill-trees", "general.yml");
if (!FileUtils.getFile(MMOCore.plugin, "loot-chests").exists())
copyDefaultFile("loot-chests/default_loot_chests.yml");
if (!FileUtils.getFile(MMOCore.plugin, "professions").exists()) {
copyDefaultFile("professions/alchemy.yml");
copyDefaultFile("professions/farming.yml");
copyDefaultFile("professions/fishing.yml");
copyDefaultFile("professions/mining.yml");
copyDefaultFile("professions/smelting.yml");
copyDefaultFile("professions/smithing.yml");
copyDefaultFile("professions/woodcutting.yml");
copyDefaultFile("professions/enchanting.yml");
}
loadDefaultFile("attributes.yml");
loadDefaultFile("items.yml");
loadDefaultFile("messages.yml");
loadDefaultFile("stats.yml");
loadDefaultFile("waypoints.yml");
loadDefaultFile("restrictions.yml");
loadDefaultFile("sounds.yml");
loadDefaultFile("loot-chests.yml");
loadDefaultFile("exp-tables.yml");
loadDefaultFile("exp-sources.yml");
loadDefaultFile("triggers.yml");
loadDefaultFile("conditions.yml");
loadDefaultFile("guilds.yml");
if (!FileUtils.getFile(MMOCore.plugin, "quests").exists()) {
copyDefaultFile("quests/adv-begins.yml");
copyDefaultFile("quests/tutorial.yml");
copyDefaultFile("quests/fetch-mango.yml");
}
if (!FileUtils.getFile(MMOCore.plugin, "skill-trees").exists()) {
copyDefaultFile("skill-trees/combat.yml");
copyDefaultFile("skill-trees/mage-arcane-mage.yml");
copyDefaultFile("skill-trees/rogue-marksman.yml");
copyDefaultFile("skill-trees/warrior-paladin.yml");
copyDefaultFile("skill-trees/general.yml");
}
if (!FileUtils.getFile(MMOCore.plugin, "waypoints").exists()) {
copyDefaultFile("waypoints/default_waypoints.yml");
}
copyDefaultFile("conditions.yml");
copyDefaultFile("exp-sources.yml");
copyDefaultFile("guilds.yml");
copyDefaultFile("items.yml");
copyDefaultFile("messages.yml");
copyDefaultFile("restrictions.yml");
copyDefaultFile("sounds.yml");
copyDefaultFile("stats.yml");
final ConfigurationSection config = MMOCore.plugin.getConfig();
commandVerbose.reload(MMOCore.plugin.getConfig().getConfigurationSection("command-verbose"));
@ -179,27 +194,19 @@ public class ConfigManager {
return new ChatInput(player, type, null, output);
}
public void loadDefaultFile(String name) {
loadDefaultFile("", name);
public void copyDefaultFile(String path) {
FileUtils.copyDefaultFile(MMOCore.plugin, path);
}
public void loadDefaultFile(String path, String name) {
String newPath = "";
if (!path.isEmpty()) {
String[] subpaths = path.split("/");
for (String subpath : subpaths) {
newPath += "/" + subpath;
File folder = new File(MMOCore.plugin.getDataFolder() + (newPath));
if (!folder.exists()) folder.mkdir();
}
}
@Deprecated
public void loadDefaultFile(String name) {
copyDefaultFile(name);
}
File file = new File(MMOCore.plugin.getDataFolder() + (newPath), name);
if (!file.exists()) try {
Files.copy(MMOCore.plugin.getResource("default/" + (path.isEmpty() ? "" : path + "/") + name), file.getAbsoluteFile().toPath());
} catch (IOException e) {
e.printStackTrace();
}
@Deprecated
public void copyDefaultFile(String path, String name) {
if (path.isEmpty()) copyDefaultFile(name);
else copyDefaultFile(path + "/" + name);
}
@Deprecated

View File

@ -2,17 +2,16 @@ package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.droptable.DropTable;
import net.Indyuce.mmocore.util.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
public class DropTableManager implements MMOCoreManager {
private final Map<String, DropTable> map = new HashMap<>();
@ -21,6 +20,7 @@ public class DropTableManager implements MMOCoreManager {
map.put(table.getId(), table);
}
@Nullable
public DropTable get(String path) {
return map.get(path);
}
@ -29,19 +29,22 @@ public class DropTableManager implements MMOCoreManager {
return map.containsKey(path);
}
@NotNull
public Collection<DropTable> getDropTables() {
return map.values();
}
@NotNull
public Set<String> getKeys() {
return map.keySet();
}
/*
* can only be used once the plugin has been fully loaded (+ enabled). used
/**
* Can only be used once the plugin has been fully loaded (+ enabled). used
* to load extra drop tables from different config files e.g blocks, fishing
* drop tables
*/
@NotNull
public DropTable loadDropTable(Object obj) throws IllegalArgumentException {
if (obj instanceof String)
@ -58,23 +61,12 @@ public class DropTableManager implements MMOCoreManager {
@Override
public void initialize(boolean clearBefore) {
if (clearBefore)
map.clear();
if (clearBefore) map.clear();
for (File file : new File(MMOCore.plugin.getDataFolder() + "/drop-tables").listFiles())
try {
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
for (String key : config.getKeys(false))
try {
register(new DropTable(config.getConfigurationSection(key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load drop table '" + key + "': " + exception.getMessage());
}
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load drop table file '" + file.getName() + "': " + exception.getMessage());
}
// Load drop tables
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "drop-tables", false, (name, config) -> {
register(new DropTable(config));
}, "Could not load drop table '%s' from file '%s': %s");
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> map.values().forEach(table -> table.getPostLoadAction().performAction()));
}

View File

@ -1,21 +1,18 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import net.Indyuce.mmocore.util.FileUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
public class ExperienceManager implements MMOCoreManager {
private final Map<String, ExpCurve> expCurves = new HashMap<>();
@ -112,22 +109,15 @@ public class ExperienceManager implements MMOCoreManager {
}
// Exp curves
for (File file : new File(MMOCore.plugin.getDataFolder() + "/expcurves").listFiles())
try {
ExpCurve curve = new ExpCurve(file);
expCurves.put(curve.getId(), curve);
} catch (IllegalArgumentException | IOException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp curve '" + file.getName() + "': " + exception.getMessage());
}
FileUtils.loadObjectsFromFolderRaw(MMOCore.plugin, "expcurves", file -> {
final ExpCurve curve = new ExpCurve(file);
expCurves.put(curve.getId(), curve);
}, "Could not load exp curve from file '%s': %s");
// Exp tables
FileConfiguration expTablesConfig = new ConfigFile("exp-tables").getConfig();
for (String key : expTablesConfig.getKeys(false))
try {
ExperienceTable table = new ExperienceTable(expTablesConfig.getConfigurationSection(key));
expTables.put(table.getId(), table);
} catch (RuntimeException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp table '" + key + "': " + exception.getMessage());
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin ,"exp-tables", false, (key, config) -> {
final ExperienceTable table = new ExperienceTable(config);
expTables.put(table.getId(), table);
}, "Could not load exp table '%s' from file '%s': %s");
}
}

View File

@ -12,7 +12,6 @@ import net.Indyuce.mmocore.gui.social.guild.EditableGuildCreation;
import net.Indyuce.mmocore.gui.social.guild.EditableGuildView;
import net.Indyuce.mmocore.gui.social.party.EditablePartyCreation;
import net.Indyuce.mmocore.gui.social.party.EditablePartyView;
import org.bukkit.Bukkit;
import java.util.*;
import java.util.function.BiFunction;
@ -44,7 +43,7 @@ public class InventoryManager {
//Loads the specific inventories
for (SpecificInventoryLoader loader : SpecificInventoryLoader.values()) {
try {
MMOCore.plugin.configManager.loadDefaultFile("gui/" + loader.name, loader.name + "-default.yml");
MMOCore.plugin.configManager.copyDefaultFile("gui/" + loader.name + "/" + loader.name + "-default.yml");
} catch (Exception exception) {
MMOCore.log(Level.WARNING, "Could not load inventory 'gui/" + loader.name + "/" + loader.name + "-default" + "': " + exception.getMessage());
}
@ -59,7 +58,7 @@ public class InventoryManager {
list.forEach(inv ->
{
try {
MMOCore.plugin.configManager.loadDefaultFile("gui", inv.getId() + ".yml");
MMOCore.plugin.configManager.copyDefaultFile("gui/" + inv.getId() + ".yml");
inv.reload(new ConfigFile("/gui", inv.getId()).getConfig());
} catch (Exception exception) {
MMOCore.log(Level.WARNING, "Could not load inventory '" + (inv instanceof ClassConfirmation ? "class-confirm/" : "") + inv.getId() + "': " + exception.getMessage());

View File

@ -1,12 +1,12 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.chest.LootChestRegion;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.loot.chest.LootChest;
import net.Indyuce.mmocore.loot.chest.LootChestRegion;
import net.Indyuce.mmocore.util.FileUtils;
import net.Indyuce.mmocore.util.HashableLocation;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -14,7 +14,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
public class LootChestManager implements MMOCoreManager {
@ -69,14 +68,9 @@ public class LootChestManager implements MMOCoreManager {
regions.clear();
}
FileConfiguration config = new ConfigFile("loot-chests").getConfig();
for (String key : config.getKeys(false))
try {
LootChestRegion region = new LootChestRegion(config.getConfigurationSection(key));
regions.put(region.getId(), region);
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"An error occured while trying to load loot chest region '" + key + "': " + exception.getMessage());
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "loot-chests", false, (key, config) -> {
LootChestRegion region = new LootChestRegion(config.getConfigurationSection(key));
regions.put(region.getId(), region);
}, "Could not load loot chest region '%s' from file '%s': %s");
}
}

View File

@ -1,59 +1,49 @@
package net.Indyuce.mmocore.manager;
import java.io.File;
import java.util.Arrays;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.Quest;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.util.FileUtils;
import org.apache.commons.lang.Validate;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.Quest;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
public class QuestManager implements MMOCoreManager {
private final Map<String, Quest> quests = new LinkedHashMap<>();
public void load(File file) {
if (file.isDirectory())
Arrays.stream(file.listFiles()).sorted().forEach(this::load);
else
try {
register(new Quest(file.getName().substring(0, file.getName().length() - 4), YamlConfiguration.loadConfiguration(file)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load quest '" + file.getName() + "': " + exception.getMessage());
}
}
private final Map<String, Quest> quests = new LinkedHashMap<>();
public void register(Quest quest) {
quests.put(quest.getId(), quest);
}
public void register(Quest quest) {
quests.put(quest.getId(), quest);
}
public Quest get(String id) {
return quests.get(id);
}
public Quest get(String id) {
return quests.get(id);
}
public Quest getOrThrow(String id) {
Validate.isTrue(quests.containsKey(id), "Could not find quest with ID '" + id + "'");
return get(id);
}
public Quest getOrThrow(String id) {
Validate.isTrue(quests.containsKey(id), "Could not find quest with ID '" + id + "'");
return get(id);
}
public Collection<Quest> getAll() {
return quests.values();
}
public Collection<Quest> getAll() {
return quests.values();
}
@Override
public void initialize(boolean clearBefore) {
if (clearBefore)
quests.clear();
@Override
public void initialize(boolean clearBefore) {
if (clearBefore) quests.clear();
load(new File(MMOCore.plugin.getDataFolder() + "/quests"));
for (Quest quest : quests.values())
try {
quest.getPostLoadAction().performAction();
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not post-load quest '" + quest.getId() + "': " + exception.getMessage());
}
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "quests", true, (key, config) -> {
register(new Quest(key, config));
}, "Could not load quest from file '%s': %s");
for (Quest quest : quests.values())
try {
quest.getPostLoadAction().performAction();
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not post-load quest '" + quest.getId() + "': " + exception.getMessage());
}
}
}

View File

@ -4,11 +4,12 @@ import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigFile;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.list.Ambers;
import net.Indyuce.mmocore.skill.list.Neptune_Gift;
import net.Indyuce.mmocore.skill.list.Sneaky_Picky;
import net.Indyuce.mmocore.util.FileUtils;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -16,7 +17,10 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.*;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
public class SkillManager implements MMOCoreManager {
@ -26,7 +30,6 @@ public class SkillManager implements MMOCoreManager {
skills.put(skill.getHandler().getId().toUpperCase(), skill);
}
@Nullable
public RegisteredSkill getSkill(String id) {
return skills.get(id.toUpperCase());
@ -42,53 +45,38 @@ public class SkillManager implements MMOCoreManager {
}
public void initialize(boolean clearBefore) {
if (clearBefore)
if (clearBefore) {
MythicLib.plugin.getSkills().initialize(true);
skills.clear();
}
// Register MMOCore specific skills
MythicLib.plugin.getSkills().registerSkillHandler(new Ambers());
MythicLib.plugin.getSkills().registerSkillHandler(new Neptune_Gift());
MythicLib.plugin.getSkills().registerSkillHandler(new Sneaky_Picky());
// Check for default files
File skillFolder = new File(MMOCore.plugin.getDataFolder() + "/skills");
// Save default files if necessary
final File skillFolder = FileUtils.getFile(MMOCore.plugin, "skills");
if (!skillFolder.exists())
try {
skillFolder.mkdir();
for (SkillHandler handler : MythicLib.plugin.getSkills().getHandlers()) {
InputStream res = MMOCore.plugin.getResource("default/skills/" + handler.getLowerCaseId() + ".yml");
final InputStream res = MMOCore.plugin.getResource("default/skills/default_mmo_skills/" + handler.getLowerCaseId() + ".yml");
MMOCore.plugin.getLogger().log(Level.INFO, ("default/skills/default_mmo_skills/" + handler.getLowerCaseId() + ".yml") + " => " + (res != null));
if (res != null)
Files.copy(res, new File(MMOCore.plugin.getDataFolder() + "/skills/" + handler.getLowerCaseId() + ".yml").getAbsoluteFile().toPath());
Files.copy(res, new File(MMOCore.plugin.getDataFolder() + "/skills/default_mmo_skills/" + handler.getLowerCaseId() + ".yml").getAbsoluteFile().toPath());
}
} catch (IOException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not save default skill configs: " + exception.getMessage());
}
for (SkillHandler handler : MythicLib.plugin.getSkills().getHandlers()) {
// Check if config file exists
ConfigFile config = new ConfigFile("/skills", handler.getLowerCaseId());
if (!config.exists()) {
config.getConfig().set("name", UtilityMethods.caseOnWords(handler.getId().replace("_", " ").replace("-", " ").toLowerCase()));
config.getConfig().set("lore", Arrays.asList("This is the default skill description", "", "&e{cooldown}s Cooldown", "&9Costs {mana} {mana_name}"));
config.getConfig().set("material", "BOOK");
for (Object param : handler.getParameters()) {
config.getConfig().set(param + ".base", 0);
config.getConfig().set(param + ".per-level", 0);
config.getConfig().set(param + ".min", 0);
config.getConfig().set(param + ".max", 0);
}
config.save();
}
try {
final RegisteredSkill skill = new RegisteredSkill(handler, config.getConfig());
this.skills.put(handler.getId(), skill);
} catch (RuntimeException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load skill '" + handler.getId() + "': " + exception.getMessage());
}
}
// Load skills
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "skills", true, (name, config) -> {
final SkillHandler<?> handler = MythicLib.plugin.getSkills().getHandler(UtilityMethods.enumName(name));
Validate.notNull(handler, "Could not find skill handler with ID '" + UtilityMethods.enumName(name) + "'");
final RegisteredSkill skill = new RegisteredSkill(handler, config);
this.skills.put(handler.getId(), skill);
}, "Could not load skill from file '%s': %s");
}
}

View File

@ -1,14 +1,15 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.skilltree.ParentType;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.Indyuce.mmocore.manager.registry.MMOCoreRegister;
import net.Indyuce.mmocore.skilltree.ParentType;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import org.bukkit.configuration.file.YamlConfiguration;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import net.Indyuce.mmocore.util.FileUtils;
import java.io.File;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@ -25,7 +26,6 @@ public class SkillTreeManager extends MMOCoreRegister<SkillTree> {
return index >= 0 && index < registered.values().stream().collect(Collectors.toList()).size();
}
public SkillTreeNode getNode(String fullId) {
return skillTreeNodes.get(fullId);
}
@ -56,25 +56,11 @@ public class SkillTreeManager extends MMOCoreRegister<SkillTree> {
@Override
public void initialize(boolean clearBefore) {
if (clearBefore)
registered.clear();
File file = new File(MMOCore.plugin.getDataFolder() + "/skill-trees");
if (!file.exists())
file.mkdirs();
load(file);
}
if (clearBefore) registered.clear();
public void load(File file) {
if (file.isDirectory()) {
List<File> fileList = Arrays.asList(file.listFiles()).stream().sorted().collect(Collectors.toList());
for (File child : fileList) {
load(child);
}
} else {
SkillTree skillTree = SkillTree.loadSkillTree(YamlConfiguration.loadConfiguration(file));
if (skillTree != null)
register(skillTree);
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "skill-trees", true, (key, config) -> {
SkillTree skillTree = SkillTree.loadSkillTree(config);
if (skillTree != null) register(skillTree);
}, "Could not load skill tree from file '%s': %s");
}
}

View File

@ -1,10 +1,10 @@
package net.Indyuce.mmocore.manager;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.util.FileUtils;
import net.Indyuce.mmocore.waypoint.Waypoint;
import net.Indyuce.mmocore.api.ConfigFile;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
@ -49,13 +49,10 @@ public class WaypointManager implements MMOCoreManager {
if (clearBefore)
waypoints.clear();
FileConfiguration config = new ConfigFile("waypoints").getConfig();
for (String key : config.getKeys(false))
try {
register(new Waypoint(config.getConfigurationSection(key)));
} catch (RuntimeException exception) {
MMOCore.log(Level.WARNING, "Could not load waypoint '" + key + "': " + exception.getMessage());
}
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "waypoints", false, (key, config) -> {
register(new Waypoint(config));
}, "Could not load waypoint '%s' from file '%s': %s");
for (Waypoint waypoint : waypoints.values())
try {

View File

@ -1,14 +1,14 @@
package net.Indyuce.mmocore.manager.profession;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.manager.MMOCoreManager;
import net.Indyuce.mmocore.util.FileUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.*;
import java.util.logging.Level;
@ -69,14 +69,10 @@ public class ProfessionManager implements MMOCoreManager {
professionManagers.forEach(manager -> manager.initialize(clearBefore));
// Register professions
for (File file : new File(MMOCore.plugin.getDataFolder() + "/professions").listFiles())
try {
String id = file.getName().substring(0, file.getName().length() - 4);
register(new Profession(id, YamlConfiguration.loadConfiguration(file)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load profession " + file.getName() + ": " + exception.getMessage());
}
// Register professions
FileUtils.loadObjectsFromFolder(MMOCore.plugin, "professions", true, (name, config) -> {
register(new Profession(name, config));
}, "Could not load profession from file '%s': %s");
// Load profession-specific configurations
for (Profession profession : professions.values())

View File

@ -1,39 +0,0 @@
package net.Indyuce.mmocore.util;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class ConfigUtils {
public static <T> void iterateConfigSectionList(@NotNull ConfigurationSection config,
@NotNull List<T> list,
@NotNull Function<ConfigurationSection, T> subconfigHandler,
@NotNull Function<Integer, T> fill,
@NotNull BiConsumer<String, RuntimeException> errorHandler) {
int expectedOrdinal = 1;
for (String key : config.getKeys(false))
try {
final int index = Integer.parseInt(key);
final ConfigurationSection subconfig = config.getConfigurationSection(key);
Validate.notNull(subconfig, "Not a configuration section");
// Replace
if (index < expectedOrdinal) list.set(index, subconfigHandler.apply(subconfig));
else {
while (expectedOrdinal < index)
list.add(fill.apply(expectedOrdinal++));
list.add(subconfigHandler.apply(subconfig));
expectedOrdinal++;
}
} catch (RuntimeException exception) {
errorHandler.accept(key, exception);
}
}
}

View File

@ -0,0 +1,138 @@
package net.Indyuce.mmocore.util;
import net.Indyuce.mmocore.MMOCore;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Level;
public class FileUtils {
public static <T> void iterateConfigSectionList(@NotNull ConfigurationSection config,
@NotNull List<T> list,
@NotNull Function<ConfigurationSection, T> subconfigHandler,
@NotNull Function<Integer, T> fill,
@NotNull BiConsumer<String, RuntimeException> errorHandler) {
int expectedOrdinal = 1;
for (String key : config.getKeys(false))
try {
final int index = Integer.parseInt(key);
final ConfigurationSection subconfig = config.getConfigurationSection(key);
Validate.notNull(subconfig, "Not a configuration section");
// Replace
if (index < expectedOrdinal) list.set(index, subconfigHandler.apply(subconfig));
else {
while (expectedOrdinal < index)
list.add(fill.apply(expectedOrdinal++));
list.add(subconfigHandler.apply(subconfig));
expectedOrdinal++;
}
} catch (RuntimeException exception) {
errorHandler.accept(key, exception);
}
}
public static void loadObjectsFromFolder(@NotNull Plugin plugin,
@NotNull String path,
boolean singleObject,
@NotNull BiConsumer<String, ConfigurationSection> action,
@NotNull String errorMessageFormat) {
// Action to perform
final Consumer<File> fileAction = file -> {
final FileConfiguration config = YamlConfiguration.loadConfiguration(file);
if (singleObject) try {
final String name = file.getName().substring(0, file.getName().length() - 4);
action.accept(name, config);
} catch (Throwable throwable) {
MMOCore.plugin.getLogger().log(Level.WARNING, errorMessageFormat.formatted(file.getName(), throwable.getMessage()));
}
else for (String key : config.getKeys(false))
try {
action.accept(key, config.getConfigurationSection(key));
} catch (Throwable throwable) {
MMOCore.plugin.getLogger().log(Level.WARNING, errorMessageFormat.formatted(key, file.getName(), throwable.getMessage()));
}
};
// Perform on all paths
exploreFolderRecursively(getFile(plugin, path), fileAction);
}
public static void loadObjectsFromFolderRaw(@NotNull Plugin plugin,
@NotNull String path,
@NotNull Consumer<File> action,
@NotNull String errorMessageFormat) {
// Action to perform
final Consumer<File> fileAction = file -> {
try {
action.accept(file);
} catch (Throwable throwable) {
MMOCore.plugin.getLogger().log(Level.WARNING, errorMessageFormat.formatted(file.getName(), throwable.getMessage()));
}
};
// Perform on all paths
exploreFolderRecursively(getFile(plugin, path), fileAction);
}
private static void exploreFolderRecursively(@Nullable File file, @NotNull Consumer<File> action) {
if (!file.exists()) return;
if (file.isFile()) action.accept(file);
else Arrays.stream(file.listFiles()).sorted().forEach(subfile -> exploreFolderRecursively(subfile, action));
}
@NotNull
public static File getFile(@NotNull Plugin plugin, @NotNull String path) {
return new File(plugin.getDataFolder() + "/" + path);
}
public static boolean moveIfExists(@NotNull Plugin plugin,
@NotNull String filePath,
@NotNull String newFolderPath) {
final File existing = getFile(plugin, filePath);
final boolean result = existing.exists();
if (result) {
final String fullPath = newFolderPath + "/" + filePath;
mkdirFolders(plugin, fullPath);
Validate.isTrue(existing.renameTo(getFile(plugin, fullPath)), "Could not move '%s' to '%s'".formatted(filePath, newFolderPath));
}
return result;
}
private static void mkdirFolders(@NotNull Plugin plugin, @NotNull String fullPath) {
String currentPath = "";
final String[] subpaths = fullPath.split("/");
for (int i = 0; i < subpaths.length - 1; i++) {
currentPath += "/" + subpaths[i];
getFile(plugin, currentPath).mkdir();
}
}
public static void copyDefaultFile(@NotNull Plugin plugin, @NotNull String path) {
mkdirFolders(plugin, path);
final File file = new File(plugin.getDataFolder(), path);
if (!file.exists()) try {
Files.copy(MMOCore.plugin.getResource("default/" + path), file.getAbsoluteFile().toPath());
} catch (Throwable throwable) {
throw new RuntimeException("Could not load default file '" + path + "'", throwable);
}
}
}

View File

@ -57,16 +57,18 @@ custom-mine-conditions:
# broken when custom mining conditions are met
protect-custom-mine: false
# Edit the plugin handling parties here.
# Choose the plugin handling parties here.
# Supported values (just copy and paste):
# - mmocore
# - mmocore (Default built-in party system)
# - dungeonsxl
# - parties
# - party_and_friends (Use this one if you are using Party and Friends Extended for Spigot)
# - party_and_friends_bungeecord_velocity (Use this one if you are using Party and Friends For Bungeecord, Party and Friends For Velocity or Party and Friends Extended Edition for Bungeecord/Velocity. This one requires https://www.spigotmc.org/resources/spigot-party-api-for-party-and-friends.39751/ to be installed)
# - heroes
# - mcmmo
# - obteam (addon for DungeonMMO)
# - mythicdungeons (only when using default party handler)
# - mythicdungeons (Make sure `PartyPlugin` is set to `Default` in MythicDungeons)
# - mythicdungeons_inject (Make sure `PartyPlugin` is set to `MMOCore` in MythicDungeons)
# - obteam (Addon for DungeonMMO)
# - party_and_friends (When using Party and Friends (Extended) for Spigot)
# - party_and_friends_bungeecord_velocity (When using Party and Friends (Extended) Edition for BungeeCord/Velocity. Requires https://www.spigotmc.org/resources/spigot-party-api-for-party-and-friends.39751/ to be installed)
# - parties
party-plugin: mmocore
# Edit the plugin handling guilds here.

View File

@ -1,15 +0,0 @@
# Every brewing recipe requires an empty water bottle.
# Make sure every brewing recipe has a different ID.
# It is only used as reference in the plugin, doesn't really matter.
# Brewing recipe ID
mana-pot-recipe:
# Ingredient used to brew the empty water bottles.
ingredient: MATERIAL.MANA_FLOWER
# Items replacing empty water bottles when brewing is complete.
result: CONSUMABLE.MANA_POTION
# Time required to brew empty water bottles.
cook-time: 10

View File

@ -1,14 +0,0 @@
# Make sure every furnace recipe has a different ID.
# It is only used as reference in the plugin, doesn't really matter.
# Furnace recipe ID
emerald-recipe:
# Item being smelted.
ingredient: MATERIAL.EMERALD_GEODE
# Item given as output.
result: MATERIAL.SHINY_EMERALD
# Time required to smelt the item.
cook-time: 10

Some files were not shown because too many files have changed in this diff Show More