WIP 1.20.6 support

This commit is contained in:
nossr50
2024-05-02 06:28:20 -07:00
parent 5628df988f
commit 78558107b3
51 changed files with 1874 additions and 736 deletions

View File

@@ -4,31 +4,40 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.VisibleForTesting;
import java.io.File;
import java.util.List;
@Deprecated
public abstract class LegacyConfigLoader {
protected final File configFile;
protected final @NotNull File configFile;
protected final @NotNull File dataFolder;
protected String fileName;
protected @NotNull String fileName;
protected YamlConfiguration config;
public LegacyConfigLoader(String relativePath, String fileName, @NotNull File dataFolder) {
public LegacyConfigLoader(@NotNull String relativePath, @NotNull String fileName, @NotNull File dataFolder) {
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, relativePath + File.separator + fileName);
loadFile();
}
public LegacyConfigLoader(String fileName, @NotNull File dataFolder) {
public LegacyConfigLoader(@NotNull String fileName, @NotNull File dataFolder) {
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, fileName);
loadFile();
}
@VisibleForTesting
public LegacyConfigLoader(@NotNull File file) {
this.fileName = file.getName();
this.dataFolder = file.getParentFile();
configFile = new File(dataFolder, fileName);
loadFile();
}
@Deprecated
public LegacyConfigLoader(String relativePath, String fileName) {
this.fileName = fileName;

View File

@@ -2,22 +2,30 @@ package com.gmail.nossr50.config.skills.alchemy;
import com.gmail.nossr50.config.LegacyConfigLoader;
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.PotionUtil;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.*;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import org.jetbrains.annotations.VisibleForTesting;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.gmail.nossr50.util.PotionUtil.*;
public class PotionConfig extends LegacyConfigLoader {
private static PotionConfig instance;
private final List<ItemStack> concoctionsIngredientsTierOne = new ArrayList<>();
private final List<ItemStack> concoctionsIngredientsTierTwo = new ArrayList<>();
@@ -28,30 +36,34 @@ public class PotionConfig extends LegacyConfigLoader {
private final List<ItemStack> concoctionsIngredientsTierSeven = new ArrayList<>();
private final List<ItemStack> concoctionsIngredientsTierEight = new ArrayList<>();
private final Map<String, AlchemyPotion> potionMap = new HashMap<>();
/**
* Map of potion names to AlchemyPotion objects.
*/
private final Map<String, AlchemyPotion> loadedPotions = new HashMap<>();
private PotionConfig() {
public PotionConfig() {
super("potions.yml");
loadKeys();
}
public static PotionConfig getInstance() {
if (instance == null) {
instance = new PotionConfig();
}
return instance;
@VisibleForTesting
PotionConfig(File file) {
super(file);
}
@Override
protected void loadKeys() {
}
public void loadPotions() {
loadConcoctions();
loadPotionMap();
}
private void loadConcoctions() {
ConfigurationSection concoctionSection = config.getConfigurationSection("Concoctions");
@VisibleForTesting
void loadConcoctions() {
final ConfigurationSection concoctionSection = config.getConfigurationSection("Concoctions");
// Load the ingredients for each tier
loadConcoctionsTier(concoctionsIngredientsTierOne, concoctionSection.getStringList("Tier_One_Ingredients"));
loadConcoctionsTier(concoctionsIngredientsTierTwo, concoctionSection.getStringList("Tier_Two_Ingredients"));
loadConcoctionsTier(concoctionsIngredientsTierThree, concoctionSection.getStringList("Tier_Three_Ingredients"));
@@ -71,7 +83,7 @@ public class PotionConfig extends LegacyConfigLoader {
}
private void loadConcoctionsTier(List<ItemStack> ingredientList, List<String> ingredientStrings) {
if (ingredientStrings != null && ingredientStrings.size() > 0) {
if (ingredientStrings != null && !ingredientStrings.isEmpty()) {
for (String ingredientString : ingredientStrings) {
ItemStack ingredient = loadIngredient(ingredientString);
@@ -85,23 +97,24 @@ public class PotionConfig extends LegacyConfigLoader {
/**
* Find the Potions configuration section and load all defined potions.
*/
private void loadPotionMap() {
int loadPotionMap() {
ConfigurationSection potionSection = config.getConfigurationSection("Potions");
int pass = 0;
int fail = 0;
int potionsLoaded = 0;
int failures = 0;
for (String potionName : potionSection.getKeys(false)) {
AlchemyPotion potion = loadPotion(potionSection.getConfigurationSection(potionName));
if (potion != null) {
potionMap.put(potionName, potion);
pass++;
loadedPotions.put(potionName, potion);
potionsLoaded++;
} else {
fail++;
failures++;
}
}
LogUtils.debug(mcMMO.p.getLogger(), "Loaded " + pass + " Alchemy potions, skipped " + fail + ".");
mcMMO.p.getLogger().info("Loaded " + potionsLoaded + " Alchemy potions, skipped " + failures + ".");
return potionsLoaded;
}
/**
@@ -114,37 +127,88 @@ public class PotionConfig extends LegacyConfigLoader {
*/
private AlchemyPotion loadPotion(ConfigurationSection potion_section) {
try {
final String key = potion_section.getName();
final String displayName = potion_section.getString("Name") != null
? LocaleLoader.addColors(potion_section.getString("Name"))
: null;
final ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
boolean extended = false;
boolean upgraded = false;
String name = potion_section.getString("Name");
if (name != null) {
name = ChatColor.translateAlternateColorCodes('&', name);
if (potionData != null) {
extended = potionData.getBoolean("Extended", false);
upgraded = potionData.getBoolean("Upgraded", false);
}
PotionData data;
if (!potion_section.contains("PotionData")) { // Backwards config compatability
short dataValue = Short.parseShort(potion_section.getName());
Potion potion = Potion.fromDamage(dataValue);
data = new PotionData(potion.getType(), potion.hasExtendedDuration(), potion.getLevel() == 2);
Material material;
final String materialString = potion_section.getString("Material", null);
if (materialString != null) {
material = ItemUtils.exhaustiveMaterialLookup(materialString);
if (material == null) {
mcMMO.p.getLogger().warning("PotionConfig: Failed to parse material for potion " + key + ": " + materialString);
mcMMO.p.getLogger().warning("PotionConfig: Defaulting to POTION");
material = Material.POTION;
}
} else {
ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
data = new PotionData(PotionType.valueOf(potionData.getString("PotionType", "WATER")), potionData.getBoolean("Extended", false), potionData.getBoolean("Upgraded", false));
mcMMO.p.getLogger().warning("PotionConfig: Missing Material config entry for potion " + key + "," +
" from configuration section: " + potion_section + ", defaulting to POTION");
material = Material.POTION;
}
Material material = Material.POTION;
String mat = potion_section.getString("Material", null);
if (mat != null) {
material = Material.valueOf(mat);
final ItemStack itemStack = new ItemStack(material, 1);
final PotionMeta potionMeta = (PotionMeta) itemStack.getItemMeta();
if (potionMeta == null) {
mcMMO.p.getLogger().severe("PotionConfig: Failed to get PotionMeta for " + displayName + ", from configuration section:" +
" " + potion_section);
return null;
}
// extended and upgraded seem to be mutually exclusive
if (extended && upgraded) {
mcMMO.p.getLogger().warning("Potion " + key + " has both Extended and Upgraded set to true," +
" defaulting to Extended.");
upgraded = false;
}
String potionTypeStr = potionData.getString("PotionType", null);
if (potionTypeStr == null) {
mcMMO.p.getLogger().severe("PotionConfig: Missing PotionType for " + displayName + ", from configuration section:" +
" " + potion_section);
return null;
}
PotionType potionType = matchPotionType(potionTypeStr, upgraded, extended);
if (potionType == null) {
// try matching to key
mcMMO.p.getLogger().warning("Failed to match potion type, trying to match with config key...");
matchPotionType(key, upgraded, extended);
}
if (potionType == null) {
mcMMO.p.getLogger().severe("PotionConfig: Failed to parse potion type for: " + potionTypeStr);
return null;
}
// Set base potion type
// NOTE: extended/ignored are effectively ignored here on 1.20.5 and later
PotionUtil.setBasePotionType(potionMeta, potionType, extended, upgraded);
// // Use the name of the potion to indicate upgrade status if not set in PotionData
// if(convertPotionConfigName(key).toUpperCase().contains("STRONG"))
// upgraded = true;
//
// if(convertPotionConfigName(key).toUpperCase().contains("LONG"))
// extended = true;
List<String> lore = new ArrayList<>();
if (potion_section.contains("Lore")) {
for (String line : potion_section.getStringList("Lore")) {
lore.add(ChatColor.translateAlternateColorCodes('&', line));
}
}
potionMeta.setLore(lore);
List<PotionEffect> effects = new ArrayList<>();
if (potion_section.contains("Effects")) {
for (String effect : potion_section.getStringList("Effects")) {
String[] parts = effect.split(" ");
@@ -154,9 +218,9 @@ public class PotionConfig extends LegacyConfigLoader {
int duration = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
if (type != null) {
effects.add(new PotionEffect(type, duration, amplifier));
potionMeta.addCustomEffect(new PotionEffect(type, duration, amplifier), true);
} else {
mcMMO.p.getLogger().warning("Failed to parse effect for potion " + name + ": " + effect);
mcMMO.p.getLogger().severe("PotionConfig: Failed to parse effect for potion " + displayName + ": " + effect);
}
}
}
@@ -165,8 +229,9 @@ public class PotionConfig extends LegacyConfigLoader {
if (potion_section.contains("Color")) {
color = Color.fromRGB(potion_section.getInt("Color"));
} else {
color = this.generateColor(effects);
color = this.generateColor(potionMeta.getCustomEffects());
}
potionMeta.setColor(color);
Map<ItemStack, String> children = new HashMap<>();
if (potion_section.contains("Children")) {
@@ -175,14 +240,15 @@ public class PotionConfig extends LegacyConfigLoader {
if (ingredient != null) {
children.put(ingredient, potion_section.getConfigurationSection("Children").getString(child));
} else {
mcMMO.p.getLogger().warning("Failed to parse child for potion " + name + ": " + child);
mcMMO.p.getLogger().severe("PotionConfig: Failed to parse child for potion " + displayName + ": " + child);
}
}
}
return new AlchemyPotion(material, data, name, lore, effects, color, children);
// TODO: Might not need to .setItemMeta
itemStack.setItemMeta(potionMeta);
return new AlchemyPotion(itemStack, children);
} catch (Exception e) {
mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getName());
mcMMO.p.getLogger().warning("PotionConfig: Failed to load Alchemy potion: " + potion_section.getName());
return null;
}
}
@@ -210,39 +276,52 @@ public class PotionConfig extends LegacyConfigLoader {
return null;
}
/**
* Get the ingredients for the given tier.
* @param tier Tier to get ingredients for.
* @return List of ingredients for the given tier.
*/
public List<ItemStack> getIngredients(int tier) {
switch (tier) {
case 8:
return concoctionsIngredientsTierEight;
case 7:
return concoctionsIngredientsTierSeven;
case 6:
return concoctionsIngredientsTierSix;
case 5:
return concoctionsIngredientsTierFive;
case 4:
return concoctionsIngredientsTierFour;
case 3:
return concoctionsIngredientsTierThree;
case 2:
return concoctionsIngredientsTierTwo;
case 1:
default:
return concoctionsIngredientsTierOne;
}
return switch (tier) {
case 8 -> concoctionsIngredientsTierEight;
case 7 -> concoctionsIngredientsTierSeven;
case 6 -> concoctionsIngredientsTierSix;
case 5 -> concoctionsIngredientsTierFive;
case 4 -> concoctionsIngredientsTierFour;
case 3 -> concoctionsIngredientsTierThree;
case 2 -> concoctionsIngredientsTierTwo;
default -> concoctionsIngredientsTierOne;
};
}
/**
* Check if the given ItemStack is a valid potion.
* @param item ItemStack to be checked.
* @return True if the given ItemStack is a valid potion, false otherwise.
*/
public boolean isValidPotion(ItemStack item) {
return getPotion(item) != null;
}
/**
* Get the AlchemyPotion that corresponds to the given name.
* @param name Name of the potion to be checked.
* @return AlchemyPotion that corresponds to the given name.
*/
public AlchemyPotion getPotion(String name) {
return potionMap.get(name);
return loadedPotions.get(name);
}
/**
* Get the AlchemyPotion that corresponds to the given ItemStack.
*
* @param item ItemStack to be checked.
*
* @return AlchemyPotion that corresponds to the given ItemStack.
*/
public AlchemyPotion getPotion(ItemStack item) {
for (AlchemyPotion potion : potionMap.values()) {
if (potion.isSimilar(item)) {
for (AlchemyPotion potion : loadedPotions.values()) {
if (potion.isSimilarPotion(item)) {
return potion;
}
}

View File

@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.treasure.*;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.EnchantmentUtils;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.PotionUtil;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -13,12 +14,13 @@ import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
public class FishingTreasureConfig extends BukkitConfig {
public static final String FILENAME = "fishing_treasures.yml";
@@ -204,30 +206,40 @@ public class FishingTreasureConfig extends BukkitConfig {
}
if (materialName.contains("POTION")) {
// Update for 1.20.5
Material mat = Material.matchMaterial(materialName);
if (mat == null) {
reason.add("Potion format for " + FILENAME + " has changed");
continue;
} else {
item = new ItemStack(mat, amount, data);
PotionMeta itemMeta = (PotionMeta) item.getItemMeta();
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
if (itemMeta == null) {
mcMMO.p.getLogger().severe("Item meta when adding potion to fishing treasure was null, contact the mcMMO devs!");
if (potionMeta == null) {
mcMMO.p.getLogger().severe("FishingConfig: Item meta when adding potion to fishing treasure was null," +
" contact the mcMMO devs!");
reason.add("FishingConfig: Item meta when adding potion to fishing treasure was null");
continue;
}
PotionType potionType = null;
try {
potionType = PotionType.valueOf(config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
} catch (IllegalArgumentException ex) {
reason.add("Invalid Potion_Type: " + config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
}
String potionTypeStr;
potionTypeStr = config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER");
boolean extended = config.getBoolean(type + "." + treasureName + ".PotionData.Extended", false);
boolean upgraded = config.getBoolean(type + "." + treasureName + ".PotionData.Upgraded", false);
itemMeta.setBasePotionData(new PotionData(potionType, extended, upgraded));
final PotionType potionType = matchPotionType(potionTypeStr, extended, upgraded);
if (potionType == null) {
reason.add("FishingConfig: Could not derive potion type from: " + potionTypeStr +", " + extended + ", " + upgraded);
continue;
}
// Set the base potion type
// NOTE: Upgraded/Extended are ignored in 1.20.5 and later
PotionUtil.setBasePotionType(potionMeta, potionType, upgraded, extended);
if (customName != null) {
itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', customName));
potionMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', customName));
}
if (config.contains(type + "." + treasureName + ".Lore")) {
@@ -235,9 +247,9 @@ public class FishingTreasureConfig extends BukkitConfig {
for (String s : config.getStringList(type + "." + treasureName + ".Lore")) {
lore.add(ChatColor.translateAlternateColorCodes('&', s));
}
itemMeta.setLore(lore);
potionMeta.setLore(lore);
}
item.setItemMeta(itemMeta);
item.setItemMeta(potionMeta);
}
} else if (material == Material.ENCHANTED_BOOK) {
//If any whitelisted enchants exist we use whitelist-based matching
@@ -355,7 +367,8 @@ public class FishingTreasureConfig extends BukkitConfig {
Enchantment enchantment = EnchantmentUtils.getByName(enchantmentName);
if (enchantment == null) {
mcMMO.p.getLogger().warning("Skipping invalid enchantment in " + FILENAME + ": " + enchantmentName);
mcMMO.p.getLogger().info("Skipping invalid enchantment in '" + FILENAME + "', named:"
+ enchantmentName);
continue;
}

View File

@@ -6,6 +6,7 @@ import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.BlockUtils;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.PotionUtil;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -14,7 +15,6 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import java.io.IOException;
@@ -165,22 +165,33 @@ public class TreasureConfig extends BukkitConfig {
Material mat = Material.matchMaterial(materialName);
if (mat == null) {
reason.add("Potion format for " + FILENAME + " has changed");
continue;
} else {
item = new ItemStack(mat, amount, data);
PotionMeta itemMeta = (PotionMeta) item.getItemMeta();
PotionType potionType = null;
try {
potionType = PotionType.valueOf(config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
} catch (IllegalArgumentException ex) {
reason.add("Invalid Potion_Type: " + config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
if (potionMeta == null) {
mcMMO.p.getLogger().severe("Item meta when adding potion to treasure was null, contact the mcMMO devs!");
reason.add("Item meta when adding potion to treasure was null, contact the mcMMO devs!");
continue;
}
String potionTypeStr;
potionTypeStr = config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER");
boolean extended = config.getBoolean(type + "." + treasureName + ".PotionData.Extended", false);
boolean upgraded = config.getBoolean(type + "." + treasureName + ".PotionData.Upgraded", false);
itemMeta.setBasePotionData(new PotionData(potionType, extended, upgraded));
PotionType potionType = PotionUtil.matchPotionType(potionTypeStr, extended, upgraded);
if (potionType == null) {
reason.add("Could not derive potion type from: " + potionTypeStr +", " + extended + ", " + upgraded);
continue;
}
// Set the base potion type
// NOTE: extended/upgraded are ignored in 1.20.5 and later
PotionUtil.setBasePotionType(potionMeta, potionType, extended, upgraded);
if (config.contains(type + "." + treasureName + ".Custom_Name")) {
itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString(type + "." + treasureName + ".Custom_Name")));
potionMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString(type + "." + treasureName + ".Custom_Name")));
}
if (config.contains(type + "." + treasureName + ".Lore")) {
@@ -188,9 +199,9 @@ public class TreasureConfig extends BukkitConfig {
for (String s : config.getStringList(type + "." + treasureName + ".Lore")) {
lore.add(ChatColor.translateAlternateColorCodes('&', s));
}
itemMeta.setLore(lore);
potionMeta.setLore(lore);
}
item.setItemMeta(itemMeta);
item.setItemMeta(potionMeta);
}
} else if (material != null) {
item = new ItemStack(material, amount, data);